@@ -646,11 +646,14 @@ def perform_robo(self, args, clients_to_run):
646646
647647 if not matched :
648648 continue
649- # To add last entry in the csv
650- all_dataframes = pd .concat (
651- [df for df in all_dataframes if isinstance (df , pd .DataFrame )],
652- ignore_index = True
653- )
649+ # Generate a band-steering report only when monitoring collected rows.
650+ collected_dataframes = [df for df in all_dataframes if isinstance (df , pd .DataFrame )]
651+ if not collected_dataframes or all (df .empty for df in collected_dataframes ):
652+ self .stop ()
653+ if args .postcleanup :
654+ self .cleanup ()
655+ raise RuntimeError ("All active CXs were missing; no band-steering monitoring data was collected." )
656+ all_dataframes = pd .concat (collected_dataframes , ignore_index = True )
654657 last_idx = all_dataframes .index [- 1 ]
655658
656659 all_dataframes .loc [last_idx , "status" ] = "Stopped"
@@ -735,6 +738,9 @@ def perform_robo(self, args, clients_to_run):
735738 if args .do_interopability and i != 0 :
736739 self .stop_specific (to_run_cxs [i - 1 ])
737740 time .sleep (5 )
741+ elif not args .do_interopability and i != 0 :
742+ # Reset the previous cumulative CX set before the next capacity.
743+ self .stop_specific (created_cx_lists_keys [:incremental_capacity_list [i - 1 ]])
738744 if args .interopability_config :
739745 if args .do_interopability and i == 0 :
740746 # To disconnect all the selected devices at the starting selected
@@ -744,7 +750,11 @@ def perform_robo(self, args, clients_to_run):
744750 # To configure device which is under test
745751 is_device_configured = self .configure_specific ([device_to_run_resource ])
746752 if is_device_configured :
747- self .start_specific (to_run_cxs [i ])
753+ # Start cumulative CXs for capacity tests or isolated CXs for interoperability.
754+ if args .do_interopability :
755+ self .start_specific (to_run_cxs [i ])
756+ else :
757+ self .start_specific (created_cx_lists_keys [:incremental_capacity_list [i ]])
748758
749759 # Determine device names based on the current iteration
750760 if args .do_interopability and args .load_type != "wc_intended_load" :
@@ -1383,10 +1393,18 @@ def stop_specific(self, cx_list):
13831393 "cx_name" : cx_name ,
13841394 "cx_state" : "STOPPED"
13851395 }, debug_ = self .debug )
1396+ self .clear_endp_counters ()
1397+
1398+ def clear_endp_counters (self ):
1399+ """Clear all endpoint counters after CXs stop."""
1400+ self .json_post ("/cli-json/clear_endp_counters" , {
1401+ "endp_name" : "all"
1402+ }, debug_ = self .debug )
13861403
13871404 def stop (self ):
13881405
13891406 self .cx_profile .stop_cx ()
1407+ self .clear_endp_counters ()
13901408 self .station_profile .admin_down ()
13911409
13921410 def remove_missing_cx (self ):
@@ -1426,7 +1444,6 @@ def pre_cleanup(self):
14261444 def cleanup (self ):
14271445 if self .robo_ip :
14281446 self .remove_missing_cx ()
1429- logger .info ("self.cx_profile.created_cx %s" , self .cx_profile .created_cx )
14301447 logger .info ("cleanup done" )
14311448 self .cx_profile .cleanup ()
14321449
@@ -1577,7 +1594,8 @@ def monitor(self, iteration, individual_df, device_names, incremental_capacity_l
15771594 if self .stopped_by_user :
15781595 individual_df = self .append_stopped_monitor_row (
15791596 individual_df , iteration , incremental_capacity_list , overall_start_time )
1580- return individual_df , self .stop_test
1597+ # Propagate missing CX failure to stop band-steering coordinates.
1598+ return individual_df , True if self .do_bandsteering else self .stop_test
15811599 self .monitoring_started_with_available_cx = True
15821600 missing_active_cxs = set (self .current_iteration_cxs ).intersection (self .missing_cx_logged )
15831601 if missing_active_cxs and not self .pre_monitoring_missing_logged :
@@ -1617,8 +1635,8 @@ def monitor(self, iteration, individual_df, device_names, incremental_capacity_l
16171635 break
16181636 throughput [index ] = self .get_layer3_endp_data (self .current_iteration_cxs )
16191637 if self .current_iteration_cxs and self .should_stop_for_missing_cx (self .current_iteration_cxs ):
1620- logger . error ( "No active CX recovered; ending this iteration with collected data." )
1621- test_stopped_by_user = self .stop_test
1638+ # Propagate missing CX failure to stop band-steering coordinates.
1639+ test_stopped_by_user = True if self . do_bandsteering else self .stop_test
16221640 break
16231641 # Check if next sleep would overshoot the end_time
16241642 is_last_iteration = ((current_time + timedelta (seconds = 1 if self .dowebgui else self .report_timer )) >= end_time )
@@ -1912,9 +1930,6 @@ def monitor(self, iteration, individual_df, device_names, incremental_capacity_l
19121930 for i in range (len (upload_throughput )):
19131931 connections_upload .update ({keys [i ]: float (f"{ (upload_throughput [i ]):.2f} " )})
19141932
1915- logger .info ("connections download {}" .format (connections_download ))
1916- logger .info ("connections upload {}" .format (connections_upload ))
1917-
19181933 self .actual_monitoring_duration_seconds += (datetime .now () - start_time ).total_seconds ()
19191934 return individual_df , test_stopped_by_user
19201935
@@ -1962,7 +1977,8 @@ def monitor_for_robo(self, iteration, individual_df, device_names, incremental_c
19621977 if self .stopped_by_user :
19631978 individual_df = self .append_stopped_monitor_row (
19641979 individual_df , iteration , incremental_capacity_list , overall_start_time )
1965- return individual_df , self .stop_test
1980+ # End robot monitoring so collected data can proceed to report generation.
1981+ return individual_df , True
19661982 self .monitoring_started_with_available_cx = True
19671983
19681984 # Initialize variables for real-time connections data
@@ -2031,8 +2047,8 @@ def monitor_for_robo(self, iteration, individual_df, device_names, incremental_c
20312047 break
20322048 throughput [index ] = self .get_layer3_endp_data (self .current_iteration_cxs )
20332049 if self .current_iteration_cxs and self .should_stop_for_missing_cx (self .current_iteration_cxs ):
2034- logger . error ( "No active CX recovered; ending this iteration with collected data." )
2035- test_stopped_by_user = self . stop_test
2050+ # End robot monitoring so collected data can proceed to report generation.
2051+ test_stopped_by_user = True
20362052 break
20372053 # Check if next sleep would overshoot the end_time
20382054 is_last_iteration = ((current_time + timedelta (seconds = 1 if self .dowebgui else self .report_timer )) >= end_time )
@@ -2414,9 +2430,6 @@ def monitor_for_robo(self, iteration, individual_df, device_names, incremental_c
24142430 for i in range (len (upload_throughput )):
24152431 connections_upload .update ({keys [i ]: float (f"{ (upload_throughput [i ]):.2f} " )})
24162432
2417- logger .info ("connections download {}" .format (connections_download ))
2418- logger .info ("connections upload {}" .format (connections_upload ))
2419-
24202433 self .actual_monitoring_duration_seconds += (datetime .now () - start_time ).total_seconds ()
24212434 return individual_df , test_stopped_by_user
24222435
@@ -2993,6 +3006,10 @@ def generate_report(self, iterations_before_test_stopped_by_user, incremental_ca
29933006 data_iter = data [data ['Iteration' ] == i + 1 ]
29943007 avg_rtt_data = []
29953008
3009+ if data_iter .empty :
3010+ logger .warning ("Skipping report section for iteration %s because no monitoring data was collected." , i + 1 )
3011+ continue
3012+
29963013 # for sig in self.signal_list[0:int(incremental_capacity_list[i])]:
29973014 # signal_data.append(int(sig)*(-1))
29983015 # rssi_signal_data.append(signal_data)
@@ -3463,6 +3480,10 @@ def generate_report(self, iterations_before_test_stopped_by_user, incremental_ca
34633480 data_iter = data [data ['Iteration' ] == i + 1 ]
34643481 avg_rtt_data = []
34653482
3483+ if data_iter .empty :
3484+ logger .warning ("Skipping report section for iteration %s because no monitoring data was collected." , i + 1 )
3485+ continue
3486+
34663487 # Fetch devices_on_running from real_client_list
34673488 devices_on_running .append (self .real_client_list [data1 [i ][- 1 ] - 1 ].split (" " )[- 1 ])
34683489 # If the device fails to configure, skip its data in the report
@@ -3937,6 +3958,12 @@ def generate_report_robo(self, iterations_before_test_stopped_by_user, increment
39373958 data_iter = data [data ['Iteration' ] == i + 1 ]
39383959 avg_rtt_data = []
39393960
3961+ if data_iter .empty :
3962+ logger .warning (
3963+ "Skipping report section for iteration %s at coordinate %s because no monitoring data was collected." ,
3964+ i + 1 , coordinate )
3965+ continue
3966+
39403967 # for sig in self.signal_list[0:int(incremental_capacity_list[i])]:
39413968 # signal_data.append(int(sig)*(-1))
39423969 # rssi_signal_data.append(signal_data)
@@ -5355,6 +5382,9 @@ def main():
53555382 if args .do_interopability and i != 0 :
53565383 throughput .stop_specific (to_run_cxs [i - 1 ])
53575384 time .sleep (5 )
5385+ elif not args .do_interopability and i != 0 :
5386+ # Reset the previous cumulative CX set before the next capacity.
5387+ throughput .stop_specific (created_cx_lists_keys [:incremental_capacity_list [i - 1 ]])
53585388 if args .interopability_config :
53595389 if args .do_interopability and i == 0 :
53605390 # To disconnect all the selected devices at the starting selected
@@ -5364,7 +5394,11 @@ def main():
53645394 # To configure device which is under test
53655395 is_device_configured = throughput .configure_specific ([device_to_run_resource ])
53665396 if is_device_configured :
5367- throughput .start_specific (to_run_cxs [i ])
5397+ # Start cumulative CXs for capacity tests or isolated CXs for interoperability.
5398+ if args .do_interopability :
5399+ throughput .start_specific (to_run_cxs [i ])
5400+ else :
5401+ throughput .start_specific (created_cx_lists_keys [:incremental_capacity_list [i ]])
53685402
53695403 # Determine device names based on the current iteration
53705404 if args .do_interopability and args .load_type != "wc_intended_load" :
0 commit comments