Merge branch 'master' of github.com:greearb/lanforge-scripts

This commit is contained in:
Ben Greear
2021-05-06 10:54:07 -07:00
8 changed files with 377 additions and 237 deletions

View File

@@ -19,7 +19,6 @@ if 'py-json' not in sys.path:
sys.path.append(os.path.join(os.path.abspath('..'), 'py-json'))
import argparse
from realm import Realm
import datetime
def influx_add_parser_args(parser):
@@ -32,11 +31,8 @@ def influx_add_parser_args(parser):
help='--influx_tag <key> <val> Can add more than one of these.', default=[])
class CSVtoInflux(Realm):
class CSVtoInflux():
def __init__(self,
lfclient_host="localhost",
lfclient_port=8080,
debug=False,
_exit_on_error=False,
_exit_on_fail=False,
_proxy_str=None,
@@ -44,15 +40,8 @@ class CSVtoInflux(Realm):
influxdb=None,
_influx_tag=[],
target_csv=None):
super().__init__(lfclient_host=lfclient_host,
lfclient_port=lfclient_port,
debug_=debug,
_exit_on_error=_exit_on_error,
_exit_on_fail=_exit_on_fail,
_proxy_str=_proxy_str,
_capture_signal_list=_capture_signal_list)
self.influxdb = influxdb
self.target_csv = target_csv
self.target_csv = target_csv.replace('/home/lanforge/html-reports/', '')
self.influx_tag = _influx_tag
# Submit data to the influx db if configured to do so.

View File

