Skip to content

Commit b0be7ca

Browse files
authored
[xcvrd] add unit test infrastructure and unit tests for xcvrd (#133)
Summary: This PR provides the necessary infrastructure to add pytest support and integration in sonic-xcvrd submodule. This PR also adds unit tests for xcvrd daemon. What is the motivation for this PR? To add the pytest unittest support in sonic-platform-daemon, sonix-xcvrd daemon as well as add some unit tests Signed-off-by: vaibhav-dahiya <[email protected]>
1 parent 8555077 commit b0be7ca

File tree

8 files changed

+532
-0
lines changed

8 files changed

+532
-0
lines changed

sonic-xcvrd/pytest.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[pytest]
2+
addopts = --cov=xcvrd --cov-report html

sonic-xcvrd/setup.cfg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[aliases]
2+
test=pytest

sonic-xcvrd/setup.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424
setup_requires=[
2525
'wheel'
2626
],
27+
tests_require=[
28+
'pytest',
29+
'pytest-cov',
30+
],
2731
classifiers=[
2832
'Development Status :: 4 - Beta',
2933
'Environment :: No Input/Output (Daemon)',

sonic-xcvrd/tests/__init__.py

Whitespace-only changes.

sonic-xcvrd/tests/mock_platform.py

Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
class MockDevice:
2+
def __init__(self):
3+
self.name = None
4+
self.presence = True
5+
self.model = 'FAN Model'
6+
self.serial = 'Fan Serial'
7+
8+
def get_name(self):
9+
return self.name
10+
11+
def get_presence(self):
12+
return self.presence
13+
14+
def get_model(self):
15+
return self.model
16+
17+
def get_serial(self):
18+
return self.serial
19+
20+
def get_position_in_parent(self):
21+
return 1
22+
23+
def is_replaceable(self):
24+
return True
25+
26+
def get_status(self):
27+
return True
28+
29+
30+
class MockFan(MockDevice):
31+
STATUS_LED_COLOR_RED = 'red'
32+
STATUS_LED_COLOR_GREEN = 'green'
33+
34+
def __init__(self):
35+
MockDevice.__init__(self)
36+
self.speed = 20
37+
self.speed_tolerance = 20
38+
self.target_speed = 20
39+
self.status = True
40+
self.direction = 'intake'
41+
self.led_status = 'red'
42+
43+
def get_speed(self):
44+
return self.speed
45+
46+
def get_speed_tolerance(self):
47+
return self.speed_tolerance
48+
49+
def get_target_speed(self):
50+
return self.target_speed
51+
52+
def get_status(self):
53+
return self.status
54+
55+
def get_direction(self):
56+
return self.direction
57+
58+
def get_status_led(self):
59+
return self.led_status
60+
61+
def set_status_led(self, value):
62+
self.led_status = value
63+
64+
def make_under_speed(self):
65+
self.speed = 1
66+
self.target_speed = 2
67+
self.speed_tolerance = 0
68+
69+
def make_over_speed(self):
70+
self.speed = 2
71+
self.target_speed = 1
72+
self.speed_tolerance = 0
73+
74+
def make_normal_speed(self):
75+
self.speed = 1
76+
self.target_speed = 1
77+
self.speed_tolerance = 0
78+
79+
80+
class MockErrorFan(MockFan):
81+
def get_speed(self):
82+
raise Exception('Fail to get speed')
83+
84+
85+
class MockPsu(MockDevice):
86+
def __init__(self):
87+
MockDevice.__init__(self)
88+
self.fan_list = []
89+
90+
def get_all_fans(self):
91+
return self.fan_list
92+
93+
94+
class MockFanDrawer(MockDevice):
95+
def __init__(self, index):
96+
MockDevice.__init__(self)
97+
self.name = 'FanDrawer {}'.format(index)
98+
self.fan_list = []
99+
self.led_status = 'red'
100+
101+
def get_name(self):
102+
return self.name
103+
104+
def get_all_fans(self):
105+
return self.fan_list
106+
107+
def get_status_led(self):
108+
return self.led_status
109+
110+
def set_status_led(self, value):
111+
self.led_status = value
112+
113+
114+
class MockThermal(MockDevice):
115+
def __init__(self, index=None):
116+
MockDevice.__init__(self)
117+
self.name = None
118+
self.name = 'Thermal {}'.format(index) if index != None else None
119+
self.temperature = 2
120+
self.minimum_temperature = 1
121+
self.maximum_temperature = 5
122+
self.high_threshold = 3
123+
self.low_threshold = 1
124+
self.high_critical_threshold = 4
125+
self.low_critical_threshold = 0
126+
127+
def get_name(self):
128+
return self.name
129+
130+
def get_temperature(self):
131+
return self.temperature
132+
133+
def get_minimum_recorded(self):
134+
return self.minimum_temperature
135+
136+
def get_maximum_recorded(self):
137+
return self.maximum_temperature
138+
139+
def get_high_threshold(self):
140+
return self.high_threshold
141+
142+
def get_low_threshold(self):
143+
return self.low_threshold
144+
145+
def get_high_critical_threshold(self):
146+
return self.high_critical_threshold
147+
148+
def get_low_critical_threshold(self):
149+
return self.low_critical_threshold
150+
151+
def make_over_temper(self):
152+
self.high_threshold = 2
153+
self.temperature = 3
154+
self.low_threshold = 1
155+
156+
def make_under_temper(self):
157+
self.high_threshold = 3
158+
self.temperature = 1
159+
self.low_threshold = 2
160+
161+
def make_normal_temper(self):
162+
self.high_threshold = 3
163+
self.temperature = 2
164+
self.low_threshold = 1
165+
166+
167+
class MockErrorThermal(MockThermal):
168+
def get_temperature(self):
169+
raise Exception('Fail to get temperature')
170+
171+
172+
class MockChassis:
173+
def __init__(self):
174+
self.fan_list = []
175+
self.psu_list = []
176+
self.thermal_list = []
177+
self.fan_drawer_list = []
178+
self.sfp_list = []
179+
self.is_chassis_system = False
180+
181+
def get_all_fans(self):
182+
return self.fan_list
183+
184+
def get_all_psus(self):
185+
return self.psu_list
186+
187+
def get_all_thermals(self):
188+
return self.thermal_list
189+
190+
def get_all_fan_drawers(self):
191+
return self.fan_drawer_list
192+
193+
def get_all_sfps(self):
194+
return self.sfp_list
195+
196+
def get_num_thermals(self):
197+
return len(self.thermal_list)
198+
199+
def make_absence_fan(self):
200+
fan = MockFan()
201+
fan.presence = False
202+
fan_drawer = MockFanDrawer(len(self.fan_drawer_list))
203+
fan_drawer.fan_list.append(fan)
204+
self.fan_list.append(fan)
205+
self.fan_drawer_list.append(fan_drawer)
206+
207+
def make_fault_fan(self):
208+
fan = MockFan()
209+
fan.status = False
210+
fan_drawer = MockFanDrawer(len(self.fan_drawer_list))
211+
fan_drawer.fan_list.append(fan)
212+
self.fan_list.append(fan)
213+
self.fan_drawer_list.append(fan_drawer)
214+
215+
def make_under_speed_fan(self):
216+
fan = MockFan()
217+
fan.make_under_speed()
218+
fan_drawer = MockFanDrawer(len(self.fan_drawer_list))
219+
fan_drawer.fan_list.append(fan)
220+
self.fan_list.append(fan)
221+
self.fan_drawer_list.append(fan_drawer)
222+
223+
def make_over_speed_fan(self):
224+
fan = MockFan()
225+
fan.make_over_speed()
226+
fan_drawer = MockFanDrawer(len(self.fan_drawer_list))
227+
fan_drawer.fan_list.append(fan)
228+
self.fan_list.append(fan)
229+
self.fan_drawer_list.append(fan_drawer)
230+
231+
def make_error_fan(self):
232+
fan = MockErrorFan()
233+
fan_drawer = MockFanDrawer(len(self.fan_drawer_list))
234+
fan_drawer.fan_list.append(fan)
235+
self.fan_list.append(fan)
236+
self.fan_drawer_list.append(fan_drawer)
237+
238+
def make_over_temper_thermal(self):
239+
thermal = MockThermal()
240+
thermal.make_over_temper()
241+
self.thermal_list.append(thermal)
242+
243+
def make_under_temper_thermal(self):
244+
thermal = MockThermal()
245+
thermal.make_under_temper()
246+
self.thermal_list.append(thermal)
247+
248+
def make_error_thermal(self):
249+
thermal = MockErrorThermal()
250+
self.thermal_list.append(thermal)
251+
252+
def is_modular_chassis(self):
253+
return self.is_chassis_system
254+
255+
def set_modular_chassis(self, is_true):
256+
self.is_chassis_system = is_true
257+
258+
def set_my_slot(self, my_slot):
259+
self.my_slot = my_slot
260+
261+
def get_my_slot(self):
262+
return self.my_slot
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
STATE_DB = ''
2+
CHASSIS_STATE_DB = ''
3+
4+
5+
class Table:
6+
def __init__(self, db, table_name):
7+
self.table_name = table_name
8+
self.mock_dict = {}
9+
10+
def _del(self, key):
11+
if key in self.mock_dict:
12+
del self.mock_dict[key]
13+
pass
14+
15+
def set(self, key, fvs):
16+
self.mock_dict[key] = fvs
17+
pass
18+
19+
def get(self, key):
20+
if key in self.mock_dict:
21+
return self.mock_dict[key]
22+
return None
23+
24+
def get_size(self):
25+
return (len(self.mock_dict))
26+
27+
28+
class FieldValuePairs:
29+
def __init__(self, fvs):
30+
self.fv_dict = dict(fvs)
31+
pass
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# name lanes alias
2+
Ethernet0 29,30,31,32 fortyGigE0/0
3+
Ethernet4 25,26,27,28 fortyGigE0/4
4+
Ethernet8 37,38,39,40 fortyGigE0/8
5+
Ethernet12 33,34,35,36 fortyGigE0/12
6+
Ethernet16 41,42,43,44 fortyGigE0/16
7+
Ethernet20 45,46,47,48 fortyGigE0/20
8+
Ethernet24 5,6,7,8 fortyGigE0/24
9+
Ethernet28 1,2,3,4 fortyGigE0/28
10+
Ethernet32 9,10,11,12 fortyGigE0/32
11+
Ethernet36 13,14,15,16 fortyGigE0/36
12+
Ethernet40 21,22,23,24 fortyGigE0/40
13+
Ethernet44 17,18,19,20 fortyGigE0/44
14+
Ethernet48 49,50,51,52 fortyGigE0/48

0 commit comments

Comments
 (0)