@@ -20,12 +20,13 @@ def __init__(self, oper_type, vm_list, portchannel_ports, vm_dut_map, test_args,
2020 self .shandle = SadOper (self .oper_type , self .vm_list , self .portchannel_ports , self .vm_dut_map , self .test_args , self .dut_ssh )
2121
2222 def setup (self ):
23- if 'bgp' in self .oper_type :
24- self .shandle .sad_setup (is_up = False )
23+ self .shandle .sad_setup (is_up = False )
2524 return self .shandle .retreive_test_info (), self .shandle .retreive_logs ()
2625
27- def verify (self ):
26+ def verify (self , pre_check = True ):
2827 self .shandle .sad_bgp_verify ()
28+ if 'lag' in self .oper_type :
29+ self .shandle .sad_lag_verify (pre_check = pre_check )
2930 return self .shandle .retreive_logs ()
3031
3132 def revert (self ):
@@ -111,6 +112,9 @@ def __init__(self, oper_type, vm_list, portchannel_ports, vm_dut_map, test_args,
111112 super (SadOper , self ).__init__ (oper_type , vm_list , portchannel_ports , vm_dut_map , test_args )
112113 self .dut_ssh = dut_ssh
113114 self .dut_needed = None
115+ self .lag_members_down = None
116+ self .neigh_lag_state = None
117+ self .msg_prefix = ['Postboot' , 'Preboot' ]
114118
115119 def populate_bgp_state (self ):
116120 if self .oper_type == 'neigh_bgp_down' :
@@ -121,19 +125,42 @@ def populate_bgp_state(self):
121125 self .neigh_bgp ['changed_state' ] = 'Active'
122126 self .dut_bgp ['changed_state' ] = 'Idle'
123127 self .dut_needed = self .dut_bgp
128+ elif self .oper_type == 'neigh_lag_down' :
129+ # on the DUT side, bgp states are different pre and post boot. hence passing multiple values
130+ self .neigh_bgp ['changed_state' ] = 'Idle'
131+ self .dut_bgp ['changed_state' ] = 'Connect,Active,Idle'
132+ self .dut_needed = self .dut_bgp
133+ elif self .oper_type == 'dut_lag_down' :
134+ self .neigh_bgp ['changed_state' ] = 'Idle'
135+ self .dut_bgp ['changed_state' ] = 'Active,Connect,Idle'
136+ self .dut_needed = self .dut_bgp
124137
125138 def sad_setup (self , is_up = True ):
126139 self .log = []
140+
127141 if not is_up :
128142 self .setup ()
129143 self .populate_bgp_state ()
130- self .log .append ('BGP state change will be for %s' % self .neigh_vm )
131- if self .oper_type == 'neigh_bgp_down' :
132- self .log .append ('Changing state of AS %s to shut' % self .neigh_bgp ['asn' ])
133- self .vm_handle .change_bgp_neigh_state (self .neigh_bgp ['asn' ], is_up = is_up )
134- elif self .oper_type == 'dut_bgp_down' :
135- self .change_bgp_dut_state (is_up = is_up )
136- time .sleep (30 )
144+ if 'lag' in self .oper_type :
145+ self .populate_lag_state ()
146+
147+ if 'bgp' in self .oper_type :
148+ self .log .append ('BGP state change will be for %s' % self .neigh_vm )
149+ if self .oper_type == 'neigh_bgp_down' :
150+ self .log .append ('Changing state of AS %s to shut' % self .neigh_bgp ['asn' ])
151+ self .vm_handle .change_bgp_neigh_state (self .neigh_bgp ['asn' ], is_up = is_up )
152+ elif self .oper_type == 'dut_bgp_down' :
153+ self .change_bgp_dut_state (is_up = is_up )
154+ time .sleep (30 )
155+ elif 'lag' in self .oper_type :
156+ self .log .append ('LAG state change will be for %s' % self .neigh_vm )
157+ if self .oper_type == 'neigh_lag_down' :
158+ self .log .append ('Changing state of LAG %s to shut' % self .vm_dut_map [self .neigh_name ]['neigh_portchannel' ])
159+ self .vm_handle .change_neigh_lag_state (self .vm_dut_map [self .neigh_name ]['neigh_portchannel' ], is_up = is_up )
160+ elif self .oper_type == 'dut_lag_down' :
161+ self .change_dut_lag_state (is_up = is_up )
162+ # wait for sometime for lag members state to sync
163+ time .sleep (120 )
137164
138165 def change_bgp_dut_state (self , is_up = True ):
139166 state = ['shutdown' , 'startup' ]
@@ -149,18 +176,19 @@ def change_bgp_dut_state(self, is_up=True):
149176 self .fails ['dut' ].add ('Stderr: %s' % stderr )
150177
151178 def verify_bgp_dut_state (self , state = 'Idle' ):
179+ states = state .split (',' )
152180 bgp_state = {}
153181 bgp_state ['v4' ] = bgp_state ['v6' ] = False
154182 for key in self .neigh_bgp .keys ():
155183 if key not in ['v4' , 'v6' ]:
156184 continue
157- self .log .append ('Verifying if the DUT side BGP peer %s is %s' % (self .neigh_bgp [key ], state ))
185+ self .log .append ('Verifying if the DUT side BGP peer %s is %s' % (self .neigh_bgp [key ], states ))
158186 stdout , stderr , return_code = self .cmd (['ssh' , '-oStrictHostKeyChecking=no' , self .dut_ssh , 'show ip bgp neighbor %s' % self .neigh_bgp [key ]])
159187 if return_code == 0 :
160188 for line in stdout .split ('\n ' ):
161189 if 'BGP state' in line :
162190 curr_state = re .findall ('BGP state = (\w+)' , line )[0 ]
163- bgp_state [key ] = (curr_state == state )
191+ bgp_state [key ] = (curr_state in states )
164192 break
165193 else :
166194 self .fails ['dut' ].add ('Retreiving BGP info for peer %s from DUT side failed' % self .neigh_bgp [key ])
@@ -181,3 +209,68 @@ def sad_bgp_verify(self):
181209 self .log .append ('BGP state down as expected on DUT' )
182210 else :
183211 self .fails ['dut' ].add ('BGP state not down on DUT' )
212+
213+ def populate_lag_state (self ):
214+ if self .oper_type == 'neigh_lag_down' :
215+ self .neigh_lag_state = 'disabled'
216+ self .lag_members_down = self .vm_dut_map [self .neigh_name ]['dut_ports' ]
217+ elif self .oper_type == 'dut_lag_down' :
218+ self .lag_members_down = self .vm_dut_map [self .neigh_name ]['dut_ports' ]
219+ self .neigh_lag_state = 'notconnect'
220+
221+ def change_dut_lag_state (self , is_up = True ):
222+ state = ['shutdown' , 'startup' ]
223+ dut_portchannel = self .vm_dut_map [self .neigh_name ]['dut_portchannel' ]
224+ if not re .match ('(PortChannel|Ethernet)\d+' , dut_portchannel ): return
225+ self .log .append ('Changing state of %s from DUT side to %s' % (dut_portchannel , state [is_up ]))
226+ stdout , stderr , return_code = self .cmd (['ssh' , '-oStrictHostKeyChecking=no' , self .dut_ssh , 'sudo config interface %s %s' % (state [is_up ], dut_portchannel )])
227+ if return_code != 0 :
228+ self .fails ['dut' ].add ('%s: State change not successful from DUT side for %s' % (self .msg_prefix [1 - is_up ], dut_portchannel ))
229+ self .fails ['dut' ].add ('%s: Return code: %d' % (self .msg_prefix [1 - is_up ], return_code ))
230+ self .fails ['dut' ].add ('%s: Stderr: %s' % (self .msg_prefix [1 - is_up ], stderr ))
231+ else :
232+ self .log .append ('State change successful on DUT' )
233+
234+ def verify_dut_lag_member_state (self , lag_memb_output , pre_check = True ):
235+ success = True
236+ for member in self .vm_dut_map [self .neigh_name ]['dut_ports' ]:
237+ if self .lag_members_down is not None and member in self .lag_members_down :
238+ search_str = '%s(D)' % member
239+ else :
240+ search_str = '%s(S)' % member
241+
242+ if lag_memb_output .find (search_str ) != - 1 :
243+ self .log .append ('Lag member %s state as expected' % member )
244+ else :
245+ success = False
246+ self .fails ['dut' ].add ('%s: Lag member %s state not as expected' % (self .msg_prefix [pre_check ], member ))
247+ return success
248+
249+ def verify_dut_lag_state (self , pre_check = True ):
250+ pat = re .compile (".*%s\s+LACP\(A\)\(Dw\)\s+(.*)" % self .vm_dut_map [self .neigh_name ]['dut_portchannel' ])
251+ stdout , stderr , return_code = self .cmd (['ssh' , '-oStrictHostKeyChecking=no' , self .dut_ssh , 'show interfaces portchannel' ])
252+ if return_code == 0 :
253+ for line in stdout .split ('\n ' ):
254+ if self .vm_dut_map [self .neigh_name ]['dut_portchannel' ] in line :
255+ is_match = pat .match (line )
256+ if is_match and self .verify_dut_lag_member_state (is_match .group (1 ), pre_check = pre_check ):
257+ self .log .append ('Lag state is down as expected on the DUT' )
258+ self .log .append ('Pattern check: %s' % line )
259+ else :
260+ self .fails ['dut' ].add ('%s: Lag state is not down on the DUT' % self .msg_prefix [pre_check ])
261+ self .fails ['dut' ].add ('%s: Obtained: %s' % (self .msg_prefix [pre_check ], line ))
262+ break
263+ else :
264+ self .fails ['dut' ].add ('%s: Retreiving LAG info from DUT side failed' % self .msg_prefix [pre_check ])
265+ self .fails ['dut' ].add ('%s: Return code: %d' % (self .msg_prefix [pre_check ], return_code ))
266+ self .fails ['dut' ].add ('%s: Stderr: %s' % (self .msg_prefix [pre_check ], stderr ))
267+
268+ def sad_lag_verify (self , pre_check = True ):
269+ fails_vm , lag_state = self .vm_handle .verify_neigh_lag_state (self .vm_dut_map [self .neigh_name ]['neigh_portchannel' ], state = self .neigh_lag_state , pre_check = pre_check )
270+ self .fails [self .neigh_vm ] |= fails_vm
271+ if lag_state :
272+ self .log .append ('LAG state down as expected for %s' % self .neigh_vm )
273+ else :
274+ self .fails [self .neigh_vm ].add ('%s: LAG state not down for %s' % (self .msg_prefix [pre_check ], self .neigh_vm ))
275+ self .log .append ('Verifying LAG state on the dut end' )
276+ self .verify_dut_lag_state (pre_check = pre_check )
0 commit comments