saving changes

This commit is contained in:
Nikita Yadav
2021-10-28 12:16:56 +05:30
parent 109ad2c564
commit c033f577d9
564 changed files with 154848 additions and 8 deletions

View File

@@ -108,7 +108,7 @@ All code must be written in python 3 and conform to PEP 8 style guide. The test
├── mdu
|── mesh
|── scale
|── README.md -/* Pytest framework and testcases information */
|── README.md -/* Pytest spatial_consist and testcases information */
```
### Setup Instructions

7
lanforge/lanforge-scripts/.gitignore vendored Normal file
View File

@@ -0,0 +1,7 @@
*.bash.txt
*.sh.txt
*.pl.txt
*~
*.iml
**/*.iml
.idea

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,268 @@
package LANforge::GuiJson;
use strict;
use warnings;
use JSON;
#use Exporter 'import';
use Scalar::Util 'blessed';
if (defined $ENV{'DEBUG'}) {
use Data::Dumper;
use diagnostics;
use Carp;
$SIG{ __DIE__ } = sub { Carp::confess( @_ ) };
}
our $NL="\n";
our @EXPORT_OK=qw(new);
our $refs_example = q( \@portnames or ["sta1", "sta2"] not ("sta1", "sta2"));
sub new {
my $this = {
'url' => undef,
'handler' => undef,
'uri' => undef,
'header' => undef,
'data' => undef,
'headermap' => {},
}; # Create an anonymous hash, and #self points to it.
bless $this; # Connect the hash to the package Cocoa.
return $this; # Return the reference to the hash.
}
=pod
=head1 GuiResponseToHash
=cut
sub GuiResponseToHash {
my $self = shift;
my $response = shift;
my $ra_data = JSON::decode($response);
my $rh_data = {};
$rh_data->{'handler'} = $ra_data->[0]->{'handler'};
$rh_data->{'uri'} = $ra_data->[1]->{'uri'};
$rh_data->{'header'} = $ra_data->[2]->{'header'};
$rh_data->{'data'} = $ra_data->[3]->{'data'};
#print Dumper($rh_data);
return $rh_data;
}
sub Request {
my $self = shift;
$self->{'url'} = shift;
if (!defined $self->{'url'}) {
die("Request wants url; example 'http://localhost:8080/PortTab')");
}
my $json = JSON->new;
my $ra_data = $json->decode(`curl -s $self->{'url'}`);
#print "---------------------------------------------------------------------\n";
#print Dumper($ra_data);
#print "---------------------------------------------------------------------\n";
$self->{'handler'} = @$ra_data[0]->{'handler'};
die("GuiJson response missing 'handler'") if (!defined $self->{'handler'});
$self->{'uri'} = @$ra_data[1]->{'uri'};
die("GuiJson response missing 'uri'") if (!defined $self->{'uri'});
$self->{'header'} = @$ra_data[2]->{'header'};
die("GuiJson response missing 'header'") if (!defined $self->{'header'});
$self->{'data'} = @$ra_data[3]->{'data'};
die("GuiJson response missing 'data'") if (!defined $self->{'data'});
$self->MakeHeaderMap();
} # ~Request
sub MakeHeaderMap {
my $self = shift;
$self->{'headermap'} = {};
if (!defined $self->{'header'}) {
print STDERR Dumper($self);
die("MakeHeaderMap: self->{'header'} unset\n");
}
my $index = 0;
for my $headername (@{$self->{'header'}}) {
$self->{'headermap'}->{$headername} = $index;
$index++;
}
}
sub GetHeaderMap {
my $self = shift;
return $self->{'headermap'};
}
=pod
=head1 GetRecordsMatching
GetRecordsMatching expects results of GetGuiResponseToHash and a list of port EIDs or names
$ra_ports = GetRecordsMatching($rh_data, $header_name, $value)
=cut
sub GetRecordsMatching {
my $self = shift;
my $header_name = shift;
my $ra_needles = shift;
my $ra_results = [];
if (!defined $header_name || $header_name eq '') {
print STDERR "GetRecordsMatching wants arg1: header name\n";
return $ra_results;
}
if (!defined $ra_needles || ref($ra_needles) ne 'ARRAY') {
print Dumper($ra_needles);
my $example = q( \@portnames or ["sta1", "sta2"] not ("sta1", "sta2"));
print STDERR "GetRecordsMatching wants arg3: list values to match against <$header_name>.\nPass array references, eg:\n$example\n";
return $ra_results;
}
my $value = undef;
my @matches = undef;
for my $ra_port (@{$self->{'data'}}) {
$value = $ra_port->[ $self->HeaderIdx($header_name)];
#print "$header_name: $value\n";
@matches = grep { /$value/ } @$ra_needles;
if (@matches) {
push(@$ra_results, $ra_port);
}
}
return $ra_results;
} # ~GetRecordsMatching
=pod
=head1 HeaderTrans
HeaderTrans($name) is used to resolve header regex to a field
name. HeaderTrans uses $headermap keys if they match exactly,
even if the $name passed in looks like a regex. Field names
Not found in $self->headertrans hash are then resolved as
regexes using grep { /$name/ } @fieldnames. Only the first
match is cached.
$fieldname = HeaderIdx( "No CX (us)")
# plain return 'No CX (us)'
$idx = HeaderIdx( "No CX.*")
# regex evaluated only if 'No CX.*' doesn't exist
# as a literal key in $self->headertrans
=cut
sub HeaderTrans {
my $self = shift;
my $headername = shift;
my %headermap = %{$self->{'headermap'}};
$self->{'headertrans'} = {}
if (!defined $self->{'headertrans'});
if (!defined $headername || "$headername" eq "") {
die("HeaderTrans: Header name is empty or unset, bye\n");
return -1;
}
my %headertrans = %{$self->{'headertrans'}};
if (defined $headertrans{$headername}) {
return $headertrans{$headername};
}
if (defined $headermap{$headername}) {
$headertrans{$headername} = $headername;
return $headername;
}
# look for regex matches next
my @matches = grep { /$headername/ } keys %{$self->{'headermap'}};
if (@matches < 1) {
print STDERR "HeaderTrans: Headermap name <$headername> unmached, you get -1.\n";
$headertrans{$headername} = -1;
return -1;
}
my $a = $matches[0];
$headertrans{$headername} = $a;
if (@matches > 1) {
print STDERR "Headermap name <$headername> has multiple matches, you get $a.\n";
}
return $a;
}
=pod
=head1 HeaderIdx
HeaderIdx($name) is used to resolve header name to index in
array holding record data. HeaderIdx uses HeaderTrans() to
map names ore regexes to resolved field names and only do
regex lookups once per pattern.
$idx = HeaderIdx( "Alias") # plain name
$idx = HeaderIdx( "No CX.*") # regex
=cut
sub HeaderIdx {
my $self = shift;
my $headername = shift;
my %headermap = %{$self->{'headermap'}};
if (!defined $headername || "$headername" eq "") {
die("Header name is empty or unset, bye\n");
return -1;
}
my $key = $self->HeaderTrans($headername);
if (defined $headermap{$key}) {
return $headermap{$key};
}
print STDERR "headermap{$key} undefined, you get -1\n";
return -1;
} # ~HeaderIdx
=pod
=head1 GetFields
Returns matching fields from a record;
$ra_needles are an array of strings to match to select records
$ra_field_names are field names to return from those records
$rh = GetFields($header_name, $ra_needles, $ra_field_names)
=cut
sub GetFields {
my $self = shift;
my $header_name = shift;
my $ra_needles = shift;
my $ra_field_names = shift;
my $ra_records = [];
my $rh_field_values = {};
if (!defined $header_name || $header_name eq '') {
print STDERR "GetFields wants arg2: header name\n";
return $rh_field_values;
}
if (!defined $ra_needles || ref($ra_needles) ne 'ARRAY') {
print Dumper($ra_needles);
print STDERR "GetFields wants arg3: list values to match against <$header_name>.\nPass array references, eg:\n$::refs_example\n";
return $rh_field_values;
}
if (!defined $ra_field_names || ref($ra_field_names) ne 'ARRAY') {
my $arg_str = join(", ", @$ra_needles);
print STDERR "GetFields wants arg4: list field names to return if <$header_name> matches <$arg_str>\nPass array references, eg:\n$::refs_example\n";
return $rh_field_values;
}
$ra_records = $self->GetRecordsMatching($header_name, $ra_needles);
return $rh_field_values if (@$ra_records < 1);
for my $ra_record (@$ra_records) {
next if (@$ra_record < 1);
next if (! defined @$ra_record[$self->HeaderIdx($header_name)]);
my $record_name = @$ra_record[$self->HeaderIdx($header_name)];
next if (!defined $record_name || "$record_name" eq "");
#print "record name[$record_name]\n";
#print Dumper($ra_record);
my $rh_record_vals = {};
$rh_field_values->{$record_name} = $rh_record_vals;
#print Dumper($ra_field_names);
for my $field_name (@$ra_field_names) {
next if (!defined $field_name || "$field_name" eq "");
my $xl_name = $self->HeaderTrans($field_name);
my $field_idx = $self->HeaderIdx($xl_name);
next if (!defined @$ra_record[$field_idx]);
#print "Field Name $field_name [".@$ra_record[$field_idx]."] ";
$rh_record_vals->{$xl_name} = @$ra_record[$field_idx];
}
#print Dumper($rh_record_vals);
}
return $rh_field_values;
}
1;

View File

@@ -0,0 +1,197 @@
# JsonUtils
package LANforge::JsonUtils;
use strict;
use warnings;
use diagnostics;
use Carp;
$SIG{ __DIE__ } = sub { Carp::confess( @_ ) };
$SIG{ __WARN__ } = sub { Carp::confess( @_ ) };
# Un-buffer output
$| = 1;
use Getopt::Long;
use JSON::XS;
use HTTP::Request;
use LWP;
use LWP::UserAgent;
use JSON;
use Data::Dumper;
if (defined $ENV{'DEBUG'}) {
use Data::Dumper;
use diagnostics;
use Carp;
$SIG{ __DIE__ } = sub { Carp::confess( @_ ) };
}
our $NL="\n";
use Exporter 'import';
our @EXPORT_OK=qw(err logg xpand json_request get_links_from get_thru json_post get_port_names flatten_list);
sub err {
my $i;
for $i (@_) {
print STDERR "$i";
}
print STDERR $NL;
}
sub logg {
my $i;
for $i (@_) {
print STDOUT "$i ";
}
# print STDOUT $NL;
}
sub xpand {
my ($rrl) = @_;
die("Will not expand a blank URI") if ("" eq $rrl || $rrl =~ m/^\s*$/);
return $rrl if ($rrl =~ /^http/);
return $rrl if ($rrl =~ m{^$main::HostUri/});
return "${main::HostUri}$rrl" if ($rrl =~ m{^/});
return "${main::HostUri}/$rrl";
}
sub json_request {
my ($uri) = @_;
my $url = xpand($uri);
#logg("$uri becomes $url\n");
my $req = new HTTP::Request("GET" => $url);
$req->header("Accept" => "application/json");
my $response = $::Web->request($req);
if ($response->code != 200) {
err("Status ".$response->code.": ".$response->content."\n");
if ($response->content =~ /(Can't connect|Connection refused)/) {
exit(1);
}
return {};
}
#print Dumper($response->content);
return $::Decoder->decode($response->content);
}
sub json_post {
my ($uri, $rh_data) = @_;
my $url = xpand($uri);
#print STDERR "URI $uri\n";
my $req = HTTP::Request->new("POST" => $url);
$req->header('Accept' => 'application/json');
$req->header('Content-Type' => 'application/json; charset=UTF-8');
$req->content(encode_json($rh_data));
#print "json_post: ".Dumper($rh_data);
#print Dumper($req);
my $response = $::Web->request($req);
#print Dumper($response);
if ($response->code != 200) {
err("Status ".$response->code.": ".$response->content."\n");
if ($response->content =~ /(Can't connect|Connection refused)/) {
exit(1);
}
return {};
}
my $rh_response = $::Decoder->decode($response->content);
print Dumper($rh_response)
if ( defined $rh_response->{"Resource"}
&& defined $rh_response->{"Resource"}->{"warnings"});
print Dumper($rh_response)
if ( defined $rh_response->{"errors"}
|| defined $rh_response->{"error_list"});
return $rh_response;
}
# use this to create a flat hash of $eid ->{result data} when given
# [ { $eid->{data}}, {}, {} ] which is harder to navigate
sub flatten_list {
my $rh_list = shift;
my $list_name = shift;
my $rh_irefs = {};
return if (!defined $rh_list);
#print "\n- FF ------------------------------------------------------------\n";
#print Dumper($rh_list);
#print "\n~ FF ------------------------------------------------------------\n";
if (!defined $rh_list->{$list_name}) {
print "flatten_list: $list_name not found\n";
return;
}
if (ref $rh_list->{$list_name} eq "HASH") {
return if ( (keys %{$rh_list->{$list_name}} < 1));
}
if (ref $rh_list->{$list_name} ne "ARRAY") {
print "flatten_list: $list_name not Array Ref:\n";
print "-------------------------------------------------\n";
print Dumper($rh_list);
print "-------------------------------------------------\n";
return;
}
#print "\n- FG -------------------------------------------------------------------\n";
#print Dumper($rh_list->{$list_name});
#print "\n~ FG -------------------------------------------------------------------\n";
my $v = @{$rh_list->{$list_name}};
my @k = (@{$rh_list->{$list_name}});
for (my $i=0; $i < $v; $i++) {
my @rh_k = keys %{$k[$i]};
my @rh_v = values %{$k[$i]};
my $rh_id = $rh_k[0];
#print "\n- FG -------------------------------------------------------------------\n";
#print Dumper($rh_id);
#print "\n~ FG -------------------------------------------------------------------\n";
$rh_irefs->{$rh_id} = $rh_v[0];
}
#print "\n- FG -------------------------------------------------------------------\n";
#print Dumper($rh_irefs);
#print "\n~ FG -------------------------------------------------------------------\n";
$rh_list->{"flat_list"} = $rh_irefs;
}
sub get_port_names {
my ($rh_gpn, $arrayname) = @_;
my $ra_gpn2 = $rh_gpn->{$arrayname};
my $ra_gpn_links2 = [];
#print Dumper($ra_gpn2);
for my $rh_gpn2 (@$ra_gpn2) {
#print Dumper($rh_gpn2);
for my $key (keys %$rh_gpn2) {
my $v = $rh_gpn2->{$key};
next if (!(defined $v->{'_links'}));
my $rh_i = {
'uri' => $v->{'_links'},
'alias' => $v->{'alias'}
};
if (defined $v->{'device'}) {
$rh_i->{'device'} = $v->{'device'};
}
push(@$ra_gpn_links2, $rh_i);
}
}
#print Dumper($ra_links2);
return $ra_gpn_links2;
}
sub get_links_from {
my ($rh_glf, $arrayname) = @_;
my $ra_glf2 = $rh_glf->{$arrayname};
my $ra_glf_links2 = [];
for my $rh_glf2 (@$ra_glf2) {
for my $key (keys %$rh_glf2) {
my $v = $rh_glf2->{$key};
next if (!(defined $v->{'_links'}));
push(@$ra_glf_links2, $v->{'_links'});
}
}
#print Dumper($ra_links2);
return $ra_glf_links2;
}
# eg get_thru( 'interface', 'device' )
sub get_thru {
my ($inner, $key, $rh_top) = @_;
if (!(defined $rh_top->{$inner})) {
print Dumper($rh_top);
return -1;
}
my $rh_inner = $rh_top->{$inner};
return $rh_inner->{$key};
}
1;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,80 @@
# test utilities for LANforge scripts
package LANforge::Test;
use strict;
use warnings;
use diagnostics;
use Carp;
# Ubuntu: libtest2-suite-perl
use Test2::V0 qw(ok fail done_testing);
use Test2::Tools::Basic qw(plan);
$SIG{ __DIE__ } = sub { Carp::confess( @_ ) };
$SIG{ __WARN__ } = sub { Carp::confess( @_ ) };
# Un-buffer output
$| = 1;
use Data::Dumper;
if (defined $ENV{'DEBUG'}) {
use Data::Dumper;
use diagnostics;
use Carp;
$SIG{ __DIE__ } = sub { Carp::confess( @_ ) };
}
require Exporter;
our @EXPORT_OK=qw(new test);
#our $FAIL = 'fail';
#our $OK = 'pass';
#our $PASS = 'pass';
our @test_errors = ();
sub new {
my $class = shift;
my $self = {};
my %parm = @_;
$self->{'Name'} = $parm{'Name'};
$self->{'Desc'} = $parm{'Desc'};
$self->{'Errors'} = [];
$self->{'ExpectedNumber'} = 1;
$self->{'Test'} = undef;
if (defined $parm{'Test'}) {
#print "new: Creating Test $self->{'Name'}\n";
$self->{'Test'} = $parm{'Test'};
}
if (defined $parm{'ExpectedNumber'}) {
$self->{'ExpectedNumber'} = $parm{'ExpectedNumber'};
}
bless $self, $class;
return $self;
}
sub run {
plan(1);
my $self = shift;
print "Run $self->{Name}\n";
my $result = shift;
ok($result, $self->{'Name'}) || fail($self->{'Name'});
done_testing();
}
sub test {
my $self = shift;
if (! (defined $self->{'Test'})) {
print "LANforge::test lacks self->Test, please rewrite your script.\n";
return $::FAIL;
}
return $self->{'Test'}($self, @_);
}
sub test_err {
my $self = shift;
for my $e (@_) {
my $ref = "".(caller(1))[3].":".(caller(1))[2]."";
push (@::test_errors, "$ref: $e");
}
}
1;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,123 @@
package LANforge::csv;
use strict;
use warnings;
use diagnostics;
use Carp;
$SIG{ __DIE__ } = sub { Carp::confess( @_ ) };
#use Data::Dumper;
#use Data::Dumper::Concise;
sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
my $self = {};
$self->{'ignore_comments'} = 1;
$self->{'skip_comments'} = 0;
$self->{'trim_whitespace'} = 1;
$self->{'rows'}=();
bless($self, $class);
return $self;
}
sub readFile {
my $self = shift;
my $filename = shift;
die ("readFile: no filename provided.")
if (!defined $filename || $filename eq "");
open(my $fh, "<", "$filename")
or die("readFile: $!");
my @lines = ();
while(<$fh>) {
chomp;
my @row = undef;
#print "COMMENT: $_\n" if (/^\s*?\#.*/ && $self->{ignore_comments});
next if (/^\s*?\#.*/ && $self->{skip_comments});
if (/^\s*?\#.*/ && $self->{ignore_comments}) {
@row = ();
push(@{$self->{rows}}, \@row);
next;
}
else {
@row = split(/,/);
}
# trim() on all cell values
if ($self->{trim_whitespace}) {
s{^\s+|\s+$}{}g foreach @row;
}
push(@{$self->{rows}}, \@row);
}
close $fh;
}
sub getRow {
my $self = shift;
my $row_num = shift;
die("getRow: no row number provided")
if (!defined($row_num) || $row_num eq "");
return undef if ($row_num >= @{$self->rows});
return ${$self->rows}[$row_num];
}
sub getCell {
my $self = shift;
my $cell_num = shift;
my $row_num = shift;
my $default = (shift || 'undef');
die("getCell: no row number provided")
if (!defined($row_num) || $row_num eq "");
die("getCell: no cell number provided")
if (!defined($cell_num) || $cell_num eq "");
if ($row_num >= @{$self->{rows}}) {
#warn Dumper(@{$self->{rows}});
warn "row $row_num greater than number of rows(@{$self->{rows}})\n";
return $default;
}
my $ra_row = ${$self->{rows}}[$row_num];
if (!defined $ra_row) {
#warn "row $row_num unset\n";
return $default;
}
if ($cell_num >= @{$ra_row}) {
#warn "cell $cell_num beyond size of row (".@{$ra_row}.")\n";
#warn Dumper($ra_row);
return $default;
}
if (!defined $ra_row->[$cell_num]) {
#warn "value at [$cell_num,$row_num] unset\n";
#warn Dumper($ra_row);
return $default;
}
return $ra_row->[$cell_num];
}
sub getRows {
my $self = shift;
return $self->{rows};
}
sub rows {
my $self = shift;
return $self->{rows};
}
sub numRows {
my $self = shift;
return 0+@{$self->{rows}};
}
1;
=pod
This is a simple CSV parser, please install Text::CSV or someting more sophisticated
For instance, do not embed commas or newlines into the csv cells.
=end

View File

@@ -0,0 +1,29 @@
BSD 3-Clause License
Copyright (c) 2020, Telecom Infra Project
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,296 @@
# LANforge Perl, Python, and Shell Scripts #
This is a collection of scripts and scripting libraries designed to work
with LANforge systems. On your LANforge system, these scripts are
typically installed into `/home/lanforge/scripts`. The `LANforge/` sub directory holds
the perl modules (`.pm` files) that are common to the perl scripts.
## LANforge CLI Users Guide: https://www.candelatech.com/lfcli_ug.php ##
The LANforge CLI Users Guide is a good place to start for understanding scripts
## LANforge on system cli help and cli command composer ##
The LANforge has an on system help / system query, when on LANforge browse to
http://local_host:8080
The LANforge has an on system cli help and cli command composer
http://local_host:8080/help
### Commonly Used ###
The `lf_*.pl` scripts are typically more complete and general purpose
scripts, though some are ancient and very specific. In particular,
these scripts are more modern and may be a good place to start:
| Name | Purpose |
|------------------|-----------|
| `lf_associate_ap.pl` | LANforge server script for associating virtual stations to an arbitrary SSID |
| `lf_attenmod.pl` | Query and update CT70X programmable attenuators |
| `lf_firemod.pl` | Query and update connections (Layer 3) |
| `lf_icemod.pl` | Query and update WAN links and impairments |
| `lf_portmod.pl` | Query and update physical and virtual ports |
| `lf_tos_test.py` | Generate traffic at different QoS and report in spreadsheet |
| `lf_sniff.py` | Create packet capture files, especially OFDMA /AX captures |
The `lf_wifi_rest_example.pl` script shows how one might call the other scripts from
within a script.
### Examples and Documents ###
Read more examples in the [scripting LANforge](http://www.candelatech.com/lfcli_api_cookbook.php) cookbook.
## Python Scripts ##
When starting to use Python, please run the update_dependencies.py script located in py-scripts to install all necessary dependencies for this library.
### Python Scripts py-json/LANforge ###
Core communication files to LANforge
| Name | Purpose |
|------|---------|
| `add_dut.py` | defined list of DUT keys, cli equivalent: https://www.candelatech.com/lfcli_ug.php#add_dut |
| `add_file_endp.py` | Add a File endpoint to the LANforge Manager. cli equivalent: add_file_endp https://www.candelatech.com/lfcli_ug.php#add_file_endp |
| `add_l4_endp.py` | Add a Layer 4-7 (HTTP, FTP, TELNET, ..) endpoint to the LANforge Manager. cli equivalent: add_l4_endp https://www.candelatech.com/lfcli_ug.php#add_l4_endp |
| `add_monitor.py` | Add a WIFI Monitor interface. These are useful for doing low-level wifi packet capturing. cli equivalent: add_monitor https://www.candelatech.com/lfcli_ug.php#add_monitor |
| `add_sta.py` | Add a WIFI Virtual Station (Virtual STA) interface. cli equivalent: add_sta https://www.candelatech.com/lfcli_ug.php#add_sta |
| `add_vap.py` | Add a WIFI Virtual Access Point (VAP) interface. cli equivalent: add_vap https://www.candelatech.com/lfcli_ug.php#add_vap |
| `set_port.py` | This command allows you to modify attributes on an Ethernet port. cli equivalent: set_port https://www.candelatech.com/lfcli_ug.php#set_port |
| `lfcli_base.py` | json communication to LANforge |
| `LFRequest.py` | Class holds default settings for json requests to LANforge, see: https://gist.github.com/aleiphoenix/4159510|
| `LFUtils.py` | Defines useful common methods |
| `set_port.py` | This command allows you to modify attributes on an Ethernet port. These options includes the IP address, netmask, gateway address, MAC, MTU, and TX Queue Length. cli equivalent: set_port https://www.candelatech.com/lfcli_ug.php#set_port |
### Python Scripts py-json/ ###
| Name | Purpose |
|------|---------|
| `base_profile.py` | Class: BaseProfile Use example: py-json/l3_cxprofile2.py used to define generic utility methods to be inherited by other classes |
| `create_wanlink.py` | Create and modify WAN Links Using LANforge JSON AP : http://www.candelatech.com/cookbook.php?vol=cli&book=JSON:+Managing+WANlinks+using+JSON+and+Python |
| `cv_commands.py` | This is a library file used to create a chamber view scenario. import this file as showed in create_chamberview.py to create a scenario |
| `cv_test_manager.py` | This script is working as library for chamberview tests. It holds different commands to automate test. |
| `cv_test_reports.py` | Class: lanforge_reports Pulls reports from LANforge |
| `dataplane_test_profile.py` | Library to Run Dataplane Test: Using lf_cv_base class |
| `dut_profile.py` | Class: DUTProfile (new_dut_profile) Use example: py-scripts/update_dut.py used to updates a Device Under Test (DUT) entry in the LANforge test scenario A common reason to use this would be to update MAC addresses in a DUT when you switch between different items of the same make/model of a DUT |
| `fio_endp_profile.py` | Class: FIOEndpProfile (new_fio_endp_profile) Use example: py-scripts/test_fileio.py will create stations or macvlans with matching fileio endpoints to generate and verify fileio related traffic |
| `gen_cxprofile.py` | Class: GenCXProfile (new_generic_endp_profile) Use example: test_generic.py will create stations and endpoints to generate traffic based on a command-line specified command type |
| `http_profile.py` | Class: HTTPProfile (new_http_profile) Use example: test_ipv4_l4_wifi.py will create stations and endpoints to generate and verify layer-4 upload traffic |
| `l3_cxprofile.py` | Class: L3CXProfile (new_l3_cx_profile) Use example: test_ipv4_variable_time.py will create stations and endpoints to generate and verify layer-3 traffic |
| `l3_cxprofile2.py` | Class: L3CXProfile2 (new_l3_cx_profile, ver=2) No current use example, inherits utility functions from BaseProfile, maintains functionality of L3CXProfile |
| `l4_cxprofile.py` | Class: L4CXProfile (new_l4_cx_profile) Use example: test_ipv4_l4.py will create stations and endpoints to generate and verify layer-4 traffic |
| `lf_cv_base.py` | Class: ChamberViewBase, Base Class to be used for Chamber View Tests, inherited by DataPlaneTest in dataplane_test_profile.py |
| `lfdata.py` | Class: LFDataCollection, class used for data collection utility methods |
| `mac_vlan_profile.py` | Class: MACVLANProfile (new_mvlan_profile) Use example: test_fileio.py will create stations or macvlans with matching fileio endpoints to generate and verify fileio related traffic. |
| `multicast_profile.py` | Class: MULTICASTProfile (new_multicast_profile) Use example: test_l3_longevity.py multi cast profiles are created in this test |
| `port_utils.py` | Class: PortUtils used to set the ftp or http port |
| `qvlan_profile.py` | Class: QVLANProfile (new_qvlan_profile) Use example: create_qvlan.py (802.1Q VLAN) |
| `realm.py` | Class: The Realm Class is inherited by most python tests. Realm Class inherites from LFCliBase. The Realm Class contains the configurable components for LANforge, For example L3 / L4 cross connects, stations. http://www.candelatech.com/cookbook.php?vol=cli&book=Python_Create_Test_Scripts_With_the_Realm_Class |
| `realm_test.py` | Python script meant to test functionality of realm methods |
| `show_ports.py` | Python script example of how to check a LANforge json url |
| `station_profile.py` | Class: StationProfile (new_station_profile) Use example: most scripts create and use station profiles |
| `test_base.py` | Class: TestBase, basic class for creating tests, uses basic functions for cleanup, starting/stopping, and passing of tests |
| `test_group_profile.py` | Class: TestGroupProfile (new_test_group_profile) Use example: test_fileio.py will create stations or macvlans with matching fileio endpoints to generate and verify fileio related traffic |
| `test_utility.py` | Standard Script for Webconsole Test Utility |
| `vap_profile.py` | Class: VAPProfile (new_vap_profile) profile for creating Virtual AP's Use example: create_vap.py |
| `vr_profile2.py` | Class: VRProfile (new_vap_profile, ver=2) No current use example, inherits utility functions from BaseProfile |
| `wifi_monitor_profile.py` | Class: WifiMonitor (new_wifi_monitor_profile) Use example: tip_station_powersave.py This script uses filters from realm's PacketFilter class to filter pcap output for specific packets. |
| `wlan_theoretical_sta.py` | Class: abg11_calculator Standard Script for WLAN Capaity Calculator Use example: wlan_capacitycalculator.py |
| `ws-sta-monitor.py` | Example of how to filter messages from the :8081 websocket |
| `ws_generic_monitor.py` | Class: WS_Listener web socket listener Use example: ws_generic_monitor_test.py, ws_generic_monitor to monitor events triggered by scripts, This script when running, will monitor the events triggered by test_ipv4_connection.py |
### Python Scripts py-scripts ###
Test scripts and helper scripts
| Name | Purpose |
|------|---------|
| `cicd_TipIntegration.py` | Facebook TIP infrastructure|
| `cicd_testrail.py` | TestRail API binding for Python 3 |
| `cicd_testrailAndInfraSetup.py` | Facebook TIP infrastructure |
| `connection_test.py` | Standard Script for Connection Testing - Creates HTML and pdf report as a result (Used for web-console) |
| `create_bond.py` | This script can be used to create a bond |
| `create_bridge.py` | Script for creating a variable number of bridges |
| `create_chamberview.py` | Script for creating a chamberview scenario |
| `create_l3.py` | This script will create a variable number of layer3 stations each with their own set of cross-connects and endpoints |
| `create_l4.py` | This script will create a variable number of layer4 stations each with their own set of cross-connects and endpoints |
| `create_macvlan.py` | Script for creating a variable number of macvlans |
| `create_qvlan.py` | Script for creating a variable number of qvlans |
| `create_station.py` | Script for creating a variable number of stations |
| `create_station_from_df.py` | Script for creating a variable number of stations from a file |
| `create_vap.py` | Script for creating a variable number of VAPs |
| `create_vr.py` | Script for creating a variable number of bridges |
| `csv_convert.py` | Python script to read in a LANforge Dataplane CSV file and output a csv file that works with a customer's RvRvO visualization tool.|
| `csv_processor.py` | Python script to assist processing csv files|
| `csv_to_influx.py` | Python script to copy the data from a CSV file from the KPI file generated from a Wifi Capacity test to an Influx database|
| `download_test.py` | download_test.py will do lf_report::add_kpi(tags, 'throughput-download-bps', $my_value);|
| `event_breaker.py` | This file is intended to expose concurrency problems in the /events/ URL handler by querying events rapidly. Please use concurrently with event_flood.py. |
| `event_flood.py` | This file is intended to expose concurrency problems in the /events/ URL handler by inserting events rapidly. Please concurrently use with event_breaker.py.|
| `example_security_connection.py` | This python script creates a variable number of stations using user-input security
| `ftp_html.py` | This FTP Test is used to "Verify that N clients connected on Specified band and can simultaneously download some amount of file from FTP server and measures the time taken by client to Download/Upload the file |
| `grafana_profile.py` | Class for creating and managing a grafana dashboard |
| `html_template.py` | This script is used for DFS Test Report generation |
| `influx.py` | Class for communicating with influx |
| `influx2.py` | Class for communicating with influx |
| `layer3_test.py` | Python script to test and monitor layer 3 connections |
| `layer4_test.py` | Python script to test and monitor layer 4 connections |
| `lf_ap_auto_test.py` | This script is used to automate running AP-Auto tests |
| `lf_dataplane_test.py` | This script is used to automate running Dataplane tests |
| `lf_dfs_test.py` | Test testing dynamic frequency selection (dfs) between an AP connected to a controller and Lanforge|
| `lf_dut_sta_vap_test.py` | Load an existing scenario, start some layer 3 traffic, and test the Linux based DUT that has SSH server |
| `lf_ftp_test.py` | Python script will create stations and endpoints to generate and verify layer-4 traffic over an ftp connection |
| `lf_graph.py` | Classes for creating images from graphs using data sets |
| `lf_mesh_test.py` | This script is used to automate running Mesh tests |
| `lf_report.py` | This program is a helper class for reporting results for a lanforge python script |
| `lf_report_test.py` | Python script to test reporting |
| `lf_rvr_test.py` | This script is used to automate running Rate-vs-Range tests |
| `lf_snp_test.py` | Test scaling and performance (snp) run various configurations and measures data rates |
| `lf_tr398_test.py` | This script is used to automate running TR398 tests |
| `lf_wifi_capacity_test.py` | This is a test file which will run a wifi capacity test |
| `recordinflux.py` | recordinflux will record data from existing lanforge endpoints to record to an already existing influx database |
| `run_cv_scenario.py` | Set the LANforge to a BLANK database then it will load the specified database and start a graphical report |
| `rvr_scenario.py` | This script will set the LANforge to a BLANK database then it will load the specified database and start a graphical report |
| `scenario.py` | Python script to load a database file and control test groups |
| `sta_connect.py` | Create a station, run TCP and UDP traffic then verify traffic was received. Stations are cleaned up afterwards |
| `sta_connect2.py` | Create a station, run TCP and UDP traffic then verify traffic was received. Stations are cleaned up afterwards |
| `sta_connect_example.py` | Example of how to instantiate StaConnect and run the test |
| `sta_connect_multi_example.py` | Example of how to instantiate StaConnect and run the test |
| `station_layer3.py` | this script creates one station with given arguments |
| `stations_connected.py` | Contains examples of using realm to query stations and get specific information from them |
| `test_1k_clients_jedtest.py` | Python script to test 1k client connections |
| `test_client_admission.py` | This script will create one station at a time and generate downstream traffic |
| `test_fileio.py` | Test FileIO traffic |
| `test_generic.py` | Test generic traffic using generic cross-connect and endpoint type |
| `test_ipv4_connection.py` | Test connections to a VAP of varying security types (WEP, WPA, WPA2, WPA3, Open) |
| `test_ipv4_l4.py` | Test layer 4 traffic using layer 4 cross-connect and endpoint type |
| `test_ipv4_l4_ftp_upload.py` | Test ftp upload traffic |
| `test_ipv4_l4_ftp_urls_per_ten.py` | Test the number of urls per ten minutes in ftp traffic |
| `test_ipv4_l4_ftp_wifi.py` | Test ftp upload traffic wifi-wifi |
| `test_ipv4_l4_urls_per_ten.py` | Test urls per ten minutes in layer 4 traffic |
| `test_ipv4_l4_wifi.py` | Test layer 4 upload traffic wifi-wifi|
| `test_ipv4_ttls.py` | Test connection to ttls system |
| `test_ipv4_variable_time.py` | Test connection and traffic on VAPs of varying security types (WEP, WPA, WPA2, WPA3, Open) |
| `test_ipv6_connection.py` | Test IPV6 connection to VAPs of varying security types (WEP, WPA, WPA2, WPA3, Open) |
| `test_ipv6_variable_time.py` | Test IPV6 connection and traffic on VAPs of varying security types (WEP, WPA, WPA2, WPA3, Open) |
| `test_l3_WAN_LAN.py` | Test traffic over a bridged NAT connection |
| `test_l3_longevity.py` | Create variable stations on multiple radios, configurable rates, PDU, ToS, TCP and/or UDP traffic, upload and download, attenuation |
| `test_l3_powersave_traffic.py` | Python script to test for layer 3 powersave traffic |
| `test_l3_scenario_throughput.py` | Load an existing scenario and run the simultaneous throughput over time and generate report and P=plot the G=graph|
| `test_l3_unicast_traffic_gen.py` | Generate unicast traffic over a list of stations|
| `test_status_msg.py` | Test the status message passing functions of /status-msg |
| `test_wanlink.py` | Python script to test wanlink creation |
| `test_wpa_passphrases.py` | Python script to test challenging wpa psk passphrases |
| `testgroup.py` | Python script to test creation and control of test groups |
| `testgroup2.py` | Python script to test creation and control of test groups |
| `tip_station_powersave.py` | Generate and test for powersave packets within traffic run over multiple stations |
| `update_dependencies.py` | Python script to update dependencies for various Candelatech python scripts |
| `update_dut.py` | This script updates a Device Under Test (DUT) entry in the LANforge test scenario |
| `wlan_capacity_calculator.py` | Standard Script for WLAN Capacity Calculator |
| `ws_generic_monitor_test.py` | This example is to demonstrate ws_generic_monitor to monitor events triggered by scripts, This script when running, will monitor the events triggered by test_ipv4_connection.py |
## Perl and Shell Scripts ##
| Name | Purpose |
|------|---------|
| `associate_loop.sh` | Use this script to associate stations between SSIDs A and B |
| `attenuator_series_example.csv` | Example of CSV input for a series of attenuator settings |
| `attenuator_series.pl` | Reads a CSV of attenuator settings and replays them to CT70X programmble attenuator |
| `ftp-upload.pl` | Use this script to collect and upload station data to FTP site |
| `imix.pl` | packet loss survey tool |
| `lf_associate_ap.pl` | LANforge server script for associating virtual stations to an chosen SSID |
| `lf_attenmod.pl` | This program is used to modify the LANforge attenuator through the LANforge |
| `lf_auto_wifi_cap.pl` | This program is used to automatically run LANforge-GUI WiFi Capacity tests |
| `lf_cmc_macvlan.pl` | Stress test sets up traffic types of udp , tcp , continuously starts and stops the connections |
| `lf_create_bcast.pl` | creates a L3 broadcast connection |
| `lf_cycle_wanlinks.pl` | example of how to call lf_icemod.pl from a script |
| `lf_endp_script.pl` | create a hunt script on a L3 connection endpoint |
| `lf_firemod.pl` | queries and modifies L3 connections |
| `lf_generic_ping.pl` | Generate a batch of Generic lfping endpoints |
| `lf_gui_cmd.pl` | Initiate a stress test |
| `lf_icemod.pl` | queries and modified WANLink connections |
| `lf_ice.pl` | adds and configures wanlinks |
| `lf_l4_auth.pl` | example of scripting L4 http script with basic auth |
| `lf_l4_reset.sh` | reset any layer 4 connection that reaches 0 Mbps over last minute |
| `lf_log_parse.pl` | Convert the timestamp in LANforge logs (it is in unix-time, miliseconds) to readable date |
| `lf_loop_traffic.sh` | Repeatedly start and stop a L3 connection |
| `lf_macvlan_l4.pl` | Set up connection types: lf_udp, lf_tcp across 1 real port and many macvlan ports on 2 machines. Then continously starts and stops the connections. |
| `lf_mcast.bash` | Create a multicast L3 connection endpoint |
| `lf_monitor.pl` | Monitor L4 connections |
| `lf_nfs_io.pl` | Creates and runs NFS connections |
| `lf_parse_tshark_log.pl` | Basic parsing of tshark logs |
| `lf_portmod.pl` | Queries and changes LANforge physical and virtual ports |
| `lf_port_walk.pl` | Creates a series of connections, useful for basic firewall testing |
| `lf_show_events.pl` | Displays and clears LANforge event log |
| `lf_staggered_dl.sh` | his script starts a series of Layer-3 connections across a series of stations each station will wait $nap seconds, download $quantity KB and then remove its old CX. |
| `lf_sta_name.pl` | Use this script to alter a virtual station names |
| `lf_verify.pl` | Creates a basic L3 connection to verify that two ethernet ports are physically connected |
| `lf_voip.pl` | Creates series of VOIP connections between two LANforge machines |
| `lf_voip_test.pl` | Creates series of VOIP connections and runs them |
| `lf_vue_mod.sh` | Bash script that wraps common operations for Virtual User Endpoint operations done by `lf_associate_ap` |
| `lf_wifi_rest_example.pl` | Example script that queries a LF GUI for JSON data and displays a slice of it |
| `lf_zlt_binary.pl` | Configures a Zero Loss Throughput test |
| `list_phy_sta.sh` | Lists virtual stations backed by specified physical radio |
| `min_max_ave_station.pl` | This script looks for min-max-average bps for rx-rate in a station csv data file |
| `multi_routers.pl` | Routing cleanup script that can be used with virtual routers |
| `print_udev.sh` | Prints out Linux Udev rules describing how to name ports by MAC address |
| `sensorz.pl` | Displays temperature readings for CPU and ATH10K radios |
| `show-port-from-json.pl` | Example script showing how to display a slice from a JSON GUI response |
| `station-toggle.sh` | Use this script to toggle a set of stations on or off |
| `sysmon.sh` | grabs netdev stats and timestamp every second or so, saves to logfile. |
| `test_refcnt.pl` | creates MAC-VLANs and curl requests for each |
| `topmon.sh` | LANforge system monitor that can be used from cron |
| `wait_on_ports.pl` | waits on ports to have IP addresses, can up/down port to stimulate new DHCP lease |
| `wifi-roaming-times.pl` | parses `wpa_supplicant_log.wiphyX` file to determine roaming times |
### LANForge Monitoring ###
From LANforge cli on port 4001 do a 'show_event' to see events from LANforge
### Compatibility ###
Scripts will be kept backwards and forwards compatible with LANforge
releases as much as possible.
### Installation ###
These scripts call each other and rely on the structure of this directory. To use these scripts in other locations,
such as your laptop, either copy the entire scripts directory or do a __git clone__ of this repository. Just copying
one script to a separate directory is going to break its requirements.
### Requirements ###
The perl scripts require the following perl packages to be installed. Most of these
perl packages are available through your repository as `.deb` or `.rpm` packages.
| Perl Package | RPM | Required |
| -------------------|------------------|----------------|
| Net::Telnet | perl-Net-Telnet | Yes |
| JSON | perl-JSON | Yes, for JSON parsing |
| JSON::PrettyPrint | perl-JSON-PP | No, useful for debugging |
| Python3 Package | RPM | Required |
|-------------------------|-----------|---------------|
| Pexpect | python3-pexpect | yes |
| XlsxWriter | python3-xlsxwriter | yes, Xlsx output |
#### Pip v Pip3 ####
Please use pip3, we are targeting Python 3 with our scripts. If your pip/pip3 repositories have a difficult time connecting,
it's likely that you are trying to download from **pypi.python.org**. This is a deprecated location. Please update
using the **pypi.org** servers. Consider updating your ``~/.pypirc`` file:
````
[distutils]
index-servers =
pypi
[pypi]
repository: https://upload.pypi.org/legacy/
````
As [described on Python.org](https://packaging.python.org/guides/migrating-to-pypi-org/).
### License ###
Code in this repository is released under the BSD license (see license.txt).
### Support ###
Please contact support@candelatech.com if you have any questions.
_Thanks,
Ben_

View File

@@ -0,0 +1,15 @@
#!/usr/bin/env xdg-open
[Desktop Entry]
Version=1.0
Encoding=UTF-8
Name=WLANPro Test
Name[en_US.ISO8859-1]=WLANPro Test
Comment=WLANPro Test
Comment[en_US.ISO8859-1]=WLANPro Test
Path=/home/lanforge/Desktop
Exec=/home/lanforge/Desktop/wpro.sh
Icon=/usr/share/icons/Adwaita/scalable/apps/utilities-terminal-symbolic.svg
Type=Application
Terminal=true
Categories=Network;X-Candela-Technologies
GenericName[en_US]=WLANPro Test

View File

@@ -0,0 +1,57 @@
#!/bin/perl
# ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
# use this script after bringing up stations with a DHCP lease
# then admin-down the stations. Go into /home/lanforge/vr_conf
# and change the settings with this script on all the files
# in a manner like this:
#
# root# cd /home/lanforge/vr_conf
# root# ~lanforge/scripts/add-dhcp-hostname.pl dhclient_sta*conf
#
# At this point you can bring up your stations. If you need to
# check a lanforge dhcpd lease file, please look at the dhcp database
# found in /home/lanforge/vr_conf/vrcx_br1_dhcp_lease.db
# entries should have a "client-hostname: " entry.
# ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
use strict;
use warnings;
use diagnostics;
$| = 1;
if (@ARGV < 1) {
print "No files requested.\n";
exit 1;
}
my @chars = ("A".."Z", "a".."z", "0".."9");
my $rand_name = "";
for my $fname (@ARGV) {
print "File: $fname ";
my @lines = `cat $fname`;
chomp @lines;
die("Unable to open $fname for writing: $!")
unless open(my $fh, ">", $fname);
my $ifname='';
for my $line (@lines) {
next if ($line =~ /^\s*$/);
next if ($line =~ /^. LANforge-generated/);
next if ($line =~ /^. Remove first/);
next if ($line =~ /^. automatically over-write/);
next if ($line =~ /^send host-name/);
if ($line =~ /^# sta\d+/) {
($ifname) = $line =~ /^# (sta\d+)\s*$/;
}
print $fh "$line\n";
}
$rand_name = "";
$rand_name .= $chars[ rand @chars] for 1..8;
#print "* ";
#print "$rand_name\n";
print $fh "interface \"$ifname\" {\n";
print $fh " send host-name \"$rand_name\";\n";
print $fh "}\n";
close $fh;
}
print "done\n";

View File

@@ -0,0 +1,516 @@
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
use Carp;
use Data::Dumper;
use File::Temp qw(tempfile tempdir);
use Getopt::Long;
my $Q='"';
my $q="'";
my @idhunks = split(' ', `id`);
my @hunks = grep { /uid=/ } @idhunks;
die ("Must be root to use this")
unless( $hunks[0] eq "uid=0(root)" );
@idhunks = undef;
@hunks = undef;
my $start_time = `date +%Y%m%d-%H%M%S`;
chomp($start_time);
my $do_help = 0;
my $do_automatic = ( -t STDIN ) ? 0 : 1; # test for terminal stdin
my $debug = $ENV{'DEBUG'};
my $usage = "$0 :
Use this to update /etc/hosts and /etc/httpd/http.conf for
LANforge server operations. By default this script will backup
your /etc/hosts file to /etc/.hosts.\$date and write a new copy
to /tmp/t_hosts_\$random. It will show you the difference between
the files and prompt you to continue. When you approve it will
copy /tmp/t_hosts_\$random to /etc/hosts.
-d --debug enable debug (or use \$ set DEBUG=1)
-a --auto automatic operation mode, no prompts
-h --help this message
";
GetOptions(
"h|help" => \$do_help,
"d|debug" => \$debug,
"a|auto|automatic" => \$do_automatic,
) || die($usage);
if ($do_help) {
print $usage;
exit(0);
}
sub syslogg {
my $msg = join('\n', @_);
$msg =~ s/\r*\n/ /;
`logger -t adjust_apache "$msg"`
}
sub err {
my $msg = "[error] ".join("\n", @_);
print STDERR $msg, "\n";
syslogg($msg) if ($do_automatic);
}
sub die_err {
my $msg = "[fatal] ".join("\n", @_);
syslogg($msg) if ($do_automatic);
die($msg);
}
sub warning {
my $msg = "[warning] ".join("\n", @_);
print STDOUT $msg, "\n";
syslogg($msg) if ($do_automatic);
}
sub info {
my $msg = "[inf] ".join("\n", @_);
print STDOUT $msg, "\n";
syslogg($msg) if ($do_automatic);
}
my $MgrHostname = `cat /etc/hostname`;
chomp($MgrHostname);
info("Will be setting hostname to $MgrHostname");
sleep 3 if ($debug);
my $config_v = "/home/lanforge/config.values";
# grab the config.values file
die_err("Unable to find $config_v" )
unless ( -f $config_v);
my @configv_lines = `cat $config_v`;
die_err("Probably too little data in config.values")
unless (@configv_lines > 5);
my %configv = ();
foreach my $line (@configv_lines) {
my ($key, $val) = $line =~ /^(\S+)\s+(.*)$/;
$configv{$key} = $val;
}
die_err("Unable to parse config.values")
unless ((keys %configv) > 5);
die_err("no mgt_dev in config.values")
unless defined $configv{'mgt_dev'};
info("LANforge config states mgt_dev $configv{'mgt_dev'}");
if ( ! -d "/sys/class/net/$configv{'mgt_dev'}") {
die_err( "Please run lfconfig again with your updated mgt_port value.");
}
my $ipline = `ip -o a show $configv{"mgt_dev"}`;
my ($ip) = $ipline =~ / inet ([0-9.]+)(\/\d+)? /g;
die_err("No ip found for mgt_dev; your config.values file is out of date: $!")
unless ((defined $ip) && ($ip ne ""));
print "ip: $ip\n" if ($debug);
# This must be kept in sync with similar code in lf_kinstall.
my $found_localhost = 0;
my $fname = "/etc/hosts";
my $backup = "/etc/.hosts.$start_time";
`cp $fname $backup`;
die_err("Unable to create backup of /etc/hosts at $backup") if ( ! -f $backup );
my ($fh, $editfile) = tempfile( "t_hosts_XXXX", DIR=>'/tmp', SUFFIX=>'.txt');
if (-f "$fname") {
my @lines = `cat $fname`;
#open(FILE, ">$fname") or die "Couldn't open file: $fname for writing: $!\n\n";
my $foundit = 0;
my $i;
# chomp is way to simplistic if we need to weed out \r\n characters as well
#chomp(@lines);
for (my $i = 0; $i < @lines; $i++) {
($lines[$i]) = $lines[$i] =~ /^([^\r\n]+)\r?\n$/;
}
# we want to consolidate the $ip $hostname entry for MgrHostname
my @newlines = ();
my %more_hostnames = ();
my $new_entry = "$ip ";
#my $blank = 0;
#my $was_blank = 0;
my $counter = 0;
if ((exists $ENV{"DEBUG"}) && ($ENV{"DEBUG"} eq "1")) {
$debug = 1;
}
my %host_map = (
"localhost.localdomain" => "127.0.0.1",
"localhost" => "127.0.0.1",
"localhost4.localdomain4" => "127.0.0.1",
"localhost4" => "127.0.0.1",
"localhost.localdomain" => "::1",
"localhost" => "::1",
"localhost6.loaldomain6" => "::1",
"localhost6" => "::1",
$MgrHostname => $ip,
"lanforge.localnet" => "192.168.1.101",
"lanforge.localdomain" => "192.168.1.101",
);
my %comment_map = ();
my %address_marker_map = ();
my %address_map = (
"127.0.0.1" => "localhost.localdomain localhost localhost4.localdomain4 localhost4",
"::1" => "localhost.localdomain localhost localhost6.loaldomain6 localhost6",
$ip => $MgrHostname,
"192.168.1.101" => "lanforge.localnet lanforge.localdomain",
);
if ($debug) {
print Dumper(\%address_map);
print Dumper(\%host_map);
}
my $prevname = "";
my $previp = "";
for my $ln (@lines) {
next if (!(defined $ln));
# print "\nLN[$ln]\n" if ($debug);
next if ($ln =~ /^\s*$/);
next if ($ln =~ /^\s*#/);
next if ($ln =~ /LF-HOSTAME-NEXT/); # old typo
next if ($ln =~ /LF-HOSTNAME-NEXT/);
my $comment = undef;
# print "PARSING IPv4 ln[$ln]\n" if ($debug);
if ($ln =~ /#/) {
($comment) = $ln =~ /^[^#]+(#.*)$/;
($ln) = $ln =~ /^([^#]+)\s*#/;
print "line with comment becomes [$ln]\n" if ($debug);
}
@hunks = split(/\s+/, $ln);
my $middleip = 0;
my $counter2 = -1;
my $linehasip = 0;
my $lfhostname = 0;
if ((defined $comment) && ($comment ne "")) {
$comment_map{$hunks[0]} = $comment;
}
for my $hunk (@hunks) {
# print "\n HUNK",$counter2,"-:$hunk:- " if ($debug);
$counter2++;
next if ($hunk =~ /^localhost/);
next if ($hunk =~ /^lanforge-srv$/);
next if ($hunk =~ /^lanforge\.local(domain|net)$/);
next if ($hunk =~ /^extra6?-\d+/);
if ($hunk =~ /^\s*$/) {
next;
}
if ($hunk =~ /^$ip$/) {
$linehasip++;
$lfhostname++;
}
elsif ($hunk =~ /^$MgrHostname$/) {
$lfhostname++;
$prevname = $hunk;
}
$previp = "" if (!defined($previp));
if (($hunk =~ /^127\.0\.0\.1/)
|| ($hunk =~ /^192\.168\.1\.101/)
|| ($hunk =~ /^::1$/)) {
$previp = $hunk;
$linehasip++;
}
elsif ($hunk =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) {
$linehasip++;
# print " IP4($hunk)" if ($debug);
if ($counter2 > 0) { # we're not first item on line
$middleip++ if ($counter2 > 0);
# print "middle" if ($debug);
}
if (!(defined $address_map{$hunk})) {
$address_map{$hunk} = "";
}
# print "+IP4" if ($debug);
if (("" ne $prevname) && ($counter2 > 0)) {
# print " hunk($hunk)prev($prevname)" if ($debug);
$address_map{$hunk} .= " $prevname"
if ($address_map{$hunk} !~ /\s*$prevname\s*/);
# $host_map{$prevname} .= " $hunk";
if ($host_map{$prevname} !~ /\b$hunk\b/) {
$host_map{$prevname} .= " $hunk";
}
}
$previp = $hunk;
}
elsif (($hunk =~ /[G-Zg-z]+\.?/) || ($hunk =~ /^[^:A-Fa-f0-9]+/)) {
# print " notIP($hunk)" if ($debug);
$prevname = $hunk;
if ($middleip) {
# print " middle($previp)" if ($debug);
$address_map{$previp} .= " $hunk"
if ($address_map{$previp} !~ /\b$hunk\b/);
$prevname = $hunk;
if ($host_map{$prevname} !~ /\b$hunk\b/) {
$host_map{$prevname} .= " $previp";
}
}
elsif ($linehasip) {
# print " prev($previp) hunk($hunk)" if ($debug);
$address_map{$previp} .= " $hunk"
if ($address_map{$previp} !~ /\s*$hunk\s*/);
if ((defined $prevname) && (exists $host_map{$prevname}) && ($host_map{$prevname} !~ /\b$hunk\b/)) {
$host_map{$hunk} .= " $previp";
}
}
elsif ($lfhostname) {
$more_hostnames{$hunk} = 1;
if ($host_map{$prevname} !~ /\b$hunk\b/) {
$host_map{$hunk} .= " $previp";
}
}
else { # strange word
if ("" eq $previp) {
print " hunk($hunk) has no IP***" if ($debug);
$more_hostnames{$hunk} = 1;
}
elsif ($address_map{$previp} !~ /\s*$hunk\s*/) {
$address_map{$previp} .= " $hunk";
if ($host_map{$prevname} !~ /\b$hunk\b/) {
$host_map{$hunk} .= " $previp";
}
}
}
}
elsif (($hunk =~ /::/)
|| ($hunk =~ /[0-9A-Fa-f]+:/)) {
# print " hunk6($hunk)" if ($debug);
$linehasip++;
if (!(defined $address_map{$hunk})) {
$address_map{$hunk} = "";
}
$previp = $hunk;
}
elsif ($address_map{$previp} !~ /\s*$hunk\s*/) {
# is hostname and not an ip
$address_map{$previp} .= " $hunk";
if ($host_map{$prevname} !~ /\b$hunk\b/) {
$host_map{$hunk} .= " $previp";
}
}
} # ~foreach hunk
} # ~foreach line
if (($host_map{$MgrHostname} !~ /^\s*$/) && ($host_map{$MgrHostname} =~ /\S+\s+\S+/)) {
print("Multiple IPs for this hostname: " . $host_map{$MgrHostname} . "\n") if ($debug);
my @iphunks = split(/\s+/, $host_map{$MgrHostname});
print "Changing $MgrHostname to $ip; hostmap: <<$host_map{$MgrHostname}>> addrmap: <<$address_map{$ip}>>\n"
if ($debug);
$host_map{$MgrHostname} = $ip;
}
for my $name (sort keys %more_hostnames) {
$address_map{$ip} .= " $name";
print "updated address_map entry: $ip -> $address_map{$ip}\n" if ($debug);
}
# this might be premature
unshift(@newlines, "192.168.1.101 " . $address_map{"192.168.1.101"});
unshift(@newlines, "127.0.0.1 " . $address_map{"127.0.0.1"});
unshift(@newlines, "::1 " . $address_map{"::1"});
my %used_addresses = ();
delete($address_map{"192.168.1.101"});
$used_addresses{"192.168.1.101"} = 1;
delete($address_map{"127.0.0.1"});
$used_addresses{"127.0.0.1"} = 1;
delete($address_map{"::1"});
$used_addresses{"::1"} = 1;
if ($debug) {
print "# ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----\n";
print "\nAddress map\n";
print Dumper(\%address_map);
print "\nHost map\n";
print Dumper(\%host_map);
print "# ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----\n";
sleep 2;
}
# ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
# we want to maintain the original line ordering as faithfully as possible
# ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
for my $ln (@lines) {
$ln = "" if (!(defined $ln));
print "old[$ln]\n" if ($debug);
# if we are comments or blank lines, preserve them
next if ($ln =~ /LF-HOSTNAME-NEXT/);
next if ($ln =~ /\b$MgrHostname\b/); # skip our mgt hostname
next if ($ln =~ /^$host_map{$MgrHostname}\s+/); # line starts with present IP addr
if (($ln =~ /^\s*$/) || ($ln =~ /^\s*#/)) {
push(@newlines, $ln);
next;
}
@hunks = split(/\s+/, $ln);
if (exists $address_map{$hunks[0]}) {
if ((exists $address_marker_map{$hunks[0]})
|| (exists $used_addresses{$hunks[0]})) {
print "already printed $hunks[0]\n" if ($debug);
next;
}
my $comment = "";
if (exists $comment_map{$hunks[0]}) {
$comment = " $comment_map{$hunks[0]}";
}
push(@newlines, "$hunks[0] $address_map{$hunks[0]}$comment");
$address_marker_map{$hunks[0]} = 1;
next;
}
if (!(exists $used_addresses{$hunks[0]})) {
warning("untracked IP <<$hunks[0]>> Used addresses:");
print Dumper(\%address_marker_map) if ($debug);
print Dumper(\%used_addresses) if ($debug);
}
}
push(@newlines, "###-LF-HOSTNAME-NEXT-###");
push(@newlines, $ip . " " . $address_map{$ip});
if ($debug) {
print "# ----- new /etc/hosts ----- ----- ----- ----- ----- ----- ----- ----- ----- -----\n";
for my $ln (@newlines) {
print "$ln\n";
}
print "# ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----\n";
sleep 5;
}
# write to /tmp/t_hosts_$random
for my $ln (@newlines) {
print $fh "$ln\n";
}
close $fh;
my $wc_edit_file = `wc -l < $editfile`;
chomp($wc_edit_file);
my $wc_orig_file = `wc -l < $backup`;
if ($wc_edit_file == 0) {
die_err("Abandoning $editfile, it was blank.");
exit(1);
}
my $there_are_diffs = `/bin/diff /etc/hosts $editfile > /dev/null && echo 0 || echo 1`;
chomp($there_are_diffs);
$there_are_diffs = int($there_are_diffs);
if (! $there_are_diffs) {
info("No difference in hosts file.");
sleep(1) if (!$do_automatic);
}
elsif (!$do_automatic) {
my $msg = "Original /etc/hosts file backed up to $backup\n"
. "The hosts file differs by " . ($wc_orig_file - $wc_edit_file) . "lines, at: $editfile\n"
. "Displaying difference...\n";
info($msg);
sleep(2);
my $diffcmd = "diff -y /etc/hosts $editfile";
if ( -x "/usr/bin/colordiff" ) {
$diffcmd = "colordiff -y /etc/hosts $editfile";
}
open(my $diff_in, "-|", $diffcmd);
my ($diff_out, $diff_file) = tempfile( "diff_hosts_XXXX", DIR=>"/tmp" );
my @diff_lines = <$diff_in>;
close($diff_in);
print $diff_out join("", @diff_lines);
close($diff_out);
system("/bin/less -Nr $diff_file");
print "/bin/less -dNr $diff_file\n" if ($debug);
# prompt to exit
print "Press Enter to continue, [ctrl-c] to quit >";
my $i = <STDIN>;
}
if ($there_are_diffs) {
warning("Line comparison: $backup\: $wc_orig_file, $editfile\: $wc_edit_file");
warning("Installing new hosts file from $editfile, backup at $backup");
system("cp $editfile /etc/hosts");
}
} # ~if found hosts file
my $local_crt ="";
my $local_key ="";
my $hostname_crt ="";
my $hostname_key ="";
# check for hostname shaped cert files
if (-f "/etc/pki/tls/certs/localhost.crt") {
$local_crt = "/etc/pki/tls/certs/localhost.crt";
}
if (-f "/etc/pki/tls/private/localhost.key") {
$local_key = "/etc/pki/tls/private/localhost.key";
}
if (-f "/etc/pki/tls/certs/$MgrHostname.crt") {
$hostname_crt = "/etc/pki/tls/certs/$MgrHostname.crt";
}
if (-f "/etc/pki/tls/private/$MgrHostname.key") {
$hostname_key = "/etc/pki/tls/private/$MgrHostname.key";
}
# grab the 0000-default.conf file
my @places_to_check = (
"/etc/apache2/apache2.conf",
"/etc/apache2/ports.conf",
"/etc/apache2/sites-available/000-default.conf",
"/etc/apache2/sites-available/0000-default.conf",
"/etc/httpd/conf/http.conf",
"/etc/httpd/conf/httpd.conf",
"/etc/httpd/conf.d/ssl.conf",
"/etc/httpd/conf.d/00-ServerName.conf",
);
foreach my $file (@places_to_check) {
if (-f $file) {
print "Checking $file...\n";
my @lines = `cat $file`;
chomp @lines;
# we want to match Listen 80$ or Listen 443 https$
# we want to replace with Listen lanforge-mgr:80$ or Listen lanforge-mgr:443 https$
@hunks = grep {/^\s*(Listen|SSLCertificate)/} @lines;
if (@hunks) {
my $edited = 0;
my @newlines = ();
@hunks = (@hunks, "\n");
print "Something to change in $file\n";
print "These lines are interesting:\n";
print join("\n", @hunks);
foreach my $confline (@lines) {
if ($confline =~ /^\s*Listen\s+(?:80|443) */) {
$confline =~ s/Listen /Listen ${MgrHostname}:/;
print "$confline\n";
}
elsif ($confline =~ /^\s*Listen\s+(?:[^:]+:(80|443)) */) {
$confline =~ s/Listen [^:]+:/Listen ${MgrHostname}:/;
print "$confline\n";
}
if ($confline =~ /^\s*SSLCertificateFile /) {
$confline = "SSLCertificateFile $hostname_crt" if ("" ne $hostname_crt);
}
if ($confline =~ /^\s*SSLCertificateKeyFile /) {
$confline = "SSLCertificateKeyFile $hostname_key" if ("" ne $hostname_key);
}
push @newlines, $confline;
$edited++ if ($confline =~ /# modified by lanforge/);
}
push(@newlines, "# modified by lanforge\n") if ($edited == 0);
my $fh;
die($!) unless open($fh, ">", $file);
print $fh join("\n", @newlines);
close $fh;
}
else {
print "Nothing looking like [Listen 80|443] in $file\n";
}
}
} # ~for places_to_check
if (-d "/etc/httpd/conf.d") {
die($!) unless open(FILE, ">", "/etc/httpd/conf.d/00-ServerName.conf");
print FILE "ServerName $MgrHostname\n";
#print FILE "Listen $MgrHostname:80\n";
#print FILE "Listen $MgrHostname:443\n";
close FILE;
}
#

View File

@@ -0,0 +1,203 @@
#!/bin/bash
#
# adjust_ice.sh
#
# This script takes a csv data file with downlink, uplink and rtt values
# and uses the values to adjust an existing running wanlink.
#
# Each value is checked against the committed information rate (CIR) limits
# and when the limit is exceeded a shuffled value is chosen between a default
# min and max.
#
# Inputs are:
# csv filename
# name of wanlink
# run time between value changes
cd /home/lanforge/scripts
file=$1
name=$2
run_time=$3
print_help() {
echo "Usage: $0 {csv filename} {wanlink name} {run time}"
echo " Use this on lanforge localhost"
echo " Run time units are seconds"
echo " $0 values.csv wanlink-01 60"
echo ""
}
if [ $# -eq 0 ]; then
print_help
exit 1
fi
slices=10
cir_dn=3500000
cir_up=2000000
min=20000
max=200000
dates=()
downlink=()
uplink=()
delay=()
declare -A months
months=([Jan]=1 [Feb]=2 [Mar]=3 [Apr]=4 [May]=5 [Jun]=6 [Jul]=7 [Aug]=8 [Sep]=9 [Oct]=10 [Nov]=11 [Dec]=12)
# expects a "d-m-y hours:minutes meridian" format
function date_to_ts() {
local year
local hourmin
local meridian
[ -z "$1" ] && echo "date_to_ts: wants \$1 date string" && exit 1
local hunks=($1);
local datehunks=()
IFS=- read -r -a datehunks < <(echo "${hunks[0]}")
local month=${datehunks[1]}
local monthno=${months[$month]}
#echo "${monthno}/${datehunks[0]}/${datehunks[2]} ${hunks[1]} ${hunks[2]}"
date --date "${monthno}/${datehunks[0]}/${datehunks[2]} ${hunks[1]} ${hunks[2]}" +"%s"
}
function get_values() {
while read -r line
do
if [[ $line != "" ]]; then
if [[ $line == *DATE* ]]; then
continue;
fi
if [[ $line != *-* ]]; then
continue;
fi
local datestr=`echo $line |cut -d '"' -f1 |sed 's/,/ /g'`
local timest=$(date_to_ts "$datestr")
dates+=($timest)
local dl=`echo $line |cut -d '"' -f2 |sed 's/,//g'`
if [[ $dl < $cir_dn ]]; then
let dl=$(( $cir_dn - $dl ))
downlink+=( $dl )
else
let bas=$(shuf -i "$min-$max" -n1)
downlink+=( $bas )
fi
local ul=`echo $line |cut -d '"' -f6 |sed 's/,//g'`
if [[ $ul < $cir_up ]]; then
let ul=$(( $cir_up - $ul ))
uplink+=( $ul )
else
let bas=$(shuf -i "$min-$max" -n1)
uplink+=( $bas )
fi
local lat=`echo $line |cut -d '"' -f9 |sed 's/,//g' |cut -d '.' -f1`
let lat=$(( $lat/2 ))
delay+=( $lat )
fi
done < $file
}
function modify_values {
[ -z "$1" ] && echo "modify_values wants row index \$1, bye" && exit 1
local row_idx=$1
local dl_now=0
local ul_now=0
local lt_now=0
local ts_now=${dates[$row_idx]}
local ts_next=${dates[ $(( $row_idx +1 )) ]}
local delta=$(( $ts_next - $ts_now ))
local pause=$(( $delta / $slices ))
#echo "now: $ts_now, next: $ts_next, delta: $delta pause: $pause"
local downlink_now="${downlink[$row_idx]}"
local downlink_next="${downlink[ $(( $row_idx +1 )) ]}"
local downlink_delta=$(( $downlink_next - $downlink_now ))
local uplink_now="${uplink[$row_idx]}"
local uplink_next="${uplink[ $(( $row_idx +1 )) ]}"
local uplink_delta=$(( $uplink_next - $uplink_now ))
local delay_now="${delay[ $row_idx ]}"
local delay_next="${delay[ $(( $row_idx +1 )) ]}"
local delay_delta=$(( $delay_next - $delay_now ))
local dl_series=()
local ul_series=()
local delay_series=()
local j;
#echo "Deltas: $downlink_delta $uplink_delta $delay_delta"
echo "Now: $downlink_now $uplink_now $delay_now"
for ((j=1; j < $slices; ++j)); do
local d_j=$(( $downlink_delta / $slices ))
local u_j=$(( $uplink_delta / $slices ))
local l_j=$(( $delay_delta / $slices ))
local d_a=$d_j
local u_a=$u_j
if [[ $l_j != 0 ]]; then
local l_a=$l_j
else
local l_a=1
fi
[[ $d_j -lt 0 ]] && d_a=$(( -1 * $d_j ))
[[ $u_j -lt 0 ]] && u_a=$(( -1 * $u_j ))
[[ $l_j -lt 0 ]] && l_a=$(( -1 * $l_j ))
local d_i=$(( ($j * $d_j) + `shuf -i 1-$d_a -n1` ))
local u_i=$(( ($j * $u_j) + `shuf -i 1-$u_a -n1` ))
local l_i=$(( ($j * $l_j) + `shuf -i 1-$l_a -n1` ))
#echo "$j: $d_i $u_i $l_i"
echo "$j: $(($downlink_now + $d_i)) $(($uplink_now + $u_i)) $(($delay_now + $l_i))"
dl_series+=( $(($downlink_now + $d_i)) )
ul_series+=( $(($uplink_now + $u_i)) )
delay_series+=( $(($delay_now + $l_i)) )
done
echo "Next: $downlink_next $uplink_next $delay_next"
for ((j=0; j < 9; ++j)); do
dl_now=${dl_series[$j]}
ul_now=${ul_series[$j]}
lt_now=${delay_series[$j]}
echo "set wanlink $name: $dl_now $ul_now $lt_now"
echo "set wanlink $name-A: Downlink $dl_now, Delay $lt_now"
./lf_firemod.pl --mgr localhost --quiet on --action do_cmd --cmd \
"set_wanlink_info $name-A $dl_now $lt_now NA NA NA NA" &>/dev/null
echo "set wanlink $name-B: Uplink $ul_now, Delay $lt_now"
./lf_firemod.pl --mgr localhost --quiet on --action do_cmd --cmd \
"set_wanlink_info $name-B $ul_now $lt_now NA NA NA NA" &>/dev/null
echo "B-LOOP Waiting for $pause seconds."
sleep $pause
done
}
get_values
stop_at="$(( ${#downlink[@]} - 1 ))"
for ((i=0; i < $stop_at; ++i)); do
#echo "set wanlink $name: ${downlink[i]} ${uplink[i]} ${delay[i]}"
echo "set wanlink $name-A: Downlink ${downlink[i]}, Delay ${delay[i]}"
./lf_firemod.pl --mgr localhost --quiet on --action do_cmd --cmd \
"set_wanlink_info $name-A ${downlink[i]} ${delay[i]} NA NA NA NA" &>/dev/null
echo "set wanlink $name-B: Uplink ${uplink[i]}, Delay ${delay[i]}"
./lf_firemod.pl --mgr localhost --quiet on --action do_cmd --cmd \
"set_wanlink_info $name-B ${uplink[i]} ${delay[i]} NA NA NA NA" &>/dev/null
echo "A-LOOP Waiting for $run_time seconds."
sleep $run_time
[[ $i -ge $stop_at ]] && break
modify_values $i
done

View File

@@ -0,0 +1,83 @@
#!/bin/bash
. ~lanforge/lanforge.profile
# We can set channel and number of antennas when creating one station or many stations
# Example 1
./lf_associate_ap.pl --mgr idtest \
--resource 7 \
--action add \
--radio wiphy0 \
--antenna ALL \
--channel 153 \
--first_ip DHCP \
--num_sta 5 \
--ssid hedtest-wpa2-153 \
--security wpa2 \
--passphrase hedtest-wpa2-153
# Example 2
# we can also start traffic with this example
# create layer 3 connections between those stations and upstream bridge port
# action step1 make the layer 3 connections and runs them for duration
./lf_associate_ap.pl --mgr idtest \
--resource 7 \
--radio wiphy0 \
--antenna ALL \
--channel 153 \
--first_ip DHCP \
--num_sta 5 \
--ssid hedtest-wpa2-153 \
--security wpa2 \
--passphrase hedtest-wpa2-153 \
--duration 5min \
--upstream br0 \
--bps_min 1000000 \
--cxtype tcp \
--poll_time 5 \
--action step1
# Example 3
# if we wanted to create the connections independently, we can do it like this:
pkt_size=720
for n in `seq 100 105`; do
station="sta$n"
endpa="tcp$n-A"
endpb="tcp$n-B"
cxname="tcp$n"
./lf_firemod.pl --mgr idtest --resource 7 --action create_endp --endp_type lf_tcp \
--endp_name "$endpa" --port_name "br0" --speed 1000000 --min_pkt_sz $pkt_size
./lf_firemod.pl --mgr idtest --resource 7 --action create_endp --endp_type lf_tcp \
--endp_name "$endpb" --port_name "sta$n" --speed 1000000 --min_pkt_sz $pkt_size
./lf_firemod.pl --mgr idtest --resource 7 --action create_cx --cx_name $cxname --cx_endps $endpa,$endpb
done
for n in `seq 100 105`; do
cxname="tcp$n"
./lf_firemod.pl --mgr idtest --resource 7 --action do_cmd --cli_cmd "set_cx_state all $cxname RUNNING"
done
# poll every two seconds
for i in `seq 1 $((5 * 30))` ; do
for n in `seq 100 105`; do
./lf_firemod.pl --mgr idtest --resource 7 --action show_endp --endp_name "tcp$n-A" --endp_vals rx_bps
./lf_firemod.pl --mgr idtest --resource 7 --action show_endp --endp_name "tcp$n-B" --endp_vals rx_bps
done
sleep 2
done
for n in `seq 100 105`; do
cxname="tcp$1"
./lf_firemod.pl --mgr idtest --resource 7 --action do_cmd --cli_cmd "set_cx_state all $cxname QUIESCE"
done
# print out all connections:
for n in `seq 100 105`; do
./lf_firemod.pl --mgr idtest --resource 7 --action show_cx --endp_name "tcp$n" --endp_vals rx_bps
done

View File

@@ -0,0 +1,498 @@
#!/usr/bin/python3
'''
NAME:
ap_ctl.py
PURPOSE:
Script that logs into an AP via Serial, SSH, or Telnet to read data or execute commands
EXAMPLE:
./ap_ctl.py --scheme "serial" "--tty "Serial port for accessing AP" --prompt "#" --dest <ip if using SSH or Telnet> --port <port , none for serial> --user <user name>
--passwd <password> --action <command>
In a program:
ap_info= subprocess.run(["./ap_ctl.py", "--scheme", ap_dict['ap_scheme'], "--prompt", ap_dict['ap_prompt'],"--dest", ap_dict['ap_ip'], "--port", ap_dict["ap_port"],
"--user", ap_dict['ap_user'], "--passwd", ap_dict['ap_pw'],"--action", "powercfg"],stdout=subprocess.PIPE)
NOTES:
LANforge 192.168.100.178
Controller at 192.168.100.112 admin/Cisco123
Controller is 192.1.0.10
AP is on serial port /dev/ttyUSB1 or /dev/ttyUSB2 9600 8 n 1
make sure pexpect is installed:
$ sudo yum install python3-pexpect
You might need to install pexpect-serial using pip:
$ pip3 install pexpect-serial
$ sudo pip3 install pexpect-serial
./ap_ctl.py
'''
import sys
if sys.version_info[0] != 3:
print("This script requires Python 3")
exit()
import logging
import time
from time import sleep
import argparse
import pexpect
import serial
from pexpect_serial import SerialSpawn
# pip install pexpect-serial (on Ubuntu)
# sudo pip install pexpect-serial (on Ubuntu for everyone)
default_host = "localhost"
default_ports = {
"serial": None,
"ssh": 22,
"telnet": 23
}
NL = "\n"
CR = "\r\n"
Q = '"'
A = "'"
FORMAT = '%(asctime)s %(name)s %(levelname)s: %(message)s'
band = "a"
logfile = "stdout"
# regex101.com ,
# this will be in the tx_power script
# ^\s+1\s+6\s+\S+\s+\S+\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)
def usage():
print("$0 used connect to Cisco AP:")
print("-a|--ap: AP to act upon")
print("-d|--dest: destination host")
print("-o|--port: destination port")
print("-u|--user: AP login name")
print("-p|--pass: AP password")
print("-s|--scheme (serial|telnet|ssh): connect to controller via serial, ssh or telnet")
print("--tty Serial port for accessing AP")
print("-l|--log file: log messages here")
print("-b|--baud: serial baud rate")
print("-z|--action: action")
print("-h|--help")
# see https://stackoverflow.com/a/13306095/11014343
class FileAdapter(object):
def __init__(self, logger):
self.logger = logger
def write(self, data):
# NOTE: data can be a partial line, multiple lines
data = data.strip() # ignore leading/trailing whitespace
if data: # non-blank
self.logger.info(data)
def flush(self):
pass # leave it to logging to flush properly
# Test command if lanforge connected ttyUSB0
# sudo ./ap_ctl.py -a lanforge -d 0 -o 0 -u "lanforge" -p "lanforge" -s "serial" -t "/dev/ttyUSB0"
# sample for lanforge 192.168.100.178
# sudo ./ap_ctl.py -a APA53.0E7B.EF9C -d 0 -o 0 -u "admin" -p "Admin123" -s "serial" -t "/dev/ttyUSB2" -z "show_log"
def main():
global logfile
AP_ESCAPE = "Escape character is '^]'."
AP_USERNAME = "Username:"
AP_PASSWORD = "Password:"
AP_EN = "en"
AP_MORE = "--More--"
AP_EXIT = "exit"
LF_PROMPT = "$"
CR = "\r\n"
parser = argparse.ArgumentParser(description="Cisco AP Control Script")
parser.add_argument("-a", "--prompt", type=str, help="ap prompt")
parser.add_argument("-d", "--dest", type=str, help="address of the AP 172.19.27.55")
parser.add_argument("-o", "--port", type=int, help="control port on the AP, 2008")
parser.add_argument("-u", "--user", type=str, help="credential login/username, admin")
parser.add_argument("-p", "--passwd", type=str, help="credential password Wnbulab@123")
parser.add_argument("-s", "--scheme", type=str, choices=["serial", "ssh", "telnet"], help="Connect via serial, ssh or telnet")
parser.add_argument("-t", "--tty", type=str, help="tty serial device for connecting to AP")
parser.add_argument("-l", "--log", type=str, help="logfile for messages, stdout means output to console",default="stdout")
parser.add_argument("-z", "--action", type=str, help="action, current action is powercfg")
parser.add_argument("-b", "--baud", type=str, help="action, baud rate lanforge: 115200 cisco: 9600")
args = None
try:
args = parser.parse_args()
host = args.dest
scheme = args.scheme
port = (default_ports[scheme], args.port)[args.port != None]
user = args.user
if (args.log != None):
logfile = args.log
except Exception as e:
logging.exception(e)
usage()
exit(2)
console_handler = logging.StreamHandler()
formatter = logging.Formatter(FORMAT)
logg = logging.getLogger(__name__)
logg.setLevel(logging.DEBUG)
file_handler = None
if (logfile is not None):
if (logfile != "stdout"):
file_handler = logging.FileHandler(logfile, "w")
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(formatter)
logg.addHandler(file_handler)
logging.basicConfig(format=FORMAT, handlers=[file_handler])
else:
# stdout logging
logging.basicConfig(format=FORMAT, handlers=[console_handler])
egg = None # think "eggpect"
ser = None
try:
if (scheme == "serial"):
#eggspect = pexpect.fdpexpect.fdspan(telcon, logfile=sys.stdout.buffer)
ser = serial.Serial(args.tty, int(args.baud), timeout=5)
print("Created serial connection on %s, open: %s"%(args.tty, ser.is_open))
egg = SerialSpawn(ser)
egg.logfile = FileAdapter(logg)
time.sleep(1)
egg.sendline(CR)
time.sleep(1)
elif (scheme == "ssh"):
if (port is None):
port = 22
cmd = "ssh -p%d %s@%s"%(port, user, host)
logg.info("Spawn: "+cmd+NL)
egg = pexpect.spawn(cmd)
#egg.logfile_read = sys.stdout.buffer
egg.logfile = FileAdapter(logg)
elif (scheme == "telnet"):
if (port is None):
port = 23
cmd = "telnet {} {}".format(host, port)
logg.info("Spawn: "+cmd+NL)
egg = pexpect.spawn(cmd)
egg.logfile = FileAdapter(logg)
# Will login below as needed.
else:
usage()
exit(1)
except Exception as e:
logging.exception(e)
AP_PROMPT = "{}>".format(args.prompt)
AP_HASH = "{}#".format(args.prompt)
time.sleep(0.1)
logged_in = False
loop_count = 0
while (loop_count <= 8 and logged_in == False):
loop_count += 1
i = egg.expect_exact([AP_ESCAPE,AP_PROMPT,AP_HASH,AP_USERNAME,AP_PASSWORD,AP_MORE,LF_PROMPT,pexpect.TIMEOUT],timeout=5)
if i == 0:
logg.info("Expect: {} i: {} before: {} after: {}".format(AP_ESCAPE,i,egg.before,egg.after))
egg.sendline(CR) # Needed after Escape or should just do timeout and then a CR?
sleep(1)
if i == 1:
logg.info("Expect: {} i: {} before: {} after: {}".format(AP_PROMPT,i,egg.before,egg.after))
egg.sendline(AP_EN)
sleep(1)
j = egg.expect_exact([AP_PASSWORD,pexpect.TIMEOUT],timeout=5)
if j == 0:
logg.info("Expect: {} i: {} j: {} before: {} after: {}".format(AP_PASSWORD,i,j,egg.before,egg.after))
egg.sendline(args.passwd)
sleep(1)
k = egg.expect_exact([AP_HASH,pexpect.TIMEOUT],timeout=5)
if k == 0:
logg.info("Expect: {} i: {} j: {} k: {} before: {} after: {}".format(AP_PASSWORD,i,j,k,egg.before,egg.after))
logged_in = True
if k == 1:
logg.info("Expect: {} i: {} j: {} k: {} before: {} after: {}".format("Timeout",i,j,k,egg.before,egg.after))
if j == 1:
logg.info("Expect: {} i: {} j: {} before: {} after: {}".format("Timeout",i,j,egg.before,egg.after))
if i == 2:
logg.info("Expect: {} i: {} before: {} after: {}".format(AP_HASH,i,egg.before,egg.after))
logged_in = True
sleep(1)
if i == 3:
logg.info("Expect: {} i: {} before: {} after: {}".format(AP_USERNAME,i,egg.before,egg.after))
egg.sendline(args.user)
sleep(1)
if i == 4:
logg.info("Expect: {} i: {} before: {} after: {}".format(AP_PASSWORD,i,egg.before,egg.after))
egg.sendline(args.passwd)
sleep(1)
if i == 5:
logg.info("Expect: {} i: {} before: {} after: {}".format(AP_MORE,i,egg.before,egg.after))
if (scheme == "serial"):
egg.sendline("r")
else:
egg.sendcontrol('c')
sleep(1)
# for Testing serial connection using Lanforge
if i == 6:
logg.info("Expect: {} i: {} before: {} after: {}".format(LF_PROMPT,i,egg.before.decode('utf-8', 'ignore'),egg.after.decode('utf-8', 'ignore')))
if (loop_count < 3):
egg.send("ls -lrt")
sleep(1)
if (loop_count > 4):
logged_in = True # basically a test mode using lanforge serial
if i == 7:
logg.info("Expect: {} i: {} before: {} after: {}".format("Timeout",i,egg.before,egg.after))
egg.sendline(CR)
sleep(1)
if (args.action == "powercfg"):
logg.info("execute: show controllers dot11Radio 1 powercfg | g T1")
egg.sendline('show controllers dot11Radio 1 powercfg | g T1')
egg.expect([pexpect.TIMEOUT], timeout=3) # do not delete this for it allows for subprocess to see output
print(egg.before.decode('utf-8', 'ignore')) # do not delete this for it allows for subprocess to see output
i = egg.expect_exact([AP_MORE,pexpect.TIMEOUT],timeout=5)
if i == 0:
egg.sendcontrol('c')
if i == 1:
logg.info("send cntl c anyway")
egg.sendcontrol('c')
elif (args.action == "clear_log"):
logg.info("execute: clear log")
egg.sendline('clear log')
sleep(0.4)
egg.sendline('show log')
egg.expect([pexpect.TIMEOUT], timeout=2) # do not delete this for it allows for subprocess to see output
print(egg.before.decode('utf-8', 'ignore')) # do not delete this for it allows for subprocess to see output
# allow for normal logout below
elif (args.action == "show_log"):
logg.info("execute: show log")
egg.sendline('show log')
sleep(0.4)
egg.expect([pexpect.TIMEOUT], timeout=2) # do not delete this for it allows for subprocess to see output
print(egg.before.decode('utf-8', 'ignore')) # do not delete this for it allows for subprocess to see output
i = egg.expect_exact([AP_MORE,pexpect.TIMEOUT],timeout=4)
if i == 0:
egg.sendline('r')
egg.expect([pexpect.TIMEOUT], timeout=4) # do not delete this for it allows for subprocess to see output
print(egg.before.decode('utf-8', 'ignore')) # do not delete this for it allows for subprocess to see output
if i == 1:
print(egg.before.decode('utf-8', 'ignore')) # do not delete this for it allows for subprocess to see output
# allow for normal logout below
# show log | g DOT11_DRV
# CAC_EXPIRY_EVT: CAC finished on DFS channel 52
elif (args.action == "cac_expiry_evt"):
logg.info("execute: show log | g CAC_EXPIRY_EVT")
egg.sendline('show log | g CAC_EXPIRY_EVT')
sleep(0.4)
egg.expect([pexpect.TIMEOUT], timeout=2) # do not delete this for it allows for subprocess to see output
print(egg.before.decode('utf-8', 'ignore')) # do not delete this for it allows for subprocess to see output
i = egg.expect_exact([AP_MORE,pexpect.TIMEOUT],timeout=4)
if i == 0:
egg.sendline('r')
egg.expect([pexpect.TIMEOUT], timeout=4) # do not delete this for it allows for subprocess to see output
print(egg.before.decode('utf-8', 'ignore')) # do not delete this for it allows for subprocess to see output
if i == 1:
print(egg.before.decode('utf-8', 'ignore')) # do not delete this for it allows for subprocess to see output
elif (args.action == "ds_data_5ghz"):
logg.info("execute: wl -i wl1 bs_data")
egg.sendline('wl -i wl1 bs_data')
egg.expect([pexpect.TIMEOUT], timeout=4) # do not detete this for it allow for subprocess to read
print(egg.before.decode('utf-8','ignore')) # do not delete this for it allows for subprocess to see output
elif (args.action == "ds_data_24ghz"):
logg.info("execute: wl -i wl0 bs_data")
egg.sendline('wl -i wl1 bs_data')
egg.expect([pexpect.TIMEOUT], timeout=4) # do not detete this for it allow for subprocess to read
print(egg.before.decode('utf-8','ignore')) # do not delete this for it allows for subprocess to see output
else: # no other command at this time so send the same power command
#logg.info("no action so execute: show controllers dot11Radio 1 powercfg | g T1")
logg.info("no action")
i = egg.expect_exact([AP_PROMPT,AP_HASH,pexpect.TIMEOUT],timeout=1)
if i == 0:
logg.info("received {} we are done send exit".format(AP_PROMPT))
egg.sendline(AP_EXIT)
if i == 1:
logg.info("received {} send exit".format(AP_HASH))
egg.sendline(AP_EXIT)
if i == 2:
logg.info("timed out waiting for {} or {}".format(AP_PROMPT,AP_HASH))
# ctlr.execute(cn_cmd)
''' NOTES for AP DFS
#############################
1. Do "show AP summary" on the controller to see the list of AP's connected.
2. Now, check the channel configured on the AP using the commend "show ap channel <AP-Name>"
3. Check for the current channel and Channel width for Slot id 1. See the output of this command.
4. Before making any changes, please connect at least 1 client to this AP in 5GHz radio.
Keep running the ping traffic to the default gateway of the AP.
4. Now, configure dfs channel for this AP with 20MHz as channel width.
6. After CAC Expiry, Client should connect back - Verify the pings are passing through or not.
Note time:
"show logging" in the AP will show the CAC timer details. You can grep for "DFS CAC timer enabled time 60" and "changed to DFS channel 52, running CAC for 60 seconds.
Wait for 60 sec and check for this log "CAC_EXPIRY_EVT: CAC finished on DFS channel 52"
[*07/07/2020 23:37:48.1460] changed to DFS channel 52, running CAC for 60 seconds.
[*07/07/2020 23:38:48.7240] CAC_EXPIRY_EVT: CAC finished on DFS channel 52
"make a note of the time and check the CAC timer expired in 60-61 seconds.
7. Now, trigger the radar on Channel 52. AP should move to another channel.
Also, When the radar is triggered, capture the CSA frames and verify the CSA count is set to 10 or not.
8. Now, verify the black-list time of the channel for this AP. : show ap auto-rf 802.11a <AP-Name>
In the controller, give the command "show ap auto-rf 802.11a <AP-Name>" under Radar information you should see the "Detected Channels and Blacklist Times" .
Black list time will be 1800 seconds which is 30 minutes.
Radar Information
DFS stats on serving radio................... 0
DFS stats on RHL radio....................... 0
DFS stats triggered.......................... 0
Cumulative stats on serving radio............ 0
Cumulative stats on RHL radio................ 0
Cumulative stats triggered................... 0
Detected Channels
Channel 100................................ 5 seconds ago
Blacklist Times
Channel 100................................ 1795 seconds remaining
(Cisco Controller) >show ap channel APA453.0E7B.CF9C
Slot Id ..................................... 0
802.11b/g Current Channel ..................... 11*
Allowed Channel List........................... 1,2,3,4,5,6,7,8,9,10,11
Slot Id ..................................... 1
802.11a Current Channel ....................... (36,40) 40MHz / Cap 160MHz
Allowed Channel List........................... 36,40,44,48,52,56,60,64,100,
........................... 104,108,112,116,120,124,128,
........................... 132,136,140,144,149,153,157,
........................... 161,165
###########################
Password: [*02/09/2021 14:30:04.2290] Radio [1] Admininstrative state ENABLED change to DISABLED
[*02/09/2021 14:30:04.2300] DOT11_DRV[1]: Stop Radio1
[*02/09/2021 14:30:04.2520] DOT11_DRV[1]: DFS CAC timer enabled time 60
[*02/09/2021 14:30:04.2740] DOT11_DRV[1]: DFS CAC timer enabled time 60
[*02/09/2021 14:30:04.2740] Stopped Radio 1
[*02/09/2021 14:30:36.2810] Radio [1] Admininstrative state DISABLED change to ENABLED
[*02/09/2021 14:30:36.3160] DOT11_DRV[1]: set_channel Channel set to 52/20 <<<<<< ????
[*02/09/2021 14:30:36.3390] wlc_ucode_download: wl0: Loading 129 MU ucode
[*02/09/2021 14:30:36.4420] wlc_ucode_download: wl0: Loading 129 MU ucode
[*02/09/2021 14:30:36.5440] wlc_ucode_download: wl0: Loading 129 MU ucode
[*02/09/2021 14:30:36.6490] DOT11_DRV[1]: DFS CAC timer enabled time 60 <<<<<< ????
[*02/09/2021 14:30:37.2100] wl0: wlc_iovar_ext: vap_amsdu_rx_max: BCME -23
[*02/09/2021 14:30:37.2100] wl: Unsupported
[*02/09/2021 14:30:37.2100] ERROR: return from vap_amsdu_rx_max was -45
[*02/09/2021 14:30:37.4100] wlc_ucode_download: wl0: Loading 129 MU ucode
[*02/09/2021 14:30:37.5040] DOT11_CFG[1]: Starting radio 1
[*02/09/2021 14:30:37.5050] DOT11_DRV[1]: Start Radio1 <<<<<<<<<
[*02/09/2021 14:30:37.5120] DOT11_DRV[1]: set_channel Channel set to 52/20
[*02/09/2021 14:30:37.5340] wlc_ucode_download: wl0: Loading 129 MU ucode
[*02/09/2021 14:30:37.6360] wlc_ucode_download: wl0: Loading 129 MU ucode
[*02/09/2021 14:30:37.7370] wlc_ucode_download: wl0: Loading 129 MU ucode
[*02/09/2021 14:30:37.8410] DOT11_DRV[1]: DFS CAC timer enabled time 60 <<<<<<<
[*02/09/2021 14:30:37.8650] wlc_ucode_download: wl0: Loading 129 MU ucode
[*02/09/2021 14:30:37.9800] changed to DFS channel 52, running CAC for 60 seconds. <<<<< Note use this one
[*02/09/2021 14:30:38.0020] Started Radio 1 <<<<< After start radio
[*02/09/2021 14:31:07.4650] wl0: wlc_iovar_ext: olpc_cal_force: BCME -16
[*02/09/2021 14:31:38.4210] CAC_EXPIRY_EVT: CAC finished on DFS channel 52 <<<<<< Start with this very unique CAC finished
[*02/09/2021 14:31:48.2850] chatter: client_ip_table :: ClientIPTable no client entry found, dropping packet 04:F0:21:F
# note lf_hackrf.py begins transmitting immediately... see if that is what is to happen?
[*02/09/2021 15:20:53.7470] wcp/dfs :: RadarDetection: radar detected <<<<< Radar detected
[*02/09/2021 15:20:53.7470] wcp/dfs :: RadarDetection: sending packet out to capwapd, slotId=1, msgLen=386, chanCnt=1 2
[*02/09/2021 15:20:53.7720] DOT11_DRV[1]: DFS CAC timer disabled time 0
[*02/09/2021 15:20:53.7780] Enabling Channel and channel width Switch Announcement on current channel
[*02/09/2021 15:20:53.7870] DOT11_DRV[1]: set_dfs Channel set to 36/20, CSA count 6 <<<<<<< Channel Set
[*02/09/2021 15:20:53.8530] DOT11_DRV[1]: DFS CAC timer enabled time 60
Trying another station
*02/09/2021 15:25:32.6130] Radio [1] Admininstrative state ENABLED change to DISABLED
[*02/09/2021 15:25:32.6450] DOT11_DRV[1]: Stop Radio1
[*02/09/2021 15:25:32.6590] Stopped Radio 1
[*02/09/2021 15:25:52.1700] wlc_ucode_download: wl0: Loading 129 MU ucode
[*02/09/2021 15:26:04.6640] Radio [1] Admininstrative state DISABLED change to ENABLED
[*02/09/2021 15:26:04.6850] DOT11_DRV[1]: set_channel Channel set to 36/20
[*02/09/2021 15:26:04.7070] wlc_ucode_download: wl0: Loading 129 MU ucode
[*02/09/2021 15:26:04.8090] wlc_ucode_download: wl0: Loading 129 MU ucode
[*02/09/2021 15:26:04.9090] wlc_ucode_download: wl0: Loading 129 MU ucode
[*02/09/2021 15:26:05.5620] wl0: wlc_iovar_ext: vap_amsdu_rx_max: BCME -23
[*02/09/2021 15:26:05.5620] wl: Unsupported
[*02/09/2021 15:26:05.5620] ERROR: return from vap_amsdu_rx_max was -45
[*02/09/2021 15:26:05.7600] wlc_ucode_download: wl0: Loading 129 MU ucode
[*02/09/2021 15:26:05.8530] DOT11_CFG[1]: Starting radio 1
[*02/09/2021 15:26:05.8540] DOT11_DRV[1]: Start Radio1
[*02/09/2021 15:26:05.8610] DOT11_DRV[1]: set_channel Channel set to 36/20
[*02/09/2021 15:26:05.8830] wlc_ucode_download: wl0: Loading 129 MU ucode
[*02/09/2021 15:26:05.9890] wlc_ucode_download: wl0: Loading 129 MU ucode
[*02/09/2021 15:26:06.0900] wlc_ucode_download: wl0: Loading 129 MU ucode
[*02/09/2021 15:26:06.2080] wlc_ucode_download: wl0: Loading 129 MU ucode
[*02/09/2021 15:26:06.5350] Started Radio 1
[*02/09/2021 15:26:15.9750] chatter: client_ip_table :: ClientIPTable no client entry found, dropping packet 04:F0:21:
Username: [*02/09/2021 15:33:49.8680] Radio [1] Admininstrative state ENABLED change to DISABLED
[*02/09/2021 15:33:49.9010] DOT11_DRV[1]: Stop Radio1
[*02/09/2021 15:33:49.9160] Stopped Radio 1
[*02/09/2021 15:34:14.4150] DOT11_DRV[1]: set_channel Channel set to 56/20
[*02/09/2021 15:34:14.4370] wlc_ucode_download: wl0: Loading 129 MU ucode
[*02/09/2021 15:34:14.5390] wlc_ucode_download: wl0: Loading 129 MU ucode
[*02/09/2021 15:34:14.6400] wlc_ucode_download: wl0: Loading 129 MU ucode
[*02/09/2021 15:34:14.7450] DOT11_DRV[1]: DFS CAC timer enabled time 60
[*02/09/2021 15:34:21.9160] Radio [1] Admininstrative state DISABLED change to ENABLED
[*02/09/2021 15:34:21.9370] DOT11_DRV[1]: set_channel Channel set to 56/20
[*02/09/2021 15:34:21.9590] wlc_ucode_download: wl0: Loading 129 MU ucode
[*02/09/2021 15:34:22.0610] wlc_ucode_download: wl0: Loading 129 MU ucode
[*02/09/2021 15:34:22.1610] wlc_ucode_download: wl0: Loading 129 MU ucode
[*02/09/2021 15:34:22.2650] DOT11_DRV[1]: DFS CAC timer enabled time 60
[*02/09/2021 15:34:22.8270] wl0: wlc_iovar_ext: vap_amsdu_rx_max: BCME -23
[*02/09/2021 15:34:22.8270] wl: Unsupported
[*02/09/2021 15:34:22.8270] ERROR: return from vap_amsdu_rx_max was -45
[*02/09/2021 15:34:23.0280] wlc_ucode_download: wl0: Loading 129 MU ucode
[*02/09/2021 15:34:23.1210] DOT11_CFG[1]: Starting radio 1
[*02/09/2021 15:34:23.1210] DOT11_DRV[1]: Start Radio1
[*02/09/2021 15:34:23.1280] DOT11_DRV[1]: set_channel Channel set to 56/20
[*02/09/2021 15:34:23.1510] wlc_ucode_download: wl0: Loading 129 MU ucode
[*02/09/2021 15:34:23.2520] wlc_ucode_download: wl0: Loading 129 MU ucode
[*02/09/2021 15:34:23.3520] wlc_ucode_download: wl0: Loading 129 MU ucode
[*02/09/2021 15:34:23.4560] DOT11_DRV[1]: DFS CAC timer enabled time 60
[*02/09/2021 15:34:23.4800] wlc_ucode_download: wl0: Loading 129 MU ucode
[*02/09/2021 15:34:23.5960] changed to DFS channel 56, running CAC for 60 seconds.
[*02/09/2021 15:34:23.6180] Started Radio 1
'''
if __name__ == '__main__':
main()
####
####
####

View File

@@ -0,0 +1,138 @@
#!/bin/bash
echo "----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- "
echo " This script will issue local arp flushes. "
echo " Those commands cannot be issued against a remote lanforge."
echo "----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- "
sleep 2
mgr=localhost
port=4001
station=wlan0
upstream=eth1
num_mvlans=200
cxlist=()
ports=($station)
saved_gc_stale_time=`cat /proc/sys/net/ipv4/neigh/default/gc_stale_time`
saved_base_reachable_time_ms=`cat /proc/sys/net/ipv4/neigh/default/base_reachable_time_ms`
trap do_sigint ABRT
trap do_sigint INT
trap do_sigint KILL
trap do_sigint PIPE
trap do_sigint QUIT
trap do_sigint SEGV
trap do_sigint TERM
function do_sigint() {
echo -en "\nDefaulting arp timings "
for ((i=0; i < num_mvlans; i++)); do
mvlan="${upstream}#${i}"
echo $saved_gc_stale_time > /proc/sys/net/ipv4/neigh/$mvlan/gc_stale_time
echo $saved_base_reachable_time_ms > /proc/sys/net/ipv4/neigh/$mvlan/base_reachable_time_ms
echo -n "."
done
echo ""
echo -en "\nStopping connections: "
fire_cmd stop_group udp-arp
#for cx in "${cxlist[@]}"; do
# echo -n ":"
# fire_cmd set_cx_state default_tm $cx STOPPED >/dev/null
#done
echo ""
fire_cmd clear_group udp-arp
echo -n "Removing connections: "
for cx in "${cxlist[@]}"; do
echo -n "x"
fire_cmd rm_cx default_tm $cx STOPPED >/dev/null
done
echo ""
echo -n "Removing endpoints: "
for cx in "${cxlist[@]}"; do
echo -n "-"
fire_cmd rm_endp ${cx}-A STOPPED >/dev/null
fire_cmd rm_endp ${cx}-B STOPPED >/dev/null
done
echo ""
set +x
exit 0
}
function fire_cmd() {
./lf_firemod.pl --mgr $mgr --mgr_port $port --quiet yes \
--action do_cmd --cmd "$*" &>/dev/null
}
function fire_newcx() {
local cxname=$1; shift
local sta=$1; shift
local eth=$1; shift
./lf_firemod.pl --mgr $mgr --mgr_port $port --action create_cx --quiet yes \
--cx_name $cxname --use_ports $sta,$eth --use_speeds 11500,11500 --endp_type udp \
&>/dev/null
}
# create new set of vlans, this will also recreate them using random mac addresses
#num_vlans=$(( $num_mvlans - 1))
set -e
if (( num_mvlans < 1 )); then
echo "Too few vlans"
exit 1
fi
echo -n "Removing old $num_mvlans macvlans: "
for ((i=0; i < num_mvlans; i++)); do
mvlan="${upstream}#${i}"
fire_cmd rm_vlan 1 1 $mvlan
echo -n "-"
sleep 0.03
done
sleep 1
echo " Checking for $num_mvlans old vlans:"
while (./lf_portmod.pl --mgr localhost --list_port_names | grep -q "$upstream#"); do
sleep 1
echo -n ","
done
echo -n "Adding $num_mvlans new macvlans: "
for ((i=0; i < num_mvlans; i++)); do
fire_cmd add_mvlan 1 1 $upstream 'xx:xx:xx:*:*:xx' $i
echo -n ":"
sleep 0.05
done
# "84033538"
for ((i=0; i < num_mvlans; i++)); do
mvlan="${upstream}#${i}"
fire_cmd set_port 1 1 "$mvlan" NA NA NA NA 2147483648 NA NA NA NA 75513858
echo -n "="
sleep 0.05
echo 1 > /proc/sys/net/ipv4/neigh/$mvlan/gc_stale_time
echo 1 > /proc/sys/net/ipv4/neigh/$mvlan/base_reachable_time
done
echo ""
fire_cmd add_group udp-arp
sleep 2
echo -n "Creating $num_mvlans connections: "
for ((i=0; i < num_mvlans; i++)); do
mvlan="${upstream}#${i}"
fire_newcx "udp-$i" $station $mvlan
echo -n "+"
cxlist+=("udp-$i")
ports+=($mvlan)
fire_cmd add_tgcx udp-arp "udp-$i"
done
sleep 2
#for ((i=0; i < num_mvlans; i++)); do
#echo -n "="
#fire_cmd set_cx_state default_tm "udp-$i" RUNNING
#done
fire_cmd start_group udp-arp
sleep 2
echo ""
echo -n "Starting arp flushing: "
while : ; do
for p in "${ports[@]}"; do
ip neigh flush dev $p
done
echo -n "!"
sleep 0.2
done
#

View File

@@ -0,0 +1,158 @@
#!/bin/bash
##### ##### ##### ##### ##### ##### ##### ##### ##### ##### ##### ##### #####
## ##
## Use this script to associate stations between SSIDs A and B ##
## ##
## Install this script in /home/lanforge ##
## Usage: ./associate_loop -m localhost -r 1 -a SSIDA -b SSIDB -n 10 -i 5 ##
## -w wiphy0 -s sta1,sta2,sta3,sta4,sta5,sta6,sta7,sta8,sta9,sta10 ##
## ##
## ##
## ##
## ##
##### ##### ##### ##### ##### ##### ##### ##### ##### ##### ##### ##### #####
Q='"'
A="'"
#set -e
#set -x
usage="$0 -m localhost -r 1 -w wiphy0 -s sta1,sta2...<max> -a SSIDA -b SSIDB -n <seconds> -i <iterations>
-m: manager ip address
-r: resourse id
-w: radio name for stations
-s: station list, comma separated (no spaces)
-a: first ssid
-b: second ssid
-n: naptime in seconds
-i: iteration to loop
Associate one station (sta1) for 1 second, 10 iterations:
$0 -m localhost -r 1 -w wiphy0 -s sta1,wlan1 -a testap1 -b testap2 -n 1 -i 10
Associate ten stations (sta105..sta109) for 5 seconds, indefinitely:
stations=\`seq -f 'sta%g' -s, 105 109\`
$0 -m 192.168.101.1 -r 2 -w wiphy1 -s \$stations -a testap1 -b testab2 -n 5 -i 0
Hit control-c to stop.
"
modscript=""
if [ -f "lf_firemod" ]; then
modscript="./lf_firemod.pl"
elif [ -f "/home/lanforge/scripts/lf_firemod.pl" ]; then
modscript="/home/lanforge/scripts/lf_firemod.pl"
fi
cd /home/lanforge/scripts
[ -z "$modscript" ] && {
echo "script [$modscript] not present, please use this script from /home/lanforge or /home/lanforge/scripts"
exit 1
}
infinite=0
while getopts ":a:b:i:m:n:r:s:w:" opt ; do
case $opt in
a) SSIDA="$OPTARG" ;;
b) SSIDB="$OPTARG" ;;
i) iterations="$OPTARG" ;;
m) manager="$OPTARG" ;;
n) naptime="$OPTARG" ;;
r) resource="$OPTARG" ;;
s) stations="$OPTARG" ;;
w) wiphy="$OPTARG" ;;
esac
done
[ -z "$stations" ] && {
echo "-s: stations, requires {begin,...end} for stations;"
echo "$usage"
exit 1
}
sta_start=0
sta_end=0;
IFS="," sta_hunks=($stations);
unset IFS
#if [ ${#sta_hunks[@]} -gt 1 ] ; then
# sta_start=${sta_hunks[0]}
# sta_end=${sta_hunks[1]}
#else
# sta_start=${sta_hunks[0]}
# sta_end=${sta_hunks[0]}
#fi
[ -z "$naptime" ] && {
echo "-n: naptime required: seconds between changing ssids"
echo "$usage"
exit 1
}
[ -z "$iterations" ] && {
echo "-i: iterations to switch ssids"
echo "$usage"
exit 1
}
[ $iterations -lt 0 ] && {
echo "-i: positive number of iterations only, please"
exit 1;
}
[ $iterations -eq 0 ] && {
echo "Infinite iterations selected."
infinite=1;
}
[ -z "$SSIDB" ] && {
echo "-b: SSID B required"
echo "$usage"
exit 1
}
[ -z "$SSIDA" ] && {
echo "-a: SSID A required"
echo "$usage"
exit 1
}
[ -z "$resource" ] && {
echo "-r: resource number for radio owning the station to modify"
echo "$usage"
exit 1
}
[ -z "$wiphy" ] && {
echo "-w: wiphy radio owning the station"
echo "$usage"
exit 1;
}
[ -z "$manager" ] && {
echo "-m: ip address of LANforge manager "
echo "$usage"
exit 1;
}
use_ssid=0 # 0 := a, 1 := b
while [ $infinite == 1 -o $iterations -ge 0 ] ; do
for sta in "${sta_hunks[@]}"; do
if [ $use_ssid == 0 ]; then
newssid=$SSIDA
else
newssid=$SSIDB
fi
[ -z "$wiphy" ] && {
echo "radio unconfigured, error."
exit 1
}
clicmd="add_sta 1 $resource $wiphy $sta NA $newssid"
$modscript --quiet yes --mgr $manager --resource $resource --action do_cmd --cmd "$clicmd"
sleep 0.05
done
if [ $use_ssid = 1 ]; then
use_ssid=0;
else
use_ssid=1;
fi
iterations=$(($iterations - 1))
sleep $naptime
done
#eof

View File

@@ -0,0 +1,357 @@
#!/usr/bin/perl
##
## Reads a CSV of attenuator settings and plays them back
## Remember that 300 is deci-dB; eg 300: sets a channel to 30.0 dB
##
use strict;
use warnings;
use diagnostics;
use Carp;
$SIG{__DIE__} = sub{Carp::confess(@_)};
use Getopt::Long;
use lib '/home/lanforge/scripts';
use Net::Telnet;
use Time::HiRes qw(usleep);
use LANforge::Utils;
use LANforge::csv qw();
$| = 1;
our $usage = qq($0: replay a csv file of attenuator values
--mgr|m LANforge manager host
--file|f CSV file
--delay|d Override of %delay variable, milliseconds between applying rows
--loop|l Repeat indefinitely
--channel|c Override of channels variable, eg: 1.2.3.1,2.3.4.3
--minimum|min|i Set minimum attenuation value (not lower than zero)
--maximum|max|x Set maximum attenuation value (not higher than 955)
--dry_run|dryrun|dry|n Do not apply attenuation, just parse file, ignore nap times
Example that works on localhost manager:
$0 --file values.csv
Example that overrides delay to 1600, overrides channels and runs once:
$0 --mgr 192.168.101.1 --file values.csv --delay 1600 --channel 1.1.3.1,1.1.3.2,1.1.3.3
Example that overrides delay to 600ms, loops forever, and overrides min and max attenuation
$0 -m 192.168.101.1 -f values.csv -d 600 -l -min 10 -max 900
File Format:
# < comment lines are ignored
# 60 milliseconds between rows
delay,60
# Directives: DELAY,delay and naptime are equivalent
# Sets minimum and maximum attenuation for all channels
min,10
max,900
# Directives: MINIMUM,MAXIMUM,MIN,MAX,minimum,min,maximum and max are allowed
# The next line defines column B as attenuator channel 1.1.13.1
# and column C as attenuator channel 2.1.25.1. Remember that
# attennuator channels are values (shelf).(resource).(serialno).(channel)
# and channels are presently values {1, 2, 3, 4}.
channels,1.1.13.1,2.1.25.1
# Directives: CHANNELS,channels are equivalent
# Attenuation values are in deci-dBm, resolution of 5ddB:
# The next line sets 1.1.13.1 to 36.5dB, 2.1.25.1 to 30.0dB:
attenuate,365,300
# Directives: ATTENUATE,attenuate, "", and _ are equivalent.
# The next line leaves 1.1.13.1 alone, sets 2.1.25.1 to 31.0dB,
# _ is an abbreviation for attenuate
_,NA,+10
# The next line leaves 1.1.13.1 alone, sets 2.1.25.1 to 30.5dB,
# Blank first column is an abbreviation for attenuate
,NA,-5
# Only some basic CSV formulas are interpretable, and only operate
# on the previous values of the attenuator; the next line sets
# sets 1.1.13.1 to 36.0dB, sets 2.1.25.1 to 31.0dB
,=B6-5,=C6+5
# does nothing for a period
_,_,NA,,
# does nothing for 35ms
sleep,35
# Directives: SLEEP,sleep, and nap are equivalent
);
our $csvfile = undef;
our $delay = -1;
our $delay_override = -1;
our $do_loop = 0;
our @channels = (); # in order list of channels
our %last_atten = (); # a map of last-known values
our $channel_override= undef;
our $quiet = "yes";
our $line = 0; # line number
our $lfmgr_host = "localhost";
our $lfmgr_port = 4001;
our $dryrun = 0;
our $min_atten = 0;
our $max_atten = 995;
GetOptions (
'manager|mgr|m=s' => \$::lfmgr_host,
'mgr_port|port|p=i' => \$::lfmgr_port,
'file|f=s' => \$::csvfile,
'delay|d=i' => \$::delay_override,
'loop|l' => \$::do_loop,
'channels|c' => \$::channel_override,
'quiet|q=s' => \$::quiet,
'dry_run|dry|n' => \$::dryrun,
'minimum|min|mn|i=i' => \$::min_atten,
'maximum|max|mx|x=i' => \$::max_atten,
) || die("$::usage");
die("Please specify a manager address;\n$::usage")
if (!defined $::lfmgr_host || "$::lfmgr_host" eq "");
die("Please specify a csv file;\n$::usage")
if (!defined $::csvfile || "$::csvfile" eq "");
die("Unable to find csv file: $::csvfile")
unless(-f $::csvfile );
our $cfile=new LANforge::csv();
$::cfile->readFile($::csvfile);
if ($::cfile->numRows < 1) {
die( "empty file, nothing to do");
}
if ($::quiet eq "1" ) {
$::quiet = "yes";
}
elsif ($::quiet eq "0" ) {
$::quiet = "no";
}
if (defined $::channel_override && "$::channel_override" != "") {
for my $c ( split(/,/, $::channel_override)) {
push(@::channels, $c);
$::last_atten{$c} = 0;
}
}
die("Minimum attenuation must be between [0-954]")
if ($::min_atten > 994 || $::min_atten < 0);
die("Maximum attenuation must be between [1-995]")
if ($::max_atten > 995 || $::max_atten < 1);
die("Minimum attenuation must be less than maximum attenuation")
if ($::max_atten <= $::min_atten);
sub lastAtten {
my $arg = shift;
die ("lastAtten: called without argument")
if (! defined $arg || "$arg" eq "");
if ($arg =~ /^\d+$/) {
if (!defined($::channels[$arg])) {
warn "Channels: ".join(', ', @::channels);
die ("no channel recorded at position $arg");
}
die ("no channel [$::channels[$arg]]")
if (!defined $::last_atten{$::channels[$arg]});
return $::last_atten{$::channels[$arg]};
}
elsif ($arg =~ /^\d+\.\d+\.\d+\.\d+$/) {
die ("no channel [$::channels[$arg]]")
if (!defined $::last_atten{$::channels[$arg]});
return $::last_atten{$arg};
}
die ("lastAtten: What is channel $arg?");
}
sub attenuate {
my $channel = shift;
my $value = shift;
die("attenuate: no line number")
if (!defined $::line || "$::line" eq "");
die("attenuate: $::line: no channel")
if (!defined $channel || "$channel" eq "");
return if (!defined $value || "$value" eq "");
return if (lc($value) =~ /^(na|_)$/);
return if (lc($value) =~ /^\s*[!;\#]/);
my ($shelf, $resource, $serno, $chan) = split(/\./, $channel);
#print "shelf:$shelf, r:$resource, ser:$serno, ch:$chan\n";
die( "[$::line] attenuate: shelf misconfigured:[$channel][$value]")
if ($shelf != 1);
die( "[$::line] attenuate: resource misconfigured:[$channel][$value]")
if ($resource < 1);
die( "[$::line] attenuate: serial number misconfigured:[$channel][$value]")
if ($serno < 1);
die( "[$::line] attenuate: channel misconfigured:[$channel][$value]")
if ($chan < 0 || $chan > 4);
my $prev_value = $::last_atten{$channel};
if ($value =~ /^[-+]/) {
die("[$::line] attenuate: no previous value set for $channel")
if (! defined $prev_value);
$value = $prev_value + (0+$value);
#warn "VALUE MATH[$value] ";
}
if ($value > $::max_atten) {
warn("[$::line] attenuate: value cannot be higher than $::max_atten")
unless($::quiet eq "yes");
$value = $::max_atten;
}
if ($value < $::min_atten) {
warn("[$::line] attenuate: value cannot be lower than $::min_atten")
unless($::quiet eq "yes");
$value = $::min_atten;
}
$::last_atten{$channel} = $value;
$::utils->doAsyncCmd("set_atten $shelf $resource $serno $chan $value")
unless (defined $::dryrun && $::dryrun);
print "$::line: set_atten $shelf.$resource.$serno.$chan $value\n"
if ($::quiet ne "yes" || $::dryrun);
}
##
## M A I N
##
# connect to manager
our $utils = new LANforge::Utils();
$utils->connect($lfmgr_host, $lfmgr_port);
if ($::quiet eq "yes") {
$::utils->cli_send_silent(1); # Do show input to CLI
$::utils->cli_rcv_silent(1); # Repress output from CLI ??
}
else {
$::utils->cli_send_silent(0); # Do show input to CLI
$::utils->cli_rcv_silent(0); # Repress output from CLI ??
}
if (defined $::delay_override && $::delay_override != -1 && $::delay_override < 1000) {
warn("$0: --delay is in milliseconds, values less than 1000 (1 second) might be meaningless");
sleep 2;
}
die ("$0: --delay of zero or less is not permitted.")
if (defined $::delay_override && $::delay_override != -1 && $::delay_override <= 0);
$::delay = $::delay_override if (defined $::delay_override && $::delay_override > 0);
my $loop_count = 0;
while ($loop_count == 0 || $::do_loop) {
$loop_count++;
for (my $rownum = 0; $rownum < $::cfile->numRows(); $rownum++) {
$::line = $rownum+1;
my $ra_row = $::cfile->getRow($rownum);
next if (@{$ra_row} == 0); # empty row
if (lc($ra_row->[0]) =~ /^(delay|naptime)$/) {
next if (defined $::delay_override && $::delay_override != -1);
$::delay = 0 + $ra_row->[1];
die ("$line: delay of zero or less is not permitted")
if ($::delay <= 0);
next;
}
if (lc($ra_row->[0]) =~ /^channels$/ && (!defined $::channel_override)) {
my @tempchannels = @$ra_row;
shift @tempchannels;
%::last_atten= ();
for my $c (@tempchannels) {
push(@::channels, $c);
$::last_atten{$c} = -1;
}
next;
}
if (lc($ra_row->[0]) =~ /^(sleep|nap)$/) {
if (!defined $ra_row->[1] || (0 + $ra_row->[1]) < 1) {
die("$line: sleep value needs to be 1ms or greater");
}
usleep($ra_row->[1] *1000) unless ($::dryrun);
next;
}
if (lc($ra_row->[0]) =~ /^(attenuate|_)$/ || $ra_row->[0] eq "") {
#print "\n";
my $col = 1;
foreach my $ch (@::channels) {
my $value = "NA";
my $data = $::cfile->getCell($col, $rownum, "na");
#print "DATA($col,$::line)[$data] ";
if (!defined $data || "$data" eq "" ) {
$col++;
next;
}
if (lc($data) =~ /^(na|_)$/ || $data =~ /^\s*\#.*$/) {
#warn ("skipping data[$data] at $col,$::line");
$col++;
next;
}
if ($data =~ /^\d+$/) {
$value = 0 + $data;
}
elsif ($data =~ /^=[B-Z]\d+[+-]\d+$/i) { # we have a formula
my ($acol,$arow,$delta) = $data =~ /^=([B-Z])(\d+)([+-]\d+)$/i;
$acol = ord(uc($acol)) - 65;
my $pval = $::cfile->getCell($acol, $arow-1, 0);
if (!defined $pval) {
$pval = lastAtten($col-1);# $::last_atten{$::channels[$col]};
warn("Failed to find valid references at cell[$col,$::line], using previous attenuation:".$pval);
}
if ( $pval !~ /^\d+$/) {
$value = lastAtten($col-1);# $::last_atten{$::channels[$col]};
die("Failed to find valid references at cell[$col,$::line]:".$value)
if ( ! defined $value);
#$value = $value + (0+$delta);
warn "Substituting [$value]: cell[$col,$::line] refers to cell[$acol,$arow] with non absolute value:$pval";
}
else {
$value = $pval + (0 + $delta);
}
#print "acol[$acol] arow[$arow] delta[$delta] pval[$pval] value[$value]\n";
}
elsif ($data =~ /^\@?[+]+\d+$/ ) { # add relative
my ($delta) = $data =~ /^\@?[+]+(\d+)$/;
my $pval = lastAtten($col-1); #$::last_atten{$::channels[$col]};
$value = $pval + (0 + $delta);
}
elsif ( $data =~ /^\@?[-]+\d+$/ ) { # subtract relative
my ($delta) = $data =~ /^\@?[-]+(\d+)$/;
my $pval = lastAtten($col-1); #$::last_atten{$::channels[$col]};
$value = $pval + (-1 * (0 + $delta));
}
else {
warn "Unknown directive[$data] ";
$col++;
next;
}
attenuate($ch, "$value");
$col++;
}
die("Step delay not set correctly[$::delay]")
if (!defined $::delay || "$::delay" eq "" || (0+$::delay) < 1);
usleep($::delay * 1000) unless ($::dryrun);
next
}
die("$::line: unknown directive[".$ra_row->[0]);
}
}
## eof

View File

@@ -0,0 +1,15 @@
# test of the attenuator loop
channels, 1.1.14.1, 1.1.14.2, 1.1.14.3, 1.1.3.1, 1.1.3.2, 1.1.3.3
delay,1000
950,850,750, 950,850,750
sleep,1000
-10,-10,-10, -10,-10,-10
-10,-10,NA, -10,-10,NA
-10,-10,NA, -10,-10,NA
-10,-10,-10, -10,-10,-10
+10,+10,+10, +10,+10,+10
+10,+10,NA, +10,+10,NA
+10,+10,NA, +10,+10,NA
+10,+10,+10, +10,+10,+10
# eof
1 # test of the attenuator loop
2 channels, 1.1.14.1, 1.1.14.2, 1.1.14.3, 1.1.3.1, 1.1.3.2, 1.1.3.3
3 delay,1000
4 950,850,750, 950,850,750
5 sleep,1000
6 -10,-10,-10, -10,-10,-10
7 -10,-10,NA, -10,-10,NA
8 -10,-10,NA, -10,-10,NA
9 -10,-10,-10, -10,-10,-10
10 +10,+10,+10, +10,+10,+10
11 +10,+10,NA, +10,+10,NA
12 +10,+10,NA, +10,+10,NA
13 +10,+10,+10, +10,+10,+10
14 # eof

View File

@@ -0,0 +1,127 @@
#!/usr/bin/env python3
from html.parser import HTMLParser
import urllib.request
from html.entities import name2codepoint
import re
import datetime
import argparse
import os
import time
import glob
import sys
import subprocess
#===========ARGUMENT PARSING==============
parser = argparse.ArgumentParser()
parser.add_argument("--versionNumber", type=str, help="Specify version number to search for")
args = parser.parse_args()
if args.versionNumber != None:
ver = args.versionNumber
else:
parser.print_help()
parser.exit()
#=============HTML PARSING================
url = "http://jed-centos7/pld/"
with urllib.request.urlopen(url) as response:
html = response.read()
webpage = html.decode('utf-8')
#print(webpage)
searchPattern = '(LANforgeGUI_(\d+\.\d+\.\d+)_Linux64.tar.bz2)<\/a><\/td><td align="right">(\d+\-\d+\-\d+\ \d+\:\d+)'
searchResults = re.findall(searchPattern, webpage)
webFiles = []
for file in searchResults:
if ver == file[1]:
webFiles.append({'filename':file[0], 'timestamp': datetime.datetime.strptime(file[2], "%Y-%m-%d %H:%M")})
if len(webFiles) == 0:
print("Failed to find webfile with version number %s" % (ver))
sys.exit(1)
#=========CHECK DIR FOR FILES=============
filePath = "/home/lanforge/Downloads/"
dir = glob.glob(filePath + "LANforgeGUI_%s*" % ver)
dirFiles = []
for file in dir:
if ver in file:
fileTime = datetime.datetime.strptime(time.ctime(os.stat(file).st_ctime), "%a %b %d %H:%M:%S %Y") # Fri May 8 08:31:43 2020
dirFiles.append({'filename':file[25:], 'timestamp':fileTime})
if len(dirFiles) == 0:
print("Unable to find file in {filePath} with version %s" % ver)
#sys.exit(1)
#============FIND NEWEST FILES============
def findNewestVersion(filesArray):
newest = filesArray[0]
if len(filesArray) > 0:
for file in filesArray:
if file['timestamp'] > newest['timestamp']:
newest = file
return newest
newestWebFile = findNewestVersion(webFiles)
if len(dirFiles) != 0:
newestDirFile = findNewestVersion(dirFiles)
else:
newestDirFile = {'filename':'placeholder', 'timestamp': datetime.datetime.strptime("0", "%H")}
#=======COMPARE WEB AND DIR FILES=========
if newestWebFile['timestamp'] > newestDirFile['timestamp']:
try:
if newestDirFile['filename'] != 'placeholder':
subprocess.call(["rm", "%s%s" % (filePath, newestDirFile['filename'])])
print("No file found")
print("Downloading newest %s from %s" % (newestWebFile['filename'], url))
else:
print("Found newer version of GUI")
print("Downloading %s from %s" % (newestWebFile['filename'], url))
#=====ATTEMPT DOWNLOAD AND INSTALL=========
subprocess.call(["curl", "-o", "%s%s" % (filePath, newestWebFile['filename']), "%s%s" % (url, newestWebFile['filename'])])
time.sleep(5)
except Exception as e:
print("%s Download failed. Please try again." % e)
sys.exit(1)
try:
print("Attempting to extract files")
subprocess.call(["tar", "-xf", "%s%s" % (filePath, newestWebFile['filename']), "-C", "/home/lanforge/"])
except Exception as e:
print("%s\nExtraction failed. Please try again" % e)
sys.exit(1)
#time.sleep(90)
try:
if "/home/lanforge/.config/autostart/LANforge-auto.desktop" not in glob.glob("/home/lanforge/.config/autostart/*"):
print("Copying LANforge-auto.desktop to /home/lanforge/.config/autostart/")
subprocess.call(["cp", "/home/lanforge/%s/LANforge-auto.desktop" % (newestWebFile['filename'][:len(newestWebFile)-18]), "/home/lanforge/.config/autostart/"])
except Exception as e:
print("%s\nCopy failed. Please try again" % e)
sys.exit(1)
try:
print("Attempting to install %s at /home/lanforge" % newestWebFile['filename'])
os.system("cd /home/lanforge/%s; sudo bash lfgui_install.bash" % (newestWebFile['filename'][:len(newestWebFile)-18]))
except Exception as e:
print("%s\nInstallation failed. Please Try again." % e)
sys.exit(1)
#=========ATTEMPT TO RESTART GUI==========
# try:
# print("Killing current GUI process")
# os.system("if pgrep java; then pgrep java | xargs kill -9 ;fi")
# except Exception as e:
# print("%s\nProcess kill failed. Please try again" % e)
# sys.exit(1)
else:
print("Current GUI version up to date")
sys.exit(0)

View File

@@ -0,0 +1,61 @@
#!/bin/bash
mgr="192.168.100.86"
./lf_portmod.pl --manager $mgr --load port-regression > /dev/null
sleep 10s
for x in vap0 sta0 eth1#0 eth1 eth1.1 rddVR0 br0
do
#Test MAC
port_output=`./lf_portmod.pl --quiet 1 --manager $mgr --card 2 --port_name $x --show_port MAC`
answer=${port_output:5}
# echo "MAC exists: $x $answer
if [ -z "$answer" ]; then
echo "Failed to find MAC address for $x."
exit 1
fi
#Test port UP
port_output=`./lf_portmod.pl --quiet 1 --manager $mgr --card 2 --port_name $x --show_port Current`
answer=${port_output:9:2}
# echo "DB UP: $x $answer"
if [ $answer != "UP" ]; then
echo "Failed, port $x is down after loading DB."
exit 1
fi
#Test port UP after reset
./lf_portmod.pl --quiet 1 --manager $mgr --card 2 --port_name $x --cmd reset > /dev/null
sleep 2s
port_output=`./lf_portmod.pl --quiet 1 --manager $mgr --card 2 --port_name $x --show_port Current`
answer=${port_output:9:2}
# echo "UP after reset: $x $answer"
if [ $answer != "UP" ]; then
echo "Failed, port $x is down after resetting."
exit 1
fi
#Test DOWN after ifdown
./lf_portmod.pl --quiet 1 --manager $mgr --card 2 --port_name $x --set_ifstate down
port_output=`./lf_portmod.pl --quiet 1 --manager $mgr --card 2 --port_name $x --show_port Current`
answer=${port_output:9:4}
# echo "DOWN after ifdown: $x $answer"
if [ $answer != "DOWN" ]; then
echo "Failed, port $x is still up after ifdown."
exit 1
fi
#Test UP after ifup
./lf_portmod.pl --quiet 1 --manager $mgr --card 2 --port_name $x --set_ifstate up
sleep 5s
port_output=`./lf_portmod.pl --quiet 1 --manager $mgr --card 2 --port_name $x --show_port Current`
answer=${port_output:9:2}
# echo "UP after ifup: $x $answer"
if [ $answer != "UP" ]; then
echo "Failed, port $x is still down after ifup."
exit 1
fi
done
echo "Test passed."

View File

@@ -0,0 +1,59 @@
#!/usr/bin/perl
##
## Calculated EAP-AKA AUTN based on:
## AUTN = (SQN xor AK) || AMF || MAC = 48 + 16 + 64 = 128 bits
##
use strict;
use warnings;
use diagnostics;
use Carp;
$SIG{__DIE__} = sub{Carp::confess(@_)};
use Getopt::Long;
$| = 1;
our $usage = qq($0: calculate AUTN
All input is in ascii hex.
--sqn SQN
--ak AK, output of f5
--amf AMF for test-set configuration
--mac MAC, output of f1
Example for test-set 19 (4.3.19) from 3GPP TS 35.208, v6.0.0 Release 6
$0 --sqn 16f3b3f70fc2 --ak ada15aeb7bb8 --amf c3ab --mac 2a5c23d15ee351d5
);
our $sqn = "";
our $ak = "";
our $amf = "";
our $mac = "";
GetOptions (
'sqn=s' => \$::sqn,
'ak=s' => \$::ak,
'amf=s' => \$::amf,
'mac=s' => \$::mac,
) || die("$::usage");
#AUTN = (SQN xor AK) || AMF || MAC = 48 + 16 + 64 = 128 bits
print "AUTN for SQN: $sqn AK: $ak AMF: $amf MAC: $mac\n";
my $i;
my @sqnc = split("", $sqn);
my @akc = split("", $ak);
if (@sqnc != 12) {
die("sqn must have 12 ascii bytes.");
}
if (@akc != 12) {
die("akc must have 12 ascii bytes.");
}
for ($i = 0; $i<12; $i++) {
my $v = hex($sqnc[$i]);
$v ^= hex($akc[$i]);
printf "%1x", $v;
}
print $amf;
print $mac;
print "\n";
## eof

View File

@@ -0,0 +1,36 @@
#!/bin/bash
# example based off https://www.endpoint.com/blog/2014/10/30/openssl-csr-with-alternative-names-one
hostname="$1"
hostname1=$hostname.local
ipaddr=
cat > tmp_csr_details.txt <<-EOF
[req]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn
[ dn ]
C=US
ST=Washington
L=Ferndale
O=Candela Technologies, Inc.
OU=LANforge
emailAddress=support@candelatech.com
CN = $hostname
[ req_ext ]
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = $hostname1
DNS.2 = $ipaddr
EOF
# Lets call openssl now by piping the newly created file in
openssl req -new -sha256 -nodes -out ${hostname}.csr -newkey rsa:2048\
-keyout ${hostname}.key -config <( cat temp_csr_details.txt )
#

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,509 @@
#!/usr/bin/env python3
import sys
if sys.version_info[0] != 3:
print("This script requires Python 3")
exit(1)
if 'py-json' not in sys.path:
sys.path.append('py-json')
import traceback
from LANforge import LFUtils
from LANforge.LFUtils import *
from LANforge.lfcli_base import LFCliBase
from generic_cx import GenericCx
mgrURL = "http://localhost:8080/"
staName = "sta0"
staNameUri = "port/1/1/" + staName
suppress_related = True
class ConnectTest(LFCliBase):
def __init__(self, lfhost, lfport):
super().__init__(lfhost, lfport, True)
super().check_connect()
# compare pre-test values to post-test values
@staticmethod
def CompareVals(_name, preVal, postVal):
print("Comparing %s" % _name)
if postVal > preVal:
print(" Test Passed")
else:
print(" Test Failed: %s did not increase after 5 seconds" % _name)
def run(self):
print("See home/lanforge/Documents/connectTestLogs/connectTestLatest for specific values on latest test")
eth1IP = super().json_get("/port/1/1/eth1")
if eth1IP['interface']['ip'] == "0.0.0.0":
print("Warning: Eth1 lacks ip address")
exit(1)
# Create stations and turn dhcp on
print("Creating station and turning on dhcp")
response = super().json_get("/" + staNameUri)
if response is not None:
if response["interface"] is not None:
print("removing old station")
removePort(1, staName, mgrURL)
waitUntilPortsDisappear(mgrURL, [staName])
time.sleep(1)
url = "cli-json/add_sta"
data = {
"shelf": 1,
"resource": 1,
"radio": "wiphy0",
"sta_name": staName,
"ssid": "jedway-wpa2-x2048-4-4",
"key": "jedway-wpa2-x2048-4-4",
"mode": 0,
"mac": "xx:xx:xx:xx:*:xx",
"flags": (0x400 + 0x20000 + 0x1000000000) # create admin down
}
super().json_post(url, data, suppress_related_commands_=suppress_related)
wait_until_ports_appear(mgrURL, [staName], True)
time.sleep(8)
reqURL = "cli-json/set_port"
data = {
"shelf": 1,
"resource": 1,
"port": staName,
"current_flags": (0x1 + 0x80000000),
"interest": (0x2 + 0x4000 + 0x800000) # current, dhcp, down,
}
super().json_post(reqURL, data, suppress_related_commands_=suppress_related)
time.sleep(0.5)
super().json_post("cli-json/set_port", portUpRequest(1, staName))
reqURL = "cli-json/nc_show_ports"
data = {"shelf": 1,
"resource": 1,
"port": staName,
"probe_flags": 1}
super().json_post(reqURL, data, suppress_related_commands_=suppress_related)
time.sleep(0.5)
waitUntilPortsAdminUp(1, mgrURL, [staName])
duration = 0
maxTime = 300
ip = "0.0.0.0"
while (ip == "0.0.0.0") and (duration < maxTime):
station_info = super().json_get("/" + staNameUri + "?fields=port,ip")
LFUtils.debug_printer.pprint(station_info)
if (station_info is not None) and ("interface" in station_info) and ("ip" in station_info["interface"]):
ip = station_info["interface"]["ip"]
if ip == "0.0.0.0":
duration += 4
time.sleep(4)
else:
break
if duration >= maxTime:
print(staName+" failed to get an ip. Ending test")
print("Cleaning up...")
removePort(1, staName, mgrURL)
sys.exit(1)
print("Creating endpoints and cross connects")
#==============| ENDPOINT CREATION |=================
# create l4 endpoint
url = "/cli-json/add_l4_endp"
data = {
"alias": "l4Test",
"shelf": 1,
"resource": 1,
"port": staName,
"type": "l4_generic",
"timeout": 1000,
"url_rate": 600,
"url": "dl http://localhost/ /dev/null",
"proxy_port" : "NA"
}
super().json_post(url, data, suppress_related_commands_=suppress_related)
data = {
"endpoint": "all"
}
super().json_post("/cli-json/nc_show_endpoints", data, suppress_related_commands_=suppress_related)
time.sleep(5)
# create fileio endpoint
url = "/cli-json/add_file_endp"
data = {
"alias": "fioTest",
"shelf": 1,
"resource": 1,
"port": staName,
"type": "fe_nfs",
"directory": "/mnt/fe-test"
}
super().json_post(url, data, suppress_related_commands_=suppress_related)
time.sleep(1)
data = {
"endpoint": "all"
}
super().json_post("/cli-json/nc_show_endpoints", data)
time.sleep(1)
# create generic endpoints
genl = GenericCx(lfclient_host=self.lfclient_host, lfclient_port=self.lfclient_port)
genl.createGenEndp("genTest1", 1, 1, staName, "gen_generic")
genl.createGenEndp("genTest2", 1, 1, staName, "gen_generic")
genl.setFlags("genTest1", "ClearPortOnStart", 1)
genl.setFlags("genTest2", "ClearPortOnStart", 1)
genl.setFlags("genTest2", "Unmanaged", 1)
genl.setCmd("genTest1", "lfping -i 0.1 -I %s 10.40.0.1" % staName)
time.sleep(.05)
data = {
"endpoint": "all"
}
super().json_post("/cli-json/nc_show_endpoints", data, suppress_related_commands_=suppress_related)
# create redirects for wanlink
url = "/cli-json/add_rdd"
data = {
"shelf": 1,
"resource": 1,
"port": "rdd0",
"peer_ifname": "rdd1"
}
super().json_post(url, data, suppress_related_commands_=suppress_related)
url = "/cli-json/add_rdd"
data = {
"shelf": 1,
"resource": 1,
"port": "rdd1",
"peer_ifname": "rdd0"
}
super().json_post(url, data, suppress_related_commands_=suppress_related)
time.sleep(.05)
# reset redirect ports
url = "/cli-json/reset_port"
data = {
"shelf": 1,
"resource": 1,
"port": "rdd0"
}
super().json_post(url, data, suppress_related_commands_=suppress_related)
url = "/cli-json/reset_port"
data = {
"shelf": 1,
"resource": 1,
"port": "rdd1"
}
super().json_post(url, data, suppress_related_commands_=suppress_related)
time.sleep(.05)
# create wanlink endpoints
url = "/cli-json/add_wl_endp"
data = {
"alias": "wlan0",
"shelf": 1,
"resource": 1,
"port": "rdd0",
"latency": 20,
"max_rate": 1544000
}
super().json_post(url, data, suppress_related_commands_=suppress_related)
url = "/cli-json/add_wl_endp"
data = {
"alias": "wlan1",
"shelf": 1,
"resource": 1,
"port": "rdd1",
"latency": 30,
"max_rate": 1544000
}
super().json_post(url, data, suppress_related_commands_=suppress_related)
time.sleep(.05)
data = {
"endpoint": "all"
}
super().json_post("/cli-json/nc_show_endpoints", data, suppress_related_commands_=suppress_related)
time.sleep(10)
#==============| CX CREATION |===================
# create cx for tcp and udp
cmd = ("./lf_firemod.pl --action create_cx --cx_name testTCP --use_ports %s,eth1 --use_speeds 360000,"
"150000 --endp_type tcp > ~/Documents/connectTestLogs/connectTestLatest.log" % staName)
execWrap(cmd)
cmd = ("./lf_firemod.pl --action create_cx --cx_name testUDP --use_ports %s,eth1 --use_speeds 360000,"
"150000 --endp_type udp >> ~/Documents/connectTestLogs/connectTestLatest.log" % staName)
execWrap(cmd)
time.sleep(.05)
# create cx for l4_endp
url = "/cli-json/add_cx"
data = {
"alias": "CX_l4Test",
"test_mgr": "default_tm",
"tx_endp": "l4Test",
"rx_endp": "NA"
}
super().json_post(url, data, suppress_related_commands_=suppress_related)
time.sleep(.05)
# create fileio cx
url = "/cli-json/add_cx"
data = {
"alias": "CX_fioTest",
"test_mgr": "default_tm",
"tx_endp": "fioTest",
"rx_endp": "NA"
}
super().json_post(url, data, suppress_related_commands_=suppress_related)
time.sleep(.05)
# create generic cx
url = "/cli-json/add_cx"
data = {
"alias": "CX_genTest1",
"test_mgr": "default_tm",
"tx_endp": "genTest1",
"rx_endp": "genTest2"
}
super().json_post(url, data, suppress_related_commands_=suppress_related)
time.sleep(.05)
# create wanlink cx
url = "/cli-json/add_cx"
data = {
"alias": "CX_wlan0",
"test_mgr": "default_tm",
"tx_endp": "wlan0",
"rx_endp": "wlan1"
}
super().json_post(url, data, suppress_related_commands_=suppress_related)
time.sleep(.5)
data = {
"endpoint": "all"
}
super().json_post("/cli-json/nc_show_endpoints", data, suppress_related_commands_=suppress_related)
cxNames = ["testTCP", "testUDP", "CX_l4Test", "CX_fioTest", "CX_genTest1", "CX_wlan0"]
# get data before running traffic
try:
get_info = {}
sleep(5)
get_info['testTCPA'] = super().json_get("/endp/testTCP-A?fields=tx+bytes,rx+bytes")
get_info['testTCPB'] = super().json_get("/endp/testTCP-B?fields=tx+bytes,rx+bytes")
get_info['testUDPA'] = super().json_get("/endp/testUDP-A?fields=tx+bytes,rx+bytes")
get_info['testUDPB'] = super().json_get("/endp/testUDP-B?fields=tx+bytes,rx+bytes")
get_info['l4Test'] = super().json_get("/layer4/l4Test?fields=bytes-rd")
get_info['genTest1'] = super().json_get("/generic/genTest1?fields=last+results")
get_info['wlan0'] = super().json_get("/wl_ep/wlan0")
get_info['wlan1'] = super().json_get("/wl_ep/wlan1")
for name in get_info:
#print("==================\n"+name+"\n====================")
if 'endpoint' not in get_info[name]:
print(get_info[name])
raise ValueError ("%s missing endpoint value" % name)
testTCPATX = get_info['testTCPA']['endpoint']['tx bytes']
testTCPARX = get_info['testTCPA']['endpoint']['rx bytes']
testTCPBTX = get_info['testTCPB']['endpoint']['tx bytes']
testTCPBRX = get_info['testTCPB']['endpoint']['rx bytes']
testUDPATX = get_info['testUDPA']['endpoint']['tx bytes']
testUDPARX = get_info['testUDPA']['endpoint']['rx bytes']
testUDPBTX = get_info['testUDPB']['endpoint']['tx bytes']
testUDPBRX = get_info['testUDPB']['endpoint']['rx bytes']
l4TestBR = get_info['l4Test']['endpoint']['bytes-rd']
genTest1LR = get_info['genTest1']['endpoint']['last results']
wlan0TXB = get_info['wlan0']['endpoint']['tx bytes']
wlan0RXP = get_info['wlan0']['endpoint']['rx pkts']
wlan1TXB = get_info['wlan1']['endpoint']['tx bytes']
wlan1RXP = get_info['wlan1']['endpoint']['rx pkts']
except Exception as e:
print("Something went wrong")
print(e)
print("Cleaning up...")
time.sleep(15)
LFUtils.removePort(1, staName, mgrURL)
endpNames = ["testTCP-A", "testTCP-B",
"testUDP-A", "testUDP-B",
"l4Test", "fioTest",
"genTest1", "genTest2",
"wlan0", "wlan1"]
removeCX(mgrURL, cxNames)
removeEndps(mgrURL, endpNames)
traceback.print_stack()
sys.exit(1)
# start cx traffic
print("\nStarting CX Traffic")
for name in range(len(cxNames)):
cmd = (
"./lf_firemod.pl --mgr localhost --quiet yes --action do_cmd --cmd \"set_cx_state default_tm %s RUNNING\" >> /tmp/connectTest.log" % (cxNames[name]))
execWrap(cmd)
# print("Sleeping for 5 seconds")
time.sleep(5)
# show tx and rx bytes for ports
os.system("echo eth1 >> ~/Documents/connectTestLogs/connectTestLatest.log")
cmd = (
"./lf_portmod.pl --quiet 1 --manager localhost --port_name eth1 --show_port \"Txb,Rxb\" >> ~/Documents/connectTestLogs/connectTestLatest.log")
execWrap(cmd)
os.system("echo %s >> ~/Documents/connectTestLogs/connectTestLatest.log" % staName)
cmd = (
"./lf_portmod.pl --quiet 1 --manager localhost --port_name %s --show_port \"Txb,Rxb\" >> ~/Documents/connectTestLogs/connectTestLatest.log" % staName)
execWrap(cmd)
# show tx and rx for endpoints PERL
os.system("echo TestTCP-A >> ~/Documents/connectTestLogs/connectTestLatest.log")
cmd = (
"./lf_firemod.pl --action show_endp --endp_name testTCP-A --endp_vals \"Tx Bytes,Rx Bytes\" >> ~/Documents/connectTestLogs/connectTestLatest.log")
execWrap(cmd)
os.system("echo TestTCP-B >> ~/Documents/connectTestLogs/connectTestLatest.log")
cmd = (
"./lf_firemod.pl --action show_endp --endp_name testTCP-B --endp_vals \"Tx Bytes,Rx Bytes\" >> ~/Documents/connectTestLogs/connectTestLatest.log")
execWrap(cmd)
os.system("echo TestUDP-A >> ~/Documents/connectTestLogs/connectTestLatest.log")
cmd = (
"./lf_firemod.pl --action show_endp --endp_name testUDP-A --endp_vals \"Tx Bytes,Rx Bytes\" >> ~/Documents/connectTestLogs/connectTestLatest.log")
execWrap(cmd)
os.system("echo TestUDP-B >> ~/Documents/connectTestLogs/connectTestLatest.log")
cmd = (
"./lf_firemod.pl --action show_endp --endp_name testUDP-B --endp_vals \"Tx Bytes,Rx Bytes\" >> ~/Documents/connectTestLogs/connectTestLatest.log")
execWrap(cmd)
os.system("echo l4Test >> ~/Documents/connectTestLogs/connectTestLatest.log")
cmd = (
"./lf_firemod.pl --action show_endp --endp_name l4Test --endp_vals Bytes-Read-Total >> ~/Documents/connectTestLogs/connectTestLatest.log")
execWrap(cmd)
os.system("echo fioTest >> ~/Documents/connectTestLogs/connectTestLatest.log")
cmd = (
"./lf_firemod.pl --action show_endp --endp_name fioTest --endp_vals \"Bytes Written,Bytes Read\" >> ~/Documents/connectTestLogs/connectTestLatest.log")
execWrap(cmd)
os.system("echo genTest1 >> ~/Documents/connectTestLogs/connectTestLatest.log")
cmd = (
"./lf_firemod.pl --action show_endp --endp_name genTest1 >> ~/Documents/connectTestLogs/connectTestLatest.log")
execWrap(cmd)
os.system("echo wlan0 >> ~/Documents/connectTestLogs/connectTestLatest.log")
cmd = (
"./lf_firemod.pl --action show_endp --endp_name wlan0 --endp_vals \"Rx Pkts,Tx Bytes,Cur-Backlog,Dump File,Tx3s\" >> ~/Documents/connectTestLogs/connectTestLatest.log")
execWrap(cmd)
os.system("echo wlan1 >> ~/Documents/connectTestLogs/connectTestLatest.log")
cmd = (
"./lf_firemod.pl --action show_endp --endp_name wlan1 --endp_vals \"Rx Pkts,Tx Bytes,Cur-Backlog,Dump File,Tx3s\" >> ~/Documents/connectTestLogs/connectTestLatest.log")
execWrap(cmd)
# stop cx traffic
print("Stopping CX Traffic")
for name in range(len(cxNames)):
cmd = (
"./lf_firemod.pl --mgr localhost --quiet yes --action do_cmd --cmd \"set_cx_state default_tm %s STOPPED\" >> /tmp/connectTest.log" % (cxNames[name]))
execWrap(cmd)
# print("Sleeping for 15 seconds")
time.sleep(15)
# get data for endpoints JSON
print("Collecting Data")
try:
ptestTCPA = super().json_get("endp/testTCP-A?fields=tx+bytes,rx+bytes")
ptestTCPATX = ptestTCPA['endpoint']['tx bytes']
ptestTCPARX = ptestTCPA['endpoint']['rx bytes']
ptestTCPB = super().json_get("/endp/testTCP-B?fields=tx+bytes,rx+bytes")
ptestTCPBTX = ptestTCPB['endpoint']['tx bytes']
ptestTCPBRX = ptestTCPB['endpoint']['rx bytes']
ptestUDPA = super().json_get("/endp/testUDP-A?fields=tx+bytes,rx+bytes")
ptestUDPATX = ptestUDPA['endpoint']['tx bytes']
ptestUDPARX = ptestUDPA['endpoint']['rx bytes']
ptestUDPB = super().json_get("/endp/testUDP-B?fields=tx+bytes,rx+bytes")
ptestUDPBTX = ptestUDPB['endpoint']['tx bytes']
ptestUDPBRX = ptestUDPB['endpoint']['rx bytes']
pl4Test = super().json_get("/layer4/l4Test?fields=bytes-rd")
pl4TestBR = pl4Test['endpoint']['bytes-rd']
pgenTest1 = super().json_get("/generic/genTest1?fields=last+results")
pgenTest1LR = pgenTest1['endpoint']['last results']
pwlan0 = super().json_get("/wl_ep/wlan0")
pwlan0TXB = pwlan0['endpoint']['tx bytes']
pwlan0RXP = pwlan0['endpoint']['rx pkts']
pwlan1 = super().json_get("/wl_ep/wlan1")
pwlan1TXB = pwlan1['endpoint']['tx bytes']
pwlan1RXP = pwlan1['endpoint']['rx pkts']
except Exception as e:
print("Something went wrong")
print(e)
print("Cleaning up...")
time.sleep(15)
reqURL = "/cli-json/rm_vlan"
data = {
"shelf": 1,
"resource": 1,
"port": staName
}
super().json_post(reqURL, data, suppress_related_commands_=suppress_related)
endpNames = ["testTCP-A", "testTCP-B",
"testUDP-A", "testUDP-B",
"l4Test", "fioTest",
"genTest1", "genTest2",
"wlan0", "wlan1"]
removeCX(mgrURL, cxNames)
removeEndps(mgrURL, endpNames)
sys.exit(1)
# print("Sleeping for 5 seconds")
time.sleep(5)
print("\n")
self.CompareVals("testTCP-A TX", testTCPATX, ptestTCPATX)
self.CompareVals("testTCP-A RX", testTCPARX, ptestTCPARX)
self.CompareVals("testTCP-B TX", testTCPBTX, ptestTCPBTX)
self.CompareVals("testTCP-B RX", testTCPBRX, ptestTCPBRX)
self.CompareVals("testUDP-A TX", testUDPATX, ptestUDPATX)
self.CompareVals("testUDP-A RX", testUDPARX, ptestUDPARX)
self.CompareVals("testUDP-B TX", testUDPBTX, ptestUDPBTX)
self.CompareVals("testUDP-B RX", testUDPBRX, ptestUDPBRX)
self.CompareVals("l4Test Bytes Read", l4TestBR, pl4TestBR)
self.CompareVals("genTest1 Last Results", genTest1LR, pgenTest1LR)
self.CompareVals("wlan0 TX Bytes", wlan0TXB, pwlan0TXB)
self.CompareVals("wlan0 RX Pkts", wlan0RXP, pwlan0RXP)
self.CompareVals("wlan1 TX Bytes", wlan1TXB, pwlan1TXB)
self.CompareVals("wlan1 RX Pkts", wlan1RXP, pwlan1RXP)
print("\n")
# remove all endpoints and cxs
print("Cleaning up...")
LFUtils.removePort(1, staName, mgrURL)
endpNames = ["testTCP-A", "testTCP-B",
"testUDP-A", "testUDP-B",
"l4Test", "fioTest",
"genTest1", "genTest2",
"wlan0", "wlan1"]
removeCX(mgrURL, cxNames)
removeEndps(mgrURL, endpNames)
# ~class
def main():
lfclient_host = "localhost"
lfclient_port = 8080
test = ConnectTest(lfclient_host, lfclient_port)
test.run()
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,19 @@
#!/bin/bash
ticker_time="$1"
orig_time="$1"
#echo ""
while [[ $ticker_time -gt 0 ]]; do
sleep 1
ticker_time=$(( $ticker_time - 1 ))
countd=$orig_time
printf "\r"
for n in `seq 0 $orig_time`; do
if [[ $n -lt $ticker_time ]]; then
echo -n '#'
else
echo -n '-'
fi
done
echo -n " $ticker_time/$orig_time"
done
echo ""

View File

@@ -0,0 +1,149 @@
#!/usr/bin/env python3
''' Author: Nikita Yadav
This script will calculate the cpu and memory utilization by the system during runtime the output of which is a graph on html page also the second tab of html gives the system logs
steps to run script:
1- On mate terminal type python3 (file_name) -t (your duration in minutes for how much time you want to run the script).
2- Example python3 cpu_stat.py -t 1
3- Wait for the time provided to calculate statistics.
4- After the script ends check for log.html file.
5- Log.html file file show results in tab format selected.
'''
import argparse
import os
import matplotlib.pyplot as plt
import datetime
import base64
import logging
import threading
import time
fh = ''
fh_1 = ''
def cpu_percent(cmd):
global fh
fh = os.popen(cmd)
def memory_percent(cmd):
global fh_1
fh_1 = os.popen(cmd)
def htmlimage(data_4, data):
html = open("log.html", 'w')
img = data_4 + " " + data
html.write(img)
def main():
global duration
parser = argparse.ArgumentParser()
parser.add_argument("-t", "--duration", type=int, help="Enter the Time for which you want to run test (in minutes)")
try:
args = parser.parse_args()
if (args.duration is not None):
duration = args.duration
except Exception as e:
logging.exception(e)
exit(2)
endTime = datetime.datetime.now() + datetime.timedelta(seconds=duration)
now = datetime.datetime.now()
starttime = datetime.datetime(now.year, now.month, now.day, now.hour, now.minute, now.second)
delta = datetime.timedelta(seconds=10)
cpu_stats_data = {"system": [], "kernel": []}
memory_stats_data = {"Total": [], "Used": []}
iterations = duration * 60
cmd_1 = "top -bn1 -d 1 -n " + str(iterations) + " | grep '%Cpu(s)' "
cmd_2 = "top -bn1 -d 1 -n " + str(iterations) + " | grep 'MiB Mem'"
t1 = threading.Thread(target=cpu_percent, args=(cmd_1,))
t2 = threading.Thread(target=memory_percent, args=(cmd_2,))
t1.start()
t2.start()
t1.join()
t2.join()
time.sleep(10)
output = fh.read() + fh.readline()
output_1 = fh_1.read() + fh_1.readline()
data = output.split('\n')
data_1 = output_1.split('\n')
for i in data:
# print(i.split(','))
if len(i) > 3:
cpu_stats_data["system"].append(float(i.split(',')[0].split()[1]))
cpu_stats_data["kernel"].append(float(i.split(',')[1].split()[0]))
# print(cpu_stats_data)
for i in data_1:
if len(i) > 3:
memory_stats_data["Total"].append(float(i.split(',')[0].split()[3]))
memory_stats_data["Used"].append(float(i.split(',')[2].split()[0]))
# print(memory_stats_data)
sample_times = [starttime + i * delta for i in range(len(cpu_stats_data["system"]))]
label_locations = [d for d in sample_times if d.minute % 1 == 0]
labels = [d.strftime('%Y-%m-%d %H:%M:%S') for d in label_locations]
# print(labels)
#print(sample_times)
# thread creation
# graphs
#plot1
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.plot(sample_times, cpu_stats_data['system'], '-', lw=1, color='r', label="system cpu%")
ax.plot(sample_times, cpu_stats_data['kernel'], '-', lw=1, color='b', label="kernel cpu%")
ax.set_ylabel('CPU (%)', color='r')
ax.set_xlabel('time (s)')
plt.tight_layout()
ax.set_ylim(0., max(cpu_stats_data['system']) + 20)
plt.xticks(rotation='vertical')
fig.legend(["System CPU Utilization", "Kernel CPU Utilization"], loc='upper center')
ax.grid()
fig.savefig("cpu.png")
#plot2
fig_1 = plt.figure()
ax_1 = fig_1.add_subplot(1, 1, 1)
ax_1.plot(sample_times, memory_stats_data["Total"], '-', lw=1, color='r', label="Total MEMORY AVAILABLE")
ax_1.plot(sample_times, memory_stats_data["Used"], '-', lw=1, color='b', label="Total MEMORY USED")
ax_1.set_ylabel('Total available', color='r')
ax_1.set_xlabel('time (s)')
plt.tight_layout()
ax_1.set_ylim(0., max(memory_stats_data["Total"]) + 2000)
plt.xticks(rotation='vertical')
fig_1.legend(["TOTAL MEMORY AVAILABLE", "TOTAL MEMORY USED"], loc='upper center')
ax_1.grid()
fig_1.savefig("MEMORY.png")
cmd_1 = "timeout 2s journalctl -p err --since '24 hour ago' > syslog.txt"
fh_2 = os.system(cmd_1)
fi_open = open("syslog.txt", "r+")
out = fi_open.read()
data_3 = out.split(" ")
data_uri = base64.b64encode(open('cpu.png', 'rb').read()).decode('utf-8')
data_uri_1 = base64.b64encode(open('MEMORY.png', 'rb').read()).decode('utf-8')
data_a = '<img title="CPU utilization" src="data:image/png;base64,{0}">'.format(
data_uri) + " " + '<img title="CPU utilization" src="data:image/png;base64,{0}">'.format(data_uri_1)
data_4 = "<!DOCTYPE html><html><head> <meta name='viewport' content='width=device-width, initial-scale=1''><style>.accordion {background-color: #eee;color: #444;cursor: pointer;padding: 18px;width: 50%; border: none;text-align: left;outline: none;font-size: 15px;transition: 0.4s;}.active, .accordion:hover {background-color: #ccc; }.panel {padding: 0 18px;display: none;background-color: white;overflow: hidden;}</style></head><body> <button class='accordion''>CPU UTILIZATION</button> <div class='panel'> <p>" + data_a + "</p></div><script>acc = document.getElementsByClassName('accordion');var i;for (i = 0; i < acc.length; i++) {acc[i].addEventListener('click', function() {this.classList.toggle('active');var panel = this.nextElementSibling;if (panel.style.display === 'ock') {panel.style.display = 'none;} else {panel.style.display = 'block';}});}</script></body></html>"
logs = " "
for i in data_3:
logs = logs + i
data = "<head> <meta name='viewport' content='width=device-width, initial-scale=1'> <style>.accordion { background-color: #eee; color: #444; cursor: pointer;padding: 18px; width: 50%; border: none;text-align: left;outline: none;font-size: 10px;transition: 0.4s;} .active, .accordion:hover { background-color: #ccc;} .panel { padding: 0 18px; display: none; background-color: white; overflow: hidden;} </style> </head> <button class='accordion'>SYSTEM LOGS</button> <div class='panel'> <font face = 'Courier New' size = '2' color='#ff0000'>" + logs + "</font><br /> </div> <script> var acc = document.getElementsByClassName('accordion'); var i; for (i = 0; i < acc.length; i++) {acc[i].addEventListener('click', function() { this.classList.toggle('active');var panel = this.nextElementSibling;if (panel.style.display === 'block') {panel.style.display = 'none';} else {panel.style.display = 'block';}});} </script> "
htmlimage(data_4, data)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,101 @@
#!/bin/bash
#set -x
CIFS_USERNAME="lanforge"
CIFS_PASSWORD="lanforge"
NFS_SRV="192.168.100.3"
NFS_PATH="/mnt/d2"
CIFS_SRV="192.168.100.3"
CIF_PATH="/mnt/d2"
LOCAL_MOUNT_PATH="/mnt"
NFS_OPTS=""
if [ $# -lt 4 ]; then
echo "Usage: `basename $0` NFS|CIFS <ethN> <first_mvlan> <last_mvlan> <server server-path local-mnt-path>"
exit 1
fi
IF=$2
MV_START=$3
MV_STOP=$4
if [ ! -z "$5" ]
then
NFS_SRV=$5
CIFS_SRV=$5
fi
if [ ! -z "$6" ]
then
NFS_PATH=$6
CIFS_PATH=$6
fi
if [ ! -z "$7" ]
then
LOCAL_MOUNT_PATH=$7
fi
if [ $1 = "CIFS" ]; then
LOCAL_PATH="$LOCAL_MOUNT_PATH/cifs_${IF}#"
CIFS_OPTS="username=$CIFS_USERNAME,password=$CIFS_PASSWORD,$CIFS_OPTS"
else
LOCAL_PATH="$LOCAL_MOUNT_PATH/nfs_${IF}#"
fi
LIP=clientaddr
if uname -a | grep 2.6.20
then
LIP=local_ip
fi
for ((m=MV_START; m <= MV_STOP ; m++))
do
if [ `ifconfig $IF#$m > /dev/null 2>&1; echo $?` -eq "1" ]; then
echo "*** MISSING INTERFACE: $IF#$m"
echo
elif [ `ifconfig $IF#$m | grep "inet addr" > /dev/null; echo $?` -eq "1" ]; then
echo "*** MISSING IP ADDRESS ON INTERFACE: $IF#$m"
else
if [ ! -d "$LOCAL_PATH$m" ]; then
echo "mkdir -p $LOCAL_PATH$m"
mkdir -p $LOCAL_PATH$m
fi
IPADDR=`ifconfig $IF#$m | grep "inet addr" | awk -F":" '{ print $2}' |\
awk '{ print $1}'`
# Ping seems to fail sometimes..probably file-server is under too much load or something
# so try the ping up to 5 times.
for ((q=0;q<5;q+=1))
do
if [ `ping -c 1 -w 1 -I $IPADDR $NFS_SRV > /dev/null; echo $?` -eq "0" ]; then
q=10; # done
if [ $1 = "CIFS" ]; then
echo "mount -t cifs -o local_ip=$IPADDR,$CIFS_OPTS //$CIFS_SRV$CIFS_PATH $LOCAL_PATH$m"
if [ `mount -t cifs -o local_ip=$IPADDR,$CIFS_OPTS //$CIFS_SRV$CIFS_PATH $LOCAL_PATH$m >\
/dev/null; echo $?` -ne "0" ]; then
echo
fi
else
echo "mount -t nfs -o $LIP=$IPADDR,$NFS_OPTS $NFS_SRV:$NFS_PATH $LOCAL_PATH$m"
if [ `mount -t nfs -o $LIP=$IPADDR,$NFS_OPTS $NFS_SRV:$NFS_PATH $LOCAL_PATH$m >\
/dev/null; echo $?` -ne "0" ]; then
echo
fi
fi
else
echo "*** UNABLE TO PING: $NFS_SRV FROM: $IF#$m, $IPADDR"
fi
done
fi
done
echo "********************************************"
if [ $1 = "CIFS" ]; then
echo "Total number of mounts according to 'mount': `mount | grep "$CIFS_SRV$CIFS_PATH" |\
grep "$LOCAL_PATH" | grep "type cifs" |\
wc | awk '{ print $1 }'`"
else
echo "Total number of NFS mounts according to 'mount': `mount | grep "$NFS_SRV:$NFS_PATH" |\
grep "$LOCAL_PATH" | grep -i "type $1" | grep "$LIP=" | grep "addr=$NFS_SRV" |\
wc | awk '{ print $1 }'`"
echo
fi

View File

@@ -0,0 +1,25 @@
#!/bin/bash
[ -z "$1" ] && echo "Please tell me where to place the files." && exit 1
[ ! -d "$1" ] && echo "I cannot see that directory." && exit 1
[ ! -w "$1" ] && echo "I cannot write to that directory." && exit 1
sizes=( 4K 48K 128K 256K 2048K )
name_prefix="data_slug"
index="$1/slug_list.html"
cat > $index <<EOF
<html><head>
<title>Files of random data</title>
</head>
<body>
<h1>Files of random data</h1>
<ul>
EOF
for s in "${sizes[@]}"; do
fname="${name_prefix}_${s}.bin"
echo "<li><a href='$fname'>$fname</a></li>" >> $index
dd if=/dev/urandom of="$1/$fname" iflag=fullblock oflag=direct bs=${s} count=1
done
echo "</ul></html>" >> $index
ls -lSs $1/$name_prefix*
#

View File

@@ -0,0 +1,67 @@
#!/bin/bash
usage="$0 <manager> <group-name> <endp-name-prefix>"
if [[ x$1 = x ]]; then
echo "Please provide lanforge manager hostname or ip"
echo $usage
exit 1
fi
if [[ x$2 = x ]]; then
echo "Please provide a group name"
echo $usage
exit 1
fi
if [[ x$3 = x ]]; then
echo "Please provide an endpoint name prefix"
echo $usage
exit 1
fi
# query for endpoints maching prefix
if [ -f /tmp/endp.$$ ]; then
rm -f /tmp/endp.$$
fi
./lf_firemod.pl --mgr $1 --quiet yes --action list_endp > /tmp/endp.$$
lines=`wc -l < /tmp/endp.$$`
if [ $lines -lt 1 ]; then
echo "Unable to see any endpoints"
exit 1
fi
declare -A names
while read line; do
hunks=($line)
endp="${hunks[1]}"
endp=${endp/]/}
endp=${endp/[/}
if [[ $endp = D_* ]]; then
continue
fi
# if name lacks a -A/B ending, it is prolly generic and the cx begins with CX_
if [[ $endp = *-A ]] || [[ $endp = *-B ]]; then
cxname=${endp%-A}
cxname=${cxname%-B}
else
cxname="CX_${endp}"
fi
if [[ $cxname = $3* ]] || [[ $cxname = CX_$3* ]]; then
names[$cxname]=1
fi
done < /tmp/endp.$$
if [ ${#names[@]} -lt 1 ]; then
echo "No connections start with $3"
exit 1
fi
echo "Creating group $2"
./lf_firemod.pl --mgr $1 --quiet 1 --cmd "add_group '$2'"
for n in ${!names[@]}; do
echo "adding connection $n to '$2'"
./lf_firemod.pl --mgr $1 --quiet 1 --cmd "add_tgcx '$2' '$n'"
done

View File

@@ -0,0 +1,28 @@
#!/bin/bash
#This script modifies DB directories so they appear alphabetically in LANforge.
# Script instructions
# First become root: su -
# Copy the script to /home/lanforge/scripts/
# cp db_sorter.sh /home/lanforge/scripts/
# Make the script executable:
# chmod +x /home/lanforge/scripts/db_sorter.sh
# Run script:
# /home/lanforge/scripts/db_sorter.sh
# If your databases are not in /home/lanforge/DB/ change the below line to reflect your DB directory's location.
db_dir="/home/lanforge/DB/"
# grab alphabetical list then use awk to just get dir name
# to sort reverse alphabetical order change ls -lr below to ls -l
dir_list=`ls -lr $db_dir | awk ' ''{print $9}' | grep -v "day_*"`
# goes through list, creates/removes file to trigger dir modified date
while read -r line; do
if [[ $line != "" ]] && [[ -d ${db_dir}/${line} ]] && [[ $line != "day_*" ]]; then
touch "${db_dir}/${line}/a"
rm "${db_dir}/${line}/a"
fi
#needs sleep otherwise file mod date does not order correctly
sleep .01s
done <<< "$dir_list"

View File

@@ -0,0 +1,221 @@
#!/usr/bin/perl
#
# Shows current leases.
#
# THIS SCRIPT IS PUBLIC DOMAIN, NO RIGHTS RESERVED!
#
# I've removed the email addresses of Christian and vom to avoid
# putting them on spam lists. If either of you would like to have
# your email in here please send mail to the DHCP bugs list at ISC.
#
# 2008-07-13, Christian Hammers
#
# 2009-06-?? - added loading progress counter, pulls hostname, adjusted formatting
# vom
#
# 2013-04-22 - added option to choose lease file, made manufacture information
# optional, sar
#
# 2016-01-19 - updated to better trim the manu string and output the hostnames, sar
#
# 2016-01-18 - Mainly cosmetics. Eliminated spurious output in "parsable" mode.
# Provided for the various conventional lease file locations. (cbp)
use strict;
use warnings;
use POSIX qw(strftime);
my @LEASES = ('/var/db/dhcpd.leases', '/var/lib/dhcp/dhcpd.leases', '/var/lib/dhcp3/dhcpd.leases');
my @all_leases;
my @leases;
my @OUIS = ('/usr/share/hwdata/oui.txt', '/usr/share/misc/oui.txt', '/usr/local/etc/oui.txt');
my $OUI_URL = 'http://standards.ieee.org/regauth/oui/oui.txt';
my $oui;
my %data;
my $opt_format = 'human';
my $opt_keep = 'active';
our $total_leases = 0;
## Return manufactorer name for specified MAC address (aa:bb:cc:dd:ee:ff).
sub get_manufactorer_for_mac($) {
my $manu = "-NA-";
if (defined $oui) {
$manu = join('-', ($_[0] =~ /^(..):(..):(..):/));
$manu = `grep -i '$manu' $oui | cut -f3`;
$manu =~ s/^\s+|\s+$//g;
}
return $manu;
}
## Read oui.txt or print warning.
sub check_oui_file() {
for my $oui_cand (@OUIS) {
if ( -r $oui_cand) {
$oui = $oui_cand;
last;
}
}
if (not defined $oui) {
print(STDERR "To get manufacturer names please download $OUI_URL ");
print(STDERR "to /usr/local/etc/oui.txt\n");
}
}
## Read current leases file into array.
sub read_dhcpd_leases() {
my $db;
for my $db_cand (@LEASES) {
if ( -r $db_cand) {
$db = $db_cand;
last;
}
}
die("Cannot find leases db") unless defined $db;
open(F, $db) or die("Cannot open $db: $!");
print("Reading leases from $db\n") if $opt_format eq 'human';
my $content = join('', <F>);
close(F);
@all_leases = split(/lease/, $content);
foreach my $lease (@all_leases) {
if ($lease =~ /^\s+([\.\d]+)\s+{.*starts \d+ ([\/\d\ \:]+);.*ends \d+ ([\/\d\ \:]+);.*ethernet ([a-f0-9:]+);/s) {
++$total_leases;
}
}
}
## Add manufactor name and sort out obsolet assignements.
sub process_leases() {
my $gm_now = strftime("%Y/%m/%d %H:%M:%S", gmtime());
my %tmp_leases; # for sorting and filtering
my $counter = $opt_format eq 'human' ? 1 : 0;
# parse entries
foreach my $lease (@all_leases) {
# skip invalid lines
next if not ($lease =~ /^\s+([\.\d]+)\s+{.*starts \d+ ([\/\d\ \:]+);.*ends \d+ ([\/\d\ \:]+);.*ethernet ([a-f0-9:]+);(.*client-hostname \"(\S+)\";)*/s);
# skip outdated lines
next if ($opt_keep eq 'active' and $3 lt $gm_now);
# I like 'human' output, but this part is not helpful when parsing that human output by another script. --Ben
#if ($counter) {
# my $percent = (($counter / $total_leases)*100);
# printf "Processing: %2d%% complete\r", $percent;
# ++$counter;
#}
my $hostname = "-NA-";
if ($6) {
$hostname = $6;
}
my $mac = $4;
my $date_end = $3;
my %entry = (
'ip' => $1,
'date_begin' => $2,
'date_end' => $date_end,
'mac' => $mac,
'hostname' => $hostname,
# Too slow. --Ben 'manu' => get_manufactorer_for_mac($mac),
'manu' => "",
);
$entry{'date_begin'} =~ s#\/#-#g; # long live ISO 8601
$entry{'date_end'} =~ s#\/#-#g;
if ($opt_keep eq 'all') {
push(@leases, \%entry);
} elsif (not defined $tmp_leases{$mac} or $tmp_leases{$mac}{'date_end'} gt $date_end) {
$tmp_leases{$mac} = \%entry;
}
}
# In case we used the hash to filtered
if (%tmp_leases) {
foreach (sort keys %tmp_leases) {
my $h = $tmp_leases{$_};
push(@leases, $h);
}
}
# print "\n";
}
# Output all valid leases.
sub output_leases() {
if ($opt_format eq 'human') {
printf "%-19s%-16s%-15s%-20s%-20s\n","MAC","IP","hostname","valid until","manufacturer";
print("===============================================================================================\n");
}
foreach (@leases) {
if ($opt_format eq 'human') {
printf("%-19s%-16s%-14.14s %-20s%-20s\n",
$_->{'mac'}, # MAC
$_->{'ip'}, # IP address
$_->{'hostname'}, # hostname
$_->{'date_end'}, # Date
$_->{'manu'}); # manufactor name
} else {
printf("MAC %s IP %s HOSTNAME %s BEGIN %s END %s MANUFACTURER %s\n",
$_->{'mac'},
$_->{'ip'},
$_->{'hostname'},
$_->{'date_begin'},
$_->{'date_end'},
$_->{'manu'});
}
}
}
# Commandline Processing.
sub cli_processing() {
while (my $arg = shift(@ARGV)) {
if ($arg eq '--help') {
print(
"Prints active DHCP leases.\n\n".
"Usage: $0 [options]\n".
" --help shows this help\n".
" --parsable machine readable output with full dates\n".
" --last prints the last (even if end<now) entry for every MAC\n".
" --all prints all entries i.e. more than one per MAC\n".
" --lease uses the next argument as the name of the lease file\n".
" the default is to try /var/db/dhcpd.leases then\n".
" /var/lib/dhcp/dhcpd.leases then\n".
" /var/lib/dhcp3/dhcpd.leases\n".
"\n");
exit(0);
} elsif ($arg eq '--parsable') {
$opt_format = 'parsable';
} elsif ($arg eq '--last') {
$opt_keep = 'last';
} elsif ($arg eq '--all') {
$opt_keep = 'all';
} elsif ($arg eq '--lease') {
unshift @LEASES, shift(@ARGV);
} else {
die("Unknown option $arg");
}
}
}
#
# main()
#
cli_processing();
#check_oui_file();
read_dhcpd_leases();
process_leases();
output_leases();

View File

@@ -0,0 +1,37 @@
#!/usr/bin/env python3
import smtplib
from email.message import EmailMessage
import sys
def writeEmail(emailBody):
msg = EmailMessage()
msg.set_content(emailBody)
return msg
def sendEmail(email, sender, recipient, subject, smtpServer='localhost'):
email['Subject'] = subject
email['From'] = sender
email['To'] = recipient
try:
s = smtplib.SMTP(smtpServer)
s.send_message(email)
s.quit()
return True
except Exception as e:
print("Send Failed, {}".format(e))
sys.exit(2)
#body = "Hello This Is A Test"
#subject = "Test Email"
#recipient = "logan.lipke@candelatech.com"
#sender = "lanforge@candelatech.com"
#email = writeEmail(body)
#sendEmail(email, sender, recipient, subject)

View File

@@ -0,0 +1,27 @@
#!/bin/bash
[[ $# < 2 ]] && {
echo "Usage: $0 'a command' eth1 eth2 sta2 st3"
echo "Runs 'a command' in a vrf environment for all following stations"
exit 1
}
[[ -f lib_vrf.bash ]] || {
echo "missing lib_vrf.bash, cannot continue"
exit 1
}
. lib_vrf.bash
execthis="$1"
shift
for eth in "$@"; do
[[ $execthis = $eth ]] && continue
vrf=${IFNAMES[$eth]}
if [[ x$vrf = x ]] || [[ $vrf = unknown ]]; then
echo "Skipping interface $eth"
continue
fi
echo "[$execthis] $vrf"
ip vrf exec $vrf $execthis &
done

View File

@@ -0,0 +1,68 @@
#!/usr/bin/perl -w
use strict;
use warnings;
use diagnostics;
$|=1;
package main;
our $fan_util = "/usr/local/bin/f81866_fan";
if ( ! -x $fan_util ) {
die "f81866_fan utility $fan_util not found\n";
}
my @sensor_lines_a = `sensors`;
chomp(@sensor_lines_a);
my @sensor_lines_b = grep ! /^\s*$/, @sensor_lines_a;
@sensor_lines_a = grep ! /^(Physical id|Core|coretemp|Adapter: ISA adapter)/, @sensor_lines_b;
#print ("Found: ".join("\n", @sensor_lines_a));
my $found_a10k = 0;
my $temp = 0;
my $maxtemp = 0;
for my $line (@sensor_lines_a) {
if ($line =~ /^ath10k_hwmon-pci.*/) {
#print "found a10k! $line\n";
$found_a10k = 1;
}
if ($found_a10k && $line =~ /temp1:\s+([^ ]+).*$/) {
#print "found a10k: $line\n";
if ($1 ne "N/A") {
($temp) = $line =~ /[+](\d+\.\d+)/;
if (defined $temp && $temp > 40.0) {
$maxtemp = $temp if ($temp > $maxtemp);
#print "temp($temp) maxtemp($maxtemp)\n";
}
$temp = 0;
}
$found_a10k = 0;
}
}
my $duty = 0;
if ($maxtemp < 40) {
$duty = 0;
}
elsif ($maxtemp < 50) {
$duty = 50;
}
elsif ($maxtemp < 56) {
$duty = 55;
}
elsif ($maxtemp < 60) {
$duty = 60;
}
elsif ($maxtemp < 70) {
$duty = 70;
}
elsif ($maxtemp < 80) {
$duty = 80;
}
elsif ($maxtemp >= 80) {
$duty = 100;
}
#print "[$maxtemp]C -> duty[$duty]\n";
system("/usr/bin/logger -t fanctl_lf0312 'temp:$maxtemp C, duty:$duty'");
exec("$fan_util $duty");
#

View File

@@ -0,0 +1,92 @@
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
use Carp;
#$SIG{ __DIE__ } = sub { Carp::confess( @_ ) };
#$SIG{ __WARN__ } = sub { Carp::confess( @_ ) };
use POSIX qw(ceil floor);
use Scalar::Util; #::looks_like_number;
use Getopt::Long;
use Socket;
use Cwd qw(getcwd);
my $cwd = getcwd();
package main;
# Un-buffer output
$| = 1;
# use lib prepends to @INC, so put lower priority first
# This is before run-time, so cannot condition this with normal 'if' logic.
use lib '/home/lanforge/scripts';
use lib "./";
use List::Util qw(first);
use LANforge::Endpoint;
use LANforge::Utils;
use Net::Telnet ();
my $lfmgr_host = "jedway3";
my $lfmgr_port = 4001;
our $t = new Net::Telnet(Prompt => '/default\@btbits\>\>/',
Timeout => 20);
$t->open(Host => $lfmgr_host,
Port => $lfmgr_port,
Timeout => 10);
$t->waitfor("/btbits\>\>/");
# Configure our utils.
our $utils = new LANforge::Utils();
$utils->telnet($t); # Set our telnet object.
our $quiet = 1;
if ($utils->isQuiet()) {
if (defined $ENV{'LOG_CLI'} && $ENV{'LOG_CLI'} ne "") {
$utils->cli_send_silent(0);
}
else {
$utils->cli_send_silent(1); # Do not show input to telnet
}
$utils->cli_rcv_silent(1); # Repress output from telnet
}
else {
$utils->cli_send_silent(0); # Show input to telnet
$utils->cli_rcv_silent(0); # Show output from telnet
}
$utils->log_cli("# $0 ".`date "+%Y-%m-%d %H:%M:%S"`);
my $num_connects = 4000;
my $num_vlans = 1000;
my @connections = ();
my $index = 0;
my $portnum = 0;
my $n = 0;
for (my $c = 1; $c <= $num_connects; $c++) {
$n = (10 * $num_connects) + $c;
push(@::connections, "con".substr("$n", 1));
}
my @cmds = ();
foreach my $con_name (@::connections) {
@cmds = (
"add_endp ${con_name}-A 1 1 rd0a#$portnum lf_tcp -1 NO 2400 2400 NO 300 300 increasing",
"set_endp_report_timer ${con_name}-A 15000",
"set_endp_details ${con_name}-A 8912 8912",
"add_endp ${con_name}-B 1 1 rd1b lf_tcp -1 NO 2400 2400 NO 300 300 increasing",
"set_endp_report_timer ${con_name}-B 15000",
"set_endp_details ${con_name}-B 8912 8912",
"add_cx ${con_name} default_tm ${con_name}-A ${con_name}-B",
"set_cx_report_timer default_tm ${con_name} 15000 cxonly",
);
foreach my $cmd (@cmds) {
$utils->doCmd($cmd);
print ".";
#sleep 1;
}
print "0";
}
#

View File

@@ -0,0 +1,31 @@
#!/bin/bash
export PATH=".:$PATH"
FM="./lf_firemod.pl"
mgr=idtest
rsrc=3
max=1000
numvlan=199
connections=()
for c in `seq 1 $max`; do
n=$(( (10 * $max) + $c ))
connections[$c]="con${n:1:${#max}}"
done
index=0
portnum=0
for c in "${connections[@]}"; do
echo -n .
$FM --mgr $mgr --resource $rsrc --action create_endp --endp_name ${c}-A --speed 25000 --endp_type lf_tcp --port_name "eth1#$portnum"
$FM --mgr $mgr --resource $rsrc --action create_endp --endp_name ${c}-B --speed 25000 --endp_type lf_tcp --port_name "eth2"
$FM --mgr $mgr --resource $rsrc --action create_cx --cx_name ${c} --cx_endps ${c}-A,${c}-B --report_timer 8000
echo -n o
index=$((index + 1))
portnum=$((index % $numvlan))
done
echo " done"
#

View File

@@ -0,0 +1,105 @@
#!/usr/bin/perl -w
## ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
##
## Use this script to collect and upload station data
## to an FTP host.
##
## ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
use strict;
use warnings;
use Carp;
use Getopt::Long;
use Socket;
use Cwd;
use Net::FTP;
$SIG{ __DIE__ } = sub { Carp::confess( @_ ) };
$| = 1;
## ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
our $def_user = 'anonymous';
our $def_pass = 'anonymous';
our $def_srcdir = Cwd::getcwd();
our $def_destdir = '/WIN7_LanForge_Data/';
our $def_ftphost = "192.168.1.222";
our @file_list = ();
our $verbose = 0;
our $debug = 0;
our $username = $def_user;
our $password = $def_pass;
our $ftp_host = $def_ftphost;
our $srcdir = $def_srcdir;
our $destdir = $def_destdir;
## ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
our $usage = "\n$0:
--user username [$def_user]
--passwd password [$def_pass]
--srcdir sourcedir [$def_srcdir]
--host host [$def_ftphost]
--destdir destdir [$def_destdir]
--verbose=1 [$verbose]
--debug=1 [$debug]
-- file1 file2 ... fileN # use -- to start a list of files or globs on cmdline
";
GetOptions (
'user|u=s' => \$::username,
'passwd|p=s' => \$::password,
'host|h=s' => \$::ftp_host,
'srcdir|s=s' => \$::srcdir,
'destdir|t=s' => \$::destdir,
'verbose|v=n' => \$::verbose,
'debug|d=n' => \$::debug
) || die($usage);
die "Cannot open $srcdir " if ( ! -e $srcdir );
if (@ARGV > 0) {
# we were passed -- file1 file2 ... fileN on commandline
print "Checking files listed on command line...\n" if ($verbose);
for my $filename (@ARGV) {
if ($filename =~ /(\*|\?|\{\n)/) {
my @expanded = glob("$srcdir/$filename");
for my $filename2 (@expanded) {
if ( -e $filename2 ) {
push(@file_list, $filename2);
}
else {
print STDERR "File $filename2 not found\n";
}
}
}
else {
if ( -e "$srcdir/$filename" ) {
push(@file_list, "$srcdir/$filename");
}
else {
print STDERR "File $srcdir/$filename not found\n";
}
}
}
}
else {
# we were just given a directory
print "Looking for 'sta*.csv' files in $srcdir...\n" if ($verbose);
@file_list = glob("$srcdir/sta*.csv");
}
die "No CSV files present in $srcdir" if (@file_list < 1);
my $ftp_server = Net::FTP->new($ftp_host,
Debug=>$debug,
Timeout=>15,
Port=>21,
Passive=>0)
or die "Can't open $ftp_host\n";
$ftp_server->login($username, $password) or die "Can't log $username in\n";
$ftp_server->cwd($destdir) or die "Unable to cd to $destdir\n";
for my $filename (@file_list) {
print "uploading $filename\n" if ($verbose);
$ftp_server->put($filename) or die "Unable to upload $filename\n";
}
##
## eof
##

View File

@@ -0,0 +1,55 @@
#!/bin/bash
# Ideally we want to get close to 600 stations
# but we'll want to see how big a batch we can create
#wiphy0 stations sta0000-0199
#wiphy1 stations sta0200-0399
#wiphy2 stations sta0400-0462
#wiphy3 stations sta0463-0526
M=ct524-genia.jbr.candelatech.com
SSID=(jedway-wpa2-x2048-5-1 jedway-wpa2-x2048-5-1)
#declare -A batches=(
# [wiphy0]=000,200
# [wiphy1]=200,200
# [wiphy2]=400,63
# [wiphy3]=463,63
#)
declare -A batches=(
[wiphy0]=000,4
[wiphy1]=004,4
[wiphy2]=008,4
[wiphy3]=012,4
)
function create_batch() {
local radio=$1
local start=$2
local num=$3
[[ x$radio = x ]] && echo "create_batch wants (radio, first, number_sta)" && exit 1
[[ x$start = x ]] && echo "create_batch wants (radio, first, number_sta)" && exit 2
[[ x$num = x ]] && echo "create_batch wants (radio, first, number_sta)" && exit 3
#echo "radio[$radio] start[$start] num[$num]"
set -x
./lf_associate_ap.pl --mgr $M --radio $radio --action add \
--first_sta "sta${start}" --num_sta ${num} \
--first_ip DHCP --ssid "${SSID[0]}" \
--security wpa2 --passphrase "${SSID[1]}" \
--admin_down_on_add || exit 1
set +x
}
sorted=$(for radio in "${!batches[@]}"; do
echo $radio
done | sort)
set -e
for radio in $sorted; do
value="${batches[$radio]}"
hunks=( ${value//,/ } )
create_batch $radio ${hunks[0]} ${hunks[1]}
sleep 1
done

View File

@@ -0,0 +1,96 @@
#!/bin/bash
files=(
gr-osmosdr
hackrf
PyQt4
PyQwt
SDL
SoapySDR
airspyone_host
boost-program-options
boost-serialization
codec2
comedilib
dbusmenu-qt
fftw-libs-single
flex
freeglut
gnuradio
gr-fcdproplus
gr-iqbal
gsl
hidapi
jack-audio-connection-kit
kde-filesystem
libffado
libgfortran
libmng
libosmo-dsp
libquadmath
libsodium
libxml++
log4cpp
log4cpp-devel
openblas
openblas-serial
openblas-threads
openpgm
phonon
portaudio
python-rpm-macros
python2-cheetah
python2-devel
python2-nose
python2-numpy
python2-numpy-f2py
python2-pyopengl
python2-pyqt4-sip
python2-rpm-macros
python2-scipy
python2-sip
python2-tkinter
python2-wxpython
python3-rpm-generators
qt
qt-common
qt-x11
qwt
qwt5-qt4
rtl-sdr
tix
tk
uhd
wxGTK3-gl
wxGTK3-media
zeromq
phonon-backend-gstreamer
sni-qt
)
#G=/var/tmp/deps_list.txt
#echo "" > $G
urls_file="urls_file.txt"
echo "" > $urls_file
while read L; do
[[ x$L = x ]] && continue
o=${L:0:1}
o=${o,,}
# where would be a logical place to see if the package has already been installed , use rpm -qa "$L"
echo "https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/${o}/${L}.rpm"
done < deps_list.uniq.txt > $urls_file
exit
# ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
function f() {
for f in "${files[@]}"; do
dnf repoquery --deplist --queryformat '%{name}.%{%arch}' "$f" \
| grep 'provider:' \
| sort | uniq \
| grep -v '\.i686' \
>> $G
echo -n "."
done
}

View File

@@ -0,0 +1,62 @@
#!/bin/bash
[ ! -f urls_file.txt ] && echo "Where is urls_list.txt?" && exit 1
DLD=/home/lanforge/Downloads
installed_list=()
already_downloaded_list=()
not_found_list=()
candidate_list=()
while read L; do
# echo "$L"
bzname=`basename $L`
short=${bzname%.fc30*}
if [[ x$short = x ]]; then
echo "bad substitution on $L"
continue
fi
echo -n "Looking for $short"
rez=`rpm -qa ${short}*`
# echo "result $?"
if [[ x$rez = x ]]; then
echo -n "$bzname is not installed"
if compgen -G "${DLD}/${bzname}"; then
echo " already downloaded"
already_downloaded_list+=($bzname);
else
wget -q -O "${DLD}/${bzname}" "$L"
if (( $? != 0 )); then
letterurl="${L%/*}/"
needle="${short:0:13}"
echo -n " need to look for ${letterurl}${needle} ..."
some_match=`curl -sq "${letterurl}" | grep -- "$needle"`
if (( $? != 0 )) || [[ x$some_match = x ]]; then
echo "Unable to find $short"
not_found_list+=("$L")
else
echo "possible candidate"
candidate_list+=("$some_match")
fi
fi
fi
fi
done < urls_file.txt
echo ""
echo "Installed list: "
printf "%s, " "${installed_list[@]}"
echo ""
echo "Already downloaded list: "
printf " %s\\n" "${already_downloaded_list[@]}"
echo ""
echo "Not found list: "
printf " %s\\n" "${not_found_list[@]}"
echo ""
echo "Candidate list: "
printf " %s\\n" "${candidate_list[@]}"
echo "done."

View File

@@ -0,0 +1,150 @@
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/a/airspyone_host-1.0.9-6.20180615gitbfb66708.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/a/alsa-lib-1.2.1.2-3.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/a/alternatives-1.11-4.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/b/bash-5.0.11-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/b/boost-date-time-1.69.0-9.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/b/boost-filesystem-1.69.0-9.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/b/boost-program-options-1.69.0-9.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/b/boost-regex-1.69.0-9.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/b/boost-serialization-1.69.0-9.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/b/boost-thread-1.69.0-9.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/c/ca-certificates-2020.2.40-1.1.fc30.noarch.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/c/cairo-1.16.0-6.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/c/codec2-0.8.1-3.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/c/comedilib-0.8.1-23.fc29.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/d/dbus-libs-1:1.12.16-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/d/dbusmenu-qt-0.9.3-0.21.20160218.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/f/fftw-libs-single-3.3.8-4.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/f/filesystem-3.10-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/f/flex-2.6.4-2.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/f/fontconfig-2.13.1-9.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/f/freeglut-3.0.0-10.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/f/freetype-2.9.1-7.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/g/glib2-2.60.7-3.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/g/glibc-2.29-29.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/g/glibc-common-2.29-29.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/g/glibmm24-2.60.1-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/g/gnuradio-3.7.13.4-5.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/g/gnuradio-3.7.13.5-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/g/gr-fcdproplus-3.7.2-0.9.rc1.20180618gite5ff8396.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/g/gr-iqbal-0.37.2-34.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/g/gsl-2.4-8.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/g/gsm-1.0.18-4.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/g/gstreamer1-1.16.0-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/g/gstreamer1-plugins-base-1.16.0-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/g/gstreamer1-plugins-good-1.16.0-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/g/gtk3-3.24.11-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/h/hackrf-2018.01.1-3.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/h/hidapi-0.8.0-0.11.d17db57.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/j/jack-audio-connection-kit-1.9.12-9.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/k/kde-filesystem-4-61.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/k/krb5-libs-1.17-15.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/lcms2-2.9-5.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libconfig-1.7.2-3.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libffado-2.4.1-6.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libgcc-9.3.1-2.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libgfortran-9.3.1-2.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libglvnd-glx-1:1.1.0-4.gitf92208b.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libgomp-9.3.1-2.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libICE-1.0.9-15.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libiec61883-1.2.0-21.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libjpeg-turbo-2.0.2-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libmng-2.0.3-9.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libosmo-dsp-0.3-10.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libpng-2:1.6.36-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libquadmath-9.0.1-0.10.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libquadmath-9.3.1-2.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libraw1394-2.1.2-9.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libsamplerate-0.1.9-3.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libsigc++20-2.10.2-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libSM-1.2.3-2.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libsndfile-1.0.28-10.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libsodium-1.0.18-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libstdc++-9.3.1-2.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libtiff-4.0.10-8.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libunwind-1.3.1-5.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libusbx-1.0.22-2.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libX11-1.6.7-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libXcursor-1.1.15-5.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libXext-1.3.3-11.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libXfixes-5.0.3-9.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libXft-2.3.2-12.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libXi-1.7.10-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libXinerama-1.1.4-3.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libxml2-2.9.10-3.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libxml++-2.40.1-8.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libXrandr-1.5.1-9.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libXrender-0.9.10-9.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/libXxf86vm-1.1.4-11.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/log4cpp-1.1.1-10.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/l/log4cpp-devel-1.1.1-10.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/m/m4-1.4.18-10.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/n/ncurses-libs-6.1-10.20180923.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/o/openblas-0.3.5-5.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/o/openblas-0.3.9-2.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/o/openblas-serial-0.3.9-2.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/o/openblas-threads-0.3.9-2.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/o/openpgm-5.2.122-16.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/o/openssl-libs-1:1.1.1g-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/o/opus-1.3.1-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/o/orc-0.4.29-2.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/pam-1.3.1-17.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/phonon-4.10.2-3.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/pkgconf-pkg-config-1.6.1-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/portaudio-19-29.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/pulseaudio-libs-12.2-9.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/pulseaudio-libs-glib2-12.2-9.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/pygtk2-2.24.0-25.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/PyQt4-4.12.3-6.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/PyQwt-5.2.0-42.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/python2-2.7.16-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/python2-2.7.18-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/python2-cheetah-3.1.0-7.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/python2-dbus-1.2.8-5.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/python2-devel-2.7.18-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/python2-libs-2.7.18-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/python2-lxml-4.2.5-2.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/python2-nose-1.3.7-22.fc30.noarch.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/python2-numpy-1:1.16.2-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/python2-numpy-1:1.16.4-2.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/python2-numpy-f2py-1:1.16.4-2.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/python2-pyopengl-3.1.1a1-15.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/python2-pyqt4-sip-4.19.19-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/python2-rpm-macros-3-47.fc30.noarch.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/python2-scipy-1.2.0-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/python2-setuptools-40.8.0-2.fc30.noarch.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/python2-sip-4.19.19-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/python2-tkinter-2.7.18-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/python2-wxpython-3.0.2.0-25.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/python3-3.7.7-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/python3-rpm-generators-8-1.fc30.noarch.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/python3-setuptools-40.8.0-2.fc30.noarch.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/python-rpm-macros-3-47.fc30.noarch.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/p/python-srpm-macros-3-47.fc30.noarch.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/q/qt-1:4.8.7-47.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/q/qt-1:4.8.7-49.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/q/qt-common-1:4.8.7-47.fc30.noarch.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/q/qt-common-1:4.8.7-49.fc30.noarch.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/q/qt-settings-30.3-1.fc30.noarch.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/q/qt-x11-1:4.8.7-49.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/q/qwt5-qt4-5.2.2-36.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/q/qwt-6.1.3-10.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/r/redhat-rpm-config-132-1.fc30.noarch.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/r/rpm-4.14.2.1-5.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/r/rtl-sdr-0.6.0-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/s/SDL-1.2.15-41.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/s/shadow-utils-2:4.6-9.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/s/SoapySDR-0.6.1-3.20180806gite694813.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/s/sqlite-libs-3.26.0-7.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/s/systemd-libs-241-14.git18dd3fb.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/s/systemd-udev-241-14.git18dd3fb.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/t/tcl-1:8.6.8-2.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/t/tix-1:8.4.3-26.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/t/tk-1:8.6.8-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/u/uhd-3.12.0.0-4.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/w/wxBase3-3.0.4-8.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/w/wxGTK3-3.0.4-8.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/w/wxGTK3-gl-3.0.4-8.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/w/wxGTK3-media-3.0.4-8.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/z/zeromq-4.3.2-1.fc30.x86_64.rpm
https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/30/Everything/x86_64/Packages/z/zlib-1.2.11-19.fc30.x86_64.rpm

View File

@@ -0,0 +1,65 @@
Notes on writing GUI automated tests (such as AP-Auto, TR-398, Dataplane, Capacity test, etc)
AP-Auto:
In the GUI, configure the AP-Auto test as wished, and save the test config on the
Advanced Configuration page. In this example, I use the name: ap-auto-32-64-dual
In LANforge CLI, you can dump the saved configuration:
default@btbits>> show_text_blob Plugin-Settings AP-Auto-ap-auto-32-64-dual
TEXT-BLOB:Plugin-Settings.AP-Auto-ap-auto-32-64-dual::[BLANK]
show_events: 1
show_log: 1
port_sorting: 0
notes0: Chamber to Chamber test.
bg: 0xE0ECF8
test_rig: TR-398 test bed
....
Save this text to a file for later use: AP-Auto-ap-auto-32-64-dual.txt
# Save AP-Auto configuration text using the ../lf_testmod.pl script:
../lf_testmod.pl --mgr 192.168.100.156 --action show --test_name AP-Auto-ap-auto-32-64-dual > test_configs/mytest.txt
# Save WiFi-Capacity configuration (saved as 'fb-192' using the ../lf_testmod.pl script:
../lf_testmod.pl --mgr 192.168.100.156 --action show --test_name Wifi-Capacity-fb-192 > test_configs/mytest.txt
# Save Chamber View scenario:
../lf_testmod.pl --mgr 192.168.100.156 --action show --test_name simpleThput --test_type Network-Connectivity > test_configs/myscenario.txt
# To load a test file into the LANforge server configuration:
../lf_testmod.pl --mgr 192.168.100.156 --action set --test_name AP-Auto-ben --file test_configs/mytest.txt
# Load a scenario into the LANforge server configuration
../lf_testmod.pl --mgr 192.168.100.156 --action set --test_type Network-Connectivity --test_name 64sta --file test_configs/myscenario.txt
###
Once test cases have been loaded into the server, you can tell the GUI to run tests for you, potentially modifying the
test configuration through the GUI.
# Tell the GUI to read the latest test config from the server.
../lf_gui_cmd.pl --manager localhost --port 3990 --cmd "cli show_text_blob"
# Tell the Chamber-View GUI widget to load and build the specified scenario.
../lf_gui_cmd.pl --manager localhost --port 3990 --load 64sta
# Now, tell the GUI to run a test with the new config.
# Note that the --tconfig option does not have the "AP-Auto-" prepended to it, that is automatically
# done by the GUI in order to make sure each test has its own namespace.
../lf_gui_cmd.pl --manager localhost --port 3990 --ttype "AP-Auto" --tname ap-auto-ben --tconfig ben --rpt_dest /tmp/lf_reports/
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.

View File

@@ -0,0 +1,408 @@
#!/bin/bash
# Run some automated GUI tests, save the results
# Example of how to run this and override LFMANAGER default settings. Other values can
# be over-ridden as well.
#
# LFMANAGER=192.168.100.156 ./basic_regression.bash
#
# Run subset of tests
# LFMANAGER=192.168.100.156 DEFAULT_ENABLE=0 DO_SHORT_AP_STABILITY_RESET=1 ./basic_regression.bash
#
#
# Disable stdout buffering in python so that we get serial console log
# output promptly.
#set -x
PYTHONUNBUFFERED=1
export PYTHONUNBUFFERED
AP_SERIAL=${AP_SERIAL:-NONE}
LF_SERIAL=${LF_SERIAL:-NONE}
APGW=${APGW:-172.16.0.1}
LFPASSWD=${LFPASSWD:-lanforge} # Root password on LANforge machine
AP_AUTO_CFG_FILE=${AP_AUTO_CFG_FILE:-test_configs/AP-Auto-ap-auto-32-64-dual.txt}
WCT_CFG_FILE=${WCT_CFG_FILE:-test_configs/WCT-64sta.txt}
DPT_CFG_FILE=${DPT_CFG_FILE:-test_configs/dpt-pkt-sz.txt}
SCENARIO_CFG_FILE=${SCENARIO_CFG_FILE:-test_configs/64_sta_scenario.txt}
WCT_DURATION=${WCT_DURATION:-60s}
# LANforge target machine
LFMANAGER=${LFMANAGER:-localhost}
# LANforge GUI machine (may often be same as target)
GMANAGER=${GMANAGER:-localhost}
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:-Unspecified}
# DUT configuration
DUT_FLAGS=${DUT_FLAGS:-NA}
DUT_FLAGS_MASK=${DUT_FLAGS_MASK:-NA}
DUT_SW_VER=${DUT_SW_VER:-NA}
DUT_HW_VER=${DUT_HW_VER:-NA}
DUT_MODEL=${DUT_MODEL:-NA}
DUT_SERIAL=${DUT_SERIAL:-NA}
DUT_SSID1=${DUT_SSID1:-NA}
DUT_SSID2=${DUT_SSID2:-NA}
DUT_SSID3=${DUT_SSID3:-NA}
DUT_PASSWD1=${DUT_PASSWD1:-NA}
DUT_PASSWD2=${DUT_PASSWD2:-NA}
DUT_PASSWD3=${DUT_PASSWD3:-NA}
DUT_BSSID1=${DUT_BSSID1:-NA}
DUT_BSSID2=${DUT_BSSID2:-NA}
DUT_BSSID3=${DUT_BSSID3:-NA}
# Tests to run
DEFAULT_ENABLE=${DEFAULT_ENABLE:-1}
DO_DPT_PKT_SZ=${DO_DPT_PKT_SZ:-$DEFAULT_ENABLE}
DO_WCT_DL=${DO_WCT_DL:-$DEFAULT_ENABLE}
DO_WCT_UL=${DO_WCT_UL:-$DEFAULT_ENABLE}
DO_WCT_BI=${DO_WCT_BI:-$DEFAULT_ENABLE}
DO_SHORT_AP_BASIC_CX=${DO_SHORT_AP_BASIC_CX:-$DEFAULT_ENABLE}
DO_SHORT_AP_TPUT=${DO_SHORT_AP_TPUT:-$DEFAULT_ENABLE}
DO_SHORT_AP_STABILITY_RESET=${DO_SHORT_AP_STABILITY_RESET:-$DEFAULT_ENABLE}
DO_SHORT_AP_STABILITY_RADIO_RESET=${DO_SHORT_AP_STABILITY_RADIO_RESET:-$DEFAULT_ENABLE}
DO_SHORT_AP_STABILITY_NO_RESET=${DO_SHORT_AP_STABILITY_NO_RESET:-$DEFAULT_ENABLE}
DATESTR=$(date +%F-%T)
RSLTS_DIR=${RSLTS_DIR:-basic_regression_results_$DATESTR}
# Probably no config below here
AP_AUTO_CFG=ben
WCT_CFG=ben
DPT_CFG=ben
# Change testbed_poll.pl if scenario changes below.
SCENARIO=tip-auto
RPT_TMPDIR=${MY_TMPDIR}/lf_reports
LF_SER_DEV=$(basename $LF_SERIAL)
DUT_SER_DEV=$(basename $AP_SERIAL)
LF_SER_LOG=$MY_TMPDIR/lanforge_console_log_$LF_SER_DEV.txt
DUT_SER_LOG=$MY_TMPDIR/dut_console_log_$DUT_SER_DEV.txt
REGLOG=$MY_TMPDIR/basic_regression_log_$$.txt
# Query DUT from the scenario
DUT=`grep DUT: $SCENARIO_CFG_FILE |head -1|grep -o "DUT: .*"|cut -f2 -d ' '`
echo "Found DUT: $DUT from scenario $SCENARIO_CFG_FILE"
function pre_test {
# Remove existing data connections.
../lf_gui_cmd.pl --manager $GMANAGER --port $GMPORT --cmd "cli rm_cx all all"
../lf_gui_cmd.pl --manager $GMANAGER --port $GMPORT --cmd "cli rm_endp YES_ALL"
# Clear port counters.
../lf_gui_cmd.pl --manager $GMANAGER --port $GMPORT --cmd "cli clear_port_counters ALL ALL ALL"
# Clean logs, this bounces radios and such too as side effect
../lf_gui_cmd.pl --manager $GMANAGER --port $GMPORT --cmd "cli admin clean_logs"
if [ "_${LF_SERIAL}" != "_NONE" ]
then
# Kill any existing processes on this serial port
pkill -f ".*openwrt_ctl.*$LF_SERIAL.*"
../openwrt_ctl.py --action lurk $OWRTCTL_ARGS --tty $LF_SERIAL --scheme serial --user root --passwd $LFPASSWD --prompt "\[root@" > $LF_SER_LOG 2>&1 &
fi
if [ "_${AP_SERIAL}" != "_NONE" ]
then
# Kill any existing processes on this serial port
pkill -f ".*openwrt_ctl.*$AP_SERIAL.*"
../openwrt_ctl.py --action logread $OWRTCTL_ARGS --tty $AP_SERIAL --scheme serial > $DUT_SER_LOG 2>&1 &
fi
}
function reboot_dut {
../openwrt_ctl.py --action reboot $OWRTCTL_ARGS --tty $AP_SERIAL --scheme serial
# TODO: Support hard-power cycle with power-ctl switch as well?
}
function post_test {
DEST=$1
mkdir -p $DEST/logs
if [ "_${LF_SERIAL}" != "_NONE" ]
then
# Kill any existing processes on this serial port
pkill -f ".*openwrt_ctl.*$LF_SERIAL.*"
mv $LF_SER_LOG $DEST/logs/lanforge_console_log.txt
fi
if [ "_${AP_SERIAL}" != "_NONE" ]
then
# Kill any existing processes on this serial port
pkill -f ".*openwrt_ctl.*$AP_SERIAL.*"
mv $DUT_SER_LOG $DEST/logs/dut_console_log.txt
# Look for firmware crash files
PIDD=$$
../openwrt_ctl.py $OWRTCTL_ARGS --tty $AP_SERIAL --scheme serial --action cmd --value "tar -cvzf /tmp/bugcheck.tgz /tmp/bugcheck"
../openwrt_ctl.py $OWRTCTL_ARGS --tty $AP_SERIAL --scheme serial --action upload --value "/tmp/bugcheck.tgz" --value2 "lanforge@$APGW:bugcheck-$PIDD.tgz"
# Grab the file from LANforge
scp lanforge@$LFMANAGER:bugcheck-$PIDD.tgz $DEST/logs/bugcheck.tgz
# Clean log file
ssh lanforge@$LFMANAGER "rm bugcheck-$PIDD.tgz"
# detect a few fatal flaws and reqest AP restart if found.
grep "Hardware became unavailable" $DEST/logs/dut_console_log.txt && reboot_dut
fi
mv $REGLOG $DEST/logs/test_automation_log.txt
if [ -f /home/lanforge/lanforge_log_0.txt ]
then
# Must be running on LF itself
cp /home/lanforge/lanforge_log_*.txt* $DEST/logs/
cp /home/lanforge/wifi/*log* $DEST/logs/
else
# Try via scp. Root perms needed to read wifi logs, thus root@
scp root@$LFMANAGER:/home/lanforge/lanforge_log_*.txt* $DEST/logs/
scp root@$LFMANAGER:/home/lanforge/wifi/*log* $DEST/logs/
fi
}
set -x
mkdir -p $RSLTS_DIR
# Load scenario file
../lf_testmod.pl --mgr $LFMANAGER --action set --test_type Network-Connectivity --test_name $SCENARIO --file $SCENARIO_CFG_FILE
# Load AP-Auto config file
../lf_testmod.pl --mgr $LFMANAGER --action set --test_name AP-Auto-$AP_AUTO_CFG --file $AP_AUTO_CFG_FILE
# Load Wifi Capacity config file
../lf_testmod.pl --mgr $LFMANAGER --action set --test_name Wifi-Capacity-$WCT_CFG --file $WCT_CFG_FILE
# Load Dataplane config file
../lf_testmod.pl --mgr $LFMANAGER --action set --test_name dataplane-test-latest-$DPT_CFG --file $DPT_CFG_FILE
# Set DUT info if configured.
if [ "_$DUT" != "_" ]
then
../lf_portmod.pl --manager $LFMANAGER \
--cli_cmd "add_dut $DUT $DUT_FLAGS NA '$DUT_SW_VER' '$DUT_HW_VER' '$DUT_MODEL' '$DUT_SERIAL' NA NA NA '$DUT_SSID1' '$DUT_PASSWD1' '$DUT_SSID2' '$DUT_PASSWD2' '$DUT_SSID3' '$DUT_PASSWD3' NA NA $DUT_FLAGS_MASK NA NA NA $DUT_BSSID1 $DUT_BSSID2 $DUT_BSSID3"
fi
# Make sure GUI is synced up with the server
../lf_gui_cmd.pl --manager $GMANAGER --port $GMPORT --cmd "cli show_text_blob"
../lf_gui_cmd.pl --manager $GMANAGER --port $GMPORT --cmd "cli show_dut"
# Pause to let GUI finish getting data from the server
sleep 20
# Tell GUI to load and build the scenario
../lf_gui_cmd.pl --manager $GMANAGER --port $GMPORT --scenario $SCENARIO
# Clean out temp report directory on local system and remote
if [ -d $RPT_TMPDIR ]
then
rm -fr $RPT_TMPDIR/*
fi
ssh lanforge\@$GMANAGER "test -d $RPT_TMPDIR && rm -fr $RPT_TMPDIR";
# Do dataplane pkt size test
echo "Checking if we should run Dataplane packet size test."
if [ "_$DO_DPT_PKT_SZ" == "_1" ]
then
pre_test
../lf_gui_cmd.pl --manager $GMANAGER --port $GMPORT --ttype "Dataplane" --tname dpt-ben --tconfig $DPT_CFG \
--modifier_key "Test Rig ID:" --modifier_val "$TEST_RIG_ID" \
--modifier_key "DUT_NAME" --modifier_val "$DUT" \
--modifier_key "KPI_TEST_ID" --modifier_val "Dataplane Pkt-Size" \
--modifier_key "Show Low-Level Graphs" --modifier_val true \
--rpt_dest $RPT_TMPDIR > $REGLOG 2>&1
mv $RPT_TMPDIR/* $RSLTS_DIR/dataplane_pkt_sz
post_test $RSLTS_DIR/dataplane_pkt_sz
fi
# Do capacity test
echo "Checking if we should run WCT Download test."
if [ "_$DO_WCT_DL" == "_1" ]
then
pre_test
../lf_gui_cmd.pl --manager $GMANAGER --port $GMPORT --ttype "WiFi Capacity" --tname wct-ben --tconfig $WCT_CFG \
--modifier_key "Test Rig ID:" --modifier_val "$TEST_RIG_ID" \
--modifier_key "DUT_NAME" --modifier_val "$DUT" \
--modifier_key "KPI_TEST_ID" --modifier_val "Capacity-Download" \
--modifier_key "RATE_DL" --modifier_val "1Gbps" \
--modifier_key "RATE_UL" --modifier_val "0" \
--modifier_key "VERBOSITY" --modifier_val "9" \
--modifier_key "Duration:" --modifier_val "$WCT_DURATION" \
--rpt_dest $RPT_TMPDIR > $REGLOG 2>&1
mv $RPT_TMPDIR/* $RSLTS_DIR/wifi_capacity_dl
post_test $RSLTS_DIR/wifi_capacity_dl
fi
echo "Checking if we should run WCT Upload test."
if [ "_$DO_WCT_UL" == "_1" ]
then
pre_test
../lf_gui_cmd.pl --manager $GMANAGER --port $GMPORT --ttype "WiFi Capacity" --tname wct-ben --tconfig $WCT_CFG \
--modifier_key "Test Rig ID:" --modifier_val "$TEST_RIG_ID" \
--modifier_key "DUT_NAME" --modifier_val "$DUT" \
--modifier_key "KPI_TEST_ID" --modifier_val "Capacity-Upload" \
--modifier_key "RATE_UL" --modifier_val "1Gbps" \
--modifier_key "RATE_DL" --modifier_val "0" \
--modifier_key "VERBOSITY" --modifier_val "9" \
--modifier_key "Duration:" --modifier_val "$WCT_DURATION" \
--rpt_dest $RPT_TMPDIR > $REGLOG 2>&1
mv $RPT_TMPDIR/* $RSLTS_DIR/wifi_capacity_ul
post_test $RSLTS_DIR/wifi_capacity_ul
fi
echo "Checking if we should run WCT Bi-Direction test."
if [ "_$DO_WCT_BI" == "_1" ]
then
pre_test
../lf_gui_cmd.pl --manager $GMANAGER --port $GMPORT --ttype "WiFi Capacity" --tname wct-ben --tconfig $WCT_CFG \
--modifier_key "Test Rig ID:" --modifier_val "$TEST_RIG_ID" \
--modifier_key "DUT_NAME" --modifier_val "$DUT" \
--modifier_key "KPI_TEST_ID" --modifier_val "Capacity-TCP-UL+DL" \
--modifier_key "RATE_UL" --modifier_val "1Gbps" \
--modifier_key "RATE_DL" --modifier_val "1Gbps" \
--modifier_key "Protocol:" --modifier_val "TCP-IPv4" \
--modifier_key "VERBOSITY" --modifier_val "9" \
--modifier_key "Duration:" --modifier_val "$WCT_DURATION" \
--rpt_dest $RPT_TMPDIR > $REGLOG 2>&1
mv $RPT_TMPDIR/* $RSLTS_DIR/wifi_capacity_bi
post_test $RSLTS_DIR/wifi_capacity_bi
fi
# Run basic-cx test
echo "Checking if we should run Short-AP Basic CX test."
if [ "_$DO_SHORT_AP_BASIC_CX" == "_1" ]
then
pre_test
../lf_gui_cmd.pl --manager $GMANAGER --port $GMPORT --ttype "AP-Auto" --tname ap-auto-ben --tconfig $AP_AUTO_CFG \
--modifier_key "Test Rig ID:" --modifier_val "$TEST_RIG_ID" \
--modifier_key "DUT_NAME" --modifier_val "$DUT" \
--modifier_key "Band-Steering" --modifier_val false \
--modifier_key "Multi-Station Throughput vs Pkt Size" --modifier_val false \
--rpt_dest $RPT_TMPDIR > $REGLOG 2>&1
mv $RPT_TMPDIR/* $RSLTS_DIR/ap_auto_basic_cx
post_test $RSLTS_DIR/ap_auto_basic_cx
fi
# Run Throughput, Dual-Band, Capacity test in a row, the Capacity will use results from earlier
# tests.
echo "Checking if we should run Short-AP Throughput test."
if [ "_$DO_SHORT_AP_TPUT" == "_1" ]
then
pre_test
../lf_gui_cmd.pl --manager $GMANAGER --port $GMPORT --ttype "AP-Auto" --tname ap-auto-ben --tconfig $AP_AUTO_CFG \
--modifier_key "Test Rig ID:" --modifier_val "$TEST_RIG_ID" \
--modifier_key "DUT_NAME" --modifier_val "$DUT" \
--modifier_key "Basic Client Connectivity" --modifier_val false \
--modifier_key "Throughput vs Pkt Size" --modifier_val true \
--modifier_key "Dual Band Performance" --modifier_val true \
--modifier_key "Band-Steering" --modifier_val false \
--modifier_key "Multi-Station Throughput vs Pkt Size" --modifier_val false \
--modifier_key "Capacity" --modifier_val true \
--rpt_dest $RPT_TMPDIR > $REGLOG 2>&1
mv $RPT_TMPDIR/* $RSLTS_DIR/ap_auto_capacity
post_test $RSLTS_DIR/ap_auto_capacity
fi
# Run Stability test (single port resets, voip, tcp, udp)
echo "Checking if we should run Short-AP Stability Reset test."
if [ "_$DO_SHORT_AP_STABILITY_RESET" == "_1" ]
then
pre_test
../lf_gui_cmd.pl --manager $GMANAGER --port $GMPORT --ttype "AP-Auto" --tname ap-auto-ben --tconfig $AP_AUTO_CFG \
--modifier_key "Test Rig ID:" --modifier_val "$TEST_RIG_ID" \
--modifier_key "DUT_NAME" --modifier_val "$DUT" \
--modifier_key "KPI_TEST_ID" --modifier_val "AP-Auto Port-Reset" \
--modifier_key "Basic Client Connectivity" --modifier_val false \
--modifier_key "Stability" --modifier_val true \
--modifier_key "Band-Steering" --modifier_val false \
--modifier_key "Multi-Station Throughput vs Pkt Size" --modifier_val false \
--modifier_key "Stability Duration:" --modifier_val $STABILITY_DURATION \
--rpt_dest $RPT_TMPDIR > $REGLOG 2>&1
mv $RPT_TMPDIR/* $RSLTS_DIR/ap_auto_stability_reset_ports
post_test $RSLTS_DIR/ap_auto_stability_reset_ports
fi
# Run Stability test (radio resets, voip, tcp, udp)
echo "Checking if we should run Short-AP Stability Radio Reset test."
if [ "_$DO_SHORT_AP_STABILITY_RADIO_RESET" == "_1" ]
then
pre_test
../lf_gui_cmd.pl --manager $GMANAGER --port $GMPORT --ttype "AP-Auto" --tname ap-auto-ben --tconfig $AP_AUTO_CFG \
--modifier_key "Test Rig ID:" --modifier_val "$TEST_RIG_ID" \
--modifier_key "DUT_NAME" --modifier_val "$DUT" \
--modifier_key "KPI_TEST_ID" --modifier_val "AP-Auto Radio-Reset" \
--modifier_key "Basic Client Connectivity" --modifier_val false \
--modifier_key "Stability" --modifier_val true \
--modifier_key "Band-Steering" --modifier_val false \
--modifier_key "Stability Duration:" --modifier_val $STABILITY_DURATION \
--modifier_key "Multi-Station Throughput vs Pkt Size" --modifier_val false \
--modifier_key "Reset Radios" --modifier_val true \
--rpt_dest $RPT_TMPDIR > $REGLOG 2>&1
mv $RPT_TMPDIR/* $RSLTS_DIR/ap_auto_stability_reset_radios
post_test $RSLTS_DIR/ap_auto_stability_reset_radios
fi
# Run Stability test (no resets, no voip, tcp, udp)
echo "Checking if we should run Short-AP Stability No-Reset test."
if [ "_$DO_SHORT_AP_STABILITY_NO_RESET" == "_1" ]
then
pre_test
../lf_gui_cmd.pl --manager $GMANAGER --port $GMPORT --ttype "AP-Auto" --tname ap-auto-ben --tconfig $AP_AUTO_CFG \
--modifier_key "Test Rig ID:" --modifier_val "$TEST_RIG_ID" \
--modifier_key "DUT_NAME" --modifier_val "$DUT" \
--modifier_key "KPI_TEST_ID" --modifier_val "AP-Auto No-Reset" \
--modifier_key "Basic Client Connectivity" --modifier_val false \
--modifier_key "Band-Steering" --modifier_val false \
--modifier_key "Stability" --modifier_val true \
--modifier_key "Stability Duration:" --modifier_val $STABILITY_DURATION \
--modifier_key "Multi-Station Throughput vs Pkt Size" --modifier_val false \
--modifier_key "VOIP Call Count:" --modifier_val 0 \
--modifier_key "Concurrent Ports To Reset:" --modifier_val 0 \
--rpt_dest $RPT_TMPDIR > $REGLOG 2>&1
mv $RPT_TMPDIR/* $RSLTS_DIR/ap_auto_stability_no_reset
post_test $RSLTS_DIR/ap_auto_stability_no_reset
fi
if [ "_${LFLOG_PID}" != "_" ]
then
kill $LFLOG_PID
mv $LF_SER_LOG $RSLTS_DIR/lanforge_console_log.txt
fi
if [ "_${DUTLOG_PID}" != "_" ]
then
kill $DUTLOG_PID
mv $$DUT_SER_LOG $RSLTS_DIR/dut_console_log.txt
fi
RPT_ARGS=
if [ "_${NOTES_HTML}" == "_" ]
then
NOTES_HTML=NA
fi
if [ "_${GITLOG}" == "_" ]
then
GITLOG=NA
fi
if [ "_${DUTGITLOG}" == "_" ]
then
DUTGITLOG=NA
fi
echo "./lf_gui_report_summary.pl --title \"$TEST_RIG_ID: $DUT_SW_VER\" --dir $RSLTS_DIR --dutgitlog $DUTGITLOG --gitlog $GITLOG --notes $NOTES_HTML"
./lf_gui_report_summary.pl --title "$TEST_RIG_ID: $DUT_SW_VER" --dir $RSLTS_DIR --dutgitlog $DUTGITLOG --gitlog $GITLOG --notes $NOTES_HTML < index_template.html > $RSLTS_DIR/index.html
echo "Done with automated regression test."
echo "Results-Dir: $RSLTS_DIR"

View File

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

View File

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

View File

@@ -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 href=\"(.*.tar.gz)\">(.*)<\/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;
}

View File

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

View File

@@ -0,0 +1,11 @@
set term pngcairo size 1280,768
set output "plot.png"
set datafile separator "\t"
set ylabel "Data"
set xlabel "Test#"
#set xdata time
set grid
#set key outside
set key off
plot filename using 1:2 with lines

View File

@@ -0,0 +1,11 @@
set term pngcairo size 1280,768
set output "plot.png"
set datafile separator "\t"
#set ylabel "Data"
set xlabel "Test#"
#set xdata time
set grid
set key outside
#set key off
#plot filename using 1:2 with lines

View File

@@ -0,0 +1,58 @@
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<meta name='viewport' content='width=device-width, initial-scale=1' />
<title>___TITLE___</title> <link rel='shortcut icon' href='canvil.ico' type='image/x-icon' />
<link rel='stylesheet' href='report.css' />
<link rel='stylesheet' href='custom.css' />
<style>
pre {
overflow: auto;
}
img {
width: 100%;
max-width: 8in;
}
</style>
</head>
<body>
<div class='HeaderStyle'>
<h1 class='TitleFontPrint'>___TITLE___</h1><br/>
<h4 class='TitleFontPrintSub'><br>___DATE___</h4></div>
<div class='contentDiv'>
<br>
<h3>Individual test results and logs.</h3>
<table border="1" cellpadding="6" cellspacing="0" style="border-top-color: gray; border-top-style: solid; border-top-width: 1px; border-right-color: gray; border-right-style: solid; border-right-width: 1px; border-bottom-color: gray; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: gray; border-left-style: solid; border-left-width: 1px">
<!-- <tr><td><a href=ap_auto_basic_cx/index.html>AP Auto Basic CX Report</a></td><td><a href=ap_auto_basic_cx/logs>Logs</a></td></tr> -->
___TR_TESTS___
</table>
<P>
<table border="1" cellpadding="2" cellspacing="0" style="border-top-color: gray; border-top-style: solid; border-top-width: 1px; border-right-color: gray; border-right-style: solid; border-right-width: 1px; border-bottom-color: gray; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: gray; border-left-style: solid; border-left-width: 1px">
<tr><th>Test Rig</th><th>DUT Hardware</th><th>DUT Software</th><th>DUT Model</th><th>DUT Serial</th></tr>
<!-- <tr><td>Ben-Home-OTA</td><td>Linksys-MR8300</td><td>TIP-OpenWrt</td><td>Linksys-MR8300</td><td>Unknown</td></tr> -->
___TR_DUT___
</table>
<P>
<table border="1" cellpadding="2" cellspacing="0" style="border-top-color: gray; border-top-style: solid; border-top-width: 1px; border-right-color: gray; border-right-style: solid; border-right-width: 1px; border-bottom-color: gray; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: gray; border-left-style: solid; border-left-width: 1px">
<tr><th>Test-ID</th><th>Short Description</th><th>Pass/Fail</th><th>Subtest-Passed</th><th>Subtest-Failed</th><th>Numeric Result</th><th>Test Details</th></tr>
<!-- <tr><td>AP AUtomated Test</td><td>Daul Band Performance</td><td>PASS</td><td>1</td><td>2</td><td>86.44</td><td>Dual-Concurrent vs 90% of Sum: 435.68 Mbps / 558.84 Mbps Dual-Concurrent vs 90% of Sum: 598.17 Mbps / 630.11 Mbps</td></tr> -->
___TR_KPI___
</table>
<P>
___TESTBED_NOTES___
</div><!--end content-div -->
<div class='FooterStyle'><span class='Gradient'>Generated by Candela Technologies LANforge network testing tool.<br/>
<a href='https://www.candelatech.com/' target='_blank'>www.candelatech.com</a>
</span>
<a class='LogoImgLink' href='https://www.candelatech.com/' target='_blank'><img align='right' src='candela_swirl_small-72h.png'></a></div><br/>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,322 @@
#!/usr/bin/perl -w
# Generate HTML summary page for a collection of GUI reports (with kpi.csv)
# (C) 2020 Candela Technologies Inc.
#
use strict;
use warnings;
use diagnostics;
use Carp;
$SIG{ __DIE__ } = sub { Carp::confess( @_ ) };
$SIG{ __WARN__ } = sub { Carp::confess( @_ ) };
# Un-buffer output
$| = 1;
# use lib prepends to @INC, so put lower priority first
# This is before run-time, so cannot condition this with normal 'if' logic.
use lib '/home/lanforge/scripts';
use lib "../";
use lib "./";
use Getopt::Long;
use HTML::Entities;
our $dir = "";
our $notes = "";
our $gitlog = "";
our $dutgitlog = "";
our $title = "Automated test results.";
########################################################################
# Nothing to configure below here, most likely.
########################################################################
our $usage = <<"__EndOfUsage__";
$0 [ --dir directory-to-process --notes testbed-notes-file.html --dutgitlog dut-gitlog-output.html --gitlog gitlog-output.html ] < html_template.html
Example:
cat html-template | $0 --dir ~/tmp/results --title "My Title" --notes testbeds/my_testbed/testbed_notes.html --dutgitlog /tmp/dgitlog.html --gitlog /tmp/gitlog.html
__EndOfUsage__
my $i = 0;
my $show_help = 0;
GetOptions
(
'dir|d=s' => \$::dir,
'notes|n=s' => \$::notes,
'gitlog|g=s' => \$::gitlog,
'dutgitlog=s' => \$::dutgitlog,
'title|t=s' => \$::title,
'help|h' => \$show_help,
) || die("$::usage");
if ($show_help) {
print $usage;
exit 0;
}
my $testbed_notes = "";
if (-f "$notes") {
$testbed_notes .= "<b>Test Bed Notes.</b><br>\n";
$testbed_notes .= `cat $notes`;
}
if (-f "$dutgitlog") {
$testbed_notes .= "<P>\n";
$testbed_notes .= `cat $dutgitlog`;
$testbed_notes .= "<p>\n";
}
if (-f "$gitlog") {
$testbed_notes .= "<P>\n";
$testbed_notes .= `cat $gitlog`;
$testbed_notes .= "<p>\n";
}
$testbed_notes .= "<p><b>Top lanforge-scripts commits.</b><br><pre>\n";
$testbed_notes .= `git log -n 8 --oneline`;
$testbed_notes .= "</pre>\n";
chdir($dir);
my @files = `ls`;
chomp(@files);
my $line;
# Find some html helpers and copy them to current dir.
foreach $line (@files) {
if ( -d $line) {
if ( -f "$line/canvil.ico") {
`cp $line/canvil.ico ./`;
`cp $line/*.css ./`;
`cp $line/candela_swirl* ./`;
`cp $line/CandelaLogo* ./`;
last;
}
}
}
my $dut_tr = "";
my $kpi_tr = "";
my $tests_tr = "";
# TODO: Add git commit history for other repositories perhaps?
foreach my $line (@files) {
if ( -d $line) {
#print "Checking report: $line\n";
if ( -d "$line/logs") {
processLogs("$line/logs");
my $log_links = "";
my $li = 0;
my $iline;
my @ifiles = `ls $line/logs/*-idx.html`;
chomp(@ifiles);
foreach $iline (@ifiles) {
$log_links .= " <a href=$iline>[$li]</a>";
}
if ($log_links ne "") {
$log_links = "Errors: $log_links";
}
$tests_tr .= "<tr><td><a href=\"$line/index.html\">$line</a></td><td><a href=\"$line/logs\">Logs</a> $log_links</td></tr>\n";
}
else {
$tests_tr .= "<tr><td><a href=\"$line/index.html\">$line</html></td><td></td></tr>\n";
}
if ( -f "$line/kpi.csv") {
my @kpi = `cat $line/kpi.csv`;
chomp(@kpi);
my $i = 0;
foreach my $k (@kpi) {
$i++;
if ($i == 1) {
next; # skip header
}
my @cols = split(/\t/, $k);
if ($dut_tr eq "") {
$dut_tr = "<tr><td>$cols[1]</td><td>$cols[2]</td><td>$cols[3]</td><td>$cols[4]</td><td>$cols[5]</td></tr>\n";
}
my $nval = $cols[10];
if ( $nval =~ /^[+-]?(?=\.?\d)\d*\.?\d*(?:e[+-]?\d+)?\z/i ) {
$nval = sprintf("%.2f", $nval);
}
my $s_passed = "0";
my $s_failed = "0";
if (@cols >= 16) {
$s_passed = $cols[14];
$s_failed = $cols[15];
}
$kpi_tr .= "<tr><td>$cols[7]</td><td>$cols[8]</td><td>$cols[9]</td><td>$s_passed</td><td>$s_failed</td><td>$nval</td><td>$cols[11]</td></tr>\n";
}
}
}
}
my $date = `date`;
while (<>) {
my $ln = $_;
chomp($ln);
$ln =~ s/___TITLE___/$title/g;
$ln =~ s/___DATE___/$date/g;
$ln =~ s/___TR_DUT___/$dut_tr/g;
$ln =~ s/___TR_KPI___/$kpi_tr/g;
$ln =~ s/___TR_TESTS___/$tests_tr/g;
$ln =~ s/___TESTBED_NOTES___/$testbed_notes/g;
print "$ln\n";
}
exit(0);
sub processLogs {
my $ldir = shift;
my @files = `ls $ldir`;
chomp(@files);
open(CSV, ">$ldir/logs.csv");
print CSV "FILE\tBUGS\tWARNINGS\tCRASHED\tRESTARTING\n";
foreach $line (@files) {
if ($line =~ /console.*\.txt$/) {
my $bugs = 0;
my $warnings = 0;
my $crashed = 0;
my $restarting = 0;
my $tag = 0;
my $logf = $ldir . "/" . $line;
my $logh = $logf . ".html";
my $loghb = $line . ".html";
my $loghi = $logf . "-idx.html";
#print("Processing log file: $logf\n");
open(IFILE, "<", $logf ) or die( "could not read $logf");
open(IDX, ">$loghi");
open(LOGH, ">$logh");
print IDX getHtmlHdr("Log file index: $line");
print LOGH getHtmlHdr("Log file: $line");
print LOGH "<pre>\n";
print IDX "<a href=$loghb>Full Logs in HTML format</a><br>\n";
print IDX "<a href=$line>Full Logs in Text format</a><P>\n";
print IDX "<b>Interesting log sections.</b><br>\n";
print IDX "<ol>\n";
while (<IFILE>) {
my $ln = $_;
chomp($ln);
#print("ln: $ln\n");
my $enc_ln = encode_entities($ln);
# Get rid of some funk
$enc_ln =~ s/\&\#0\;//g;
if (($ln =~ /WARNING:/) ||
($ln =~ /BUG:/) ||
($ln =~ /Hardware became unavailable during restart/) ||
($ln =~ /restarting hardware/) ||
($ln =~ /oom-killer/) ||
($ln =~ /crashed/)) {
if ($ln =~ /WARNING:/) {
$warnings++;
}
elsif ($ln =~ /BUG:/) {
$bugs++;
}
elsif ($ln =~ /restarting hardware/) {
$restarting++;
}
elsif (($ln =~ /crashed/) || # software/firmware crashed
($ln =~ /oom-killer/) || # System OOM, processes were force-killed by kernel
($ln =~ /became unavailable/)) { # hardware crashed
$crashed++;
}
print IDX "<li><a href=$loghb#$tag>$enc_ln</a></li>\n";
print LOGH "<a name='$tag'></a>\n";
print LOGH "<pre style='color:red'>$enc_ln</pre>\n";
$tag++;
}
else {
print LOGH "$enc_ln\n";
}
}
#print ("Done with file\n");
print LOGH "</pre>\n";
print IDX "</ol>\n";
print LOGH getHtmlFooter();
print IDX getHtmlFooter();
close(IDX);
close(LOGH);
close(IFILE);
print CSV "$line\t$bugs\t$warnings\t$crashed\t$restarting\n";
if ($bugs + $warnings +$crashed + $restarting == 0) {
# Remove index since it has no useful data
unlink($loghi);
}
}
}
#print("Done processing logs.\n");
}
sub getHtmlHdr {
my $title = shift;
return "<!DOCTYPE html>\n" .
"<html>\n" .
" <head>\n" .
" <meta charset='utf-8' />\n" .
" <meta name='viewport' content='width=device-width, initial-scale=1' />\n" .
" <title>$title</title> <link rel='shortcut icon' href='canvil.ico' type='image/x-icon' />\n" .
" <link rel='stylesheet' href='../report.css' />\n" .
" <link rel='stylesheet' href='../custom.css' />\n" .
" <style>\n" .
" pre {\n" .
" overflow: auto;\n" .
" }\n" .
" img {\n" .
" width: 100%;\n" .
" max-width: 8in;\n" .
" }\n" .
" </style>\n" .
" </head>\n" .
" <body>\n" .
"<div class='HeaderStyle'>\n" .
"<h1 class='TitleFontPrint'>$title</h1><br/>\n" .
"\n" .
"<div class='contentDiv'>\n";
}
sub getHtmlFooter {
return "</div><!--end content-div -->\n" .
"<div class='FooterStyle'><span class='Gradient'>Generated by Candela Technologies LANforge network testing tool.<br/>\n" .
" <a href='https://www.candelatech.com/' target='_blank'>www.candelatech.com</a>\n" .
"</span>\n" .
"<a class='LogoImgLink' href='https://www.candelatech.com/' target='_blank'><img align='right' src='../candela_swirl_small-72h.png'></a></div><br/>\n" .
" </body>\n" .
"</html>\n";
}
# ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
# ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----

View File

@@ -0,0 +1,17 @@
set term pngcairo size 150,100
set output "plot.png"
set datafile separator "\t"
#set ylabel "Data"
#set xlabel "Test#"
set ylabel
set xlabel
#set xdata time
#set grid
#set key outside
set key off
unset xtics
unset ytics
unset border
set title
plot filename using 1:2 with lines

View File

@@ -0,0 +1,17 @@
set term pngcairo size 150,100
set output "plot.png"
set datafile separator "\t"
#set ylabel "Data"
#set xlabel "Test#"
set ylabel
set xlabel
#set xdata time
#set grid
#set key outside
set key off
unset xtics
unset ytics
unset border
set title
#plot filename using 1:2 with lines

View File

@@ -0,0 +1,12 @@
profile_link 1.1 STA-AC 64 'DUT: TR398-DUT Radio-1' NA wiphy0,AUTO -1
profile_link 1.1 upstream 1 'DUT: TR398-DUT LAN' NA eth1,AUTO -1
chamber TR-398 495 239 NA 10.0
chamber MobileStations 305 240 NA 10.0
dut Lexus 0 0
dut SurfacePro 110 152
dut iphone 0 0
dut Comcast 565 309
dut NetgearAP 987 177
resource 1.2 0 0

View File

@@ -0,0 +1,171 @@
show_events: 1
show_log: 1
port_sorting: 0
notes0: Chamber to Chamber test.
bg: 0xE0ECF8
test_rig: TR-398 test bed
show_scan: 1
auto_helper: 1
skip_2: 1
skip_5: 1
dut5-0: TR398-DUT NETGEAR68-5G
dut2-0: TR398-DUT NETGEAR68
dut5-1: NA
dut2-1: NA
dut5-2: NA
dut2-2: NA
spatial_streams: AUTO
bandw_options: AUTO
modes: Auto
upstream_port: 1.1.1 eth1
operator: Ben Greear @ Candela Technologies
mconn: 1
tos: 0
vid_buf: 500000
vid_speed: 700000
reset_stall_thresh_udp_dl: 100000
reset_stall_thresh_udp_ul: 100000
reset_stall_thresh_tcp_dl: 100000
reset_stall_thresh_tcp_ul: 100000
reset_stall_thresh_l4: 100000
reset_stall_thresh_voip: 0
stab_udp_dl_min: 500000
stab_udp_dl_max: 1544000
stab_udp_ul_min: 500000
stab_udp_ul_max: 1544000
stab_tcp_dl_min: 500000
stab_tcp_dl_max: 1544000
stab_tcp_ul_min: 500000
stab_tcp_ul_max: 1544000
dl_speed: 85%
ul_speed: 85%
max_stations_2: 32
max_stations_5: 64
max_stations_dual: 64
lt_sta: 2
voip_calls: 10
lt_dur: 120
reset_dur: 300
lt_gi: 30
dur20: 20
hunt_retries: 1
cap_dl: 1
cap_ul: 1
cap_use_pkt_sizes: 0
stability_reset_radios: 0
pkt_loss_thresh: 10000
frame_sizes: 200, 512, 1024, MTU
capacities: 1, 10, 32, 64, 128
pf_text0: # modes: /a, /an-20 4x4, /an-40 4x4, /b, /bg, /bgn-20, /anAC-20,40,80
pf_text1: # stations: 1, 10, 20, 50, ...
pf_text2: # Non-specified and fields set to "*" means match all.
pf_text3: # For a/b/g modes, Auto-BW == 20, Auto-NSS == 1
pf_text4: # For /n modes, Auto-BW == 40, Auto-NSS == 4
pf_text5: # For /ac and /ax modes, Auto-BW == 80, Auto-NSS == 4
pf_text6:
pf_text7: # /a mode
pf_text8: 5 * 64 2Mbps mode=802.11a sta=1
pf_text9: 5 * 1370 25Mbps mode=802.11a sta=1
pf_text10: 5 * MTU 26Mbps mode=802.11a sta=1
pf_text11:
pf_text12: 5 * 64 50Mbps mode=802.11an sta=1 bw=20 nss=4
pf_text13: 5 * 1370 245Mbps mode=802.11an sta=1 bw=20 nss=4
pf_text14: 5 * MTU 245Mbps mode=802.11an sta=1 bw=20 nss=4
pf_text15:
pf_text16: 5 * 64 50Mbps mode=802.11an sta=1 bw=40 nss=4
pf_text17: 5 * 1370 455Mbps mode=802.11an sta=1 bw=40 nss=4
pf_text18: 5 * MTU 456Mbps mode=802.11an sta=1 bw=40 nss=4
pf_text19:
pf_text20: # For any amount of /b stations
pf_text21: 2.4 * 64 1Mbps mode=802.11b sta=*
pf_text22: 2.4 * 1370 7Mbps mode=802.11b sta=*
pf_text23: 2.4 * MTU 7Mbps mode=802.11b sta=*
pf_text24:
pf_text25: # For any amount of /bg stations
pf_text26: 2.4 * 64 2Mbps mode=802.11bg sta=*
pf_text27: 2.4 * 1370 21Mbps mode=802.11bg sta=*
pf_text28: 2.4 * MTU 22Mbps mode=802.11bg sta=*
pf_text29:
pf_text30: # For /bgn 20Mhz stations.
pf_text31: 2.4 * 64 50Mbps mode=802.11bgn sta=1 bw=20 nss=4
pf_text32: 2.4 * 1370 240Mbps mode=802.11bgn sta=1 bw=20 nss=4
pf_text33: 2.4 * MTU 241Mbps mode=802.11bgn sta=1 bw=20 nss=4
pf_text34:
pf_text35: 2.4 * 64 50Mbps mode=802.11bgn sta=10 bw=20 nss=4
pf_text36: 2.4 * 1370 240Mbps mode=802.11bgn sta=10 bw=20 nss=4
pf_text37: 2.4 * MTU 241Mbps mode=802.11bgn sta=10 bw=20 nss=4
pf_text38:
pf_text39: 2.4 * 64 50Mbps mode=802.11bgn sta=50 bw=20 nss=4
pf_text40: 2.4 * 1370 240Mbps mode=802.11bgn sta=50 bw=20 nss=4
pf_text41: 2.4 * MTU 245Mbps mode=802.11bgn sta=50 bw=20 nss=4
pf_text42:
pf_text43: 2.4 * 64 50Mbps mode=802.11bgn sta=100 bw=20 nss=4
pf_text44: 2.4 * 1370 235Mbps mode=802.11bgn sta=100 bw=20 nss=4
pf_text45: 2.4 * MTU 245Mbps mode=802.11bgn sta=100 bw=20 nss=4
pf_text46:
pf_text47: 2.4 * 64 50Mbps mode=802.11bgn sta=200 bw=20 nss=4
pf_text48: 2.4 * 1370 230Mbps mode=802.11bgn sta=200 bw=20 nss=4
pf_text49: 2.4 * MTU 235Mbps mode=802.11bgn sta=200 bw=20 nss=4
pf_text50:
pf_text51: # 40Mhz /n on 2.4, same values for all number of stations currently.
pf_text52: 2.4 * 64 50Mbps mode=802.11bgn sta=* bw=40 nss=4
pf_text53: 2.4 * 1370 280Mbps mode=802.11bgn sta=* bw=40 nss=4
pf_text54: 2.4 * MTU 281Mbps mode=802.11bgn sta=* bw=40 nss=4
pf_text55:
pf_text56: # For /an-AC 20Mhz stations.
pf_text57: 5 * 64 50Mbps mode=802.11an-AC sta=1 bw=20 nss=4
pf_text58: 5 * 1370 300Mbps mode=802.11an-AC sta=1 bw=20 nss=4
pf_text59: 5 * MTU 305Mbps mode=802.11an-AC sta=1 bw=20 nss=4
pf_text60:
pf_text61: # For /an-AC 40Mhz stations
pf_text62: 5 * 64 50Mbps mode=802.11an-AC sta=1 bw=40 nss=4
pf_text63: 5 * 1370 615Mbps mode=802.11an-AC sta=1 bw=40 nss=4
pf_text64: 5 * MTU 630Mbps mode=802.11an-AC sta=1 bw=40 nss=4
pf_text65:
pf_text66: # For /an-AC 80Mhz stations.
pf_text67: 5 DL 64 50Mbps mode=802.11an-AC sta=1 bw=80 nss=4
pf_text68: 5 DL 1370 1300Mbps mode=802.11an-AC sta=1 bw=80 nss=4
pf_text69: 5 DL MTU 1300Mbps mode=802.11an-AC sta=1 bw=80 nss=4
pf_text70: 5 UL 64 50Mbps mode=802.11an-AC sta=1 bw=80 nss=4
pf_text71: 5 UL 1370 1100Mbps mode=802.11an-AC sta=1 bw=80 nss=4
pf_text72: 5 UL MTU 1100Mbps mode=802.11an-AC sta=1 bw=80 nss=4
pf_text73:
pf_text74: 5 DL 64 50Mbps mode=802.11an-AC sta=10 bw=80 nss=4
pf_text75: 5 DL 1370 1300Mbps mode=802.11an-AC sta=10 bw=80 nss=4
pf_text76: 5 DL MTU 1300Mbps mode=802.11an-AC sta=10 bw=80 nss=4
pf_text77: 5 UL 64 50Mbps mode=802.11an-AC sta=10 bw=80 nss=4
pf_text78: 5 UL 1370 1200Mbps mode=802.11an-AC sta=10 bw=80 nss=4
pf_text79: 5 UL MTU 1200Mbps mode=802.11an-AC sta=10 bw=80 nss=4
pf_text80:
pf_text81: 5 * 64 50Mbps mode=802.11an-AC sta=50 bw=80 nss=4
pf_text82: 5 * 1370 1200Mbps mode=802.11an-AC sta=50 bw=80 nss=4
pf_text83: 5 * MTU 1200Mbps mode=802.11an-AC sta=50 bw=80 nss=4
pf_text84:
pf_text85: 5 * 64 50Mbps mode=802.11an-AC sta=100 bw=80 nss=4
pf_text86: 5 * 1370 1100Mbps mode=802.11an-AC sta=100 bw=80 nss=4
pf_text87: 5 * MTU 1100Mbps mode=802.11an-AC sta=100 bw=80 nss=4
pf_text88:
pf_text89: # Auto (full capabilities) entries, for tput test, DUT is wave-1 3x3/2x2
pf_text90: 2.4 * 64 50Mbps mode=Auto sta=* bw=Auto nss=Auto
pf_text91: 2.4 * 1370 280Mbps mode=Auto sta=* bw=Auto nss=Auto
pf_text92: 2.4 * MTU 282Mbps mode=Auto sta=* bw=Auto nss=Auto
pf_text93:
pf_text94: 5 * 64 50Mbps mode=Auto sta=* bw=Auto nss=Auto
pf_text95: 5 * 1370 650Mbps mode=Auto sta=* bw=Auto nss=Auto
pf_text96: 5 * MTU 650Mbps mode=Auto sta=* bw=Auto nss=Auto
radio2-0: 1.1.8 wiphy1
radio2-1: 1.1.9 wiphy3
radio2-2: 1.1.10 wiphy5
radio5-0: 1.1.3 wiphy0
radio5-1: 1.1.5 wiphy2
radio5-2: 1.1.7 wiphy4
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: 20000
reset_duration_max: 30000

View File

@@ -0,0 +1,126 @@
[BLANK]
sel_port-0: 1.1.eth1
sel_port-1: 1.1.sta00000
sel_port-2: 1.1.sta00001
sel_port-3: 1.1.sta00002
sel_port-4: 1.1.sta00003
sel_port-5: 1.1.sta00004
sel_port-6: 1.1.sta00005
sel_port-7: 1.1.sta00006
sel_port-8: 1.1.sta00007
sel_port-9: 1.1.sta00008
sel_port-10: 1.1.sta00009
sel_port-11: 1.1.sta00010
sel_port-12: 1.1.sta00011
sel_port-13: 1.1.sta00012
sel_port-14: 1.1.sta00013
sel_port-15: 1.1.sta00014
sel_port-16: 1.1.sta00015
sel_port-17: 1.1.sta00016
sel_port-18: 1.1.sta00017
sel_port-19: 1.1.sta00018
sel_port-20: 1.1.sta00019
sel_port-21: 1.1.sta00020
sel_port-22: 1.1.sta00021
sel_port-23: 1.1.sta00022
sel_port-24: 1.1.sta00023
sel_port-25: 1.1.sta00024
sel_port-26: 1.1.sta00025
sel_port-27: 1.1.sta00026
sel_port-28: 1.1.sta00027
sel_port-29: 1.1.sta00028
sel_port-30: 1.1.sta00029
sel_port-31: 1.1.sta00030
sel_port-32: 1.1.sta00031
sel_port-33: 1.1.sta00032
sel_port-34: 1.1.sta00033
sel_port-35: 1.1.sta00034
sel_port-36: 1.1.sta00035
sel_port-37: 1.1.sta00036
sel_port-38: 1.1.sta00037
sel_port-39: 1.1.sta00038
sel_port-40: 1.1.sta00039
sel_port-41: 1.1.sta00040
sel_port-42: 1.1.sta00041
sel_port-43: 1.1.sta00042
sel_port-44: 1.1.sta00043
sel_port-45: 1.1.sta00044
sel_port-46: 1.1.sta00045
sel_port-47: 1.1.sta00046
sel_port-48: 1.1.sta00047
sel_port-49: 1.1.sta00048
sel_port-50: 1.1.sta00049
sel_port-51: 1.1.sta00050
sel_port-52: 1.1.sta00051
sel_port-53: 1.1.sta00052
sel_port-54: 1.1.sta00053
sel_port-55: 1.1.sta00054
sel_port-56: 1.1.sta00055
sel_port-57: 1.1.sta00056
sel_port-58: 1.1.sta00057
sel_port-59: 1.1.sta00058
sel_port-60: 1.1.sta00059
sel_port-61: 1.1.sta00060
sel_port-62: 1.1.sta00061
sel_port-63: 1.1.sta00062
sel_port-64: 1.1.sta00063
show_events: 1
show_log: 0
port_sorting: 0
bg: 0xE0ECF8
test_rig:
show_scan: 1
auto_helper: 1
skip_2: 0
skip_5: 0
batch_size: 1,2,5,10,20,40,64
loop_iter: 1
duration: 20000
test_groups: 0
test_groups_subset: 0
protocol: UDP-IPv4
dl_rate_sel: Total Download Rate:
dl_rate: 1000000000
ul_rate_sel: Total Upload Rate:
ul_rate: 0
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: 1
do_pf: 0
pf_min_period_dl: 1544000
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

View File

@@ -0,0 +1,55 @@
[BLANK]
sel_port-0: 1.1.sta0000
show_events: 1
show_log: 0
port_sorting: 0
bg: 0xE0ECF8
test_rig:
show_scan: 1
auto_helper: 0
skip_2: 0
skip_5: 0
selected_dut: TR398-DUT
duration: 10000
traffic_port: 1.1.10 sta00000
upstream_port: 1.1.1 eth1
path_loss: 10
speed: 75%
speed2: 56Kbps
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
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 300
attenuations2: 0 300
chamber: 0
tt_deg: 0..+45..359
cust_pkt_sz:
show_3s: 0
show_ll_graphs: 0
show_gp_graphs: 1
show_1m: 1
pause_iter: 0
show_realtime: 1
operator:
mconn: 1
mpkt: 1000
tos: 0
loop_iterations: 1

View File

@@ -0,0 +1,70 @@
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<meta name='viewport' content='width=device-width, initial-scale=1' />
<title>___TITLE___</title> <link rel='shortcut icon' href='canvil.ico' type='image/x-icon' />
<link rel='stylesheet' href='report.css' />
<link rel='stylesheet' href='custom.css' />
<style>
pre {
overflow: auto;
}
img {
width: 100%;
max-width: 8in;
}
</style>
</head>
<body>
<div class='HeaderStyle'>
<h1 class='TitleFontPrint'>___TITLE___</h1><br/>
<div class='contentDiv'>
<br>
<h3>Latest test run details.</h3>
<table border="1" cellpadding="6" cellspacing="0" style="border-top-color: gray; border-top-style: solid; border-top-width: 1px; border-right-color: gray; border-right-style: solid; border-right-width: 1px; border-bottom-color: gray; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: gray; border-left-style: solid; border-left-width: 1px">
<tr><th>Test ID</th><th>Test Run</th><th>Date</th><th>DUT Hardware</th><th>DUT Sofware</th><th>DUT Model</th><th>Pass</th><th>Fail</th><th>Log Bugs</th><th>Warnings</th><th>Crashes</th><th>Other</th></tr>
___LATEST_RUN___
</table>
<table border=0>
___LATEST_RUN_PNGS___
</table>
<P>
<h3>Scores and other top-priority test results.</h3>
<table border="1" cellpadding="6" cellspacing="0" style="border-top-color: gray; border-top-style: solid; border-top-width: 1px; border-right-color: gray; border-right-style: solid; border-right-width: 1px; border-bottom-color: gray; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: gray; border-left-style: solid; border-left-width: 1px">
<tr><th>Test ID</th><th>Description</th><th>Plot Thumbnail</th><th>Last Run Details</th></tr>
___SCORE_RUNS___
</table>
<P>
<h3>Historical graphs for each Data Set Group.</h3>
<table border="1" cellpadding="6" cellspacing="0" style="border-top-color: gray; border-top-style: solid; border-top-width: 1px; border-right-color: gray; border-right-style: solid; border-right-width: 1px; border-bottom-color: gray; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: gray; border-left-style: solid; border-left-width: 1px">
<tr><th>Test-Id</th><th>Description</th><th>Plot Thumbnail</th></tr>
___GROUP_GRAPHS___
</table>
<P>
<h3>Individual Test Run Details for all data sets.</h3>
<table border="1" cellpadding="6" cellspacing="0" style="border-top-color: gray; border-top-style: solid; border-top-width: 1px; border-right-color: gray; border-right-style: solid; border-right-width: 1px; border-bottom-color: gray; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: gray; border-left-style: solid; border-left-width: 1px">
<tr><th>Test ID</th><th>Test Run</th><th>Date</th><th>DUT Hardware</th><th>DUT Sofware</th><th>DUT Model</th><th>Pass</th><th>Fail</th><th>Log Bugs</th><th>Warnings</th><th>Crashes</th><th>Other</th></tr>
___TEST_RUNS___
</table>
<P>
<h3>Historical graphs for each Data Set.</h3>
<table border="1" cellpadding="6" cellspacing="0" style="border-top-color: gray; border-top-style: solid; border-top-width: 1px; border-right-color: gray; border-right-style: solid; border-right-width: 1px; border-bottom-color: gray; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: gray; border-left-style: solid; border-left-width: 1px">
<tr><th>Test ID</th><th>Description</th><th>Plot Thumbnail</th><th>Last Run Details</th></tr>
___DATA_GRAPHS___
</table>
<P>
</div><!--end content-div -->
<div class='FooterStyle'><span class='Gradient'>Generated by Candela Technologies LANforge network testing tool.<br/>
<a href='https://www.candelatech.com/' target='_blank'>www.candelatech.com</a>
</span>
<a class='LogoImgLink' href='https://www.candelatech.com/' target='_blank'><img align='right' src='candela_swirl_small-72h.png'></a></div><br/>
</body>
</html>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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 "<b>Top wlan-testing git commits.</b><br><pre>" > ./tmp_gitlog.html
git log -n 8 --oneline >> ./tmp_gitlog.html
echo "</pre>" >> ./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 "<b>Top wlan-ap git commits.</b><br><pre>" > $DUTGITLOG
(cd ../../../wlan-ap && git log -n 8 --oneline $DUT_SW_VER >> $DUTGITLOG && cd -)
echo "</pre>" >> $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"

View File

@@ -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 "<b>Top wlan-testing git commits.</b><br><pre>" > ./tmp_gitlog.html
git log -n 8 --oneline >> ./tmp_gitlog.html
echo "</pre>" >> ./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 "<b>Top wlan-ap git commits.</b><br><pre>" > $DUTGITLOG
(cd ../../../wlan-ap && git log -n 8 --oneline $DUT_SW_VER >> $DUTGITLOG && cd -)
echo "</pre>" >> $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"

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,213 @@
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
use Carp;
#use Time::HiRes;
# wow, this would have been cool but ... nope
use Archive::Har();
use Try::Tiny;
use Getopt::Long;
use utf8;
require JSON;
require JSON::XS;
#use JSON::XS;
use Data::Dumper;
$SIG{ __DIE__ } = sub { Carp::confess( @_ ) };
$SIG{ __WARN__ } = sub { Carp::confess( @_ ) };
#use constant NA => "NA";
use constant NL => "\n";
use constant Q => q(");
use constant a => q(');
use constant qQ => qq('");
use constant CS => q(: );
use constant c => q(,);
use constant dQH => q( ." -H ');
use constant CA => q(=>$::curl_args);
use constant MP => q( 'method'=>'POST',);
use constant PD => q( 'post_data'=>);
#use constant nbsp => "&nbsp;";
$| = 1;
package main;
my $usage = qq($0 --har {file.jar} # HAR file saved from browser
--out {bot.pm} # portal bot module to create
--help|-h # this
);
our $quiet = 1;
our $help = 0;
our $outfile;
our $harfile;
GetOptions (
'quiet|q:s' => \$quiet,
'help|h' => \$help,
'har=s' => \$::harfile,
'out|o=s' => \$::outfile,
) || (print($usage) && exit(1));
if ($help) {
print($usage);
exit(0);
}
if (!(defined $::harfile) || !(defined $::outfile)) {
print $usage;
exit(1);
}
die("unable to open $::harfile: $!") unless open(my $fh, "<", $::harfile);
read $fh, my $har_txt, -s $fh; # should yank that into LANforge::Utils
close $fh;
our $Decoder = JSON->new->utf8;
#print "** $har_txt".NL;
## ----- ----- ----- ----- ----- ----- ----- ----- -----
## Creating an Archive::HAR is not very efficient
## ----- ----- ----- ----- ----- ----- ----- ----- -----
#$::harfile = Archive::Har->new();
#$::harfile->string($har_txt);
#print Dumper($::harfile);
#foreach my $log_entry ($::harfile->entries()) {
# print "Log Entry: ".$log_entry->pageref() .NL if ($log_entry->pageref());
# print "DT: ".$log_entry->started_date_time() .NL if ($log_entry->started_date_time());
# #print "Request: ".Dumper($log_entry->request()) .NL;
# print "Request Url:".$log_entry->request()->{url} .NL;
# my $headers = $log_entry->request()->{headers};
# foreach my $header (@$headers) {
# print "Header: ".$header->{name} .NL;
# }
# #print "Response: ".Dumper($log_entry->response()) .NL;
# #print "Server: ".$log_entry->server_ip_address() .NL;
#}
## ----- ----- ----- ----- ----- ----- ----- ----- -----
## Creating a plain JSON object is more efficient,
## and more compatible with FF
## ----- ----- ----- ----- ----- ----- ----- ----- -----
my $json = $::Decoder->decode($har_txt);
$::Decoder->canonical(1);
$::Decoder->allow_blessed(1);
my %ordered_entries = ();
print "I see ".(length($json->{log}->{entries}))." entries\n";
foreach my $entry (@{$json->{log}->{entries}}) {
my $request_start = $entry->{startedDateTime};
$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;
for my $request_start ( sort keys %ordered_entries ) {
print "Start: $request_start\n";
my $entry = $ordered_entries{$request_start};
my $request = $$entry->{request};
my $response = $$entry->{response};
my $req_headers = $request->{headers};
my $res_headers = $response->{headers};
my $req_cookies = $request->{cookies} if (defined $request->{cookies}) || [];
my $res_cookies = $response->{cookies} if (defined $response->{cookies}) || [];
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;
}
# seems like HTTP/2 POSTS to google lack any postData?
if (($method eq "POST") && ($request->{httpVersion} =~ m|^HTTP/1|)) {
$found_login_post++;
print $fh c.NL.MP.NL;
print $fh PD.a. $request->{'postData'}->{'text'} .a;
}
print $fh c.NL.q( 'url'=>).Q. $url .Q.c.NL;
print $fh q( 'print'=>1).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 "=pod".NL;
if ($response->{status} == 301 || $response->{status} == 302) {
$found_redirect++;
print $fh "Expect redirect: ".$response->{status}.NL;
}
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
#
# create find_redirect_url()
# create submit_login()
# create interpret_login_response()
# create submit_logout()
close $fh;
###
###
###

View File

@@ -0,0 +1,130 @@
#!/usr/bin/perl
package main;
if (defined $ENV{DEBUG}) {
use strict;
use warnings;
use diagnostics;
use Carp;
use Data::Dumper;
}
use Time::HiRes qw(usleep ualarm gettimeofday stat lstat utime);
#use Time::Format qw/%time/;
# use lib prepends to @INC, so put lower priority first
# This is before run-time, so cannot condition this with normal 'if' logic.
use lib '/home/lanforge/scripts';
use lib "./";
use LANforge::Utils;
use Net::Telnet ();
use Getopt::Long;
our $quiet = 1;
my $report_filename = "/tmp/hires_report.txt";
my $duration_sec = 60;
my $cx = "rdtest";
our $lfmgr_host = 'localhost';
our $lfmgr_port = 4001;
$| = 1;
my $t = new Net::Telnet(Prompt => '/default\@btbits\>\>/',
Timeout => 60);
$t->open(Host => $::lfmgr_host,
Port => $::lfmgr_port,
Timeout => 10);
$t->max_buffer_length(16 * 1024 * 1000); # 16 MB buffer
$t->waitfor("/btbits\>\>/");
# Configure our utils.
our $utils = new LANforge::Utils();
$::utils->telnet($t); # Set our telnet object.
if ($::utils->isQuiet()) {
if (defined $ENV{'LOG_CLI'} && $ENV{'LOG_CLI'} ne "") {
$::utils->cli_send_silent(0);
}
else {
$::utils->cli_send_silent(1); # Do not show input to telnet
}
$::utils->cli_rcv_silent(1); # Repress output from telnet
}
else {
$::utils->cli_send_silent(0); # Show input to telnet
$::utils->cli_rcv_silent(0); # Show output from telnet
}
#$::utils->log_cli("# $0 ".`date "+%Y-%m-%d %H:%M:%S"`);
$SIG{'INT'} = sub {
$::utils->doCmd("set_cx_state all $cx STOPPED");
exit 0;
};
# start rdtest
my %times = ();
$times{gettimeofday().'_before_set_cx_state'} = gettimeofday() ." before_start_cx 0 0";
$::utils->doCmd("set_cx_report_timer all $cx 250");
$::utils->doCmd("set_cx_state all $cx RUNNING");
$times{gettimeofday().'_after_set_cx_state'} = gettimeofday() ." after_start_cx 0 0";
my $timelimit = $duration_sec + time();
my $show_cx_str = '';
my $lastline = '';
my $lasttime = 0;
my @hunks = ();
my $delta = 0;
my $tod = gettimeofday();
my $last_a = 0;
my $last_b = 0;
my $step_a = 0;
my $step_b = 0;
while ($tod < $timelimit) {
# the command below does not indicate last reported timestamp, skip it
# $show_cx_str = $::utils->doAsyncCmd("show_cxe all $cx");
# $times{gettimeofday()."_show_cxe"} = $show_cx_str;
$tod = gettimeofday();
$lastline=`tail -1 /home/lanforge/lf_reports/${cx}-A*`;
@hunks = split(',', $lastline);
$hunks[0] = $hunks[0]/1000 if ($hunks[0] > 0);
$last_a = $hunks[0] if ($last_a == 0);
if ($hunks[0] gt $last_a){
print "\nnew report A entry!\n";
$step_a = $hunks[0] - $last_a;
$last_a = $hunks[0];
$delta = $tod - $hunks[0];
$times{"${tod}_tail_csv-A"} = "$hunks[0] $hunks[1] $step_a $delta";
}
$lastline=`tail -1 /home/lanforge/lf_reports/${cx}-B*`;
@hunks = split(',', $lastline);
$hunks[0] = $hunks[0]/1000 if ($hunks[0] > 0);
$last_b = $hunks[0] if ($last_b == 0);
if ($hunks[0] gt $last_b) {
print "\nnew report B entry!\n";
$step_b = $hunks[0] - $last_b;
$last_b = $hunks[0];
$delta = $tod - $hunks[0];
$times{"${tod}_tail_csv-B"} = "$hunks[0] $hunks[1] $step_b $delta";
}
usleep(125);
if (time() gt $lasttime) {
print "\r".($timelimit - time())." sec remaining ";
$lasttime = time();
}
} #~while
$::utils->doCmd("set_cx_state all $cx STOPPED");
print "...collected.\n";
die unless open(my $fh, ">", $report_filename);
#print $fh "TimeKeyInput csv_record_tstampsecs endpoint sec_since_last_report seconds_lag_since_last_report\n";
print $fh "clock csv_tstamp_secs endpoint sec_btwn_reports tstamp_lag_sec\n";
foreach $key (sort {$a cmp $b} (keys %times)) {
my ($clock) = $key =~ m/^([^_]+)/;
@hunks = split(' ', $times{$key});
print$fh sprintf "%14.3f %15.3f %18s %20.3f %15.3f\n", 0.0+$clock, $hunks[0], $hunks[1], $hunks[2], $hunks[3];
}
close $fh;
print "View the report at $report_filename\n";
#eof

View File

@@ -0,0 +1,29 @@
#!/usr/bin/perl
# Convert LANforge logs and hostapd log timestamps to human readable timestamp.
use POSIX qw( strftime );
while (<>) {
my $ln = $_;
if ($ln =~ /^(\d+)\.(\d+): (.*)/) {
my $time_sec = $1;
my $usec = $2;
my $rest = $3;
my $usec_pad = sprintf("%06d", $usec);
my $dt = strftime("%Y-%m-%d %H:%M:%S", localtime($time_sec));
print "$dt.$usec_pad $rest\n";
}
elsif ($ln =~ /^(\d+): (.*)/) {
my $tot_msec = $1;
my $rest = $2;
my $sec = int($tot_msec / 1000);
my $msec = $tot_msec % 1000;
my $msec_pad = sprintf("%03d", $msec);
my $dt = strftime("%Y-%m-%d %H:%M:%S", localtime($sec));
print "$dt.$msec_pad $rest\n";
}
else {
print $ln;
}
}

460
lanforge/lanforge-scripts/imix.pl Executable file
View File

@@ -0,0 +1,460 @@
#!/usr/bin/perl
# IMIX Throughput Test
#
# Uses a binary search algorithm to determine the maximum throughput at which
# a specified percent packet loss occurs and a maximum latency is allowed
# for a given theoretical throughput rate at different packet sizes suggested
# by IMIX literature.
#
# USAGE: perl imix.pl lf_host port-1 port-2 theoretical_rate max_latency
# max_drop_percentage binary_search_attempts endpoint_duration test_loops
#
# Example: perl imix.pl 192.168.100.192 1 2 10000000 200 10 9 10 1
# Un-buffer output
$| = 1;
use strict;
use Net::Telnet ();
use LANforge::Port;
use LANforge::Utils;
use LANforge::Endpoint;
my $script_name = "imix.pl";
my $lfmgr_host = undef;
my $lfmgr_port = 4001;
my $test_mgr = "imix_tm";
my $shelf = 1;
# This sets up connections between 2 LANforge machines
my $lf1 = 1; # Minor Resource EID.
my $lf2 = 1; # Set to "" or same as $lf1 if we have no second machine. For second machine set
# to second Resource minor EID to create mac-vlans on it.
# Port pairs. These are the ports that should be talking to each other.
# i.e. the third column in lf1_ports talks to the third column in lf2_ports.
# EIDs or aliases can be used.
# Port pairs must match on each shelf - will enhance to allow any pair on each shelf.
#my @lf1_ports = (1); #, 2, 3);
#my @lf2_ports = (2); #, 2, 3);
my @lf1_ports = ("eth2"); #, "eth0");
my @lf2_ports = ("eth3"); #, "eth1");
my @lf1_port_ips = ("172.1.1.100");
my @lf2_port_ips = ("172.1.1.101");
my @lf1_port_gws = ("172.1.1.1");
my @lf2_port_gws = ("172.1.1.1");
# IMIX Type Definition for UDP
# Packet sizes are in bytes of UDP payload
my @cx_types = ("lf_udp", "lf_udp", "lf_udp", "lf_udp", "lf_udp", "lf_udp", "lf_udp", "lf_udp");
my @min_pkt_szs = ( 22, 86, 214, 470, 982, 1238, 1458, 1472);
my @max_pkt_szs = ( 22, 86, 214, 470, 982, 1238, 1458, 1472);
my @tput_rates = ( 1000000, 4000000, 12000000, 45000000,155000000,155000000,155000000,155000000);
my $tput = 1544000; # Network/Device Under Test Maximum Theoretical Throughput in bps.
my $max_latency = 1; # Maximum Latency in miliseconds, allowed before adjusting rate down.
my $drop_percent = 0.0001; # Maximum Drop-Percentage allowed before adjusting rate down.
my $binary_search_attempts = 9; # Number of attempts to find throughput for a given pkt size and $drop_percent.
my $endp_wait_for_update = 10; # Seconds allowed for endpoints to update.
my $endp_duration = 30; # Seconds endpoints are allowed to run which can affect results.
my $loop_max = 1; # Number of times the entire test will be run
my @endp_drops = ();
########################################################################
# Nothing to configure below here, most likely.
########################################################################
# Parse cmd-line args
my $i;
for ($i = 0; $i<@ARGV; $i++) {
my $var = $ARGV[$i];
if ($var =~ m/(\S+)=(.*)/) {
my $arg = $1;
my $val = $2;
handleCmdLineArg($arg, $val);
}
else {
handleCmdLineArg($var);
}
}
if ($lfmgr_host == undef) {
print "\nYou must define a LANforge Manager!!!\n\n"
. "For example:\n"
. "./$script_name mgr=locahost\n"
. "OR\n"
. "./$script_name mgr=192.168.1.101\n\n";
printHelp();
exit (1);
}
my $min_rate = $tput;
my $max_rate = $min_rate;
my $report_timer = 1000; # Report timer for endpoints.
my @endpoint_names = (); #will be added to as they are created
my @cx_names = ();
# Open connection to the LANforge server.
my $t = new Net::Telnet(Prompt => '/default\@btbits\>\>/');
my $timeout = 60;
$t->open(Host => $lfmgr_host,
Port => $lfmgr_port,
Timeout => $timeout);
$t->waitfor("/btbits\>\>/");
# Configure our utils.
my $utils = new LANforge::Utils();
$utils->telnet($t); # Set our telnet object.
$utils->cli_send_silent(0); # Do show input to CLI
$utils->cli_rcv_silent(0); # Repress output from CLI ??
my $dt = "";
my $loop = 0;
for ($loop = 0; $loop<$loop_max; $loop++) {
$dt = `date`;
chomp($dt);
print "\n\n***** Starting loop: $loop at: $dt *****\n\n";
@endpoint_names = ();
@cx_names = ();
initToDefaults();
# Now, add back the test manager we will be using
doCmd("add_tm $test_mgr");
doCmd("tm_register $test_mgr default"); #Add default user
doCmd("tm_register $test_mgr default_gui"); #Add default GUI user
# Add some IP addresses to the ports
initIpAddresses();
# Add our endpoints
addCrossConnects();
print "Loop $loop: Done adding CXs.\n";
print "Pause $endp_wait_for_update seconds for endpoints to update.\n";
sleep($endp_wait_for_update);
# Start Cross-Connects
for (my $q=0; $q<@cx_names; $q++) {
my $cmd = "set_cx_state $test_mgr " . $cx_names[$q] . " RUNNING";
doCmd($cmd);
my @next_adj = (int($max_rate / 2), int($max_rate / 2));
my @current_rate = ($max_rate, $max_rate);
my @last_current_rate = (0,0);
my @new_rate = (0,0);
my $flag = 0;
my $best_rate = 0;
my $adj_count = 0;
my $p1 = $q+$q;
my $p2 = $p1+1;
for ($adj_count=0; $adj_count < $binary_search_attempts; $adj_count++) {
doCmd("clear_endp_counters");
doCmd("clear_cx_counters");
print "Adjustment Period: $adj_count\n";
print "sleep $endp_duration seconds\n";
sleep($endp_duration);
for (my $p=$p1; $p<=$p2; $p++) {
my $endp1 = new LANforge::Endpoint();
$utils->updateEndpoint($endp1, $endpoint_names[$p]);
my $en1 = $endp1->rx_drop_seq();
my $en2 = $endp1->port_id();
my $en3 = $endp1->real_rx_rate();
my $lat = $endp1->avg_latency();
my $i = $p-$p1;
if ( $en1 > $drop_percent || $lat > $max_latency ) {
print "RATE DOWN: Percent Dropped is $en1 : Port is $en2 : Real RX Rate is: $en3 : Latency: $lat\n";
$new_rate[$i] = $current_rate[$i] - $next_adj[$i];
}
elsif ( $current_rate[$i] < $max_rate ) {
print "RATE UP: Percent Dropped is $en1 : Port is $en2 : Real RX Rate is: $en3 : Latency: $lat\n";
$last_current_rate[$i] = $current_rate[$i];
$new_rate[$i] = $current_rate[$i] + $next_adj[$i];
}
else {
# packet size is too small for this LF system to generate at this rate
# TO DO: make an imix script that uses armageddon instead of user-space UDP
$best_rate = $en3;
$flag = 1;
$adj_count = $binary_search_attempts;
last;
}
$next_adj[$i] = int($next_adj[$i] / 2);
$current_rate[$i] = $new_rate[$i];
} #for $endpoint_names
# set both endpoints to zero rate to quiesce
my $cmd = "add_endp " . $endpoint_names[$p1] . " $shelf $lf1 " . " NA lf_udp " .
" -1 NO 0 0 NA NA NA NA ";
doCmd($cmd);
$cmd = "add_endp " . $endpoint_names[$p2] . " $shelf $lf1 " . " NA lf_udp " .
" -1 NO 0 0 NA NA NA NA ";
doCmd($cmd);
sleep(5);
# set both endpoints to new rate
$cmd = "add_endp " . $endpoint_names[$p1] . " $shelf $lf1 " . " NA lf_udp " .
" -1 NO " . $new_rate[0] . " " . $new_rate[0] . " NA NA NA NA ";
doCmd($cmd);
$cmd = "add_endp " . $endpoint_names[$p2] . " $shelf $lf1 " . " NA lf_udp " .
" -1 NO " . $new_rate[1] . " " . $new_rate[1] . " NA NA NA NA ";
doCmd($cmd);
} #for $adj_count
doCmd("set_cx_state $test_mgr " . $cx_names[$q] . " STOPPED");
doCmd("clear_cx_counters");
doCmd("clear_port_counters");
if ( $flag != 1 ) {
print "\n\n*********************************************************\n";
print "Theoretical Throughput: $max_rate bps.\n";
print "IMIX Packet Size: $min_pkt_szs[$q] byte payload.\n";
print "Loss and Latency Allowance: $drop_percent % drops and $max_latency ms latency.\n";
print "Measured Throughput on Endpoint 1: $last_current_rate[0] bps.\n";
print "Measured Throughput on Endpoint 2: $last_current_rate[1] bps.\n\n";
sleep(10);
}
else {
print "\n\nMax Rate of $max_rate bps is too high for $min_pkt_szs[$q] byte packet size.\n";
print "At $min_pkt_szs[$q] byte packet size, the best user-space rate is: $best_rate bps.\n\n";
}
} #for cross-connects
} #for $loop_max
initPortsToDefault();
$dt = `date`;
chomp($dt);
print "Done at: $dt\n\n";
exit(0);
sub initToDefaults {
# Clean up database if stuff exists
doCmd("rm_cx $test_mgr all");
doCmd("rm_endp YES_ALL");
doCmd("rm_test_mgr $test_mgr");
initPortsToDefault();
}#initToDefaults
# Wait until the system can update a port..
sub throttleCard {
my $s = shift;
my $c = shift;
my $p1 = new LANforge::Port();
$utils->updatePort($p1, $s, $c, 1);
}#throttle
sub initPortsToDefault {
clearMacVlanPorts($shelf, $lf1);
if ($lf2 ne "") {
clearMacVlanPorts($shelf, $lf2);
}
throttleCard($shelf, $lf1);
if ($lf2 ne "") {
throttleCard($shelf, $lf2);
}
# Set all ports we are messing with to known state.
my $i = 0;
for ($i = 0; $i<@lf1_ports; $i++) {
my $tmp = $lf1_ports[$i];
my $tmp2 = $lf2_ports[$i];
doCmd("set_port $shelf $lf1 $tmp 0.0.0.0 0.0.0.0 0.0.0.0 NA NA NA");
if ($lf2 ne "") {
doCmd("set_port $shelf $lf2 $tmp2 0.0.0.0 0.0.0.0 0.0.0.0 NA NA NA");
}
}
}
sub clearMacVlanPorts {
my $s = shift;
my $c = shift;
my $i;
my $found_one = 1;
my @ports = ();
while ($found_one) {
$found_one = 0;
doCmd("probe_ports");
# Clear out any existing MAC-VLAN ports.
$utils->error("");
@ports = $utils->getPortListing($s, $c);
my $mx = @ports;
print "Found $mx ports for card: $shelf.$lf1\n";
if (($mx == 0) || ($utils->error() =~ /Timed out/g)) {
# System is too backlogged to answer, wait a bit
print " Will try listing ports again in a few seconds...system is backlogged now!\n";
sleep(5);
$found_one = 1;
next;
}
my $throttle = 0;
for ($i = 0; $i<$mx; $i++) {
if ($ports[$i]->isMacVlan()) {
doCmd($ports[$i]->getDeleteCmd());
} #fi isMacVlan
}
}
}
sub initIpAddresses {
# Set all ports we are messing with to known state.
my $i = 0;
for ($i = 0; $i<@lf1_ports; $i++) {
my $tmp = $lf1_ports[$i];
my $tmp2 = $lf2_ports[$i];
my $cmd = "set_port $shelf $lf1 $tmp " . $lf1_port_ips[$i] . " 255.255.255.0 " .
$lf1_port_gws[$i] . " NA NA NA";
doCmd($cmd);
$cmd = "set_port $shelf $lf2 $tmp2 " . $lf2_port_ips[$i] . " 255.255.255.0 " .
$lf2_port_gws[$i] . " NA NA NA";
doCmd($cmd);
}
}
sub addCrossConnects {
my $ep = 0;
my $cx = 0;
my $i = 0;
for ($i = 0; $i<@cx_types; $i++) {
my $j = 0;
for ($j = 0; $j<@lf1_ports; $j++) {
my $burst = "NO";
my $szrnd = "NO";
my $pattern = "increasing";
my $ep1 = "endp-${ep}-TX";
$ep++;
my $ep2 = "endp-${ep}-RX";
$ep++;
@endpoint_names = (@endpoint_names, $ep1, $ep2);
my $cmd = "add_endp $ep1 $shelf $lf1 " . $lf1_ports[$j] . " " . @cx_types[$i] .
" -1 $burst $min_rate $max_rate $szrnd " . $min_pkt_szs[$i] .
" " . $max_pkt_szs[$i] . " $pattern ";
doCmd($cmd);
$cmd = "add_endp $ep2 $shelf $lf2 " . $lf2_ports[$j] . " " . @cx_types[$i] .
" -1 $burst $min_rate $max_rate $szrnd " . $min_pkt_szs[$i] .
" " . $max_pkt_szs[$i] . " $pattern ";
doCmd($cmd);
# Now, add the cross-connects
my $cx_name = "cx-${cx}";
$cmd = "add_cx $cx_name $test_mgr $ep1 $ep2";
doCmd($cmd);
doCmd("set_cx_report_timer $test_mgr $cx_name $report_timer");
$cx++;
@cx_names = (@cx_names, $cx_name);
}#for all ports
}#for all endpoint types
}#addCrossConnects
sub doCmd {
my $cmd = shift;
print ">>> $cmd\n";
$t->print($cmd);
my @rslt = $t->waitfor(Match => '/ \>\>RSLT:(.*)/',
Timeout => $timeout);
print "**************\n @rslt ................\n\n";
#sleep(1);
}
sub printHelp {
print "\n"
. "USAGE: mgr=[ip-of-mgr] lf1=X lf2=Y\n"
. " lf1_ports=[\"1 2 3\"|\"eth2 eth3\"] lf2_ports=[\"4 5 6\"|\"eth4 eth5\"]\n"
. " rate=1544000 (bps) max_delay=1 (ms) max_drop=0.0001 (%) search_tries=9\n"
. " ep_wait=10 (s) ep_run=30 (s) imix_loops=1\n"
. "\n";
}
sub handleCmdLineArg {
my $arg = $_[0];
my $val = $_[1];
if ($arg eq "mgr") {
$lfmgr_host = $val;
}
elsif ($arg eq "lf1") {
$lf1 = $val;
}
elsif ($arg eq "lf2") {
$lf2 = $val;
}
elsif ($arg eq "lf1_ports") {
@lf1_ports = split(/ /, $val);
}
elsif ($arg eq "lf2_ports") {
@lf2_ports = split(/ /, $val);
}
elsif ($arg eq "rate") {
$tput = $val;
}
elsif ($arg eq "max_delay") {
$max_latency = $val;
}
elsif ($arg eq "max_drop") {
$drop_percent = $val;
}
elsif ($arg eq "search_tries") {
$binary_search_attempts = $val;
}
elsif ($arg eq "ep_wait") {
$endp_wait_for_update = $val;
}
elsif ($arg eq "ep_run") {
$endp_duration = $val;
}
elsif ($arg eq "imix_loops") {
$loop_max = $val;
}
else {
printHelp();
exit(1);
}
} # handleCmdLineArg

View File

@@ -0,0 +1,46 @@
#!/bin/bash
# This bash script installs Influx, Grafana, and Ghost on Fedora or CentOS.
# Run this script as a normal user with sudo access.
# You need to provide your username at the beginning of the script.
# There are a few fields you will need to enter when this installs Ghost, and you will be prompted by the script.
# Many scripts in this library are built around Influx, Grafana, and Ghost. Influx is a time series database,
# Grafana has dashboards which display the data stored in Influx,
# and Ghost is a blogging platform which creates an easy way for a user to view automated reports which are built using LANforge scripts
# Once a user uses this script, the user can use those features with the credentials for the system this script sets up.
# After running this script, Grafana is at port 3000, Influx is at port 8086, and Ghost is at port 2368
# The user will need to login to those through a web browser to create login credentials, and find API tokens.
# These API tokens are needed to run many scripts in LANforge scripts with these three programs.
echo Type in your username here
read -r USER
#Influx installation
wget https://dl.influxdata.com/influxdb/releases/influxdb2-2.0.4.x86_64.rpm
sudo yum localinstall influxdb2-2.0.4.x86_64.rpm
sudo service influxdb start
sudo service influxdb enable
#Grafana installation
wget https://dl.grafana.com/oss/release/grafana-7.5.3-1.x86_64.rpm
sudo yum localinstall grafana-7.5.3-1.x86_64.rpm -y
sudo systemctl start grafana-server
sudo systemctl enable grafana-server
#Ghost installation
sudo adduser ghost
sudo usermod -aG sudo ghost
sudo ufw allow 'Nginx Full'
curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash
sudo npm install ghost-cli@latest -g
# Ensure that NPM is up to date
npm cache verify
sudo npm install -g n
sudo n stable
curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash
npm install ghost-cli@latest -g
sudo mkdir -p /var/www/ghostsite
sudo chown ${USER}:${USER} /var/www/ghostsite
sudo chmod 775 /var/www/ghostsite
cd /var/www/ghostsite
ghost install local

View File

@@ -0,0 +1,52 @@
#!/bin/bash
#This script installs Influx, Grafana, and Ghost on Ubuntu.
#Run this script as a normal user with sudo access.
#You need to provide your username at the beginning of the script.
#There are a few fields you will need to enter when it is installing Ghost, and you will be prompted by the script.
#Lanforge scripts is built around Influx, Grafana, and Ghost. Influx is a time series database,
#Grafana has dashboards which display the data stored in Influx,
#and Ghost is a blogging platform which creates an easy way for a user to view automated reports which are built using LANforge scripts
#Once a user uses this script, the user can use those features with the credentials for the system this script sets up.
#After running this script, Grafana is accessible through port 3000, Influx is at port 8086, and Ghost is accessible at 2368
#The user will need to login to those through a web browser to create login credentials, and find API tokens.
#These API tokens are needed to run many scripts in LANforge scripts with the functionality these three programs provide.
#Update necessary parts of system
echo Type in your username here
read -r USER
sudo apt-get update && sudo apt-get upgrade -y
sudo apt-get install nginx mysql-server nodejs npm -y
#Influx installation
wget https://dl.influxdata.com/influxdb/releases/influxdb2-2.0.7-amd64.deb
sudo dpkg -i influxdb2-2.0.7-amd64.deb
sudo systemctl unmask influxdb
sudo systemctl start influxdb
sudo systemctl enable influxdb
#Grafana installation
sudo apt-get install -y adduser libfontconfig1
wget https://dl.grafana.com/oss/release/grafana_8.0.5_amd64.deb
sudo dpkg -i grafana_8.0.5_amd64.deb
sudo systemctl start grafana-server
sudo systemctl enable grafana-server
#Ghost installation
sudo adduser ghost
sudo usermod -aG sudo ghost
sudo ufw allow 'Nginx Full'
curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash
sudo npm install ghost-cli@latest -g
# Ensure that NPM is up to date
npm cache verify
sudo npm install -g n
sudo n stable
curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash
npm install ghost-cli@latest -g
sudo mkdir -p /var/www/ghostsite
sudo chown ${USER}:${USER} /var/www/ghostsite
sudo chmod 775 /var/www/ghostsite
cd /var/www/ghostsite
ghost install local

View File

@@ -0,0 +1,26 @@
#!/bin/bash
set -x
./lf_associate_ap.pl -m ct524-genia.jbr --resource 1 --radio wiphy2 --action del_all_phy --port_del wiphy0
./lf_associate_ap.pl -m ct524-genia.jbr --resource 1 --radio wiphy2 --action del_all_phy --port_del wiphy1
./lf_associate_ap.pl -m ct524-genia.jbr --resource 1 --radio wiphy2 --action del_all_phy --port_del wiphy2
./lf_associate_ap.pl -m ct524-genia.jbr --resource 1 --radio wiphy2 --action del_all_phy --port_del wiphy3
sleep 5
while read line; do
echo "Orphan: $line"
hunks=($line)
./lf_portmod.pl -m ct524-genia.jbr --cmd delete --port_name "${hunks[1]}"
done < <(./lf_portmod.pl -m ct524-genia.jbr --resource 1 --list_port_names | grep sta)
sleep 5
echo "" > /tmp/clilog
now=`date +%Y-%m-%d-%H%M%S`
sudo tcpdump -eSni br0 -B 2048 -w "/tmp/dump-${now}" host ct524-genia.jbr.candelatech.com and port 4001 &
sleep 5
./lf_associate_ap.pl -m ct524-genia.jbr --resource 1 --radio wiphy2 --action add --security wpa2 \
--ssid jedway-wpa2-x64-3-1 --passphrase jedway-wpa2-x64-3-1 --wifi_mode anAC --first_sta sta2000 \
--first_ip DHCP --num_stations 30 --log_cli /tmp/clilog
sleep 1
sudo killall tcpdump
set +x
echo done

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,78 @@
#!/usr/bin/perl -w
use strict;
use warnings;
use diagnostics;
use Carp;
use Time::HiRes qw(usleep);
$SIG{ __DIE__ } = sub { Carp::confess( @_ ) };
$SIG{ __WARN__ } = sub { Carp::confess( @_ ) };
# Un-buffer output
$| = 1;
use Getopt::Long;
use JSON::XS;
use HTTP::Request;
use LWP;
use LWP::UserAgent;
use Data::Dumper;
use JSON;
use lib '/home/lanforge/scripts';
use lib "../";
use lib "./";
use LANforge::JsonUtils qw(logg err json_request get_links_from get_thru json_post get_port_names flatten_list);
package main;
# Default values for ye ole cmd-line args.
our $Resource = 1;
our $quiet = "yes";
our $Host = "localhost";
our $Port = 8080;
our $HostUri = "http://$Host:$Port";
our $Web = LWP::UserAgent->new;
our $Decoder = JSON->new->utf8;
my $usage = qq("$0 --host {ip or hostname} # connect to this
--port {port number} # defaults to 8080
);
##
## M A I N
##
GetOptions
(
'host=s' => \$::Host,
'port=i' => \$::Port,
) || (print($usage) && exit(1));
$::HostUri = "http://$Host:$Port";
my $rh_update = {
'shelf'=>1, 'resource'=>1, 'port'=>'all', 'probe_flags'=>'0x9'
};
my $uri = "/shelf/1";
my $rh = json_request($uri);
my $ra_links = get_links_from($rh, 'resources');
my @links2= ();
my $ra_alias_links = [];
logg("\nRefreshing after setting up... ");
my $rh_response = json_post("/cli-json/nc_show_ports", $rh_update);
# wait on ports up
my $ports_still_down = 1;
while ($ports_still_down > 0) {
$rh = json_request("/port/1/1/list?fields=_links,port,device,down");
flatten_list($rh, 'interfaces');
$ports_still_down=0;
for my $rh_p (values %{$rh->{'flat_list'}}) {
next unless $rh_p->{'device'} =~ /^sta/;
#print "$rh_p->{'device'} is $rh_p->{'down'} ";
$ports_still_down++
if ($rh_p->{'down'});
}
print "ports down: $ports_still_down ";
$rh_response = json_post("/cli-json/nc_show_ports", $rh_update);
sleep 1;
}
#

View File

@@ -0,0 +1,318 @@
#!/usr/bin/perl -w
use strict;
use warnings;
use diagnostics;
use Carp;
$SIG{ __DIE__ } = sub { Carp::confess( @_ ) };
$SIG{ __WARN__ } = sub { Carp::confess( @_ ) };
# Un-buffer output
$| = 1;
use Getopt::Long;
use JSON::XS;
use HTTP::Request;
use LWP;
use LWP::UserAgent;
use Data::Dumper;
use Time::HiRes qw(usleep);
use JSON;
use lib '/home/lanforge/scripts';
use LANforge::JsonUtils qw(logg err json_request get_links_from get_thru json_post get_port_names flatten_list);
package main;
# Default values for ye ole cmd-line args.
our $Resource = 1;
our $quiet = "yes";
our $Host = "localhost";
our $Port = 8080;
our $HostUri = "http://$Host:$Port";
our $Web = LWP::UserAgent->new;
our $Decoder = JSON->new->utf8;
our $ssid;
our $security;
our $passphrase;
my $usage = qq("$0 --host {ip or hostname} # connect to this
--port {port number} # defaults to 8080
);
##
## M A I N
##
my $des_resource = 6;
GetOptions
(
'host=s' => \$::Host,
'port=i' => \$::Port,
'resource=i' => \$des_resource
) || (print($usage) && exit(1));
$::HostUri = "http://$Host:$Port";
my $uri = "/shelf/1";
my $rh = json_request($uri);
my $ra_links = get_links_from($rh, 'resources');
my @ports_up= ();
# TODO: make this a JsonUtils::list_ports()
$uri = "/port/1/${des_resource}/list?fields=alias,device,down,phantom,port";
logg("requesting $uri\n");
$rh = json_request($uri);
#print Dumper($rh);
flatten_list($rh, 'interfaces');
#print "\n- 1 -------------------------------------------------------------\n";
#print Dumper($rh->{'flat_list'});
#print "\n- 2 -------------------------------------------------------------\n";
#print Dumper(\(keys %{$rh->{'flat_list'}}));
for my $rh_p (keys %{$rh->{'flat_list'}}) {
#print "\n- 1 -------------------------------------------------------------\n";
#print Dumper($rh->{'flat_list'}->{$rh_p});
#print "\n".ref ($rh->{'flat_list'}->{$rh_p}->{'down'});
#print "\n".$rh->{'flat_list'}->{$rh_p}->{'down'}();
#print "\n- 2 -------------------------------------------------------------\n";
#.$rh->{'flat_list'}->{$rh_p}->{'down'};
my $onoff = $rh->{'flat_list'}->{$rh_p}->{'down'};
#print "truth? $onoff\n";
if ($onoff) { # should force a truthy value
push(@ports_up, $rh_p);
}
}
#print "\n- 3 -------------------------------------------------------------\n";
#print Dumper(\@ports_up);
#print "\n- 4 -------------------------------------------------------------\n";
# find first station
my $rh_sta;
#print "\n- 5 -------------------------------------------------------------\n";
#print Dumper(\@ports_up);
#print "\n- 5 -------------------------------------------------------------\n";
for my $rh_up (@ports_up) {
#print "\n- 6 -------------------------------------------------------------\n";
#print Dumper($rh->{'flat_list'});
#print "\n- 6 -------------------------------------------------------------\n";
my $eid = $rh->{'flat_list'}->{$rh_up}->{'port'};
print ("rhup: $rh_up; EID $eid\n");
my @hunks = split(/[.]/, $eid);
if ($hunks[1]) {
$rh_sta = $rh_up;
}
}
if (!defined $rh_sta) {
die("Unable to find a virtual station. Is one up?");
}
# delete old CXes and old endpoints
# TODO: collect_cx_names
my $rh_cxlist = json_request("/cx/list");
my @cx_names = ();
for my $cx_name (sort keys %$rh_cxlist) {
#print " cx_name[$cx_name]";
next if (ref $rh_cxlist->{$cx_name} ne "HASH");
next if (!defined $rh_cxlist->{$cx_name}->{"name"});
next if ($rh_cxlist->{$cx_name}->{"name"} eq "uri");
push(@cx_names, $rh_cxlist->{$cx_name}->{"name"});
}
print "\nRemoving cx: ";
$uri = "/cli-json/rm_cx";
for my $cx_name (sort @cx_names) {
print "$cx_name ";
$rh = {
"test_mgr" => "all",
"cx_name" => $cx_name
};
json_post($uri, $rh);
}
sleep 1;
my $rh_endplist = json_request("/endp/list");
print "\nRemoving endpoints: ";
flatten_list($rh_endplist, 'endpoint');
#print Dumper($rh_endplist->{'flat_list'});
#sleep 10;
my @endp_names = ();
for my $ep_name (keys %{$rh_endplist->{'flat_list'}}) {
next if (!defined $ep_name);
next if ($ep_name eq "");
next if ((ref $ep_name) eq "ARRAY");
next if (!defined $rh_endplist->{'flat_list'}->{$ep_name}->{"name"});
next if ($rh_endplist->{'flat_list'}->{$ep_name}->{"name"} eq "");
#print "epn:".Dumper($rh_endplist->{'flat_list'}->{$ep_name}->{"name"});
push(@endp_names, $ep_name);
}
$uri = "/cli-json/rm_endp";
for my $ep_name (@endp_names) {
if (!defined $ep_name || $ep_name =~/^\s*$/ || (ref $ep_name) eq "ARRAY") {
print " skipping ep_name[$ep_name]";
print Dumper(\$ep_name);
next;
}
print "[$ep_name] ";
#usleep(500000);
$rh = { "endp_name" => $ep_name };
json_post($uri, $rh);
}
print "\nRefreshing...";
my $h = {"endpoint"=>"all"};
json_request("/cli-json/nc_show_endpoints", $h);
sleep 1;
$h = {"test_mgr"=>"all", "cross_connect"=>"all"};
json_request("/cli-json/show_cxe", $h);
# assume resource 1, eth1 is present, and create an endpoint to it
# -A and -B are expected convention for endpoint names
# create 10 endpoints
my $rh_ports = json_request("/port/1/$des_resource/list");
flatten_list($rh_ports, 'interfaces');
my $rh_endp_A = {
'alias' => 'udp_json',
'shelf' => 1,
'resource' => 1,
'port' => 'b1000', # or eth1
'type' => 'lf_udp',
'ip_port' => -1,
'is_rate_bursty' => 'NO',
'min_rate' => 100000,
'min_pkt' => -1,
'max_pkt' => -1,
'payload_pattern' => 'increasing',
'multi_conn' => 0
};
my $rh_endp_B = {
'alias' => 'udp_json',
'shelf' => 1,
'resource' => $des_resource,
'port' => 'unset',
'type' => 'lf_udp',
'ip_port' => -1,
'is_rate_bursty' => 'NO',
'min_rate' => 12800,
'min_pkt' => -1,
'max_pkt' => -1,
'payload_pattern' => 'increasing',
'multi_conn' => 0
};
my $rh_cx = {
"alias" => 'udp_json',
"test_mgr" => 'default_tm',
'tx_endp' => '',
'rx_endp' => ''
};
$h = {"endpoint"=>"all"};
json_request("/cli-json/nc_show_endpoints", $h);
$h = {"test_mgr"=>"all", "cross_connect"=>"all"};
json_request("/cli-json/show_cxe", $h);
sleep 1;
print "\nConstructing new Endpoints: ";
my $num_ports = scalar keys(%{$rh_ports->{'flat_list'}});
my $num_cx = 0;
for my $rh_p (values %{$rh_ports->{'flat_list'}}) {
last if ($num_cx >= ($num_ports-1));
next if ($rh_p->{'alias'} !~ /^v*sta/);
my $end_a_alias = "udp_json_$num_cx-A";
my $end_b_alias = "udp_json_$num_cx-B";
my $port_b = $rh_p->{'alias'};
print "$port_b ";
$rh_endp_B->{'port'} = $port_b;
$rh_endp_B->{'alias'} = $end_b_alias;
$rh_endp_A->{'alias'} = $end_a_alias;
$num_cx++;
json_post("/cli-json/add_endp", $rh_endp_A);
json_post("/cli-json/add_endp", $rh_endp_B);
}
print "\nRefreshing...";
$h = {"endpoint"=>"all"};
json_request("/cli-json/nc_show_endpoints", $h);
sleep 1;
print "\nConstructing new CX: ";
$num_cx = 0;
for my $rh_p (values %{$rh_ports->{'flat_list'}}) {
last if ($num_cx >= ($num_ports-1));
next if ($rh_p->{'alias'} !~ /^v*sta/);
my $end_a_alias = "udp_json_${num_cx}-A";
my $end_b_alias = "udp_json_${num_cx}-B";
my $port_b = $rh_p->{'alias'};
my $cx_alias = "udp_json_".$num_cx;
$rh_cx->{'alias'} = $cx_alias;
$rh_cx->{'tx_endp'} = $end_a_alias;
$rh_cx->{'rx_endp'} = $end_b_alias;
json_post("/cli-json/add_cx", $rh_cx);
print " $cx_alias";
$num_cx++;
}
print "\nRefreshing...";
$h = {"endpoint"=>"all"};
json_request("/cli-json/nc_show_endpoints", $h);
$rh_cxlist = json_request("/cx/list");
@cx_names = ();
for my $cx_name (sort keys %$rh_cxlist) {
next if (ref $rh_cxlist->{$cx_name} ne "HASH");
next if (!defined $rh_cxlist->{$cx_name}->{"name"});
push(@cx_names, $rh_cxlist->{$cx_name}->{"name"});
}
for my $cx_alias (sort @cx_names) {
my $rh_cx_t = {
'test_mgr' => 'default_tm',
'cx_name' => $cx_alias,
'milliseconds'=> 1000,
};
json_post("/cli-json/set_cx_report_timer", $rh_cx_t);
}
print "\nRefreshing...";
$h = {"endpoint"=>"all"};
json_request("/cli-json/nc_show_endpoints", $h);
sleep 1;
$h = {"test_mgr"=>"all", "cross_connect"=>"all"};
json_request("/cli-json/show_cxe", $h);
my $set_state = {
'test_mgr' => 'default_tm',
'cx_name' => 'udp_ex',
'cx_state' => 'RUNNING'
};
@cx_names = ();
$rh_cxlist = json_request("/cx/list");
for my $cx_name (sort keys %$rh_cxlist) {
next if (ref $rh_cxlist->{$cx_name} ne "HASH");
next if (!defined $rh_cxlist->{$cx_name}->{"name"});
push(@cx_names, $rh_cxlist->{$cx_name}->{"name"});
}
print "\nStarting: ";
for my $cxname (@cx_names) {
print " $cxname";
$set_state->{'cx_name'} = $cxname;
json_post("/cli-json/set_cx_state", $set_state);
}
sleep 1;
$set_state = {
'test_mgr' => 'default_tm',
'cx_name' => 'udp_ex',
'cx_state' => 'STOPPED'
};
print "\nStopping: ";
for my $cxname (@cx_names) {
$set_state->{'cx_name'} = $cxname;
print " $cxname";
json_post("/cli-json/set_cx_state", $set_state);
}
print "...done\n";
#

View File

@@ -0,0 +1,191 @@
#!/usr/bin/perl -w
use strict;
use warnings;
use diagnostics;
use Carp;
$SIG{ __DIE__ } = sub { Carp::confess( @_ ) };
$SIG{ __WARN__ } = sub { Carp::confess( @_ ) };
# Un-buffer output
$| = 1;
use Getopt::Long;
use JSON::XS;
use HTTP::Request;
use LWP;
use LWP::UserAgent;
use Data::Dumper;
use JSON;
use lib '/home/lanforge/scripts';
use lib "../";
use lib "./";
use LANforge::JsonUtils qw(logg err json_request get_links_from get_thru json_post get_port_names);
package main;
# Default values for ye ole cmd-line args.
our $Resource = 1;
our $quiet = "yes";
our $Host = "localhost";
our $Port = 8080;
our $HostUri = "http://$Host:$Port";
our $Web = LWP::UserAgent->new;
our $Decoder = JSON->new->utf8;
our $ssid;
our $security;
our $passphrase;
my $usage = qq("$0 --host {ip or hostname} # connect to this
--port {port number} # defaults to 8080
);
##
## M A I N
##
GetOptions
(
'host=s' => \$::Host,
'port=i' => \$::Port
) || (print($usage) && exit(1));
$::HostUri = "http://$Host:$Port";
my $uri = "/shelf/1";
my $rh = json_request($uri);
my $ra_links = get_links_from($rh, 'resources');
my @links2= ();
my $ra_alias_links = [];
# TODO: make this a JsonUtils::list_ports()
for $uri (@$ra_links) {
$uri =~ s{/resource}{/port}g;
$uri .= "/list";
#logg("requesting $uri");
$rh = json_request($uri);
#print Dumper($rh);
push( @$ra_alias_links, @{get_port_names($rh, 'interfaces')});
push(@links2, @{get_links_from($rh, 'interfaces')});
#logg("\nfound: ");
#logg(@links2);
}
#print Dumper($ra_alias_links);
my $rh_existing_cx = json_request("/cx/list");
#print Dumper($rh_existing_cx);
my $rh_existing_cxnames = {};
for my $eid (keys %$rh_existing_cx) {
next if ($eid !~ /^\d+\.\d+$/);
print "=================================================================================\n";
print Dumper($rh_existing_cx->{$eid});
print "=================================================================================\n";
my $rh_cx = $rh_existing_cx->{$eid};
print Dumper($rh_cx);
print "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==\n";
my $cx_n = $rh_cx->{'name'};
print " $cx_n \n";
$rh_existing_cxnames->{$cx_n} = $rh_cx;
}
# assume resource 1, eth1 is present, and create an endpoint to it
# -A and -B are expected convention for endpoint names
my $i=999;
for my $rh_alias_link (@$ra_alias_links) {
$i+=1;
if (defined ($rh_existing_cxnames->{"udp_$i"})) {
print " udp_$i already exists ";
next;
}
my $resourceB_uri = $rh_alias_link->{'uri'};
my ($resourceB) = $resourceB_uri =~ m{/port/1/(\d+)/};
if ($rh_alias_link->{'alias'} !~ /^sta/) {
print " skipping $rh_alias_link->{'alias'} ";
next;
}
my $rh_endp_A = {
'alias' => "udp_$i-A",
'shelf' => 1,
'resource' => 1,
'port' => 'b1000', # or eth1
'type' => 'lf_udp',
'ip_port' => -1,
'is_rate_bursty' => 'NO',
'min_rate' => 1000000,
'min_pkt' => -1,
'max_pkt' => -1,
'payload_pattern' => 'increasing',
'multi_conn' => 0
};
json_post("/cli-json/add_endp", $rh_endp_A);
print Dumper($rh_alias_link);
my $rh_endp_B = {
'alias' => "udp_$i-B",
'shelf' => 1,
'resource' => $resourceB,
'port' => $rh_alias_link->{'alias'},
'type' => 'lf_udp',
'ip_port' => -1,
'is_rate_bursty' => 'NO',
'min_rate' => 12800,
'min_pkt' => -1,
'max_pkt' => -1,
'payload_pattern' => 'increasing',
'multi_conn' => 0
};
json_post("/cli-json/add_endp", $rh_endp_B);
my $rh_cx ={
'alias' => "udp_$i",
'test_mgr' => 'default_tm',
'tx_endp' => "udp_$i-A",
'rx_endp' => "udp_$i-B"
};
json_post("/cli-json/add_cx", $rh_cx);
$rh_cx = {
'test_mgr' => 'default_tm',
'cx_name' => "udp_$i",
'milliseconds'=> 1000,
};
json_post("/cli-json/set_cx_report_timer", $rh_cx);
}
sleep (1);
$rh_existing_cx = json_request("/cx/list");
for my $eid (keys %$rh_existing_cx) {
next if ($eid !~ /\d+\.\d+/);
my $rh_cx = $rh_existing_cx->{$eid};
my $cx_name = $rh_cx->{'name'};
next if ($cx_name !~ /^udp_/);
print "run $cx_name ";
my $set_state = {
'test_mgr' => 'default_tm',
'cx_name' => $cx_name,
'cx_state' => 'RUNNING'
};
json_post("/cli-json/set_cx_state", $set_state);
}
print "\nLetting things run...";
sleep(2);
print "shutting them down...";
for my $eid (keys %$rh_existing_cx) {
next if ($eid !~ /\d+\.\d+/);
my $rh_cx = $rh_existing_cx->{$eid};
my $cx_name = $rh_cx->{'name'};
next if ($cx_name !~ /^udp_/);
print "q $cx_name ";
my $set_state = {
'test_mgr' => 'default_tm',
'cx_name' => $cx_name,
'cx_state' => 'QUIESCE'
};
json_post("/cli-json/set_cx_state", $set_state);
}
#

View File

@@ -0,0 +1,94 @@
#!/usr/bin/perl -w
use strict;
use warnings;
use diagnostics;
use Carp;
$SIG{ __DIE__ } = sub { Carp::confess( @_ ) };
$SIG{ __WARN__ } = sub { Carp::confess( @_ ) };
# Un-buffer output
$| = 1;
use Getopt::Long;
use JSON::XS;
use HTTP::Request;
use LWP;
use LWP::UserAgent;
use Data::Dumper;
use JSON;
use Time::HiRes qw(usleep nanosleep);
# using this is going to want high inotify instances, like mentioned here:
# sysctl fs.inotify.max_user_instances=256
# https://forum.proxmox.com/threads/unable-to-create-new-inotify-object-too-many-open-files-at-usr-share-perl5.23700/
use Proc::Background;
use lib '/home/lanforge/scripts';
use lib "../";
use lib "./";
use LANforge::JsonUtils qw(logg err json_request get_links_from get_thru json_post get_port_names);
package main;
# Default values for ye ole cmd-line args.
our $Resource = 1;
our $quiet = "yes";
our $Host = "localhost";
our $Port = 8080;
our $HostUri = "http://$Host:$Port";
our $Web = LWP::UserAgent->new;
our $Decoder = JSON->new->utf8;
our $ssid;
our $security;
our $passphrase;
my $usage = qq("$0 --host {ip or hostname} # connect to this
--port {port number} # defaults to 8080
);
##
## M A I N
##
GetOptions
(
'host=s' => \$::Host,
'port=i' => \$::Port
) || (print($usage) && exit(1));
$::HostUri = "http://$Host:$Port";
my $uri = "/shelf/1";
my $rh = json_request($uri);
my $ra_links = get_links_from($rh, 'resources');
my @links2= ();
my $ra_alias_links = [];
my $rh_existing_cx = json_request("/cx/list");
my $rh_existing_cxnames = {};
for my $eid (keys %$rh_existing_cx) {
next if ($eid !~ /^\d+\.\d+$/);
print "EID[$eid]:";
print "=================================================================================\n";
print Dumper($rh_existing_cx->{$eid});
print "=================================================================================\n";
my $rh_cx = $rh_existing_cx->{$eid};
print Dumper($rh_cx);
print "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==\n";
my $cx_n = $rh_cx->{'name'};
print " $cx_n ";
$rh_existing_cxnames->{$cx_n} = $rh_cx;
}
# $SIG{'CHLD'} = "wait_for_child_to_die"; # do we need this?
my @pids=();
for my $cx_name (keys %$rh_existing_cxnames) {
next if ($cx_name !~ /^udp_/);
my $proc = Proc::Background->new("./cx_test_helper.pl --cxname $cx_name");
push(@pids, $proc->pid());
print " cx_name $cx_name ".$proc->pid();
usleep(1500);
}
print "...done\n";
#

View File

@@ -0,0 +1,113 @@
#!/usr/bin/perl -w
use strict;
use warnings;
use diagnostics;
use Carp;
$SIG{ __DIE__ } = sub { Carp::confess( @_ ) };
$SIG{ __WARN__ } = sub { Carp::confess( @_ ) };
# Un-buffer output
$| = 1;
use Getopt::Long;
use JSON::XS;
use HTTP::Request;
use LWP;
use LWP::UserAgent;
use Data::Dumper;
use JSON;
use Linux::Inotify2;
use lib '/home/lanforge/scripts';
use lib "../";
use lib "./";
use LANforge::JsonUtils qw(logg err json_request get_links_from get_thru json_post get_port_names);
package main;
# Default values for ye ole cmd-line args.
our $Resource = 1;
our $quiet = "yes";
our $Host = "localhost";
our $Port = 8080;
our $HostUri = "http://$Host:$Port";
our $Web = LWP::UserAgent->new;
our $Decoder = JSON->new->utf8;
our $ssid;
our $security;
our $passphrase;
my $usage = qq("$0 --host {ip or hostname} # connect to this
--port {port number} # defaults to 8080
--cxname {name of connection to toggle}
);
##
## M A I N
##
our $cxname;
GetOptions
(
'host=s' => \$::Host,
'port=i' => \$::Port,
'cxname=s' => \$::cxname
) || (print($usage) && exit(1));
$::HostUri = "http://$Host:$Port";
# using this is going to want high inotify instances, like mentioned here:
# sysctl fs.inotify.max_user_instances=256
# https://forum.proxmox.com/threads/unable-to-create-new-inotify-object-too-many-open-files-at-usr-share-perl5.23700/
# wait until /tmp/startcx appears
our $toggle="startcx";
# create a new object
my $inotify_c = new Linux::Inotify2
or die "Unable to create new inotify object: $!" ;
my $inotify_d = new Linux::Inotify2
or die "Unable to create new inotify object: $!" ;
# create watch
$inotify_c->watch ("/tmp", IN_CREATE, sub {
my $event = shift;
print("I see $event->{name}\n");
return if ($event->{name} =~ /$toggle$/);
}) or die "watch creation failed" ;
while() {
my @events = $inotify_c->read;
last;
#unless (@events > 0) { print "read error: $!"; last; }
}
print "run $cxname ";
my $set_state = {
'test_mgr' => 'default_tm',
'cx_name' => $cxname,
'cx_state' => 'RUNNING'
};
json_post("/cli-json/set_cx_state", $set_state);
$inotify_d->watch ("/tmp", IN_DELETE, sub {
my $event = shift;
print("Delete seen for $event->{name}\n");
return if ($event->{name} =~ /$toggle$/);
}) or die "watch creation failed" ;
while() {
my @events = $inotify_d->read;
last;
#unless (@events > 0) { print "read error: $!"; last; }
}
print "quiesce $cxname ";
$set_state = {
'test_mgr' => 'default_tm',
'cx_name' => $cxname,
'cx_state' => 'QUIESCE'
};
json_post("/cli-json/set_cx_state", $set_state);
print "...done\n";

View File

@@ -0,0 +1,193 @@
#!/usr/bin/perl -w
use strict;
use warnings;
use diagnostics;
use Carp;
$SIG{ __DIE__ } = sub { Carp::confess( @_ ) };
$SIG{ __WARN__ } = sub { Carp::confess( @_ ) };
# Un-buffer output
$| = 1;
use Getopt::Long;
use JSON::XS;
use HTTP::Request;
use LWP;
use LWP::UserAgent;
use Data::Dumper;
use Time::HiRes qw(usleep);
use JSON;
use lib '/home/lanforge/scripts';
use lib "../";
use lib "./";
use LANforge::JsonUtils qw(logg err json_request get_links_from get_thru json_post get_port_names flatten_list);
package main;
# Default values for ye ole cmd-line args.
our $Resource = 1;
our $quiet = "yes";
our $Host = "localhost";
our $Port = 8080;
our $HostUri = "http://$Host:$Port";
our $Web = LWP::UserAgent->new;
our $Decoder = JSON->new->utf8;
our $ssid;
our $security;
our $passphrase;
my $usage = qq("$0 --action {add|list|show|annotate|del}
# list: lists all device names
# show: shows everything about device
# annotate: updates the note for the device
--note {"double quoted stuff"}
# del:
--name {Device Under Test name}
# when adding, use:
--name {Device Under Test name}
--img {picture name: c:\\stuff.png}
--sw_version {text}
--hw_version {text}
--mgt_ip {1.1.1.1}
--model_num {blanktronix345}
--serial_num {asdf1234}
--serial_port {1.2.ttyS0}
--api_id {0-127}
--lan_port {1.1.eth1}
--wan_port {1.1.eth2}
--ssid1 --passwd1 --ssid2 --passwd2 --ssid3 --passwd3 {stuff}
);
my $action;
my $name = "";
my $notes = "";
my $img_file = "";
my $sw_version = "";
my $hw_version = "";
my $mgt_ip = "";
my $model_num = "";
my $serial_num = "";
my $serial_port = "";
my $api_id = "";
my $lan_port = "";
my $wan_port = "";
my $ssid1 = "";
my $ssid2 = "";
my $ssid3 = "";
my $passwd1 = "";
my $passwd2 = "";
my $passwd3 = "";
my $help;
##
## M A I N
##
GetOptions( 'host=s' => \$::Host,
'action=s' => \$action,
'name=s' => \$name,
'notes=s' => \$notes,
'img_file=s' => \$img_file,
'sw_version=s' => \$sw_version,
'hw_version=s' => \$hw_version,
'mgt_ip=s' => \$mgt_ip,
'model_num=s' => \$model_num,
'serial_num=s' => \$serial_num,
'serial_port=s' => \$serial_port,
'api_id=s' => \$api_id,
'lan_port=s' => \$lan_port,
'wan_port=s' => \$wan_port,
'ssid1=s' => \$ssid1,
'ssid2=s' => \$ssid2,
'ssid3=s' => \$ssid3,
'passwd1=s' => \$passwd1,
'passwd2=s' => \$passwd2,
'passwd3=s' => \$passwd3,
'h|help' => \$help)
|| (print($usage) && exit(1));
if ($help) {
print $usage;
exit 0;
}
if (!defined $action) {
print $usage;
exit 1;
}
$::HostUri = "http://$Host:$Port";
my $DEBUGURI = "?__debug=1";
my $uri_args = ""; # ="$DEBUG_URI";
our $URI = "$::HostUri/dut";
our $Post_URI = "$::HostUri/cli-json";
if ($action eq "list") {
my $uri = "$::URI/list";
my $rh = json_request($uri);
flatten_list($rh, 'duts');
for my $rh_dut (sort keys %{$rh->{'flat_list'}}) {
print "$rh_dut\n";
}
exit 0;
}
if ($action eq "show") {
die ("show what DUT? use --name:\n$usage")
unless (defined $name && $name ne "");
my $uri = "$::URI/$name";
my $rh = json_request($uri);
print Dumper($rh->{'dut'});
die("unable to find DUT $name")
unless(defined $rh->{'dut'});
print Dumper($rh->{'dut'});
exit 0;
}
my $varnames = q(name img_file sw_version hw_version mgt_ip model_num serial_num serial_port api_id lan_port wan_port ssid1 ssid2 ssid3 passwd1 passwd2 passwd3);
if ($action eq "add") {
die ("show what DUT? use --name:\n$usage")
unless (defined $name && $name ne "");
my $rh_post = {};
for my $k (sort split(' ', $varnames)) {
my $v = eval("return \$$k;");
if ((defined $v) && ($v ne "")) {
$rh_post->{$k} = $v ;
}
else {
$rh_post->{$k} = "NA";
}
}
print Dumper($rh_post);
my $post_uri = "$::Post_URI/add_dut$DEBUGURI";
json_post($post_uri, $rh_post);
}
if ($action eq "annotate") {
die ("show what DUT? use --name:\n$usage")
unless (defined $name && $name ne "");
die ("what notes? use --notes:\n$usage")
unless (defined $notes);
my $rh_post = {};
my @note_lines=();
if ($notes eq "") {
$notes = '[BLANK]';
}
@note_lines = split(/\r?\n/, $notes);
if ($note_lines[0] ne "[BLANK]") {
unshift(@note_lines, "[BLANK]");
}
print Dumper(\@note_lines);
my $post_uri = "$::Post_URI/add_dut_notes${DEBUGURI}";
for my $note_line (@note_lines) {
print Dumper(\$note_line);
my $rh = {
'dut' => $name,
'text' => $note_line
};
json_post($post_uri, $rh);
}
}
#

View File

@@ -0,0 +1,108 @@
#!/bin/bash
unset proxy
unset http_proxy
set -x
set -e
ajson_h="Accept: application/json"
cjson_h="Content-type: application/json"
dbg=""
#dbg="__debug=1&"
R=1
W=wiphy0
M="10200"
N="10202"
SSID="jedway-wpa2-x2048-4-1"
KEY="jedway-wpa2-x2048-4-1"
#
# works for ifdown:
# set_port 1 8 sta8000 NA NA NA NA 1 NA NA NA NA 8388610
# works for ifup:
# set_port 1 8 sta8000 NA NA NA NA 0 NA NA NA NA 8388611
#
echo -n "Removing: "
for n in `seq $M $N`; do
n=${n:1}
echo -n "sta$n "
echo "shelf=1&resource=$R&port=sta$n" > /tmp/curl_data
curl -sq -H "$ajson_h" -X POST -d '@/tmp/curl_data' http://localhost:8080/cli-form/rm_vlan ||:
done
echo "."
sleep 2
echo -n "Adding: "
for n in `seq $M $N`; do
n=${n:1}
echo -n "${dbg}shelf=1&resource=$R&radio=$W" > /tmp/curl_data
echo -n "&sta_name=sta$n" >> /tmp/curl_data
echo -n "&flags=68727874560&ssid=idtest-1100-wpa2&key=idtest-1100-wpa2" >> /tmp/curl_data
echo -n "&mac=xx:xx:xx:xx:*:xx&mode=0&rate=DEFAULT" >> /tmp/curl_data
curl -sq -H "$ajson_h" -X POST -d '@/tmp/curl_data' http://localhost:8080/cli-form/add_sta ||:
done
sleep 2
for n in `seq $M $N`; do
n=${n:1}
echo -n "${dbg}shelf=1&resource=$R&port=sta$n" > /tmp/curl_data
echo -n '&current_flags=2147483648&interest=16384' >> /tmp/curl_data
curl -sq -H "$ajson_h" -X POST -d '@/tmp/curl_data' http://localhost:8080/cli-form/set_port ||:
done
echo "."
sleep 1
echo -n "Bringing ports up "
for n in `seq $M $N`; do
n=${n:1}
echo -n "${dbg}shelf=1&resource=$R&port=sta$n" > /tmp/curl_data
echo -n '&current_flags=0&interest=8388611' >> /tmp/curl_data
curl -sq -H "$ajson_h" -X POST -d '@/tmp/curl_data' http://localhost:8080/cli-form/set_port ||:
done
echo "."
sleep 3
echo -n "Querying ports "
for n in `seq $M $N`; do
curl -sq -H "$ajson_h" -X GET -o /tmp/response "http://localhost:8080/port/1/$R/sta$n"
echo -n "."
#if [ -s /tmp/response ]; then
# json_pp < /tmp/response
#fi
done
echo "...done."
exit
echo 'shelf=1&resource=3&port=sta3100' > /tmp/curl_data
curl -sq -H "$ajson_h" -X POST -d '@/tmp/curl_data' http://localhost:8080/cli-form/rm_vlan
sleep 1
echo 'shelf=1&resource=3&radio=wiphy1&sta_name=sta3100&flags=1024&ssid=idtest-1100-wpa2&nickname=sta3100&key=idtest-1100-wpa2&mac=XX:XX:XX:XX:*:*&flags_mask=1024' > /tmp/curl_data
curl -sq -H "$ajson_h" -X POST -d '@/tmp/curl_data' http://localhost:8080/cli-form/add_sta
sleep 1
rm -f /tmp/response
curl -sq -H "$ajson_h" -X GET -o /tmp/response http://localhost:8080/port/1/3/sta3100
if [ -s /tmp/response ]; then
json_pp < /tmp/response
fi
sleep 2
echo '{"shelf":1,"resource":3,"port":"sta3100"}' > /tmp/curl_data
curl -sq -H "$ajson_h" -H "$cjson_h" -X POST -d '@/tmp/curl_data' http://localhost:8080/cli-json/rm_vlan
sleep 2
echo '{"shelf":1,"resource":3,"radio":"wiphy1","sta_name":"sta3100","flags":1024,"ssid":idtest-1100-wpa2","nickname":"sta3100","key":"idtest-1100-wpa2","mac":"XX:XX:XX:XX:*:XX","flags_mask":1024}' > /tmp/curl_data
curl -sq -H "$ajson_h" -H "$cjson_h" -X POST -d '@/tmp/curl_data' http://localhost:8080/cli-json/add_sta
sleep 1
rm -f /tmp/response
curl -sq -H "$ajson_h" -X GET -o /tmp/response http://localhost:8080/port/1/3/sta3100
if [ -s /tmp/response ]; then
json_pp < /tmp/response
fi
#

View File

@@ -0,0 +1,252 @@
#!/bin/bash
set -e
unset proxy
unset http_proxy
Q='"'
q="'"
S='*'
application_json="application/json"
accept_json="Accept: $application_json"
accept_html='Accept: text/html'
accept_text='Accept: text/plain'
#accept_any="'Accept: */*'" # just dont use
content_plain='Content-Type: text/plain'
content_json="Content-Type: $application_json"
switches='-sqv'
function Kurl() {
echo =======================================================================================
echo curl $switches $@
echo =======================================================================================
#set -x
curl $switches "$@"
#set +x
echo ""
echo =======================================================================================
}
function Jurl() {
echo =J=====================================================================================
echo curl $switches -H "$accept_json" -H "$content_json" "$@"
echo =J=====================================================================================
set -x
curl $switches -H "$accept_json" -H "$content_json" "$@"
set +x
echo ""
echo =J=====================================================================================
}
url="http://localhost:8080"
if true; then
#echo 'shelf=1&resource=3&port=sta3000&mac=xx:xx:xx:xx:xx:*' > /tmp/curl_data
echo '{"shelf":1,"resource":1,"port":"eth3","current_flags":1, "interest":2}' > /tmp/curl_data
Jurl -X POST -d '@/tmp/curl_data' "http://localhost:8080/cli-json/set_port"
fi
exit
if false; then
Kurl $acept_json $url/resource/1/list
echo 'shelf=1&resource=3&port=sta3000&mac=xx:xx:xx:xx:xx:*' > /tmp/curl_data
curl -sqv -H 'Accept: application/json' -X POST -d '@/tmp/curl_data' http://localhost:8080/cli-form/set_port
url="http://localhost:8080/cli"
echo 'cmd=scan_wifi+1+3+sta30000' > /tmp/curl_data
Kurl -X POST -d '@/tmp/curl_data' -H "$accept_json" "$url"
# this is not supported
# url="http://localhost:8080/cli/scan_wifi"
# echo '1+3+sta30000' > /tmp/curl_data
# Kurl -X POST -d '@/tmp/curl_data' -H "$accept_json" "$url"
#Kurl -X GET "$url/help/set_wifi_radio?cli=1%203%20wiphy1%20NA%20-1%20NA%20NA%20NA%20NA%20NA%20NA%20NA%20NA%200x1%20NA"
#CMD: set_wifi_radio 1 3 wiphy1 NA -1 NA NA NA NA NA NA NA NA 0x1 NA
echo "shelf=1&resource=3&radio=wiphy1&channel=-1&antenna=3x3&flags=0x10" > /tmp/curl_data
Kurl -H "$accept_json" -X POST -d "@/tmp/curl_data" "$url/cli-form/set_wifi_radio"
#CMD: add_sta 1 3 wiphy1 sta3000 0 idtest-1000-open NA [BLANK] AUTO NA 00:0e:8e:98:64:45 8 NA NA NA NA NA 0
echo "shelf=1&resource=3&radio=wiphy1&sta_name=sta3000&flags=0&ssid=idtest-1000-open&key=[BLANK]&ap=AUTO&mac=00:0e:8e:98:64:45&mode=8&flags_mask=0" > /tmp/curl_data
Kurl -H "$accept_json" -X POST -d "@/tmp/curl_data" "$url/cli-form/add_sta"
#CMD: set_port 1 3 sta3000 0.0.0.0 255.255.0.0 0.0.0.0 NA 2147483648 00:0e:8e:98:64:45 NA NA NA 8405038 1000 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NONE
echo 'shelf=&resource=1&port=3&ip_addr=sta3000&netmask=0.0.0.0&gateway=255.255.0.0&cmd_flags=0.0.0.0&mac=2147483648&mtu=00:0e:8e:98:64:45&report_timer=8405038&flags2=1000&ipv6_dflt_gw=N&bypass_wdt=A' > /tmp/curl_data
Kurl -H "$accept_json" -X POST -d "@/tmp/curl_data" "$url/cli-form/set_port"
echo -n "shelf=1&resource=3&radio=wiphy1&mode=NA&channel=-1&country=NA&frequency=NA&frag_thresh=NA" > /tmp/curl_data
echo -n "&rate=NA&rts=NA&txpower=NA&mac=NA&antenna=NA&flags=1&flags_mask=1&const_tx=NA" >> /tmp/curl_data
echo -n "&pulse_width=NA&pulse_interval=NA&vdev_count=NA&peer_count=NA&stations_count=NA" >> /tmp/curl_data
echo -n "&rate_ctrl_count=NA&fwname=NA&fwver=NA&txdesc_count=NA&tids_count=NA&skid_limit=NA" >> /tmp/curl_data
echo -n "&active_peer_count=NA&tx_pulses=NA&pulse2_interval_us=NA&max_amsdu=NA&pref_ap=NA" >> /tmp/curl_data
Kurl -X GET -d "@/tmp/curl_data" $url/help/set_wifi_radio
echo -n "http://cholla:8080/help/set_wifi_radio?"
echo -n "shelf=1&resource=3&radio=wiphy1&mac=02:04:05:06:07:11&flags=1&flags_mask=1"
# -1=auto or -1=ANY
#CMD: set_wifi_radio 1 3 wiphy1 NA -1 NA NA NA NA NA NA NA NA 0x1 NA
echo -n "shelf=1&resource=3&radio=NA&mode=NA&channel=NA&country=NA&frequency=NA&frag_thresh=NA" > /tmp/curl_data
echo -n "&rate=NA&rts=NA&txpower=NA&mac=NA&antenna=NA&flags=NA&flags_mask=NA&const_tx=NA" >> /tmp/curl_data
echo -n "&pulse_width=NA&pulse_interval=NA&vdev_count=NA&peer_count=NA&stations_count=NA" >> /tmp/curl_data
echo -n "&rate_ctrl_count=NA&fwname=NA&fwver=NA&txdesc_count=NA&tids_count=NA&skid_limit=NA" >> /tmp/curl_data
echo -n "&active_peer_count=NA&tx_pulses=NA&pulse2_interval_us=NA&max_amsdu=NA&pref_ap=NA" >> /tmp/curl_data
url="http://localhost:8080/cli-form/set_wifi_radio"
Kurl -X POST -d "@/tmp/curl_data" $url
#CMD: add_sta 1 3 wiphy1 sta3000 0 idtest-1000-open NA [BLANK] AUTO NA 00:0e:8e:98:64:45 8 NA NA NA NA NA 0
#CMD: set_port 1 3 sta3000 0.0.0.0 255.255.0.0 0.0.0.0 NA 2147483648 00:0e:8e:98:64:45 NA NA NA 8405038 1000 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NONE
# help demo
url="http://localhost:8080/cli-form/add_vsta"
Kurl -X POST -d 'help=1' -H "$accept_json" "$url"
Kurl -X POST -d 'help=?' -H "$accept_json" "$url"
Kurl -X POST -d 'help=%63' -H "$accept_json" "$url"
#$::resource, $::sta_wiphy, $sta_name, "$flags", "$::ssid", "$::passphrase", $mac_addr, "$flagsmask", $wifi_m, $::bssid);
url="http://localhost:8080/cli-form/add_vsta"
echo 'shelf=1&resource=3&sta_wiphy=&sta_name=&flags=&ssid=&passphrase=&flagsmask=&wifi_m=&bssid=' > /tmp/curl_data
Kurl -X POST -d '@/tmp/curl_data' -H "$accept_json" "$url"
url="http://localhost:8080/cli-form/add_sta"
echo 'shelf=1&resource=3&sta_wiphy=&sta_name=&flags=&ssid=&passphrase=&flagsmask=&wifi_m=&bssid=' > /tmp/curl_data
Kurl -X POST -d '@/tmp/curl_data' -H "$accept_json" "$url"
#fmt_port_cmd($resource, $sta_name, $ip_addr, $mac_addr);
url="http://localhost:8080/cli-form/set_port"
echo 'shelf=1&resource=3&port=&ip_addr=&mac=' > /tmp/curl_data
Kurl -X POST -d '@/tmp/curl_data' -H "$accept_json" "$url"
#if ($::admin_down_on_add) {
# my $cur_flags = 0x1; # port down
# my $ist_flags = 0x800000; # port down
# $sta1_cmd = fmt_cmd("set_port", 1, $resource, $sta_name, "NA",
# "NA", "NA", "NA", "$cur_flags",
# "NA", "NA", "NA", "NA", "$ist_flags");
# 3doCmd($sta1_cmd);
#}
echo 'cmd=set_port_alias&shelf=1&resource=2&port=sta333&vport=NA&alias=bob33' > /tmp/curl_data
Kurl -X POST --data "@/tmp/curl_data" -H "$accept_json" -H "$content_plain" "$url"
sleep 5
echo 'cmd=set_port_alias&shelf=1&resource=2&port=sta333&vport=NA&alias=bob33' > /tmp/curl_data
Kurl -X POST --data "@/tmp/curl_data" -H "$accept_json" -H "$content_json" "$url"
echo 'shelf=1&resource=3&port=12&vport=NA&alias-64=Ym9iMzMK' > /tmp/curl_data
Kurl -X POST --data "@/tmp/curl_data" -H "$accept_json" "$url"
echo 'shelf=1&resource=3&port=12&vport=NA&alias=bob+33' > /tmp/curl_data
Kurl -X POST --data "@/tmp/curl_data" -H "$accept_json" "$url"
url="http://localhost:8080/cli-form/"
Kurl -X POST -d 'cmd=gossip&message=hi+there' -H "$accept_json" "$url"
url="http://localhost:8080/cli-form/scan_wifi"
echo 'shelf=1&resource=3&port=sta30000' > /tmp/curl_data
Kurl -X POST -d '@/tmp/curl_data' -H "$accept_json" "$url"
# the protocol command can only send back errors
# udp--2.b2000-03.sta30000
#url="http://localhost:8080/cli-form/getMAC"
#echo 'CX=udp--2.b2000-03.sta30000&AorB=A' > /tmp/curl_data
#Kurl -X POST --data "@/tmp/curl_data" -H "$accept_json" "$url"
fi
echo ""
echo "END"
exit
echo =======================================================================================
url="http://localhost:8080/port/1/2/2"
Kurl -X GET $url
Kurl -X HEAD $url
Kurl -X PUT $url
Kurl -X DELETE $url
port_fields=(
"Crypt"
"Beacon"
"MAC"
"QLEN"
"Misc"
"Phantom"
"TX Pkts"
"Login-Fail"
"IPv6 Gateway"
"Logout-OK"
"CX Time (us)"
"Connections"
"Mask"
"No CX (us)"
"Channel"
"RX Bytes"
"bps RX"
"TX Errors"
"RX-Rate"
"ANQP Time (us)"
"RX Miss"
"Bytes TX LL"
"SSID"
"TX Fifo"
"DHCP (ms)"
"Retry"
"Port"
"Bytes RX LL"
"RX Errors"
"4Way Time (us)"
"Logout-Fail"
"Pps RX"
"MTU"
"AP"
"RX Length"
"Parent Dev"
"bps RX LL"
"RX Fifo"
"RX Drop"
"Pps TX"
"Noise"
"IP"
"TX Wind"
"RX Frame"
"Key/Phrase"
"Signal"
"SEC"
"IPv6 Address"
"TX Abort"
"Device"
"Gateway IP"
"TX-Rate"
"CX Ago"
"RX Pkts"
"Reset"
"TX Crr"
"RX Over"
"TX Bytes"
"Activity"
"Collisions"
"Alias"
"bps TX"
"bps TX LL"
"Status"
"TX HB"
"Down"
"RX CRC"
"Login-OK"
)
for name in "${port_fields[@]}"; do
#echo "field <$name>"
name2="${name// /%20}"
url="http://localhost:8080/port/1/2/2,3,4?fields=$name2,Port"
echo -n "..."
curl -si -H 'Accept: application/json' "$url" > /tmp/response
echo "$url"
grep 'HTTP/1.1' /tmp/response
tail -1 /tmp/response
echo ""
sleep 0.05
done

View File

@@ -0,0 +1,104 @@
#!/bin/bash
set -e
unset proxy
unset http_proxy
Q='"'
q="'"
S='*'
application_json="application/json"
accept_json="Accept: $application_json"
accept_html='Accept: text/html'
accept_text='Accept: text/plain'
#accept_any="'Accept: */*'" # just dont use
content_plain='Content-Type: text/plain'
content_json="Content-Type: $application_json"
switches='-sq'
#switches='-sq'
function Kurl() {
echo "======================================================================================="
echo "curl $switches $@"
echo "======================================================================================="
curl $switches "$@" | json_pp
echo ""
echo "======================================================================================="
}
function Jurl() {
echo "=J====================================================================================="
echo "curl $switches -H $accept_json -H $content_json $@"
echo "=J====================================================================================="
curl $switches -H "$accept_json" -H "$content_json" -X POST "$@"
echo ""
echo "=J====================================================================================="
}
url="http://jedtest.jbr:8080"
#url="http://127.0.0.1:8080"
data_file="/var/tmp/data.$$"
result_file="/var/tmp/result_file.$$"
function PortDown() {
echo "{\"shelf\":1,\"resource\":3,\"port\":\"$1\",\"current_flags\":1, \"interest\":8388610}" > $data_file
curl $switches -H "$accept_json" -H "$content_json" -X POST -d"@$data_file" "$url/cli-json/set_port"
sleep 0.3
for f in `seq 1 10`; do
echo "{\"shelf\":1,\"resource\":3,\"port\":\"$1\"}" > $data_file
curl $switches -H "$accept_json" -H "$content_json" -X POST -d"@$data_file" "$url/cli-json/nc_show_ports"
sleep 0.5
curl $switches "$url/port/1/3/$1?fields=alias,ip,down" | json_reformat > $result_file
egrep '"down" *: "?true"?' $result_file && break || :
done
}
function PortUp() {
#set_port 1 3 sta3101 NA NA NA NA 0 NA NA NA NA 8388610
echo "{\"shelf\":1,\"resource\":3,\"port\":\"$1\",\"current_flags\":0, \"interest\":8388610}" > $data_file
curl $switches -H "$accept_json" -H "$content_json" -X POST -d"@$data_file" "$url/cli-json/set_port"
sleep 1
for f in `seq 1 100`; do
echo "{\"shelf\":1,\"resource\":3,\"port\":\"$1\"}" > $data_file
#Jurl -d"@$data_file" "$url/cli-json/nc_show_ports"
curl $switches -H "$accept_json" -H "$content_json" -X POST -d"@$data_file" "$url/cli-json/nc_show_ports"
sleep 0.5
curl $switches "$url/port/1/3/$1?fields=alias,ip,down" | json_reformat > $result_file
#cat $result_file
egrep '"down" : "?false"?' $result_file && break || :
done
}
function CxToggle() {
echo "{\"test_mgr\":\"all\",\"cx_name\":\"$1\",\"cx_state\":\"$2\"}" > $data_file
curl $switches -H "$accept_json" -H "$content_json" -X POST -d"@$data_file" "$url/cli-json/set_cx_state"
}
while true; do
for e in `seq 3000 3020` ; do
ea="udp:r3r2:$e"
eu="udp%3Ar3r2%3A${e}-A"
CxToggle "$ea" "STOPPED"
sleep 0.1
curl $switches -H "$accept_json" "$url/endp/$eu?fields=name,run" | json_reformat > $result_file
sleep 0.1
done
for sta in `seq 100 121`; do
stb=$(( $sta + 3000))
PortDown "sta$stb"
done
for sta in `seq 100 121`; do
stb=$(( $sta + 3000))
PortUp "sta$stb"
done
sleep 4
for e in `seq 3000 3020` ; do
ea="udp:r3r2:$e"
eu="udp%3Ar3r2%3A${e}-A"
CxToggle "$ea" "RUNNING"
sleep 0.1
curl $switches -H "$accept_json" "$url/endp/$eu?fields=name,run" | json_reformat > $result_file
sleep 0.1
done
sleep 14
done
#

View File

@@ -0,0 +1,151 @@
#!/bin/bash
set -e
unset proxy
unset http_proxy
Q='"'
q="'"
S='*'
series=(10000 10001 10002 11000 11001 11002 12000 12001 12002)
ra=1
rb=2
application_json="application/json"
accept_json="Accept: $application_json"
accept_html='Accept: text/html'
accept_text='Accept: text/plain'
#accept_any="'Accept: */*'" # just dont use
content_plain='Content-Type: text/plain'
content_json="Content-Type: $application_json"
headers="/var/tmp/headers.$$"
switches="-s -D $headers -o $result"
#switches='-sq'
data_file=/var/tmp/data.$$
result=/var/tmp/result.$$
function Kurl() {
echo "======================================================================================="
echo "curl $switches $@"
echo "======================================================================================="
curl $switches "$@" | json_pp
echo ""
echo "======================================================================================="
}
function Jurl() {
echo "=J====================================================================================="
echo "curl $switches -H $accept_json -H $content_json $@"
echo "=J====================================================================================="
curl $switches -H "$accept_json" -H "$content_json" -X POST "$@"
echo ""
echo "=J====================================================================================="
}
function Kuurl() {
echo "URL: ${@:$#}"
echo "" > $result
echo "" > $headers
#curl $switches -H "$accept_json" -H "$content_json" -X POST -d"@$data_file" "$@" ||:
set -x
curl "$@" ||:
set +x
grep 'HTTP/1.1 200' $headers || (echo "${@:$#}"; cat $headers; exit 1)
}
HOST=${1:-jedtest.jbr}
url="http://${HOST}:8080"
#url="http://127.0.0.1:8080"
function PortDown() {
switches="-s -D $headers -o $result"
echo "{\"shelf\":1,\"resource\":$ra,\"port\":\"$1\",\"current_flags\":1, \"interest\":8388610}" > $data_file
Kuurl $switches -H "$accept_json" -H "$content_json" -X POST -d"@$data_file" "$url/cli-json/set_port"
sleep 0.3
for try in `seq 1 100`; do
echo "{\"shelf\":1,\"resource\":$ra,\"port\":\"$1\"}" > $data_file
cat $data_file
Kuurl $switches -H "$accept_json" -H "$content_json" -X POST -d"@$data_file" "$url/cli-json/nc_show_ports"
sleep 0.5
Kuurl $switches "$url/port/1/$ra/$1?fields=alias,ip,down"
json_pp < $result || cat $result
grep '"down".*true' $result && break || :
done
}
function PortUp() {
#set_port 1 3 sta3101 NA NA NA NA 0 NA NA NA NA 8388610
echo "{\"shelf\":1,\"resource\":$ra,\"port\":\"$1\",\"current_flags\":0, \"interest\":8388610}" > $data_file
curl $switches -H "$accept_json" -H "$content_json" -X POST -d"@$data_file" "$url/cli-json/set_port"
sleep 1
for try in `seq 1 100`; do
echo "{\"shelf\":1,\"resource\":$ra,\"port\":\"$1\"}" > $data_file
#Jurl -d"@$data_file" "$url/cli-json/nc_show_ports"
curl $switches -H "$accept_json" -H "$content_json" -X POST -d"@$data_file" "$url/cli-json/nc_show_ports"
sleep 0.5
curl $switches "$url/port/1/$ra/$1?fields=alias,ip,down"
json_pp < $result || cat $result
grep '"down".*false' $result && break || :
done
}
function CxToggle() {
echo "{\"test_mgr\":\"all\",\"cx_name\":\"$1\",\"cx_state\":\"$2\"}" > $data_file
cat $data_file
Kuurl $switches -H "$accept_json" -H "$content_json" -X POST -d"@$data_file" "$url/cli-json/set_cx_state"
}
function CxCreate() { # alias, port
echo "{\"alias\":\"$1-A\",\"shelf\":1,\"resource\":$ra,\"port\":\"$2\",\"type\":\"lf_udp\",\"ip_port\":\"AUTO\",\"is_rate_bursty\":\"NO\",\"min_rate\":164000,\"min_pkt\":-1,\"max_pkt\":0}" > $data_file
cat $data_file
Kuurl $switches -H "$accept_json" -H "$content_json" -X POST -d"@$data_file" "$url/cli-json/add_endp"
echo "{\"alias\":\"$1-B\",\"shelf\":1,\"resource\":$rb,\"port\":\"b2000\",\"type\":\"lf_udp\",\"ip_port\":\"AUTO\",\"is_rate_bursty\":\"NO\",\"min_rate\":64000,\"min_pkt\":-1,\"max_pkt\":0}" > $data_file
cat $data_file
Kuurl $switches -H "$accept_json" -H "$content_json" -X POST -d"@$data_file" "$url/cli-json/add_endp"
echo "{\"alias\":\"$1\",\"test_mgr\":\"default_tm\",\"tx_endp\":\"$1-A\",\"rx_endp\":\"$1-B\"}" > $data_file
cat $data_file
Kuurl $switches -H "$accept_json" -H "$content_json" -X POST -d"@$data_file" "$url/cli-json/add_cx"
echo "{\"endpoint\":\"$1-A\"}" > $data_file
Kuurl $switches -H "$accept_json" -H "$content_json" -X POST -d"@$data_file" "$url/cli-json/nc_show_endpoints"
echo "{\"endpoint\":\"$1-B\"}" > $data_file
Kuurl $switches -H "$accept_json" -H "$content_json" -X POST -d"@$data_file" "$url/cli-json/nc_show_endpoints"
}
# create some cx
for eidcx in "${series[@]}" ; do
CxCreate "udp-$eidcx" "vsta$eidcx"
sleep 1
Kuurl $switches -H "$accept_json" "$url/endp/udp-$eidcx-A?fields=name,run"
Kuurl $switches -H "$accept_json" "$url/endp/udp-$eidcx-B?fields=name,run"
Kuurl $switches -H "$accept_json" "$url/cx/udp-$eidcx?fields=name,state"
done
sleep 4
for try in 1 2; do
for eidcx in "${series[@]}" ; do
sleep 1
CxToggle "udp-$eidcx" "STOPPED"
Kuurl $switches -H "$accept_json" "$url/endp/udp-$eidcx-A?fields=name,run"
Kuurl $switches -H "$accept_json" "$url/endp/udp-$eidcx-B?fields=name,run"
Kuurl $switches -H "$accept_json" "$url/cx/udp-$eidcx?fields=name,state"
done
for sta in "${series[@]}"; do
PortDown "vsta$sta"
done
sleep 5
for sta in "${series[@]}"; do
PortUp "vsta$sta"
done
sleep 5
for eidcx in "${series[@]}" ; do
sleep 1
CxToggle "udp-$eidcx" "RUNNING"
Kuurl $switches -H "$accept_json" "$url/endp/udp-$eidcx-A?fields=name,run"
Kuurl $switches -H "$accept_json" "$url/endp/udp-$eidcx-B?fields=name,run"
Kuurl $switches -H "$accept_json" "$url/cx/udp-$eidcx?fields=name,state"
done
sleep 20
done
echo "DONE"
#

View File

@@ -0,0 +1,65 @@
#!/bin/bash
set -e
unset proxy
unset http_proxy
Q='"'
q="'"
S='*'
application_json="application/json"
accept_json="Accept: $application_json"
accept_html='Accept: text/html'
accept_text='Accept: text/plain'
#accept_any="'Accept: */*'" # just dont use
content_plain='Content-Type: text/plain'
content_json="Content-Type: $application_json"
switches='-sqv'
#switches='-sq'
data_file=/var/tmp/data.$$
function Kurl() {
echo "======================================================================================="
echo "curl $switches $@"
echo "======================================================================================="
curl $switches "$@" | json_pp
echo ""
echo "======================================================================================="
}
function Jurl() {
echo "=J====================================================================================="
echo "curl $switches -H $accept_json -H $content_json $@"
echo "=J====================================================================================="
curl $switches -H "$accept_json" -H "$content_json" -X POST "$@"
echo ""
echo "=J====================================================================================="
}
#url="http://jed-f24m64-9119:8080"
url="http://127.0.0.1:8080"
while true; do
curl -sq -H "$accept_html" $url/help/ > /var/tmp/help.html
perl -ne "m{href='(/help/[^']+)'} && print \"\$1\n\";" /var/tmp/help.html > /var/tmp/help_cmds.txt
for f in `cat /var/tmp/help_cmds.txt`; do
curl --retry 10 -sq -H "$accept_html" "${url}$f" >/dev/null
done
curl -sq -H "$accept_json" ${url}/resource/list | json_reformat > $data_file
#less $data_file
perl -ne 'm{"_links"\s*:\s*"([^ ]+)"} && print "$1\n";' $data_file > /var/tmp/resources.txt
for f in `cat /var/tmp/resources.txt`; do
echo "$f"
(curl --retry 10 -sq -H "$accept_json" "${url}$f" |json_reformat) || exit 1
done
curl -sq -H "$accept_json" ${url}/port/list | json_reformat > $data_file
#less $data_file
perl -ne 'm{"_links"\s*:\s*"([^ ]+)"} && print "$1\n";' $data_file > /var/tmp/ports.txt
for f in `cat /var/tmp/ports.txt`; do
echo "$f"
(curl --retry 10 -sq -H "$accept_json" "${url}$f" |json_reformat) || exit 1
done
done
#

View File

@@ -0,0 +1,419 @@
#!/usr/bin/perl -w
use strict;
use warnings;
use diagnostics;
use Carp;
$SIG{ __DIE__ } = sub { Carp::confess( @_ ) };
$SIG{ __WARN__ } = sub { Carp::confess( @_ ) };
# Un-buffer output
$| = 1;
use Getopt::Long;
use JSON::XS;
use HTTP::Request;
use LWP;
use LWP::UserAgent;
use Data::Dumper;
use Time::HiRes qw(usleep);
use JSON;
use lib '/home/lanforge/scripts';
use lib "../";
use lib "./";
use LANforge::JsonUtils qw(logg err json_request get_links_from get_thru json_post get_port_names flatten_list);
package main;
# Default values for ye ole cmd-line args.
our $Resource = 1;
our $quiet = "yes";
our $Host = "localhost";
our $Port = 8080;
our $HostUri = "http://$Host:$Port";
our $Web = LWP::UserAgent->new;
our $Decoder = JSON->new->utf8;
our $ssid;
our $security;
our $passphrase;
my $usage = qq("$0 --host {ip or hostname} # connect to this
--port {port number} # defaults to 8080
);
my $des_resource = 6;
#my $pat_port_type = '^eth\d[#]\d+';
my $pat_port_type = '^v*sta\d+';
##
## M A I N
##
GetOptions
(
'host=s' => \$::Host,
'port=i' => \$::Port
) || (print($usage) && exit(1));
$::HostUri = "http://$Host:$Port";
my $DEBUGURI = "?__debug=1";
my $uri_args = ""; # ="$DEBUG_URI";
my $uri = "/shelf/1";
my $rh = json_request($uri);
my $ra_links = get_links_from($rh, 'resources');
my @ports_up= ();
# TODO: make this a JsonUtils::list_ports()
$uri = "/port/1/${des_resource}/list?fields=alias,device,down,phantom,port";
#logg("requesting $uri");
$rh = json_request($uri);
flatten_list($rh, 'interfaces');
for my $rh_p (keys %{$rh->{'flat_list'}}) {
# truthy value evaluates better
my $onoff = $rh->{'flat_list'}->{$rh_p}->{'down'};
print "$rh_p down? $onoff ";
if ($onoff) {
push(@ports_up, $rh_p);
}
}
# find first station
my $rh_sta;
for my $rh_up (@ports_up) {
my $eid = $rh->{'flat_list'}->{$rh_up}->{'port'};
my @hunks = split(/[.]/, $eid);
if ($hunks[1]) {
$rh_sta = $rh_up;
}
}
if (!defined $rh_sta) {
die("Unable to find a virtual station. Is one up?");
}
# delete old CXes and old endpoints
# TODO: collect_l4cx_names
my $rh_endplist = json_request("/layer4/list");
print "\nRemoving L4: ";
my @endp_names = ();
#sleep 2;
#print "-------------------------------------------------------------------------\n";
#print Dumper($rh_endplist);
#print "-------------------------------------------------------------------------\n";
#sleep 2;
if (defined $rh_endplist->{"endpoint"}
&& (ref $rh_endplist->{"endpoint"} eq "HASH")) {
# indicates we only have one
push(@endp_names, $rh_endplist->{"endpoint"}->{"name"});
}
elsif (defined $rh_endplist->{"endpoint"}) {
flatten_list($rh_endplist, 'endpoint');
#print "FLAT LIST:\n";
#print Dumper($rh_endplist->{'flat_list'});
for my $ep_name (keys %{$rh_endplist->{'flat_list'}}) {
print "?$ep_name? ";
next if (!defined $ep_name);
next if ($ep_name eq "");
next if ((ref $ep_name) eq "ARRAY");
next if (!defined $rh_endplist->{'flat_list'}->{$ep_name}->{"name"});
next if ($rh_endplist->{'flat_list'}->{$ep_name}->{"name"} eq "");
#print "\nepn:".Dumper($rh_endplist->{'flat_list'}->{$ep_name}->{"name"});
push(@endp_names, $ep_name);
}
}
if ((@endp_names < 1) && (defined $rh_endplist->{"endpoint"})) {
# check for mutated L4endp entries that only exist in EID form
#die "Unknown L4 endpoint state"
# if (!(defined $rh_endplist->{"endpoint"}));
die "No endpoint entries"
if (scalar @{$rh_endplist->{"endpoint"}} < 1);
for $rh (@{$rh_endplist->{"endpoint"}}) {
#print Dumper($rh);
my @k = keys(%$rh);
#print "$k[0] ";
push(@endp_names, $k[0]);
}
}
#print Dumper(\@endp_names);
my @cx_names = ();
if (@endp_names > 0) {
for my $endp_name (@endp_names) {
next if ($endp_name =~ /^CX_D_/);
print " endp_name[$endp_name]";
push(@cx_names, "CX_".$endp_name);
}
}
my $rh_req = {
"test_mgr" => "default_tm",
"suppress_preexec_method" => 1,
"suppress_preexec_cli" => 1,
};
for my $cx_name (@cx_names) {
print "rm_cx $cx_name ";
$rh_req->{"cx_name"} = $cx_name;
print "rm_cx $cx_name ";
json_post("/cli-json/rm_cx", $rh_req);
}
print "\nRemoved ".scalar @cx_names." cx\n";
my $rh_show_cxe = { "test_mgr"=>"all", "cross_connect"=>"all"};
json_post("/cli-json/show_cxe${DEBUGURI}", $rh_show_cxe);
sleep 2;
print "\nRemoving ".scalar @endp_names;
$uri = "/cli-json/rm_endp${uri_args}";
for my $ep_name (@endp_names) {
if (!defined $ep_name || $ep_name =~/^\s*$/ || (ref $ep_name) eq "ARRAY") {
#print " rm_endp [$ep_name]"; #skipping
#print Dumper(\$ep_name);
next;
}
print " -$ep_name ";
$rh = { "endp_name" => $ep_name };
json_post($uri, $rh);
}
print "\nRefreshing...";
my $h = {"endpoint"=>"all"};
json_request("/cli-json/nc_show_endpoints${uri_args}", $h);
sleep 1;
$h = {"test_mgr"=>"all", "cross_connect"=>"all"};
json_request("/cli-json/show_cxe${uri_args}", $h);
# assume resource 1, eth1 is present, and create an endpoint to it
# -A and -B are expected convention for endpoint names
##
## Create New Endpoints
##
my $rh_ports = json_request("/port/1/${des_resource}/list");
flatten_list($rh_ports, 'interfaces');
my $rh_endp_A = { # actual endpoint
#'alias' => "untitled",
'shelf' => 1,
'resource' => $des_resource,
'type' => 'l4_generic',
'timeout' => '2000',
'url_rate' => '600',
'url' => 'dl http://idtest.candelatech.com/ /dev/null',
'max_speed' => '1000000',
'http_auth_type' => 0,
'proxy_auth_type' => 512,
};
my $rh_endp_B = { # dummy endpoints, # we don't actually need
#'alias' => "D_untitled",
'shelf' => 1,
'resource' => $des_resource,
# port
'type' => 'l4_generic',
'proxy_port' => 'NA',
'timeout' => 0,
'url_rate' => 0,
'url' => ' ',
'max_speed' => 'NA',
};
my $rh_set_flags_a = {
# 'name' =>
'flag' => 'GetUrlsFromFile',
'val' => 0,
};
my $rh_set_flags_b = {
# 'name' =>
'flag' => 'unmanaged',
'val' => 1,
};
my $rh_add_cx = {
# "alias" =>,
'test_mgr' => 'default_tm',
#'tx_endp' =>,
#'rx_endp' =>
};
print "\nConstructing new Endpoints B: ";
my $num_ports = scalar keys(%{$rh_ports->{'flat_list'}});
my $num_cx = 0;
my $disp_num = $des_resource * 1000;
# create dummy port and set it unmanaged
my $create_b_side = 0;
if ($create_b_side) {
for my $rh_p (values %{$rh_ports->{'flat_list'}}) {
last if ($num_cx >= ($num_ports-1));
next if ($rh_p->{'alias'} !~ /$pat_port_type/);
# create dummy port and set it unmanaged
my $end_b_alias = "D_l4json${disp_num}";
$rh_endp_B->{'port'} = $rh_p->{'alias'};
$rh_endp_B->{'alias'} = $end_b_alias;
$num_cx++;
$disp_num++;
print " +$end_b_alias ";
json_post("/cli-json/add_l4_endp${uri_args}", $rh_endp_B);
}
sleep 1;
$num_cx = 0;
$disp_num = $des_resource * 1000;
print "\nSetting Endpoint flags: ";
for my $rh_p (values %{$rh_ports->{'flat_list'}}) {
last if ($num_cx >= ($num_ports-1));
next if ($rh_p->{'alias'} !~ /$pat_port_type/);
my $end_b_alias = "D_l4json${disp_num}";
$rh_set_flags_b->{'name'} = $end_b_alias;
$num_cx++;
$disp_num++;
print " ~$end_b_alias ";
json_post("/cli-json/set_endp_flag${uri_args}", $rh_set_flags_b);
}
sleep 1;
}
$num_cx = 0;
$disp_num = $des_resource * 1000;
print "\nAdding Endpoint A: ";
for my $rh_p (values %{$rh_ports->{'flat_list'}}) {
last if ($num_cx >= ($num_ports-1));
next if ($rh_p->{'alias'} !~ /$pat_port_type/);
my $end_a_alias = "l4json${disp_num}";
$rh_endp_A->{'port'} = $rh_p->{'alias'};
$rh_endp_A->{'alias'} = $end_a_alias;
$num_cx++;
$disp_num++;
print " +$end_a_alias; ";
json_post("/cli-json/add_l4_endp${uri_args}", $rh_endp_A);
}
$num_cx = 0;
$disp_num = $des_resource * 1000;
print "\nSet_endp_flag: ";
for my $rh_p (values %{$rh_ports->{'flat_list'}}) {
last if ($num_cx >= ($num_ports-1));
next if ($rh_p->{'alias'} !~ /$pat_port_type/);
my $end_a_alias = "l4json${disp_num}";
$rh_set_flags_a->{'name'} = $end_a_alias;
$num_cx++;
$disp_num++;
print " ~$end_a_alias ";
json_post("/cli-json/set_endp_flag${uri_args}", $rh_set_flags_a);
}
print "\nRefreshing...";
$h = {"endpoint"=>"all"};
json_request("/cli-json/nc_show_endpoints${uri_args}", $h);
sleep 4;
print "\nConstructing new CX: ";
$num_cx = 0;
$disp_num = $des_resource * 1000;
print Dumper($rh_ports->{'flat_list'});
for my $rh_p (values %{$rh_ports->{'flat_list'}}) {
last if ($num_cx >= ($num_ports-1));
next if ($rh_p->{'alias'} !~ /$pat_port_type/);
my $end_a_alias = "l4json${disp_num}";
my $end_b_alias = ($create_b_side) ? "D_l4json${disp_num}" : "NA";
my $cx_alias = "CX_l4json${disp_num}";
$rh_add_cx->{'alias'} = $cx_alias;
$rh_add_cx->{'tx_endp'} = $end_a_alias;
$rh_add_cx->{'rx_endp'} = $end_b_alias;
$num_cx++;
$disp_num++;
print " $cx_alias ";
json_post("/cli-json/add_cx${uri_args}", $rh_add_cx);
}
$h = {"endpoint"=>"all"};
json_request("/cli-json/nc_show_endpoints", $h);
sleep 4;
$h = {"test_mgr"=>"all", "cross_connect"=>"all"};
json_request("/cli-json/show_cxe", $h);
sleep 4;
print "\nRefreshing...";
$h = {"endpoint"=>"all"};
json_request("/cli-json/nc_show_endpoints", $h);
sleep 4;
$h = {"test_mgr"=>"all", "cross_connect"=>"all"};
json_request("/cli-json/show_cxe", $h);
sleep 4;
# wait for data to distribute
my $num_unfinished = 1;
while ($num_unfinished > 0) {
$num_unfinished = 0;
my $rh_cx = json_request("/layer4/list");
print "\n- 337 --------------------------------------------------------\n";
print Dumper($rh_cx);
print "\n- 337 --------------------------------------------------------\n";
flatten_list($rh_cx, "endpoint");
@cx_names = sort keys %{$rh_cx->{'flat_list'}};
for my $cx_alias (sort @cx_names) {
if ($cx_alias =~ /^1\./) {
print " -$cx_alias ";
$num_unfinished++ ;
}
}
print " Unfinished: $num_unfinished\n";
sleep 1 if ($num_unfinished);
}
@endp_names = ();
my $rh_endp = json_request("/layer4/list");
flatten_list($rh_endp, "endpoint");
print "\n- 354 --------------------------------------------------------\n";
print Dumper($rh_endp);
print "\n- 354 --------------------------------------------------------\n";
@endp_names = sort keys %{$rh_endp->{'flat_list'}};
@cx_names = ();
for my $endp_name (@endp_names) {
next if ($endp_name =~ m/^D_/);
if ($endp_name =~ m/^1\./) {
print " what? $endp_name ";
next;
}
push(@cx_names, "CX_${endp_name}");
}
my $rh_cx_t = {
'test_mgr' => 'default_tm',
#'cx_name' => $cx_alias,
'milliseconds'=> 1000,
};
print "\nSetting timers: ";
for my $cx_alias (sort @cx_names) {
if ($cx_alias =~ /^\s*$/ || ref $cx_alias eq "ARRAY") {
print "BLANK CX_NAME: ".Dumper(\@cx_names);
next;
}
$rh_cx_t->{'cx_name'} = $cx_alias;
print " ~$cx_alias ";
json_post("/cli-json/set_cx_report_timer", $rh_cx_t);
}
print "\nRefreshing...";
$h = {"endpoint"=>"all"};
json_request("/cli-json/nc_show_endpoints", $h);
sleep 1;
$h = {"test_mgr"=>"all", "cross_connect"=>"all"};
json_request("/cli-json/show_cxe", $h);
sleep 1;
$rh_cx_t = {
'test_mgr' => 'default_tm',
#'cx_name' => $cx_alias,
'cx_state'=> "RUNNING",
};
print "\nStarting cx...";
for my $cx_alias (sort @cx_names) {
$rh_cx_t->{'cx_name'} = $cx_alias;
print " +$cx_alias ";
json_post("/cli-json/set_cx_state", $rh_cx_t);
}
sleep 5;
print "\nStopping cx...";
$rh_cx_t = {
'test_mgr' => 'default_tm',
#'cx_name' => $cx_alias,
'cx_state'=> "STOPPED",
};
for my $cx_alias (sort @cx_names) {
$rh_cx_t->{'cx_name'} = $cx_alias;
print " -$cx_alias ";
json_post("/cli-json/set_cx_state", $rh_cx_t);
}
#

View File

@@ -0,0 +1,331 @@
#!/usr/bin/perl -w
use strict;
use warnings;
use diagnostics;
use Carp;
use Time::HiRes qw(usleep);
$SIG{ __DIE__ } = sub { Carp::confess( @_ ) };
$SIG{ __WARN__ } = sub { Carp::confess( @_ ) };
# Un-buffer output
$| = 1;
use Getopt::Long;
use JSON::XS;
use HTTP::Request;
use LWP;
use LWP::UserAgent;
use Data::Dumper;
use JSON;
use lib '/home/lanforge/scripts';
use lib "../";
use lib "./";
use LANforge::JsonUtils qw(logg err json_request get_links_from get_thru json_post get_port_names flatten_list);
package main;
# Default values for ye ole cmd-line args.
our $Resource = 1;
our $quiet = "yes";
our $Host = "localhost";
our $Port = 8080;
our $HostUri = "http://$Host:$Port";
our $Web = LWP::UserAgent->new;
our $Decoder = JSON->new->utf8;
our $use_ssid = "kedtest-wpa2";
our $use_pass = "kedtest-wpa2";
my $usage = qq("$0 --host {ip or hostname} # connect to this
--port {port number} # defaults to 8080
--ssid {ssid}
--pass {passwd}
);
my $num_sta = 3;
my $des_resource = 1;
##
## M A I N
##
GetOptions
(
'host=s' => \$::Host,
'port=i' => \$::Port,
'ssid=s' => \$::use_ssid,
'pass=s' => \$::use_pass,
) || (print($usage) && exit(1));
$::HostUri = "http://$Host:$Port";
my $uri = "/shelf/1";
my $rh = json_request($uri);
my $ra_links = get_links_from($rh, 'resources');
my @links2= ();
my $ra_alias_links = [];
# TODO: make this a JsonUtils::list_ports()
for $uri (@$ra_links) {
$uri =~ s{/resource}{/port}g;
$uri .= "/list?fields=_links,device,alias,port";
print "$uri\n";
$rh = json_request($uri);
if (defined $rh->{'interfaces'}) {
flatten_list($rh, 'interfaces');
#push(@$ra_alias_links, keys(%{$rh->{'flat_list'}}));
push( @$ra_alias_links, get_port_names($rh, 'interfaces'));
#push(@links2, keys(%{$rh->{'flat_list'}}));
push(@links2, @{get_links_from($rh, 'interfaces')});
}
}
# destroy stations
my @radios = ();
my @destroy_me = ();
for my $rh_alias_link (@$ra_alias_links) {
for my $rh_link (@$rh_alias_link) {
if ( ($rh_link->{'uri'} =~m{^/port/1/$des_resource/})
&& ($rh_link->{'device'} =~m{^sta})) {
push(@destroy_me, $rh_link);
}
push(@radios, $rh_link)
if (($rh_link->{'uri'} =~m{^/port/1/$des_resource/})
&& ($rh_link->{'device'} =~m{^wiphy}));
}
}
logg("\nDestroying these: ");
for my $rh_target (@destroy_me) {
my $alias = $rh_target->{'device'};
my @hunks = split(/[\/]/, $rh_target->{'uri'});
# TODO: create JsonUtils::rm_vlan($eid, $alias)
# suppress_postexec used to reduce the update traffic concurrent with large set of deletions
my $rh_data = {
'shelf'=>1,
'resource'=>$hunks[3],
'port'=>$alias
};
logg(" $alias");
my $rh_response = json_post("/cli-json/rm_vlan", $rh_data);
usleep (15000);
}
my $rh_update = {
'shelf'=>1, 'resource'=>$des_resource, 'port'=>'all', 'probe_flags'=>'0x1'
};
logg("\nRefreshing: ");
my $rh_response = json_post("/cli-json/nc_show_ports", $rh_update);
my $remaining = 1;
while ($remaining > 0) {
$rh = json_request("/port/1/$des_resource/list");
flatten_list($rh, 'interfaces');
$remaining = 0;
for my $name (keys %{$rh->{'flat_list'}}) {
$remaining ++
if ($name =~ /^v*sta/);
}
print "Remaining stations: $remaining, ";
sleep 1;
}
# this really should poll for ports to wait for them to disappear
sleep 3;
my @new_stations = ();
logg("\nCreating new stations on these: ");
#print Dumper(\@radios);
my $rh_radio;
my $radio_name;
my $resource;
my $range;
my $radio_num;
my $radio_counter = 0;
$rh_response = json_post("/cli-json/nc_show_ports", $rh_update);
# add_sta + ht20 -ht40 -ht80 -create_admin_down
# flags=142609408&mode=8
print "\nAdding stations...\n";
for $rh_radio (@radios) {
$radio_name = $rh_radio->{'alias'};
my @hunks = split(/[\/]/, $rh_radio->{'uri'});
($radio_num) = $radio_name =~ /wiphy(\d+)/;
$resource = $hunks[3];
$range = ($resource * 1000) + ($radio_num * 100);
logg("\n/cli-json/add_sta on 1.$resource.$radio_name\n");
for (my $i = $range; $i < ($range+$num_sta); $i++) {
# TODO: create JsonUtils::add_sta($eid, $alias...)
my $rh_data = {
'shelf'=>1,
'resource'=>$resource,
#'radio'=>'x'.$radio_name, # use to prompt radio not found error
'radio'=>$radio_name,
'sta_name'=>'sta'.$radio_counter,
#'alias'=>'vsta'.$i, # deprecated, use set_port + interest.set_alias
#'flags'=>68862086144, # has port-down set
'flags'=>142609408,
'ssid'=> $::use_ssid,
'key'=> $::use_pass,
'mac'=>'xx:xx:xx:xx:*:xx',
'mode'=>0,
'rate'=>'DEFAULT'
};
logg(" sta$radio_counter");
my $rh_response = json_post("/cli-json/add_sta", $rh_data);
usleep(300000);
$radio_counter +=1;
}
$rh_response = json_post("/cli-json/nc_show_ports", $rh_update);
sleep 1;
} # for
logg("\nUpdating aliases ");
$rh_response = json_post("/cli-json/nc_show_ports", $rh_update);
sleep 5;
$radio_counter = 0;
for $rh_radio (@radios) {
$radio_name = $rh_radio->{'alias'};
my @hunks = split(/[\/]/, $rh_radio->{'uri'});
($radio_num) = $radio_name =~ /wiphy(\d+)/;
$resource = $hunks[3];
$range = ($resource * 10000) + ($radio_num * 1000);
for (my $i = $range; $i < ($range+$num_sta); $i++) {
print "sta$radio_counter:vsta$i ";
#my $eidname = "1.$resource.sta$radio_counter";
# set port up + dhcp + alias
my $rh_data = {
'shelf'=>1,
'resource'=>$resource,
'port'=>'sta'.$radio_counter,
'current_flags'=>2147483648,
'interest'=>20480,
'alias'=>'vsta'.$i
};
my $rh_response = json_post("/cli-json/set_port", $rh_data);
$radio_counter+=1;
usleep(300000);
}
}
$rh_response = json_post("/cli-json/nc_show_ports", $rh_update);
sleep 5;
$radio_counter = 0;
for $rh_radio (@radios) {
$radio_name = $rh_radio->{'alias'};
my @hunks = split(/[\/]/, $rh_radio->{'uri'});
($radio_num) = $radio_name =~ /wiphy(\d+)/;
$resource = $hunks[3];
$range = ($resource * 10000) + ($radio_num * 1000);
for (my $i = $range; $i < ($range+$num_sta); $i++) {
print "sta$radio_counter:vsta$i ";
#my $eidname = "1.$resource.sta$radio_counter";
# set port up + dhcp + alias
my $rh_data = {
'shelf'=>1,
'resource'=>$resource,
'port'=>'sta'.$radio_counter,
'current_flags'=>0,
'interest'=>8388608,
};
my $rh_response = json_post("/cli-json/set_port", $rh_data);
$radio_counter+=1;
sleep 1;
}
}
logg("\nRefreshing after setting up... ");
$rh_response = json_post("/cli-json/nc_show_ports", $rh_update);
sleep 4;
# wait on ports up
my $ports_still_down = 1;
while ($ports_still_down > 0) {
# this logic has to see if port is phantom and if port is over-subscribed
$rh = json_request("/port/1/$des_resource/list?fields=_links,port,device,down,phantom,channel");
flatten_list($rh, 'interfaces');
$ports_still_down=0;
for my $rh_p (values %{$rh->{'flat_list'}}) {
next unless $rh_p->{'device'} =~ /^sta/;
#print "$rh_p->{'device'} Down: $rh_p->{'down'} Ph $rh_p->{'phantom'} Channel: $rh_p->{'channel'} \n";
next if ($rh_p->{'phantom'}); # does not count as down
next if (!$rh_p->{'channel'}); # probably oversubscribed or misconfigured
$ports_still_down++
if ($rh_p->{'down'});
}
print "ports down: $ports_still_down ";
$rh_response = json_post("/cli-json/nc_show_ports", $rh_update);
sleep 4;
}
sleep 4;
my $port_uri = "/port/1/$des_resource?fields=_links,device,alias,port";
# ports down
my $set_port = "/cli-json/set_port";
logg("\nsetting ports down: ");
$rh = json_request($port_uri);
flatten_list($rh, 'interfaces');
@links2 = ();
for my $k (keys %{$rh->{"flat_list"}}) {
print "\n -- 200 ---------------------------------------------------------------\n";
print Dumper($rh->{"flat_list"}->{$k});
print "\n -- 200 ---------------------------------------------------------------\n";
my $Link = $rh->{"flat_list"}->{$k}->{"_links"};
print "LINK $Link\n";
push(@links2, $Link);
}
for my $port_uri (@links2) {
print "URI: $port_uri\n";
$rh = json_request($port_uri);
my $device = get_thru('interface', 'device', $rh);
next if ($device !~ /^sta/);
logg($device." ");
my $port = get_thru('interface', 'port', $rh);
my @hunks = split(/\./, $port);
my $resource = $hunks[1];
my %post = (
#'suppress_preexec_cli'=>'false',
#'suppress_preexec_method'=>'false',
#'suppress_postexec_cli'=>'false',
#'suppress_postexec_method'=>'false',
"shelf" => 1,
"resource" => 0+$resource,
"port" => $device,
'suppress_postexec_cli'=>'true',
"current_flags" => 1,
"interest" => 8388610
);
my $rh_response = json_post($set_port, \%post);
usleep(10000);
}
logg(" updating ");
$rh_response = json_post("/cli-json/nc_show_ports", $rh_update);
sleep 1;
logg("\nsetting ports up ");
for my $port_uri (@links2) {
$rh = json_request($port_uri);
my $device = get_thru('interface', 'device', $rh);
next if ($device !~ /^sta/);
logg($device." ");
my $port = get_thru('interface', 'port', $rh);
my @hunks = split(/\./, $port);
my $resource = $hunks[1];
# 'shelf=1&resource=2&port=vap2000&cmd_flags=0&current_flags=0&interest=8388610'
my %post = (
#'suppress_preexec_cli'=>'false',
#'suppress_preexec_method'=>'false',
#'suppress_postexec_cli'=>'false',
#'suppress_postexec_method'=>'false',
"shelf" => 1,
"resource" => 0+$resource,
"port" => $device,
'suppress_postexec_cli'=>'true',
"current_flags" => 0,
"interest" => 8388610
);
my $rh_response = json_post($set_port, \%post);
usleep(10000);
}
logg(" updating ");
$rh_response = json_post("/cli-json/nc_show_ports", $rh_update);
#

View File

@@ -0,0 +1,206 @@
#!/usr/bin/perl -w
use strict;
use warnings;
use diagnostics;
use Carp;
$SIG{ __DIE__ } = sub { Carp::confess( @_ ) };
$SIG{ __WARN__ } = sub { Carp::confess( @_ ) };
# Un-buffer output
$| = 1;
use Getopt::Long;
use Time::HiRes qw(usleep);
use JSON::XS;
use HTTP::Request;
use LWP;
use LWP::UserAgent;
use Data::Dumper;
use JSON;
use lib '/home/lanforge/scripts';
use lib "../";
use lib "./";
use LANforge::JsonUtils qw(logg err json_request get_links_from get_thru json_post get_port_names);
package main;
# Default values for ye ole cmd-line args.
our $Resource = 1;
our $quiet = "yes";
our $Host = "localhost";
our $Port = 8080;
our $HostUri = "http://$Host:$Port";
our $Web = LWP::UserAgent->new;
our $Decoder = JSON->new->utf8;
my $usage = qq("$0 --host {ip or hostname} # connect to this
--port {port number} # defaults to 8080
);
my $do_destroy = 0;
##
## M A I N
##
GetOptions
(
'host=s' => \$::Host,
'port=i' => \$::Port,
) || (print($usage) && exit(1));
$::HostUri = "http://$Host:$Port";
my $uri = "/shelf/1";
my $rh = json_request($uri);
my $ra_links = get_links_from($rh, 'resources');
my @links2= ();
my $ra_alias_links = [];
# TODO: make this a JsonUtils::list_ports()
for $uri (@$ra_links) {
$uri =~ s{/resource}{/port}g;
$uri .= "/list";
#logg("requesting $uri");
$rh = json_request($uri);
push( @$ra_alias_links, @{get_port_names($rh, 'interfaces')});
push(@links2, @{get_links_from($rh, 'interfaces')});
#logg("\nfound: ");
#logg(@links2);
}
# destroy stations on resource 3, 7, 8
my @radios = ();
my @destroy_me = ();
for my $rh_alias_link (@$ra_alias_links) {
push(@destroy_me, $rh_alias_link)
if (($rh_alias_link->{'uri'} =~m{^/port/1/[3678]/})
&& ($rh_alias_link->{'alias'} =~m{^sta}));
push(@radios, $rh_alias_link)
if (($rh_alias_link->{'uri'} =~m{^/port/1/[3678]/})
&& ($rh_alias_link->{'alias'} =~m{^wiphy}));
}
if ($do_destroy) {
logg("\nDestroying these: ");
for my $rh_target (@destroy_me) {
my $alias = $rh_target->{'alias'};
my @hunks = split(/[\/]/, $rh_target->{'uri'});
# TODO: create JsonUtils::rm_vlan($eid, $alias)
my $rh_data = {
'shelf'=>1, 'resource'=>$hunks[3], 'port'=>$alias
};
logg(" $alias");
json_post("/cli-json/rm_vlan", $rh_data);
usleep(150);
}
# this really should poll for ports to wait for them to disappear
sleep 2;
}
my @new_stations = ();
my $rh_radio;
my $radio_name;
my $resource;
my $range;
my $radio_num;
my @stations=();
logg("\nCreating new stations on these: ") if ($do_destroy);
for $rh_radio (@radios) {
$radio_name = $rh_radio->{'alias'};
my @hunks = split(/[\/]/, $rh_radio->{'uri'});
($radio_num) = $radio_name =~ /wiphy(\d+)/;
$resource = $hunks[3];
$range = ($resource * 1000) + ($radio_num * 100);
#logg("\n/cli-json/add_sta = ");
for (my $i = $range; $i < ($range+20); $i++) {
if ($resource == 3 || $resource >= 6) {
push(@stations, { 'resource'=>$resource, 'station'=> "sta$i"});
}
if ($do_destroy) {
# TODO: create JsonUtils::add_sta($eid, $alias...)
my $rh_data = {
'shelf'=>1,
'resource'=>$resource,
'radio'=>$radio_name,
'sta_name'=>"sta$i",
'flags'=>68862086144, # has port-down set
'ssid'=>'idtest-1200-wpa2',
'key'=>'idtest-1200-wpa2',
'mac'=>'xx:xx:xx:xx:*:xx',
'mode'=>0,
'rate'=>'DEFAULT'
};
logg(" sta$i");
json_post("/cli-json/add_sta", $rh_data);
usleep(210);
}
}
}
if ($do_destroy) {
sleep 1;
logg("\nSetting dhcp: ");
for my $rh_station (@stations) {
# this sets dhcp
logg(" $rh_station->{'station'}");
my $rh_data = {
'shelf'=>1,
'resource'=>$rh_station->{'resource'},
'port'=>$rh_station->{'station'},
'cmd_flags'=>0,
'current_flags'=>2147483648,
'interest'=>16386
};
# TODO: create JsonUtils::set_dhcp($eid, $alias, $on_off)
json_post("/cli-json/set_port", $rh_data);
usleep(210);
}
sleep 1;
}
my $set_port = "/cli-json/set_port";
logg("\nsetting ports up ");
for my $rh_station (@stations) {
logg(" $rh_station->{'station'}");
my %post = (
"shelf" => 1, "resource" => 0+$rh_station->{'resource'},
"port" => $rh_station->{"station"},
"current_flags" => 0, "interest" => 8388610
);
my $rh_response = json_post($set_port, \%post);
}
sleep 1;
my $number_down = scalar @stations;
logg("\nwaiting to raise $number_down ");
while($number_down > 0) {
$number_down = scalar @stations;
for my $rh_station (@stations) {
my $url = "/port/1/$rh_station->{'resource'}/$rh_station->{'station'}?fields=device,down,ip";
my $rh_obj = json_request($url);
if ($rh_obj->{'interface'}->{'ip'} ne "0.0.0.0") {
$number_down--;
}
#logg(" $number_down ".$rh_station->{'station'});
}
logg(" ".((scalar @stations) - $number_down)." up,");
last if ($number_down < 2);
sleep 3;
my $rh_response = json_post("/cli-json/nc_show_ports", {"shelf"=>1,"resource"=>"all","port"=>"all"});
}
# ports down
sleep 3;
logg("\nsetting ports down: ");
for my $rh_station (@stations) {
logg(" $rh_station->{'station'}");
my %post = (
"shelf" => 1, "resource" => 0+$rh_station->{'resource'},
"port" => $rh_station->{"station"},
"current_flags" => 1, "interest" => 8388610
);
my $rh_response = json_post($set_port, \%post);
}
#

View File

@@ -0,0 +1,183 @@
#!/usr/bin/perl -w
use strict;
use warnings;
use diagnostics;
use Carp;
use Time::HiRes qw(usleep);
$SIG{ __DIE__ } = sub { Carp::confess( @_ ) };
$SIG{ __WARN__ } = sub { Carp::confess( @_ ) };
# Un-buffer output
$| = 1;
use Getopt::Long;
use JSON::XS;
use HTTP::Request;
use LWP;
use LWP::UserAgent;
use Data::Dumper;
use JSON;
use lib '/home/lanforge/scripts';
use lib "../";
use lib "./";
use LANforge::JsonUtils qw(logg err json_request get_links_from get_thru json_post get_port_names flatten_list);
package main;
# Default values for ye ole cmd-line args.
our $Resource = 1;
our $quiet = "yes";
our $Host = "localhost";
our $Port = 8080;
our $HostUri = "http://$Host:$Port";
our $Web = LWP::UserAgent->new;
our $Decoder = JSON->new->utf8;
my $usage = qq("$0 --host {ip or hostname} # connect to this
--port {port number} # defaults to 8080
);
##
## M A I N
##
GetOptions
(
'host=s' => \$::Host,
'port=i' => \$::Port,
) || (print($usage) && exit(1));
$::HostUri = "http://$Host:$Port";
my $uri = "/shelf/1";
my $rh = json_request($uri);
my $ra_links = get_links_from($rh, 'resources');
my @links2= ();
my $ra_alias_links = [];
#print Dumper($rh_stations);
#sub flatten_list {
# my $rh_list = shift;
# my $list_name = shift;
# my $rh_irefs = {};
# for (my $i=0; $i < @{$rh_stations->{"interfaces"}}; $i++) {
# my @k = keys(%{$rh_stations->{"interfaces"}[$i]});
# my $id = $k[0];
# #print "ID[$id]\n";
# $rh_irefs->{$id} = $rh_stations->{"interfaces"}[$i]->{$id};
# }
# $rh_list->{"flat_list"} = $rh_irefs;
#}
# TODO: make this a JsonUtils::list_ports()
for $uri (@$ra_links) {
$uri =~ s{/resource}{/port}g;
$uri .= "/list";
#logg("requesting $uri");
$rh = json_request($uri);
#print Dumper($rh);
push( @$ra_alias_links, @{get_port_names($rh, 'interfaces')});
push(@links2, @{get_links_from($rh, 'interfaces')});
#logg("\nfound: ");
#logg(@links2);
}
#print Dumper($ra_alias_links);
# destroy stations on resource 3
my @radios = ();
for my $rh_alias_link (@$ra_alias_links) {
push(@radios, $rh_alias_link)
if (($rh_alias_link->{'uri'} =~m{^/port/1/[3]/})
&& ($rh_alias_link->{'alias'} =~m{^wiphy}));
}
logg(" updating ");
my $rh_update = {
'shelf'=>1, 'resource'=>'all', 'port'=>'all', 'probe_flags'=>'0x1'
};
my $rh_response = json_post("/cli-json/nc_show_ports", $rh_update);
# this really should poll for ports to wait for them to disappear
sleep 2;
my @new_stations = ();
logg("\nCreating new stations on these: ");
#print Dumper(\@radios);
my $rh_radio;
my $radio_name;
my $resource;
my $range;
my $num_sta = 160;
my $radio_num;
my $radio_counter = 0;
logg(" updating ");
$rh_response = json_post("/cli-json/nc_show_ports", $rh_update);
sleep 2;
$radio_counter = 0;
for $rh_radio (@radios) {
$radio_name = $rh_radio->{'alias'};
my @hunks = split(/[\/]/, $rh_radio->{'uri'});
($radio_num) = $radio_name =~ /wiphy(\d+)/;
$resource = $hunks[3];
$range = ($resource * 10000) + ($radio_num * 1000);
my $rh_stations = json_request("/port/1/$resource/all?fields=port,device,mac");
flatten_list($rh_stations, "interfaces");
for (my $i = $range; $i < ($range+$num_sta); $i++) {
print "sta$radio_counter = vsta$i [ $range .. ".($range+$num_sta)."] 1/$resource/$radio_num $radio_name \n";
my $portname = "sta$radio_counter";
my $eidport = "1.$resource.$portname";
if (defined $rh_stations->{"flat_list"}->{$eidport}) {
#my $macaddr = $rh_stations->{"flat_list"}->{$eidport}->{"mac"};
my $eid = $rh_stations->{"flat_list"}->{$eidport}->{"port"};
my @hunks = split(/[.]/, $eid);
die("port eid is bad: $eid")
if (!defined $hunks[2]);
my $portid = 0 + $hunks[2];
my $rh_data = {
'shelf'=>1,
'resource'=>$resource,
'port'=>$portname,
'interest'=>4096,
#'suppress_preexec_cli'=>'true',
#'suppress_preexec_method'=>'true',
#'suppress_postexec_cli'=>'false',
#'suppress_postexec_method'=>'false',
'alias'=>'vsta'.$i
}; # todo: set_alias
$rh_response = json_post("/cli-json/set_port", $rh_data);
#usleep(10000);
# set port up + dhcp
$rh_data = {
#'suppress_preexec_cli'=>'true',
#'suppress_preexec_method'=>'true',
#'suppress_postexec_cli'=>'false',
#'suppress_postexec_method'=>'false',
'shelf'=>1,
'resource'=>$resource,
'port'=>'sta'.$radio_counter,
'cmd_flags'=>0,
'current_flags'=>2147483648,
'interest'=>16386
};
# TODO: create JsonUtils::set_dhcp($eid, $alias, $on_off)
# set_port - port up, enable dhcp
# current_flags=2147483648&interest=16386
my $rh_response = json_post("/cli-json/set_port", $rh_data);
$radio_counter+=1;
usleep(10000);
}
else {
print " 1.$resource.sta$radio_counter not found ";
}
}
}
logg(" updating ");
$rh_response = json_post("/cli-json/nc_show_ports", $rh_update);
sleep 2;
#

View File

@@ -0,0 +1,13 @@
#!/bin/bash
# this is a test of the JSON add/show chamber api
echo 'name=cha&flags=OPEN' > /tmp/curl_data
curl -sqv -H 'Accept: application/json' -X POST -d '@/tmp/curl_data' http://cholla5:8080/cli-form/add_chamber
echo 'name=cha' > /tmp/curl_data
curl -sqv -H 'Accept: application/json' -X POST -d '@/tmp/curl_data' http://cholla5:8080/cli-form/show_chamber
#chamber [id] [angle] [flags] [table-speed-rpm]
#echo "cmd=chamber&arg1=cha&arg2=0&arg3=OPEN&arg5=3" > /tmp/curl_data
echo 'cmd=chamber&arg1=cha&arg2=0&arg3=open&arg5=3'
curl -sqv -H 'Accept: application/json' -X POST -d '@/tmp/curl_data' http://cholla5:8080/cli-form/admin

View File

@@ -0,0 +1,62 @@
#!/usr/bin/perl -w
use strict;
use warnings;
use diagnostics;
use Carp;
$SIG{ __DIE__ } = sub { Carp::confess( @_ ) };
$SIG{ __WARN__ } = sub { Carp::confess( @_ ) };
# Un-buffer output
$| = 1;
use Getopt::Long;
use JSON::XS;
use HTTP::Request;
use LWP;
use LWP::UserAgent;
use Data::Dumper;
use JSON;
use lib '/home/lanforge/scripts';
use lib "../";
use lib "./";
use LANforge::JsonUtils qw(err logg xpand json_request);
package main;
# Default values for ye ole cmd-line args.
our $Resource = 1;
our $quiet = "yes";
our $Host = "localhost";
our $Port = 8080;
our $HostUri = "http://$Host:$Port";
our $Web = LWP::UserAgent->new;
our $Decoder = JSON->new->utf8;
my $usage = qq($0: --host [hostname] # hostname or IP to query
--port [port] # port like 8080
);
##
## M A I N
##
GetOptions
(
'port=i' => \$::Port,
'host=s' => \$::Host,
) || (print($usage) && exit(1));
$HostUri = "http://$Host:$Port";
my $uri = "/port/1/1/list";
my $rh = json_request($uri);
#print Dumper($rh->{interfaces});
for my $rh_e (@{$rh->{interfaces}}) {
my @keys = keys(%$rh_e);
my $rh_val = $rh_e->{$keys[0]};
next if ($keys[0] !~ /sta/);
my $resp = json_request($rh_val->{_links}."?fields=alias,port,mode");
print Dumper($resp->{interface});
sleep 0.1;
}
#

View File

@@ -0,0 +1,70 @@
#!/usr/bin/perl -w
use strict;
use warnings;
use diagnostics;
use Carp;
$SIG{ __DIE__ } = sub { Carp::confess( @_ ) };
$SIG{ __WARN__ } = sub { Carp::confess( @_ ) };
# Un-buffer output
$| = 1;
use Getopt::Long;
use JSON::XS;
use HTTP::Request;
use LWP;
use LWP::UserAgent;
use Data::Dumper;
use Time::HiRes qw(usleep);
use JSON;
use lib '/home/lanforge/scripts';
use LANforge::JsonUtils qw(logg err json_request get_links_from get_thru json_post get_port_names flatten_list);
package main;
# Default values for ye ole cmd-line args.
our $Resource = 1;
our $quiet = "yes";
our $Host = "localhost";
our $Port = 8080;
our $HostUri = "http://$Host:$Port";
our $Web = LWP::UserAgent->new;
our $Decoder = JSON->new->utf8;
our $ssid;
our $security;
our $passphrase;
my $usage = qq("$0 --host {ip or hostname} # connect to this
--port {port number} # defaults to 8080
);
my $des_resource = 1;
GetOptions
(
'host=s' => \$::Host,
'port=i' => \$::Port,
'resource=i' => \$des_resource
) || (print($usage) && exit(1));
$::HostUri = "http://$Host:$Port";
my $uri = "/stations/list";
my $rh = json_request($uri);
my $ra_links = get_links_from($rh, 'stations');
# print(Dumper($ra_links));
my @attribs = ("ap", "signal", "tx rate", "rx rate", "capabilities");
for my $sta_uri (@$ra_links) {
my $with_fields = "$sta_uri?fields=station+bssid,capabilities,rx+rate,tx+rate,signal,ap";
$rh = json_request($with_fields);
#print(Dumper($rh));
#print(Dumper($rh->{station}));
print("Station ", $rh->{station}->{'station bssid'}, "\n");
for my $k (@attribs) {
print(" $k: ".$rh->{station}->{$k}."\n");
}
print("\n");
}

View File

@@ -0,0 +1,454 @@
#!/usr/bin/perl -w
=pod
Use this script to create a large number of L3 connections for emulating video
traffic. This script is going to assume that all the connections are going to
use the same traffic type and same traffic speed. This test will collect all the
L3 connections into a test group.
=cut
use strict;
use warnings;
use diagnostics;
use Carp;
$SIG{ __DIE__ } = sub { Carp::confess( @_ ) };
$SIG{ __WARN__ } = sub { Carp::confess( @_ ) };
# Un-buffer output
$| = 1;
# use lib prepends to @INC, so put lower priority first
# This is before run-time, so cannot condition this with normal 'if' logic.
use lib '/home/lanforge/scripts';
use lib "./";
use Data::Dumper;
use LANforge::Endpoint;
use LANforge::Port;
use LANforge::Utils;
use Net::Telnet ();
use Getopt::Long;
our $quiet = "yes";
our $lfmgr_host = "localhost";
our $lfmgr_port = 4001;
our $resource = 1;
our $action = "";
our $vid_mode = "yt-sdr-1080p30";
our $buffer_size = (3 * 1024 * 1024);
our $clear_group = -1;
my $cmd;
our $cx_name = "";
our $upstream = "";
our $endp_type = "tcp";
our $first_sta = "";
my $log_cli = "unset"; # use ENV{LOG_CLI} elsewhere
our $num_cx = -1;
my $show_help = 0;
our $speed = 1000 * 1000 * 1000;
our $generic_test_grp; # we will manage our generic connections using this group (l3_video_em)
our $l3_test_grp; # the actual Layer 3 cx will live here, starting with _L3_
our $use_ports_str = "NA";
our $use_speeds_str = "NA";
our $use_max_speeds = "NA";
our $usage = <<"__EndOfUsage__";
Usage: $0 # create a large group of Layer 3 creations that emulate video traffic
--action -a { create | destroy | start | stop }
--buffer_size -b {bytes K|M} # size of emulated RX buffer, default 3MB
--clear_group -z # empty test group first
--cx_name -c {connection prefix}
--endp_type -t {tcp|udp|lf_tcp|lf_udp}
--first_sta -i {name}
--log_cli {1|filename} # log cli commands
--mgr -m {lanforge server} # default localhost
--mgr_port -p {lanforge port} # default 4002
--num_cx -n {number} # default 1
--resource -r {station resource}
--speed -s {bps K|M|G} # maximum speed of tx side, default 1Gbps
--stream --vid_mode -e {stream resolution name|list} # default yt-sdr-1080p30
# list of streams maintained in l3_video_em.pl
--test_grp -g {test group name} # all connections placed in this group
# default is {cx_name}_tg for the Generic connections
# we manage Layer 3 connections in _L3_{cx_name}_tg
--upstream -u {port short-EID} # video transmitter port;
# use 1.1.eth1 or 1.2.br0 for example
# upstream port does not need to be on same resource
Examples:
# create 30 stations emulating 720p HDR 60fps transmitted from resource 2:
$0 --action create --buffer_size 8M --clear_group --cx_name yt1080p60.1 \\
--endp_type udp --first_sta sta0000 --num_cx 30 \\
--resource 2 --speed 200M --stream yt-hdr-720p60 --test_group yt60fps \\
--upstream 1.2.br0
# start test group:
$0 -a start -g yt60fps
# stop test group:
$0 -a stop -g yt60fps
# add 30 more stations on resource 3 to group
$0 -a create -b 8M -c yt1080p60.3 -t udp -i sta0100 -n 30 -r 3 \\
-s 200M -e yt-hdr-720p60 -g yt60fps -u 1.2.br0
# destroy test group
$0 -a destroy -g yt60fps
__EndOfUsage__
if (@ARGV < 2) {
print $usage;
exit 0;
}
our $debug = 0;
GetOptions
(
'action|a=s' => \$::action,
'buffer_size|b=s' => \$::buffer_size,
'clear_group|z' => \$::clear_group,
'cx_name|c=s' => \$::cx_name,
'debug|d' => \$::debug,
'endp_type|type|t=s' => \$::endp_type,
'first_sta|i=s' => \$::first_sta,
'help|h' => \$show_help,
'log_cli=s{0,1}' => \$log_cli,
'manager|mgr|m=s' => \$::lfmgr_host,
'mgr_port|p=i' => \$::lfmgr_port,
'num_cx|n=i' => \$::num_cx,
'quiet|q=s' => \$::quiet,
'resource|r=i' => \$::resource,
'speed|s=i' => \$::speed,
'stream|vid_mode|e' => \$::vid_mode,
'test_group|test_grp|group|g=s' => \$::generic_test_grp,
'upstream|u=s' => \$::upstream,
) || die($::usage);
if ($show_help) {
print $usage;
exit 0;
}
if ($::debug) {
$ENV{DEBUG} = 1 if (!(defined $ENV{DEBUG}));
}
if ($::quiet eq "0") {
$::quiet = "no";
}
elsif ($::quiet eq "1") {
$::quiet = "yes";
}
if (defined $log_cli) {
if ($log_cli ne "unset") {
# here is how we reset the variable if it was used as a flag
if ($log_cli eq "") {
$ENV{'LOG_CLI'} = 1;
}
else {
$ENV{'LOG_CLI'} = $log_cli;
}
}
}
our $utils = new LANforge::Utils;
$::utils->connect($lfmgr_host, $lfmgr_port);
#$::utils->doCmd("log_level 8");
# ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------
# M A I N
# ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------
# Apply defaults
if (!(defined $::generic_test_grp) || ("" eq $::generic_test_grp) || ("NA" eq $::generic_test_grp)) {
# use cx_name as prefix
if (!(defined $::cx_name) || ("" eq $::cx_name) || ("NA" eq $::cx_name)) {
die("No test_grp or cx_name is defined. Bye.");
}
$::generic_test_grp = $::cx_name ."_tg";
}
$::l3_test_grp = "_L3_".$::generic_test_grp;
# get a list of test groups
my $ra_tg_list = $::utils->test_groups();
print Dumper($ra_tg_list) if ($::debug);
my $ra_l3_cx_names = $::utils->group_items($::l3_test_grp);
my $ra_generic_cx_names = $::utils->group_items($::generic_test_grp);
# ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------
if (($::clear_group > 0) || ($::action eq "destroy")) {
if (@$ra_tg_list < 1) {
print "No test groups defined, bye.";
exit(1);
}
my @matches = grep {/^$::generic_test_grp$/} @$ra_tg_list;
print Dumper(\@matches) if ($::debug);
if (@matches < 1) {
print "No test group matching name [$::generic_test_grp], bye.";
exit(1);
}
print "will clear groups $::generic_test_grp and $::l3_test_grp\n";
$::utils->doCmd("clear_group $::generic_test_grp");
$::utils->doCmd("clear_group $::l3_test_grp");
}
# ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------
if ($::action eq "create") {
my $re = q(^TestGroup name:\s+).$::generic_test_grp.q(\s+[\[]);
my @matches = grep {/$re/} @$ra_tg_list;
print Dumper(\@matches) if ($::debug);
if (@matches < 1) {
print "Creating test group [$::generic_test_grp]...";
$::utils->doCmd($::utils->fmt_cmd("add_group", $::generic_test_grp));
print "Creating test group [$::l3_test_grp]...";
$::utils->doCmd($::utils->fmt_cmd("add_group", $::l3_test_grp));
}
if (!(defined $::cx_name) or ("" eq $::cx_name)) {
$::cx_name = $::generic_test_grp."-";
}
if (!(defined $::buffer_size) or ($::buffer_size < 0)) {
print ("Please set --buffer_size, bye.");
exit(1);
}
if (!(defined $::endp_type) or ("" eq $::endp_type)) {
print ("Please set --endp_type {tcp|udp}");
}
elsif ($::endp_type eq "tcp") {
$::endp_type = "lf_tcp";
}
elsif ($::endp_type eq "udp") {
$::endp_type = "lf_udp";
}
if ($::num_cx < 1) {
print "How many connections should we create? --num_cx 1? Bye.\n";
exit(1);
}
if (!(defined $::first_sta) or ("" eq $::first_sta)) {
print "Please set first station name: --first_sta 200; bye.";
exit(1);
}
if (!(defined $::upstream) or ("" eq $::upstream)) {
print "Please set your upstream port: --upstream 1.1.eth1; bye.";
exit(1);
}
elsif ($::upstream !~ /^1.\d+\.\S+$/) {
print "Upstream port should be named 1.<resource>.<name>\n EG: --upstream 1.1.eth1\nbye.";
exit(1);
}
if ( ! -x "./lf_firemod.pl" ) {
print "I don't see ./lf_firemod.pl, bye.";
exit(1);
}
my $upstream_resource = $::resource;
my $rh_eid_map = $::utils->get_eid_map($::resource);
die("Unable to find keys in rh_eid_map") if ((keys(%$rh_eid_map)) < 1);
my $rh_upstream_map = $rh_eid_map;
if ($::upstream !~ /^1\.$::resource\.\S+$/) {
$upstream_resource = (split('.', $::upstream))[1];
if (!(defined $upstream_resource) || ("" eq $upstream_resource)) {
die("Problem with upstream resource name");
}
$rh_upstream_map = $::utils->get_eid_map($upstream_resource);
}
#print Dumper($rh_eid_map);
# build a list of ports -n ports long starting at -first_port
my @ports = ();
my $rh_first_dev = $::utils->find_by_name($rh_eid_map, $::first_sta);
die("Unable to find dev record for port $::first_sta on resource $::resource")
if ($rh_first_dev == -1);
my $parent_name = $rh_first_dev->{parent};
die("Unable to find parent of $::first_sta, bye.")
if (!(defined $parent_name));
my $ra_interfaces = $::utils->ports_on_radio($rh_eid_map, $parent_name);
while (@$ra_interfaces < $::num_cx) {
# hack wiphy names
my ($wi, $nu) = $parent_name =~ /^([a-z]+)(\d+)$/;
$nu = 1 + $nu;
$parent_name = "${wi}${nu}";
my $ra_more = $::utils->ports_on_radio($rh_eid_map, $parent_name);
push(@$ra_interfaces, @$ra_more);
}
die("Unable to find any subinterfaces of $parent_name")
if (@$ra_interfaces < 1);
# want a pattern that matches Qvlan and Mvlan patterns, not just stations
# things like eth1.3 or rd0#0 or r0b#0
my ($prefix) = $::first_sta =~ /^(.*?[^0-9]+)\d+$/i;
#print "PREFIX IS $prefix\n";
my @selected_list = ();
foreach my $iface (sort @$ra_interfaces) {
#print "iface[$iface] ";
next if ($iface !~ /^$prefix/);
push(@selected_list, $iface);
last if (@selected_list >= $::num_cx);
}
if (@selected_list != $::num_cx) {
my $a = @selected_list;
print "Number of interfaces($a) does not match number of connections($::num_cx).\n"
." You probably don't have as many interfaces as you think.\n";
sleep 5;
}
my @next_cmds = ();
for (my $i=0; $i < @selected_list; $i++) {
my $j = 10000 + $i;
my $cname = "_".$::cx_name . substr("$j", 1);
my $ports = join('.', 1, $::resource, $selected_list[$i]).",".$::upstream;
#print "Connection name $name uses $ports\n";
my $cmd = qq(/home/lanforge/scripts/lf_firemod.pl --mgr $::lfmgr_host --mgr_port $::lfmgr_port )
.qq(--action create_cx --cx_name $cname --endp_type $::endp_type )
.qq(--use_ports $ports --use_speeds 0,0 --report_timer 3000);
#print "CMD: $cmd\n";
`$cmd`;
push(@next_cmds, "set_endp_flag $cname-A AutoHelper 1");
push(@next_cmds, "set_endp_flag $cname-B AutoHelper 1");
push(@next_cmds, $::utils->fmt_cmd("add_tgcx", $::l3_test_grp, $cname));
}
sleep 1;
$::utils->doAsyncCmd("nc_show_endpoints all"); # this helps prepare us for adding next generic connections
print "adding L3 CX to $::l3_test_grp ";
for my $cmd (@next_cmds) {
print ".";
$::utils->doCmd($cmd);
}
print "done\n";
print "Creating Generic connections for video emulation ";
$::utils->sleep_ms(20);
@next_cmds = ();
for (my $i=0; $i < @selected_list; $i++) {
my $j = 10000 + $i;
my $cname = "_".$::cx_name . substr("$j", 1);
my $ports = join('.', 1, $::resource, $selected_list[$i]).",".$::upstream;
my $gname = $::cx_name . substr("$j", 1);
my $gnr_cmd = qq(/home/lanforge/scripts/l3_video_em.pl --mgr $::lfmgr_host --mgr_port $::lfmgr_port )
.qq(--cx_name $cname --max_tx 1G --buf_size $::buffer_size )
.qq(--stream $::vid_mode --quiet yes );
$cmd = qq(./lf_firemod.pl --mgr $::lfmgr_host --mgr_port $::lfmgr_port)
.qq( --action create_endp --endp_name $gname --endp_type 'generic')
.qq( --port_name ).$selected_list[$i]
.q( --endp_cmd ").$gnr_cmd.q(");
`$cmd`;
print ".";
$::utils->sleep_ms(20);
#print "adding CX_$gname to $::generic_test_grp\n";
push(@next_cmds, $::utils->fmt_cmd("add_tgcx", $::generic_test_grp, "CX_".$gname));
}
print "done\n";
sleep 1;
$::utils->doAsyncCmd("nc_show_endpoints all"); # this helps prepare us for adding next generic connections
print "Adding generic connections to $::generic_test_grp ";
for my $cmd (@next_cmds) {
print ".";
$::utils->doCmd($cmd);
}
print "done\n";
exit 0;
}
# ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------
if ($::action eq "destroy") {
my @cmds = ();
if (@$ra_generic_cx_names < 1) {
print "No layer 3 connections in group [$::generic_test_grp], bye\n";
}
else {
print "Removing generic connections ";
foreach my $cx_name (@$ra_generic_cx_names) {
push(@cmds, "rm_cx default_tm ".$cx_name);
}
foreach my $cx_name (@$ra_generic_cx_names) {
$cx_name =~ s/^CX_/D_/;
push(@cmds, "rm_endp ".$cx_name);
$cx_name =~ s/^D_//;
push(@cmds, "rm_endp ".$cx_name);
}
foreach my $cmd (@cmds) {
print ".";
$::utils->doCmd($cmd);
$::utils->sleep_ms(30);
}
print "done\n";
}
$::utils->doCmd("rm_group $::generic_test_grp");
if (@$ra_l3_cx_names < 1) {
print "No layer 3 connections in group [$::l3_test_grp], bye\n";
}
else {
print "Removing L3 endpoints ";
@cmds = ();
foreach my $cx_name (@$ra_l3_cx_names) {
push(@cmds, "rm_cx default_tm ".$cx_name);
}
foreach my $cx_name (@$ra_l3_cx_names) {
push(@cmds, "rm_endp ${cx_name}-A");
push(@cmds, "rm_endp ${cx_name}-B");
}
foreach my $cmd (@cmds) {
print ".";
$::utils->doCmd($cmd);
$::utils->sleep_ms(30);
}
print "done\n";
}
$::utils->doCmd("rm_group $::l3_test_grp");
exit 0;
}
# ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------
if ($::action eq "start") {
if (!(defined $::generic_test_grp) || ("" eq $::generic_test_grp)) {
print "Please specify test group to start: --test_grp foo; bye.";
exit(1);
}
# collect all cx names in the test group and start up the
# video pulser on them
print "Starting connections...";
$::utils->doCmd("start_group $::l3_test_grp");
sleep 1;
$::utils->doCmd("start_group $::generic_test_grp");
exit 0;
}
# ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------
if ($::action eq "stop") {
if (!(defined $::generic_test_grp) || ("" eq $::generic_test_grp)) {
print "Please specify test group to stop: --test_grp foo; bye.";
exit(1);
}
# collect all cx names in the test group and start up the
# video pulser on them
print "Stopping connections...";
$::utils->doCmd("stop_group $::generic_test_grp");
sleep 1;
$::utils->doCmd("stop_group $::l3_test_grp");
exit 0;
}
# ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------
else {
die "What kind of action is [$::action]?";
}
# ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------
#END {
# if (defined $::utils->{telnet}) {
# print STDERR "reducing log level";
# $::utils->doCmd("log_level 2");
# }
#}

Some files were not shown because too many files have changed in this diff Show More