@@ -421,12 +421,14 @@ def __clearArpAndFdbTables(self):
421
421
logger .info ('Clearing all fdb entries on DUT {}' .format (self .duthost .hostname ))
422
422
self .duthost .shell ('sonic-clear fdb all' )
423
423
424
- def __fetchTestLogs (self , rebootOper = None ):
424
+ def __fetchTestLogs (self , rebootOper = None , log_dst_suffix = None ):
425
425
"""
426
- Fetch test logs from duthost and ptfhost after individual test run
426
+ Fetch test logs from duthost and ptfhost.
427
+ @param rebootOper: if provided it will be added to each individual file name
428
+ @param log_dst_suffix: if provided it will be appended to the directory name
427
429
"""
428
- if rebootOper :
429
- dir_name = "{}_{}" .format (self .request .node .name , rebootOper )
430
+ if log_dst_suffix :
431
+ dir_name = "{}_{}" .format (self .request .node .name , log_dst_suffix )
430
432
else :
431
433
dir_name = self .request .node .name
432
434
report_file_dir = os .path .realpath ((os .path .join (os .path .dirname (__file__ ), "../../logs/platform_tests/" )))
@@ -596,7 +598,7 @@ def runRebootTest(self):
596
598
if self .postboot_setup :
597
599
self .postboot_setup ()
598
600
# capture the test logs, and print all of them in case of failure, or a summary in case of success
599
- log_dir = self .__fetchTestLogs (rebootOper )
601
+ log_dir = self .__fetchTestLogs (rebootOper , log_dst_suffix = rebootOper )
600
602
self .print_test_logs_summary (log_dir )
601
603
if self .advanceboot_loganalyzer and post_reboot_analysis :
602
604
verification_errors = post_reboot_analysis (marker , event_counters = event_counters ,
@@ -630,6 +632,88 @@ def runRebootTestcase(self, prebootList=None, inbootList=None, prebootFiles='pee
630
632
self .imageInstall (prebootList , inbootList , prebootFiles )
631
633
return self .runRebootTest ()
632
634
635
+ def runMultiHopRebootTestcase (self , upgrade_path_urls , prebootFiles = 'peer_dev_info,neigh_port_info' ,
636
+ base_image_setup = None , pre_hop_setup = None ,
637
+ post_hop_teardown = None , multihop_advanceboot_loganalyzer_factory = None ):
638
+ """
639
+ This method validates and prepares test bed for multi-hop reboot test case. It runs the reboot test case using
640
+ provided test arguments.
641
+ @param prebootList: list of operation to run before reboot process
642
+ @param prebootFiles: preboot files
643
+ """
644
+ # Install image A (base image)
645
+ self .imageInstall (None , None , prebootFiles )
646
+ if base_image_setup :
647
+ base_image_setup ()
648
+
649
+ test_results = dict ()
650
+ test_case_name = str (self .request .node .name )
651
+ test_results [test_case_name ] = list ()
652
+ for hop_index , _ in enumerate (upgrade_path_urls [1 :], start = 1 ):
653
+ try :
654
+ if pre_hop_setup :
655
+ pre_hop_setup (hop_index )
656
+ if multihop_advanceboot_loganalyzer_factory :
657
+ pre_reboot_analysis , post_reboot_analysis = multihop_advanceboot_loganalyzer_factory (hop_index )
658
+ marker = pre_reboot_analysis ()
659
+ event_counters = self .__setupRebootOper (None )
660
+
661
+ # Run the upgrade
662
+ thread = InterruptableThread (
663
+ target = self .__runPtfRunner ,
664
+ kwargs = {"ptf_collect_dir" : "./logs/ptf_collect/hop{}/" .format (hop_index )})
665
+ thread .daemon = True
666
+ thread .start ()
667
+ # give the test REBOOT_CASE_TIMEOUT (1800s) to complete the reboot with IO,
668
+ # and then additional 300s to examine the pcap, logs and generate reports
669
+ ptf_timeout = REBOOT_CASE_TIMEOUT + 300
670
+ thread .join (timeout = ptf_timeout , suppress_exception = True )
671
+ self .ptfhost .shell ("pkill -f 'ptftests advanced-reboot.ReloadTest'" , module_ignore_errors = True )
672
+ # the thread might still be running, and to catch any exceptions after pkill allow 10s to join
673
+ thread .join (timeout = 10 )
674
+
675
+ self .__verifyRebootOper (None )
676
+ if self .duthost .num_asics () == 1 and not check_bgp_router_id (self .duthost , self .mgFacts ):
677
+ test_results [test_case_name ].append ("Failed to verify BGP router identifier is Loopback0 on %s" %
678
+ self .duthost .hostname )
679
+ if post_hop_teardown :
680
+ post_hop_teardown (hop_index )
681
+ except Exception :
682
+ traceback_msg = traceback .format_exc ()
683
+ err_msg = "Exception caught while running advanced-reboot test on ptf: \n {}" .format (traceback_msg )
684
+ logger .error (err_msg )
685
+ test_results [test_case_name ].append (err_msg )
686
+ finally :
687
+ # capture the test logs, and print all of them in case of failure, or a summary in case of success
688
+ log_dir = self .__fetchTestLogs (log_dst_suffix = "hop{}" .format (hop_index ))
689
+ self .print_test_logs_summary (log_dir )
690
+ if multihop_advanceboot_loganalyzer_factory and post_reboot_analysis :
691
+ verification_errors = post_reboot_analysis (marker , event_counters = event_counters , log_dir = log_dir )
692
+ if verification_errors :
693
+ logger .error ("Post reboot verification failed. List of failures: {}"
694
+ .format ('\n ' .join (verification_errors )))
695
+ test_results [test_case_name ].extend (verification_errors )
696
+ # Set the post_reboot_analysis to None to avoid using it again after post_hop_teardown
697
+ # on the subsequent iteration in the event that we land in the finally block before
698
+ # the new one is initialised
699
+ post_reboot_analysis = None
700
+ self .acl_manager_checker (test_results [test_case_name ])
701
+ self .__clearArpAndFdbTables ()
702
+ self .__revertRebootOper (None )
703
+
704
+ failed_list = [(testcase , failures ) for testcase , failures in list (test_results .items ())
705
+ if len (failures ) != 0 ]
706
+ pytest_assert (len (failed_list ) == 0 , "Advanced-reboot failure. Failed multi-hop test {testname} "
707
+ "on update {hop_index} from {from_image} to {to_image}, "
708
+ "failure summary:\n {fail_summary}" .format (
709
+ testname = self .request .node .name ,
710
+ hop_index = hop_index ,
711
+ from_image = upgrade_path_urls [hop_index - 1 ],
712
+ to_image = upgrade_path_urls [hop_index ],
713
+ fail_summary = failed_list
714
+ ))
715
+ return True # Success
716
+
633
717
def __setupRebootOper (self , rebootOper ):
634
718
if self .dual_tor_mode :
635
719
for device in self .duthosts :
@@ -694,10 +778,11 @@ def __revertRebootOper(self, rebootOper):
694
778
logger .info ('Running revert handler for reboot operation {}' .format (rebootOper ))
695
779
rebootOper .revert ()
696
780
697
- def __runPtfRunner (self , rebootOper = None ):
781
+ def __runPtfRunner (self , rebootOper = None , ptf_collect_dir = "./logs/ptf_collect/" ):
698
782
"""
699
783
Run single PTF advanced-reboot.ReloadTest
700
784
@param rebootOper:Reboot operation to conduct before/during reboot process
785
+ @param ptf_collect_dir: PTF log collection directory
701
786
"""
702
787
logger .info ("Running PTF runner on PTF host: {0}" .format (self .ptfhost ))
703
788
@@ -775,6 +860,7 @@ def __runPtfRunner(self, rebootOper=None):
775
860
platform = "remote" ,
776
861
params = params ,
777
862
log_file = '/tmp/advanced-reboot.ReloadTest.log' ,
863
+ ptf_collect_dir = ptf_collect_dir ,
778
864
module_ignore_errors = self .moduleIgnoreErrors ,
779
865
timeout = REBOOT_CASE_TIMEOUT ,
780
866
is_python3 = True
0 commit comments