Coverage for test/d7a/dll/test_dll_access_profile.py: 100%

62 statements  

« prev     ^ index     » next       coverage.py v7.5.0, created at 2024-05-24 08:03 +0200

1# 

2# Copyright (c) 2015-2021 University of Antwerp, Aloxy NV. 

3# 

4# This file is part of pyd7a. 

5# See https://github.com/Sub-IoT/pyd7a for further info. 

6# 

7# Licensed under the Apache License, Version 2.0 (the "License"); 

8# you may not use this file except in compliance with the License. 

9# You may obtain a copy of the License at 

10# 

11# http://www.apache.org/licenses/LICENSE-2.0 

12# 

13# Unless required by applicable law or agreed to in writing, software 

14# distributed under the License is distributed on an "AS IS" BASIS, 

15# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

16# See the License for the specific language governing permissions and 

17# limitations under the License. 

18# 

19import unittest 

20 

21from bitstring import ConstBitStream 

22 

23from d7a.dll.access_profile import AccessProfile, CsmaCaMode, SubBand 

24from d7a.dll.sub_profile import SubProfile 

25from d7a.phy.channel_header import ChannelHeader, ChannelBand, ChannelCoding, ChannelClass 

26from d7a.types.ct import CT 

27 

28 

29class TestAccessProfile(unittest.TestCase): 

30 valid_channel_header = ChannelHeader( 

31 channel_class=ChannelClass.NORMAL_RATE, 

32 channel_coding=ChannelCoding.PN9, 

33 channel_band=ChannelBand.BAND_433 

34 ) 

35 

36 valid_sub_bands = [ 

37 SubBand(), 

38 SubBand(), 

39 SubBand(), 

40 SubBand(), 

41 SubBand(), 

42 SubBand(), 

43 SubBand(), 

44 SubBand() 

45 ] 

46 

47 valid_sub_profiles = [ 

48 SubProfile(), 

49 SubProfile(), 

50 SubProfile(), 

51 SubProfile() 

52 ] 

53 

54 def test_validation_ok(self): 

55 ap = AccessProfile(channel_header=self.valid_channel_header, 

56 sub_profiles=self.valid_sub_profiles, 

57 sub_bands=self.valid_sub_bands) 

58 

59 

60 def test_validation_sub_profiles(self): 

61 def bad(): 

62 ap = AccessProfile(channel_header=self.valid_channel_header, 

63 sub_profiles=[], 

64 sub_bands=self.valid_sub_bands) 

65 

66 self.assertRaises(ValueError, bad) 

67 

68 def test_validation_sub_profiles_count(self): 

69 def bad(): 

70 sub_profiles = [SubProfile() for _ in range(10)] # too many ... 

71 

72 ap = AccessProfile(channel_header=self.valid_channel_header, 

73 sub_profiles=sub_profiles, 

74 sub_bands=self.valid_sub_bands) 

75 

76 self.assertRaises(ValueError, bad) 

77 

78 def test_validation_sub_bands_type(self): 

79 def bad(): 

80 ap = AccessProfile(channel_header=self.valid_channel_header, 

81 sub_profiles=self.valid_sub_profiles, 

82 sub_bands=[None]) 

83 

84 self.assertRaises(ValueError, bad) 

85 

86 def test_validation_sub_bands_count(self): 

87 def bad(): 

88 sub_bands = [SubBand() for _ in range(10)] # too many ... 

89 

90 ap = AccessProfile(channel_header=self.valid_channel_header, 

91 sub_profiles=self.valid_sub_profiles, 

92 sub_bands=sub_bands) 

93 

94 self.assertRaises(ValueError, bad) 

95 

96 def test_byte_generation(self): 

97 expected = [ 

98 0b00101000, # channel header 

99 ] 

100 

101 for _ in range(AccessProfile.NUMBER_OF_SUB_PROFILES): 

102 expected.extend(list(bytearray(SubProfile()))) 

103 

104 expected.extend(list(bytearray(SubBand()))) # only one sub_band 

105 

106 ap = AccessProfile(channel_header=self.valid_channel_header, 

107 sub_bands=[SubBand()], 

108 sub_profiles=self.valid_sub_profiles) 

109 

110 bytes = bytearray(ap) 

111 for i in range(len(bytes)): 

112 self.assertEqual(expected[i], bytes[i]) 

113 

114 self.assertEqual(len(expected), len(bytes)) 

115 

116 def test_parse(self): 

117 bytes = list(bytearray(self.valid_channel_header)) 

118 

119 for _ in range(AccessProfile.NUMBER_OF_SUB_PROFILES): 

120 bytes.extend(list(bytearray(SubProfile()))) 

121 

122 for _ in range(AccessProfile.MAX_NUMBER_OF_SUB_BANDS): 

123 bytes.extend(list(bytearray(SubBand()))) 

124 

125 ap = AccessProfile.parse(ConstBitStream(bytes=bytes)) 

126 self.assertEqual(ap.channel_header.channel_band, self.valid_channel_header.channel_band) 

127 self.assertEqual(ap.channel_header.channel_coding, self.valid_channel_header.channel_coding) 

128 self.assertEqual(ap.channel_header.channel_class, self.valid_channel_header.channel_class) 

129 self.assertEqual(len(ap.sub_bands), AccessProfile.MAX_NUMBER_OF_SUB_BANDS) 

130 for sb in ap.sub_bands: 

131 self.assertEqual(sb.channel_index_start, SubBand().channel_index_start) 

132 self.assertEqual(sb.channel_index_end, SubBand().channel_index_end) 

133 self.assertEqual(sb.cca, SubBand().cca) 

134 self.assertEqual(sb.duty, SubBand().duty) 

135 self.assertEqual(sb.eirp, SubBand().eirp) 

136 

137 for sp in ap.sub_profiles: 

138 self.assertEqual(sp.subband_bitmap, SubProfile().subband_bitmap) 

139 self.assertEqual(sp.scan_automation_period.exp, SubProfile().scan_automation_period.exp) 

140 self.assertEqual(sp.scan_automation_period.mant, SubProfile().scan_automation_period.mant) 

141 

142 self.assertEqual(len(ap.sub_profiles), AccessProfile.NUMBER_OF_SUB_PROFILES) 

143