mirror of
https://github.com/Telecominfraproject/wlan-lanforge-scripts.git
synced 2025-11-02 03:37:55 +00:00
Merge /home/greearb/btbits/x64_btbits/server/lf_scripts
This commit is contained in:
2
py-scripts/.gitignore
vendored
Normal file
2
py-scripts/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
regression_test.txt
|
||||
regression_test.rc
|
||||
@@ -1,665 +0,0 @@
|
||||
""" file under progress not ffor testing
|
||||
|
||||
"""
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
import time
|
||||
|
||||
import threading
|
||||
|
||||
import os
|
||||
|
||||
import paramiko
|
||||
|
||||
from queue import Queue
|
||||
|
||||
from cx_time import IPv4Test
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class DFS_TESTING:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def __init__(self):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def set_dfs_channel_in_ap(self):
|
||||
|
||||
ssh = paramiko.SSHClient() # creating shh client object we use this object to connect to router
|
||||
|
||||
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # automatically adds the missing host key
|
||||
|
||||
ssh.connect('192.168.200.190', port=22, username='root', password='Lanforge12345!xzsawq@!')
|
||||
|
||||
stdin, stdout, stderr = ssh.exec_command('conf_set system:wlanSettings:wlanSettingTable:wlan1:channel 52')
|
||||
|
||||
output = stdout.readlines()
|
||||
|
||||
print('\n'.join(output))
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
exit(0)
|
||||
|
||||
|
||||
|
||||
def create_station_on_GUI(self,y1,y2):
|
||||
|
||||
global var1
|
||||
|
||||
self.y1 = y1
|
||||
|
||||
self.y2 = y2
|
||||
|
||||
cmd = "python3 sta_cx.py --mgr 192.168.200.13 --num_stations 1 --ssid TestAP95 --passwd lanforge --security wpa2 --radio wiphy0"
|
||||
|
||||
print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.chdir('/home/lanforge/lanforge-scripts/py-scripts')
|
||||
|
||||
print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
x = os.popen(cmd).read()
|
||||
|
||||
print("station created")
|
||||
|
||||
y1 ='station created'
|
||||
|
||||
|
||||
|
||||
with open("data.txt", "w")as f:
|
||||
|
||||
f.write(x)
|
||||
|
||||
f.close()
|
||||
|
||||
|
||||
|
||||
file = open("data.txt", "r")
|
||||
|
||||
for i in file:
|
||||
|
||||
if "channel associated is " in i:
|
||||
|
||||
my_list = list(i.split(" "))
|
||||
|
||||
print(my_list[3])
|
||||
|
||||
print(type(my_list[3]))
|
||||
|
||||
var1 = my_list[3]
|
||||
|
||||
|
||||
|
||||
print(var1)
|
||||
|
||||
var = var1.replace("\n", "")
|
||||
|
||||
|
||||
|
||||
if var == "52" or var == "56" or var == "60" or var == "64" or var == "100" or var == "104" or var == "108" or var == "112" or var == "116" or var == "120" or var == "124" or var == "128" or var == "132" or var == "136" or var == "140":
|
||||
|
||||
print('Station is on DFS Channel')
|
||||
|
||||
self.y2 = 'station is on DFS Channel'
|
||||
|
||||
else:
|
||||
|
||||
print('Station is on Non DFS channel')
|
||||
|
||||
self.y2 = 'Station is on Non DFS channel'
|
||||
|
||||
|
||||
|
||||
return (self.y1 , self.y2)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
''' ########### HACKRF ####################### '''
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def generate_radar_at_ch52(self, r):
|
||||
|
||||
self.r = r
|
||||
|
||||
cmd = "sudo python lf_hackrf.py --pulse_width 1 --pulse_interval 1428 --pulse_count 18 --sweep_time 1000 --freq 5260000"
|
||||
|
||||
# print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.chdir('/usr/lib64/python2.7/site-packages/')
|
||||
|
||||
#print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.system(cmd)
|
||||
|
||||
self.r = "Radar detected"
|
||||
|
||||
return self.r
|
||||
|
||||
|
||||
|
||||
def generate_radar_at_ch56(self):
|
||||
|
||||
cmd = "sudo python lf_hackrf.py --pulse_width 1 --pulse_interval 1428 --pulse_count 18 --sweep_time 1000 --freq 5280000"
|
||||
|
||||
# print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.chdir('/usr/lib64/python2.7/site-packages/')
|
||||
|
||||
# print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.system(cmd)
|
||||
|
||||
|
||||
|
||||
def generate_radar_at_ch60(self):
|
||||
|
||||
cmd = "sudo python lf_hackrf.py --pulse_width 1 --pulse_interval 1428 --pulse_count 18 --sweep_time 1000 --freq 5300000"
|
||||
|
||||
# print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.chdir('/usr/lib64/python2.7/site-packages/')
|
||||
|
||||
# print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.system(cmd)
|
||||
|
||||
|
||||
|
||||
def generate_radar_at_ch64(self):
|
||||
|
||||
cmd = "sudo python lf_hackrf.py --pulse_width 1 --pulse_interval 1428 --pulse_count 18 --sweep_time 1000 --freq 5320000"
|
||||
|
||||
# print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.chdir('/usr/lib64/python2.7/site-packages/')
|
||||
|
||||
# print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.system(cmd)
|
||||
|
||||
|
||||
|
||||
def generate_radar_at_ch100(self,r):
|
||||
|
||||
self.r = r
|
||||
|
||||
cmd = "sudo python lf_hackrf.py --pulse_width 1 --pulse_interval 1428 --pulse_count 18 --sweep_time 1000 --freq 5500000"
|
||||
|
||||
# print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.chdir('/usr/lib64/python2.7/site-packages/')
|
||||
|
||||
# print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.system(cmd)
|
||||
|
||||
self.r = "Radar received"
|
||||
|
||||
return self.r
|
||||
|
||||
|
||||
|
||||
def generate_radar_at_ch104(self):
|
||||
|
||||
cmd = "sudo python lf_hackrf.py --pulse_width 1 --pulse_interval 1428 --pulse_count 18 --sweep_time 1000 --freq 5520000"
|
||||
|
||||
# print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.chdir('/usr/lib64/python2.7/site-packages/')
|
||||
|
||||
# print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.system(cmd)
|
||||
|
||||
|
||||
|
||||
def generate_radar_at_ch108(self):
|
||||
|
||||
cmd = "sudo python lf_hackrf.py --pulse_width 1 --pulse_interval 1428 --pulse_count 18 --sweep_time 1000 --freq 5540000"
|
||||
|
||||
# print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.chdir('/usr/lib64/python2.7/site-packages/')
|
||||
|
||||
# print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.system(cmd)
|
||||
|
||||
|
||||
|
||||
def generate_radar_at_ch112(self):
|
||||
|
||||
cmd = "sudo python lf_hackrf.py --pulse_width 1 --pulse_interval 1428 --pulse_count 18 --sweep_time 1000 --freq 5560000"
|
||||
|
||||
# print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.chdir('/usr/lib64/python2.7/site-packages/')
|
||||
|
||||
# print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.system(cmd)
|
||||
|
||||
|
||||
|
||||
def generate_radar_at_ch116(self):
|
||||
|
||||
cmd = "sudo python lf_hackrf.py --pulse_width 1 --pulse_interval 1428 --pulse_count 18 --sweep_time 1000 --freq 5280000"
|
||||
|
||||
# print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.chdir('/usr/lib64/python2.7/site-packages/')
|
||||
|
||||
# print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.system(cmd)
|
||||
|
||||
|
||||
|
||||
def generate_radar_at_ch120(self):
|
||||
|
||||
cmd = "sudo python lf_hackrf.py --pulse_width 1 --pulse_interval 1428 --pulse_count 18 --sweep_time 1000 --freq 5600000"
|
||||
|
||||
#print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.chdir('/usr/lib64/python2.7/site-packages/')
|
||||
|
||||
# print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.system(cmd)
|
||||
|
||||
|
||||
|
||||
def generate_radar_at_ch124(self):
|
||||
|
||||
cmd = "sudo python lf_hackrf.py --pulse_width 1 --pulse_interval 1428 --pulse_count 18 --sweep_time 1000 --freq 5620000"
|
||||
|
||||
# print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.chdir('/usr/lib64/python2.7/site-packages/')
|
||||
|
||||
# print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.system(cmd)
|
||||
|
||||
|
||||
|
||||
def generate_radar_at_ch128(self):
|
||||
|
||||
cmd = "sudo python lf_hackrf.py --pulse_width 1 --pulse_interval 1428 --pulse_count 18 --sweep_time 1000 --freq 5640000"
|
||||
|
||||
# print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.chdir('/usr/lib64/python2.7/site-packages/')
|
||||
|
||||
# print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.system(cmd)
|
||||
|
||||
|
||||
|
||||
def generate_radar_at_ch132(self):
|
||||
|
||||
cmd = "sudo python lf_hackrf.py --pulse_width 1 --pulse_interval 1428 --pulse_count 18 --sweep_time 1000 --freq 5660000"
|
||||
|
||||
# print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.chdir('/usr/lib64/python2.7/site-packages/')
|
||||
|
||||
# print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.system(cmd)
|
||||
|
||||
|
||||
|
||||
def generate_radar_at_ch136(self):
|
||||
|
||||
cmd = "sudo python lf_hackrf.py --pulse_width 1 --pulse_interval 1428 --pulse_count 18 --sweep_time 1000 --freq 5680000"
|
||||
|
||||
# print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.chdir('/usr/lib64/python2.7/site-packages/')
|
||||
|
||||
# print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.system(cmd)
|
||||
|
||||
|
||||
|
||||
def generate_radar_at_ch140(self):
|
||||
|
||||
cmd = "sudo python lf_hackrf.py --pulse_width 1 --pulse_interval 1428 --pulse_count 18 --sweep_time 1000 --freq 5700000"
|
||||
|
||||
# print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.chdir('/usr/lib64/python2.7/site-packages/')
|
||||
|
||||
# print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.system(cmd)
|
||||
|
||||
|
||||
|
||||
def hackrf_status_off(self):
|
||||
|
||||
cmd = "sudo python lf_hackrf.py --pulse_width 1 --pulse_interval 1428 --pulse_count 18 --sweep_time 1000 --freq 5220000"
|
||||
|
||||
# print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.chdir('/usr/lib64/python2.7/site-packages/')
|
||||
|
||||
# print("Current working directory: {0}".format(os.getcwd()))
|
||||
|
||||
os.system(cmd)
|
||||
|
||||
|
||||
|
||||
def monitor_station_channel(self,m):
|
||||
|
||||
self.m = m
|
||||
|
||||
obj = IPv4Test(_host="192.168.200.13",
|
||||
|
||||
_port=8080,
|
||||
|
||||
_ssid="TestAP95",
|
||||
|
||||
_password="lanforge",
|
||||
|
||||
_security="wpa2",
|
||||
|
||||
_radio="wiphy0")
|
||||
|
||||
obj.cleanup(obj.sta_list)
|
||||
|
||||
obj.build()
|
||||
|
||||
obj.station_profile.admin_up()
|
||||
|
||||
obj.local_realm.wait_for_ip(obj.sta_list)
|
||||
|
||||
time.sleep(30)
|
||||
|
||||
var = obj.json_get("/port/1/1/sta0000?fields=channel")
|
||||
|
||||
var_1 = var['interface']['channel']
|
||||
|
||||
self.m = var_1
|
||||
|
||||
return self.m
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def aps_radio_off(self):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
|
||||
def aps_not_switch_automatically(self):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
|
||||
def check_ap_channel_switching_time(self):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
dfs = DFS_TESTING()
|
||||
|
||||
|
||||
|
||||
que = Queue()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
''' algorithm and sequence to be followed '''
|
||||
|
||||
|
||||
|
||||
print("Hackrf is ON")
|
||||
|
||||
print("press s --> enter --> q to stop hackrf")
|
||||
|
||||
dfs.hackrf_status_off()
|
||||
|
||||
print("Now hackrf is OFF")
|
||||
|
||||
|
||||
|
||||
#set channel on ap //netgear
|
||||
|
||||
|
||||
|
||||
threads_list = []
|
||||
|
||||
t1 = threading.Thread(target=lambda q, arg1, arg2: q.put(dfs.create_station_on_GUI(arg1, arg2)), args=(que, "", ""))
|
||||
|
||||
t1.start()
|
||||
|
||||
threads_list.append(t1)
|
||||
|
||||
t1.join()
|
||||
|
||||
|
||||
|
||||
# Check thread's return value
|
||||
|
||||
global my_var
|
||||
|
||||
|
||||
|
||||
result = que.get()
|
||||
|
||||
print("hi i reached", result)
|
||||
|
||||
my_var = result
|
||||
|
||||
|
||||
|
||||
list_1 = list(my_var)
|
||||
|
||||
print("my list", list_1)
|
||||
|
||||
|
||||
|
||||
if any("station is on DFS Channel" in s for s in list_1):
|
||||
|
||||
t2 = threading.Thread(target=lambda q, arg1: q.put(dfs.generate_radar_at_ch52(arg1)), args=(que, ""))
|
||||
|
||||
t2.start()
|
||||
|
||||
threads_list.append(t2)
|
||||
|
||||
t2.join()
|
||||
|
||||
x = que.get()
|
||||
|
||||
print("result", x)
|
||||
|
||||
else:
|
||||
|
||||
print("radar unreachable")
|
||||
|
||||
|
||||
|
||||
t3=threading.Thread(target=lambda q, arg1: q.put(dfs.monitor_station_channel(arg1)), args=(que, ""))
|
||||
|
||||
t3.start()
|
||||
|
||||
threads_list.append(t3)
|
||||
|
||||
t3.join()
|
||||
|
||||
y = que.get()
|
||||
|
||||
print("channel after radar is ", y)
|
||||
|
||||
|
||||
|
||||
if (y != "52"):
|
||||
|
||||
print("station is on Non DFS Channel")
|
||||
|
||||
else:
|
||||
|
||||
print("station is on DFS Channel")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
"""t2 = threading.Thread(target=lambda q, arg1: q.put(dfs.generate_radar_at_ch52(arg1)), args=(que, ""))
|
||||
|
||||
t2.start()
|
||||
|
||||
threads_list.append(t2)
|
||||
|
||||
t2.join()"""
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Join all the threads
|
||||
|
||||
"""for t in threads_list:
|
||||
|
||||
t.join()"""
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
"""print("my var", my_var)
|
||||
|
||||
empty_list = []
|
||||
|
||||
list = empty_list.append(my_var)
|
||||
|
||||
print("list", list)"""
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
'''t2 = threading.Thread(target=dfs.generate_radar_at_ch100())
|
||||
|
||||
t2.start()
|
||||
|
||||
t2.join()
|
||||
|
||||
print("radar received")
|
||||
|
||||
|
||||
|
||||
t3 = threading.Thread(target=dfs.create_station_on_GUI())
|
||||
|
||||
t3.start()
|
||||
|
||||
t3.join()
|
||||
|
||||
print("station reassociated")'''
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
'''dfs.hackrf_status_off()
|
||||
|
||||
dfs.aps_radio_off()
|
||||
|
||||
dfs.aps_not_switch_automatically()
|
||||
|
||||
#generate radar and check for all dfs channels
|
||||
|
||||
dfs.check_ap_channel_switching_time()
|
||||
|
||||
#after testing turn off hackrf'''
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
main()
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
# LANForge Python Scripts
|
||||
# LANForge Python Scripts
|
||||
This directory contains python scripts useful for unit-tests. It uses libraries in ../py-json. Please place new tests in this directory. Unless they are libraries, please avoid adding python scripts to ../py-json. Please read https://www.candelatech.com/cookbook/cli/json-python to learn about how to use the LANforge client JSON directly. Review http://www.candelatech.com/scripting_cookbook.php to understand more about scripts in general.
|
||||
|
||||
# Getting Started
|
||||
|
||||
The first step is to make sure all dependencies are installed in your system by running update_deps.py in this folder.
|
||||
|
||||
Please consider using the `LFCliBase` class as your script superclass. It will help you with a consistent set of JSON handling methods and pass and fail methods for recording test results. Below is a sample snippet that includes LFCliBase:
|
||||
|
||||
if 'py-json' not in sys.path:
|
||||
@@ -12,11 +15,11 @@ Please consider using the `LFCliBase` class as your script superclass. It will h
|
||||
from LANforge.LFUtils import *
|
||||
import realm
|
||||
from realm import Realm
|
||||
|
||||
|
||||
class Eggzample(LFCliBase):
|
||||
def __init__(self, lfclient_host, lfclient_port):
|
||||
super().__init__(lfclient_host, lfclient_port, debug=True)
|
||||
|
||||
|
||||
def main():
|
||||
eggz = Eggzample("http://localhost", 8080)
|
||||
frontpage_json = eggz.json_get("/")
|
||||
@@ -25,7 +28,7 @@ Please consider using the `LFCliBase` class as your script superclass. It will h
|
||||
"message": "hello world"
|
||||
}
|
||||
eggz.json_post("/cli-json/gossip", data, debug_=True)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -47,14 +50,14 @@ The above example will stimulate output on the LANforge client websocket `ws://l
|
||||
* /stations: entities that are associated to your virtual access points (vAP)
|
||||
There are more URIs you can explore, these are the more useful ones.
|
||||
|
||||
#### Scripts included are:
|
||||
#### Scripts included are:
|
||||
|
||||
* `cicd_TipIntegration.py`: battery of TIP tests that include upgrading DUT and executing sta_connect script
|
||||
|
||||
* `cicd_testrail.py`:
|
||||
* `cicd_testrail.py`:
|
||||
* `function send_get`: Issues a GET request (read) against the API.
|
||||
* `function send_post`: Issues a write against the API.
|
||||
* `function __send_request`:
|
||||
* `function __send_request`:
|
||||
* `function get_project_id`: Gets the project ID using the project name
|
||||
* `function get_run_id`: Gets the run ID using test name and project name
|
||||
* `function update_testrail`: Update TestRail for a given run_id and case_id
|
||||
@@ -74,7 +77,7 @@ There are more URIs you can explore, these are the more useful ones.
|
||||
* `run_cv_scenario.py`:
|
||||
* class `RunCvScenario`: imports the LFCliBase class.
|
||||
* function `get_report_file_name`: returns report name
|
||||
* function `build`: loads and sends the ports available?
|
||||
* function `build`: loads and sends the ports available?
|
||||
* function `start`: /gui_cli takes commands keyed on 'cmd' and this function create an array of commands
|
||||
* `sta_connect.py`: This function creates a station, create TCP and UDP traffic, run it a short amount of time,
|
||||
and verify whether traffic was sent and received. It also verifies the station connected
|
||||
@@ -88,7 +91,7 @@ There are more URIs you can explore, these are the more useful ones.
|
||||
* function `remove_stations`: removes all stations
|
||||
* function `num_associated`:
|
||||
* function `clear_test_results`:
|
||||
* function `run`:
|
||||
* function `run`:
|
||||
* function `setup`:
|
||||
* function `start`:
|
||||
* function `stop`:
|
||||
@@ -103,61 +106,61 @@ There are more URIs you can explore, these are the more useful ones.
|
||||
* function `get_upstream_url`:
|
||||
* function `compare_vals`: compares pre-test values to post-test values
|
||||
* function `remove_stations`: removes all ports
|
||||
* function `num_associated`:
|
||||
* function `num_associated`:
|
||||
* function `clear_test_results`
|
||||
* function `setup`: verifies upstream url, creates stations and turns dhcp on, creates endpoints,
|
||||
UDP endpoints,
|
||||
* function `start`:
|
||||
* function `start`:
|
||||
* function `stop`:
|
||||
* function `cleanup`:
|
||||
* function `main`:
|
||||
* function `main`:
|
||||
|
||||
* `sta_connect_example.py`: example of how to instantiate StaConnect and run the test
|
||||
|
||||
* `sta_connect_multi_example.py`: example of how to instantiate StaConnect and run the test and create multiple OPEN stations,have
|
||||
some stations using WPA2
|
||||
* `sta_connect_multi_example.py`: example of how to instantiate StaConnect and run the test and create multiple OPEN stations,have
|
||||
some stations using WPA2
|
||||
|
||||
* `stations_connected.py`: Contains examples of using realm to query stations and get specific information from them
|
||||
|
||||
* `test_ipv4_connection.py`: This script will create a variable number of stations that will attempt to connect to a chosen SSID using a provided password and security type.
|
||||
The test is considered passed if all stations are able to associate and obtain IPV4 addresses
|
||||
* `test_ipv4_connection.py`: This script will create a variable number of stations that will attempt to connect to a chosen SSID using a provided password and security type.
|
||||
The test is considered passed if all stations are able to associate and obtain IPV4 addresses
|
||||
* class `IPv4Test`
|
||||
* function `build`: This function will use the given parameters (Number of stations, SSID, password, and security type) to create a series of stations.
|
||||
* function `start`: This function will admin-up the stations created in the build phase. It will then check all stations periodically for association and IP addresses.
|
||||
This will continue until either the specified timeout has been reached or all stations obtain an IP address.
|
||||
* function `stop`: This function will admin-down all stations once one of the ending criteria is met.
|
||||
* function `start`: This function will admin-up the stations created in the build phase. It will then check all stations periodically for association and IP addresses.
|
||||
This will continue until either the specified timeout has been reached or all stations obtain an IP address.
|
||||
* function `stop`: This function will admin-down all stations once one of the ending criteria is met.
|
||||
* function `cleanup`: This function will clean up all stations created during the test.
|
||||
* command line options :
|
||||
* `--mgr`: Specifies the hostname where LANforge is running. Defaults to http://localhost
|
||||
* `--mgr_port`: Specifies the port to use when connecting to LANforge. Defaults to 8080
|
||||
* `--ssid`: Specifies SSID to be used in the test
|
||||
* `--password`: Specifies the password for the SSID to be used in the test
|
||||
* `--password`: Specifies the password for the SSID to be used in the test
|
||||
* `--security`: Specifies security type (WEP, WPA, WPA2, WPA3, Open) of SSID to be used in the test
|
||||
* `--num_stations`: Specifies number of stations to create for the test
|
||||
* `--radio`: Specifies the radio to be used in the test. Eg wiphy0
|
||||
* `--debug`: Turns on debug output for the test
|
||||
* `--help`: Displays help output for the script
|
||||
|
||||
* `test_ipv6_connection.py`: This script will create a variable number of stations that will attempt to connect to a chosen SSID using a provided password and security type.
|
||||
The test is considered passed if all stations are able to associate and obtain IPV6 addresses
|
||||
* `test_ipv6_connection.py`: This script will create a variable number of stations that will attempt to connect to a chosen SSID using a provided password and security type.
|
||||
The test is considered passed if all stations are able to associate and obtain IPV6 addresses
|
||||
* class `IPv6Test`
|
||||
* function `build`: This function will use the given parameters (Number of stations, SSID, password, and security type) to create a series of stations.
|
||||
* function `start`: This function will admin-up the stations created in the build phase. It will then check all stations periodically for association and IP addresses.
|
||||
This will continue until either the specified timeout has been reached or all stations obtain an IP address.
|
||||
* function `stop`: This function will admin-down all stations once one of the ending criteria is met.
|
||||
* function `start`: This function will admin-up the stations created in the build phase. It will then check all stations periodically for association and IP addresses.
|
||||
This will continue until either the specified timeout has been reached or all stations obtain an IP address.
|
||||
* function `stop`: This function will admin-down all stations once one of the ending criteria is met.
|
||||
* function `cleanup`: This function will clean up all stations created during the test.
|
||||
* Command line options :
|
||||
* `--mgr`: Specifies the hostname where LANforge is running. Defaults to http://localhost
|
||||
* `--mgr_port`: Specifies the port to use when connecting to LANforge. Defaults to 8080
|
||||
* `--ssid`: Specifies SSID to be used in the test
|
||||
* `--password`: Specifies the password for the SSID to be used in the test
|
||||
* `--password`: Specifies the password for the SSID to be used in the test
|
||||
* `--security`: Specifies security type (WEP, WPA, WPA2, WPA3, Open) of SSID to be used in the test
|
||||
* `--num_stations`: Specifies number of stations to create for the test
|
||||
* `--radio`: Specifies the radio to be used in the test. Eg wiphy0
|
||||
* `--debug`: Turns on debug output for the test
|
||||
* `--help`: Displays help output for the script
|
||||
|
||||
* `test_l3_unicast_traffic_gen.py`: This script will create stations, create traffic between upstream port and stations, run traffic.
|
||||
* `test_l3_unicast_traffic_gen.py`: This script will create stations, create traffic between upstream port and stations, run traffic.
|
||||
The traffic on the stations will be checked once per minute to verify that traffic is transmitted and received.
|
||||
Test will exit on failure of not receiving traffic for one minute on any station.
|
||||
* class `L3VariableTimeLongevity`
|
||||
@@ -170,10 +173,10 @@ Test will exit on failure of not receiving traffic for one minute on any station
|
||||
* `-d, --test_duration`: Determines the total length of the test. Consists of number followed by letter indicating length
|
||||
10m would be 10 minutes or 3d would be 3 days. Available options for length are Day (d), Hour (h), Minute (m), or Second (s)
|
||||
* `-t, --endp_type`: Specifies type of endpoint to be used in the test. Options are lf_udp, lf_udp6, lf_tcp, lf_tcp6
|
||||
* `-u, --upstream_port`: This is the upstream port to be used for traffic. An upstream port is some data source on the wired LAN or WAN beyond the AP
|
||||
* `-u, --upstream_port`: This is the upstream port to be used for traffic. An upstream port is some data source on the wired LAN or WAN beyond the AP
|
||||
* `-r, --radio`: This switch will determine the radio name, number of stations, ssid, and ssid password. Security type is fixed at WPA2.
|
||||
Usage of this switch could look like: `--radio wiphy1 64 candelaTech-wpa2-x2048-5-3 candelaTech-wpa2-x2048-5-3`
|
||||
|
||||
|
||||
* `test_ipv4_l4_urls_per_ten.py`: This script measure the number of urls per ten minutes over layer 4 traffic
|
||||
* class `IPV4L4`
|
||||
* function `build`: This function will create all stations and cross-connects to be used in the test
|
||||
@@ -186,17 +189,17 @@ Test will exit on failure of not receiving traffic for one minute on any station
|
||||
* `--mgr`: Specifies the hostname where LANforge is running. Defaults to http://localhost
|
||||
* `--mgr_port`: Specifies the port to use when connecting to LANforge. Defaults to 8080
|
||||
* `--ssid`: Specifies SSID to be used in the test
|
||||
* `--password`: Specifies the password for the SSID to be used in the test
|
||||
* `--password`: Specifies the password for the SSID to be used in the test
|
||||
* `--security`: Specifies security type (WEP, WPA, WPA2, WPA3, Open) of SSID to be used in the test
|
||||
* `--num_stations`: Specifies number of stations to create for the test
|
||||
* `--radio`: Specifies the radio to be used in the test. Eg wiphy0
|
||||
* `--requests_per_ten`: Configures the number of request per ten minutes
|
||||
* `--num_tests`: Configures the number of tests to be run. Each test runs for ten minutes
|
||||
* `--url`: Specifies the upload/download, address, and destination. Example: dl http://10.40.0.1 /dev/null
|
||||
* `--target_per_ten`: Rate of target urls per ten minutes. 90% of this value will be considered the threshold for a passed test.
|
||||
* `--target_per_ten`: Rate of target urls per ten minutes. 90% of this value will be considered the threshold for a passed test.
|
||||
* `--debug`: Turns on debug output for the test
|
||||
* `--help`: Displays help output for the script
|
||||
|
||||
|
||||
|
||||
* `test_ipv4_l4_ftp_urls_per_ten.py`: This script measure the number of urls per ten minutes over layer 4 ftp traffic
|
||||
* class `IPV4L4`
|
||||
@@ -210,29 +213,29 @@ Test will exit on failure of not receiving traffic for one minute on any station
|
||||
* `--mgr`: Specifies the hostname where LANforge is running. Defaults to http://localhost
|
||||
* `--mgr_port`: Specifies the port to use when connecting to LANforge. Defaults to 8080
|
||||
* `--ssid`: Specifies SSID to be used in the test
|
||||
* `--password`: Specifies the password for the SSID to be used in the test
|
||||
* `--password`: Specifies the password for the SSID to be used in the test
|
||||
* `--security`: Specifies security type (WEP, WPA, WPA2, WPA3, Open) of SSID to be used in the test
|
||||
* `--num_stations`: Specifies number of stations to create for the test
|
||||
* `--radio`: Specifies the radio to be used in the test. Eg wiphy0
|
||||
* `--requests_per_ten`: Configures the number of request per ten minutes
|
||||
* `--num_tests`: Configures the number of tests to be run. Each test runs for ten minutes
|
||||
* `--url`: Specifies the upload/download, address, and destination. Example: dl http://10.40.0.1 /dev/null
|
||||
* `--target_per_ten`: Rate of target urls per ten minutes. 90% of this value will be considered the threshold for a passed test.
|
||||
* `--target_per_ten`: Rate of target urls per ten minutes. 90% of this value will be considered the threshold for a passed test.
|
||||
* `--debug`: Turns on debug output for the test
|
||||
* `--help`: Displays help output for the script
|
||||
|
||||
* `test_generic`:
|
||||
* class `GenTest`: This script will create
|
||||
* class `GenTest`: This script will create
|
||||
* function `build`: This function will create the stations and cross-connects to be used during the test.
|
||||
* function `start`: This function will start traffic and measure different values dependent on the command chosen.
|
||||
* function `start`: This function will start traffic and measure different values dependent on the command chosen.
|
||||
Commands currently available for use: lfping, generic, and speedtest.
|
||||
* function `stop`: This function will admin-down stations, stop traffic on cross-connects and cleanup any stations or cross-connects associated with the test.
|
||||
* function `cleanup`: This function will remove any stations and cross-connects created during the test.
|
||||
* Command line options:
|
||||
* Command line options:
|
||||
* `--mgr`: Specifies the hostname where LANforge is running. Defaults to http://localhost
|
||||
* `--mgr_port`: Specifies the port to use when connecting to LANforge. Defaults to 8080
|
||||
* `--ssid`: Specifies SSID to be used in the test
|
||||
* `--password`: Specifies the password for the SSID to be used in the test
|
||||
* `--password`: Specifies the password for the SSID to be used in the test
|
||||
* `--security`: Specifies security type (WEP, WPA, WPA2, WPA3, Open) of SSID to be used in the test
|
||||
* `--num_stations`: Specifies number of stations to create for the test
|
||||
* `--radio`: Specifies the radio to be used in the test. Eg wiphy0
|
||||
@@ -263,6 +266,3 @@ Test will exit on failure of not receiving traffic for one minute on any station
|
||||
* class `VapStations`
|
||||
* function `run`:
|
||||
* function `main`:
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
py-scripts/artifacts/CandelaLogo2-90dpi-200x90-trans.png
Executable file
BIN
py-scripts/artifacts/CandelaLogo2-90dpi-200x90-trans.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 8.9 KiB |
BIN
py-scripts/artifacts/banner.png
Executable file
BIN
py-scripts/artifacts/banner.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 199 KiB |
@@ -1,9 +1,7 @@
|
||||
"""
|
||||
Candela Technologies Inc.
|
||||
|
||||
Info : Standard Script for Connection Testing
|
||||
Date :
|
||||
Author : Shivam Thakur
|
||||
Info : Standard Script for Connection Testing - Creates HTML and pdf report as a result (Used for web-console)
|
||||
|
||||
"""
|
||||
|
||||
@@ -22,21 +20,22 @@ import datetime
|
||||
import time
|
||||
import os
|
||||
from test_utility import CreateHTML
|
||||
from test_utility import RuntimeUpdates
|
||||
# from test_utility import RuntimeUpdates
|
||||
from test_utility import StatusMsg
|
||||
import pdfkit
|
||||
|
||||
|
||||
webconsole_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.getcwd())))
|
||||
|
||||
class ConnectionTest(LFCliBase):
|
||||
|
||||
def __init__(self, lfclient_host="localhost", lfclient_port=8080, radio="wiphy1", sta_prefix="sta", start_id=0,
|
||||
num_sta=2,
|
||||
dut_ssid="lexusdut", dut_security="open", dut_passwd="[BLANK]", upstream="eth1", _test_update=None, name_prefix="L3Test",
|
||||
dut_ssid="lexusdut", dut_security="open", dut_passwd="[BLANK]", upstream="eth1", name_prefix="L3Test",
|
||||
session_id="Layer3Test", test_name="Client/s Connectivity Test", pass_criteria=20, _debug_on=False,
|
||||
_exit_on_error=False, _exit_on_fail=False):
|
||||
super().__init__(lfclient_host, lfclient_port, _debug=_debug_on, _halt_on_error=_exit_on_error,
|
||||
_exit_on_fail=_exit_on_fail)
|
||||
print("Test is about to start")
|
||||
self.host = lfclient_host
|
||||
self.port = lfclient_port
|
||||
self.radio = radio
|
||||
@@ -53,37 +52,34 @@ class ConnectionTest(LFCliBase):
|
||||
self.session_id = session_id
|
||||
self.test_name = test_name
|
||||
self.test_duration = 1
|
||||
self.test_update = _test_update
|
||||
self.local_realm = realm.Realm(lfclient_host=self.host, lfclient_port=self.port)
|
||||
self.station_profile = self.local_realm.new_station_profile()
|
||||
self.pass_fail = ""
|
||||
|
||||
self.status_msg = StatusMsg(lfclient_host=self.host, lfclient_port=self.port, session_id=self.session_id)
|
||||
station_list = []
|
||||
for i in range(0, self.num_sta):
|
||||
station_list.append(self.sta_prefix + str(i).zfill(4))
|
||||
print(station_list)
|
||||
self.station_data = dict.fromkeys(station_list)
|
||||
for i in station_list:
|
||||
self.station_data[i] = "None"
|
||||
print(self.station_data)
|
||||
|
||||
self.test_update.send_update({"test_status": '1', "data": 'None', "data": [], "label": "Client Connectivity Time"})
|
||||
|
||||
try:
|
||||
self.status_msg.update('1', {"data": 'Initializing...', "data": [], "label": "Client Connectivity Time"})
|
||||
except:
|
||||
pass
|
||||
self.reports_path = webconsole_dir+"/reports/" + self.test_name + "_" + self.session_id + '/'
|
||||
|
||||
print(self.reports_path)
|
||||
|
||||
if not os.path.exists(self.reports_path):
|
||||
os.makedirs(self.reports_path)
|
||||
print("Test is Initialized")
|
||||
self.station_list = LFUtils.portNameSeries(prefix_=self.sta_prefix, start_id_=self.sta_start_id,
|
||||
end_id_=self.num_sta - 1, padding_number_=10000, radio=self.radio)
|
||||
print(self.station_profile.station_names)
|
||||
self.test_update.send_update({"test_status": '2', "data": 'None', "data": [], "label": "Client Connectivity Time"})
|
||||
|
||||
try:
|
||||
self.status_msg.update('2', {"data": 'Initialized...', "data": [], "label": "Client Connectivity Time"})
|
||||
except:
|
||||
pass
|
||||
|
||||
def precleanup(self):
|
||||
print("precleanup started")
|
||||
sta_list = []
|
||||
for i in self.local_realm.station_list():
|
||||
if (list(i.keys())[0] == '1.1.wlan0'):
|
||||
@@ -92,19 +88,19 @@ class ConnectionTest(LFCliBase):
|
||||
pass
|
||||
else:
|
||||
sta_list.append(list(i.keys())[0])
|
||||
print(sta_list)
|
||||
for sta in sta_list:
|
||||
self.local_realm.rm_port(sta, check_exists=True)
|
||||
time.sleep(1)
|
||||
|
||||
LFUtils.wait_until_ports_disappear(base_url=self.lfclient_url, port_list=sta_list,
|
||||
debug=self.debug)
|
||||
print("precleanup done")
|
||||
self.test_update.send_update({"test_status": '3', "data": 'None', "data": [], "label": "Client Connectivity Time"})
|
||||
try:
|
||||
self.status_msg.update('3', {"data": 'Building...', "data": [], "label": "Client Connectivity Time"})
|
||||
except:
|
||||
pass
|
||||
|
||||
def build(self):
|
||||
|
||||
print("Building Test Configuration")
|
||||
self.station_profile.use_security(self.security, self.ssid, self.password)
|
||||
self.station_profile.set_number_template("00")
|
||||
self.station_profile.set_command_flag("add_sta", "create_admin_down", 1)
|
||||
@@ -113,18 +109,21 @@ class ConnectionTest(LFCliBase):
|
||||
self.station_profile.create(radio=self.radio, sta_names_=self.station_list, debug=self.debug)
|
||||
self.local_realm.wait_until_ports_appear(sta_list=self.station_list)
|
||||
self.update(status="build complete")
|
||||
print("Test Build done")
|
||||
self.test_update.send_update({"test_status": '4', "data": 'None', "data": [], "label": "Client Connectivity Time"})
|
||||
try:
|
||||
self.status_msg.update('4', {"data": 'Starting...', "data": [], "label": "Client Connectivity Time"})
|
||||
except:
|
||||
pass
|
||||
|
||||
def update(self, status="None"):
|
||||
for i in self.station_list:
|
||||
print(self.json_get("port/1/1/" + i + "/?fields=ip,ap,down"))
|
||||
self.station_data[i.split(".")[2]] = \
|
||||
self.json_get("port/1/1/" + i.split(".")[2] + "/?fields=ip,ap,down,phantom&cx%20time%20(us)")['interface']
|
||||
self.test_update.send_update({"test_status": '5', "data": 'None', "data": [], "label": "Client Connectivity Time"})
|
||||
try:
|
||||
self.status_msg.update('5', {"data": 'None', "data": [], "label": "Client Connectivity Time"})
|
||||
except:
|
||||
pass
|
||||
|
||||
def start(self, print_pass=False, print_fail=False):
|
||||
print("Test is starting")
|
||||
def start(self):
|
||||
self.station_profile.admin_up()
|
||||
associated_map = {}
|
||||
self.ip_map = {}
|
||||
@@ -134,7 +133,7 @@ class ConnectionTest(LFCliBase):
|
||||
for sta_name in self.station_profile.station_names:
|
||||
sta_status = self.json_get("port/1/1/" + str(sta_name).split(".")[2] + "?fields=port,alias,ip,ap",
|
||||
debug_=self.debug)
|
||||
print(sta_status)
|
||||
|
||||
if (sta_status is None or sta_status['interface'] is None) or (sta_status['interface']['ap'] is None):
|
||||
continue
|
||||
if (len(sta_status['interface']['ap']) == 17) and (sta_status['interface']['ap'][-3] == ':'):
|
||||
@@ -147,65 +146,50 @@ class ConnectionTest(LFCliBase):
|
||||
else:
|
||||
time.sleep(1)
|
||||
|
||||
if self.debug:
|
||||
print("sta_list", len(self.station_profile.station_names), self.station_profile.station_names)
|
||||
print("ip_map", len(self.ip_map), self.ip_map)
|
||||
print("associated_map", len(associated_map), associated_map)
|
||||
|
||||
if (len(self.station_profile.station_names) == len(self.ip_map)) and (
|
||||
len(self.station_profile.station_names) == len(associated_map)):
|
||||
self._pass("PASS: All stations associated with IP", print_pass)
|
||||
print("Test Passed")
|
||||
|
||||
#("Test Passed")
|
||||
for sta_name in self.station_profile.station_names:
|
||||
sta_status = self.json_get("port/1/1/" + str(sta_name).split(".")[2] + "?fields=cx%20time%20(us)",
|
||||
debug_=self.debug)
|
||||
print(sta_status)
|
||||
#(sta_status)
|
||||
while sta_status['interface']['cx time (us)'] == 0:
|
||||
sta_status = self.json_get("port/1/1/" + str(sta_name).split(".")[2] + "?fields=cx%20time%20(us)",
|
||||
debug_=self.debug)
|
||||
print(sta_status)
|
||||
# #(sta_status)
|
||||
continue
|
||||
cx_time[sta_name] = sta_status['interface']['cx time (us)']
|
||||
else:
|
||||
self._fail("FAIL: Not all stations able to associate/get IP", print_fail)
|
||||
print("sta_list", self.station_profile.station_names)
|
||||
print("ip_map", self.ip_map)
|
||||
for sta_name in self.ip_map.keys():
|
||||
sta_status = self.json_get("port/1/1/" + str(sta_name).split(".")[2] + "?fields=cx%20time%20(us)",
|
||||
debug_=self.debug)
|
||||
print(sta_status)
|
||||
while sta_status['interface']['cx time (us)'] == 0:
|
||||
sta_status = self.json_get("port/1/1/" + str(sta_name).split(".")[2] + "?fields=cx%20time%20(us)",
|
||||
debug_=self.debug)
|
||||
print(sta_status)
|
||||
# #(sta_status)
|
||||
continue
|
||||
cx_time[sta_name] = sta_status['interface']['cx time (us)']
|
||||
print("associated_map", associated_map)
|
||||
print("Test Failed")
|
||||
print(self.ip_map)
|
||||
print(associated_map)
|
||||
print("cx time:", cx_time)
|
||||
self.test_result_data = []
|
||||
self.keys = ["Client Name", "BSSID", "Channel", "Connection Time (ms)", "DHCP (ms)", "IPv4 Address", "MAC Address", "Mode", "Result"]
|
||||
for sta_name in self.station_profile.station_names:
|
||||
sta_status = self.json_get(
|
||||
"port/1/1/" + str(sta_name).split(".")[2] + "?fields=alias,ap,channel,cx%20time%20(us),ip,mac,mode,dhcp%20(ms)",
|
||||
debug_=self.debug)
|
||||
print("ironman")
|
||||
print(sta_status['interface'])
|
||||
self.test_result_data.append(sta_status['interface'])
|
||||
print(self.test_result_data)
|
||||
|
||||
offset = 0
|
||||
self.chart_data = {}
|
||||
for data in self.test_result_data:
|
||||
if (data["cx time (us)"]/1000 <= self.pass_criteria) and (data["cx time (us)"]/1000 > 0):
|
||||
self.chart_data[data['alias']] = data["cx time (us)"]/1000
|
||||
if (int(data["cx time (us)"])/1000 <= self.pass_criteria) and (int(data["cx time (us)"])/1000 > 0):
|
||||
self.chart_data[data['alias']] = float(data["cx time (us)"])/1000
|
||||
data['Result'] = "PASS"
|
||||
else:
|
||||
self.chart_data[data['alias']] = data["cx time (us)"] / 1000
|
||||
self.chart_data[data['alias']] = float(data["cx time (us)"]) / 1000
|
||||
offset +=1
|
||||
data['Result'] = "FAIL"
|
||||
data["cx time (us)"] = str(data["cx time (us)"]/1000)+" / "+str(self.pass_criteria)+"ms"
|
||||
data["cx time (us)"] = str(float(data["cx time (us)"])/1000)+" / "+str(self.pass_criteria)+"ms"
|
||||
|
||||
objective = 'The Client Connectivity Test is designed to test the Performance of the Access Point. It will tell the Average Connection time that station takes to connect to Wifi Access Point. It will tell you Pass/Fail Criteria and detailed Report for Client Connection'
|
||||
|
||||
@@ -223,26 +207,32 @@ class ConnectionTest(LFCliBase):
|
||||
chart_params={"chart_head": "Client Connection Time", "xlabel": "Clients", "ylabel": "Connection Time"})
|
||||
self.html.write(self.html_data.report)
|
||||
self.html.close()
|
||||
options = {
|
||||
"enable-local-file-access": None
|
||||
}
|
||||
pdfkit.from_file(self.reports_path + self.test_name + "_" + self.session_id + ".html",
|
||||
self.reports_path + self.test_name + "_" + self.session_id + '_report.pdf', options=options)
|
||||
|
||||
self.test_update.send_update({"test_status": '6', "data": 'None', "data": [], "label": "Client Connectivity Time"})
|
||||
try:
|
||||
self.status_msg.update('6', {"data": 'None', "data": [], "label": "Client Connectivity Time"})
|
||||
except:
|
||||
pass
|
||||
|
||||
def stop(self):
|
||||
print("Stopping Test")
|
||||
self.station_profile.admin_down()
|
||||
LFUtils.wait_until_ports_admin_down(port_list=self.station_profile.station_names)
|
||||
self.test_update.send_update({"test_status": '7', "data": 'None', "data": [], "label": "Client Connectivity Time"})
|
||||
|
||||
try:
|
||||
self.status_msg.update('7', {"data": 'None', "data": [], "label": "Client Connectivity Time"})
|
||||
except:
|
||||
pass
|
||||
def postcleanup(self):
|
||||
self.station_profile.cleanup()
|
||||
LFUtils.wait_until_ports_disappear(base_url=self.lfclient_url,
|
||||
port_list=self.station_profile.station_names,
|
||||
debug=self.debug)
|
||||
print("Test Completed")
|
||||
self.test_update.send_update({"test_status": '8', "data": 'None', "data": [], "label": "Client Connectivity Time"})
|
||||
|
||||
self.station_profile.cleanup(delay=1)
|
||||
try:
|
||||
self.status_msg.update('8', {"data": 'None', "data": [], "label": "Client Connectivity Time"})
|
||||
except:
|
||||
pass
|
||||
|
||||
def main():
|
||||
# This has --mgr, --mgr_port and --debug
|
||||
parser = LFCliBase.create_bare_argparse(prog="connection_test.py", formatter_class=argparse.RawTextHelpFormatter,
|
||||
epilog="About This Script")
|
||||
|
||||
@@ -251,27 +241,36 @@ def main():
|
||||
parser.add_argument('--passwd', help='--passwd of dut', default="[BLANK]")
|
||||
parser.add_argument('--radio', help='--radio to use on LANforge', default="wiphy1")
|
||||
parser.add_argument('--security', help='--security of dut', default="open")
|
||||
parser.add_argument('--session_id', help='--session_id is for websocket', default="local")
|
||||
parser.add_argument('--session_id', help='--session_id is for websocket', default=getSessionID())
|
||||
parser.add_argument('--test_name', help='--test_name is for webconsole reports', default="Client Connectivity Test")
|
||||
parser.add_argument('--num_clients', type=int, help='--num_sta is number of stations you want to create', default=2)
|
||||
parser.add_argument('--pass_criteria', type=int, help='--pass_criteria is pass criteria for connection Time', default=50)
|
||||
parser.add_argument('--pass_criteria', type=int, help='--pass_criteria is pass criteria for connection Time', default=300)
|
||||
args = parser.parse_args()
|
||||
# args.session_id = "local";
|
||||
print(args)
|
||||
update = RuntimeUpdates(args.session_id, {"test_status": '0', "data": 'None', "data": [], "label": "Client Connectivity Time"})
|
||||
|
||||
# Start Test
|
||||
obj = ConnectionTest(lfclient_host="192.168.200.12", lfclient_port=args.mgr_port,
|
||||
obj = ConnectionTest(lfclient_host=args.mgr, lfclient_port=args.mgr_port,
|
||||
session_id=args.session_id, test_name=args.test_name,
|
||||
dut_ssid=args.ssid, dut_passwd=args.passwd, dut_security=args.security,
|
||||
num_sta=args.num_clients, radio=args.radio, pass_criteria=args.pass_criteria, _test_update=update)
|
||||
num_sta=args.num_clients, radio=args.radio, pass_criteria=args.pass_criteria)
|
||||
obj.precleanup()
|
||||
obj.build()
|
||||
obj.start()
|
||||
obj.stop()
|
||||
obj.postcleanup()
|
||||
|
||||
print(obj.chart_data)
|
||||
update.send_update({"test_status": '10', "data": obj.chart_data, "label": ["Client Names","Client Connectivity Time (ms)"], "result": obj.pass_fail})
|
||||
# #(obj.chart_data)
|
||||
try:
|
||||
obj.status_msg.update('10', {"data": 'done...', "data": [], "label": "Client Connectivity Time"})
|
||||
except:
|
||||
pass
|
||||
for i in obj.status_msg.read()['messages']:
|
||||
print(i)
|
||||
def getSessionID():
|
||||
x = datetime.datetime.now()
|
||||
id = x.strftime("%x").replace("/","_")+"_"+x.strftime("%x") + "_" + x.strftime("%X").split(":")[0] + "_" + x.strftime("%X").split(":")[1] + "_" + x.strftime("%X").split(":")[2]+str(x).split(".")[1]
|
||||
id = str(id).replace("/", "_").split("P")[0].replace(" ","")
|
||||
return id
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
97
py-scripts/create_bond.py
Executable file
97
py-scripts/create_bond.py
Executable file
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""create_bond.py Script to create a bond
|
||||
|
||||
This script can be used to create a bond, only one can be created at a time. Network devices must be specified
|
||||
as a list of comma-separated items with no spaces.
|
||||
|
||||
Use './create_bond.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
|
||||
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'))
|
||||
import LANforge
|
||||
from LANforge.lfcli_base import LFCliBase
|
||||
from LANforge import LFUtils
|
||||
from realm import Realm
|
||||
import time
|
||||
import pprint
|
||||
|
||||
|
||||
class CreateBond(LFCliBase):
|
||||
def __init__(self, _network_dev_list=None,
|
||||
_host=None,
|
||||
_port=None,
|
||||
_shelf=1,
|
||||
_resource=1,
|
||||
_debug_on=False):
|
||||
super().__init__(_host, _port)
|
||||
self.host = _host
|
||||
self.shelf = _shelf
|
||||
self.resource = _resource
|
||||
self.timeout = 120
|
||||
self.debug = _debug_on
|
||||
self.network_dev_list = _network_dev_list
|
||||
|
||||
def build(self):
|
||||
data = {
|
||||
'shelf': self.shelf,
|
||||
'resource': self.resource,
|
||||
'port': 'bond0000',
|
||||
'network_devs': self.network_dev_list
|
||||
}
|
||||
self.json_post("cli-json/add_bond", data)
|
||||
time.sleep(3)
|
||||
bond_set_port = {
|
||||
"shelf": self.shelf,
|
||||
"resource": self.resource,
|
||||
"port": "bond0000",
|
||||
"current_flags": 0x80000000,
|
||||
"interest": 0x4000 # (0x2 + 0x4000 + 0x800000) # current, dhcp, down
|
||||
}
|
||||
self.json_post("cli-json/set_port", bond_set_port)
|
||||
|
||||
|
||||
def main():
|
||||
parser = LFCliBase.create_basic_argparse(
|
||||
prog='create_bond.py',
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
epilog='''\
|
||||
Create bonds
|
||||
''',
|
||||
|
||||
description='''\
|
||||
create_bond.py
|
||||
--------------------
|
||||
Command example:
|
||||
./create_bond.py
|
||||
--network_dev_list eth0,eth1
|
||||
--debug
|
||||
''')
|
||||
|
||||
required = parser.add_argument_group('required arguments')
|
||||
required.add_argument('--network_dev_list', help='list of network devices in the bond, must be comma separated '
|
||||
'with no spaces', required=True)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
create_bond = CreateBond(_host=args.mgr,
|
||||
_port=args.mgr_port,
|
||||
_network_dev_list=args.network_dev_list,
|
||||
_debug_on=args.debug
|
||||
)
|
||||
create_bond.build()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -136,6 +136,7 @@ Command example:
|
||||
target_device=args.target_device)
|
||||
|
||||
create_bridge.build()
|
||||
print('Created %s bridges' % num_bridge)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
162
py-scripts/create_chamberview.py
Executable file
162
py-scripts/create_chamberview.py
Executable file
@@ -0,0 +1,162 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
Note: To Run this script gui should be opened with
|
||||
|
||||
path: cd LANforgeGUI_5.4.3 (5.4.3 can be changed with GUI version)
|
||||
pwd (Output : /home/lanforge/LANforgeGUI_5.4.3)
|
||||
./lfclient.bash -cli-socket 3990
|
||||
|
||||
Note: Scenario names should be different, for each run of this script.
|
||||
in case of same scenario name scenario will be appended to the same name.
|
||||
|
||||
Note: Script for creating a chamberview scenario.
|
||||
Run this script to set/create a chamber view scenario.
|
||||
ex. on how to run this script:
|
||||
|
||||
create_chamberview.py -m "localhost" -o "8080" -cs "scenario_name"
|
||||
--line "Resource=1.1 Profile=STA-AC Amount=1 Uses-1=wiphy0 Uses-2=AUTO Freq=-1
|
||||
DUT=Test DUT_Radio=Radio-1 Traffic=http VLAN="
|
||||
--line "Resource=1.1 Profile=upstream Amount=1 Uses-1=eth1 Uses-2=AUTO Freq=-1
|
||||
DUT=Test DUT_Radio=Radio-1 Traffic=http VLAN="
|
||||
|
||||
Output:
|
||||
You should see build scenario with the given arguments at the end of this script.
|
||||
To verify this:
|
||||
open Chamber View -> Manage scenario
|
||||
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import argparse
|
||||
import time
|
||||
import re
|
||||
|
||||
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'))
|
||||
|
||||
from cv_commands import chamberview as cv
|
||||
|
||||
def main():
|
||||
global Resource, Amount, DUT, DUT_Radio, Profile, Uses1, Uses2, Traffic, Freq, VLAN
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="""
|
||||
For Two line scenario use --line twice as shown in example, for multi line scenario
|
||||
use --line argument to create multiple lines
|
||||
\n
|
||||
create_chamberview.py -m "localhost" -o "8080" -cs "scenario_name"
|
||||
--line "Resource=1.1 Profile=STA-AC Amount=1 Uses-1=wiphy0 Uses-2=AUTO Freq=-1
|
||||
DUT=Test DUT_Radio=Radio-1 Traffic=http VLAN="
|
||||
--line "Resource=1.1 Profile=upstream Amount=1 Uses-1=eth1 Uses-2=AUTO Freq=-1
|
||||
DUT=Test DUT_Radio=Radio-1 Traffic=http VLAN="
|
||||
""")
|
||||
parser.add_argument("-m", "--lfmgr", type=str,
|
||||
help="address of the LANforge GUI machine (localhost is default)")
|
||||
parser.add_argument("-o", "--port", type=int,
|
||||
help="IP Port the LANforge GUI is listening on (8080 is default)")
|
||||
parser.add_argument("-cs", "--create_scenario", "--create_lf_scenario", type=str,
|
||||
help="name of scenario to be created")
|
||||
parser.add_argument("-l", "--line", action='append', nargs='+', type=str, required=True,
|
||||
help="line number")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.lfmgr is not None:
|
||||
lfjson_host = args.lfmgr
|
||||
if args.port is not None:
|
||||
lfjson_port = args.port
|
||||
|
||||
createCV = cv(lfjson_host, lfjson_port); # Create a object
|
||||
scenario_name = args.create_scenario
|
||||
line = args.line
|
||||
|
||||
Resource = "1.1"
|
||||
Profile = "STA-AC"
|
||||
Amount = "1"
|
||||
DUT = "DUT"
|
||||
DUT_Radio = "Radio-1"
|
||||
Uses1 = "wiphy0"
|
||||
Uses2 = "AUTO"
|
||||
Traffic = "http"
|
||||
Freq = "-1"
|
||||
VLAN = ""
|
||||
|
||||
for i in range(len(line)):
|
||||
if " " in line[i][0]:
|
||||
line[i][0] = (re.split(' ', line[i][0]))
|
||||
elif "," in line[i][0]:
|
||||
line[i][0] = (re.split(',', line[i][0]))
|
||||
print("in second")
|
||||
elif ", " in line[i][0]:
|
||||
line[i][0] = (re.split(',', line[i][0]))
|
||||
print("in third")
|
||||
elif " ," in line[i][0]:
|
||||
line[i][0] = (re.split(',', line[i][0]))
|
||||
print("in forth")
|
||||
else:
|
||||
print("Wrong arguments entered !")
|
||||
exit(1)
|
||||
|
||||
for j in range(len(line[i][0])):
|
||||
line[i][0][j] = line[i][0][j].split("=")
|
||||
for k in range(len(line[i][0][j])):
|
||||
name = line[i][0][j][k]
|
||||
if str(name) == "Resource" or str(name) == "Res" or str(name) == "R":
|
||||
Resource = line[i][0][j][k + 1]
|
||||
elif str(name) == "Profile" or str(name) == "Prof" or str(name) == "P":
|
||||
Profile = line[i][0][j][k + 1]
|
||||
elif str(name) == "Amount" or str(name) == "Sta" or str(name) == "A":
|
||||
Amount = line[i][0][j][k + 1]
|
||||
elif str(name) == "Uses-1" or str(name) == "U1" or str(name) == "U-1":
|
||||
Uses1 = line[i][0][j][k + 1]
|
||||
elif str(name) == "Uses-2" or str(name) == "U2" or str(name) == "U-2":
|
||||
Uses2 = line[i][0][j][k + 1]
|
||||
elif str(name) == "Freq" or str(name) == "Freq" or str(name) == "F":
|
||||
Freq = line[i][0][j][k + 1]
|
||||
elif str(name) == "DUT" or str(name) == "dut" or str(name) == "D":
|
||||
DUT = line[i][0][j][k + 1]
|
||||
elif str(name) == "DUT_Radio" or str(name) == "dr" or str(name) == "DR":
|
||||
DUT_Radio = line[i][0][j][k + 1]
|
||||
elif str(name) == "Traffic" or str(name) == "Traf" or str(name) == "T":
|
||||
Traffic = line[i][0][j][k + 1]
|
||||
elif str(name) == "VLAN" or str(name) == "Vlan" or str(name) == "V":
|
||||
VLAN = line[i][0][j][k + 1]
|
||||
else:
|
||||
continue
|
||||
|
||||
createCV.manage_cv_scenario(scenario_name,
|
||||
Resource,
|
||||
Profile,
|
||||
Amount,
|
||||
DUT,
|
||||
DUT_Radio,
|
||||
Uses1,
|
||||
Uses2,
|
||||
Traffic,
|
||||
Freq,
|
||||
VLAN
|
||||
); # To manage scenario
|
||||
|
||||
|
||||
createCV.sync_cv() #chamberview sync
|
||||
time.sleep(2)
|
||||
createCV.apply_cv_scenario(scenario_name) #Apply scenario
|
||||
time.sleep(2)
|
||||
createCV.sync_cv()
|
||||
time.sleep(2)
|
||||
createCV.apply_cv_scenario(scenario_name) # Apply scenario
|
||||
|
||||
time.sleep(2)
|
||||
createCV.build_cv_scenario() #build scenario
|
||||
print("End")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,11 +1,9 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
This script will create a variable 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.
|
||||
This script will create a variable number of layer3 stations each with their own set of cross-connects and endpoints.
|
||||
|
||||
Use './test_ipv4_variable_time.py --help' to see command line usage and options
|
||||
Use './create_l3.py --help' to see command line usage and options
|
||||
"""
|
||||
|
||||
import sys
|
||||
@@ -26,13 +24,14 @@ import time
|
||||
import datetime
|
||||
from realm import TestGroupProfile
|
||||
|
||||
|
||||
class CreateL3(Realm):
|
||||
def __init__(self,
|
||||
ssid, security, password, sta_list, name_prefix, upstream, radio,
|
||||
host="localhost", port=8080, mode = 0, ap=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", use_ht160=False,
|
||||
number_template="00000", use_ht160=False,
|
||||
_debug_on=False,
|
||||
_exit_on_error=False,
|
||||
_exit_on_fail=False):
|
||||
@@ -45,8 +44,8 @@ class CreateL3(Realm):
|
||||
self.security = security
|
||||
self.password = password
|
||||
self.radio = radio
|
||||
self.mode= mode
|
||||
self.ap=ap
|
||||
self.mode = mode
|
||||
self.ap = ap
|
||||
self.number_template = number_template
|
||||
self.debug = _debug_on
|
||||
self.name_prefix = name_prefix
|
||||
@@ -63,9 +62,8 @@ class CreateL3(Realm):
|
||||
self.station_profile.mode = 9
|
||||
self.station_profile.mode = mode
|
||||
if self.ap is not None:
|
||||
self.station_profile.set_command_param("add_sta", "ap",self.ap)
|
||||
#self.station_list= LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=2, padding_number_=10000, radio='wiphy0') #Make radio a user defined variable from terminal.
|
||||
|
||||
self.station_profile.set_command_param("add_sta", "ap", self.ap)
|
||||
# self.station_list= LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=2, padding_number_=10000, radio='wiphy0') #Make radio a user defined variable from terminal.
|
||||
|
||||
self.cx_profile.host = self.host
|
||||
self.cx_profile.port = self.port
|
||||
@@ -75,54 +73,16 @@ class CreateL3(Realm):
|
||||
self.cx_profile.side_b_min_bps = side_b_min_rate
|
||||
self.cx_profile.side_b_max_bps = side_b_max_rate
|
||||
|
||||
|
||||
def __get_rx_values(self):
|
||||
cx_list = self.json_get("endp?fields=name,rx+bytes", debug_=self.debug)
|
||||
if self.debug:
|
||||
print(self.cx_profile.created_cx.values())
|
||||
print("==============\n", cx_list, "\n==============")
|
||||
cx_rx_map = {}
|
||||
for cx_name in cx_list['endpoint']:
|
||||
if cx_name != 'uri' and cx_name != 'handler':
|
||||
for item, value in cx_name.items():
|
||||
for value_name, value_rx in value.items():
|
||||
if value_name == 'rx bytes' and item in self.cx_profile.created_cx.values():
|
||||
cx_rx_map[item] = value_rx
|
||||
return cx_rx_map
|
||||
|
||||
def start(self, print_pass=False, print_fail=False):
|
||||
self.station_profile.admin_up()
|
||||
temp_stas = self.station_profile.station_names.copy()
|
||||
|
||||
if self.wait_for_ip(temp_stas):
|
||||
self._pass("All stations got IPs")
|
||||
else:
|
||||
self._fail("Stations failed to get IPs")
|
||||
self.exit_fail()
|
||||
self.cx_profile.start_cx()
|
||||
|
||||
|
||||
def stop(self):
|
||||
self.cx_profile.stop_cx()
|
||||
self.station_profile.admin_down()
|
||||
|
||||
def pre_cleanup(self):
|
||||
self.cx_profile.cleanup_prefix()
|
||||
for sta in self.sta_list:
|
||||
self.rm_port(sta, check_exists=True)
|
||||
|
||||
def cleanup(self):
|
||||
self.cx_profile.cleanup()
|
||||
self.station_profile.cleanup()
|
||||
LFUtils.wait_until_ports_disappear(base_url=self.lfclient_url,
|
||||
port_list=self.station_profile.station_names,
|
||||
debug=self.debug)
|
||||
|
||||
def build(self):
|
||||
|
||||
self.station_profile.use_security(self.security,
|
||||
self.ssid,
|
||||
self.password)
|
||||
self.ssid,
|
||||
self.password)
|
||||
self.station_profile.set_number_template(self.number_template)
|
||||
print("Creating stations")
|
||||
self.station_profile.set_command_flag("add_sta", "create_admin_down", 1)
|
||||
@@ -132,11 +92,12 @@ class CreateL3(Realm):
|
||||
sta_names_=self.sta_list,
|
||||
debug=self.debug)
|
||||
self.cx_profile.create(endp_type="lf_udp",
|
||||
side_a=self.station_profile.station_names,
|
||||
side_b=self.upstream,
|
||||
sleep_time=0)
|
||||
side_a=self.station_profile.station_names,
|
||||
side_b=self.upstream,
|
||||
sleep_time=0)
|
||||
self._pass("PASS: Station build finished")
|
||||
|
||||
|
||||
def main():
|
||||
parser = LFCliBase.create_basic_argparse(
|
||||
prog='create_l3.py',
|
||||
@@ -175,55 +136,59 @@ python3 ./test_ipv4_variable_time.py
|
||||
--a_min 1000
|
||||
--b_min 1000
|
||||
--ap "00:0e:8e:78:e1:76"
|
||||
--number_template 0000
|
||||
--debug
|
||||
''')
|
||||
|
||||
required_args=None
|
||||
required_args = None
|
||||
for group in parser._action_groups:
|
||||
if group.title == "required arguments":
|
||||
required_args=group
|
||||
required_args = group
|
||||
break;
|
||||
if required_args is not None:
|
||||
required_args.add_argument('--a_min', help='--a_min bps rate minimum for side_a', default=256000)
|
||||
required_args.add_argument('--b_min', help='--b_min bps rate minimum for side_b', default=256000)
|
||||
|
||||
optional_args=None
|
||||
optional_args = None
|
||||
for group in parser._action_groups:
|
||||
if group.title == "optional arguments":
|
||||
optional_args=group
|
||||
optional_args = group
|
||||
break;
|
||||
if optional_args is not None:
|
||||
optional_args.add_argument('--mode',help='Used to force mode of stations')
|
||||
optional_args.add_argument('--ap',help='Used to force a connection to a particular AP')
|
||||
optional_args.add_argument('--mode', help='Used to force mode of stations')
|
||||
optional_args.add_argument('--ap', help='Used to force a connection to a particular AP')
|
||||
optional_args.add_argument('--number_template', help='Start the station numbering with a particular number. Default is 0000', default=0000)
|
||||
args = parser.parse_args()
|
||||
|
||||
num_sta = 2
|
||||
if (args.num_stations is not None) and (int(args.num_stations) > 0):
|
||||
num_sta = int(args.num_stations)
|
||||
|
||||
station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=num_sta-1, padding_number_=10000, radio=args.radio)
|
||||
station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=num_sta - 1, padding_number_=10000,
|
||||
radio=args.radio)
|
||||
ip_var_test = CreateL3(host=args.mgr,
|
||||
port=args.mgr_port,
|
||||
number_template="0000",
|
||||
sta_list=station_list,
|
||||
name_prefix="VT",
|
||||
upstream=args.upstream_port,
|
||||
ssid=args.ssid,
|
||||
password=args.passwd,
|
||||
radio=args.radio,
|
||||
security=args.security,
|
||||
use_ht160=False,
|
||||
side_a_min_rate=args.a_min,
|
||||
side_b_min_rate=args.b_min,
|
||||
mode=args.mode,
|
||||
ap=args.ap,
|
||||
_debug_on=args.debug)
|
||||
port=args.mgr_port,
|
||||
number_template=str(args.number_template),
|
||||
sta_list=station_list,
|
||||
name_prefix="VT",
|
||||
upstream=args.upstream_port,
|
||||
ssid=args.ssid,
|
||||
password=args.passwd,
|
||||
radio=args.radio,
|
||||
security=args.security,
|
||||
use_ht160=False,
|
||||
side_a_min_rate=args.a_min,
|
||||
side_b_min_rate=args.b_min,
|
||||
mode=args.mode,
|
||||
ap=args.ap,
|
||||
_debug_on=args.debug)
|
||||
|
||||
ip_var_test.pre_cleanup()
|
||||
ip_var_test.build()
|
||||
if not ip_var_test.passes():
|
||||
print(ip_var_test.get_fail_message())
|
||||
ip_var_test.exit_fail()
|
||||
print('Creates %s stations and connections' % num_sta)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
This script will create a variable 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 './test_ipv4_variable_time.py --help' to see command line usage and options
|
||||
"""
|
||||
This script will create a variable number of layer4 stations each with their own set of cross-connects and endpoints.
|
||||
|
||||
Use './create_l4.py --help' to see command line usage and options
|
||||
"""
|
||||
import sys
|
||||
import os
|
||||
|
||||
@@ -75,38 +73,6 @@ class CreateL4(Realm):
|
||||
self.cx_profile.side_b_min_bps = side_b_min_rate
|
||||
self.cx_profile.side_b_max_bps = side_b_max_rate
|
||||
|
||||
|
||||
def __get_rx_values(self):
|
||||
cx_list = self.json_get("endp?fields=name,rx+bytes", debug_=self.debug)
|
||||
if self.debug:
|
||||
print(self.cx_profile.created_cx.values())
|
||||
print("==============\n", cx_list, "\n==============")
|
||||
cx_rx_map = {}
|
||||
for cx_name in cx_list['endpoint']:
|
||||
if cx_name != 'uri' and cx_name != 'handler':
|
||||
for item, value in cx_name.items():
|
||||
for value_name, value_rx in value.items():
|
||||
if value_name == 'rx bytes' and item in self.cx_profile.created_cx.values():
|
||||
cx_rx_map[item] = value_rx
|
||||
return cx_rx_map
|
||||
|
||||
def start(self, print_pass=False, print_fail=False):
|
||||
self.station_profile.admin_up()
|
||||
temp_stas = self.station_profile.station_names.copy()
|
||||
|
||||
if self.wait_for_ip(temp_stas):
|
||||
self._pass("All stations got IPs")
|
||||
else:
|
||||
self._fail("Stations failed to get IPs")
|
||||
self.exit_fail()
|
||||
self.cx_profile.start_cx()
|
||||
|
||||
|
||||
def stop(self):
|
||||
self.cx_profile.stop_cx()
|
||||
self.station_profile.admin_down()
|
||||
|
||||
|
||||
def cleanup(self):
|
||||
self.cx_profile.cleanup()
|
||||
self.station_profile.cleanup()
|
||||
@@ -136,11 +102,11 @@ def main():
|
||||
''',
|
||||
|
||||
description='''\
|
||||
test_ipv4_variable_time.py:
|
||||
layer4.py:
|
||||
--------------------
|
||||
Generic command layout:
|
||||
|
||||
python3 ./test_ipv4_variable_time.py
|
||||
python3 ./layer4.py
|
||||
--upstream_port eth1
|
||||
--radio wiphy0
|
||||
--num_stations 32
|
||||
@@ -215,6 +181,8 @@ python3 ./test_ipv4_variable_time.py
|
||||
print(ip_var_test.get_fail_message())
|
||||
ip_var_test.exit_fail()
|
||||
|
||||
print('Created %s stations and connections' % num_sta)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -1,325 +1,105 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
|
||||
if sys.version_info[0] != 3:
|
||||
print("This script requires Python 3")
|
||||
exit(1)
|
||||
|
||||
if 'py-json' not in sys.path:
|
||||
sys.path.append('../py-json')
|
||||
|
||||
# import argparse
|
||||
from LANforge.lfcli_base import LFCliBase
|
||||
from LANforge.LFUtils import *
|
||||
from LANforge import LFUtils
|
||||
from LANforge import add_file_endp
|
||||
from LANforge.add_file_endp import *
|
||||
import argparse
|
||||
from realm import Realm
|
||||
import time
|
||||
import datetime
|
||||
import pprint
|
||||
|
||||
|
||||
class FileIOTest(Realm):
|
||||
def __init__(self, host, port, ssid, security, password,
|
||||
number_template="00000",
|
||||
class CreateMacVlan(Realm):
|
||||
def __init__(self, host, port,
|
||||
radio="wiphy0",
|
||||
test_duration="5m",
|
||||
upstream_port="eth1",
|
||||
num_ports=1,
|
||||
server_mount="10.40.0.1:/var/tmp/test",
|
||||
macvlan_parent=None,
|
||||
first_mvlan_ip=None,
|
||||
netmask=None,
|
||||
gateway=None,
|
||||
dhcp=True,
|
||||
use_macvlans=False,
|
||||
use_test_groups=False,
|
||||
write_only_test_group=None,
|
||||
read_only_test_group=None,
|
||||
port_list=[],
|
||||
ip_list=None,
|
||||
connections_per_port=1,
|
||||
mode="both",
|
||||
update_group_args={"name": None, "action": None, "cxs": None},
|
||||
_debug_on=False,
|
||||
_exit_on_error=False,
|
||||
_exit_on_fail=False):
|
||||
super().__init__(host, port)
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.radio = radio
|
||||
self.upstream_port = upstream_port
|
||||
self.ssid = ssid
|
||||
self.security = security
|
||||
self.password = password
|
||||
self.number_template = number_template
|
||||
self.test_duration = test_duration
|
||||
self.port_list = []
|
||||
self.connections_per_port = connections_per_port
|
||||
self.use_macvlans = use_macvlans
|
||||
self.mode = mode.lower()
|
||||
self.ip_list = ip_list
|
||||
self.netmask = netmask
|
||||
self.gateway = gateway
|
||||
self.dhcp = dhcp
|
||||
if self.use_macvlans:
|
||||
if macvlan_parent is not None:
|
||||
self.macvlan_parent = macvlan_parent
|
||||
self.port_list = port_list
|
||||
else:
|
||||
if macvlan_parent is not None:
|
||||
self.macvlan_parent = macvlan_parent
|
||||
self.port_list = port_list
|
||||
|
||||
self.use_test_groups = use_test_groups
|
||||
if self.use_test_groups:
|
||||
if self.mode == "write":
|
||||
if write_only_test_group is not None:
|
||||
self.write_only_test_group = write_only_test_group
|
||||
else:
|
||||
raise ValueError("--write_only_test_group must be used to set test group name")
|
||||
if self.mode == "read":
|
||||
if read_only_test_group is not None:
|
||||
self.read_only_test_group = read_only_test_group
|
||||
else:
|
||||
raise ValueError("--read_only_test_group must be used to set test group name")
|
||||
if self.mode == "both":
|
||||
if write_only_test_group is not None and read_only_test_group is not None:
|
||||
self.write_only_test_group = write_only_test_group
|
||||
self.read_only_test_group = read_only_test_group
|
||||
else:
|
||||
raise ValueError("--write_only_test_group and --read_only_test_group "
|
||||
"must be used to set test group names")
|
||||
|
||||
|
||||
|
||||
self.wo_profile = self.new_fio_endp_profile()
|
||||
self.mvlan_profile = self.new_mvlan_profile()
|
||||
|
||||
if not self.use_macvlans and len(self.port_list) > 0:
|
||||
self.station_profile = self.new_station_profile()
|
||||
self.station_profile.lfclient_url = self.lfclient_url
|
||||
self.station_profile.ssid = self.ssid
|
||||
self.station_profile.ssid_pass = self.password
|
||||
self.station_profile.security = self.security
|
||||
self.station_profile.number_template_ = self.number_template
|
||||
self.station_profile.mode = 0
|
||||
|
||||
self.wo_profile.server_mount = server_mount
|
||||
self.wo_profile.num_connections_per_port = connections_per_port
|
||||
|
||||
self.ro_profile = self.wo_profile.create_ro_profile()
|
||||
|
||||
if self.use_macvlans:
|
||||
self.mvlan_profile.num_macvlans = int(num_ports)
|
||||
self.mvlan_profile.desired_macvlans = self.port_list
|
||||
self.mvlan_profile.macvlan_parent = self.macvlan_parent
|
||||
self.mvlan_profile.dhcp = dhcp
|
||||
self.mvlan_profile.netmask = netmask
|
||||
self.mvlan_profile.first_ip_addr = first_mvlan_ip
|
||||
self.mvlan_profile.gateway = gateway
|
||||
self.mvlan_profile.num_macvlans = int(num_ports)
|
||||
self.mvlan_profile.desired_macvlans = self.port_list
|
||||
self.mvlan_profile.macvlan_parent = self.macvlan_parent
|
||||
self.mvlan_profile.dhcp = dhcp
|
||||
self.mvlan_profile.netmask = netmask
|
||||
self.mvlan_profile.first_ip_addr = first_mvlan_ip
|
||||
self.mvlan_profile.gateway = gateway
|
||||
|
||||
self.created_ports = []
|
||||
if self.use_test_groups:
|
||||
if self.mode is not None:
|
||||
if self.mode == "write":
|
||||
self.wo_tg_profile = self.new_test_group_profile()
|
||||
self.wo_tg_profile.group_name = self.write_only_test_group
|
||||
elif self.mode == "read":
|
||||
self.ro_tg_profile = self.new_test_group_profile()
|
||||
self.ro_tg_profile.group_name = self.read_only_test_group
|
||||
elif self.mode == "both":
|
||||
self.wo_tg_profile = self.new_test_group_profile()
|
||||
self.ro_tg_profile = self.new_test_group_profile()
|
||||
self.wo_tg_profile.group_name = self.write_only_test_group
|
||||
self.ro_tg_profile.group_name = self.read_only_test_group
|
||||
else:
|
||||
raise ValueError("Unknown mode given ", self.mode)
|
||||
else:
|
||||
raise ValueError("Mode ( read, write, or both ) must be specified")
|
||||
|
||||
if update_group_args is not None and update_group_args['name'] is not None:
|
||||
temp_tg = self.new_test_group_profile()
|
||||
temp_cxs = update_group_args['cxs'].split(',')
|
||||
if update_group_args['action'] == "add":
|
||||
temp_tg.group_name = update_group_args['name']
|
||||
if not temp_tg.check_group_exists():
|
||||
temp_tg.create_group()
|
||||
for cx in temp_cxs:
|
||||
if "CX_" not in cx:
|
||||
cx = "CX_" + cx
|
||||
temp_tg.add_cx(cx)
|
||||
if update_group_args['action'] == "del":
|
||||
temp_tg.group_name = update_group_args['name']
|
||||
if temp_tg.check_group_exists():
|
||||
for cx in temp_cxs:
|
||||
temp_tg.rm_cx(cx)
|
||||
time.sleep(5)
|
||||
|
||||
self.wo_tg_exists = False
|
||||
self.ro_tg_exists = False
|
||||
self.wo_tg_cx_exists = False
|
||||
self.ro_tg_cx_exists = False
|
||||
print("Checking for pre-existing test groups and cxs")
|
||||
if self.use_test_groups:
|
||||
if self.mode == "write":
|
||||
if self.wo_tg_profile.check_group_exists():
|
||||
self.wo_tg_exists = True
|
||||
if len(self.wo_tg_profile.list_cxs()) > 0:
|
||||
self.wo_tg_cx_exists = True
|
||||
elif self.mode == "read":
|
||||
if self.ro_tg_profile.check_group_exists():
|
||||
self.ro_tg_exists = True
|
||||
if len(self.ro_tg_profile.list_cxs()) > 0:
|
||||
self.ro_tg_cx_exists = True
|
||||
elif self.mode == "both":
|
||||
if self.wo_tg_profile.check_group_exists():
|
||||
self.wo_tg_exists = True
|
||||
if len(self.wo_tg_profile.list_cxs()) > 0:
|
||||
self.wo_tg_cx_exists = True
|
||||
if self.ro_tg_profile.check_group_exists():
|
||||
self.ro_tg_exists = True
|
||||
if len(self.ro_tg_profile.list_cxs()) > 0:
|
||||
self.ro_tg_cx_exists = True
|
||||
|
||||
def __compare_vals(self, val_list):
|
||||
passes = 0
|
||||
expected_passes = 0
|
||||
# print(val_list)
|
||||
for item in val_list:
|
||||
expected_passes += 1
|
||||
# print(item)
|
||||
if item[0] == 'r':
|
||||
# print("TEST", item,
|
||||
# val_list[item]['read-bps'],
|
||||
# self.ro_profile.min_read_rate_bps,
|
||||
# val_list[item]['read-bps'] > self.ro_profile.min_read_rate_bps)
|
||||
|
||||
if val_list[item]['read-bps'] > self.wo_profile.min_read_rate_bps:
|
||||
passes += 1
|
||||
else:
|
||||
# print("TEST", item,
|
||||
# val_list[item]['write-bps'],
|
||||
# self.wo_profile.min_write_rate_bps,
|
||||
# val_list[item]['write-bps'] > self.wo_profile.min_write_rate_bps)
|
||||
|
||||
if val_list[item]['write-bps'] > self.wo_profile.min_write_rate_bps:
|
||||
passes += 1
|
||||
if passes == expected_passes:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
|
||||
def __get_values(self):
|
||||
time.sleep(3)
|
||||
if self.mode == "write":
|
||||
cx_list = self.json_get("fileio/%s?fields=write-bps,read-bps" % (
|
||||
','.join(self.wo_profile.created_cx.keys())), debug_=self.debug)
|
||||
elif self.mode == "read":
|
||||
cx_list = self.json_get("fileio/%s?fields=write-bps,read-bps" % (
|
||||
','.join(self.ro_profile.created_cx.keys())), debug_=self.debug)
|
||||
else:
|
||||
cx_list = self.json_get("fileio/%s,%s?fields=write-bps,read-bps" % (
|
||||
','.join(self.wo_profile.created_cx.keys()),
|
||||
','.join(self.ro_profile.created_cx.keys())), debug_=self.debug)
|
||||
# print(cx_list)
|
||||
# print("==============\n", cx_list, "\n==============")
|
||||
cx_map = {}
|
||||
# pprint.pprint(cx_list)
|
||||
if cx_list is not None:
|
||||
cx_list = cx_list['endpoint']
|
||||
for i in cx_list:
|
||||
for item, value in i.items():
|
||||
# print(item, value)
|
||||
cx_map[self.name_to_eid(item)[2]] = {"read-bps": value['read-bps'], "write-bps": value['write-bps']}
|
||||
# print(cx_map)
|
||||
return cx_map
|
||||
|
||||
def build(self):
|
||||
# Build stations
|
||||
if self.use_macvlans:
|
||||
print("Creating MACVLANs")
|
||||
self.mvlan_profile.create(admin_down=False, sleep_time=.5, debug=self.debug)
|
||||
self._pass("PASS: MACVLAN build finished")
|
||||
self.created_ports += self.mvlan_profile.created_macvlans
|
||||
elif not self.use_macvlans and self.ip_list is None:
|
||||
self.station_profile.use_security(self.security, self.ssid, self.password)
|
||||
self.station_profile.set_number_template(self.number_template)
|
||||
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.port_list, debug=self.debug)
|
||||
self._pass("PASS: Station build finished")
|
||||
self.created_ports += self.station_profile.station_names
|
||||
|
||||
if len(self.ip_list) > 0:
|
||||
# print("++++++++++++++++\n", self.ip_list, "++++++++++++++++\n")
|
||||
for num_port in range(len(self.port_list)):
|
||||
if self.ip_list[num_port] != 0:
|
||||
if self.gateway is not None and self.netmask is not None:
|
||||
shelf = self.name_to_eid(self.port_list[num_port])[0]
|
||||
resource = self.name_to_eid(self.port_list[num_port])[1]
|
||||
port = self.name_to_eid(self.port_list[num_port])[2]
|
||||
req_url = "/cli-json/set_port"
|
||||
data = {
|
||||
"shelf": shelf,
|
||||
"resource": resource,
|
||||
"port": port,
|
||||
"ip_addr": self.ip_list[num_port],
|
||||
"netmask": self.netmask,
|
||||
"gateway": self.gateway
|
||||
}
|
||||
self.json_post(req_url, data)
|
||||
self.created_ports.append("%s.%s.%s" % (shelf, resource, port))
|
||||
else:
|
||||
raise ValueError("Netmask and gateway must be specified")
|
||||
|
||||
print("Creating MACVLANs")
|
||||
self.mvlan_profile.create(admin_down=False, sleep_time=.5, debug=self.debug)
|
||||
self._pass("PASS: MACVLAN build finished")
|
||||
self.created_ports += self.mvlan_profile.created_macvlans
|
||||
|
||||
def main():
|
||||
parser = LFCliBase.create_bare_argparse(
|
||||
prog='create_macvlan.py',
|
||||
# formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
epilog='''Creates FileIO endpoints which can be NFS, CIFS or iSCSI endpoints.''',
|
||||
epilog='''Creates MACVLAN endpoints.''',
|
||||
|
||||
description='''\
|
||||
create_macvlan.py:
|
||||
--------------------
|
||||
Generic command layout:
|
||||
./create_macvlan.py --macvlan_parent <port> --num_ports <num ports> --use_macvlans
|
||||
./create_macvlan.py --macvlan_parent <port> --num_ports <num ports>
|
||||
--first_mvlan_ip <first ip in series> --netmask <netmask to use> --gateway <gateway ip addr>
|
||||
|
||||
./create_macvlan.py --macvlan_parent eth2 --num_ports 3 --use_macvlans --first_mvlan_ip 192.168.92.13
|
||||
./create_macvlan.py --macvlan_parent eth2 --num_ports 3 --first_mvlan_ip 192.168.92.13
|
||||
--netmask 255.255.255.0 --gateway 192.168.92.1
|
||||
|
||||
./create_macvlan.py --radio 1.wiphy0 --test_duration 1m --macvlan_parent eth1 --num_ports 3 --use_macvlans
|
||||
--use_ports eth1#0,eth1#1,eth1#2 --connections_per_port 2 --mode write
|
||||
./create_macvlan.py --radio 1.wiphy0 --macvlan_parent eth1 --num_ports 3
|
||||
--use_ports eth1#0,eth1#1,eth1#2 --connections_per_port 2
|
||||
|
||||
./create_macvlan.py --radio 1.wiphy0 --test_duration 1m --macvlan_parent eth1 --num_ports 3 --use_macvlans
|
||||
./create_macvlan.py --radio 1.wiphy0 --macvlan_parent eth1 --num_ports 3
|
||||
--first_mvlan_ip 10.40.3.100 --netmask 255.255.240.0 --gateway 10.40.0.1
|
||||
--use_test_groups --write_only_test_group test_wo --read_only_test_group test_ro
|
||||
--add_to_group test_wo
|
||||
|
||||
./create_macvlan.py --radio 1.wiphy0 --test_duration 1m --macvlan_parent eth1 --num_ports 3 --use_macvlans
|
||||
./create_macvlan.py --radio 1.wiphy0 --macvlan_parent eth1 --num_ports 3
|
||||
--use_ports eth1#0=10.40.3.103,eth1#1,eth1#2 --connections_per_port 2
|
||||
--netmask 255.255.240.0 --gateway 10.40.0.1
|
||||
|
||||
''')
|
||||
parser.add_argument('--num_stations', help='Number of stations to create', default=0)
|
||||
parser.add_argument('--radio', help='radio EID, e.g: 1.wiphy2')
|
||||
parser.add_argument('--ssid', help='SSID for stations to associate to')
|
||||
parser.add_argument('--passwd', '--password', '--key', help='WiFi passphrase/password/key')
|
||||
parser.add_argument('--security', help='security type to use for ssid { wep | wpa | wpa2 | wpa3 | open }')
|
||||
parser.add_argument('-u', '--upstream_port',
|
||||
help='non-station port that generates traffic: <resource>.<port>, e.g: 1.eth1',
|
||||
default='1.eth1')
|
||||
parser.add_argument('--test_duration', help='sets the duration of the test', default="5m")
|
||||
parser.add_argument('--server_mount', help='--server_mount The server to mount, ex: 192.168.100.5/exports/test1',
|
||||
default="10.40.0.1:/var/tmp/test")
|
||||
|
||||
help='non-station port that generates traffic: <resource>.<port>, e.g: 1.eth1',
|
||||
default='1.eth1')
|
||||
parser.add_argument('--macvlan_parent', help='specifies parent port for macvlan creation', default=None)
|
||||
parser.add_argument('--first_port', help='specifies name of first port to be used', default=None)
|
||||
parser.add_argument('--num_ports', help='number of ports to create', default=1)
|
||||
@@ -328,36 +108,13 @@ Generic command layout:
|
||||
parser.add_argument('--use_ports', help='list of comma separated ports to use with ips, \'=\' separates name and ip'
|
||||
'{ port_name1=ip_addr1,port_name1=ip_addr2 }. '
|
||||
'Ports without ips will be left alone', default=None)
|
||||
parser.add_argument('--use_macvlans', help='will create macvlans', action='store_true', default=False)
|
||||
parser.add_argument('--first_mvlan_ip', help='specifies first static ip address to be used or dhcp', default=None)
|
||||
parser.add_argument('--netmask', help='specifies netmask to be used with static ip addresses', default=None)
|
||||
parser.add_argument('--gateway', help='specifies default gateway to be used with static addressing', default=None)
|
||||
parser.add_argument('--use_test_groups', help='will use test groups to start/stop instead of single endps/cxs',
|
||||
action='store_true', default=False)
|
||||
parser.add_argument('--read_only_test_group', help='specifies name to use for read only test group', default=None)
|
||||
parser.add_argument('--write_only_test_group', help='specifies name to use for write only test group', default=None)
|
||||
parser.add_argument('--mode', help='write,read,both', default='both', type=str)
|
||||
tg_group = parser.add_mutually_exclusive_group()
|
||||
tg_group.add_argument('--add_to_group', help='name of test group to add cxs to', default=None)
|
||||
tg_group.add_argument('--del_from_group', help='name of test group to delete cxs from', default=None)
|
||||
parser.add_argument('--cxs', help='list of cxs to add/remove depending on use of --add_to_group or --del_from_group'
|
||||
, default=None)
|
||||
args = parser.parse_args()
|
||||
|
||||
update_group_args = {
|
||||
"name": None,
|
||||
"action": None,
|
||||
"cxs": None
|
||||
}
|
||||
if args.add_to_group is not None and args.cxs is not None:
|
||||
update_group_args['name'] = args.add_to_group
|
||||
update_group_args['action'] = "add"
|
||||
update_group_args['cxs'] = args.cxs
|
||||
elif args.del_from_group is not None and args.cxs is not None:
|
||||
update_group_args['name'] = args.del_from_group
|
||||
update_group_args['action'] = "del"
|
||||
update_group_args['cxs'] = args.cxs
|
||||
|
||||
port_list = []
|
||||
ip_list = []
|
||||
if args.first_port is not None and args.use_ports is not None:
|
||||
@@ -365,17 +122,17 @@ Generic command layout:
|
||||
if (args.num_ports is not None) and (int(args.num_ports) > 0):
|
||||
start_num = int(args.first_port[3:])
|
||||
num_ports = int(args.num_ports)
|
||||
port_list = LFUtils.port_name_series(prefix="sta", start_id=start_num, end_id=start_num+num_ports-1,
|
||||
padding_number=10000,
|
||||
radio=args.radio)
|
||||
port_list = LFUtils.port_name_series(prefix="sta", start_id=start_num, end_id=start_num + num_ports - 1,
|
||||
padding_number=10000,
|
||||
radio=args.radio)
|
||||
else:
|
||||
if (args.num_ports is not None) and args.macvlan_parent is not None and (int(args.num_ports) > 0) \
|
||||
and args.macvlan_parent in args.first_port:
|
||||
start_num = int(args.first_port[args.first_port.index('#')+1:])
|
||||
and args.macvlan_parent in args.first_port:
|
||||
start_num = int(args.first_port[args.first_port.index('#') + 1:])
|
||||
num_ports = int(args.num_ports)
|
||||
port_list = LFUtils.port_name_series(prefix=args.macvlan_parent+"#", start_id=start_num,
|
||||
end_id=start_num+num_ports-1, padding_number=100000,
|
||||
radio=args.radio)
|
||||
port_list = LFUtils.port_name_series(prefix=args.macvlan_parent + "#", start_id=start_num,
|
||||
end_id=start_num + num_ports - 1, padding_number=100000,
|
||||
radio=args.radio)
|
||||
else:
|
||||
raise ValueError("Invalid values for num_ports [%s], macvlan_parent [%s], and/or first_port [%s].\n"
|
||||
"first_port must contain parent port and num_ports must be greater than 0"
|
||||
@@ -383,14 +140,9 @@ Generic command layout:
|
||||
else:
|
||||
if args.use_ports is None:
|
||||
num_ports = int(args.num_ports)
|
||||
if not args.use_macvlans:
|
||||
port_list = LFUtils.port_name_series(prefix="sta", start_id=0, end_id=num_ports - 1,
|
||||
padding_number=10000,
|
||||
radio=args.radio)
|
||||
else:
|
||||
port_list = LFUtils.port_name_series(prefix=args.macvlan_parent + "#", start_id=0,
|
||||
end_id=num_ports - 1, padding_number=100000,
|
||||
radio=args.radio)
|
||||
port_list = LFUtils.port_name_series(prefix=args.macvlan_parent + "#", start_id=0,
|
||||
end_id=num_ports - 1, padding_number=100000,
|
||||
radio=args.radio)
|
||||
else:
|
||||
temp_list = args.use_ports.split(',')
|
||||
for port in temp_list:
|
||||
@@ -413,34 +165,25 @@ Generic command layout:
|
||||
# print(port_list)
|
||||
|
||||
# exit(1)
|
||||
ip_test = FileIOTest(args.mgr,
|
||||
args.mgr_port,
|
||||
ssid=args.ssid,
|
||||
password=args.passwd,
|
||||
security=args.security,
|
||||
port_list=port_list,
|
||||
ip_list=ip_list,
|
||||
test_duration=args.test_duration,
|
||||
upstream_port=args.upstream_port,
|
||||
_debug_on=args.debug,
|
||||
|
||||
macvlan_parent=args.macvlan_parent,
|
||||
use_macvlans=args.use_macvlans,
|
||||
first_mvlan_ip=args.first_mvlan_ip,
|
||||
netmask=args.netmask,
|
||||
gateway=args.gateway,
|
||||
dhcp=dhcp,
|
||||
num_ports=args.num_ports,
|
||||
use_test_groups=args.use_test_groups,
|
||||
write_only_test_group=args.write_only_test_group,
|
||||
read_only_test_group=args.read_only_test_group,
|
||||
update_group_args = update_group_args,
|
||||
connections_per_port=args.connections_per_port,
|
||||
mode=args.mode
|
||||
# want a mount options param
|
||||
)
|
||||
ip_test = CreateMacVlan(args.mgr,
|
||||
args.mgr_port,
|
||||
port_list=port_list,
|
||||
ip_list=ip_list,
|
||||
upstream_port=args.upstream_port,
|
||||
_debug_on=args.debug,
|
||||
macvlan_parent=args.macvlan_parent,
|
||||
first_mvlan_ip=args.first_mvlan_ip,
|
||||
netmask=args.netmask,
|
||||
gateway=args.gateway,
|
||||
dhcp=dhcp,
|
||||
num_ports=args.num_ports,
|
||||
connections_per_port=args.connections_per_port,
|
||||
# want a mount options param
|
||||
)
|
||||
|
||||
ip_test.build()
|
||||
print('Created %s MacVlan connections' % args.num_ports)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
main()
|
||||
161
py-scripts/create_qvlan.py
Executable file
161
py-scripts/create_qvlan.py
Executable file
@@ -0,0 +1,161 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
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.lfcli_base import LFCliBase
|
||||
from LANforge.LFUtils import *
|
||||
from LANforge.add_file_endp import *
|
||||
from LANforge import LFUtils
|
||||
import argparse
|
||||
from realm import Realm
|
||||
|
||||
|
||||
class CreateQVlan(Realm):
|
||||
def __init__(self,
|
||||
host="localhost",
|
||||
port=8080,
|
||||
qvlan_parent=None,
|
||||
num_ports=1,
|
||||
dhcp=True,
|
||||
netmask=None,
|
||||
first_qvlan_ip=None,
|
||||
gateway=None,
|
||||
port_list=[],
|
||||
ip_list=[],
|
||||
exit_on_error=False,
|
||||
debug=False):
|
||||
super().__init__(host, port)
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.qvlan_parent = qvlan_parent
|
||||
self.debug = debug
|
||||
self.port_list = port_list
|
||||
self.ip_list = ip_list
|
||||
self.exit_on_error = exit_on_error
|
||||
|
||||
self.qvlan_profile = self.new_qvlan_profile()
|
||||
self.qvlan_profile.num_qvlans = int(num_ports)
|
||||
self.qvlan_profile.desired_qvlans = self.port_list
|
||||
self.qvlan_profile.qvlan_parent = self.qvlan_parent
|
||||
self.qvlan_profile.dhcp = dhcp
|
||||
self.qvlan_profile.netmask = netmask
|
||||
self.qvlan_profile.first_ip_addr = first_qvlan_ip
|
||||
self.qvlan_profile.gateway = gateway
|
||||
self.qvlan_profile.dhcp = dhcp
|
||||
|
||||
def build(self):
|
||||
print("Creating QVLAN stations")
|
||||
self.qvlan_profile.create(admin_down=False, sleep_time=.5, debug=self.debug)
|
||||
|
||||
|
||||
def main():
|
||||
parser = LFCliBase.create_bare_argparse(
|
||||
prog='create_qvlan.py',
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
epilog='''Creates Q-VLAN stations attached to the Eth port of the user's choice.''',
|
||||
|
||||
description='''\
|
||||
create_qvlan.py:
|
||||
---------------------
|
||||
Generic command ''')
|
||||
parser.add_argument('--radio', help='radio EID, e.g: 1.wiphy2')
|
||||
parser.add_argument('--qvlan_parent', help='specifies parent port for qvlan creation', default=None)
|
||||
parser.add_argument('--first_port', help='specifies name of first port to be used', default=None)
|
||||
parser.add_argument('--num_ports', help='number of ports to create', default=1)
|
||||
parser.add_argument('--first_qvlan_ip', help='specifies first static ip address to be used or dhcp', default=None)
|
||||
parser.add_argument('--netmask', help='specifies netmask to be used with static ip addresses', default=None)
|
||||
parser.add_argument('--gateway', help='specifies default gateway to be used with static addressing', default=None)
|
||||
parser.add_argument('--use_ports',
|
||||
help='list of comma separated ports to use with ips, \'=\' separates name and ip { port_name1=ip_addr1,port_name1=ip_addr2 }. Ports without ips will be left alone',
|
||||
default=None)
|
||||
tg_group = parser.add_mutually_exclusive_group()
|
||||
tg_group.add_argument('--add_to_group', help='name of test group to add cxs to', default=None)
|
||||
parser.add_argument('--cxs', help='list of cxs to add/remove depending on use of --add_to_group or --del_from_group'
|
||||
, default=None)
|
||||
parser.add_argument('--use_qvlans', help='will create qvlans', action='store_true', default=False)
|
||||
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
update_group_args = {
|
||||
"name": None,
|
||||
"action": None,
|
||||
"cxs": None
|
||||
}
|
||||
# update_group_args['name'] =
|
||||
if args.first_qvlan_ip in ["dhcp", "DHCP"]:
|
||||
dhcp = True
|
||||
else:
|
||||
dhcp = False
|
||||
update_group_args['action'] = "add"
|
||||
update_group_args['cxs'] = args.cxs
|
||||
port_list = []
|
||||
ip_list = []
|
||||
if args.first_port is not None and args.use_ports is not None:
|
||||
if args.first_port.startswith("sta"):
|
||||
if (args.num_ports is not None) and (int(args.num_ports) > 0):
|
||||
start_num = int(args.first_port[3:])
|
||||
num_ports = int(args.num_ports)
|
||||
port_list = LFUtils.port_name_series(prefix="sta", start_id=start_num, end_id=start_num + num_ports - 1,
|
||||
padding_number=10000,
|
||||
radio=args.radio)
|
||||
print(1)
|
||||
else:
|
||||
if (args.num_ports is not None) and args.qvlan_parent is not None and (int(args.num_ports) > 0) \
|
||||
and args.qvlan_parent in args.first_port:
|
||||
start_num = int(args.first_port[args.first_port.index('#') + 1:])
|
||||
num_ports = int(args.num_ports)
|
||||
port_list = LFUtils.port_name_series(prefix=args.qvlan_parent + "#", start_id=start_num,
|
||||
end_id=start_num + num_ports - 1, padding_number=10000,
|
||||
radio=args.radio)
|
||||
print(2)
|
||||
else:
|
||||
raise ValueError("Invalid values for num_ports [%s], qvlan_parent [%s], and/or first_port [%s].\n"
|
||||
"first_port must contain parent port and num_ports must be greater than 0"
|
||||
% (args.num_ports, args.qvlan_parent, args.first_port))
|
||||
else:
|
||||
if args.use_ports is None:
|
||||
num_ports = int(args.num_ports)
|
||||
port_list = LFUtils.port_name_series(prefix=args.qvlan_parent + "#", start_id=1,
|
||||
end_id=num_ports, padding_number=10000,
|
||||
radio=args.radio)
|
||||
print(3)
|
||||
else:
|
||||
temp_list = args.use_ports.split(',')
|
||||
for port in temp_list:
|
||||
port_list.append(port.split('=')[0])
|
||||
if '=' in port:
|
||||
ip_list.append(port.split('=')[1])
|
||||
else:
|
||||
ip_list.append(0)
|
||||
|
||||
if len(port_list) != len(ip_list):
|
||||
raise ValueError(temp_list, " ports must have matching ip addresses!")
|
||||
|
||||
print(port_list)
|
||||
print(ip_list)
|
||||
create_qvlan = CreateQVlan(args.mgr,
|
||||
args.mgr_port,
|
||||
qvlan_parent=args.qvlan_parent,
|
||||
num_ports=args.num_ports,
|
||||
dhcp=dhcp,
|
||||
netmask=args.netmask,
|
||||
first_qvlan_ip=args.first_qvlan_ip,
|
||||
gateway=args.gateway,
|
||||
port_list=port_list,
|
||||
ip_list=ip_list,
|
||||
debug=args.debug)
|
||||
create_qvlan.build()
|
||||
print('Created %s QVLAN stations' % num_ports)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -17,7 +17,6 @@ if 'py-json' not in sys.path:
|
||||
from LANforge.lfcli_base import LFCliBase
|
||||
from LANforge import LFUtils
|
||||
from realm import Realm
|
||||
import time
|
||||
import pprint
|
||||
|
||||
|
||||
@@ -91,7 +90,6 @@ def main():
|
||||
--------------------
|
||||
Command example:
|
||||
./create_station.py
|
||||
--upstream_port eth1
|
||||
--radio wiphy0
|
||||
--num_stations 3
|
||||
--security open
|
||||
@@ -131,6 +129,7 @@ Command example:
|
||||
_debug_on=args.debug)
|
||||
|
||||
create_station.build()
|
||||
print('Created %s stations' % num_sta)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
137
py-scripts/create_station_from_df.py
Executable file
137
py-scripts/create_station_from_df.py
Executable file
@@ -0,0 +1,137 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
Script for creating a variable number of stations.
|
||||
"""
|
||||
|
||||
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'))
|
||||
from LANforge.lfcli_base import LFCliBase
|
||||
from realm import Realm
|
||||
import pandas as pd
|
||||
import pprint
|
||||
|
||||
|
||||
class CreateStation(Realm):
|
||||
def __init__(self,
|
||||
_ssid=None,
|
||||
_security=None,
|
||||
_password=None,
|
||||
_host=None,
|
||||
_port=None,
|
||||
_sta_list=None,
|
||||
_number_template="00000",
|
||||
_radio="wiphy0",
|
||||
_proxy_str=None,
|
||||
_debug_on=False,
|
||||
_up=True,
|
||||
_exit_on_error=False,
|
||||
_exit_on_fail=False):
|
||||
super().__init__(_host,
|
||||
_port)
|
||||
self.host = _host
|
||||
self.port = _port
|
||||
self.ssid = _ssid
|
||||
self.security = _security
|
||||
self.password = _password
|
||||
self.sta_list = _sta_list
|
||||
self.radio = _radio
|
||||
self.timeout = 120
|
||||
self.number_template = _number_template
|
||||
self.debug = _debug_on
|
||||
self.up = _up
|
||||
self.station_profile = self.new_station_profile()
|
||||
self.station_profile.lfclient_url = self.lfclient_url
|
||||
self.station_profile.ssid = self.ssid
|
||||
self.station_profile.ssid_pass = self.password,
|
||||
self.station_profile.security = self.security
|
||||
self.station_profile.number_template_ = self.number_template
|
||||
self.station_profile.mode = 0
|
||||
if self.debug:
|
||||
print("----- Station List ----- ----- ----- ----- ----- ----- \n")
|
||||
pprint.pprint(self.sta_list)
|
||||
print("---- ~Station List ----- ----- ----- ----- ----- ----- \n")
|
||||
|
||||
|
||||
def build(self):
|
||||
# Build stations
|
||||
self.station_profile.use_security(self.security, self.ssid, self.password)
|
||||
self.station_profile.set_number_template(self.number_template)
|
||||
|
||||
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)
|
||||
if self.up:
|
||||
self.station_profile.admin_up()
|
||||
|
||||
self._pass("PASS: Station build finished")
|
||||
|
||||
|
||||
def main():
|
||||
required=[]
|
||||
required.append({'name':'--df','help':'Which file you want to build stations off of?'})
|
||||
parser = LFCliBase.create_basic_argparse(
|
||||
prog='create_station_from_df.py',
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
epilog='''\
|
||||
Create stations
|
||||
''',
|
||||
description='''\
|
||||
create_station.py
|
||||
--------------------
|
||||
Command example:
|
||||
./create_station_from_df.py
|
||||
--upstream_port eth1
|
||||
--df df.csv
|
||||
--security open
|
||||
--ssid netgear
|
||||
--passwd BLANK
|
||||
--debug
|
||||
''',
|
||||
more_required=required)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
df=pd.read_csv(args.df)
|
||||
unique=df[['radio','ssid','passwd','security']].drop_duplicates().reset_index(drop=True)
|
||||
for item in unique.index:
|
||||
uniquedf=unique.iloc[item]
|
||||
df1=df.merge(pd.DataFrame(uniquedf).transpose(),on=['radio','ssid','passwd','security'])
|
||||
try:
|
||||
radio=uniquedf['radio']
|
||||
except:
|
||||
radio=args.radio
|
||||
station_list=df1['station']
|
||||
try:
|
||||
ssid=uniquedf['ssid']
|
||||
passwd=uniquedf['passwd']
|
||||
security=uniquedf['security']
|
||||
except:
|
||||
ssid=args.ssid
|
||||
passwd=args.passwd
|
||||
security=args.security
|
||||
create_station = CreateStation(_host=args.mgr,
|
||||
_port=args.mgr_port,
|
||||
_ssid=ssid,
|
||||
_password=passwd,
|
||||
_security=security,
|
||||
_sta_list=station_list,
|
||||
_radio=radio,
|
||||
_proxy_str=args.proxy,
|
||||
_debug_on=args.debug)
|
||||
|
||||
create_station.build()
|
||||
print('Created %s stations' % len(unique.index))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -59,7 +59,7 @@ class CreateVAP(Realm):
|
||||
self.vap_profile.dhcp = self.dhcp
|
||||
if self.debug:
|
||||
print("----- VAP List ----- ----- ----- ----- ----- ----- \n")
|
||||
pprint.pprint(self.sta_list)
|
||||
pprint.pprint(self.vap_list)
|
||||
print("---- ~VAP List ----- ----- ----- ----- ----- ----- \n")
|
||||
|
||||
|
||||
|
||||
182
py-scripts/create_vr.py
Executable file
182
py-scripts/create_vr.py
Executable file
@@ -0,0 +1,182 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
Script for creating a variable number of bridges.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
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'))
|
||||
from LANforge.lfcli_base import LFCliBase
|
||||
from LANforge import LFUtils
|
||||
from realm import Realm
|
||||
import time
|
||||
from pprint import pprint
|
||||
|
||||
class CreateVR(Realm):
|
||||
def __init__(self,
|
||||
lfclient_host="localhost",
|
||||
lfclient_port=8080,
|
||||
debug=False,
|
||||
# resource=1, # USE name=1.2.vr0 convention instead
|
||||
vr_name=None,
|
||||
ports_list=(),
|
||||
services_list=(),
|
||||
_exit_on_error=False,
|
||||
_exit_on_fail=False,
|
||||
_proxy_str=None,
|
||||
_capture_signal_list=()):
|
||||
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)
|
||||
|
||||
eid_name = self.name_to_eid(vr_name)
|
||||
self.vr_name = eid_name
|
||||
self.ports_list = ports_list
|
||||
self.services_list = services_list
|
||||
self.vr_profile = self.new_vr_profile()
|
||||
|
||||
def clean(self):
|
||||
if (self.vr_name is None) or (self.vr_profile.vr_eid is None) and (self.vr_profile.vr_eid) == "":
|
||||
print("No vr_eid to clean")
|
||||
return
|
||||
self.rm_port("1.1.rd90a", debug_=self.debug)
|
||||
self.rm_port("1.1.rd90b", debug_=self.debug)
|
||||
self.wait_until_ports_disappear(sta_list=["1.1.rd90a", "1.1.rd90b"],
|
||||
debug_=self.debug)
|
||||
|
||||
if (self.vr_profile.vr_eid is not None) \
|
||||
and (self.vr_profile.vr_eid[1] is not None) \
|
||||
and (self.vr_profile.vr_eid[2] is not None):
|
||||
self.vr_profile.cleanup(debug=self.debug)
|
||||
|
||||
if (self.vr_name is not None) \
|
||||
and (self.vr_name[1] is not None) \
|
||||
and (self.vr_name[2] is not None):
|
||||
data = {
|
||||
"shelf": 1,
|
||||
"resource": self.vr_name[1],
|
||||
"router_name": self.vr_name[2]
|
||||
}
|
||||
self.json_post("/cli-json/rm_vr", data, debug_=self.debug)
|
||||
time.sleep(1)
|
||||
self.json_post("/cli-json/nc_show_vr", {
|
||||
"shelf": 1,
|
||||
"resource": self.vr_name[1],
|
||||
"router": "all"
|
||||
}, debug_=self.debug)
|
||||
self.json_post("/cli-json/nc_show_vrcx", {
|
||||
"shelf": 1,
|
||||
"resource": self.vr_name[1],
|
||||
"cx_name": "all"
|
||||
}, debug_=self.debug)
|
||||
|
||||
|
||||
def build(self):
|
||||
self.vr_profile.apply_netsmith(self.vr_name[1], delay=5, debug=self.debug)
|
||||
self.json_post("/cli-json/add_rdd", {
|
||||
"shelf": 1,
|
||||
"resource": self.vr_name[1],
|
||||
"port": "rd90a",
|
||||
"peer_ifname": "rd90b",
|
||||
"report_timer": "3000"
|
||||
})
|
||||
self.json_post("/cli-json/add_rdd", {
|
||||
"shelf": 1,
|
||||
"resource": self.vr_name[1],
|
||||
"port": "rd90b",
|
||||
"peer_ifname": "rd90a",
|
||||
"report_timer": "3000"
|
||||
})
|
||||
self.wait_until_ports_appear(sta_list=["1.1.rd90a", "1.1.rd90b"], debug_=self.debug)
|
||||
self.vr_profile.vrcx_list(resource=self.vr_name[1], do_sync=True) # do_sync
|
||||
self.vr_profile.create(vr_name=self.vr_name, debug=self.debug)
|
||||
self.vr_profile.sync_netsmith(resource=self.vr_name[1], debug=self.debug)
|
||||
self._pass("created router")
|
||||
|
||||
def start(self):
|
||||
"""
|
||||
Move a vrcx into a router and then movie it out
|
||||
:return: void
|
||||
"""
|
||||
# move rd90a into router
|
||||
self.vr_profile.refresh_netsmith(resource=self.vr_name[1], debug=self.debug)
|
||||
if self.debug:
|
||||
pprint(("vr_eid", self.vr_name))
|
||||
self.vr_profile.wait_until_vrcx_appear(resource=self.vr_name[1], name_list=["rd90a", "rd90b"])
|
||||
self.vr_profile.add_vrcx(vr_eid=self.vr_name, connection_name_list="rd90a", debug=True)
|
||||
|
||||
self.vr_profile.refresh_netsmith(resource=self.vr_name[1], debug=self.debug)
|
||||
# test to make sure that vrcx is inside vr we expect
|
||||
self.vr_profile.vrcx_list(resource=self.vr_name[1], do_sync=True)
|
||||
vr_list = self.vr_profile.router_list(resource=self.vr_name[1], do_refresh=True)
|
||||
router = self.vr_profile.find_cached_router(resource=self.vr_name[1], router_name=self.vr_name[2])
|
||||
pprint(("cached router 120: ", router))
|
||||
router_eid = LFUtils.name_to_eid(router["eid"])
|
||||
pprint(("router eid 122: ", router_eid))
|
||||
full_router = self.json_get("/vr/1/%s/%s/%s" %(router_eid[0], router_eid[1], self.vr_name[2]), debug_=True)
|
||||
pprint(("full router: ", full_router))
|
||||
time.sleep(5)
|
||||
if router is None:
|
||||
self._fail("Unable to find router after vrcx move "+self.vr_name)
|
||||
self.exit_fail()
|
||||
|
||||
def stop(self):
|
||||
pass
|
||||
|
||||
|
||||
def main():
|
||||
parser = LFCliBase.create_bare_argparse(
|
||||
prog=__file__,
|
||||
description="""\
|
||||
{f}
|
||||
--------------------
|
||||
Command example:
|
||||
{f} --vr_name 1.vr0 --ports 1.br0,1.rdd0a --services 1.br0=dhcp,nat --services 1.vr0=radvd
|
||||
{f} --vr_name 2.vr0 --ports 2.br0,2.vap2 --services
|
||||
|
||||
--debug
|
||||
""".format(f=__file__))
|
||||
required = parser.add_argument_group('required arguments')
|
||||
required.add_argument('--vr_name', '--vr_names', required=True,
|
||||
help='EID of virtual router, like 1.2.vr0')
|
||||
|
||||
optional = parser.add_argument_group('optional arguments')
|
||||
|
||||
optional.add_argument('--ports', default=None, required=False,
|
||||
help='Comma separated list of ports to add to virtual router')
|
||||
optional.add_argument('--services', default=None, required=False,
|
||||
help='Add router services to a port, "br0=nat,dhcp"')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
create_vr = CreateVR(lfclient_host=args.mgr,
|
||||
lfclient_port=args.mgr_port,
|
||||
vr_name=args.vr_name,
|
||||
ports_list=args.ports,
|
||||
services_list=args.services,
|
||||
debug=args.debug,
|
||||
_exit_on_error=True,
|
||||
_exit_on_fail=True)
|
||||
create_vr.clean()
|
||||
create_vr.build()
|
||||
create_vr.start()
|
||||
# create_vr.monitor()
|
||||
create_vr.stop()
|
||||
create_vr.clean()
|
||||
print('Created Virtual Router')
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
#
|
||||
112
py-scripts/csv_convert.py
Executable file
112
py-scripts/csv_convert.py
Executable file
@@ -0,0 +1,112 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# This program is used to read in a LANforge Dataplane CSV file and output
|
||||
# a csv file that works with a customer's RvRvO visualization tool.
|
||||
#
|
||||
# Example use case:
|
||||
#
|
||||
# Read in ~/text-csv-0-candela.csv, output is stored at outfile.csv
|
||||
# ./py-scripts/csv_convert.py -i ~/text-csv-0-candela.csv
|
||||
|
||||
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'))
|
||||
|
||||
class CSVParcer():
|
||||
def __init__(self,csv_infile=None,csv_outfile=None,ddb=False):
|
||||
|
||||
idx = 0
|
||||
i_atten = -1
|
||||
i_rotation = -1
|
||||
i_rxbps = -1
|
||||
fpo = open(csv_outfile, "w")
|
||||
with open(csv_infile) as fp:
|
||||
line = fp.readline()
|
||||
if not line:
|
||||
exit(1)
|
||||
# Read in initial line, this is the CSV headers. Parse it to find the column indices for
|
||||
# the columns we care about.
|
||||
x = line.split(",")
|
||||
cni = 0
|
||||
for cn in x:
|
||||
if (cn == "Atten"):
|
||||
i_atten = cni
|
||||
if (cn == "Rotation"):
|
||||
i_rotation = cni
|
||||
if (cn == "Rx-Bps"):
|
||||
i_rxbps = cni
|
||||
cni += 1
|
||||
|
||||
# Write out out header for the new file.
|
||||
fpo.write("Step Index,Position [Deg],Attenuation [dB],Traffic Pair 1 Throughput [Mbps]\n")
|
||||
|
||||
# Read rest of the input lines, processing one at a time. Covert the columns as
|
||||
# needed, and write out new data to the output file.
|
||||
line = fp.readline()
|
||||
|
||||
step_i = 0
|
||||
while line:
|
||||
x = line.split(",")
|
||||
mbps_data = x[i_rxbps]
|
||||
mbps_array = mbps_data.split(" ")
|
||||
mbps_val = float(mbps_array[0])
|
||||
if (mbps_array[1] == "Gbps"):
|
||||
mbps_val *= 1000
|
||||
if (mbps_array[1] == "Kbps"):
|
||||
mbps_val /= 1000
|
||||
if (mbps_array[1] == "bps"):
|
||||
mbps_val /= 1000000
|
||||
|
||||
attenv = float(x[i_atten])
|
||||
if ddb:
|
||||
attenv /= 10
|
||||
|
||||
fpo.write("%s,%s,%s,%s\n" % (step_i, x[i_rotation], attenv, mbps_val))
|
||||
line = fp.readline()
|
||||
step_i += 1
|
||||
|
||||
def main():
|
||||
|
||||
#debug_on = False
|
||||
parser = argparse.ArgumentParser(
|
||||
prog='csv_convert.py',
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
epilog='''\
|
||||
Useful Information:
|
||||
''',
|
||||
|
||||
description='''
|
||||
csv_convert.py:
|
||||
converts the candela csv into the comcast csv and xlsx,
|
||||
renames input file from candela to comcast if not outfile given
|
||||
''')
|
||||
|
||||
# for testing parser.add_argument('-i','--infile', help="input file of csv data", default='text-csv-0-candela.csv')
|
||||
parser.add_argument('-i','--infile', help="input file of csv data", required=True)
|
||||
parser.add_argument('-d','--ddb', help="Specify attenuation units are in ddb in source file",
|
||||
action='store_true', default=False)
|
||||
parser.add_argument('-o','--outfile', help="output file in .csv format", default='outfile.csv')
|
||||
|
||||
|
||||
args = parser.parse_args()
|
||||
csv_outfile_name = None
|
||||
|
||||
if args.infile:
|
||||
csv_infile_name = args.infile
|
||||
if args.outfile:
|
||||
csv_outfile_name = args.outfile
|
||||
|
||||
print("infile: %s outfile: %s convert-ddb: %s"%(csv_infile_name, csv_outfile_name, args.ddb))
|
||||
|
||||
CSVParcer(csv_infile_name, csv_outfile_name, args.ddb)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
161
py-scripts/csv_to_influx.py
Executable file
161
py-scripts/csv_to_influx.py
Executable file
@@ -0,0 +1,161 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copies the data from a CSV file from the KPI file generated from a Wifi Capacity test to an Influx database
|
||||
|
||||
# The CSV requires three columns in order to work: Date, test details, and numeric-score.
|
||||
|
||||
# Date is a unix timestamp, test details is the variable each datapoint is measuring, and numeric-score is the value for that timepoint and variable.
|
||||
|
||||
import sys
|
||||
import os
|
||||
from pprint import pprint
|
||||
from influx2 import RecordInflux
|
||||
|
||||
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 realm import Realm
|
||||
import datetime
|
||||
|
||||
def influx_add_parser_args(parser):
|
||||
parser.add_argument('--influx_host', help='Hostname for the Influx database', default=None)
|
||||
parser.add_argument('--influx_port', help='IP Port for the Influx database', default=8086)
|
||||
parser.add_argument('--influx_org', help='Organization for the Influx database', default=None)
|
||||
parser.add_argument('--influx_token', help='Token for the Influx database', default=None)
|
||||
parser.add_argument('--influx_bucket', help='Name of the Influx bucket', default=None)
|
||||
parser.add_argument('--influx_tag', action='append', nargs=2,
|
||||
help='--influx_tag <key> <val> Can add more than one of these.', default=[])
|
||||
|
||||
|
||||
class CSVtoInflux(Realm):
|
||||
def __init__(self,
|
||||
lfclient_host="localhost",
|
||||
lfclient_port=8080,
|
||||
debug=False,
|
||||
_exit_on_error=False,
|
||||
_exit_on_fail=False,
|
||||
_proxy_str=None,
|
||||
_capture_signal_list=[],
|
||||
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.influx_tag = _influx_tag
|
||||
|
||||
# Submit data to the influx db if configured to do so.
|
||||
def post_to_influx(self):
|
||||
with open(self.target_csv) as fp:
|
||||
line = fp.readline()
|
||||
line = line.split('\t')
|
||||
# indexes tell us where in the CSV our data is located. We do it this way so that even if the columns are moved around, as long as they are present, the script will still work.
|
||||
numeric_score_index = line.index('numeric-score')
|
||||
test_id_index = line.index('test-id')
|
||||
date_index = line.index('Date')
|
||||
test_details_index = line.index('test details')
|
||||
short_description_index = line.index('short-description')
|
||||
graph_group_index = line.index('Graph-Group')
|
||||
units_index = line.index('Units')
|
||||
line = fp.readline()
|
||||
while line:
|
||||
line = line.split('\t') #split the line by tabs to separate each item in the string
|
||||
date = line[date_index]
|
||||
date = datetime.datetime.utcfromtimestamp(int(date) / 1000).isoformat() #convert to datetime so influx can read it, this is required
|
||||
numeric_score = line[numeric_score_index]
|
||||
numeric_score = float(numeric_score) #convert to float, InfluxDB cannot
|
||||
test_details = line[test_details_index]
|
||||
short_description = line[short_description_index]
|
||||
test_id = line[test_id_index]
|
||||
tags = dict()
|
||||
tags['script'] = line[test_id_index]
|
||||
tags['short-description'] = line[short_description_index]
|
||||
tags['test_details'] = line[test_details_index]
|
||||
tags['Graph-Group'] = line[graph_group_index]
|
||||
tags['Units'] = line[units_index]
|
||||
for item in self.influx_tag: # Every item in the influx_tag command needs to be added to the tags variable
|
||||
tags[item[0]] = item[1]
|
||||
self.influxdb.post_to_influx(short_description, numeric_score, tags, date)
|
||||
line = fp.readline()
|
||||
#influx wants to get data in the following format:
|
||||
# variable n ame, value, tags, date
|
||||
# total-download-mbps-speed-for-the-duration-of-this-iteration 171.085494 {'script': 'WiFi Capacity'} 2021-04-14T19:04:04.902000
|
||||
|
||||
|
||||
def main():
|
||||
lfjson_host = "localhost"
|
||||
lfjson_port = 8080
|
||||
endp_types = "lf_udp"
|
||||
debug = False
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
prog='test_l3_longevity.py',
|
||||
# formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
epilog='''
|
||||
''',
|
||||
|
||||
description='''\
|
||||
csv_to_influx.py:
|
||||
--------------------
|
||||
|
||||
Summary :
|
||||
----------
|
||||
Copies the data from a CSV file generated by a wifi capacity test to an influx database.
|
||||
|
||||
Column names are designed for the KPI file generated by our Wifi Capacity Test.
|
||||
|
||||
A user can of course change the column names to match these in order to input any csv file.
|
||||
|
||||
The CSV file needs to have the following columns:
|
||||
--date - which is a UNIX timestamp
|
||||
--test details - which is the variable being measured by the test
|
||||
--numeric-score - which is the value for that variable at that point in time.
|
||||
|
||||
Generic command layout:
|
||||
-----------------------
|
||||
python .\\csv_to_influx.py
|
||||
|
||||
|
||||
Command:
|
||||
python3 csv_to_influx.py --influx_host localhost --influx_org Candela --influx_token random_token --influx_bucket lanforge
|
||||
--target_csv kpi.csv
|
||||
|
||||
|
||||
''')
|
||||
|
||||
influx_add_parser_args(parser)
|
||||
|
||||
# This argument is specific to this script, so not part of the generic influxdb parser args
|
||||
# method above.
|
||||
parser.add_argument('--target_csv', help='CSV file to record to influx database', default="")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
influxdb = RecordInflux(_lfjson_host=lfjson_host,
|
||||
_lfjson_port=lfjson_port,
|
||||
_influx_host=args.influx_host,
|
||||
_influx_port=args.influx_port,
|
||||
_influx_org=args.influx_org,
|
||||
_influx_token=args.influx_token,
|
||||
_influx_bucket=args.influx_bucket)
|
||||
|
||||
csvtoinflux = CSVtoInflux(influxdb=influxdb,
|
||||
target_csv=args.target_csv,
|
||||
_influx_tag=args.influx_tag)
|
||||
csvtoinflux.post_to_influx()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
81
py-scripts/download_test.py
Normal file
81
py-scripts/download_test.py
Normal file
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env python3
|
||||
"""download_test.py will do lf_report::add_kpi(tags, 'throughput-download-bps', $my_value);"""
|
||||
import sys
|
||||
import os
|
||||
|
||||
|
||||
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'))
|
||||
|
||||
from LANforge.lfcli_base import LFCliBase
|
||||
from influx import RecordInflux
|
||||
from realm import Realm
|
||||
import argparse
|
||||
|
||||
class DownloadTest(Realm):
|
||||
def __init__(self,
|
||||
_sta_list=None,
|
||||
_ssid=None,
|
||||
_password=None,
|
||||
_security=None,
|
||||
):
|
||||
super().__init__(_host,
|
||||
_port)
|
||||
self.host = _host
|
||||
self.ssid=_ssid
|
||||
self.security = _security
|
||||
self.password = _password
|
||||
|
||||
self.sta_list= _sta_list
|
||||
|
||||
def main():
|
||||
parser = LFCliBase.create_bare_argparse(
|
||||
prog='download_test.py',
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
epilog='''
|
||||
Download throughput test''',
|
||||
|
||||
)
|
||||
parser.add_argument('--influx_user', help='Username for your Influx database', required=True)
|
||||
parser.add_argument('--influx_passwd', help='Password for your Influx database', required=True)
|
||||
parser.add_argument('--influx_db', help='Name of your Influx database', required=True)
|
||||
parser.add_argument('--longevity', help='How long you want to gather data', default='4h')
|
||||
parser.add_argument('--device', help='Device to monitor', action='append', required=True)
|
||||
parser.add_argument('--monitor_interval', help='How frequently you want to append to your database', default='5s')
|
||||
parser.add_argument('--target_kpi', help='Monitor only selected columns', action='append', default=target_kpi)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
num_sta = 2
|
||||
if (args.num_stations is not None) and (int(args.num_stations) > 0):
|
||||
num_stations_converted = int(args.num_stations)
|
||||
num_sta = num_stations_converted
|
||||
|
||||
station_list = LFUtils.port_name_series(prefix="sta",
|
||||
start_id=0,
|
||||
end_id=num_sta-1,
|
||||
padding_number=10000,
|
||||
radio=args.radio)
|
||||
|
||||
monitor_interval = LFCliBase.parse_time(args.monitor_interval).total_seconds()
|
||||
longevity = LFCliBase.parse_time(args.longevity).total_seconds()
|
||||
grapher = DownloadTest(_host=args.mgr,
|
||||
_port=args.mgr_port,
|
||||
_influx_db=args.influx_db,
|
||||
_influx_user=args.influx_user,
|
||||
_influx_passwd=args.influx_passwd,
|
||||
_longevity=longevity,
|
||||
_devices=args.device,
|
||||
_monitor_interval=monitor_interval,
|
||||
_target_kpi=args.target_kpi,
|
||||
_ssid=args.ssid,
|
||||
_password=args.passwd,
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
131
py-scripts/event_breaker.py
Executable file
131
py-scripts/event_breaker.py
Executable file
@@ -0,0 +1,131 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
This file is intended to expose concurrency
|
||||
problems in the /events/ URL handler by querying events rapidly.
|
||||
Please use concurrently with event_flood.py.
|
||||
"""
|
||||
import sys
|
||||
|
||||
if sys.version_info[0] != 3:
|
||||
print("This script requires Python 3")
|
||||
exit(1)
|
||||
|
||||
if 'py-json' not in sys.path:
|
||||
sys.path.append('../py-json')
|
||||
|
||||
import argparse
|
||||
from LANforge.lfcli_base import LFCliBase
|
||||
from realm import Realm
|
||||
import datetime
|
||||
from datetime import datetime
|
||||
import time
|
||||
from time import sleep
|
||||
import pprint
|
||||
|
||||
class EventBreaker(Realm):
|
||||
def __init__(self, host, port,
|
||||
duration=None,
|
||||
_debug_on=False,
|
||||
_exit_on_error=False,
|
||||
_exit_on_fail=False):
|
||||
super().__init__(host, port)
|
||||
self.counter = 0
|
||||
self.test_duration=duration
|
||||
if (self.test_duration is None):
|
||||
raise ValueError("run wants numeric run_duration_sec")
|
||||
|
||||
def create(self):
|
||||
pass
|
||||
|
||||
def run(self):
|
||||
|
||||
now = datetime.now()
|
||||
now_ms = 0
|
||||
end_time = self.parse_time(self.test_duration) + now
|
||||
client_time_ms = 0
|
||||
prev_client_time_ms = 0
|
||||
start_loop_time_ms = 0
|
||||
loop_time_ms = 0
|
||||
prev_loop_time_ms = 0
|
||||
num_events = 0
|
||||
prev_num_events = 0
|
||||
bad_events = []
|
||||
while datetime.now() < end_time:
|
||||
bad_events = []
|
||||
start_loop_time_ms = int(self.get_milliseconds(datetime.now()))
|
||||
print ('\r♦ ', end='')
|
||||
#prev_loop_time_ms = loop_time_ms
|
||||
# loop_time_ms = self.get_milliseconds(datetime.now())
|
||||
prev_client_time_ms = client_time_ms
|
||||
response = self.json_get("/events/all")
|
||||
#pprint.pprint(response)
|
||||
|
||||
if "events" not in response:
|
||||
pprint.pprint(response)
|
||||
raise AssertionError("no events in response")
|
||||
events = response["events"]
|
||||
prev_num_events = num_events
|
||||
num_events = len(events)
|
||||
if num_events != prev_num_events:
|
||||
print("%s events Δ%s"%(num_events, (num_events - prev_num_events)))
|
||||
if "candela.lanforge.HttpEvents" in response:
|
||||
client_time_ms = float(response["candela.lanforge.HttpEvents"]["duration"])
|
||||
# print(" client_time %d"%client_time_ms)
|
||||
|
||||
if abs(prev_client_time_ms - client_time_ms) > 30:
|
||||
print(" client time %d ms Δ%d"%(client_time_ms, (prev_client_time_ms - client_time_ms)),
|
||||
end='')
|
||||
event_index = 0
|
||||
for record in events:
|
||||
|
||||
for k in record.keys():
|
||||
if record[k] is None:
|
||||
print (' ☠no %s☠'%k, end='')
|
||||
continue
|
||||
# pprint.pprint( record[k])
|
||||
if "NA" == record[k]["event"] \
|
||||
or "NA" == record[k]["name"] \
|
||||
or "NA" == record[k]["type"] \
|
||||
or "NA" == record[k]["priority"]:
|
||||
bad_events.append(int(k))
|
||||
pprint.pprint(record[k])
|
||||
# print( " ☠id[%s]☠"%k, end='')
|
||||
if len(bad_events) > 0:
|
||||
pprint.pprint(events[event_index])
|
||||
print( " ☠id[%s]☠"%bad_events, end='')
|
||||
exit(1)
|
||||
event_index += 1
|
||||
prev_loop_time_ms = loop_time_ms
|
||||
now_ms = int(self.get_milliseconds(datetime.now()))
|
||||
loop_time_ms = now_ms - start_loop_time_ms
|
||||
if (prev_loop_time_ms - loop_time_ms) > 15:
|
||||
print(" loop time %d ms Δ%d "
|
||||
%(loop_time_ms, (prev_loop_time_ms - loop_time_ms)),
|
||||
end='')
|
||||
if (prev_loop_time_ms - loop_time_ms) > 30:
|
||||
print("")
|
||||
|
||||
def cleanup(self):
|
||||
pass
|
||||
|
||||
def main():
|
||||
parser = LFCliBase.create_bare_argparse(
|
||||
prog='event_breaker.py',
|
||||
formatter_class=argparse.RawTextHelpFormatter)
|
||||
|
||||
parser.add_argument("--test_duration", help='test duration', default="30s" )
|
||||
# if optional_args is not None:
|
||||
args = parser.parse_args()
|
||||
|
||||
event_breaker = EventBreaker(host=args.mgr,
|
||||
port=args.mgr_port,
|
||||
duration=args.test_duration,
|
||||
_debug_on=True,
|
||||
_exit_on_error=True,
|
||||
_exit_on_fail=True)
|
||||
event_breaker.create()
|
||||
event_breaker.run()
|
||||
event_breaker.cleanup()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
114
py-scripts/event_flood.py
Executable file
114
py-scripts/event_flood.py
Executable file
@@ -0,0 +1,114 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
This file is intended to expose concurrency
|
||||
problems in the /events/ URL handler by inserting events rapidly.
|
||||
Please concurrently use with event_breaker.py.
|
||||
"""
|
||||
import sys
|
||||
|
||||
if sys.version_info[0] != 3:
|
||||
print("This script requires Python 3")
|
||||
exit(1)
|
||||
|
||||
if 'py-json' not in sys.path:
|
||||
sys.path.append('../py-json')
|
||||
|
||||
import argparse
|
||||
from LANforge.lfcli_base import LFCliBase
|
||||
from realm import Realm
|
||||
import datetime
|
||||
from datetime import datetime
|
||||
import time
|
||||
from time import sleep
|
||||
import pprint
|
||||
|
||||
class EventBreaker(Realm):
|
||||
def __init__(self, host, port,
|
||||
duration=None,
|
||||
pause_ms=None,
|
||||
_debug_on=False,
|
||||
_exit_on_error=False,
|
||||
_exit_on_fail=False):
|
||||
super().__init__(host, port)
|
||||
self.counter = 0
|
||||
self.test_duration = duration
|
||||
self.pause_ms = pause_ms
|
||||
if (self.test_duration is None):
|
||||
raise ValueError("run wants numeric run_duration_sec")
|
||||
|
||||
def create(self):
|
||||
pass
|
||||
|
||||
def run(self):
|
||||
last_second_ms = 0
|
||||
start_time = datetime.now()
|
||||
now_ms = 0
|
||||
end_time = self.parse_time(self.test_duration) + start_time
|
||||
client_time_ms = 0
|
||||
prev_client_time_ms = 0
|
||||
start_loop_time_ms = 0
|
||||
loop_time_ms = 0
|
||||
prev_loop_time_ms = 0
|
||||
num_events = 0
|
||||
prev_num_events = 0
|
||||
|
||||
while datetime.now() < end_time:
|
||||
sleep( self.pause_ms / 1000 )
|
||||
start_loop_time_ms = int(self.get_milliseconds(datetime.now()))
|
||||
print ('\r♦ ', end='')
|
||||
#prev_loop_time_ms = loop_time_ms
|
||||
# loop_time_ms = self.get_milliseconds(datetime.now())
|
||||
prev_client_time_ms = client_time_ms
|
||||
response_list = []
|
||||
response = self.json_post("/cli-json/add_event",
|
||||
{
|
||||
"event_id": "new",
|
||||
"details": "event_flood %d"%start_loop_time_ms,
|
||||
"priority": "INFO",
|
||||
"name": "custom"
|
||||
},
|
||||
response_json_list_=response_list)
|
||||
# pprint.pprint(response_list)
|
||||
prev_client_time_ms = client_time_ms
|
||||
prev_loop_time_ms = loop_time_ms
|
||||
now = int(self.get_milliseconds(datetime.now()))
|
||||
loop_time_ms = now - start_loop_time_ms
|
||||
|
||||
client_time_ms = response_list[0]["LAST"]["duration"]
|
||||
if (client_time_ms != prev_client_time_ms):
|
||||
print(" client %d ms %d"%(client_time_ms,
|
||||
(prev_client_time_ms - client_time_ms)),
|
||||
end='')
|
||||
if (loop_time_ms != prev_loop_time_ms):
|
||||
print(" loop %d ms %d "%(loop_time_ms,
|
||||
(prev_loop_time_ms - loop_time_ms)),
|
||||
end='')
|
||||
if (last_second_ms + 1000) < now:
|
||||
last_second_ms = now
|
||||
print("")
|
||||
def cleanup(self):
|
||||
pass
|
||||
|
||||
def main():
|
||||
parser = LFCliBase.create_bare_argparse(
|
||||
prog='event_breaker.py',
|
||||
formatter_class=argparse.RawTextHelpFormatter)
|
||||
|
||||
parser.add_argument("--test_duration", help='test duration', default="30s" )
|
||||
parser.add_argument("--pause_ms", help='interval between submitting events', default="30" )
|
||||
# if optional_args is not None:
|
||||
args = parser.parse_args()
|
||||
|
||||
event_breaker = EventBreaker(host=args.mgr,
|
||||
port=args.mgr_port,
|
||||
duration=args.test_duration,
|
||||
pause_ms=int(args.pause_ms),
|
||||
_debug_on=True,
|
||||
_exit_on_error=True,
|
||||
_exit_on_fail=True)
|
||||
event_breaker.create()
|
||||
event_breaker.run()
|
||||
event_breaker.cleanup()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
47
py-scripts/example-configs/mesh-ferndale-cfg.txt
Normal file
47
py-scripts/example-configs/mesh-ferndale-cfg.txt
Normal file
@@ -0,0 +1,47 @@
|
||||
chamber-0: RootAP
|
||||
chamber-1: Node1
|
||||
chamber-2: Node2
|
||||
chamber-3:
|
||||
chamber-4: MobileStations
|
||||
sta_amount-0: 1
|
||||
sta_amount-1: 1
|
||||
sta_amount-2: 1
|
||||
sta_amount-3: 1
|
||||
sta_amount-4: 1
|
||||
radios-0-0: 1.2.wiphy0
|
||||
radios-0-1:
|
||||
radios-0-2:
|
||||
radios-0-3: 1.2.wiphy1
|
||||
radios-0-4:
|
||||
radios-0-5:
|
||||
radios-1-0: 1.3.wiphy0
|
||||
radios-1-1:
|
||||
radios-1-2:
|
||||
radios-1-3: 1.3.wiphy1
|
||||
radios-1-4:
|
||||
radios-1-5:
|
||||
radios-2-0: 1.4.wiphy0
|
||||
radios-2-1:
|
||||
radios-2-2:
|
||||
radios-2-3: 1.4.wiphy1
|
||||
radios-2-4:
|
||||
radios-2-5:
|
||||
radios-3-0:
|
||||
radios-3-1:
|
||||
radios-3-2:
|
||||
radios-3-3:
|
||||
radios-3-4:
|
||||
radios-3-5:
|
||||
radios-4-0: 1.1.2 wiphy0
|
||||
radios-4-1:
|
||||
radios-4-2:
|
||||
radios-4-3: 1.1.3 wiphy1
|
||||
radios-4-4:
|
||||
radios-4-5:
|
||||
ap_arrangements: Current Position
|
||||
tests: Roam
|
||||
traf_combo: STA
|
||||
sta_position: Current Position
|
||||
traffic_types: UDP
|
||||
direction: Download
|
||||
path: Orbit Current
|
||||
43
py-scripts/example-configs/tr398-ferndale-ac-cfg.txt
Normal file
43
py-scripts/example-configs/tr398-ferndale-ac-cfg.txt
Normal file
@@ -0,0 +1,43 @@
|
||||
# Example radio setup, calibration data, and attenuator setup.
|
||||
# At least the attenuation will be unique for your testbed
|
||||
# so run the calibration step, view the config, and paste the appropriate
|
||||
# lines into a file similar to this.
|
||||
|
||||
radio-0: 1.1.2 wiphy0
|
||||
radio-1: 1.1.3 wiphy1
|
||||
radio-2: 1.1.4 wiphy2
|
||||
radio-3: 1.1.5 wiphy3
|
||||
radio-4: 1.1.6 wiphy4
|
||||
radio-5: 1.1.7 wiphy5
|
||||
rssi_0_2-0: -26
|
||||
rssi_0_2-1: -26
|
||||
rssi_0_2-2: -26
|
||||
rssi_0_2-3: -26
|
||||
rssi_0_2-4: -27
|
||||
rssi_0_2-5: -27
|
||||
rssi_0_2-6: -27
|
||||
rssi_0_2-7: -27
|
||||
rssi_0_2-8: -25
|
||||
rssi_0_2-9: -25
|
||||
rssi_0_2-10: -25
|
||||
rssi_0_2-11: -25
|
||||
rssi_0_5-0: -38
|
||||
rssi_0_5-1: -38
|
||||
rssi_0_5-2: -38
|
||||
rssi_0_5-3: -38
|
||||
rssi_0_5-4: -38
|
||||
rssi_0_5-5: -38
|
||||
rssi_0_5-6: -38
|
||||
rssi_0_5-7: -38
|
||||
rssi_0_5-8: -47
|
||||
rssi_0_5-9: -47
|
||||
rssi_0_5-10: -47
|
||||
rssi_0_5-11: -47
|
||||
atten-0: 1.1.85.0
|
||||
atten-1: 1.1.85.1
|
||||
atten-2: 1.1.85.2
|
||||
atten-3: 1.1.85.3
|
||||
atten-4: 1.1.1002.0
|
||||
atten-5: 1.1.1002.1
|
||||
atten-8: 1.1.1002.2
|
||||
atten-9: 1.1.1002.3
|
||||
@@ -1,109 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import os
|
||||
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 LANforge
|
||||
from LANforge.lfcli_base import LFCliBase
|
||||
from LANforge import LFUtils
|
||||
import realm
|
||||
import argparse
|
||||
import time
|
||||
import pprint
|
||||
|
||||
|
||||
class IPv4Test(LFCliBase):
|
||||
def __init__(self, ssid, security, password, sta_list=None, number_template="00000", host="localhost", port=8080, radio ="wiphy0",_debug_on=False,
|
||||
_exit_on_error=False,
|
||||
_exit_on_fail=False):
|
||||
super().__init__(host, port, _debug=_debug_on, _halt_on_error=_exit_on_error, _exit_on_fail=_exit_on_fail)
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.ssid = ssid
|
||||
self.security = security
|
||||
self.password = password
|
||||
self.sta_list = sta_list
|
||||
self.timeout = 120
|
||||
self.radio=radio
|
||||
self.number_template = number_template
|
||||
self.debug = _debug_on
|
||||
self.local_realm = realm.Realm(lfclient_host=self.host, lfclient_port=self.port)
|
||||
self.station_profile = self.local_realm.new_station_profile()
|
||||
|
||||
self.station_profile.lfclient_url = self.lfclient_url
|
||||
self.station_profile.ssid = self.ssid
|
||||
self.station_profile.ssid_pass = self.password,
|
||||
self.station_profile.security = self.security
|
||||
self.station_profile.number_template_ = self.number_template
|
||||
self.station_profile.mode = 0
|
||||
|
||||
def build(self):
|
||||
# Build stations
|
||||
self.station_profile.use_security(self.security, self.ssid, self.password)
|
||||
self.station_profile.set_number_template(self.number_template)
|
||||
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.admin_up()
|
||||
if self.local_realm.wait_for_ip(station_list=self.sta_list, debug=self.debug, timeout_sec=30):
|
||||
self._pass("Station build finished")
|
||||
self.exit_success()
|
||||
else:
|
||||
self._fail("Stations not able to acquire IP. Please check network input.")
|
||||
self.exit_fail()
|
||||
|
||||
|
||||
def cleanup(self, sta_list):
|
||||
self.station_profile.cleanup(sta_list)
|
||||
LFUtils.wait_until_ports_disappear(base_url=self.lfclient_url, port_list=sta_list,
|
||||
debug=self.debug)
|
||||
|
||||
def main():
|
||||
|
||||
parser = LFCliBase.create_basic_argparse(
|
||||
prog='example_open_connection.py',
|
||||
# formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
epilog='''\
|
||||
Example code that creates a specified amount of stations on a specified SSID using Open security.
|
||||
''',
|
||||
|
||||
description='''\
|
||||
example_open_connection.py
|
||||
--------------------
|
||||
|
||||
Generic command example:
|
||||
python3 ./example_open_connection.py
|
||||
--mgr localhost
|
||||
--mgr_port 8080
|
||||
--num_stations 3
|
||||
--radio wiphy1
|
||||
--ssid netgear-open
|
||||
--passwd [BLANK]
|
||||
--debug
|
||||
''')
|
||||
|
||||
args = parser.parse_args()
|
||||
num_sta = 2
|
||||
if (args.num_stations is not None) and (int(args.num_stations) > 0):
|
||||
num_sta = int(args.num_stations)
|
||||
|
||||
station_list = LFUtils.portNameSeries(prefix_="sta",
|
||||
start_id_=0,
|
||||
end_id_=num_sta-1,
|
||||
padding_number_=10000)
|
||||
ip_test = IPv4Test(host=args.mgr, port=args.mgr_port, ssid=args.ssid, password=args.passwd,
|
||||
security="open", radio=args.radio, sta_list=station_list)
|
||||
ip_test.cleanup(station_list)
|
||||
ip_test.timeout = 60
|
||||
ip_test.build()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -21,7 +21,7 @@ class IPv4Test(LFCliBase):
|
||||
def __init__(self, ssid, security, password, sta_list=None, ap=None, mode = 0, number_template="00000", host="localhost", port=8080,radio = "wiphy0",_debug_on=False,
|
||||
_exit_on_error=False,
|
||||
_exit_on_fail=False):
|
||||
super().__init__(host, port, _debug=_debug_on, _halt_on_error=_exit_on_error, _exit_on_fail=_exit_on_fail)
|
||||
super().__init__(host, port, _debug=_debug_on, _exit_on_fail=_exit_on_fail)
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.ssid = ssid
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import os
|
||||
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 LANforge
|
||||
from LANforge.lfcli_base import LFCliBase
|
||||
from LANforge import LFUtils
|
||||
import realm
|
||||
import argparse
|
||||
import time
|
||||
import pprint
|
||||
|
||||
|
||||
class IPv4Test(LFCliBase):
|
||||
def __init__(self, ssid, security, password, sta_list=None, number_template="00000", radio = "wiphy0",_debug_on=False, host="locahost", port=8080,
|
||||
_exit_on_error=False,
|
||||
_exit_on_fail=False):
|
||||
super().__init__(host, port, _debug=_debug_on, _halt_on_error=_exit_on_error, _exit_on_fail=_exit_on_fail)
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.radio = radio
|
||||
self.ssid = ssid
|
||||
self.security = security
|
||||
self.password = password
|
||||
self.sta_list = sta_list
|
||||
self.timeout = 120
|
||||
self.number_template = number_template
|
||||
self.debug = _debug_on
|
||||
self.local_realm = realm.Realm(lfclient_host=self.host, lfclient_port=self.port)
|
||||
self.station_profile = self.local_realm.new_station_profile()
|
||||
|
||||
self.station_profile.lfclient_url = self.lfclient_url
|
||||
self.station_profile.ssid = self.ssid
|
||||
self.station_profile.ssid_pass = self.password,
|
||||
self.station_profile.security = self.security
|
||||
self.station_profile.number_template_ = self.number_template
|
||||
self.station_profile.mode = 0
|
||||
|
||||
def build(self):
|
||||
# Build stations
|
||||
self.station_profile.use_security(self.security, self.ssid, self.password)
|
||||
self.station_profile.set_number_template(self.number_template)
|
||||
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.admin_up()
|
||||
if self.local_realm.wait_for_ip(station_list=self.sta_list, debug=self.debug, timeout_sec=30):
|
||||
self._pass("Station build finished")
|
||||
self.exit_success()
|
||||
else:
|
||||
self._fail("Stations not able to acquire IP. Please check network input.")
|
||||
self.exit_fail()
|
||||
|
||||
def cleanup(self, sta_list):
|
||||
self.station_profile.cleanup(sta_list)
|
||||
LFUtils.wait_until_ports_disappear(base_url=self.lfclient_url, port_list=sta_list,
|
||||
debug=self.debug)
|
||||
|
||||
def main():
|
||||
|
||||
parser = LFCliBase.create_basic_argparse(
|
||||
prog='example_wep_connection.py',
|
||||
# formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
epilog='''\
|
||||
Example code that creates a specified amount of stations on a specified SSID using WEP security.
|
||||
''',
|
||||
|
||||
description='''\
|
||||
example_wep_connection.py
|
||||
--------------------
|
||||
|
||||
Generic command example:
|
||||
python3 ./example_wep_connection.py
|
||||
--host localhost
|
||||
--port 8080
|
||||
--num_stations 3
|
||||
--radio wiphy1
|
||||
--ssid jedway-wep-48
|
||||
--passwd jedway-wep-48
|
||||
--debug
|
||||
''')
|
||||
|
||||
args = parser.parse_args()
|
||||
num_sta = 2
|
||||
if (args.num_stations is not None) and (int(args.num_stations) > 0):
|
||||
num_stations_converted = int(args.num_stations)
|
||||
num_sta = num_stations_converted
|
||||
|
||||
station_list = LFUtils.portNameSeries(prefix_="sta",
|
||||
start_id_=0,
|
||||
end_id_=num_sta-1,
|
||||
padding_number_=10000)
|
||||
ip_test = IPv4Test(host=args.mgr,port=args.mgr_port, ssid=args.ssid, password=args.passwd,
|
||||
security="wep", radio=args.radio, sta_list=station_list)
|
||||
ip_test.cleanup(station_list)
|
||||
ip_test.timeout = 60
|
||||
ip_test.build()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,109 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import os
|
||||
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 LANforge
|
||||
from LANforge.lfcli_base import LFCliBase
|
||||
from LANforge import LFUtils
|
||||
import realm
|
||||
import argparse
|
||||
import time
|
||||
import pprint
|
||||
|
||||
|
||||
class IPv4Test(LFCliBase):
|
||||
def __init__(self, ssid, security, password, sta_list=None,host="localhost", port=8080, number_template="00000", radio="wiphy0",_debug_on=False,
|
||||
_exit_on_error=False,
|
||||
_exit_on_fail=False):
|
||||
super().__init__(host, port, _debug=_debug_on, _halt_on_error=_exit_on_error, _exit_on_fail=_exit_on_fail)
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.ssid = ssid
|
||||
self.radio = radio
|
||||
self.security = security
|
||||
self.password = password
|
||||
self.sta_list = sta_list
|
||||
self.timeout = 120
|
||||
self.number_template = number_template
|
||||
self.debug = _debug_on
|
||||
self.local_realm = realm.Realm(lfclient_host=self.host, lfclient_port=self.port)
|
||||
self.station_profile = self.local_realm.new_station_profile()
|
||||
|
||||
self.station_profile.lfclient_url = self.lfclient_url
|
||||
self.station_profile.ssid = self.ssid
|
||||
self.station_profile.ssid_pass = self.password,
|
||||
self.station_profile.security = self.security
|
||||
self.station_profile.number_template_ = self.number_template
|
||||
self.station_profile.mode = 0
|
||||
|
||||
def build(self):
|
||||
# Build stations
|
||||
self.station_profile.use_security(self.security, self.ssid, self.password)
|
||||
self.station_profile.set_number_template(self.number_template)
|
||||
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.admin_up()
|
||||
if self.local_realm.wait_for_ip(station_list=self.sta_list, debug=self.debug, timeout_sec=30):
|
||||
self._pass("Station build finished")
|
||||
self.exit_success()
|
||||
else:
|
||||
self._fail("Stations not able to acquire IP. Please check network input.")
|
||||
self.exit_fail()
|
||||
|
||||
def cleanup(self, sta_list):
|
||||
self.station_profile.cleanup(sta_list)
|
||||
LFUtils.wait_until_ports_disappear(base_url=self.lfclient_url, port_list=sta_list,
|
||||
debug=self.debug)
|
||||
|
||||
def main():
|
||||
parser = LFCliBase.create_basic_argparse(
|
||||
prog='example_wpa2_connection.py',
|
||||
# formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
epilog='''\
|
||||
Example code that creates a specified amount of stations on a specified SSID using WPA2 security.
|
||||
''',
|
||||
|
||||
description='''\
|
||||
example_wpa2_connection.py
|
||||
--------------------
|
||||
|
||||
Generic command example
|
||||
python3 ./example_wpa2_connection.py
|
||||
--host localhost
|
||||
--port 8080
|
||||
--num_stations 3
|
||||
--ssid netgear-wpa2
|
||||
--passwd admin123-wpa2
|
||||
--radio wiphy1
|
||||
--debug
|
||||
''')
|
||||
|
||||
args = parser.parse_args()
|
||||
num_sta = 2
|
||||
if (args.num_stations is not None) and (int(args.num_stations) > 0):
|
||||
num_stations_converted = int(args.num_stations)
|
||||
num_sta = num_stations_converted
|
||||
|
||||
station_list = LFUtils.portNameSeries(prefix_="sta",
|
||||
start_id_=0,
|
||||
end_id_=num_sta-1,
|
||||
padding_number_=10000,
|
||||
radio=args.radio)
|
||||
ip_test = IPv4Test(host=args.mgr, port=args.mgr_port, ssid=args.ssid, password=args.passwd, radio=args.radio,
|
||||
security="wpa2", sta_list=station_list)
|
||||
ip_test.cleanup(station_list)
|
||||
ip_test.timeout = 60
|
||||
ip_test.build()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,110 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import os
|
||||
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 LANforge
|
||||
from LANforge.lfcli_base import LFCliBase
|
||||
from LANforge import LFUtils
|
||||
import realm
|
||||
import argparse
|
||||
import time
|
||||
import pprint
|
||||
|
||||
|
||||
class IPv4Test(LFCliBase):
|
||||
def __init__(self, ssid, security, password, host="localhost", port=8080,sta_list=None, number_template="00000", radio = "wiphy0",_debug_on=False,
|
||||
_exit_on_error=False,
|
||||
_exit_on_fail=False):
|
||||
super().__init__(host, port, _debug=_debug_on, _halt_on_error=_exit_on_error, _exit_on_fail=_exit_on_fail)
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.ssid = ssid
|
||||
self.radio = radio
|
||||
self.security = security
|
||||
self.password = password
|
||||
self.sta_list = sta_list
|
||||
self.timeout = 120
|
||||
self.number_template = number_template
|
||||
self.debug = _debug_on
|
||||
self.local_realm = realm.Realm(lfclient_host=self.host, lfclient_port=self.port)
|
||||
self.station_profile = self.local_realm.new_station_profile()
|
||||
|
||||
self.station_profile.lfclient_url = self.lfclient_url
|
||||
self.station_profile.ssid = self.ssid
|
||||
self.station_profile.ssid_pass = self.password,
|
||||
self.station_profile.security = self.security
|
||||
self.station_profile.number_template_ = self.number_template
|
||||
self.station_profile.mode = 0
|
||||
|
||||
def build(self):
|
||||
# Build stations
|
||||
#print("We've gotten into the build stations function")
|
||||
self.station_profile.use_security(self.security, self.ssid, self.password)
|
||||
self.station_profile.set_number_template(self.number_template)
|
||||
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.admin_up()
|
||||
if self.local_realm.wait_for_ip(station_list=self.sta_list, debug=self.debug, timeout_sec=30):
|
||||
self._pass("Station build finished")
|
||||
self.exit_success()
|
||||
else:
|
||||
self._fail("Stations not able to acquire IP. Please check network input.")
|
||||
self.exit_fail()
|
||||
|
||||
|
||||
def cleanup(self, sta_list):
|
||||
self.station_profile.cleanup(sta_list)
|
||||
LFUtils.wait_until_ports_disappear(base_url=self.lfclient_url, port_list=sta_list,
|
||||
debug=self.debug)
|
||||
|
||||
def main():
|
||||
parser = LFCliBase.create_basic_argparse(
|
||||
prog='example_wpa3_connection.py',
|
||||
# formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
epilog='''\
|
||||
Example code that creates a specified amount of stations on a specified SSID using WPA3 security.
|
||||
''',
|
||||
|
||||
description='''\
|
||||
example_wpa3_connection.py
|
||||
--------------------
|
||||
|
||||
Generic command example:
|
||||
python3 ./example_wpa3_connection.py
|
||||
--host localhost
|
||||
--port 8080
|
||||
--num_stations 3
|
||||
--ssid netgear-wpa3
|
||||
--passwd admin123-wpa3
|
||||
--radio wiphy1
|
||||
--debug
|
||||
''')
|
||||
|
||||
args = parser.parse_args()
|
||||
num_sta = 2
|
||||
if (args.num_stations is not None) and (int(args.num_stations) > 0):
|
||||
num_stations_converted = int(args.num_stations)
|
||||
num_sta = num_stations_converted
|
||||
|
||||
station_list = LFUtils.portNameSeries(prefix_="sta",
|
||||
start_id_=0,
|
||||
end_id_=num_sta-1,
|
||||
padding_number_=10000,
|
||||
radio=args.radio)
|
||||
ip_test = IPv4Test(host=args.mgr, port=args.mgr_port, ssid=args.ssid, password=args.passwd, radio=args.radio,
|
||||
security="wpa3", sta_list=station_list)
|
||||
ip_test.cleanup(station_list)
|
||||
ip_test.timeout = 60
|
||||
ip_test.build()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,114 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import os
|
||||
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
|
||||
import LANforge
|
||||
from LANforge.lfcli_base import LFCliBase
|
||||
from LANforge import LFUtils
|
||||
import realm
|
||||
import time
|
||||
import pprint
|
||||
|
||||
|
||||
class IPv4Test(LFCliBase):
|
||||
def __init__(self, ssid, security, password, sta_list=None, host="locahost", port=8080, number_template="00000", radio ="wiphy0", _debug_on=False,
|
||||
_exit_on_error=False,
|
||||
_exit_on_fail=False):
|
||||
super().__init__(host, port, _debug=_debug_on, _halt_on_error=_exit_on_error, _exit_on_fail=_exit_on_fail)
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.ssid = ssid
|
||||
self.radio= radio
|
||||
self.security = security
|
||||
self.password = password
|
||||
self.sta_list = sta_list
|
||||
self.timeout = 120
|
||||
self.number_template = number_template
|
||||
self.debug = _debug_on
|
||||
self.local_realm = realm.Realm(lfclient_host=self.host, lfclient_port=self.port)
|
||||
self.station_profile = self.local_realm.new_station_profile()
|
||||
|
||||
self.station_profile.lfclient_url = self.lfclient_url
|
||||
self.station_profile.ssid = self.ssid
|
||||
self.station_profile.ssid_pass = self.password,
|
||||
self.station_profile.security = self.security
|
||||
self.station_profile.number_template_ = self.number_template
|
||||
self.station_profile.mode = 0
|
||||
|
||||
def build(self):
|
||||
# Build stations
|
||||
self.station_profile.use_security(self.security, self.ssid, self.password)
|
||||
self.station_profile.set_number_template(self.number_template)
|
||||
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.admin_up()
|
||||
if self.local_realm.wait_for_ip(station_list=self.sta_list, debug=self.debug, timeout_sec=30):
|
||||
self._pass("Station build finished")
|
||||
self.exit_success()
|
||||
|
||||
else:
|
||||
self._fail("Stations not able to acquire IP. Please check network input.")
|
||||
self.exit_fail()
|
||||
|
||||
|
||||
def cleanup(self, sta_list):
|
||||
self.station_profile.cleanup(sta_list)
|
||||
LFUtils.wait_until_ports_disappear(base_url=self.lfclient_url, port_list=sta_list,
|
||||
debug=self.debug)
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
parser = LFCliBase.create_basic_argparse(
|
||||
prog='example_wpa_connection.py',
|
||||
# formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
epilog='''\
|
||||
Example code that creates a specified amount of stations on a specified SSID using WPA security.
|
||||
''',
|
||||
|
||||
description='''\
|
||||
example_wpa_connection.py
|
||||
--------------------
|
||||
|
||||
Generic command example:
|
||||
python3 ./example_wpa_connection.py
|
||||
--host localhost
|
||||
--port 8080
|
||||
--num_stations 3
|
||||
--ssid netgear-wpa
|
||||
--passwd admin123-wpa
|
||||
--radio wiphy1
|
||||
--debug
|
||||
''')
|
||||
|
||||
args = parser.parse_args()
|
||||
num_sta = 2
|
||||
if (args.num_stations is not None) and (int(args.num_stations) > 0):
|
||||
num_stations_converted = int(args.num_stations)
|
||||
num_sta = num_stations_converted
|
||||
|
||||
station_list = LFUtils.portNameSeries(prefix_="sta",
|
||||
start_id_=0,
|
||||
end_id_=num_sta-1,
|
||||
padding_number_=10000,
|
||||
radio=args.radio)
|
||||
|
||||
ip_test = IPv4Test(host=args.mgr, port=args.mgr_port, ssid=args.ssid, password=args.passwd, radio=args.radio,
|
||||
security="wpa", sta_list=station_list)
|
||||
ip_test.cleanup(station_list)
|
||||
ip_test.timeout = 60
|
||||
ip_test.build()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
381
py-scripts/ftp_html.py
Normal file
381
py-scripts/ftp_html.py
Normal file
@@ -0,0 +1,381 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from matplotlib import pyplot as plt
|
||||
from datetime import datetime
|
||||
import numpy as np
|
||||
import os.path
|
||||
from os import path
|
||||
import sys
|
||||
import pdfkit
|
||||
sys.path.append('/home/lanforge/.local/lib/python3.6/site-packages')
|
||||
def report_banner(date):
|
||||
banner_data = """
|
||||
<!DOCTYPE html>
|
||||
<html lang='en'>
|
||||
<head>
|
||||
<meta charset='UTF-8'>
|
||||
<meta name='viewport' content='width=device-width, initial-scale=1' />
|
||||
<title>LANforge Report</title>
|
||||
</head>
|
||||
<title>FTP Test </title></head>
|
||||
<body>
|
||||
<div class='Section report_banner-1000x205' style='background-image:url("/home/lanforge/LANforgeGUI_5.4.3/images/report_banner-1000x205.jpg");background-repeat:no-repeat;padding:0;margin:0;min-width:1000px; min-height:205px;width:1000px; height:205px;max-width:1000px; max-height:205px;'>
|
||||
<br>
|
||||
<img align='right' style='padding:25;margin:5;width:200px;' src="/home/lanforge/LANforgeGUI_5.4.3/images/CandelaLogo2-90dpi-200x90-trans.png" border='0' />
|
||||
<div class='HeaderStyle'>
|
||||
<br>
|
||||
<h1 class='TitleFontPrint' style='color:darkgreen;'> FTP Test </h1>
|
||||
<h3 class='TitleFontPrint' style='color:darkgreen;'>""" + str(date) + """</h3>
|
||||
</div>
|
||||
</div>
|
||||
<br><br>
|
||||
"""
|
||||
return str(banner_data)
|
||||
def test_objective(objective= 'This FTP Test is used to "Verify that N clients connected on Specified band and can simultaneously download some amount of file from FTP server and measuring the time taken by client to Download/Upload the file."'):
|
||||
test_objective = """
|
||||
<!-- Test Objective -->
|
||||
<h3 align='left'>Objective</h3>
|
||||
<p align='left' width='900'>""" + str(objective) + """</p>
|
||||
<br>
|
||||
"""
|
||||
return str(test_objective)
|
||||
def test_setup_information(test_setup_data=None):
|
||||
if test_setup_data is None:
|
||||
return None
|
||||
else:
|
||||
var = ""
|
||||
for i in test_setup_data:
|
||||
var = var + "<tr><td>" + i + "</td><td colspan='3'>" + str(test_setup_data[i]) + "</td></tr>"
|
||||
|
||||
setup_information = """
|
||||
<!-- Test Setup Information -->
|
||||
<table width='700px' border='1' cellpadding='2' cellspacing='0' style='border-top-color: gray; border-top-style: solid; border-top-width: 1px; border-right-color: gray; border-right-style: solid; border-right-width: 1px; border-bottom-color: gray; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: gray; border-left-style: solid; border-left-width: 1px'>
|
||||
<tr>
|
||||
<th colspan='2'>Test Setup Information</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Device Under Test</td>
|
||||
<td>
|
||||
<table width='100%' border='0' cellpadding='2' cellspacing='0' style='border-top-color: gray; border-top-style: solid; border-top-width: 1px; border-right-color: gray; border-right-style: solid; border-right-width: 1px; border-bottom-color: gray; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: gray; border-left-style: solid; border-left-width: 1px'>
|
||||
""" + str(var) + """
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
"""
|
||||
return str(setup_information)
|
||||
|
||||
|
||||
def pass_fail_description(data=" This Table will give Pass/Fail results. "):
|
||||
pass_fail_info = """
|
||||
<!-- Radar Detect status -->
|
||||
<h3 align='left'>PASS/FAIL Results</h3>
|
||||
<p align='left' width='900'>""" + str(data) + """</p>
|
||||
<br>
|
||||
"""
|
||||
return str(pass_fail_info)
|
||||
|
||||
|
||||
def download_upload_time_description(data=" This Table will FTP Download/Upload Time of Clients."):
|
||||
download_upload_time= """
|
||||
<!-- Radar Detect status -->
|
||||
<h3 align='left'>File Download/Upload Time (sec)</h3>
|
||||
<p align='left' width='900'>""" + str(data) + """</p>
|
||||
<br>
|
||||
"""
|
||||
return str(download_upload_time)
|
||||
|
||||
|
||||
def add_pass_fail_table(result_data, row_head_list, col_head_list):
|
||||
var_row = "<th></th>"
|
||||
for row in col_head_list:
|
||||
var_row = var_row + "<th>" + str(row) + "</th>"
|
||||
list_data = []
|
||||
dict_data = {}
|
||||
bands = result_data[1]["bands"]
|
||||
file_sizes = result_data[1]["file_sizes"]
|
||||
directions = result_data[1]["directions"]
|
||||
for b in bands:
|
||||
final_data = ""
|
||||
for size in file_sizes:
|
||||
for d in directions:
|
||||
for data in result_data.values():
|
||||
if data["band"] == b and data["direction"] == d and data["file_size"] == size:
|
||||
if data["result"] == "Pass":
|
||||
final_data = final_data + "<td style='background-color:Green'>Pass</td>"
|
||||
elif data["result"] == "Fail":
|
||||
final_data = final_data + "<td style='background-color:Red'>Fail</td>"
|
||||
|
||||
list_data.append(final_data)
|
||||
|
||||
#print(list_data)
|
||||
j = 0
|
||||
for i in row_head_list:
|
||||
dict_data[i] = list_data[j]
|
||||
j = j + 1
|
||||
#print(dict_data)
|
||||
var_col = ""
|
||||
for col in row_head_list:
|
||||
var_col = var_col + "<tr><td>" + str(col) + "</td><!-- Add Variable Here -->" + str(
|
||||
dict_data[col]) + "</tr>"
|
||||
|
||||
pass_fail_table = """
|
||||
<!-- Radar Detected Table -->
|
||||
<table width='1000px' border='1' cellpadding='2' cellspacing='0' >
|
||||
|
||||
<table width='1000px' border='1' >
|
||||
<tr>
|
||||
""" + str(var_row) + """
|
||||
</tr>
|
||||
""" + str(var_col) + """
|
||||
</table>
|
||||
</table>
|
||||
<br><br><br><br><br><br><br>
|
||||
"""
|
||||
return pass_fail_table
|
||||
|
||||
|
||||
def download_upload_time_table(result_data, row_head_list, col_head_list):
|
||||
var_row = "<th></th>"
|
||||
for row in col_head_list:
|
||||
var_row = var_row + "<th>" + str(row) + "</th>"
|
||||
list_data = []
|
||||
dict_data = {}
|
||||
bands = result_data[1]["bands"]
|
||||
file_sizes = result_data[1]["file_sizes"]
|
||||
directions = result_data[1]["directions"]
|
||||
for b in bands:
|
||||
final_data = ""
|
||||
for size in file_sizes:
|
||||
for d in directions:
|
||||
for data in result_data.values():
|
||||
data_time = data['time']
|
||||
if data_time.count(0) == 0:
|
||||
Min = min(data_time)
|
||||
Max = max(data_time)
|
||||
Sum = int(sum(data_time))
|
||||
Len = len(data_time)
|
||||
Avg = round(Sum / Len,2)
|
||||
elif data_time.count(0) == len(data_time):
|
||||
Min = "-"
|
||||
Max = "-"
|
||||
Avg = "-"
|
||||
else:
|
||||
data_time = [i for i in data_time if i != 0]
|
||||
Min = min(data_time)
|
||||
Max = max(data_time)
|
||||
Sum = int(sum(data_time))
|
||||
Len = len(data_time)
|
||||
Avg = round(Sum / Len,2)
|
||||
string_data = "Min=" + str(Min) + ",Max=" + str(Max) + ",Avg=" + str(Avg) + " (sec)"
|
||||
if data["band"] == b and data["direction"] == d and data["file_size"] == size:
|
||||
final_data = final_data + """<td>""" + string_data + """</td>"""
|
||||
|
||||
list_data.append(final_data)
|
||||
|
||||
#print(list_data)
|
||||
j = 0
|
||||
for i in row_head_list:
|
||||
dict_data[i] = list_data[j]
|
||||
j = j + 1
|
||||
#print(dict_data)
|
||||
var_col = ""
|
||||
for col in row_head_list:
|
||||
var_col = var_col + "<tr><td>" + str(col) + "</td><!-- Add Variable Here -->" + str(
|
||||
dict_data[col]) + "</tr>"
|
||||
|
||||
download_upload_table = """
|
||||
<!-- Radar Detected Table -->
|
||||
<table width='1000px' border='1' cellpadding='2' cellspacing='0' >
|
||||
|
||||
<table width='1000px' border='1' >
|
||||
<tr>
|
||||
""" + str(var_row) + """
|
||||
</tr>
|
||||
""" + str(var_col) + """
|
||||
</table>
|
||||
</table>
|
||||
<br><br><br><br><br><br><br>
|
||||
"""
|
||||
return download_upload_table
|
||||
def graph_html(graph_path="",graph_name="",graph_description=""):
|
||||
graph_html_obj = """
|
||||
<h3>""" +graph_name+ """</h3>
|
||||
<p>""" +graph_description+ """</p>
|
||||
<img align='center' style='padding:15;margin:5;width:1000px;' src=""" + graph_path + """ border='1' />
|
||||
<br><br>
|
||||
"""
|
||||
return str(graph_html_obj)
|
||||
|
||||
|
||||
def bar_plot(ax,x_axis, data, colors=None, total_width=0.8, single_width=1, legend=True):
|
||||
# Check if colors where provided, otherwhise use the default color cycle
|
||||
if colors is None:
|
||||
colors = plt.rcParams['axes.prop_cycle'].by_key()['color']
|
||||
|
||||
# Number of bars per group
|
||||
n_bars = len(data)
|
||||
|
||||
# The width of a single bar
|
||||
bar_width = total_width / n_bars
|
||||
|
||||
# List containing handles for the drawn bars, used for the legend
|
||||
bars = []
|
||||
|
||||
# Iterate over all data
|
||||
for i, (name, values) in enumerate(data.items()):
|
||||
# The offset in x direction of that bar
|
||||
x_offset = (i - n_bars / 2) * bar_width + bar_width / 2
|
||||
|
||||
# Draw a bar for every value of that type
|
||||
for x, y in enumerate(values):
|
||||
bar = ax.bar(x + x_offset, y, width=bar_width * single_width, color=colors[i % len(colors)])
|
||||
|
||||
# Add a handle to the last drawn bar, which we'll need for the legend
|
||||
bars.append(bar[0])
|
||||
|
||||
# Draw legend if we need
|
||||
if legend:
|
||||
ax.legend(bars, data.keys(),bbox_to_anchor=(1.1,1.05),loc='upper right')
|
||||
ax.set_ylabel('Time in seconds')
|
||||
ax.set_xlabel("stations")
|
||||
x_data = x_axis
|
||||
idx = np.asarray([i for i in range(len(x_data))])
|
||||
ax.set_xticks(idx)
|
||||
|
||||
ax.set_xticklabels(x_data)
|
||||
|
||||
def generate_graph(result_data, x_axis,band,size,graph_path):
|
||||
# bands = result_data[1]["bands"]
|
||||
# file_sizes = result_data[1]["file_sizes"]
|
||||
num_stations = result_data[1]["num_stations"]
|
||||
# for b in bands:
|
||||
# for size in file_sizes:
|
||||
|
||||
dict_of_graph = {}
|
||||
color = []
|
||||
graph_name = ""
|
||||
graph_description=""
|
||||
count = 0
|
||||
for data in result_data.values():
|
||||
if data["band"] == band and data["file_size"] == size and data["direction"] == "Download":
|
||||
dict_of_graph["Download"] = data["time"]
|
||||
color.append("Orange")
|
||||
graph_name = "File size "+ size +" " + str(num_stations) + " Clients " +band+ "-File Download Times(secs)"
|
||||
graph_description = "Out of "+ str(data["num_stations"])+ " clients, "+ str(data["num_stations"] - data["time"].count(0))+ " are able to download " + "within " + str(data["duration"]) + " min."
|
||||
count = count + 1
|
||||
if data["band"] == band and data["file_size"] == size and data["direction"] == "Upload":
|
||||
dict_of_graph["Upload"] = data["time"]
|
||||
color.append("Blue")
|
||||
graph_name = "File size "+ size +" " + str(num_stations) + " Clients " +band+ "-File Upload Times(secs)"
|
||||
graph_description = graph_description + "Out of " + str(data["num_stations"]) + " clients, " + str(
|
||||
data["num_stations"] - data["time"].count(0)) + " are able to upload " + "within " +str(data["duration"]) + " min."
|
||||
count = count + 1
|
||||
if count == 2:
|
||||
graph_name = "File size "+ size +" " + str(num_stations) + " Clients " +band+ "-File Download and Upload Times(secs)"
|
||||
if len(dict_of_graph) != 0:
|
||||
fig, ax = plt.subplots()
|
||||
bar_plot(ax, x_axis, dict_of_graph, total_width=.8, single_width=.9, colors=color)
|
||||
my_dpi = 96
|
||||
figure = plt.gcf() # get current figure
|
||||
figure.set_size_inches(18, 6)
|
||||
|
||||
# when saving, specify the DPI
|
||||
plt.savefig(graph_path + "/image"+band+size+".png", dpi=my_dpi)
|
||||
return str(graph_html(graph_path + "/image"+band+size+".png", graph_name,graph_description))
|
||||
else:
|
||||
return ""
|
||||
def input_setup_info_table(input_setup_info=None):
|
||||
if input_setup_info is None:
|
||||
return None
|
||||
else:
|
||||
var = ""
|
||||
for i in input_setup_info:
|
||||
var = var + "<tr><td>" + i + "</td><td colspan='3'>" + str(input_setup_info[i]) + "</td></tr>"
|
||||
|
||||
setup_information = """
|
||||
<!-- Test Setup Information -->
|
||||
<table width='700px' border='1' cellpadding='2' cellspacing='0' style='border-top-color: gray; border-top-style: solid; border-top-width: 1px; border-right-color: gray; border-right-style: solid; border-right-width: 1px; border-bottom-color: gray; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: gray; border-left-style: solid; border-left-width: 1px'>
|
||||
<tr>
|
||||
<th colspan='2'>Input Setup Information</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Information</td>
|
||||
<td>
|
||||
<table width='100%' border='0' cellpadding='2' cellspacing='0' style='border-top-color: gray; border-top-style: solid; border-top-width: 1px; border-right-color: gray; border-right-style: solid; border-right-width: 1px; border-bottom-color: gray; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: gray; border-left-style: solid; border-left-width: 1px'>
|
||||
""" + str(var) + """
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
"""
|
||||
return str(setup_information)
|
||||
|
||||
|
||||
def generate_report(result_data=None,
|
||||
date=None,
|
||||
test_setup_info={},
|
||||
input_setup_info={},
|
||||
graph_path="/home/lanforge/html-reports/FTP-Test"):
|
||||
# Need to pass this to test_setup_information()
|
||||
input_setup_info = input_setup_info
|
||||
test_setup_data = test_setup_info
|
||||
x_axis = []
|
||||
num_stations = result_data[1]["num_stations"]
|
||||
for i in range(1, num_stations + 1, 1):
|
||||
x_axis.append(i)
|
||||
column_head = []
|
||||
rows_head = []
|
||||
bands = result_data[1]["bands"]
|
||||
file_sizes = result_data[1]["file_sizes"]
|
||||
directions = result_data[1]["directions"]
|
||||
|
||||
for size in file_sizes:
|
||||
for direction in directions:
|
||||
column_head.append(size + " " + direction)
|
||||
for band in bands:
|
||||
if band != "Both":
|
||||
rows_head.append(str(num_stations) + " Clients-" + band)
|
||||
else:
|
||||
rows_head.append(str(num_stations // 2) + "+" + str(num_stations // 2) + " Clients-2.4G+5G")
|
||||
|
||||
reports_root = graph_path + "/" + str(date)
|
||||
if path.exists(graph_path):
|
||||
os.mkdir(reports_root)
|
||||
print("Reports Root is Created")
|
||||
|
||||
else:
|
||||
os.mkdir(graph_path)
|
||||
os.mkdir(reports_root)
|
||||
print("Reports Root is created")
|
||||
print("Generating Reports in : ", reports_root)
|
||||
|
||||
html_report = report_banner(date) + \
|
||||
test_setup_information(test_setup_data) + \
|
||||
test_objective() + \
|
||||
pass_fail_description() + \
|
||||
add_pass_fail_table(result_data, rows_head, column_head) + \
|
||||
download_upload_time_description() + \
|
||||
download_upload_time_table(result_data, rows_head, column_head)
|
||||
|
||||
for b in bands:
|
||||
for size in file_sizes:
|
||||
html_report = html_report + \
|
||||
generate_graph(result_data, x_axis, b, size, graph_path=reports_root)
|
||||
|
||||
html_report = html_report + input_setup_info_table(input_setup_info)
|
||||
|
||||
# write the html_report into a file in /home/lanforge/html_reports in a directory named FTP-Test and html_report name should be having a timesnap with it
|
||||
f = open(reports_root + "/report.html", "a")
|
||||
# f = open("report.html", "a")
|
||||
f.write(html_report)
|
||||
f.close()
|
||||
# write logic to generate pdf here
|
||||
pdfkit.from_file(reports_root + "/report.html", reports_root + "/report.pdf")
|
||||
|
||||
|
||||
# test blocks from here
|
||||
if __name__ == '__main__':
|
||||
generate_report()
|
||||
87
py-scripts/grafana_profile.py
Executable file
87
py-scripts/grafana_profile.py
Executable file
@@ -0,0 +1,87 @@
|
||||
#!/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 GrafanaRequest import GrafanaRequest
|
||||
from LANforge.lfcli_base import LFCliBase
|
||||
|
||||
|
||||
class UseGrafana(LFCliBase):
|
||||
def __init__(self,
|
||||
_grafana_token,
|
||||
host="localhost",
|
||||
_grafana_host="localhost",
|
||||
port=8080,
|
||||
_debug_on=False,
|
||||
_exit_on_fail=False,
|
||||
_grafana_port=3000):
|
||||
super().__init__(host, port, _debug=_debug_on, _exit_on_fail=_exit_on_fail)
|
||||
self.grafana_token = _grafana_token
|
||||
self.grafana_port = _grafana_port
|
||||
self.grafana_host = _grafana_host
|
||||
self.GR = GrafanaRequest(self.grafana_host, str(self.grafana_port), _folderID=0, _api_token=self.grafana_token)
|
||||
|
||||
def create_dashboard(self,
|
||||
dashboard_name):
|
||||
return self.GR.create_dashboard(dashboard_name)
|
||||
|
||||
def delete_dashboard(self,
|
||||
dashboard_uid):
|
||||
return self.GR.delete_dashboard(dashboard_uid)
|
||||
|
||||
def list_dashboards(self):
|
||||
return self.GR.list_dashboards()
|
||||
|
||||
|
||||
def main():
|
||||
parser = LFCliBase.create_basic_argparse(
|
||||
prog='grafana_profile.py',
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
epilog='''Manage Grafana database''',
|
||||
description='''\
|
||||
grafana_profile.py
|
||||
------------------
|
||||
Command example:
|
||||
./grafana_profile.py
|
||||
--grafana_token
|
||||
--''')
|
||||
required = parser.add_argument_group('required arguments')
|
||||
required.add_argument('--grafana_token', help='token to access your Grafana database', required=True)
|
||||
|
||||
optional = parser.add_argument_group('optional arguments')
|
||||
optional.add_argument('--dashboard_name', help='name of dashboard to create', default=None)
|
||||
optional.add_argument('--dashboard_uid', help='UID of dashboard to modify', default=None)
|
||||
optional.add_argument('--delete_dashboard',
|
||||
help='Call this flag to delete the dashboard defined by UID',
|
||||
default=None)
|
||||
optional.add_argument('--grafana_port', help='Grafana port if different from 3000', default=3000)
|
||||
optional.add_argument('--grafana_host', help='Grafana host', default='localhost')
|
||||
optional.add_argument('--list_dashboards', help='List dashboards on Grafana server', default=None)
|
||||
args = parser.parse_args()
|
||||
|
||||
Grafana = UseGrafana(args.grafana_token,
|
||||
args.grafana_port,
|
||||
args.grafana_host
|
||||
)
|
||||
if args.dashboard_name is not None:
|
||||
Grafana.create_dashboard(args.dashboard_name)
|
||||
|
||||
if args.delete_dashboard is not None:
|
||||
Grafana.delete_dashboard(args.dashboard_uid)
|
||||
|
||||
if args.list_dashboards is not None:
|
||||
Grafana.list_dashboards()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
1010
py-scripts/html_template.py
Normal file
1010
py-scripts/html_template.py
Normal file
File diff suppressed because it is too large
Load Diff
78
py-scripts/influx.py
Normal file
78
py-scripts/influx.py
Normal file
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# pip3 install influxdb
|
||||
|
||||
import sys
|
||||
|
||||
if sys.version_info[0] != 3:
|
||||
print("This script requires Python 3")
|
||||
exit(1)
|
||||
|
||||
import requests
|
||||
import json
|
||||
from influxdb import InfluxDBClient
|
||||
import datetime
|
||||
from LANforge.lfcli_base import LFCliBase
|
||||
import time
|
||||
|
||||
|
||||
class RecordInflux(LFCliBase):
|
||||
def __init__(self,
|
||||
_lfjson_host="lanforge",
|
||||
_lfjson_port=8080,
|
||||
_influx_host="localhost",
|
||||
_influx_port=8086,
|
||||
_influx_user=None,
|
||||
_influx_passwd=None,
|
||||
_influx_db=None,
|
||||
_debug_on=False,
|
||||
_exit_on_fail=False):
|
||||
super().__init__(_lfjson_host, _lfjson_port,
|
||||
_debug=_debug_on,
|
||||
_exit_on_fail=_exit_on_fail)
|
||||
self.influx_host = _influx_host
|
||||
self.influx_port = _influx_port
|
||||
self.influx_user = _influx_user
|
||||
self.influx_passwd = _influx_passwd
|
||||
self.influx_db = _influx_db
|
||||
self.client = InfluxDBClient(self.influx_host,
|
||||
self.influx_port,
|
||||
self.influx_user,
|
||||
self.influx_passwd,
|
||||
self.influx_db)
|
||||
|
||||
def post_to_influx(self, key, value, tags):
|
||||
data = dict()
|
||||
data["measurement"] = key
|
||||
data["tags"] = tags
|
||||
data["time"] = str(datetime.datetime.utcnow().isoformat())
|
||||
data["fields"] = dict()
|
||||
data["fields"]["value"] = value
|
||||
data1 = [data]
|
||||
self.client.write_points(data1)
|
||||
|
||||
# Don't use this unless you are sure you want to.
|
||||
# More likely you would want to generate KPI in the
|
||||
# individual test cases and poke those relatively small bits of
|
||||
# info into influxdb.
|
||||
# This will not end until the 'longevity' timer has expired.
|
||||
# This function pushes data directly into the Influx database and defaults to all columns.
|
||||
def monitor_port_data(self,
|
||||
lanforge_host="localhost",
|
||||
devices=None,
|
||||
longevity=None,
|
||||
monitor_interval=None):
|
||||
url = 'http://' + lanforge_host + ':8080/port/1/1/'
|
||||
end = datetime.datetime.now() + datetime.timedelta(0, longevity)
|
||||
while datetime.datetime.now() < end:
|
||||
for station in devices:
|
||||
url1 = url + station
|
||||
response = json.loads(requests.get(url1).text)
|
||||
|
||||
# Poke everything into influx db
|
||||
for key in response['interface'].keys():
|
||||
tags = dict()
|
||||
tags["region"] = 'us-west'
|
||||
self.posttoinflux("%s-%s" % (station, key), response['interface'][key], tags)
|
||||
|
||||
time.sleep(monitor_interval)
|
||||
95
py-scripts/influx2.py
Normal file
95
py-scripts/influx2.py
Normal file
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# pip3 install influxdb-client
|
||||
|
||||
# Version 2.0 influx DB Client
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
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 requests
|
||||
import json
|
||||
import influxdb_client
|
||||
from influxdb_client.client.write_api import SYNCHRONOUS
|
||||
import datetime
|
||||
from LANforge.lfcli_base import LFCliBase
|
||||
import time
|
||||
|
||||
class RecordInflux(LFCliBase):
|
||||
def __init__(self,
|
||||
_lfjson_host="lanforge",
|
||||
_lfjson_port=8080,
|
||||
_influx_host="localhost",
|
||||
_influx_port=8086,
|
||||
_influx_org=None,
|
||||
_influx_token=None,
|
||||
_influx_bucket=None,
|
||||
_debug_on=False,
|
||||
_exit_on_fail=False):
|
||||
super().__init__(_lfjson_host, _lfjson_port,
|
||||
_debug=_debug_on,
|
||||
_exit_on_fail=_exit_on_fail)
|
||||
self.influx_host = _influx_host
|
||||
self.influx_port = _influx_port
|
||||
self.influx_org = _influx_org
|
||||
self.influx_token = _influx_token
|
||||
self.influx_bucket = _influx_bucket
|
||||
self.url = "http://%s:%s"%(self.influx_host, self.influx_port)
|
||||
self.client = influxdb_client.InfluxDBClient(url=self.url,
|
||||
token=self.influx_token,
|
||||
org=self.influx_org,
|
||||
debug=_debug_on)
|
||||
self.write_api = self.client.write_api(write_options=SYNCHRONOUS)
|
||||
#print("org: ", self.influx_org)
|
||||
#print("token: ", self.influx_token)
|
||||
#print("bucket: ", self.influx_bucket)
|
||||
#exit(0)
|
||||
|
||||
def post_to_influx(self, key, value, tags, time):
|
||||
p = influxdb_client.Point(key)
|
||||
for tag_key, tag_value in tags.items():
|
||||
p.tag(tag_key, tag_value)
|
||||
print(tag_key, tag_value)
|
||||
p.time(time)
|
||||
p.field("value", value)
|
||||
self.write_api.write(bucket=self.influx_bucket, org=self.influx_org, record=p)
|
||||
|
||||
def set_bucket(self, b):
|
||||
self.influx_bucket = b
|
||||
|
||||
# Don't use this unless you are sure you want to.
|
||||
# More likely you would want to generate KPI in the
|
||||
# individual test cases and poke those relatively small bits of
|
||||
# info into influxdb.
|
||||
# This will not end until the 'longevity' timer has expired.
|
||||
# This function pushes data directly into the Influx database and defaults to all columns.
|
||||
def monitor_port_data(self,
|
||||
lanforge_host="localhost",
|
||||
devices=None,
|
||||
longevity=None,
|
||||
monitor_interval=None,
|
||||
bucket=None,
|
||||
tags=None): # dict
|
||||
url = 'http://' + lanforge_host + ':8080/port/1/1/'
|
||||
end = datetime.datetime.now() + datetime.timedelta(0, longevity)
|
||||
while datetime.datetime.now() < end:
|
||||
for station in devices:
|
||||
url1 = url + station
|
||||
response = json.loads(requests.get(url1).text)
|
||||
|
||||
current_time = str(datetime.datetime.utcnow().isoformat())
|
||||
|
||||
# Poke everything into influx db
|
||||
for key in response['interface'].keys():
|
||||
self.post_to_influx("%s-%s" % (station, key), response['interface'][key], tags, current_time)
|
||||
|
||||
time.sleep(monitor_interval)
|
||||
370
py-scripts/lf_ap_auto_test.py
Executable file
370
py-scripts/lf_ap_auto_test.py
Executable file
@@ -0,0 +1,370 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
Note: To Run this script gui should be opened with
|
||||
|
||||
path: cd LANforgeGUI_5.4.3 (5.4.3 can be changed with GUI version)
|
||||
pwd (Output : /home/lanforge/LANforgeGUI_5.4.3)
|
||||
./lfclient.bash -cli-socket 3990
|
||||
|
||||
This script is used to automate running AP-Auto tests. You
|
||||
may need to view an AP Auto test configured through the GUI to understand
|
||||
the options and how best to input data.
|
||||
|
||||
./lf_ap_auto_test.py --mgr localhost --port 8080 --lf_user lanforge --lf_password lanforge \
|
||||
--instance_name ap-auto-instance --config_name test_con --upstream 1.1.eth2 \
|
||||
--dut5_0 'linksys-8450 Default-SSID-5gl c4:41:1e:f5:3f:25 (2)' \
|
||||
--dut2_0 'linksys-8450 Default-SSID-2g c4:41:1e:f5:3f:24 (1)' \
|
||||
--max_stations_2 100 --max_stations_5 100 --max_stations_dual 200 \
|
||||
--radio2 1.1.wiphy0 --radio2 1.1.wiphy2 \
|
||||
--radio5 1.1.wiphy1 --radio5 1.1.wiphy3 --radio5 1.1.wiphy4 \
|
||||
--radio5 1.1.wiphy5 --radio5 1.1.wiphy6 --radio5 1.1.wiphy7 \
|
||||
--set 'Basic Client Connectivity' 1 --set 'Multi Band Performance' 1 \
|
||||
--set 'Skip 2.4Ghz Tests' 1 --set 'Skip 5Ghz Tests' 1 \
|
||||
--set 'Throughput vs Pkt Size' 0 --set 'Capacity' 0 --set 'Stability' 0 --set 'Band-Steering' 0 \
|
||||
--set 'Multi-Station Throughput vs Pkt Size' 0 --set 'Long-Term' 0 \
|
||||
--test_rig Testbed-01 --pull_report \
|
||||
--influx_host c7-graphana --influx_port 8086 --influx_org Candela \
|
||||
--influx_token=-u_Wd-L8o992701QF0c5UmqEp7w7Z7YOMaWLxOMgmHfATJGnQbbmYyNxHBR9PgD6taM_tcxqJl6U8DjU1xINFQ== \
|
||||
--influx_bucket ben \
|
||||
--influx_tag testbed Ferndale-01
|
||||
|
||||
Note:
|
||||
--enable [option] will attempt to select any checkbox of that name to true.
|
||||
--disable [option] will attempt to un-select any checkbox of that name to true.
|
||||
--raw_line 'line contents' will add any setting to the test config. This is
|
||||
useful way to support any options not specifically enabled by the
|
||||
command options.
|
||||
--set modifications will be applied after the other config has happened,
|
||||
so it can be used to override any other config.
|
||||
|
||||
Example of raw text config for ap-auto, to show other possible options:
|
||||
|
||||
sel_port-0: 1.1.sta00500
|
||||
show_events: 1
|
||||
show_log: 0
|
||||
port_sorting: 0
|
||||
kpi_id: AP Auto
|
||||
bg: 0xE0ECF8
|
||||
test_rig: Ferndale-01-Basic
|
||||
show_scan: 1
|
||||
auto_helper: 1
|
||||
skip_2: 1
|
||||
skip_5: 1
|
||||
skip_5b: 1
|
||||
skip_dual: 0
|
||||
skip_tri: 1
|
||||
dut5b-0: NA
|
||||
dut5-0: linksys-8450 Default-SSID-5gl c4:41:1e:f5:3f:25 (2)
|
||||
dut2-0: linksys-8450 Default-SSID-2g c4:41:1e:f5:3f:24 (1)
|
||||
dut5b-1: NA
|
||||
dut5-1: NA
|
||||
dut2-1: NA
|
||||
dut5b-2: NA
|
||||
dut5-2: NA
|
||||
dut2-2: NA
|
||||
spatial_streams: AUTO
|
||||
bandw_options: AUTO
|
||||
modes: Auto
|
||||
upstream_port: 1.1.2 eth2
|
||||
operator:
|
||||
mconn: 1
|
||||
tos: 0
|
||||
vid_buf: 1000000
|
||||
vid_speed: 700000
|
||||
reset_stall_thresh_udp_dl: 9600
|
||||
cx_prcnt: 950000
|
||||
cx_open_thresh: 35
|
||||
cx_psk_thresh: 75
|
||||
cx_1x_thresh: 130
|
||||
reset_stall_thresh_udp_ul: 9600
|
||||
reset_stall_thresh_tcp_dl: 9600
|
||||
reset_stall_thresh_tcp_ul: 9600
|
||||
reset_stall_thresh_l4: 100000
|
||||
reset_stall_thresh_voip: 20000
|
||||
stab_mcast_dl_min: 100000
|
||||
stab_mcast_dl_max: 0
|
||||
stab_udp_dl_min: 56000
|
||||
stab_udp_dl_max: 0
|
||||
stab_udp_ul_min: 56000
|
||||
stab_udp_ul_max: 0
|
||||
stab_tcp_dl_min: 500000
|
||||
stab_tcp_dl_max: 0
|
||||
stab_tcp_ul_min: 500000
|
||||
stab_tcp_ul_max: 0
|
||||
dl_speed: 85%
|
||||
ul_speed: 85%
|
||||
max_stations_2: 100
|
||||
max_stations_5: 100
|
||||
max_stations_5b: 64
|
||||
max_stations_dual: 200
|
||||
max_stations_tri: 64
|
||||
lt_sta: 2
|
||||
voip_calls: 0
|
||||
lt_dur: 3600
|
||||
reset_dur: 600
|
||||
lt_gi: 30
|
||||
dur20: 20
|
||||
hunt_retries: 1
|
||||
hunt_iter: 15
|
||||
bind_bssid: 1
|
||||
set_txpower_default: 0
|
||||
cap_dl: 1
|
||||
cap_ul: 0
|
||||
cap_use_pkt_sizes: 0
|
||||
stability_reset_radios: 0
|
||||
stability_use_pkt_sizes: 0
|
||||
pkt_loss_thresh: 10000
|
||||
frame_sizes: 200, 512, 1024, MTU
|
||||
capacities: 1, 2, 5, 10, 20, 40, 64, 128, 256, 512, 1024, MAX
|
||||
pf_text0: 2.4 DL 200 70Mbps
|
||||
pf_text1: 2.4 DL 512 110Mbps
|
||||
pf_text2: 2.4 DL 1024 115Mbps
|
||||
pf_text3: 2.4 DL MTU 120Mbps
|
||||
pf_text4:
|
||||
pf_text5: 2.4 UL 200 88Mbps
|
||||
pf_text6: 2.4 UL 512 106Mbps
|
||||
pf_text7: 2.4 UL 1024 115Mbps
|
||||
pf_text8: 2.4 UL MTU 120Mbps
|
||||
pf_text9:
|
||||
pf_text10: 5 DL 200 72Mbps
|
||||
pf_text11: 5 DL 512 185Mbps
|
||||
pf_text12: 5 DL 1024 370Mbps
|
||||
pf_text13: 5 DL MTU 525Mbps
|
||||
pf_text14:
|
||||
pf_text15: 5 UL 200 90Mbps
|
||||
pf_text16: 5 UL 512 230Mbps
|
||||
pf_text17: 5 UL 1024 450Mbps
|
||||
pf_text18: 5 UL MTU 630Mbps
|
||||
radio2-0: 1.1.4 wiphy0
|
||||
radio2-1: 1.1.6 wiphy2
|
||||
radio5-0: 1.1.5 wiphy1
|
||||
radio5-1: 1.1.7 wiphy3
|
||||
radio5-2: 1.1.8 wiphy4
|
||||
radio5-3: 1.1.9 wiphy5
|
||||
radio5-4: 1.1.10 wiphy6
|
||||
radio5-5: 1.1.11 wiphy7
|
||||
basic_cx: 0
|
||||
tput: 0
|
||||
tput_multi: 0
|
||||
tput_multi_tcp: 1
|
||||
tput_multi_udp: 1
|
||||
tput_multi_dl: 1
|
||||
tput_multi_ul: 1
|
||||
dual_band_tput: 1
|
||||
capacity: 0
|
||||
band_steering: 0
|
||||
longterm: 0
|
||||
mix_stability: 0
|
||||
loop_iter: 1
|
||||
reset_batch_size: 1
|
||||
reset_duration_min: 10000
|
||||
reset_duration_max: 60000
|
||||
bandsteer_always_5g: 0
|
||||
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import argparse
|
||||
import time
|
||||
import json
|
||||
from os import path
|
||||
|
||||
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'))
|
||||
|
||||
from cv_test_manager import cv_test as cvtest
|
||||
from cv_test_manager import *
|
||||
from cv_commands import chamberview as cv
|
||||
|
||||
|
||||
class ApAutoTest(cvtest):
|
||||
def __init__(self,
|
||||
lf_host="localhost",
|
||||
lf_port=8080,
|
||||
lf_user="lanforge",
|
||||
lf_password="lanforge",
|
||||
instance_name="ap_auto_instance",
|
||||
config_name="ap_auto_config",
|
||||
upstream="1.1.eth1",
|
||||
pull_report=False,
|
||||
dut5_0="NA",
|
||||
dut2_0="NA",
|
||||
load_old_cfg=False,
|
||||
max_stations_2=100,
|
||||
max_stations_5=100,
|
||||
max_stations_dual=200,
|
||||
radio2=[],
|
||||
radio5=[],
|
||||
enables=[],
|
||||
disables=[],
|
||||
raw_lines=[],
|
||||
raw_lines_file="",
|
||||
sets=[],
|
||||
):
|
||||
super().__init__(lfclient_host=lf_host, lfclient_port=lf_port)
|
||||
|
||||
self.lf_host = lf_host
|
||||
self.lf_port = lf_port
|
||||
self.lf_user = lf_user
|
||||
self.lf_password =lf_password
|
||||
self.createCV = cv(lf_host, lf_port);
|
||||
self.instance_name = instance_name
|
||||
self.config_name = config_name
|
||||
self.upstream = upstream
|
||||
self.pull_report = pull_report
|
||||
self.load_old_cfg = load_old_cfg
|
||||
self.test_name = "AP-Auto"
|
||||
self.dut5_0 = dut5_0
|
||||
self.dut2_0 = dut2_0
|
||||
self.max_stations_2 = max_stations_2
|
||||
self.max_stations_5 = max_stations_5
|
||||
self.max_stations_dual = max_stations_dual
|
||||
self.radio2 = radio2
|
||||
self.radio5 = radio5
|
||||
self.enables = enables
|
||||
self.disables = disables
|
||||
self.raw_lines = raw_lines
|
||||
self.raw_lines_file = raw_lines_file
|
||||
self.sets = sets
|
||||
|
||||
def setup(self):
|
||||
# Nothing to do at this time.
|
||||
return
|
||||
|
||||
|
||||
def run(self):
|
||||
self.createCV.sync_cv()
|
||||
time.sleep(2)
|
||||
self.createCV.sync_cv()
|
||||
|
||||
blob_test = "%s-"%(self.test_name)
|
||||
|
||||
self.rm_text_blob(self.config_name, blob_test) # To delete old config with same name
|
||||
self.show_text_blob(None, None, False)
|
||||
|
||||
# Test related settings
|
||||
cfg_options = []
|
||||
|
||||
ridx = 0
|
||||
for r in self.radio2:
|
||||
cfg_options.append("radio2-%i: %s"%(ridx, r[0]))
|
||||
ridx += 1
|
||||
|
||||
ridx = 0
|
||||
for r in self.radio5:
|
||||
cfg_options.append("radio5-%i: %s"%(ridx, r[0]))
|
||||
ridx += 1
|
||||
|
||||
self.apply_cfg_options(cfg_options, self.enables, self.disables, self.raw_lines, self.raw_lines_file)
|
||||
|
||||
# Command line args take precedence.
|
||||
if self.upstream != "":
|
||||
cfg_options.append("upstream_port: " + self.upstream)
|
||||
if self.dut5_0 != "":
|
||||
cfg_options.append("dut5-0: " + self.dut5_0)
|
||||
if self.dut2_0 != "":
|
||||
cfg_options.append("dut2-0: " + self.dut2_0)
|
||||
if self.max_stations_2 != -1:
|
||||
cfg_options.append("max_stations_2: " + str(self.max_stations_2))
|
||||
if self.max_stations_5 != -1:
|
||||
cfg_options.append("max_stations_5: " + str(self.max_stations_5))
|
||||
if self.max_stations_dual != -1:
|
||||
cfg_options.append("max_stations_dual: " + str(self.max_stations_dual))
|
||||
|
||||
# We deleted the scenario earlier, now re-build new one line at a time.
|
||||
self.build_cfg(self.config_name, blob_test, cfg_options)
|
||||
|
||||
cv_cmds = []
|
||||
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,
|
||||
cv_cmds)
|
||||
|
||||
self.rm_text_blob(self.config_name, blob_test) # To delete old config with same name
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
parser = argparse.ArgumentParser("""
|
||||
Open this file in an editor and read the top notes for more details.
|
||||
|
||||
Example:
|
||||
./lf_ap_auto_test.py --mgr localhost --port 8080 --lf_user lanforge --lf_password lanforge \
|
||||
--instance_name ap-auto-instance --config_name test_con --upstream 1.1.eth2 \
|
||||
--dut5_0 'linksys-8450 Default-SSID-5gl c4:41:1e:f5:3f:25 (2)' \
|
||||
--dut2_0 'linksys-8450 Default-SSID-2g c4:41:1e:f5:3f:24 (1)' \
|
||||
--max_stations_2 100 --max_stations_5 100 --max_stations_dual 200 \
|
||||
--radio2 1.1.wiphy0 --radio2 1.1.wiphy2 \
|
||||
--radio5 1.1.wiphy1 --radio5 1.1.wiphy3 --radio5 1.1.wiphy4 \
|
||||
--radio5 1.1.wiphy5 --radio5 1.1.wiphy6 --radio5 1.1.wiphy7 \
|
||||
--set 'Basic Client Connectivity' 1 --set 'Multi Band Performance' 1 \
|
||||
--set 'Skip 2.4Ghz Tests' 1 --set 'Skip 5Ghz Tests' 1 \
|
||||
--set 'Throughput vs Pkt Size' 0 --set 'Capacity' 0 --set 'Stability' 0 --set 'Band-Steering' 0 \
|
||||
--set 'Multi-Station Throughput vs Pkt Size' 0 --set 'Long-Term' 0 \
|
||||
--test_rig Testbed-01 --pull_report \
|
||||
--influx_host c7-graphana --influx_port 8086 --influx_org Candela \
|
||||
--influx_token=-u_Wd-L8o992701QF0c5UmqEp7w7Z7YOMaWLxOMgmHfATJGnQbbmYyNxHBR9PgD6taM_tcxqJl6U8DjU1xINFQ== \
|
||||
--influx_bucket ben \
|
||||
--influx_tag testbed Ferndale-01
|
||||
"""
|
||||
)
|
||||
cv_add_base_parser(parser) # see cv_test_manager.py
|
||||
|
||||
parser.add_argument("-u", "--upstream", type=str, default="",
|
||||
help="Upstream port for wifi capacity test ex. 1.1.eth1")
|
||||
|
||||
parser.add_argument("--max_stations_2", type=int, default=-1,
|
||||
help="Specify maximum 2.4Ghz stations")
|
||||
parser.add_argument("--max_stations_5", type=int, default=-1,
|
||||
help="Specify maximum 5Ghz stations")
|
||||
parser.add_argument("--max_stations_dual", type=int, default=-1,
|
||||
help="Specify maximum stations for dual-band tests")
|
||||
parser.add_argument("--dut5_0", type=str, default="",
|
||||
help="Specify 5Ghz DUT entry. Syntax is somewhat tricky: DUT-name SSID BSID (bssid-idx), example: linksys-8450 Default-SSID-5gl c4:41:1e:f5:3f:25 (2)")
|
||||
parser.add_argument("--dut2_0", type=str, default="",
|
||||
help="Specify 5Ghz DUT entry. Syntax is somewhat tricky: DUT-name SSID BSID (bssid-idx), example: linksys-8450 Default-SSID-2g c4:41:1e:f5:3f:24 (1)")
|
||||
|
||||
parser.add_argument("--radio2", action='append', nargs=1, default=[],
|
||||
help="Specify 2.4Ghz radio. May be specified multiple times.")
|
||||
parser.add_argument("--radio5", action='append', nargs=1, default=[],
|
||||
help="Specify 5Ghz radio. May be specified multiple times.")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
cv_base_adjust_parser(args)
|
||||
|
||||
CV_Test = ApAutoTest(lf_host = args.mgr,
|
||||
lf_port = args.port,
|
||||
lf_user = args.lf_user,
|
||||
lf_password = args.lf_password,
|
||||
instance_name = args.instance_name,
|
||||
config_name = args.config_name,
|
||||
upstream = args.upstream,
|
||||
pull_report = args.pull_report,
|
||||
dut5_0 = args.dut5_0,
|
||||
dut2_0 = args.dut2_0,
|
||||
load_old_cfg = args.load_old_cfg,
|
||||
max_stations_2 = args.max_stations_2,
|
||||
max_stations_5 = args.max_stations_5,
|
||||
max_stations_dual = args.max_stations_dual,
|
||||
radio2 = args.radio2,
|
||||
radio5 = args.radio5,
|
||||
enables = args.enable,
|
||||
disables = args.disable,
|
||||
raw_lines = args.raw_line,
|
||||
raw_lines_file = args.raw_lines_file,
|
||||
sets = args.set
|
||||
)
|
||||
CV_Test.setup()
|
||||
CV_Test.run()
|
||||
|
||||
CV_Test.check_influx_kpi(args)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,327 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
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
|
||||
import time
|
||||
import test_l3_longevity as DFS
|
||||
|
||||
|
||||
def valid_endp_types(_endp_type):
|
||||
etypes = _endp_type.split()
|
||||
for endp_type in etypes:
|
||||
valid_endp_type=['lf_udp','lf_udp6','lf_tcp','lf_tcp6','mc_udp','mc_udp6']
|
||||
if not (str(endp_type) in valid_endp_type):
|
||||
print('invalid endp_type: %s. Valid types lf_udp, lf_udp6, lf_tcp, lf_tcp6, mc_udp, mc_udp6' % endp_type)
|
||||
exit(1)
|
||||
return _endp_type
|
||||
|
||||
def main():
|
||||
lfjson_host = "localhost"
|
||||
lfjson_port = 8080
|
||||
endp_types = "lf_udp"
|
||||
debug_on = False
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
prog='lf_cisco_dfs.py',
|
||||
#formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
epilog='''\
|
||||
Useful Information:
|
||||
1. Polling interval for checking traffic is fixed at 1 minute
|
||||
2. The test will generate csv file
|
||||
3. The tx/rx rates are fixed at 256000 bits per second
|
||||
4. Maximum stations per radio is 64
|
||||
''',
|
||||
|
||||
description='''\
|
||||
lf_cisco_dfs.py:
|
||||
--------------------
|
||||
|
||||
Summary :
|
||||
----------
|
||||
create stations, create traffic between upstream port and stations, run traffic.
|
||||
The traffic on the stations will be checked once per minute to verify that traffic is transmitted
|
||||
and recieved.
|
||||
|
||||
Generic command layout:
|
||||
-----------------------
|
||||
python .\\lf_cisco_dfs.py --test_duration <duration> --endp_type <traffic types> --upstream_port <port>
|
||||
--radio "radio==<radio> stations==<number staions> ssid==<ssid> ssid_pw==<ssid password> security==<security type: wpa2, open, wpa3>" --debug
|
||||
Multiple radios may be entered with individual --radio switches
|
||||
|
||||
generiic command with controller setting channel and channel width test duration 5 min
|
||||
python3 lf_cisco_dfs.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>"
|
||||
--duration 5m
|
||||
|
||||
|
||||
<duration>: number followed by one of the following
|
||||
d - days
|
||||
h - hours
|
||||
m - minutes
|
||||
s - seconds
|
||||
|
||||
<traffic type>:
|
||||
lf_udp : IPv4 UDP traffic
|
||||
lf_tcp : IPv4 TCP traffic
|
||||
lf_udp6 : IPv6 UDP traffic
|
||||
lf_tcp6 : IPv6 TCP traffic
|
||||
mc_udp : IPv4 multi cast UDP traffic
|
||||
mc_udp6 : IPv6 multi cast UDP traffic
|
||||
|
||||
<tos>:
|
||||
BK, BE, VI, VO: Optional wifi related Tos Settings. Or, use your preferred numeric values.
|
||||
|
||||
#################################
|
||||
#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'
|
||||
--tos: Support different ToS settings: BK | BE | VI | VO | numeric',default="BE"
|
||||
--debug: Enable debugging',default=False
|
||||
-t / --endp_type <types of traffic> example --endp_type \"lf_udp lf_tcp mc_udp\" Default: lf_udp , options: lf_udp, lf_udp6, lf_tcp, lf_tcp6, mc_udp, mc_udp6',
|
||||
default='lf_udp', type=valid_endp_types
|
||||
-u / --upstream_port <cross connect upstream_port> example: --upstream_port eth1',default='eth1')
|
||||
-o / --outfile <Output file for csv data>", default='longevity_results'
|
||||
|
||||
#########################################
|
||||
# Examples
|
||||
# #######################################
|
||||
Example #1 running traffic with two radios
|
||||
1. Test duration 4 minutes
|
||||
2. Traffic IPv4 TCP
|
||||
3. Upstream-port eth1
|
||||
4. Radio #0 wiphy0 has 32 stations, ssid = candelaTech-wpa2-x2048-4-1, ssid password = candelaTech-wpa2-x2048-4-1
|
||||
5. Radio #1 wiphy1 has 64 stations, ssid = candelaTech-wpa2-x2048-5-3, ssid password = candelaTech-wpa2-x2048-5-3
|
||||
6. Create connections with TOS of BK and VI
|
||||
|
||||
Command: (remove carriage returns)
|
||||
python3 .\\lf_cisco_dfs.py --test_duration 4m --endp_type \"lf_tcp lf_udp mc_udp\" --tos \"BK VI\" --upstream_port eth1
|
||||
--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 lf_cisco_dfs.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('--amount_ports_to_reset', help='--amount_ports_to_reset \"<min amount ports> <max amount ports>\" ', default=None)
|
||||
parser.add_argument('--port_reset_seconds', help='--ports_reset_seconds \"<min seconds> <max seconds>\" ', default="10 30")
|
||||
|
||||
parser.add_argument('--mgr', help='--mgr <hostname for where LANforge GUI is running>',default='localhost')
|
||||
parser.add_argument('-d','--test_duration', help='--test_duration <how long to run> example --time 5d (5 days) default: 3m options: number followed by d, h, m or s',default='3m')
|
||||
parser.add_argument('--tos', help='--tos: Support different ToS settings: BK | BE | VI | VO | numeric',default="BE")
|
||||
parser.add_argument('--debug', help='--debug: Enable debugging',default=False)
|
||||
parser.add_argument('-t', '--endp_type', help='--endp_type <types of traffic> example --endp_type \"lf_udp lf_tcp mc_udp\" Default: lf_udp , options: lf_udp, lf_udp6, lf_tcp, lf_tcp6, mc_udp, mc_udp6',
|
||||
default='lf_udp', type=valid_endp_types)
|
||||
parser.add_argument('-u', '--upstream_port', help='--upstream_port <cross connect upstream_port> example: --upstream_port eth1',default='eth1')
|
||||
parser.add_argument('-o','--csv_outfile', help="--csv_outfile <Output file for csv data>", default='longevity_results')
|
||||
parser.add_argument('--polling_interval', help="--polling_interval <seconds>", default='60s')
|
||||
#parser.add_argument('-c','--csv_output', help="Generate csv output", default=False)
|
||||
|
||||
parser.add_argument('-r','--radio', action='append', nargs=1, help='--radio \
|
||||
\"radio==<number_of_wiphy stations=<=number of stations> ssid==<ssid> ssid_pw==<ssid password> security==<security>\" '\
|
||||
, required=True)
|
||||
parser.add_argument("--cap_ctl_out", help="--cap_ctl_out , switch the cisco controller output will be captured", action='store_true')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
#print("args: {}".format(args))
|
||||
debug_on = args.debug
|
||||
|
||||
if args.test_duration:
|
||||
test_duration = args.test_duration
|
||||
|
||||
if args.polling_interval:
|
||||
polling_interval = args.polling_interval
|
||||
|
||||
if args.endp_type:
|
||||
endp_types = args.endp_type
|
||||
|
||||
if args.mgr:
|
||||
lfjson_host = args.mgr
|
||||
|
||||
if args.upstream_port:
|
||||
side_b = args.upstream_port
|
||||
|
||||
if args.radio:
|
||||
radios = args.radio
|
||||
|
||||
if args.csv_outfile != None:
|
||||
current_time = time.strftime("%m_%d_%Y_%H_%M_%S", time.localtime())
|
||||
csv_outfile = "{}_{}.csv".format(args.csv_outfile,current_time)
|
||||
print("csv output file : {}".format(csv_outfile))
|
||||
|
||||
|
||||
MAX_NUMBER_OF_STATIONS = 64
|
||||
|
||||
radio_name_list = []
|
||||
number_of_stations_per_radio_list = []
|
||||
ssid_list = []
|
||||
ssid_password_list = []
|
||||
ssid_security_list = []
|
||||
|
||||
#optional radio configuration
|
||||
reset_port_enable_list = []
|
||||
reset_port_time_min_list = []
|
||||
reset_port_time_max_list = []
|
||||
|
||||
print("radios {}".format(radios))
|
||||
for radio_ in radios:
|
||||
radio_keys = ['radio','stations','ssid','ssid_pw','security']
|
||||
radio_info_dict = dict(map(lambda x: x.split('=='), str(radio_).replace('[','').replace(']','').replace("'","").split()))
|
||||
print("radio_dict {}".format(radio_info_dict))
|
||||
|
||||
for key in radio_keys:
|
||||
if key not in radio_info_dict:
|
||||
print("missing config, for the {}, all of the following need to be present {} ".format(key,radio_keys))
|
||||
exit(1)
|
||||
|
||||
radio_name_list.append(radio_info_dict['radio'])
|
||||
number_of_stations_per_radio_list.append(radio_info_dict['stations'])
|
||||
ssid_list.append(radio_info_dict['ssid'])
|
||||
ssid_password_list.append(radio_info_dict['ssid_pw'])
|
||||
ssid_security_list.append(radio_info_dict['security'])
|
||||
|
||||
optional_radio_reset_keys = ['reset_port_enable']
|
||||
radio_reset_found = True
|
||||
for key in optional_radio_reset_keys:
|
||||
if key not in radio_info_dict:
|
||||
#print("port reset test not enabled")
|
||||
radio_reset_found = False
|
||||
break
|
||||
|
||||
if radio_reset_found:
|
||||
reset_port_enable_list.append(True)
|
||||
reset_port_time_min_list.append(radio_info_dict['reset_port_time_min'])
|
||||
reset_port_time_max_list.append(radio_info_dict['reset_port_time_max'])
|
||||
else:
|
||||
reset_port_enable_list.append(False)
|
||||
reset_port_time_min_list.append('0s')
|
||||
reset_port_time_max_list.append('0s')
|
||||
|
||||
|
||||
|
||||
index = 0
|
||||
station_lists = []
|
||||
for (radio_name_, number_of_stations_per_radio_) in zip(radio_name_list,number_of_stations_per_radio_list):
|
||||
number_of_stations = int(number_of_stations_per_radio_)
|
||||
if number_of_stations > MAX_NUMBER_OF_STATIONS:
|
||||
print("number of stations per radio exceeded max of : {}".format(MAX_NUMBER_OF_STATIONS))
|
||||
quit(1)
|
||||
station_list = LFUtils.portNameSeries(prefix_="sta", start_id_= 1 + index*1000, end_id_= number_of_stations + index*1000,
|
||||
padding_number_=10000, radio=radio_name_)
|
||||
station_lists.append(station_list)
|
||||
index += 1
|
||||
|
||||
#print("endp-types: %s"%(endp_types))
|
||||
|
||||
dfs = DFS.L3VariableTime(
|
||||
lfjson_host,
|
||||
lfjson_port,
|
||||
args=args,
|
||||
number_template="00",
|
||||
station_lists= station_lists,
|
||||
name_prefix="LT-",
|
||||
endp_types=endp_types,
|
||||
tos=args.tos,
|
||||
side_b=side_b,
|
||||
radio_name_list=radio_name_list,
|
||||
number_of_stations_per_radio_list=number_of_stations_per_radio_list,
|
||||
ssid_list=ssid_list,
|
||||
ssid_password_list=ssid_password_list,
|
||||
ssid_security_list=ssid_security_list,
|
||||
test_duration=test_duration,
|
||||
polling_interval= polling_interval,
|
||||
reset_port_enable_list=reset_port_enable_list,
|
||||
reset_port_time_min_list=reset_port_time_min_list,
|
||||
reset_port_time_max_list=reset_port_time_max_list,
|
||||
side_a_min_rate=256000,
|
||||
side_b_min_rate=256000,
|
||||
debug_on=debug_on,
|
||||
outfile=csv_outfile)
|
||||
|
||||
dfs.pre_cleanup()
|
||||
|
||||
dfs.build()
|
||||
if not dfs.passes():
|
||||
print("build step failed.")
|
||||
print(dfs.get_fail_message())
|
||||
exit(1)
|
||||
dfs.start(False, False)
|
||||
dfs.stop()
|
||||
if not dfs.passes():
|
||||
print("stop test failed")
|
||||
print(dfs.get_fail_message())
|
||||
|
||||
|
||||
print("Pausing 30 seconds after run for manual inspection before we clean up.")
|
||||
time.sleep(30)
|
||||
dfs.cleanup()
|
||||
if dfs.passes():
|
||||
print("Full test passed, all connections increased rx bytes")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
File diff suppressed because it is too large
Load Diff
281
py-scripts/lf_dataplane_test.py
Executable file
281
py-scripts/lf_dataplane_test.py
Executable file
@@ -0,0 +1,281 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
Note: To Run this script gui should be opened with
|
||||
|
||||
path: cd LANforgeGUI_5.4.3 (5.4.3 can be changed with GUI version)
|
||||
pwd (Output : /home/lanforge/LANforgeGUI_5.4.3)
|
||||
./lfclient.bash -cli-socket 3990
|
||||
|
||||
This script is used to automate running Dataplane tests. You
|
||||
may need to view a Dataplane test configured through the GUI to understand
|
||||
the options and how best to input data.
|
||||
|
||||
./lf_dataplane_test.py --mgr localhost --port 8080 --lf_user lanforge --lf_password lanforge \
|
||||
--instance_name dataplane-instance --config_name test_con --upstream 1.1.eth2 \
|
||||
--dut linksys-8450 --duration 15s --station 1.1.sta01500 \
|
||||
--download_speed 85% --upload_speed 0 \
|
||||
--raw_line 'pkts: Custom;60;142;256;512;1024;MTU' \
|
||||
--raw_line 'cust_pkt_sz: 88 1200' \
|
||||
--raw_line 'directions: DUT Transmit;DUT Receive' \
|
||||
--raw_line 'traffic_types: UDP;TCP' \
|
||||
--test_rig Testbed-01 --pull_report \
|
||||
--influx_host c7-graphana --influx_port 8086 --influx_org Candela \
|
||||
--influx_token=-u_Wd-L8o992701QF0c5UmqEp7w7Z7YOMaWLxOMgmHfATJGnQbbmYyNxHBR9PgD6taM_tcxqJl6U8DjU1xINFQ== \
|
||||
--influx_bucket ben \
|
||||
--influx_tag testbed Ferndale-01
|
||||
|
||||
Note:
|
||||
--raw_line 'line contents' will add any setting to the test config. This is
|
||||
useful way to support any options not specifically enabled by the
|
||||
command options.
|
||||
--set modifications will be applied after the other config has happened,
|
||||
so it can be used to override any other config.
|
||||
|
||||
Example of raw text config for Dataplane, to show other possible options:
|
||||
|
||||
show_events: 1
|
||||
show_log: 0
|
||||
port_sorting: 0
|
||||
kpi_id: Dataplane Pkt-Size
|
||||
notes0: ec5211 in bridge mode, wpa2 auth.
|
||||
bg: 0xE0ECF8
|
||||
test_rig:
|
||||
show_scan: 1
|
||||
auto_helper: 0
|
||||
skip_2: 0
|
||||
skip_5: 0
|
||||
skip_5b: 1
|
||||
skip_dual: 0
|
||||
skip_tri: 1
|
||||
selected_dut: ea8300
|
||||
duration: 15000
|
||||
traffic_port: 1.1.157 sta01500
|
||||
upstream_port: 1.1.2 eth2
|
||||
path_loss: 10
|
||||
speed: 85%
|
||||
speed2: 0Kbps
|
||||
min_rssi_bound: -150
|
||||
max_rssi_bound: 0
|
||||
channels: AUTO
|
||||
modes: Auto
|
||||
pkts: Custom;60;142;256;512;1024;MTU
|
||||
spatial_streams: AUTO
|
||||
security_options: AUTO
|
||||
bandw_options: AUTO
|
||||
traffic_types: UDP;TCP
|
||||
directions: DUT Transmit;DUT Receive
|
||||
txo_preamble: OFDM
|
||||
txo_mcs: 0 CCK, OFDM, HT, VHT
|
||||
txo_retries: No Retry
|
||||
txo_sgi: OFF
|
||||
txo_txpower: 15
|
||||
attenuator: 0
|
||||
attenuator2: 0
|
||||
attenuator_mod: 255
|
||||
attenuator_mod2: 255
|
||||
attenuations: 0..+50..950
|
||||
attenuations2: 0..+50..950
|
||||
chamber: 0
|
||||
tt_deg: 0..+45..359
|
||||
cust_pkt_sz: 88 1200
|
||||
show_bar_labels: 1
|
||||
show_prcnt_tput: 0
|
||||
show_3s: 0
|
||||
show_ll_graphs: 0
|
||||
show_gp_graphs: 1
|
||||
show_1m: 1
|
||||
pause_iter: 0
|
||||
outer_loop_atten: 0
|
||||
show_realtime: 1
|
||||
operator:
|
||||
mconn: 1
|
||||
mpkt: 1000
|
||||
tos: 0
|
||||
loop_iterations: 1
|
||||
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import argparse
|
||||
import time
|
||||
import json
|
||||
from os import path
|
||||
|
||||
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'))
|
||||
|
||||
from cv_test_manager import cv_test as cvtest
|
||||
from cv_test_manager import *
|
||||
from cv_commands import chamberview as cv
|
||||
|
||||
|
||||
class DataplaneTest(cvtest):
|
||||
def __init__(self,
|
||||
lf_host="localhost",
|
||||
lf_port=8080,
|
||||
lf_user="lanforge",
|
||||
lf_password="lanforge",
|
||||
instance_name="dpt_instance",
|
||||
config_name="dpt_config",
|
||||
upstream="1.1.eth2",
|
||||
pull_report=False,
|
||||
load_old_cfg=False,
|
||||
upload_speed="0",
|
||||
download_speed="85%",
|
||||
duration="15s",
|
||||
station="1.1.sta01500",
|
||||
dut="NA",
|
||||
enables=[],
|
||||
disables=[],
|
||||
raw_lines=[],
|
||||
raw_lines_file="",
|
||||
sets=[],
|
||||
):
|
||||
super().__init__(lfclient_host=lf_host, lfclient_port=lf_port)
|
||||
|
||||
self.lf_host = lf_host
|
||||
self.lf_port = lf_port
|
||||
self.lf_user = lf_user
|
||||
self.lf_password =lf_password
|
||||
self.createCV = cv(lf_host, lf_port);
|
||||
self.instance_name = instance_name
|
||||
self.config_name = config_name
|
||||
self.dut = dut
|
||||
self.duration = duration
|
||||
self.upstream = upstream
|
||||
self.station = station
|
||||
self.pull_report = pull_report
|
||||
self.load_old_cfg = load_old_cfg
|
||||
self.test_name = "Dataplane"
|
||||
self.upload_speed = upload_speed
|
||||
self.download_speed = download_speed
|
||||
self.enables = enables
|
||||
self.disables = disables
|
||||
self.raw_lines = raw_lines
|
||||
self.raw_lines_file = raw_lines_file
|
||||
self.sets = sets
|
||||
|
||||
def setup(self):
|
||||
# Nothing to do at this time.
|
||||
return
|
||||
|
||||
|
||||
def run(self):
|
||||
self.createCV.sync_cv()
|
||||
time.sleep(2)
|
||||
self.createCV.sync_cv()
|
||||
|
||||
blob_test = "dataplane-test-latest-"
|
||||
|
||||
self.rm_text_blob(self.config_name, blob_test) # To delete old config with same name
|
||||
self.show_text_blob(None, None, False)
|
||||
|
||||
# Test related settings
|
||||
cfg_options = []
|
||||
|
||||
### HERE###
|
||||
self.apply_cfg_options(cfg_options, self.enables, self.disables, self.raw_lines, self.raw_lines_file)
|
||||
|
||||
# cmd line args take precedence and so come last in the cfg array.
|
||||
if self.upstream != "":
|
||||
cfg_options.append("upstream_port: " + self.upstream)
|
||||
if self.station != "":
|
||||
cfg_options.append("traffic_port: " + self.station)
|
||||
if self.download_speed != "":
|
||||
cfg_options.append("speed: " + self.download_speed)
|
||||
if self.upload_speed != "":
|
||||
cfg_options.append("speed2: " + self.upload_speed)
|
||||
if self.duration != "":
|
||||
cfg_options.append("duration: " + self.duration)
|
||||
if self.dut != "":
|
||||
cfg_options.append("selected_dut: " + self.dut)
|
||||
|
||||
# We deleted the scenario earlier, now re-build new one line at a time.
|
||||
|
||||
self.build_cfg(self.config_name, blob_test, cfg_options)
|
||||
|
||||
cv_cmds = []
|
||||
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,
|
||||
cv_cmds)
|
||||
self.rm_text_blob(self.config_name, blob_test) # To delete old config with same name
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
parser = argparse.ArgumentParser("""
|
||||
Open this file in an editor and read the top notes for more details.
|
||||
|
||||
Example:
|
||||
|
||||
./lf_dataplane_test.py --mgr localhost --port 8080 --lf_user lanforge --lf_password lanforge \
|
||||
--instance_name dataplane-instance --config_name test_con --upstream 1.1.eth2 \
|
||||
--dut linksys-8450 --duration 15s --station 1.1.sta01500 \
|
||||
--download_speed 85% --upload_speed 0 \
|
||||
--raw_line 'pkts: Custom;60;142;256;512;1024;MTU' \
|
||||
--raw_line 'cust_pkt_sz: 88 1200' \
|
||||
--raw_line 'directions: DUT Transmit;DUT Receive' \
|
||||
--raw_line 'traffic_types: UDP;TCP' \
|
||||
--test_rig Testbed-01 --pull_report \
|
||||
--influx_host c7-graphana --influx_port 8086 --influx_org Candela \
|
||||
--influx_token=-u_Wd-L8o992701QF0c5UmqEp7w7Z7YOMaWLxOMgmHfATJGnQbbmYyNxHBR9PgD6taM_tcxqJl6U8DjU1xINFQ== \
|
||||
--influx_bucket ben \
|
||||
--influx_tag testbed Ferndale-01
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
cv_add_base_parser(parser) # see cv_test_manager.py
|
||||
|
||||
parser.add_argument("-u", "--upstream", type=str, default="",
|
||||
help="Upstream port for wifi capacity test ex. 1.1.eth2")
|
||||
parser.add_argument("--station", type=str, default="",
|
||||
help="Station to be used in this test, example: 1.1.sta01500")
|
||||
|
||||
parser.add_argument("--dut", default="",
|
||||
help="Specify DUT used by this test, example: linksys-8450")
|
||||
parser.add_argument("--download_speed", default="",
|
||||
help="Specify requested download speed. Percentage of theoretical is also supported. Default: 85%")
|
||||
parser.add_argument("--upload_speed", default="",
|
||||
help="Specify requested upload speed. Percentage of theoretical is also supported. Default: 0")
|
||||
parser.add_argument("--duration", default="",
|
||||
help="Specify duration of each traffic run")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
cv_base_adjust_parser(args)
|
||||
|
||||
CV_Test = DataplaneTest(lf_host = args.mgr,
|
||||
lf_port = args.port,
|
||||
lf_user = args.lf_user,
|
||||
lf_password = args.lf_password,
|
||||
instance_name = args.instance_name,
|
||||
config_name = args.config_name,
|
||||
upstream = args.upstream,
|
||||
pull_report = args.pull_report,
|
||||
load_old_cfg = args.load_old_cfg,
|
||||
download_speed = args.download_speed,
|
||||
upload_speed = args.upload_speed,
|
||||
duration = args.duration,
|
||||
dut = args.dut,
|
||||
station = args.station,
|
||||
enables = args.enable,
|
||||
disables = args.disable,
|
||||
raw_lines = args.raw_line,
|
||||
raw_lines_file = args.raw_lines_file,
|
||||
sets = args.set
|
||||
)
|
||||
CV_Test.setup()
|
||||
CV_Test.run()
|
||||
|
||||
CV_Test.check_influx_kpi(args)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
2846
py-scripts/lf_dfs_test.py
Executable file
2846
py-scripts/lf_dfs_test.py
Executable file
File diff suppressed because it is too large
Load Diff
549
py-scripts/lf_ftp_test.py
Executable file
549
py-scripts/lf_ftp_test.py
Executable file
@@ -0,0 +1,549 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
|
||||
NAME: ftp_test.py
|
||||
|
||||
PURPOSE:
|
||||
will create stations and endpoints to generate and verify layer-4 traffic over an ftp connection.
|
||||
find out download/upload time of each client according to file size.
|
||||
This script will monitor the bytes-rd attribute of the endpoints.
|
||||
|
||||
SETUP:
|
||||
|
||||
Create a file to be downloaded linux: fallocate -l <size> <name> example fallocate -l 2M ftp_test.txt
|
||||
|
||||
|
||||
EXAMPLE:
|
||||
'./ftp_test.py --ssid "jedway-wap2-x2048-5-3" --passwd "jedway-wpa2-x2048-5-3" --security wpa2 --bands "5G" --direction "Download" \
|
||||
--file_size "2MB" --num_stations 2
|
||||
|
||||
INCLUDE_IN_README
|
||||
|
||||
|
||||
-Jitendrakumar Kushavah
|
||||
Copyright 2021 Candela Technologies Inc
|
||||
License: Free to distribute and modify. LANforge systems must be licensed.
|
||||
|
||||
"""
|
||||
import sys
|
||||
from ftp_html import *
|
||||
import paramiko
|
||||
if sys.version_info[0] != 3:
|
||||
print("This script requires Python 3")
|
||||
exit(1)
|
||||
if 'py-json' not in sys.path:
|
||||
sys.path.append('../py-json')
|
||||
|
||||
from LANforge import LFUtils
|
||||
from LANforge.lfcli_base import LFCliBase
|
||||
from LANforge.LFUtils import *
|
||||
import realm
|
||||
import argparse
|
||||
from datetime import datetime
|
||||
import time
|
||||
import os
|
||||
|
||||
class ftp_test(LFCliBase):
|
||||
def __init__(self, lfclient_host="localhost", lfclient_port=8080, radio = "wiphy0", sta_prefix="sta", start_id=0, num_sta= None,
|
||||
dut_ssid=None,dut_security=None, dut_passwd=None, file_size=None, band=None,
|
||||
upstream="eth1",_debug_on=False, _exit_on_error=False, _exit_on_fail=False, direction= None):
|
||||
super().__init__(lfclient_host, lfclient_port, _debug=_debug_on, _exit_on_fail=_exit_on_fail)
|
||||
print("Test is about to start")
|
||||
self.host = lfclient_host
|
||||
self.port = lfclient_port
|
||||
self.radio = radio
|
||||
self.upstream = upstream
|
||||
self.sta_prefix = sta_prefix
|
||||
self.sta_start_id = start_id
|
||||
self.num_sta = num_sta
|
||||
self.ssid = dut_ssid
|
||||
self.security = dut_security
|
||||
self.password = dut_passwd
|
||||
self.requests_per_ten = 1
|
||||
self.band=band
|
||||
self.file_size=file_size
|
||||
self.direction=direction
|
||||
self.local_realm = realm.Realm(lfclient_host=self.host, lfclient_port=self.port)
|
||||
self.station_profile = self.local_realm.new_station_profile()
|
||||
self.cx_profile = self.local_realm.new_http_profile()
|
||||
self.port_util = realm.PortUtils(self.local_realm)
|
||||
self.cx_profile.requests_per_ten = self.requests_per_ten
|
||||
|
||||
print("Test is Initialized")
|
||||
|
||||
def set_values(self):
|
||||
#This method will set values according user input
|
||||
|
||||
if self.band == "5G":
|
||||
self.radio = ["wiphy2"] # need to pass in the radios
|
||||
if self.file_size == "2MB":
|
||||
|
||||
#providing time duration for Pass or fail criteria
|
||||
self.duration = self.convert_min_in_time(1)
|
||||
elif self.file_size == "500MB":
|
||||
self.duration = self.convert_min_in_time(1) # 30
|
||||
elif self.file_size == "1000MB":
|
||||
self.duration = self.convert_min_in_time(1) # 50
|
||||
else:
|
||||
self.duration = self.convert_min_in_time(10) # 10
|
||||
elif self.band == "2.4G":
|
||||
self.radio = ["wiphy0"] # need to pass in the radios
|
||||
if self.file_size == "2MB":
|
||||
self.duration = self.convert_min_in_time(1) # 2
|
||||
elif self.file_size == "500MB":
|
||||
self.duration = self.convert_min_in_time(1) # 60
|
||||
elif self.file_size == "1000MB":
|
||||
self.duration = self.convert_min_in_time(1) # 80
|
||||
else:
|
||||
self.duration = self.convert_min_in_time(10) # 10
|
||||
elif self.band == "Both":
|
||||
self.radio = ["wiphy2", "wiphy0"] # need to pass in the radios
|
||||
|
||||
#if Both then number of stations are half for 2.4G and half for 5G
|
||||
self.num_sta = self.num_sta // 2
|
||||
print(self.num_sta)
|
||||
if self.file_size == "2MB":
|
||||
self.duration = self.convert_min_in_time(1) # 2
|
||||
elif self.file_size == "500MB":
|
||||
self.duration = self.convert_min_in_time(1) # 60
|
||||
elif self.file_size == "1000MB":
|
||||
self.duration = self.convert_min_in_time(1) # 80
|
||||
else:
|
||||
self.duration = self.convert_min_in_time(10) # 10
|
||||
|
||||
self.file_size_bytes=int(self.convert_file_size_in_Bytes(self.file_size))
|
||||
|
||||
|
||||
def precleanup(self):
|
||||
self.count=0
|
||||
|
||||
#delete everything in the GUI before starting the script
|
||||
try:
|
||||
self.local_realm.load("BLANK")
|
||||
except:
|
||||
print("Couldn't load 'BLANK' Test configurations")
|
||||
|
||||
for rad in self.radio:
|
||||
if rad == "wiphy2":
|
||||
|
||||
#select mode(All stations will connects to 5G)
|
||||
self.station_profile.mode = 10
|
||||
self.count=self.count+1
|
||||
|
||||
elif rad == "wiphy0": # This probably is not the best selection mode
|
||||
|
||||
# select mode(All stations will connects to 2.4G)
|
||||
self.station_profile.mode = 6
|
||||
self.count = self.count + 1
|
||||
|
||||
#check Both band if both band then for 2.4G station id start with 20
|
||||
if self.count == 2:
|
||||
self.sta_start_id = self.num_sta
|
||||
self.num_sta = 2 * (self.num_sta)
|
||||
|
||||
#if Both band then first 20 stations will connects to 5G
|
||||
self.station_profile.mode = 10
|
||||
self.cx_profile.cleanup()
|
||||
|
||||
#create station list with sta_id 20
|
||||
self.station_list1 = LFUtils.portNameSeries(prefix_=self.sta_prefix, start_id_=self.sta_start_id,
|
||||
end_id_=self.num_sta - 1, padding_number_=10000,
|
||||
radio=rad)
|
||||
|
||||
#cleanup station list which started sta_id 20
|
||||
self.station_profile.cleanup(self.station_list1, debug_=self.debug)
|
||||
LFUtils.wait_until_ports_disappear(base_url=self.lfclient_url,
|
||||
port_list=self.station_list,
|
||||
debug=self.debug)
|
||||
return
|
||||
#clean layer4 ftp traffic
|
||||
self.cx_profile.cleanup()
|
||||
self.station_list = LFUtils.portNameSeries(prefix_=self.sta_prefix, start_id_=self.sta_start_id,
|
||||
end_id_=self.num_sta - 1, padding_number_=10000,
|
||||
radio=rad)
|
||||
|
||||
#cleans stations
|
||||
self.station_profile.cleanup(self.station_list , delay=1, debug_=self.debug)
|
||||
LFUtils.wait_until_ports_disappear(base_url=self.lfclient_url,
|
||||
port_list=self.station_list,
|
||||
debug=self.debug)
|
||||
time.sleep(1)
|
||||
|
||||
print("precleanup done")
|
||||
|
||||
def build(self):
|
||||
|
||||
#set ftp
|
||||
self.port_util.set_ftp(port_name=self.local_realm.name_to_eid(self.upstream)[2], resource=1, on=True)
|
||||
|
||||
for rad in self.radio:
|
||||
|
||||
#station build
|
||||
self.station_profile.use_security(self.security, self.ssid, self.password)
|
||||
self.station_profile.set_number_template("00")
|
||||
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=rad, sta_names_=self.station_list, debug=self.debug)
|
||||
self.local_realm.wait_until_ports_appear(sta_list=self.station_list)
|
||||
self.station_profile.admin_up()
|
||||
if self.local_realm.wait_for_ip(self.station_list):
|
||||
self._pass("All stations got IPs")
|
||||
else:
|
||||
self._fail("Stations failed to get IPs")
|
||||
exit(1)
|
||||
#building layer4
|
||||
self.cx_profile.direction ="dl"
|
||||
self.cx_profile.dest = "/dev/null"
|
||||
print('DIRECTION',self.direction)
|
||||
|
||||
if self.direction == "Download":
|
||||
self.cx_profile.create(ports=self.station_profile.station_names, ftp_ip="10.40.0.1/ftp_test.txt",
|
||||
sleep_time=.5,debug_=self.debug,suppress_related_commands_=True, ftp=True, user="lanforge",
|
||||
passwd="lanforge", source="")
|
||||
|
||||
|
||||
elif self.direction == "Upload":
|
||||
dict_sta_and_ip = {}
|
||||
|
||||
#data from GUI for find out ip addr of each station
|
||||
data = self.json_get("ports/list?fields=IP")
|
||||
|
||||
# This loop for find out proper ip addr and station name
|
||||
for i in self.station_list:
|
||||
for j in data['interfaces']:
|
||||
for k in j:
|
||||
if i == k:
|
||||
dict_sta_and_ip[k] = j[i]['ip']
|
||||
|
||||
|
||||
|
||||
#list of ip addr of all stations
|
||||
ip = list(dict_sta_and_ip.values())
|
||||
|
||||
eth_list = []
|
||||
client_list = []
|
||||
|
||||
#list of all stations
|
||||
for i in range(len(self.station_list)):
|
||||
client_list.append(self.station_list[i][4:])
|
||||
|
||||
#list of upstream port
|
||||
eth_list.append(self.upstream)
|
||||
|
||||
#create layer for connection for upload
|
||||
for client_num in range(len(self.station_list)):
|
||||
self.cx_profile.create(ports=eth_list, ftp_ip=ip[client_num] + "/ftp_test_upload.txt", sleep_time=.5,
|
||||
debug_=self.debug, suppress_related_commands_=True, ftp=True,
|
||||
user="lanforge", passwd="lanforge",
|
||||
source="", upload_name=client_list[client_num])
|
||||
|
||||
|
||||
#check Both band present then build stations with another station list
|
||||
if self.count == 2:
|
||||
self.station_list = self.station_list1
|
||||
|
||||
# if Both band then another 20 stations will connects to 2.4G
|
||||
self.station_profile.mode = 6
|
||||
print("Test Build done")
|
||||
|
||||
def start(self, print_pass=False, print_fail=False):
|
||||
for rad in self.radio:
|
||||
self.cx_profile.start_cx()
|
||||
|
||||
print("Test Started")
|
||||
|
||||
|
||||
def stop(self):
|
||||
self.cx_profile.stop_cx()
|
||||
self.station_profile.admin_down()
|
||||
|
||||
def postcleanup(self):
|
||||
self.cx_profile.cleanup()
|
||||
self.local_realm.load("BLANK")
|
||||
self.station_profile.cleanup(self.station_profile.station_names, delay=1, debug_=self.debug)
|
||||
LFUtils.wait_until_ports_disappear(base_url=self.lfclient_url, port_list=self.station_profile.station_names,
|
||||
debug=self.debug)
|
||||
|
||||
#Create file for given file size
|
||||
def file_create(self):
|
||||
if os.path.isfile("/home/lanforge/ftp_test.txt"):
|
||||
os.remove("/home/lanforge/ftp_test.txt")
|
||||
os.system("fallocate -l " +self.file_size +" /home/lanforge/ftp_test.txt")
|
||||
print("File creation done", self.file_size)
|
||||
|
||||
#convert file size MB or GB into Bytes
|
||||
def convert_file_size_in_Bytes(self,size):
|
||||
if (size.endswith("MB")) or (size.endswith("Mb")) or (size.endswith("GB")) or (size.endswith("Gb")):
|
||||
if (size.endswith("MB")) or (size.endswith("Mb")):
|
||||
return float(size[:-2]) * 10**6
|
||||
elif (size.endswith("GB")) or (size.endswith("Gb")):
|
||||
return float(size[:-2]) * 10**9
|
||||
|
||||
|
||||
def my_monitor(self,time1):
|
||||
#data in json format
|
||||
data = self.json_get("layer4/list?fields=bytes-rd")
|
||||
|
||||
print("layer4/list?fields=bytes-read: {}".format(data))
|
||||
|
||||
|
||||
#list of layer 4 connections name
|
||||
self.data1 = []
|
||||
for i in range(self.num_sta):
|
||||
if self.num_sta == 1:
|
||||
# the station num is 1 , yet the station is 0
|
||||
print("i: {} self.num_sta: {}".format(i,self.num_sta))
|
||||
print("data['endpoint'][{}]: {}".format(i,data['endpoint']))
|
||||
print("data list: {}".format((str(list(data['endpoint'].keys())))[2:-2]))
|
||||
print("data list: {}".format((str(list(data['endpoint'].keys())))[2:-2]))
|
||||
#self.data1.append((str(list(data['endpoint']['name']))))
|
||||
self.data1.append((str((data['endpoint']['name']))))
|
||||
|
||||
else:
|
||||
# the station num is 1 , yet the station is 0
|
||||
print("i: {} self.num_sta: {}".format(i,self.num_sta))
|
||||
print("data['endpoint'][{}]: {}".format(i,data['endpoint'][i]))
|
||||
print("data list: {}".format((str(list(data['endpoint'][i].keys())))[2:-2]))
|
||||
self.data1.append((str(list(data['endpoint'][i].keys())))[2:-2])
|
||||
|
||||
data2 = self.data1
|
||||
print("data1: {}".format(self.data1))
|
||||
print("data2: {}".format(data2))
|
||||
list_of_time = []
|
||||
list1 = []
|
||||
list2 = []
|
||||
|
||||
for i in range(self.num_sta):
|
||||
list_of_time.append(0)
|
||||
|
||||
print("list_of_time: {}".format(list_of_time))
|
||||
|
||||
num_sta_finished = 0
|
||||
while list_of_time.count(0) != 0:
|
||||
|
||||
#run script upto given time
|
||||
if str(datetime.now()- time1) >= self.duration:
|
||||
break
|
||||
|
||||
for i in range(self.num_sta):
|
||||
data = self.json_get("layer4/list?fields=bytes-rd")
|
||||
#print("data from bytes-rd: {}".format(data))
|
||||
|
||||
|
||||
if self.num_sta == 1:
|
||||
#reading uc-avg data in json format
|
||||
uc_avg= self.json_get("layer4/list?fields=uc-avg")
|
||||
#print("layer4/list?fields=uc-avg: {}".format(uc_avg))
|
||||
if data['endpoint']['bytes-rd'] <= self.file_size_bytes:
|
||||
data = self.json_get("layer4/list?fields=bytes-rd")
|
||||
if data['endpoint']['bytes-rd'] >= self.file_size_bytes:
|
||||
list1.append(i)
|
||||
print("list1: {} list2: {}".format(list1,list2))
|
||||
if list1.count(i) == 1:
|
||||
list2.append(i)
|
||||
list1 = list2
|
||||
print("CX_{} list1: {} list2: {}".format(data2[0],list1,list2))
|
||||
|
||||
#stop station after download or upload file with particular size
|
||||
self.json_post("/cli-json/set_cx_state", {
|
||||
"test_mgr": "default_tm",
|
||||
"cx_name": "CX_" + data2[0],
|
||||
"cx_state": "STOPPED"
|
||||
}, debug_=self.debug)
|
||||
list_of_time[i] = round(int(uc_avg['endpoint']['uc-avg'])/1000,1)
|
||||
num_sta_finished += 1
|
||||
if num_sta_finished >= self.num_sta:
|
||||
break
|
||||
else:
|
||||
#reading uc-avg data in json format
|
||||
uc_avg= self.json_get("layer4/list?fields=uc-avg")
|
||||
if data['endpoint'][i][data2[i]]['bytes-rd'] <= self.file_size_bytes:
|
||||
data = self.json_get("layer4/list?fields=bytes-rd")
|
||||
if data['endpoint'][i][data2[i]]['bytes-rd'] >= self.file_size_bytes:
|
||||
list1.append(i)
|
||||
print("list1: {} list2: {}".format(list1,list2))
|
||||
|
||||
if list1.count(i) == 1:
|
||||
list2.append(i)
|
||||
list1 = list2
|
||||
print("CX_{} list1: {} list2: {}".format(data2[i],list1,list2))
|
||||
|
||||
#stop station after download or upload file with particular size
|
||||
self.json_post("/cli-json/set_cx_state", {
|
||||
"test_mgr": "default_tm",
|
||||
"cx_name": "CX_" + data2[i],
|
||||
"cx_state": "STOPPED"
|
||||
}, debug_=self.debug)
|
||||
|
||||
list_of_time[i] = round(int(uc_avg['endpoint'][i][data2[i]]['uc-avg'])/1000,1)
|
||||
time.sleep(0.5)
|
||||
# print(".", end='')
|
||||
|
||||
|
||||
#return list of download/upload time in seconds
|
||||
return list_of_time
|
||||
|
||||
#Method for arrange ftp download/upload time data in dictionary
|
||||
def ftp_test_data(self, list_time, pass_fail, bands, file_sizes, directions, num_stations):
|
||||
|
||||
#creating dictionary for single iteration
|
||||
create_dict={}
|
||||
|
||||
create_dict["band"] = self.band
|
||||
create_dict["direction"] = self.direction
|
||||
create_dict["file_size"] = self.file_size
|
||||
create_dict["time"] = list_time
|
||||
create_dict["duration"] = self.time_test
|
||||
create_dict["result"] = pass_fail
|
||||
create_dict["bands"] = bands
|
||||
create_dict["file_sizes"] = file_sizes
|
||||
create_dict["directions"] = directions
|
||||
create_dict["num_stations"] = num_stations
|
||||
|
||||
return create_dict
|
||||
|
||||
#Method for AP reboot
|
||||
def ap_reboot(self, ip, user, pswd):
|
||||
|
||||
print("starting AP reboot")
|
||||
|
||||
# creating shh client object we use this object to connect to router
|
||||
ssh = paramiko.SSHClient()
|
||||
|
||||
# automatically adds the missing host key
|
||||
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
ssh.connect(ip, port=22, username=user, password=pswd, banner_timeout=600)
|
||||
stdin, stdout, stderr = ssh.exec_command('reboot')
|
||||
output = stdout.readlines()
|
||||
ssh.close()
|
||||
# print('\n'.join(output))
|
||||
|
||||
time.sleep(180)
|
||||
print("AP rebooted")
|
||||
|
||||
def convert_min_in_time(self,total_minutes):
|
||||
|
||||
#saving time in minutus
|
||||
self.time_test = total_minutes
|
||||
|
||||
# Get hours with floor division
|
||||
hours = total_minutes // 60
|
||||
|
||||
# Get additional minutes with modulus
|
||||
minutes = total_minutes % 60
|
||||
|
||||
# Create time as a string
|
||||
time_string = str("%d:%02d" % (divmod(total_minutes, 60))) + ":00" + ":000000"
|
||||
|
||||
return time_string
|
||||
|
||||
def pass_fail_check(self,time_list):
|
||||
if time_list.count(0) == 0:
|
||||
return "Pass"
|
||||
else:
|
||||
return "Fail"
|
||||
|
||||
def main():
|
||||
# This has --mgr, --mgr_port and --debug
|
||||
parser = LFCliBase.create_bare_argparse(prog="netgear-ftp", formatter_class=argparse.RawTextHelpFormatter, epilog="About This Script")
|
||||
# Adding More Arguments for custom use
|
||||
parser.add_argument('--ssid',type=str, help='--ssid', default="TestAP-Jitendra")
|
||||
parser.add_argument('--passwd',type=str, help='--passwd', default="BLANK")
|
||||
parser.add_argument('--security', type=str, help='--security', default="open")
|
||||
parser.add_argument('--radios',nargs="+",help='--radio to use on LANforge for 5G and 2G', default=["wiphy0"])
|
||||
|
||||
# Test variables
|
||||
parser.add_argument('--bands', nargs="+", help='--bands defaults ["5G","2.4G","Both"]', default=["5G","2.4G","Both"])
|
||||
parser.add_argument('--directions', nargs="+", help='--directions defaults ["Download","Upload"]', default=["Download","Upload"])
|
||||
parser.add_argument('--file_sizes', nargs="+", help='--File Size defaults ["2MB","500MB","1000MB"]', default=["2MB","500MB","1000MB"])
|
||||
parser.add_argument('--num_stations', type=int, help='--num_client is number of stations', default=40)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# 1st time stamp for test duration
|
||||
time_stamp1 = datetime.now()
|
||||
|
||||
#use for creating ftp_test dictionary
|
||||
iteraration_num=0
|
||||
|
||||
#empty dictionary for whole test data
|
||||
ftp_data={}
|
||||
|
||||
#For all combinations ftp_data of directions, file size and client counts, run the test
|
||||
for band in args.bands:
|
||||
for direction in args.directions:
|
||||
for file_size in args.file_sizes:
|
||||
# Start Test
|
||||
obj = ftp_test(lfclient_host=args.mgr,
|
||||
lfclient_port=args.mgr_port,
|
||||
dut_ssid=args.ssid,
|
||||
dut_passwd=args.passwd,
|
||||
dut_security=args.security,
|
||||
num_sta= args.num_stations,
|
||||
band=band,
|
||||
file_size=file_size,
|
||||
direction=direction
|
||||
)
|
||||
|
||||
iteraration_num=iteraration_num+1
|
||||
obj.file_create()
|
||||
obj.set_values()
|
||||
obj.precleanup()
|
||||
#if file_size != "2MB":
|
||||
#obj.ap_reboot("192.168.213.190","root","Password@123xzsawq@!")
|
||||
obj.build()
|
||||
if not obj.passes():
|
||||
print(obj.get_fail_message())
|
||||
exit(1)
|
||||
|
||||
#First time stamp
|
||||
time1 = datetime.now()
|
||||
|
||||
obj.start(False, False)
|
||||
|
||||
#return list of download/upload completed time stamp
|
||||
time_list = obj.my_monitor(time1)
|
||||
|
||||
# check pass or fail
|
||||
pass_fail = obj.pass_fail_check(time_list)
|
||||
|
||||
#dictionary of whole data
|
||||
ftp_data[iteraration_num] = obj.ftp_test_data(time_list,pass_fail,args.bands,args.file_sizes,args.directions,args.num_stations)
|
||||
|
||||
obj.stop()
|
||||
obj.postcleanup()
|
||||
|
||||
#2nd time stamp for test duration
|
||||
time_stamp2 = datetime.now()
|
||||
|
||||
#total time for test duration
|
||||
test_duration = str(time_stamp2 - time_stamp1)[:-7]
|
||||
|
||||
print("FTP Test Data", ftp_data)
|
||||
|
||||
date = str(datetime.now()).split(",")[0].replace(" ", "-").split(".")[0]
|
||||
|
||||
test_setup_info = {
|
||||
"AP Name": "vap5",
|
||||
"SSID": args.ssid,
|
||||
"Number of Stations": args.num_stations,
|
||||
"Test Duration": test_duration
|
||||
}
|
||||
|
||||
input_setup_info = {
|
||||
"IP": "192.168.213.190" ,
|
||||
"user": "root",
|
||||
"Contact": "support@candelatech.com"
|
||||
}
|
||||
generate_report(ftp_data,
|
||||
date,
|
||||
test_setup_info,
|
||||
input_setup_info,
|
||||
graph_path="/home/lanforge/html-reports/FTP-Test")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
211
py-scripts/lf_graph.py
Normal file
211
py-scripts/lf_graph.py
Normal file
@@ -0,0 +1,211 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib as mpl
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import pdfkit
|
||||
import math
|
||||
|
||||
# internal candela references included during intial phases, to be deleted at future date
|
||||
|
||||
# graph reporting classes
|
||||
class lf_bar_graph():
|
||||
def __init__(self,
|
||||
_data_set= [[30,55,69,37],[45,67,34,22],[22,45,12,34]],
|
||||
_xaxis_name="x-axis",
|
||||
_yaxis_name="y-axis",
|
||||
_xaxis_categories=[1,2,3,4],
|
||||
_graph_image_name="image_name",
|
||||
_label=["bi-downlink", "bi-uplink",'uplink'],
|
||||
_color=None,
|
||||
_bar_width=0.25,
|
||||
_color_edge='grey',
|
||||
_font_weight='bold',
|
||||
_color_name=['lightcoral','darkgrey','r','g','b','y'],
|
||||
_figsize=(10,5),
|
||||
_dpi=96):
|
||||
|
||||
self.data_set=_data_set
|
||||
self.xaxis_name=_xaxis_name
|
||||
self.yaxis_name=_yaxis_name
|
||||
self.xaxis_categories=_xaxis_categories
|
||||
self.graph_image_name=_graph_image_name
|
||||
self.label=_label
|
||||
self.color=_color
|
||||
self.bar_width=_bar_width
|
||||
self.color_edge=_color_edge
|
||||
self.font_weight=_font_weight
|
||||
self.color_name=_color_name
|
||||
self.figsize=_figsize
|
||||
|
||||
|
||||
|
||||
def build_bar_graph(self):
|
||||
if self.color is None:
|
||||
i = 0
|
||||
self.color = []
|
||||
for col in self.data_set:
|
||||
self.color.append(self.color_name[i])
|
||||
i = i+1
|
||||
|
||||
fig = plt.subplots(figsize=self.figsize)
|
||||
i = 0
|
||||
for set in self.data_set:
|
||||
if i > 0:
|
||||
br = br1
|
||||
br2 = [x + self.bar_width for x in br]
|
||||
plt.bar(br2, self.data_set[i], color=self.color[i], width=self.bar_width,
|
||||
edgecolor=self.color_edge, label=self.label[i])
|
||||
br1 = br2
|
||||
i = i+1
|
||||
else:
|
||||
br1 = np.arange(len(self.data_set[i]))
|
||||
plt.bar(br1, self.data_set[i], color=self.color[i], width=self.bar_width,
|
||||
edgecolor=self.color_edge, label=self.label[i])
|
||||
i=i+1
|
||||
plt.xlabel(self.xaxis_name, fontweight='bold', fontsize=15)
|
||||
plt.ylabel(self.yaxis_name, fontweight='bold', fontsize=15)
|
||||
plt.xticks([r + self.bar_width for r in range(len(self.data_set[0]))],
|
||||
self.xaxis_categories)
|
||||
plt.legend()
|
||||
|
||||
fig = plt.gcf()
|
||||
plt.savefig("%s.png"% (self.graph_image_name), dpi=96)
|
||||
plt.close()
|
||||
print("{}.png".format(self.graph_image_name))
|
||||
|
||||
return "%s.png" % (self.graph_image_name)
|
||||
|
||||
|
||||
class lf_scatter_graph():
|
||||
def __init__(self,
|
||||
_x_data_set= ["sta0 ","sta1","sta2","sta3"],
|
||||
_y_data_set= [[30,55,69,37]],
|
||||
_xaxis_name="x-axis",
|
||||
_yaxis_name="y-axis",
|
||||
_label = ["num1", "num2"],
|
||||
_graph_image_name="image_name",
|
||||
_color=["r","y"],
|
||||
_figsize=(9,4)):
|
||||
self.x_data_set = _x_data_set
|
||||
self.y_data_set = _y_data_set
|
||||
self.xaxis_name = _xaxis_name
|
||||
self.yaxis_name = _yaxis_name
|
||||
self.figsize = _figsize
|
||||
self.graph_image_name = _graph_image_name
|
||||
self.color = _color
|
||||
self.label = _label
|
||||
|
||||
def build_scatter_graph(self):
|
||||
if self.color is None:
|
||||
self.color = ["orchid", "lime", "aquamarine", "royalblue", "darkgray", "maroon"]
|
||||
fig = plt.subplots(figsize=self.figsize)
|
||||
plt.scatter(self.x_data_set, self.y_data_set[0], color=self.color[0], label=self.label[0])
|
||||
if len(self.y_data_set) > 1:
|
||||
for i in range(1,len(self.y_data_set)):
|
||||
plt.scatter(self.x_data_set, self.y_data_set[i], color=self.color[i], label=self.label[i])
|
||||
plt.xlabel(self.xaxis_name, fontweight='bold', fontsize=15)
|
||||
plt.ylabel(self.yaxis_name, fontweight='bold', fontsize=15)
|
||||
plt.gcf().autofmt_xdate()
|
||||
plt.legend()
|
||||
plt.savefig("%s.png" % (self.graph_image_name), dpi=96)
|
||||
plt.close()
|
||||
print("{}.png".format(self.graph_image_name))
|
||||
|
||||
return "%s.png" % (self.graph_image_name)
|
||||
|
||||
class lf_stacked_graph():
|
||||
def __init__(self,
|
||||
_data_set= [[1,2,3,4],[1,1,1,1],[1,1,1,1]],
|
||||
_xaxis_name="Stations",
|
||||
_yaxis_name="Numbers",
|
||||
_label = ['Success','Fail'],
|
||||
_graph_image_name="image_name",
|
||||
_color = ["b","g"],
|
||||
_figsize=(9,4)):
|
||||
self.data_set = _data_set # [x_axis,y1_axis,y2_axis]
|
||||
self.xaxis_name = _xaxis_name
|
||||
self.yaxis_name = _yaxis_name
|
||||
self.figsize = _figsize
|
||||
self.graph_image_name = _graph_image_name
|
||||
self.label = _label
|
||||
self.color = _color
|
||||
|
||||
|
||||
def build_stacked_graph(self):
|
||||
fig = plt.subplots(figsize=self.figsize)
|
||||
if self.color is None:
|
||||
self.color = ["darkred", "tomato", "springgreen", "skyblue", "indigo", "plum"]
|
||||
plt.bar(self.data_set[0], self.data_set[1], color=self.color[0])
|
||||
plt.bar(self.data_set[0], self.data_set[2], bottom=self.data_set[1], color=self.color[1])
|
||||
if len(self.data_set) > 3:
|
||||
for i in range(3, len(self.data_set)):
|
||||
plt.bar(self.data_set[0], self.data_set[i], bottom=np.array(self.data_set[i-2])+np.array(self.data_set[i-1]), color=self.color[i-1])
|
||||
plt.xlabel(self.xaxis_name)
|
||||
plt.ylabel(self.yaxis_name)
|
||||
plt.legend(self.label)
|
||||
plt.savefig("%s.png" % (self.graph_image_name), dpi=96)
|
||||
plt.close()
|
||||
print("{}.png".format(self.graph_image_name))
|
||||
|
||||
return "%s.png" % (self.graph_image_name)
|
||||
# Unit Test
|
||||
if __name__ == "__main__":
|
||||
|
||||
output_html_1 = "graph_1.html"
|
||||
output_pdf_1 = "graph_1.pdf"
|
||||
|
||||
# test build_bar_graph with defaults
|
||||
graph = lf_bar_graph()
|
||||
graph_html_obj = """
|
||||
<img align='center' style='padding:15;margin:5;width:1000px;' src=""" + "%s" % (graph.build_bar_graph()) + """ border='1' />
|
||||
<br><br>
|
||||
"""
|
||||
#
|
||||
test_file = open(output_html_1, "w")
|
||||
test_file.write(graph_html_obj)
|
||||
test_file.close()
|
||||
|
||||
# write to pdf
|
||||
# write logic to generate pdf here
|
||||
# wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.focal_amd64.deb
|
||||
# sudo apt install ./wkhtmltox_0.12.6-1.focal_amd64.deb
|
||||
options = {"enable-local-file-access" : None} # prevent eerror Blocked access to file
|
||||
pdfkit.from_file(output_html_1, output_pdf_1, options=options)
|
||||
|
||||
|
||||
# test build_bar_graph setting values
|
||||
dataset = [[45,67,34,22],[22,45,12,34],[30,55,69,37]]
|
||||
x_axis_values = [1,2,3,4]
|
||||
|
||||
output_html_2 = "graph_2.html"
|
||||
output_pdf_2 = "graph_2.pdf"
|
||||
|
||||
# test build_bar_graph with defaults
|
||||
graph = lf_bar_graph(_data_set=dataset,
|
||||
_xaxis_name="stations",
|
||||
_yaxis_name="Throughput 2 (Mbps)",
|
||||
_xaxis_categories=x_axis_values,
|
||||
_graph_image_name="Bi-single_radio_2.4GHz",
|
||||
_label=["bi-downlink", "bi-uplink",'uplink'],
|
||||
_color=None,
|
||||
_color_edge='red')
|
||||
graph_html_obj = """
|
||||
<img align='center' style='padding:15;margin:5;width:1000px;' src=""" + "%s" % (graph.build_bar_graph()) + """ border='1' />
|
||||
<br><br>
|
||||
"""
|
||||
#
|
||||
test_file = open(output_html_2, "w")
|
||||
test_file.write(graph_html_obj)
|
||||
test_file.close()
|
||||
|
||||
# write to pdf
|
||||
# write logic to generate pdf here
|
||||
# wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.focal_amd64.deb
|
||||
# sudo apt install ./wkhtmltox_0.12.6-1.focal_amd64.deb
|
||||
options = {"enable-local-file-access" : None} # prevent eerror Blocked access to file
|
||||
pdfkit.from_file(output_html_2, output_pdf_2, options=options)
|
||||
|
||||
|
||||
|
||||
285
py-scripts/lf_mesh_test.py
Executable file
285
py-scripts/lf_mesh_test.py
Executable file
@@ -0,0 +1,285 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
Note: To Run this script gui should be opened with
|
||||
|
||||
path: cd LANforgeGUI_5.4.3 (5.4.3 can be changed with GUI version)
|
||||
pwd (Output : /home/lanforge/LANforgeGUI_5.4.3)
|
||||
./lfclient.bash -cli-socket 3990
|
||||
|
||||
This script is used to automate running Mesh tests. You
|
||||
may need to view a Mesh test configured through the GUI to understand
|
||||
the options and how best to input data.
|
||||
|
||||
./lf_mesh_test.py --mgr localhost --port 8080 --lf_user lanforge --lf_password lanforge \
|
||||
--instance_name mesh-instance --config_name test_con --upstream 1.1.eth1 \
|
||||
--raw_line 'selected_dut2: RootAP wactest 08:36:c9:19:47:40 (1)' \
|
||||
--raw_line 'selected_dut5: RootAP wactest 08:36:c9:19:47:50 (2)' \
|
||||
--duration 15s \
|
||||
--download_speed 85% --upload_speed 56Kbps \
|
||||
--raw_line 'velocity: 100' \
|
||||
--raw_lines_file example-configs/mesh-ferndale-cfg.txt \
|
||||
--test_rig Ferndale-Mesh-01 --pull_report
|
||||
|
||||
Note:
|
||||
--raw_line 'line contents' will add any setting to the test config. This is
|
||||
useful way to support any options not specifically enabled by the
|
||||
command options.
|
||||
--set modifications will be applied after the other config has happened,
|
||||
so it can be used to override any other config.
|
||||
|
||||
Example of raw text config for Mesh, to show other possible options:
|
||||
|
||||
show_events: 1
|
||||
show_log: 0
|
||||
port_sorting: 0
|
||||
kpi_id: Mesh
|
||||
bg: 0xE0ECF8
|
||||
test_rig:
|
||||
show_scan: 1
|
||||
auto_helper: 1
|
||||
skip_2: 0
|
||||
skip_5: 0
|
||||
skip_5b: 1
|
||||
skip_dual: 0
|
||||
skip_tri: 1
|
||||
selected_dut5: RootAP wactest 08:36:c9:19:47:50 (2)
|
||||
selected_dut2: RootAP wactest 08:36:c9:19:47:40 (1)
|
||||
upstream_port: 1.1.1 eth1
|
||||
operator:
|
||||
mconn: 5
|
||||
tos: 0
|
||||
dur: 60
|
||||
speed: 100%
|
||||
speed2: 56Kbps
|
||||
velocity: 100
|
||||
path_loops: 1
|
||||
bgscan_mod: simple
|
||||
bgscan_short: 30
|
||||
bgscan_long: 300
|
||||
bgscan_rssi: -60
|
||||
skip_2: 0
|
||||
skip_5: 0
|
||||
skip_dhcp: 0
|
||||
show_tx_mcs: 1
|
||||
show_rx_mcs: 1
|
||||
chamber-0: RootAP
|
||||
chamber-1: Node1
|
||||
chamber-2: Node2
|
||||
chamber-3:
|
||||
chamber-4: MobileStations
|
||||
sta_amount-0: 1
|
||||
sta_amount-1: 1
|
||||
sta_amount-2: 1
|
||||
sta_amount-3: 1
|
||||
sta_amount-4: 1
|
||||
radios-0-0: 1.2.2 wiphy0
|
||||
radios-0-1:
|
||||
radios-0-2:
|
||||
radios-0-3: 1.2.3 wiphy1
|
||||
radios-0-4:
|
||||
radios-0-5:
|
||||
radios-1-0: 1.3.2 wiphy0
|
||||
radios-1-1:
|
||||
radios-1-2:
|
||||
radios-1-3: 1.3.3 wiphy1
|
||||
radios-1-4:
|
||||
radios-1-5:
|
||||
radios-2-0: 1.4.2 wiphy0
|
||||
radios-2-1:
|
||||
radios-2-2:
|
||||
radios-2-3: 1.4.3 wiphy1
|
||||
radios-2-4:
|
||||
radios-2-5:
|
||||
radios-3-0:
|
||||
radios-3-1:
|
||||
radios-3-2:
|
||||
radios-3-3:
|
||||
radios-3-4:
|
||||
radios-3-5:
|
||||
radios-4-0: 1.1.2 wiphy0
|
||||
radios-4-1:
|
||||
radios-4-2:
|
||||
radios-4-3: 1.1.3 wiphy1
|
||||
radios-4-4:
|
||||
radios-4-5:
|
||||
ap_arrangements: Current Position
|
||||
tests: Roam
|
||||
traf_combo: STA
|
||||
sta_position: Current Position
|
||||
traffic_types: UDP
|
||||
direction: Download
|
||||
path: Orbit Current
|
||||
traf_use_sta: 0
|
||||
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import argparse
|
||||
import time
|
||||
import json
|
||||
from os import path
|
||||
|
||||
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'))
|
||||
|
||||
from cv_test_manager import cv_test as cvtest
|
||||
from cv_test_manager import *
|
||||
from cv_commands import chamberview as cv
|
||||
|
||||
|
||||
class MeshTest(cvtest):
|
||||
def __init__(self,
|
||||
lf_host="localhost",
|
||||
lf_port=8080,
|
||||
lf_user="lanforge",
|
||||
lf_password="lanforge",
|
||||
instance_name="dpt_instance",
|
||||
config_name="dpt_config",
|
||||
upstream="1.1.eth1",
|
||||
pull_report=False,
|
||||
load_old_cfg=False,
|
||||
upload_speed="56Kbps",
|
||||
download_speed="85%",
|
||||
duration="60s",
|
||||
enables=[],
|
||||
disables=[],
|
||||
raw_lines=[],
|
||||
raw_lines_file="",
|
||||
sets=[],
|
||||
):
|
||||
super().__init__(lfclient_host=lf_host, lfclient_port=lf_port)
|
||||
|
||||
self.lf_host = lf_host
|
||||
self.lf_port = lf_port
|
||||
self.lf_user = lf_user
|
||||
self.lf_password =lf_password
|
||||
self.createCV = cv(lf_host, lf_port);
|
||||
self.instance_name = instance_name
|
||||
self.config_name = config_name
|
||||
self.duration = duration
|
||||
self.upstream = upstream
|
||||
self.pull_report = pull_report
|
||||
self.load_old_cfg = load_old_cfg
|
||||
self.test_name = "Mesh"
|
||||
self.upload_speed = upload_speed
|
||||
self.download_speed = download_speed
|
||||
self.enables = enables
|
||||
self.disables = disables
|
||||
self.raw_lines = raw_lines
|
||||
self.raw_lines_file = raw_lines_file
|
||||
self.sets = sets
|
||||
|
||||
def setup(self):
|
||||
# Nothing to do at this time.
|
||||
return
|
||||
|
||||
|
||||
def run(self):
|
||||
self.createCV.sync_cv()
|
||||
time.sleep(2)
|
||||
self.createCV.sync_cv()
|
||||
|
||||
blob_test = "Mesh-"
|
||||
|
||||
self.rm_text_blob(self.config_name, blob_test) # To delete old config with same name
|
||||
self.show_text_blob(None, None, False)
|
||||
|
||||
# Test related settings
|
||||
cfg_options = []
|
||||
|
||||
### HERE###
|
||||
self.apply_cfg_options(cfg_options, self.enables, self.disables, self.raw_lines, self.raw_lines_file)
|
||||
|
||||
# cmd line args take precedence and so come last in the cfg array.
|
||||
if self.upstream != "":
|
||||
cfg_options.append("upstream_port: " + self.upstream)
|
||||
if self.download_speed != "":
|
||||
cfg_options.append("speed: " + self.download_speed)
|
||||
if self.upload_speed != "":
|
||||
cfg_options.append("speed2: " + self.upload_speed)
|
||||
if self.duration != "":
|
||||
cfg_options.append("duration: " + self.duration)
|
||||
|
||||
# We deleted the scenario earlier, now re-build new one line at a time.
|
||||
|
||||
self.build_cfg(self.config_name, blob_test, cfg_options)
|
||||
|
||||
cv_cmds = []
|
||||
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,
|
||||
cv_cmds)
|
||||
self.rm_text_blob(self.config_name, blob_test) # To delete old config with same name
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
parser = argparse.ArgumentParser("""
|
||||
Open this file in an editor and read the top notes for more details.
|
||||
|
||||
Example:
|
||||
./lf_mesh_test.py --mgr localhost --port 8080 --lf_user lanforge --lf_password lanforge \
|
||||
--instance_name mesh-instance --config_name test_con --upstream 1.1.eth1 \
|
||||
--raw_line 'selected_dut2: RootAP wactest 08:36:c9:19:47:40 (1)' \
|
||||
--raw_line 'selected_dut5: RootAP wactest 08:36:c9:19:47:50 (2)' \
|
||||
--duration 15s \
|
||||
--download_speed 85% --upload_speed 56Kbps \
|
||||
--raw_line 'velocity: 100' \
|
||||
--raw_lines_file example-configs/mesh-ferndale-cfg.txt \
|
||||
--test_rig Ferndale-Mesh-01 --pull_report
|
||||
|
||||
NOTE: There is quite a lot of config needed, see example-configs/mesh-ferndale-cfg.txt
|
||||
Suggestion is to configure the test through the GUI, make sure it works, then view
|
||||
the config and paste it into your own cfg.txt file.
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
cv_add_base_parser(parser) # see cv_test_manager.py
|
||||
|
||||
parser.add_argument("-u", "--upstream", type=str, default="",
|
||||
help="Upstream port for wifi capacity test ex. 1.1.eth2")
|
||||
|
||||
parser.add_argument("--download_speed", default="",
|
||||
help="Specify requested download speed. Percentage of theoretical is also supported. Default: 85%")
|
||||
parser.add_argument("--upload_speed", default="",
|
||||
help="Specify requested upload speed. Percentage of theoretical is also supported. Default: 0")
|
||||
parser.add_argument("--duration", default="",
|
||||
help="Specify duration of each traffic run")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
cv_base_adjust_parser(args)
|
||||
|
||||
CV_Test = MeshTest(lf_host = args.mgr,
|
||||
lf_port = args.port,
|
||||
lf_user = args.lf_user,
|
||||
lf_password = args.lf_password,
|
||||
instance_name = args.instance_name,
|
||||
config_name = args.config_name,
|
||||
upstream = args.upstream,
|
||||
pull_report = args.pull_report,
|
||||
load_old_cfg = args.load_old_cfg,
|
||||
download_speed = args.download_speed,
|
||||
upload_speed = args.upload_speed,
|
||||
duration = args.duration,
|
||||
enables = args.enable,
|
||||
disables = args.disable,
|
||||
raw_lines = args.raw_line,
|
||||
raw_lines_file = args.raw_lines_file,
|
||||
sets = args.set
|
||||
)
|
||||
CV_Test.setup()
|
||||
CV_Test.run()
|
||||
|
||||
# Mesh does not do KPI currently.
|
||||
#CV_Test.check_influx_kpi(args)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
358
py-scripts/lf_report.py
Executable file
358
py-scripts/lf_report.py
Executable file
@@ -0,0 +1,358 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
'''
|
||||
NAME: lf_report.py
|
||||
|
||||
PURPOSE:
|
||||
|
||||
This program is a helper class for reporting results for a lanforge python script.
|
||||
The class will generate an output directory based on date and time in the /home/lanforge/reports-data/ .
|
||||
If the reports-data is not present then the date and time directory will be created in the current directory.
|
||||
The banner and Candela Technology logo will be copied in the results directory.
|
||||
The results directory may be over written and many of the other paramaters during construction.
|
||||
Creating the date time directory on construction was a design choice.
|
||||
|
||||
EXAMPLE:
|
||||
|
||||
This is a helper class, a unit test is included at the bottom of the file.
|
||||
To test lf_report.py and lf_graph.py together use the lf_report_test.py file
|
||||
|
||||
LICENSE:
|
||||
Free to distribute and modify. LANforge systems must be licensed.
|
||||
Copyright 2021 Candela Technologies Inc
|
||||
|
||||
'''
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import datetime
|
||||
import pandas as pd
|
||||
import pdfkit
|
||||
|
||||
# internal candela references included during intial phases, to be deleted at future date
|
||||
# https://candelatech.atlassian.net/wiki/spaces/LANFORGE/pages/372703360/Scripting+Data+Collection+March+2021
|
||||
# base report class
|
||||
class lf_report():
|
||||
def __init__(self,
|
||||
#_path the report directory under which the report directories will be created.
|
||||
_path = "/home/lanforge/report-data",
|
||||
_alt_path = "",
|
||||
_date = "",
|
||||
_title="LANForge Test Run Heading",
|
||||
_table_title="LANForge Table Heading",
|
||||
_graph_title="LANForge Graph Title",
|
||||
_obj = "",
|
||||
_obj_title = "",
|
||||
_output_html="outfile.html",
|
||||
_output_pdf="outfile.pdf",
|
||||
_results_dir_name = "LANforge_Test_Results",
|
||||
_output_format = 'html', # pass in on the write functionality, current not used
|
||||
_dataframe="",
|
||||
_path_date_time=""): # this is where the final report is placed.
|
||||
#other report paths,
|
||||
|
||||
# _path is where the directory with the data time will be created
|
||||
if _path == "local" or _path == "here":
|
||||
self.path = os.path.abspath(__file__)
|
||||
print("path set to file path: {}".format(self.path))
|
||||
elif _alt_path != "":
|
||||
self.path = _alt_path
|
||||
print("path set to alt path: {}".format(self.path))
|
||||
else:
|
||||
self.path = _path
|
||||
print("path set: {}".format(self.path))
|
||||
|
||||
self.dataframe=_dataframe
|
||||
self.title=_title
|
||||
self.table_title=_table_title
|
||||
self.graph_title=_graph_title
|
||||
self.date=_date
|
||||
self.output_html=_output_html
|
||||
self.path_date_time = _path_date_time
|
||||
self.write_output_html = ""
|
||||
self.output_pdf=_output_pdf
|
||||
self.write_output_pdf = ""
|
||||
self.banner_html = ""
|
||||
self.graph_titles=""
|
||||
self.graph_image=""
|
||||
self.html = ""
|
||||
self.custom_html = ""
|
||||
self.objective = _obj
|
||||
self.obj_title = _obj_title
|
||||
#self.systeminfopath = ""
|
||||
self.date_time_directory = ""
|
||||
self.banner_directory = "artifacts"
|
||||
self.banner_file_name = "banner.png" # does this need to be configurable
|
||||
self.logo_directory = "artifacts"
|
||||
self.logo_file_name = "CandelaLogo2-90dpi-200x90-trans.png" # does this need to be configurable.
|
||||
self.current_path = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
# pass in _date to allow to change after construction
|
||||
self.set_date_time_directory(_date,_results_dir_name)
|
||||
self.build_date_time_directory()
|
||||
|
||||
# move the banners and candela images to report path
|
||||
self.copy_banner()
|
||||
self.copy_logo()
|
||||
|
||||
def copy_banner(self):
|
||||
banner_src_file = str(self.current_path)+'/'+str(self.banner_directory)+'/'+str(self.banner_file_name)
|
||||
banner_dst_file = str(self.path_date_time)+'/'+ str(self.banner_file_name)
|
||||
#print("banner src_file: {}".format(banner_src_file))
|
||||
#print("dst_file: {}".format(banner_dst_file))
|
||||
shutil.copy(banner_src_file,banner_dst_file)
|
||||
|
||||
def copy_logo(self):
|
||||
logo_src_file = str(self.current_path)+'/'+str(self.logo_directory)+'/'+str(self.logo_file_name)
|
||||
logo_dst_file = str(self.path_date_time)+'/'+ str(self.logo_file_name)
|
||||
#print("logo_src_file: {}".format(logo_src_file))
|
||||
#print("logo_dst_file: {}".format(logo_dst_file))
|
||||
shutil.copy(logo_src_file,logo_dst_file)
|
||||
|
||||
def move_graph_image(self,):
|
||||
graph_src_file = str(self.graph_image)
|
||||
graph_dst_file = str(self.path_date_time)+'/'+ str(self.graph_image)
|
||||
print("graph_src_file: {}".format(graph_src_file))
|
||||
print("graph_dst_file: {}".format(graph_dst_file))
|
||||
shutil.move(graph_src_file,graph_dst_file)
|
||||
|
||||
|
||||
def set_path(self,_path):
|
||||
self.path = _path
|
||||
|
||||
def set_date_time_directory(self,_date,_results_dir_name):
|
||||
self.date = _date
|
||||
self.results_dir_name = _results_dir_name
|
||||
if self.date != "":
|
||||
self.date_time_directory = str(self.date) + str("_") + str(self.results_dir_name)
|
||||
else:
|
||||
self.date = str(datetime.datetime.now().strftime("%Y_%m_%d_%H_%M_%S")).replace(':','-')
|
||||
self.date_time_directory = self.date + str("_") + str(self.results_dir_name)
|
||||
|
||||
#def set_date_time_directory(self,date_time_directory):
|
||||
# self.date_time_directory = date_time_directory
|
||||
|
||||
|
||||
def build_date_time_directory(self):
|
||||
if self.date_time_directory == "":
|
||||
self.set_date_time_directory()
|
||||
self.path_date_time = os.path.join(self.path, self.date_time_directory)
|
||||
print("path_date_time {}".format(self.path_date_time))
|
||||
try:
|
||||
if not os.path.exists(self.path_date_time):
|
||||
os.mkdir(self.path_date_time)
|
||||
except:
|
||||
self.path_date_time = os.path.join(self.current_path, self.date_time_directory)
|
||||
if not os.path.exists(self.path_date_time):
|
||||
os.mkdir(self.path_date_time)
|
||||
print("report path : {}".format(self.path_date_time))
|
||||
|
||||
def set_title(self,_title):
|
||||
self.title = _title
|
||||
|
||||
def set_table_title(self,_table_title):
|
||||
self.table_title = _table_title
|
||||
|
||||
def set_graph_title(self,_graph_title):
|
||||
self.graph_title = _graph_title
|
||||
|
||||
def set_date(self,_date):
|
||||
self.date = _date
|
||||
|
||||
def set_table_dataframe(self,_dataframe):
|
||||
self.dataframe = _dataframe
|
||||
|
||||
def set_table_dataframe_from_csv(self,_csv):
|
||||
self.dataframe = pd.read_csv(_csv)
|
||||
|
||||
def set_custom_html(self,_custom_html):
|
||||
self.custom_html = _custom_html
|
||||
|
||||
def set_obj_html(self,_obj_title, _obj ):
|
||||
self.objective = _obj
|
||||
self.obj_title = _obj_title
|
||||
|
||||
def set_graph_image(self,_graph_image):
|
||||
self.graph_image = _graph_image
|
||||
|
||||
def get_path(self):
|
||||
return self.path
|
||||
# get_path_date_time, get_report_path and need to be the same ()
|
||||
def get_path_date_time(self):
|
||||
return self.path_date_time
|
||||
|
||||
def get_report_path(self):
|
||||
return self.path_date_time
|
||||
|
||||
def file_add_path(self, file):
|
||||
output_file = str(self.path_date_time)+'/'+ str(file)
|
||||
print("output file {}".format(output_file))
|
||||
return output_file
|
||||
|
||||
def write_html(self):
|
||||
self.write_output_html = str(self.path_date_time)+'/'+ str(self.output_html)
|
||||
print("write_output_html: {}".format(self.write_output_html))
|
||||
try:
|
||||
test_file = open(self.write_output_html, "w")
|
||||
test_file.write(self.html)
|
||||
test_file.close()
|
||||
except:
|
||||
print("write_html failed")
|
||||
return self.write_output_html
|
||||
|
||||
# https://wkhtmltopdf.org/usage/wkhtmltopdf.txt
|
||||
# page_size A4, A3, Letter, Legal
|
||||
# orientation Portrait , Landscape
|
||||
def write_pdf(self, _page_size = 'A4', _orientation = 'Portrait'):
|
||||
# write logic to generate pdf here
|
||||
# wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.focal_amd64.deb
|
||||
# sudo apt install ./wkhtmltox_0.12.6-1.focal_amd64.deb
|
||||
|
||||
options = {"enable-local-file-access" : None,
|
||||
'orientation': _orientation,
|
||||
'page-size': _page_size} # prevent error Blocked access to file
|
||||
self.write_output_pdf = str(self.path_date_time)+'/'+ str(self.output_pdf)
|
||||
pdfkit.from_file(self.write_output_html, self.write_output_pdf, options=options)
|
||||
pass
|
||||
|
||||
def generate_report(self):
|
||||
self.write_html()
|
||||
self.write_pdf()
|
||||
|
||||
# only use is pass all data in constructor, no graph output
|
||||
def build_all(self):
|
||||
self.build_banner()
|
||||
self.build_table_title()
|
||||
self.build_table()
|
||||
|
||||
def build_banner(self):
|
||||
self.banner_html = """
|
||||
<!DOCTYPE html>
|
||||
<html lang='en'>
|
||||
<head>
|
||||
<meta charset='UTF-8'>
|
||||
<meta name='viewport' content='width=device-width, initial-scale=1' />
|
||||
<br>
|
||||
</head>
|
||||
|
||||
<title>BANNER </title></head>
|
||||
<body>
|
||||
<div class='Section report_banner-1000x205' style='background-image:url("banner.png");background-repeat:no-repeat;padding:0;margin:0;min-width:1000px; min-height:205px;width:1000px; height:205px;max-width:1000px; max-height:205px;'>
|
||||
<br>
|
||||
<img align='right' style='padding:25;margin:5;width:200px;' src="CandelaLogo2-90dpi-200x90-trans.png" border='0' />
|
||||
|
||||
<div class='HeaderStyle'>
|
||||
<br>
|
||||
<h1 class='TitleFontPrint' style='color:darkgreen;'>""" + str(self.title) + """</h1>
|
||||
<h3 class='TitleFontPrint' style='color:darkgreen;'>""" + str(self.date) + """</h3>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
</div>
|
||||
"""
|
||||
self.html += self.banner_html
|
||||
|
||||
def build_table_title(self):
|
||||
self.table_title_html = """
|
||||
<html lang='en'>
|
||||
<head>
|
||||
<meta charset='UTF-8'>
|
||||
<meta name='viewport' content='width=device-width, initial-scale=1' />
|
||||
<div class='HeaderStyle'>
|
||||
<h2 class='TitleFontPrint' style='color:darkgreen;'>""" + str(self.table_title) + """</h2>
|
||||
"""
|
||||
self.html += self.table_title_html
|
||||
|
||||
def build_date_time(self):
|
||||
self.date_time = str(datetime.datetime.now().strftime("%Y-%m-%d-%H-h-%m-m-%S-s")).replace(':','-')
|
||||
return self.date_time
|
||||
|
||||
def build_path_date_time(self):
|
||||
try:
|
||||
self.path_date_time = os.path.join(self.path,self.date_time)
|
||||
os.mkdir(self.path_date_time)
|
||||
except:
|
||||
curr_dir_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
self.path_date_time = os.path.join(curr_dir_path,self.date_time)
|
||||
os.mkdir(self.path_date_time)
|
||||
|
||||
def build_table(self):
|
||||
self.dataframe_html = self.dataframe.to_html(index=False) # have the index be able to be passed in.
|
||||
self.html += self.dataframe_html
|
||||
|
||||
def build_custom(self):
|
||||
self.html += self.custom_html
|
||||
|
||||
def build_objective(self):
|
||||
self.obj_html = """
|
||||
<!-- Test Objective -->
|
||||
<h3 align='left'>""" + str(self.obj_title) + """</h3>
|
||||
<p align='left' width='900'>""" + str(self.objective) + """</p>
|
||||
"""
|
||||
self.html += self.obj_html
|
||||
|
||||
def build_graph_title(self):
|
||||
self.table_graph_html = """
|
||||
<html lang='en'>
|
||||
<head>
|
||||
<meta charset='UTF-8'>
|
||||
<meta name='viewport' content='width=device-width, initial-scale=1' />
|
||||
<div class='HeaderStyle'>
|
||||
<h2 class='TitleFontPrint' style='color:darkgreen;'>""" + str(self.graph_title) + """</h2>
|
||||
"""
|
||||
self.html += self.table_graph_html
|
||||
|
||||
def build_graph(self):
|
||||
self.graph_html_obj = """
|
||||
<img align='center' style='padding:15;margin:5;width:1000px;' src=""" + "%s" % (self.graph_image) + """ border='1' />
|
||||
<br><br>
|
||||
"""
|
||||
self.html +=self.graph_html_obj
|
||||
|
||||
|
||||
# Unit Test
|
||||
if __name__ == "__main__":
|
||||
|
||||
# Testing: generate data frame
|
||||
dataframe = pd.DataFrame({
|
||||
'product':['CT521a-264-1ac-1n','CT521a-1ac-1ax','CT522-264-1ac2-1n','CT523c-2ac2-db-10g-cu','CT523c-3ac2-db-10g-cu','CT523c-8ax-ac10g-cu','CT523c-192-2ac2-1ac-10g'],
|
||||
'radios':[1,1,2,2,6,9,3],
|
||||
'MIMO':['N','N','N','Y','Y','Y','Y'],
|
||||
'stations':[200,64,200,128,384,72,192],
|
||||
'mbps':[300,300,300,10000,10000,10000,10000]
|
||||
})
|
||||
|
||||
print(dataframe)
|
||||
|
||||
# Testing: generate data frame
|
||||
dataframe2 = pd.DataFrame({
|
||||
'station':[1,2,3,4,5,6,7],
|
||||
'time_seconds':[23,78,22,19,45,22,25]
|
||||
})
|
||||
|
||||
report = lf_report()
|
||||
report.set_title("Banner Title One")
|
||||
report.build_banner()
|
||||
|
||||
report.set_table_title("Title One")
|
||||
report.build_table_title()
|
||||
|
||||
report.set_table_dataframe(dataframe)
|
||||
report.build_table()
|
||||
|
||||
report.set_table_title("Title Two")
|
||||
report.build_table_title()
|
||||
|
||||
report.set_table_dataframe(dataframe2)
|
||||
report.build_table()
|
||||
|
||||
#report.build_all()
|
||||
|
||||
html_file = report.write_html()
|
||||
print("returned file ")
|
||||
print(html_file)
|
||||
report.write_pdf()
|
||||
|
||||
print("report path {}".format(report.get_path()))
|
||||
129
py-scripts/lf_report_test.py
Normal file
129
py-scripts/lf_report_test.py
Normal file
@@ -0,0 +1,129 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib as mpl
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import pdfkit
|
||||
from lf_report import lf_report
|
||||
from lf_graph import lf_bar_graph, lf_scatter_graph , lf_stacked_graph
|
||||
|
||||
# Unit Test
|
||||
if __name__ == "__main__":
|
||||
|
||||
# Testing: generate data frame
|
||||
dataframe = pd.DataFrame({
|
||||
'product':['CT521a-264-1ac-1n','CT521a-1ac-1ax','CT522-264-1ac2-1n','CT523c-2ac2-db-10g-cu','CT523c-3ac2-db-10g-cu','CT523c-8ax-ac10g-cu','CT523c-192-2ac2-1ac-10g'],
|
||||
'radios':[1,1,2,2,6,9,3],
|
||||
'MIMO':['N','N','N','Y','Y','Y','Y'],
|
||||
'stations':[200,64,200,128,384,72,192],
|
||||
'mbps':[300,300,300,10000,10000,10000,10000]
|
||||
})
|
||||
|
||||
print(dataframe)
|
||||
|
||||
# Testing: generate data frame
|
||||
dataframe2 = pd.DataFrame({
|
||||
'station':[1,2,3,4,5,6,7],
|
||||
'time_seconds':[23,78,22,19,45,22,25]
|
||||
})
|
||||
|
||||
|
||||
#report = lf_report(_dataframe=dataframe)
|
||||
report = lf_report()
|
||||
|
||||
report_path = report.get_path()
|
||||
report_path_date_time = report.get_path_date_time()
|
||||
|
||||
print("path: {}".format(report_path))
|
||||
print("path_date_time: {}".format(report_path_date_time))
|
||||
|
||||
report.set_title("Banner Title One")
|
||||
report.build_banner()
|
||||
|
||||
|
||||
#report.set_title("Banner Title Two")
|
||||
#report.build_banner()
|
||||
|
||||
report.set_table_title("Title One")
|
||||
report.build_table_title()
|
||||
|
||||
report.set_table_dataframe(dataframe)
|
||||
report.build_table()
|
||||
|
||||
report.set_table_title("Title Two")
|
||||
report.build_table_title()
|
||||
|
||||
report.set_table_dataframe(dataframe2)
|
||||
report.build_table()
|
||||
|
||||
# test lf_graph in report
|
||||
dataset = [[45,67,34,22],[22,45,12,34],[30,55,69,37]]
|
||||
x_axis_values = [1,2,3,4]
|
||||
|
||||
report.set_graph_title("Graph Title")
|
||||
report.build_graph_title()
|
||||
|
||||
graph = lf_bar_graph(_data_set=dataset,
|
||||
_xaxis_name="stations",
|
||||
_yaxis_name="Throughput 2 (Mbps)",
|
||||
_xaxis_categories=x_axis_values,
|
||||
_graph_image_name="Bi-single_radio_2.4GHz",
|
||||
_label=["bi-downlink", "bi-uplink",'uplink'],
|
||||
_color=None,
|
||||
_color_edge='red')
|
||||
|
||||
|
||||
graph_png = graph.build_bar_graph()
|
||||
|
||||
print("graph name {}".format(graph_png))
|
||||
|
||||
report.set_graph_image(graph_png)
|
||||
# need to move the graph image to the results
|
||||
report.move_graph_image()
|
||||
|
||||
report.build_graph()
|
||||
set1 = [1, 2, 3, 4]
|
||||
set2 = [[45, 67, 45, 34], [34, 56, 45, 34], [45, 78, 23, 45]]
|
||||
graph2 = lf_scatter_graph(_x_data_set=set1, _y_data_set=set2, _xaxis_name="x-axis",
|
||||
_yaxis_name="y-axis",
|
||||
_graph_image_name="image_name1",
|
||||
_color=None,
|
||||
_label=["s1", "s2", "s3"])
|
||||
graph_png = graph2.build_scatter_graph()
|
||||
|
||||
print("graph name {}".format(graph_png))
|
||||
|
||||
report.set_graph_image(graph_png)
|
||||
report.move_graph_image()
|
||||
|
||||
report.build_graph()
|
||||
dataset = [["1", "2", "3", "4"], [12, 45, 67, 34], [23, 67, 23, 12], [25, 45, 34, 23]]
|
||||
graph = lf_stacked_graph(_data_set=dataset,
|
||||
_xaxis_name="Stations",
|
||||
_yaxis_name="Login PASS/FAIL",
|
||||
_label=['Success', 'Fail', 'both'],
|
||||
_graph_image_name="login_pass_fail1",
|
||||
_color=None)
|
||||
|
||||
graph_png = graph.build_stacked_graph()
|
||||
|
||||
print("graph name {}".format(graph_png))
|
||||
|
||||
report.set_graph_image(graph_png)
|
||||
report.move_graph_image()
|
||||
report.build_graph()
|
||||
#report.build_all()
|
||||
|
||||
html_file = report.write_html()
|
||||
print("returned file {}".format(html_file))
|
||||
print(html_file)
|
||||
|
||||
# try other pdf formats
|
||||
#report.write_pdf()
|
||||
#report.write_pdf(_page_size = 'A3', _orientation='Landscape')
|
||||
#report.write_pdf(_page_size = 'A4', _orientation='Landscape')
|
||||
report.write_pdf(_page_size = 'Legal', _orientation='Landscape')
|
||||
#report.write_pdf(_page_size = 'Legal', _orientation='Portrait')
|
||||
|
||||
#report.generate_report()
|
||||
273
py-scripts/lf_rvr_test.py
Executable file
273
py-scripts/lf_rvr_test.py
Executable file
@@ -0,0 +1,273 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
Note: To Run this script gui should be opened with
|
||||
|
||||
path: cd LANforgeGUI_5.4.3 (5.4.3 can be changed with GUI version)
|
||||
pwd (Output : /home/lanforge/LANforgeGUI_5.4.3)
|
||||
./lfclient.bash -cli-socket 3990
|
||||
|
||||
This script is used to automate running Rate-vs-Range tests. You
|
||||
may need to view a Rate-vs-Range test configured through the GUI to understand
|
||||
the options and how best to input data.
|
||||
|
||||
./lf_rvr_test.py --mgr localhost --port 8080 --lf_user lanforge --lf_password lanforge \
|
||||
--instance_name rvr-instance --config_name test_con --upstream 1.1.eth1 \
|
||||
--dut RootAP --duration 15s --station 1.1.wlan0 \
|
||||
--download_speed 85% --upload_speed 56Kbps \
|
||||
--raw_line 'pkts: MTU' \
|
||||
--raw_line 'directions: DUT Transmit' \
|
||||
--raw_line 'traffic_types: TCP' \
|
||||
--test_rig Ferndale-Mesh-01 --pull_report \
|
||||
--raw_line 'attenuator: 1.1.1040' \
|
||||
--raw_line 'attenuations: 0..+50..950' \
|
||||
--raw_line 'attenuator_mod: 3' \
|
||||
--influx_host c7-graphana --influx_port 8086 --influx_org Candela \
|
||||
--influx_token=-u_Wd-L8o992701QF0c5UmqEp7w7Z7YOMaWLxOMgmHfATJGnQbbmYyNxHBR9PgD6taM_tcxqJl6U8DjU1xINFQ== \
|
||||
--influx_bucket ben \
|
||||
--influx_tag testbed Ferndale-Advanced
|
||||
|
||||
Note:
|
||||
attenuator_mod: selects the attenuator modules, bit-field.
|
||||
This example uses 3, which is first two attenuator modules on Attenuator ID 1040.
|
||||
|
||||
--raw_line 'line contents' will add any setting to the test config. This is
|
||||
useful way to support any options not specifically enabled by the
|
||||
command options.
|
||||
--set modifications will be applied after the other config has happened,
|
||||
so it can be used to override any other config.
|
||||
|
||||
Example of raw text config for Rate-vsRange, to show other possible options:
|
||||
|
||||
sel_port-0: 1.1.wlan0
|
||||
show_events: 1
|
||||
show_log: 0
|
||||
port_sorting: 0
|
||||
kpi_id: Rate vs Range
|
||||
bg: 0xE0ECF8
|
||||
test_rig:
|
||||
show_scan: 1
|
||||
auto_helper: 0
|
||||
skip_2: 0
|
||||
skip_5: 0
|
||||
skip_5b: 1
|
||||
skip_dual: 0
|
||||
skip_tri: 1
|
||||
selected_dut: RootAP
|
||||
duration: 15000
|
||||
traffic_port: 1.1.6 wlan0
|
||||
upstream_port: 1.1.1 eth1
|
||||
path_loss: 10
|
||||
speed: 85%
|
||||
speed2: 56Kbps
|
||||
min_rssi_bound: -150
|
||||
max_rssi_bound: 0
|
||||
channels: AUTO
|
||||
modes: Auto
|
||||
pkts: MTU
|
||||
spatial_streams: AUTO
|
||||
security_options: AUTO
|
||||
bandw_options: AUTO
|
||||
traffic_types: TCP
|
||||
directions: DUT Transmit
|
||||
txo_preamble: OFDM
|
||||
txo_mcs: 0 CCK, OFDM, HT, VHT
|
||||
txo_retries: No Retry
|
||||
txo_sgi: OFF
|
||||
txo_txpower: 15
|
||||
attenuator: 1.1.1040
|
||||
attenuator2: 0
|
||||
attenuator_mod: 243
|
||||
attenuator_mod2: 255
|
||||
attenuations: 0..+50..950
|
||||
attenuations2: 0..+50..950
|
||||
chamber: 0
|
||||
tt_deg: 0..+45..359
|
||||
cust_pkt_sz:
|
||||
show_bar_labels: 1
|
||||
show_prcnt_tput: 0
|
||||
show_3s: 0
|
||||
show_ll_graphs: 0
|
||||
show_gp_graphs: 1
|
||||
show_1m: 1
|
||||
pause_iter: 0
|
||||
outer_loop_atten: 0
|
||||
show_realtime: 1
|
||||
operator:
|
||||
mconn: 1
|
||||
mpkt: 1000
|
||||
tos: 0
|
||||
loop_iterations: 1
|
||||
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import argparse
|
||||
import time
|
||||
import json
|
||||
from os import path
|
||||
|
||||
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'))
|
||||
|
||||
from cv_test_manager import cv_test as cvtest
|
||||
from cv_test_manager import *
|
||||
from cv_commands import chamberview as cv
|
||||
|
||||
|
||||
class RvrTest(cvtest):
|
||||
def __init__(self,
|
||||
lf_host="localhost",
|
||||
lf_port=8080,
|
||||
lf_user="lanforge",
|
||||
lf_password="lanforge",
|
||||
instance_name="rvr_instance",
|
||||
config_name="rvr_config",
|
||||
upstream="1.1.eth1",
|
||||
pull_report=False,
|
||||
load_old_cfg=False,
|
||||
upload_speed="0",
|
||||
download_speed="85%",
|
||||
duration="15s",
|
||||
station="1.1.wlan0",
|
||||
dut="NA",
|
||||
enables=[],
|
||||
disables=[],
|
||||
raw_lines=[],
|
||||
raw_lines_file="",
|
||||
sets=[],
|
||||
):
|
||||
super().__init__(lfclient_host=lf_host, lfclient_port=lf_port)
|
||||
|
||||
self.lf_host = lf_host
|
||||
self.lf_port = lf_port
|
||||
self.lf_user = lf_user
|
||||
self.lf_password =lf_password
|
||||
self.createCV = cv(lf_host, lf_port);
|
||||
self.instance_name = instance_name
|
||||
self.config_name = config_name
|
||||
self.dut = dut
|
||||
self.duration = duration
|
||||
self.upstream = upstream
|
||||
self.station = station
|
||||
self.pull_report = pull_report
|
||||
self.load_old_cfg = load_old_cfg
|
||||
self.test_name = "Rate vs Range"
|
||||
self.upload_speed = upload_speed
|
||||
self.download_speed = download_speed
|
||||
self.enables = enables
|
||||
self.disables = disables
|
||||
self.raw_lines = raw_lines
|
||||
self.raw_lines_file = raw_lines_file
|
||||
self.sets = sets
|
||||
|
||||
def setup(self):
|
||||
# Nothing to do at this time.
|
||||
return
|
||||
|
||||
|
||||
def run(self):
|
||||
self.createCV.sync_cv()
|
||||
time.sleep(2)
|
||||
self.createCV.sync_cv()
|
||||
|
||||
blob_test = "rvr-test-latest-"
|
||||
|
||||
self.rm_text_blob(self.config_name, blob_test) # To delete old config with same name
|
||||
self.show_text_blob(None, None, False)
|
||||
|
||||
# Test related settings
|
||||
cfg_options = []
|
||||
|
||||
### HERE###
|
||||
self.apply_cfg_options(cfg_options, self.enables, self.disables, self.raw_lines, self.raw_lines_file)
|
||||
|
||||
# cmd line args take precedence and so come last in the cfg array.
|
||||
if self.upstream != "":
|
||||
cfg_options.append("upstream_port: " + self.upstream)
|
||||
if self.station != "":
|
||||
cfg_options.append("traffic_port: " + self.station)
|
||||
if self.download_speed != "":
|
||||
cfg_options.append("speed: " + self.download_speed)
|
||||
if self.upload_speed != "":
|
||||
cfg_options.append("speed2: " + self.upload_speed)
|
||||
if self.duration != "":
|
||||
cfg_options.append("duration: " + self.duration)
|
||||
if self.dut != "":
|
||||
cfg_options.append("selected_dut: " + self.dut)
|
||||
|
||||
# We deleted the scenario earlier, now re-build new one line at a time.
|
||||
|
||||
self.build_cfg(self.config_name, blob_test, cfg_options)
|
||||
|
||||
cv_cmds = []
|
||||
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,
|
||||
cv_cmds)
|
||||
self.rm_text_blob(self.config_name, blob_test) # To delete old config with same name
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
parser = argparse.ArgumentParser("""
|
||||
Open this file in an editor and read the top notes for more details.
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
cv_add_base_parser(parser) # see cv_test_manager.py
|
||||
|
||||
parser.add_argument("-u", "--upstream", type=str, default="",
|
||||
help="Upstream port for wifi capacity test ex. 1.1.eth2")
|
||||
parser.add_argument("--station", type=str, default="",
|
||||
help="Station to be used in this test, example: 1.1.sta01500")
|
||||
|
||||
parser.add_argument("--dut", default="",
|
||||
help="Specify DUT used by this test, example: linksys-8450")
|
||||
parser.add_argument("--download_speed", default="",
|
||||
help="Specify requested download speed. Percentage of theoretical is also supported. Default: 85%")
|
||||
parser.add_argument("--upload_speed", default="",
|
||||
help="Specify requested upload speed. Percentage of theoretical is also supported. Default: 0")
|
||||
parser.add_argument("--duration", default="",
|
||||
help="Specify duration of each traffic run")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
cv_base_adjust_parser(args)
|
||||
|
||||
CV_Test = RvrTest(lf_host = args.mgr,
|
||||
lf_port = args.port,
|
||||
lf_user = args.lf_user,
|
||||
lf_password = args.lf_password,
|
||||
instance_name = args.instance_name,
|
||||
config_name = args.config_name,
|
||||
upstream = args.upstream,
|
||||
pull_report = args.pull_report,
|
||||
load_old_cfg = args.load_old_cfg,
|
||||
download_speed = args.download_speed,
|
||||
upload_speed = args.upload_speed,
|
||||
duration = args.duration,
|
||||
dut = args.dut,
|
||||
station = args.station,
|
||||
enables = args.enable,
|
||||
disables = args.disable,
|
||||
raw_lines = args.raw_line,
|
||||
raw_lines_file = args.raw_lines_file,
|
||||
sets = args.set
|
||||
)
|
||||
CV_Test.setup()
|
||||
CV_Test.run()
|
||||
|
||||
CV_Test.check_influx_kpi(args)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
2631
py-scripts/lf_snp_test.py
Executable file
2631
py-scripts/lf_snp_test.py
Executable file
File diff suppressed because it is too large
Load Diff
326
py-scripts/lf_tr398_test.py
Executable file
326
py-scripts/lf_tr398_test.py
Executable file
@@ -0,0 +1,326 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
Note: To Run this script gui should be opened with
|
||||
|
||||
path: cd LANforgeGUI_5.4.3 (5.4.3 can be changed with GUI version)
|
||||
pwd (Output : /home/lanforge/LANforgeGUI_5.4.3)
|
||||
./lfclient.bash -cli-socket 3990
|
||||
|
||||
This script is used to automate running TR398 tests. You
|
||||
may need to view a TR398 test configured through the GUI to understand
|
||||
the options and how best to input data.
|
||||
|
||||
./lf_tr398_test.py --mgr localhost --port 8080 --lf_user lanforge --lf_password lanforge \
|
||||
--instance_name tr398-instance --config_name test_con \
|
||||
--upstream 1.2.eth2 \
|
||||
--dut5 'TR398-DUT ruckus750-5 4c:b1:cd:18:e8:ec (1)' \
|
||||
--dut2 'TR398-DUT ruckus750-2 4c:b1:cd:18:e8:e8 (2)' \
|
||||
--raw_lines_file example-configs/tr398-ferndale-ac-cfg.txt \
|
||||
--set 'Calibrate Attenuators' 0 \
|
||||
--set 'Receiver Sensitivity' 0 \
|
||||
--set 'Maximum Connection' 1 \
|
||||
--set 'Maximum Throughput' 1 \
|
||||
--set 'Airtime Fairness' 0 \
|
||||
--set 'Range Versus Rate' 0 \
|
||||
--set 'Spatial Consistency' 0 \
|
||||
--set 'Multiple STAs Performance' 0 \
|
||||
--set 'Multiple Assoc Stability' 0 \
|
||||
--set 'Downlink MU-MIMO' 0 \
|
||||
--set 'AP Coexistence' 0 \
|
||||
--set 'Long Term Stability' 0 \
|
||||
--test_rig Testbed-01
|
||||
|
||||
Note:
|
||||
--raw_line 'line contents' will add any setting to the test config. This is
|
||||
useful way to support any options not specifically enabled by the
|
||||
command options.
|
||||
--set modifications will be applied after the other config has happened,
|
||||
so it can be used to override any other config. Above, we are disabling many
|
||||
of the subtests, and enablign just Maximum Connection and Maximum Throughput
|
||||
tests.
|
||||
|
||||
The RSSI values are calibrated, so you will need to run the calibration step and
|
||||
call with appropriate values for your particular testbed. This is loaded from
|
||||
example-configs/tr398-ferndale-ac-cfg.txt in this example.
|
||||
Contents of that file is a list of raw lines, for instance:
|
||||
|
||||
rssi_0_2-0: -26
|
||||
rssi_0_2-1: -26
|
||||
rssi_0_2-2: -26
|
||||
....
|
||||
|
||||
Example of raw text config for TR-398, to show other possible options:
|
||||
|
||||
show_events: 1
|
||||
show_log: 0
|
||||
port_sorting: 0
|
||||
kpi_id: TR_398
|
||||
notes0: Standard LANforge TR-398 automation setup, DUT is in large chamber CT840a, LANforge test system is in
|
||||
notes1: smaller CT810a chamber. CT704b and CT714 4-module attenuators are used. Directional antennas
|
||||
notes2: mounted on the sides of the DUT chamber are used to communicate to the DUT. DUT is facing forward at
|
||||
notes3: the zero-rotation angle.
|
||||
bg: 0xE0ECF8
|
||||
test_rig: TR-398 test bed
|
||||
show_scan: 1
|
||||
auto_helper: 1
|
||||
skip_2: 0
|
||||
skip_5: 0
|
||||
skip_5b: 1
|
||||
skip_dual: 0
|
||||
skip_tri: 1
|
||||
selected_dut5: TR398-DUT ruckus750-5 4c:b1:cd:18:e8:ec (1)
|
||||
selected_dut2: TR398-DUT ruckus750-2 4c:b1:cd:18:e8:e8 (2)
|
||||
upstream_port: 1.2.2 eth2
|
||||
operator:
|
||||
mconn: 5
|
||||
band2_freq: 2437
|
||||
band5_freq: 5180
|
||||
tos: 0
|
||||
speed: 65%
|
||||
speed_max_cx_2: 2000000
|
||||
speed_max_cx_5: 8000000
|
||||
max_tput_speed_2: 100000000
|
||||
max_tput_speed_5: 560000000
|
||||
rxsens_deg_rot: 45
|
||||
rxsens_pre_steps: 8
|
||||
stability_udp_dur: 3600
|
||||
stability_iter: 288
|
||||
calibrate_mode: 4
|
||||
calibrate_nss: 1
|
||||
dur120: 120
|
||||
dur180: 180
|
||||
i_5g_80: 195000000
|
||||
i_5g_40: 90000000
|
||||
i_2g_20: 32000000
|
||||
spatial_deg_rot: 30
|
||||
spatial_retry: 0
|
||||
reset_pp: 99
|
||||
rxsens_stop_at_pass: 0
|
||||
auto_coex: 1
|
||||
rvr_adj: 0
|
||||
rssi_2m_2: -20
|
||||
rssi_2m_5: -32
|
||||
extra_dl_path_loss: 3
|
||||
dur60: 60
|
||||
turn_table: TR-398
|
||||
radio-0: 1.1.2 wiphy0
|
||||
radio-1: 1.1.3 wiphy1
|
||||
radio-2: 1.1.4 wiphy2
|
||||
radio-3: 1.1.5 wiphy3
|
||||
radio-4: 1.1.6 wiphy4
|
||||
radio-5: 1.1.7 wiphy5
|
||||
rssi_0_2-0: -26
|
||||
rssi_0_2-1: -26
|
||||
rssi_0_2-2: -26
|
||||
rssi_0_2-3: -26
|
||||
rssi_0_2-4: -27
|
||||
rssi_0_2-5: -27
|
||||
rssi_0_2-6: -27
|
||||
rssi_0_2-7: -27
|
||||
rssi_0_2-8: -25
|
||||
rssi_0_2-9: -25
|
||||
rssi_0_2-10: -25
|
||||
rssi_0_2-11: -25
|
||||
rssi_0_5-0: -38
|
||||
rssi_0_5-1: -38
|
||||
rssi_0_5-2: -38
|
||||
rssi_0_5-3: -38
|
||||
rssi_0_5-4: -38
|
||||
rssi_0_5-5: -38
|
||||
rssi_0_5-6: -38
|
||||
rssi_0_5-7: -38
|
||||
rssi_0_5-8: -47
|
||||
rssi_0_5-9: -47
|
||||
rssi_0_5-10: -47
|
||||
rssi_0_5-11: -47
|
||||
atten-0: 1.1.85.0
|
||||
atten-1: 1.1.85.1
|
||||
atten-2: 1.1.85.2
|
||||
atten-3: 1.1.85.3
|
||||
atten-4: 1.1.1002.0
|
||||
atten-5: 1.1.1002.1
|
||||
atten-8: 1.1.1002.2
|
||||
atten-9: 1.1.1002.3
|
||||
atten_cal: 1
|
||||
rxsens: 0
|
||||
max_cx: 0
|
||||
max_tput: 0
|
||||
atf: 0
|
||||
rvr: 0
|
||||
spatial: 0
|
||||
multi_sta: 0
|
||||
reset: 0
|
||||
mu_mimo: 0
|
||||
stability: 0
|
||||
ap_coex: 0
|
||||
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import argparse
|
||||
import time
|
||||
import json
|
||||
from os import path
|
||||
|
||||
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'))
|
||||
|
||||
from cv_test_manager import cv_test as cvtest
|
||||
from cv_test_manager import *
|
||||
from cv_commands import chamberview as cv
|
||||
|
||||
|
||||
class DataplaneTest(cvtest):
|
||||
def __init__(self,
|
||||
lf_host="localhost",
|
||||
lf_port=8080,
|
||||
lf_user="lanforge",
|
||||
lf_password="lanforge",
|
||||
instance_name="tr398_instance",
|
||||
config_name="tr398_config",
|
||||
upstream="1.2.eth2",
|
||||
pull_report=False,
|
||||
load_old_cfg=False,
|
||||
raw_lines_file="",
|
||||
dut5="",
|
||||
dut2="",
|
||||
enables=[],
|
||||
disables=[],
|
||||
raw_lines=[],
|
||||
sets=[],
|
||||
):
|
||||
super().__init__(lfclient_host=lf_host, lfclient_port=lf_port)
|
||||
|
||||
self.lf_host = lf_host
|
||||
self.lf_port = lf_port
|
||||
self.lf_user = lf_user
|
||||
self.lf_password =lf_password
|
||||
self.createCV = cv(lf_host, lf_port);
|
||||
self.instance_name = instance_name
|
||||
self.config_name = config_name
|
||||
self.dut5 = dut5
|
||||
self.dut2 = dut2
|
||||
self.raw_lines_file = raw_lines_file
|
||||
self.upstream = upstream
|
||||
self.pull_report = pull_report
|
||||
self.load_old_cfg = load_old_cfg
|
||||
self.test_name = "TR-398"
|
||||
self.enables = enables
|
||||
self.disables = disables
|
||||
self.raw_lines = raw_lines
|
||||
self.sets = sets
|
||||
|
||||
def setup(self):
|
||||
# Nothing to do at this time.
|
||||
return
|
||||
|
||||
|
||||
def run(self):
|
||||
self.createCV.sync_cv()
|
||||
time.sleep(2)
|
||||
self.createCV.sync_cv()
|
||||
|
||||
blob_test = "%s-"%(self.test_name)
|
||||
|
||||
self.rm_text_blob(self.config_name, blob_test) # To delete old config with same name
|
||||
self.show_text_blob(None, None, False)
|
||||
|
||||
# Test related settings
|
||||
cfg_options = []
|
||||
|
||||
self.apply_cfg_options(cfg_options, self.enables, self.disables, self.raw_lines, self.raw_lines_file)
|
||||
|
||||
# cmd line args take precedence
|
||||
if self.upstream != "":
|
||||
cfg_options.append("upstream_port: " + self.upstream)
|
||||
if self.dut5 != "":
|
||||
cfg_options.append("selected_dut5: " + self.dut5)
|
||||
if self.dut2 != "":
|
||||
cfg_options.append("selected_dut2: " + self.dut2)
|
||||
|
||||
# We deleted the scenario earlier, now re-build new one line at a time.
|
||||
|
||||
self.build_cfg(self.config_name, blob_test, cfg_options)
|
||||
|
||||
cv_cmds = []
|
||||
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,
|
||||
cv_cmds)
|
||||
|
||||
self.rm_text_blob(self.config_name, blob_test) # To delete old config with same name
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
parser = argparse.ArgumentParser("""
|
||||
Open this file in an editor and read the top notes for more details.
|
||||
|
||||
Example:
|
||||
|
||||
./lf_tr398_test.py --mgr localhost --port 8080 --lf_user lanforge --lf_password lanforge \
|
||||
--instance_name tr398-instance --config_name test_con \
|
||||
--upstream 1.2.eth2 \
|
||||
--dut5 'TR398-DUT ruckus750-5 4c:b1:cd:18:e8:ec (1)' \
|
||||
--dut2 'TR398-DUT ruckus750-2 4c:b1:cd:18:e8:e8 (2)' \
|
||||
--raw_lines_file example-configs/tr398-ferndale-ac-cfg.txt \
|
||||
--set 'Calibrate Attenuators' 0 \
|
||||
--set 'Receiver Sensitivity' 0 \
|
||||
--set 'Maximum Connection' 1 \
|
||||
--set 'Maximum Throughput' 1 \
|
||||
--set 'Airtime Fairness' 0 \
|
||||
--set 'Range Versus Rate' 0 \
|
||||
--set 'Spatial Consistency' 0 \
|
||||
--set 'Multiple STAs Performance' 0 \
|
||||
--set 'Multiple Assoc Stability' 0 \
|
||||
--set 'Downlink MU-MIMO' 0 \
|
||||
--set 'AP Coexistence' 0 \
|
||||
--set 'Long Term Stability' 0 \
|
||||
--test_rig Testbed-01
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
cv_add_base_parser(parser) # see cv_test_manager.py
|
||||
|
||||
parser.add_argument("-u", "--upstream", type=str, default="",
|
||||
help="Upstream port for wifi capacity test ex. 1.1.eth2")
|
||||
|
||||
parser.add_argument("--dut2", default="",
|
||||
help="Specify 2Ghz DUT used by this test, example: 'TR398-DUT ruckus750-2 4c:b1:cd:18:e8:e8 (2)'")
|
||||
parser.add_argument("--dut5", default="",
|
||||
help="Specify 5Ghz DUT used by this test, example: 'TR398-DUT ruckus750-5 4c:b1:cd:18:e8:ec (1)'")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
cv_base_adjust_parser(args)
|
||||
|
||||
CV_Test = DataplaneTest(lf_host = args.mgr,
|
||||
lf_port = args.port,
|
||||
lf_user = args.lf_user,
|
||||
lf_password = args.lf_password,
|
||||
instance_name = args.instance_name,
|
||||
config_name = args.config_name,
|
||||
upstream = args.upstream,
|
||||
pull_report = args.pull_report,
|
||||
load_old_cfg = args.load_old_cfg,
|
||||
dut2 = args.dut2,
|
||||
dut5 = args.dut5,
|
||||
raw_lines_file = args.raw_lines_file,
|
||||
enables = args.enable,
|
||||
disables = args.disable,
|
||||
raw_lines = args.raw_line,
|
||||
sets = args.set
|
||||
)
|
||||
CV_Test.setup()
|
||||
CV_Test.run()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
546
py-scripts/lf_wifi_capacity_test.py
Executable file
546
py-scripts/lf_wifi_capacity_test.py
Executable file
@@ -0,0 +1,546 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
Note: To Run this script gui should be opened with
|
||||
|
||||
path: cd LANforgeGUI_5.4.3 (5.4.3 can be changed with GUI version)
|
||||
pwd (Output : /home/lanforge/LANforgeGUI_5.4.3)
|
||||
./lfclient.bash -cli-socket 3990
|
||||
|
||||
Note: This is a test file which will run a wifi capacity test.
|
||||
ex. on how to run this script (if stations are available in lanforge):
|
||||
The influx part can be skipped if you are not using influx/graphana.
|
||||
|
||||
./lf_wifi_capacity_test.py --mgr localhost --port 8080 --lf_user lanforge --lf_password lanforge \
|
||||
--instance_name this_inst --config_name test_con --upstream 1.1.eth2 --batch_size 1,5,25,50,100 --loop_iter 1 \
|
||||
--protocol UDP-IPv4 --duration 6000 --pull_report \
|
||||
--test_rig Testbed-01 \
|
||||
--influx_host c7-graphana --influx_port 8086 --influx_org Candela \
|
||||
--influx_token=-u_Wd-L8o992701QF0c5UmqEp7w7Z7YOMaWLxOMgmHfATJGnQbbmYyNxHBR9PgD6taM_tcxqJl6U8DjU1xINFQ== \
|
||||
--influx_bucket ben --influx_tag testbed Ferndale-01
|
||||
|
||||
ex. on how to run this script (to create new stations):
|
||||
./lf_wifi_capacity_test.py --mgr localhost --port 8080 --lf_user lanforge --lf_password lanforge \
|
||||
--instance_name wct_instance --config_name wifi_config --upstream 1.1.eth1 --batch_size 1,5,25 --loop_iter 1 \
|
||||
--protocol UDP-IPv4 --duration 6000 --pull_report --stations 1.1.sta0000,1.1.sta0001 \
|
||||
--create_stations --radio wiphy0 --ssid test-ssid --security open --paswd [BLANK] \
|
||||
--test_rig Testbed-01
|
||||
|
||||
|
||||
Note:
|
||||
--pull_report == If specified, this will pull reports from lanforge to your code directory,
|
||||
from where you are running this code
|
||||
|
||||
--stations == Enter stations to use for wifi capacity
|
||||
|
||||
Example of raw text config for Capacity, to show other possible options:
|
||||
|
||||
sel_port-0: 1.1.eth1
|
||||
sel_port-1: 1.1.sta00000
|
||||
sel_port-2: 1.1.sta00001
|
||||
sel_port-3: 1.1.sta00002
|
||||
sel_port-4: 1.1.sta00003
|
||||
sel_port-5: 1.1.sta00004
|
||||
sel_port-6: 1.1.sta00005
|
||||
sel_port-7: 1.1.sta00006
|
||||
sel_port-8: 1.1.sta00007
|
||||
sel_port-9: 1.1.sta00008
|
||||
sel_port-10: 1.1.sta00009
|
||||
sel_port-11: 1.1.sta00010
|
||||
sel_port-12: 1.1.sta00011
|
||||
sel_port-13: 1.1.sta00012
|
||||
sel_port-14: 1.1.sta00013
|
||||
sel_port-15: 1.1.sta00014
|
||||
sel_port-16: 1.1.sta00015
|
||||
sel_port-17: 1.1.sta00016
|
||||
sel_port-18: 1.1.sta00017
|
||||
sel_port-19: 1.1.sta00018
|
||||
sel_port-20: 1.1.sta00019
|
||||
sel_port-21: 1.1.sta00020
|
||||
sel_port-22: 1.1.sta00021
|
||||
sel_port-23: 1.1.sta00022
|
||||
sel_port-24: 1.1.sta00023
|
||||
sel_port-25: 1.1.sta00024
|
||||
sel_port-26: 1.1.sta00025
|
||||
sel_port-27: 1.1.sta00026
|
||||
sel_port-28: 1.1.sta00027
|
||||
sel_port-29: 1.1.sta00028
|
||||
sel_port-30: 1.1.sta00029
|
||||
sel_port-31: 1.1.sta00030
|
||||
sel_port-32: 1.1.sta00031
|
||||
sel_port-33: 1.1.sta00032
|
||||
sel_port-34: 1.1.sta00033
|
||||
sel_port-35: 1.1.sta00034
|
||||
sel_port-36: 1.1.sta00035
|
||||
sel_port-37: 1.1.sta00036
|
||||
sel_port-38: 1.1.sta00037
|
||||
sel_port-39: 1.1.sta00038
|
||||
sel_port-40: 1.1.sta00039
|
||||
sel_port-41: 1.1.sta00040
|
||||
sel_port-42: 1.1.sta00041
|
||||
sel_port-43: 1.1.sta00042
|
||||
sel_port-44: 1.1.sta00043
|
||||
sel_port-45: 1.1.sta00044
|
||||
sel_port-46: 1.1.sta00045
|
||||
sel_port-47: 1.1.sta00046
|
||||
sel_port-48: 1.1.sta00047
|
||||
sel_port-49: 1.1.sta00048
|
||||
sel_port-50: 1.1.sta00049
|
||||
sel_port-51: 1.1.sta00500
|
||||
sel_port-52: 1.1.sta00501
|
||||
sel_port-53: 1.1.sta00502
|
||||
sel_port-54: 1.1.sta00503
|
||||
sel_port-55: 1.1.sta00504
|
||||
sel_port-56: 1.1.sta00505
|
||||
sel_port-57: 1.1.sta00506
|
||||
sel_port-58: 1.1.sta00507
|
||||
sel_port-59: 1.1.sta00508
|
||||
sel_port-60: 1.1.sta00509
|
||||
sel_port-61: 1.1.sta00510
|
||||
sel_port-62: 1.1.sta00511
|
||||
sel_port-63: 1.1.sta00512
|
||||
sel_port-64: 1.1.sta00513
|
||||
sel_port-65: 1.1.sta00514
|
||||
sel_port-66: 1.1.sta00515
|
||||
sel_port-67: 1.1.sta00516
|
||||
sel_port-68: 1.1.sta00517
|
||||
sel_port-69: 1.1.sta00518
|
||||
sel_port-70: 1.1.sta00519
|
||||
sel_port-71: 1.1.sta00520
|
||||
sel_port-72: 1.1.sta00521
|
||||
sel_port-73: 1.1.sta00522
|
||||
sel_port-74: 1.1.sta00523
|
||||
sel_port-75: 1.1.sta00524
|
||||
sel_port-76: 1.1.sta00525
|
||||
sel_port-77: 1.1.sta00526
|
||||
sel_port-78: 1.1.sta00527
|
||||
sel_port-79: 1.1.sta00528
|
||||
sel_port-80: 1.1.sta00529
|
||||
sel_port-81: 1.1.sta00530
|
||||
sel_port-82: 1.1.sta00531
|
||||
sel_port-83: 1.1.sta00532
|
||||
sel_port-84: 1.1.sta00533
|
||||
sel_port-85: 1.1.sta00534
|
||||
sel_port-86: 1.1.sta00535
|
||||
sel_port-87: 1.1.sta00536
|
||||
sel_port-88: 1.1.sta00537
|
||||
sel_port-89: 1.1.sta00538
|
||||
sel_port-90: 1.1.sta00539
|
||||
sel_port-91: 1.1.sta00540
|
||||
sel_port-92: 1.1.sta00541
|
||||
sel_port-93: 1.1.sta00542
|
||||
sel_port-94: 1.1.sta00543
|
||||
sel_port-95: 1.1.sta00544
|
||||
sel_port-96: 1.1.sta00545
|
||||
sel_port-97: 1.1.sta00546
|
||||
sel_port-98: 1.1.sta00547
|
||||
sel_port-99: 1.1.sta00548
|
||||
sel_port-100: 1.1.sta00549
|
||||
sel_port-101: 1.1.sta01000
|
||||
sel_port-102: 1.1.sta01001
|
||||
sel_port-103: 1.1.sta01002
|
||||
sel_port-104: 1.1.sta01003
|
||||
sel_port-105: 1.1.sta01004
|
||||
sel_port-106: 1.1.sta01005
|
||||
sel_port-107: 1.1.sta01006
|
||||
sel_port-108: 1.1.sta01007
|
||||
sel_port-109: 1.1.sta01008
|
||||
sel_port-110: 1.1.sta01009
|
||||
sel_port-111: 1.1.sta01010
|
||||
sel_port-112: 1.1.sta01011
|
||||
sel_port-113: 1.1.sta01012
|
||||
sel_port-114: 1.1.sta01013
|
||||
sel_port-115: 1.1.sta01014
|
||||
sel_port-116: 1.1.sta01015
|
||||
sel_port-117: 1.1.sta01016
|
||||
sel_port-118: 1.1.sta01017
|
||||
sel_port-119: 1.1.sta01018
|
||||
sel_port-120: 1.1.sta01019
|
||||
sel_port-121: 1.1.sta01020
|
||||
sel_port-122: 1.1.sta01021
|
||||
sel_port-123: 1.1.sta01022
|
||||
sel_port-124: 1.1.sta01023
|
||||
sel_port-125: 1.1.sta01024
|
||||
sel_port-126: 1.1.sta01025
|
||||
sel_port-127: 1.1.sta01026
|
||||
sel_port-128: 1.1.sta01027
|
||||
sel_port-129: 1.1.sta01028
|
||||
sel_port-130: 1.1.sta01029
|
||||
sel_port-131: 1.1.sta01030
|
||||
sel_port-132: 1.1.sta01031
|
||||
sel_port-133: 1.1.sta01032
|
||||
sel_port-134: 1.1.sta01033
|
||||
sel_port-135: 1.1.sta01034
|
||||
sel_port-136: 1.1.sta01035
|
||||
sel_port-137: 1.1.sta01036
|
||||
sel_port-138: 1.1.sta01037
|
||||
sel_port-139: 1.1.sta01038
|
||||
sel_port-140: 1.1.sta01039
|
||||
sel_port-141: 1.1.sta01040
|
||||
sel_port-142: 1.1.sta01041
|
||||
sel_port-143: 1.1.sta01042
|
||||
sel_port-144: 1.1.sta01043
|
||||
sel_port-145: 1.1.sta01044
|
||||
sel_port-146: 1.1.sta01045
|
||||
sel_port-147: 1.1.sta01046
|
||||
sel_port-148: 1.1.sta01047
|
||||
sel_port-149: 1.1.sta01048
|
||||
sel_port-150: 1.1.sta01049
|
||||
sel_port-151: 1.1.sta01500
|
||||
sel_port-152: 1.1.sta01501
|
||||
sel_port-153: 1.1.sta01502
|
||||
sel_port-154: 1.1.sta01503
|
||||
sel_port-155: 1.1.sta01504
|
||||
sel_port-156: 1.1.sta01505
|
||||
sel_port-157: 1.1.sta01506
|
||||
sel_port-158: 1.1.sta01507
|
||||
sel_port-159: 1.1.sta01508
|
||||
sel_port-160: 1.1.sta01509
|
||||
sel_port-161: 1.1.sta01510
|
||||
sel_port-162: 1.1.sta01511
|
||||
sel_port-163: 1.1.sta01512
|
||||
sel_port-164: 1.1.sta01513
|
||||
sel_port-165: 1.1.sta01514
|
||||
sel_port-166: 1.1.sta01515
|
||||
sel_port-167: 1.1.sta01516
|
||||
sel_port-168: 1.1.sta01517
|
||||
sel_port-169: 1.1.sta01518
|
||||
sel_port-170: 1.1.sta01519
|
||||
sel_port-171: 1.1.sta01520
|
||||
sel_port-172: 1.1.sta01521
|
||||
sel_port-173: 1.1.sta01522
|
||||
sel_port-174: 1.1.sta01523
|
||||
sel_port-175: 1.1.sta01524
|
||||
sel_port-176: 1.1.sta01525
|
||||
sel_port-177: 1.1.sta01526
|
||||
sel_port-178: 1.1.sta01527
|
||||
sel_port-179: 1.1.sta01528
|
||||
sel_port-180: 1.1.sta01529
|
||||
sel_port-181: 1.1.sta01530
|
||||
sel_port-182: 1.1.sta01531
|
||||
sel_port-183: 1.1.sta01532
|
||||
sel_port-184: 1.1.sta01533
|
||||
sel_port-185: 1.1.sta01534
|
||||
sel_port-186: 1.1.sta01535
|
||||
sel_port-187: 1.1.sta01536
|
||||
sel_port-188: 1.1.sta01537
|
||||
sel_port-189: 1.1.sta01538
|
||||
sel_port-190: 1.1.sta01539
|
||||
sel_port-191: 1.1.sta01540
|
||||
sel_port-192: 1.1.sta01541
|
||||
sel_port-193: 1.1.sta01542
|
||||
sel_port-194: 1.1.sta01543
|
||||
sel_port-195: 1.1.sta01544
|
||||
sel_port-196: 1.1.sta01545
|
||||
sel_port-197: 1.1.wlan4
|
||||
sel_port-198: 1.1.wlan5
|
||||
sel_port-199: 1.1.wlan6
|
||||
sel_port-200: 1.1.wlan7
|
||||
show_events: 1
|
||||
show_log: 0
|
||||
port_sorting: 0
|
||||
kpi_id: WiFi Capacity
|
||||
bg: 0xE0ECF8
|
||||
test_rig:
|
||||
show_scan: 1
|
||||
auto_helper: 1
|
||||
skip_2: 0
|
||||
skip_5: 0
|
||||
skip_5b: 1
|
||||
skip_dual: 0
|
||||
skip_tri: 1
|
||||
batch_size: 1
|
||||
loop_iter: 1
|
||||
duration: 6000
|
||||
test_groups: 0
|
||||
test_groups_subset: 0
|
||||
protocol: UDP-IPv4
|
||||
dl_rate_sel: Total Download Rate:
|
||||
dl_rate: 1000000000
|
||||
ul_rate_sel: Total Upload Rate:
|
||||
ul_rate: 10000000
|
||||
prcnt_tcp: 100000
|
||||
l4_endp:
|
||||
pdu_sz: -1
|
||||
mss_sel: 1
|
||||
sock_buffer: 0
|
||||
ip_tos: 0
|
||||
multi_conn: -1
|
||||
min_speed: -1
|
||||
ps_interval: 60-second Running Average
|
||||
fairness: 0
|
||||
naptime: 0
|
||||
before_clear: 5000
|
||||
rpt_timer: 1000
|
||||
try_lower: 0
|
||||
rnd_rate: 1
|
||||
leave_ports_up: 0
|
||||
down_quiesce: 0
|
||||
udp_nat: 1
|
||||
record_other_ssids: 0
|
||||
clear_reset_counters: 0
|
||||
do_pf: 0
|
||||
pf_min_period_dl: 0
|
||||
pf_min_period_ul: 0
|
||||
pf_max_reconnects: 0
|
||||
use_mix_pdu: 0
|
||||
pdu_prcnt_pps: 1
|
||||
pdu_prcnt_bps: 0
|
||||
pdu_mix_ln-0:
|
||||
show_scan: 1
|
||||
show_golden_3p: 0
|
||||
save_csv: 0
|
||||
show_realtime: 1
|
||||
show_pie: 1
|
||||
show_per_loop_totals: 1
|
||||
show_cx_time: 1
|
||||
show_dhcp: 1
|
||||
show_anqp: 1
|
||||
show_4way: 1
|
||||
show_latency: 1
|
||||
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import argparse
|
||||
import time
|
||||
import json
|
||||
from os import path
|
||||
|
||||
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'))
|
||||
|
||||
from cv_test_manager import cv_test as cvtest
|
||||
from cv_commands import chamberview as cv
|
||||
from cv_test_manager import *
|
||||
|
||||
|
||||
class WiFiCapacityTest(cvtest):
|
||||
def __init__(self,
|
||||
lf_host="localhost",
|
||||
lf_port=8080,
|
||||
lf_user="lanforge",
|
||||
lf_password="lanforge",
|
||||
instance_name="wct_instance",
|
||||
config_name="wifi_config",
|
||||
upstream="eth1",
|
||||
batch_size="1",
|
||||
loop_iter="1",
|
||||
protocol="UDP-IPv4",
|
||||
duration="5000",
|
||||
pull_report=False,
|
||||
load_old_cfg=False,
|
||||
upload_rate="10Mbps",
|
||||
download_rate="1Gbps",
|
||||
sort="interleave",
|
||||
stations="",
|
||||
create_stations=False,
|
||||
radio="wiphy0",
|
||||
security="open",
|
||||
paswd="[BLANK]",
|
||||
ssid="",
|
||||
enables=[],
|
||||
disables=[],
|
||||
raw_lines=[],
|
||||
raw_lines_file="",
|
||||
sets=[],
|
||||
):
|
||||
super().__init__(lfclient_host=lf_host, lfclient_port=lf_port)
|
||||
|
||||
self.lf_host = lf_host
|
||||
self.lf_port = lf_port
|
||||
self.lf_user = lf_user
|
||||
self.lf_password =lf_password
|
||||
self.createCV = cv(lf_host, lf_port);
|
||||
self.station_profile = self.new_station_profile()
|
||||
self.pull_report = pull_report
|
||||
self.load_old_cfg = load_old_cfg
|
||||
self.instance_name = instance_name
|
||||
self.config_name = config_name
|
||||
self.test_name = "WiFi Capacity"
|
||||
self.batch_size = batch_size
|
||||
self.loop_iter = loop_iter
|
||||
self.protocol = protocol
|
||||
self.duration = duration
|
||||
self.upload_rate = upload_rate
|
||||
self.download_rate = download_rate
|
||||
self.upstream = upstream
|
||||
self.sort = sort
|
||||
self.stations = stations
|
||||
self.create_stations =create_stations
|
||||
self.security = security
|
||||
self.ssid = ssid
|
||||
self.paswd = paswd
|
||||
self.radio = radio
|
||||
self.enables = enables
|
||||
self.disables = disables
|
||||
self.raw_lines = raw_lines
|
||||
self.raw_lines_file = raw_lines_file
|
||||
self.sets = sets
|
||||
|
||||
def setup(self):
|
||||
if self.create_stations and self.stations != "":
|
||||
sta = self.stations.split(",")
|
||||
self.station_profile.cleanup(sta)
|
||||
self.station_profile.use_security(self.security, self.ssid, self.paswd)
|
||||
self.station_profile.create(radio=self.radio, sta_names_=sta, debug=self.debug)
|
||||
self.station_profile.admin_up()
|
||||
self.wait_for_ip(station_list=sta)
|
||||
print("stations created")
|
||||
|
||||
|
||||
def run(self):
|
||||
self.createCV.sync_cv()
|
||||
time.sleep(2)
|
||||
|
||||
self.rm_text_blob(self.config_name, "Wifi-Capacity-") # To delete old config with same name
|
||||
self.show_text_blob(None, None, False)
|
||||
|
||||
# Test related settings
|
||||
cfg_options = []
|
||||
|
||||
port_list = [self.upstream]
|
||||
if self.stations == "":
|
||||
stas = self.station_map() # See realm
|
||||
for eid in stas.keys():
|
||||
port_list.append(eid)
|
||||
else:
|
||||
stas = self.stations.split(",")
|
||||
for s in stas:
|
||||
port_list.append(s)
|
||||
|
||||
idx = 0
|
||||
for eid in port_list:
|
||||
add_port = "sel_port-" + str(idx) + ": " + eid
|
||||
self.create_test_config(self.config_name, "Wifi-Capacity-", add_port)
|
||||
idx += 1
|
||||
|
||||
self.apply_cfg_options(cfg_options, self.enables, self.disables, self.raw_lines, self.raw_lines_file)
|
||||
|
||||
if self.batch_size != "":
|
||||
cfg_options.append("batch_size: " + self.batch_size)
|
||||
if self.loop_iter != "":
|
||||
cfg_options.append("loop_iter: " + self.loop_iter)
|
||||
if self.protocol != "":
|
||||
cfg_options.append("protocol: " + str(self.protocol))
|
||||
if self.duration != "":
|
||||
cfg_options.append("duration: " + self.duration)
|
||||
if self.upload_rate != "":
|
||||
cfg_options.append("ul_rate: " + self.upload_rate)
|
||||
if self.download_rate != "":
|
||||
cfg_options.append("dl_rate: " + self.download_rate)
|
||||
|
||||
blob_test = "Wifi-Capacity-"
|
||||
|
||||
# We deleted the scenario earlier, now re-build new one line at a time.
|
||||
self.build_cfg(self.config_name, blob_test, cfg_options)
|
||||
|
||||
cv_cmds = []
|
||||
|
||||
if self.sort == 'linear':
|
||||
cmd = "cv click '%s' 'Linear Sort'" % self.instance_name
|
||||
cv_cmds.append(cmd)
|
||||
if self.sort == 'interleave':
|
||||
cmd = "cv click '%s' 'Interleave Sort'" % self.instance_name
|
||||
cv_cmds.append(cmd)
|
||||
|
||||
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,
|
||||
cv_cmds)
|
||||
|
||||
self.rm_text_blob(self.config_name, blob_test) # To delete old config with same name
|
||||
|
||||
self.rm_text_blob(self.config_name, "Wifi-Capacity-") # To delete old config with same name
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="""
|
||||
./lf_wifi_capacity_test.py --mgr localhost --port 8080 --lf_user lanforge --lf_password lanforge \
|
||||
--instance_name wct_instance --config_name wifi_config --upstream 1.1.eth1 --batch_size 1 --loop_iter 1 \
|
||||
--protocol UDP-IPv4 --duration 6000 --pull_report --stations 1.1.sta0000,1.1.sta0001 \
|
||||
--create_stations --radio wiphy0 --ssid test-ssid --security open --paswd [BLANK] \
|
||||
--test_rig Testbed-01 \
|
||||
--influx_host c7-graphana --influx_port 8086 --influx_org Candela \
|
||||
--influx_token=-u_Wd-L8o992701QF0c5UmqEp7w7Z7YOMaWLxOMgmHfATJGnQbbmYyNxHBR9PgD6taM_tcxqJl6U8DjU1xINFQ== \
|
||||
--influx_bucket ben \
|
||||
--influx_tag testbed Ferndale-01
|
||||
""")
|
||||
|
||||
cv_add_base_parser(parser) # see cv_test_manager.py
|
||||
|
||||
parser.add_argument("-u", "--upstream", type=str, default="",
|
||||
help="Upstream port for wifi capacity test ex. 1.1.eth1")
|
||||
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("-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("-paswd", "--paswd", default="[BLANK]",
|
||||
help="ssid Password")
|
||||
args = parser.parse_args()
|
||||
|
||||
cv_base_adjust_parser(args)
|
||||
|
||||
WFC_Test = WiFiCapacityTest(lf_host=args.mgr,
|
||||
lf_port=args.port,
|
||||
lf_user=args.lf_user,
|
||||
lf_password=args.lf_password,
|
||||
instance_name=args.instance_name,
|
||||
config_name=args.config_name,
|
||||
upstream=args.upstream,
|
||||
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.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()
|
||||
|
||||
WFC_Test.check_influx_kpi(args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
192
py-scripts/measure_station_time_up.py
Executable file
192
py-scripts/measure_station_time_up.py
Executable file
@@ -0,0 +1,192 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
Script for creating a variable number of stations.
|
||||
"""
|
||||
|
||||
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'))
|
||||
from LANforge.lfcli_base import LFCliBase
|
||||
from LANforge import LFUtils
|
||||
from realm import Realm
|
||||
import datetime
|
||||
import pprint
|
||||
import pandas as pd
|
||||
import time
|
||||
|
||||
|
||||
class MeasureTimeUp(Realm):
|
||||
def __init__(self,
|
||||
_ssid=None,
|
||||
_security=None,
|
||||
_password=None,
|
||||
_host=None,
|
||||
_port=None,
|
||||
_num_sta=None,
|
||||
_number_template="00000",
|
||||
_radio=["wiphy0", "wiphy1"],
|
||||
_proxy_str=None,
|
||||
_debug_on=False,
|
||||
_up=True,
|
||||
_exit_on_error=False,
|
||||
_exit_on_fail=False,
|
||||
_load=None,
|
||||
_action="overwrite",
|
||||
_clean_chambers="store_true",
|
||||
_start=None,
|
||||
_quiesce=None,
|
||||
_stop=None,
|
||||
_clean_dut="no"):
|
||||
super().__init__(_host,
|
||||
_port)
|
||||
self.host = _host
|
||||
self.port = _port
|
||||
self.ssid = _ssid
|
||||
self.security = _security
|
||||
self.password = _password
|
||||
self.num_sta = _num_sta
|
||||
self.radio = _radio
|
||||
# self.timeout = 120
|
||||
self.number_template = _number_template
|
||||
self.debug = _debug_on
|
||||
self.up = _up
|
||||
self.station_profile = self.new_station_profile()
|
||||
self.station_profile.lfclient_url = self.lfclient_url
|
||||
self.station_profile.ssid = self.ssid
|
||||
self.station_profile.ssid_pass = self.password,
|
||||
self.station_profile.security = self.security
|
||||
self.station_profile.number_template_ = self.number_template
|
||||
self.station_profile.mode = 0
|
||||
self.load = _load
|
||||
self.action = _action
|
||||
self.clean_chambers = _clean_chambers
|
||||
self.start = _start
|
||||
self.quiesce = _quiesce
|
||||
self.stop = _stop
|
||||
self.clean_dut = _clean_dut
|
||||
|
||||
def build(self):
|
||||
# Build stations
|
||||
self.station_profile.use_security(self.security, self.ssid, self.password)
|
||||
self.station_profile.set_number_template(self.number_template)
|
||||
|
||||
print("Creating stations")
|
||||
start_num = 0
|
||||
sta_names = []
|
||||
for item in self.radio:
|
||||
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)
|
||||
sta_list = LFUtils.port_name_series(prefix="sta",
|
||||
start_id=start_num,
|
||||
end_id=self.num_sta + start_num,
|
||||
padding_number=10000,
|
||||
radio=item)
|
||||
start_num = self.num_sta + start_num + 1
|
||||
sta_names.extend(sta_list)
|
||||
self.station_profile.create(radio=item, sta_names_=sta_list, debug=self.debug)
|
||||
|
||||
def station_up(self):
|
||||
if self.up:
|
||||
self.station_profile.admin_up()
|
||||
self.wait_for_ip(station_list=self.station_profile.station_names)
|
||||
self._pass("PASS: Station build finished")
|
||||
|
||||
def scenario(self):
|
||||
if self.load is not None:
|
||||
data = {
|
||||
"name": self.load,
|
||||
"action": self.action,
|
||||
"clean_dut": "no",
|
||||
"clean_chambers": "no"
|
||||
}
|
||||
if self.clean_dut:
|
||||
data['clean_dut'] = "yes"
|
||||
if self.clean_chambers:
|
||||
data['clean_chambers'] = "yes"
|
||||
print("Loading database %s" % self.load)
|
||||
self.json_post("/cli-json/load", data)
|
||||
|
||||
elif self.start is not None:
|
||||
print("Starting test group %s..." % self.start)
|
||||
self.json_post("/cli-json/start_group", {"name": self.start})
|
||||
elif self.stop is not None:
|
||||
print("Stopping test group %s..." % self.stop)
|
||||
self.json_post("/cli-json/stop_group", {"name": self.stop})
|
||||
elif self.quiesce is not None:
|
||||
print("Quiescing test group %s..." % self.quiesce)
|
||||
self.json_post("/cli-json/quiesce_group", {"name": self.quiesce})
|
||||
|
||||
|
||||
def main():
|
||||
parser = LFCliBase.create_basic_argparse(
|
||||
prog='measure_station_time_up.py',
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
epilog='''\
|
||||
Measure how long it takes to up stations
|
||||
''',
|
||||
|
||||
description='''\
|
||||
measure_station_time_up.py
|
||||
--------------------
|
||||
Command example:
|
||||
./measure_station_time_up.py
|
||||
--radio wiphy0
|
||||
--num_stations 3
|
||||
--security open
|
||||
--ssid netgear
|
||||
--passwd BLANK
|
||||
--debug
|
||||
--outfile
|
||||
''')
|
||||
required = parser.add_argument_group('required arguments')
|
||||
required.add_argument('--report_file', help='where you want to store results', required=True)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
dictionary = dict()
|
||||
for num_sta in list(filter(lambda x: (x % 2 == 0), [*range(0, 200)])):
|
||||
print(num_sta)
|
||||
try:
|
||||
create_station = MeasureTimeUp(_host=args.mgr,
|
||||
_port=args.mgr_port,
|
||||
_ssid=args.ssid,
|
||||
_password=args.passwd,
|
||||
_security=args.security,
|
||||
_num_sta=num_sta,
|
||||
_radio=["wiphy0", "wiphy1"],
|
||||
_proxy_str=args.proxy,
|
||||
_debug_on=args.debug,
|
||||
_load='FACTORY_DFLT')
|
||||
create_station.scenario()
|
||||
time.sleep(5.0 + num_sta / 10)
|
||||
start = datetime.datetime.now()
|
||||
create_station.build()
|
||||
built = datetime.datetime.now()
|
||||
create_station.station_up()
|
||||
stationsup = datetime.datetime.now()
|
||||
dictionary[num_sta] = [start, built, stationsup]
|
||||
create_station.wait_until_ports_disappear(base_url=self.lfclient_url, port_list=station_list)
|
||||
time.sleep(5.0 + num_sta / 20)
|
||||
except:
|
||||
pass
|
||||
df = pd.DataFrame.from_dict(dictionary).transpose()
|
||||
df.columns = ['Start', 'Built', 'Stations Up']
|
||||
df['built duration'] = df['Built'] - df['Start']
|
||||
df['Up Stations'] = df['Stations Up'] - df['Built']
|
||||
df['duration'] = df['Stations Up'] - df['Start']
|
||||
for variable in ['built duration', 'duration']:
|
||||
df[variable] = [x.total_seconds() for x in df[variable]]
|
||||
df.to_pickle(args.report_file)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
86
py-scripts/recordinflux.py
Executable file
86
py-scripts/recordinflux.py
Executable file
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env python3
|
||||
"""recordinflux will record data from existing lanforge endpoints to record to an already existing influx database.
|
||||
|
||||
This data can then be streamed in Grafana or any other graphing program the user chooses while this script runs.
|
||||
|
||||
https://influxdb-python.readthedocs.io/en/latest/include-readme.html
|
||||
|
||||
|
||||
Use './recordinflux.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
|
||||
|
||||
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'))
|
||||
|
||||
from LANforge.lfcli_base import LFCliBase
|
||||
import argparse
|
||||
|
||||
|
||||
def main():
|
||||
parser = LFCliBase.create_bare_argparse(
|
||||
prog='recordinflux.py',
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
epilog='''
|
||||
Record data to an Influx database in order to be able stream to Grafana or other graphing software''',
|
||||
description='''
|
||||
recordinflux.py:
|
||||
----------------------------
|
||||
Generic command example:
|
||||
./recordinflux.py --influx_user lanforge \\
|
||||
--influx_passwd password \\
|
||||
--influx_db lanforge \\
|
||||
--stations \\
|
||||
--longevity 5h'''
|
||||
)
|
||||
target_kpi = ['bps rx', 'rx bytes', 'pps rx', 'rx pkts', 'rx drop']
|
||||
parser.add_argument('--influx_user', help='Username for your Influx database')
|
||||
parser.add_argument('--influx_passwd', help='Password for your Influx database')
|
||||
parser.add_argument('--influx_token', help='Token for your Influx database', default=None)
|
||||
parser.add_argument('--influx_db', help='Name of your Influx database')
|
||||
parser.add_argument('--influx_bucket', help='Name of your Influx bucket')
|
||||
parser.add_argument('--influx_org', help='Name of your Influx Organization')
|
||||
parser.add_argument('--influx_port', help='Name of your Influx Port', default=8086)
|
||||
parser.add_argument('--longevity', help='How long you want to gather data', default='4h')
|
||||
parser.add_argument('--device', help='Device to monitor', action='append', required=True)
|
||||
parser.add_argument('--monitor_interval', help='How frequently you want to append to your database', default='5s')
|
||||
parser.add_argument('--target_kpi', help='Monitor only selected columns', action='append', default=target_kpi)
|
||||
args = parser.parse_args()
|
||||
monitor_interval = LFCliBase.parse_time(args.monitor_interval).total_seconds()
|
||||
longevity = LFCliBase.parse_time(args.longevity).total_seconds()
|
||||
tags=dict()
|
||||
tags['script'] = 'recordinflux'
|
||||
if args.influx_user is None:
|
||||
from influx2 import RecordInflux
|
||||
grapher = RecordInflux(_influx_host=args.mgr,
|
||||
_influx_port=args.influx_port,
|
||||
_influx_bucket=args.influx_db,
|
||||
_influx_token=args.influx_token,
|
||||
_influx_org=args.influx_org)
|
||||
grapher.monitor_port_data(longevity=longevity,
|
||||
devices=args.device,
|
||||
monitor_interval=monitor_interval,
|
||||
tags=tags)
|
||||
|
||||
else:
|
||||
from influx import RecordInflux
|
||||
grapher = RecordInflux(_influx_host=args.mgr,
|
||||
_port=args.mgr_port,
|
||||
_influx_db=args.influx_db,
|
||||
_influx_user=args.influx_user,
|
||||
_influx_passwd=args.influx_passwd)
|
||||
grapher.getdata(longevity=longevity,
|
||||
devices=args.device,
|
||||
monitor_interval=monitor_interval,
|
||||
target_kpi=args.target_kpi)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
17
py-scripts/regression_test.rc.example
Normal file
17
py-scripts/regression_test.rc.example
Normal file
@@ -0,0 +1,17 @@
|
||||
# Example settings file for regression_test.sh #
|
||||
# #
|
||||
# Edit your own copy of regression_test.rc and regression #
|
||||
# test.sh should use it. Please do not check in your #
|
||||
# regression_test.rc file, That will break other people's settings. #
|
||||
# #
|
||||
|
||||
# Run tests against these AP credentials:
|
||||
SSID_USED=ChickenNet
|
||||
PASSWD_USED=ameliachicken
|
||||
SECURITY=wpa3
|
||||
|
||||
# Point tests at this GUI:
|
||||
MGR=localhost
|
||||
MGR_PORT=8080
|
||||
|
||||
#
|
||||
322
py-scripts/regression_test.sh
Executable file
322
py-scripts/regression_test.sh
Executable file
@@ -0,0 +1,322 @@
|
||||
#!/bin/bash
|
||||
#This bash script aims to automate the test process of all Candela Technologies's test_* scripts in the lanforge-scripts directory. The script can be run 2 ways and may include (via user input) the "start_num" and "stop_num" variables to select which tests should be run.
|
||||
# OPTION ONE: ./test_all_scripts.sh : this command runs all the scripts in the array "testCommands"
|
||||
# OPTION TWO: ./test_all_scripts.sh 4 5 : this command runs py-script commands (in testCommands array) that include the py-script options beginning with 4 and 5 (inclusive) in case function ret_case_num.
|
||||
#Variables
|
||||
|
||||
FILE="/tmp/gui-update.lock"
|
||||
if test -f "$FILE"; then
|
||||
echo "Finish updating your GUI"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
HOMEPATH=$(realpath ~)
|
||||
|
||||
if [[ ${#1} -gt 0 ]]; then
|
||||
SSID_USED=$1
|
||||
PASSWD_USED=$2
|
||||
SECURITY=$3
|
||||
if [[ ${#4} -gt 0 ]]; then
|
||||
MGR=$4
|
||||
# FILENAME=$5 # this appears unused
|
||||
elif [ -f "$1" ]; then
|
||||
source "$1"
|
||||
elif [ -f ./regression_test.rc ]; then
|
||||
source ./regression_test.rc # this version is a better unix name
|
||||
elif [ -f ./regression_test.txt ]; then
|
||||
source ./regression_test.txt # this less unixy name was discussed earlier
|
||||
fi
|
||||
else # these are jedway lab defaults
|
||||
SSID_USED="jedway-wpa2-x2048-5-3"
|
||||
PASSWD_USED="jedway-wpa2-x2048-5-3"
|
||||
SECURITY="wpa2"
|
||||
fi
|
||||
NUM_STA=${NUM_STA:-4}
|
||||
TEST_HTTP_IP=${TEST_HTTP_IP:-10.40.0.1}
|
||||
MGRLEN="$(${#MGR})"
|
||||
RADIO_USED="wiphy0"
|
||||
COL_NAMES="name,tx_bytes,rx_bytes,dropped"
|
||||
|
||||
#START_NUM=0
|
||||
CURR_TEST_NUM=0
|
||||
CURR_TEST_NAME="BLANK"
|
||||
#STOP_NUM=9
|
||||
|
||||
REPORT_DIR="${HOMEPATH}/html-reports"
|
||||
if [ ! -d "$REPORT_DIR" ]; then
|
||||
echo "Report directory [$REPORT_DIR] not found, bye."
|
||||
exit 1
|
||||
fi
|
||||
REPORT_DATA="${HOMEPATH}/report-data"
|
||||
if [ ! -d "${REPORT_DATA}" ]; then
|
||||
echo "Data directory [$REPORT_DATA] not found, bye."
|
||||
exit 1
|
||||
fi
|
||||
TEST_DIR="${REPORT_DATA}/${NOW}"
|
||||
#set -vex
|
||||
echo $MGRLEN
|
||||
#Test array
|
||||
if [[ $MGRLEN -gt 0 ]]; then
|
||||
function run_l3_longevity {
|
||||
./test_l3_longevity.py --test_duration 15s --upstream_port eth1 --radio "radio==wiphy0 stations==4 ssid==$SSID_USED ssid_pw==$PASSWD_USED security==$SECURITY" --radio "radio==wiphy1 stations==4 ssid==$SSID_USED ssid_pw==$PASSWD_USED security==$SECURITY" --mgr "$MGR"
|
||||
}
|
||||
function testgroup_list_groups {
|
||||
./scenario.py --load test_l3_scenario_throughput;./testgroup.py --group_name group1 --add_group --add_cx cx0000,cx0001,cx0002 --remove_cx cx0003 --list_groups --debug --mgr "$MGR"
|
||||
}
|
||||
function testgroup_list_connections {
|
||||
./scenario.py --load test_l3_scenario_throughput;./testgroup.py --group_name group1 --add_group --add_cx cx0000,cx0001,cx0002 --remove_cx cx0003 --show_group --debug --mgr "$MGR"
|
||||
}
|
||||
function testgroup_delete_group {
|
||||
./scenario.py --load test_l3_scenario_throughput;./testgroup.py --group_name group1 --add_group --add_cx cx0000,cx0001,cx0002 --remove_cx cx0003;./testgroup.py --group_name group1--del_group --debug --mgr "$MGR"
|
||||
}
|
||||
testCommands=(
|
||||
"./example_security_connection.py --num_stations $NUM_STA --ssid $SSID_USED --passwd $PASSWD_USED --radio $RADIO_USED --security wpa2 --debug --mgr $MGR"
|
||||
"./sta_connect2.py --dut_ssid $SSID_USED --dut_passwd $PASSWD_USED --dut_security $SECURITY --mgr $MGR"
|
||||
# want if [[ $DO_FILEIO = 1 ]]
|
||||
"./test_fileio.py --macvlan_parent eth2 --num_ports 3 --use_macvlans --first_mvlan_ip 192.168.92.13 --netmask 255.255.255.0 --gateway 192.168.92.1 --test_duration 30s --mgr $MGR" # Better tested on Kelly, where VRF is turned off
|
||||
"./test_generic.py --radio $RADIO_USED --ssid $SSID_USED --passwd $PASSWD_USED --security $SECURITY --num_stations $NUM_STA --type lfping --dest $TEST_HTTP_IP --debug --mgr $MGR"
|
||||
"./test_generic.py --radio $RADIO_USED --ssid $SSID_USED --passwd $PASSWD_USED --security $SECURITY --num_stations $NUM_STA --type speedtest --speedtest_min_up 20 --speedtest_min_dl 20 --speedtest_max_ping 150 --security $SECURITY --debug --mgr $MGR"
|
||||
"./test_generic.py --radio $RADIO_USED --ssid $SSID_USED --passwd $PASSWD_USED --security $SECURITY --num_stations $NUM_STA --type iperf3 --debug --mgr $MGR"
|
||||
"./test_generic.py --radio $RADIO_USED --ssid $SSID_USED --passwd $PASSWD_USED --security $SECURITY --num_stations $NUM_STA --type lfcurl --dest $TEST_HTTP_IP --file_output ${HOMEPATH}/Documents/lfcurl_output.txt --debug --mgr $MGR"
|
||||
"./testgroup.py --group_name group1 --add_group --list_groups --debug --mgr $MGR"
|
||||
testgroup_list_groups
|
||||
testgroup_list_connections
|
||||
testgroup_delete_group
|
||||
"./testgroup2.py --num_stations 4 --ssid lanforge --passwd password --security wpa2 --radio wiphy0 --group_name group0 --add_group --mgr $MGR"
|
||||
"./test_ipv4_connection.py --radio $RADIO_USED --num_stations $NUM_STA --ssid $SSID_USED --passwd $PASSWD_USED --security $SECURITY --debug --mgr $MGR"
|
||||
"./test_ipv4_l4_urls_per_ten.py --radio $RADIO_USED --num_stations $NUM_STA --security $SECURITY --ssid $SSID_USED --passwd $PASSWD_USED --num_tests 1 --requests_per_ten 600 --target_per_ten 600 --debug --mgr $MGR"
|
||||
"./test_ipv4_l4_wifi.py --radio $RADIO_USED --num_stations $NUM_STA --security $SECURITY --ssid $SSID_USED --passwd $PASSWD_USED --test_duration 15s --debug --mgr $MGR"
|
||||
"./test_ipv4_l4.py --radio $RADIO_USED --num_stations 4 --security $SECURITY --ssid $SSID_USED --passwd $PASSWD_USED --test_duration 15s --debug --mgr $MGR"
|
||||
"./test_ipv4_variable_time.py --radio $RADIO_USED --ssid $SSID_USED --passwd $PASSWD_USED --security $SECURITY --test_duration 15s --output_format excel --layer3_cols $COL_NAMES --debug --mgr $MGR"
|
||||
"./test_ipv4_variable_time.py --radio $RADIO_USED --ssid $SSID_USED --passwd $PASSWD_USED --security $SECURITY --test_duration 15s --output_format csv --layer3_cols $COL_NAMES --debug --mgr $MGR"
|
||||
"./test_ipv4_l4_ftp_upload.py --upstream_port eth1 --radio $RADIO_USED --num_stations $NUM_STA --security $SECURITY --ssid $SSID_USED --passwd $PASSWD_USED --test_duration 15s --debug --mgr $MGR"
|
||||
"./test_ipv6_connection.py --radio $RADIO_USED --ssid $SSID_USED --passwd $PASSWD_USED --security $SECURITY --debug --mgr $MGR"
|
||||
"./test_ipv6_variable_time.py --radio $RADIO_USED --ssid $SSID_USED --passwd $PASSWD_USED --security $SECURITY --test_duration 15s --cx_type tcp6 --debug --mgr $MGR"
|
||||
run_l3_longevity
|
||||
"./test_l3_powersave_traffic.py --radio $RADIO_USED --ssid $SSID_USED --passwd $PASSWD_USED --security $SECURITY --debug --mgr $MGR"
|
||||
"./test_l3_scenario_throughput.py -t 15s -sc test_l3_scenario_throughput --mgr $MGR"
|
||||
"./test_status_msg.py --debug --mgr $MGR" #this is all which is needed to run
|
||||
"./test_wanlink.py --debug --mgr $MGR"
|
||||
#"./ws_generic_monitor_test.py --mgr $MGR"
|
||||
"./create_bridge.py --radio wiphy1 --upstream_port eth1 --target_device sta0000 --debug --mgr $MGR"
|
||||
"./create_l3.py --radio wiphy1 --ssid $SSID_USED --passwd $PASSWD_USED --security $SECURITY --debug --mgr $MGR"
|
||||
"./create_l4.py --radio wiphy1 --ssid $SSID_USED --passwd $PASSWD_USED --security $SECURITY --debug --mgr $MGR"
|
||||
"./create_macvlan.py --radio wiphy1 --macvlan_parent eth1 --debug --mgr $MGR"
|
||||
"./create_qvlan.py --first_qvlan_ip 192.168.1.50"
|
||||
"./create_station.py --radio wiphy1 --ssid $SSID_USED --passwd $PASSWD_USED --security $SECURITY --debug --mgr $MGR"
|
||||
"./create_vap.py --radio wiphy1 --ssid $SSID_USED --passwd $PASSWD_USED --security $SECURITY --debug --mgr $MGR"
|
||||
"./create_vr.py --vr_name 2.vr0 --ports 2.br0,2.vap2 --services"
|
||||
"./wlan_capacity_calculator.py -sta 11abg -t Voice -p 48 -m 106 -e WEP -q Yes -b 1 2 5.5 11 -pre Long -s N/A -co G.711 -r Yes -c Yes --mgr $MGR"
|
||||
"./wlan_capacity_calculator.py -sta 11n -t Voice -d 17 -ch 40 -gu 800 -high 9 -e WEP -q Yes -ip 5 -mc 42 -b 6 9 12 24 -m 1538 -co G.729 -pl Greenfield -cw 15 -r Yes -c Yes --mgr $MGR"
|
||||
"./wlan_capacity_calculator.py -sta 11ac -t Voice -d 9 -spa 3 -ch 20 -gu 800 -high 1 -e TKIP -q Yes -ip 3 -mc 0 -b 6 12 24 54 -m 1518 -co Greenfield -cw 15 -rc Yes --mgr $MGR"
|
||||
)
|
||||
else
|
||||
function run_l3_longevity {
|
||||
./test_l3_longevity.py --test_duration 15s --upstream_port eth1 --radio "radio==wiphy0 stations==4 ssid==$SSID_USED ssid_pw==$PASSWD_USED security==$SECURITY" --radio "radio==wiphy1 stations==4 ssid==$SSID_USED ssid_pw==$PASSWD_USED security==$SECURITY"
|
||||
}
|
||||
function testgroup_list_groups {
|
||||
./scenario.py --load test_l3_scenario_throughput;./testgroup.py --group_name group1 --add_group --add_cx cx0000,cx0001,cx0002 --remove_cx cx0003 --list_groups --debug
|
||||
}
|
||||
function testgroup_list_connections {
|
||||
./scenario.py --load test_l3_scenario_throughput;./testgroup.py --group_name group1 --add_group --add_cx cx0000,cx0001,cx0002 --remove_cx cx0003 --show_group --debug
|
||||
}
|
||||
function testgroup_delete_group {
|
||||
./scenario.py --load test_l3_scenario_throughput;./testgroup.py --group_name group1 --add_group --add_cx cx0000,cx0001,cx0002 --remove_cx cx0003;./testgroup.py --group_name group1--del_group --debug
|
||||
}
|
||||
|
||||
testCommands=(
|
||||
#"../cpu_stats.py --duration 15"
|
||||
"./example_security_connection.py --num_stations $NUM_STA --ssid jedway-wpa-1 --passwd jedway-wpa-1 --radio $RADIO_USED --security wpa --debug"
|
||||
"./example_security_connection.py --num_stations $NUM_STA --ssid $SSID_USED --passwd $PASSWD_USED --radio $RADIO_USED --security wpa2 --debug"
|
||||
"./example_security_connection.py --num_stations $NUM_STA --ssid jedway-wep-48 --passwd 0123456789 --radio $RADIO_USED --security wep --debug"
|
||||
"./example_security_connection.py --num_stations $NUM_STA --ssid jedway-wpa3-1 --passwd jedway-wpa3-1 --radio $RADIO_USED --security wpa3 --debug"
|
||||
"./sta_connect2.py --dut_ssid $SSID_USED --dut_passwd $PASSWD_USED --dut_security $SECURITY"
|
||||
"./sta_connect_example.py"
|
||||
# want if [[ $DO_FILEIO = 1 ]]
|
||||
"./test_fileio.py --macvlan_parent eth2 --num_ports 3 --use_macvlans --first_mvlan_ip 192.168.92.13 --netmask 255.255.255.0 --test_duration 30s --gateway 192.168.92.1" # Better tested on Kelly, where VRF is turned off
|
||||
"./test_generic.py --radio $RADIO_USED --ssid $SSID_USED --passwd $PASSWD_USED --security $SECURITY --num_stations $NUM_STA --type lfping --dest $TEST_HTTP_IP --debug"
|
||||
"./test_generic.py --radio $RADIO_USED --ssid $SSID_USED --passwd $PASSWD_USED --security $SECURITY --num_stations $NUM_STA --type speedtest --speedtest_min_up 20 --speedtest_min_dl 20 --speedtest_max_ping 150 --security $SECURITY --debug"
|
||||
"./test_generic.py --radio $RADIO_USED --ssid $SSID_USED --passwd $PASSWD_USED --security $SECURITY --num_stations $NUM_STA --type iperf3 --debug"
|
||||
"./test_generic.py --radio $RADIO_USED --ssid $SSID_USED --passwd $PASSWD_USED --security $SECURITY --num_stations $NUM_STA --type lfcurl --dest $TEST_HTTP_IP --file_output ${HOMEPATH}/Documents/lfcurl_output.txt --debug"
|
||||
"./testgroup.py --group_name group1 --add_group --list_groups --debug"
|
||||
testgroup_list_groups
|
||||
testgroup_list_connections
|
||||
testgroup_delete_group
|
||||
"./testgroup2.py --num_stations 4 --ssid lanforge --passwd password --security wpa2 --radio wiphy0 --group_name group0 --add_group"
|
||||
"./test_ipv4_connection.py --radio $RADIO_USED --num_stations $NUM_STA --ssid $SSID_USED --passwd $PASSWD_USED --security $SECURITY --debug"
|
||||
"./test_ipv4_l4_urls_per_ten.py --radio $RADIO_USED --num_stations $NUM_STA --security $SECURITY --ssid $SSID_USED --passwd $PASSWD_USED --num_tests 1 --requests_per_ten 600 --target_per_ten 600 --debug"
|
||||
"./test_ipv4_l4_wifi.py --radio $RADIO_USED --num_stations $NUM_STA --security $SECURITY --ssid $SSID_USED --passwd $PASSWD_USED --test_duration 15s --debug"
|
||||
"./test_ipv4_l4.py --radio $RADIO_USED --num_stations 4 --security $SECURITY --ssid $SSID_USED --passwd $PASSWD_USED --test_duration 15s --debug"
|
||||
"./test_ipv4_variable_time.py --radio $RADIO_USED --ssid $SSID_USED --passwd $PASSWD_USED --security $SECURITY --test_duration 15s --output_format excel --layer3_cols $COL_NAMES --debug"
|
||||
"./test_ipv4_variable_time.py --radio $RADIO_USED --ssid $SSID_USED --passwd $PASSWD_USED --security $SECURITY --test_duration 15s --output_format csv --layer3_cols $COL_NAMES --debug"
|
||||
"./test_ipv4_l4_ftp_upload.py --upstream_port eth1 --radio $RADIO_USED --num_stations $NUM_STA --security $SECURITY --ssid $SSID_USED --passwd $PASSWD_USED --test_duration 15s --debug"
|
||||
"./test_ipv6_connection.py --radio $RADIO_USED --ssid $SSID_USED --passwd $PASSWD_USED --security $SECURITY --debug"
|
||||
"./test_ipv6_variable_time.py --radio $RADIO_USED --ssid $SSID_USED --passwd $PASSWD_USED --security $SECURITY --test_duration 15s --cx_type tcp6 --debug"
|
||||
run_l3_longevity
|
||||
"./test_l3_powersave_traffic.py --radio $RADIO_USED --ssid $SSID_USED --passwd $PASSWD_USED --security $SECURITY --debug"
|
||||
#"./test_l3_scenario_throughput.py -t 15s -sc test_l3_scenario_throughput" #always hangs the regression
|
||||
"./test_status_msg.py --action run_test " #this is all which is needed to run
|
||||
"./test_wanlink.py --debug"
|
||||
#"./ws_generic_monitor_test.py"
|
||||
#"../py-json/ws-sta-monitor.py --debug"
|
||||
"./create_bridge.py --radio wiphy1 --upstream_port eth1 --target_device sta0000 --debug"
|
||||
"./create_l3.py --radio wiphy1 --ssid $SSID_USED --passwd $PASSWD_USED --security $SECURITY --debug"
|
||||
"./create_l4.py --radio wiphy1 --ssid $SSID_USED --passwd $PASSWD_USED --security $SECURITY --debug"
|
||||
"./create_macvlan.py --radio wiphy1 --macvlan_parent eth1 --debug"
|
||||
"./create_station.py --radio wiphy1 --ssid $SSID_USED --passwd $PASSWD_USED --security $SECURITY --debug"
|
||||
"./create_vap.py --radio wiphy1 --ssid $SSID_USED --passwd $PASSWD_USED --security $SECURITY --debug"
|
||||
"./create_vr.py --vr_name 2.vr0 --ports 2.br0,2.vap2 --services"
|
||||
"./create_qvlan.py --radio wiphy1 --qvlan_parent eth1"
|
||||
"./wlan_capacity_calculator.py -sta 11abg -t Voice -p 48 -m 106 -e WEP -q Yes -b 1 2 5.5 11 -pre Long -s N/A -co G.711 -r Yes -c Yes"
|
||||
"./wlan_capacity_calculator.py -sta 11n -t Voice -d 17 -ch 40 -gu 800 -high 9 -e WEP -q Yes -ip 5 -mc 42 -b 6 9 12 24 -m 1538 -co G.729 -pl Greenfield -cw 15 -r Yes -c Yes"
|
||||
"./wlan_capacity_calculator.py -sta 11ac -t Voice -d 9 -spa 3 -ch 20 -gu 800 -high 1 -e TKIP -q Yes -ip 3 -mc 0 -b 6 12 24 54 -m 1518 -co Greenfield -cw 15 -rc Yes"
|
||||
)
|
||||
fi
|
||||
#declare -A name_to_num
|
||||
#if you want to run just one test as part of regression_test, you can call one test by calling its name_to_num identifier.
|
||||
name_to_num=(
|
||||
["example_security_connection"]=1
|
||||
["test_ipv4_connection"]=2
|
||||
["test_generic"]=3
|
||||
["test_ipv4_l4_urls_per_ten"]=4
|
||||
["test_ipv4_l4_wifi"]=5
|
||||
["test_ipv4_l4"]=6
|
||||
["test_ipv4_variable_time"]=7
|
||||
["create_bridge"]=8
|
||||
["create_l3"]=9
|
||||
["create_l4"]=10
|
||||
["create_macvlan"]=11
|
||||
["create_station"]=12
|
||||
["create_vap"]=13
|
||||
["cpu_stats"]=14
|
||||
["test_fileio"]=15
|
||||
["testgroup"]=16
|
||||
["test_ipv6_connection"]=17
|
||||
["test_ipv6_variable_time"]=18
|
||||
["test_l3_longevity"]=19
|
||||
["test_l3_powersave_traffic"]=20
|
||||
["test_l3_scenario_throughput"]=21
|
||||
["test_status_msg"]=22
|
||||
["test_wanlink"]=23
|
||||
["wlan_theoretical_sta"]=24
|
||||
["ws_generic_monitor_test"]=25
|
||||
["sta_connect2"]=26
|
||||
["wlan_capacity_calculator"]=27
|
||||
["test_generic"]=28
|
||||
["new_script"]=29
|
||||
["sta_connect_example.py"]=30
|
||||
)
|
||||
|
||||
function blank_db() {
|
||||
echo "Loading blank scenario..." >>"${HOMEPATH}/test_all_output_file.txt"
|
||||
./scenario.py --load BLANK >>"${HOMEPATH}/test_all_output_file.txt"
|
||||
#check_blank.py
|
||||
}
|
||||
|
||||
function echo_print() {
|
||||
echo "Beginning $CURR_TEST_NAME test..." >>"${HOMEPATH}/test_all_output_file.txt"
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
for i in "${testCommands[@]}"; do
|
||||
if [[ $MGRLEN -gt 0 ]]; then
|
||||
./scenario.py --load FACTORY_DFLT --mgr "${MGR}"
|
||||
else
|
||||
./scenario.py --load FACTORY_DFLT
|
||||
fi
|
||||
NAME=$(cat < /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)
|
||||
CURR_TEST_NAME=${i%%.py*}
|
||||
CURR_TEST_NAME=${CURR_TEST_NAME#./*}
|
||||
CURR_TEST_NUM="${name_to_num[$CURR_TEST_NAME]}"
|
||||
|
||||
#if (( $CURR_TEST_NUM > $STOP_NUM )) || (( $STOP_NUM == $CURR_TEST_NUM )) && (( $STOP_NUM != 0 )); then
|
||||
# exit 1
|
||||
#fi
|
||||
echo ""
|
||||
echo "Test $CURR_TEST_NUM: $CURR_TEST_NAME"
|
||||
|
||||
#if (( $CURR_TEST_NUM > $START_NUM )) || (( $CURR_TEST_NUM == $START_NUM )); then
|
||||
echo_print
|
||||
echo "$i"
|
||||
$i > "${TEST_DIR}/${NAME}.txt" 2> "${TEST_DIR}/${NAME}_stderr.txt"
|
||||
chmod 664 "${TEST_DIR}/${NAME}.txt"
|
||||
FILESIZE=$(stat -c%s "${TEST_DIR}/${NAME}_stderr.txt") || 0
|
||||
if (( FILESIZE > 0)); then
|
||||
results+=("<tr><td>${CURR_TEST_NAME}</td><td class='scriptdetails'>${i}</td>
|
||||
<td class='failure'>Failure</td>
|
||||
<td><a href=\"${URL2}/${NAME}.txt\" target=\"_blank\">STDOUT</a></td>
|
||||
<td><a href=\"${URL2}/${NAME}_stderr.txt\" target=\"_blank\">STDERR</a></td></tr>")
|
||||
else
|
||||
results+=("<tr><td>${CURR_TEST_NAME}</td><td class='scriptdetails'>${i}</td>
|
||||
<td class='success'>Success</td>
|
||||
<td><a href=\"${URL2}/${NAME}.txt\" target=\"_blank\">STDOUT</a></td>
|
||||
<td></td></tr>")
|
||||
fi
|
||||
#fi
|
||||
done
|
||||
}
|
||||
|
||||
function html_generator() {
|
||||
header="<html>
|
||||
<head>
|
||||
<title>Regression Test Results $NOW</title>
|
||||
<style>
|
||||
.success {
|
||||
background-color:green;
|
||||
}
|
||||
.failure {
|
||||
background-color:red;
|
||||
}
|
||||
table {
|
||||
border: 1px solid gray;
|
||||
}
|
||||
td {
|
||||
margin: 0;
|
||||
padding: 2px;
|
||||
font-family: 'Courier New',courier,sans-serif;
|
||||
}
|
||||
h1, h2, h3, h4 {
|
||||
font-family: 'Century Gothic',Arial,sans,sans-serif;
|
||||
}
|
||||
.scriptdetails {
|
||||
font-size: 10px;
|
||||
}
|
||||
</style>
|
||||
<script src=\"sortabletable.js\"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Regression Results</h1>
|
||||
<h4>$NOW</h4>
|
||||
<table border ='1' id='myTable2'>
|
||||
<tr>
|
||||
<th onclick=\"sortTable(0)\">Command Name</th>
|
||||
<th onclick=\"sortTable(1)\">Command</th>
|
||||
<th onclick=\"sortTable(2)\">Status</th>
|
||||
<th onclick=\"sortTable(3)\">STDOUT</th>
|
||||
<th onclick=\"sortTable(4)\">STDERR</th>
|
||||
</tr>"
|
||||
tail="</body>
|
||||
</html>"
|
||||
|
||||
fname="${HOMEPATH}/html-reports/test_all_output_file-${NOW}.html"
|
||||
echo "$header" >> "$fname"
|
||||
echo "${results[@]}" >> "$fname"
|
||||
echo "</table>" >> "$fname"
|
||||
echo "$tail" >> "$fname"
|
||||
if [ -f "${HOMEPATH}/html-reports/latest.html" ]; then
|
||||
rm -f "${HOMEPATH}/html-reports/latest.html"
|
||||
fi
|
||||
ln -s "${fname}" "${HOMEPATH}/html-reports/latest.html"
|
||||
}
|
||||
|
||||
results=()
|
||||
NOW=$(date +"%Y-%m-%d-%H-%M")
|
||||
NOW="${NOW/:/-}"
|
||||
TEST_DIR="${REPORT_DATA}/${NOW}"
|
||||
URL2="/report-data/${NOW}"
|
||||
mkdir "${TEST_DIR}"
|
||||
echo "Recording data to ${TEST_DIR}"
|
||||
|
||||
run_test
|
||||
html_generator
|
||||
#test generic and fileio are for macvlans
|
||||
@@ -91,7 +91,7 @@ class RunCvScenario(LFCliBase):
|
||||
"cv is_built",
|
||||
"cv sync",
|
||||
"sleep 2",
|
||||
"cv create '%s' test_ref" % self.cv_test,
|
||||
"cv create '%s' 'test_ref' 'true'" % self.cv_test,
|
||||
"sleep 2",
|
||||
"cv load test_ref '%s'" % self.test_profile,
|
||||
"sleep 1",
|
||||
|
||||
225
py-scripts/rvr_scenario.py
Executable file
225
py-scripts/rvr_scenario.py
Executable file
@@ -0,0 +1,225 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# This script will set the LANforge to a BLANK database then it will load the specified database
|
||||
# and start a graphical report
|
||||
|
||||
import sys
|
||||
|
||||
if sys.version_info[0] != 3:
|
||||
print("This script requires Python 3")
|
||||
exit(1)
|
||||
|
||||
if 'py-json' not in sys.path:
|
||||
sys.path.append('../py-json')
|
||||
|
||||
import argparse
|
||||
from LANforge import LFUtils
|
||||
from LANforge.lfcli_base import LFCliBase
|
||||
from LANforge.LFUtils import *
|
||||
from realm import Realm
|
||||
import pprint
|
||||
from pprint import pprint
|
||||
|
||||
"""
|
||||
cvScenario.lanforge_db = args.lanforge_db
|
||||
if args.cv_test is not None:
|
||||
cvScenario.cv_test = args.cv_test
|
||||
if args.test_scenario is not None:
|
||||
cvScenario.test_scenario = args.test_scenario
|
||||
"""
|
||||
|
||||
class RunCvScenario(LFCliBase):
|
||||
def __init__(self, lfhost="localhost", lfport=8080, debug_=False, lanforge_db_=None, cv_scenario_=None, cv_test_=None, test_scenario_=None):
|
||||
super().__init__( _lfjson_host=lfhost, _lfjson_port=lfport, _debug=debug_, _halt_on_error=True, _exit_on_error=True, _exit_on_fail=True)
|
||||
self.lanforge_db = lanforge_db_
|
||||
self.cv_scenario = cv_scenario_
|
||||
self.cv_test = cv_test_
|
||||
self.test_profile = test_scenario_
|
||||
self.localrealm = Realm(lfclient_host=lfhost, lfclient_port=lfport, debug_=debug_)
|
||||
self.report_name = None
|
||||
|
||||
def get_report_file_name(self):
|
||||
return self.report_name
|
||||
|
||||
def build(self):
|
||||
data = {
|
||||
"name": "BLANK",
|
||||
"action":"overwrite",
|
||||
"clean_dut":"yes",
|
||||
"clean_chambers": "yes"
|
||||
}
|
||||
self.json_post("/cli-json/load", data)
|
||||
sleep(1)
|
||||
port_counter = 0;
|
||||
attempts = 6
|
||||
while (attempts > 0) and (port_counter > 0):
|
||||
sleep(1)
|
||||
attempts -= 1
|
||||
print("looking for ports like vap+")
|
||||
port_list = self.localrealm.find_ports_like("vap+")
|
||||
alias_map = LFUtils.portListToAliasMap(port_list)
|
||||
port_counter = len(alias_map)
|
||||
|
||||
port_list = self.localrealm.find_ports_like("sta+")
|
||||
alias_map = LFUtils.portListToAliasMap(port_list)
|
||||
port_counter += len(alias_map)
|
||||
if port_counter == 0:
|
||||
break
|
||||
|
||||
if (port_counter != 0) and (attempts == 0):
|
||||
print("There appears to be a vAP in this database, quitting.")
|
||||
pprint(alias_map)
|
||||
exit(1)
|
||||
|
||||
data = {
|
||||
"name": self.lanforge_db,
|
||||
"action":"overwrite",
|
||||
"clean_dut":"yes",
|
||||
"clean_chambers": "yes"
|
||||
}
|
||||
self.json_post("/cli-json/load", data)
|
||||
sleep(5)
|
||||
self._pass("Loaded scenario %s" % self.lanforge_db, True)
|
||||
return True
|
||||
|
||||
def start(self, debug_=False):
|
||||
# /gui_cli takes commands keyed on 'cmd', so we create an array of commands
|
||||
commands = [
|
||||
#"cv apply '%s'" % self.cv_scenario,
|
||||
"sleep 5",
|
||||
"cv build",
|
||||
"sleep 5",
|
||||
"cv is_built",
|
||||
"sleep 2",
|
||||
"cv sync",
|
||||
"sleep 1",
|
||||
"cv create '%s' test_ref 'true'" % self.cv_test,
|
||||
"sleep 5",
|
||||
"cv load test_ref '%s'" % self.test_profile,
|
||||
"sleep 2",
|
||||
"cv click test_ref 'Auto Save Report'",
|
||||
"sleep 4",
|
||||
"cv click test_ref Start",
|
||||
"sleep 2",
|
||||
"cv click test_ref 'Another Iteration'",
|
||||
"sleep 240", #sleep for (test duration for 1 time test takes x num iterations requested) - this example is 2 iterations
|
||||
"cv click test_ref 'Another Iteration'", #unselect Another Iteration before test ends
|
||||
"sleep 50" #finish test
|
||||
"cv get test_ref 'Report Location:'",
|
||||
"sleep 5",
|
||||
"cv click test_ref 'Save HTML'",
|
||||
"cv click test_ref 'Close'",
|
||||
"sleep 1",
|
||||
"cv click test_ref Cancel",
|
||||
"sleep 1",
|
||||
"exit"
|
||||
]
|
||||
response_json = []
|
||||
for command in commands:
|
||||
data = {
|
||||
"cmd": command
|
||||
}
|
||||
try:
|
||||
debug_par = ""
|
||||
if debug_:
|
||||
debug_par="?_debug=1"
|
||||
if command.endswith("is_built"):
|
||||
print("Waiting for scenario to build...", end='')
|
||||
self.localrealm.wait_while_building(debug_=False)
|
||||
print("...proceeding")
|
||||
elif command.startswith("sleep "):
|
||||
nap = int(command.split(" ")[1])
|
||||
print("sleeping %d..." % nap)
|
||||
sleep(nap)
|
||||
print("...proceeding")
|
||||
else:
|
||||
response_json = []
|
||||
print("running %s..." % command, end='')
|
||||
response = self.json_post("/gui-json/cmd%s" % debug_par, data, debug_=False, response_json_list_=response_json)
|
||||
if debug_:
|
||||
LFUtils.debug_printer.pprint(response_json)
|
||||
print("...proceeding")
|
||||
|
||||
|
||||
except Exception as x:
|
||||
print(x)
|
||||
|
||||
self._pass("report finished", print_=True)
|
||||
|
||||
|
||||
def stop(self):
|
||||
pass
|
||||
|
||||
def cleanup(self):
|
||||
pass
|
||||
|
||||
|
||||
def main():
|
||||
lfjson_host = "localhost"
|
||||
lfjson_port = 8080
|
||||
parser = argparse.ArgumentParser(
|
||||
description="""LANforge Reporting Script: Load a scenario and run a RvR report
|
||||
Example:
|
||||
./load_ap_scenario.py --lfmgr 127.0.0.1 --lanforge_db 'handsets' --cv_test --test_scenario 'test-20'
|
||||
""")
|
||||
parser.add_argument("-m", "--lfmgr", type=str,
|
||||
help="address of the LANforge GUI machine (localhost is default)")
|
||||
parser.add_argument("-o", "--port", type=int,
|
||||
help="IP Port the LANforge GUI is listening on (8080 is default)")
|
||||
parser.add_argument("--lanforge_db", "--db", "--lanforge_scenario", type=str,
|
||||
help="Name of test scenario database (see Status Tab)")
|
||||
parser.add_argument("-c", "--cv_scenario", type=str, required=True,
|
||||
help="Name of Chamber View test scenario (see CV Manage Scenarios)")
|
||||
parser.add_argument("-n", "--cv_test", type=str, required = True,
|
||||
help="Chamber View test")
|
||||
parser.add_argument("-s", "--test_profile", "--test_settings", type=str, required=True,
|
||||
help="Name of the saved CV test settings")
|
||||
|
||||
args = parser.parse_args()
|
||||
if args.lfmgr is not None:
|
||||
lfjson_host = args.lfmgr
|
||||
if args.port is not None:
|
||||
lfjson_port = args.port
|
||||
|
||||
run_cv_scenario = RunCvScenario(lfjson_host, lfjson_port)
|
||||
|
||||
if args.lanforge_db is not None:
|
||||
run_cv_scenario.lanforge_db = args.lanforge_db
|
||||
if args.cv_scenario is not None:
|
||||
run_cv_scenario.cv_scenario = args.cv_scenario
|
||||
if args.cv_test is not None:
|
||||
run_cv_scenario.cv_test = args.cv_test
|
||||
if args.test_profile is not None:
|
||||
run_cv_scenario.test_profile = args.test_profile
|
||||
|
||||
if (run_cv_scenario.lanforge_db is None) or (run_cv_scenario.lanforge_db == ""):
|
||||
run_cv_scenario.lanforge_db = "DFLT"
|
||||
# raise ValueError("Please specificy scenario database name with --lanforge_db")
|
||||
|
||||
if not (run_cv_scenario.build() and run_cv_scenario.passes()):
|
||||
print("scenario failed to build.")
|
||||
print(run_cv_scenario.get_fail_message())
|
||||
exit(1)
|
||||
|
||||
if not (run_cv_scenario.start() and run_cv_scenario.passes()):
|
||||
print("scenario failed to start.")
|
||||
print(run_cv_scenario.get_fail_message())
|
||||
exit(1)
|
||||
|
||||
if not (run_cv_scenario.stop() and run_cv_scenario.passes()):
|
||||
print("scenario failed to stop:")
|
||||
print(run_cv_scenario.get_fail_message())
|
||||
exit(1)
|
||||
|
||||
if not (run_cv_scenario.cleanup() and run_cv_scenario.passes()):
|
||||
print("scenario failed to clean up:")
|
||||
print(run_cv_scenario.get_fail_message())
|
||||
exit(1)
|
||||
|
||||
report_file = run_cv_scenario.get_report_file_name()
|
||||
print("Report file saved to "+report_file)
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
297
py-scripts/sandbox/test_ipv4_variable_time2.py
Executable file
297
py-scripts/sandbox/test_ipv4_variable_time2.py
Executable file
@@ -0,0 +1,297 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""test_ipv4_variable_time.py will create stations and endpoints to generate and verify layer-3 traffic.
|
||||
|
||||
This script will create a variable 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 './test_ipv4_variable_time.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
|
||||
|
||||
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 test_base import TestBase
|
||||
import time
|
||||
import datetime
|
||||
|
||||
|
||||
class IPV4VariableTime(Realm, TestBase):
|
||||
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,
|
||||
monitor=False,
|
||||
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):
|
||||
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.security = security
|
||||
self.password = password
|
||||
self.radio = radio
|
||||
self.mode = mode
|
||||
self.ap = ap
|
||||
self.number_template = number_template
|
||||
self.debug = _debug_on
|
||||
# self.json_post("/cli-json/set_resource", {
|
||||
# "shelf":1,
|
||||
# "resource":all,
|
||||
# "max_staged_bringup": 30,
|
||||
# "max_trying_ifup": 15,
|
||||
# "max_station_bringup": 6
|
||||
# })
|
||||
self.name_prefix = name_prefix
|
||||
self.test_duration = test_duration
|
||||
self.station_profile = self.new_station_profile(ver = 2, station_list = sta_list)
|
||||
self.cx_profile = self.new_l3_cx_profile(ver = 2)
|
||||
|
||||
#station profile settings
|
||||
self.station_profile.lfclient_url = self.lfclient_url
|
||||
self.station_profile.ssid = self.ssid
|
||||
self.station_profile.ssid_pass = self.password
|
||||
self.station_profile.security = self.security
|
||||
self.station_profile.number_template_ = self.number_template
|
||||
self.station_profile.debug = self.debug
|
||||
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)
|
||||
self.station_profile.use_ht160 = use_ht160
|
||||
self.station_profile.mode = mode
|
||||
if self.ap is not None:
|
||||
self.station_profile.set_command_param("add_sta", "ap", self.ap)
|
||||
|
||||
#cx profile settings
|
||||
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
|
||||
self.profiles.extend([self.station_profile, self.cx_profile])
|
||||
|
||||
def main():
|
||||
optional = []
|
||||
optional.append({'name': '--mode', 'help': 'Used to force mode of stations'})
|
||||
optional.append({'name': '--ap', 'help': 'Used to force a connection to a particular AP'})
|
||||
optional.append({'name': '--output_format', 'help': 'choose either csv or xlsx'})
|
||||
optional.append({'name': '--report_file', 'help': 'where you want to store results', 'default': None})
|
||||
optional.append({'name': '--a_min', 'help': '--a_min bps rate minimum for side_a', 'default': 256000})
|
||||
optional.append({'name': '--b_min', 'help': '--b_min bps rate minimum for side_b', 'default': 256000})
|
||||
optional.append(
|
||||
{'name': '--test_duration', 'help': '--test_duration sets the duration of the test', 'default': "2m"})
|
||||
optional.append({'name': '--layer3_cols', 'help': 'Columns wished to be monitored from layer 3 endpoint tab',
|
||||
'default': ['name', 'tx bytes', 'rx bytes']})
|
||||
optional.append({'name': '--port_mgr_cols', 'help': 'Columns wished to be monitored from port manager tab',
|
||||
'default': ['ap', 'ip', 'parent dev']})
|
||||
optional.append(
|
||||
{'name': '--compared_report', 'help': 'report path and file which is wished to be compared with new report',
|
||||
'default': None})
|
||||
optional.append({'name': '--monitor_interval',
|
||||
'help': 'frequency of monitor polls - ex: 250ms, 35s, 2h',
|
||||
'default': '2s'})
|
||||
optional.append({'name': '--monitor',
|
||||
'help': 'whether test data should be recorded and stored in a report'})
|
||||
parser = Realm.create_basic_argparse(
|
||||
prog='test_ipv4_variable_time.py',
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
epilog='''\
|
||||
Create stations to test connection and traffic on VAPs of varying security types (WEP, WPA, WPA2, WPA3, Open)
|
||||
''',
|
||||
description='''\
|
||||
test_ipv4_variable_time.py:
|
||||
--------------------
|
||||
Generic command layout:
|
||||
|
||||
python3 ./test_ipv4_variable_time.py
|
||||
--upstream_port eth1
|
||||
--radio wiphy0
|
||||
--num_stations 32
|
||||
--security {open|wep|wpa|wpa2|wpa3}
|
||||
--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"}
|
||||
--ssid netgear
|
||||
--password admin123
|
||||
--test_duration 2m (default)
|
||||
--monitor_interval_ms
|
||||
--monitor
|
||||
--a_min 3000
|
||||
--b_min 1000
|
||||
--ap "00:0e:8e:78:e1:76"
|
||||
--output_format csv
|
||||
--report_file ~/Documents/results.csv (Example of csv file output - please use another extension for other file formats)
|
||||
--compared_report ~/Documents/results_prev.csv (Example of csv file retrieval - please use another extension for other file formats) - UNDER CONSTRUCTION
|
||||
--layer3_cols'name','tx bytes','rx bytes','dropped' (column names from the GUI to print on report - please read below to know what to put here according to preferences)
|
||||
--port_mgr_cols 'ap','ip' (column names from the GUI to print on report - please read below to know what to put here according to preferences)
|
||||
--debug
|
||||
===============================================================================
|
||||
** FURTHER INFORMATION **
|
||||
Using the layer3_cols flag:
|
||||
|
||||
Currently the output function does not support inputting the columns in layer3_cols the way they are displayed in the GUI. This quirk is under construction. To output
|
||||
certain columns in the GUI in your final report, please match the according GUI column display to it's counterpart to have the columns correctly displayed in
|
||||
your report.
|
||||
|
||||
GUI Column Display Layer3_cols argument to type in (to print in report)
|
||||
|
||||
Name | 'name'
|
||||
EID | 'eid'
|
||||
Run | 'run'
|
||||
Mng | 'mng'
|
||||
Script | 'script'
|
||||
Tx Rate | 'tx rate'
|
||||
Tx Rate (1 min) | 'tx rate (1 min)'
|
||||
Tx Rate (last) | 'tx rate (last)'
|
||||
Tx Rate LL | 'tx rate ll'
|
||||
Rx Rate | 'rx rate'
|
||||
Rx Rate (1 min) | 'rx rate (1 min)'
|
||||
Rx Rate (last) | 'rx rate (last)'
|
||||
Rx Rate LL | 'rx rate ll'
|
||||
Rx Drop % | 'rx drop %'
|
||||
Tx PDUs | 'tx pdus'
|
||||
Tx Pkts LL | 'tx pkts ll'
|
||||
PDU/s TX | 'pdu/s tx'
|
||||
Pps TX LL | 'pps tx ll'
|
||||
Rx PDUs | 'rx pdus'
|
||||
Rx Pkts LL | 'pps rx ll'
|
||||
PDU/s RX | 'pdu/s tx'
|
||||
Pps RX LL | 'pps rx ll'
|
||||
Delay | 'delay'
|
||||
Dropped | 'dropped'
|
||||
Jitter | 'jitter'
|
||||
Tx Bytes | 'tx bytes'
|
||||
Rx Bytes | 'rx bytes'
|
||||
Replays | 'replays'
|
||||
TCP Rtx | 'tcp rtx'
|
||||
Dup Pkts | 'dup pkts'
|
||||
Rx Dup % | 'rx dup %'
|
||||
OOO Pkts | 'ooo pkts'
|
||||
Rx OOO % | 'rx ooo %'
|
||||
RX Wrong Dev | 'rx wrong dev'
|
||||
CRC Fail | 'crc fail'
|
||||
RX BER | 'rx ber'
|
||||
CX Active | 'cx active'
|
||||
CX Estab/s | 'cx estab/s'
|
||||
1st RX | '1st rx'
|
||||
CX TO | 'cx to'
|
||||
Pattern | 'pattern'
|
||||
Min PDU | 'min pdu'
|
||||
Max PDU | 'max pdu'
|
||||
Min Rate | 'min rate'
|
||||
Max Rate | 'max rate'
|
||||
Send Buf | 'send buf'
|
||||
Rcv Buf | 'rcv buf'
|
||||
CWND | 'cwnd'
|
||||
TCP MSS | 'tcp mss'
|
||||
Bursty | 'bursty'
|
||||
A/B | 'a/b'
|
||||
Elapsed | 'elapsed'
|
||||
Destination Addr | 'destination addr'
|
||||
Source Addr | 'source addr'
|
||||
''',
|
||||
more_optional=optional)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
num_sta = 2
|
||||
if (args.num_stations is not None) and (int(args.num_stations) > 0):
|
||||
num_sta = int(args.num_stations)
|
||||
|
||||
|
||||
station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=num_sta - 1, padding_number_=10000,
|
||||
radio=args.radio)
|
||||
|
||||
#transfer below to l3cxprofile2 or base_profile-----------------------#
|
||||
# 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')
|
||||
|
||||
# if type(args.layer3_cols) is not list:
|
||||
# layer3_cols = list(args.layer3_cols.split(","))
|
||||
# # send col names here to file to reformat
|
||||
# else:
|
||||
# layer3_cols = args.layer3_cols
|
||||
# # send col names here to file to reformat
|
||||
# if type(args.port_mgr_cols) is not list:
|
||||
# port_mgr_cols = list(args.port_mgr_cols.split(","))
|
||||
# # send col names here to file to reformat
|
||||
# else:
|
||||
# port_mgr_cols = args.port_mgr_cols
|
||||
# # send col names here to file to reformat
|
||||
# if args.debug:
|
||||
# print("Layer 3 Endp column names are...")
|
||||
# print(layer3_cols)
|
||||
# print("Port Manager column names are...")
|
||||
# print(port_mgr_cols)
|
||||
|
||||
|
||||
ip_var_test = IPV4VariableTime(host=args.mgr,
|
||||
port=args.mgr_port,
|
||||
number_template="0000",
|
||||
sta_list=station_list,
|
||||
name_prefix="VT",
|
||||
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=args.a_min,
|
||||
side_b_min_rate=args.b_min,
|
||||
mode=args.mode,
|
||||
ap=args.ap,
|
||||
_debug_on=args.debug)
|
||||
|
||||
ip_var_test.begin()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -22,6 +22,7 @@ from LANforge.lfcli_base import LFCliBase
|
||||
from LANforge.LFUtils import *
|
||||
import realm
|
||||
from realm import Realm
|
||||
import time
|
||||
|
||||
OPEN="open"
|
||||
WEP="wep"
|
||||
@@ -38,7 +39,7 @@ class StaConnect(LFCliBase):
|
||||
# do not use `super(LFCLiBase,self).__init__(self, host, port, _debugOn)
|
||||
# that is py2 era syntax and will force self into the host variable, making you
|
||||
# very confused.
|
||||
super().__init__(host, port, _debug=_debugOn, _halt_on_error=_exit_on_error, _exit_on_fail=_exit_on_fail)
|
||||
super().__init__(host, port, _debug=_debugOn, _exit_on_fail=_exit_on_fail)
|
||||
self.debugOn = _debugOn
|
||||
self.dut_security = ""
|
||||
self.dut_ssid = _dut_ssid
|
||||
|
||||
@@ -15,15 +15,13 @@ if 'py-json' not in sys.path:
|
||||
sys.path.append('../py-json')
|
||||
|
||||
import argparse
|
||||
import LANforge
|
||||
from LANforge import LFUtils
|
||||
# from LANforge import LFCliBase
|
||||
from LANforge import lfcli_base
|
||||
from LANforge.lfcli_base import LFCliBase
|
||||
from LANforge.LFUtils import *
|
||||
import realm
|
||||
from realm import Realm
|
||||
import pprint
|
||||
from influx import RecordInflux
|
||||
import time
|
||||
|
||||
OPEN="open"
|
||||
WEP="wep"
|
||||
@@ -35,6 +33,8 @@ MODE_AUTO=0
|
||||
class StaConnect2(LFCliBase):
|
||||
def __init__(self, host, port, _dut_ssid="jedway-open-1", _dut_passwd="NA", _dut_bssid="",
|
||||
_user="", _passwd="", _sta_mode="0", _radio="wiphy0",
|
||||
_influx_host=None, _influx_db=None, _influx_user=None,
|
||||
_influx_passwd=None,
|
||||
_resource=1, _upstream_resource=1, _upstream_port="eth1",
|
||||
_sta_name=None, _sta_prefix='sta', _bringup_time_sec=300,
|
||||
debug_=False, _dut_security=OPEN, _exit_on_error=False,
|
||||
@@ -42,7 +42,7 @@ class StaConnect2(LFCliBase):
|
||||
# do not use `super(LFCLiBase,self).__init__(self, host, port, _debugOn)
|
||||
# that is py2 era syntax and will force self into the host variable, making you
|
||||
# very confused.
|
||||
super().__init__(host, port, _debug=debug_, _halt_on_error=_exit_on_error, _exit_on_fail=_exit_on_fail)
|
||||
super().__init__(host, port, _debug=debug_, _exit_on_fail=_exit_on_fail)
|
||||
self.debug = debug_
|
||||
self.dut_security = _dut_security
|
||||
self.dut_ssid = _dut_ssid
|
||||
@@ -72,6 +72,10 @@ class StaConnect2(LFCliBase):
|
||||
self.station_profile = None
|
||||
self.l3_udp_profile = None
|
||||
self.l3_tcp_profile = None
|
||||
self.influx_host = _influx_host
|
||||
self.influx_db = _influx_db
|
||||
self.influx_user = _influx_user
|
||||
self.influx_passwd = _influx_passwd
|
||||
|
||||
# def get_realm(self) -> Realm: # py > 3.6
|
||||
def get_realm(self):
|
||||
@@ -216,6 +220,16 @@ class StaConnect2(LFCliBase):
|
||||
self.station_profile.admin_up()
|
||||
LFUtils.waitUntilPortsAdminUp(self.resource, self.lfclient_url, self.station_names)
|
||||
|
||||
if self.influx_db is not None:
|
||||
grapher = RecordInflux(_influx_host=self.influx_host,
|
||||
_influx_db=self.influx_db,
|
||||
_influx_user=self.influx_user,
|
||||
_influx_passwd=self.influx_passwd,
|
||||
_longevity=1,
|
||||
_devices=self.station_names,
|
||||
_monitor_interval=1,
|
||||
_target_kpi=['bps rx'])
|
||||
|
||||
# station_info = self.jsonGet(self.mgr_url, "%s?fields=port,ip,ap" % (self.getStaUrl()))
|
||||
duration = 0
|
||||
maxTime = self.bringup_time_sec
|
||||
@@ -254,6 +268,9 @@ class StaConnect2(LFCliBase):
|
||||
"probe_flags": 1
|
||||
}
|
||||
self.json_post("/cli-json/nc_show_ports", data)
|
||||
if self.influx_db is not None:
|
||||
grapher.getdata()
|
||||
LFUtils.wait_until_ports_appear()
|
||||
|
||||
for sta_name in self.station_names:
|
||||
sta_url = self.get_station_url(sta_name)
|
||||
@@ -391,6 +408,12 @@ Example:
|
||||
parser.add_argument("--debug", type=str, help="enable debugging")
|
||||
parser.add_argument("--prefix", type=str, help="Station prefix. Default: 'sta'", default='sta')
|
||||
parser.add_argument("--bringup_time", type=int, help="Seconds to wait for stations to associate and aquire IP. Default: 300", default=300)
|
||||
parser.add_argument('--influx_user', help='Username for your Influx database', default=None)
|
||||
parser.add_argument('--influx_passwd', help='Password for your Influx database', default=None)
|
||||
parser.add_argument('--influx_db', help='Name of your Influx database', default=None)
|
||||
parser.add_argument('--influx_host', help='Host of your influx database if different from the system you are running on', default='localhost')
|
||||
parser.add_argument('--monitor_interval', help='How frequently you want to append to your database', default='5s')
|
||||
|
||||
args = parser.parse_args()
|
||||
if args.dest is not None:
|
||||
lfjson_host = args.dest
|
||||
@@ -405,8 +428,13 @@ Example:
|
||||
|
||||
staConnect = StaConnect2(lfjson_host, lfjson_port,
|
||||
debug_=True,
|
||||
_influx_db = args.influx_db,
|
||||
_influx_passwd = args.influx_passwd,
|
||||
_influx_user = args.influx_user,
|
||||
_influx_host = args.influx_host,
|
||||
_exit_on_fail=True,
|
||||
_exit_on_error=False)
|
||||
|
||||
if args.user is not None:
|
||||
staConnect.user = args.user
|
||||
if args.passwd is not None:
|
||||
@@ -438,6 +466,7 @@ Example:
|
||||
staConnect.setup()
|
||||
staConnect.start()
|
||||
print("napping %f sec" % staConnect.runtime_secs)
|
||||
|
||||
time.sleep(staConnect.runtime_secs)
|
||||
staConnect.stop()
|
||||
run_results = staConnect.get_result_list()
|
||||
|
||||
@@ -14,23 +14,52 @@ if 'py-json' not in sys.path:
|
||||
import sta_connect
|
||||
from sta_connect import StaConnect
|
||||
import time
|
||||
import argparse
|
||||
from LANforge.lfcli_base import LFCliBase
|
||||
|
||||
def main():
|
||||
parser = LFCliBase.create_basic_argparse(
|
||||
prog='sta_connect_example.py',
|
||||
formatter_class=argparse.RawTextHelpFormatter
|
||||
)
|
||||
required_args=None
|
||||
for group in parser._action_groups:
|
||||
if group.title == "required arguments":
|
||||
required_args=group
|
||||
break;
|
||||
|
||||
optional_args=None
|
||||
for group in parser._action_groups:
|
||||
if group.title == "optional arguments":
|
||||
optional_args=group
|
||||
break;
|
||||
|
||||
args = parser.parse_args()
|
||||
if args.upstream_port is None:
|
||||
args.upstream_port = "eth2"
|
||||
if args.ssid is None:
|
||||
args.ssid = "Default-SSID-2g"
|
||||
if args.passwd is None:
|
||||
args.passwd = "12345678"
|
||||
if args.security is None:
|
||||
args.security = sta_connect.WPA2
|
||||
if args.radio is None:
|
||||
args.radio = "wiphy0"
|
||||
staConnect = StaConnect("localhost", 8080, _debugOn=False)
|
||||
staConnect.sta_mode = 0
|
||||
staConnect.upstream_resource = 1
|
||||
staConnect.upstream_port = "eth2"
|
||||
staConnect.radio = "wiphy0"
|
||||
staConnect.upstream_port = args.upstream_port
|
||||
staConnect.radio = args.radio
|
||||
staConnect.resource = 1
|
||||
staConnect.dut_security = sta_connect.WPA2
|
||||
staConnect.dut_ssid = "Default-SSID-2g"
|
||||
staConnect.dut_passwd = "12345678"
|
||||
staConnect.dut_security = args.security
|
||||
staConnect.dut_ssid = args.ssid
|
||||
staConnect.dut_passwd = args.passwd
|
||||
staConnect.station_names = [ "sta000" ]
|
||||
staConnect.setup()
|
||||
staConnect.start()
|
||||
time.sleep(20)
|
||||
staConnect.stop()
|
||||
staConnect.finish()
|
||||
#staConnect.finish()
|
||||
staConnect.cleanup()
|
||||
is_passing = staConnect.passes()
|
||||
if is_passing == False:
|
||||
|
||||
103
py-scripts/station_layer3.py
Normal file
103
py-scripts/station_layer3.py
Normal file
@@ -0,0 +1,103 @@
|
||||
'''this script creates 1 station on given arguments
|
||||
how to run - [lanforge@LF4-Node2 py-scripts]$ python3 station_banao.py -hst localhost -s TestAP22 -pwd [BLANK] -sec open -rad wiphy0
|
||||
|
||||
'''
|
||||
|
||||
import sys
|
||||
import argparse
|
||||
import time
|
||||
if 'py-json' not in sys.path:
|
||||
sys.path.append('../py-json')
|
||||
from LANforge import LFUtils
|
||||
from LANforge import lfcli_base
|
||||
from LANforge.lfcli_base import LFCliBase
|
||||
from LANforge.LFUtils import *
|
||||
import realm
|
||||
from realm import Realm
|
||||
|
||||
class STATION(LFCliBase):
|
||||
def __init__(self, lfclient_host, lfclient_port, ssid, paswd, security, radio, sta_list=None, name_prefix="L3Test", upstream="eth2"):
|
||||
super().__init__(lfclient_host, lfclient_port)
|
||||
self.host = lfclient_host
|
||||
self.port = lfclient_port
|
||||
self.ssid = ssid
|
||||
self.paswd = paswd
|
||||
self.security = security
|
||||
self.radio = radio
|
||||
self.sta_list = sta_list
|
||||
self.name_prefix = name_prefix
|
||||
self.upstream = upstream
|
||||
|
||||
self.local_realm = realm.Realm(lfclient_host=self.host, lfclient_port=self.port)
|
||||
self.station_profile = self.local_realm.new_station_profile()
|
||||
self.station_profile.ssid = self.ssid
|
||||
self.station_profile.ssid_pass = self.paswd,
|
||||
self.station_profile.security = self.security
|
||||
self.cx_profile = self.local_realm.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 = 1000000
|
||||
self.cx_profile.side_a_max_bps = 1000000
|
||||
self.cx_profile.side_b_min_bps = 1000000
|
||||
self.cx_profile.side_b_max_bps = 1000000
|
||||
|
||||
|
||||
def precleanup(self, sta_list):
|
||||
self.cx_profile.cleanup_prefix()
|
||||
for sta in self.sta_list:
|
||||
self.local_realm.rm_port(sta, check_exists=True)
|
||||
LFUtils.wait_until_ports_disappear(base_url=self.lfclient_url,
|
||||
port_list=sta_list,
|
||||
debug=self.debug)
|
||||
time.sleep(1)
|
||||
|
||||
def build(self):
|
||||
self.station_profile.use_security(self.security, self.ssid, self.paswd)
|
||||
self.station_profile.create(radio=self.radio)
|
||||
self.cx_profile.create(endp_type="lf_udp", side_a=self.station_profile.station_names, side_b=self.upstream,
|
||||
sleep_time=0)
|
||||
|
||||
def start(self, sta_list):
|
||||
self.station_profile.admin_up()
|
||||
temp_stas = self.station_profile.station_names.copy()
|
||||
if self.local_realm.wait_for_ip(temp_stas):
|
||||
self._pass("All stations got IPs")
|
||||
else:
|
||||
self._fail("Stations failed to get IPs")
|
||||
self.exit_fail()
|
||||
self.cx_profile.start_cx()
|
||||
|
||||
|
||||
def stop(self):
|
||||
# Bring stations down
|
||||
self.station_profile.admin_down()
|
||||
self.cx_profile.stop_cx()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Netgear AP DFS Test Script")
|
||||
parser.add_argument('-hst', '--host', type=str, help='host name')
|
||||
parser.add_argument('-s', '--ssid', type=str, help='ssid for client')
|
||||
parser.add_argument('-pwd', '--passwd', type=str, help='password to connect to ssid')
|
||||
parser.add_argument('-sec', '--security', type=str, help='security')
|
||||
parser.add_argument('-rad', '--radio', type=str, help='radio at which client will be connected')
|
||||
#parser.add_argument()
|
||||
args = parser.parse_args()
|
||||
num_sta = 1
|
||||
station_list = LFUtils.port_name_series(prefix="sta",
|
||||
start_id=0,
|
||||
end_id=num_sta - 1,
|
||||
padding_number=10000,
|
||||
radio=args.radio)
|
||||
obj = STATION(lfclient_host= args.host, lfclient_port=8080, ssid=args.ssid , paswd=args.passwd, security=args.security, radio=args.radio, sta_list=station_list)
|
||||
obj.precleanup(station_list)
|
||||
obj.build()
|
||||
obj.start(station_list)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -24,7 +24,7 @@ class Test1KClients(LFCliBase):
|
||||
side_a_min_rate= 0,side_a_max_rate= 56000,
|
||||
side_b_min_rate= 0,side_b_max_rate= 56000,
|
||||
num_sta_=200,
|
||||
test_duration="30s",
|
||||
test_duration="2d",
|
||||
_debug_on=True,
|
||||
_exit_on_error=False,
|
||||
_exit_on_fail=False):
|
||||
@@ -67,6 +67,16 @@ class Test1KClients(LFCliBase):
|
||||
self.cx_profile.side_b_max_bps = side_b_max_rate
|
||||
|
||||
self.station_profile_map = {}
|
||||
#change resource admin_up rate
|
||||
self.local_realm.json_post("/cli-json/set_resource", {
|
||||
"shelf":1,
|
||||
"resource":all,
|
||||
"max_staged_bringup": 30,
|
||||
"max_trying_ifup": 15,
|
||||
"max_station_bringup": 6
|
||||
})
|
||||
|
||||
|
||||
def build(self):
|
||||
for (radio, name_series) in self.station_radio_map.items():
|
||||
print("building stations for %s"%radio)
|
||||
@@ -133,7 +143,7 @@ class Test1KClients(LFCliBase):
|
||||
self.local_realm.wait_for_ip(station_list=self.station_radio_map[radio], debug=self.debug, timeout_sec=30)
|
||||
curr_ip_num = self.local_realm.get_curr_num_ips(num_sta_with_ips=prev_ip_num,station_list=self.station_radio_map[radio], debug=self.debug)
|
||||
while ((prev_ip_num < curr_ip_num) and (curr_ip_num < total_num_sta)):
|
||||
self.local_realm.wait_for_ip(station_list=self.station_radio_map[radio], debug=self.debug, timeout_sec=60)
|
||||
self.local_realm.wait_for_ip(station_list=self.station_radio_map[radio], debug=self.debug, timeout_sec=90)
|
||||
prev_ip_num = curr_ip_num
|
||||
curr_ip_num = self.local_realm.get_curr_num_ips(num_sta_with_ips=prev_ip_num,station_list=self.station_radio_map[radio], debug=self.debug)
|
||||
if curr_ip_num == total_num_sta:
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
#!/bin/bash
|
||||
#This bash script aims to automate the test process of all Candela Technologies's test_* scripts in the lanforge-scripts directory. The script can be run 2 ways and may include (via user input) the "start_num" and "stop_num" variables to select which tests should be run.
|
||||
# OPTION ONE: ./test_all_scripts.sh : this command runs all the scripts in the array "testCommands"
|
||||
|
||||
122
py-scripts/test_client_admission.py
Normal file
122
py-scripts/test_client_admission.py
Normal file
@@ -0,0 +1,122 @@
|
||||
""" This script will create one station at a time and generate downstream traffic at 5Mbps then again create next station create layer3 and will continue doing same until Ap stops admiting client
|
||||
This script can be used for for client admission test for particular AP
|
||||
|
||||
arguements = >python3 load_21.py -hst 192.168.200.13 -s Nikita -pwd [BLANK] -sec open -rad wiphy1 --num_sta 60
|
||||
-Nikita Yadav
|
||||
-date: 23-02-2021
|
||||
"""
|
||||
import sys
|
||||
import argparse
|
||||
import time
|
||||
|
||||
if 'py-json' not in sys.path:
|
||||
sys.path.append('../py-json')
|
||||
from LANforge import LFUtils
|
||||
from LANforge import lfcli_base
|
||||
from LANforge.lfcli_base import LFCliBase
|
||||
from LANforge.LFUtils import *
|
||||
import realm
|
||||
from realm import Realm
|
||||
|
||||
|
||||
class LoadLayer3(Realm):
|
||||
def __init__(self, lfclient_host, lfclient_port, ssid, paswd, security, radio, num_sta, name_prefix="L3", upstream="eth2"):
|
||||
|
||||
self.host = lfclient_host
|
||||
self.port = lfclient_port
|
||||
self.ssid = ssid
|
||||
self.paswd = paswd
|
||||
self.security = security
|
||||
self.radio = radio
|
||||
self.num_sta = num_sta
|
||||
|
||||
self.name_prefix = name_prefix
|
||||
self.upstream = upstream
|
||||
|
||||
self.local_realm = realm.Realm(lfclient_host=self.host, lfclient_port=self.port)
|
||||
self.station_profile = self.local_realm.new_station_profile()
|
||||
self.station_profile.ssid = self.ssid
|
||||
self.station_profile.ssid_pass = self.paswd,
|
||||
self.station_profile.security = self.security
|
||||
self.cx_profile = self.local_realm.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 = 5000000
|
||||
self.cx_profile.side_a_max_bps = 5000000
|
||||
self.cx_profile.side_b_min_bps = 0
|
||||
self.cx_profile.side_b_max_bps = 0
|
||||
|
||||
def precleanup(self, num_sta):
|
||||
num_sta = self.num_sta
|
||||
station_list = LFUtils.port_name_series(prefix="sta",
|
||||
start_id=0,
|
||||
end_id=num_sta - 1,
|
||||
padding_number=100,
|
||||
radio=self.radio)
|
||||
self.cx_profile.cleanup_prefix()
|
||||
|
||||
for sta in station_list:
|
||||
self.local_realm.rm_port(sta, check_exists=True)
|
||||
LFUtils.wait_until_ports_disappear(base_url=self.local_realm.lfclient_url, port_list=station_list,
|
||||
debug=self.local_realm.debug)
|
||||
time.sleep(1)
|
||||
|
||||
def build(self, sta_name):
|
||||
self.station_profile.use_security(self.security, self.ssid, self.paswd)
|
||||
self.station_profile.create(radio=self.radio, sta_names_=[sta_name], debug=self.local_realm.debug)
|
||||
self.station_profile.admin_up()
|
||||
if self.local_realm.wait_for_ip([sta_name]):
|
||||
self.local_realm._pass("All stations got IPs", print_=True)
|
||||
|
||||
self.cx_profile.create(endp_type="lf_udp", side_a=self.upstream, side_b=[sta_name],
|
||||
sleep_time=0)
|
||||
self.cx_profile.start_cx()
|
||||
|
||||
return 1
|
||||
else:
|
||||
self.local_realm._fail("Stations failed to get IPs", print_=True)
|
||||
return 0
|
||||
|
||||
def start(self, num_sta):
|
||||
num_sta = self.num_sta
|
||||
station_list = LFUtils.port_name_series(prefix="sta",
|
||||
start_id=0,
|
||||
end_id=num_sta - 1,
|
||||
padding_number=100,
|
||||
radio=self.radio)
|
||||
|
||||
for i in station_list:
|
||||
# self.build(i)
|
||||
if self.build(i) == 0:
|
||||
print("station not created")
|
||||
break
|
||||
else:
|
||||
print("station created")
|
||||
|
||||
def stop(self):
|
||||
# Bring stations down
|
||||
self.station_profile.admin_down()
|
||||
self.cx_profile.stop_cx()
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Client Admission Test Script")
|
||||
parser.add_argument('-hst', '--host', type=str, help='host name')
|
||||
parser.add_argument('-s', '--ssid', type=str, help='ssid for client')
|
||||
parser.add_argument('-pwd', '--passwd', type=str, help='password to connect to ssid')
|
||||
parser.add_argument('-sec', '--security', type=str, help='security')
|
||||
parser.add_argument('-rad', '--radio', type=str, help='radio at which client will be connected')
|
||||
parser.add_argument('-num_sta', '--num_sta', type=int, help='provide number of stations you want to create', default=60)
|
||||
# parser.add_argument()
|
||||
args = parser.parse_args()
|
||||
|
||||
obj = LoadLayer3(lfclient_host=args.host, lfclient_port=8080, ssid=args.ssid, paswd=args.passwd,
|
||||
security=args.security, radio=args.radio, num_sta=args.num_sta)
|
||||
obj.precleanup(num_sta=args.num_sta)
|
||||
|
||||
obj.start(num_sta=args.num_sta)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -11,6 +11,14 @@ this script will depend on the mode used, a read-only test will check the read-b
|
||||
and both will check both attributes. If the relevant attributes increase over the duration of the test it will pass,
|
||||
otherwise it will fail.
|
||||
|
||||
Example:
|
||||
./test_fileio.py --macvlan_parent <port> --num_ports <num ports> --use_macvlans
|
||||
--first_mvlan_ip <first ip in series> --netmask <netmask to use> --gateway <gateway ip addr>
|
||||
|
||||
./test_fileio.py --macvlan_parent eth2 --num_ports 3 --use_macvlans --first_mvlan_ip 192.168.92.13
|
||||
--netmask 255.255.255.0 --gateway 192.168.92.1
|
||||
|
||||
|
||||
Use './test_fileio.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.
|
||||
@@ -35,6 +43,7 @@ import realm
|
||||
import time
|
||||
import datetime
|
||||
import pprint
|
||||
import os
|
||||
|
||||
|
||||
class FileIOTest(LFCliBase):
|
||||
@@ -72,7 +81,7 @@ class FileIOTest(LFCliBase):
|
||||
_debug_on=False,
|
||||
_exit_on_error=False,
|
||||
_exit_on_fail=False):
|
||||
super().__init__(host, port, _debug=_debug_on, _halt_on_error=_exit_on_error, _exit_on_fail=_exit_on_fail)
|
||||
super().__init__(host, port, _debug=_debug_on, _exit_on_fail=_exit_on_fail)
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.radio = radio
|
||||
@@ -712,9 +721,14 @@ Generic command layout:
|
||||
dhcp = False
|
||||
else:
|
||||
dhcp = True
|
||||
# print(port_list)
|
||||
if 'nfs' in args.fs_type:
|
||||
if len(os.popen('mount -l | grep nfs').read()) > 0:
|
||||
print('Success')
|
||||
else:
|
||||
raise ValueError("No nfs share is mounted")
|
||||
else:
|
||||
exit(1)
|
||||
|
||||
# exit(1)
|
||||
ip_test = FileIOTest(args.mgr,
|
||||
args.mgr_port,
|
||||
ssid=args.ssid,
|
||||
@@ -725,7 +739,6 @@ Generic command layout:
|
||||
test_duration=args.test_duration,
|
||||
upstream_port=args.upstream_port,
|
||||
_debug_on=args.debug,
|
||||
|
||||
macvlan_parent=args.macvlan_parent,
|
||||
use_macvlans=args.use_macvlans,
|
||||
first_mvlan_ip=args.first_mvlan_ip,
|
||||
|
||||
@@ -26,7 +26,7 @@ if 'py-json' not in sys.path:
|
||||
import argparse
|
||||
from LANforge.lfcli_base import LFCliBase
|
||||
from LANforge import LFUtils
|
||||
import realm
|
||||
from realm import Realm
|
||||
import time
|
||||
import datetime
|
||||
import json
|
||||
@@ -35,10 +35,12 @@ class GenTest(LFCliBase):
|
||||
def __init__(self, ssid, security, passwd, sta_list, client, name_prefix, upstream, host="localhost", port=8080,
|
||||
number_template="000", test_duration="5m", type="lfping", dest=None, cmd =None,
|
||||
interval=1, radio=None, speedtest_min_up=None, speedtest_min_dl=None, speedtest_max_ping=None,
|
||||
file_output=None,
|
||||
loop_count=None,
|
||||
_debug_on=False,
|
||||
_exit_on_error=False,
|
||||
_exit_on_fail=False,):
|
||||
super().__init__(host, port, _local_realm=realm.Realm(host,port), _debug=_debug_on, _halt_on_error=_exit_on_error, _exit_on_fail=_exit_on_fail)
|
||||
_exit_on_fail=False):
|
||||
super().__init__(host, port, _local_realm=Realm(host,port), _debug=_debug_on, _exit_on_fail=_exit_on_fail)
|
||||
self.ssid = ssid
|
||||
self.radio = radio
|
||||
self.upstream = upstream
|
||||
@@ -48,12 +50,6 @@ class GenTest(LFCliBase):
|
||||
self.number_template = number_template
|
||||
self.name_prefix = name_prefix
|
||||
self.test_duration = test_duration
|
||||
if (speedtest_min_up is not None):
|
||||
self.speedtest_min_up = float(speedtest_min_up)
|
||||
if (speedtest_min_dl is not None):
|
||||
self.speedtest_min_dl = float(speedtest_min_dl)
|
||||
if (speedtest_max_ping is not None):
|
||||
self.speedtest_max_ping = float(speedtest_max_ping)
|
||||
self.debug = _debug_on
|
||||
if (client is not None):
|
||||
self.client_name = client
|
||||
@@ -72,57 +68,14 @@ class GenTest(LFCliBase):
|
||||
self.generic_endps_profile.dest = dest
|
||||
self.generic_endps_profile.cmd = cmd
|
||||
self.generic_endps_profile.interval = interval
|
||||
|
||||
def choose_ping_command(self):
|
||||
gen_results = self.json_get("generic/list?fields=name,last+results", debug_=self.debug)
|
||||
if self.debug:
|
||||
print(gen_results)
|
||||
if gen_results['endpoints'] is not None:
|
||||
for name in gen_results['endpoints']:
|
||||
for k, v in name.items():
|
||||
if v['name'] in self.generic_endps_profile.created_endp and not v['name'].endswith('1'):
|
||||
if v['last results'] != "" and "Unreachable" not in v['last results']:
|
||||
return True, v['name']
|
||||
else:
|
||||
return False, v['name']
|
||||
|
||||
def choose_lfcurl_command(self):
|
||||
return False, ''
|
||||
|
||||
def choose_iperf3_command(self):
|
||||
gen_results = self.json_get("generic/list?fields=name,last+results", debug_=self.debug)
|
||||
if gen_results['endpoints'] is not None:
|
||||
pprint.pprint(gen_results['endpoints'])
|
||||
#for name in gen_results['endpoints']:
|
||||
# pprint.pprint(name.items)
|
||||
#for k,v in name.items():
|
||||
exit(1)
|
||||
|
||||
|
||||
def choose_speedtest_command(self):
|
||||
gen_results = self.json_get("generic/list?fields=name,last+results", debug_=self.debug)
|
||||
if gen_results['endpoints'] is not None:
|
||||
for name in gen_results['endpoints']:
|
||||
for k, v in name.items():
|
||||
if v['last results'] is not None and v['name'] in self.generic_endps_profile.created_endp and v['last results'] != '':
|
||||
last_results = json.loads(v['last results'])
|
||||
if last_results['download'] is None and last_results['upload'] is None and last_results['ping'] is None:
|
||||
return False, v['name']
|
||||
elif last_results['download'] >= self.speedtest_min_dl and \
|
||||
last_results['upload'] >= self.speedtest_min_up and \
|
||||
last_results['ping'] <= self.speedtest_max_ping:
|
||||
return True, v['name']
|
||||
|
||||
def choose_generic_command(self):
|
||||
gen_results = self.json_get("generic/list?fields=name,last+results", debug_=self.debug)
|
||||
if (gen_results['endpoints'] is not None):
|
||||
for name in gen_results['endpoints']:
|
||||
for k, v in name.items():
|
||||
if v['name'] in self.generic_endps_profile.created_endp and not v['name'].endswith('1'):
|
||||
if v['last results'] != "" and "not known" not in v['last results']:
|
||||
return True, v['name']
|
||||
else:
|
||||
return False, v['name']
|
||||
self.generic_endps_profile.file_output= file_output
|
||||
self.generic_endps_profile.loop_count = loop_count
|
||||
if (speedtest_min_up is not None):
|
||||
self.generic_endps_profile.speedtest_min_up = float(speedtest_min_up)
|
||||
if (speedtest_min_dl is not None):
|
||||
self.generic_endps_profile.speedtest_min_dl = float(speedtest_min_dl)
|
||||
if (speedtest_max_ping is not None):
|
||||
self.generic_endps_profile.speedtest_max_ping = float(speedtest_max_ping)
|
||||
|
||||
def start(self, print_pass=False, print_fail=False):
|
||||
self.station_profile.admin_up()
|
||||
@@ -132,44 +85,13 @@ class GenTest(LFCliBase):
|
||||
if self.debug:
|
||||
pprint.pprint(self.station_profile.station_names)
|
||||
LFUtils.wait_until_ports_admin_up(base_url=self.lfclient_url, port_list=self.station_profile.station_names)
|
||||
if self.local_realm.wait_for_ip(temp_stas):
|
||||
if self.local_realm.wait_for_ip(station_list=temp_stas, ipv4=True):
|
||||
self._pass("All stations got IPs")
|
||||
else:
|
||||
self._fail("Stations failed to get IPs")
|
||||
self.exit_fail()
|
||||
cur_time = datetime.datetime.now()
|
||||
passes = 0
|
||||
expected_passes = 0
|
||||
self.generic_endps_profile.start_cx()
|
||||
time.sleep(15)
|
||||
end_time = self.local_realm.parse_time("30s") + cur_time
|
||||
print("Starting Test...")
|
||||
result = False
|
||||
while cur_time < end_time:
|
||||
cur_time = datetime.datetime.now()
|
||||
if self.generic_endps_profile.type == "lfping":
|
||||
result = self.choose_ping_command()
|
||||
elif self.generic_endps_profile.type == "generic":
|
||||
result = self.choose_generic_command()
|
||||
elif self.generic_endps_profile.type == "lfcurl":
|
||||
result = self.choose_lfcurl_command()
|
||||
elif self.generic_endps_profile.type == "speedtest":
|
||||
result = self.choose_speedtest_command()
|
||||
elif self.generic_endps_profile.type == "iperf3":
|
||||
result = self.choose_iperf3_command()
|
||||
else:
|
||||
continue
|
||||
expected_passes += 1
|
||||
if result is not None:
|
||||
if result[0]:
|
||||
passes += 1
|
||||
else:
|
||||
self._fail("%s Failed to ping %s " % (result[1], self.generic_endps_profile.dest))
|
||||
break
|
||||
time.sleep(1)
|
||||
|
||||
if passes == expected_passes:
|
||||
self._pass("PASS: All tests passed")
|
||||
self.generic_endps_profile.start_cx()
|
||||
|
||||
def stop(self):
|
||||
print("Stopping Test...")
|
||||
@@ -196,6 +118,24 @@ class GenTest(LFCliBase):
|
||||
|
||||
|
||||
def main():
|
||||
optional = []
|
||||
optional.append({'name': '--mode', 'help': 'Used to force mode of stations'})
|
||||
optional.append({'name': '--ap', 'help': 'Used to force a connection to a particular AP'})
|
||||
optional.append({'name': '--output_format', 'help': 'choose either csv or xlsx'})
|
||||
optional.append({'name': '--report_file', 'help': 'where you want to store results', 'default': None})
|
||||
optional.append({'name': '--a_min', 'help': '--a_min bps rate minimum for side_a', 'default': 256000})
|
||||
optional.append({'name': '--b_min', 'help': '--b_min bps rate minimum for side_b', 'default': 256000})
|
||||
optional.append({'name': '--gen_cols', 'help': 'Columns wished to be monitored from layer 3 endpoint tab',
|
||||
'default': ['name', 'tx bytes', 'rx bytes']})
|
||||
optional.append({'name': '--port_mgr_cols', 'help': 'Columns wished to be monitored from port manager tab',
|
||||
'default': ['ap', 'ip', 'parent dev']})
|
||||
optional.append(
|
||||
{'name': '--compared_report', 'help': 'report path and file which is wished to be compared with new report',
|
||||
'default': None})
|
||||
optional.append({'name': '--monitor_interval',
|
||||
'help': 'how frequently do you want your monitor function to take measurements; 250ms, 35s, 2h',
|
||||
'default': '2s'})
|
||||
|
||||
parser = LFCliBase.create_basic_argparse(
|
||||
prog='test_generic.py',
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
@@ -232,7 +172,8 @@ python3 ./test_generic.py
|
||||
--speedtest_min_dl 20 --speedtest_max_ping 150 --security wpa2
|
||||
IPERF3 (under construction):
|
||||
./test_generic.py --mgr localhost --mgr_port 4122 --radio wiphy1 --num_stations 3 --ssid jedway-wpa2-x2048-4-1 --passwd jedway-wpa2-x2048-4-1 --security wpa2 --type iperf3
|
||||
''')
|
||||
''',
|
||||
more_optional=optional)
|
||||
|
||||
parser.add_argument('--type', help='type of command to run: generic, lfping, iperf3-client, iperf3-server, lfcurl', default="lfping")
|
||||
parser.add_argument('--cmd', help='specifies command to be run by generic type endp', default='')
|
||||
@@ -242,7 +183,9 @@ python3 ./test_generic.py
|
||||
parser.add_argument('--speedtest_min_up', help='sets the minimum upload threshold for the speedtest type', default=None)
|
||||
parser.add_argument('--speedtest_min_dl', help='sets the minimum download threshold for the speedtest type', default=None)
|
||||
parser.add_argument('--speedtest_max_ping', help='sets the minimum ping threshold for the speedtest type', default=None)
|
||||
parser.add_argument('--client', help='client to the iperf3 server',default=None)
|
||||
parser.add_argument('--client', help='client to the iperf3 server', default=None)
|
||||
parser.add_argument('--file_output', help='location to output results of lf_curl, absolute path preferred', default=None)
|
||||
parser.add_argument('--loop_count', help='determines the number of loops to use in lf_curl', default=None)
|
||||
|
||||
args = parser.parse_args()
|
||||
num_sta = 2
|
||||
@@ -250,6 +193,54 @@ python3 ./test_generic.py
|
||||
num_stations_converted = int(args.num_stations)
|
||||
num_sta = num_stations_converted
|
||||
|
||||
# Create directory
|
||||
|
||||
# if file path with output file extension is not given...
|
||||
# check if home/lanforge/report-data exists. if not, save
|
||||
# in new folder based in current file's directory
|
||||
systeminfopath = None
|
||||
if args.report_file is None:
|
||||
new_file_path = str(datetime.datetime.now().strftime("%Y-%m-%d-%H-h-%M-m-%S-s")).replace(':',
|
||||
'-') + '-test_generic' # create path name
|
||||
try:
|
||||
path = os.path.join('/home/lanforge/report-data/', new_file_path)
|
||||
os.mkdir(path)
|
||||
except:
|
||||
curr_dir_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
path = os.path.join(curr_dir_path, new_file_path)
|
||||
os.mkdir(path)
|
||||
systeminfopath = str(path) + '/systeminfo.txt'
|
||||
|
||||
if args.output_format in ['csv', 'json', 'html', 'hdf', 'stata', 'pickle', 'pdf', 'png', 'parquet',
|
||||
'xlsx']:
|
||||
report_f = str(path) + '/data.' + args.output_format
|
||||
output = args.output_format
|
||||
else:
|
||||
print(
|
||||
'Not supporting this report format or cannot find report format provided. Defaulting to csv data file output type, naming it data.csv.')
|
||||
report_f = str(path) + '/data.csv'
|
||||
output = 'csv'
|
||||
|
||||
else:
|
||||
systeminfopath = str(args.report_file).split('/')[-1]
|
||||
report_f = args.report_file
|
||||
if args.output_format is None:
|
||||
output = str(args.report_file).split('.')[-1]
|
||||
else:
|
||||
output = args.output_format
|
||||
print("Saving final report data in ... " + report_f)
|
||||
|
||||
# Retrieve last data file
|
||||
compared_rept = None
|
||||
if args.compared_report:
|
||||
compared_report_format = args.compared_report.split('.')[-1]
|
||||
# if compared_report_format not in ['csv', 'json', 'dta', 'pkl','html','xlsx','parquet','h5']:
|
||||
if compared_report_format != 'csv':
|
||||
print(ValueError("Cannot process this file type. Please select a different file and re-run script."))
|
||||
exit(1)
|
||||
else:
|
||||
compared_rept = args.compared_report
|
||||
|
||||
station_list = LFUtils.portNameSeries(radio=args.radio,
|
||||
prefix_="sta",
|
||||
start_id_=0,
|
||||
@@ -273,6 +264,8 @@ python3 ./test_generic.py
|
||||
speedtest_min_up=args.speedtest_min_up,
|
||||
speedtest_min_dl=args.speedtest_min_dl,
|
||||
speedtest_max_ping=args.speedtest_max_ping,
|
||||
file_output=args.file_output,
|
||||
loop_count=args.loop_count,
|
||||
client=args.client,
|
||||
_debug_on=args.debug)
|
||||
|
||||
@@ -280,11 +273,54 @@ python3 ./test_generic.py
|
||||
generic_test.build()
|
||||
if not generic_test.passes():
|
||||
print(generic_test.get_fail_message())
|
||||
generic_test.exit_fail()
|
||||
generic_test.exit_fail()
|
||||
generic_test.start()
|
||||
if not generic_test.passes():
|
||||
print(generic_test.get_fail_message())
|
||||
generic_test.exit_fail()
|
||||
|
||||
try:
|
||||
genconnections = ','.join([[*x.keys()][0] for x in generic_test.json_get('generic')['endpoints']])
|
||||
except:
|
||||
raise ValueError('Try setting the upstream port flag if your device does not have an eth1 port')
|
||||
|
||||
if type(args.gen_cols) is not list:
|
||||
generic_cols = list(args.gen_cols.split(","))
|
||||
# send col names here to file to reformat
|
||||
else:
|
||||
generic_cols = args.gen_cols
|
||||
# send col names here to file to reformat
|
||||
if type(args.port_mgr_cols) is not list:
|
||||
port_mgr_cols = list(args.port_mgr_cols.split(","))
|
||||
# send col names here to file to reformat
|
||||
else:
|
||||
port_mgr_cols = args.port_mgr_cols
|
||||
# send col names here to file to reformat
|
||||
if args.debug:
|
||||
print("Generic Endp column names are...")
|
||||
print(generic_cols)
|
||||
print("Port Manager column names are...")
|
||||
print(port_mgr_cols)
|
||||
try:
|
||||
monitor_interval = Realm.parse_time(args.monitor_interval).total_seconds()
|
||||
except ValueError as error:
|
||||
print(ValueError("The time string provided for monitor_interval argument is invalid. Please see supported time stamp increments and inputs for monitor_interval in --help. "))
|
||||
exit(1)
|
||||
generic_test.start(False, False)
|
||||
generic_test.generic_endps_profile.monitor(generic_cols=generic_cols,
|
||||
sta_list=station_list,
|
||||
#port_mgr_cols=port_mgr_cols,
|
||||
report_file=report_f,
|
||||
systeminfopath=systeminfopath,
|
||||
duration_sec=Realm.parse_time(args.test_duration).total_seconds(),
|
||||
monitor_interval_ms=monitor_interval,
|
||||
created_cx=genconnections,
|
||||
output_format=output,
|
||||
compared_report=compared_rept,
|
||||
script_name='test_generic',
|
||||
arguments=args,
|
||||
debug=args.debug)
|
||||
|
||||
generic_test.stop()
|
||||
time.sleep(30)
|
||||
generic_test.cleanup(station_list)
|
||||
|
||||
2
py-scripts/test_ipv4_connection.py
Normal file → Executable file
2
py-scripts/test_ipv4_connection.py
Normal file → Executable file
@@ -48,13 +48,11 @@ class IPv4Test(LFCliBase):
|
||||
_proxy_str=_proxy_str,
|
||||
_local_realm=realm.Realm(lfclient_host=_host,
|
||||
lfclient_port=_port,
|
||||
halt_on_error_=_exit_on_error,
|
||||
_exit_on_error=_exit_on_error,
|
||||
_exit_on_fail=_exit_on_fail,
|
||||
_proxy_str=_proxy_str,
|
||||
debug_=_debug_on),
|
||||
_debug=_debug_on,
|
||||
_halt_on_error=_exit_on_error,
|
||||
_exit_on_fail=_exit_on_fail)
|
||||
self.host = _host
|
||||
self.port = _port
|
||||
|
||||
@@ -30,13 +30,13 @@ import datetime
|
||||
|
||||
class IPV4L4(LFCliBase):
|
||||
def __init__(self, host, port, ssid, security, password, url,
|
||||
station_list,
|
||||
number_template="00000", radio="wiphy0",
|
||||
test_duration="5m", upstream_port="eth1",
|
||||
_debug_on=False,
|
||||
_exit_on_error=False,
|
||||
_exit_on_fail=False):
|
||||
super().__init__(host, port, _debug=_debug_on, _halt_on_error=_exit_on_error, _exit_on_fail=_exit_on_fail)
|
||||
station_list,
|
||||
number_template="00000", radio="wiphy0",
|
||||
test_duration="5m", upstream_port="eth1",
|
||||
_debug_on=False,
|
||||
_exit_on_error=False,
|
||||
_exit_on_fail=False):
|
||||
super().__init__(host, port, _debug=_debug_on, _exit_on_fail=_exit_on_fail)
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.radio = radio
|
||||
@@ -107,8 +107,7 @@ class IPV4L4(LFCliBase):
|
||||
suppress_related_commands_=None)
|
||||
|
||||
def start(self, print_pass=False, print_fail=False):
|
||||
temp_stas = self.sta_list.copy()
|
||||
# temp_stas.append(self.local_realm.name_to_eid(self.upstream_port)[2])
|
||||
temp_stas = self.station_profile.station_names.copy()
|
||||
self.station_profile.admin_up()
|
||||
if self.local_realm.wait_for_ip(temp_stas):
|
||||
self._pass("All stations got IPs", print_pass)
|
||||
@@ -189,9 +188,8 @@ def main():
|
||||
''')
|
||||
|
||||
parser.add_argument('--test_duration', help='--test_duration sets the duration of the test', default="5m")
|
||||
parser.add_argument('--url', help='--url specifies upload/download, address, and dest', default="dl http://10.40.0.1 /dev/null")
|
||||
|
||||
|
||||
parser.add_argument('--url', help='--url specifies upload/download, address, and dest',
|
||||
default="dl http://10.40.0.1 /dev/null")
|
||||
|
||||
args = parser.parse_args()
|
||||
num_sta = 2
|
||||
@@ -199,26 +197,32 @@ def main():
|
||||
num_stations_converted = int(args.num_stations)
|
||||
num_sta = num_stations_converted
|
||||
|
||||
|
||||
station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_= num_sta-1, padding_number_=10000, radio=args.radio)
|
||||
station_list = LFUtils.portNameSeries(prefix_="sta",
|
||||
start_id_=0,
|
||||
end_id_=num_sta - 1,
|
||||
padding_number_=10000,
|
||||
radio=args.radio)
|
||||
|
||||
ip_test = IPV4L4(host=args.mgr, port=args.mgr_port,
|
||||
ssid=args.ssid,
|
||||
radio=args.radio,
|
||||
password=args.passwd,
|
||||
security=args.security,
|
||||
station_list=station_list,
|
||||
url=args.url,
|
||||
test_duration=args.test_duration,
|
||||
upstream_port=args.upstream_port,
|
||||
_debug_on=args.debug)
|
||||
ssid=args.ssid,
|
||||
radio=args.radio,
|
||||
password=args.passwd,
|
||||
security=args.security,
|
||||
station_list=station_list,
|
||||
url=args.url,
|
||||
test_duration=args.test_duration,
|
||||
upstream_port=args.upstream_port,
|
||||
_debug_on=args.debug)
|
||||
|
||||
ip_test.cleanup(station_list)
|
||||
ip_test.build()
|
||||
print('Stations built')
|
||||
if not ip_test.passes():
|
||||
print(ip_test.get_fail_message())
|
||||
ip_test.exit_fail()
|
||||
print('Starting Stations')
|
||||
ip_test.start(False, False)
|
||||
print('Stopping Stations')
|
||||
ip_test.stop()
|
||||
if not ip_test.passes():
|
||||
print(ip_test.get_fail_message())
|
||||
|
||||
@@ -34,7 +34,7 @@ class IPV4L4(LFCliBase):
|
||||
_debug_on=False,
|
||||
_exit_on_error=False,
|
||||
_exit_on_fail=False):
|
||||
super().__init__(host, port, _debug=_debug_on, _halt_on_error=_exit_on_error, _exit_on_fail=_exit_on_fail)
|
||||
super().__init__(host, port, _debug=_debug_on, _exit_on_fail=_exit_on_fail)
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.ssid = ssid
|
||||
@@ -53,6 +53,7 @@ class IPV4L4(LFCliBase):
|
||||
self.cx_profile = self.local_realm.new_l4_cx_profile()
|
||||
|
||||
self.station_profile.lfclient_url = self.lfclient_url
|
||||
print("##### station_profile.lfclient_url: {}".format(self.station_profile.lfclient_url))
|
||||
self.station_profile.ssid = self.ssid
|
||||
self.station_profile.ssid_pass = self.password,
|
||||
self.station_profile.security = self.security
|
||||
|
||||
@@ -24,15 +24,32 @@ from LANforge import LFUtils
|
||||
import realm
|
||||
import time
|
||||
import datetime
|
||||
from realm import TestGroupProfile
|
||||
|
||||
|
||||
class IPV4L4(LFCliBase):
|
||||
def __init__(self, ssid, security, password, url, requests_per_ten, station_list, host="localhost", port=8080,test_duration="2m",ap=None,mode=0,
|
||||
target_requests_per_ten=60, number_template="00000", num_tests=1, radio="wiphy0",
|
||||
_debug_on=False, upstream_port="eth1",
|
||||
_exit_on_error=False,
|
||||
_exit_on_fail=False):
|
||||
super().__init__(host, port, _debug=_debug_on, _halt_on_error=_exit_on_error, _exit_on_fail=_exit_on_fail)
|
||||
def __init__(self,
|
||||
host="localhost",
|
||||
port=8080,
|
||||
ssid=None,
|
||||
security=None,
|
||||
password=None,
|
||||
url=None,
|
||||
requests_per_ten=None,
|
||||
station_list=None,
|
||||
test_duration="2m",
|
||||
ap=None,
|
||||
mode=0,
|
||||
target_requests_per_ten=60,
|
||||
number_template="00000",
|
||||
num_tests=1,
|
||||
radio="wiphy0",
|
||||
_debug_on=False,
|
||||
upstream_port="eth1",
|
||||
_exit_on_error=False,
|
||||
_exit_on_fail=False):
|
||||
super().__init__(host, port, _debug=_debug_on, _exit_on_fail=_exit_on_fail)
|
||||
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.radio = radio
|
||||
@@ -43,6 +60,7 @@ class IPV4L4(LFCliBase):
|
||||
self.url = url
|
||||
self.mode=mode
|
||||
self.ap=ap
|
||||
self.debug=_debug_on
|
||||
self.requests_per_ten = int(requests_per_ten)
|
||||
self.number_template = number_template
|
||||
self.test_duration=test_duration
|
||||
@@ -51,6 +69,8 @@ class IPV4L4(LFCliBase):
|
||||
self.target_requests_per_ten = int(target_requests_per_ten)
|
||||
|
||||
self.local_realm = realm.Realm(lfclient_host=self.host, lfclient_port=self.port)
|
||||
self.l4cxprofile=realm.L4CXProfile(lfclient_host=host,
|
||||
lfclient_port=port,local_realm=self.local_realm)
|
||||
self.station_profile = self.local_realm.new_station_profile()
|
||||
self.cx_profile = self.local_realm.new_l4_cx_profile()
|
||||
|
||||
@@ -66,21 +86,6 @@ class IPV4L4(LFCliBase):
|
||||
self.cx_profile.url = self.url
|
||||
self.cx_profile.requests_per_ten = self.requests_per_ten
|
||||
|
||||
def __check_request_rate(self):
|
||||
endp_list = self.json_get("layer4/list?fields=urls/s")
|
||||
expected_passes = 0
|
||||
passes = 0
|
||||
if endp_list is not None and endp_list['endpoint'] is not None:
|
||||
endp_list = endp_list['endpoint']
|
||||
for item in endp_list:
|
||||
for name, info in item.items():
|
||||
if name in self.cx_profile.created_cx.keys():
|
||||
expected_passes += 1
|
||||
if info['urls/s'] * self.requests_per_ten >= self.target_requests_per_ten * .9:
|
||||
print(name, info['urls/s'], info['urls/s'] * self.requests_per_ten, self.target_requests_per_ten * .9)
|
||||
passes += 1
|
||||
|
||||
return passes == expected_passes
|
||||
|
||||
def build(self):
|
||||
# Build stations
|
||||
@@ -105,33 +110,8 @@ class IPV4L4(LFCliBase):
|
||||
self._fail("Stations failed to get IPs", print_fail)
|
||||
exit(1)
|
||||
self.cx_profile.start_cx()
|
||||
print("Starting test")
|
||||
curr_time = datetime.datetime.now()
|
||||
end_time = self.local_realm.parse_time(self.test_duration) + curr_time
|
||||
sleep_interval = self.local_realm.parse_time(self.test_duration) // 5
|
||||
passes = 0
|
||||
expected_passes = 0
|
||||
for test in range(self.num_tests):
|
||||
expected_passes += 1
|
||||
while curr_time < end_time:
|
||||
time.sleep(sleep_interval.total_seconds())
|
||||
if self.debug:
|
||||
print(".",end="")
|
||||
curr_time = datetime.datetime.now()
|
||||
|
||||
if self.cx_profile.check_errors(self.debug):
|
||||
if self.__check_request_rate():
|
||||
passes += 1
|
||||
else:
|
||||
self._fail("FAIL: Request rate did not exceed 90% target rate", print_fail)
|
||||
break
|
||||
else:
|
||||
self._fail("FAIL: Errors found getting to %s " % self.url, print_fail)
|
||||
break
|
||||
#interval_time = cur_time + datetime.timedelta(minutes=2)
|
||||
if passes == expected_passes:
|
||||
self._pass("PASS: All tests passes", print_pass)
|
||||
|
||||
print("Starting test...")
|
||||
|
||||
def stop(self):
|
||||
self.cx_profile.stop_cx()
|
||||
self.station_profile.admin_down()
|
||||
@@ -176,12 +156,14 @@ python3 ./test_ipv4_l4_urls_per_ten.py
|
||||
"an" : "10",
|
||||
"bgnAC" : "11",
|
||||
"abgnAX" : "12",
|
||||
"bgnAX" : "13",
|
||||
"bgnAX" : "13"} \\
|
||||
--num_tests 1 \\
|
||||
--url "dl http://10.40.0.1 /dev/null" \\
|
||||
--ap "00:0e:8e:78:e1:76"
|
||||
--target_per_ten 600 \\
|
||||
--test_duration 2m
|
||||
--output_format csv \\
|
||||
--report_file ~/Documents/results.csv \\
|
||||
--test_duration 2m \\
|
||||
--debug
|
||||
''')
|
||||
required = None
|
||||
@@ -203,12 +185,59 @@ python3 ./test_ipv4_l4_urls_per_ten.py
|
||||
optional.add_argument('--target_per_ten', help='--target_per_ten target number of request per ten minutes. test will check for 90 percent this value',default=600)
|
||||
optional.add_argument('--mode',help='Used to force mode of stations')
|
||||
optional.add_argument('--ap',help='Used to force a connection to a particular AP')
|
||||
optional.add_argument('--report_file',help='where you want to store results')
|
||||
optional.add_argument('--output_format', help='choose csv or xlsx') #update once other forms are completed
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
num_sta = 2
|
||||
if (args.num_stations is not None) and (int(args.num_stations) > 0):
|
||||
num_stations_converted = int(args.num_stations)
|
||||
num_sta = num_stations_converted
|
||||
if args.report_file is None:
|
||||
if args.output_format in ['csv','json','html','hdf','stata','pickle','pdf','parquet','png','df','xlsx']:
|
||||
output_form=args.output_format.lower()
|
||||
print("Defaulting file output placement to /home/lanforge.")
|
||||
rpt_file='/home/data.' + output_form
|
||||
else:
|
||||
print("Defaulting data file output type to Excel")
|
||||
rpt_file='/home/lanforge/data.xlsx'
|
||||
output_form='xlsx'
|
||||
|
||||
else:
|
||||
rpt_file=args.report_file
|
||||
if args.output_format is None:
|
||||
output_form=str(args.report_file).split('.')[-1]
|
||||
else:
|
||||
output_form=args.output_format
|
||||
|
||||
|
||||
#Create directory
|
||||
if args.report_file is None:
|
||||
try:
|
||||
homedir = str(datetime.datetime.now().strftime("%Y-%m-%d-%H-%M")).replace(':','-')+'test_ipv4_l4_urls_per_ten'
|
||||
path = os.path.join('/home/lanforge/report-data/',homedir)
|
||||
os.mkdir(path)
|
||||
except:
|
||||
path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
print('Saving file to local directory')
|
||||
else:
|
||||
pass
|
||||
|
||||
if args.report_file is None:
|
||||
if args.output_format in ['csv','json','html','hdf','stata','pickle','pdf','png','df','parquet','xlsx']:
|
||||
rpt_file=path+'/data.' + args.output_format
|
||||
output=args.output_format
|
||||
else:
|
||||
print('Defaulting data file output type to Excel')
|
||||
rpt_file=path+'/data.xlsx'
|
||||
output='xlsx'
|
||||
else:
|
||||
rpt_file=args.report_file
|
||||
if args.output_format is None:
|
||||
output=str(args.report_file).split('.')[-1]
|
||||
else:
|
||||
output=args.output_format
|
||||
|
||||
|
||||
station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=num_sta-1, padding_number_=10000,
|
||||
@@ -224,6 +253,7 @@ python3 ./test_ipv4_l4_urls_per_ten.py
|
||||
url=args.url,
|
||||
mode=args.mode,
|
||||
ap=args.ap,
|
||||
_debug_on=args.debug,
|
||||
test_duration=args.test_duration,
|
||||
num_tests=args.num_tests,
|
||||
target_requests_per_ten=args.target_per_ten,
|
||||
@@ -231,6 +261,19 @@ python3 ./test_ipv4_l4_urls_per_ten.py
|
||||
ip_test.cleanup(station_list)
|
||||
ip_test.build()
|
||||
ip_test.start()
|
||||
|
||||
try:
|
||||
layer4traffic=','.join([[*x.keys()][0] for x in ip_test.local_realm.json_get('layer4')['endpoint']])
|
||||
except:
|
||||
pass
|
||||
ip_test.l4cxprofile.monitor(col_names=['bytes-rd', 'urls/s'],
|
||||
report_file=rpt_file,
|
||||
duration_sec=ip_test.local_realm.parse_time(args.test_duration).total_seconds(),
|
||||
created_cx=layer4traffic,
|
||||
output_format=output_form,
|
||||
script_name='test_ipv4_l4_urls_per_ten',
|
||||
arguments=args,
|
||||
debug=args.debug)
|
||||
ip_test.stop()
|
||||
if not ip_test.passes():
|
||||
print(ip_test.get_fail_message())
|
||||
|
||||
@@ -35,7 +35,7 @@ class IPV4L4(LFCliBase):
|
||||
_debug_on=False,
|
||||
_exit_on_error=False,
|
||||
_exit_on_fail=False):
|
||||
super().__init__(host, port, _debug=_debug_on, _halt_on_error=_exit_on_error, _exit_on_fail=_exit_on_fail)
|
||||
super().__init__(host, port, _debug=_debug_on, _exit_on_fail=_exit_on_fail)
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.radio = radio
|
||||
|
||||
@@ -22,34 +22,37 @@ if 'py-json' not in sys.path:
|
||||
sys.path.append(os.path.join(os.path.abspath('..'), 'py-json'))
|
||||
|
||||
import argparse
|
||||
from LANforge.lfcli_base import LFCliBase
|
||||
from LANforge import LFUtils
|
||||
import realm
|
||||
from realm import Realm
|
||||
import time
|
||||
import datetime
|
||||
from realm import TestGroupProfile
|
||||
|
||||
class IPV4VariableTime(LFCliBase):
|
||||
|
||||
class IPV4VariableTime(Realm):
|
||||
def __init__(self,
|
||||
ssid, security, password, sta_list, name_prefix, upstream, radio,
|
||||
host="localhost", port=8080, mode = 0, ap=None,
|
||||
ssid=None,
|
||||
security=None,
|
||||
password=None,
|
||||
sta_list=[],
|
||||
name_prefix=None,
|
||||
upstream=None,
|
||||
radio=None,
|
||||
host="localhost",
|
||||
port=8080,
|
||||
mode=0,
|
||||
ap=None,
|
||||
traffic_type="lf_udp",
|
||||
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,
|
||||
number_template="00000",
|
||||
test_duration="5m",
|
||||
use_ht160=False,
|
||||
_debug_on=False,
|
||||
_exit_on_error=False,
|
||||
_exit_on_fail=False):
|
||||
super().__init__(host, port,
|
||||
_local_realm = realm.Realm(lfclient_host=host,
|
||||
lfclient_port=port,
|
||||
debug_=_debug_on,
|
||||
halt_on_error_=_exit_on_error),
|
||||
_debug=_debug_on,
|
||||
_halt_on_error=_exit_on_error,
|
||||
_exit_on_fail=_exit_on_fail),
|
||||
self.l3cxprofile = realm.L3CXProfile(lfclient_host=host,
|
||||
lfclient_port=port,
|
||||
local_realm=self.local_realm)
|
||||
super().__init__(lfclient_host=host,
|
||||
lfclient_port=port),
|
||||
self.l3cxprofile = self.new_l3_cx_profile()
|
||||
self.upstream = upstream
|
||||
self.host = host
|
||||
self.port = port
|
||||
@@ -58,28 +61,35 @@ class IPV4VariableTime(LFCliBase):
|
||||
self.security = security
|
||||
self.password = password
|
||||
self.radio = radio
|
||||
self.mode= mode
|
||||
self.ap=ap
|
||||
self.mode = mode
|
||||
self.ap = ap
|
||||
self.traffic_type = traffic_type
|
||||
self.number_template = number_template
|
||||
self.debug = _debug_on
|
||||
# self.json_post("/cli-json/set_resource", {
|
||||
# "shelf":1,
|
||||
# "resource":all,
|
||||
# "max_staged_bringup": 30,
|
||||
# "max_trying_ifup": 15,
|
||||
# "max_station_bringup": 6
|
||||
# })
|
||||
self.name_prefix = name_prefix
|
||||
self.test_duration = test_duration
|
||||
self.station_profile = self.local_realm.new_station_profile()
|
||||
self.cx_profile = self.local_realm.new_l3_cx_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.ssid = self.ssid
|
||||
self.station_profile.ssid_pass = self.password
|
||||
self.station_profile.security = self.security
|
||||
self.station_profile.number_template_ = self.number_template
|
||||
self.station_profile.debug = self.debug
|
||||
|
||||
self.station_profile.use_ht160 = use_ht160
|
||||
if self.station_profile.use_ht160:
|
||||
self.station_profile.mode = 9
|
||||
self.station_profile.mode = mode
|
||||
if self.ap is not None:
|
||||
self.station_profile.set_command_param("add_sta", "ap",self.ap)
|
||||
#self.station_list= LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=2, padding_number_=10000, radio='wiphy0') #Make radio a user defined variable from terminal.
|
||||
|
||||
self.station_profile.set_command_param("add_sta", "ap", self.ap)
|
||||
|
||||
self.cx_profile.host = self.host
|
||||
self.cx_profile.port = self.port
|
||||
@@ -89,33 +99,18 @@ class IPV4VariableTime(LFCliBase):
|
||||
self.cx_profile.side_b_min_bps = side_b_min_rate
|
||||
self.cx_profile.side_b_max_bps = side_b_max_rate
|
||||
|
||||
|
||||
def __get_rx_values(self):
|
||||
cx_list = self.json_get("endp?fields=name,rx+bytes", debug_=self.debug)
|
||||
if self.debug:
|
||||
print(self.cx_profile.created_cx.values())
|
||||
print("==============\n", cx_list, "\n==============")
|
||||
cx_rx_map = {}
|
||||
for cx_name in cx_list['endpoint']:
|
||||
if cx_name != 'uri' and cx_name != 'handler':
|
||||
for item, value in cx_name.items():
|
||||
for value_name, value_rx in value.items():
|
||||
if value_name == 'rx bytes' and item in self.cx_profile.created_cx.values():
|
||||
cx_rx_map[item] = value_rx
|
||||
return cx_rx_map
|
||||
|
||||
def start(self, print_pass=False, print_fail=False):
|
||||
self.station_profile.admin_up()
|
||||
# to-do- check here if upstream port got IP
|
||||
temp_stas = self.station_profile.station_names.copy()
|
||||
|
||||
if self.local_realm.wait_for_ip(temp_stas):
|
||||
if self.wait_for_ip(temp_stas):
|
||||
self._pass("All stations got IPs")
|
||||
else:
|
||||
self._fail("Stations failed to get IPs")
|
||||
self.exit_fail()
|
||||
self.cx_profile.start_cx()
|
||||
|
||||
|
||||
def stop(self):
|
||||
self.cx_profile.stop_cx()
|
||||
self.station_profile.admin_down()
|
||||
@@ -123,7 +118,7 @@ class IPV4VariableTime(LFCliBase):
|
||||
def pre_cleanup(self):
|
||||
self.cx_profile.cleanup_prefix()
|
||||
for sta in self.sta_list:
|
||||
self.local_realm.rm_port(sta, check_exists=True)
|
||||
self.rm_port(sta, check_exists=True)
|
||||
|
||||
def cleanup(self):
|
||||
self.cx_profile.cleanup()
|
||||
@@ -140,17 +135,18 @@ class IPV4VariableTime(LFCliBase):
|
||||
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.cx_profile.create(endp_type="lf_udp", side_a=self.station_profile.station_names, side_b=self.upstream, sleep_time=0)
|
||||
self.cx_profile.create(endp_type=self.traffic_type, side_a=self.station_profile.station_names, side_b=self.upstream,
|
||||
sleep_time=0)
|
||||
self._pass("PASS: Station build finished")
|
||||
|
||||
|
||||
def main():
|
||||
parser = LFCliBase.create_basic_argparse(
|
||||
parser = Realm.create_basic_argparse(
|
||||
prog='test_ipv4_variable_time.py',
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
epilog='''\
|
||||
Create stations to test connection and traffic on VAPs of varying security types (WEP, WPA, WPA2, WPA3, Open)
|
||||
''',
|
||||
|
||||
description='''\
|
||||
test_ipv4_variable_time.py:
|
||||
--------------------
|
||||
@@ -160,7 +156,7 @@ python3 ./test_ipv4_variable_time.py
|
||||
--upstream_port eth1
|
||||
--radio wiphy0
|
||||
--num_stations 32
|
||||
--security {open|wep|wpa|wpa2|wpa3} \\
|
||||
--security {open|wep|wpa|wpa2|wpa3}
|
||||
--mode 1
|
||||
{"auto" : "0",
|
||||
"a" : "1",
|
||||
@@ -179,38 +175,161 @@ python3 ./test_ipv4_variable_time.py
|
||||
--ssid netgear
|
||||
--password admin123
|
||||
--test_duration 2m (default)
|
||||
--a_min 1000
|
||||
--monitor_interval_ms
|
||||
--a_min 3000
|
||||
--b_min 1000
|
||||
--ap "00:0e:8e:78:e1:76"
|
||||
--output_format csv
|
||||
--report_file ~/Documents/results.csv (Example of csv file output - please use another extension for other file formats)
|
||||
--compared_report ~/Documents/results_prev.csv (Example of csv file retrieval - please use another extension for other file formats) - UNDER CONSTRUCTION
|
||||
--layer3_cols 'name','tx bytes','rx bytes','dropped' (column names from the GUI to print on report - please read below to know what to put here according to preferences)
|
||||
--port_mgr_cols 'ap','ip' (column names from the GUI to print on report - please read below to know what to put here according to preferences)
|
||||
--debug
|
||||
===============================================================================
|
||||
** FURTHER INFORMATION **
|
||||
Using the layer3_cols flag:
|
||||
|
||||
Currently the output function does not support inputting the columns in layer3_cols the way they are displayed in the GUI. This quirk is under construction. To output
|
||||
certain columns in the GUI in your final report, please match the according GUI column display to it's counterpart to have the columns correctly displayed in
|
||||
your report.
|
||||
|
||||
GUI Column Display Layer3_cols argument to type in (to print in report)
|
||||
|
||||
Name | 'name'
|
||||
EID | 'eid'
|
||||
Run | 'run'
|
||||
Mng | 'mng'
|
||||
Script | 'script'
|
||||
Tx Rate | 'tx rate'
|
||||
Tx Rate (1 min) | 'tx rate (1 min)'
|
||||
Tx Rate (last) | 'tx rate (last)'
|
||||
Tx Rate LL | 'tx rate ll'
|
||||
Rx Rate | 'rx rate'
|
||||
Rx Rate (1 min) | 'rx rate (1 min)'
|
||||
Rx Rate (last) | 'rx rate (last)'
|
||||
Rx Rate LL | 'rx rate ll'
|
||||
Rx Drop % | 'rx drop %'
|
||||
Tx PDUs | 'tx pdus'
|
||||
Tx Pkts LL | 'tx pkts ll'
|
||||
PDU/s TX | 'pdu/s tx'
|
||||
Pps TX LL | 'pps tx ll'
|
||||
Rx PDUs | 'rx pdus'
|
||||
Rx Pkts LL | 'pps rx ll'
|
||||
PDU/s RX | 'pdu/s tx'
|
||||
Pps RX LL | 'pps rx ll'
|
||||
Delay | 'delay'
|
||||
Dropped | 'dropped'
|
||||
Jitter | 'jitter'
|
||||
Tx Bytes | 'tx bytes'
|
||||
Rx Bytes | 'rx bytes'
|
||||
Replays | 'replays'
|
||||
TCP Rtx | 'tcp rtx'
|
||||
Dup Pkts | 'dup pkts'
|
||||
Rx Dup % | 'rx dup %'
|
||||
OOO Pkts | 'ooo pkts'
|
||||
Rx OOO % | 'rx ooo %'
|
||||
RX Wrong Dev | 'rx wrong dev'
|
||||
CRC Fail | 'crc fail'
|
||||
RX BER | 'rx ber'
|
||||
CX Active | 'cx active'
|
||||
CX Estab/s | 'cx estab/s'
|
||||
1st RX | '1st rx'
|
||||
CX TO | 'cx to'
|
||||
Pattern | 'pattern'
|
||||
Min PDU | 'min pdu'
|
||||
Max PDU | 'max pdu'
|
||||
Min Rate | 'min rate'
|
||||
Max Rate | 'max rate'
|
||||
Send Buf | 'send buf'
|
||||
Rcv Buf | 'rcv buf'
|
||||
CWND | 'cwnd'
|
||||
TCP MSS | 'tcp mss'
|
||||
Bursty | 'bursty'
|
||||
A/B | 'a/b'
|
||||
Elapsed | 'elapsed'
|
||||
Destination Addr | 'destination addr'
|
||||
Source Addr | 'source addr'
|
||||
''')
|
||||
|
||||
required_args=None
|
||||
for group in parser._action_groups:
|
||||
if group.title == "required arguments":
|
||||
required_args=group
|
||||
break
|
||||
if required_args is not None:
|
||||
required_args.add_argument('--a_min', help='--a_min bps rate minimum for side_a', default=256000)
|
||||
required_args.add_argument('--b_min', help='--b_min bps rate minimum for side_b', default=256000)
|
||||
required_args.add_argument('--test_duration', help='--test_duration sets the duration of the test', default="2m")
|
||||
optional_args=None
|
||||
for group in parser._action_groups:
|
||||
if group.title == "optional arguments":
|
||||
optional_args=group
|
||||
break
|
||||
if optional_args is not None:
|
||||
optional_args.add_argument('--mode',help='Used to force mode of stations')
|
||||
optional_args.add_argument('--ap',help='Used to force a connection to a particular AP')
|
||||
optional_args.add_argument('--report_file',help='where you want to store results')
|
||||
optional_args.add_argument('--output_format', help='choose either csv or xlsx')
|
||||
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('--traffic_type', help='Select the Traffic Type [lf_udp, lf_tcp]')
|
||||
parser.add_argument('--output_format', help='choose either csv or xlsx')
|
||||
parser.add_argument('--report_file', help='where you want to store results', default=None)
|
||||
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('--test_duration', help='--test_duration sets the duration of the test', default="2m")
|
||||
parser.add_argument('--layer3_cols', help='Columns wished to be monitored from layer 3 endpoint tab',
|
||||
default=['name', 'tx bytes', 'rx bytes', 'tx rate', 'rx rate'])
|
||||
parser.add_argument('--port_mgr_cols', help='Columns wished to be monitored from port manager tab',
|
||||
default=['ap', 'ip', 'parent dev'])
|
||||
parser.add_argument('--compared_report', help='report path and file which is wished to be compared with new report',
|
||||
default=None)
|
||||
parser.add_argument('--monitor_interval',
|
||||
help='how frequently do you want your monitor function to take measurements; 250ms, 35s, 2h',
|
||||
default='10s')
|
||||
parser.add_argument('--influx_token', help='Username for your Influx database')
|
||||
parser.add_argument('--influx_bucket', help='Password for your Influx database')
|
||||
parser.add_argument('--influx_org', help='Name of your Influx database')
|
||||
parser.add_argument('--influx_port', help='Port where your influx database is located', default=8086)
|
||||
parser.add_argument('--influx_tag', action='append', nargs=2, help='--influx_tag <key> <val> Can add more than one of these.')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
num_sta = 2
|
||||
if (args.num_stations is not None) and (int(args.num_stations) > 0):
|
||||
num_sta = int(args.num_stations)
|
||||
|
||||
station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=num_sta-1, padding_number_=10000, radio=args.radio)
|
||||
# Create directory
|
||||
|
||||
# if file path with output file extension is not given...
|
||||
# check if home/lanforge/report-data exists. if not, save
|
||||
# in new folder based in current file's directory
|
||||
|
||||
if args.report_file is None:
|
||||
new_file_path = str(datetime.datetime.now().strftime("%Y-%m-%d-%H-h-%M-m-%S-s")).replace(':',
|
||||
'-') + '_test_ipv4_variable_time' # create path name
|
||||
try:
|
||||
path = os.path.join('/home/lanforge/report-data/', new_file_path)
|
||||
os.mkdir(path)
|
||||
except:
|
||||
curr_dir_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
path = os.path.join(curr_dir_path, new_file_path)
|
||||
os.mkdir(path)
|
||||
systeminfopath = str(path) + '/systeminfo.txt'
|
||||
|
||||
if args.output_format in ['csv', 'json', 'html', 'hdf', 'stata', 'pickle', 'pdf', 'png', 'parquet',
|
||||
'xlsx']:
|
||||
report_f = str(path) + '/data.' + args.output_format
|
||||
output = args.output_format
|
||||
else:
|
||||
print(
|
||||
'Not supporting this report format or cannot find report format provided. Defaulting to csv data file output type, naming it data.csv.')
|
||||
report_f = str(path) + '/data.csv'
|
||||
output = 'csv'
|
||||
|
||||
else:
|
||||
systeminfopath = str(args.report_file).split('/')[-1]
|
||||
report_f = args.report_file
|
||||
if args.output_format is None:
|
||||
output = str(args.report_file).split('.')[-1]
|
||||
else:
|
||||
output = args.output_format
|
||||
print("IPv4 Test Report Data: {}".format(report_f))
|
||||
|
||||
# Retrieve last data file
|
||||
compared_rept = None
|
||||
if args.compared_report:
|
||||
compared_report_format = args.compared_report.split('.')[-1]
|
||||
# if compared_report_format not in ['csv', 'json', 'dta', 'pkl','html','xlsx','parquet','h5']:
|
||||
if compared_report_format != 'csv':
|
||||
print(ValueError("Cannot process this file type. Please select a different file and re-run script."))
|
||||
exit(1)
|
||||
else:
|
||||
compared_rept = args.compared_report
|
||||
|
||||
station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=num_sta - 1, padding_number_=10000,
|
||||
radio=args.radio)
|
||||
ip_var_test = IPV4VariableTime(host=args.mgr,
|
||||
port=args.mgr_port,
|
||||
number_template="0000",
|
||||
@@ -227,6 +346,7 @@ python3 ./test_ipv4_variable_time.py
|
||||
side_b_min_rate=args.b_min,
|
||||
mode=args.mode,
|
||||
ap=args.ap,
|
||||
traffic_type=args.traffic_type,
|
||||
_debug_on=args.debug)
|
||||
|
||||
ip_var_test.pre_cleanup()
|
||||
@@ -234,41 +354,90 @@ python3 ./test_ipv4_variable_time.py
|
||||
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')
|
||||
|
||||
if type(args.layer3_cols) is not list:
|
||||
layer3_cols = list(args.layer3_cols.split(","))
|
||||
# send col names here to file to reformat
|
||||
else:
|
||||
layer3_cols = args.layer3_cols
|
||||
# send col names here to file to reformat
|
||||
if type(args.port_mgr_cols) is not list:
|
||||
port_mgr_cols = list(args.port_mgr_cols.split(","))
|
||||
# send col names here to file to reformat
|
||||
else:
|
||||
port_mgr_cols = args.port_mgr_cols
|
||||
# send col names here to file to reformat
|
||||
if args.debug:
|
||||
print("Layer 3 Endp column names are...")
|
||||
print(layer3_cols)
|
||||
print("Port Manager column names are...")
|
||||
print(port_mgr_cols)
|
||||
|
||||
print("Layer 3 Endp column names are...")
|
||||
print(layer3_cols)
|
||||
print("Port Manager column names are...")
|
||||
print(port_mgr_cols)
|
||||
|
||||
try:
|
||||
monitor_interval = Realm.parse_time(args.monitor_interval).total_seconds()
|
||||
except ValueError as error:
|
||||
print(str(error))
|
||||
print(ValueError(
|
||||
"The time string provided for monitor_interval argument is invalid. Please see supported time stamp increments and inputs for monitor_interval in --help. "))
|
||||
exit(1)
|
||||
ip_var_test.start(False, False)
|
||||
|
||||
if args.report_file is None:
|
||||
if args.output_format in ['csv','json','html','hdf','stata','pickle','pdf','parquet']:
|
||||
report_f='/home/lanforge/report-data/'+str(datetime.datetime.now()).replace(':','-')+'test_ipv4_variable_time.' + args.output_format
|
||||
output=args.output_format
|
||||
else:
|
||||
print('Defaulting to Excel')
|
||||
report_f='/home/lanforge/report-data/'+str(datetime.datetime.now()).replace(':','-')+'test_ipv4_variable_time.xlsx'
|
||||
output='excel'
|
||||
if args.influx_org is not None:
|
||||
from influx2 import RecordInflux
|
||||
grapher = RecordInflux(_influx_host=args.mgr,
|
||||
_influx_port=args.influx_port,
|
||||
_influx_org=args.influx_org,
|
||||
_influx_token=args.influx_token,
|
||||
_influx_bucket=args.influx_bucket)
|
||||
devices=[station.split('.')[-1] for station in station_list]
|
||||
tags=dict()
|
||||
tags['script']='test_ipv4_variable_time'
|
||||
try:
|
||||
for k in args.influx_tag:
|
||||
tags[k[0]] = k[1]
|
||||
except:
|
||||
pass
|
||||
grapher.monitor_port_data(longevity=Realm.parse_time(args.test_duration).total_seconds(),
|
||||
devices=devices,
|
||||
monitor_interval=Realm.parse_time(args.monitor_interval).total_seconds(),
|
||||
tags=tags)
|
||||
else:
|
||||
report_f=args.report_file
|
||||
if args.output_format is None:
|
||||
output=str(args.report_file).split('.')[-1]
|
||||
else:
|
||||
output=args.output_format
|
||||
ip_var_test.l3cxprofile.monitor(layer3_cols=layer3_cols,
|
||||
sta_list=station_list,
|
||||
# port_mgr_cols=port_mgr_cols,
|
||||
report_file=report_f,
|
||||
systeminfopath=systeminfopath,
|
||||
duration_sec=Realm.parse_time(args.test_duration).total_seconds(),
|
||||
monitor_interval_ms=monitor_interval,
|
||||
created_cx=layer3connections,
|
||||
output_format=output,
|
||||
compared_report=compared_rept,
|
||||
script_name='test_ipv4_variable_time',
|
||||
arguments=args,
|
||||
debug=args.debug)
|
||||
|
||||
layer3connections=','.join([[*x.keys()][0] for x in ip_var_test.l3cxprofile.json_get('endp')['endpoint']])
|
||||
ip_var_test.l3cxprofile.monitor(col_names=['Name','Tx Rate','Rx Rate','Tx PDUs','Rx PDUs'],
|
||||
report_file=report_f,
|
||||
duration_sec=ip_var_test.local_realm.parse_time(args.test_duration).seconds,
|
||||
created_cx= layer3connections,
|
||||
output_format=output,
|
||||
script_name='test_ipv4_variable_time',
|
||||
arguments=args)
|
||||
ip_var_test.stop()
|
||||
if not ip_var_test.passes():
|
||||
print(ip_var_test.get_fail_message())
|
||||
ip_var_test.exit_fail()
|
||||
time.sleep(30)
|
||||
LFUtils.wait_until_ports_admin_up(port_list=station_list)
|
||||
|
||||
ip_var_test.cleanup()
|
||||
if ip_var_test.passes():
|
||||
ip_var_test.exit_success()
|
||||
ip_var_test.success()
|
||||
|
||||
print("IPv4 Variable Time Test Report Data: {}".format(report_f))
|
||||
|
||||
IPV4VariableTime.cx_profile.stop_cx()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -34,7 +34,7 @@ class IPv6Test(LFCliBase):
|
||||
_exit_on_error=False,
|
||||
_exit_on_fail=False,
|
||||
number_template="00"):
|
||||
super().__init__(host, port, _debug=_debug_on, _halt_on_error=_exit_on_error, _exit_on_fail=_exit_on_fail)
|
||||
super().__init__(host, port, _debug=_debug_on, _exit_on_fail=_exit_on_fail)
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.ssid = ssid
|
||||
@@ -98,8 +98,7 @@ class IPv6Test(LFCliBase):
|
||||
not sta_status['interface']['ipv6 address'].startswith('fe80') \
|
||||
and sta_status['interface']['ipv6 address'] != 'AUTO':
|
||||
if self.debug:
|
||||
|
||||
print("IP", sta_name, sta_status['interface']['ap'], sta_status['interface']['ip'])
|
||||
print("IPv6 address:", sta_name, sta_status['interface']['ap'], sta_status['interface']['ipv6 address'])
|
||||
ip_map[sta_name] = 1
|
||||
if (len(sta_list) == len(ip_map)) and (len(sta_list) == len(associated_map)):
|
||||
break
|
||||
|
||||
@@ -59,7 +59,6 @@ class IPV6VariableTime(LFCliBase):
|
||||
_exit_on_error=_exit_on_error,
|
||||
_exit_on_fail=_exit_on_fail),
|
||||
_debug=_debug_on,
|
||||
_halt_on_error=_exit_on_error,
|
||||
_exit_on_fail=_exit_on_fail)
|
||||
self.upstream = _upstream
|
||||
self.ssid = _ssid
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,6 +14,7 @@ import argparse
|
||||
from LANforge.lfcli_base import LFCliBase
|
||||
from LANforge.LFUtils import *
|
||||
from LANforge import LFUtils
|
||||
import l3_cxprofile
|
||||
import realm
|
||||
import time
|
||||
import datetime
|
||||
@@ -26,7 +27,7 @@ class L3PowersaveTraffic(LFCliBase):
|
||||
side_a_max_rate=0,
|
||||
side_b_max_rate=0, pdu_size=1000, prefix="00000", test_duration="5m",
|
||||
_debug_on=False, _exit_on_error=False, _exit_on_fail=False):
|
||||
super().__init__(host, port, _debug=_debug_on, _halt_on_error=_exit_on_error, _exit_on_fail=_exit_on_fail)
|
||||
super().__init__(host, port, _debug=_debug_on, _exit_on_fail=_exit_on_fail)
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.ssid = ssid
|
||||
@@ -35,17 +36,16 @@ class L3PowersaveTraffic(LFCliBase):
|
||||
self.sta_list = station_list
|
||||
self.prefix = prefix
|
||||
self.debug = _debug_on
|
||||
self.local_realm = realm.Realm(lfclient_host=self.host, lfclient_port=self.port, debug_=False,
|
||||
halt_on_error_=True)
|
||||
self.local_realm = realm.Realm(lfclient_host=self.host, lfclient_port=self.port, debug_=False)
|
||||
# upload
|
||||
self.cx_prof_upload = realm.L3CXProfile(self.host, self.port, self.local_realm,
|
||||
self.cx_prof_upload = l3_cxprofile.L3CXProfile(self.host, self.port, self.local_realm,
|
||||
side_a_min_bps=side_a_min_rate, side_b_min_bps=0,
|
||||
side_a_max_bps=side_a_max_rate, side_b_max_bps=0,
|
||||
side_a_min_pdu=pdu_size, side_a_max_pdu=pdu_size,
|
||||
side_b_min_pdu=0, side_b_max_pdu=0, debug_=False)
|
||||
|
||||
# download
|
||||
self.cx_prof_download = realm.L3CXProfile(self.host, self.port, self.local_realm,
|
||||
self.cx_prof_download = l3_cxprofile.L3CXProfile(self.host, self.port, self.local_realm,
|
||||
side_a_min_bps=0, side_b_min_bps=side_b_min_rate,
|
||||
side_a_max_bps=0, side_b_max_bps=side_b_max_rate,
|
||||
side_a_min_pdu=0, side_a_max_pdu=0,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
'''
|
||||
|
||||
This Script Loads the Existing Scenario and Run the Simultaenous Throughput over time and Generate Report and Plot the Graph
|
||||
This Scrip has three classes :
|
||||
This Script has three classes :
|
||||
1. LoadScenario : It will load the existing saved scenario to the Lanforge (Here used for Loading Bridged VAP)
|
||||
2. FindPorts : Fetch the L3CX Throughput and VAP Throughput
|
||||
3. Login_DUT : This class is specifically used to test the Linux based DUT that has SSH Server. It is used to read the CPU Core temperature during testing
|
||||
@@ -45,7 +45,7 @@ import realm
|
||||
from realm import Realm
|
||||
import logging
|
||||
|
||||
import paramiko as pm
|
||||
import paramiko as pmgo
|
||||
from paramiko.ssh_exception import NoValidConnectionsError as exception
|
||||
import xlsxwriter
|
||||
from bokeh.io import output_file, show
|
||||
@@ -65,7 +65,7 @@ class Login_DUT:
|
||||
self.host=HOST
|
||||
self.USERNAME = "lanforge"
|
||||
self.PASSWORD = "lanforge"
|
||||
self.CLIENT= pm.SSHClient()
|
||||
self.CLIENT= pmgo.SSHClient()
|
||||
self.LF1= self.Connect()
|
||||
self.data_core1=[]
|
||||
self.data_core2=[]
|
||||
@@ -83,7 +83,7 @@ class Login_DUT:
|
||||
|
||||
def Connect(self):
|
||||
self.CLIENT.load_system_host_keys()
|
||||
self.CLIENT.set_missing_host_key_policy(pm.AutoAddPolicy())
|
||||
self.CLIENT.set_missing_host_key_policy(pmgo.AutoAddPolicy())
|
||||
try:
|
||||
self.CLIENT.connect(self.host, username=self.USERNAME, password=self.PASSWORD,timeout=10)
|
||||
return None
|
||||
@@ -282,7 +282,7 @@ def main():
|
||||
parser.add_argument("-m", "--manager", type=str, help="Enter the address of Lanforge Manager (By default localhost)")
|
||||
parser.add_argument("-sc", "--scenario", type=str, help="Enter the Name of the Scenario you want to load (by Default DFLT)")
|
||||
|
||||
parser.add_argument("-t", "--duration", type=int, help="Enter the Time for which you want to run test (In Minutes)")
|
||||
parser.add_argument("-t", "--duration", type=str, help="Enter the Time for which you want to run test")
|
||||
parser.add_argument("-o", "--report_name", type=str, help="Enter the Name of the Output file ('Report.xlsx')")
|
||||
parser.add_argument("-td", "--test_detail", type=str, help="Enter the Test Detail in Quotes ")
|
||||
|
||||
@@ -297,8 +297,6 @@ def main():
|
||||
manager = args.manager
|
||||
if (args.scenario is not None):
|
||||
scenario = args.scenario
|
||||
if (args.duration is not None):
|
||||
duration = (args.duration * 60)/5
|
||||
if (args.report_name is not None):
|
||||
report_name = args.report_name
|
||||
if (args.duration is None):
|
||||
@@ -324,9 +322,10 @@ def main():
|
||||
Scenario_2 = LoadScenario(manager, 8080, scenario)
|
||||
#Wait for Sometime
|
||||
time.sleep(10)
|
||||
duration_sec=Realm.parse_time(args.duration).total_seconds() * 60
|
||||
|
||||
# Port Utility function for reading CX and VAP
|
||||
PortUtility(manager,8080, duration, report_name, scenario, test_detail)
|
||||
PortUtility(manager,8080, duration_sec, report_name, scenario, test_detail)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ if 'py-json' not in sys.path:
|
||||
|
||||
import argparse
|
||||
from LANforge.lfcli_base import LFCliBase
|
||||
import time
|
||||
# import time
|
||||
from uuid import uuid1
|
||||
import pprint
|
||||
from pprint import pprint
|
||||
@@ -23,7 +23,7 @@ class TestStatusMessage(LFCliBase):
|
||||
_debug_on=False,
|
||||
_exit_on_error=False,
|
||||
_exit_on_fail=False):
|
||||
super().__init__(host, port, _debug=_debug_on, _halt_on_error=_exit_on_error, _exit_on_fail=_exit_on_fail)
|
||||
super().__init__(host, port, _debug=_debug_on, _exit_on_fail=_exit_on_fail)
|
||||
self.deep_clean = _deep_clean
|
||||
self.check_connect()
|
||||
|
||||
@@ -167,7 +167,6 @@ class TestStatusMessage(LFCliBase):
|
||||
if self.debug:
|
||||
print("--- del -------------------- -------------------- --------------------")
|
||||
self.exit_on_error=False
|
||||
self.halt_on_error=False
|
||||
message_response = self.json_delete(self.session_url, debug_=False)
|
||||
if self.debug:
|
||||
print("--- ~del -------------------- -------------------- --------------------")
|
||||
@@ -195,7 +194,6 @@ class TestStatusMessage(LFCliBase):
|
||||
if self.debug:
|
||||
print("--- del -------------------- -------------------- --------------------")
|
||||
self.exit_on_error=False
|
||||
self.halt_on_error=False
|
||||
message_response = self.json_delete(self.session_url+"/this", debug_=False)
|
||||
if self.debug:
|
||||
print("--- ~del -------------------- -------------------- --------------------")
|
||||
@@ -275,9 +273,9 @@ Actions can be:
|
||||
if args.session is not None:
|
||||
status_messages.json_put("/status-msg/"+args.session, {})
|
||||
else:
|
||||
u = uuid1()
|
||||
status_messages.json_put("/status-msg/"+u, {})
|
||||
print("created session /status-msg/"+u)
|
||||
a_uuid = uuid1()
|
||||
status_messages.json_put("/status-msg/"+str(a_uuid), {})
|
||||
print("created session /status-msg/"+str(a_uuid))
|
||||
return
|
||||
|
||||
if args.action == "update":
|
||||
@@ -310,7 +308,10 @@ Actions can be:
|
||||
if args.session is None:
|
||||
print("requires --session")
|
||||
return
|
||||
response_o = status_messages.json_get("/status-msg/"+args.session)
|
||||
if args.key is None:
|
||||
print("requires --key")
|
||||
return
|
||||
response_o = status_messages.json_get("/status-msg/%s/%s"%(args.session, args.key))
|
||||
pprint(response_o)
|
||||
return
|
||||
|
||||
|
||||
@@ -1,302 +0,0 @@
|
||||
|
||||
"""
|
||||
Candela Technologies Inc.
|
||||
|
||||
Info : Standard Script for Webconsole Test Utility
|
||||
Date :
|
||||
|
||||
|
||||
"""
|
||||
|
||||
import sys
|
||||
if 'py-json' not in sys.path:
|
||||
sys.path.append('../py-json')
|
||||
from LANforge import LFUtils
|
||||
from LANforge import lfcli_base
|
||||
from LANforge.lfcli_base import LFCliBase
|
||||
from LANforge.LFUtils import *
|
||||
import realm
|
||||
from realm import PortUtils
|
||||
import argparse
|
||||
import datetime
|
||||
import time
|
||||
import matplotlib.pyplot as plt
|
||||
import threading
|
||||
import re
|
||||
import json
|
||||
import os
|
||||
webconsole_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.getcwd())))
|
||||
updates_path = webconsole_dir + "/web_json/updates.js"
|
||||
|
||||
|
||||
class ClientVisualization(LFCliBase, threading.Thread):
|
||||
def __init__(self, lfclient_host="localhost", lfclient_port=8080, num_clients= 64, max_data= 120, thread_id=None, _debug_on=False, _exit_on_error=False, _exit_on_fail=False):
|
||||
super().__init__(lfclient_host, lfclient_port, _debug=_debug_on, _halt_on_error=_exit_on_error,
|
||||
_exit_on_fail=_exit_on_fail)
|
||||
threading.Thread.__init__(self)
|
||||
self.num_clients = num_clients
|
||||
self.max_data = max_data
|
||||
self._stop_event = threading.Event()
|
||||
self.client_data = {"down":[], "phantom":[], "ip":[], "scanning":[]}
|
||||
|
||||
def stop(self):
|
||||
self._stop_event.set()
|
||||
|
||||
def stopped(self):
|
||||
return self._stop_event.is_set()
|
||||
|
||||
def run(self):
|
||||
self.start_thread()
|
||||
|
||||
def start_thread(self):
|
||||
while True:
|
||||
self.scanning = 0
|
||||
self.ip = 0
|
||||
self.down = 0
|
||||
self.phantom = 0
|
||||
for i in self.json_get("/port/list?fields=port,alias,parent%20dev,down,phantom,ip,port%20type")['interfaces']:
|
||||
|
||||
for j in i:
|
||||
print(i[j]['port type'])
|
||||
if i[j]['port type'] == "WIFI-STA" and i[j]['parent dev'] == "wiphy1" and i[j]['alias'] != 'wlan1':
|
||||
#print(j)
|
||||
if i[j]['down'] == False and i[j]['phantom'] == False and i[j]['ip'] == '0.0.0.0':
|
||||
self.scanning += 1
|
||||
elif i[j]['down'] == False and i[j]['phantom'] == True:
|
||||
self.phantom += 1
|
||||
elif i[j]['down'] == True and i[j]['phantom'] == True:
|
||||
self.phantom += 1
|
||||
self.client_data['phantom'].append(self.phantom)
|
||||
elif i[j]['down'] == True and i[j]['phantom'] == False:
|
||||
self.down += 1
|
||||
elif i[j]['ip'] != "0.0.0.0":
|
||||
self.ip += 1
|
||||
else:
|
||||
continue
|
||||
self.client_data['scanning'].append(self.scanning)
|
||||
self.client_data['phantom'].append(self.phantom)
|
||||
self.client_data['down'].append(self.down)
|
||||
self.client_data['ip'].append(self.ip)
|
||||
|
||||
|
||||
for i in self.client_data:
|
||||
if len(self.client_data[i]) >= self.max_data:
|
||||
self.client_data[i].pop(0)
|
||||
time.sleep(1)
|
||||
if self.stopped():
|
||||
break
|
||||
|
||||
|
||||
class CreateHTML():
|
||||
def __init__(self, path="", test_name="", time_snap="", dut_ssid="", test_conf_data={}, objective="", test_results={}, chart_data={}, chart_params={}):
|
||||
self.head = """
|
||||
<html>
|
||||
<head>
|
||||
<title>"""+test_name+"""</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class='Section report_banner-1000x205' style='background-image:url("../../assets/brand/banner.jpg");background-repeat:no-repeat;padding:0;margin:0;min-width:1000px; min-height:205px;width:1000px; height:205px;max-width:1000px; max-height:205px;'>
|
||||
<img align='right' style='padding:25;margin:5;width:200px;' src="../../assets/brand/logo.png" border='0' />
|
||||
<div class='HeaderStyle'>
|
||||
<br>
|
||||
<h1 class='TitleFontPrint' style='color:darkgreen;'>"""+test_name+"""</h1>
|
||||
<h3 class='TitleFontPrint' style="color:darkgreen;">"""+time_snap+"""</h3>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
"""
|
||||
self.test_conf = """
|
||||
<table width="700px" border="1" cellpadding="2" cellspacing="0" style="border-top-color: gray; border-top-style: solid; border-top-width: 1px; border-right-color: gray; border-right-style: solid; border-right-width: 1px; border-bottom-color: gray; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: gray; border-left-style: solid; border-left-width: 1px">
|
||||
<tr>
|
||||
<th colspan="2">
|
||||
Test Setup Information
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Device Under Test
|
||||
</td>
|
||||
<td>
|
||||
<table width="100%" border="0" cellpadding="2" cellspacing="0" style="border-top-color: gray; border-top-style: solid; border-top-width: 1px; border-right-color: gray; border-right-style: solid; border-right-width: 1px; border-bottom-color: gray; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: gray; border-left-style: solid; border-left-width: 1px">
|
||||
<tr>
|
||||
<td>
|
||||
SSID
|
||||
</td>
|
||||
<td colspan="3">"""+dut_ssid+"""
|
||||
</td>
|
||||
</tr>
|
||||
"""
|
||||
|
||||
for i in test_conf_data:
|
||||
self.test_conf = self.test_conf + """<tr>
|
||||
<td>"""+str(i)+"""
|
||||
</td>
|
||||
<td colspan="3">"""+test_conf_data[i]+"""
|
||||
</td>
|
||||
</tr>
|
||||
"""
|
||||
|
||||
self.test_conf = self.test_conf + """ </table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
"""
|
||||
|
||||
self.objective = """
|
||||
<br><h2 align="left">Objective</h2> <p align="left" width="900">
|
||||
"""+objective+"""
|
||||
</p>
|
||||
<br>
|
||||
"""
|
||||
|
||||
if str(test_results['summary']).__contains__("PASS"):
|
||||
self.summary_results ="""
|
||||
<br>
|
||||
<table width="700px" border="1" cellpadding="2" cellspacing="0" style="border-top-color: gray; border-top-style: solid; border-top-width: 1px; border-right-color: gray; border-right-style: solid; border-right-width: 1px; border-bottom-color: gray; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: gray; border-left-style: solid; border-left-width: 1px">
|
||||
<tr>
|
||||
<th colspan="2">
|
||||
Summary Results
|
||||
</th>
|
||||
</tr>
|
||||
<tr align='center' bgcolor="#90EE90">
|
||||
<td>
|
||||
""" + test_results['summary'] + """
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
"""
|
||||
else:
|
||||
self.summary_results = """
|
||||
<br>
|
||||
<table width="700px" border="1" cellpadding="2" cellspacing="0" style="border-top-color: gray; border-top-style: solid; border-top-width: 1px; border-right-color: gray; border-right-style: solid; border-right-width: 1px; border-bottom-color: gray; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: gray; border-left-style: solid; border-left-width: 1px">
|
||||
<tr>
|
||||
<th colspan="2">
|
||||
Summary Results
|
||||
</th>
|
||||
</tr>
|
||||
<tr align='center' bgcolor="orange">
|
||||
<td>
|
||||
""" + test_results['summary'] + """
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
"""
|
||||
chart_d =[]
|
||||
chart_label =[]
|
||||
for i in chart_data:
|
||||
chart_label.append(i)
|
||||
chart_d.append(chart_data[i])
|
||||
|
||||
|
||||
|
||||
|
||||
self.detail_result = """<table width="1000px" border="1" cellpadding="2" cellspacing="0" >
|
||||
<tr><th colspan="2">Detailed Results</th></tr>
|
||||
<table width="1000px" border="1" >
|
||||
<tr>
|
||||
"""
|
||||
for index in test_results['detail']['keys']:
|
||||
self.detail_result = self.detail_result+"<th colspan='2'>"+index+"</th>"
|
||||
self.detail_result = self.detail_result +"</tr>"
|
||||
|
||||
for data in test_results['detail']['data']:
|
||||
self.detail_result = self.detail_result + "<tr align='center'>"
|
||||
print("shivam")
|
||||
print(data)
|
||||
for i in data:
|
||||
print(data[i])
|
||||
if str(data[i]).__contains__("PASS"):
|
||||
self.detail_result = self.detail_result + "<th colspan='2' bgcolor='#90EE90'>" + str(data[i]) + "</th>"
|
||||
elif str(data[i]).__contains__("FAIL"):
|
||||
self.detail_result = self.detail_result + "<th colspan='2' bgcolor='orange'>" + str(data[i]) + "</th>"
|
||||
else:
|
||||
self.detail_result = self.detail_result + "<th colspan='2'>" + str(data[i]) + "</th>"
|
||||
self.detail_result = self.detail_result +"</tr>"
|
||||
|
||||
self.chart_data = chart_data
|
||||
chart_values = []
|
||||
for i in self.chart_data:
|
||||
chart_values.append(self.chart_data[i])
|
||||
plt.bar(list(self.chart_data.keys()), chart_values, tick_label=list(self.chart_data.keys()))
|
||||
|
||||
plt.xlabel(chart_params['xlabel'])
|
||||
# naming the y-axis
|
||||
plt.ylabel(chart_params['ylabel'])
|
||||
# plot title
|
||||
plt.title(chart_params['chart_head'])
|
||||
plt.xticks(rotation=90, fontsize=8)
|
||||
plt.tight_layout()
|
||||
# function to show the plot
|
||||
plt.savefig(fname=path + "plot.png")
|
||||
plt.close()
|
||||
|
||||
self.chart = """<img align='center' style='padding:25;margin:5;width:600px;' src="plot.png" border='0' />"""
|
||||
|
||||
|
||||
self.end = """</table>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
self.report = self.head + self.test_conf + self.objective + self.summary_results + self.chart +self.detail_result + self.end
|
||||
|
||||
|
||||
|
||||
class RuntimeUpdates():
|
||||
def __init__(self, session_id, init_data):
|
||||
self.session_id = session_id
|
||||
self.init_data = init_data
|
||||
f = open(updates_path, 'r+')
|
||||
data = f.read()
|
||||
f.close()
|
||||
obj = data[data.find('{'): data.rfind('}') + 1]
|
||||
obj = re.sub('[\']', '"', obj)
|
||||
data = json.loads(obj)
|
||||
print(data)
|
||||
data["web_updates"].append({"ID": self.session_id, "data": self.init_data})
|
||||
print(data)
|
||||
f = open(updates_path, 'r+')
|
||||
f.seek(0)
|
||||
f.truncate()
|
||||
f.write("var updates = " + str(data) + ";")
|
||||
f.close()
|
||||
|
||||
def send_update(self, update_data):
|
||||
f = open(updates_path, 'r+')
|
||||
data = f.read()
|
||||
f.close()
|
||||
obj = data[data.find('{'): data.rfind('}') + 1]
|
||||
obj = re.sub('[\']', '"', obj)
|
||||
data = json.loads(obj)
|
||||
|
||||
for update in data["web_updates"]:
|
||||
if update["ID"] == self.session_id:
|
||||
update["data"] = update_data
|
||||
print(data)
|
||||
f = open(updates_path, 'r+')
|
||||
f.seek(0)
|
||||
f.truncate()
|
||||
f.write("var updates = " + str(data) + ";")
|
||||
f.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
thread1 = ClientVisualization(lfclient_host="192.168.200.15", thread_id=1)
|
||||
thread1.start()
|
||||
for i in range(0, 100):
|
||||
time.sleep(1)
|
||||
#print(thread1.client_data)
|
||||
thread1.stop()
|
||||
# obj = RuntimeUpdates("1", {"test_status": 1, "data": "None"})
|
||||
# for i in range(0, 10):
|
||||
# time.sleep(3)
|
||||
# print(i)
|
||||
# obj.send_update({"test_status": i, "data": "None"})
|
||||
# thread1 = ClientVisualization(lfclient_host="192.168.200.15", thread_id=1)
|
||||
# thread1.start()
|
||||
# for i in range(30):
|
||||
# print(thread1.client_data)
|
||||
# thread1.stop()
|
||||
|
||||
@@ -12,29 +12,46 @@ if 'py-json' not in sys.path:
|
||||
import argparse
|
||||
from LANforge.lfcli_base import LFCliBase
|
||||
from LANforge.LFUtils import *
|
||||
import realm
|
||||
from realm import Realm
|
||||
import time
|
||||
import create_wanlink
|
||||
|
||||
class LANtoWAN(LFCliBase):
|
||||
def __init__(self, host, port, ssid, security, password, lan_port="eth2", wan_port="eth3", _debug_on=False,
|
||||
class LANtoWAN(Realm):
|
||||
def __init__(self, host, port, ssid, security, password,
|
||||
lan_port="eth2",
|
||||
wan_port="eth3",
|
||||
prefix='sta',
|
||||
number_template="00000",
|
||||
radio="wiphy0",
|
||||
sta_list = [],
|
||||
side_a_min_rate=56, side_a_max_rate=0,
|
||||
side_b_min_rate=56, side_b_max_rate=0,
|
||||
upstream = None,
|
||||
_debug_on=False,
|
||||
_exit_on_error=False,
|
||||
_exit_on_fail=False):
|
||||
super().__init__(host, port, _debug=_debug_on, _halt_on_error=_exit_on_error, _exit_on_fail=_exit_on_fail)
|
||||
super().__init__(host, port)
|
||||
self.upstream = upstream
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.ssid = ssid
|
||||
self.radio = radio
|
||||
self.sta_list = sta_list
|
||||
self.security = security
|
||||
self.password = password
|
||||
self.timeout = 120
|
||||
self.lan_port = lan_port
|
||||
self.wan_port = wan_port
|
||||
self.local_realm = realm.Realm(lfclient_host=self.host, lfclient_port=self.port)
|
||||
self.profile = realm.StationProfile(self.lfclient_url, ssid=self.ssid, ssid_pass=self.password,
|
||||
security=self.security, number_template_=self.prefix, mode=0, up=True, dhcp=True,
|
||||
debug_=False)
|
||||
self.cxProfile = realm.new_l3_cx_profile()
|
||||
self.prefix = prefix
|
||||
self.number_template = number_template
|
||||
self.station_profile = self.new_station_profile()
|
||||
self.cx_profile = self.new_l3_cx_profile()
|
||||
|
||||
def run_test(self): pass
|
||||
|
||||
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 create_wanlinks(self, shelf=1, resource=1, latency=20, max_rate=1544000):
|
||||
print("Creating wanlinks")
|
||||
@@ -43,8 +60,8 @@ class LANtoWAN(LFCliBase):
|
||||
data = {
|
||||
"shelf": shelf,
|
||||
"resource": resource,
|
||||
"port": "rdd0",
|
||||
"peer_ifname": "rdd1"
|
||||
"port": "rd0a",
|
||||
"peer_ifname": "rd1a"
|
||||
}
|
||||
self.json_post(url, data)
|
||||
|
||||
@@ -52,8 +69,8 @@ class LANtoWAN(LFCliBase):
|
||||
data = {
|
||||
"shelf": shelf,
|
||||
"resource": resource,
|
||||
"port": "rdd1",
|
||||
"peer_ifname": "rdd0"
|
||||
"port": "rd1a",
|
||||
"peer_ifname": "rd0a"
|
||||
}
|
||||
self.json_post(url, data)
|
||||
time.sleep(.05)
|
||||
@@ -64,7 +81,7 @@ class LANtoWAN(LFCliBase):
|
||||
"alias": "wlan0",
|
||||
"shelf": shelf,
|
||||
"resource": resource,
|
||||
"port": "rdd0",
|
||||
"port": "rd0a",
|
||||
"latency": latency,
|
||||
"max_rate": max_rate
|
||||
}
|
||||
@@ -75,21 +92,59 @@ class LANtoWAN(LFCliBase):
|
||||
"alias": "wlan1",
|
||||
"shelf": shelf,
|
||||
"resource": resource,
|
||||
"port": "rdd1",
|
||||
"port": "rd1a",
|
||||
"latency": latency,
|
||||
"max_rate": max_rate
|
||||
}
|
||||
self.json_post(url, data)
|
||||
create_wanlink.main(base_url='http://'+self.host+':8080')
|
||||
time.sleep(.05)
|
||||
|
||||
def run(self):
|
||||
self.profile.use_wpa2(True, self.ssid, self.password)
|
||||
self.profile.create(resource=1, radio="wiphy0", num_stations=3, debug=False)
|
||||
#self.cx_profile.use_wpa2(True, self.ssid, self.password)
|
||||
self.station_profile.create(radio="wiphy0", num_stations=3, debug=False)
|
||||
|
||||
def cleanup(self): pass
|
||||
|
||||
|
||||
def main():
|
||||
parser = LFCliBase.create_basic_argparse(
|
||||
prog='test_wanlink.py',
|
||||
formatter_class=argparse.RawTextHelpFormatter)
|
||||
for group in parser._action_groups:
|
||||
if group.title == "required arguments":
|
||||
required_args=group
|
||||
break
|
||||
#if required_args is not None:
|
||||
|
||||
optional_args=None
|
||||
for group in parser._action_groups:
|
||||
if group.title == "optional arguments":
|
||||
optional_args=group
|
||||
break
|
||||
if optional_args is not None:
|
||||
optional_args.add_argument('--lanport', help='Select the port you want for lanport', default='wiphy0')
|
||||
optional_args.add_argument('--wanport', help='Select the port you want for wanport', default='wiphy1')
|
||||
for group in parser._action_groups:
|
||||
if group.title == "optional arguments":
|
||||
optional_args=group
|
||||
break
|
||||
#if optional_args is not None:
|
||||
args = parser.parse_args()
|
||||
num_sta=4
|
||||
station_list = portNameSeries(prefix_="sta", start_id_=0, end_id_=num_sta - 1, padding_number_=10000,
|
||||
radio=args.radio)
|
||||
ltw=LANtoWAN(host=args.mgr,
|
||||
port=args.mgr_port,
|
||||
ssid=args.ssid,
|
||||
sta_list=station_list,
|
||||
security=args.security,
|
||||
password=args.passwd,
|
||||
lan_port=args.lanport,
|
||||
wan_port=args.wanport)
|
||||
ltw.create_wanlinks()
|
||||
#ltw.run()
|
||||
ltw.cleanup()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
37
py-scripts/test_wpa_passphrases.py
Normal file
37
py-scripts/test_wpa_passphrases.py
Normal file
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
''' test_wpa_passphrases will test challenging wpa psk passphrases
|
||||
|
||||
Use './test_wpa_passphrases.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.
|
||||
'''
|
||||
|
||||
|
||||
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.lfcli_base import LFCliBase
|
||||
from LANforge import LFUtils
|
||||
from realm import Realm
|
||||
|
||||
class WPAPassphrases(Realm):
|
||||
def __init__(self,
|
||||
ssid=None,
|
||||
security=None,
|
||||
password=None):
|
||||
self.ssid = ssid
|
||||
self.security = security
|
||||
self.password = password
|
||||
|
||||
|
||||
def main():
|
||||
pass
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -64,7 +64,7 @@ class TestGroup(LFCliBase):
|
||||
if self.tg_action == 'del':
|
||||
print("Removing %s" % self.tg_profile.group_name)
|
||||
if self.tg_profile.check_group_exists():
|
||||
self.tg_profile.remove_group()
|
||||
self.tg_profile.rm_group()
|
||||
else:
|
||||
print("%s not found, no action taken" % self.tg_profile.group_name)
|
||||
|
||||
@@ -154,6 +154,7 @@ def main():
|
||||
tg.do_tg_action()
|
||||
tg.update_cxs()
|
||||
tg.do_cx_action()
|
||||
time.sleep(5)
|
||||
tg.show_info()
|
||||
|
||||
|
||||
|
||||
325
py-scripts/testgroup2.py
Executable file
325
py-scripts/testgroup2.py
Executable file
@@ -0,0 +1,325 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
This script will create a variable number of layer3 stations each with their own set of cross-connects and endpoints.
|
||||
|
||||
Use './create_l3.py --help' to see command line usage and options
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
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.lfcli_base import LFCliBase
|
||||
from LANforge import LFUtils
|
||||
from realm import Realm
|
||||
import time
|
||||
import datetime
|
||||
from realm import TestGroupProfile
|
||||
|
||||
|
||||
class TestGroup2(Realm):
|
||||
def __init__(self,
|
||||
ssid, security, password, sta_list, name_prefix, upstream, radio,
|
||||
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",
|
||||
use_ht160=False,
|
||||
group_name=None,
|
||||
list_groups=None,
|
||||
tg_action=None,
|
||||
cx_action=None,
|
||||
add_cx_list=[],
|
||||
rm_cx_list=[],
|
||||
show_group=None,
|
||||
_debug_on=False,
|
||||
_exit_on_error=False,
|
||||
_exit_on_fail=False):
|
||||
super().__init__(host, port)
|
||||
self.upstream = upstream
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.ssid = ssid
|
||||
self.sta_list = sta_list
|
||||
self.security = security
|
||||
self.password = password
|
||||
self.radio = radio
|
||||
self.mode = mode
|
||||
self.ap = ap
|
||||
self.number_template = number_template
|
||||
self.debug = _debug_on
|
||||
self.name_prefix = name_prefix
|
||||
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.ssid = self.ssid
|
||||
self.station_profile.ssid_pass = self.password
|
||||
self.station_profile.security = self.security
|
||||
self.station_profile.number_template_ = self.number_template
|
||||
self.station_profile.debug = self.debug
|
||||
self.station_profile.use_ht160 = use_ht160
|
||||
if self.station_profile.use_ht160:
|
||||
self.station_profile.mode = 9
|
||||
self.station_profile.mode = mode
|
||||
if self.ap is not None:
|
||||
self.station_profile.set_command_param("add_sta", "ap", self.ap)
|
||||
# self.station_list= LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=2, padding_number_=10000, radio='wiphy0') #Make radio a user defined variable from terminal.
|
||||
|
||||
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
|
||||
|
||||
self.tg_action = tg_action
|
||||
self.cx_action = cx_action
|
||||
self.list_groups = list_groups
|
||||
self.show_group = show_group
|
||||
self.tg_profile = self.new_test_group_profile()
|
||||
if group_name is None and list_groups is None and (tg_action is not None or cx_action is not None or
|
||||
add_cx_list is not None or rm_cx_list is not None or show_group is not None):
|
||||
raise ValueError("Group name must be set if manipulating test groups")
|
||||
else:
|
||||
self.tg_profile.group_name = group_name
|
||||
|
||||
if add_cx_list is not None and len(add_cx_list) == 1 and ',' in add_cx_list[0]:
|
||||
self.add_cx_list = add_cx_list[0].split(',')
|
||||
else:
|
||||
self.add_cx_list = add_cx_list
|
||||
|
||||
if rm_cx_list is not None and len(rm_cx_list) == 1 and ',' in rm_cx_list[0]:
|
||||
self.rm_cx_list = rm_cx_list[0].split(',')
|
||||
else:
|
||||
self.rm_cx_list = rm_cx_list
|
||||
|
||||
|
||||
def pre_cleanup(self):
|
||||
self.cx_profile.cleanup_prefix()
|
||||
for sta in self.sta_list:
|
||||
self.rm_port(sta, check_exists=True)
|
||||
|
||||
def build(self):
|
||||
|
||||
self.station_profile.use_security(self.security,
|
||||
self.ssid,
|
||||
self.password)
|
||||
self.station_profile.set_number_template(self.number_template)
|
||||
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.cx_profile.create(endp_type="lf_udp",
|
||||
side_a=self.station_profile.station_names,
|
||||
side_b=self.upstream,
|
||||
sleep_time=0)
|
||||
self.add_cx_list=self.cx_profile.get_cx_names()
|
||||
self._pass("PASS: Station build finished")
|
||||
|
||||
def do_cx_action(self):
|
||||
if self.cx_action == 'start':
|
||||
print("Starting %s" % self.tg_profile.group_name)
|
||||
self.tg_profile.start_group()
|
||||
elif self.cx_action == 'stop':
|
||||
print("Stopping %s" % self.tg_profile.group_name)
|
||||
self.tg_profile.stop_group()
|
||||
elif self.cx_action == 'quiesce':
|
||||
print("Quiescing %s" % self.tg_profile.group_name)
|
||||
self.tg_profile.quiesce_group()
|
||||
|
||||
def do_tg_action(self):
|
||||
if self.tg_action == 'add':
|
||||
print("Creating %s" % self.tg_profile.group_name)
|
||||
self.tg_profile.create_group()
|
||||
if self.tg_action == 'del':
|
||||
print("Removing %s" % self.tg_profile.group_name)
|
||||
if self.tg_profile.check_group_exists():
|
||||
self.tg_profile.rm_group()
|
||||
else:
|
||||
print("%s not found, no action taken" % self.tg_profile.group_name)
|
||||
|
||||
def show_info(self):
|
||||
time.sleep(.5)
|
||||
if self.list_groups:
|
||||
tg_list = self.tg_profile.list_groups()
|
||||
if len(tg_list) > 0:
|
||||
print("Current Test Groups: ")
|
||||
for group in tg_list:
|
||||
print(group)
|
||||
else:
|
||||
print("No test groups found")
|
||||
if self.show_group:
|
||||
cx_list = self.tg_profile.list_cxs()
|
||||
if len(cx_list) > 0:
|
||||
print("Showing cxs in %s" % self.tg_profile.group_name)
|
||||
for cx in cx_list:
|
||||
print(cx)
|
||||
else:
|
||||
print("No cxs found in %s" % self.tg_profile.group_name)
|
||||
def update_cxs(self):
|
||||
if len(self.add_cx_list) > 0:
|
||||
print("Adding cxs %s to %s" % (', '.join(self.add_cx_list), self.tg_profile.group_name))
|
||||
for cx in self.add_cx_list:
|
||||
self.tg_profile.add_cx(cx)
|
||||
self.tg_profile.cx_list.append(cx)
|
||||
if len(self.rm_cx_list) > 0:
|
||||
print("Removing cxs %s from %s" % (', '.join(self.rm_cx_list), self.tg_profile.group_name))
|
||||
for cx in self.rm_cx_list:
|
||||
self.tg_profile.rm_cx(cx)
|
||||
if cx in self.tg_profile.cx_list:
|
||||
self.tg_profile.cx_list.remove(cx)
|
||||
|
||||
def main():
|
||||
parser = LFCliBase.create_basic_argparse(
|
||||
prog='testgroup2.py',
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
epilog='''\
|
||||
Create stations to test connection and traffic on VAPs of varying security types (WEP, WPA, WPA2, WPA3, Open) and then add them to a test group
|
||||
''',
|
||||
|
||||
description='''\
|
||||
testgroup2.py:
|
||||
--------------------
|
||||
Generic command layout:
|
||||
|
||||
python3 ./testgroup2.py
|
||||
--upstream_port eth1
|
||||
--radio wiphy0
|
||||
--num_stations 32
|
||||
--security {open|wep|wpa|wpa2|wpa3} \\
|
||||
--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",
|
||||
--ssid netgear
|
||||
--password admin123
|
||||
--a_min 1000
|
||||
--b_min 1000
|
||||
--ap "00:0e:8e:78:e1:76"
|
||||
--group_name group0
|
||||
--add_group
|
||||
--debug
|
||||
|
||||
./testgroup2.py --num_stations 4 --ssid lanforge --passwd password --security wpa2 --radio wiphy0 --group_name group0 --add_group
|
||||
|
||||
''')
|
||||
|
||||
required_args = None
|
||||
for group in parser._action_groups:
|
||||
if group.title == "required arguments":
|
||||
required_args = group
|
||||
break;
|
||||
if required_args is not None:
|
||||
required_args.add_argument('--a_min', help='--a_min bps rate minimum for side_a', default=256000)
|
||||
required_args.add_argument('--b_min', help='--b_min bps rate minimum for side_b', default=256000)
|
||||
required_args.add_argument('--group_name', help='specify the name of the test group to use', default=None)
|
||||
|
||||
optional_args = None
|
||||
for group in parser._action_groups:
|
||||
if group.title == "optional arguments":
|
||||
optional_args = group
|
||||
break;
|
||||
if optional_args is not None:
|
||||
optional_args.add_argument('--mode', help='Used to force mode of stations')
|
||||
optional_args.add_argument('--ap', help='Used to force a connection to a particular AP')
|
||||
|
||||
tg_group = parser.add_mutually_exclusive_group()
|
||||
tg_group.add_argument('--add_group', help='add new test group', action='store_true', default=False)
|
||||
tg_group.add_argument('--del_group', help='delete test group', action='store_true', default=False)
|
||||
parser.add_argument('--show_group', help='show connections in current test group', action='store_true', default=False)
|
||||
|
||||
cx_group = parser.add_mutually_exclusive_group()
|
||||
cx_group.add_argument('--start_group', help='start all cxs in chosen test group', default=None)
|
||||
cx_group.add_argument('--stop_group', help='stop all cxs in chosen test group', default=None)
|
||||
cx_group.add_argument('--quiesce_group', help='quiesce all cxs in chosen test groups', default=None)
|
||||
|
||||
parser.add_argument('--add_cx', help='add cx to chosen test group', nargs='*', default=[])
|
||||
parser.add_argument('--remove_cx', help='remove cx from chosen test group', nargs='*', default=[])
|
||||
args = parser.parse_args()
|
||||
|
||||
num_sta = 2
|
||||
if (args.num_stations is not None) and (int(args.num_stations) > 0):
|
||||
num_sta = int(args.num_stations)
|
||||
|
||||
station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=num_sta - 1, padding_number_=10000,
|
||||
radio=args.radio)
|
||||
|
||||
|
||||
tg_action = None
|
||||
cx_action = None
|
||||
|
||||
if args.add_group:
|
||||
tg_action = 'add'
|
||||
elif args.del_group:
|
||||
tg_action = 'del'
|
||||
|
||||
if args.start_group:
|
||||
cx_action = 'start'
|
||||
elif args.stop_group:
|
||||
cx_action = 'stop'
|
||||
elif args.quiesce_group:
|
||||
cx_action = 'quiesce'
|
||||
|
||||
ip_var_test = TestGroup2(host=args.mgr,
|
||||
port=args.mgr_port,
|
||||
number_template="0000",
|
||||
sta_list=station_list,
|
||||
name_prefix="",
|
||||
upstream=args.upstream_port,
|
||||
ssid=args.ssid,
|
||||
password=args.passwd,
|
||||
radio=args.radio,
|
||||
security=args.security,
|
||||
use_ht160=False,
|
||||
side_a_min_rate=args.a_min,
|
||||
side_b_min_rate=args.b_min,
|
||||
mode=args.mode,
|
||||
ap=args.ap,
|
||||
group_name=args.group_name,
|
||||
tg_action=tg_action,
|
||||
cx_action=cx_action,
|
||||
_debug_on=args.debug)
|
||||
|
||||
ip_var_test.pre_cleanup()
|
||||
ip_var_test.build()
|
||||
if not ip_var_test.passes():
|
||||
print(ip_var_test.get_fail_message())
|
||||
ip_var_test.exit_fail()
|
||||
ip_var_test.do_tg_action()
|
||||
ip_var_test.update_cxs()
|
||||
ip_var_test.do_cx_action()
|
||||
time.sleep(5)
|
||||
ip_var_test.show_info()
|
||||
print('Creates %s stations and connections' % num_sta)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
10
py-scripts/update_dependencies.py
Executable file
10
py-scripts/update_dependencies.py
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env python3
|
||||
import subprocess
|
||||
def main():
|
||||
command = "pip3 install pandas plotly numpy paramiko bokeh websocket-client pyarrow xlsxwriter pyshark influxdb influxdb-client --upgrade"
|
||||
res = subprocess.call(command, shell = True)
|
||||
|
||||
print("Returned Value: ", res)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,4 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
This is an outdated example. Please see modern py-scripts/test_X example scripts.
|
||||
"""
|
||||
import sys
|
||||
if sys.version_info[0] != 3:
|
||||
print("This script requires Python 3")
|
||||
|
||||
@@ -1,66 +1,54 @@
|
||||
#!/usr/bin/env python3
|
||||
'''
|
||||
Candela Technologies Inc.
|
||||
Info : Standard Script for WLAN Capacity Calculator
|
||||
Date :
|
||||
Author : Anjali Rahamatkar
|
||||
'''
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import os
|
||||
|
||||
from pip._internal.utils import logging
|
||||
|
||||
if 'py-json' not in sys.path:
|
||||
sys.path.append(os.path.join(os.path.abspath('..'), 'py-json'))
|
||||
import wlan_test
|
||||
import wlan_theoretical_sta
|
||||
|
||||
# main method
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser(description="WLAN Capacity Calculator")
|
||||
|
||||
# Station : 11abg
|
||||
parse = wlan_theoretical_sta.abg11_calculator.create_argparse( prog='wlan_capacity_calculator.py',
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
epilog='''\
|
||||
This python script calculates the theoretical value of three different stations( 11abg/11n/11ac)''',
|
||||
description='''\
|
||||
wlan_capacity_calculator.py
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
ap.add_argument("-sta", "--station", help="Enter Station Name : [11abg,11n,11ac](by Default 11abg)")
|
||||
ap.add_argument("-t", "--traffic", help="Enter the Traffic Type : [Data,Voice](by Default Data)")
|
||||
ap.add_argument("-p", "--phy",
|
||||
help="Enter the PHY Bit Rate of Data Flow : [1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54](by Default 54)")
|
||||
ap.add_argument("-e", "--encryption", help="Enter the Encryption : [None, WEP , TKIP, CCMP](by Default None)")
|
||||
ap.add_argument("-q", "--qos", help="Enter the QoS = : [No, Yes](by Default [No for 11abg] and [Yes for 11n])")
|
||||
ap.add_argument("-m", "--mac",
|
||||
help="Enter the 802.11 MAC Frame : [Any Value](by Default [106 for 11abg] and [1538 for 11n])")
|
||||
ap.add_argument("-b", "--basic", nargs='+',
|
||||
help="Enter the Basic Rate Set : [1,2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54]"
|
||||
" (by Default [1 2 5.5 11 6 12] for 11abg, [6 12 24] for 11n/11ac])")
|
||||
ap.add_argument("-pre", "--preamble", help="Enter Preamble value : [ Short, Long, N/A](by Default Short)")
|
||||
ap.add_argument("-s", "--slot", help="Enter the Slot Time : [Short, Long, N/A](by Default Short)")
|
||||
ap.add_argument("-co", "--codec", help="Enter the Codec Type (Voice Traffic): {[ G.711 , G.723 , G.729]"
|
||||
"by Default G.723 for 11abg, G.711 for 11n} and"
|
||||
"{['Mixed','Greenfield'] by Default Mixed for 11ac}")
|
||||
ap.add_argument("-r", "--rts", help="Enter the RTS/CTS Handshake : [No, Yes](by Default No)")
|
||||
ap.add_argument("-c", "--cts", help="Enter the CTS-to-self (protection) : [No, Yes](by Default No)")
|
||||
|
||||
# Station : 11n and 11ac
|
||||
|
||||
ap.add_argument("-d", "--data",
|
||||
help="Enter the Data/Voice MCS Index : ['0','1','2','3','4','5','6','7','8','9','10',"
|
||||
"'11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26',"
|
||||
"'27','28','29','30','31']by Default 7")
|
||||
ap.add_argument("-ch", "--channel", help="Enter the Channel Bandwidth = : ['20','40'] by Default 40 for 11n and "
|
||||
"['20','40','80'] by Default 80 for 11ac")
|
||||
ap.add_argument("-gu", "--guard", help="Enter the Guard Interval = : ['400','800'] (by Default 400)")
|
||||
ap.add_argument("-high", "--highest",
|
||||
help="Enter the Highest Basic MCS = : ['0','1','2','3','4','5','6','7','8','9',"
|
||||
"'10','11','12','13','14','15','16','17','18','19','20','21','22','23','24',"
|
||||
"'25','26','27','28','29','30','31'](by Default 1)")
|
||||
ap.add_argument("-pl", "--plcp",
|
||||
help="Enter the PLCP Configuration = : ['Mixed','Greenfield'] (by Default Mixed) for 11n")
|
||||
ap.add_argument("-ip", "--ip", help="Enter the IP Packets per A-MSDU = : ['0','1','2','3','4','5','6','7','8','9',"
|
||||
"'10','11','12','13','14','15','16','17','18','19','20'] (by Default 0)")
|
||||
ap.add_argument("-mc", "--mc",
|
||||
help="Enter the MAC Frames per A-MPDU = : ['0','1','2','3','4','5','6','7','8',"
|
||||
"'9','10','11','12','13','14','15','16','17','18','19','20','21','22','23',"
|
||||
"'24','25','26','27','28','29','30','31','32','33','34','35','36','37','38',"
|
||||
"'39','40','41','42','43','44','45','46','47','48','49','50','51','52','53',"
|
||||
"'54','55','56','57','58','59','60','61','62','63','64'](by Default [42 for 11n] and [64 for 11ac])")
|
||||
ap.add_argument("-cw", "--cwin", help="Enter the CWmin (leave alone for default) = : [Any Value] (by Default 15)")
|
||||
ap.add_argument("-spa", "--spatial", help="Enter the Spatial Streams = [1,2,3,4] (by Default 4)")
|
||||
ap.add_argument("-rc", "--rtscts", help="Enter the RTS/CTS Handshake and CTS-to-self "
|
||||
" = ['No','Yes'] (by Default No for 11ac)")
|
||||
Example of command line to run(11ac Station):
|
||||
./wlan_capacity_calculator.py
|
||||
-sta 11ac
|
||||
-t Voice
|
||||
-d 9
|
||||
-spa 3
|
||||
-ch 20
|
||||
-gu 800
|
||||
-high 1
|
||||
-e TKIP
|
||||
-q Yes
|
||||
-ip 3
|
||||
-mc 0
|
||||
-b 6 12 24 54
|
||||
-m 1518
|
||||
-co Greenfield
|
||||
-cw 15
|
||||
''')
|
||||
|
||||
try:
|
||||
args = ap.parse_args()
|
||||
args = parse.parse_args()
|
||||
# Station
|
||||
if (args.station is not None):
|
||||
Calculator_name = args.station
|
||||
@@ -238,22 +226,26 @@ def main():
|
||||
# Select station(802.11a/b/g/n/ac standards)
|
||||
|
||||
if "11abg" in Calculator_name:
|
||||
Station1 = wlan_test.abg11_calculator(traffic_name, phy_name, encryption_name, qos_name, mac_name, basic_name,
|
||||
Station1 = wlan_theoretical_sta.abg11_calculator(traffic_name, phy_name, encryption_name, qos_name, mac_name, basic_name,
|
||||
preamble_name, slot_name, codec_name, rts_name, cts_name)
|
||||
Station1.input_parameter()
|
||||
Station1.calculate()
|
||||
Station1.get_result()
|
||||
|
||||
if "11n" in Calculator_name:
|
||||
Station2 = wlan_test.n11_calculator(traffic_name, data_name, channel_name, guard_name, highest_name, encryption_name,
|
||||
Station2 = wlan_theoretical_sta.n11_calculator(traffic_name, data_name, channel_name, guard_name, highest_name, encryption_name,
|
||||
qos_name, ip_name,
|
||||
mc_name, basic_name, mac_name,
|
||||
codec_name, plcp_name, cwin_name, rts_name, cts_name)
|
||||
Station2.input_parameter()
|
||||
Station2.calculate()
|
||||
Station2.get_result()
|
||||
if "11ac" in Calculator_name:
|
||||
Station3 = wlan_test.ac11_calculator(traffic_name, data_name, spatial_name, channel_name, guard_name, highest_name,
|
||||
Station3 = wlan_theoretical_sta.ac11_calculator(traffic_name, data_name, spatial_name, channel_name, guard_name, highest_name,
|
||||
encryption_name
|
||||
, qos_name, ip_name, mc_name, basic_name, mac_name,
|
||||
codec_name, cwin_name, rtscts_name)
|
||||
Station3.input_parameter()
|
||||
Station3.calculate()
|
||||
Station3.get_result()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main() | ||||