Merge /home/greearb/btbits/x64_btbits/server/lf_scripts

This commit is contained in:
Ben Greear
2021-04-22 10:13:15 -07:00
141 changed files with 24521 additions and 9184 deletions

2
py-scripts/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
regression_test.txt
regression_test.rc

View File

@@ -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()

View File

@@ -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`:

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

BIN
py-scripts/artifacts/banner.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

View File

@@ -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
View 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()

View File

@@ -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
View 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()

View File

@@ -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__":

View File

@@ -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()

View File

@@ -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
View 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()

View File

@@ -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()

View 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()

View File

@@ -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
View 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
View 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
View 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()

View 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
View 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
View 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()

View 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

View 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

View File

@@ -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()

View File

@@ -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

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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
View 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
View 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

File diff suppressed because it is too large Load Diff

78
py-scripts/influx.py Normal file
View 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
View 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
View 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()

View File

@@ -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
View 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

File diff suppressed because it is too large Load Diff

549
py-scripts/lf_ftp_test.py Executable file
View 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
View 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
View 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
View 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()))

View 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
View 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

File diff suppressed because it is too large Load Diff

326
py-scripts/lf_tr398_test.py Executable file
View 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()

View 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()

View 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
View 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()

View 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
View 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

View File

@@ -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
View 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()

View 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&nbsp;min)'
Tx Rate (last) | 'tx rate (last)'
Tx Rate LL | 'tx rate ll'
Rx Rate | 'rx rate'
Rx Rate (1 min) | 'rx rate (1&nbsp;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()

View File

@@ -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

View File

@@ -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()

View File

@@ -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:

View 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()

View File

@@ -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:

View File

@@ -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"

View 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()

View File

@@ -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,

View File

@@ -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
View 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

View File

@@ -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())

View File

@@ -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

View File

@@ -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())

View File

@@ -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

View File

@@ -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&nbsp;min)'
Tx Rate (last) | 'tx rate (last)'
Tx Rate LL | 'tx rate ll'
Rx Rate | 'rx rate'
Rx Rate (1 min) | 'rx rate (1&nbsp;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()

View File

@@ -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

View File

@@ -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

View File

@@ -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,

View File

@@ -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)

View File

@@ -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

View File

@@ -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()

View File

@@ -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()

View 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()

View File

@@ -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
View 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()

View 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()

View File

@@ -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")

View File

@@ -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()
main()

View File

@@ -1,3 +1,4 @@
#!/usr/bin/env python3
"""
This example is to demonstrate ws_generic_monitor to monitor events triggered by scripts,
This script when running, will monitor the events triggered by test_ipv4_connection.py
@@ -10,19 +11,34 @@ import json
if 'py-json' not in sys.path:
sys.path.append('../py-json')
from ws_generic_monitor import WS_Listener
from realm import Realm
reference = "test_ipv4_connection.py"
class GenericMonitorTest(Realm):
def __init__(self,
ssid=None,
security=None,
password=None,
radio=None):
self.ssid=ssid
self.security=security
self.password=password
self.radio=radio
def start(self):
pass
def stop(self):
pass
def monitor(self):
pass
def main():
WS_Listener(lfclient_host="localhost", _scriptname=reference, _callback=TestRun)
WS_Listener(lfclient_host="localhost", _scriptname=reference)#, _callback=TestRun)
def TestRun(ws, message):
if (str(message).__contains__(reference)):
#print(message)
temp = json.loads(message)
event_message = str(temp['name']) + "/" + str(temp['details']) + "/" + str(temp['timestamp'])
print(event_message)
if __name__ == "__main__":
main()