mirror of
				https://github.com/Telecominfraproject/wlan-lanforge-scripts.git
				synced 2025-11-04 04:38:02 +00:00 
			
		
		
		
	smw_lf_throughput.py: original script from Netgear repo
Signed-off-by: Scott Wedge <scott.wedge@candelatech.com>
This commit is contained in:
		
							
								
								
									
										678
									
								
								py-scripts/sandbox/smw_lf_throughput.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										678
									
								
								py-scripts/sandbox/smw_lf_throughput.py
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,678 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env python3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"""throughput.py will create stations and layer-3 traffic to calculate the throughput of AP.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This script will create a VAP and apply some load by creating stations in AP's channel under VAP in order to make the channel
 | 
				
			||||||
 | 
					utilized after the channel utilized to specific level again create specific number of stations each with their own set of cross-connects and endpoints.
 | 
				
			||||||
 | 
					It will then create layer 3 traffic over a specified amount of time, testing for increased traffic at regular intervals.
 | 
				
			||||||
 | 
					This test will pass if all stations increase traffic over the full test duration.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Use './throughput_ver_2.py --help' to see command line usage and options
 | 
				
			||||||
 | 
					Copyright 2021 Candela Technologies Inc
 | 
				
			||||||
 | 
					License: Free to distribute and modify. LANforge systems must be licensed.
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					import os, paramiko, pprint
 | 
				
			||||||
 | 
					if sys.version_info[0] != 3:
 | 
				
			||||||
 | 
					    print("This script requires Python 3")
 | 
				
			||||||
 | 
					    exit(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if 'py-json' not in sys.path:
 | 
				
			||||||
 | 
					    sys.path.append(os.path.join(os.path.abspath('..'), 'py-json'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import argparse
 | 
				
			||||||
 | 
					from LANforge import LFUtils
 | 
				
			||||||
 | 
					from realm import Realm
 | 
				
			||||||
 | 
					from LANforge import LFRequest
 | 
				
			||||||
 | 
					from station_profile import StationProfile
 | 
				
			||||||
 | 
					from LANforge import set_port
 | 
				
			||||||
 | 
					import throughput_report
 | 
				
			||||||
 | 
					#import create_vap
 | 
				
			||||||
 | 
					import time,datetime,traceback
 | 
				
			||||||
 | 
					import pandas as pd
 | 
				
			||||||
 | 
					from lf_report import lf_report
 | 
				
			||||||
 | 
					from lf_graph import lf_bar_graph
 | 
				
			||||||
 | 
					from lf_csv import lf_csv
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# this class create VAP, station, and traffic
 | 
				
			||||||
 | 
					class IPV4VariableTime(Realm):
 | 
				
			||||||
 | 
					    def __init__(self, ssid=None,   security=None,       password=None,   sta_list=[],   name_prefix=None,   upstream=None,
 | 
				
			||||||
 | 
					                 radio=None,        host="localhost",    port=8080,       mode=0,        ap=None,            side_a_min_rate= 56,
 | 
				
			||||||
 | 
					                 side_a_max_rate=0, side_b_min_rate=56,  side_b_max_rate=0,              number_template="00000",
 | 
				
			||||||
 | 
					                 test_duration="5m", use_ht160=False,    _debug_on=False,                _exit_on_error=False,
 | 
				
			||||||
 | 
					                 _exit_on_fail=False, _vap_radio=None,   _vap_list = 'vap0000', _dhcp = True ):
 | 
				
			||||||
 | 
					        super().__init__(lfclient_host=host, lfclient_port=port),
 | 
				
			||||||
 | 
					        self.upstream = upstream
 | 
				
			||||||
 | 
					        self.host = host
 | 
				
			||||||
 | 
					        self.port = port
 | 
				
			||||||
 | 
					        self.ssid = ssid
 | 
				
			||||||
 | 
					        self.sta_list = sta_list
 | 
				
			||||||
 | 
					        self.vap_list = _vap_list
 | 
				
			||||||
 | 
					        self.security = security
 | 
				
			||||||
 | 
					        self.password = password
 | 
				
			||||||
 | 
					        self.radio = radio
 | 
				
			||||||
 | 
					        self.vap_radio = _vap_radio
 | 
				
			||||||
 | 
					        self.mode = mode
 | 
				
			||||||
 | 
					        self.ap = ap
 | 
				
			||||||
 | 
					        self.number_template = number_template
 | 
				
			||||||
 | 
					        self.debug = _debug_on
 | 
				
			||||||
 | 
					        self.name_prefix = name_prefix
 | 
				
			||||||
 | 
					        self.test_duration = test_duration
 | 
				
			||||||
 | 
					        self._dhcp = _dhcp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # initializing station profile
 | 
				
			||||||
 | 
					        self.station_profile = StationProfile(lfclient_url=self.lfclient_url,   local_realm=super(), debug_=self.debug,     up=False,
 | 
				
			||||||
 | 
					                                              dhcp = self._dhcp,                ssid = self.ssid,    ssid_pass = self.password,
 | 
				
			||||||
 | 
					                                              security = self.security,         number_template_ = self.number_template,    use_ht160 = use_ht160)#self.new_station_profile()##
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if self.station_profile.use_ht160:
 | 
				
			||||||
 | 
					            self.station_profile.mode = 9
 | 
				
			||||||
 | 
					        self.station_profile.mode = mode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # initializing VAP profile
 | 
				
			||||||
 | 
					        self.vap_profile = self.new_vap_profile()
 | 
				
			||||||
 | 
					        self.vap_profile.vap_name = self.vap_list
 | 
				
			||||||
 | 
					        self.vap_profile.ssid = self.ssid
 | 
				
			||||||
 | 
					        self.vap_profile.security = self.security
 | 
				
			||||||
 | 
					        self.vap_profile.ssid_pass = self.password
 | 
				
			||||||
 | 
					        self.vap_profile.mode = self.mode
 | 
				
			||||||
 | 
					        if self.debug:
 | 
				
			||||||
 | 
					            print("----- VAP List ----- ----- ----- ----- ----- ----- \n")
 | 
				
			||||||
 | 
					            pprint.pprint(self.vap_list)
 | 
				
			||||||
 | 
					            print("---- ~VAP List ----- ----- ----- ----- ----- ----- \n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # initializing traffic profile
 | 
				
			||||||
 | 
					        self.cx_profile = self.new_l3_cx_profile()
 | 
				
			||||||
 | 
					        self.cx_profile.host = self.host
 | 
				
			||||||
 | 
					        self.cx_profile.port = self.port
 | 
				
			||||||
 | 
					        self.cx_profile.name_prefix = self.name_prefix
 | 
				
			||||||
 | 
					        self.cx_profile.side_a_min_bps = side_a_min_rate
 | 
				
			||||||
 | 
					        self.cx_profile.side_a_max_bps = side_a_max_rate
 | 
				
			||||||
 | 
					        self.cx_profile.side_b_min_bps = side_b_min_rate
 | 
				
			||||||
 | 
					        self.cx_profile.side_b_max_bps = side_b_max_rate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def start(self, print_pass=False, print_fail=False):
 | 
				
			||||||
 | 
					        self.station_profile.admin_up() # admin up the stations
 | 
				
			||||||
 | 
					        # to-do- check here if upstream port got IP
 | 
				
			||||||
 | 
					        temp_stas = self.station_profile.station_names.copy()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if self.wait_for_ip(temp_stas):
 | 
				
			||||||
 | 
					            print("admin-up....")
 | 
				
			||||||
 | 
					            self._pass("All stations got IPs")
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            self._fail("Stations failed to get IPs")
 | 
				
			||||||
 | 
					            self.exit_fail()
 | 
				
			||||||
 | 
					        self.cx_profile.start_cx()  # run the traffic
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def stop(self,trf = True, ad_dwn = True):
 | 
				
			||||||
 | 
					        if trf:
 | 
				
			||||||
 | 
					            self.cx_profile.stop_cx()   # stop the traffic
 | 
				
			||||||
 | 
					        if ad_dwn:
 | 
				
			||||||
 | 
					            self.station_profile.admin_down()   # admin down the stations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def pre_cleanup(self):
 | 
				
			||||||
 | 
					        # deleting the previously created stations
 | 
				
			||||||
 | 
					        print("clearing...")
 | 
				
			||||||
 | 
					        exist_sta = []
 | 
				
			||||||
 | 
					        for u in self.json_get("/port/?fields=port+type,alias")['interfaces']:
 | 
				
			||||||
 | 
					            if list(u.values())[0]['port type'] not in ['Ethernet', 'WIFI-Radio', 'NA']:
 | 
				
			||||||
 | 
					                exist_sta.append(list(u.values())[0]['alias'])
 | 
				
			||||||
 | 
					        self.station_profile.cleanup(desired_stations=exist_sta)
 | 
				
			||||||
 | 
					        # deleting the previously created traffic
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            exist_l3 = list(filter(lambda cx_name: cx_name if (cx_name != 'handler' and cx_name != 'uri') else False,
 | 
				
			||||||
 | 
					                                   self.json_get("/cx/?fields=name")))
 | 
				
			||||||
 | 
					            list(map(lambda i: self.rm_cx(cx_name=i), exist_l3))
 | 
				
			||||||
 | 
					            list(map(lambda cx_name: [self.rm_endp(ename=i) for i in [f"{cx_name}-A", f"{cx_name}-B"]], exist_l3))
 | 
				
			||||||
 | 
					        except Exception as e:
 | 
				
			||||||
 | 
					            print("###",e,'###')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def build_vaps(self,chn = 36):
 | 
				
			||||||
 | 
					        # create VAPs with static IP_addr, netmask, gateway_IP
 | 
				
			||||||
 | 
					        self.vap_profile.use_security(self.security, self.ssid, passwd=self.password)
 | 
				
			||||||
 | 
					        self.vap_profile.set_command_param("set_port", "ip_addr", "192.168.0.1")
 | 
				
			||||||
 | 
					        self.vap_profile.set_command_flag("set_port", "ip_address", 1)
 | 
				
			||||||
 | 
					        self.vap_profile.set_command_param("set_port", "netmask", "255.255.255.0")
 | 
				
			||||||
 | 
					        self.vap_profile.set_command_flag("set_port", "ip_Mask", 1)
 | 
				
			||||||
 | 
					        self.vap_profile.set_command_param("set_port", "gateway", "192.168.0.1")
 | 
				
			||||||
 | 
					        self.vap_profile.set_command_flag("set_port", "ip_gateway", 1)
 | 
				
			||||||
 | 
					        print("Creating VAPs")
 | 
				
			||||||
 | 
					        self.vap_profile.create(resource = 1,   radio = self.vap_radio,     channel = int(chn),       up_ = True,     debug = False,
 | 
				
			||||||
 | 
					                                suppress_related_commands_ = True,          use_radius = True,  hs20_enable = False,
 | 
				
			||||||
 | 
					                                create_bridge = False)
 | 
				
			||||||
 | 
					        self._pass("PASS: VAP build finished")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def build(self):
 | 
				
			||||||
 | 
					        # creating stations using static IP and DHCP enabled stations
 | 
				
			||||||
 | 
					        self.station_profile.use_security(self.security, self.ssid, self.password)
 | 
				
			||||||
 | 
					        self.station_profile.set_number_template(self.number_template)
 | 
				
			||||||
 | 
					        self.station_profile.set_command_flag("add_sta", "create_admin_down", 1)
 | 
				
			||||||
 | 
					        self.station_profile.set_command_param("set_port", "report_timer", 1500)
 | 
				
			||||||
 | 
					        self.station_profile.set_command_flag("set_port", "rpt_timer", 1)
 | 
				
			||||||
 | 
					        print("Creating stations")
 | 
				
			||||||
 | 
					        start_ip = 2
 | 
				
			||||||
 | 
					        if self._dhcp:
 | 
				
			||||||
 | 
					            self.station_profile.create(radio=self.radio, sta_names_=self.sta_list, debug=self.debug)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            for sta_name in self.sta_list:
 | 
				
			||||||
 | 
					                ip = "192.168.0."+ str(start_ip)
 | 
				
			||||||
 | 
					                self.station_profile.set_command_param("set_port", "ip_addr", ip)
 | 
				
			||||||
 | 
					                self.station_profile.set_command_flag("set_port", "ip_address", 1)
 | 
				
			||||||
 | 
					                self.station_profile.set_command_param("set_port", "netmask", "255.255.255.0")
 | 
				
			||||||
 | 
					                self.station_profile.set_command_flag("set_port", "ip_Mask", 1)
 | 
				
			||||||
 | 
					                self.station_profile.set_command_param("set_port", "gateway", "192.168.0.1")
 | 
				
			||||||
 | 
					                self.station_profile.set_command_flag("set_port", "ip_gateway", 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                self.station_profile.create(radio=self.radio, sta_names_=[sta_name], debug=self.debug)
 | 
				
			||||||
 | 
					                start_ip += 1
 | 
				
			||||||
 | 
					        self.cx_profile.create(endp_type="lf_udp", side_a=self.station_profile.station_names, side_b=self.upstream, sleep_time=0)
 | 
				
			||||||
 | 
					        self._pass("PASS: Station build finished")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def chn_util(self,ssh_root, ssh_passwd,channnel=0):
 | 
				
			||||||
 | 
					        # To find the channel utilization
 | 
				
			||||||
 | 
					        cmd = 'iwpriv wifi1vap0 get_chutil'     # command to get channel utilization
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            ssh = paramiko.SSHClient()
 | 
				
			||||||
 | 
					            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
 | 
				
			||||||
 | 
					            ssh.connect(ssh_root, 22, 'root', ssh_passwd)
 | 
				
			||||||
 | 
					            time.sleep(20)
 | 
				
			||||||
 | 
					            #ssh.exec_command(f"conf_set system:wlanSettings:wlanSettingTable:wlan1:channel {channnel}")
 | 
				
			||||||
 | 
					            stdout = ssh.exec_command(cmd)
 | 
				
			||||||
 | 
					            stdout = (((stdout[1].readlines())[0].split(':'))[1].split(' '))[0]
 | 
				
			||||||
 | 
					            print(stdout, "----- channel utilization")
 | 
				
			||||||
 | 
					            return int(stdout)
 | 
				
			||||||
 | 
					        except paramiko.ssh_exception.NoValidConnectionsError as e:
 | 
				
			||||||
 | 
					            print("####", e, "####")
 | 
				
			||||||
 | 
					            exit(1)
 | 
				
			||||||
 | 
					        except TimeoutError as e:
 | 
				
			||||||
 | 
					            print("####", e, "####")
 | 
				
			||||||
 | 
					            exit(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def re_run_traff(self, adj_trf_rate, add_sub_rate):
 | 
				
			||||||
 | 
					        # if channel utilization level is not met re-run the traffic
 | 
				
			||||||
 | 
					        print("Re-run the traffic...")
 | 
				
			||||||
 | 
					        self.cx_profile.cleanup_prefix()
 | 
				
			||||||
 | 
					        time.sleep(.5)
 | 
				
			||||||
 | 
					        # give data rate to run the traffic
 | 
				
			||||||
 | 
					        if add_sub_rate == "sub":
 | 
				
			||||||
 | 
					            self.cx_profile.side_a_min_bps = abs(int(self.cx_profile.side_a_min_bps) - adj_trf_rate)
 | 
				
			||||||
 | 
					            self.cx_profile.side_b_min_bps = abs(int(self.cx_profile.side_b_min_bps) - adj_trf_rate)
 | 
				
			||||||
 | 
					        elif add_sub_rate == "add":
 | 
				
			||||||
 | 
					            self.cx_profile.side_a_min_bps = int(self.cx_profile.side_a_min_bps) + adj_trf_rate
 | 
				
			||||||
 | 
					            self.cx_profile.side_b_min_bps = int(self.cx_profile.side_b_min_bps) + adj_trf_rate
 | 
				
			||||||
 | 
					        self.cx_profile.created_cx.clear()
 | 
				
			||||||
 | 
					        self.cx_profile.create(endp_type="lf_udp", side_a=self.station_profile.station_names, side_b=self.upstream,
 | 
				
			||||||
 | 
					                               sleep_time=0)
 | 
				
			||||||
 | 
					        self.cx_profile.start_cx()
 | 
				
			||||||
 | 
					        print(f"-------side_a_min_bps  {self.cx_profile.side_a_min_bps}\n-------side_b_min_bps  {self.cx_profile.side_b_min_bps}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def table(self,report, title, data, dis=""):
 | 
				
			||||||
 | 
					        # creating table
 | 
				
			||||||
 | 
					        report.set_obj_html(_obj_title="",_obj=dis)
 | 
				
			||||||
 | 
					        report.set_table_title(title)
 | 
				
			||||||
 | 
					        report.build_table_title()
 | 
				
			||||||
 | 
					        report.build_objective()
 | 
				
			||||||
 | 
					        report.set_table_dataframe(data)
 | 
				
			||||||
 | 
					        report.build_table()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def grph(self,report, dis="", data_set=None, xaxis_name="stations", yaxis_name="Throughput 2 (Mbps)",
 | 
				
			||||||
 | 
					             xaxis_categories=None, label=None, graph_image_name="", multi_bar_width = 0,
 | 
				
			||||||
 | 
					             xticks_font=10,step = 1):
 | 
				
			||||||
 | 
					        # creating bar graph
 | 
				
			||||||
 | 
					        report.set_obj_html(_obj_title=graph_image_name, _obj=dis)
 | 
				
			||||||
 | 
					        #report.set_graph_title(graph_image_name)
 | 
				
			||||||
 | 
					        #report.build_graph_title()
 | 
				
			||||||
 | 
					        report.build_objective()
 | 
				
			||||||
 | 
					        graph = lf_bar_graph(_data_set = data_set,
 | 
				
			||||||
 | 
					                             _xaxis_name = xaxis_name,
 | 
				
			||||||
 | 
					                             _yaxis_name = yaxis_name,
 | 
				
			||||||
 | 
					                             _xaxis_categories = xaxis_categories,
 | 
				
			||||||
 | 
					                             _graph_image_name = graph_image_name.replace(" ","_"),
 | 
				
			||||||
 | 
					                             _label = label,
 | 
				
			||||||
 | 
					                             _color = ['darkorange','forestgreen','blueviolet'],
 | 
				
			||||||
 | 
					                             _color_edge = 'black',
 | 
				
			||||||
 | 
					                             _figsize = (10, 5),
 | 
				
			||||||
 | 
					                             _xticks_font= xticks_font,_xaxis_value_location=multi_bar_width,
 | 
				
			||||||
 | 
					                             _xaxis_step = step,_legend_handles=None, _legend_loc="best", _legend_box=(1.0,0.5), _legend_ncol=1)
 | 
				
			||||||
 | 
					        graph_png = graph.build_bar_graph()
 | 
				
			||||||
 | 
					        print("graph name {}".format(graph_png))
 | 
				
			||||||
 | 
					        report.set_graph_image(graph_png)
 | 
				
			||||||
 | 
					        report.move_graph_image()
 | 
				
			||||||
 | 
					        report.build_graph()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def report(self,util, sta_num, bps_rx_a,bps_rx_b, rep_title, upload = 1000000, download = 1000000,
 | 
				
			||||||
 | 
					              test_setup_info = None,input_setup_info = None,threshold=None):
 | 
				
			||||||
 | 
					        '''if len(threshold) < len(util):
 | 
				
			||||||
 | 
					            for i in range(len(util)):
 | 
				
			||||||
 | 
					                try:
 | 
				
			||||||
 | 
					                    tmp = threshold[i]
 | 
				
			||||||
 | 
					                except IndexError as e:
 | 
				
			||||||
 | 
					                    print(f"Threshold {threshold} and utilization {util}")
 | 
				
			||||||
 | 
					                    threshold.append(100 - int(util[i]))
 | 
				
			||||||
 | 
					        print(f"threshold {threshold} and utilization {util}")'''
 | 
				
			||||||
 | 
					        rx_a,rx_b,pas_fail_up,pas_fail_down,pas_fail_info_up,pas_fail_info_down = [],[],[],[],[],[]
 | 
				
			||||||
 | 
					        thrp_b = upload * len(sta_num)  # get overall upload values
 | 
				
			||||||
 | 
					        thrp_a = download * len(sta_num)  # get overall download values
 | 
				
			||||||
 | 
					        print(f"given upload--{thrp_b} and download--{thrp_a} values")
 | 
				
			||||||
 | 
					        index = -1
 | 
				
			||||||
 | 
					        for a in bps_rx_a:
 | 
				
			||||||
 | 
					            index += 1
 | 
				
			||||||
 | 
					            if len(a):
 | 
				
			||||||
 | 
					                rx_a.append(f'Min: {min(a)} | Max: {max(a)} | Avg: {(sum(a) / len(a)):.2f} | Total: {sum(a):.2f}')
 | 
				
			||||||
 | 
					                if thrp_a:
 | 
				
			||||||
 | 
					                    print(f"Expected throughput for util-{util[index]} and threshold-{threshold[index]}---- "
 | 
				
			||||||
 | 
					                          f"{(thrp_a / 100) * (int(threshold[index]))} \nGot overall download values for util "
 | 
				
			||||||
 | 
					                          f"'{util[index]}'----- {sum(a)} \n ")
 | 
				
			||||||
 | 
					                    if (thrp_a / 100) * int(threshold[index]) <= sum(a) and min(a) != 0:
 | 
				
			||||||
 | 
					                        pas_fail_down.append(f"PASS")# {len(sta_num)}-stations ran download traffic and met threshold")
 | 
				
			||||||
 | 
					                        #pas_fail_info_down.append(f"")
 | 
				
			||||||
 | 
					                    else:
 | 
				
			||||||
 | 
					                        pas_fail_down.append(f"FAIL")# {a.count(0)}-stations got zero throughput and overall throughput- {sum(a):.2f}")
 | 
				
			||||||
 | 
					                        #pas_fail_info_down.append(f"")
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                pas_fail_down.append("NA")
 | 
				
			||||||
 | 
					                rx_a.append(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if len(bps_rx_b[index]):
 | 
				
			||||||
 | 
					                rx_b.append(f'Min: {min(bps_rx_b[index])} | Max: {max(bps_rx_b[index])} | '
 | 
				
			||||||
 | 
					                            f'Avg: {(sum(bps_rx_b[index]) / len(bps_rx_b[index])):.2f} | Total: {sum(bps_rx_b[index]):.2f}')
 | 
				
			||||||
 | 
					                if thrp_b:
 | 
				
			||||||
 | 
					                    print(f"Expected throughput for util-{util[index]} and threshold-{threshold[index]}---- "
 | 
				
			||||||
 | 
					                          f"{(thrp_b / 100) * (int(threshold[index]))} \nGot overall upload values for util "
 | 
				
			||||||
 | 
					                          f"'{util[index]}'----- {sum(bps_rx_b[index])} \n ")
 | 
				
			||||||
 | 
					                    if (thrp_b / 100) * int(threshold[index]) <= sum(bps_rx_b[index]) and min(bps_rx_b[index])!= 0:
 | 
				
			||||||
 | 
					                        pas_fail_up.append(f"PASS")# {len(sta_num)}-stations ran upload traffic and met threshold")
 | 
				
			||||||
 | 
					                        #pas_fail_info_up.append()
 | 
				
			||||||
 | 
					                    else:
 | 
				
			||||||
 | 
					                        pas_fail_up.append(f"FAIL")# {bps_rx_b[index].count(0)}-stations got zero throughput and overall throughput- "
 | 
				
			||||||
 | 
					                                           #f"{sum(bps_rx_b[index]):.2f}")
 | 
				
			||||||
 | 
					                        #pas_fail_info_up.append(f"")
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                pas_fail_up.append("NA")
 | 
				
			||||||
 | 
					                rx_b.append(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            util[index] = f'{util[index]}%'  # append % to the util values
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        overall_tab = pd.DataFrame({
 | 
				
			||||||
 | 
					            'Channel Utilization (%)': util, "No.of.clients": [len(sta_num)] * len(util),
 | 
				
			||||||
 | 
					            'Intended Throughput(Mbps)': [f'upload: {upload} | download: {download}'] * len(util),
 | 
				
			||||||
 | 
					            'Achieved Upload Throughput(Mbps)': rx_b, 'Achieved Download Throughput(Mbps)': rx_a
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        print(f"overall table \n{overall_tab}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        pasfail_tab = pd.DataFrame({
 | 
				
			||||||
 | 
					            'Channel Utilization (%)': util,
 | 
				
			||||||
 | 
					            'Upload': pas_fail_up,
 | 
				
			||||||
 | 
					            'Download': pas_fail_down
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        print(f"pass-fail table \n {pasfail_tab}")
 | 
				
			||||||
 | 
					        report = lf_report(_results_dir_name="Throughput_Under_Channel_Load",_output_html="throughput_channel_load.html",
 | 
				
			||||||
 | 
					                           _output_pdf="throughput_channel_load.pdf")
 | 
				
			||||||
 | 
					        report.set_title(rep_title)
 | 
				
			||||||
 | 
					        report.build_banner()
 | 
				
			||||||
 | 
					        report.set_obj_html(_obj_title="Objective",
 | 
				
			||||||
 | 
					                            _obj=f"This test is designed to measure the throughput of {len(sta_num)} clients connected on 5GHz"
 | 
				
			||||||
 | 
					                                 " radio when the channel was already utilized with different percentage")
 | 
				
			||||||
 | 
					        report.build_objective()
 | 
				
			||||||
 | 
					        # test setup information
 | 
				
			||||||
 | 
					        report.set_table_title("Test Setup Information")
 | 
				
			||||||
 | 
					        report.build_table_title()
 | 
				
			||||||
 | 
					        report.test_setup_table(test_setup_data=test_setup_info, value="Device Under Test")
 | 
				
			||||||
 | 
					        self.table(report, "Min, Max, Avg Throughput", overall_tab,
 | 
				
			||||||
 | 
					              dis=f"The below table gives the information about Min, Max, and Avg throughput "
 | 
				
			||||||
 | 
					                  f"for the clients when channel utilized with {', '.join(util)}")
 | 
				
			||||||
 | 
					        self.table(report, "Pass/Fail Criteria", pasfail_tab, dis=f"This table briefs about Pass/Fail criteria  "
 | 
				
			||||||
 | 
					             f"for {', '.join(util)} channel utilization. If all the stations are able to run traffic and the overall throughput "
 | 
				
			||||||
 | 
					             f"should meet the given threshold then the test is considered to be PASS. The test fails if the overall throughput "
 | 
				
			||||||
 | 
					            f"is below the threshold value also if any one of the station is not able to run the layer-3 traffic.")
 | 
				
			||||||
 | 
					        if download:
 | 
				
			||||||
 | 
					            self.grph(report,
 | 
				
			||||||
 | 
					                 data_set=[[min(i) for i in bps_rx_a], [max(i) for i in bps_rx_a], [sum(i) / len(i) for i in bps_rx_a]],
 | 
				
			||||||
 | 
					                 dis=f"This graph represents the minimum, maximum and average throughput of "
 | 
				
			||||||
 | 
					                     f"stations when channel was utilized with {', '.join(util)} for download traffic",
 | 
				
			||||||
 | 
					                 xaxis_name="Utilizations", yaxis_name="Throughput (Mbps)",
 | 
				
			||||||
 | 
					                 xaxis_categories=util, label=["min", "max", 'avg'],multi_bar_width = 0.25,
 | 
				
			||||||
 | 
					                 graph_image_name="Download Throughput for all channel utilizations",step=1)
 | 
				
			||||||
 | 
					        if upload:
 | 
				
			||||||
 | 
					            self.grph(report,
 | 
				
			||||||
 | 
					                 data_set=[[min(i) for i in bps_rx_b], [max(i) for i in bps_rx_b], [sum(i) / len(i) for i in bps_rx_b]],
 | 
				
			||||||
 | 
					                 dis=f"This graph represents the minimum, maximum and average throughput of "
 | 
				
			||||||
 | 
					                     f"stations when channel was utilized with {', '.join(util)} for upload traffic",
 | 
				
			||||||
 | 
					                 xaxis_name="Utilizations", yaxis_name="Throughput (Mbps)",
 | 
				
			||||||
 | 
					                 xaxis_categories=util, label=["min", "max", 'avg'],multi_bar_width = 0.25,
 | 
				
			||||||
 | 
					                 graph_image_name="Upload Throughput for all channel utilization",step= 1)
 | 
				
			||||||
 | 
					        if len(sta_num) <= 40:
 | 
				
			||||||
 | 
					            step = 1
 | 
				
			||||||
 | 
					        elif 40 < len(sta_num) <= 80:
 | 
				
			||||||
 | 
					            step = 3
 | 
				
			||||||
 | 
					        elif 80 < len(sta_num) <= 100:
 | 
				
			||||||
 | 
					            step = 5
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            step = 10
 | 
				
			||||||
 | 
					        for i in range(len(util)):
 | 
				
			||||||
 | 
					            if download:
 | 
				
			||||||
 | 
					                self.grph(report, data_set=[bps_rx_a[i]],
 | 
				
			||||||
 | 
					                     dis=f"The graph shows the individual throughput for all the connected stations on 5GHz radio "
 | 
				
			||||||
 | 
					                         f"when channel was utilized with {util[i]} in download traffic",
 | 
				
			||||||
 | 
					                     xaxis_name="Stations",yaxis_name="Throughput (Mbps)", xaxis_categories=range(1, len(sta_num) + 1,step),
 | 
				
			||||||
 | 
					                     label=[util[i]], graph_image_name=f"Individual download throughput - CH{util[i]}", xticks_font=7,step = step
 | 
				
			||||||
 | 
					                    ,multi_bar_width = 0)
 | 
				
			||||||
 | 
					            if upload:
 | 
				
			||||||
 | 
					                self.grph(report, data_set=[bps_rx_b[i]],
 | 
				
			||||||
 | 
					                     dis=f"The graph shows the individual throughput for all the connected stations on 5GHz radio "
 | 
				
			||||||
 | 
					                         f"when channel was utilized with {util[i]} in upload traffic",
 | 
				
			||||||
 | 
					                     xaxis_name="stations", yaxis_name="Throughput (Mbps)", xaxis_categories=range(1, len(sta_num) + 1,step),
 | 
				
			||||||
 | 
					                     label=[util[i]], graph_image_name=f"Individual upload throughput - CH{util[i]}", xticks_font=7,step = step
 | 
				
			||||||
 | 
					                    ,multi_bar_width = 0)
 | 
				
			||||||
 | 
					        # input setup information
 | 
				
			||||||
 | 
					        report.set_table_title("Input Setup Information")
 | 
				
			||||||
 | 
					        report.build_table_title()
 | 
				
			||||||
 | 
					        report.test_setup_table(test_setup_data=input_setup_info, value="Information")
 | 
				
			||||||
 | 
					        report.build_footer()
 | 
				
			||||||
 | 
					        html_file = report.write_html()
 | 
				
			||||||
 | 
					        print("returned file {}".format(html_file))
 | 
				
			||||||
 | 
					        print(html_file)
 | 
				
			||||||
 | 
					        report.write_pdf()
 | 
				
			||||||
 | 
					        colmn = ['Stations']#'No.of.times(download/upload']
 | 
				
			||||||
 | 
					        colmn.extend(range(1, len(self.bps_rx) + 1))
 | 
				
			||||||
 | 
					        data = list(self.bps_rx.values())
 | 
				
			||||||
 | 
					        data.insert(0, self.sta_list)
 | 
				
			||||||
 | 
					        csv = lf_csv(_columns= colmn, _rows= data,
 | 
				
			||||||
 | 
					                     _filename='throughput_under_channel_load.csv')
 | 
				
			||||||
 | 
					        csv.generate_csv()
 | 
				
			||||||
 | 
					        report.csv_file_name = "throughput_under_channel_load.csv"
 | 
				
			||||||
 | 
					        report.move_csv_file()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def monitor(self, duration_sec, monitor_interval, created_cx, col_names, iterations):
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            duration_sec = Realm.parse_time(duration_sec).seconds
 | 
				
			||||||
 | 
					        except:
 | 
				
			||||||
 | 
					            if (duration_sec is None) or (duration_sec <= 1):
 | 
				
			||||||
 | 
					                raise ValueError("L3CXProfile::monitor wants duration_sec > 1 second")
 | 
				
			||||||
 | 
					            if (duration_sec <= monitor_interval):
 | 
				
			||||||
 | 
					                raise ValueError("L3CXProfile::monitor wants duration_sec > monitor_interval")
 | 
				
			||||||
 | 
					        if created_cx == None:
 | 
				
			||||||
 | 
					            raise ValueError("Monitor needs a list of Layer 3 connections")
 | 
				
			||||||
 | 
					        if (monitor_interval is None) or (monitor_interval < 1):
 | 
				
			||||||
 | 
					            raise ValueError("L3CXProfile::monitor wants monitor_interval >= 1 second")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # monitor columns
 | 
				
			||||||
 | 
					        start_time = datetime.datetime.now()
 | 
				
			||||||
 | 
					        end_time = start_time + datetime.timedelta(seconds=duration_sec)
 | 
				
			||||||
 | 
					        # bps-rx-a (download) and bps-rx-b(upload) values are taken
 | 
				
			||||||
 | 
					        self.bps_rx_a, self.bps_rx_b, self.bps_rx, index = [], [], {}, -1
 | 
				
			||||||
 | 
					        bps_rx_a_avg,bps_rx_b_avg = [],[]
 | 
				
			||||||
 | 
					        [(self.bps_rx_a.append([]), self.bps_rx_b.append([])) for i in range(len(created_cx))]
 | 
				
			||||||
 | 
					        for test in range(1 + iterations):
 | 
				
			||||||
 | 
					            while datetime.datetime.now() < end_time:
 | 
				
			||||||
 | 
					                index += 1
 | 
				
			||||||
 | 
					                response = list(self.json_get('/cx/%s?fields=%s' % (','.join(created_cx),",".join(col_names))).values())[2:]
 | 
				
			||||||
 | 
					                self.bps_rx[index] = list(map(lambda i: [float(f"{x / (1000000):.2f}") for x in i.values()],response))
 | 
				
			||||||
 | 
					                time.sleep(monitor_interval)
 | 
				
			||||||
 | 
					        # bps_rx list is calculated
 | 
				
			||||||
 | 
					        print("rx rate values are with [bps-rx-a, bps-rx-b] :-\n", self.bps_rx,"\n\n")
 | 
				
			||||||
 | 
					        for index, key in enumerate(self.bps_rx):
 | 
				
			||||||
 | 
					            for i in range(len(self.bps_rx[key])):
 | 
				
			||||||
 | 
					                if self.cx_profile.side_b_min_bps != '0' and self.cx_profile.side_b_min_bps != 0:
 | 
				
			||||||
 | 
					                    self.bps_rx_a[i].append(self.bps_rx[key][i][0])
 | 
				
			||||||
 | 
					                if self.cx_profile.side_a_min_bps != '0' and self.cx_profile.side_a_min_bps != 0:
 | 
				
			||||||
 | 
					                    self.bps_rx_b[i].append(self.bps_rx[key][i][1])
 | 
				
			||||||
 | 
					        print(f"bps-rx-a values-: \n{self.bps_rx_a}\nbps-rx-b values-: \n{self.bps_rx_b}")
 | 
				
			||||||
 | 
					        if self.cx_profile.side_a_min_bps != '0' and self.cx_profile.side_a_min_bps != 0:
 | 
				
			||||||
 | 
					            bps_rx_b_avg = [float(f"{sum(i) / len(i): .2f}") for i in self.bps_rx_b]
 | 
				
			||||||
 | 
					        if self.cx_profile.side_b_min_bps != '0' and self.cx_profile.side_b_min_bps != 0:
 | 
				
			||||||
 | 
					            bps_rx_a_avg = [float(f"{sum(i) / len(i): .2f}") for i in self.bps_rx_a]
 | 
				
			||||||
 | 
					        return bps_rx_a_avg,bps_rx_b_avg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def check_util(self,real_cli_obj = None, util_list = None, real_cli = None,
 | 
				
			||||||
 | 
					                   ssh_root = None, ssh_passwd = None,test_time = 0,up_down = [0],threshold=None,channnel=0):
 | 
				
			||||||
 | 
					        # check the utilization and run the traffic
 | 
				
			||||||
 | 
					        bps_rx_a,bps_rx_b,sta_create,count = [],[],1,0
 | 
				
			||||||
 | 
					        for util in util_list:  #  get throughput for every utilization values
 | 
				
			||||||
 | 
					            if count > 0:
 | 
				
			||||||
 | 
					                if len(up_down) > 0: # give data rate value and delete aggigned
 | 
				
			||||||
 | 
					                    self.cx_profile.side_a_min_bps, self.cx_profile.side_b_min_bps = int(float(up_down[0])),int(float( up_down[0]))
 | 
				
			||||||
 | 
					                    up_down.pop(0)
 | 
				
			||||||
 | 
					            count += 1
 | 
				
			||||||
 | 
					            stop_channel_load = 0
 | 
				
			||||||
 | 
					            util_flag = 1
 | 
				
			||||||
 | 
					            '''Loop until the expected channel utilization will get'''
 | 
				
			||||||
 | 
					            while util_flag:
 | 
				
			||||||
 | 
					                stop_channel_load += 1
 | 
				
			||||||
 | 
					                '''STOP the script if unable to set the utilization for 20 times'''
 | 
				
			||||||
 | 
					                if stop_channel_load >= 20:
 | 
				
			||||||
 | 
					                    print(f"Tried loading the channel with {util}% for {stop_channel_load} times...\n"
 | 
				
			||||||
 | 
					                          f"Unable to load the channel with {util}%\nScript exiting...")
 | 
				
			||||||
 | 
					                    exit(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                util_val = self.chn_util(ssh_root, ssh_passwd, channnel=channnel)  # find the channel utilization
 | 
				
			||||||
 | 
					                if (util - 3) <= util_val <= (util + 3):
 | 
				
			||||||
 | 
					                    util_flag = 0
 | 
				
			||||||
 | 
					                    if sta_create:
 | 
				
			||||||
 | 
					                        sta_create = 0
 | 
				
			||||||
 | 
					                        real_cli_obj.build()    # create specified no.of clients once
 | 
				
			||||||
 | 
					                    real_cli_obj.start(False, False)
 | 
				
			||||||
 | 
					                    time.sleep(20)
 | 
				
			||||||
 | 
					                    _bps_rx_a, _bps_rx_b = real_cli_obj.monitor(duration_sec=float(self.test_duration) * 60, monitor_interval=1,
 | 
				
			||||||
 | 
					                                 created_cx=real_cli_obj.cx_profile.created_cx.keys(),
 | 
				
			||||||
 | 
					                                 col_names=['bps rx a', 'bps rx b'], iterations=0)
 | 
				
			||||||
 | 
					                    #_bps_rx_a, _bps_rx_b = real_cli_obj.throughput(util,real_cli)
 | 
				
			||||||
 | 
					                    bps_rx_a.append(_bps_rx_a)
 | 
				
			||||||
 | 
					                    bps_rx_b.append(_bps_rx_b)
 | 
				
			||||||
 | 
					                    real_cli_obj.stop(trf=True,ad_dwn=False)
 | 
				
			||||||
 | 
					                else:
 | 
				
			||||||
 | 
					                    # channel utilization is less than the expected utilization value
 | 
				
			||||||
 | 
					                    if util_val < (util - 3):
 | 
				
			||||||
 | 
					                        print("less than {}% util...".format(util))
 | 
				
			||||||
 | 
					                        if ((util ) - util_val) <= 4:
 | 
				
			||||||
 | 
					                            self.re_run_traff(100000, "add")
 | 
				
			||||||
 | 
					                        elif ((util ) - util_val) <= 8:
 | 
				
			||||||
 | 
					                            self.re_run_traff(300000, "add")
 | 
				
			||||||
 | 
					                        elif ((util ) - util_val) <= 12:
 | 
				
			||||||
 | 
					                            self.re_run_traff(500000, "add")
 | 
				
			||||||
 | 
					                        elif (util ) - util_val <= 16:
 | 
				
			||||||
 | 
					                            self.re_run_traff(1000000, "add")
 | 
				
			||||||
 | 
					                        elif (util ) - util_val > 16:
 | 
				
			||||||
 | 
					                            self.re_run_traff(1500000, "add")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    # channel utilization is less than the expected utilization value
 | 
				
			||||||
 | 
					                    elif util_val > (util + 3):
 | 
				
			||||||
 | 
					                        print("greater than {}% util...".format(util))
 | 
				
			||||||
 | 
					                        if (util_val - (util )) <= 4:
 | 
				
			||||||
 | 
					                            self.re_run_traff(100000, "sub")
 | 
				
			||||||
 | 
					                        elif (util_val - (util )) <= 8:
 | 
				
			||||||
 | 
					                            self.re_run_traff(300000, "sub")
 | 
				
			||||||
 | 
					                        elif (util_val - (util )) <= 12:
 | 
				
			||||||
 | 
					                            self.re_run_traff(500000, "sub")
 | 
				
			||||||
 | 
					                        elif util_val - (util ) <= 16:
 | 
				
			||||||
 | 
					                            self.re_run_traff(1000000, "sub")
 | 
				
			||||||
 | 
					                        elif util_val - (util ) > 16:
 | 
				
			||||||
 | 
					                            self.re_run_traff(1500000, "sub")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        print(f"bps_rx_a {bps_rx_a}\nbps_rx_b {bps_rx_b}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        test_end = datetime.datetime.now().strftime("%b %d %H:%M:%S")
 | 
				
			||||||
 | 
					        print("Test ended at ", test_end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if len(threshold) < len(util_list):
 | 
				
			||||||
 | 
					            for i in range(len(util_list)):
 | 
				
			||||||
 | 
					                try:
 | 
				
			||||||
 | 
					                    tmp = threshold[i]
 | 
				
			||||||
 | 
					                except IndexError as e:
 | 
				
			||||||
 | 
					                    print(f"Threshold {threshold} and utilization {util_list}")
 | 
				
			||||||
 | 
					                    threshold.append(100 - int(util_list[i]))
 | 
				
			||||||
 | 
					        print(f"threshold {threshold} and utilization {util_list}")
 | 
				
			||||||
 | 
					        test_setup_info = {
 | 
				
			||||||
 | 
					            "AP Name": self.ap,
 | 
				
			||||||
 | 
					            "SSID": real_cli_obj.ssid,
 | 
				
			||||||
 | 
					            'No.of stations': len(real_cli),
 | 
				
			||||||
 | 
					            'Vap channel': channnel,
 | 
				
			||||||
 | 
					            'Utilization': ', '.join(map(str,util_list)),
 | 
				
			||||||
 | 
					            'Threshold': ', '.join(map(str,threshold)),
 | 
				
			||||||
 | 
					            "Total Test Duration": datetime.datetime.strptime(test_end, '%b %d %H:%M:%S') - datetime.datetime.strptime(test_time, '%b %d %H:%M:%S')
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        input_setup_info = {
 | 
				
			||||||
 | 
					            "Contact": "support@candelatech.com"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        # send all the collected data to genarate report
 | 
				
			||||||
 | 
					        real_cli_obj.report(util = util_list, sta_num = real_cli,
 | 
				
			||||||
 | 
					                                    bps_rx_a = bps_rx_a, bps_rx_b= bps_rx_b,
 | 
				
			||||||
 | 
					                                    rep_title = "Throughput Under Channel Load",
 | 
				
			||||||
 | 
					                                    upload = int(real_cli_obj.cx_profile.side_a_min_bps)/1000000,
 | 
				
			||||||
 | 
					                                    download = int(real_cli_obj.cx_profile.side_b_min_bps)/1000000,
 | 
				
			||||||
 | 
					                                    test_setup_info = test_setup_info,input_setup_info = input_setup_info,threshold= threshold)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def main():
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        optional,required = [],[]
 | 
				
			||||||
 | 
					        optional.append({'name': '--mode', 'help': 'Used to force mode of stations','default': 9})
 | 
				
			||||||
 | 
					        optional.append({'name': '--ap_name', 'help': 'AP name'})
 | 
				
			||||||
 | 
					        required.append({'name': '--ap_ip', 'help': 'IP of AP which was connected'})
 | 
				
			||||||
 | 
					        optional.append({'name': '--test_duration', 'help': 'Sets the duration of the test in minutes', 'default': 1})
 | 
				
			||||||
 | 
					        optional.append({'name':'--vap_channel', 'help':'To create VAP provide the AP channel', 'default': 36})
 | 
				
			||||||
 | 
					        required.append({'name':'--vap_radio', 'help':'VAP radio', 'default': "wiphy3"})
 | 
				
			||||||
 | 
					        optional.append({'name':'--util', 'help':'Channel utilization(provide whole number eg: 11,23,30,etc) with data_rate(bps) for that utilization',
 | 
				
			||||||
 | 
					                         'default': "20-3000000,40-6000000"})
 | 
				
			||||||
 | 
					        optional.append({'name':'--threshold', 'help':'Set the threshold for each utilization. '
 | 
				
			||||||
 | 
					                          'By default it will take 100-util_value (eg: 100-20=80) in case user not providing the Threshold'})
 | 
				
			||||||
 | 
					        required.append({'name':'--ap_password','help':'Password for AP'})
 | 
				
			||||||
 | 
					        optional.append({'name': '--upload', 'help': 'Upload bps rate minimum for side_a of netgear', 'default': 0})
 | 
				
			||||||
 | 
					        optional.append({'name': '--download', 'help': 'Download bps rate minimum for side_b of netgear', 'default': 0})
 | 
				
			||||||
 | 
					        parser = Realm.create_basic_argparse(
 | 
				
			||||||
 | 
					            prog='throughput.py',
 | 
				
			||||||
 | 
					            formatter_class=argparse.RawTextHelpFormatter,
 | 
				
			||||||
 | 
					            epilog='''\
 | 
				
			||||||
 | 
					                Measure the throughput for no.of clients when the channel was already utilized by specific load
 | 
				
			||||||
 | 
					                ''',
 | 
				
			||||||
 | 
					            description='''\
 | 
				
			||||||
 | 
					    throughput.py:
 | 
				
			||||||
 | 
					    --------------------
 | 
				
			||||||
 | 
					    Generic command layout:
 | 
				
			||||||
 | 
					    Note:- 
 | 
				
			||||||
 | 
					    **** In case user providing 'Fractional part' to the input values while running, the script will automatically truncate 
 | 
				
			||||||
 | 
					    the Fractional part except the test_duration.
 | 
				
			||||||
 | 
					    **** The script will automatically stop its execution when the channel is unable to load.
 | 
				
			||||||
 | 
					    python3 ./throughput.py
 | 
				
			||||||
 | 
					        --mode 1 {"auto"   : "0",
 | 
				
			||||||
 | 
					            "a"      : "1",
 | 
				
			||||||
 | 
					            "b"      : "2",
 | 
				
			||||||
 | 
					            "g"      : "3",
 | 
				
			||||||
 | 
					            "abg"    : "4",
 | 
				
			||||||
 | 
					            "abgn"   : "5",
 | 
				
			||||||
 | 
					            "bgn"    : "6",
 | 
				
			||||||
 | 
					            "bg"     : "7",
 | 
				
			||||||
 | 
					            "abgnAC" : "8",
 | 
				
			||||||
 | 
					            "anAC"   : "9",
 | 
				
			||||||
 | 
					            "an"     : "10",
 | 
				
			||||||
 | 
					            "bgnAC"  : "11",
 | 
				
			||||||
 | 
					            "abgnAX" : "12",
 | 
				
			||||||
 | 
					            "bgnAX"  : "13"}
 | 
				
			||||||
 | 
					        --upstream_port eth1
 | 
				
			||||||
 | 
					        --vap_radio wiphy0
 | 
				
			||||||
 | 
					        --vap_channel 36
 | 
				
			||||||
 | 
					        --radio wiphy1
 | 
				
			||||||
 | 
					        --num_stations 40
 | 
				
			||||||
 | 
					        --security {open|wep|wpa|wpa2|wpa3}
 | 
				
			||||||
 | 
					        --ssid netgear
 | 
				
			||||||
 | 
					        --password admin123
 | 
				
			||||||
 | 
					        --test_duration 1 (default)
 | 
				
			||||||
 | 
					        --upload 3000000
 | 
				
			||||||
 | 
					        --download 3000000
 | 
				
			||||||
 | 
					        --util 20-2000000,40-000000
 | 
				
			||||||
 | 
					        --threshold 80,50
 | 
				
			||||||
 | 
					        --ap_ip 192.168.208.22
 | 
				
			||||||
 | 
					        --ap_name WAC505
 | 
				
			||||||
 | 
					        --ap_password Password@123xzsawq@!
 | 
				
			||||||
 | 
					        --debug
 | 
				
			||||||
 | 
					    ===============================================================================
 | 
				
			||||||
 | 
					        ''', more_optional=optional, more_required = required)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        args = parser.parse_args()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        util_rate = args.util.split(',')
 | 
				
			||||||
 | 
					        if args.threshold != None:
 | 
				
			||||||
 | 
					            threshold = [int(float(i)) for i in args.threshold.split(',')]
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            threshold = []
 | 
				
			||||||
 | 
					        util_list, rate_list = [],[]
 | 
				
			||||||
 | 
					        for i in range(len(util_rate)):
 | 
				
			||||||
 | 
					            util_list.append(util_rate[i].split('-')[0])
 | 
				
			||||||
 | 
					            rate_list.append(util_rate[i].split('-')[1])
 | 
				
			||||||
 | 
					        util_list = [int(float(i)) for i in util_list]
 | 
				
			||||||
 | 
					        num_sta = lambda ars: ars if (ars != None and ars != 0) else 40    # if num station is None by deafault it create 2 stations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # 4 stations created under VAP by default
 | 
				
			||||||
 | 
					        station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_= 3 , padding_number_=10000, radio=args.radio)
 | 
				
			||||||
 | 
					        # vap name
 | 
				
			||||||
 | 
					        vap_name = 'vap0000'
 | 
				
			||||||
 | 
					        print("List of stations under VAP--",station_list,'\nVAP name--',vap_name)
 | 
				
			||||||
 | 
					        # traffic data rate for stations under vap
 | 
				
			||||||
 | 
					        vap_sta_upload, vap_sta_download = int(float(rate_list[0])), int(float(rate_list[0]))
 | 
				
			||||||
 | 
					        rate_list.pop(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # create stations and run traffic under VAP
 | 
				
			||||||
 | 
					        ip_var_test = IPV4VariableTime(host=args.mgr,           port=args.mgr_port,         number_template="0000",
 | 
				
			||||||
 | 
					                                       sta_list=station_list,   name_prefix="VT",           upstream=vap_name,
 | 
				
			||||||
 | 
					                                       ssid="vap_ssid",          password='[BLANK]',       radio=args.radio,
 | 
				
			||||||
 | 
					                                       security='open',         test_duration=args.test_duration,
 | 
				
			||||||
 | 
					                                       use_ht160=False,         side_a_min_rate= vap_sta_upload,
 | 
				
			||||||
 | 
					                                       side_b_min_rate=vap_sta_download,
 | 
				
			||||||
 | 
					                                       mode=args.mode,          ap=args.ap_name,                 _debug_on=args.debug,
 | 
				
			||||||
 | 
					                                       _vap_list = vap_name, _vap_radio = args.vap_radio, _dhcp = False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # ip_var_test.stop()
 | 
				
			||||||
 | 
					        # time.sleep(30)
 | 
				
			||||||
 | 
					        test_time = datetime.datetime.now().strftime("%b %d %H:%M:%S")
 | 
				
			||||||
 | 
					        print("Test started at ", test_time)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ip_var_test.pre_cleanup() # clear existing clients
 | 
				
			||||||
 | 
					        ip_var_test.build_vaps(chn = int(float(args.vap_channel)))  # create VAPs
 | 
				
			||||||
 | 
					        ip_var_test.build()     # create Stations and traffic
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if not ip_var_test.passes():
 | 
				
			||||||
 | 
					            print(ip_var_test.get_fail_message())
 | 
				
			||||||
 | 
					            ip_var_test.exit_fail()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            layer3connections = ','.join([[*x.keys()][0] for x in ip_var_test.json_get('endp')['endpoint']])
 | 
				
			||||||
 | 
					        except:
 | 
				
			||||||
 | 
					            raise ValueError('Try setting the upstream port flag if your device does not have an eth1 port')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ip_var_test.start(False, False)  # start the traffic and admin-up the sta
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        station_list1 = LFUtils.portNameSeries(prefix_="Thsta", start_id_=0, end_id_=int(num_sta(args.num_stations))-1, padding_number_=10000,
 | 
				
			||||||
 | 
					                                               radio=args.radio)
 | 
				
			||||||
 | 
					        print("Station list for netgear AP.....\n",station_list1)
 | 
				
			||||||
 | 
					        ip_var_test1 = IPV4VariableTime(host=args.mgr,          port=args.mgr_port,         number_template="0000",
 | 
				
			||||||
 | 
					                                        sta_list=station_list1, name_prefix="Thrp",         upstream=args.upstream_port,
 | 
				
			||||||
 | 
					                                        ssid= args.ssid,   password=args.passwd,       radio=args.radio,
 | 
				
			||||||
 | 
					                                        security=args.security,                    test_duration=args.test_duration,
 | 
				
			||||||
 | 
					                                        use_ht160=False,      side_a_min_rate=int(float(args.upload)),    side_b_min_rate=int(float(args.download)),
 | 
				
			||||||
 | 
					                                        mode=args.mode,       ap=args.ap_name,             _debug_on=args.debug,   _dhcp = True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # check the channel utilization
 | 
				
			||||||
 | 
					        ip_var_test.check_util(real_cli_obj = ip_var_test1, util_list = util_list,real_cli = station_list1, ssh_root = args.ap_ip,
 | 
				
			||||||
 | 
					           ssh_passwd = args.ap_password,test_time = test_time, up_down=rate_list,threshold = threshold,channnel = int(float(args.vap_channel)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if not ip_var_test.passes():
 | 
				
			||||||
 | 
					            print(ip_var_test.get_fail_message())
 | 
				
			||||||
 | 
					            ip_var_test.exit_fail()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ip_var_test.pre_cleanup() # clean the existing sta and traffics
 | 
				
			||||||
 | 
					        if ip_var_test.passes():
 | 
				
			||||||
 | 
					            ip_var_test.exit_success()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    except Exception as e:
 | 
				
			||||||
 | 
					        print("###",e,"###\nUnable to run the script...\nProvide the right values with the help of --help command\n"
 | 
				
			||||||
 | 
					                      "OR Re-run the script if the script stopped by some unexpected behavior..")
 | 
				
			||||||
 | 
					        print(traceback.format_exc())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == "__main__":
 | 
				
			||||||
 | 
					    main()
 | 
				
			||||||
		Reference in New Issue
	
	Block a user