diff --git a/gui/README.txt b/gui/README.txt index 6898d3a3..42c93511 100644 --- a/gui/README.txt +++ b/gui/README.txt @@ -57,3 +57,9 @@ test configuration through the GUI. Check /tmp/lf_reports for the report files. + + +The cicd and testbeds directories contain some code that came from another CICD implementation +Candela worked on. It is a good starting point, but will need modifications before it fully +works for your test bed. + diff --git a/gui/cicd/README.txt b/gui/cicd/README.txt new file mode 100644 index 00000000..bb1cfc1f --- /dev/null +++ b/gui/cicd/README.txt @@ -0,0 +1,104 @@ +Potential polling method for CICD integration. + +* Polling should decrease network security head-aches such as setting + up VPN access for all test beds. + +*** + +Implementation: + +* Web server accessible to all CICD test beds runs a 'test orchestrator' logic, henceforth TO + * This TO will periodically query jfrog for latest openwrt builds (see jfrog.pl) + * If new build is found, a work-item file containing pertinent info, including the HW platform + will be created, example: + +CICD_TYPE=fast +CICD_RPT_NAME=ea8300 +CICD_RPT_DIR=greearb@192.168.100.195:/var/www/html/myco/testbeds//ferndale-basic-01/reports +CICD_HW=ea8300 +CICD_FILEDATE= +CICD_GITHASH= +CICD_URL=https://myco.jfrog.io/artifactory/wlan-ap-firmware/ +CICD_FILE_NAME=ea8300 +CICD_URL_DATE=24-Apr-2020 16:32 + + * TO has manually configured list of test-beds, with some info about each test + bed, including the DUT HW platform and testing capabilities. + * It picks a test bed that matches the new build HW. + * That test bed will have a URL directory for it and it alone. + * The TO writes a new test configuration file into this directory. + The test configuration file will have the info above, and also have other + info including the tests to run and where to upload results when complete. + * TO looks for any completed results, and removes the work-item if result is found. + * TO will re-calculate historical charts and publish those if new results are found for a testbed. + It could generate email and/or poke the results into testrails or similar at this point. + * TO should run periodically every 1 minute or so to check on progress. + + +* Test bed polling: + * The test-bed (hence forth TB) will poll its directory on the TO web server to look for new jobs. + * When new job is found, the TB will download the test config file, and use scp to upload a file + to the TO to indicate it is working on the test. + * When test is complete, TB will upload results to TO server. TO now knows test bed is available + for more jobs. + * TB should pause for 2 minutes after uploading results to make sure TO notices the new results and + removes the old work item so that TB does not re-test the same work item. + + + +************* Installation / Usage *************** + +The jfrog.pl runs on the web server. This is the Test Orchestrator. +Create a directory structure looking similar to this: + +[greearb@ben-dt4 html]$ find myco -name "*" -print +myco +myco/testbeds +myco/testbeds/ferndale-basic-01 +myco/testbeds/ferndale-basic-01/pending_work +myco/testbeds/ferndale-basic-01/reports + +Copy the TESTBED_INFO from testbeds directory to the myco/testbeds directory: + +[greearb@ben-dt4 testbeds]$ pwd +/var/www/html/myco/testbeds +cp -ar /home/greearb/git/lanforge-scripts/gui/cicd/ferndale-basic-01/ ./ + + +Run the jfrog.pl script from the myco/testbeds directory: + +/home/greearb/git/lanforge-scripts/gui/cicd/cicd/jfrog.pl --passwd secret --tb_url_base greearb@192.168.100.195:/var/www/html/myco/testbeds/ + +A work-item file will be created as needed, in my case, it is here: + +[greearb@ben-dt4 testbeds]$ cat ferndale-basic-01/pending_work/fast/CICD_TEST-ea8300 +CICD_TEST=fast +CICD_RPT_DIR=greearb@192.168.100.195:/var/www/html/myco/testbeds//ferndale-basic-01/reports/fast +CICD_RPT_NAME=ea8300 +CICD_HW=ea8300 +CICD_FILEDATE= +CICD_GITHASH= +CICD_URL=https://myco.jfrog.io/artifactory/wlan-ap-firmware/ +CICD_FILE_NAME=ea8300 +CICD_URL_DATE=24-Apr-2020 16:32 + + + +************ Installation / Usage on Test Controller ************** + +# This runs on the test controller or Jump-Box. + +# Set up OS +sudo needs to work w/out password. + +sudo chmod a+rwx /dev/ttyUSB* +sudo pip3 install pexpect-serial + +Run testbed_poll.pl from the cicd testbed directory: + +The 192.168.100.195 system is the jfrog / Orchestrator machine. The jfrog +password is so that it can download the OpenWrt binary file from jfrog. + +cd ~/git/lanforge-scripts/gui/cicd/ferndale-basic-01 + +../testbed_poll.pl --jfrog_passwd secret --url http://192.168.100.195/myco/testbeds/testbed-ferndale-01/pending_work/ diff --git a/gui/cicd/ferndale-basic-01/TESTBED_INFO.txt b/gui/cicd/ferndale-basic-01/TESTBED_INFO.txt new file mode 100644 index 00000000..0db49f43 --- /dev/null +++ b/gui/cicd/ferndale-basic-01/TESTBED_INFO.txt @@ -0,0 +1,7 @@ +TESTBED_HW=ea8300 + +# Controller's view of the test bed, from wlan-testing/cicd/[testbed] directory +TESTBED_DIR=../../testbeds/ferndale-basic-01 + +TESTBED_CASEID_FAST=C1308 +TESTBED_CASEID_BASIC=C1309 diff --git a/gui/cicd/jfrog.pl b/gui/cicd/jfrog.pl new file mode 100755 index 00000000..d136e3cb --- /dev/null +++ b/gui/cicd/jfrog.pl @@ -0,0 +1,379 @@ +#!/usr/bin/perl + +# Query jfrog URL and get list of builds. +# This will be run on the test-bed orchestrator +# Run this in directory that contains the testbed_$hw/ directories +# Assumes cicd.class is found in ~/git/lanforge-scripts/gui/ + +use strict; +use warnings; +use Getopt::Long; + +my $user = "cicd_user"; +my $passwd = ""; +my $url = "https://myco.jfrog.io/artifactory/wlan-ap-firmware"; +my @platforms = ("ea8300", "ecw5410"); # Add more here as we have test beds that support them. +my $files_processed = "jfrog_files_processed.txt"; +my $tb_url_base = "cicd_user\@myco.cicd.cloud.com/testbeds"; # Used by SSH: scp -R results_dir cicd_user@myco.cicd.cloud.com/testbeds/ +my $help = 0; +my $cicd_prefix = "CICD_TEST"; +my $kpi_dir = "/home/greearb/git/lanforge-scripts/gui/"; +my @ttypes = ("fast", "basic"); +my $duplicate_work = 1; + +my $ul_host = "www"; +my $ul_dir = "candela_html/examples/cicd/"; # used by scp +my $ul_dest = "$ul_host:$ul_dir"; # used by scp +my $other_ul_dest = ""; # used by scp +my $result_url_base = "http://localhost/myco/cicd"; + +my $usage = qq($0 + [--user { jfrog user (default: cicd_user) } + [--passwd { jfrog password } + [--result_url_base { http://foo.com/myco/cicd } + [--url { jfrog URL, default is OpenWrt URL: https://myco.jfrog.io/artifactory/wlan-ap-firmware/ } + [--files_processed { text file containing file names we have already processed } + [--tb_url_base { Where to report the test results? } + +Example: + +# Use MY-CO jfrog repo +$0 --user cicd_user --passwd secret --url https://myco.jfrog.io/artifactory/wlan-ap-firmware/ \\ + --files_processed jfrog_files_processed.txt \\ + --tb_url_base cicd_user\@myco.cicd.cloud.com/testbeds + +# Download images from candelatech.com web site (for developer testing and such) +$0 --tb_url_base greearb@192.168.100.195:/var/www/html/myco/testbeds/ \\ + --url http://www.candelatech.com/downloads/myco/test_images + +); + +GetOptions +( + 'user=s' => \$user, + 'passwd=s' => \$passwd, + 'url=s' => \$url, + 'files_processed=s' => \$files_processed, + 'tb_url_base=s' => \$tb_url_base, + 'result_url_base=s' => \$result_url_base, + 'help|?' => \$help, +) || (print($usage) && exit(1)); + +if ($help) { + print($usage) && exit(0); +} + +#if ($passwd eq "") { +# print("ERROR: You must specify jfrog password.\n"); +# exit(1); +#} + +my $i; + +my $pwd = `pwd`; +chomp($pwd); + +my $listing; +my @lines; +my $j; + +# Check for any completed reports. +for ($j = 0; $j<@ttypes; $j++) { + my $ttype = $ttypes[$j]; + $listing = `ls */reports/$ttype/NEW_RESULTS-*`; + @lines = split(/\n/, $listing); + for ($i = 0; $i<@lines; $i++) { + my $ln = $lines[$i]; + chomp($ln); + if ($ln =~ /(.*)\/NEW_RESULTS/) { + my $process = $1; # For example: ben-home/reports/fast + my $completed = `cat $ln`; # Contents of the results file + chomp($completed); + if ($ln =~ /(.*)\/reports\/$ttype\/NEW_RESULTS/) { + my $tbed = $1; + my $cmd; + my $caseid = ""; + + print "Processing new results, line: $ln process: $process completed: $completed testbed: $tbed\n"; + + # Figure out the new directory from the work-item. + my $wi = `cat ./$tbed/pending_work/$completed`; + + `mv ./$tbed/pending_work/$completed /tmp/`; + + if ($wi =~ /CICD_CASE_ID=(\S+)/) { + $caseid = "--caseid $1"; + } + + if ($wi =~ /CICD_RPT_NAME=(.*)/) { + my $widir = $1; + + # Ensure we have a place to copy the new report + $cmd = "ssh $ul_host \"mkdir -p $ul_dir/$tbed/$ttype\""; + print "Ensure directory exists: $cmd\n"; + `$cmd`; + + # Upload the report directory + $cmd = "scp -C -r $process/$widir $ul_dest/$tbed/$ttype/"; + print "Uploading: $cmd\n"; + `$cmd`; + + $caseid .= " --results_url $result_url_base/$tbed/$ttype/$widir"; + } + else { + print "WARNING: No CICD_RPT_NAME line found in work-item contents:\n$wi\n"; + } + + $cmd = "cd $kpi_dir && java kpi $caseid --dir \"$pwd/$process\" && cd -"; + print ("Running kpi: $cmd\n"); + `$cmd`; + `rm $ln`; + $cmd = "scp -C $process/*.png $process/*.html $process/*.csv $process/*.ico $process/*.css $ul_dest/$tbed/$ttype/"; + print "Uploading: $cmd"; + `$cmd`; + + # This might need similar partial-upload logic as that above, if it is ever actually + # enabled. + if ($other_ul_dest ne "") { + $cmd = "scp -C -r $process $other_ul_dest/$tbed/"; + print "Uploading to secondary location: $cmd"; + `$cmd`; + } + } + } + } +} + +#Read in already_processed builds +my @processed = (); +$listing = `cat $files_processed`; +@lines = split(/\n/, $listing); +for ($i = 0; $i<@lines; $i++) { + my $ln = $lines[$i]; + chomp($ln); + print("Reported already processed: $ln\n"); + push(@processed, $ln); +} + +my $z; +for ($z = 0; $z<@platforms; $z++) { + my $pf = $platforms[$z]; + my $cmd = "curl -u $user:$passwd $url/$pf/"; + print ("Calling command: $cmd\n"); + $listing = `$cmd`; + @lines = split(/\n/, $listing); + for ($i = 0; $i<@lines; $i++) { + my $ln = $lines[$i]; + chomp($ln); + + #print("ln -:$ln:-\n"); + + if (($ln =~ /href=\"(.*)\">(.*)<\/a>\s+(.*)\s+\S+\s+\S+/) + || ($ln =~ /class=\"indexcolname\">(.*)<\/a>.*class=\"indexcollastmod\">(\S+)\s+.*/)) { + my $fname = $1; + my $name = $2; + my $date = $3; + + # Skip header + if ($ln =~ /Last modified/) { + next; + } + + # Skip parent-dir + if ($ln =~ /Parent Directory/) { + next; + } + + #print("line matched -:$ln:-\n"); + #print("fname: $fname name: $name date: $date\n"); + + if ( grep( /^$fname\s+/, @processed ) ) { + # Skip this one, already processed. + next; + } + + my $hw = ""; + my $fdate = ""; + my $githash = ""; + + if ($fname =~ /^(\S+)-(\d\d\d\d-\d\d-\d\d)-(\S+).tar.gz/) { + $hw = $1; + $fdate = $2; + $githash = $3; + } else { + print "ERROR: Un-handled filename syntax: $fname, assuming file-name is hardware name.\n"; + $hw = $fname; + } + + # Find the least used testbed for this hardware. + my $dirs = `ls`; + my @dira = split(/\n/, $dirs); + my $best_tb = ""; + my $best_backlog = 0; + my $di; + for ($di = 0; $di<@dira; $di++) { + my $dname = $dira[$di]; + chomp($dname); + if (! -d $dname) { + next; + } + if (! -f "$dname/TESTBED_INFO.txt") { + next; + } + my $tb_info = `cat $dname/TESTBED_INFO.txt`; + my $tb_hw_type = ""; + if ($tb_info =~ /TESTBED_HW=(.*)/g) { + $tb_hw_type = $1; + } + if (!hw_matches($tb_hw_type, $hw)) { + print "Skipping test bed $dname, jfrog hardware type: -:$hw:- testbed hardware type: -:$tb_hw_type:-\n"; + next; + } + print "Checking testbed $dname backlog..\n"; + my $bklog = `ls $dname/pending_work/$cicd_prefix-*`; + my $bklog_count = split(/\n/, $bklog); + if ($best_tb eq "") { + $best_tb = $dname; + $best_backlog = $bklog_count; + } else { + if ($best_backlog > $bklog_count) { + $best_tb = $dname; + $best_backlog = $bklog_count; + } + } + } + + if ($best_tb eq "") { + print "ERROR: No test bed found for hardware type: $hw\n"; + last; + } + + my $fname_nogz = $fname; + if ($fname =~ /(.*)\.tar\.gz/) { + $fname_nogz = $1; + } + + my @tbs = ($best_tb); + + # For more test coverage, send work to rest of the available test beds as well. + if ($duplicate_work) { + for ($di = 0; $di<@dira; $di++) { + my $dname = $dira[$di]; + chomp($dname); + if (! -d $dname) { + next; + } + if ($dname eq $best_tb) { + next; # processed this one above + } + if (! -f "$dname/TESTBED_INFO.txt") { + next; + } + + my $tb_info = `cat $dname/TESTBED_INFO.txt`; + my $tb_hw_type = ""; + if ($tb_info =~ /TESTBED_HW=(.*)/g) { + $tb_hw_type = $1; + } + + if (!hw_matches($tb_hw_type, $hw)) { + print "Skipping test bed $dname, jfrog hardware type: -:$hw:- testbed hardware type: -:$tb_hw_type:-\n"; + next; + } + + push(@tbs, "$dname"); + } + } + + my $q; + for ($q = 0; $q < @tbs; $q++) { + $best_tb = $tbs[$q]; + my $caseid_fast = ""; + my $caseid_basic = ""; + + my $tb_info = `cat $best_tb/TESTBED_INFO.txt`; + if ($tb_info =~ /TESTBED_CASEID_FAST=(.*)/g) { + $caseid_fast = $1; + } + if ($tb_info =~ /TESTBED_CASEID_BASIC=(.*)/g) { + $caseid_basic = $1; + } + + my $ttype = "fast"; + my $work_fname = "$best_tb/pending_work/$cicd_prefix-$fname_nogz-$ttype"; + my $work_fname_a = $work_fname; + + system("mkdir -p $best_tb/pending_work"); + system("mkdir -p $best_tb/reports/$ttype"); + + open(FILE, ">", "$work_fname"); + + print FILE "CICD_TYPE=$ttype\n"; + print FILE "CICD_RPT_NAME=$fname_nogz\n"; + print FILE "CICD_RPT_DIR=$tb_url_base/$best_tb/reports/$ttype\n"; + + print FILE "CICD_HW=$hw\nCICD_FILEDATE=$fdate\nCICD_GITHASH=$githash\n"; + print FILE "CICD_URL=$url/$pf\nCICD_FILE_NAME=$fname\nCICD_URL_DATE=$date\n"; + if ($caseid_fast ne "") { + print FILE "CICD_CASE_ID=$caseid_fast\n"; + } + + close(FILE); + + print("Next: File Name: $fname Display Name: $name Date: $date TType: $ttype\n"); + print("Work item placed at: $work_fname\n"); + + + $ttype = "basic"; + $work_fname = "$best_tb/pending_work/$cicd_prefix-$fname_nogz-$ttype"; + + system("mkdir -p $best_tb/reports/$ttype"); + + open(FILE, ">", "$work_fname"); + + print FILE "CICD_TYPE=$ttype\n"; + print FILE "CICD_RPT_NAME=$fname_nogz\n"; + print FILE "CICD_RPT_DIR=$tb_url_base/$best_tb/reports/$ttype\n"; + + print FILE "CICD_HW=$hw\nCICD_FILEDATE=$fdate\nCICD_GITHASH=$githash\n"; + print FILE "CICD_URL=$url/$pf\nCICD_FILE_NAME=$fname\nCICD_URL_DATE=$date\n"; + if ($caseid_basic ne "") { + print FILE "CICD_CASE_ID=$caseid_basic\n"; + } + + close(FILE); + + print("Next: File Name: $fname Display Name: $name Date: $date TType: $ttype\n"); + print("Work item placed at: $work_fname\n"); + #print("To download: curl --location -o /tmp/$fname -u $user:$passwd $url/$pf/$fname\n"); + } # for all testbeds + + # Note this one is processed + `echo -n "$fname " >> $files_processed`; + `date >> $files_processed`; + } + + #print "$ln\n"; + }# for all lines in a directory listing +}# for all URLs to process + +exit 0; + + +sub hw_matches { + my $a = shift; + my $b = shift; + + # Normalize equivalent HW types. + if ($a eq "mr8300") { + $a = "ea8300"; + } + if ($b eq "mr8300") { + $b = "ea8300"; + } + + if ($a eq $b) { + return 1; + } + return 0; +} diff --git a/gui/cicd/testbed_poll.pl b/gui/cicd/testbed_poll.pl new file mode 100755 index 00000000..d2c76103 --- /dev/null +++ b/gui/cicd/testbed_poll.pl @@ -0,0 +1,449 @@ +#!/usr/bin/perl + +# Query test-bed orchestator URL to see if there are new tests for us to run. +# This is expected to be run on the test-bed controller (not orchestrator) +# One of these processes will run for each test bed controlled by the controller. + +use strict; +use warnings; +use Getopt::Long; + +my $user = ""; +my $passwd = ""; +my $jfrog_user = "cicd_user"; +my $jfrog_passwd = ""; +my $url = ""; +my $next_info = "__next_test.txt"; +my $help = 0; +my $owt_log = ""; +my $log = ""; + +my $usage = qq($0 + [--jfrog_user { jfrog user (default: cicd_user) } + [--jfrog_passwd { jfrog password } + [--user { for accessing URL } + [--passwd { for accessing URL } + [--url { test-orchestrator URL for this test bed } + [--next_info { output text file containing info about the next test to process } + [--log {location} For instance: --log stdout, for openwrt_ctl expect script. + +Example: +$0 --user to_user --passwd secret --jfrog_user myco-read --jfrog_passwd myco-read \\ + --url https://myco.cicd.mycloud.com/testbed-ferndale-01/ + +# Use specific scenario file. +SCENARIO_CFG_FILE=/home/lanforge/git/wlan-testing/testbeds/ferndale-basic-01/scenario_small.txt \\ + ../testbed_poll.pl --jfrog_passwd myco-read --jfrog_user myco-read \\ + --url http://192.168.100.195/myco/testbeds/ferndale-basic-01/pending_work/ + +); + +GetOptions +( + 'jfrog_user=s' => \$jfrog_user, + 'jfrog_passwd=s' => \$jfrog_passwd, + 'user=s' => \$user, + 'passwd=s' => \$passwd, + 'url=s' => \$url, + 'next_info=s' => \$next_info, + 'log=s' => \$log, + 'help|?' => \$help, +) || (print($usage) && exit(1)); + +if ($help) { + print($usage) && exit(0); +} + +if ($jfrog_passwd eq "") { + print("ERROR: You must specify jfrog password.\n"); + exit(1); +} + +if ($user ne "" && $passwd eq "") { + print("ERROR: You must specify a password if specifying a user.\n"); + exit(1); +} + +if ($log ne "") { + $owt_log = "--log $log"; +} + +my $i; + +my $cuser = "-u $user:$passwd"; +if ($user eq "") { + $cuser = ""; +} + +my $cmd = "curl $cuser $url"; + +print_note("Checking Test-Orchestrator for new work-items"); +my $listing = do_system($cmd); +my @lines = split(/\n/, $listing); + +# First, if any have 'fast' in them, they get precedence. +for ($i = 0; $i<@lines; $i++) { + my $ln = $lines[$i]; + chomp($ln); + my $fast = 0; + if ($ln =~ /href=\"(CICD_TEST-.*-fast)\">(.*)<\/a>\s+(.*)\s+\S+\s+\S+/) { + $fast = 1; + } + elsif ($ln =~ /href=\"(CICD_TEST-.*-fast)\">(.*)<\/a>/) { + $fast = 1; + } + if ($fast) { + @lines[0] = $ln; + last; + } +} + +for ($i = 0; $i<@lines; $i++) { + my $ln = $lines[$i]; + chomp($ln); + + my $fname = ""; + my $name = ""; + my $date = ""; + + if ($ln =~ /href=\"(CICD_TEST-.*)\">(.*)<\/a>\s+(.*)\s+\S+\s+\S+/) { + $fname = $1; + $name = $2; + $date = $3; + } + elsif ($ln =~ /href=\"(CICD_TEST-.*)\">(.*)<\/a>/) { + $fname = $1; + } + + if ($fname ne "") { + # Grab that test file + $cmd = "curl --location $cuser -o $next_info $url/$fname"; + do_system($cmd); + + # Read in that file + my $jurl = ""; + my $jfile = ""; + my $report_to = ""; + my $report_name = ""; + my $swver = ""; + my $fdate = ""; + my $ttype = ""; + my $listing = do_system("cat $next_info"); + my @lines = split(/\n/, $listing); + for ($i = 0; $i<@lines; $i++) { + my $ln = $lines[$i]; + chomp($ln); + if ($ln =~ /^CICD_URL=(.*)/) { + $jurl = $1; + } + elsif ($ln =~ /^CICD_TYPE=(.*)/) { + $ttype = $1; + } + elsif ($ln =~ /^CICD_FILE_NAME=(.*)/) { + $jfile = $1; + } + elsif ($ln =~ /^CICD_RPT_DIR=(.*)/) { + $report_to = $1; + } + elsif ($ln =~ /^CICD_RPT_NAME=(.*)/) { + $report_name = $1; + } + elsif ($ln =~ /^CICD_GITHASH=(.*)/) { + $swver = $1; + } + elsif ($ln =~ /^CICD_FILEDATE=(.*)/) { + $fdate = $1; + } + } + + if ($swver eq "") { + $swver = $fdate; + } + + if ($swver eq "") { + $swver = "$jfile"; + } + + if ($jurl eq "") { + print("ERROR: No CICD_URL found, cannot download file.\n"); + exit(1); + } + if ($jfile eq "") { + print("ERROR: No CICD_FILE_NAME found, cannot download file.\n"); + exit(1); + } + + # Refresh wlan-ap repo if it exists. + if ( -d "../../../wlan-ap") { + do_system("cd ../../../wlan-ap && git pull && cd -"); + } + + print_note("Download latest AP Build from jfrog repository."); + my $cmd = "curl --location -o $jfile -u $jfrog_user:$jfrog_passwd $jurl/$jfile"; + do_system($cmd); + + do_system("rm -f openwrt-*.bin"); + do_system("rm -f *sysupgrade.bin"); # just in case openwrt prefix changes. + do_system("tar xf $jfile"); + + print_note("Copy AP build to LANforge so LANforge can serve the file to AP"); + # Next steps here are to put the OpenWrt file on the LANforge system + my $tb_info = do_system("cat TESTBED_INFO.txt"); + my $tb_dir = ""; + if ($tb_info =~ /TESTBED_DIR=(.*)/) { + $tb_dir = $1; + } + + my $env = do_system(". $tb_dir/test_bed_cfg.bash && env"); + my $lfmgr = ""; + my $serial = ""; + my $cloud_sdk = ""; + + if ($env =~ /LFMANAGER=(.*)/) { + $lfmgr = $1; + } + else { + print("ERRROR: Could not find LFMANAGER in environment, configuration error!\n"); + print("env: $env\n"); + exit(1); + } + + if ($env =~ /USE_CLOUD_SDK=(\S+)/) { + $cloud_sdk = $1; + print("NOTE: Using cloud controller: $cloud_sdk\n"); + } + else { + print("NOTE: NOT Using cloud controller\n"); + } + #print("env: $env"); + #exit(0); + + if ($env =~ /AP_SERIAL=(.*)/) { + $serial = $1; + } + else { + print("ERRROR: Could not find AP_SERIAL in environment, configuration error!\n"); + exit(1); + } + + my $gmport = "3990"; + my $gmanager = $lfmgr; + my $scenario = "myco-auto"; # matches basic_regression.bash + + if ($env =~ /GMANAGER=(.*)/) { + $gmanager = $1; + } + if ($env =~ /GMPORT=(.*)/) { + $gmport = $1; + } + + print_note("Restart LANforge GUI to be sure it is in known state."); + # Restart the GUI on the LANforge system + do_system("ssh lanforge\@$lfmgr pkill -f \"miglayout.*8080\""); + + # and then get it onto the DUT, reboot DUT, re-configure as needed, + print_note("Request AP DUT to install the test image."); + do_system("scp *sysupgrade.bin lanforge\@$lfmgr:myco-$jfile"); + + + # TODO: Kill anything using the serial port + do_system("sudo lsof -t $serial | sudo xargs --no-run-if-empty kill -9"); + + print_note("Find AP DUT default gateway."); + # and then kick off automated regression test. + # Default gateway on the AP should be one of the ports on the LANforge system, so we can use + # that to scp the file to the DUT, via serial-console connection this controller has to the DUT. + my $ap_route = do_system("../../lanforge/lanforge-scripts/openwrt_ctl.py $owt_log --scheme serial --tty $serial --action cmd --value \"ip route show\""); + my $ap_gw = ""; + if ($ap_route =~ /default via (\S+)/) { + $ap_gw = $1; + } + if ($ap_gw eq "") { + print("ERROR: Could not find default gateway for AP, route info:\n$ap_route\n"); + if ($ap_route =~ /pexpect.exceptions.TIMEOUT/) { + print("FATAL-ERROR: DUT is in bad state, bail out.\n"); + exit(33); + } + # Re-apply scenario so the LANforge gateway/NAT is enabled for sure. + my $out = do_system("../../lanforge/lanforge-scripts/lf_gui_cmd.pl --manager $gmanager --port $gmport --scenario $scenario"); + # TODO: Use power-controller to reboot the AP and retry. + if ($out =~ /pexpect.exceptions.TIMEOUT/) { + print("FATAL-ERROR: DUT is in bad state, bail out.\n"); + exit(34); + } + + $out = do_system("../../lanforge/lanforge-scripts/openwrt_ctl.py $owt_log --scheme serial --tty $serial --action reboot"); + print ("Reboot DUT to try to recover networking:\n$out\n"); + if ($out =~ /pexpect.exceptions.TIMEOUT/) { + print("FATAL-ERROR: DUT is in bad state, bail out.\n"); + exit(35); + } + sleep(15); + + $ap_route = do_system("../../lanforge/lanforge-scripts/openwrt_ctl.py $owt_log --scheme serial --tty $serial --action cmd --value \"ip route show\""); + if ($ap_route =~ /default via (\S+)/g) { + $ap_gw = $1; + } + if ($ap_route =~ /pexpect.exceptions.TIMEOUT/) { + print("FATAL-ERROR: DUT is in bad state, bail out.\n"); + exit(36); + } + if ($ap_gw eq "") { + exit(1); + } + } + + print_note("Request AP DUT to install the test image and reboot."); + # TODO: Change this to curl download?? + my $ap_out = do_system("../../lanforge/lanforge-scripts/openwrt_ctl.py $owt_log --scheme serial --tty $serial --action sysupgrade --value \"lanforge\@$ap_gw:myco-$jfile\""); + print ("Sys-upgrade results:\n$ap_out\n"); + if ($ap_out =~ /pexpect.exceptions.TIMEOUT/) { + print("FATAL-ERROR: DUT is in bad state, bail out.\n"); + exit(37); + } + # TODO: Verify this (and reboot below) worked. DUT can get wedged and in that case it will need + # a power-cycle to continue. + + # System should be rebooted at this point. + sleep(10); # Give it some more time + + if ($cloud_sdk eq "") { + print_note("Initialize AP, disable OpenVsync since this is stand-alone testbed."); + # Disable openvsync, it will re-write /etc/config/wireless + # This code should not be used when we get cloud-sdk wired up. + $ap_out = do_system("../../lanforge/lanforge-scripts/openwrt_ctl.py $owt_log --scheme serial --tty $serial --action cmd --value \"service opensync stop\""); + print ("Stop openvsync:\n$ap_out\n"); + if ($ap_out =~ /pexpect.exceptions.TIMEOUT/) { + print("FATAL-ERROR: DUT is in bad state, bail out.\n"); + exit(38); + } + $ap_out = do_system("../../lanforge/lanforge-scripts/openwrt_ctl.py $owt_log --scheme serial --tty $serial --action cmd --value \"service opensync disable\""); + print ("Disable openvsync:\n$ap_out\n"); + if ($ap_out =~ /pexpect.exceptions.TIMEOUT/) { + print("FATAL-ERROR: DUT is in bad state, bail out.\n"); + exit(39); + } + } + else { + print_note("Initialize AP, enable OpenVsync since this testbed is using Cloud-Controler: $cloud_sdk."); + $ap_out = do_system("../../lanforge/lanforge-scripts/openwrt_ctl.py $owt_log --scheme serial --tty $serial --action cmd --value \"service opensync enable\""); + print ("Enable openvsync:\n$ap_out\n"); + if ($ap_out =~ /pexpect.exceptions.TIMEOUT/) { + print("FATAL-ERROR: DUT is in bad state, bail out.\n"); + exit(40); + } + } + + # Re-apply overlay + print_note("Apply default AP configuration for this test bed."); + if ($cloud_sdk eq "") { + $ap_out = do_system("cd $tb_dir/OpenWrt-overlay && tar -cvzf ../overlay_tmp.tar.gz * && scp ../overlay_tmp.tar.gz lanforge\@$lfmgr:myco-overlay.tar.gz"); + } + else { + # Create /etc/hosts file that points us towards correct cloud-sdk machine + my $etc_hosts = "$tb_dir/OpenWrt-overlay/etc/hosts"; + open(FILE, ">", "$etc_hosts"); + print FILE "# Auto-Created by CICD process +127.0.0.1 localhost + +::1 localhost ip6-localhost ip6-loopback +ff02::1 ip6-allnodes +ff02::2 ip6-allrouters +$cloud_sdk opensync-mqtt-broker +$cloud_sdk opensync-wifi-controller +$cloud_sdk opensync.zone1.art2wave.com +"; + + # Leave 'wireless' out of the overlay since opensync will be designed to work with default config. + $ap_out = do_system("cd $tb_dir/OpenWrt-overlay && tar -cvzf ../overlay_tmp.tar.gz --exclude etc/config/wireless * && scp ../overlay_tmp.tar.gz lanforge\@$lfmgr:myco-overlay.tar.gz"); + unlink($etc_hosts); + } + + print ("Create overlay zip:\n$ap_out\n"); + + for (my $q = 0; $q<10; $q++) { + $ap_out = do_system("../../lanforge/lanforge-scripts/openwrt_ctl.py $owt_log --scheme serial --tty $serial --action download --value \"lanforge\@$ap_gw:myco-overlay.tar.gz\" --value2 \"overlay.tgz\""); + print ("Download overlay to DUT:\n$ap_out\n"); + if ($ap_out =~ /ERROR: Could not connect to LANforge/g) { + # Try to restart the network + $ap_out = do_system("../../lanforge/lanforge-scripts/openwrt_ctl.py $owt_log --scheme serial --tty $serial --action cmd --value \"/etc/init.d/network restart\""); + print ("Request restart of DUT networking:\n$ap_out\n"); + if ($q == 9) { + # We have failed to apply overlay at this point, bail out. + print("ERROR: Could not apply overlay to DUT, exiting test attempt.\n"); + exit(1); + } + print("Will retry overlay download in 10 seconds, try $q / 10\n"); + sleep(10); + } + else { + last; + } + } + $ap_out = do_system("../../lanforge/lanforge-scripts/openwrt_ctl.py $owt_log --scheme serial --tty $serial --action cmd --value \"cd / && tar -xzf /tmp/overlay.tgz\""); + print ("Un-zip overlay on DUT:\n$ap_out\n"); + if ($ap_out =~ /pexpect.exceptions.TIMEOUT/) { + print("FATAL-ERROR: DUT is in bad state, bail out.\n"); + exit(41); + } + + print_note("Reboot AP so that new configuration is applied."); + $ap_out = do_system("../../lanforge/lanforge-scripts/openwrt_ctl.py $owt_log --scheme serial --tty $serial --action reboot"); + print ("Rebooted DUT so overlay takes effect:\n$ap_out\n"); + if ($ap_out =~ /pexpect.exceptions.TIMEOUT/) { + print("FATAL-ERROR: DUT is in bad state, bail out.\n"); + exit(42); + } + + if ($ttype eq "fast") { + print_note("Start 'Fast' LANforge regression test."); + $ap_out = do_system("cd $tb_dir && DUT_SW_VER=$swver ./run_basic_fast.bash"); + } + else { + print_note("Start 'Fast' LANforge regression test."); + $ap_out = do_system("cd $tb_dir && DUT_SW_VER=$swver ./run_basic.bash"); + } + print("Regression $ttype test script output:\n$ap_out\n"); + + print_note("Upload results."); + + #When complete, upload the results to the requested location. + if ($ap_out =~ /Results-Dir: (.*)/) { + my $rslts_dir = $1; + if ($rslts_dir =~ /(.*)\'/) { + $rslts_dir = $1; + } + print ("Found results at: $rslts_dir\n"); + do_system("rm -fr /tmp/$report_name"); + do_system("mv $rslts_dir /tmp/$report_name"); + do_system("scp -C -r /tmp/$report_name $report_to/"); + do_system("echo $fname > /tmp/NEW_RESULTS-$fname"); + do_system("scp /tmp/NEW_RESULTS-$fname $report_to/"); + + # This will indirectly stop logread if it is running. + $ap_out = do_system("../../lanforge/lanforge-scripts/openwrt_ctl.py $owt_log --scheme serial --tty $serial --action cmd --value \"uptime\""); + if ($ap_out =~ /pexpect.exceptions.TIMEOUT/) { + print("FATAL-ERROR: DUT is in bad state, bail out.\n"); + exit(43); + } + } + + exit(0); + } + + #print "$ln\n"; +} + +exit 0; + +sub do_system { + my $cmd = shift; + print ">>> $cmd\n"; + return `$cmd 2>&1`; +} + +sub print_note { + my $n = shift; + my $hdr = "###############################################################"; + print "\n\n\n$hdr\n### $n\n$hdr\n\n"; +} diff --git a/gui/testbeds/README_OPENWRT.txt b/gui/testbeds/README_OPENWRT.txt new file mode 100644 index 00000000..98443bbe --- /dev/null +++ b/gui/testbeds/README_OPENWRT.txt @@ -0,0 +1,23 @@ +This automation assumes that the AP is configured as pass-through AP, not +router: + +# Until cloud-sdk is integrated, stop opensync so we can do local config +service opensync stop +service opensync disable + +# Configure /etc/config/network to bridge eth ports and wifi devices. + +# Disable DHCP +/etc/init.d/dnsmasq disable +/etc/init.d/dnsmasq stop + +# Disable DHCP v6 +/etc/init.d/odhcpd disable +/etc/init.d/odhcpd stop + +# Disable firewall ??? +/etc/init.d/firewall disable +/etc/init.d/firewall stop + +/etc/init.d/network reload + diff --git a/gui/testbeds/ferndale-basic-01/NOTES.txt b/gui/testbeds/ferndale-basic-01/NOTES.txt new file mode 100644 index 00000000..2f48c4a4 --- /dev/null +++ b/gui/testbeds/ferndale-basic-01/NOTES.txt @@ -0,0 +1,10 @@ + +DUT is an MR8300, running OpenWrt. +This uses ath10k-ct firmware, and by default, the ath10k driver only supports 32 stations per +radio. To improve this, I tweaked the setup using the fwcfg files. +The radios also only work on certain frequencies, so one has to configure them +carefully. + +See the OpenWrt-overlay directory for files that should be copied onto the DUT +to work with this test. Once OpenSync cloud stuff is complete, the overlay may +not be needed. diff --git a/gui/testbeds/ferndale-basic-01/OpenWrt-overlay/etc/config/wireless b/gui/testbeds/ferndale-basic-01/OpenWrt-overlay/etc/config/wireless new file mode 100644 index 00000000..49398647 --- /dev/null +++ b/gui/testbeds/ferndale-basic-01/OpenWrt-overlay/etc/config/wireless @@ -0,0 +1,57 @@ +config wifi-device 'radio0' + option type 'mac80211' + option hwmode '11a' + option path 'soc/40000000.pci/pci0000:00/0000:00:00.0/0000:01:00.0' + option htmode 'VHT80' + option disabled '0' + option channel '149' + +config wifi-iface 'default_radio0' + option device 'radio0' + option network 'lan' + option mode 'ap' + option disabled '0' + option ssid 'Default-SSID-5gu' + option hidden '0' + option key '12345678' + option encryption 'psk-mixed' + option isolate '1' + +config wifi-device 'radio1' + option type 'mac80211' + option hwmode '11g' + option path 'platform/soc/a000000.wifi' + option htmode 'HT20' + option disabled '0' + option channel '6' + +config wifi-iface 'default_radio1' + option device 'radio1' + option network 'lan' + option mode 'ap' + option disabled '0' + option ssid 'Default-SSID-2g' + option hidden '0' + option key '12345678' + option encryption 'psk-mixed' + option isolate '1' + +config wifi-device 'radio2' + option type 'mac80211' + option hwmode '11a' + option path 'platform/soc/a800000.wifi' + option htmode 'VHT80' + option disabled '0' + option channel '36' + +config wifi-iface 'default_radio2' + option device 'radio2' + option network 'lan' + option mode 'ap' + option ssid 'Default-SSID-5gl' + option key '12345678' + option encryption 'psk-mixed' + option isolate '1' + option hidden '0' + option disabled '0' + diff --git a/gui/testbeds/ferndale-basic-01/OpenWrt-overlay/lib/firmware/ath10k/QCA4019/hw1.0/firmware-5.bin b/gui/testbeds/ferndale-basic-01/OpenWrt-overlay/lib/firmware/ath10k/QCA4019/hw1.0/firmware-5.bin new file mode 100644 index 00000000..eba0be77 Binary files /dev/null and b/gui/testbeds/ferndale-basic-01/OpenWrt-overlay/lib/firmware/ath10k/QCA4019/hw1.0/firmware-5.bin differ diff --git a/gui/testbeds/ferndale-basic-01/OpenWrt-overlay/lib/firmware/ath10k/QCA9888/hw2.0/firmware-5.bin b/gui/testbeds/ferndale-basic-01/OpenWrt-overlay/lib/firmware/ath10k/QCA9888/hw2.0/firmware-5.bin new file mode 100644 index 00000000..eed683c8 Binary files /dev/null and b/gui/testbeds/ferndale-basic-01/OpenWrt-overlay/lib/firmware/ath10k/QCA9888/hw2.0/firmware-5.bin differ diff --git a/gui/testbeds/ferndale-basic-01/OpenWrt-overlay/lib/firmware/ath10k/fwcfg-ahb-a000000.wifi.txt b/gui/testbeds/ferndale-basic-01/OpenWrt-overlay/lib/firmware/ath10k/fwcfg-ahb-a000000.wifi.txt new file mode 100644 index 00000000..72b95681 --- /dev/null +++ b/gui/testbeds/ferndale-basic-01/OpenWrt-overlay/lib/firmware/ath10k/fwcfg-ahb-a000000.wifi.txt @@ -0,0 +1,16 @@ +vdevs = 8 +peers = 162 +active_peers = 162 +stations = 162 +rate_ctrl_objs = 7 +regdom = 840 +#fwname = firmware-5-htt-mgt-b.bin +fwver = 5 +nohwcrypt = 0 +ct_sta_mode = 0 +tx_desc = 2000 +#max_nss = 3 +tids = 260 +skid_limit = 360 +max_amsdus = 3 + diff --git a/gui/testbeds/ferndale-basic-01/OpenWrt-overlay/lib/firmware/ath10k/fwcfg-ahb-a800000.wifi.txt b/gui/testbeds/ferndale-basic-01/OpenWrt-overlay/lib/firmware/ath10k/fwcfg-ahb-a800000.wifi.txt new file mode 100644 index 00000000..72b95681 --- /dev/null +++ b/gui/testbeds/ferndale-basic-01/OpenWrt-overlay/lib/firmware/ath10k/fwcfg-ahb-a800000.wifi.txt @@ -0,0 +1,16 @@ +vdevs = 8 +peers = 162 +active_peers = 162 +stations = 162 +rate_ctrl_objs = 7 +regdom = 840 +#fwname = firmware-5-htt-mgt-b.bin +fwver = 5 +nohwcrypt = 0 +ct_sta_mode = 0 +tx_desc = 2000 +#max_nss = 3 +tids = 260 +skid_limit = 360 +max_amsdus = 3 + diff --git a/gui/testbeds/ferndale-basic-01/OpenWrt-overlay/lib/firmware/ath10k/fwcfg-pci-0000_01_00.0.txt b/gui/testbeds/ferndale-basic-01/OpenWrt-overlay/lib/firmware/ath10k/fwcfg-pci-0000_01_00.0.txt new file mode 100644 index 00000000..617fcef5 --- /dev/null +++ b/gui/testbeds/ferndale-basic-01/OpenWrt-overlay/lib/firmware/ath10k/fwcfg-pci-0000_01_00.0.txt @@ -0,0 +1,16 @@ +# 9888 chip +vdevs = 8 +peers = 202 +active_peers = 202 +stations = 202 +rate_ctrl_objs = 7 +regdom = 840 +#fwname = firmware-5-htt-mgt-b.bin +fwver = 5 +nohwcrypt = 0 +ct_sta_mode = 0 +tx_desc = 2200 +#max_nss = 3 +tids = 450 +skid_limit = 360 +max_amsdus = 3 diff --git a/gui/testbeds/ferndale-basic-01/ap-auto.txt b/gui/testbeds/ferndale-basic-01/ap-auto.txt new file mode 100644 index 00000000..2aabe2cd --- /dev/null +++ b/gui/testbeds/ferndale-basic-01/ap-auto.txt @@ -0,0 +1,107 @@ +[BLANK] +sel_port-0: 1.1.sta00500 +show_events: 1 +show_log: 0 +port_sorting: 0 +kpi_id: AP Auto +bg: 0xE0ECF8 +test_rig: +show_scan: 1 +auto_helper: 1 +skip_2: 1 +skip_5: 1 +dut5-0: ea8300 OpenWrt-5lo +dut2-0: ea8300 OpenWrt-2 +dut5-1: NA +dut2-1: NA +dut5-2: ea8300 OpenWrt-2 +dut2-2: NA +spatial_streams: AUTO +bandw_options: AUTO +modes: Auto +upstream_port: 1.1.2 eth2 +operator: +mconn: 1 +tos: 0 +vid_buf: 1000000 +vid_speed: 700000 +reset_stall_thresh_udp_dl: 9600 +reset_stall_thresh_udp_ul: 9600 +reset_stall_thresh_tcp_dl: 9600 +reset_stall_thresh_tcp_ul: 9600 +reset_stall_thresh_l4: 100000 +reset_stall_thresh_voip: 20000 +stab_udp_dl_min: 56000 +stab_udp_dl_max: 0 +stab_udp_ul_min: 56000 +stab_udp_ul_max: 0 +stab_tcp_dl_min: 500000 +stab_tcp_dl_max: 0 +stab_tcp_ul_min: 500000 +stab_tcp_ul_max: 0 +dl_speed: 85% +ul_speed: 85% +max_stations_2: 128 +max_stations_5: 132 +max_stations_dual: 260 +lt_sta: 2 +voip_calls: 0 +lt_dur: 3600 +reset_dur: 600 +lt_gi: 30 +dur20: 20 +hunt_retries: 1 +cap_dl: 1 +cap_ul: 0 +cap_use_pkt_sizes: 0 +stability_reset_radios: 0 +pkt_loss_thresh: 10000 +frame_sizes: 200, 512, 1024, MTU +capacities: 1, 2, 5, 10, 20, 40, 64, 128, 256, 512, 1024, MAX +radio2-0: 1.1.4 wiphy0 +radio2-1: 1.1.6 wiphy2 +radio5-0: 1.1.5 wiphy1 +radio5-1: 1.1.7 wiphy3 +radio5-2: 1.1.8 wiphy4 +radio5-3: 1.1.9 wiphy5 +radio5-4: 1.1.10 wiphy6 +radio5-5: 1.1.11 wiphy7 +basic_cx: 1 +tput: 0 +dual_band_tput: 0 +capacity: 0 +longterm: 0 +mix_stability: 0 +loop_iter: 1 +reset_batch_size: 1 +reset_duration_min: 10000 +reset_duration_max: 60000 + +# Configure pass/fail metrics for this testbed. +pf_text0: 2.4 DL 200 70Mbps +pf_text1: 2.4 DL 512 110Mbps +pf_text2: 2.4 DL 1024 115Mbps +pf_text3: 2.4 DL MTU 120Mbps +pf_text4: +pf_text5: 2.4 UL 200 88Mbps +pf_text6: 2.4 UL 512 106Mbps +pf_text7: 2.4 UL 1024 115Mbps +pf_text8: 2.4 UL MTU 120Mbps +pf_text9: +pf_text10: 5 DL 200 72Mbps +pf_text11: 5 DL 512 185Mbps +pf_text12: 5 DL 1024 370Mbps +pf_text13: 5 DL MTU 525Mbps +pf_text14: +pf_text15: 5 UL 200 90Mbps +pf_text16: 5 UL 512 230Mbps +pf_text17: 5 UL 1024 450Mbps +pf_text18: 5 UL MTU 630Mbps + +# Tune connect-time thresholds. +cx_prcnt: 950000 +cx_open_thresh: 35 +cx_psk_thresh: 75 +cx_1x_thresh: 130 + + diff --git a/gui/testbeds/ferndale-basic-01/dpt-pkt-sz.txt b/gui/testbeds/ferndale-basic-01/dpt-pkt-sz.txt new file mode 100644 index 00000000..b51685d6 --- /dev/null +++ b/gui/testbeds/ferndale-basic-01/dpt-pkt-sz.txt @@ -0,0 +1,55 @@ +[BLANK] +show_events: 1 +show_log: 0 +port_sorting: 0 +kpi_id: Dataplane +bg: 0xE0ECF8 +test_rig: +show_scan: 1 +auto_helper: 0 +skip_2: 0 +skip_5: 0 +selected_dut: ea8300 +duration: 15000 +traffic_port: 1.1.136 sta01001 +upstream_port: 1.1.2 eth2 +path_loss: 10 +speed: 85% +speed2: 0Kbps +min_rssi_bound: -150 +max_rssi_bound: 0 +channels: AUTO +modes: Auto +pkts: 60;142;256;512;1024;MTU;4000 +spatial_streams: AUTO +security_options: AUTO +bandw_options: AUTO +traffic_types: UDP +directions: DUT Transmit;DUT Receive +txo_preamble: OFDM +txo_mcs: 0 CCK, OFDM, HT, VHT +txo_retries: No Retry +txo_sgi: OFF +txo_txpower: 15 +attenuator: 0 +attenuator2: 0 +attenuator_mod: 255 +attenuator_mod2: 255 +attenuations: 0..+50..950 +attenuations2: 0..+50..950 +chamber: 0 +tt_deg: 0..+45..359 +cust_pkt_sz: +show_3s: 0 +show_ll_graphs: 1 +show_gp_graphs: 1 +show_1m: 1 +pause_iter: 0 +show_realtime: 1 +operator: +mconn: 1 +mpkt: 1000 +tos: 0 +loop_iterations: 1 + + diff --git a/gui/testbeds/ferndale-basic-01/run_basic.bash b/gui/testbeds/ferndale-basic-01/run_basic.bash new file mode 100755 index 00000000..9f3800c2 --- /dev/null +++ b/gui/testbeds/ferndale-basic-01/run_basic.bash @@ -0,0 +1,71 @@ +#!/bin/bash + +# Example usage of this script +# DUT_SW_VER=my-build-id ./run_basic.bash +# +# Other DUT variables in test_bed_cfg.bash may also be over-ridden, +# including those below. See LANforge 'add_dut' CLI command for +# details on what these variables are for. + +# DUT_FLAGS DUT_FLAGS_MASK DUT_SW_VER DUT_HW_VER DUT_MODEL +# DUT_SERIAL DUT_SSID1 DUT_SSID2 DUT_SSID3 +# DUT_PASSWD1 DUT_PASSWD2 DUT_PASSWD3 +# DUT_BSSID1 DUT_BSSID2 DUT_BSSID3 + +# Source config file +. test_bed_cfg.bash + +echo "Top wlan-testing git commits.
" > ./tmp_gitlog.html
+git log -n 8 --oneline >> ./tmp_gitlog.html
+echo "
" >> ./tmp_gitlog.html + +NOTES_HTML=`pwd`/testbed_notes.html +GITLOG=`pwd`/tmp_gitlog.html + +if [ -d "../../../wlan-ap" ] +then + DUTGITLOG=/tmp/${DUT_SW_VER}_dut_gitlog.html + echo "Top wlan-ap git commits.
" > $DUTGITLOG
+    (cd ../../../wlan-ap && git log -n 8 --oneline $DUT_SW_VER >> $DUTGITLOG && cd -)
+    echo "
" >> $DUTGITLOG + export DUTGITLOG +fi +export NOTES_HTML GITLOG + +# TODO: Copy config file to cloud controller and restart it +# and/or do other config to make it work. + +# Change to scripts dir +cd ../../ + +# Where to place results. basic_regression.bash will use this variable. +RSLTS_DIR=/tmp/ferndale-01-basic-regression +export RSLTS_DIR + +# Clean any existing data from the results dir +rm -fr $RSLTS_DIR + +# Run one test +# DEFAULT_ENABLE=0 DO_SHORT_AP_STABILITY_RESET=1 ./basic_regression.bash + +# Clean up old DHCP leases +../lf_gui_cmd.pl --manager $GMANAGER --port $GMPORT --cmd "cli clear_port_counters ALL ALL ALL dhcp_leases" + +# Run all tests +./basic_regression.bash + +cd - + +if [ ! -d $RSLTS_DIR ] +then + echo "Test did not run as expected, $RSLTS_DIR not found." + mkdir -p $RSLTS_DIR +fi + +if [ -f ${MY_TMPDIR}/basic_regression_log.txt ] +then + echo "Found ${MY_TMPDIR}/basic_regression_log.txt, moving into $RSLTS_DIR" + mv ${MY_TMPDIR}/basic_regression_log.txt $RSLTS_DIR/ +fi + +echo "See results in $RSLTS_DIR" diff --git a/gui/testbeds/ferndale-basic-01/run_basic_fast.bash b/gui/testbeds/ferndale-basic-01/run_basic_fast.bash new file mode 100755 index 00000000..b8d2d5d4 --- /dev/null +++ b/gui/testbeds/ferndale-basic-01/run_basic_fast.bash @@ -0,0 +1,81 @@ +#!/bin/bash + +# Example usage of this script +# DUT_SW_VER=my-build-id ./run_basic.bash +# +# Other DUT variables in test_bed_cfg.bash may also be over-ridden, +# including those below. See LANforge 'add_dut' CLI command for +# details on what these variables are for. + +# DUT_FLAGS DUT_FLAGS_MASK DUT_SW_VER DUT_HW_VER DUT_MODEL +# DUT_SERIAL DUT_SSID1 DUT_SSID2 DUT_SSID3 +# DUT_PASSWD1 DUT_PASSWD2 DUT_PASSWD3 +# DUT_BSSID1 DUT_BSSID2 DUT_BSSID3 + +DO_SHORT_AP_BASIC_CX=${DO_SHORT_AP_BASIC_CX:-1} +DO_WCT_BI=${DO_WCT_BI:-1} + +export DO_SHORT_AP_BASI_CX DO_WCT_BI + +# Source config file +. test_bed_cfg.bash + +echo "Top wlan-testing git commits.
" > ./tmp_gitlog.html
+git log -n 8 --oneline >> ./tmp_gitlog.html
+echo "
" >> ./tmp_gitlog.html + +NOTES_HTML=`pwd`/testbed_notes.html +GITLOG=`pwd`/tmp_gitlog.html + +if [ -d "../../../wlan-ap" ] +then + DUTGITLOG=/tmp/${DUT_SW_VER}_dut_gitlog.html + echo "Top wlan-ap git commits.
" > $DUTGITLOG
+    (cd ../../../wlan-ap && git log -n 8 --oneline $DUT_SW_VER >> $DUTGITLOG && cd -)
+    echo "
" >> $DUTGITLOG + export DUTGITLOG +fi +export NOTES_HTML GITLOG + +# TODO: Copy config file to cloud controller and restart it +# and/or do other config to make it work. + +# Change to scripts dir +cd ../../ + +# Where to place results. basic_regression.bash will use this variable. +RSLTS_DIR=/tmp/ferndale-01-basic-regression-fast +export RSLTS_DIR + +# Clean any existing data from the results dir +rm -fr $RSLTS_DIR + +# Clean up old DHCP leases +../lf_gui_cmd.pl --manager $GMANAGER --port $GMPORT --cmd "cli clear_port_counters ALL ALL ALL dhcp_leases" + +# Run a subset of available tests +# See 'Tests to run' comment in basic_regression.bash for available options. + +#DEFAULT_ENABLE=0 WCT_DURATION=20s DO_SHORT_AP_BASIC_CX=1 DO_WCT_BI=1 ./basic_regression.bash + +DEFAULT_ENABLE=0 WCT_DURATION=20s ./basic_regression.bash + + +# Run all tests +#./basic_regression.bash + +cd - + +if [ ! -d $RSLTS_DIR ] +then + echo "Test did not run as expected, $RSLTS_DIR not found." + mkdir -p $RSLTS_DIR +fi + +if [ -f ${MY_TMPDIR}/basic_regression_log.txt ] +then + echo "Found ${MY_TMPDIR}/basic_regression_log.txt, moving into $RSLTS_DIR" + mv ${MY_TMPDIR}/basic_regression_log.txt $RSLTS_DIR/ +fi + +echo "See results in $RSLTS_DIR" diff --git a/gui/testbeds/ferndale-basic-01/scenario.txt b/gui/testbeds/ferndale-basic-01/scenario.txt new file mode 100644 index 00000000..78da790a --- /dev/null +++ b/gui/testbeds/ferndale-basic-01/scenario.txt @@ -0,0 +1,15 @@ +profile_link 1.1 STA-AC 64 'DUT: ea8300 Radio-1' NA wiphy0,AUTO -1 +profile_link 1.1 STA-AC 64 'DUT: ea8300 Radio-1' NA wiphy2,AUTO -1 +profile_link 1.1 STA-AC 64 'DUT: ea8300 Radio-2' NA wiphy1,AUTO -1 +profile_link 1.1 STA-AC 64 'DUT: ea8300 Radio-3' NA wiphy3,AUTO -1 +profile_link 1.1 upstream-dhcp 1 NA NA eth2,AUTO -1 +profile_link 1.1 uplink-nat 1 'DUT: upstream LAN 92.168.100.1/24' NA eth3,eth2 -1 +profile_link 1.1 STA-AC 1 'DUT: ea8300 Radio-2' NA wiphy4,AUTO -1 +profile_link 1.1 STA-AC 1 'DUT: ea8300 Radio-3' NA wiphy5,AUTO -1 +profile_link 1.1 STA-AC 1 'DUT: ea8300 Radio-2' NA wiphy6,AUTO -1 +profile_link 1.1 STA-AC 1 'DUT: ea8300 Radio-3' NA wiphy7,AUTO -1 +dut ea8300 393 148 +dut upstream 306 62 +resource 1.1 132 218 + + diff --git a/gui/testbeds/ferndale-basic-01/scenario_small.txt b/gui/testbeds/ferndale-basic-01/scenario_small.txt new file mode 100644 index 00000000..29e92c5a --- /dev/null +++ b/gui/testbeds/ferndale-basic-01/scenario_small.txt @@ -0,0 +1,15 @@ +profile_link 1.1 STA-AC 8 'DUT: ea8300 Radio-1' NA wiphy0,AUTO -1 +profile_link 1.1 STA-AC 8 'DUT: ea8300 Radio-1' NA wiphy2,AUTO -1 +profile_link 1.1 STA-AC 8 'DUT: ea8300 Radio-2' NA wiphy1,AUTO -1 +profile_link 1.1 STA-AC 8 'DUT: ea8300 Radio-3' NA wiphy3,AUTO -1 +profile_link 1.1 upstream-dhcp 1 NA NA eth2,AUTO -1 +profile_link 1.1 uplink-nat 1 'DUT: upstream LAN 92.168.100.1/24' NA eth3,eth2 -1 +#profile_link 1.1 STA-AC 1 'DUT: ea8300 Radio-2' NA wiphy4,AUTO -1 +#profile_link 1.1 STA-AC 1 'DUT: ea8300 Radio-3' NA wiphy5,AUTO -1 +#profile_link 1.1 STA-AC 1 'DUT: ea8300 Radio-2' NA wiphy6,AUTO -1 +#profile_link 1.1 STA-AC 1 'DUT: ea8300 Radio-3' NA wiphy7,AUTO -1 +dut ea8300 393 148 +dut upstream 306 62 +resource 1.1 132 218 + + diff --git a/gui/testbeds/ferndale-basic-01/test_bed_cfg.bash b/gui/testbeds/ferndale-basic-01/test_bed_cfg.bash new file mode 100644 index 00000000..76144e45 --- /dev/null +++ b/gui/testbeds/ferndale-basic-01/test_bed_cfg.bash @@ -0,0 +1,61 @@ +# Example test-bed configuration + +# Scripts should source this file to set the default environment variables +# and then override the variables specific to their test case (and it can be done +# in opposite order for same results +# +# After the env variables are set, +# call the 'lanforge/lanforge-scripts/gui/basic_regression.bash' +# from the directory in which it resides. + +PWD=`pwd` +AP_SERIAL=${AP_SERIAL:-/dev/ttyUSB1} +LF_SERIAL=${LF_SERIAL:-/dev/ttyUSB0} +LFPASSWD=${LFPASSWD:-lanforge} # Root password on LANforge machine +AP_AUTO_CFG_FILE=${AP_AUTO_CFG_FILE:-$PWD/ap-auto.txt} +WCT_CFG_FILE=${WCT_CFG_FILE:-$PWD/wct.txt} +DPT_CFG_FILE=${DPT_CFG_FILE:-$PWD/dpt-pkt-sz.txt} +SCENARIO_CFG_FILE=${SCENARIO_CFG_FILE:-$PWD/scenario.txt} + +# Default to enable cloud-sdk for this testbed, cloud-sdk is at IP addr below +USE_CLOUD_SDK=${USE_CLOUD_SDK:-192.168.100.164} + +# LANforge target machine +LFMANAGER=${LFMANAGER:-192.168.100.209} + +# LANforge GUI machine (may often be same as target) +GMANAGER=${GMANAGER:-192.168.100.209} +GMPORT=${GMPORT:-3990} +MY_TMPDIR=${MY_TMPDIR:-/tmp} + +# Test configuration (10 minutes by default, in interest of time) +STABILITY_DURATION=${STABILITY_DURATION:-600} +TEST_RIG_ID=${TEST_RIG_ID:-Ferndale-01-Basic} + +# DUT configuration +DUT_FLAGS=${DUT_FLAGS:-0x22} # AP, WPA-PSK +#DUT_FLAGS=${DUT_FLAGS:-0x2} # AP, Open +DUT_FLAGS_MASK=${DUT_FLAGS_MASK:-0xFFFF} +DUT_SW_VER=${DUT_SW_VER:-OpenWrt-Stock} +DUT_HW_VER=Linksys-EA8300 +DUT_MODEL=Linksys-EA8300 +DUT_SERIAL=${DUT_SERIAL:-NA} +DUT_SSID1=${DUT_SSID1:-Default-SSID-2g} +DUT_SSID2=${DUT_SSID2:-Default-SSID-5gl} +DUT_SSID3=${DUT_SSID3:-Default-SSID-5gu} +DUT_PASSWD1=${DUT_PASSWD1:-12345678} +DUT_PASSWD2=${DUT_PASSWD2:-12345678} +DUT_PASSWD3=${DUT_PASSWD3:-12345678} +DUT_BSSID1=24:f5:a2:08:21:6c +DUT_BSSID2=24:f5:a2:08:21:6d +DUT_BSSID3=24:f5:a2:08:21:6e + +export LF_SERIAL AP_SERIAL LFPASSWD +export AP_AUTO_CFG_FILE WCT_CFG_FILE DPT_CFG_FILE SCENARIO_CFG_FILE +export LFMANAGER GMANAGER GMPORT MY_TMPDIR +export STABILITY_DURATION TEST_RIG_ID +export DUT_FLAGS DUT_FLAGS_MASK DUT_SW_VER DUT_HW_VER DUT_MODEL +export DUT_SERIAL DUT_SSID1 DUT_SSID2 DUT_SSID3 +export DUT_PASSWD1 DUT_PASSWD2 DUT_PASSWD3 +export DUT_BSSID1 DUT_BSSID2 DUT_BSSID3 +export USE_CLOUD_SDK diff --git a/gui/testbeds/ferndale-basic-01/wct.txt b/gui/testbeds/ferndale-basic-01/wct.txt new file mode 100644 index 00000000..3c791071 --- /dev/null +++ b/gui/testbeds/ferndale-basic-01/wct.txt @@ -0,0 +1,323 @@ +[BLANK] +sel_port-0: 1.1.eth2 +sel_port-1: 1.1.sta00000 +sel_port-2: 1.1.sta01000 +sel_port-3: 1.1.sta00500 +sel_port-4: 1.1.sta01500 +sel_port-5: 1.1.sta03000 +sel_port-6: 1.1.sta03500 +sel_port-7: 1.1.sta04000 +sel_port-8: 1.1.sta04500 +sel_port-9: 1.1.sta00001 +sel_port-10: 1.1.sta01001 +sel_port-11: 1.1.sta00501 +sel_port-12: 1.1.sta01501 +sel_port-13: 1.1.sta00002 +sel_port-14: 1.1.sta01002 +sel_port-15: 1.1.sta00502 +sel_port-16: 1.1.sta01502 +sel_port-17: 1.1.sta00003 +sel_port-18: 1.1.sta01003 +sel_port-19: 1.1.sta00503 +sel_port-20: 1.1.sta01503 +sel_port-21: 1.1.sta00004 +sel_port-22: 1.1.sta01004 +sel_port-23: 1.1.sta00504 +sel_port-24: 1.1.sta01504 +sel_port-25: 1.1.sta00005 +sel_port-26: 1.1.sta01005 +sel_port-27: 1.1.sta00505 +sel_port-28: 1.1.sta01505 +sel_port-29: 1.1.sta00006 +sel_port-30: 1.1.sta01006 +sel_port-31: 1.1.sta00506 +sel_port-32: 1.1.sta01506 +sel_port-33: 1.1.sta00007 +sel_port-34: 1.1.sta01007 +sel_port-35: 1.1.sta00507 +sel_port-36: 1.1.sta01507 +sel_port-37: 1.1.sta00008 +sel_port-38: 1.1.sta01008 +sel_port-39: 1.1.sta00508 +sel_port-40: 1.1.sta01508 +sel_port-41: 1.1.sta00009 +sel_port-42: 1.1.sta01009 +sel_port-43: 1.1.sta00509 +sel_port-44: 1.1.sta01509 +sel_port-45: 1.1.sta00010 +sel_port-46: 1.1.sta01010 +sel_port-47: 1.1.sta00510 +sel_port-48: 1.1.sta01510 +sel_port-49: 1.1.sta00011 +sel_port-50: 1.1.sta01011 +sel_port-51: 1.1.sta00511 +sel_port-52: 1.1.sta01511 +sel_port-53: 1.1.sta00012 +sel_port-54: 1.1.sta01012 +sel_port-55: 1.1.sta00512 +sel_port-56: 1.1.sta01512 +sel_port-57: 1.1.sta00013 +sel_port-58: 1.1.sta01013 +sel_port-59: 1.1.sta00513 +sel_port-60: 1.1.sta01513 +sel_port-61: 1.1.sta00014 +sel_port-62: 1.1.sta01014 +sel_port-63: 1.1.sta00514 +sel_port-64: 1.1.sta01514 +sel_port-65: 1.1.sta00015 +sel_port-66: 1.1.sta01015 +sel_port-67: 1.1.sta00515 +sel_port-68: 1.1.sta01515 +sel_port-69: 1.1.sta00016 +sel_port-70: 1.1.sta01016 +sel_port-71: 1.1.sta00516 +sel_port-72: 1.1.sta01516 +sel_port-73: 1.1.sta00017 +sel_port-74: 1.1.sta01017 +sel_port-75: 1.1.sta00517 +sel_port-76: 1.1.sta01517 +sel_port-77: 1.1.sta00018 +sel_port-78: 1.1.sta01018 +sel_port-79: 1.1.sta00518 +sel_port-80: 1.1.sta01518 +sel_port-81: 1.1.sta00019 +sel_port-82: 1.1.sta01019 +sel_port-83: 1.1.sta00519 +sel_port-84: 1.1.sta01519 +sel_port-85: 1.1.sta00020 +sel_port-86: 1.1.sta01020 +sel_port-87: 1.1.sta00520 +sel_port-88: 1.1.sta01520 +sel_port-89: 1.1.sta00021 +sel_port-90: 1.1.sta01021 +sel_port-91: 1.1.sta00521 +sel_port-92: 1.1.sta01521 +sel_port-93: 1.1.sta00022 +sel_port-94: 1.1.sta01022 +sel_port-95: 1.1.sta00522 +sel_port-96: 1.1.sta01522 +sel_port-97: 1.1.sta00023 +sel_port-98: 1.1.sta01023 +sel_port-99: 1.1.sta00523 +sel_port-100: 1.1.sta01523 +sel_port-101: 1.1.sta00024 +sel_port-102: 1.1.sta01024 +sel_port-103: 1.1.sta00524 +sel_port-104: 1.1.sta01524 +sel_port-105: 1.1.sta00025 +sel_port-106: 1.1.sta01025 +sel_port-107: 1.1.sta00525 +sel_port-108: 1.1.sta01525 +sel_port-109: 1.1.sta00026 +sel_port-110: 1.1.sta01026 +sel_port-111: 1.1.sta00526 +sel_port-112: 1.1.sta01526 +sel_port-113: 1.1.sta00027 +sel_port-114: 1.1.sta01027 +sel_port-115: 1.1.sta00527 +sel_port-116: 1.1.sta01527 +sel_port-117: 1.1.sta00028 +sel_port-118: 1.1.sta01028 +sel_port-119: 1.1.sta00528 +sel_port-120: 1.1.sta01528 +sel_port-121: 1.1.sta00029 +sel_port-122: 1.1.sta01029 +sel_port-123: 1.1.sta00529 +sel_port-124: 1.1.sta01529 +sel_port-125: 1.1.sta00030 +sel_port-126: 1.1.sta01030 +sel_port-127: 1.1.sta00530 +sel_port-128: 1.1.sta01530 +sel_port-129: 1.1.sta00031 +sel_port-130: 1.1.sta01031 +sel_port-131: 1.1.sta00531 +sel_port-132: 1.1.sta01531 +sel_port-133: 1.1.sta00032 +sel_port-134: 1.1.sta01032 +sel_port-135: 1.1.sta00532 +sel_port-136: 1.1.sta01532 +sel_port-137: 1.1.sta00033 +sel_port-138: 1.1.sta01033 +sel_port-139: 1.1.sta00533 +sel_port-140: 1.1.sta01533 +sel_port-141: 1.1.sta00034 +sel_port-142: 1.1.sta01034 +sel_port-143: 1.1.sta00534 +sel_port-144: 1.1.sta01534 +sel_port-145: 1.1.sta00035 +sel_port-146: 1.1.sta01035 +sel_port-147: 1.1.sta00535 +sel_port-148: 1.1.sta01535 +sel_port-149: 1.1.sta00036 +sel_port-150: 1.1.sta01036 +sel_port-151: 1.1.sta00536 +sel_port-152: 1.1.sta01536 +sel_port-153: 1.1.sta00037 +sel_port-154: 1.1.sta01037 +sel_port-155: 1.1.sta00537 +sel_port-156: 1.1.sta01537 +sel_port-157: 1.1.sta00038 +sel_port-158: 1.1.sta01038 +sel_port-159: 1.1.sta00538 +sel_port-160: 1.1.sta01538 +sel_port-161: 1.1.sta00039 +sel_port-162: 1.1.sta01039 +sel_port-163: 1.1.sta00539 +sel_port-164: 1.1.sta01539 +sel_port-165: 1.1.sta00040 +sel_port-166: 1.1.sta01040 +sel_port-167: 1.1.sta00540 +sel_port-168: 1.1.sta01540 +sel_port-169: 1.1.sta00041 +sel_port-170: 1.1.sta01041 +sel_port-171: 1.1.sta00541 +sel_port-172: 1.1.sta01541 +sel_port-173: 1.1.sta00042 +sel_port-174: 1.1.sta01042 +sel_port-175: 1.1.sta00542 +sel_port-176: 1.1.sta01542 +sel_port-177: 1.1.sta00043 +sel_port-178: 1.1.sta01043 +sel_port-179: 1.1.sta00543 +sel_port-180: 1.1.sta01543 +sel_port-181: 1.1.sta00044 +sel_port-182: 1.1.sta01044 +sel_port-183: 1.1.sta00544 +sel_port-184: 1.1.sta01544 +sel_port-185: 1.1.sta00045 +sel_port-186: 1.1.sta01045 +sel_port-187: 1.1.sta00545 +sel_port-188: 1.1.sta01545 +sel_port-189: 1.1.sta00046 +sel_port-190: 1.1.sta01046 +sel_port-191: 1.1.sta00546 +sel_port-192: 1.1.sta01546 +sel_port-193: 1.1.sta00047 +sel_port-194: 1.1.sta01047 +sel_port-195: 1.1.sta00547 +sel_port-196: 1.1.sta01547 +sel_port-197: 1.1.sta00048 +sel_port-198: 1.1.sta01048 +sel_port-199: 1.1.sta00548 +sel_port-200: 1.1.sta01548 +sel_port-201: 1.1.sta00049 +sel_port-202: 1.1.sta01049 +sel_port-203: 1.1.sta00549 +sel_port-204: 1.1.sta01549 +sel_port-205: 1.1.sta00050 +sel_port-206: 1.1.sta01050 +sel_port-207: 1.1.sta00550 +sel_port-208: 1.1.sta01550 +sel_port-209: 1.1.sta00051 +sel_port-210: 1.1.sta01051 +sel_port-211: 1.1.sta00551 +sel_port-212: 1.1.sta01551 +sel_port-213: 1.1.sta00052 +sel_port-214: 1.1.sta01052 +sel_port-215: 1.1.sta00552 +sel_port-216: 1.1.sta01552 +sel_port-217: 1.1.sta00053 +sel_port-218: 1.1.sta01053 +sel_port-219: 1.1.sta00553 +sel_port-220: 1.1.sta01553 +sel_port-221: 1.1.sta00054 +sel_port-222: 1.1.sta01054 +sel_port-223: 1.1.sta00554 +sel_port-224: 1.1.sta01554 +sel_port-225: 1.1.sta00055 +sel_port-226: 1.1.sta01055 +sel_port-227: 1.1.sta00555 +sel_port-228: 1.1.sta01555 +sel_port-229: 1.1.sta00056 +sel_port-230: 1.1.sta01056 +sel_port-231: 1.1.sta00556 +sel_port-232: 1.1.sta01556 +sel_port-233: 1.1.sta00057 +sel_port-234: 1.1.sta01057 +sel_port-235: 1.1.sta00557 +sel_port-236: 1.1.sta01557 +sel_port-237: 1.1.sta00058 +sel_port-238: 1.1.sta01058 +sel_port-239: 1.1.sta00558 +sel_port-240: 1.1.sta01558 +sel_port-241: 1.1.sta00059 +sel_port-242: 1.1.sta01059 +sel_port-243: 1.1.sta00559 +sel_port-244: 1.1.sta01559 +sel_port-245: 1.1.sta00060 +sel_port-246: 1.1.sta01060 +sel_port-247: 1.1.sta00560 +sel_port-248: 1.1.sta01560 +sel_port-249: 1.1.sta00061 +sel_port-250: 1.1.sta01061 +sel_port-251: 1.1.sta00561 +sel_port-252: 1.1.sta01561 +sel_port-253: 1.1.sta00062 +sel_port-254: 1.1.sta01062 +sel_port-255: 1.1.sta00562 +sel_port-256: 1.1.sta01562 +sel_port-257: 1.1.sta00063 +sel_port-258: 1.1.sta01063 +sel_port-259: 1.1.sta00563 +sel_port-260: 1.1.sta01563 +show_events: 1 +show_log: 0 +port_sorting: 2 +kpi_id: WiFi Capacity +bg: 0xE0ECF8 +test_rig: +show_scan: 1 +auto_helper: 1 +skip_2: 0 +skip_5: 0 +batch_size: 1,5,10,20,40,80 +loop_iter: 1 +duration: 30000 +test_groups: 0 +test_groups_subset: 0 +protocol: TCP-IPv4 +dl_rate_sel: Total Download Rate: +dl_rate: 1000000000 +ul_rate_sel: Total Upload Rate: +ul_rate: 1000000000 +prcnt_tcp: 100000 +l4_endp: +pdu_sz: -1 +mss_sel: 1 +sock_buffer: 0 +ip_tos: 0 +multi_conn: -1 +min_speed: -1 +ps_interval: 60-second Running Average +fairness: 0 +naptime: 0 +before_clear: 5000 +rpt_timer: 1000 +try_lower: 0 +rnd_rate: 1 +leave_ports_up: 0 +down_quiesce: 0 +udp_nat: 1 +record_other_ssids: 0 +clear_reset_counters: 0 +do_pf: 0 +pf_min_period_dl: 128000 +pf_min_period_ul: 0 +pf_max_reconnects: 0 +use_mix_pdu: 0 +pdu_prcnt_pps: 1 +pdu_prcnt_bps: 0 +pdu_mix_ln-0: +show_scan: 1 +show_golden_3p: 0 +save_csv: 0 +show_realtime: 1 +show_pie: 1 +show_per_loop_totals: 1 +show_cx_time: 1 +show_dhcp: 1 +show_anqp: 1 +show_4way: 1 +show_latency: 1 + + diff --git a/har-to-portal.pl b/har-to-portal.pl index 5fd4af7f..1d508dcb 100755 --- a/har-to-portal.pl +++ b/har-to-portal.pl @@ -83,6 +83,8 @@ our $Decoder = JSON->new->utf8; # #print "Server: ".$log_entry->server_ip_address() .NL; #} + + ## ----- ----- ----- ----- ----- ----- ----- ----- ----- ## Creating a plain JSON object is more efficient, ## and more compatible with FF @@ -98,9 +100,51 @@ foreach my $entry (@{$json->{log}->{entries}}) { $ordered_entries{$request_start} = \$entry; } print "------------------------------------------------------------------------------------\n"; +die("unable to open $::outfile: $!") unless open($fh, ">", $::outfile); +print $fh q[ +##----------------------------------------------------------------------------# +## # +## Activate this module with the --bot/-b switch # +## from the portal-bot.pl command line; EG: # +## portal-bot.pl -b h1.pm ... # +## # +## It is absolutely necessary that no code in bot:: modules endangers the # +## operation of the portal-bot script. Do not call die() or exit(). # +## Communicate your displeasure using logg(), dbgdie() or signal_exit(). # +##----------------------------------------------------------------------------# +package bot; + +if (defined $ENV{'PBOT_NOFORK'} && $ENV{'PBOT_NOFORK'} eq "1") { + use strict; + use warnings; + use diagnostics; + use Carp; + $SIG{ __DIE__ } = sub { Carp::confess( @_ ) }; + use Data::Dumper; +} + +use URI::Escape; +use botlib qw(dbg isBlank logg signal_exit dbgdie newEvent request); +use Exporter; +our @EXPORT_OK = qw(find_redirect_url submit_login submit_logout interpret_login_response); +#use HTML::TreeBuilder::XPath; +use Encode; + +@main::delays=(0.0, 0.0, 1.1); +$::curl_args .=" --max-redirs 0"; +our $extra_args = " --max-redirs 0" + ." --keepalive-time 6800" + ." --max-time 6800" + ." -H 'Connection: keep-alive'" + ." -H 'User-Agent: Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:51.0) Gecko/20100101 Firefox/51.0'" + ; + +sub find_redirect_url { +} +]; # end module top + my $found_redirect = 0; my $found_login_post = 0; -die("unable to open $::outfile: $!") unless open($fh, ">", $::outfile); for my $request_start ( sort keys %ordered_entries ) { print "Start: $request_start\n"; @@ -116,29 +160,30 @@ for my $request_start ( sort keys %ordered_entries ) { my $url = $request->{url}; my $method = $request->{method}; + print $fh "\n=pod\n"; print $fh "------------------------------------------------------------------------------------\n"; print $fh "$method: $url\n"; print $fh "------------------------------------------------------------------------------------\n"; + print $fh "=cut\n"; print $fh "request({'curl_args'".CA; - for my $header_e (@$req_headers) { print $fh NL.dQH. $header_e->{name} .CS. $header_e->{value} .qQ; } - print $fh c.NL; # seems like HTTP/2 POSTS to google lack any postData? if (($method eq "POST") && ($request->{httpVersion} =~ m|^HTTP/1|)) { $found_login_post++; - print $fh MP.NL; - print $fh PD.a. $request->{'postData'}->{'text'} .a.c.NL; + print $fh c.NL.MP.NL; + print $fh PD.a. $request->{'postData'}->{'text'} .a; } - print $fh q( 'url'=>).Q. $url .Q.c.NL; + print $fh c.NL.q( 'url'=>).Q. $url .Q.c.NL; print $fh q( 'print'=>1).NL; - print $fh q[}, \@response);].NL.NL; + print $fh q[}, \@response);].NL; + for my $req_cookie(@$req_cookies) { print $fh " request_cookie "; print $fh "{'".$req_cookie->{name}."'} = '".$req_cookie->{value}."';\n"; } - print $fh NL; + print $fh "=pod".NL; if ($response->{status} == 301 || $response->{status} == 302) { $found_redirect++; print $fh "Expect redirect: ".$response->{status}.NL; @@ -146,10 +191,12 @@ for my $request_start ( sort keys %ordered_entries ) { for my $header_e (@$res_headers) { print $fh " response_header: ".$header_e->{name} .": ".$header_e->{value} .NL; } + print $fh "=cut".NL; for my $res_cookie(@$res_cookies) { print $fh " response_cookie"; print $fh "{'".$res_cookie->{name}."'} = '".$res_cookie->{value}."';\n"; } + print $fh NL; } # ~for each request sorted by time # diff --git a/lf_sniff.py b/lf_sniff.py index fb408da3..162c0f7b 100755 --- a/lf_sniff.py +++ b/lf_sniff.py @@ -51,7 +51,7 @@ lfstation = "1.wlan0" sniffer_radios = "2.wiphy0" upstream = "" dur = 5 * 60 -moni_flags = "0x100000000"; # 160Mhz mode enabled +moni_flags = "0x100000000" # 160Mhz mode enabled # rssi_adjust = (current_nf - nf_at_calibration) @@ -222,11 +222,11 @@ def main(): # Create monitor interface mname = "moni%sa"%(moni_idx); subprocess.run(["./lf_portmod.pl", "--manager", lfmgr, - "--cli_cmd", "add_monitor 1 %s %s %s %s 0xFFFFFFFFFFFF %s %s"%(rad_resource, rad_name, mname, moni_flags, aid, bssid)]); + "--cli_cmd", "add_monitor 1 %s %s %s %s 0xFFFFFFFFFFFF %s %s"%(rad_resource, rad_name, mname, moni_flags, aid, bssid)]) - print("Created monitor interface: %s on resource %s\n"%(mname, rad_resource)); - monis_n.append(mname); - monis_r.append(rad_resource); + print("Created monitor interface: %s on resource %s\n"%(mname, rad_resource)) + monis_n.append(mname) + monis_r.append(rad_resource) idx = idx + 1 diff --git a/py-json/LANforge/LFUtils.py b/py-json/LANforge/LFUtils.py index ebc21281..f6d57a31 100644 --- a/py-json/LANforge/LFUtils.py +++ b/py-json/LANforge/LFUtils.py @@ -159,7 +159,7 @@ def portDownRequest(resource_id, port_name, debug_on=False): :param port_name: :return: """ - print("portDownRequest") + data = { "shelf": 1, "resource": resource_id, @@ -169,6 +169,7 @@ def portDownRequest(resource_id, port_name, debug_on=False): "report_timer": REPORT_TIMER_MS_FAST, } if (debug_on): + print("Port down request") debug_printer.pprint(data) return data diff --git a/py-json/LANforge/add_monitor.py b/py-json/LANforge/add_monitor.py new file mode 100644 index 00000000..fda9645e --- /dev/null +++ b/py-json/LANforge/add_monitor.py @@ -0,0 +1,7 @@ +# flags relating to adding a monitor +flags = { + "disable_ht40" : 0x800, + "disable_ht80" : 0x8000000, + "ht160_enable" : 0x100000000, +} +default_flags_mask = 0xFFFFFFFFFFFF diff --git a/py-json/realm.py b/py-json/realm.py index 62758483..a26df1d9 100755 --- a/py-json/realm.py +++ b/py-json/realm.py @@ -10,6 +10,8 @@ from LANforge import add_sta from LANforge import lfcli_base from LANforge.lfcli_base import LFCliBase from generic_cx import GenericCx +from LANforge import add_monitor +from LANforge.add_monitor import * import datetime @@ -34,7 +36,7 @@ class Realm(LFCliBase): while (last_response != "YES"): response = self.json_post("/gui-json/cmd%s" % dbg_param, data, debug_=debug_, response_json_list_=response_json) #LFUtils.debug_printer.pprint(response_json) - last_response = response_json[0]["LAST"]["response"]; + last_response = response_json[0]["LAST"]["response"] if (last_response != "YES"): last_response = None response_json = [] @@ -201,11 +203,11 @@ class Realm(LFCliBase): return info return [1, int(info[0]), info[1]] - def wait_for_ip(self): + def wait_for_ip(self, resource, station_list, ipv6=False): num_ports = 0 num_ips = 0 print("Waiting for ips...") - response = super().json_get("/port/list?fields=alias,ip,port+type") + response = super().json_get("/port/1/%s/%s?fields=alias,ip,port+type" % (resource, ",".join(station_list))) if (response is None) or ("interfaces" not in response): print("station_list: incomplete response:") pprint(response) @@ -213,23 +215,37 @@ class Realm(LFCliBase): for x in range(len(response['interfaces'])): for k, v in response['interfaces'][x].items(): - if "wlan" not in v['alias'] and v['port type'] == "WIFI-STA" or v['port type'] == "Ethernet": + if "wlan" not in v['alias'] and v['port type'] == "WIFI-STA" \ + or v['port type'] == "Ethernet": num_ports += 1 + if ipv6: + num_ports -= 1 # Prevents eth0 from being counted, preventing infinite loop while num_ips != num_ports: num_ips = 0 - response = super().json_get("/port/list?fields=alias,ip,port+type") + response = super().json_get("/port/1/%s/%s?fields=alias,ip,port+type,ipv6+address" % + (resource, ",".join(station_list))) if (response is None) or ("interfaces" not in response): print("station_list: incomplete response:") pprint(response) exit(1) - for x in range(len(response['interfaces'])): - for k, v in response['interfaces'][x].items(): - if "wlan" not in v['alias'] and v['port type'] == "WIFI-STA" or v['port type'] == "Ethernet": - if v['ip'] != '0.0.0.0': - num_ips += 1 - time.sleep(1) + if not ipv6: + for x in range(len(response['interfaces'])): + for k, v in response['interfaces'][x].items(): + if "wlan" not in v['alias'] and v['port type'] == "WIFI-STA" or v['port type'] == "Ethernet": + if v['ip'] != '0.0.0.0': + num_ips += 1 + time.sleep(1) + if ipv6: + for x in range(len(response['interfaces'])): + for k, v in response['interfaces'][x].items(): + if v['alias'] != "eth0" and "wlan" not in v['alias'] and v['port type'] == "WIFI-STA" \ + or v['port type'] == "Ethernet": + if v['ipv6 address'] != 'DELETED' and not v['ipv6 address'].startswith('fe80') \ + and v['ipv6 address'] != 'AUTO': + num_ips += 1 + time.sleep(1) def parse_time(self, time_string): if isinstance(time_string, str): @@ -252,13 +268,58 @@ class Realm(LFCliBase): raise ValueError("time_string must be of type str. Type %s provided" % type(time_string)) return duration_time + def remove_all_stations(self, resource): + port_list = self.station_list() + sta_list = [] + if sta_list is not None: + print("Removing all stations") + for item in list(port_list): + if "sta" in list(item)[0]: + sta_list.append(self.name_to_eid(list(item)[0])[2]) + + for sta_name in sta_list: + req_url = "cli-json/rm_vlan" + data = { + "shelf": 1, + "resource": resource, + "port": sta_name + } + self.json_post(req_url, data) + + def remove_all_endps(self): + endp_list = self.json_get("/endp") + if endp_list is not None: + print("Removing all endps") + endp_list = list(endp_list['endpoint']) + for endp_name in range(len(endp_list)): + name = list(endp_list[endp_name])[0] + req_url = "cli-json/rm_endp" + data = { + "endp_name": name + } + self.json_post(req_url, data) + + def remove_all_cxs(self): + cx_list = list(self.cx_list()) + not_cx = ['warnings', 'errors', 'handler', 'uri', 'items'] + if cx_list is not None: + print("Removing all cxs") + for cx_name in cx_list: + if cx_name in not_cx: + continue + req_url = "cli-json/rm_cx" + data = { + "test_mgr": "default_tm", + "cx_name": cx_name + } + self.json_post(req_url, data) def parse_link(self, link): link = self.lfclient_url + link info = () def new_station_profile(self): - station_prof = StationProfile(self.lfclient_url, debug_=self.debug) + station_prof = StationProfile(self.lfclient_url, local_realm=self, debug_=self.debug) return station_prof def new_l3_cx_profile(self): @@ -333,7 +394,7 @@ class L3CXProfile(LFCliBase): self.json_post("/cli-json/set_cx_state", { "test_mgr": "default_tm", "cx_name": cx_name, - "cx_state":"RUNNING" + "cx_state": "RUNNING" }, debug_=self.debug) print(".", end='') print("") @@ -344,11 +405,29 @@ class L3CXProfile(LFCliBase): self.json_post("/cli-json/set_cx_state", { "test_mgr": "default_tm", "cx_name": cx_name, - "cx_state":"STOPPED" + "cx_state": "STOPPED" }, debug_=self.debug) print(".", end='') print("") + def cleanup(self): + print("Cleaning up cxs and endpoints") + if len(self.created_cx) != 0: + for cx_name in self.created_cx.keys(): + req_url = "cli-json/rm_cx" + data = { + "test_mgr": "default_tm", + "cx_name": cx_name + } + self.json_post(req_url, data) + + for side in range(len(self.created_cx[cx_name])): + req_url = "cli-json/rm_endp" + data = { + "endp_name": self.created_cx[cx_name][side] + } + self.json_post(req_url, data) + def create(self, endp_type, side_a, side_b, sleep_time=0.03, suppress_related_commands=None, debug_=False): if self.debug: debug_=True @@ -516,7 +595,7 @@ class L3CXProfile(LFCliBase): else: raise ValueError("side_a or side_b must be of type list but not both: side_a is type %s side_b is type %s" % (type(side_a), type(side_b))) - print("post_data", cx_post_data) + #print("post_data", cx_post_data) for data in cx_post_data: url = "/cli-json/add_cx" self.local_realm.json_post(url, data, debug_=debug_, suppress_related_commands_=suppress_related_commands) @@ -536,6 +615,7 @@ class L4CXProfile(LFCliBase): self.url = "http://localhost/" self.requests_per_ten = 600 self.local_realm = local_realm + self.created_cx = {} def check_errors(self, debug=False): fields_list = ["!conn", "acc.+denied", "bad-proto", "bad-url", "other-err", "total-err", "rslv-p", "rslv-h", @@ -560,6 +640,45 @@ class L4CXProfile(LFCliBase): print(list(debug_info), " Endps in this list showed errors getting to %s " % self.url) return False + def start_cx(self): + print("Starting CXs...") + for cx_name in self.created_cx.keys(): + self.json_post("/cli-json/set_cx_state", { + "test_mgr": "default_tm", + "cx_name": self.created_cx[cx_name], + "cx_state": "RUNNING" + }, debug_=self.debug) + print(".", end='') + print("") + + def stop_cx(self): + print("Stopping CXs...") + for cx_name in self.created_cx.keys(): + self.json_post("/cli-json/set_cx_state", { + "test_mgr": "default_tm", + "cx_name": self.created_cx[cx_name], + "cx_state": "STOPPED" + }, debug_=self.debug) + print(".", end='') + print("") + + def cleanup(self): + print("Cleaning up cxs and endpoints") + if len(self.created_cx) != 0: + for cx_name in self.created_cx.keys(): + req_url = "cli-json/rm_cx" + data = { + "test_mgr": "default_tm", + "cx_name": self.created_cx[cx_name] + } + self.json_post(req_url, data) + #pprint(data) + req_url = "cli-json/rm_endp" + data = { + "endp_name": cx_name + } + self.json_post(req_url, data) + #pprint(data) def create(self, ports=[], sleep_time=.5, debug_=False, suppress_related_commands_=None): cx_post_data = [] @@ -568,10 +687,6 @@ class L4CXProfile(LFCliBase): shelf = self.local_realm.name_to_eid(port_name)[0] resource = self.local_realm.name_to_eid(port_name)[1] name = self.local_realm.name_to_eid(port_name)[2] - elif len(self.local_realm.name_to_eid(port_name)) == 2: - shelf = 1 - resource = self.local_realm.name_to_eid(port_name)[0] - name = self.local_realm.name_to_eid(port_name)[1] else: raise ValueError("Unexpected name for port_name %s" % port_name) endp_data = { @@ -589,12 +704,13 @@ class L4CXProfile(LFCliBase): time.sleep(sleep_time) endp_data = { - "alias": "CX_" + self.local_realm.name_to_eid(port_name)[-1] + "_l4", + "alias": "CX_" + name + "_l4", "test_mgr": "default_tm", - "tx_endp": self.local_realm.name_to_eid(port_name)[-1] + "_l4", + "tx_endp": name + "_l4", "rx_endp": "NA" } cx_post_data.append(endp_data) + self.created_cx[name + "_l4"] = "CX_" + name + "_l4" for cx_data in cx_post_data: url = "/cli-json/add_cx" @@ -645,6 +761,85 @@ class GenCXProfile(LFCliBase): self.local_realm.json_post(url, data, debug_=debug_, suppress_related_commands_=suppress_related_commands_) time.sleep(sleep_time) +class WifiMonitor: + def __init__(self, lfclient_url, local_realm, up=True, debug_=False, resource_=1): + self.debug = debug_ + self.lfclient_url = lfclient_url + self.up = up + self.local_realm = local_realm + self.monitor_name = None + self.resource = resource_ + self.flag_names = [] + self.flag_mask_names = [] + self.flags_mask = add_monitor.default_flags_mask + self.aid = "NA" # used when sniffing /ax radios + self.bsssid = "00:00:00:00:00:00" # used when sniffing on /ax radios + + def create(self, resource_=1,channel=None, radio_="wiphy0", name_="moni0" ): + print("Creating monitor " + name_) + self.monitor_name = name_ + computed_flags = 0 + for flag_n in self.flag_names: + computed_flags += add_monitor.flags[flag_n] + data ={ + "shelf": 1, + "resource": resource_, + "radio": radio_, + "freqency":5785, + "mode": "NA", #0 for AUTO or "NA" + "channel": channel + + } + self.local_realm.json_post("/cli-json/set_wifi_radio", _data= data) + + self.local_realm.json_post("/cli-json/add_monitor", { + "shelf": 1, + "resource": resource_, + "radio": radio_, + "ap_name": self.monitor_name, + "flags": computed_flags, + "flags_mask": self.flags_mask + }) + def set_flag(self, param_name, value): + if (param_name not in add_monitor.flags): + raise ValueError("Flag '%s' does not exist for add_monitor, consult add_monitor.py" % param_name) + if (value == 1) and (param_name not in self.flag_names): + self.flag_names.append(param_name) + elif (value == 0) and (param_name in self.flag_names): + del self.flag_names[param_name] + self.flags_mask |= add_monitor.flags[param_name] + + def cleanup(self): + print("Cleaning up monitors") + LFUtils.removePort(resource=self.resource, port_name = self.monitor_name, baseurl=self.lfclient_url, debug=self.debug) + + + def admin_up(self): + up_request = LFUtils.port_up_request(resource_id=self.resource, port_name=self.monitor_name) + self.local_realm.json_post("/cli-json/set_port", up_request) + + def admin_down(self): + down_request = LFUtils.portDownRequest(resource_id=self.resource, port_name=self.monitor_name) + self.local_realm.json_post("/cli-json/set_port", down_request) + + def start_sniff(self, capname=None): + if capname is None: + raise ValueError("Need a capture file name") + data = { + "shelf": 1, + "resource": 1, + "port": self.monitor_name, + "display": "NA", + "flags": 0x2, + "outfile": capname, + "duration": 45 + } + self.local_realm.json_post("/cli-json/sniff_port", _data= data) + + + # "sniff_port 1 %s %s NA %s %s.pcap %i"%(r, m, sflags, m, int(dur)) + + # use the station profile to set the combination of features you want on your stations # once this combination is configured, build the stations with the build(resource, radio, number) call @@ -657,7 +852,7 @@ class GenCXProfile(LFCliBase): # profile.build(resource, radio, 64) # class StationProfile: - def __init__(self, lfclient_url, ssid="NA", ssid_pass="NA", security="open", number_template_="00000", mode=0, up=True, + def __init__(self, lfclient_url, local_realm, ssid="NA", ssid_pass="NA", security="open", number_template_="00000", mode=0, up=True, dhcp=True, debug_=False): self.debug = debug_ self.lfclient_url = lfclient_url @@ -667,8 +862,9 @@ class StationProfile: self.up = up self.dhcp = dhcp self.security = security + self.local_realm = local_realm self.COMMANDS = ["add_sta", "set_port"] - self.desired_add_sta_flags = ["wpa2_enable", "80211u_enable", "create_admin_down"] + self.desired_add_sta_flags = ["wpa2_enable", "80211u_enable", "create_admin_down"] self.desired_add_sta_flags_mask = ["wpa2_enable", "80211u_enable", "create_admin_down"] self.number_template = number_template_ self.station_names = [] @@ -682,6 +878,7 @@ class StationProfile: "mode": 0, "mac": "xx:xx:xx:xx:*:xx", "flags": 0, # (0x400 + 0x20000 + 0x1000000000) # create admin down + } self.desired_set_port_cmd_flags = [] self.desired_set_port_current_flags = ["if_down"] @@ -700,19 +897,31 @@ class StationProfile: # TODO: create use_wpa3() - def use_wpa2(self, on=False, ssid=None, passwd=None): + def use_security(self, security_type, ssid=None, passwd=None): + types = {"wep": "wep_enable", "wpa": "wpa_enable", "wpa2": "wpa2_enable", "wpa3": "use-wpa3", "open": "[BLANK]"} self.add_sta_data["ssid"] = ssid - if on: + if security_type in types.keys(): if (ssid is None) or ("" == ssid): - raise ValueError("use_wpa2: WPA2 requires ssid") + raise ValueError("use_security: %s requires ssid" % security_type) if (passwd is None) or ("" == passwd): - raise ValueError("use_wpa2: WPA2 requires passphrase or [BLANK]") + raise ValueError("use_security: %s requires passphrase or [BLANK]" % security_type) + for name in types.values(): + if name in self.desired_add_sta_flags and name in self.desired_add_sta_flags_mask: + self.desired_add_sta_flags.remove(name) + self.desired_add_sta_flags_mask.remove(name) + if security_type != "open": + self.desired_add_sta_flags.append(types[security_type]) + #self.set_command_flag("add_sta", types[security_type], 1) + self.desired_add_sta_flags_mask.append(types[security_type]) + else: + passwd = "[BLANK]" self.set_command_param("add_sta", "ssid", ssid) self.set_command_param("add_sta", "key", passwd) - self.set_command_flag("add_sta", "wpa2_enable", 1) - self.add_sta_data["key"] = passwd - else: - self.set_command_flag("add_sta", "wpa2_enable", 0) + # unset any other security flag before setting our present flags + if security_type == "wpa3": + self.set_command_param("add_sta", "ieee80211w", 2) + + #self.add_sta_data["key"] = passwd def set_command_param(self, command_name, param_name, param_value): # we have to check what the param name is @@ -745,8 +954,10 @@ class StationProfile: return if (value == 1) and (param_name not in self.desired_add_sta_flags): self.desired_add_sta_flags.append(param_name) + self.desired_add_sta_flags_mask.append(param_name) elif value == 0: self.desired_add_sta_flags.remove(param_name) + self.desired_add_sta_flags_mask.append(param_name) elif command_name == "set_port": if (param_name not in set_port.set_port_current_flags) and (param_name not in set_port.set_port_cmd_flags) and (param_name not in set_port.set_port_interest_flags): @@ -808,6 +1019,21 @@ class StationProfile: json_response = set_port_r.jsonPost(self.debug) time.sleep(0.03) + def cleanup(self, resource, desired_stations): + current_stations = self.local_realm.json_get("port/1/%s/%s?fields=alias" % (resource, ','.join(self.station_names))) + if current_stations is not None and current_stations['interfaces'] is not None: + print("Cleaning up stations") + for station in current_stations['interfaces']: + for eid,info in station.items(): + if info['alias'] in desired_stations: + req_url = "cli-json/rm_vlan" + data = { + "shelf": 1, + "resource": resource, + "port": info['alias'] + } + self.local_realm.json_post(req_url, data) + # Checks for errors in initialization values and creates specified number of stations using init parameters def create(self, resource, radio, num_stations=0, sta_names_=None, dry_run=False, up_=None, debug=False): # try: @@ -831,9 +1057,10 @@ class StationProfile: self.desired_add_sta_flags.append("create_admin_down") # create stations down, do set_port on them, then set stations up - self.add_sta_data["flags"] = self.add_named_flags(self.desired_add_sta_flags, add_sta.add_sta_flags) + self.add_sta_data["flags"] = self.add_named_flags(self.desired_add_sta_flags, add_sta.add_sta_flags) self.add_sta_data["flags_mask"] = self.add_named_flags(self.desired_add_sta_flags_mask, add_sta.add_sta_flags) self.add_sta_data["radio"] = radio + self.add_sta_data["resource"] = resource self.set_port_data["current_flags"] = self.add_named_flags(self.desired_set_port_current_flags, set_port.set_port_current_flags) diff --git a/py-scripts/test_ipv4_l4.py b/py-scripts/test_ipv4_l4.py index 38411f9f..f4560cd1 100755 --- a/py-scripts/test_ipv4_l4.py +++ b/py-scripts/test_ipv4_l4.py @@ -19,7 +19,7 @@ import datetime class IPV4L4(LFCliBase): - def __init__(self, host, port, ssid, security, password, url, requests_per_ten, station_list, prefix="00000", + def __init__(self, host, port, ssid, security, password, url, requests_per_ten, station_list, number_template="00000", resource=1, test_duration="5m", _debug_on=False, @@ -33,33 +33,25 @@ class IPV4L4(LFCliBase): self.password = password self.url = url self.requests_per_ten = requests_per_ten - self.prefix = prefix + self.number_template = number_template self.sta_list = station_list self.resource = resource self.test_duration = test_duration self.local_realm = realm.Realm(lfclient_host=self.host, lfclient_port=self.port) - self.profile = realm.StationProfile(self.lfclient_url, ssid=self.ssid, ssid_pass=self.password, - security=self.security, number_template_=self.prefix, mode=0, up=False, - dhcp=True, - debug_=False) - self.cx_profile = realm.L4CXProfile(lfclient_host=self.host, lfclient_port=self.port, - local_realm=self.local_realm, debug_=False) + self.station_profile = self.local_realm.new_station_profile() + self.cx_profile = self.local_realm.new_l4_cx_profile() + + self.station_profile.lfclient_url = self.lfclient_url + self.station_profile.ssid = self.ssid + self.station_profile.ssid_pass = self.password, + self.station_profile.security = self.security + self.station_profile.number_template_ = self.number_template + self.station_profile.mode = 0 + self.cx_profile.url = self.url self.cx_profile.requests_per_ten = self.requests_per_ten - def __set_all_cx_state(self, state, sleep_time=5): - print("Setting CX States to %s" % state) - for sta_name in self.sta_list: - req_url = "cli-json/set_cx_state" - data = { - "test_mgr": "default_tm", - "cx_name": "CX_" + sta_name + "_l4", - "cx_state": state - } - self.json_post(req_url, data) - time.sleep(sleep_time) - def __compare_vals(self, old_list, new_list): passes = 0 expected_passes = 0 @@ -68,7 +60,7 @@ class IPV4L4(LFCliBase): expected_passes += 1 if new_list[item] > old_list[item]: passes += 1 - # print(item, new_list[item], old_list[item], passes, expected_passes) + #print(item, new_list[item], old_list[item], passes, expected_passes) if passes == expected_passes: return True @@ -91,13 +83,13 @@ class IPV4L4(LFCliBase): def build(self): # Build stations - self.profile.use_wpa2(True, self.ssid, self.password) - self.profile.set_number_template(self.prefix) + self.station_profile.use_security(self.security, self.ssid, self.password) + self.station_profile.set_number_template(self.number_template) print("Creating stations") - self.profile.set_command_flag("add_sta", "create_admin_down", 1) - self.profile.set_command_param("set_port", "report_timer", 1500) - self.profile.set_command_flag("set_port", "rpt_timer", 1) - self.profile.create(resource=1, radio="wiphy0", sta_names_=self.sta_list, debug=self.debug) + self.station_profile.set_command_flag("add_sta", "create_admin_down", 1) + self.station_profile.set_command_param("set_port", "report_timer", 1500) + self.station_profile.set_command_flag("set_port", "rpt_timer", 1) + self.station_profile.create(resource=1, radio="wiphy0", sta_names_=self.sta_list, debug=self.debug) self._pass("PASS: Station build finished") temp_sta_list = [] for station in range(len(self.sta_list)): @@ -109,9 +101,11 @@ class IPV4L4(LFCliBase): cur_time = datetime.datetime.now() old_rx_values = self.__get_values() end_time = self.local_realm.parse_time(self.test_duration) + cur_time - self.profile.admin_up(1) - self.local_realm.wait_for_ip() - self.__set_all_cx_state("RUNNING") + self.station_profile.admin_up(1) + temp_stas = self.sta_list.copy() + temp_stas.append("eth1") + self.local_realm.wait_for_ip(self.resource, temp_stas) + self.cx_profile.start_cx() passes = 0 expected_passes = 0 while cur_time < end_time: @@ -133,59 +127,19 @@ class IPV4L4(LFCliBase): break old_rx_values = new_rx_values cur_time = datetime.datetime.now() - - # test for valid url, no 404s - # new script; desired minimum urls for 10 min + if passes == expected_passes: + self._pass("PASS: All tests passes", print_pass) def stop(self): - self.__set_all_cx_state("STOPPED") + self.cx_profile.stop_cx() for sta_name in self.sta_list: data = LFUtils.portDownRequest(1, sta_name) url = "json-cli/set_port" self.json_post(url, data) - def cleanup(self): - layer4_list = self.json_get("layer4/list?fields=name") - print(layer4_list) - - if layer4_list is not None and 'endpoint' in layer4_list: - if layer4_list['endpoint'] is not None: - - for name in self.sta_list: - req_url = "cli-json/rm_cx" - data = { - "test_mgr": "default_tm", - "cx_name": "CX_" + name + "_l4" - } - self.json_post(req_url, data, True) - - time.sleep(5) - for endps in list(layer4_list['endpoint']): - for name, info in endps.items(): - print(name) - - req_url = "cli-json/rm_endp" - data = { - "endp_name": name - } - self.json_post(req_url, data, True) - - port_list = self.local_realm.station_list() - sta_list = [] - for item in list(port_list): - # print(list(item)) - if "sta" in list(item)[0]: - sta_list.append(self.local_realm.name_to_eid(list(item)[0])[2]) - - for sta_name in sta_list: - req_url = "cli-json/rm_vlan" - data = { - "shelf": 1, - "resource": self.resource, - "port": sta_name - } - self.json_post(req_url, data, self.debug) - time.sleep(.05) + def cleanup(self, sta_list): + self.cx_profile.cleanup() + self.station_profile.cleanup(self.resource, sta_list) LFUtils.wait_until_ports_disappear(resource_id=self.resource, base_url=self.lfclient_url, port_list=sta_list, debug=self.debug) @@ -193,11 +147,11 @@ class IPV4L4(LFCliBase): def main(): lfjson_host = "localhost" lfjson_port = 8080 - station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=9, padding_number_=10000) + station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=1, padding_number_=10000) ip_test = IPV4L4(lfjson_host, lfjson_port, ssid="jedway-wpa2-x2048-4-4", password="jedway-wpa2-x2048-4-4", - security="open", station_list=station_list, url="dl http://10.40.0.1 /dev/null", test_duration="5m", + security="wpa2", station_list=station_list, url="dl http://10.40.0.1 /dev/null", test_duration="5m", requests_per_ten=600) - ip_test.cleanup() + ip_test.cleanup(station_list) ip_test.build() if not ip_test.passes(): print(ip_test.get_fail_message()) @@ -208,7 +162,7 @@ def main(): print(ip_test.get_fail_message()) exit(1) time.sleep(30) - ip_test.cleanup() + ip_test.cleanup(station_list) if ip_test.passes(): print("Full test passed, all endpoints had increased bytes-rd throughout test duration") diff --git a/py-scripts/test_ipv4_l4_urls_per_ten.py b/py-scripts/test_ipv4_l4_urls_per_ten.py index 85b26c1e..69340b1c 100755 --- a/py-scripts/test_ipv4_l4_urls_per_ten.py +++ b/py-scripts/test_ipv4_l4_urls_per_ten.py @@ -1,13 +1,13 @@ #!/usr/bin/env python3 import sys - +import os if sys.version_info[0] != 3: print("This script requires Python 3") exit(1) if 'py-json' not in sys.path: - sys.path.append('../py-json') + sys.path.append(os.path.join(os.path.abspath('..'), 'py-json')) import argparse from LANforge.lfcli_base import LFCliBase @@ -20,7 +20,7 @@ import datetime class IPV4L4(LFCliBase): def __init__(self, host, port, ssid, security, password, url, requests_per_ten, station_list, - target_requests_per_ten=600, prefix="00000", resource=1, num_tests=1, + target_requests_per_ten=600, number_template="00000", resource=1, num_tests=1, _debug_on=False, _exit_on_error=False, _exit_on_fail=False): @@ -32,19 +32,22 @@ class IPV4L4(LFCliBase): self.password = password self.url = url self.requests_per_ten = requests_per_ten - self.prefix = prefix + self.number_template = number_template self.sta_list = station_list self.resource = resource self.num_tests = num_tests self.target_requests_per_ten = target_requests_per_ten self.local_realm = realm.Realm(lfclient_host=self.host, lfclient_port=self.port) - self.profile = realm.StationProfile(self.lfclient_url, ssid=self.ssid, ssid_pass=self.password, - security=self.security, number_template_=self.prefix, mode=0, up=False, - dhcp=True, - debug_=False) - self.cx_profile = realm.L4CXProfile(lfclient_host=self.host, lfclient_port=self.port, - local_realm=self.local_realm, debug_=False) + self.station_profile = self.local_realm.new_station_profile() + self.cx_profile = self.local_realm.new_l4_cx_profile() + + self.station_profile.lfclient_url = self.lfclient_url + self.station_profile.ssid = self.ssid + self.station_profile.ssid_pass = self.password, + self.station_profile.security = self.security + self.station_profile.number_template_ = self.number_template + self.station_profile.mode = 0 self.cx_profile.url = self.url self.cx_profile.requests_per_ten = self.requests_per_ten @@ -76,13 +79,13 @@ class IPV4L4(LFCliBase): def build(self): # Build stations - self.profile.use_wpa2(True, self.ssid, self.password) - self.profile.set_number_template(self.prefix) + self.station_profile.use_security(self.security, self.ssid, self.password) + self.station_profile.set_number_template(self.number_template) print("Creating stations") - self.profile.set_command_flag("add_sta", "create_admin_down", 1) - self.profile.set_command_param("set_port", "report_timer", 1500) - self.profile.set_command_flag("set_port", "rpt_timer", 1) - self.profile.create(resource=1, radio="wiphy0", sta_names_=self.sta_list, debug=self.debug) + self.station_profile.set_command_flag("add_sta", "create_admin_down", 1) + self.station_profile.set_command_param("set_port", "report_timer", 1500) + self.station_profile.set_command_flag("set_port", "rpt_timer", 1) + self.station_profile.create(resource=1, radio="wiphy0", sta_names_=self.sta_list, debug=self.debug) self._pass("PASS: Station build finished") temp_sta_list = [] for station in range(len(self.sta_list)): @@ -91,13 +94,16 @@ class IPV4L4(LFCliBase): self.cx_profile.create(ports=temp_sta_list, sleep_time=.5, debug_=self.debug, suppress_related_commands_=None) def start(self, print_pass=False, print_fail=False): + print("Starting test") cur_time = datetime.datetime.now() interval_time = cur_time + datetime.timedelta(minutes=10) passes = 0 expected_passes = 0 - self.profile.admin_up(1) - self.local_realm.wait_for_ip() - self.__set_all_cx_state("RUNNING") + self.station_profile.admin_up(1) + temp_stas = self.sta_list.copy() + temp_stas.append("eth1") + self.local_realm.wait_for_ip(self.resource, temp_stas) + self.cx_profile.start_cx() for test in range(self.num_tests): expected_passes += 1 while cur_time < interval_time: @@ -118,53 +124,15 @@ class IPV4L4(LFCliBase): self._pass("PASS: All tests passes", print_pass) def stop(self): - self.__set_all_cx_state("STOPPED") + self.cx_profile.stop_cx() for sta_name in self.sta_list: data = LFUtils.portDownRequest(1, sta_name) url = "json-cli/set_port" self.json_post(url, data) - def cleanup(self): - layer4_list = self.json_get("layer4/list?fields=name") - print(layer4_list) - - if layer4_list is not None and 'endpoint' in layer4_list: - if layer4_list['endpoint'] is not None: - - for name in self.sta_list: - req_url = "cli-json/rm_cx" - data = { - "test_mgr": "default_tm", - "cx_name": "CX_" + name + "_l4" - } - self.json_post(req_url, data, True) - - time.sleep(5) - for endps in list(layer4_list['endpoint']): - for name, info in endps.items(): - print(name) - - req_url = "cli-json/rm_endp" - data = { - "endp_name": name - } - self.json_post(req_url, data, True) - - port_list = self.local_realm.station_list() - sta_list = [] - for item in list(port_list): - if "sta" in list(item)[0]: - sta_list.append(self.local_realm.name_to_eid(list(item)[0])[2]) - - for sta_name in sta_list: - req_url = "cli-json/rm_vlan" - data = { - "shelf": 1, - "resource": self.resource, - "port": sta_name - } - self.json_post(req_url, data, self.debug) - time.sleep(.05) + def cleanup(self, sta_list): + self.cx_profile.cleanup() + self.station_profile.cleanup(self.resource, sta_list) LFUtils.wait_until_ports_disappear(resource_id=self.resource, base_url=self.lfclient_url, port_list=sta_list, debug=self.debug) @@ -172,12 +140,12 @@ class IPV4L4(LFCliBase): def main(): lfjson_host = "localhost" lfjson_port = 8080 - station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=9, padding_number_=10000) + station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=1, padding_number_=10000) ip_test = IPV4L4(lfjson_host, lfjson_port, ssid="jedway-wpa2-x2048-4-4", password="jedway-wpa2-x2048-4-4", - security="open", station_list=station_list, url="dl http://10.40.0.1 /dev/null", num_tests=1, + security="wpa2", station_list=station_list, url="dl http://10.40.0.1 /dev/null", num_tests=1, target_requests_per_ten=600, requests_per_ten=600) - ip_test.cleanup() + ip_test.cleanup(station_list) ip_test.build() ip_test.start() ip_test.stop() @@ -185,7 +153,7 @@ def main(): print(ip_test.get_fail_message()) exit(1) time.sleep(30) - ip_test.cleanup() + ip_test.cleanup(station_list) if ip_test.passes(): print("Full test passed, all endpoints met or exceeded 90% of the target rate") diff --git a/py-scripts/test_ipv4_variable_time.py b/py-scripts/test_ipv4_variable_time.py index 4d00604b..ce45bbed 100755 --- a/py-scripts/test_ipv4_variable_time.py +++ b/py-scripts/test_ipv4_variable_time.py @@ -1,25 +1,28 @@ #!/usr/bin/env python3 import sys +import os if sys.version_info[0] != 3: print("This script requires Python 3") exit(1) if 'py-json' not in sys.path: - sys.path.append('../py-json') + sys.path.append(os.path.join(os.path.abspath('..'), 'py-json')) import argparse from LANforge.lfcli_base import LFCliBase -from LANforge.LFUtils import * +from LANforge import LFUtils import realm import time import datetime class IPV4VariableTime(LFCliBase): - def __init__(self, host, port, ssid, security, password, num_stations, side_a_min_rate=56, side_b_min_rate=56, side_a_max_rate=0, - side_b_max_rate=0, prefix="00000", test_duration="5m", + def __init__(self, host, port, ssid, security, password, sta_list, name_prefix, resource=1, + side_a_min_rate=56, side_a_max_rate=0, + side_b_min_rate=56, side_b_max_rate=0, + number_template="00000", test_duration="5m", _debug_on=False, _exit_on_error=False, _exit_on_fail=False): @@ -27,33 +30,32 @@ class IPV4VariableTime(LFCliBase): self.host = host self.port = port self.ssid = ssid + self.sta_list = sta_list self.security = security self.password = password - self.num_stations = num_stations - self.prefix = prefix - self.local_realm = realm.Realm(lfclient_host=self.host, lfclient_port=self.port) - self.station_profile = realm.StationProfile(self.lfclient_url, ssid=self.ssid, ssid_pass=self.password, - security=self.security, number_template_=self.prefix, mode=0, up=True, - dhcp=True, - debug_=False) - self.cx_profile = realm.L3CXProfile(self.host, self.port, self.local_realm, side_a_min_bps=side_a_min_rate, - side_b_min_bps=side_b_min_rate, side_a_max_bps=side_a_max_rate, - side_b_max_bps=side_b_max_rate, debug_=False) + self.number_template = number_template + self.resource = resource + self.name_prefix = name_prefix self.test_duration = test_duration + self.local_realm = realm.Realm(lfclient_host=self.host, lfclient_port=self.port) + self.station_profile = self.local_realm.new_station_profile() + self.cx_profile = self.local_realm.new_l3_cx_profile() + + self.station_profile.lfclient_url = self.lfclient_url + self.station_profile.ssid = self.ssid + self.station_profile.ssid_pass = self.password, + self.station_profile.security = self.security + self.station_profile.number_template_ = self.number_template + self.station_profile.mode = 0 + + self.cx_profile.host = self.host + self.cx_profile.port = self.port + self.cx_profile.name_prefix = self.name_prefix + self.cx_profile.side_a_min_bps = side_a_min_rate + self.cx_profile.side_a_max_bps = side_a_max_rate + self.cx_profile.side_b_min_bps = side_b_min_rate + self.cx_profile.side_b_max_bps = side_b_max_rate - def __set_all_cx_state(self, state, sleep_time=5): - print("Setting CX States to %s" % state) - cx_list = list(self.local_realm.cx_list()) - for cx_name in cx_list: - if cx_name != 'handler' or cx_name != 'uri': - req_url = "cli-json/set_cx_state" - data = { - "test_mgr": "default_tm", - "cx_name": cx_name, - "cx_state": state - } - self.json_post(req_url, data) - time.sleep(sleep_time) def __get_rx_values(self): cx_list = self.json_get("endp?fields=name,rx+bytes", debug_=True) @@ -84,11 +86,15 @@ class IPV4VariableTime(LFCliBase): else: return False - def run_test(self, print_pass=False, print_fail=False): + def start(self, print_pass=False, print_fail=False): + self.station_profile.admin_up(self.resource) + temp_stas = self.sta_list.copy() + temp_stas.append("eth1") + self.local_realm.wait_for_ip(self.resource, temp_stas) cur_time = datetime.datetime.now() old_cx_rx_values = self.__get_rx_values() end_time = self.local_realm.parse_time(self.test_duration) + cur_time - self.__set_all_cx_state("RUNNING") + self.cx_profile.start_cx() passes = 0 expected_passes = 0 while cur_time < end_time: @@ -114,79 +120,60 @@ class IPV4VariableTime(LFCliBase): if passes == expected_passes: self._pass("PASS: All tests passed", print_pass) - self.__set_all_cx_state("STOPPED") + def stop(self): + self.cx_profile.stop_cx() + for sta_name in self.sta_list: + data = LFUtils.portDownRequest(1, sta_name) + url = "json-cli/set_port" + self.json_post(url, data) - def cleanup(self): - print("Cleaning up stations") - port_list = self.local_realm.station_list() - sta_list = [] - for item in list(port_list): - # print(list(item)) - if "sta" in list(item)[0]: - sta_list.append(self.local_realm.name_to_eid(list(item)[0])[2]) + def cleanup(self, sta_list): + self.cx_profile.cleanup() + self.station_profile.cleanup(self.resource, sta_list) + LFUtils.wait_until_ports_disappear(resource_id=self.resource, base_url=self.lfclient_url, port_list=sta_list, + debug=self.debug) - for sta_name in sta_list: - req_url = "cli-json/rm_vlan" - data = { - "shelf": 1, - "resource": 1, - "port": sta_name - } - # print(data) - self.json_post(req_url, data) - - cx_list = list(self.local_realm.cx_list()) - if cx_list is not None: - print("Cleaning up cxs") - for cx_name in cx_list: - if cx_name != 'handler' or cx_name != 'uri': - req_url = "cli-json/rm_cx" - data = { - "test_mgr": "default_tm", - "cx_name": cx_name - } - self.json_post(req_url, data) - - print("Cleaning up endps") - endp_list = self.json_get("/endp") - if endp_list is not None: - endp_list = list(endp_list['endpoint']) - for endp_name in range(len(endp_list)): - name = list(endp_list[endp_name])[0] - req_url = "cli-json/rm_endp" - data = { - "endp_name": name - } - self.json_post(req_url, data) - - def run(self): - sta_list = [] - - self.station_profile.use_wpa2(True, self.ssid, self.password) - self.station_profile.set_number_template(self.prefix) + def build(self): + self.station_profile.use_security(self.security, self.ssid, self.password) + self.station_profile.set_number_template(self.number_template) print("Creating stations") - self.station_profile.create(resource=1, radio="wiphy0", num_stations=self.num_stations, debug=False) - - for name in list(self.local_realm.station_list()): - if "sta" in list(name)[0]: - sta_list.append(list(name)[0]) - - print("sta_list", sta_list) - self.cx_profile.create(endp_type="lf_udp", side_a=sta_list, side_b="1.eth1", sleep_time=.5) + self.station_profile.set_command_flag("add_sta", "create_admin_down", 1) + self.station_profile.set_command_param("set_port", "report_timer", 1500) + self.station_profile.set_command_flag("set_port", "rpt_timer", 1) + temp_sta_list = [] + for station in range(len(self.sta_list)): + temp_sta_list.append(str(self.resource) + "." + self.sta_list[station]) + self.station_profile.create(resource=1, radio="wiphy0", sta_names_=self.sta_list, debug=False) + self.cx_profile.create(endp_type="lf_udp", side_a=temp_sta_list, side_b="1.eth1", sleep_time=.5) + self._pass("PASS: Station build finished") def main(): lfjson_host = "localhost" lfjson_port = 8080 - ip_var_test = IPV4VariableTime(lfjson_host, lfjson_port, prefix="00", ssid="jedway-wpa2-x2048-4-4", + station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=4, padding_number_=10000) + ip_var_test = IPV4VariableTime(lfjson_host, lfjson_port, number_template="00", sta_list=station_list, + name_prefix="var_time", + ssid="jedway-wpa2-x2048-4-4", password="jedway-wpa2-x2048-4-4", - security="open", num_stations=10, test_duration="5m", + resource=1, + security="wpa2", test_duration="5m", side_a_min_rate=256, side_b_min_rate=256) - ip_var_test.cleanup() - ip_var_test.run() - time.sleep(5) - ip_var_test.run_test(print_pass=True, print_fail=True) - ip_var_test.cleanup() + + ip_var_test.cleanup(station_list) + ip_var_test.build() + if not ip_var_test.passes(): + print(ip_var_test.get_fail_message()) + exit(1) + ip_var_test.start(False, False) + ip_var_test.stop() + if not ip_var_test.passes(): + print(ip_var_test.get_fail_message()) + exit(1) + time.sleep(30) + ip_var_test.cleanup(station_list) + if ip_var_test.passes(): + print("Full test passed, all connections increased rx bytes") if __name__ == "__main__": diff --git a/py-scripts/test_ipv6_connection.py b/py-scripts/test_ipv6_connection.py index 682257eb..3b3ee89f 100755 --- a/py-scripts/test_ipv6_connection.py +++ b/py-scripts/test_ipv6_connection.py @@ -7,7 +7,7 @@ if sys.version_info[0] != 3: exit(1) if 'py-json' not in sys.path: - sys.path.append('../py-json') + sys.path.append(os.path.join(os.path.abspath('..'), 'py-json')) import LANforge from LANforge.lfcli_base import LFCliBase from LANforge import LFUtils @@ -17,7 +17,8 @@ import pprint class IPv6Test(LFCliBase): - def __init__(self, host, port, ssid, security, password, sta_list=None, num_stations=0, prefix="00000", _debug_on=False, + def __init__(self, host, port, ssid, security, password, resource=1, sta_list=None, num_stations=0, prefix="00000", + _debug_on=False, _exit_on_error=False, _exit_on_fail=False): super().__init__(host, port, _debug=_debug_on, _halt_on_error=_exit_on_error, _exit_on_fail=_exit_on_fail) @@ -29,16 +30,21 @@ class IPv6Test(LFCliBase): self.num_stations = num_stations self.sta_list = sta_list self.timeout = 120 + self.resource = resource self.prefix = prefix self.debug = _debug_on self.local_realm = realm.Realm(lfclient_host=self.host, lfclient_port=self.port) - self.profile = realm.StationProfile(self.lfclient_url, ssid=self.ssid, ssid_pass=self.password, - security=self.security, number_template_=self.prefix, mode=0, up=False, dhcp=True, - debug_=False) + self.station_profile = self.local_realm.new_station_profile() + + self.station_profile.lfclient_url = self.lfclient_url + self.station_profile.ssid = self.ssid + self.station_profile.ssid_pass = self.password, + self.station_profile.security = self.security + self.station_profile.number_template_ = self.number_template + self.station_profile.mode = 0 def build(self): - # Build stations - self.profile.use_wpa2(True, self.ssid, self.password) + self.station_profile.use_security(self.security, self.ssid, self.password) self.profile.set_number_template(self.prefix) print("Creating stations") self.profile.set_command_flag("add_sta", "create_admin_down", 1) @@ -48,7 +54,6 @@ class IPv6Test(LFCliBase): self._pass("PASS: Station build finished") def start(self, sta_list, print_pass, print_fail): - # Bring stations up self.profile.admin_up(1) associated_map = {} ip_map = {} @@ -94,34 +99,19 @@ class IPv6Test(LFCliBase): # print(sta_name) self.json_post(url, data) - def cleanup(self, resource): - port_list = self.local_realm.station_list() - sta_list = [] - print("Cleaning up...") - for item in list(port_list): - # print(list(item)) - if "sta" in list(item)[0]: - sta_list.append(self.local_realm.name_to_eid(list(item)[0])[2]) - - for sta_name in sta_list: - req_url = "cli-json/rm_vlan" - data = { - "shelf": 1, - "resource": 1, - "port": sta_name - } - self.json_post(req_url, data, self.debug) - time.sleep(.05) - LFUtils.wait_until_ports_disappear(resource_id=resource, base_url=self.lfclient_url, port_list=sta_list, debug=self.debug) + def cleanup(self, sta_list): + self.profile.cleanup(self.resource, sta_list) + LFUtils.wait_until_ports_disappear(resource_id=self.resource, base_url=self.lfclient_url, port_list=sta_list, + debug=self.debug) def main(): lfjson_host = "localhost" lfjson_port = 8080 - station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=29, padding_number_=10000) + station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=1, padding_number_=10000) ipv6_test = IPv6Test(lfjson_host, lfjson_port, ssid="jedway-wpa2-x2048-4-4", password="jedway-wpa2-x2048-4-4", - security="open", sta_list=station_list) - ipv6_test.cleanup(1) + security="wpa2", sta_list=station_list) + ipv6_test.cleanup(station_list) ipv6_test.timeout = 60 ipv6_test.build() if not ipv6_test.passes(): @@ -133,7 +123,7 @@ def main(): print(ipv6_test.get_fail_message()) exit(1) time.sleep(30) - ipv6_test.cleanup(1) + ipv6_test.cleanup(station_list) if ipv6_test.passes(): print("Full test passed, all stations associated and got IP") diff --git a/py-scripts/test_ipv6_variable_time.py b/py-scripts/test_ipv6_variable_time.py index 22f06ff3..c647ab95 100755 --- a/py-scripts/test_ipv6_variable_time.py +++ b/py-scripts/test_ipv6_variable_time.py @@ -1,25 +1,29 @@ #!/usr/bin/env python3 import sys +import os if sys.version_info[0] != 3: print("This script requires Python 3") exit(1) if 'py-json' not in sys.path: - sys.path.append('../py-json') + sys.path.append(os.path.join(os.path.abspath('..'), 'py-json')) import argparse from LANforge.lfcli_base import LFCliBase -from LANforge.LFUtils import * +from LANforge import LFUtils import realm import time import datetime class IPV6VariableTime(LFCliBase): - def __init__(self, host, port, ssid, security, password, num_stations, side_a_min_rate=56, side_b_min_rate=56, side_a_max_rate=0, - side_b_max_rate=0, prefix="00000", test_duration="5m", + def __init__(self, host, port, ssid, security, password, name_prefix, sta_list, + side_a_min_rate=56, side_a_max_rate=0, + side_b_min_rate=56, side_b_max_rate=0, + number_template="00000", test_duration="5m", + resource=1, _debug_on=False, _exit_on_error=False, _exit_on_fail=False): @@ -27,33 +31,32 @@ class IPV6VariableTime(LFCliBase): self.host = host self.port = port self.ssid = ssid + self.sta_list = sta_list + self.name_prefix = name_prefix self.security = security self.password = password - self.num_stations = num_stations - self.prefix = prefix - self.local_realm = realm.Realm(lfclient_host=self.host, lfclient_port=self.port) - self.station_profile = realm.StationProfile(self.lfclient_url, ssid=self.ssid, ssid_pass=self.password, - security=self.security, number_template_=self.prefix, mode=0, up=True, - dhcp=True, - debug_=False) - self.cx_profile = realm.L3CXProfile(self.host, self.port, self.local_realm, side_a_min_rate=side_a_min_rate, - side_b_min_rate=side_b_min_rate, side_a_max_rate=side_a_max_rate, - side_b_max_rate=side_b_max_rate, debug_=False) + self.number_template = number_template + self.resource = resource self.test_duration = test_duration + self.local_realm = realm.Realm(lfclient_host=self.host, lfclient_port=self.port) + self.station_profile = self.local_realm.new_station_profile() + self.cx_profile = self.local_realm.new_l3_cx_profile() + + self.station_profile.lfclient_url = self.lfclient_url + self.station_profile.ssid = self.ssid + self.station_profile.ssid_pass = self.password, + self.station_profile.security = self.security + self.station_profile.number_template_ = self.number_template + self.station_profile.mode = 0 + + self.cx_profile.host = self.host + self.cx_profile.port = self.port + self.cx_profile.name_prefix = self.name_prefix + self.cx_profile.side_a_min_bps = side_a_min_rate + self.cx_profile.side_a_max_bps = side_a_max_rate + self.cx_profile.side_b_min_bps = side_b_min_rate + self.cx_profile.side_b_max_bps = side_b_max_rate - def __set_all_cx_state(self, state, sleep_time=5): - print("Setting CX States to %s" % state) - cx_list = list(self.local_realm.cx_list()) - for cx_name in cx_list: - if cx_name != 'handler' or cx_name != 'uri': - req_url = "cli-json/set_cx_state" - data = { - "test_mgr": "default_tm", - "cx_name": cx_name, - "cx_state": state - } - self.json_post(req_url, data) - time.sleep(sleep_time) def __get_rx_values(self): cx_list = self.json_get("endp?fields=name,rx+bytes", debug_=True) @@ -84,11 +87,16 @@ class IPV6VariableTime(LFCliBase): else: return False - def run_test(self, print_pass=False, print_fail=False): + def start(self, print_pass=False, print_fail=False): + print("Starting test") + self.station_profile.admin_up(self.resource) + temp_stas = self.sta_list.copy() + temp_stas.append("eth1") + self.local_realm.wait_for_ip(self.resource, temp_stas, ipv6=True) cur_time = datetime.datetime.now() old_cx_rx_values = self.__get_rx_values() end_time = self.local_realm.parse_time(self.test_duration) + cur_time - self.__set_all_cx_state("RUNNING") + self.cx_profile.start_cx() passes = 0 expected_passes = 0 while cur_time < end_time: @@ -114,79 +122,58 @@ class IPV6VariableTime(LFCliBase): if passes == expected_passes: self._pass("PASS: All tests passed", print_pass) - self.__set_all_cx_state("STOPPED") + def stop(self): + self.cx_profile.stop_cx() + for sta_name in self.sta_list: + data = LFUtils.portDownRequest(1, sta_name) + url = "json-cli/set_port" + self.json_post(url, data) - def cleanup(self): - print("Cleaning up stations") - port_list = self.local_realm.station_list() - sta_list = [] - for item in list(port_list): - # print(list(item)) - if "sta" in list(item)[0]: - sta_list.append(self.local_realm.name_to_eid(list(item)[0])[2]) - - for sta_name in sta_list: - req_url = "cli-json/rm_vlan" - data = { - "shelf": 1, - "resource": 1, - "port": sta_name - } - # print(data) - self.json_post(req_url, data) - - cx_list = list(self.local_realm.cx_list()) - if cx_list is not None: - print("Cleaning up cxs") - for cx_name in cx_list: - if cx_name != 'handler' or cx_name != 'uri': - req_url = "cli-json/rm_cx" - data = { - "test_mgr": "default_tm", - "cx_name": cx_name - } - self.json_post(req_url, data) - - print("Cleaning up endps") - endp_list = self.json_get("/endp") - if endp_list is not None: - endp_list = list(endp_list['endpoint']) - for endp_name in range(len(endp_list)): - name = list(endp_list[endp_name])[0] - req_url = "cli-json/rm_endp" - data = { - "endp_name": name - } - self.json_post(req_url, data) + def cleanup(self, sta_list): + self.cx_profile.cleanup() + self.station_profile.cleanup(self.resource, sta_list) + LFUtils.wait_until_ports_disappear(resource_id=self.resource, base_url=self.lfclient_url, port_list=sta_list, + debug=self.debug) def build(self): - sta_list = [] - - self.station_profile.use_wpa2(True, self.ssid, self.password) - self.station_profile.set_number_template(self.prefix) + self.station_profile.use_security(self.security, self.ssid, self.password) + self.station_profile.set_number_template(self.number_template) print("Creating stations") - self.station_profile.create(resource=1, radio="wiphy0", num_stations=self.num_stations, debug=False) - - for name in list(self.local_realm.station_list()): - if "sta" in list(name)[0]: - sta_list.append(list(name)[0]) - - print("sta_list", sta_list) - self.cx_profile.create(endp_type="lf_udp6", side_a=sta_list, side_b="1.eth1", sleep_time=.5) + self.station_profile.set_command_flag("add_sta", "create_admin_down", 1) + self.station_profile.set_command_param("set_port", "report_timer", 1500) + self.station_profile.set_command_flag("set_port", "rpt_timer", 1) + temp_sta_list = [] + for station in range(len(self.sta_list)): + temp_sta_list.append(str(self.resource) + "." + self.sta_list[station]) + self.station_profile.create(resource=1, radio="wiphy0", sta_names_=self.sta_list, debug=False) + self.cx_profile.create(endp_type="lf_udp6", side_a=temp_sta_list, side_b="1.eth1", sleep_time=.5) + self._pass("PASS: Station build finished") def main(): lfjson_host = "localhost" lfjson_port = 8080 - ip_var_test = IPV6VariableTime(lfjson_host, lfjson_port, prefix="00", ssid="jedway-wpa2-x2048-4-4", + station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=1, padding_number_=10000) + ip_var_test = IPV6VariableTime(lfjson_host, lfjson_port, number_template="00", sta_list=station_list, + name_prefix="var_time", + ssid="jedway-wpa2-x2048-4-4", password="jedway-wpa2-x2048-4-4", - security="open", num_stations=10, test_duration="5m", + resource=1, security="wpa2", test_duration="5m", side_a_min_rate=256, side_b_min_rate=256) - ip_var_test.cleanup() + ip_var_test.cleanup(station_list) ip_var_test.build() - time.sleep(5) - ip_var_test.run_test(print_pass=True, print_fail=True) - ip_var_test.cleanup() + if not ip_var_test.passes(): + print(ip_var_test.get_fail_message()) + exit(1) + ip_var_test.start(False, False) + ip_var_test.stop() + if not ip_var_test.passes(): + print(ip_var_test.get_fail_message()) + exit(1) + time.sleep(30) + ip_var_test.cleanup(station_list) + if ip_var_test.passes(): + print("Full test passed, all connections increased rx bytes") if __name__ == "__main__": diff --git a/py-scripts/test_l3_powersave_traffic.py b/py-scripts/test_l3_powersave_traffic.py old mode 100644 new mode 100755 index 443212a0..3c1faf1c --- a/py-scripts/test_l3_powersave_traffic.py +++ b/py-scripts/test_l3_powersave_traffic.py @@ -21,9 +21,8 @@ import datetime #Currently, this test can only be applied to UDP connections class L3PowersaveTraffic(LFCliBase): - #attributes: station list, side_a_min_rate (and max_rate), side_b_min_rate (and max_rate), def __init__(self, host, port, ssid, security, password, station_list, side_a_min_rate=56, side_b_min_rate=56, side_a_max_rate=0, - side_b_max_rate=0, prefix="00000", test_duration="5m", + side_b_max_rate=0, pdu_size = 1000, prefix="00000", test_duration="5m", _debug_on=False, _exit_on_error=False, _exit_on_fail=False): super().__init__(host, port, _debug=_debug_on, _halt_on_error=_exit_on_error, _exit_on_fail=_exit_on_fail) self.host = host @@ -33,128 +32,149 @@ class L3PowersaveTraffic(LFCliBase): self.password = password self.sta_list = station_list self.prefix = prefix - self.local_realm = realm.Realm(lfclient_host=self.host, lfclient_port=self.port) + self.debug = _debug_on + self.local_realm = realm.Realm(lfclient_host=self.host, lfclient_port=self.port, debug_=False, halt_on_error_=True) #upload - self.cx_prof_upload = realm.L3CXProfile(self.host, self.port, self.local_realm, side_a_min_bps=side_a_min_rate, - side_b_min_bps=0, side_a_max_bps=side_a_max_rate, - side_b_max_bps=0, debug_=True) + self.cx_prof_upload = realm.L3CXProfile(self.host, self.port, self.local_realm, + side_a_min_bps=side_a_min_rate,side_b_min_bps=0, + side_a_max_bps=side_a_max_rate,side_b_max_bps=0, + side_a_min_pdu=pdu_size, side_a_max_pdu=pdu_size, + side_b_min_pdu=0, side_b_max_pdu=0, debug_=False) #download - self.cx_prof_download = realm.L3CXProfile(self.host, self.port, self.local_realm, side_a_min_bps=0, - side_b_min_bps=side_b_min_rate, side_a_max_bps=0, - side_b_max_bps=side_b_max_rate, debug_=True) + self.cx_prof_download = realm.L3CXProfile(self.host, self.port, self.local_realm, + side_a_min_bps=0, side_b_min_bps=side_b_min_rate, + side_a_max_bps=0,side_b_max_bps=side_b_max_rate, + side_a_min_pdu=0, side_a_max_pdu=0, + side_b_min_pdu=pdu_size,side_b_max_pdu=pdu_size, debug_=False) self.test_duration = test_duration - self.station_profile = realm.StationProfile(self.lfclient_url, ssid=self.ssid, ssid_pass=self.password, + self.station_profile = realm.StationProfile(self.lfclient_url, self.local_realm, ssid=self.ssid, ssid_pass=self.password, security=self.security, number_template_=self.prefix, mode=0, up=True, dhcp=True, debug_=False) - self.station_profile.admin_up(resource=1) + self.new_monitor = realm.WifiMonitor(self.lfclient_url, self.local_realm,debug_= _debug_on) + - def build(self,UorD): - #upload would set TXBPs on A side of endpoint - #download would set TXBps on B side of endpoint - #build - print("Creating stations for" + UorD + "traffic") - self.station_profile.use_wpa2(False, self.ssid, self.password) + def build(self): + self.station_profile.use_security("open", ssid=self.ssid, passwd=self.password) self.station_profile.set_number_template(self.prefix) self.station_profile.set_command_flag("add_sta", "create_admin_down", 1) self.station_profile.set_command_param("set_port", "report_timer", 1500) self.station_profile.set_command_flag("set_port", "rpt_timer", 1) self.station_profile.set_command_flag("add_sta", "power_save_enable", 1) + #channel = self.json_get("/port/1/%s/%s/"%(1,"wiphy0")) + #rint("The channel name is...") + self.new_monitor.create(resource_=1, channel=157, radio_= "wiphy1", name_="moni0") self.station_profile.create(resource=1, radio="wiphy0", sta_names_=self.sta_list, debug=False) + # station_channel = self.json_get("/port/1/%s/%s") + # pprint.pprint(station_channel) - self._pass("PASS: Station build for" + UorD + "finished") + + self._pass("PASS: Station builds finished") temp_sta_list = [] for name in list(self.local_realm.station_list()): if "sta" in list(name)[0]: temp_sta_list.append(list(name)[0]) - print("temp_sta_list", temp_sta_list) + + #print("temp_sta_list", temp_sta_list) self.cx_prof_upload.name_prefix = "UDP_up" self.cx_prof_download.name_prefix = "UDP_down" - print("Beginning create upload") + print("Creating upload cx profile ") self.cx_prof_upload.create(endp_type="lf_udp", side_a=temp_sta_list, side_b="1.eth1", sleep_time=.05) - #create 2 cx profiles - print("Beginning create download") + print("Creating download cx profile") self.cx_prof_download.create(endp_type="lf_udp", side_a=temp_sta_list, side_b="1.eth1", sleep_time=.05) + def __set_all_cx_state(self, state, sleep_time=5): + + print("Setting CX States to %s" % state) + cx_list = list(self.local_realm.cx_list()) + for cx_name in cx_list: + req_url = "cli-json/set_cx_state" + data = { + "test_mgr": "default_tm", + "cx_name": cx_name, + "cx_state": state + } + self.json_post(req_url, data) + time.sleep(sleep_time) - def start(self): + + def __get_rx_values(self): + cx_list = self.json_get("/endp/list?fields=name,rx+bytes", debug_=False) + #print("==============\n", cx_list, "\n==============") + cx_rx_map = {} + for cx_name in cx_list['endpoint']: + if cx_name != 'uri' and cx_name != 'handler': + for item, value in cx_name.items(): + for value_name, value_rx in value.items(): + if value_name == 'rx bytes': + cx_rx_map[item] = value_rx + return cx_rx_map + + + def start(self, print_pass=False, print_fail = False): #start one test, measure #start second test, measure - #start upload, - pass + cur_time = datetime.datetime.now() + end_time = self.local_realm.parse_time(self.test_duration) + cur_time + #admin up on new monitor + self.new_monitor.admin_up() + now = datetime.datetime.now() + date_time = now.strftime("%Y-%m-%d-%H%M%S") + curr_mon_name = self.new_monitor.monitor_name + #("date and time: ",date_time) + self.new_monitor.start_sniff("/home/lanforge/Documents/"+curr_mon_name+"-"+date_time+".cap") + #admin up on station + + self.station_profile.admin_up(resource=1) + #self.new_monitor.set_flag() + self.__set_all_cx_state("RUNNING") + + while cur_time < end_time: + #DOUBLE CHECK + interval_time = cur_time + datetime.timedelta(minutes=1) + while cur_time < interval_time: + cur_time = datetime.datetime.now() + time.sleep(1) + def stop(self): - pass - - + #switch off new monitor + self.new_monitor.admin_down() + self.__set_all_cx_state("STOPPED") + for sta_name in self.sta_list: + data = LFUtils.portDownRequest(1, sta_name) + url = "json-cli/set_port" + self.json_post(url, data) + + def cleanup(self): - """print("Cleaning up stations") - port_list = self.local_realm.station_list() - sta_list = [] - for item in list(port_list): - # print(list(item)) - if "sta" in list(item)[0]: - sta_list.append(self.local_realm.name_to_eid(list(item)[0])[2]) - - for sta_name in sta_list: - req_url = "cli-json/rm_vlan" - data = { - "shelf": 1, - "resource": 1, - "port": sta_name - } - # print(data) - self.json_post(req_url, data) - - cx_list = list(self.local_realm.cx_list()) - if cx_list is not None: - print("Cleaning up cxs") - for cx_name in cx_list: - if cx_name != 'handler' or cx_name != 'uri': - req_url = "cli-json/rm_cx" - data = { - "test_mgr": "default_tm", - "cx_name": cx_name - } - self.json_post(req_url, data) - - print("Cleaning up endps") - endp_list = self.json_get("/endp") - if endp_list is not None: - endp_list = list(endp_list['endpoint']) - for endp_name in range(len(endp_list)): - name = list(endp_list[endp_name])[0] - req_url = "cli-json/rm_endp" - data = { - "endp_name": name - } - self.json_post(req_url, data) """ - pass - - + self.new_monitor.cleanup() + self.cx_prof_download.cleanup() + self.cx_prof_upload.cleanup() + self.station_profile.cleanup(resource=1,desired_stations=self.sta_list) + def main(): - #param for TCP or UDP for tests + lfjson_host = "localhost" lfjson_port = 8080 - #creates object of class L3PowersaveTraffic, inputs rates for upload and download - #station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=4, padding_number_=10000) - + #station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=4, padding_number_=10000) + station_list = ["sta0000","sta0001"] ip_powersave_test = L3PowersaveTraffic(lfjson_host, lfjson_port, ssid = "jedway-open" , security = "open", - password ="[BLANK]", station_list = ["sta01", "sta02"] , side_a_min_rate=5600, side_b_min_rate=5600, side_a_max_rate=0, - side_b_max_rate=0, prefix="00000", test_duration="5m", - _debug_on=True, _exit_on_error=True, _exit_on_fail=True) - #ip_powersave_test.cleanup() - ip_powersave_test.build("upload") - # ip_powersave_test.start("upload") - #ip_powersave_test.start("download") - #ip_powersave_test.cleanup() + password ="[BLANK]", station_list = station_list , side_a_min_rate=2000, side_b_min_rate=2000, side_a_max_rate=0, + side_b_max_rate=0, prefix="00000", test_duration="30s", + _debug_on=False, _exit_on_error=True, _exit_on_fail=True) + ip_powersave_test.cleanup() + ip_powersave_test.build() + ip_powersave_test.start() + ip_powersave_test.stop() + ip_powersave_test.cleanup() if __name__ == "__main__": - #main(sys.argv[1:]) + main() diff --git a/py-scripts/test_wep_connection.py b/py-scripts/test_wep_connection.py new file mode 100755 index 00000000..8a825834 --- /dev/null +++ b/py-scripts/test_wep_connection.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python3 + +import sys +import os +if sys.version_info[0] != 3: + print("This script requires Python 3") + exit(1) + +if 'py-json' not in sys.path: + sys.path.append(os.path.join(os.path.abspath('..'), 'py-json')) +import LANforge +from LANforge.lfcli_base import LFCliBase +from LANforge import LFUtils +import realm +import time +import pprint + + +class IPv4Test(LFCliBase): + def __init__(self, host, port, ssid, security, password, resource=1, sta_list=None, number_template="00000", _debug_on=False, + _exit_on_error=False, + _exit_on_fail=False): + super().__init__(host, port, _debug=_debug_on, _halt_on_error=_exit_on_error, _exit_on_fail=_exit_on_fail) + self.host = host + self.port = port + self.ssid = ssid + self.security = security + self.password = password + self.sta_list = sta_list + self.resource = resource + self.timeout = 120 + self.number_template = number_template + self.debug = _debug_on + self.local_realm = realm.Realm(lfclient_host=self.host, lfclient_port=self.port) + self.station_profile = self.local_realm.new_station_profile() + + self.station_profile.lfclient_url = self.lfclient_url + self.station_profile.ssid = self.ssid + self.station_profile.ssid_pass = self.password, + self.station_profile.security = self.security + self.station_profile.number_template_ = self.number_template + self.station_profile.mode = 0 + + def build(self): + # Build stations + self.station_profile.use_security(self.security, self.ssid, self.password) + self.station_profile.set_number_template(self.number_template) + print("Creating stations") + self.station_profile.set_command_flag("add_sta", "create_admin_down", 1) + self.station_profile.set_command_param("set_port", "report_timer", 1500) + self.station_profile.set_command_flag("set_port", "rpt_timer", 1) + self.station_profile.create(resource=1, radio="wiphy0", sta_names_=self.sta_list, debug=False) + self._pass("PASS: Station build finished") + + def start(self, sta_list, print_pass, print_fail): + self.station_profile.admin_up(1) + associated_map = {} + ip_map = {} + print("Starting test...") + for sec in range(self.timeout): + for sta_name in sta_list: + sta_status = self.json_get("port/1/1/" + sta_name + "?fields=port,alias,ip,ap", debug_=self.debug) + # print(sta_status) + if sta_status is None or sta_status['interface'] is None or sta_status['interface']['ap'] is None: + continue + if len(sta_status['interface']['ap']) == 17 and sta_status['interface']['ap'][-3] == ':': + # print("Associated", sta_name, sta_status['interface']['ap'], sta_status['interface']['ip']) + associated_map[sta_name] = 1 + if sta_status['interface']['ip'] != '0.0.0.0': + # print("IP", sta_name, sta_status['interface']['ap'], sta_status['interface']['ip']) + ip_map[sta_name] = 1 + if (len(sta_list) == len(ip_map)) and (len(sta_list) == len(associated_map)): + break + else: + time.sleep(1) + + if self.debug: + print("sta_list", len(sta_list), sta_list) + print("ip_map", len(ip_map), ip_map) + print("associated_map", len(associated_map), associated_map) + if (len(sta_list) == len(ip_map)) and (len(sta_list) == len(associated_map)): + self._pass("PASS: All stations associated with IP", print_pass) + else: + self._fail("FAIL: Not all stations able to associate/get IP", print_fail) + print("sta_list", sta_list) + print("ip_map", ip_map) + print("associated_map", associated_map) + + return self.passes() + + def stop(self): + # Bring stations down + for sta_name in self.sta_list: + data = LFUtils.portDownRequest(1, sta_name) + url = "json-cli/set_port" + # print(sta_name) + self.json_post(url, data) + + def cleanup(self, sta_list): + self.station_profile.cleanup(self.resource, sta_list) + LFUtils.wait_until_ports_disappear(resource_id=self.resource, base_url=self.lfclient_url, port_list=sta_list, + debug=self.debug) + +def main(): + lfjson_host = "localhost" + lfjson_port = 8080 + station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=1, padding_number_=10000) + ip_test = IPv4Test(lfjson_host, lfjson_port, ssid="jedway-wep-48", password="0123456789", + security="wep", sta_list=station_list) + ip_test.cleanup(station_list) + ip_test.timeout = 60 + ip_test.build() + if not ip_test.passes(): + print(ip_test.get_fail_message()) + exit(1) + ip_test.start(station_list, False, False) + ip_test.stop() + if not ip_test.passes(): + print(ip_test.get_fail_message()) + exit(1) + time.sleep(30) + ip_test.cleanup(station_list) + if ip_test.passes(): + print("Full test passed, all stations associated and got IP") + + +if __name__ == "__main__": + main() diff --git a/py-scripts/test_ipv4_connection.py b/py-scripts/test_wpa2_connection.py similarity index 66% rename from py-scripts/test_ipv4_connection.py rename to py-scripts/test_wpa2_connection.py index 6eff996d..2b1e1acb 100755 --- a/py-scripts/test_ipv4_connection.py +++ b/py-scripts/test_wpa2_connection.py @@ -1,13 +1,13 @@ #!/usr/bin/env python3 import sys - +import os if sys.version_info[0] != 3: print("This script requires Python 3") exit(1) if 'py-json' not in sys.path: - sys.path.append('../py-json') + sys.path.append(os.path.join(os.path.abspath('..'), 'py-json')) import LANforge from LANforge.lfcli_base import LFCliBase from LANforge import LFUtils @@ -17,7 +17,7 @@ import pprint class IPv4Test(LFCliBase): - def __init__(self, host, port, ssid, security, password, sta_list=None, num_stations=0, prefix="00000", _debug_on=False, + def __init__(self, host, port, ssid, security, password, resource=1, sta_list=None, number_template="00000", _debug_on=False, _exit_on_error=False, _exit_on_fail=False): super().__init__(host, port, _debug=_debug_on, _halt_on_error=_exit_on_error, _exit_on_fail=_exit_on_fail) @@ -26,30 +26,34 @@ class IPv4Test(LFCliBase): self.ssid = ssid self.security = security self.password = password - self.num_stations = num_stations self.sta_list = sta_list + self.resource = resource self.timeout = 120 - self.prefix = prefix + self.number_template = number_template self.debug = _debug_on self.local_realm = realm.Realm(lfclient_host=self.host, lfclient_port=self.port) - self.profile = realm.StationProfile(self.lfclient_url, ssid=self.ssid, ssid_pass=self.password, - security=self.security, number_template_=self.prefix, mode=0, up=False, dhcp=True, - debug_=False) + self.station_profile = self.local_realm.new_station_profile() + + self.station_profile.lfclient_url = self.lfclient_url + self.station_profile.ssid = self.ssid + self.station_profile.ssid_pass = self.password, + self.station_profile.security = self.security + self.station_profile.number_template_ = self.number_template + self.station_profile.mode = 0 def build(self): # Build stations - self.profile.use_wpa2(True, self.ssid, self.password) - self.profile.set_number_template(self.prefix) + self.station_profile.use_security(self.security, self.ssid, self.password) + self.station_profile.set_number_template(self.number_template) print("Creating stations") - self.profile.set_command_flag("add_sta", "create_admin_down", 1) - self.profile.set_command_param("set_port", "report_timer", 1500) - self.profile.set_command_flag("set_port", "rpt_timer", 1) - self.profile.create(resource=1, radio="wiphy0", sta_names_=self.sta_list, debug=False) + self.station_profile.set_command_flag("add_sta", "create_admin_down", 1) + self.station_profile.set_command_param("set_port", "report_timer", 1500) + self.station_profile.set_command_flag("set_port", "rpt_timer", 1) + self.station_profile.create(resource=1, radio="wiphy0", sta_names_=self.sta_list, debug=False) self._pass("PASS: Station build finished") def start(self, sta_list, print_pass, print_fail): - # Bring stations up - self.profile.admin_up(1) + self.station_profile.admin_up(1) associated_map = {} ip_map = {} print("Starting test...") @@ -92,33 +96,18 @@ class IPv4Test(LFCliBase): # print(sta_name) self.json_post(url, data) - def cleanup(self, resource): - port_list = self.local_realm.station_list() - sta_list = [] - for item in list(port_list): - # print(list(item)) - if "sta" in list(item)[0]: - sta_list.append(self.local_realm.name_to_eid(list(item)[0])[2]) - - for sta_name in sta_list: - req_url = "cli-json/rm_vlan" - data = { - "shelf": 1, - "resource": 1, - "port": sta_name - } - self.json_post(req_url, data, self.debug) - time.sleep(.05) - LFUtils.wait_until_ports_disappear(resource_id=resource, base_url=self.lfclient_url, port_list=sta_list, debug=self.debug) - + def cleanup(self, sta_list): + self.station_profile.cleanup(self.resource, sta_list) + LFUtils.wait_until_ports_disappear(resource_id=self.resource, base_url=self.lfclient_url, port_list=sta_list, + debug=self.debug) def main(): lfjson_host = "localhost" lfjson_port = 8080 - station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=29, padding_number_=10000) + station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=1, padding_number_=10000) ip_test = IPv4Test(lfjson_host, lfjson_port, ssid="jedway-wpa2-x2048-4-4", password="jedway-wpa2-x2048-4-4", - security="open", sta_list=station_list) - ip_test.cleanup(1) + security="wpa2", sta_list=station_list) + ip_test.cleanup(station_list) ip_test.timeout = 60 ip_test.build() if not ip_test.passes(): @@ -130,7 +119,7 @@ def main(): print(ip_test.get_fail_message()) exit(1) time.sleep(30) - ip_test.cleanup(1) + ip_test.cleanup(station_list) if ip_test.passes(): print("Full test passed, all stations associated and got IP") diff --git a/py-scripts/test_wpa3_connection.py b/py-scripts/test_wpa3_connection.py new file mode 100755 index 00000000..cd3660fb --- /dev/null +++ b/py-scripts/test_wpa3_connection.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python3 + +import sys +import os +if sys.version_info[0] != 3: + print("This script requires Python 3") + exit(1) +if 'py-json' not in sys.path: + sys.path.append(os.path.join(os.path.abspath('..'), 'py-json')) +import LANforge +from LANforge.lfcli_base import LFCliBase +from LANforge import LFUtils +import realm +import time +import pprint + + +class IPv4Test(LFCliBase): + def __init__(self, host, port, ssid, security, password, resource=1, sta_list=None, number_template="00000", _debug_on=False, + _exit_on_error=False, + _exit_on_fail=False): + super().__init__(host, port, _debug=_debug_on, _halt_on_error=_exit_on_error, _exit_on_fail=_exit_on_fail) + self.host = host + self.port = port + self.ssid = ssid + self.security = security + self.password = password + self.sta_list = sta_list + self.resource = resource + self.timeout = 120 + self.number_template = number_template + self.debug = _debug_on + self.local_realm = realm.Realm(lfclient_host=self.host, lfclient_port=self.port) + self.station_profile = self.local_realm.new_station_profile() + + self.station_profile.lfclient_url = self.lfclient_url + self.station_profile.ssid = self.ssid + self.station_profile.ssid_pass = self.password, + self.station_profile.security = self.security + self.station_profile.number_template_ = self.number_template + self.station_profile.mode = 0 + + def build(self): + # Build stations + #print("We've gotten into the build stations function") + self.station_profile.use_security(self.security, self.ssid, self.password) + self.station_profile.set_number_template(self.number_template) + print("Creating stations") + self.station_profile.set_command_flag("add_sta", "create_admin_down", 1) + self.station_profile.set_command_param("set_port", "report_timer", 1500) + self.station_profile.set_command_flag("set_port", "rpt_timer", 1) + self.station_profile.create(resource=1, radio="wiphy0", sta_names_=self.sta_list, debug=False) + self._pass("PASS: Station build finished") + + def start(self, sta_list, print_pass, print_fail): + self.station_profile.admin_up(1) + associated_map = {} + ip_map = {} + print("Starting test...") + for sec in range(self.timeout): + for sta_name in sta_list: + sta_status = self.json_get("port/1/1/" + sta_name + "?fields=port,alias,ip,ap", debug_=self.debug) + # print(sta_status) + if sta_status is None or sta_status['interface'] is None or sta_status['interface']['ap'] is None: + continue + if len(sta_status['interface']['ap']) == 17 and sta_status['interface']['ap'][-3] == ':': + # print("Associated", sta_name, sta_status['interface']['ap'], sta_status['interface']['ip']) + associated_map[sta_name] = 1 + if sta_status['interface']['ip'] != '0.0.0.0': + # print("IP", sta_name, sta_status['interface']['ap'], sta_status['interface']['ip']) + ip_map[sta_name] = 1 + if (len(sta_list) == len(ip_map)) and (len(sta_list) == len(associated_map)): + break + else: + time.sleep(1) + + if self.debug: + print("sta_list", len(sta_list), sta_list) + print("ip_map", len(ip_map), ip_map) + print("associated_map", len(associated_map), associated_map) + if (len(sta_list) == len(ip_map)) and (len(sta_list) == len(associated_map)): + self._pass("PASS: All stations associated with IP", print_pass) + else: + self._fail("FAIL: Not all stations able to associate/get IP", print_fail) + print("sta_list", sta_list) + print("ip_map", ip_map) + print("associated_map", associated_map) + + return self.passes() + + def stop(self): + # Bring stations down + for sta_name in self.sta_list: + data = LFUtils.portDownRequest(1, sta_name) + url = "json-cli/set_port" + # print(sta_name) + self.json_post(url, data) + + def cleanup(self, sta_list): + self.station_profile.cleanup(self.resource, sta_list) + LFUtils.wait_until_ports_disappear(resource_id=self.resource, base_url=self.lfclient_url, port_list=sta_list, + debug=self.debug) + +def main(): + lfjson_host = "localhost" + lfjson_port = 8080 + station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=1, padding_number_=10000) + ip_test = IPv4Test(lfjson_host, lfjson_port, ssid="jedway-wpa3-44", password="jedway-wpa3-44", + security="wpa3", sta_list=station_list,_debug_on=False) + #print("created IPv4Test object") + ip_test.cleanup(station_list) + ip_test.timeout = 60 + ip_test.build() + if not ip_test.passes(): + print(ip_test.get_fail_message()) + exit(1) + ip_test.start(station_list, False, False) + ip_test.stop() + if not ip_test.passes(): + print(ip_test.get_fail_message()) + exit(1) + time.sleep(30) + ip_test.cleanup(station_list) + if ip_test.passes(): + print("Full test passed, all stations associated and got IP") + + +if __name__ == "__main__": + main() diff --git a/py-scripts/test_wpa_connection.py b/py-scripts/test_wpa_connection.py new file mode 100755 index 00000000..4a10be14 --- /dev/null +++ b/py-scripts/test_wpa_connection.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python3 + +import sys +import os +if sys.version_info[0] != 3: + print("This script requires Python 3") + exit(1) + +if 'py-json' not in sys.path: + sys.path.append(os.path.join(os.path.abspath('..'), 'py-json')) +import LANforge +from LANforge.lfcli_base import LFCliBase +from LANforge import LFUtils +import realm +import time +import pprint + + +class IPv4Test(LFCliBase): + def __init__(self, host, port, ssid, security, password, resource=1, sta_list=None, number_template="00000", _debug_on=False, + _exit_on_error=False, + _exit_on_fail=False): + super().__init__(host, port, _debug=_debug_on, _halt_on_error=_exit_on_error, _exit_on_fail=_exit_on_fail) + self.host = host + self.port = port + self.ssid = ssid + self.security = security + self.password = password + self.sta_list = sta_list + self.resource = resource + self.timeout = 120 + self.number_template = number_template + self.debug = _debug_on + self.local_realm = realm.Realm(lfclient_host=self.host, lfclient_port=self.port) + self.station_profile = self.local_realm.new_station_profile() + + self.station_profile.lfclient_url = self.lfclient_url + self.station_profile.ssid = self.ssid + self.station_profile.ssid_pass = self.password, + self.station_profile.security = self.security + self.station_profile.number_template_ = self.number_template + self.station_profile.mode = 0 + + def build(self): + # Build stations + self.station_profile.use_security(self.security, self.ssid, self.password) + self.station_profile.set_number_template(self.number_template) + print("Creating stations") + self.station_profile.set_command_flag("add_sta", "create_admin_down", 1) + self.station_profile.set_command_param("set_port", "report_timer", 1500) + self.station_profile.set_command_flag("set_port", "rpt_timer", 1) + self.station_profile.create(resource=1, radio="wiphy0", sta_names_=self.sta_list, debug=False) + self._pass("PASS: Station build finished") + + def start(self, sta_list, print_pass, print_fail): + self.station_profile.admin_up(1) + associated_map = {} + ip_map = {} + print("Starting test...") + for sec in range(self.timeout): + for sta_name in sta_list: + sta_status = self.json_get("port/1/1/" + sta_name + "?fields=port,alias,ip,ap", debug_=self.debug) + # print(sta_status) + if sta_status is None or sta_status['interface'] is None or sta_status['interface']['ap'] is None: + continue + if len(sta_status['interface']['ap']) == 17 and sta_status['interface']['ap'][-3] == ':': + # print("Associated", sta_name, sta_status['interface']['ap'], sta_status['interface']['ip']) + associated_map[sta_name] = 1 + if sta_status['interface']['ip'] != '0.0.0.0': + # print("IP", sta_name, sta_status['interface']['ap'], sta_status['interface']['ip']) + ip_map[sta_name] = 1 + if (len(sta_list) == len(ip_map)) and (len(sta_list) == len(associated_map)): + break + else: + time.sleep(1) + + if self.debug: + print("sta_list", len(sta_list), sta_list) + print("ip_map", len(ip_map), ip_map) + print("associated_map", len(associated_map), associated_map) + if (len(sta_list) == len(ip_map)) and (len(sta_list) == len(associated_map)): + self._pass("PASS: All stations associated with IP", print_pass) + else: + self._fail("FAIL: Not all stations able to associate/get IP", print_fail) + print("sta_list", sta_list) + print("ip_map", ip_map) + print("associated_map", associated_map) + + return self.passes() + + def stop(self): + # Bring stations down + for sta_name in self.sta_list: + data = LFUtils.portDownRequest(1, sta_name) + url = "json-cli/set_port" + # print(sta_name) + self.json_post(url, data) + + def cleanup(self, sta_list): + self.station_profile.cleanup(self.resource, sta_list) + LFUtils.wait_until_ports_disappear(resource_id=self.resource, base_url=self.lfclient_url, port_list=sta_list, + debug=self.debug) + +def main(): + lfjson_host = "localhost" + lfjson_port = 8080 + station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=1, padding_number_=10000) + ip_test = IPv4Test(lfjson_host, lfjson_port, ssid="jedway-wpa-1", password="jedway-wpa-1", + security="wpa", sta_list=station_list) + ip_test.cleanup(station_list) + ip_test.timeout = 60 + ip_test.build() + if not ip_test.passes(): + print(ip_test.get_fail_message()) + exit(1) + ip_test.start(station_list, False, False) + ip_test.stop() + if not ip_test.passes(): + print(ip_test.get_fail_message()) + exit(1) + time.sleep(30) + ip_test.cleanup(station_list) + if ip_test.passes(): + print("Full test passed, all stations associated and got IP") + + +if __name__ == "__main__": + main()