diff --git a/jlanpro_test.pl b/jlanpro_test.pl new file mode 100755 index 00000000..5f99f7e7 --- /dev/null +++ b/jlanpro_test.pl @@ -0,0 +1,1043 @@ +#!/usr/bin/perl -w +# +# Data should be 500 bytes +# Test rig is one upstream wired system, which will be the manager as well as resource +# One ct523b as resource2, and a stand-by ct523b as resource3 +# WPA2 PSK encryption + +# 3x3 client testing: +# 20 clients uploading for 30 sec +# 20 clients downloading 30 sec +# 40 clients upload + download 1 minute +# Quiesce and wait 30 seconds + +# 2x2: Same +# 1x2: Same + +# Mixed mode: 10 3x3, 15 2x2, 15 1x1 (Same data pattern) + +# WiFi Capacit test notes: +# Mix of TCP and UDP, using MTU sized frames +# All 64 stations are on one 4x4 radio + +# Mixed With interference: Same as mixed mode +# Assume other test EQ is doing interference? + +# Each ct523b has 4 radios. We will spread stations among them. +# This script can work on systems with fewer radios as well, see comments +# below about naming the 3a,3b,4a,4b radios with duplicate names. + +use strict; +use warnings; +use diagnostics; +use Getopt::Long; +use Socket; +use POSIX; +our $pld_size = 500; +our $ssid = "wlanpro"; +our $psk = "wlanpro_passwd"; +# Default radio setup for 523b with 2ac, 2ac2. +# For something like a 522 with 2 radios, set 3a, 3b to wiphy0, and +# 4a 4b to wiphy1. +our $radio_3a = "wiphy0"; +our $radio_3b = "wiphy1"; +our $radio_4a = "wiphy2"; +our $radio_4b = "wiphy3"; +our $sta_max = 40; # For upload/download tests +our $wct_sta_max = 64; # For wifi-capacity-test on single radio (4a) +our $gui_host = "127.0.0.1"; # auto-wifi-cap script will not work properly if not run on same machine as GUI +our $gui_port = 7777; +our $resource = 2; +our $speed_dl_tot = 1000000000; +our $speed_ul_tot = 1000000000; +our $speed_ul_bi_tot = 200000000; # 200Mbps upload speed when in bi-directional mode +our $testcase = -1; +our $manager = "localhost"; +our $log_name = ""; + +our $endp_type = "lf_udp"; +our $security = "wpa2"; +our $upstream_resource = 1; +our $upstream_port = "eth1"; +our $multicon = "1"; +our $rest_time = 20; +our $quiet = "yes"; +our $report_timer = 1000; # 1 second report timer +our $rpt_timer_wct = 3000; # 3-second rpt timer for wifi-capacity test +our $settle_timer_wct = 10000; # 10-sec wait for connections to get running before clearing and starting the test proper +our $wct_duration_sec = 20; # Duration for each iteration +our $one_way_test_time = 30; +our $bi_test_time = 30; +our $interferer_cx = "inteferer_cx"; +our $ip = "DHCP"; +our $netmask = "255.255.0.0"; +our $ipn = 0; + +my $usage = "$0 + [--pld_size { bytes } ] + [--ssid {ssid}] + [--passphrase {password}] + [--3a {wiphy-radio-3x3-a}] + [--3b {wiphy-radio-3x3-b}] + [--4a {wiphy-radio-4x4-a}] + [--4b {wiphy-radio-4x4-b}] + [--resource {resource-number}] + [--upstream_resource {resource-number}] + [--upstream_port {port}] + [--speed_ul_tot {speed-bps (default: $speed_ul_tot)}] + [--speed_dl_tot {speed-bps (default: $speed_dl_tot)}] + [--speed_ul_bi_tot {speed-bps for upload in bi-directional test (default: $speed_ul_bi_tot)}] + [--security {open | wpa2}] + [--manager {manager-machine IP or hostname}] + [--testcase {test-case: -1: all except cleanup, 0: setup, 1: 3x3 ul/dl, + 2: 2x2 ul/dl 3: 1x1 ul/dl, 4: mix ul/dl, 5: mix ul/dl + interference, + 6: wifi-capacity-test, 100: cleanup}] + [--log_name {log-file-name}] + [--rest_time {seconds to sleep between rest runs, dfault is $rest_time}] + [--gui_host {LANforge gui_host (127.0.0.1): Must be same as where this script runs.}] + [--gui_port {LANforge gui_port (7777): Start your GUI with -cli-port 7777}] + [--interferer_cx { name of existing LANforge interferer-cx that we should start for the interference test }] + [--ip { DHCP | starting IP address. Default is to use DHCP. }] + [--netmask { Ignored if using DHCP, otherwise something like 255.255.255.0. Default is $netmask. }] + [--sta_max {max num stations}] + [--wct_sta_max {max num stations for capacity test}] + [--multicon {0: off|1: default|AUTO: means 0}] + +NOTE: The total speed will be multiplied by 1.0 for 3x3 and mixed tests, 0.75 for 2x2 testing, + and 0.5 for 1x1 testing. This should still attempt near theoretical throughput without + over-driving the DUT too badly. + +For the interference test, it is expected that the user create a CX of the proper name in +LANforge, associated to a wifi station, etc, and this script will simply start and stop it. +That will simplify this script and will give more flexibility on how the interferer is +configured. By default, the intereferer CX name will be 'interferer_cx'. + +Example command: + +# Run test case 5, assumes test case 0 (setup) has already been run. +./wlanpro_test.pl --ssid mu-mimo-5G --passphrase hello123 --resource 2 --upstream_resource 1 \ + --upstream_port eth4 --manager 192.168.100.182 --gui_port 7777 --interferer_cx inter_r3_w0 --testcase 5 + +# Run all test cases with Fixed IP addresses (instead of DHCP) +./wlanpro_test.pl --ssid mu-mimo-5G --passphrase hello123 --resource 2 --upstream_resource 1 --upstream_port eth4 --manager 192.168.100.182 --gui_host 192.168.100.149 --gui_port 7777 --interferer_cx inter_r3_w0 --testcase -1 --ip 5.5.5.1 --netmask 255.255.255.0 + + +Interesting bugs: + +While testing with a netgear r7800, I noticed that the RX encoding rate received from the AP +can be NSS 2 even when the station is configured for NSS 1. I double-checked that the association +request is using NSS 1 info, so this appears to be a bug in the Netgear. But, since the LANforge +radio can actually decode NSS 2 frames, then the packets are actually received and the Netgear gets +better performance than is warranted in this configuration. This appears to be a bug in the Netgear. + +"; + +my $usage_notes = " +Errors reported by the LANforge-GUI that you should be able to ignore: + +* ERROR: Cannot change MAC address with the 'add-vwifi' command. + Reason: Existing MAC would be fine anyway. + +"; + +my $script_start = time(); + +GetOptions ( + 'pld_size=i' => \$pld_size, + 'ssid=s' => \$ssid, + 'passphrase=s' => \$psk, + '3a=s' => \$radio_3a, + '3b=s' => \$radio_3b, + '4a=s' => \$radio_4a, + '4b=s' => \$radio_4b, + 'resource=i' => \$resource, + 'upstream_resource=i' => \$upstream_resource, + 'upstream_port=s' => \$upstream_port, + 'rest_time=i' => \$rest_time, + 'speed_ul_tot=s' => \$speed_ul_tot, + 'speed_ul_bi_tot=s' => \$speed_ul_bi_tot, + 'speed_dl_tot=s' => \$speed_dl_tot, + 'security=s' => \$security, + 'manager=s' => \$manager, + 'mgr=s' => \$manager, + 'testcase=i' => \$testcase, + 'log_name=s' => \$log_name, + 'gui_host=s' => \$gui_host, + 'gui_port=i' => \$gui_port, + 'interferer_cx=s' => \$interferer_cx, + 'ip=s' => \$ip, + 'netmask=s' => \$netmask, + 'sta_max=i' => \$sta_max, + 'wct_sta_max=i' => \$wct_sta_max, + 'multicon=s' => \$multicon, + ) || (print($usage) && exit(1)); + +if ($log_name eq "") { + $log_name = "wlanpro_log_" . $ssid . "_" . time() . ".txt"; +} +my @radios = ($radio_3a, $radio_3b, $radio_4a, $radio_4b); +my $radio_count = @radios; +my $i; +my $cmd; +my $log_prefix = "LANforge wlanpro-test\nConfiguration:\n" . + " SSID: $ssid passphrase: $psk security: $security resource: $resource\n" . + " speed_dl_request: $speed_dl_tot speed_ul_request: $speed_ul_tot payload-size: $pld_size traffic-type: $endp_type\n" . + " speed_ul_bi_request: $speed_ul_bi_tot interferer: $interferer_cx\n" . + " Test started at: " . `date` . "\n\n"; +my $brief_log = "$log_prefix"; +my $summary_text = "$log_prefix"; +my $mini_summary_text = "$log_prefix"; + +if ($ip ne "DHCP") { + $ipn = ip2ipn($ip); +} + +# Initial setup for test cases, create $sta_max stations +my @cxs = (); +my @stations = (); +my @stations4a = (); +my $sta_on_4a = 0; + +$SIG{'INT'} = sub { + print "Caught ctrl-C, exiting!\n"; + exit 1; +}; + +open(LOGF, ">$log_name") or die("Could not open log file: $log_name $!\n"); + +logp($log_prefix); + +# Stop any running tests. +stop_all_cx(); + +# Delete any wifi-capacity generated connections at this time, it will clean things +# up, and it will make parsing reporting data faster. +sub remove_cxs { + my @cx_dump = `./lf_firemod.pl --mgr $manager --action do_cmd --cmd \"show_cx\"`; + for (my $i = 0; $i<@cx_dump; $i++) { + my $line = $cx_dump[$i]; + chomp($line); + #print "looking for $upstream_resource, $upstream_port **** $line ****\n"; + # also match udp--1.eth4-02.sta102-B + if ($line =~ /CX:\s+((tcp|udp)\-\-$upstream_resource\.[^-]+-\S+)\b/) { + my $cxn = $1; + $cmd = "./lf_firemod.pl --mgr $manager --action delete_cxe --cx_name $cxn"; + do_cmd($cmd); + } + } +} + +remove_cxs(); +# Stop the interferer, just in case it is already running for some reason +$cmd = "./lf_firemod.pl --mgr $manager --action do_cmd --cmd \"set_cx_state default_tm $interferer_cx STOPPED\""; +do_cmd($cmd); + +# Set upstream port to DHCP or fixed IP as requested. +$cmd = "./lf_portmod.pl --quiet $quiet --manager $manager --card $upstream_resource --port_name $upstream_port --ip $ip --netmask $netmask"; +do_cmd($cmd); + +# Set radios to 3x3 mode. +if ($testcase == -1 || $testcase == 0) { + for ($i = 0; $i<$radio_count; $i++) { + my $radio = $radios[$i]; + my $set_cmd = "set_wifi_radio 1 $resource $radio NA NA NA NA NA NA NA NA NA 7"; + $cmd = "./lf_firemod.pl --mgr $manager --action do_cmd --cmd \"$set_cmd\""; + do_cmd($cmd); + } +} + +# Find wlanX for 4a radio. +if ($radio_4a =~ /\S+(\d+)/) { + my $sta_name = "wlan$1"; + @stations4a = (@stations4a, $sta_name); + my $radio = $radio_4a; + $sta_on_4a++; + if ($testcase == -1 || $testcase == 0 || $testcase == 6) { + my $_ip = incr_ip(); + $cmd = "./lf_vue_mod.sh --mgr $manager --create_sta --resource $resource --name $sta_name --radio $radio --security $security --ssid $ssid --passphrase $psk --ip $_ip --netmask $netmask"; + do_cmd($cmd); + + # Set to maximum mode. The stations might have been + # previously set to a different mode on an earlier run of this script. + $cmd = "./lf_portmod.pl --quiet $quiet --manager $manager --card $resource --port_name $sta_name --wifi_mode 8 --set_speed DEFAULT --set_ifstate up"; + do_cmd($cmd); + } +} + +for ($i = 0; $i < $sta_max; $i++) { + my $sta_idx = $i + 100; + my $radio_idx = $i % $radio_count; + my $radio = $radios[$radio_idx]; + my $sta_name = "sta$sta_idx"; + + if ($radio eq $radio_4a) { + $sta_on_4a++; + @stations4a = (@stations4a, $sta_name); + } + + @stations = (@stations, $sta_name); + + if ($testcase == -1 || $testcase == 0) { + my $_ip = incr_ip(); + $cmd = "./lf_vue_mod.sh --mgr $manager --create_sta --resource $resource --name $sta_name --radio $radio --security $security --ssid $ssid --passphrase $psk --ip $_ip --netmask $netmask"; + do_cmd($cmd); + + # Set to maximum mode. The stations might have been + # previously set to a different mode on an earlier run of this script. + $cmd = "./lf_portmod.pl --quiet $quiet --manager $manager --card $resource --port_name $sta_name --wifi_mode 8 --set_speed DEFAULT --set_ifstate up"; + do_cmd($cmd); + } + # Create data connection + my $cxn = "l3-${sta_name}"; + my $endpa = "$cxn-A"; + my $endpb = "$cxn-B"; + my $pkt_sz ="--min_pkt_sz $pld_size --max_pkt_sz $pld_size"; + my $gen_args = "--mgr $manager --multicon $multicon $pkt_sz --endp_type $endp_type --action create_endp --report_timer $report_timer"; + + if ($testcase == -1 || $testcase == 0) { + $cmd = "./lf_firemod.pl --resource $resource $gen_args --endp_name $endpa --speed 0 --port_name $sta_name"; + do_cmd($cmd); + + $cmd = "./lf_firemod.pl --resource $upstream_resource $gen_args --endp_name $endpb --speed 0 --port_name $upstream_port"; + do_cmd($cmd); + + $cmd = "./lf_firemod.pl --mgr $manager --action create_cx --cx_name $cxn --cx_endps $endpa,$endpb --report_timer $report_timer"; + do_cmd($cmd); + } + + @cxs = (@cxs, $cxn); +} + +# Create rest of the 4a-stations for Wifi Capacity Test +while ($sta_on_4a < $wct_sta_max) { + my $sta_idx = $sta_on_4a + 200; + my $radio = $radio_4a; + my $sta_name = "sta$sta_idx"; + + @stations4a = (@stations4a, $sta_name); + $sta_on_4a++; + + if ($testcase == -1 || $testcase == 0 || $testcase == 6) { + my $_ip = incr_ip(); + $cmd = "./lf_vue_mod.sh --mgr $manager --create_sta --resource $resource --name $sta_name --radio $radio --security $security --ssid $ssid --passphrase $psk --ip $_ip --netmask $netmask"; + do_cmd($cmd); + + # Set to maximum mode. The stations might have been + # previously set to a different mode on an earlier run of this script. + # Set them to admin-down, the wifi-capacity-test will bring them up as needed. + $cmd = "./lf_portmod.pl --quiet $quiet --manager $manager --card $resource --port_name $sta_name --wifi_mode 8 --set_speed DEFAULT --set_ifstate down"; + do_cmd($cmd); + } +} + +stop_all_cx(); + + +if ($testcase == -1 || $testcase == 1) { + wait_for_stations(); + do_test_series("3x3 station upload/download test", 1.0); +} + +if ($testcase == -1 || $testcase == 2) { + # Test case 2, set stations to 2x2 and re-test + my $start = time(); + for ($i = 0; $i<$radio_count; $i++) { + my $radio = $radios[$i]; + my $set_cmd = "set_wifi_radio 1 $resource $radio NA NA NA NA NA NA NA NA NA 4"; + $cmd = "./lf_firemod.pl --mgr $manager --action do_cmd --cmd \"$set_cmd\""; + do_cmd($cmd); + } + + wait_for_stations(); + check_more_rest($testcase, $start); + do_test_series("2x2 station upload/download test", 0.75); +} + +if ($testcase == -1 || $testcase == 3) { + # Test case 3, set stations to 1x1 and re-test + my $start = time(); + for ($i = 0; $i<$radio_count; $i++) { + my $radio = $radios[$i]; + my $set_cmd = "set_wifi_radio 1 $resource $radio NA NA NA NA NA NA NA NA NA 1"; + $cmd = "./lf_firemod.pl --mgr $manager --action do_cmd --cmd \"$set_cmd\""; + do_cmd($cmd); + } + + wait_for_stations(); + check_more_rest($testcase, $start); + do_test_series("1x1 station upload/download test", 0.50); +} + + +# Mixed mode test: 10 3x3, 15 2x2, 15 1x1 (Same data pattern) +if ($testcase == -1 || $testcase == 4 || $testcase == 5) { + # Set radio back to full antenna capacity + my $start = time(); + for ($i = 0; $i<$radio_count; $i++) { + my $radio = $radios[$i]; + my $set_cmd = "set_wifi_radio 1 $resource $radio NA NA NA NA NA NA NA NA NA 0"; + $cmd = "./lf_firemod.pl --mgr $manager --action do_cmd --cmd \"$set_cmd\""; + do_cmd($cmd); + } + + # 1/4 stations + for ($i = 0; $i $now) { + my $st = ($start + $rest_time) - $now; + print "Sleeping $st seconds for rest time..."; + sleep($st); + } + } +} + +# Wait until all stations are associated and have IP addresses. +sub wait_for_stations { + # Wait until stations are associated, return count + my $j; + for ($j = 0; $j<60; $j++) { + my $all_up = 1; + for ($i = 0; $i<@stations; $i++) { + my $sta_name = $stations[$i]; + $cmd = "./lf_portmod.pl --quiet $quiet --mgr $manager --resource $resource --show_port AP,IP --port_name $sta_name"; + logp("$cmd\n"); + my @output = `$cmd`; + if ($output[0] =~ "AP: Not-Associated") { + logp("Station $sta_name is not associated, waiting...\n"); + sleep(1); + $all_up = 0; + last; + } + if ($output[1] =~ "IP: 0.0.0.0") { + logp("Station $sta_name does not have an IP address, waiting...\n"); + sleep(1); + $all_up = 0; + last; + } + } + + if ($all_up) { + last; + } + } +} + +sub do_one_test { + my $speed_ul = shift; + my $speed_dl = shift; + my $cx_cnt = shift; + my $sleep_sec = shift; + my $series_desc = shift; + + # Download for X seconds + for ($i = 0; $i<$cx_cnt; $i++) { + my $cxn = $cxs[$i]; + my $endpa = "$cxn-A"; + my $endpb = "$cxn-B"; + + $cmd = "./lf_firemod.pl --mgr $manager --action set_endp --endp_name $endpa --speed $speed_ul"; + do_cmd($cmd); + + $cmd = "./lf_firemod.pl --mgr $manager --action set_endp --endp_name $endpb --speed $speed_dl"; + do_cmd($cmd); + + $cmd = "./lf_firemod.pl --mgr $manager --action do_cmd --cmd \"set_cx_state default_tm $cxn RUNNING\""; + do_cmd($cmd); + } + + $cmd = "./lf_firemod.pl --mgr $manager --action do_cmd --cmd \"clear_port_counters\""; + do_cmd($cmd); + + my $msg = "Waiting $sleep_sec seconds for test to run, $cx_cnt connections, requested per-connection speed, UL: $speed_ul DL: $speed_dl.\n" . + " Test-case: $series_desc\n\n"; + logp($msg); + $mini_summary_text .= "$cx_cnt connections, requested per-connection speed, UL: $speed_ul DL: $speed_dl\n"; + + sleep($sleep_sec); + + logp("Gathering stats for this test run...\n"); + + # Gather layer-3 stats data + my $sp; + + my $tmpfe = "wptest_endp_stats_tmp.txt"; + `./lf_portmod.pl --manager $manager --cli_cmd "nc_show_endp" > $tmpfe`; + + my $tmpf = "wptest_stats_tmp.txt"; + `./lf_portmod.pl --manager $manager --cli_cmd "nc_show_port 1 $resource" > $tmpf`; + if ($resource != $upstream_resource) { + `./lf_portmod.pl --manager $manager --cli_cmd "nc_show_port 1 $upstream_resource" >> $tmpf`; + } + + # Stop the connections while we process stats. + stop_all_cx(); + + logp("Processing stats for this test run...\n"); + + # Process stats + $sp = `cat $tmpfe`; + logf("$sp\n"); + + # Open-code the report gathering for efficiency. + + # For each endpoint, see if it is one we care about, and gather reporting. Put it + # in a hash so we can search for it efficiently and generate ordered output. + my %endp_rx_rate = (); + my %endp_tx_rate = (); + my @lines = split("\n", $sp); + # Append dummy line to make it easier to terminate the parse logic. + @lines = (@lines, "Endpoint [________] (NOT_RUNNING)\n"); + my $endp_text = ""; + my $ep = ""; + + for ($i = 0; $i<@lines;$i++) { + my $line = $lines[$i]; + chomp($line); + if (($line =~ /Endpoint\s+\[(.*)\]/) || + ($line =~ /WanLink\s+\[(.*)\]/) || + ($line =~ /ArmEndp\s+\[(.*)\]/) || + # TODO: Layer-4 ? + ($line =~ /VoipEndp\s+\[(.*)\]/)) { + my $m1 = $1; + + #print "Found starting line: $line name: $m1 endp_name: $endp_name\n"; + + if ($endp_text ne "") { + # endp_text holds output for endpoint $ep. Gather stats and store them in our hashes + if ($endp_text =~ /.*RealTxRate:\s+(\S+)bps.*RealRxRate:\s+(\S+)bps/s) { + $endp_tx_rate{$ep} = $1; + $endp_rx_rate{$ep} = $2; + #print "Found $ep tx-rate: $1 rx-rate: $2\n"; + } + } + + $endp_text = "$line\n"; + $ep = $m1; + } + else { + if ($endp_text ne "") { + $endp_text .= "$line\n"; + } + } + } + + my $tot_dl_bps = 0; + my $tot_ul_bps = 0; + # Our endp names are derived from cx, so use that to our advantage. + for ($i = 0; $i<$cx_cnt; $i++) { + my $cxn = $cxs[$i]; + my $epa = "$cxn-A"; + my $epb = "$cxn-B"; + + $summary_text .= "$cxn:"; + my $tx = $endp_tx_rate{$epa}; + my $rx = $endp_rx_rate{$epa}; + + $tot_dl_bps += $rx; + $summary_text .= sprintf(" Download RX: %.3fMbps", $rx / 1000000); + $summary_text .= sprintf(" Upload TX: %.3fMbps", $tx / 1000000); + + $tx = $endp_tx_rate{$epb}; + $rx = $endp_rx_rate{$epb}; + + $tot_ul_bps += $rx; + $summary_text .= sprintf(" Upload RX: %.3fMbps", $rx / 1000000); + $summary_text .= sprintf(" Download TX: %.3fMbps", $tx / 1000000); + $summary_text .= "\n"; + } + $summary_text .= sprintf("Total Endpoint Upload RX: %.3fMbps Download RX: %.3fMbps\n\n", $tot_ul_bps / 1000000, $tot_dl_bps / 1000000); + $mini_summary_text .= sprintf("Total Endpoint Upload RX: %.3fMbps Download RX: %.3fMbps\n\n", $tot_ul_bps / 1000000, $tot_dl_bps / 1000000); + + # Port + $sp = `cat $tmpf`; + logf("$sp\n"); + @lines = split("\n", $sp); + # Append dummy line to make it easier to terminate the parse logic. + @lines = (@lines, "Shelf: 9999, Card: 9999, Port: 9999 Type: STA Alias: \n"); + + my %port_mac = (); + my %port_tx_rate_link = (); + my %port_tx_rate = (); + my %port_rx_rate = (); + my %port_ssid = (); + my %port_mode = (); + my %port_nss = (); + my %port_bandwidth = (); + my %port_channel = (); + my %port_ap = (); + my %port_rx_rate_link = (); + my %port_signal = (); + my %port_activity = (); + + my $port_text = ""; + my $s = -1; + my $c = -1; + my $p = -1; + + for ($i = 0; $i<@lines;$i++) { + my $line = $lines[$i]; + chomp($line); + #print "line: $line\n"; + if ($line =~ /Shelf:\s+(\d+).*Card:\s+(\d+).*Port:\s+(\d+)/) { + my $m1 = $1; + my $m2 = $2; + my $m3 = $3; + + if ($port_text ne "") { + # port_text holds output for port $s.$c.$p. Gather stats and store them in our hashes + if ($port_text =~ /DEV:\s+(\S+)/) { + $p = $1; + } + my $pkey = "$s.$c.$p"; + #print "pkey: $pkey\n"; + # We want: bps_rx,bps_tx,MAC,TX-Rate,Signal,Link-Activity,Channel,Bandwidth,NSS + if ($port_text =~ /.*MAC:\s+(\S+).*Tx-Rate:\s+(\S+).*bps_tx:\s+(\S+)\s+bps_rx:\s+(\S+).*/s) { + $port_mac{$pkey} = $1; + $port_tx_rate_link{$pkey} = $2; + $port_tx_rate{$pkey} = $3; + $port_rx_rate{$pkey} = $4; + } + else { + print "Did not find MAC etc in text: $port_text\n"; + exit 1; + } + + if ($port_text =~ /.*ESSID: (.*) Antenna.*/) { + $port_ssid{$pkey} = $1; + } + + # WiFi stuff should come from the Probed section + if ($port_text =~ /.*Probed:\s+(.*)/s) { + my $haystack = $1; + + # We want: Mode,NSS,Bandwidth,Channel,AP,RX-Rate,Signal,Link-Activity + if ($haystack =~ /.*Mode:\s+(\S+).* NSS:\s+(\S+).*Bandwidth: (\S+).*Channel:\s+(\S+).* AP:\s+(\S+).*RX-Rate: (\S+).*Signal: (\S+).*Link-Activity: (\S+).*/s) { + $port_mode{$pkey} = $1; + $port_nss{$pkey} = $2; + $port_bandwidth{$pkey} = $3; + $port_channel{$pkey} = $4; + $port_ap{$pkey} = $5; + $port_rx_rate_link{$pkey} = $6; + $port_signal{$pkey} = $7; + $port_activity{$pkey} = $8; + } + # Deal with no AP or Signal field reported. + elsif ($haystack =~ /.*Mode:\s+(\S+).* NSS:\s+(\S+).*Bandwidth: (\S+).*Channel:\s+(\S+).*RX-Rate: (\S+).*Link-Activity: (\S+).*/s) { + $port_mode{$pkey} = $1; + $port_nss{$pkey} = $2; + $port_bandwidth{$pkey} = $3; + $port_channel{$pkey} = $4; + $port_rx_rate_link{$pkey} = $5; + $port_signal{$pkey} = $6; + $port_activity{$pkey} = $7; + $port_ap{$pkey} = "NA"; + $port_signal{$pkey} = "-1"; + } + else { + print "Did not find probed wifi data, raw-text:\n$haystack\nFull port output:\n$port_text"; + exit 1; + } + } + } + + $port_text = "$line\n"; + $s = $m1; + $c = $m2; + $p = $m3; + } + else { + if ($port_text ne "") { + $port_text .= "$line\n"; + } + } + }# for + + $tot_dl_bps = 0; + $tot_ul_bps = 0; + + for ($i = 0; $i<@stations; $i++) { + my $sta_name = $stations[$i]; + my $pkey = "1.$resource.$sta_name"; + my $mac = $port_mac{$pkey}; + my $tx_rate_link = $port_tx_rate_link{$pkey}; + my $tx_rate = $port_tx_rate{$pkey}; + my $rx_rate = $port_rx_rate{$pkey}; + my $ssid = $port_ssid{$pkey}; + my $mode = $port_mode{$pkey}; + my $nss = $port_nss{$pkey}; + my $bandwidth = $port_bandwidth{$pkey}; + my $channel = $port_channel{$pkey}; + my $ap = $port_ap{$pkey}; + my $rx_rate_link = $port_rx_rate_link{$pkey}; + my $signal = $port_signal{$pkey}; + my $activity = $port_activity{$pkey}; + + $brief_log .= "Station Stats:\nMAC: $mac SSID: $ssid Mode: $mode NSS: $nss Bandwidth: $bandwidth\n"; + $brief_log .= "\tChannel: $channel AP: $ap Signal: $signal Activity: $activity TX-Link-Rate: $tx_rate_link RX-Link-Rate: $rx_rate_link\n"; + $brief_log .= "\tTX-Rate: ${tx_rate}bps RX-Rate: ${rx_rate}bps"; + + $summary_text .= "$sta_name:"; + $tot_dl_bps += $rx_rate; + $summary_text .= sprintf(" RX: %.3fMbps", $rx_rate / 1000000); + + $tot_ul_bps += $tx_rate; + $summary_text .= sprintf(" TX: %.3fMbps", $tx_rate / 1000000); + + $summary_text .= " NSS: $nss RX-Rate: $rx_rate_link TX-Rate: $tx_rate_link Signal: $signal\n"; + } + $summary_text .= sprintf("Total station TX: %.3fMbps RX: %.3fMbps\n\n", $tot_ul_bps / 1000000, $tot_dl_bps / 1000000); + + # Radio stats + $tot_dl_bps = 0; + $tot_ul_bps = 0; + my @rep_ports = uniq(@radios); + for ($i = 0; $i<@rep_ports; $i++) { + my $sta_name = $rep_ports[$i]; + my $pkey = "1.$resource.$sta_name"; + + my $mac = $port_mac{$pkey}; + my $tx_rate = $port_tx_rate{$pkey}; + my $rx_rate = $port_rx_rate{$pkey}; + my $mode = $port_mode{$pkey}; + my $nss = $port_nss{$pkey}; + + $brief_log .= "Radio Stats for $sta_name:\nMAC: $mac Mode: $mode NSS: $nss\n"; + $brief_log .= "\tTX-Rate: ${tx_rate}bps RX-Rate: ${rx_rate}bps"; + + $summary_text .= "$sta_name:"; + $tot_dl_bps += $rx_rate; + $summary_text .= sprintf(" RX: %.3fMbps", $rx_rate / 1000000); + $tot_ul_bps += $tx_rate; + $summary_text .= sprintf(" TX: %.3fMbps", $tx_rate / 1000000); + $summary_text .= " Mode: $mode NSS: $nss\n"; + } + $summary_text .= sprintf("Total Radio TX: %.3fMbps RX: %.3fMbps\n\n", $tot_ul_bps / 1000000, $tot_dl_bps / 1000000); + + # Upstream port + my $pkey = "1.$upstream_resource.$upstream_port"; + my $mac = $port_mac{$pkey}; + my $tx_rate = $port_tx_rate{$pkey}; + my $rx_rate = $port_rx_rate{$pkey}; + my $mode = $port_mode{$pkey}; + my $nss = $port_nss{$pkey}; + + $brief_log .= "Upstream Port Stats for $pkey:\nMAC: $mac"; + $brief_log .= " TX-Rate: ${tx_rate}bps RX-Rate: ${rx_rate}bps"; + + $summary_text .= "$pkey:"; + $summary_text .= sprintf(" RX: %.3fMbps", $rx_rate / 1000000); + $summary_text .= sprintf(" TX: %.3fMbps", $tx_rate / 1000000); + + # The code below works, and makes use of existing scripts to make it perhaps more + # clear to understand, but it is quite slow. So, will hand-code some more efficient + # reporting. --Ben +# my $tot_dl_bps = 0; +# my $tot_ul_bps = 0; +# # Our endp names are derived from cx, so use that to our advantage. +# for ($i = 0; $i<$cx_cnt; $i++) { +# my $cxn = $cxs[$i]; +# my $epa = "$cxn-A"; +# my $epb = "$cxn-B"; + +# my $ep_stats = `./lf_firemod.pl --endp_name $epa --stats_from_file $tmpfe --endp_vals RealRxRate,RealTxRate`; +# $brief_log .= "Endpoint Stats for $epa:\n$ep_stats\n\n"; +# $summary_text .= "$cxn:"; +# if ($ep_stats =~ /RealRxRate:\s+(\d+)/) { +# $tot_dl_bps += $1; +# $summary_text .= sprintf(" Download RX: %.3fMbps", $1 / 1000000); +# } +# if ($ep_stats =~ /RealTxRate:\s+(\d+)/) { +# $summary_text .= sprintf(" Upload TX: %.3fMbps", $1 / 1000000); +# } +# $ep_stats = `./lf_firemod.pl --endp_name $epb --stats_from_file $tmpfe --endp_vals RealRxRate,RealTxRate`; +# $brief_log .= "Endpoint Stats for $epb:\n$ep_stats\n\n"; +# if ($ep_stats =~ /RealRxRate:\s+(\d+)/) { +# $tot_ul_bps += $1; +# $summary_text .= sprintf(" Upload RX: %.3fMbps", $1 / 1000000); +# } +# if ($ep_stats =~ /RealTxRate:\s+(\d+)/) { +# $summary_text .= sprintf(" Download TX: %.3fMbps", $1 / 1000000); +# } +# $summary_text .= "\n"; +# } +# $summary_text .= sprintf("Total Endpoint Upload RX: %.3fMbps Download RX: %.3fMbps\n\n", $tot_ul_bps / 1000000, $tot_dl_bps / 1000000); +# $mini_summary_text .= sprintf("Total Endpoint Upload RX: %.3fMbps Download RX: %.3fMbps\n\n", $tot_ul_bps / 1000000, $tot_dl_bps / 1000000); + +# # Port +# $sp = `cat $tmpf`; +# logf("$sp\n"); + +# $tot_dl_bps = 0; +# $tot_ul_bps = 0; +# for ($i = 0; $i<@stations; $i++) { +# my $sta_name = $stations[$i]; +# my $sta_stats = `./lf_portmod.pl --card $resource --port_name $sta_name --stats_from_file $tmpf --show_port AP,ESSID,bps_rx,bps_tx,MAC,Mode,RX-Rate,TX-Rate,Signal,Link-Activity,Channel,Bandwidth,NSS`; +# $brief_log .= "Station Stats:\n$sta_stats\n\n"; +# $summary_text .= "$sta_name:"; +# if ($sta_stats =~ /bps_rx:\s+(\d+)/) { +# $tot_dl_bps += $1; +# $summary_text .= sprintf(" RX: %.3fMbps", $1 / 1000000); +# } +# if ($sta_stats =~ /bps_tx:\s+(\d+)/) { +# $tot_ul_bps += $1; +# $summary_text .= sprintf(" TX: %.3fMbps", $1 / 1000000); +# } +# if ($sta_stats =~ /NSS:\s+(\d+)/) { +# $summary_text .= " NSS: $1"; +# } +# if ($sta_stats =~ /RX-Rate:\s+(\S+)/) { +# $summary_text .= " RX-Rate: $1"; +# } +# if ($sta_stats =~ /TX-Rate:\s+(\S+)/) { +# $summary_text .= " TX-Rate: $1"; +# } +# if ($sta_stats =~ /Signal:\s+(\S+)/) { +# $summary_text .= " Signal: $1"; +# } +# $summary_text .= "\n"; +# } +# $summary_text .= sprintf("Total station TX: %.3fMbps RX: %.3fMbps\n\n", $tot_ul_bps / 1000000, $tot_dl_bps / 1000000); + +# # Radio stats +# $tot_dl_bps = 0; +# $tot_ul_bps = 0; +# my @rep_ports = uniq(@radios); +# for ($i = 0; $i<@rep_ports; $i++) { +# my $sta_name = $rep_ports[$i]; +# my $sta_stats = `./lf_portmod.pl --card $resource --port_name $sta_name --stats_from_file $tmpf --show_port bps_rx,bps_tx,MAC,Mode,NSS`; +# $brief_log .= "Radio Stats for $sta_name:\n$sta_stats\n\n"; +# $summary_text .= "$sta_name:"; +# if ($sta_stats =~ /bps_rx:\s+(\d+)/) { +# $tot_dl_bps += $1; +# $summary_text .= sprintf(" RX: %.3fMbps", $1 / 1000000); +# } +# if ($sta_stats =~ /bps_tx:\s+(\d+)/) { +# $tot_ul_bps += $1; +# $summary_text .= sprintf(" TX: %.3fMbps", $1 / 1000000); +# } +# if ($sta_stats =~ /Mode:\s+(\S+)/) { +# $summary_text .= " Mode: $1"; +# } +# $summary_text .= "\n"; +# } +# $summary_text .= sprintf("Total Radio TX: %.3fMbps RX: %.3fMbps\n\n", $tot_ul_bps / 1000000, $tot_dl_bps / 1000000); + +# # Upstream port +# my $p_stats = `./lf_portmod.pl --card $upstream_resource --port_name $upstream_port --stats_from_file $tmpf --show_port bps_rx,bps_tx,MAC,RX-Rate,TX-Rate`; +# $brief_log .= "Upstream Port Stats:\n$p_stats\n\n"; +# $summary_text .= "$upstream_port:"; +# if ($p_stats =~ /bps_rx:\s+(\d+)/) { +# $tot_dl_bps += $1; +# $summary_text .= sprintf(" RX: %.3fMbps", $1 / 1000000); +# } +# if ($p_stats =~ /bps_tx:\s+(\d+)/) { +# $tot_ul_bps += $1; +# $summary_text .= sprintf(" TX: %.3fMbps", $1 / 1000000); +# } +# if ($p_stats =~ /RX-Rate:\s+(\S+)/) { +# $summary_text .= " RX-Rate: $1"; +# } +# if ($p_stats =~ /TX-Rate:\s+(\S+)/) { +# $summary_text .= " TX-Rate: $1"; +# } + $summary_text .= "\n"; +} + +sub stop_all_cx { + $cmd = "./lf_firemod.pl --mgr $manager --action do_cmd --cmd \"set_cx_state all all STOPPED\""; + do_cmd($cmd); +} + +sub stop_all_my_cx { + my $i; + + for ($i = 0; $i<@cxs; $i++) { + my $cxn = $cxs[$i]; + $cmd = "./lf_firemod.pl --mgr $manager --action do_cmd --cmd \"set_cx_state default_tm $cxn STOPPED\""; + do_cmd($cmd); + } +} + +sub logf { + my $text = shift; + print LOGF $text; +} + +sub logp { + my $text = shift; + print LOGF $text; + print $text; # to std-out too +} + +sub logpb { + my $text = shift; + print LOGF $text; + print $text; # to std-out too + $brief_log .= "$text"; + $summary_text .= "$text"; # Even sparser summary output +} + +sub do_test_series { + my $desc = shift; + my $speed_mult = shift; + my $msg = "\n" . `date` . "Doing test series: $desc\n"; + + logpb($msg); + $mini_summary_text .= $msg; + + # First test case, 20 stations downloading, 3x3 mode. + logpb("\nDoing download test with 20 stations.\n"); + do_one_test(0, floor(($speed_dl_tot * $speed_mult) / 20), 20, $one_way_test_time, $desc); + # Upload 30 sec + logpb("\nDoing upload test with 20 stations.\n"); + do_one_test( floor(($speed_ul_tot * $speed_mult) / 20), 0, 20, $one_way_test_time, $desc); + # Upload/Download 1 minute sec + logpb("\nDoing upload/download test with $sta_max stations.\n"); + do_one_test(floor(($speed_ul_bi_tot * $speed_mult) / $sta_max), + floor(($speed_dl_tot * $speed_mult) / $sta_max), + $sta_max, + $bi_test_time, + $desc); +} + +sub do_cmd { + my $cmd = shift; + logp("$cmd\n"); + return system($cmd); +} + +sub uniq { + my %seen; + grep !$seen{$_}++, @_; +} + +sub incr_ip { + if ($ip eq "DHCP") { + return "DHCP"; + } + $ipn++; + return ipn2ip($ipn); +} + +sub ip2ipn { + return unpack 'N', inet_aton(shift); +} + +sub ipn2ip { + return inet_ntoa( pack 'N', shift ); +} + + +my @array = qw(one two three two three); +my @filtered = uniq(@array); diff --git a/mem-info.sh b/mem-info.sh new file mode 100755 index 00000000..68cf40ac --- /dev/null +++ b/mem-info.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -x +java_pid=`pgrep java` +[ -z "$java_pid" ] && echo "no running java process" && exit 1 + +p_jmap=`which jmap` +[ -z "$p_jmap" ] && echo "jmap not found" && exit 1 + +now=`date +heap_+%Y-%m-%d_%I-%M-%S` +$p_jmap -dump:live,format=b,file=/home/lanforge/Documents/$now.bin $java_pid + +jstack $java_pid +echo done