l3_cxprofile.py : updated to support one interface,

port_probe.py : added more supported mcs in calculation
test_ip_variable_time.py : added support for use_existing_sta
removed create_sta as it was defaulted True and could not be set by
construct.

inconsistent list construction between single and multiple elements
decided around May 23, 2018
Updates for probe with AX210 , AX200 wiphy

Signed-off-by: Chuck SmileyRekiere <chuck.smileyrekiere@candelatech.com>
This commit is contained in:
Chuck SmileyRekiere
2021-11-12 17:02:13 -07:00
parent 1aa792930a
commit e5e3c90336
2 changed files with 94 additions and 53 deletions

View File

@@ -199,35 +199,35 @@ class ProbePort(LFCliBase):
# MCS (Modulation Coding Scheme) determines the constands # MCS (Modulation Coding Scheme) determines the constands
# MCS 0 == Modulation BPSK R = 1/2 , N_bpscs = 1, # MCS 0 == Modulation BPSK R = 1/2 , N_bpscs = 1,
# Only for HT configuration # Only for HT configuration
if self.tx_mcs == 0 or self.tx_mcs == 16 or self.tx_mcs == 24: if self.tx_mcs == 0 or self.tx_mcs == 8 or self.tx_mcs == 16 or self.tx_mcs == 24:
R = 1 / 2 R = 1 / 2
N_bpscs = 1 N_bpscs = 1
# MCS 1 == Modulation QPSK R = 1/2 , N_bpscs = 2 # MCS 1 == Modulation QPSK R = 1/2 , N_bpscs = 2
elif self.tx_mcs == 1 or self.tx_mcs == 17 or self.tx_mcs == 25: elif self.tx_mcs == 1 or self.tx_mcs == 9 or self.tx_mcs == 17 or self.tx_mcs == 25:
R = 1 / 2 R = 1 / 2
N_bpscs = 2 N_bpscs = 2
# MCS 2 == Modulation QPSK R = 3/4 , N_bpscs = 2 # MCS 2 == Modulation QPSK R = 3/4 , N_bpscs = 2
elif self.tx_mcs == 2 or self.tx_mcs == 18 or self.tx_mcs == 26: elif self.tx_mcs == 2 or self.tx_mcs == 10 or self.tx_mcs == 18 or self.tx_mcs == 26:
R = 3 / 4 R = 3 / 4
N_bpscs = 2 N_bpscs = 2
# MCS 3 == Modulation 16-QAM R = 1/2 , N_bpscs = 4 # MCS 3 == Modulation 16-QAM R = 1/2 , N_bpscs = 4
elif self.tx_mcs == 3 or self.tx_mcs == 19 or self.tx_mcs == 27: elif self.tx_mcs == 3 or self.tx_mcs == 11 or self.tx_mcs == 19 or self.tx_mcs == 27:
R = 1 / 2 R = 1 / 2
N_bpscs = 4 N_bpscs = 4
# MCS 4 == Modulation 16-QAM R = 3/4 , N_bpscs = 4 # MCS 4 == Modulation 16-QAM R = 3/4 , N_bpscs = 4
elif self.tx_mcs == 4 or self.tx_mcs == 20 or self.tx_mcs == 28: elif self.tx_mcs == 4 or self.tx_mcs == 12 or self.tx_mcs == 20 or self.tx_mcs == 28:
R = 3 / 4 R = 3 / 4
N_bpscs = 4 N_bpscs = 4
# MCS 5 == Modulation 64-QAM R = 2/3 , N_bpscs = 6 # MCS 5 == Modulation 64-QAM R = 2/3 , N_bpscs = 6
elif self.tx_mcs == 5 or self.tx_mcs == 21 or self.tx_mcs == 29: elif self.tx_mcs == 5 or self.tx_mcs == 13 or self.tx_mcs == 21 or self.tx_mcs == 29:
R = 2 / 3 R = 2 / 3
N_bpscs = 6 N_bpscs = 6
# MCS 6 == Modulation 64-QAM R = 3/4 , N_bpscs = 6 # MCS 6 == Modulation 64-QAM R = 3/4 , N_bpscs = 6
elif self.tx_mcs == 6 or self.tx_mcs == 22 or self.tx_mcs == 30: elif self.tx_mcs == 6 or self.tx_mcs == 14 or self.tx_mcs == 22 or self.tx_mcs == 30:
R = 3 / 4 R = 3 / 4
N_bpscs = 6 N_bpscs = 6
# MCS 7 == Modulation 64-QAM R = 5/6 , N_bpscs = 6 # MCS 7 == Modulation 64-QAM R = 5/6 , N_bpscs = 6
elif self.tx_mcs == 7 or self.tx_mcs == 23 or self.tx_mcs == 31: elif self.tx_mcs == 7 or self.tx_mcs == 15 or self.tx_mcs == 23 or self.tx_mcs == 31:
R = 5 / 6 R = 5 / 6
N_bpscs = 6 N_bpscs = 6
@@ -290,35 +290,35 @@ class ProbePort(LFCliBase):
# MCS (Modulation Coding Scheme) determines the constands # MCS (Modulation Coding Scheme) determines the constands
# MCS 0 == Modulation BPSK R = 1/2 , N_bpscs = 1, # MCS 0 == Modulation BPSK R = 1/2 , N_bpscs = 1,
# Only for HT configuration # Only for HT configuration
if self.rx_mcs == 0 or self.rx_mcs == 16 or self.rx_mcs == 24: if self.rx_mcs == 0 or self.rx_mcs == 8 or self.rx_mcs == 16 or self.rx_mcs == 24:
R = 1 / 2 R = 1 / 2
N_bpscs = 1 N_bpscs = 1
# MCS 1 == Modulation QPSK R = 1/2 , N_bpscs = 2 # MCS 1 == Modulation QPSK R = 1/2 , N_bpscs = 2
elif self.rx_mcs == 1 or self.rx_mcs == 17 or self.rx_mcs == 25: elif self.rx_mcs == 1 or self.rx_mcs == 9 or self.rx_mcs == 17 or self.rx_mcs == 25:
R = 1 / 2 R = 1 / 2
N_bpscs = 2 N_bpscs = 2
# MCS 2 == Modulation QPSK R = 3/4 , N_bpscs = 2 # MCS 2 == Modulation QPSK R = 3/4 , N_bpscs = 2
elif self.rx_mcs == 2 or self.rx_mcs == 18 or self.rx_mcs == 26: elif self.rx_mcs == 2 or self.rx_mcs == 10 or self.rx_mcs == 18 or self.rx_mcs == 26:
R = 3 / 4 R = 3 / 4
N_bpscs = 2 N_bpscs = 2
# MCS 3 == Modulation 16-QAM R = 1/2 , N_bpscs = 4 # MCS 3 == Modulation 16-QAM R = 1/2 , N_bpscs = 4
elif self.rx_mcs == 3 or self.rx_mcs == 19 or self.rx_mcs == 27: elif self.rx_mcs == 3 or self.rx_mcs == 11 or self.rx_mcs == 19 or self.rx_mcs == 27:
R = 1 / 2 R = 1 / 2
N_bpscs = 4 N_bpscs = 4
# MCS 4 == Modulation 16-QAM R = 3/4 , N_bpscs = 4 # MCS 4 == Modulation 16-QAM R = 3/4 , N_bpscs = 4
elif self.rx_mcs == 4 or self.rx_mcs == 20 or self.rx_mcs == 28: elif self.rx_mcs == 4 or self.rx_mcs == 12 or self.rx_mcs == 20 or self.rx_mcs == 28:
R = 3 / 4 R = 3 / 4
N_bpscs = 4 N_bpscs = 4
# MCS 5 == Modulation 64-QAM R = 2/3 , N_bpscs = 6 # MCS 5 == Modulation 64-QAM R = 2/3 , N_bpscs = 6
elif self.rx_mcs == 5 or self.rx_mcs == 21 or self.rx_mcs == 29: elif self.rx_mcs == 5 or self.rx_mcs == 13 or self.rx_mcs == 21 or self.rx_mcs == 29:
R = 2 / 3 R = 2 / 3
N_bpscs = 6 N_bpscs = 6
# MCS 6 == Modulation 64-QAM R = 3/4 , N_bpscs = 6 # MCS 6 == Modulation 64-QAM R = 3/4 , N_bpscs = 6
elif self.rx_mcs == 6 or self.rx_mcs == 22 or self.rx_mcs == 30: elif self.rx_mcs == 6 or self.rx_mcs == 14 or self.rx_mcs == 22 or self.rx_mcs == 30:
R = 3 / 4 R = 3 / 4
N_bpscs = 6 N_bpscs = 6
# MCS 7 == Modulation 64-QAM R = 5/6 , N_bpscs = 6 # MCS 7 == Modulation 64-QAM R = 5/6 , N_bpscs = 6
elif self.rx_mcs == 7 or self.rx_mcs == 23 or self.rx_mcs == 31: elif self.rx_mcs == 7 or self.rx_mcs == 15 or self.rx_mcs == 23 or self.rx_mcs == 31:
R = 5 / 6 R = 5 / 6
N_bpscs = 6 N_bpscs = 6

