77
88
99class PrebootTest (object ):
10- def __init__ (self , oper_type , vm_list , portchannel_ports , vm_dut_map , test_args , dut_ssh ):
10+ def __init__ (self , oper_type , vm_list , portchannel_ports , vm_dut_map , test_args , dut_ssh , vlan_ports ):
1111 self .oper_type = oper_type
1212 self .vm_list = vm_list
1313 self .portchannel_ports = portchannel_ports
1414 self .vm_dut_map = vm_dut_map
1515 self .test_args = test_args
1616 self .dut_ssh = dut_ssh
17+ self .vlan_ports = vlan_ports
1718 self .fails_vm = set ()
1819 self .fails_dut = set ()
1920 self .log = []
20- self .shandle = SadOper (self .oper_type , self .vm_list , self .portchannel_ports , self .vm_dut_map , self .test_args , self .dut_ssh )
21+ self .shandle = SadOper (self .oper_type , self .vm_list , self .portchannel_ports , self .vm_dut_map , self .test_args , self .dut_ssh , self . vlan_ports )
2122
2223 def setup (self ):
2324 self .shandle .sad_setup (is_up = False )
2425 return self .shandle .retreive_test_info (), self .shandle .retreive_logs ()
2526
2627 def verify (self , pre_check = True ):
27- self .shandle .sad_bgp_verify ()
28- if 'lag' in self .oper_type :
29- self .shandle .sad_lag_verify (pre_check = pre_check )
28+ if 'vlan' in self .oper_type :
29+ self .shandle .verify_vlan_port_state (pre_check = pre_check )
30+ else :
31+ self .shandle .sad_bgp_verify ()
32+ if 'lag' in self .oper_type :
33+ self .shandle .sad_lag_verify (pre_check = pre_check )
3034 return self .shandle .retreive_logs ()
3135
3236 def revert (self ):
@@ -35,14 +39,16 @@ def revert(self):
3539
3640
3741class SadPath (object ):
38- def __init__ (self , oper_type , vm_list , portchannel_ports , vm_dut_map , test_args ):
42+ def __init__ (self , oper_type , vm_list , portchannel_ports , vm_dut_map , test_args , vlan_ports ):
3943 self .oper_type = ''
4044 self .cnt = 1
4145 self .memb_cnt = 0
4246 self .vm_list = vm_list
4347 self .portchannel_ports = portchannel_ports
4448 self .vm_dut_map = vm_dut_map
4549 self .test_args = test_args
50+ self .vlan_ports = vlan_ports
51+ self .vlan_if_port = self .test_args ['vlan_if_port' ]
4652 self .neigh_vms = []
4753 self .neigh_names = dict ()
4854 self .vm_handles = dict ()
@@ -53,13 +59,16 @@ def __init__(self, oper_type, vm_list, portchannel_ports, vm_dut_map, test_args)
5359 self .fails ['dut' ] = set ()
5460 self .tot_memb_cnt = 0
5561 self .memb_index = 0
62+ self .if_port = []
63+ self .down_vlan_info = []
5664 self .extract_oper_info (oper_type )
5765
5866 def extract_oper_info (self , oper_type ):
5967 if oper_type and ':' in oper_type :
6068 temp = oper_type .split (':' )
6169 self .oper_type = temp [0 ]
62- # get number of VMs where the sad pass oper needs to be done
70+ # get number of VMs where the sad pass oper needs to be done. For vlan_member case,
71+ # this will be the number of down vlan ports
6372 self .cnt = int (temp [1 ])
6473 if len (temp ) > 2 :
6574 # get the number of lag members in a portchannel that should be brought down
@@ -122,6 +131,24 @@ def select_member(self):
122131 if self .tot_memb_cnt != 0 :
123132 self .memb_index = datetime .datetime .now ().day % self .tot_memb_cnt
124133
134+ def select_vlan_ports (self ):
135+ self .if_port = sorted (self .vlan_if_port , key = lambda tup : tup [0 ])
136+ vlan_len = len (self .if_port )
137+ vlan_index = datetime .datetime .now ().day % vlan_len if vlan_len > 0 else 0
138+ exceed_len = vlan_index + self .cnt - vlan_len
139+ if exceed_len <= 0 :
140+ self .down_vlan_info .extend (self .if_port [vlan_index :vlan_index + self .cnt ])
141+ self .if_port = self .if_port [0 :vlan_index ] + self .if_port [vlan_index + self .cnt :]
142+ else :
143+ self .down_vlan_info .extend (self .if_port [vlan_index :])
144+ self .down_vlan_info .extend (self .if_port [0 :exceed_len ])
145+ self .if_port = self .if_port [exceed_len :exceed_len + vlan_len - self .cnt ]
146+
147+ def down_vlan_ports (self ):
148+ # extract the selected vlan ports and mark them down
149+ for item in self .down_vlan_info :
150+ self .vlan_ports .remove (item [1 ])
151+
125152 def setup (self ):
126153 self .select_vm ()
127154 self .get_neigh_name ()
@@ -146,15 +173,15 @@ def setup(self):
146173 self .log .append ('DUT BGP v6: %s' % self .dut_bgps [vm ]['v6' ])
147174
148175 def retreive_test_info (self ):
149- return self .vm_list , self .portchannel_ports , self .neigh_vms
176+ return self .vm_list , self .portchannel_ports , self .neigh_vms , self . vlan_ports
150177
151178 def retreive_logs (self ):
152179 return self .log , self .fails
153180
154181
155182class SadOper (SadPath ):
156- def __init__ (self , oper_type , vm_list , portchannel_ports , vm_dut_map , test_args , dut_ssh ):
157- super (SadOper , self ).__init__ (oper_type , vm_list , portchannel_ports , vm_dut_map , test_args )
183+ def __init__ (self , oper_type , vm_list , portchannel_ports , vm_dut_map , test_args , dut_ssh , vlan_ports ):
184+ super (SadOper , self ).__init__ (oper_type , vm_list , portchannel_ports , vm_dut_map , test_args , vlan_ports )
158185 self .dut_ssh = dut_ssh
159186 self .dut_needed = dict ()
160187 self .lag_members_down = dict ()
@@ -185,10 +212,14 @@ def sad_setup(self, is_up=True):
185212 self .log = []
186213
187214 if not is_up :
188- self .setup ()
189- self .populate_bgp_state ()
190- if 'lag' in self .oper_type :
191- self .populate_lag_state ()
215+ if 'vlan' in self .oper_type :
216+ self .select_vlan_ports ()
217+ self .down_vlan_ports ()
218+ else :
219+ self .setup ()
220+ self .populate_bgp_state ()
221+ if 'lag' in self .oper_type :
222+ self .populate_lag_state ()
192223
193224 if 'bgp' in self .oper_type :
194225 self .log .append ('BGP state change will be for %s' % ", " .join (self .neigh_vms ))
@@ -220,6 +251,47 @@ def sad_setup(self, is_up=True):
220251 # wait for sometime for lag members state to sync
221252 time .sleep (120 )
222253
254+ elif 'vlan' in self .oper_type :
255+ self .change_vlan_port_state (is_up = is_up )
256+
257+ def change_vlan_port_state (self , is_up = True ):
258+ state = ['shutdown' , 'startup' ]
259+
260+ for intf , port in self .down_vlan_info :
261+ if not re .match ('Ethernet\d+' , intf ): continue
262+ self .log .append ('Changing state of %s from DUT side to %s' % (intf , state [is_up ]))
263+ stdout , stderr , return_code = self .cmd (['ssh' , '-oStrictHostKeyChecking=no' , self .dut_ssh , 'sudo config interface %s %s' % (state [is_up ], intf )])
264+ if return_code != 0 :
265+ self .fails ['dut' ].add ('%s: State change not successful from DUT side for %s' % (self .msg_prefix [1 - is_up ], intf ))
266+ self .fails ['dut' ].add ('%s: Return code: %d' % (self .msg_prefix [1 - is_up ], return_code ))
267+ self .fails ['dut' ].add ('%s: Stderr: %s' % (self .msg_prefix [1 - is_up ], stderr ))
268+ else :
269+ self .log .append ('State change successful on DUT for %s' % intf )
270+
271+ def verify_vlan_port_state (self , state = 'down' , pre_check = True ):
272+ self .log = []
273+ # pattern match "Ethernet252 177,178,179,180 40G 9100 Ethernet64/1 routed down down QSFP28 off"
274+ # extract the admin status
275+ pat = re .compile ('(\S+\s+){7}%s' % state )
276+ for intf , port in self .down_vlan_info :
277+ stdout , stderr , return_code = self .cmd (['ssh' , '-oStrictHostKeyChecking=no' , self .dut_ssh , 'show interfaces status %s' % intf ])
278+ if return_code == 0 :
279+ for line in stdout .split ('\n ' ):
280+ if intf in line :
281+ is_match = pat .match (line .strip ())
282+ if is_match :
283+ self .log .append ('Interface state is down as expected on the DUT for %s' % intf )
284+ self .log .append ('Pattern check: %s' % line )
285+ break
286+
287+ else :
288+ self .fails ['dut' ].add ('%s: Interface state is not down on the DUT for %s' % (self .msg_prefix [pre_check ], intf ))
289+ self .fails ['dut' ].add ('%s: Obtained: %s' % (self .msg_prefix [pre_check ], line ))
290+ else :
291+ self .fails ['dut' ].add ('%s: Retreiving interface %s info from DUT side failed' % (self .msg_prefix [pre_check ], intf ))
292+ self .fails ['dut' ].add ('%s: Return code: %d' % (self .msg_prefix [pre_check ], return_code ))
293+ self .fails ['dut' ].add ('%s: Stderr: %s' % (self .msg_prefix [pre_check ], stderr ))
294+
223295 def change_bgp_dut_state (self , is_up = True ):
224296 state = ['shutdown' , 'startup' ]
225297 for vm in self .neigh_vms :
0 commit comments