From bb47c45e1b1c1d6c77566f5da10d880de4221f2d Mon Sep 17 00:00:00 2001 From: Alex Gavin Date: Tue, 14 Jan 2025 16:34:11 -0800 Subject: [PATCH 01/10] py-json: Run formatter on README Signed-off-by: Alex Gavin --- py-json/README.md | 237 ++++++++++++++++++++++++---------------------- 1 file changed, 125 insertions(+), 112 deletions(-) diff --git a/py-json/README.md b/py-json/README.md index 0f30527f..43d9dab7 100644 --- a/py-json/README.md +++ b/py-json/README.md @@ -4,11 +4,10 @@ Similar to the sibling directory [`LANforge/`](../LANforge/) that provides Perl JSON adapters for Perl-based LANforge automation, the `py-json` directory provides Python adapters for Python-based LANforge automation. Existing LANforge automation-based test and helper scripts exist mostly in [`py-scripts/`](../py-scripts/). This directory (`py-json`) is largely intended for utility and library Python code for use in external scripts. -To leverage this automation, the LANforge GUI must be active and running with the `-http` switch (active by default). It is possible to run the LANforge GUI in *headless* mode using the `-daemon` switch, as well. +To leverage this automation, the LANforge GUI must be active and running with the `-http` switch (active by default). It is possible to run the LANforge GUI in _headless_ mode using the `-daemon` switch, as well. Follow our [getting started cookbook](http://www.candelatech.com/cookbook.php?vol=cli&book=Querying+the+LANforge+GUI+for+JSON+Data) to learn more about how to leverage the LANforge JSON API or email [`support@candelatech.com`](mailto:support@candelatech.com) with questions. - ## Getting Started To get started, please first follow the setup instructions outlined in the `py-scripts` README [here](../py-scripts/README.md). @@ -29,73 +28,80 @@ begin with these imports: Core communication files to LANforge -| Name | Purpose | -|------|---------| -| `add_dut.py` | defined list of DUT keys, cli equivalent: https://www.candelatech.com/lfcli_ug.php#add_dut | -| `add_file_endp.py` | Add a File endpoint to the LANforge Manager. cli equivalent: add_file_endp https://www.candelatech.com/lfcli_ug.php#add_file_endp | -| `add_l4_endp.py` | Add a Layer 4-7 (HTTP, FTP, TELNET, ..) endpoint to the LANforge Manager. cli equivalent: add_l4_endp https://www.candelatech.com/lfcli_ug.php#add_l4_endp | -| `add_monitor.py` | Add a WIFI Monitor interface. These are useful for doing low-level wifi packet capturing. cli equivalent: add_monitor https://www.candelatech.com/lfcli_ug.php#add_monitor | -| `add_sta.py` | Add a WIFI Virtual Station (Virtual STA) interface. cli equivalent: add_sta https://www.candelatech.com/lfcli_ug.php#add_sta | -| `add_vap.py` | Add a WIFI Virtual Access Point (VAP) interface. cli equivalent: add_vap https://www.candelatech.com/lfcli_ug.php#add_vap | -| `set_port.py` | This command allows you to modify attributes on an Ethernet port. cli equivalent: set_port https://www.candelatech.com/lfcli_ug.php#set_port | -| `lfcli_base.py` | json communication to LANforge | -| `LFRequest.py` | Class holds default settings for json requests to LANforge, see: https://gist.github.com/aleiphoenix/4159510| -| `LFUtils.py` | Defines useful common methods | -| `set_port.py` | This command allows you to modify attributes on an Ethernet port. These options includes the IP address, netmask, gateway address, MAC, MTU, and TX Queue Length. cli equivalent: set_port https://www.candelatech.com/lfcli_ug.php#set_port | - +| Name | Purpose | +| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `add_dut.py` | defined list of DUT keys, cli equivalent: https://www.candelatech.com/lfcli_ug.php#add_dut | +| `add_file_endp.py` | Add a File endpoint to the LANforge Manager. cli equivalent: add_file_endp https://www.candelatech.com/lfcli_ug.php#add_file_endp | +| `add_l4_endp.py` | Add a Layer 4-7 (HTTP, FTP, TELNET, ..) endpoint to the LANforge Manager. cli equivalent: add_l4_endp https://www.candelatech.com/lfcli_ug.php#add_l4_endp | +| `add_monitor.py` | Add a WIFI Monitor interface. These are useful for doing low-level wifi packet capturing. cli equivalent: add_monitor https://www.candelatech.com/lfcli_ug.php#add_monitor | +| `add_sta.py` | Add a WIFI Virtual Station (Virtual STA) interface. cli equivalent: add_sta https://www.candelatech.com/lfcli_ug.php#add_sta | +| `add_vap.py` | Add a WIFI Virtual Access Point (VAP) interface. cli equivalent: add_vap https://www.candelatech.com/lfcli_ug.php#add_vap | +| `set_port.py` | This command allows you to modify attributes on an Ethernet port. cli equivalent: set_port https://www.candelatech.com/lfcli_ug.php#set_port | +| `lfcli_base.py` | json communication to LANforge | +| `LFRequest.py` | Class holds default settings for json requests to LANforge, see: https://gist.github.com/aleiphoenix/4159510 | +| `LFUtils.py` | Defines useful common methods | +| `set_port.py` | This command allows you to modify attributes on an Ethernet port. These options includes the IP address, netmask, gateway address, MAC, MTU, and TX Queue Length. cli equivalent: set_port https://www.candelatech.com/lfcli_ug.php#set_port | ### Python Scripts `py-json/` -| Name | Purpose | -|------|---------| -| `base_profile.py` | Class: BaseProfile Use example: py-json/l3_cxprofile2.py used to define generic utility methods to be inherited by other classes | -| `create_wanlink.py` | Create and modify WAN Links Using LANforge JSON AP : http://www.candelatech.com/cookbook.php?vol=cli&book=JSON:+Managing+WANlinks+using+JSON+and+Python | -| `cv_commands.py` | This is a library file used to create a chamber view scenario. import this file as showed in create_chamberview.py to create a scenario | -| `cv_test_manager.py` | This script is working as library for chamberview tests. It holds different commands to automate test. | -| `cv_test_reports.py` | Class: lanforge_reports Pulls reports from LANforge | -| `dut_profile.py` | Class: DUTProfile (new_dut_profile) Use example: py-scripts/update_dut.py used to updates a Device Under Test (DUT) entry in the LANforge test scenario A common reason to use this would be to update MAC addresses in a DUT when you switch between different items of the same make/model of a DUT | -| `fio_endp_profile.py` | Class: FIOEndpProfile (new_fio_endp_profile) Use example: py-scripts/test_fileio.py will create stations or macvlans with matching fileio endpoints to generate and verify fileio related traffic | -| `gen_cxprofile.py` | Class: GenCXProfile (new_generic_endp_profile) Use example: test_generic.py will create stations and endpoints to generate traffic based on a command-line specified command type | -| `http_profile.py` | Class: HTTPProfile (new_http_profile) Use example: test_ipv4_l4_wifi.py will create stations and endpoints to generate and verify layer-4 upload traffic | -| `l3_cxprofile.py` | Class: L3CXProfile (new_l3_cx_profile) Use example: test_ipv4_variable_time.py will create stations and endpoints to generate and verify layer-3 traffic | -| `l3_cxprofile2.py` | Class: L3CXProfile2 (new_l3_cx_profile, ver=2) No current use example, inherits utility functions from BaseProfile, maintains functionality of L3CXProfile | -| `l4_cxprofile.py` | Class: L4CXProfile (new_l4_cx_profile) Use example: test_ipv4_l4.py will create stations and endpoints to generate and verify layer-4 traffic | -| `lf_cv_base.py` | Class: ChamberViewBase, Base Class to be used for Chamber View Tests, inherited by DataPlaneTest in dataplane_test_profile.py | -| `lfdata.py` | Class: LFDataCollection, class used for data collection utility methods | -| `mac_vlan_profile.py` | Class: MACVLANProfile (new_mvlan_profile) Use example: test_fileio.py will create stations or macvlans with matching fileio endpoints to generate and verify fileio related traffic. | -| `multicast_profile.py` | Class: MULTICASTProfile (new_multicast_profile) Use example: test_l3_longevity.py multi cast profiles are created in this test | -| `port_utils.py` | Class: PortUtils used to set the ftp or http port | -| `qvlan_profile.py` | Class: QVLANProfile (new_qvlan_profile) Use example: create_qvlan.py (802.1Q VLAN) | -| `realm.py` | Class: The Realm Class is inherited by most python tests. Realm Class inherites from LFCliBase. The Realm Class contains the configurable components for LANforge, For example L3 / L4 cross connects, stations. http://www.candelatech.com/cookbook.php?vol=cli&book=Python_Create_Test_Scripts_With_the_Realm_Class | -| `realm_test.py` | Python script meant to test functionality of realm methods | -| `station_profile.py` | Class: StationProfile (new_station_profile) Use example: most scripts create and use station profiles | -| `test_base.py` | Class: TestBase, basic class for creating tests, uses basic functions for cleanup, starting/stopping, and passing of tests | -| `test_group_profile.py` | Class: TestGroupProfile (new_test_group_profile) Use example: test_fileio.py will create stations or macvlans with matching fileio endpoints to generate and verify fileio related traffic | -| `test_utility.py` | Standard Script for Webconsole Test Utility | -| `vap_profile.py` | Class: VAPProfile (new_vap_profile) profile for creating Virtual AP's Use example: create_vap.py | -| `vr_profile2.py` | Class: VRProfile (new_vap_profile, ver=2) No current use example, inherits utility functions from BaseProfile | -| `wifi_monitor_profile.py` | Class: WifiMonitor (new_wifi_monitor_profile) Use example: tip_station_powersave.py This script uses filters from realm's PacketFilter class to filter pcap output for specific packets. | -| `wlan_theoretical_sta.py` | Class: abg11_calculator Standard Script for WLAN Capaity Calculator Use example: wlan_capacitycalculator.py | -| `ws-sta-monitor.py` | Example of how to filter messages from the :8081 websocket | -| `ws_generic_monitor.py` | Class: WS_Listener web socket listener Use example: ws_generic_monitor_test.py, ws_generic_monitor to monitor events triggered by scripts, This script when running, will monitor the events triggered by test_ipv4_connection.py | - - -## These Scripts ## - - * `__init__.py`: this is a module header and it defines its relationship to sub-module LANforge, - requiring LFRequest. - * `LANforge`: this module is for our json library. Use gain access to these by using: - `import LANforge` - `from LANforge import LFUtils` - `from LANforge import LFRequest` -## create_sta.py ## + +| Name | Purpose | +| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `base_profile.py` | Class: BaseProfile Use example: py-json/l3_cxprofile2.py used to define generic utility methods to be inherited by other classes | +| `create_wanlink.py` | Create and modify WAN Links Using LANforge JSON AP : http://www.candelatech.com/cookbook.php?vol=cli&book=JSON:+Managing+WANlinks+using+JSON+and+Python | +| `cv_commands.py` | This is a library file used to create a chamber view scenario. import this file as showed in create_chamberview.py to create a scenario | +| `cv_test_manager.py` | This script is working as library for chamberview tests. It holds different commands to automate test. | +| `cv_test_reports.py` | Class: lanforge_reports Pulls reports from LANforge | +| `dut_profile.py` | Class: DUTProfile (new_dut_profile) Use example: py-scripts/update_dut.py used to updates a Device Under Test (DUT) entry in the LANforge test scenario A common reason to use this would be to update MAC addresses in a DUT when you switch between different items of the same make/model of a DUT | +| `fio_endp_profile.py` | Class: FIOEndpProfile (new_fio_endp_profile) Use example: py-scripts/test_fileio.py will create stations or macvlans with matching fileio endpoints to generate and verify fileio related traffic | +| `gen_cxprofile.py` | Class: GenCXProfile (new_generic_endp_profile) Use example: test_generic.py will create stations and endpoints to generate traffic based on a command-line specified command type | +| `http_profile.py` | Class: HTTPProfile (new_http_profile) Use example: test_ipv4_l4_wifi.py will create stations and endpoints to generate and verify layer-4 upload traffic | +| `l3_cxprofile.py` | Class: L3CXProfile (new_l3_cx_profile) Use example: test_ipv4_variable_time.py will create stations and endpoints to generate and verify layer-3 traffic | +| `l3_cxprofile2.py` | Class: L3CXProfile2 (new_l3_cx_profile, ver=2) No current use example, inherits utility functions from BaseProfile, maintains functionality of L3CXProfile | +| `l4_cxprofile.py` | Class: L4CXProfile (new_l4_cx_profile) Use example: test_ipv4_l4.py will create stations and endpoints to generate and verify layer-4 traffic | +| `lf_cv_base.py` | Class: ChamberViewBase, Base Class to be used for Chamber View Tests, inherited by DataPlaneTest in dataplane_test_profile.py | +| `lfdata.py` | Class: LFDataCollection, class used for data collection utility methods | +| `mac_vlan_profile.py` | Class: MACVLANProfile (new_mvlan_profile) Use example: test_fileio.py will create stations or macvlans with matching fileio endpoints to generate and verify fileio related traffic. | +| `multicast_profile.py` | Class: MULTICASTProfile (new_multicast_profile) Use example: test_l3_longevity.py multi cast profiles are created in this test | +| `port_utils.py` | Class: PortUtils used to set the ftp or http port | +| `qvlan_profile.py` | Class: QVLANProfile (new_qvlan_profile) Use example: create_qvlan.py (802.1Q VLAN) | +| `realm.py` | Class: The Realm Class is inherited by most python tests. Realm Class inherites from LFCliBase. The Realm Class contains the configurable components for LANforge, For example L3 / L4 cross connects, stations. http://www.candelatech.com/cookbook.php?vol=cli&book=Python_Create_Test_Scripts_With_the_Realm_Class | +| `realm_test.py` | Python script meant to test functionality of realm methods | +| `station_profile.py` | Class: StationProfile (new_station_profile) Use example: most scripts create and use station profiles | +| `test_base.py` | Class: TestBase, basic class for creating tests, uses basic functions for cleanup, starting/stopping, and passing of tests | +| `test_group_profile.py` | Class: TestGroupProfile (new_test_group_profile) Use example: test_fileio.py will create stations or macvlans with matching fileio endpoints to generate and verify fileio related traffic | +| `test_utility.py` | Standard Script for Webconsole Test Utility | +| `vap_profile.py` | Class: VAPProfile (new_vap_profile) profile for creating Virtual AP's Use example: create_vap.py | +| `vr_profile2.py` | Class: VRProfile (new_vap_profile, ver=2) No current use example, inherits utility functions from BaseProfile | +| `wifi_monitor_profile.py` | Class: WifiMonitor (new_wifi_monitor_profile) Use example: tip_station_powersave.py This script uses filters from realm's PacketFilter class to filter pcap output for specific packets. | +| `wlan_theoretical_sta.py` | Class: abg11_calculator Standard Script for WLAN Capaity Calculator Use example: wlan_capacitycalculator.py | +| `ws-sta-monitor.py` | Example of how to filter messages from the :8081 websocket | +| `ws_generic_monitor.py` | Class: WS_Listener web socket listener Use example: ws_generic_monitor_test.py, ws_generic_monitor to monitor events triggered by scripts, This script when running, will monitor the events triggered by test_ipv4_connection.py | + +## These Scripts + +- `__init__.py`: this is a module header and it defines its relationship to sub-module LANforge, + requiring LFRequest. +- `LANforge`: this module is for our json library. Use gain access to these by using: + `import LANforge` + `from LANforge import LFUtils` + `from LANforge import LFRequest` + +## create_sta.py + Please follow though `create_sta.py` to see how you can utilize the JSON API provided by the LANforge client. It is possible to use similar commands to create virtual Access points. -## create_wanlink.py ## + +## create_wanlink.py + Example that creates a WANlink -## generic_cx.py ## + +## generic_cx.py + Example that creates a cross connect -## realm.py ## + +## realm.py + Module defining the Realm class. `Realm` is a toolbox class that also serves as a facade for finer-grained methods in LFUtils and LFRequest: *`def __init__()`: our constructor @@ -165,63 +171,70 @@ Module defining the Realm class. `Realm` is a toolbox class that also serves as file specified by the `pcap_file` argument. It redirects this output into a txt file in /tmp and returns the lines in that file as an array. +## realm_test.py - -## realm_test.py ## Exercises realm.py -## test_l4.py ## + +## test_l4.py + Example of how to use LFRequest to create a L4 endpoint -## wct-example.py ## + +## wct-example.py + Example of using expect on port 3990 to operate a WiFi Capacity Test -## ws-sta-monitor.py ## -Websocket 8081 client that filters interesting station events from the lfclient websocket +## ws-sta-monitor.py + +Websocket 8081 client that filters interesting station events from the lfclient websocket +## LANforge -## LANforge ## This directory defines the LANforge module holding the following classes: - * lfcli_base.py / class **LFCliBase**: This is a base class we encourage using for creating tests and + +- lfcli_base.py / class **LFCliBase**: This is a base class we encourage using for creating tests and other automation scripts. It provides a centralized manner for making uniform JSON GET and POST calls. - * `__init__`: call this from your classes __init__ method as super().__init__(...) like below: - - class MyScript(LFCliBase): - def __init__(self, host, port, debug_=False, _exit_on_error=False, _exit_on_fail=False): - super().__init__(host, port, _debug=debug_, _exit_on_fail=_exit_on_fail) - - Those parameters provide base functionality: - * host: lfclient host running the LANforge GUI or headless LANforgeGUI -daemon - * port: lfclient HTTP port, typically 8080 - * _debug: provides verbose mode behavior - * _exit_on_fail: if a test calls _fail(), exit - - * LFRequest.py / class **LFRequest**: provides default mechanism to make API queries, use this - to create most of your API requests, but you may also use the normal - `urllib.request` library on simple GET requests if you wish. - * form_post(): post data in url-encoded format - * json_post(): post data in JSON format - * get(): GET method returns text (which could be JSON) - * get_as_json(): converts get() JSON results into python objects - * add_post_data(): provide a dictionary to this method before calling formPost() or jsonPost() - - * LFUtils.py / class **LFUtils**: defines constants and utility methods - * class PortEID: convenient handle for port objects - * sta_new_down_sta_request(): create POST data object for station down - * port_set_dhcp_down_request(): create POST data object for station down, apply `use_dhcp` flags - * port_dhcp_up_request(): apply `use_dhcp`, ask for station to come up - * port_up_request(): ask for station to come up - * port_down_request(): ask for station to go down - * generate_mac(): generate mac addresses - * port_name_series(): produce a padded-number series of port names - * generate_random_hex(): series of random octets - * portAliasesInList(): returns station aliases from `/port` listing - * find_port_eids(): returns EIDs of ports - * wait_until_ports_admin_down(): watch ports until they report admin down - * wait_until_ports_admin_up(): watch ports until they report admin up - * wait_until_ports_disappear(): use this after deleting ports - * ~~waitUntilPortsDisappear()~~: use this after deleting ports, **deprecated** - * wait_until_ports_appear(): use this after `add_sta` or `set_port` - * remove_port(): remove a port using rm_vlan command - * remove_cx(): request a list of CX names be removed - * remove_endps(): request a list of endpoint names be removed - * exec_wrap(): hair trigger method that exits when a command fails when called by os.system() + + - `__init__`: call this from your classes **init** method as super().**init**(...) like below: + + class MyScript(LFCliBase): + def **init**(self, host, port, debug*=False, \_exit_on_error=False, \_exit_on_fail=False): + super().**init**(host, port, \_debug=debug*, \_exit_on_fail=\_exit_on_fail) + +Those parameters provide base functionality: +_ host: lfclient host running the LANforge GUI or headless LANforgeGUI -daemon +_ port: lfclient HTTP port, typically 8080 +_ \_debug: provides verbose mode behavior +_ \_exit_on_fail: if a test calls \_fail(), exit + +- LFRequest.py / class **LFRequest**: provides default mechanism to make API queries, use this + to create most of your API requests, but you may also use the normal + `urllib.request` library on simple GET requests if you wish. + + - form_post(): post data in url-encoded format + - json_post(): post data in JSON format + - get(): GET method returns text (which could be JSON) + - get_as_json(): converts get() JSON results into python objects + - add_post_data(): provide a dictionary to this method before calling formPost() or jsonPost() + +- LFUtils.py / class **LFUtils**: defines constants and utility methods + - class PortEID: convenient handle for port objects + - sta_new_down_sta_request(): create POST data object for station down + - port_set_dhcp_down_request(): create POST data object for station down, apply `use_dhcp` flags + - port_dhcp_up_request(): apply `use_dhcp`, ask for station to come up + - port_up_request(): ask for station to come up + - port_down_request(): ask for station to go down + - generate_mac(): generate mac addresses + - port_name_series(): produce a padded-number series of port names + - generate_random_hex(): series of random octets + - portAliasesInList(): returns station aliases from `/port` listing + - find_port_eids(): returns EIDs of ports + - wait_until_ports_admin_down(): watch ports until they report admin down + - wait_until_ports_admin_up(): watch ports until they report admin up + - wait_until_ports_disappear(): use this after deleting ports + - ~~waitUntilPortsDisappear()~~: use this after deleting ports, **deprecated** + - wait_until_ports_appear(): use this after `add_sta` or `set_port` + - remove_port(): remove a port using rm_vlan command + - remove_cx(): request a list of CX names be removed + - remove_endps(): request a list of endpoint names be removed + - exec_wrap(): hair trigger method that exits when a command fails when called by os.system() From 722fea70b1a6f62eacc7d2937b4af691057ef03e Mon Sep 17 00:00:00 2001 From: Alex Gavin Date: Tue, 14 Jan 2025 16:38:29 -0800 Subject: [PATCH 02/10] py-json: Reformat realm.py function list Signed-off-by: Alex Gavin --- py-json/README.md | 156 ++++++++++++++++++++++++---------------------- 1 file changed, 80 insertions(+), 76 deletions(-) diff --git a/py-json/README.md b/py-json/README.md index 43d9dab7..6f9cb631 100644 --- a/py-json/README.md +++ b/py-json/README.md @@ -15,14 +15,18 @@ To get started, please first follow the setup instructions outlined in the `py-s To use this module, make sure your include path captures this module by adding it to your `sys.path`. We recommend your scripts in `../py-scripts` begin with these imports: - 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 +```Python +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 +``` ### Python Scripts `py-json/LANforge/` @@ -102,74 +106,74 @@ Example that creates a cross connect ## realm.py -Module defining the Realm class. `Realm` is a toolbox class that also serves as a facade for finer-grained methods in LFUtils and LFRequest: - - *`def __init__()`: our constructor - *`def wait_until_ports_appear()`: takes a list of ports and waits until they all appear in the list of existing stations - *`def wait_until_ports_disappear()`: takes a list of ports and waits until they all disappear from the list of existing stations - *`def rm_port()`: takes a string in eid format and attempts to remove it - *`def port_exists()`: takes a string in eid format and returns a boolean depending on if the port exists - *`def admin_up()`: takes a string in eid format attempts to set it to admin up - *`def admin_down()`: takes a string in eid format attempts to set it to admin down - *`def reset_port()`: takes a string in eid format requests a port reset - *`def rm_cx()`: takes a cross connect name as a string and attempts to remove it from LANforge - *`def rm_endp()`: takes an endpoint name as a string and attempts to remove it from LANforge - *`def set_endp_tos()`: attempts to set tos of a specified endpoint name - *`def stop_cx()`: attempts to stop a cross connect with the given name - *`def cleanup_cxe_prefix()`: attempts to remove all existing cross connects and endpoints - *`def channel_freq()`: takes a channel and returns its corresponding frequency - *`def freq_channel()`: takes a frequency and returns its corresponding channel - *`def wait_while_building()`: checks for OK or BUSY when querying cli-json/cv+is_built - *`def load()`: loads a database from the GUI - *`def cx_list()`: request json list of cross connects - *`def waitUntilEndpsAppear()`: takes a list of endpoints and waits until they all disappear from the list of existing endpoints - *deprecated method use def wait_until_endps_appear() instead* - *`def wait_until_endps_appear()`: takes a list of endpoints and waits until they all appear in the list of existing endpoints - *`def waitUntilCxsAppear()`: takes a list of cross connects and waits until they all disappear from the list of existing cross connects - *deprecated method use def wait_until_cxs_appear() instead* - *`def wait_until_cxs_appear()`: takes a list of cross connects and waits until they all disappear from the list of existing cross connects - *`def station_map()`: request a map of stations via `/port/list` and alter the list to name based map of only stations - *`def station_list()`: request a list of stations - *`def vap_list()`: request a list of virtual APs - *`def remove_vlan_by_eid()`: a way of deleting a port/station/vAP - *`def find_ports_like()`: returns a list of ports matching a string prefix, like: - * `sta\*` matches names starting with `sta` - * `sta10+` matches names with port numbers 10 or greater - * `sta[10..20]` matches a range of stations including the range sta10 -- sta20 - *`def name_to_eid()`: takes a name like `1.1.eth1` and returns it split into an array `[1, 1, "eth1"]` - *`def wait_for_ip()`: takes a list of stations and waits until they all have an ip address. Default wait time is 360 seconds, - can take -1 as timeout argument to determine timeout based on mean ip acquisition time - *`def get_curr_num_ips()`: returns the number of stations with an ip address - *`def duration_time_to_seconds()`: returns an integer for a time string converted to seconds - *`def remove_all_stations()`: attempts to remove all currently existing stations - *`def remove_all_endps()`: attempts to remove all currently existing endpoints - *`def remove_all_cxs()`: attempts to remove all currently existing cross connects - *`def new_station_profile()`: creates a blank station profile, configure station properties in this profile - and then use its `create()` method to create a series of stations - *`def new_multicast_profile()`: creates a blank multicast profile, configure it then call `create()` - *`def new_wifi_monitor_profile()`: creates a blank wifi monitor profile, configure it then call `create()` - *`def new_l3_cx_profile()`: creates a blank Layer-3 profile, configure this connection profile and - then use its `create()` method to create a series of endpoints and cross connects - *`def new_l4_cx_profile()`: creates a blank Layer-4 (http/ftp) profile, configure it then call `create()` - *`def new_generic_endp_profile()`: creates a blank Generic endpoint profile, configure it then call `create()` - *`def new_generic_cx_profile()`: creates a blank Generic connection profile (for lfping/iperf3/curl-post/speedtest.net) - then configure and call `create()` - *`def new_vap_profile()`: creates a blank VAP profile, configure it then call `create()` - *`def new_vr_profile()`: creates a blank VR profile, configure it then call `create()` - *`def new_http_profile()`: creates a blank HTTP profile, configure it then call `create()` - *`def new_fio_endp_profile()`: creates a blank FileIO profile, configure it then call `create()` - *`def new_dut_profile()`: creates a blank DUT profile, configure it then call `create()` - *`def new_mvlan_profile()`: creates a blank MACVLAN profile, configure it then call `create()` - *`def new_qvlan_profile()`: creates a blank QVLAN profile, configure it then call `create()` - *`def new_test_group_profile()`: creates a blank Test Group profile, configure it then call `create()` - *`class PacketFilter()`: This class provides filters that can be used with tshark - *`def get_filter_wlan_assoc_packets()`: This packet filter will look for wlan.fc.type_subtype<=3. It takes - two arguments: `ap_mac` and `sta_mac` - *`def get_filter_wlan_null_packets()`: This packet filter will look for wlan.fc.type_subtype==44. It takes - two arguments: `ap_mac` and `sta_mac` - *`def run_filter()`: This function will run the filter specified by the `filter` argument on the pcap - file specified by the `pcap_file` argument. It redirects this output into a txt file in /tmp - and returns the lines in that file as an array. +* `class Realm()`: toolbox class that also serves as a facade for finer-grained methods in LFUtils and LFRequest + * `def __init__()`: our constructor + * `def wait_until_ports_appear()`: takes a list of ports and waits until they all appear in the list of existing stations + * `def wait_until_ports_disappear()`: takes a list of ports and waits until they all disappear from the list of existing stations + * `def rm_port()`: takes a string in eid format and attempts to remove it + * `def port_exists()`: takes a string in eid format and returns a boolean depending on if the port exists + * `def admin_up()`: takes a string in eid format attempts to set it to admin up + * `def admin_down()`: takes a string in eid format attempts to set it to admin down + * `def reset_port()`: takes a string in eid format requests a port reset + * `def rm_cx()`: takes a cross connect name as a string and attempts to remove it from LANforge + * `def rm_endp()`: takes an endpoint name as a string and attempts to remove it from LANforge + * `def set_endp_tos()`: attempts to set tos of a specified endpoint name + * `def stop_cx()`: attempts to stop a cross connect with the given name + * `def cleanup_cxe_prefix()`: attempts to remove all existing cross connects and endpoints + * `def channel_freq()`: takes a channel and returns its corresponding frequency + * `def freq_channel()`: takes a frequency and returns its corresponding channel + * `def wait_while_building()`: checks for OK or BUSY when querying cli-json/cv+is_built + * `def load()`: loads a database from the GUI + * `def cx_list()`: request json list of cross connects + * `def waitUntilEndpsAppear()`: takes a list of endpoints and waits until they all disappear from the list of existing endpoints + *deprecated method use def wait_until_endps_appear() instead* + * `def wait_until_endps_appear()`: takes a list of endpoints and waits until they all appear in the list of existing endpoints + * `def waitUntilCxsAppear()`: takes a list of cross connects and waits until they all disappear from the list of existing cross connects + *deprecated method use def wait_until_cxs_appear() instead* + * `def wait_until_cxs_appear()`: takes a list of cross connects and waits until they all disappear from the list of existing cross connects + * `def station_map()`: request a map of stations via `/port/list` and alter the list to name based map of only stations + * `def station_list()`: request a list of stations + * `def vap_list()`: request a list of virtual APs + * `def remove_vlan_by_eid()`: a way of deleting a port/station/vAP + * `def find_ports_like()`: returns a list of ports matching a string prefix, like: + * `sta\*` matches names starting with `sta` + * `sta10+` matches names with port numbers 10 or greater + * `sta[10..20]` matches a range of stations including the range sta10 -- sta20 + * `def name_to_eid()`: takes a name like `1.1.eth1` and returns it split into an array `[1, 1, "eth1"]` + * `def wait_for_ip()`: takes a list of stations and waits until they all have an ip address. Default wait time is 360 seconds, + can take -1 as timeout argument to determine timeout based on mean ip acquisition time + * `def get_curr_num_ips()`: returns the number of stations with an ip address + * `def duration_time_to_seconds()`: returns an integer for a time string converted to seconds + * `def remove_all_stations()`: attempts to remove all currently existing stations + * `def remove_all_endps()`: attempts to remove all currently existing endpoints + * `def remove_all_cxs()`: attempts to remove all currently existing cross connects + * `def new_station_profile()`: creates a blank station profile, configure station properties in this profile + and then use its `create()` method to create a series of stations + * `def new_multicast_profile()`: creates a blank multicast profile, configure it then call `create()` + * `def new_wifi_monitor_profile()`: creates a blank wifi monitor profile, configure it then call `create()` + * `def new_l3_cx_profile()`: creates a blank Layer-3 profile, configure this connection profile and + then use its `create()` method to create a series of endpoints and cross connects + * `def new_l4_cx_profile()`: creates a blank Layer-4 (http/ftp) profile, configure it then call `create()` + * `def new_generic_endp_profile()`: creates a blank Generic endpoint profile, configure it then call `create()` + * `def new_generic_cx_profile()`: creates a blank Generic connection profile (for lfping/iperf3/curl-post/speedtest.net) + then configure and call `create()` + * `def new_vap_profile()`: creates a blank VAP profile, configure it then call `create()` + * `def new_vr_profile()`: creates a blank VR profile, configure it then call `create()` + * `def new_http_profile()`: creates a blank HTTP profile, configure it then call `create()` + * `def new_fio_endp_profile()`: creates a blank FileIO profile, configure it then call `create()` + * `def new_dut_profile()`: creates a blank DUT profile, configure it then call `create()` + * `def new_mvlan_profile()`: creates a blank MACVLAN profile, configure it then call `create()` + * `def new_qvlan_profile()`: creates a blank QVLAN profile, configure it then call `create()` + * `def new_test_group_profile()`: creates a blank Test Group profile, configure it then call `create()` + +* `class PacketFilter()`: This class provides filters that can be used with tshark + * `def get_filter_wlan_assoc_packets()`: This packet filter will look for wlan.fc.type_subtype<=3. It takes + two arguments: `ap_mac` and `sta_mac` + * `def get_filter_wlan_null_packets()`: This packet filter will look for wlan.fc.type_subtype==44. It takes + two arguments: `ap_mac` and `sta_mac` + * `def run_filter()`: This function will run the filter specified by the `filter` argument on the pcap + file specified by the `pcap_file` argument. It redirects this output into a txt file in /tmp + and returns the lines in that file as an array. ## realm_test.py From 131fb62e17374339a90ccb1a140f47523e424d20 Mon Sep 17 00:00:00 2001 From: Alex Gavin Date: Tue, 14 Jan 2025 16:40:09 -0800 Subject: [PATCH 03/10] Run formatter on main README Signed-off-by: Alex Gavin --- README.md | 250 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 128 insertions(+), 122 deletions(-) diff --git a/README.md b/README.md index 0448751d..eea0dd02 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ Please contact [`support@candelatech.com`](mailto:support@candelatech.com) if you have any questions or encounter issues. ## Overview + These scripts span a variety of use cases, including automating Chamber View tests, configuring LANforge ports and traffic pairs, and much more. **No additional setup is required to run these scripts on a system with LANforge pre-installed**. On your LANforge system, you can find this repository in the `/home/lanforge/scripts/` directory. (e.g. CT523c, CT521b). The contents of the directory match the version of LANforge installed on your system (see the [tagged releases](https://github.com/greearb/lanforge-scripts/tags) to clone specific version.) @@ -12,6 +13,7 @@ These scripts span a variety of use cases, including automating Chamber View tes To setup and use these scripts on a system without LANforge pre-installed or to use a specific version (e.g. specific LANforge release), please follow the instructions outlined in the [LANforge Python Scripts README](./py-scripts/README.md). For more advanced users wanting to develop their own automation, we offer the following: + - Auto-generated Python library in [`lanforge_client/`](./lanforge_client/) - **NOTE: This library is under development and subject to change as it progresses.** - Designed to make LANforge CLI commands and LANforge JSON API endpoints available in Python. @@ -49,20 +51,21 @@ If you would like to contribute to LANforge scripts, please read the [`CONTRIBUT - [Querying the LANforge JSON API using Python Cookbook](https://www.candelatech.com/cookbook/cli/json-python) ### Commonly Used Scripts + The `lf_*.pl` scripts are typically more complete and general purpose scripts, though some are ancient and very specific. In particular, these scripts are more modern and may be a good place to start: -| Name | Purpose | -|------------------|-----------| -| `lf_associate_ap.pl` | LANforge server script for associating virtual stations to an arbitrary SSID | -| `lf_attenmod.pl` | Query and update CT70X programmable attenuators | -| `lf_firemod.pl` | Query and update connections (Layer 3) | -| `lf_icemod.pl` | Query and update WAN links and impairments | -| `lf_portmod.pl` | Query and update physical and virtual ports | -| `lf_tos_test.py` | Generate traffic at different QoS and report in spreadsheet | -| `lf_sniff.py` | Create packet capture files, especially OFDMA /AX captures | +| Name | Purpose | +| -------------------- | ---------------------------------------------------------------------------- | +| `lf_associate_ap.pl` | LANforge server script for associating virtual stations to an arbitrary SSID | +| `lf_attenmod.pl` | Query and update CT70X programmable attenuators | +| `lf_firemod.pl` | Query and update connections (Layer 3) | +| `lf_icemod.pl` | Query and update WAN links and impairments | +| `lf_portmod.pl` | Query and update physical and virtual ports | +| `lf_tos_test.py` | Generate traffic at different QoS and report in spreadsheet | +| `lf_sniff.py` | Create packet capture files, especially OFDMA /AX captures | The `lf_wifi_rest_example.pl` script shows how one might call the other scripts from within a script. @@ -72,14 +75,17 @@ within a script. When the LANforge GUI is running, a user can use the web-based LANforge Command Composer tool to generate CLI commands, either for use directly through the telnet interface (port 4001) or indirectly through the `cli-json/` LANFORGE JSON API endpoint. To access this tool, perform the following steps: + 1. Navigate to the Help page (either from the LANforge or remotely) - - From the LANforge system (e.g. through VNC): [`http://localhost:8080/help`](http://localhost:8080/help) - - Remotely: - - Directly by IP address: `http://192.168.1.101:8080/help` - - If your network supports DNS resolution: `http://ct523c-cafe:8080/help` + + - From the LANforge system (e.g. through VNC): [`http://localhost:8080/help`](http://localhost:8080/help) + - Remotely: + - Directly by IP address: `http://192.168.1.101:8080/help` + - If your network supports DNS resolution: `http://ct523c-cafe:8080/help` 2. Click on the link for your desired command, e.g. `add_sta` - - Each CLI command will display two links. The link *on the left side* takes you to the Command Composer tool + + - Each CLI command will display two links. The link _on the left side_ takes you to the Command Composer tool 3. Set the desired fields for the command @@ -101,110 +107,110 @@ Existing offerings largely include test and helper scripts in addition to import Helper scripts, especially creation and modification scripts, are designed as tools in a toolbox. Each toolbox script performs a single task, like a tool in the toolbox. For example, the [`create_station.py`](./py-scripts/create_station.py) is designed to create and configure LANforge station ports, providing many options for that specific use case. -| Name | Purpose | -|------|---------| -| `create_bond.py` | Creates and configures a single Bond port using a variable number of child ports | -| [`create_bridge.py`](./py-scripts/create_bridge.py) | Creates and configures a single Bridge port using a variable number of child ports | -| `create_chamberview_dut.py` | Creates a single LANforge DUT object, primarily useful in Chamber View | -| `create_chamberview.py` | Creates a single LANforge Chamber View Scenario | -| `create_l3.py` | Creates and configures a variable number of LANforge L3 CX traffic pairs using existing ports | -| `create_l4.py` | Creates and configures a variable number of LANforge L4 traffic endpoints using existing ports | -| [`create_macvlan.py`](./py-scripts/create_macvlan.py) | Creates and configures a variable number of MACVLAN ports (different from 802.1Q VLAN) using a single parent interface | -| [`create_qvlan.py`](./py-scripts/create_qvlan.py) | Creates and configures a variable number of 802.1Q VLAN ports using a single parent interface | -| [`create_station.py`](./py-scripts/create_station.py) | Creates and configures a variable number of WiFi stations using a single parent radio | -| `create_vap.py` | Creates and configures a variable number of WiFi virtual APs (vAPs) using a single parent radio | -| `csv_convert.py` | Python script to read in a LANforge Dataplane CSV file and output a csv file that works with a customer's RvRvO visualization tool.| -| `csv_processor.py` | Python script to assist processing csv files| -| `lf_ap_auto_test.py` | This script is used to automate running AP-Auto tests | -| `lf_dataplane_test.py` | This script is used to automate running Dataplane tests | -| `lf_ftp_test.py` | Python script will create stations and endpoints to generate and verify layer-4 traffic over an ftp connection | -| `lf_graph.py` | Classes for creating images from graphs using data sets | -| `lf_mesh_test.py` | This script is used to automate running Mesh tests | -| `lf_report.py` | This program is a helper class for reporting results for a lanforge python script | -| `lf_report_test.py` | Python script to test reporting | -| `lf_rvr_test.py` | This script is used to automate running Rate-vs-Range tests | -| `lf_snp_test.py` | Test scaling and performance (snp) run various configurations and measures data rates | -| `lf_tr398_test.py` | This script is used to automate running TR398 tests | -| `lf_wifi_capacity_test.py` | This is a test file which will run a wifi capacity test | -| `run_cv_scenario.py` | Set the LANforge to a BLANK database then it will load the specified database and start a graphical report | -| `rvr_scenario.py` | This script will set the LANforge to a BLANK database then it will load the specified database and start a graphical report | -| `scenario.py` | Python script to load a database file and control test groups | -| `sta_connect.py` | Create a station, run TCP and UDP traffic then verify traffic was received. Stations are cleaned up afterwards | -| `sta_connect2.py` | Create a station, run TCP and UDP traffic then verify traffic was received. Stations are cleaned up afterwards | -| `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 | -| `stations_connected.py` | Contains examples of using realm to query stations and get specific information from them | -| `test_client_admission.py` | This script will create one station at a time and generate downstream traffic | -| `test_fileio.py` | Test FileIO traffic | -| `test_generic.py` | Test generic traffic using generic cross-connect and endpoint type | -| `test_ipv4_ttls.py` | Test connection to ttls system | -| `test_ipv6_connection.py` | Test IPV6 connection to VAPs of varying security types (WEP, WPA, WPA2, WPA3, Open) | -| `test_l3_WAN_LAN.py` | Test traffic over a bridged NAT connection | -| `test_l3_longevity.py` | Create variable stations on multiple radios, configurable rates, PDU, ToS, TCP and/or UDP traffic, upload and download, attenuation | -| `test_l3_powersave_traffic.py` | Python script to test for layer 3 powersave traffic | -| `test_l3_scenario_throughput.py` | Load an existing scenario and run the simultaneous throughput over time and generate report and P=plot the G=graph| -| `test_l3_unicast_traffic_gen.py` | Generate unicast traffic over a list of stations| -| `test_status_msg.py` | Test the status message passing functions of /status-msg | -| `test_wanlink.py` | Python script to test wanlink creation | -| `testgroup.py` | Python script to test creation and control of test groups | -| `tip_station_powersave.py` | Generate and test for powersave packets within traffic run over multiple stations | -| `update_dependencies.py` | Installs required Python dependencies required to run LANforge Python scripts. See the [`py-scripts/` README](./py-scripts/README.md#setup) for more information. | -| `wlan_capacity_calculator.py` | Standard Script for WLAN Capacity Calculator | -| `ws_generic_monitor_test.py` | 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 | +| Name | Purpose | +| ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `create_bond.py` | Creates and configures a single Bond port using a variable number of child ports | +| [`create_bridge.py`](./py-scripts/create_bridge.py) | Creates and configures a single Bridge port using a variable number of child ports | +| `create_chamberview_dut.py` | Creates a single LANforge DUT object, primarily useful in Chamber View | +| `create_chamberview.py` | Creates a single LANforge Chamber View Scenario | +| `create_l3.py` | Creates and configures a variable number of LANforge L3 CX traffic pairs using existing ports | +| `create_l4.py` | Creates and configures a variable number of LANforge L4 traffic endpoints using existing ports | +| [`create_macvlan.py`](./py-scripts/create_macvlan.py) | Creates and configures a variable number of MACVLAN ports (different from 802.1Q VLAN) using a single parent interface | +| [`create_qvlan.py`](./py-scripts/create_qvlan.py) | Creates and configures a variable number of 802.1Q VLAN ports using a single parent interface | +| [`create_station.py`](./py-scripts/create_station.py) | Creates and configures a variable number of WiFi stations using a single parent radio | +| `create_vap.py` | Creates and configures a variable number of WiFi virtual APs (vAPs) using a single parent radio | +| `csv_convert.py` | Python script to read in a LANforge Dataplane CSV file and output a csv file that works with a customer's RvRvO visualization tool. | +| `csv_processor.py` | Python script to assist processing csv files | +| `lf_ap_auto_test.py` | This script is used to automate running AP-Auto tests | +| `lf_dataplane_test.py` | This script is used to automate running Dataplane tests | +| `lf_ftp_test.py` | Python script will create stations and endpoints to generate and verify layer-4 traffic over an ftp connection | +| `lf_graph.py` | Classes for creating images from graphs using data sets | +| `lf_mesh_test.py` | This script is used to automate running Mesh tests | +| `lf_report.py` | This program is a helper class for reporting results for a lanforge python script | +| `lf_report_test.py` | Python script to test reporting | +| `lf_rvr_test.py` | This script is used to automate running Rate-vs-Range tests | +| `lf_snp_test.py` | Test scaling and performance (snp) run various configurations and measures data rates | +| `lf_tr398_test.py` | This script is used to automate running TR398 tests | +| `lf_wifi_capacity_test.py` | This is a test file which will run a wifi capacity test | +| `run_cv_scenario.py` | Set the LANforge to a BLANK database then it will load the specified database and start a graphical report | +| `rvr_scenario.py` | This script will set the LANforge to a BLANK database then it will load the specified database and start a graphical report | +| `scenario.py` | Python script to load a database file and control test groups | +| `sta_connect.py` | Create a station, run TCP and UDP traffic then verify traffic was received. Stations are cleaned up afterwards | +| `sta_connect2.py` | Create a station, run TCP and UDP traffic then verify traffic was received. Stations are cleaned up afterwards | +| `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 | +| `stations_connected.py` | Contains examples of using realm to query stations and get specific information from them | +| `test_client_admission.py` | This script will create one station at a time and generate downstream traffic | +| `test_fileio.py` | Test FileIO traffic | +| `test_generic.py` | Test generic traffic using generic cross-connect and endpoint type | +| `test_ipv4_ttls.py` | Test connection to ttls system | +| `test_ipv6_connection.py` | Test IPV6 connection to VAPs of varying security types (WEP, WPA, WPA2, WPA3, Open) | +| `test_l3_WAN_LAN.py` | Test traffic over a bridged NAT connection | +| `test_l3_longevity.py` | Create variable stations on multiple radios, configurable rates, PDU, ToS, TCP and/or UDP traffic, upload and download, attenuation | +| `test_l3_powersave_traffic.py` | Python script to test for layer 3 powersave traffic | +| `test_l3_scenario_throughput.py` | Load an existing scenario and run the simultaneous throughput over time and generate report and P=plot the G=graph | +| `test_l3_unicast_traffic_gen.py` | Generate unicast traffic over a list of stations | +| `test_status_msg.py` | Test the status message passing functions of /status-msg | +| `test_wanlink.py` | Python script to test wanlink creation | +| `testgroup.py` | Python script to test creation and control of test groups | +| `tip_station_powersave.py` | Generate and test for powersave packets within traffic run over multiple stations | +| `update_dependencies.py` | Installs required Python dependencies required to run LANforge Python scripts. See the [`py-scripts/` README](./py-scripts/README.md#setup) for more information. | +| `wlan_capacity_calculator.py` | Standard Script for WLAN Capacity Calculator | +| `ws_generic_monitor_test.py` | 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 | ## Perl and Shell Scripts -| Name | Purpose | -|------|---------| -| `associate_loop.sh` | Use this script to associate stations between SSIDs A and B | -| `attenuator_series_example.csv` | Example of CSV input for a series of attenuator settings | -| `attenuator_series.pl` | Reads a CSV of attenuator settings and replays them to CT70X programmble attenuator | -| `ftp-upload.pl` | Use this script to collect and upload station data to FTP site | -| `imix.pl` | packet loss survey tool | -| `lf_associate_ap.pl` | LANforge server script for associating virtual stations to an chosen SSID | -| `lf_attenmod.pl` | This program is used to modify the LANforge attenuator through the LANforge | -| `lf_auto_wifi_cap.pl` | This program is used to automatically run LANforge-GUI WiFi Capacity tests | -| `lf_cmc_macvlan.pl` | Stress test sets up traffic types of udp , tcp , continuously starts and stops the connections | -| `lf_create_bcast.pl` | creates a L3 broadcast connection | -| `lf_cycle_wanlinks.pl` | example of how to call lf_icemod.pl from a script | -| `lf_endp_script.pl` | create a hunt script on a L3 connection endpoint | -| `lf_firemod.pl` | queries and modifies L3 connections | -| `lf_generic_ping.pl` | Generate a batch of Generic lfping endpoints | -| `lf_gui_cmd.pl` | Initiate a stress test | -| `lf_icemod.pl` | queries and modified WANLink connections | -| `lf_ice.pl` | adds and configures wanlinks | -| `lf_l4_auth.pl` | example of scripting L4 http script with basic auth | -| `lf_l4_reset.sh` | reset any layer 4 connection that reaches 0 Mbps over last minute | -| `lf_log_parse.pl` | Convert the timestamp in LANforge logs (it is in unix-time, miliseconds) to readable date | -| `lf_loop_traffic.sh` | Repeatedly start and stop a L3 connection | -| `lf_macvlan_l4.pl` | Set up connection types: lf_udp, lf_tcp across 1 real port and many macvlan ports on 2 machines. Then continously starts and stops the connections. | -| `lf_mcast.bash` | Create a multicast L3 connection endpoint | -| `lf_monitor.pl` | Monitor L4 connections | -| `lf_nfs_io.pl` | Creates and runs NFS connections | -| `lf_parse_tshark_log.pl` | Basic parsing of tshark logs | -| `lf_portmod.pl` | Queries and changes LANforge physical and virtual ports | -| `lf_port_walk.pl` | Creates a series of connections, useful for basic firewall testing | -| `lf_show_events.pl` | Displays and clears LANforge event log | -| `lf_staggered_dl.sh` | his script starts a series of Layer-3 connections across a series of stations each station will wait $nap seconds, download $quantity KB and then remove its old CX. | -| `lf_sta_name.pl` | Use this script to alter a virtual station names | -| `lf_verify.pl` | Creates a basic L3 connection to verify that two ethernet ports are physically connected | -| `lf_voip.pl` | Creates series of VOIP connections between two LANforge machines | -| `lf_voip_test.pl` | Creates series of VOIP connections and runs them | -| `lf_vue_mod.sh` | Bash script that wraps common operations for Virtual User Endpoint operations done by `lf_associate_ap` | -| `lf_wifi_rest_example.pl` | Example script that queries a LF GUI for JSON data and displays a slice of it | -| `lf_zlt_binary.pl` | Configures a Zero Loss Throughput test | -| `list_phy_sta.sh` | Lists virtual stations backed by specified physical radio | -| `min_max_ave_station.pl` | This script looks for min-max-average bps for rx-rate in a station csv data file | -| `multi_routers.pl` | Routing cleanup script that can be used with virtual routers | -| `print_udev.sh` | Prints out Linux Udev rules describing how to name ports by MAC address | -| `sensorz.pl` | Displays temperature readings for CPU and ATH10K radios | -| `show-port-from-json.pl` | Example script showing how to display a slice from a JSON GUI response | -| `station-toggle.sh` | Use this script to toggle a set of stations on or off | -| `sysmon.sh` | grabs netdev stats and timestamp every second or so, saves to logfile. | -| `test_refcnt.pl` | creates MAC-VLANs and curl requests for each | -| `topmon.sh` | LANforge system monitor that can be used from cron | -| `wait_on_ports.pl` | waits on ports to have IP addresses, can up/down port to stimulate new DHCP lease | -| `wifi-roaming-times.pl` | parses `wpa_supplicant_log.wiphyX` file to determine roaming times | +| Name | Purpose | +| ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `associate_loop.sh` | Use this script to associate stations between SSIDs A and B | +| `attenuator_series_example.csv` | Example of CSV input for a series of attenuator settings | +| `attenuator_series.pl` | Reads a CSV of attenuator settings and replays them to CT70X programmble attenuator | +| `ftp-upload.pl` | Use this script to collect and upload station data to FTP site | +| `imix.pl` | packet loss survey tool | +| `lf_associate_ap.pl` | LANforge server script for associating virtual stations to an chosen SSID | +| `lf_attenmod.pl` | This program is used to modify the LANforge attenuator through the LANforge | +| `lf_auto_wifi_cap.pl` | This program is used to automatically run LANforge-GUI WiFi Capacity tests | +| `lf_cmc_macvlan.pl` | Stress test sets up traffic types of udp , tcp , continuously starts and stops the connections | +| `lf_create_bcast.pl` | creates a L3 broadcast connection | +| `lf_cycle_wanlinks.pl` | example of how to call lf_icemod.pl from a script | +| `lf_endp_script.pl` | create a hunt script on a L3 connection endpoint | +| `lf_firemod.pl` | queries and modifies L3 connections | +| `lf_generic_ping.pl` | Generate a batch of Generic lfping endpoints | +| `lf_gui_cmd.pl` | Initiate a stress test | +| `lf_icemod.pl` | queries and modified WANLink connections | +| `lf_ice.pl` | adds and configures wanlinks | +| `lf_l4_auth.pl` | example of scripting L4 http script with basic auth | +| `lf_l4_reset.sh` | reset any layer 4 connection that reaches 0 Mbps over last minute | +| `lf_log_parse.pl` | Convert the timestamp in LANforge logs (it is in unix-time, miliseconds) to readable date | +| `lf_loop_traffic.sh` | Repeatedly start and stop a L3 connection | +| `lf_macvlan_l4.pl` | Set up connection types: lf_udp, lf_tcp across 1 real port and many macvlan ports on 2 machines. Then continously starts and stops the connections. | +| `lf_mcast.bash` | Create a multicast L3 connection endpoint | +| `lf_monitor.pl` | Monitor L4 connections | +| `lf_nfs_io.pl` | Creates and runs NFS connections | +| `lf_parse_tshark_log.pl` | Basic parsing of tshark logs | +| `lf_portmod.pl` | Queries and changes LANforge physical and virtual ports | +| `lf_port_walk.pl` | Creates a series of connections, useful for basic firewall testing | +| `lf_show_events.pl` | Displays and clears LANforge event log | +| `lf_staggered_dl.sh` | his script starts a series of Layer-3 connections across a series of stations each station will wait $nap seconds, download $quantity KB and then remove its old CX. | +| `lf_sta_name.pl` | Use this script to alter a virtual station names | +| `lf_verify.pl` | Creates a basic L3 connection to verify that two ethernet ports are physically connected | +| `lf_voip.pl` | Creates series of VOIP connections between two LANforge machines | +| `lf_voip_test.pl` | Creates series of VOIP connections and runs them | +| `lf_vue_mod.sh` | Bash script that wraps common operations for Virtual User Endpoint operations done by `lf_associate_ap` | +| `lf_wifi_rest_example.pl` | Example script that queries a LF GUI for JSON data and displays a slice of it | +| `lf_zlt_binary.pl` | Configures a Zero Loss Throughput test | +| `list_phy_sta.sh` | Lists virtual stations backed by specified physical radio | +| `min_max_ave_station.pl` | This script looks for min-max-average bps for rx-rate in a station csv data file | +| `multi_routers.pl` | Routing cleanup script that can be used with virtual routers | +| `print_udev.sh` | Prints out Linux Udev rules describing how to name ports by MAC address | +| `sensorz.pl` | Displays temperature readings for CPU and ATH10K radios | +| `show-port-from-json.pl` | Example script showing how to display a slice from a JSON GUI response | +| `station-toggle.sh` | Use this script to toggle a set of stations on or off | +| `sysmon.sh` | grabs netdev stats and timestamp every second or so, saves to logfile. | +| `test_refcnt.pl` | creates MAC-VLANs and curl requests for each | +| `topmon.sh` | LANforge system monitor that can be used from cron | +| `wait_on_ports.pl` | waits on ports to have IP addresses, can up/down port to stimulate new DHCP lease | +| `wifi-roaming-times.pl` | parses `wpa_supplicant_log.wiphyX` file to determine roaming times | ## Compatibility @@ -225,13 +231,13 @@ See the setup steps outlined in the `py-scripts/` README [here](./py-scripts/REA To use LANforge Perl automation, the system which will run the scripts must have the following packages installed. On Linux systems, most of these packages are available through your system's package manager as `.deb` or `.rpm` packages. -| Package | RPM | Required | -| -------------------|--------------------|----------------| -| Net::Telnet | perl-Net-Telnet | Yes | -| JSON | perl-JSON | Yes, for JSON parsing | -| JSON::PrettyPrint | perl-JSON-PP | No, but useful for debugging | -| Pexpect | python3-pexpect | Yes | -| XlsxWriter | python3-xlsxwriter | Yes, for Xlsx output | +| Package | RPM | Required | +| ----------------- | ------------------ | ---------------------------- | +| Net::Telnet | perl-Net-Telnet | Yes | +| JSON | perl-JSON | Yes, for JSON parsing | +| JSON::PrettyPrint | perl-JSON-PP | No, but useful for debugging | +| Pexpect | python3-pexpect | Yes | +| XlsxWriter | python3-xlsxwriter | Yes, for Xlsx output | ## License From debdefe5aef9873b6ee158e124187bc9eccc9608 Mon Sep 17 00:00:00 2001 From: Alex Gavin Date: Tue, 14 Jan 2025 16:46:50 -0800 Subject: [PATCH 04/10] Run formatter on CONTRIBUTING.md Signed-off-by: Alex Gavin --- CONTRIBUTING.md | 54 +++++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cbc0df45..8a21bf19 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -24,7 +24,7 @@ For developer environment setup, please first follow the steps outlined in [here To avoid the headache of updating your PR and enable minimal back-and-forth, this project supports the same GitHub Actions-based automated code linting checks locally through Git pre-commit hooks. **We strongly encourage configuring pre-commit hooks before submitting a PR**, as passing automated code linting is a requirement for submission review. -If you haven't used Git pre-commit hooks before, pre-commit Git hooks are programs run locally *on commit*. This project uses the pre-commit hooks (using `pre-commit`) to run automated code linting locally, either on commit or manually by running `pre-commit run` (after setup). Pre-commit hooks can be useful for much more than automated code linting, though. Please review the `pre-commit` documentation [here](https://pre-commit.com/) for more information on pre-commit hooks as well as the `pre-commit` tool supported by this project. +If you haven't used Git pre-commit hooks before, pre-commit Git hooks are programs run locally _on commit_. This project uses the pre-commit hooks (using `pre-commit`) to run automated code linting locally, either on commit or manually by running `pre-commit run` (after setup). Pre-commit hooks can be useful for much more than automated code linting, though. Please review the `pre-commit` documentation [here](https://pre-commit.com/) for more information on pre-commit hooks as well as the `pre-commit` tool supported by this project. ### Setup @@ -34,39 +34,41 @@ To configure Git pre-commit hooks, run the following steps (assumes already setu 1. **Activate virtual environment** - Virtual environment setup steps are outlined in the developer environment setup instructions [here](./py-scripts/README.md#cloning-from-git-repository-usage). + Virtual environment setup steps are outlined in the developer environment setup instructions [here](./py-scripts/README.md#cloning-from-git-repository-usage). - Virtual environments are always a good idea for a new project, helping keep separate project - dependencies separate from each other. You can keep using this virtual environment for other dependencies of this project as well. + Virtual environments are always a good idea for a new project, helping keep separate project + dependencies separate from each other. You can keep using this virtual environment for other dependencies of this project as well. - ```Bash - # Substitute the path to your virtual environment here - # This is likely to be something in the form of 'x/bin/activate' - source venv/bin/activate - ``` + ```Bash + # Substitute the path to your virtual environment here + # This is likely to be something in the form of 'x/bin/activate' + source venv/bin/activate + ``` 2. **Install the 'pre-commit' package** - ```Bash - pip install --upgrade pip && pip install pre-commit - ``` + + ```Bash + pip install --upgrade pip && pip install pre-commit + ``` 3. **Configure this project's pre-commit hooks** - ```Bash - # The pre-commit configuration contains all required - # pre-commit hook tool installation required to setup - # local code linting tooling (flake8, black, etc.) - pre-commit install - ``` + + ```Bash + # The pre-commit configuration contains all required + # pre-commit hook tool installation required to setup + # local code linting tooling (flake8, black, etc.) + pre-commit install + ``` 4. **Run the pre-commit hook before it runs on commit** - ```Bash - # Without staged any changes, this command will simply skip every - # pre-commit step. However, it is still useful for visualizing - # the process. - # - # The same steps will run when you enter 'git commit' - pre-commit run - ``` + ```Bash + # Without staged any changes, this command will simply skip every + # pre-commit step. However, it is still useful for visualizing + # the process. + # + # The same steps will run when you enter 'git commit' + pre-commit run + ``` ### Unable to Commit Due to `pre-commit` Failure From aa688520ab3bb5495dfa81f8d9f1b4a7be2da6ac Mon Sep 17 00:00:00 2001 From: Alex Gavin Date: Tue, 14 Jan 2025 16:40:39 -0800 Subject: [PATCH 05/10] Run formatter on LF API README Signed-off-by: Alex Gavin --- lanforge_client/README.md | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/lanforge_client/README.md b/lanforge_client/README.md index e8805f1b..3a655220 100644 --- a/lanforge_client/README.md +++ b/lanforge_client/README.md @@ -4,7 +4,7 @@ This library provides a set of methods to operate the [LANforge JSON API](http://www.candelatech.com/cookbook.php?vol=cli&book=JSON:+Querying+the+LANforge+Client+for+JSON+Data). This is a generated library that includes Python classes and methods to perform JSON POSTs for every [LANforge CLI command](https://www.candelatech.com/lfcli_ug.php) and JSON GETs for JSON endpoints presented by the LANforge GUI. -If you are new to this API, please start at the beginning of the [LANforge Scripting Cookbook](http://www.candelatech.com/scripting_cookbook.php). +If you are new to this API, please start at the beginning of the [LANforge Scripting Cookbook](http://www.candelatech.com/scripting_cookbook.php). Example scripts are located in the [`examples/`](./examples/) directory. See the [`README.md`](./examples/README.md) for more information on available examples. @@ -48,32 +48,36 @@ A brief listing of available library code is as follows: ## Intended Usage ### Suggested Workflow + Generally, the workflow for a script using LANforge API will look something like: + 1. Import `lanforge_client` 2. Initiate a [`LFSession`](https://github.com/greearb/lanforge-scripts/blob/master/lanforge_client/lanforge_api.py#L24487) - - Ensure the script URI is directed at the manager LANforge for your testbed (should your testbed have more than one LANforge) - - Also make sure that the GUI is running. To configure the GUI to automatically start, see [this cookbook](https://www.candelatech.com/cookbook.php?vol=misc&book=Automatically+starting+LANforge+GUI+on+login) in the documentation. -3. Use a combination of [`LFJsonCommand`](https://github.com/greearb/lanforge-scripts/blob/master/lanforge_client/lanforge_api.py#L1392) to configure or [`LFJsonRequest`](https://github.com/greearb/lanforge-scripts/blob/master/lanforge_client/lanforge_api.py#L215) to query the LANforge, respectively. +- Ensure the script URI is directed at the manager LANforge for your testbed (should your testbed have more than one LANforge) +- Also make sure that the GUI is running. To configure the GUI to automatically start, see [this cookbook](https://www.candelatech.com/cookbook.php?vol=misc&book=Automatically+starting+LANforge+GUI+on+login) in the documentation. + +3. Use a combination of [`LFJsonCommand`](https://github.com/greearb/lanforge-scripts/blob/master/lanforge_client/lanforge_api.py#L1392) to configure or [`LFJsonRequest`](https://github.com/greearb/lanforge-scripts/blob/master/lanforge_client/lanforge_api.py#L215) to query the LANforge, respectively. ### Things to Keep in Mind -This library can be used directly, plus it can be used in conjunction with the LANforge [Realm](https://github.com/greearb/lanforge-scripts/blob/master/py-json/realm.py) class. It is different than than the *Realm* class. *Realm* extends the [lfcli_base](https://github.com/greearb/lanforge-scripts/blob/master/py-json/LANforge/lfcli_base.py) class that provides its own (nearly identical) REST API. The lanforge_client REST methods are built into the *BaseLFJsonRequest* class. -You would use the *Realm* class to execute high-level operations like: +This library can be used directly, plus it can be used in conjunction with the LANforge [Realm](https://github.com/greearb/lanforge-scripts/blob/master/py-json/realm.py) class. It is different than than the _Realm_ class. _Realm_ extends the [lfcli_base](https://github.com/greearb/lanforge-scripts/blob/master/py-json/LANforge/lfcli_base.py) class that provides its own (nearly identical) REST API. The lanforge_client REST methods are built into the _BaseLFJsonRequest_ class. + +You would use the _Realm_ class to execute high-level operations like: -* creating groups of stations -* creating numerous connections -* reporting KPI events like test results +- creating groups of stations +- creating numerous connections +- reporting KPI events like test results -You would use the *lanforge_client* package in places where: +You would use the _lanforge_client_ package in places where: -* you want direct LANforge CLI control that hides the URLs - * port specific flags - * endpoint specific flags -* to get session tracking and using callback keys -* you want an API that hides the REST URLs +- you want direct LANforge CLI control that hides the URLs + - port specific flags + - endpoint specific flags +- to get session tracking and using callback keys +- you want an API that hides the REST URLs -The Realm class is useful. As the *lanforge_client* package stabilizes, we anticipate replacing lower level parts of the *Realm* based operations to call into the *lanforge_client* package. +The Realm class is useful. As the _lanforge_client_ package stabilizes, we anticipate replacing lower level parts of the _Realm_ based operations to call into the _lanforge_client_ package. ## Getting started @@ -113,4 +117,3 @@ def main(): pprint.pprint(result) ``` - From d14906763b0e2feab2368cce41e5be608ebebb75 Mon Sep 17 00:00:00 2001 From: Alex Gavin Date: Tue, 14 Jan 2025 16:41:07 -0800 Subject: [PATCH 06/10] Run formatter on py-scripts README Signed-off-by: Alex Gavin --- py-scripts/README.md | 82 ++++++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 38 deletions(-) diff --git a/py-scripts/README.md b/py-scripts/README.md index 60681782..b2486ff3 100644 --- a/py-scripts/README.md +++ b/py-scripts/README.md @@ -1,12 +1,14 @@ # LANforge Python Scripts + This directory contains Python scripts to configure and test devices with LANforge traffic generation and network impairment systems. For more information, see the following online documentation or email [`support@candelatech.com`](mailto:support@candelatech.com) with questions. -* [LANforge Scripting Cookbook](http://www.candelatech.com/scripting_cookbook.php) -* [Querying the LANforge JSON API using Python Cookbook](https://www.candelatech.com/cookbook/cli/json-python) +- [LANforge Scripting Cookbook](http://www.candelatech.com/scripting_cookbook.php) +- [Querying the LANforge JSON API using Python Cookbook](https://www.candelatech.com/cookbook/cli/json-python) ## Setup + **NOTE: LANforge Python scripts require Python 3.7+** (which is backwards compatible to Fedora 27 systems). There are two primary methods to access LANforge scripts (either for use or development): @@ -16,9 +18,11 @@ There are two primary methods to access LANforge scripts (either for use or deve 2. [Cloning or downloading the scripts from the Git repository](#cloning-from-git-repository-usage) (repository linked [here](https://github.com/greearb/lanforge-scripts)) ### Pre-installed LANforge System Usage + On pre-installed LANforge systems, LANforge scripts are installed in `/home/lanforge/scripts/py-scripts/`. No further setup is required (dependencies come pre-installed). These pre-installed scripts match the LANforge software version on the system. ### Cloning from Git Repository Usage + **NOTE:** This process is generally for more advanced users or developers. However, customers under support may email [`support@candelatech.com`](mailto:support@candelatech.com) with any questions, and we can guide you through. For users who clone or download these scripts from the Git repo, some setup is required. @@ -26,6 +30,7 @@ For users who clone or download these scripts from the Git repo, some setup is r We assume you are familiar with the command line (e.g. `bash`) and already have both Python and Git installed (recall that Python 3.7 is the minimum supported version). Please complete the following two steps before running LANforge scripts on a non-LANforge system (outlined in this [section](#setup-instructions)): + 1. Ensure that the LANforge scripts version cloned matches your LANforge system version - It is possible to run with the latest version, but this is not recommended 2. Install the required LANforge scripts dependencies @@ -37,52 +42,51 @@ Please complete the following two steps before running LANforge scripts on a non 1. Open a shell and clone LANforge scripts - ```Bash - git clone https://github.com/greearb/lanforge-scripts - ``` + ```Bash + git clone https://github.com/greearb/lanforge-scripts + ``` 2. Get the version-tagged commits of the repository - ```Bash - git fetch --tags - ``` + ```Bash + git fetch --tags + ``` 3. List the version-tagged commits available - ```Bash - git tag - ``` + ```Bash + git tag + ``` 4. Select the matching tag for your LANforge system's version - ```Bash - # Checkout LANforge 5.4.7 version of LANforge scripts. - git checkout lf-5.4.7 - ``` + ```Bash + # Checkout LANforge 5.4.7 version of LANforge scripts. + git checkout lf-5.4.7 + ``` 5. Create and source a Python virtual environment (optional but **strongly suggested**) - We suggest Python's [builtin virtual environment tool](https://docs.python.org/3/tutorial/venv.html) for simplicity, although other tools requiring more configuration like [Anaconda](https://anaconda.org/) will work as well. + We suggest Python's [builtin virtual environment tool](https://docs.python.org/3/tutorial/venv.html) for simplicity, although other tools requiring more configuration like [Anaconda](https://anaconda.org/) will work as well. - ```Bash - # Create Python virtual environment named 'venv' - virtualenv venv + ```Bash + # Create Python virtual environment named 'venv' + virtualenv venv - # Enter the Python virtual environment (Linux) - source venv/bin/activate - ``` + # Enter the Python virtual environment (Linux) + source venv/bin/activate + ``` 6. Enter the `lanforge-scripts/py-scripts/` directory 7. Run the dependency installation script - ```Bash - ./update_dependencies.py - ``` + ```Bash + ./update_dependencies.py + ``` Once you have successfully completed these steps, you can now use the LANforge Python scripts. - ## Using LANforge Python Scripts There are many scripts available within not just the LANforge Python scripts but the entire LANforge scripts repository. While we recognize and continue to address documenting these scripts, this section details some information that may be useful when using these scripts. @@ -93,28 +97,30 @@ To learn more about automating Chamber View tests like TR-398, WiFi Capacity Tes ### LANforge Python Scripts in py-scripts General Classifications -* create_ - creates network element in LANforge wiphy radio -* lf_ or test_ - performs a test against an Access Point or Wifi network -* other files are various utilities +- create\_ - creates network element in LANforge wiphy radio +- lf* or test* - performs a test against an Access Point or Wifi network +- other files are various utilities ## LANforge Python Scripts Directory Structure -* py-scripts - configuration, unit test, module, and library scripts -* cv_examples - bash scripts for ochastrating Chamberview tests -* py-json - core libraries providing direct intraction with LANforge Traffic Generator -* py-json/LANforge - JSON intraction with LANforge Traffic Generator. -* lanforge_client/ - alpha version of JSON interface to LANforge Traffic Generator. + +- py-scripts - configuration, unit test, module, and library scripts +- cv_examples - bash scripts for ochastrating Chamberview tests +- py-json - core libraries providing direct intraction with LANforge Traffic Generator +- py-json/LANforge - JSON intraction with LANforge Traffic Generator. +- lanforge_client/ - alpha version of JSON interface to LANforge Traffic Generator. ## Scripts accessing Serial ports. + On Linux, you must explicitly allow users to access serial devices. Otherwise, using a USB serial device requires root permissions (e.g. have to use `sudo`). There are several methods to do so, each depending on the distribution (all requiring root access to the system). Often the easiest is to perform the following: 1. Add your user to the `dialout` and `tty` groups - ```Bash - sudo usermod -a -G dialout,tty $USER - ``` + ```Bash + sudo usermod -a -G dialout,tty $USER + ``` 2. Log out and log back in (full logout required, not just closing the terminal) - - Can also run the `newgrp` command, but this will only affect the currently running login session (i.e. that shell) + - Can also run the `newgrp` command, but this will only affect the currently running login session (i.e. that shell) From b0d20bb72e6995704d644d8fc0d967330cabc17a Mon Sep 17 00:00:00 2001 From: Alex Gavin Date: Tue, 14 Jan 2025 16:41:35 -0800 Subject: [PATCH 07/10] Run formatter on CV examples README Signed-off-by: Alex Gavin --- py-scripts/cv_examples/README.md | 44 ++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/py-scripts/cv_examples/README.md b/py-scripts/cv_examples/README.md index 445eb2a7..ea3b5bfa 100644 --- a/py-scripts/cv_examples/README.md +++ b/py-scripts/cv_examples/README.md @@ -1,18 +1,17 @@ # Chamber View Automation Examples - ## Overview + **The examples in this directory demonstrate how to use LANforge scripts to automate Chamber View tests.** The Chamber View test suite is a well-utilized LANforge feature. Primarily focused on WiFi, these tests enable users to consistently and easily test their DUT WiFi equipment in a variety of scenarios. In addition to real-time test visualization, these tests also generate comprehensive reports and CSV data for later reference. While a user can manually configure a test to their liking, save the database, and then re-run the exact same test, automated test invocation saves time and reduces potential for errors. LANforge offers a variety of scripts which can meet this goal, especially when used together. **However, it can be difficult to determine what scripts to use and how exactly to use them. This document and associated examples demonstrate how to do just that.** - - ## Example Test Automation + | Chamber View Test | Automation Script | -|-----------------------|------------------------------------------------------------------------------------| +| --------------------- | ---------------------------------------------------------------------------------- | | AP-Auto | [`AP-Auto.bash`](./AP-Auto/AP-Auto.bash) | | Continuous Throughput | [`Continuous_Throughput.bash`](./Continuous_Throughput/Continuous_Throughput.bash) | | Dataplane | [`Dataplane.bash`](./Dataplane/Dataplane.bash) | @@ -21,74 +20,82 @@ While a user can manually configure a test to their liking, save the database, a | TR-398 Issue 4 | [`TR-398_Issue_4.bash`](./TR-398_Issue_4/TR-398_Issue_4.bash) | | WiFi Capacity | [`WiFi_Capacity.bash`](./WiFi_Capacity/WiFi_Capacity.bash) | - - ## Automating Chamber View in Your Testbed As your use case for a given Chamber View test will be different than the examples shown, you will inevitably craft and adjust your automation scripts as your goals evolve. **To customize your scripts, we suggest the following workflow, which was used to create the examples in this directory.** ### Step 1: Manual Setup + In order to automate your Chamber View testing, you must first manually configure the test scenario. -#### 1. Create a DUT under the 'DUT' GUI tab +#### 1. Create a DUT under the 'DUT' GUI tab + - The minimum DUT configuration required to run any meaningful Chamber View tests is: - - DUT Name - - At least one SSID with relevant authentication parameters + - DUT Name + - At least one SSID with relevant authentication parameters - We suggest specifying AP BSSIDs per SSID and enabling 'Provides DHCP on LAN', should these options be relevant. - - Setting specific AP BSSIDs enables STAs created in Chamber View Scenarios to associate to only the selected BSSIDs (more info in next step). - - Enabling 'Provides DHCP on LAN' similarly allows LAN upstream ports to automatically enable DHCP on bringup. + - Setting specific AP BSSIDs enables STAs created in Chamber View Scenarios to associate to only the selected BSSIDs (more info in next step). + - Enabling 'Provides DHCP on LAN' similarly allows LAN upstream ports to automatically enable DHCP on bringup. #### 2. Manually Create and Build a Chamber View Scenario + Specific configuration will depend on the test you're configuring, but generally we suggest configuring an upstream which maps to your DUT. See [Chamber View Scenarios (and Test Assumptions)](#chamber-view-scenarios-and-test-assumptions) for more information on configuring Chamber View Scenarios. #### 3. Manually configure your Chamber View test as desired in the GUI + **NOTE:** Make sure to enable options like 'Auto Save Report' and 'Collect CSV Data', should those options be relevant. Specific configuration depends on the test you're configuring, but generally you should configure and run the test to verify that your configuration (both in software and physically) works as you expect. #### 4. Save the LANforge Configuration + As you will likely need this configuration in the future, be it exactly or as a fallback, we suggest you save the current configuration in a new database. 1. Navigate to the 'Status' tab. 2. In the top right corner, use the 'Saved Test Configurations' section to save a new database. - - You can reset to this configuration by selecting a saved configuration and clicking 'Load'. - - **NOTE:** Loading a database will overwrite any existing configuration on the testbed. + - You can reset to this configuration by selecting a saved configuration and clicking 'Load'. + - **NOTE:** Loading a database will overwrite any existing configuration on the testbed. ### Step 2: Scripting Setup #### 1. Transfer the test configuration to your script + **NOTE:** Do not transfer TR-398 test configuration between testbeds. Calibration data for your testbed is stored in the configuration, so transferring configuration from one testbed to another will overwrite the receiving testbed's calibration. 1. In your working, manually-configured Chamber View test, navigate to the 'Advanced Configuration' tab of the Chamber View test. 2. Click 'Show Config' - - A pop-up window with configuration data will appear. + - A pop-up window with configuration data will appear. 3. Select the entire config (Ctrl-A) and copy it to your clipboard (Ctrl-C). 4. Navigate to the where you will keep your test configs (e.g. to a directory on the LANforge system). 5. Open a new file in your preferred text editor and paste the contents (the test config) to the new file. #### 2. Adjust the script to reflect your configured Chamber View Scenario + 1. Navigate to 'Chamber View' by selecting the 'Chamber View' button at the top of the main LANforge GUI. 2. In the top right of the 'Chamber View' GUI under the 'Manage Scenarios' button, select the Chamber View Scenario for your test that you configured previously. 3. With the desired scenario selected, click 'Manage Scenarios'. 4. In the pop-up 'Create/Modify Scenario' GUI, click the 'Text Output' tab. 5. For each line in the 'Text Output' box, enter the text into a `--raw_line` option where your script invokes the `create_chamberview.py` script. - - See the [example scripts](#chamber-view-automation-examples) for example usage. + - See the [example scripts](#chamber-view-automation-examples) for example usage. #### 3. Adjust the script to reference the new test configuration + **NOTE:** If you specify an option on the command line that is different from the configuration file, the command line argument will take precedent. - Depending on how you wrote your script, this may be by changing the command line arguments you invoke the script with or adjusting variables within the script. - - Scripting examples here use environment variables set at the top of the script to configure the arguments passed to each script. + - Scripting examples here use environment variables set at the top of the script to configure the arguments passed to each script. - If using an example script, adjust the `TEST_CFG` variable to point to your config file. #### 4. Repeat as you adjust your Chamber View Scenario and Chamber View test configuration -- Any time you adjust the Chamber View test configuration in the GUI, repeat the [transfer the test configuration](#1-transfer-the-test-configuration-to-your-script), the [reflect the scenario](#2-adjust-the-script-to-reflect-your-configured-chamber-view-scenario), and [reference the configuration](#3-adjust-the-script-to-reference-the-new-test-configuration) steps to transfer the test configuration to your script. If you do not, the script will not use the changes you made. +- Any time you adjust the Chamber View test configuration in the GUI, repeat the [transfer the test configuration](#1-transfer-the-test-configuration-to-your-script), the [reflect the scenario](#2-adjust-the-script-to-reflect-your-configured-chamber-view-scenario), and [reference the configuration](#3-adjust-the-script-to-reference-the-new-test-configuration) steps to transfer the test configuration to your script. If you do not, the script will not use the changes you made. ## Chamber View Scenarios (and Test Assumptions) + ### Overview + Chamber View and Chamber View Scenarios generally aim to make the process of running complex and/or large-scale tests easier. Rather than configure the testbed by hand for every test run, Chamber View allows a user to reproduce a test consistently and easily. Chamber View Scenarios play a key role in this process of reproducible tests. Where a Chamber View test can be considered the process of making a recipe, a Chamber View Scenario would be the ingredients list, something gathered and prepared before cooking. @@ -96,12 +103,15 @@ Chamber View Scenarios play a key role in this process of reproducible tests. Wh Just as a recipe assumes specific ingredient preparation, each Chamber View test assumes specific testbed configuration. Some Chamber View tests like 'WiFi Capacity' test assume the testbed is fully configured before test invocation. Other tests like the TR-398 suite assume some pre-configuration but do some of their own configuration as well. **All tests assume some configuration, though. That configuration is a Chamber View Scenario.** **The following is configuration assumed by all Chamber View tests:** + - DUT configured as desired (including as a DUT object in LANforge) - A LANforge port configured as an 'Upstream' profile in a Chamber View Scenario - The Chamber View Scenario is applied and built successfully ### Chamber View Scenarios In Automation Scripts + The general workflow for configuring a scripted Chamber View test (and manual test) is as follows: + 1. Create DUT 2. Create and build Chamber View Scenario 3. Run the Chamber View test From 0735ada3c391eeea69acad31dfba629fcd3decd9 Mon Sep 17 00:00:00 2001 From: Alex Gavin Date: Tue, 14 Jan 2025 16:42:35 -0800 Subject: [PATCH 08/10] py-scripts/sandbox: Update README Signed-off-by: Alex Gavin --- py-scripts/sandbox/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py-scripts/sandbox/README.md b/py-scripts/sandbox/README.md index 66e18049..9cf8a163 100644 --- a/py-scripts/sandbox/README.md +++ b/py-scripts/sandbox/README.md @@ -1,3 +1,3 @@ # LANforge Scripts Sandbox -Staging area for new LANforge scripts. \ No newline at end of file +Staging area for new LANforge scripts, in various states of functionality. From f9b11a990b27f495d4e0d3e7e8ce35c85bef387c Mon Sep 17 00:00:00 2001 From: Alex Gavin Date: Tue, 14 Jan 2025 16:44:38 -0800 Subject: [PATCH 09/10] archive: Add README Signed-off-by: Alex Gavin --- archive/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 archive/README.md diff --git a/archive/README.md b/archive/README.md new file mode 100644 index 00000000..f3ba0d6d --- /dev/null +++ b/archive/README.md @@ -0,0 +1,3 @@ +# Archive + +An archive of no longer supported LANforge scripts and automation. Primarily retained as a reference for future work. From 30a78318de9f857da860e308ad1e351dfa942861 Mon Sep 17 00:00:00 2001 From: Alex Gavin Date: Tue, 14 Jan 2025 16:45:54 -0800 Subject: [PATCH 10/10] Update to Python-focused .gitignore from GitHub Original contents here: https://github.com/github/gitignore/blob/ceea7cab239eece5cb9fd9416e433a9497c2d747/Python.gitignore Signed-off-by: Alex Gavin --- .gitignore | 181 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 171 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 7d4a05e9..15201acc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,171 @@ -*.bash.txt -*.sh.txt -*.pl.txt -*~ -*.iml -**/*.iml -.idea -*.env -*.zip -**/__pycache__ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# UV +# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +#uv.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/latest/usage/project/#working-with-version-control +.pdm.toml +.pdm-python +.pdm-build/ + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +# PyPI configuration file +.pypirc