View File

@@ -48,7 +48,7 @@ class IPVariableTime(Realm):
security=None, security=None,
password=None, password=None,
sta_list=None, sta_list=None,
create_sta=True, use_existing_sta=False,
name_prefix=None, name_prefix=None,
upstream=None, upstream=None,
radio=None, radio=None,
@@ -88,7 +88,7 @@ class IPVariableTime(Realm):
self.port = port self.port = port
self.ssid = ssid self.ssid = ssid
self.sta_list = sta_list self.sta_list = sta_list
self.create_sta = create_sta self.use_existing_sta = use_existing_sta
self.security = security self.security = security
self.password = password self.password = password
self.radio = radio self.radio = radio
@@ -104,24 +104,26 @@ class IPVariableTime(Realm):
# "max_trying_ifup": 15, # "max_trying_ifup": 15,
# "max_station_bringup": 6 # "max_station_bringup": 6
# }) # })
self.name_prefix = name_prefix
self.test_duration = test_duration
self.station_profile = self.new_station_profile() self.station_profile = self.new_station_profile()
self.cx_profile = self.new_l3_cx_profile()
self.station_profile.lfclient_url = self.lfclient_url self.station_profile.lfclient_url = self.lfclient_url
self.station_profile.ssid = self.ssid self.station_profile.ssid = self.ssid
self.station_profile.ssid_pass = self.password self.station_profile.ssid_pass = self.password
self.station_profile.security = self.security self.station_profile.security = self.security
self.station_profile.number_template_ = self.number_template self.station_profile.number_template_ = self.number_template
self.station_profile.debug = self.debug self.station_profile.debug = self.debug
self.station_profile.use_ht160 = use_ht160 self.station_profile.use_ht160 = use_ht160
if self.station_profile.use_ht160: if self.station_profile.use_ht160:
self.station_profile.mode = 9 self.station_profile.mode = 9
self.station_profile.mode = mode self.station_profile.mode = mode
if self.ap is not None: if self.ap is not None:
self.station_profile.set_command_param("add_sta", "ap", self.ap) self.station_profile.set_command_param("add_sta", "ap", self.ap)
if self.use_existing_sta is True:
self.station_profile.station_names = self.sta_list
self.name_prefix = name_prefix
self.test_duration = test_duration
self.cx_profile = self.new_l3_cx_profile()
self.cx_profile.host = self.host self.cx_profile.host = self.host
self.cx_profile.port = self.port self.cx_profile.port = self.port
self.ipv6 = ipv6 self.ipv6 = ipv6
@@ -143,44 +145,48 @@ class IPVariableTime(Realm):
self.cx_profile.side_b_max_bps = side_b_max_rate self.cx_profile.side_b_max_bps = side_b_max_rate
def start(self, print_pass=False, print_fail=False): def start(self, print_pass=False, print_fail=False):
if self.create_sta: # if self.use_existing_station is False:
self.station_profile.admin_up() # to-do- check here if upstream port got IP
# to-do- check here if upstream port got IP self.station_profile.admin_up()
temp_stas = self.station_profile.station_names.copy() temp_stas = self.station_profile.station_names.copy()
print("temp_stas {temp_stas}".format(temp_stas=temp_stas))
if self.wait_for_ip(temp_stas, ipv4=not self.ipv6, ipv6=self.ipv6): if self.wait_for_ip(temp_stas, ipv4=not self.ipv6, ipv6=self.ipv6):
self._pass("All stations got IPs") self._pass("All stations got IPs")
else: else:
self._fail("Stations failed to get IPs") self._fail("Stations failed to get IPs")
self.exit_fail() self.exit_fail()
self.cx_profile.start_cx() self.cx_profile.start_cx()
def stop(self): def stop(self):
self.cx_profile.stop_cx() self.cx_profile.stop_cx()
if self.create_sta: self.station_profile.admin_down()
self.station_profile.admin_down()
def pre_cleanup(self): def pre_cleanup(self):
self.cx_profile.cleanup_prefix() self.cx_profile.cleanup_prefix()
if self.create_sta: # do not clean up station if existed prior to test
if self.use_existing_sta is False:
for sta in self.sta_list: for sta in self.sta_list:
self.rm_port(sta, check_exists=True) self.rm_port(sta, check_exists=True)
def cleanup(self): def cleanup(self):
self.cx_profile.cleanup() self.cx_profile.cleanup()
if self.create_sta: if self.use_existing_sta is False:
self.station_profile.cleanup() self.station_profile.cleanup()
LFUtils.wait_until_ports_disappear(base_url=self.lfclient_url, port_list=self.station_profile.station_names, LFUtils.wait_until_ports_disappear(base_url=self.lfclient_url, port_list=self.station_profile.station_names,
debug=self.debug) debug=self.debug)
def build(self): def build(self):
if self.create_sta: self.station_profile.use_security(self.security, self.ssid, self.password)
self.station_profile.use_security(self.security, self.ssid, self.password) self.station_profile.set_number_template(self.number_template)
self.station_profile.set_number_template(self.number_template) # print("sta_list {}".format(self.sta_list))
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)
if self.use_existing_sta is True:
print("Use Existing Stations: {sta_list}".format(sta_list=self.sta_list))
else:
print("Creating stations") print("Creating stations")
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)
self.station_profile.create(radio=self.radio, sta_names_=self.sta_list, debug=self.debug) self.station_profile.create(radio=self.radio, sta_names_=self.sta_list, debug=self.debug)
self._pass("PASS: Station build finished") self._pass("PASS: Station build finished")
@@ -222,7 +228,8 @@ class IPVariableTime(Realm):
self.build() self.build()
# exit() # exit()
if self.create_sta: # CMR What is this code doing
if self.use_existing_sta is False:
if not self.passes(): if not self.passes():
print(self.get_fail_message()) print(self.get_fail_message())
self.exit_fail() self.exit_fail()
@@ -302,7 +309,7 @@ class IPVariableTime(Realm):
debug=self.debug) debug=self.debug)
self.stop() self.stop()
if self.create_sta: if self.use_existing_sta is False:
if not self.passes(): if not self.passes():
print(self.get_fail_message()) print(self.get_fail_message())
self.exit_fail() self.exit_fail()
@@ -526,14 +533,39 @@ python3 ./test_ip_variable_time.py
Can't decide what columns to use? You can just use 'all' to select all available columns from both tables. Can't decide what columns to use? You can just use 'all' to select all available columns from both tables.
This script uses two args parsers one in the script the second is Realm args parser
Realm args parser is one directory up then traverse into /py-json/LANforge/lfcli_base.py
search for create_basic_argsparse
--mgr --mgr_port --upstream_port --num_stations --radio --security --ssid --passwd
Example command: Example command:
./test_ip_variable_time.py --mgr 192.168.100.116 --radio wiphy1 --ssid asus11ax-5 --passwd hello123 --security wpa2 1. Use Existing station , Note: put the resource.shelf.wifi-sta (below is 1.1.wlan4),
--test_duration 60s --output_format csv --traffic_type lf_tcp --a_min 600000000 --b_min 600000000 The station needs to configured with the ssid, passwd, security and mode in the LANforge GUI
--upstream_port eth2 --mode "5" --layer3_cols 'name','tx rate','rx rate' --port_mgr_cols 'alias','channel','activity','mode' ./test_ip_variable_time.py --mgr 192.168.0.100 --radio wiphy4 --ssid ssid_5g --passwd pass_5g
--num_stations 1 --security wpa2 --test_duration 60s --output_format csv --traffic_type lf_tcp
--a_min 600000000 --b_min 600000000 --upstream_port eth2 --mode '5'
--layer3_cols 'name','tx rate','rx rate' --port_mgr_cols 'alias','channel','activity','mode'
--use_existing_sta --sta_names 1.1.wlan4
2. Create a one station (script default is 1 if --num_stations not entered)
./test_ip_variable_time.py --mgr 192.168.0.100 --radio wiphy6 --ssid ssid_5g --passwd pass_5g
--security wpa2 --test_duration 60s --output_format csv --traffic_type lf_tcp
--a_min 600000000 --b_min 600000000 --upstream_port eth2 --mode '5'
--layer3_cols 'name','tx rate','rx rate' --port_mgr_cols 'alias','channel','activity','mode'
3. Create two stations
./test_ip_variable_time.py --mgr 192.168.0.100 --radio wiphy1 --ssid ssid_5g --passwd pass_5g
--security wpa2 --test_duration 60s --output_format csv --traffic_type lf_tcp
--a_min 600000000 --b_min 600000000 --upstream_port eth2 --mode '5'
--layer3_cols 'name','tx rate','rx rate' --port_mgr_cols 'alias','channel','activity','mode'
--num_stations 2
''') ''')
# Realm args parser is one directory up then traverse into /py-json/LANforge/lfcli_base.py
# search for create_basic_argsparse
# --mgr --mgr_port --upstream_port --num_stations --radio --security --ssid --passwd
parser.add_argument('--mode', help='Used to force mode of stations') parser.add_argument('--mode', help='Used to force mode of stations')
parser.add_argument('--ap', help='Used to force a connection to a particular AP') parser.add_argument('--ap', help='Used to force a connection to a particular AP')
parser.add_argument('--traffic_type', help='Select the Traffic Type [lf_udp, lf_tcp, udp, tcp], type will be ' parser.add_argument('--traffic_type', help='Select the Traffic Type [lf_udp, lf_tcp, udp, tcp], type will be '
@@ -564,21 +596,30 @@ python3 ./test_ip_variable_time.py
parser.add_argument('--influx_mgr', parser.add_argument('--influx_mgr',
help='IP address of the server your Influx database is hosted if different from your LANforge Manager', help='IP address of the server your Influx database is hosted if different from your LANforge Manager',
default=None) default=None)
parser.add_argument('--create_sta', help='Used to force a connection to a particular AP', default=True) parser.add_argument('--use_existing_sta', help='Used an existing stationsto a particular AP', action='store_true')
parser.add_argument('--sta_names', help='Used to force a connection to a particular AP', default="sta0000") parser.add_argument('--sta_names', help='Used to force a connection to a particular AP', default="sta0000")
args = parser.parse_args() args = parser.parse_args()
num_sta = 2 num_sta = 1
if (args.num_stations is not None) and (int(args.num_stations) > 0): if (args.num_stations is not None) and (int(args.num_stations) > 0):
print("one")
num_sta = int(args.num_stations) num_sta = int(args.num_stations)
if args.create_sta: if args.use_existing_sta is False:
print("two")
station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=num_sta - 1, station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=num_sta - 1,
padding_number_=10000, padding_number_=10000,
radio=args.radio) radio=args.radio)
else: else:
print("three")
station_list = args.sta_names.split(",") station_list = args.sta_names.split(",")
# Create directory
print("args.num_stations: {create}".format(create=args.num_stations))
print("args.sta_names: {create}".format(create=args.sta_names))
print("args.use_existing_sta: {create} {typeof}".format(create=args.use_existing_sta, typeof=type(args.use_existing_sta)))
print("station_list: {sta}".format(sta=station_list))
# Create directory
# if file path with output file extension is not given... # if file path with output file extension is not given...
# check if home/lanforge/report-data exists. if not, save # check if home/lanforge/report-data exists. if not, save
# in new folder based in current file's directory # in new folder based in current file's directory
@@ -604,7 +645,7 @@ python3 ./test_ip_variable_time.py
port=args.mgr_port, port=args.mgr_port,
number_template="0000", number_template="0000",
sta_list=station_list, sta_list=station_list,
create_sta=args.create_sta, use_existing_sta=args.use_existing_sta,
name_prefix="VT", name_prefix="VT",
upstream=args.upstream_port, upstream=args.upstream_port,
ssid=args.ssid, ssid=args.ssid,