@@ -315,13 +315,14 @@ if sys.version_info[0] != 3:
if 'py-json' not in sys.path:
sys.path.append(os.path.join(os.path.abspath('..'), 'py-json'))
from cv_test_manager import cv_test as cvtest
from cv_test_manager import cv_test
from cv_test_manager import *
from LANforge import LFUtils
class WiFiCapacityTest(cvtest):
class WiFiCapacityTest(cv_test):
def __init__(self,
lf_host="localhost",
lfclient_host="localhost",
lf_port=8080,
lf_user="lanforge",
lf_password="lanforge",
@@ -348,13 +349,16 @@ class WiFiCapacityTest(cvtest):
raw_lines=[],
raw_lines_file="",
sets=[],
influx_host="localhost",
influx_port=8086,
report_dir=""
):
super().__init__(lfclient_host=lf_host, lfclient_port=lf_port)
super().__init__(lfclient_host=lfclient_host, lfclient_port=lf_port)
self.lf_host = lf_host
self.lfclient_host = lfclient_host
self.lf_port = lf_port
self.lf_user = lf_user
self.lf_password =lf_password
self.lf_password = lf_password
self.station_profile = self.new_station_profile()
self.pull_report = pull_report
self.load_old_cfg = load_old_cfg
@@ -370,7 +374,7 @@ class WiFiCapacityTest(cvtest):
self.upstream = upstream
self.sort = sort
self.stations = stations
self.create_stations =create_stations
self.create_stations = create_stations
self.security = security
self.ssid = ssid
self.paswd = paswd
@@ -380,6 +384,9 @@ class WiFiCapacityTest(cvtest):
self.raw_lines = raw_lines
self.raw_lines_file = raw_lines_file
self.sets = sets
self.influx_host = influx_host,
self.influx_port = influx_port
self.report_dir=report_dir
def setup(self):
if self.create_stations and self.stations != "":
@@ -391,7 +398,6 @@ class WiFiCapacityTest(cvtest):
self.wait_for_ip(station_list=sta)
print("stations created")
def run(self):
self.sync_cv()
time.sleep(2)
@@ -403,10 +409,9 @@ class WiFiCapacityTest(cvtest):
# Test related settings
cfg_options = []
eid = LFUtils.name_to_eid(self.upstream)
port = "%i.%i.%s"%(eid[0], eid[1], eid[2])
port = "%i.%i.%s" % (eid[0], eid[1], eid[2])
port_list = [port]
if self.stations == "":
stas = self.station_map() # See realm
@@ -454,7 +459,7 @@ class WiFiCapacityTest(cvtest):
self.create_and_run_test(self.load_old_cfg, self.test_name, self.instance_name,
self.config_name, self.sets,
self.pull_report, self.lf_host, self.lf_user, self.lf_password,
self.pull_report, self.lfclient_host, self.lf_user, self.lf_password,
cv_cmds)
self.rm_text_blob(self.config_name, blob_test) # To delete old config with same name
@@ -463,7 +468,6 @@ class WiFiCapacityTest(cvtest):
def main():
parser = argparse.ArgumentParser(
description="""
./lf_wifi_capacity_test.py --mgr localhost --port 8080 --lf_user lanforge --lf_password lanforge \
@@ -507,11 +511,13 @@ def main():
help="ssid Security type")
parser.add_argument("-paswd", "--paswd", default="[BLANK]",
help="ssid Password")
parser.add_argument("--report_dir",default="")
parser.add_argument("--scenario",default="")
args = parser.parse_args()
cv_base_adjust_parser(args)
WFC_Test = WiFiCapacityTest(lf_host=args.mgr,
WFC_Test = WiFiCapacityTest(lfclient_host=args.mgr,
lf_port=args.port,
lf_user=args.lf_user,
lf_password=args.lf_password,
@@ -529,15 +535,15 @@ def main():
sort=args.sort,
stations=args.stations,
create_stations=args.create_stations,
radio =args.radio,
radio=args.radio,
ssid=args.ssid,
security =args.security,
paswd =args.paswd,
enables = args.enable,
disables = args.disable,
raw_lines = args.raw_line,
raw_lines_file = args.raw_lines_file,
sets = args.set
security=args.security,
paswd=args.paswd,
enables=args.enable,
disables=args.disable,
raw_lines=args.raw_line,
raw_lines_file=args.raw_lines_file,
sets=args.set,
)
WFC_Test.setup()
WFC_Test.run()

203
py-scripts/sandbox/lf_check_ap.py Executable file
View File

@@ -0,0 +1,203 @@
#!/usr/bin/python3
'''
NAME:
lf_check.py
PURPOSE:
Script to verify connectivity to an AP
EXAMPLE:
./lf_check_ap.py --ap_port '/dev/ttyUSB0' --ap_baud '115200' --ap_cmd "wl -i wl0 bs_data"
ap_stats wl -i wl0 bs_data
NOTES:
Script is in the sandbox
run /py-scripts/update_dependencies.py
'''
import sys
if sys.version_info[0] != 3:
print("This script requires Python3")
exit()
import logging
import time
from time import sleep
import argparse
import pexpect
import serial
from pexpect_serial import SerialSpawn
import json
from json import load
from pprint import *
# see https://stackoverflow.com/a/13306095/11014343
class FileAdapter(object):
def __init__(self, logger):
self.logger = logger
def write(self, data):
# NOTE: data can be a partial line, multiple lines
data = data.strip() # ignore leading/trailing whitespace
if data: # non-blank
self.logger.info(data)
def flush(self):
pass # leave it to logging to flush properly
class lf_check():
def __init__(self,
_ap_port,
_ap_baud,
_ap_cmd):
self.ap_port = _ap_port
self.ap_baud = _ap_baud
self.ap_cmd = _ap_cmd
def read_ap_stats(self):
# 5ghz: wl -i wl1 bs_data 2.4ghz# wl -i wl0 bs_data
ap_data = ""
ap_stats = []
#command = stats_5ghz
'''if band == "5ghz":
command = stats_5ghz
else:
command = stats_24ghz'''
# /dev/ttyUSB0 baud 115200
# configure the serial interface
#ser = serial.Serial(self.args.tty, int(self.args.baud), timeout=5)
ser = serial.Serial(self.ap_port, int(self.ap_baud), timeout=5)
ss = SerialSpawn(ser)
ss.sendline(str(self.ap_cmd))
ss.expect([pexpect.TIMEOUT], timeout=2) # do not detete line, waits for output
ap_stats = ss.before.decode('utf-8','ignore')
print("ap_stats {}".format(ap_stats))
'''ap_stats = "\
\
"
ap_stats.append("root@Docsis-Gateway:~# wl -i wl1 bs_data")
ap_stats.append("Station Address PHY Mbps Data Mbps Air Use Data Use Retries bw mcs Nss ofdma mu-mimo")
ap_stats.append("50:E0:85:87:AA:19 1016.6 48.9 6.5% 24.4% 16.6% 80 9.7 2 0.0% 0.0%")
ap_stats.append("50:E0:85:84:7A:E7 880.9 52.2 7.7% 26.1% 20.0% 80 8.5 2 0.0% 0.0%")
ap_stats.append("50:E0:85:89:5D:00 840.0 47.6 6.4% 23.8% 2.3% 80 8.0 2 0.0% 0.0%")
ap_stats.append("50:E0:85:87:5B:F4 960.7 51.5 5.9% 25.7% 0.0% 80 9 2 0.0% 0.0%")
ap_stats.append("(overall) - 200.2 26.5% - -")
# TODO: Read real stats, comment out the example above.
'''
return ap_stats
'''root@Docsis-Gateway:~# wl -i wl1 bs_data
Station Address PHY Mbps Data Mbps Air Use Data Use Retries bw mcs Nss ofdma mu-mimo
50:E0:85:87:AA:19 1064.5 52.8 6.0% 25.0% 1.5% 80 10.0 2 0.0% 0.0%
50:E0:85:84:7A:E7 927.1 53.6 7.0% 25.4% 5.7% 80 8.8 2 0.0% 0.0%
50:E0:85:89:5D:00 857.5 51.8 6.8% 24.6% 0.8% 80 8 2 0.0% 0.0%
50:E0:85:87:5B:F4 1071.7 52.8 6.0% 25.0% 1.3% 80 10 2 0.0% 0.0%
(overall) - 210.9 25.8% - -'''
'''I have some un-tested code that is starting point for querying Comcast AP in the l3_longevity script.
When still needs doing: query the data from the AP, and test that my parsing and CSV logic is working,
also add cmd-line arg to enable this or not. Would you have time to work on this and coordinate test time on
customer's system to test against their AP? Access to AP is probably ssh, possibly serial or telnet.
Firas @ Comcast can help clarify that.'''
def parse_ap_stats(self):
# Query AP for its stats. Result for /ax bcm APs looks something like this:
ap_stats = self.read_ap_stats()
ap_stats_rows = [] # Array of Arrays
for line in ap_stats:
stats_row = line.split()
ap_stats_rows.append(stats_row)
# - is this needed ?m = re.search((r'(\S+)\s+(\S+)\s+(Data Mbps)\s+(Air Use)+'ap_stats[0]
# Query all of our ports
#port_eids = self.gather_port_eids()
#for eid_name in port_eids:
# eid = self.name_to_eid(eid_name)
# url = "/port/%s/%s/%s"%(eid[0], eid[1], eid[2])
# response = self.json_get(url)
# if (response is None) or ("interface" not in response):
# print("query-port: %s: incomplete response:"%(url))
# pprint(response)
# else:
# note changed the indent
#p = response['interface']
mac = ["50:E0:85:87:AA:19","50:E0:85:84:7A:E7","50:E0:85:89:5D:00","50:E0:85:87:5B:F4"]
#mac = "50:E0:85:87:AA:19"
#mac = "50:E0:85:84:7A:E7"
#mac = "50:E0:85:89:5D:00"
#mac = "50:E0:85:87:5B:F4"
ap_row = []
i = 0
for row in ap_stats_rows:
if row[0] in mac:
#if row[0].lower == mac.lower():
ap_row = row
print("ap_row: {}".format(ap_row))
# p is map of key/values for this port
#print("ap_row : {}".format(ap_row))
#pprint(ap_row)
# Find latency, jitter for connections using this port.
#latency, jitter, tput = self.get_endp_stats_for_port(p["port"], endps)
# ap_stats_col_titles = ['Station Address','PHY Mbps','Data Mbps','Air Use','Data Use','Retries','bw','mcs','Nss','ofdma','mu-mimo'
# self.write_port_csv(len(temp_stations_list), ul, dl, ul_pdu_str, dl_pdu_str, atten_val, eid_name, p,
# latency, jitter, tput, ap_row, ap_stats_col_titles
def main():
parser = argparse.ArgumentParser(
prog='lf_check.py',
#formatter_class=argparse.RawDescriptionHelpFormatter,
formatter_class=argparse.RawTextHelpFormatter,
epilog='''\
Useful Information:
1. Verification
''',
description='''\
lf_check.py:
--------------------
#ssid TCH-XB7
#ssidpw comcats123
Summary :
----------
This file is used for verification
Generic command layout:
-----------------------
''')
parser.add_argument('--ap_port', help='--ap_port \'/dev/ttyUSB0\'',default='/dev/ttyUSB0')
parser.add_argument('--ap_baud', help='--ap_baud \'115200\'',default='115200')
parser.add_argument('--ap_cmd', help='--ap_cmd \'wl -i wl1 bs_data\'',default="wl -i wl1 bs_data")
args = parser.parse_args()
__ap_port = args.ap_port
__ap_baud = args.ap_baud
__ap_cmd = args.ap_cmd
check = lf_check(
_ap_port = __ap_port,
_ap_baud = __ap_baud,
_ap_cmd = __ap_cmd )
#check.parse_ap_stats()
check.read_ap_stats()
#check.run_test()
if __name__ == '__main__':
main()

View File

@@ -24,6 +24,7 @@ from time import sleep
import argparse
import pexpect
import serial
from pexpect_serial import SerialSpawn
import json
from json import load
from pprint import *
@@ -70,16 +71,16 @@ class lf_check():
else:
command = stats_24ghz'''
'''try:
#try:
# configure the serial interface
ser = serial.Serial(self.args.tty, int(self.args.baud), timeout=5)
egg = SerialSpawn(ser)
egg.sendline(str(command))
egg.expect([pexpect.TIMEOUT], timeout=2) # do not detete line, waits for output
ap_data = egg.before.decode('utf-8','ignore')
except:
print("WARNING unable to read AP")
'''
ser = serial.Serial("/dev/ttyUSB0", int(115200), timeout=5)
egg = SerialSpawn(ser)
egg.sendline(str(command))
egg.expect([pexpect.TIMEOUT], timeout=2) # do not detete line, waits for output
ap_data = egg.before.decode('utf-8','ignore')
#except:
# print("WARNING unable to read AP")
'''ap_stats = "\
\
" '''

View File

@@ -48,7 +48,6 @@ import time
import datetime
import subprocess
import csv
import random
# This class handles running the test and generating reports.
class L3VariableTime(Realm):
@@ -426,130 +425,6 @@ class L3VariableTime(Realm):
print("new-list:",new_list)
return False
# Verify communication to cisco controller is as expected.
# Can add support for different controllers by editing this
# or creating similar methods for different controllers.
def verify_controller(self):
if self.args == None:
return
if self.args.cisco_ctlr == None:
return
try:
print("scheme {} ctlr {} user {} passwd {} AP {} series {} band {} action {}".format(self.args.cisco_scheme,self.args.cisco_ctlr,self.args.cisco_user,
self.args.cisco_passwd, self.args.cisco_ap, self.args.cisco_series, self.args.cisco_band,"summary"))
ctl_output = subprocess.run(["../wifi_ctl_9800_3504.py", "--scheme", self.args.cisco_scheme, "-d", self.args.cisco_ctlr, "-u",
self.args.cisco_user, "-p", self.args.cisco_passwd,
"-a", self.args.cisco_ap,"--series", self.args.cisco_series,"--action", "summary"], capture_output=True)
pss = ctl_output.stdout.decode('utf-8', 'ignore')
print(pss)
except subprocess.CalledProcessError as process_error:
print("Controller unable to commicate to AP or unable to communicate to controller error code: {} output {}"
.format(process_error.returncode, process_error.output))
time.sleep(1)
exit(1)
# Find our station count
searchap = False
for line in pss.splitlines():
if (line.startswith("---------")):
searchap = True
continue
#TODO need to test with 9800 series to chelck the values
if (searchap):
pat = "%s\s+\S+\s+\S+\s+\S+\s+\S+.* \S+\s+\S+\s+(\S+)\s+\["%(self.args.cisco_ap)
#print("AP line: %s"%(line))
m = re.search(pat, line)
if (m != None):
sta_count = m.group(1)
print("AP line: %s"%(line))
print("sta-count: %s"%(sta_count))
if (int(sta_count) != int(self.total_stas)):
print("WARNING: Cisco Controller reported %s stations, should be %s"%(sta_count, self.total_stas))
if self.args.cap_ctl_out:
pss = ctl_output.stdout.decode('utf-8', 'ignore')
print(pss)
#advanced (showes summary)
#./wifi_ctl_9800_3504.py --scheme ssh -d 172.19.36.168 -p <controller_pw> --port 23 -a "9120-Chamber-1" --band a --action advanced --series 9800
def controller_show_ap_channel(self):
advanced = subprocess.run(["../wifi_ctl_9800_3504.py", "--scheme", self.args.cisco_scheme, "-d", self.args.cisco_ctlr, "-u",
self.args.cisco_user, "-p", self.args.cisco_passwd,
"-a", self.args.cisco_ap,"--series", self.args.cisco_series, "--action", "ap_channel"], capture_output=True)
pss = advanced.stdout.decode('utf-8', 'ignore')
print(pss)
if self.args.cisco_series == "9800":
for line in pss.splitlines():
search_str = self.args.cisco_ap
print("line {}".format(line))
element_list = line.lstrip().split()
print("element_list {}".format(element_list))
if (line.lstrip().startswith(search_str)):
print("line {}".format(line))
element_list = line.lstrip().split()
print("element_list {}".format(element_list))
# AP Name (0) mac (1) slot (2) Admin State [enable/disable] (3) Oper State [Up/Down] (4) Width (5) Txpwr (6,7) channel (8) mode (9)
print("ap: {} slof {} channel {} chan_width {}".format(element_list[0],element_list[2],element_list[8],element_list[5]))
if (str(self.args.cisco_channel) in str(element_list[8])) and (str(self.args.cisco_chan_width) in str(element_list[5])):
print("ap {} configuration successful: channel {} in expected {} chan_width {} in expected {}"
.format(element_list[0],self.args.cisco_channel,element_list[8],self.args.cisco_chan_width,element_list[5]))
else:
print("WARNING ap {} configuration: channel {} in expected {} chan_width {} in expected {}"
.format(element_list[0],self.args.cisco_channel,element_list[8],self.args.cisco_chan_width,element_list[5]))
break
else:
print("checking for 802.11{}".format(self.args.cisco_band))
for line in pss.splitlines():
#print("line {}".format(line))
search_str = "802.11{}".format(self.args.cisco_band)
if (line.lstrip().startswith(search_str)):
print("line {}".format(line))
element_list = line.lstrip().split()
print("element_list {}".format(element_list))
print("ap: {} channel {} chan_width {}".format(self.args.cisco_ap,element_list[4],element_list[5]))
if (str(self.args.cisco_channel) in str(element_list[4])) and (str(self.args.cisco_chan_width) in str(element_list[5])):
print("ap configuration successful: channel {} in expected {} chan_width {} in expected {}"
.format(self.args.cisco_channel,element_list[4],self.args.cisco_chan_width,element_list[5]))
else:
print("AP WARNING: channel {} expected {} chan_width {} expected {}"
.format(element_list[4],self.cisco_channel,element_list[5],self.args.cisco_chan_width))
break
print("configure ap {} channel {} chan_width {}".format(self.args.cisco_ap,self.args.cisco_channel,self.args.cisco_chan_width))
# Verify channel and channel width.
# This script supports resetting ports, allowing one to test AP/controller under data load
# while bouncing wifi stations. Check here to see if we should reset ports.
def reset_port_check(self):
for station_profile in self.station_profiles:
if station_profile.reset_port_extra_data['reset_port_enable']:
if station_profile.reset_port_extra_data['reset_port_timer_started'] == False:
print("reset_port_time_min: {}".format(station_profile.reset_port_extra_data['reset_port_time_min']))
print("reset_port_time_max: {}".format(station_profile.reset_port_extra_data['reset_port_time_max']))
station_profile.reset_port_extra_data['seconds_till_reset'] = \
random.randint(station_profile.reset_port_extra_data['reset_port_time_min'],\
station_profile.reset_port_extra_data['reset_port_time_max'])
station_profile.reset_port_extra_data['reset_port_timer_started'] = True
print("on radio {} seconds_till_reset {}".format(station_profile.add_sta_data['radio'],station_profile.reset_port_extra_data['seconds_till_reset']))
else:
station_profile.reset_port_extra_data['seconds_till_reset'] = station_profile.reset_port_extra_data['seconds_till_reset'] - 1
if self.debug: print("radio: {} countdown seconds_till_reset {}".format(station_profile.add_sta_data['radio'] ,station_profile.reset_port_extra_data['seconds_till_reset']))
if ((station_profile.reset_port_extra_data['seconds_till_reset'] <= 0)):
station_profile.reset_port_extra_data['reset_port_timer_started'] = False
port_to_reset = random.randint(0,len(station_profile.station_names)-1)
print("reset on radio {} station: {}".format(station_profile.add_sta_data['radio'],station_profile.station_names[port_to_reset]))
self.reset_port(station_profile.station_names[port_to_reset])
# Cleanup any older config that a previous run of this test may have created.
def pre_cleanup(self):
@@ -723,7 +598,6 @@ class L3VariableTime(Realm):
for atten_idx in self.attenuators:
self.set_atten(atten_idx, atten_val)
self.verify_controller()
print("Starting multicast traffic (if any configured)")
self.multicast_profile.start_mc(debug_=self.debug)
self.multicast_profile.refresh_mc(debug_=self.debug)
@@ -750,9 +624,9 @@ class L3VariableTime(Realm):
#interval_time = cur_time + datetime.timedelta(seconds=5)
interval_time = cur_time + datetime.timedelta(seconds=self.polling_interval_seconds)
#print("polling_interval_seconds {}".format(self.polling_interval_seconds))
while cur_time < interval_time:
cur_time = datetime.datetime.now()
self.reset_port_check()
time.sleep(1)
self.epoch_time = int(time.time())
@@ -1044,13 +918,6 @@ python .\\test_l3_longevity.py --test_duration <duration> --endp_type <traffic t
--radio "radio==<radio> stations==<number stations> ssid==<ssid> ssid_pw==<ssid password> security==<security type: wpa2, open, wpa3>" --debug
Multiple radios may be entered with individual --radio switches
generic command with controller setting channel and channel width test duration 5 min
python3 test_l3_longevity.py --cisco_ctlr <IP> --cisco_dfs True/False --mgr <Lanforge IP>
--cisco_channel <channel> --cisco_chan_width <20,40,80,120> --endp_type 'lf_udp lf_tcp mc_udp' --upstream_port <1.ethX>
--radio "radio==<radio 0 > stations==<number stations> ssid==<ssid> ssid_pw==<ssid password> security==<wpa2 , open>"
--radio "radio==<radio 1 > stations==<number stations> ssid==<ssid> ssid_pw==<ssid password> security==<wpa2 , open>"
--test_duration 5m
# UDP bi-directional test, no use of controller.
/test_l3_longevity.py --mgr localhost --endp_type 'lf_udp lf_tcp' --upstream_port 1.1.eth1 \
--radio "radio==1.1.wiphy0 stations==10 ssid==ASUS_70 ssid_pw==[BLANK] security==open" \
@@ -1077,16 +944,6 @@ BK, BE, VI, VO: Optional wifi related Tos Settings. Or, use your preferred num
#################################
#Command switches
#################################
--cisco_ctlr <IP of Cisco Controller>',default=None
--cisco_user <User-name for Cisco Controller>',default="admin"
--cisco_passwd <Password for Cisco Controller>',default="Cisco123
--cisco_prompt <Prompt for Cisco Controller>',default="(Cisco Controller) >
--cisco_ap <Cisco AP in question>',default="APA453.0E7B.CF9C"
--cisco_dfs <True/False>',default=False
--cisco_channel <channel>',default=None , no change
--cisco_chan_width <20 40 80 160>',default="20",choices=["20","40","80","160"]
--cisco_band <a | b | abgn>',default="a",choices=["a", "b", "abgn"]
--mgr <hostname for where LANforge GUI is running>',default='localhost'
-d / --test_duration <how long to run> example --time 5d (5 days) default: 3m options: number followed by d, h, m or s',default='3m'
@@ -1113,49 +970,9 @@ python3 .\\test_l3_longevity.py --test_duration 4m --endp_type \"lf_tcp lf_udp m
--radio "radio==wiphy0 stations==32 ssid==candelaTech-wpa2-x2048-4-1 ssid_pw==candelaTech-wpa2-x2048-4-1 security==wpa2"
--radio "radio==wiphy1 stations==64 ssid==candelaTech-wpa2-x2048-5-3 ssid_pw==candelaTech-wpa2-x2048-5-3 security==wpa2"
Example #2 using cisco controller
1. cisco controller at 192.168.100.112
2. cisco dfs True
3. cisco channel 52
4. cisco channel width 20
5. traffic 'lf_udp lf_tcp mc_udp'
6. upstream port eth3
7. radio #0 wiphy0 stations 3 ssid test_candela ssid_pw [BLANK] secruity Open
8. radio #1 wiphy1 stations 16 ssid test_candela ssid_pw [BLANK] security Open
9. lanforge manager at 192.168.100.178
10. duration 5m
Command:
python3 test_l3_longevity.py --cisco_ctlr 192.168.100.112 --cisco_dfs True --mgr 192.168.100.178
--cisco_channel 52 --cisco_chan_width 20 --endp_type 'lf_udp lf_tcp mc_udp' --upstream_port 1.eth3
--radio "radio==1.wiphy0 stations==3 ssid==test_candela ssid_pw==[BLANK] security==open"
--radio "radio==1.wiphy1 stations==16 ssid==test_candela ssid_pw==[BLANK] security==open"
--test_duration 5m
''')
parser.add_argument('--cisco_ctlr', help='--cisco_ctlr <IP of Cisco Controller>',default=None)
parser.add_argument('--cisco_user', help='--cisco_user <User-name for Cisco Controller>',default="admin")
parser.add_argument('--cisco_passwd', help='--cisco_passwd <Password for Cisco Controller>',default="Cisco123")
parser.add_argument('--cisco_prompt', help='--cisco_prompt <Prompt for Cisco Controller>',default="\(Cisco Controller\) >")
parser.add_argument('--cisco_ap', help='--cisco_ap <Cisco AP in question>',default="APA453.0E7B.CF9C")
parser.add_argument('--cisco_dfs', help='--cisco_dfs <True/False>',default=False)
parser.add_argument('--cisco_channel', help='--cisco_channel <channel>',default=None)
parser.add_argument('--cisco_chan_width', help='--cisco_chan_width <20 40 80 160>',default="20",choices=["20","40","80","160"])
parser.add_argument('--cisco_band', help='--cisco_band <a | b | abgn>',default="a",choices=["a", "b", "abgn"])
parser.add_argument('--cisco_series', help='--cisco_series <9800 | 3504>',default="3504",choices=["9800","3504"])
parser.add_argument('--cisco_scheme', help='--cisco_scheme (serial|telnet|ssh): connect via serial, ssh or telnet',default="ssh",choices=["serial","telnet","ssh"])
parser.add_argument('--cisco_wlan', help='--cisco_wlan <wlan name> default: NA, NA means no change',default="NA")
parser.add_argument('--cisco_wlanID', help='--cisco_wlanID <wlanID> default: NA , NA means not change',default="NA")
parser.add_argument('--cisco_tx_power', help='--cisco_tx_power <1 | 2 | 3 | 4 | 5 | 6 | 7 | 8> 1 is highest power default NA NA means no change',default="NA"
,choices=["1","2","3","4","5","6","7","8","NA"])
parser.add_argument('--tty', help='--tty \"/dev/ttyUSB2\" the serial interface to the AP')
parser.add_argument('--baud', help='--baud \"9600\" baud rate for the serial interface',default="9600")
parser.add_argument('--amount_ports_to_reset', help='--amount_ports_to_reset \"<min amount ports> <max amount ports>\" ', default=None)
@@ -1196,7 +1013,7 @@ python3 test_l3_longevity.py --cisco_ctlr 192.168.100.112 --cisco_dfs True --mgr
influx_add_parser_args(parser)
parser.add_argument("--cap_ctl_out", help="--cap_ctl_out, switch the cisco controller output will be captured", action='store_true')
parser.add_argument("--cap_ctl_out", help="--cap_ctl_out, switch the controller output will be captured", action='store_true')
parser.add_argument("--wait", help="--wait <time> , time to wait at the end of the test", default='0')
parser.add_argument("--show_least_most_csv", help="Should we show the least/most csv column data in reports?", action='store_true', default=False)

View File

@@ -3,7 +3,7 @@ import subprocess
def main():
print("Installing Script Python3 Dependencies")
packages = ['pandas', 'plotly', 'numpy', 'cryptography', 'paramiko', 'bokeh','pyarrow', 'websocket-client', 'xlsxwriter',\
'pyshark', 'influxdb', 'influxdb-client', 'matplotlib', 'pdfkit', 'pip-search', 'pyserial' ]
'pyshark', 'influxdb', 'influxdb-client', 'matplotlib', 'pdfkit', 'pip-search', 'pyserial', 'pexpect-serial' ]
packages_installed = []
packages_failed =[]
for package in packages:

121
py-scripts/wifi_cap_to_grafana.py Executable file
View File

@@ -0,0 +1,121 @@
#!/usr/bin/env python3
import sys
import os
import argparse
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'))
sys.path.append(os.path.join(os.path.abspath('..'), 'py-dashboard'))
from LANforge.lfcli_base import LFCliBase
from LANforge import LFUtils
import json
from csv_to_grafana import CSVtoInflux
from create_l3 import CreateL3
from lf_wifi_capacity_test import WiFiCapacityTest
from cv_test_manager import *
def main():
parser = argparse.ArgumentParser(
prog='wifi_cap_to_grafana.py',
formatter_class=argparse.RawTextHelpFormatter,
epilog='''Run Wifi Capacity and record results to Grafana''',
description='''\
wifi_cap_to_grafana.py
------------------
./wifi_cap_to_grafana.py
--num_stations
--grafana_token
--influx_host
--influx_org
--influx_token
--influx_bucket
--target_csv
--panel_name'''
)
cv_add_base_parser(parser) # see cv_test_manager.py
parser.add_argument("-b", "--batch_size", type=str, default="",
help="station increment ex. 1,2,3")
parser.add_argument("-l", "--loop_iter", type=str, default="",
help="Loop iteration ex. 1")
parser.add_argument("-p", "--protocol", type=str, default="",
help="Protocol ex.TCP-IPv4")
parser.add_argument("-d", "--duration", type=str, default="",
help="duration in ms. ex. 5000")
parser.add_argument("--download_rate", type=str, default="1Gbps",
help="Select requested download rate. Kbps, Mbps, Gbps units supported. Default is 1Gbps")
parser.add_argument("--upload_rate", type=str, default="10Mbps",
help="Select requested upload rate. Kbps, Mbps, Gbps units supported. Default is 10Mbps")
parser.add_argument("--sort", type=str, default="interleave",
help="Select station sorting behaviour: none | interleave | linear Default is interleave.")
parser.add_argument("-s", "--stations", type=str, default="",
help="If specified, these stations will be used. If not specified, all available stations will be selected. Example: 1.1.sta001,1.1.wlan0,...")
parser.add_argument("-cs", "--create_stations", default=False, action='store_true',
help="create stations in lanforge (by default: False)")
parser.add_argument('--a_min', help='--a_min bps rate minimum for side_a', default=256000)
parser.add_argument('--b_min', help='--b_min bps rate minimum for side_b', default=256000)
parser.add_argument('--number_template', help='Start the station numbering with a particular number. Default is 0000',
default=0000)
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("-radio", "--radio", default="wiphy0",
help="create stations in lanforge at this radio (by default: wiphy0)")
parser.add_argument("-ssid", "--ssid", default="",
help="ssid name")
parser.add_argument("-security", "--security", default="open",
help="ssid Security type")
parser.add_argument("-passwd", "--passwd", default="[BLANK]",
help="ssid Password")
parser.add_argument("--num_stations", default=2)
parser.add_argument("--mgr_port", default=8080)
parser.add_argument("--upstream_port", default="1.1.eth1")
parser.add_argument("--debug", default=False)
parser.add_argument("--scenario", help="", default=None)
args = parser.parse_args()
cv_base_adjust_parser(args)
# Run WiFi Capacity Test
wifi_capacity = WiFiCapacityTest(lfclient_host=args.mgr,
lf_port=args.mgr_port,
lf_user=args.lf_user,
lf_password=args.lf_password,
instance_name=args.instance_name,
config_name=args.config_name,
upstream=args.upstream_port,
batch_size=args.batch_size,
loop_iter=args.loop_iter,
protocol=args.protocol,
duration=args.duration,
pull_report=args.pull_report,
load_old_cfg=args.load_old_cfg,
download_rate=args.download_rate,
upload_rate=args.upload_rate,
sort=args.sort,
stations=args.stations,
create_stations=args.create_stations,
radio=args.radio,
ssid=args.ssid,
security=args.security,
paswd=args.passwd,
enables=args.enable,
disables=args.disable,
raw_lines=args.raw_line,
raw_lines_file=args.raw_lines_file,
sets=args.set)
wifi_capacity.apply_cv_scenario(args.scenario)
wifi_capacity.build_cv_scenario()
wifi_capacity.setup()
wifi_capacity.run()
wifi_capacity.check_influx_kpi(args)
if __name__ == "__main__":
main()