-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdemo7.java
More file actions
1821 lines (1537 loc) · 75.5 KB
/
demo7.java
File metadata and controls
1821 lines (1537 loc) · 75.5 KB
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
// *********************************************************************************************
//
// Automatically Generated Load Test Program
// -----------------------------------------
//
// Source: demo7.java
// Date : 11 Aug 2016 08:49:06 ECT
// Author: Apica ZebraTester V5.4-N / automatically generated
//
// Procedure Copyright by Ingenieurbuero David Fischer AG | A Company of the Apica Group
// All Rights Reserved
//
// http://www.apicasystem.com http://www.zebratester.com
// *********************************************************************************************
import java.io.*;
import java.util.*;
import java.util.concurrent.atomic.*;
import dfischer.utils.AbstractInputFileReader;
import dfischer.utils.Base64Decoder;
import dfischer.utils.Base64Encoder;
import dfischer.utils.ConvertToDoubleNumber;
import dfischer.utils.ContentTokenExtractor;
import dfischer.utils.ContentTokenExtractorItem;
import dfischer.utils.Cookie;
import dfischer.utils.CookieHandler;
import dfischer.utils.DigestAuthContext;
import dfischer.utils.DNSCache;
import dfischer.utils.DNSTranslationTable;
import dfischer.utils.DynamicProtobufContentParser;
import dfischer.utils.ExternalParamFile;
import dfischer.utils.FileCache;
import dfischer.utils.GenericPluginInterface;
import dfischer.utils.GetRealTimeUserInputFieldsInterface;
import dfischer.utils.HtmlContentParser;
import dfischer.utils.HtmlHeaderCookieExtractor;
import dfischer.utils.HttpLoadTest;
import dfischer.utils.HttpLoadTestIncrementUserThread;
import dfischer.utils.HttpLoadTestUserContext;
import dfischer.utils.HttpSocketPool;
import dfischer.utils.HttpTestURL;
import dfischer.utils.HttpTestURLDNSContext;
import dfischer.utils.HttpTestURLThreadHandler;
import dfischer.utils.InlineScriptExecutionException;
import dfischer.utils.InlineScriptExecutor;
import dfischer.utils.InnerLoopContext;
import dfischer.utils.Lib;
import dfischer.utils.LoadtestInlineScriptContext;
import dfischer.utils.LoadtestInlineScriptVar;
import dfischer.utils.LoadtestPluginClassLoader;
import dfischer.utils.LoadtestPluginContext;
import dfischer.utils.NextProxyConfig;
import dfischer.utils.ParseArgs;
import dfischer.utils.ParseUrl;
import dfischer.utils.PerformanceData;
import dfischer.utils.PerformanceDataTickExtension;
import dfischer.utils.ProtobufFieldAndValueElement;
import dfischer.utils.ProtobufLib;
import dfischer.utils.RealTimeUserInputField;
import dfischer.utils.ScreenshotImage;
import dfischer.utils.SetThreadStepInterface;
import dfischer.utils.SSLInit;
import dfischer.utils.SSLSessionCacheStatistic;
import dfischer.utils.SSLSessionCacheStatisticInterface;
import dfischer.utils.SuspendResumeInterface;
import dfischer.utils.TextLineTokenExtractor;
import dfischer.utils.TextLineTokenExtractorItem;
import dfischer.utils.ThreadStepInterface;
import dfischer.utils.UserInputField;
import dfischer.utils.UserTransactionContext;
import dfischer.utils.UserTransactionRuntimeHandler;
import dfischer.utils.VarInputFileReader;
import dfischer.utils.VarRandomInputFileReader;
import dfischer.utils.VaryingLoadInterface;
import dfischer.utils.VaryingTestDurationInterface;
import dfischer.utils.XmlContentParser;
import dfischer.utils.XmlDoctypeCommentParser;
import dfischer.utils.ZoneTime;
import dfischer.proxysniffer.ProxySnifferVarSourceInlineScript;
import dfischer.utils.BoundaryBasedExtractor;
import dfischer.utils.BoundaryBasedExtractorItem;
import dfischer.utils.RegExpBasedExtractor;
import dfischer.utils.RegExpBasedExtractorItem;
import dfischer.proxysniffer.WebSocketData;
import dfischer.utils.HttpTestWebsocketContext;
import dfischer.websocket.*;
/**
* Automatically generated load test program.
*/
public class demo7 extends HttpLoadTest implements Runnable, ThreadStepInterface, SetThreadStepInterface, SSLSessionCacheStatisticInterface, VaryingLoadInterface, VaryingTestDurationInterface, SuspendResumeInterface, GetRealTimeUserInputFieldsInterface
{
public static final String prxVersion = "V5.4-N";
public static final int prxCharEncoding = 2; // 1 = OS Default, 2 = ISO-8859-1, 3 = UTF-8
public static final String testDescription = "";
public static String USER_AGENT_1 = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:47.0) Gecko/20100101 Firefox/47.0";
private static final boolean CONTAINS_PARALLEL_EXECUTED_URLS = false;
private static final int MAX_PARALLEL_THREADS_PER_USER = 6; // default value for max. parallel executed URLs per user
private static int maxParallelThreadsPerUser = MAX_PARALLEL_THREADS_PER_USER; // configured value for max. parallel executed URLs per user
private static final boolean CONTAINS_EXTERNAL_RESOURCES = false; // note: external resources are typically additional Java library files (*.jar files) invoked by self-developed plug-ins. Consider that Input Files and the Main Class of Plug-Ins are NOT external resources in this context because ZebraTester knows already their declarations.
// --- WebSocket Object ---
WebSocketData webSocketData = null; // WebSocket Object that contains data of recorded WebSocket frames.
private static int plannedStartupDelay = 200; // startup delay between concurrent users in milliseconds, see main argument "-sdelay"
private static int plannedTestDuration = -1; // planned load test duration in seconds, 0 = unlimited, see main argument "-d"
private static int maxPlannedLoops = 0; // maximum planned loops per user, 0 = unlimited, see main argument "-maxloops"
private static int plannedRequestTimeout = 0; // planned request timeout in seconds, see main argument "-t"
private static String defaultTimeZone = "ECT"; // use main argument -tz <timezone> to alter
private static char defaultNumberGroupingSeparator = '\''; // use main argument -dgs a|c to alter
private static String sslProtocolVersion = "all"; // applied ssl protocol version: "all" = v3/tls/tls11/tls12, use main argument -ssl to set a fixed protocol version
private static boolean sslcmode = false; // support of deficient ssl servers, use main argument -sslcmode to enable
private static boolean sslECC = false; // elliptic curve cryptography (ECC) is disabled by default, use main argument -ecc to enable
private static boolean sslSNI = true; // server name indication (SNI) is enabled by default, use main argument -nosni to disable
private static boolean sslSNICirical = false; // the SNI TLS extension is by default set as non-critical, use main argument -snicritical to set as critical
private static final long loopErrorDelay = 20; // error delay (in milliseconds) applied if a loop of a virtual user has failed
private static final String THREAD_NAME = "T000000"; // internal
private static Integer dumpLock = new Integer(0); // internal
private static Integer inputFileLock = new Integer(0); // internal
private volatile int threadStep = ThreadStepInterface.THREAD_NO_STEP; // internal
private boolean urlCallPassed = false; // internal
private String localIpAddress = null; // internal
private static long downlinkBandwidth = 0; // max. downlink bandwidth per user. 0 = unlimited. use main argument -downlink <kbps> to alter
private static long uplinkBandwidth = 0; // max. uplink bandwidth per user. 0 = unlimited. use main argument -uplink <kbps> to alter
private static boolean dnsPerLoop = false; // true if main argument "-dnsperloop" is set = perform new DNS resolves for each executed loop. normally false
private HttpTestURLDNSContext userDNSContext = null; // user specific DNS context - normally null when no special DNS servers are used
private static volatile boolean debugFailedLoops = false; // true if main argument "-dfl" is set
private static volatile boolean debugLoops = false; // true if main argument "-dl" is set
private static volatile boolean debugHttp = false; // true if main argument "-dh" is set
private static volatile boolean debugContent = false; // true if main argument "-dc" is set
private static volatile boolean debugCookies = false; // true if main argument "-dC" is set
private static volatile boolean debugKeepAlive = false; // true if main argument "-dK" is set
private static volatile boolean debugSsl = false; // true if main argument "-dssl" is set
private static String resultFile = null; // name of binary test result file or null
private final static String httpProtocolVersion = "1.1"; // applied HTTP protocol version V1.1
private static ExternalParamFile externalParamFile = null; // used only for very large parameter values (commonly unused)
private static final String EXTERNAL_PARAM_FILE = "demo7ExtParams.dat"; // input file name for very large parameter values
private static FileCache requestFileCache = new FileCache(); // file cache for large XML, SOAP and ASCII requests
private int requestTimeout = -1; // thread input data from constructor, timeout per url request in seconds
private int remainingLoops = -1; // thread input data from constructor, number of loops per thread (optional)
private boolean checkLoopCount = false; // thread input data from constructor, number of loops per thread (optional)
private int threadNumber = -1; // thread input data from constructor, internal thread number
private int threadLoopCounter = 0; // internal loop counter per thread
private volatile int userResumeStartWaitDelay = 0; // internal, user specific delay when the load test execution is resumed
private volatile boolean decrementEndOfLoopFlag = false; // internal flag to decrement the simulated user at runtime
private volatile boolean incrementUserFlag = false; // internal flag to increment the simulated user at runtime
private volatile long incrementUserStartTime = -1; // internal start time when increment the simulated user at runtime
private static AtomicInteger totalLoopCounter = new AtomicInteger(0); // internal overall loop counter
private LoadtestPluginContext userPluginContext = null; // plug-in context per user
private LoadtestInlineScriptContext inlineScriptContext = null; // re-used, scratch, the returned context of an inline script that runs at item or URL exec scope
private Object sslSessionCache = null; // internal ssl session cache per thread
private SSLSessionCacheStatistic sslStatistic = null; // internal ssl session cache statistic per thread
private static int sslSessionCacheTimeout = 300; // timeout of ssl session cache in seconds, 0 = session cache disabled
private static int sslHandshakeRandomGeneratorType = -1; // invalid initial value, use the default secure random generator for SSL handshakes
private HttpSocketPool socketPool = null; // re-used, scratch, internal socket pool per thread and loop
private CookieHandler cookieHandler = null; // re-used, scratch, internal cookie handler per thread and loop
private HttpTestURL testURL = null; // re-used, scratch, http request and response
private HttpTestURLThreadHandler pageThreadHandler = null; // re-used, scratch, support for parallel processing of http request within a page
private int httpStatus = -1; // re-used, scratch, http response status code from webserver
private HtmlContentParser htmlContentParser = null; // re-used, scratch, used to extract vars from http response
private XmlContentParser xmlContentParser = null; // re-used, scratch, used to extract vars from http response
private DynamicProtobufContentParser protobufContentParser = null; // re-used, scratch, used to extract vars from http response
private TextLineTokenExtractor textLineTokenExtractor = null; // re-used, scratch, used to extract vars from http response
private ContentTokenExtractor contentTokenExtractor = null; // re-used, scratch, used to extract vars from http response
private BoundaryBasedExtractor boundaryBasedExtractor = null; // re-used, scratch, used to extract vars from http response
private RegExpBasedExtractor regExpBasedExtractor = null; // re-used, scratch, used to extract vars from http response
private static String kkj = "kkj"; // var declaration from web admin var handler: scope = global
private volatile UserTransactionRuntimeHandler transactionHandler = new UserTransactionRuntimeHandler(); // re-used, support to manage user-defined transactions
/**
* constructor: called from load test plug-ins (scope = global).
*/
public demo7()
{
super();
}
/**
* constructor: called when a user is created (per user).
*/
public demo7(int maxLoops, int requestTimeout, int threadNumber)
{
super();
this.requestTimeout = requestTimeout;
this.remainingLoops = maxLoops;
this.checkLoopCount = (maxLoops > 0);
this.threadNumber = threadNumber;
this.sslSessionCache = SSLInit.getNewSslSessionCache(sslSessionCacheTimeout);
this.sslStatistic = new SSLSessionCacheStatistic();
if (isMultihomed() && (!ipPerLoop()))
this.localIpAddress = getNextMultihomedIpAddress();
if (dnsCache != null)
userDNSContext = new HttpTestURLDNSContext(dnsCache, threadNumber);
// initialize context for plug-ins which are executed per user
userPluginContext = new LoadtestPluginContext(prxVersion, prxCharEncoding, this, threadNumber);
}
/**
* internal method: called when a user starts a loop.
* contains the recorded session which is called by users x loops.
*
* @param totalLoopCounter total number of loops (0..n-1) counted overall threads. This value is unique per loop.
*
* @return true: loop successful completed.
* false: loop failed.
*/
private boolean execute(int totalLoopCounter) throws Exception
{
markStartOfLoop();
threadStep = 0; // internal - start loop at thread step 0
// enable DNS resolves per loop?
if (dnsPerLoop)
userDNSContext = new HttpTestURLDNSContext(dnsCache.clone(false), threadNumber);
// debug http headers?
Object httpLogVectorObject = null;
if (debugHttp)
httpLogVectorObject = this;
// create socket pool per loop
sslSessionCache = SSLInit.getNewSslSessionCache(sslSessionCacheTimeout); // reset the SSL session cache to get new SSL session IDs for this loop
socketPool = new HttpSocketPool(this, sslProtocolVersion, sslSessionCache, sslStatistic, sslcmode);
if (sslHandshakeRandomGeneratorType != -1)
socketPool.setSslHandshakeRandomGeneratorType(sslHandshakeRandomGeneratorType);
socketPool.setSupportEllipticCurves(sslECC);
socketPool.setHintUseSNI(sslSNI);
socketPool.setSniCritical(sslSNICirical);
if (debugKeepAlive)
{
socketPool.setlogVectorObject(this);
if (debugSsl)
socketPool.enableSslLog();
}
if (downlinkBandwidth > 0)
socketPool.setDownlinkBandwidth(downlinkBandwidth);
if (uplinkBandwidth > 0)
socketPool.setUplinkBandwidth(uplinkBandwidth);
if (isMultihomed())
{
if (ipPerLoop())
localIpAddress = getNextMultihomedIpAddress();
socketPool.setClientIpAddress(localIpAddress);
log();
log("multihomed client ip address = " + localIpAddress);
}
// setup cookie handler per loop
cookieHandler = new CookieHandler();
if (debugCookies)
cookieHandler.setLogVectorInterface(this);
// customised vars from web admin var handler: scope = per loop
htmlContentParser = null;
xmlContentParser = null;
protobufContentParser = null;
// initialize context for plug-ins which are executed per loop
LoadtestPluginContext loopPluginContext = new LoadtestPluginContext(prxVersion, prxCharEncoding, this, threadNumber, socketPool, cookieHandler);
// --- VIRTUAL PAGE #0 ---
if (!executePage_0(totalLoopCounter, loopPluginContext, new InnerLoopContext(), httpLogVectorObject))
return false;
// --- PAGE BREAK: Test [0] ---
log();
log();
log("# Page #1: Start");
log("# --------------");
threadStep = setPageBreak(performanceData, threadStep, "Page #1: Start", 3000, 35, -1); // hint: param #4 is the user's think time in milliseconds, param #5 is randomness of the user's think time in percent (+/- 0..100%), param #6 is the maximum acceptable response time in milliseconds (-1 = not configured)
pageThreadHandler = new HttpTestURLThreadHandler(threadStep - 1, maxParallelThreadsPerUser, performanceData, this); // support for parallel processing of http(s) requests within a page. hint: param #2 is the number of parallel threads per user
log();
if (!executePage_1(totalLoopCounter, loopPluginContext, new InnerLoopContext(), httpLogVectorObject))
{
// execution of page 1 failed
synchResponsesParallelRequestsPage_1(totalLoopCounter, loopPluginContext, new InnerLoopContext(), httpLogVectorObject);
return false;
}
if (!synchResponsesParallelRequestsPage_1(totalLoopCounter, loopPluginContext, new InnerLoopContext(), httpLogVectorObject))
return false; // execution of page 1 failed
// page 1 successfully executed
pageThreadHandler.addPageResponseTimeToResult(this);
// --- PAGE BREAK: Test [2] ---
log();
log();
log("# Page #2: going away");
log("# -------------------");
threadStep = setPageBreak(performanceData, threadStep, "Page #2: going away", 3000, 35, -1); // hint: param #4 is the user's think time in milliseconds, param #5 is randomness of the user's think time in percent (+/- 0..100%), param #6 is the maximum acceptable response time in milliseconds (-1 = not configured)
pageThreadHandler = new HttpTestURLThreadHandler(threadStep - 1, maxParallelThreadsPerUser, performanceData, this); // support for parallel processing of http(s) requests within a page. hint: param #2 is the number of parallel threads per user
log();
if (!executePage_2(totalLoopCounter, loopPluginContext, new InnerLoopContext(), httpLogVectorObject))
{
// execution of page 2 failed
synchResponsesParallelRequestsPage_2(totalLoopCounter, loopPluginContext, new InnerLoopContext(), httpLogVectorObject);
return false;
}
if (!synchResponsesParallelRequestsPage_2(totalLoopCounter, loopPluginContext, new InnerLoopContext(), httpLogVectorObject))
return false; // execution of page 2 failed
// page 2 successfully executed
pageThreadHandler.addPageResponseTimeToResult(this);
// --- PAGE BREAK: Test [4] ---
log();
log();
log("# Page #3: all");
log("# ------------");
threadStep = setPageBreak(performanceData, threadStep, "Page #3: all", 3000, 35, -1); // hint: param #4 is the user's think time in milliseconds, param #5 is randomness of the user's think time in percent (+/- 0..100%), param #6 is the maximum acceptable response time in milliseconds (-1 = not configured)
pageThreadHandler = new HttpTestURLThreadHandler(threadStep - 1, maxParallelThreadsPerUser, performanceData, this); // support for parallel processing of http(s) requests within a page. hint: param #2 is the number of parallel threads per user
log();
if (!executePage_3(totalLoopCounter, loopPluginContext, new InnerLoopContext(), httpLogVectorObject))
{
// execution of page 3 failed
synchResponsesParallelRequestsPage_3(totalLoopCounter, loopPluginContext, new InnerLoopContext(), httpLogVectorObject);
return false;
}
if (!synchResponsesParallelRequestsPage_3(totalLoopCounter, loopPluginContext, new InnerLoopContext(), httpLogVectorObject))
return false; // execution of page 3 failed
// page 3 successfully executed
pageThreadHandler.addPageResponseTimeToResult(this);
// loop successful done
// --------------------
markEndOfPage(performanceData);
endOfExecuteLoop(true, null, -1, loopPluginContext);
log();
return true;
} // end of execute()
/**
* internal method: called when a user has completed a loop.
*/
private void endOfExecuteLoop(boolean loopPassed, HttpTestURL testURL, int threadStep, LoadtestPluginContext loopPluginContext) throws Exception
{
// log URL if last call has failed
if ((!loopPassed) && (testURL != null))
log(testURL);
// update plugin context
loopPluginContext.setLoopPassed(loopPassed);
if ((testURL != null) && (loopPluginContext.getHttpTestURL() == null))
loopPluginContext.setHttpTestURL(testURL);
if ((threadStep != -1) && (loopPluginContext.getThreadStep() == -1))
loopPluginContext.setThreadStep(threadStep);
}
/**
* Recorded http requests of page #0.
*
* @return true: method successful completed.
* false: method/loop failed.
*/
boolean executePage_0(int totalLoopCounter, LoadtestPluginContext loopPluginContext, InnerLoopContext innerLoopContext, Object httpLogVectorObject) throws Exception
{
// all http requests of page #0 successful done
return true;
}
/**
* Recorded http requests of page #1.
*
* @return true: method successful completed.
* false: method/loop failed.
*/
boolean executePage_1(int totalLoopCounter, LoadtestPluginContext loopPluginContext, InnerLoopContext innerLoopContext, Object httpLogVectorObject) throws Exception
{
// # Page #1: Start
// # --------------
// --- HTTP REQUEST: Test [1] <- WEB ADMIN Index 42 ---
String requestProt0001 = "http";
String requestHost0001 = "echo.websocket.org";
int requestPort0001 = 80;
String requestFile0001 = "/" +
"?encoding=text";
String requestHeader0001 = "GET " + requestFile0001 + " HTTP/" + httpProtocolVersion + "\r\n" +
"Host: echo.websocket.org\r\n" +
"User-Agent: " + USER_AGENT_1 + "\r\n" +
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" +
"Accept-Language: en-GB,en;q=0.5\r\n" +
"Accept-Encoding: gzip, deflate\r\n" +
"Sec-WebSocket-Version: 13\r\n" +
"Origin: http://www.websocket.org\r\n" +
"Sec-WebSocket-Extensions: permessage-deflate\r\n" +
"Sec-WebSocket-Key: PgAcnbvpMxfRyOWGdnjFTA==\r\n" +
"Connection: Keep-Alive, Upgrade\r\n" +
"Pragma: no-cache\r\n" +
"Cache-Control: no-cache\r\n" +
"Upgrade: websocket\r\n" +
"\r\n";
// execute request
testURL = new HttpTestURL(requestProt0001, requestHost0001, requestPort0001, requestHeader0001, null, requestTimeout, socketPool, cookieHandler, httpLogVectorObject);
testURL.setDNSContext(userDNSContext);
webSocketData = getWebSocketData_1470689578084();
testURL.setWebSocketContext(new HttpTestWebsocketContext(webSocketData));
performanceData.setInfoText(threadStep, testURL, -1); // hint: param #3 is the maximum acceptable response time in milliseconds (-1 = not configured)
log("[" + threadStep + "] " + testURL.getRequestInfoText() + " ...");
testURL.execute(performanceData);
requestHeader0001 = null; // support garbage collector to reduce memory
log(" " + testURL.getShortResultText());
// verify response: status code = 101, content type = [verification disabled], header text fragment = [verification disabled], recorded content size = 0
urlCallPassed = httpResponseOk(testURL, threadStep, new int[] {101}, null, null, "kkj","2"); // Test [1] <- Index 1
if (!urlCallPassed)
{
// failure - dump wrong content to thread log and abort current loop
terminateFailedUser(testURL); // set the user to be terminated at end of loop ? - only performed if the URL call has marked before to support that !
endOfExecuteLoop(false, testURL, threadStep, loopPluginContext);
return false;
}
if (debugContent && urlCallPassed)
log(testURL);
// update performance data if url call passed
if (urlCallPassed)
threadStep = setPassed(performanceData, threadStep, testURL);
else
threadStep = threadStep + 1; // url call failed - performance data already updated
// all http requests of page #1 successful done
return true;
}
/**
* Recorded http requests of page #2.
*
* @return true: method successful completed.
* false: method/loop failed.
*/
boolean executePage_2(int totalLoopCounter, LoadtestPluginContext loopPluginContext, InnerLoopContext innerLoopContext, Object httpLogVectorObject) throws Exception
{
// # Page #2: going away
// # -------------------
// --- HTTP REQUEST: Test [3] <- WEB ADMIN Index 55 ---
log();
log("# title: Home | Zauq Group");
String requestProt0003 = "http";
String requestHost0003 = "zauq.com";
int requestPort0003 = 80;
String requestFile0003 = "/";
String requestHeader0003 = "GET " + requestFile0003 + " HTTP/" + httpProtocolVersion + "\r\n" +
"Host: zauq.com\r\n" +
"User-Agent: " + USER_AGENT_1 + "\r\n" +
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" +
"Accept-Language: en-GB,en;q=0.5\r\n" +
"Accept-Encoding: gzip, deflate\r\n" +
"Connection: Keep-Alive\r\n" +
"\r\n";
// execute request
testURL = new HttpTestURL(requestProt0003, requestHost0003, requestPort0003, requestHeader0003, null, requestTimeout, socketPool, cookieHandler, httpLogVectorObject);
testURL.setDNSContext(userDNSContext);
performanceData.setInfoText(threadStep, testURL, -1); // hint: param #3 is the maximum acceptable response time in milliseconds (-1 = not configured)
log("[" + threadStep + "] " + testURL.getRequestInfoText() + " ...");
testURL.execute(performanceData);
requestHeader0003 = null; // support garbage collector to reduce memory
log(" " + testURL.getShortResultText());
// verify response: status code = 200, content type = "TEXT/HTML", header text fragment = [verification disabled], recorded content size = 5112
// content test algorithm: search text
urlCallPassed = httpResponseOk(testURL, threadStep, new int[] {200}, "TEXT/HTML", null, "div class=\"collapse navbar-collapse navbar-right\""); // Test [3] <- Index 3
if (!urlCallPassed)
{
// failure - dump wrong content to thread log and abort current loop
terminateFailedUser(testURL); // set the user to be terminated at end of loop ? - only performed if the URL call has marked before to support that !
endOfExecuteLoop(false, testURL, threadStep, loopPluginContext);
return false;
}
if (debugContent && urlCallPassed)
log(testURL);
// update performance data if url call passed
if (urlCallPassed)
threadStep = setPassed(performanceData, threadStep, testURL);
else
threadStep = threadStep + 1; // url call failed - performance data already updated
// all http requests of page #2 successful done
return true;
}
/**
* Recorded http requests of page #3.
*
* @return true: method successful completed.
* false: method/loop failed.
*/
boolean executePage_3(int totalLoopCounter, LoadtestPluginContext loopPluginContext, InnerLoopContext innerLoopContext, Object httpLogVectorObject) throws Exception
{
// all http requests of page #3 successful done
return true;
}
boolean synchResponsesParallelRequestsPage_1(int totalLoopCounter, LoadtestPluginContext loopPluginContext, InnerLoopContext innerLoopContext, Object httpLogVectorObject) throws Exception
{
int lastThreadStepInMainThread = threadStep; // save last executed thread step
// wait for the response of all parallel requests
threadStep = pageThreadHandler.getLastThreadStep();
pageThreadHandler.waitForSynch();
log("Page 1 Time = " + pageThreadHandler.getPageTime() + " ms");
// all done
threadStep = lastThreadStepInMainThread; // restore last executed thread step
return true; // end of asynch response checks for this page
}
boolean synchResponsesParallelRequestsPage_2(int totalLoopCounter, LoadtestPluginContext loopPluginContext, InnerLoopContext innerLoopContext, Object httpLogVectorObject) throws Exception
{
int lastThreadStepInMainThread = threadStep; // save last executed thread step
// wait for the response of all parallel requests
threadStep = pageThreadHandler.getLastThreadStep();
pageThreadHandler.waitForSynch();
log("Page 2 Time = " + pageThreadHandler.getPageTime() + " ms");
// all done
threadStep = lastThreadStepInMainThread; // restore last executed thread step
return true; // end of asynch response checks for this page
}
boolean synchResponsesParallelRequestsPage_3(int totalLoopCounter, LoadtestPluginContext loopPluginContext, InnerLoopContext innerLoopContext, Object httpLogVectorObject) throws Exception
{
int lastThreadStepInMainThread = threadStep; // save last executed thread step
// wait for the response of all parallel requests
threadStep = pageThreadHandler.getLastThreadStep();
pageThreadHandler.waitForSynch();
log("Page 3 Time = " + pageThreadHandler.getPageTime() + " ms");
// all done
threadStep = lastThreadStepInMainThread; // restore last executed thread step
return true; // end of asynch response checks for this page
}
/**
* implement GetRealTimeUserInputFieldsInterface: get the definition and the value of all real-time user input fields.
*/
public ArrayList<RealTimeUserInputField> getRealTimeUserInputFields()
{
try
{
ArrayList<RealTimeUserInputField> realTimeUserInputFieldList = new ArrayList<RealTimeUserInputField>();
return realTimeUserInputFieldList;
}
catch (Exception e)
{
log(e);
return null;
}
}
/**
* implement ThreadStepInterface: get the current execution step (current URL call or page break) of a simulated user.
*/
public int getExecutionStep()
{
return threadStep;
}
/**
* implement SetThreadStepInterface: set the current execution step (current URL call or page break) of a simulated user.
*/
public void setExecutionStep(int threadStep)
{
this.threadStep = threadStep;
}
/**
* implement SSLSessionCacheStatisticInterface: get statistic data about the SSL session cache behavior of a simulated user.
*/
public SSLSessionCacheStatistic getSSLSessionCacheStatistic()
{
return sslStatistic;
}
/**
* implement VaryingTestDurationInterface: support to extend or to reduce the planned test duration.
*/
public int getPlannedTestDuration()
{
return plannedTestDuration;
}
public void setExtendTestDuration(int deltaSeconds)
{
if (plannedTestDuration == 0)
{
plannedTestDuration = deltaSeconds; // the old planned test duration was unlimited but is now limited
return;
}
if (deltaSeconds == 0)
{
plannedTestDuration = 0; // the new planned test duration is now unlimited
return;
}
plannedTestDuration = plannedTestDuration + deltaSeconds;
}
/**
* implement SuspendResumeInterface: support to suspend and to resume the test execution.
*/
public int getPlannedStartupDelay()
{
return plannedStartupDelay;
}
public void setUserResumeStartWaitDelay(int millis)
{
userResumeStartWaitDelay = millis;
}
/**
* implement VaryingLoadInterface: support to decrement the number of simulated users at runtime.
*/
public void setDecrementEndOfLoopFlag(boolean decrementEndOfLoopFlag)
{
this.decrementEndOfLoopFlag = decrementEndOfLoopFlag;
}
public boolean isDecrementEndOfLoopFlag()
{
return decrementEndOfLoopFlag;
}
/**
* internal method: execute the loops for one simulated user as a thread.
* controls the thread and displays the (thread-)log if one loop has been completed.
*/
public void run()
{
// user terminated by inline script, at start of user ?
if (isTerminateUser())
{
System.out.println("# --- thread " + Thread.currentThread().getName() + " aborted --- " + ZoneTime.dateToShortString() + " ---");
return;
}
try
{
while (true)
{
threadStep = ThreadStepInterface.THREAD_NO_STEP;
clearLog();
// execute loop
log("--- loop started --- " + ZoneTime.dateToShortString() + " ---");
boolean loopPassed = this.execute(totalLoopCounter.getAndIncrement());
performanceData.addUserTransactionMeasuredSamples(transactionHandler.getPendingTransactions());
performanceData.addUserTransactionNotExecutedSamples(transactionHandler.getNotExecutedTransactions());
transactionHandler.resetTransactions();
performanceData.addSocktPoolStatistic(socketPool);
socketPool.closePool();
performanceData.addSSLCacheStatistic(sslStatistic.getSSLSessionCacheStatisticResult());
sslStatistic.reset();
// eof of input file ?
if (abortedByEofInputFile())
return; // endOfRun() not called in such a case
// check loop result
String remainingLoopInfo = "";
if (checkLoopCount)
remainingLoopInfo = " [remaining loops = " + (remainingLoops - 1) + "]";
if (loopPassed)
{
performanceData.addPassedLoop();
log("--- loop passed --- " + ZoneTime.dateToShortString() + " ---" + remainingLoopInfo);
}
else
{
performanceData.addFailedLoop();
log("--- loop failed --- " + ZoneTime.dateToShortString() + " ---" + remainingLoopInfo);
}
threadStep = ThreadStepInterface.THREAD_NO_STEP;
// display thread log to standard output
if (debugLoops || (debugFailedLoops && (!loopPassed)))
{
synchronized (dumpLock)
{
dumpLog(System.out); // full log
}
}
// check if max loops reached
if (checkLoopCount)
{
// all done ?
remainingLoops--;
if (remainingLoops <= 0)
{
endOfRun();
return;
}
}
// check if simulated user must be decremented
if (decrementEndOfLoopFlag)
{
endOfRun();
decrementEndOfLoopFlag = false; // reset flag for further use
return;
}
// check if max test duration reached
if ((plannedTestDuration > 0) && (((System.currentTimeMillis() - testDurationStart) / 1000) >= plannedTestDuration))
{
endOfRun();
return;
}
// check if this specific user is terminated earlier than planned by a HTTP content verification or by a plug-in
if (isTerminateUser())
{
endOfRun();
System.out.println("# --- thread " + Thread.currentThread().getName() + " terminate failed user --- " + ZoneTime.dateToShortString() + " ---");
return;
}
// check if load test execution is temporary suspended
boolean wasSuspended = false;
while (isSuspend())
{
wasSuspended = true;
try { Thread.currentThread().sleep(20); } catch (InterruptedException ie) {}
if (abortedByRemote() || abortedByEofInputFile())
{
endOfRun();
return;
}
// check if max test duration reached during suspend
if ((plannedTestDuration > 0) && (((System.currentTimeMillis() - testDurationStart) / 1000) >= plannedTestDuration))
{
endOfRun();
return;
}
}
// check if load test execution is resumed
if (wasSuspended)
{
try { sleepRemoteInterruptable(userResumeStartWaitDelay); } catch (InterruptedException ie) {}
}
// wait 20 milliseconds if loop has failed
if (!loopPassed)
try { Thread.currentThread().sleep(loopErrorDelay); } catch (InterruptedException ie) {}
// execute next loop
threadLoopCounter++;
} // end: while (true)
}
catch (Throwable tex)
{
log("*** INTERNAL ERROR / LOAD TEST ABORTED ***");
log(tex);
log();
synchronized (dumpLock)
{
dumpLog(System.out); // full log
System.err.println("*** INTERNAL ERROR / LOAD TEST ABORTED ***");
tex.printStackTrace(System.err);
System.exit(-2);
}
}
finally
{
// remove the reference to this load test instance and the reference to the thread that runs this instance
try
{
getUserContextTable().getWriteLock().lock();
getOwnLoadTestUserContext().setLoadTestUserFinallyEnded();
getUserContextTable().getWriteLock().unlock();
}
catch (Throwable texFinal)
{
System.err.println("*** INTERNAL FINALLY ERROR / LOAD TEST ABORTED ***");
texFinal.printStackTrace(System.err);
System.exit(-2);
}
}
}
/**
* internal method: called when a user has completed the test-run.
*/
public void endOfRun()
{
clearLog();
if (debugLoops && (getLog().size() > 0))
{
synchronized (dumpLock)
{
dumpLog(System.out); // dump log of inline scripts and load test plug-ins which are executed at end of user
}
}
}
/**
* Main program. Starts the test and waits until all have been done.
*/
public static void main(String[] args)
{
// check command line argument -h or -help
if ((ParseArgs.hasOption(args, "-h")) || (ParseArgs.hasOption(args, "-help")))
{
System.out.println();
System.out.println("Help - Proxy Sniffer Load Test Program:");
System.out.println();
System.out.println("-u <number> ->> required argument: number of concurrent users");
System.out.println("-d <seconds> ->> required argument: planned test duration in seconds (default: 30, 0 = unlimited)");
System.out.println("-t <seconds> ->> required argument: request timeout per url in seconds");
System.out.println();
System.out.println("-sdelay <milliseconds> ->> startup delay time between concurrent users in milliseconds (default: 200)");
System.out.println("-mtpu <number> ->> maximum number of parallel threads per user (default: " + MAX_PARALLEL_THREADS_PER_USER + ")");
System.out.println("-maxloops <number> ->> maximum number of loops per user (default: 0 = unlimited)");
System.out.println("-downlink <kbps> ->> maximum downlink network bandwidth per user in kilobits per second (default: 0 = unlimited)");
System.out.println("-uplink <kbps> ->> maximum uplink network bandwidth per user in kilobits per second (default: 0 = unlimited)");
System.out.println("-multihomed <filename> ->> use serveral client ip addresses - file format: <addr1>, <addr2>, ... (all on the same line)");
System.out.println("-sampling <seconds> ->> statistic sampling interval in seconds (default: 15)");
System.out.println("-percpage <percent> ->> additional sampling rate per web page call in percent (default: 100)");
System.out.println("-percurl <percent> ->> additional sampling rate per url call in percent (default: 0)");
System.out.println("-percurlopt <level> ->> extended sampling level per url call, see application reference manual (default: 0 = disabled)");
System.out.println("-maxerrsnap <number> ->> maximum number of error snapshots per url (default: 0 = unlimited)");
System.out.println("-maxerrmem <megabytes> ->> maximum size of memory in megabytes which can be used for error snapshots (default: 20, -1 = unlimited)");
System.out.println("-nosdelayCluster ->> apply startup delay time between concurrent users per exec agent, but not per cluster job (default: apply per cluster job)");
System.out.println("-setuseragent \"<text>\" ->> replace the recorded value of the HTTP request header field User-Agent with a new value");
System.out.println("-collect <host>[:<port>] ->> collect additional data from external measuring agents (data collectors)");
System.out.println("-res <filename> ->> overrides the default name of the binary output file");
System.out.println("-nores ->> disables to create the binary output file");
System.out.println();
System.out.println("-ssl <version> ->> set SSL version: possible options are \"all\" (default), \"v3\", \"tls\", \"tls11\" or \"tls12\"");
System.out.println("-sslcache <seconds> ->> timeout of user-related SSL session cache (default: 300, 0 = cache disabled)");
System.out.println("-sslrandom <type> ->> set the type of the random generator used for SSL handshakes: possible options are \"fast\", \"iaik\" (default) or \"java\"");
System.out.println("-sslcmode ->> apply SSL/HTTPS compatibility workarounds for deficient SSL servers");
System.out.println("-ecc ->> enable support of elliptic curve cryptography (ECC)");
System.out.println("-nosni ->> disable support of server name indication (SNI)");
System.out.println("-snicritical ->> set the TLS SNI extension as critical (default: non-critical)");
System.out.println("-iaikLast ->> adds the IAIK security provider at the last position (instead of default: IAIK at first position)");
System.out.println();
System.out.println("-dnssrv <IP-1>[,IP-N]) ->> use specific DNS server(s) to resolve DNS host names (default: use OS to resolve host names)");
System.out.println("-dnshosts <filename> ->> use specific DNS hosts file (default: use OS to resolve host names)");
System.out.println("-dnstranslation <filename> ->> use a DNS translation file that converts DNS names. It might be needed to disable TLS SNI if this option is used");
System.out.println("-dnsenattl ->> enable consideration of DNS TTL by using the received TTL-values from the DNS Server(s) (default: TTL disabled)");
System.out.println("-dnsfixttl <seconds> ->> enable DNS TTL by using a fixed TTL-value of seconds for all DNS resolves");
System.out.println("-dnsperloop ->> perform new DNS resolves for each executed loop. All resolves are stable within the same loop (no consideration of DNS TTL within a loop)");
System.out.println("-dnsstatistic ->> collect statistical data about DNS resolutions. Note: use this option only if not any other, more specific DNS option is enabled");
System.out.println("-dnsdebug ->> debug DNS resolves and the DNS cache");
System.out.println();
System.out.println("-dfl ->> debug execution steps of all failed loops to standard output");
System.out.println("-dl ->> debug execution steps of all loops to standard output");
System.out.println("-dh ->> debug HTTP protocol headers to standard output, includes the -dl option");
System.out.println("-dc ->> debug HTTP content data to standard output, includes the -dl option");
System.out.println("-dhc ->> debug HTTP protocol headers and HTTP content data to standard output, includes the -dl option");
System.out.println("-dC ->> debug cookies to standard output, includes the -dl option");
System.out.println("-dK ->> debug keep-alive (socket pool) to standard output, includes the -dl option");
System.out.println("-dssl ->> debug SSL handshake (https) to standard output, includes the -dl and the -dK option");
System.out.println();
System.out.println("-tz <timezone> ->> set time zone (see Application Reference Manual: supported time zones)");
System.out.println("-dgs a|c ->> set number format (decimal group separator) a = ' c = ,");
System.out.println("-annotation <text> ->> adds an annotation for this test run");
System.out.println();
System.out.println("-execAgentHost <ip address or dns name> ->> set the ip address or the dns name of the exec agent from which the license is used (default: 127.0.0.1)");
System.out.println("-execAgentPort <port> ->> set the tcp/ip port of the exec agent (default: 7993)");
System.out.println("-execAgentProtocol <plain | http | https> ->> set the protocol of the exec agent (default: plain)");
System.out.println("-execAgentUsername <string> ->> set the auth. username for the exec agent (default: [no username])");
System.out.println("-execAgentPassword <string> ->> set the auth. password for the exec agent (default: [no password])");
System.out.println();
System.out.println("-h ->> display this help text");
System.out.println("-help ->> display this help text");
System.out.println();
System.exit(-1);
}
System.out.println("+----------------------------------------------------------------+");
System.out.println("| Welcome to the ZebraTester Load Test Program. |");
System.out.println("| Additional help available with program argument \"-help\" |");
System.out.println("| Procedure Copyright by Ingenieurbuero David Fischer AG, |");
System.out.println("| a company of the Apica group. All rights reserved. |");
System.out.println("+----------------------------------------------------------------+");
// check command line argument -ecc
sslECC = (ParseArgs.hasOption(args, "-ecc")); // enable ssl ecc ?
// initialize ssl/https support
SSLInit.execute(!ParseArgs.hasOption(args, "-iaikLast"), true);
if (sslECC)
SSLInit.enableECC();
// check command line argument -nosni
if (ParseArgs.hasOption(args, "-nosni")) // disable ssl sni ?
sslSNI = false;
// check command line argument -snicritical
if (ParseArgs.hasOption(args, "-snicritical")) // set ssl sni as critical tls extension ?
sslSNICirical = true;
// set default character set for response content tests
setCharEncoding(prxCharEncoding);
// check command line argument -tz <timezone>
String timeZoneString = ParseArgs.getString(args, "-tz");
if (timeZoneString != null)
defaultTimeZone = timeZoneString.toUpperCase(); // set time zone?
ZoneTime.setDefaultTimeZone(defaultTimeZone);
// check command line argument -dgs a|c