-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathjlanpro_test.pl
executable file
·1043 lines (892 loc) · 35.3 KB
/
jlanpro_test.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/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|-1: auto}]
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<floor($sta_max/4); $i++) {
my $sta_name = $stations[$i];
$cmd = "./lf_portmod.pl --quiet $quiet --manager $manager --card $resource --port_name $sta_name --wifi_mode 8 --set_speed \"v-3 Streams /AC\"";
do_cmd($cmd);
}
for ($i = floor($sta_max/4); $i<floor($sta_max*0.375); $i++) {
my $sta_name = $stations[$i];
$cmd = "./lf_portmod.pl --quiet $quiet --manager $manager --card $resource --port_name $sta_name --wifi_mode 8 --set_speed \"v-2 Streams /AC\"";
do_cmd($cmd);
}
for ($i = floor($sta_max*0.375);$ i<$sta_max; $i++) {
my $sta_name = $stations[$i];
$cmd = "./lf_portmod.pl --quiet $quiet --manager $manager --card $resource --port_name $sta_name --wifi_mode 8 --set_speed \"v-1 Stream /AC\"";
do_cmd($cmd);
}
wait_for_stations();
check_more_rest($testcase, $start);
if ($testcase == -1 || $testcase == 4) {
do_test_series("Mixed mode: 10 3x3, 15 2x2, 10 1x1 station upload/download test", 1.0);
if ($testcase == -1) {
sleep($rest_time);
}
}
}
# Interference mixed-mode test case
if ($testcase == -1 || $testcase == 5) {
wait_for_stations();
$cmd = "./lf_firemod.pl --mgr $manager --action do_cmd --cmd \"set_cx_state default_tm $interferer_cx RUNNING\"";
do_cmd($cmd);
do_test_series("Mixed mode: 10 3x3, 15 2x2, 10 1x1 station upload/download test with interference", 1.0);
$cmd = "./lf_firemod.pl --mgr $manager --action do_cmd --cmd \"set_cx_state default_tm $interferer_cx STOPPED\"";
do_cmd($cmd);
}
# WiFi capacity test
if ($testcase == -1 || $testcase == 6) {
# Set radio back to full antenna capacity
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);
}
for ($i = 0; $i < @stations; $i++) {
my $sta_name = $stations[$i];
$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);
}
#wait_for_stations(); WCT takes care of bringing stations up/down
my $sta_list = join(",", @stations4a);
# Call to automated wifi capacity test plugin
do_cmd("./lf_auto_wifi_cap.pl --mgr $manager --resource $resource --radio $radio_4a --speed_dl $speed_dl_tot --ssid $ssid --num_sta $wct_sta_max --upstream $upstream_port --upstream_resource $upstream_resource --percent_tcp 50 --increment 1,5,10,20,30,45,64 --duration $wct_duration_sec --endp_type mix --test_name wlanpro-$ssid --test_text 'Wlan-Pro test case #6 to ssid $ssid' --multicon $multicon --use_existing_sta --use_existing_cfg --use_station $sta_list --gui_host $gui_host --gui_port $gui_port --report_timer $rpt_timer_wct --settle_timer $settle_timer_wct");
}
if ($testcase == 100) {
# Cleanup
for ($i = 0; $i<@stations; $i++) {
my $sta_name = $stations[$i];
$cmd = "./lf_portmod.pl --quiet $quiet --mgr $manager --resource $resource --cmd delete --port_name $sta_name";
do_cmd("$cmd\n");
}
for ($i = 0; $i<@stations4a; $i++) {
my $sta_name = $stations4a[$i];
$cmd = "./lf_portmod.pl --quiet $quiet --mgr $manager --resource $resource --cmd delete --port_name $sta_name";
do_cmd("$cmd\n");
}
for ($i = 0; $i<@cxs; $i++) {
my $cxn = $cxs[$i];
$cmd = "./lf_firemod.pl --mgr $manager --action delete_cxe --cx_name $cxn";
do_cmd($cmd);
}
remove_cxs();
# Set radio back to full antenna capacity
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);
}
}
my $now_sec = time();
my $took = ($now_sec - $script_start) / 60;
logpb("Entire run took: $took minutes.\n");
logpb("Completed test at " . `date` . "\n\n");
# Append brief log and final log to the report.
logf($brief_log);
logp($summary_text);
logp("\n\n$mini_summary_text");
exit 0;
sub check_more_rest {
my $testcase = shift;
my $start = shift;
if ($testcase == -1) {
# Running tests in series, so we need to add in our rest time
my $now = time();
if ($start + $rest_time > $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");