@loadstrike/loadstrike-sdk 1.0.20801 → 1.0.21301
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -2
- package/dist/cjs/autopilot-contracts.js +11 -0
- package/dist/cjs/autopilot.js +717 -0
- package/dist/cjs/cluster.js +27 -2
- package/dist/cjs/correlation.js +132 -0
- package/dist/cjs/index.js +7 -2
- package/dist/cjs/local.js +116 -6
- package/dist/cjs/reporting.js +12 -0
- package/dist/cjs/runtime.js +966 -36
- package/dist/esm/autopilot-contracts.js +8 -0
- package/dist/esm/autopilot.js +709 -0
- package/dist/esm/cluster.js +27 -2
- package/dist/esm/correlation.js +132 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/local.js +116 -6
- package/dist/esm/reporting.js +12 -0
- package/dist/esm/runtime.js +966 -36
- package/dist/types/autopilot-contracts.d.ts +113 -0
- package/dist/types/autopilot.d.ts +43 -0
- package/dist/types/cluster.d.ts +21 -1
- package/dist/types/correlation.d.ts +132 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/local.d.ts +6 -0
- package/dist/types/reporting.d.ts +12 -0
- package/dist/types/runtime.d.ts +871 -0
- package/package.json +1 -1
package/dist/cjs/runtime.js
CHANGED
|
@@ -48,14 +48,26 @@ exports.LoadStrikeOperationType = {
|
|
|
48
48
|
Error: "Error"
|
|
49
49
|
};
|
|
50
50
|
class LoadStrikePluginDataTable {
|
|
51
|
+
/**
|
|
52
|
+
* Exposes the public constructor operation.
|
|
53
|
+
* Use this when the surrounding wrapper type makes this operation the clearest way to express your intent.
|
|
54
|
+
*/
|
|
51
55
|
constructor(tableName, headers = [], rows = []) {
|
|
52
56
|
this.tableName = requireNonEmpty(tableName, "Table name must be provided.");
|
|
53
57
|
this.headers = [...headers];
|
|
54
58
|
this.rows = rows.map((row) => ({ ...row }));
|
|
55
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Creates a new instance of this public SDK type.
|
|
62
|
+
* Use this when you are starting a run definition from scratch.
|
|
63
|
+
*/
|
|
56
64
|
static create(tableName) {
|
|
57
65
|
return new LoadStrikePluginDataTable(tableName);
|
|
58
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Creates a new instance of this public SDK type.
|
|
69
|
+
* Use this when you are starting a run definition from scratch.
|
|
70
|
+
*/
|
|
59
71
|
static Create(tableName) {
|
|
60
72
|
return LoadStrikePluginDataTable.create(tableName);
|
|
61
73
|
}
|
|
@@ -71,14 +83,26 @@ class LoadStrikePluginDataTable {
|
|
|
71
83
|
}
|
|
72
84
|
exports.LoadStrikePluginDataTable = LoadStrikePluginDataTable;
|
|
73
85
|
class LoadStrikePluginData {
|
|
86
|
+
/**
|
|
87
|
+
* Exposes the public constructor operation.
|
|
88
|
+
* Use this when the surrounding wrapper type makes this operation the clearest way to express your intent.
|
|
89
|
+
*/
|
|
74
90
|
constructor(pluginName, tables = [], hints = []) {
|
|
75
91
|
this.pluginName = requireNonEmpty(pluginName, "Plugin name must be provided.");
|
|
76
92
|
this.tables = tables.map((table) => new LoadStrikePluginDataTable(table.tableName, table.headers, table.rows));
|
|
77
93
|
this.hints = [...hints];
|
|
78
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* Creates a new instance of this public SDK type.
|
|
97
|
+
* Use this when you are starting a run definition from scratch.
|
|
98
|
+
*/
|
|
79
99
|
static create(pluginName) {
|
|
80
100
|
return new LoadStrikePluginData(pluginName);
|
|
81
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Creates a new instance of this public SDK type.
|
|
104
|
+
* Use this when you are starting a run definition from scratch.
|
|
105
|
+
*/
|
|
82
106
|
static Create(pluginName) {
|
|
83
107
|
return LoadStrikePluginData.create(pluginName);
|
|
84
108
|
}
|
|
@@ -104,6 +128,10 @@ class MeasurementAccumulator {
|
|
|
104
128
|
get Count() {
|
|
105
129
|
return this.count;
|
|
106
130
|
}
|
|
131
|
+
/**
|
|
132
|
+
* Exposes the public record operation.
|
|
133
|
+
* Use this when the surrounding wrapper type makes this operation the clearest way to express your intent.
|
|
134
|
+
*/
|
|
107
135
|
record(reply, observedLatencyMs) {
|
|
108
136
|
const latencyMs = resolveRecordedLatency(reply.customLatencyMs, observedLatencyMs);
|
|
109
137
|
const sizeBytes = Math.max(toNumber(reply.sizeBytes), 0);
|
|
@@ -126,6 +154,10 @@ class MeasurementAccumulator {
|
|
|
126
154
|
count: 1
|
|
127
155
|
});
|
|
128
156
|
}
|
|
157
|
+
/**
|
|
158
|
+
* Builds the configured payload or helper object.
|
|
159
|
+
* Use this when all builder inputs are ready to be materialized.
|
|
160
|
+
*/
|
|
129
161
|
build(allRequestCount, durationMs) {
|
|
130
162
|
const count = this.count;
|
|
131
163
|
const totalDurationMs = Math.max(durationMs, 0);
|
|
@@ -184,6 +216,10 @@ class StepStatsAccumulator {
|
|
|
184
216
|
this.ok = new MeasurementAccumulator();
|
|
185
217
|
this.fail = new MeasurementAccumulator();
|
|
186
218
|
}
|
|
219
|
+
/**
|
|
220
|
+
* Exposes the public record operation.
|
|
221
|
+
* Use this when the surrounding wrapper type makes this operation the clearest way to express your intent.
|
|
222
|
+
*/
|
|
187
223
|
record(reply, observedLatencyMs) {
|
|
188
224
|
if (reply.isSuccess) {
|
|
189
225
|
this.ok.record(reply, observedLatencyMs);
|
|
@@ -191,6 +227,10 @@ class StepStatsAccumulator {
|
|
|
191
227
|
}
|
|
192
228
|
this.fail.record(reply, observedLatencyMs);
|
|
193
229
|
}
|
|
230
|
+
/**
|
|
231
|
+
* Builds the configured payload or helper object.
|
|
232
|
+
* Use this when all builder inputs are ready to be materialized.
|
|
233
|
+
*/
|
|
194
234
|
build(allScenarioRequestCount, durationMs) {
|
|
195
235
|
const ok = this.ok.build(allScenarioRequestCount, durationMs);
|
|
196
236
|
const fail = this.fail.build(allScenarioRequestCount, durationMs);
|
|
@@ -230,18 +270,34 @@ class ScenarioStatsAccumulator {
|
|
|
230
270
|
this.loadSimulationStats = { simulationName: "", value: 0 };
|
|
231
271
|
this.currentOperation = "None";
|
|
232
272
|
}
|
|
273
|
+
/**
|
|
274
|
+
* Exposes the public setLoadSimulation operation.
|
|
275
|
+
* Use this when the surrounding wrapper type makes this operation the clearest way to express your intent.
|
|
276
|
+
*/
|
|
233
277
|
setLoadSimulation(simulationName, value) {
|
|
234
278
|
this.loadSimulationStats = {
|
|
235
279
|
simulationName,
|
|
236
280
|
value
|
|
237
281
|
};
|
|
238
282
|
}
|
|
283
|
+
/**
|
|
284
|
+
* Exposes the public setCurrentOperation operation.
|
|
285
|
+
* Use this when the surrounding wrapper type makes this operation the clearest way to express your intent.
|
|
286
|
+
*/
|
|
239
287
|
setCurrentOperation(operation) {
|
|
240
288
|
this.currentOperation = operation;
|
|
241
289
|
}
|
|
290
|
+
/**
|
|
291
|
+
* Returns current operation.
|
|
292
|
+
* Use this when current operation is required for branching, logging, or assertions.
|
|
293
|
+
*/
|
|
242
294
|
getCurrentOperation() {
|
|
243
295
|
return this.currentOperation;
|
|
244
296
|
}
|
|
297
|
+
/**
|
|
298
|
+
* Exposes the public recordScenario operation.
|
|
299
|
+
* Use this when the surrounding wrapper type makes this operation the clearest way to express your intent.
|
|
300
|
+
*/
|
|
245
301
|
recordScenario(reply, observedLatencyMs) {
|
|
246
302
|
if (reply.isSuccess) {
|
|
247
303
|
this.ok.record(reply, observedLatencyMs);
|
|
@@ -249,6 +305,10 @@ class ScenarioStatsAccumulator {
|
|
|
249
305
|
}
|
|
250
306
|
this.fail.record(reply, observedLatencyMs);
|
|
251
307
|
}
|
|
308
|
+
/**
|
|
309
|
+
* Exposes the public recordStep operation.
|
|
310
|
+
* Use this when the surrounding wrapper type makes this operation the clearest way to express your intent.
|
|
311
|
+
*/
|
|
252
312
|
recordStep(stepName, reply, observedLatencyMs) {
|
|
253
313
|
const existing = this.steps.get(stepName);
|
|
254
314
|
const step = existing ?? new StepStatsAccumulator(this.scenarioName, stepName, this.nextStepSortIndex += 1);
|
|
@@ -257,6 +317,10 @@ class ScenarioStatsAccumulator {
|
|
|
257
317
|
}
|
|
258
318
|
step.record(reply, observedLatencyMs);
|
|
259
319
|
}
|
|
320
|
+
/**
|
|
321
|
+
* Builds the configured payload or helper object.
|
|
322
|
+
* Use this when all builder inputs are ready to be materialized.
|
|
323
|
+
*/
|
|
260
324
|
build(durationMs) {
|
|
261
325
|
const totalRequests = this.ok.Count + this.fail.Count;
|
|
262
326
|
const ok = this.ok.build(totalRequests, durationMs);
|
|
@@ -301,6 +365,10 @@ class ScenarioStatsAccumulator {
|
|
|
301
365
|
}
|
|
302
366
|
}
|
|
303
367
|
class LoadStrikeResponse {
|
|
368
|
+
/**
|
|
369
|
+
* Creates a successful reply.
|
|
370
|
+
* Use this when a step or scenario completed successfully and should report a success response.
|
|
371
|
+
*/
|
|
304
372
|
static ok(...args) {
|
|
305
373
|
const normalized = normalizeSuccessResponseCall(args);
|
|
306
374
|
const reply = {
|
|
@@ -313,6 +381,10 @@ class LoadStrikeResponse {
|
|
|
313
381
|
};
|
|
314
382
|
return attachReplyProjection(reply);
|
|
315
383
|
}
|
|
384
|
+
/**
|
|
385
|
+
* Creates a successful reply.
|
|
386
|
+
* Use this when a step or scenario completed successfully and should report a success response.
|
|
387
|
+
*/
|
|
316
388
|
static Ok(...args) {
|
|
317
389
|
return LoadStrikeResponse.ok(...args);
|
|
318
390
|
}
|
|
@@ -322,6 +394,10 @@ class LoadStrikeResponse {
|
|
|
322
394
|
static OkWithPayload(payload, statusCode = "200", sizeBytesOrMessage = 0, messageOrSizeBytes = "", customLatencyMs) {
|
|
323
395
|
return LoadStrikeResponse.okWithPayload(payload, statusCode, sizeBytesOrMessage, messageOrSizeBytes, customLatencyMs);
|
|
324
396
|
}
|
|
397
|
+
/**
|
|
398
|
+
* Creates a failed reply.
|
|
399
|
+
* Use this when a step or scenario should record an explicit failure response.
|
|
400
|
+
*/
|
|
325
401
|
static fail(...args) {
|
|
326
402
|
const normalized = normalizeFailureResponseCall(args);
|
|
327
403
|
const reply = {
|
|
@@ -334,6 +410,10 @@ class LoadStrikeResponse {
|
|
|
334
410
|
};
|
|
335
411
|
return attachReplyProjection(reply);
|
|
336
412
|
}
|
|
413
|
+
/**
|
|
414
|
+
* Creates a failed reply.
|
|
415
|
+
* Use this when a step or scenario should record an explicit failure response.
|
|
416
|
+
*/
|
|
337
417
|
static Fail(...args) {
|
|
338
418
|
return LoadStrikeResponse.fail(...args);
|
|
339
419
|
}
|
|
@@ -384,6 +464,10 @@ class LoadStrikeStep {
|
|
|
384
464
|
}
|
|
385
465
|
exports.LoadStrikeStep = LoadStrikeStep;
|
|
386
466
|
class LoadStrikeSimulation {
|
|
467
|
+
/**
|
|
468
|
+
* Builds a constant injection load shape.
|
|
469
|
+
* Use this when requests should be injected at a fixed rate over a duration.
|
|
470
|
+
*/
|
|
387
471
|
static inject(rate, intervalSeconds, duringSeconds) {
|
|
388
472
|
return attachLoadSimulationProjection({
|
|
389
473
|
Kind: "Inject",
|
|
@@ -392,9 +476,17 @@ class LoadStrikeSimulation {
|
|
|
392
476
|
DuringSeconds: duringSeconds
|
|
393
477
|
});
|
|
394
478
|
}
|
|
479
|
+
/**
|
|
480
|
+
* Builds a constant injection load shape.
|
|
481
|
+
* Use this when requests should be injected at a fixed rate over a duration.
|
|
482
|
+
*/
|
|
395
483
|
static Inject(rate, intervalSeconds, duringSeconds) {
|
|
396
484
|
return LoadStrikeSimulation.inject(rate, intervalSeconds, duringSeconds);
|
|
397
485
|
}
|
|
486
|
+
/**
|
|
487
|
+
* Builds an iteration-limited constant-concurrency load shape.
|
|
488
|
+
* Use this when a fixed number of iterations should be shared across constant workers.
|
|
489
|
+
*/
|
|
398
490
|
static iterationsForConstant(copies, iterations) {
|
|
399
491
|
return attachLoadSimulationProjection({
|
|
400
492
|
Kind: "IterationsForConstant",
|
|
@@ -402,9 +494,17 @@ class LoadStrikeSimulation {
|
|
|
402
494
|
Iterations: iterations
|
|
403
495
|
});
|
|
404
496
|
}
|
|
497
|
+
/**
|
|
498
|
+
* Builds an iteration-limited constant-concurrency load shape.
|
|
499
|
+
* Use this when a fixed number of iterations should be shared across constant workers.
|
|
500
|
+
*/
|
|
405
501
|
static IterationsForConstant(copies, iterations) {
|
|
406
502
|
return LoadStrikeSimulation.iterationsForConstant(copies, iterations);
|
|
407
503
|
}
|
|
504
|
+
/**
|
|
505
|
+
* Builds an iteration-limited injection load shape.
|
|
506
|
+
* Use this when a fixed number of injected iterations should be executed.
|
|
507
|
+
*/
|
|
408
508
|
static iterationsForInject(rate, intervalSeconds, iterations) {
|
|
409
509
|
return attachLoadSimulationProjection({
|
|
410
510
|
Kind: "IterationsForInject",
|
|
@@ -413,9 +513,17 @@ class LoadStrikeSimulation {
|
|
|
413
513
|
Iterations: iterations
|
|
414
514
|
});
|
|
415
515
|
}
|
|
516
|
+
/**
|
|
517
|
+
* Builds an iteration-limited injection load shape.
|
|
518
|
+
* Use this when a fixed number of injected iterations should be executed.
|
|
519
|
+
*/
|
|
416
520
|
static IterationsForInject(rate, intervalSeconds, iterations) {
|
|
417
521
|
return LoadStrikeSimulation.iterationsForInject(rate, intervalSeconds, iterations);
|
|
418
522
|
}
|
|
523
|
+
/**
|
|
524
|
+
* Builds a constant-concurrency load shape.
|
|
525
|
+
* Use this when a fixed number of virtual users should stay active.
|
|
526
|
+
*/
|
|
419
527
|
static keepConstant(copies, duringSeconds) {
|
|
420
528
|
return attachLoadSimulationProjection({
|
|
421
529
|
Kind: "KeepConstant",
|
|
@@ -423,9 +531,17 @@ class LoadStrikeSimulation {
|
|
|
423
531
|
DuringSeconds: duringSeconds
|
|
424
532
|
});
|
|
425
533
|
}
|
|
534
|
+
/**
|
|
535
|
+
* Builds a constant-concurrency load shape.
|
|
536
|
+
* Use this when a fixed number of virtual users should stay active.
|
|
537
|
+
*/
|
|
426
538
|
static KeepConstant(copies, duringSeconds) {
|
|
427
539
|
return LoadStrikeSimulation.keepConstant(copies, duringSeconds);
|
|
428
540
|
}
|
|
541
|
+
/**
|
|
542
|
+
* Builds a randomized injection load shape.
|
|
543
|
+
* Use this when traffic should fluctuate between a minimum and maximum rate.
|
|
544
|
+
*/
|
|
429
545
|
static injectRandom(minRate, maxRate, intervalSeconds, duringSeconds) {
|
|
430
546
|
return attachLoadSimulationProjection({
|
|
431
547
|
Kind: "InjectRandom",
|
|
@@ -435,9 +551,17 @@ class LoadStrikeSimulation {
|
|
|
435
551
|
DuringSeconds: duringSeconds
|
|
436
552
|
});
|
|
437
553
|
}
|
|
554
|
+
/**
|
|
555
|
+
* Builds a randomized injection load shape.
|
|
556
|
+
* Use this when traffic should fluctuate between a minimum and maximum rate.
|
|
557
|
+
*/
|
|
438
558
|
static InjectRandom(minRate, maxRate, intervalSeconds, duringSeconds) {
|
|
439
559
|
return LoadStrikeSimulation.injectRandom(minRate, maxRate, intervalSeconds, duringSeconds);
|
|
440
560
|
}
|
|
561
|
+
/**
|
|
562
|
+
* Builds a ramping injection load shape.
|
|
563
|
+
* Use this when request rate should increase over time.
|
|
564
|
+
*/
|
|
441
565
|
static rampingInject(rate, intervalSeconds, duringSeconds) {
|
|
442
566
|
return attachLoadSimulationProjection({
|
|
443
567
|
Kind: "RampingInject",
|
|
@@ -446,9 +570,17 @@ class LoadStrikeSimulation {
|
|
|
446
570
|
DuringSeconds: duringSeconds
|
|
447
571
|
});
|
|
448
572
|
}
|
|
573
|
+
/**
|
|
574
|
+
* Builds a ramping injection load shape.
|
|
575
|
+
* Use this when request rate should increase over time.
|
|
576
|
+
*/
|
|
449
577
|
static RampingInject(rate, intervalSeconds, duringSeconds) {
|
|
450
578
|
return LoadStrikeSimulation.rampingInject(rate, intervalSeconds, duringSeconds);
|
|
451
579
|
}
|
|
580
|
+
/**
|
|
581
|
+
* Builds a ramping-concurrency load shape.
|
|
582
|
+
* Use this when the number of active virtual users should climb over time.
|
|
583
|
+
*/
|
|
452
584
|
static rampingConstant(copies, duringSeconds) {
|
|
453
585
|
return attachLoadSimulationProjection({
|
|
454
586
|
Kind: "RampingConstant",
|
|
@@ -456,21 +588,37 @@ class LoadStrikeSimulation {
|
|
|
456
588
|
DuringSeconds: duringSeconds
|
|
457
589
|
});
|
|
458
590
|
}
|
|
591
|
+
/**
|
|
592
|
+
* Builds a ramping-concurrency load shape.
|
|
593
|
+
* Use this when the number of active virtual users should climb over time.
|
|
594
|
+
*/
|
|
459
595
|
static RampingConstant(copies, duringSeconds) {
|
|
460
596
|
return LoadStrikeSimulation.rampingConstant(copies, duringSeconds);
|
|
461
597
|
}
|
|
598
|
+
/**
|
|
599
|
+
* Builds a pause segment in a load profile.
|
|
600
|
+
* Use this when a simulation should intentionally idle for a period.
|
|
601
|
+
*/
|
|
462
602
|
static pause(duringSeconds) {
|
|
463
603
|
return attachLoadSimulationProjection({
|
|
464
604
|
Kind: "Pause",
|
|
465
605
|
DuringSeconds: duringSeconds
|
|
466
606
|
});
|
|
467
607
|
}
|
|
608
|
+
/**
|
|
609
|
+
* Builds a pause segment in a load profile.
|
|
610
|
+
* Use this when a simulation should intentionally idle for a period.
|
|
611
|
+
*/
|
|
468
612
|
static Pause(duringSeconds) {
|
|
469
613
|
return LoadStrikeSimulation.pause(duringSeconds);
|
|
470
614
|
}
|
|
471
615
|
}
|
|
472
616
|
exports.LoadStrikeSimulation = LoadStrikeSimulation;
|
|
473
617
|
class LoadStrikeCounter {
|
|
618
|
+
/**
|
|
619
|
+
* Exposes the public constructor operation.
|
|
620
|
+
* Use this when the surrounding wrapper type makes this operation the clearest way to express your intent.
|
|
621
|
+
*/
|
|
474
622
|
constructor(name, initialValueOrUnit = 0, unitOfMeasure = "") {
|
|
475
623
|
this.type = "counter";
|
|
476
624
|
this.name = requireNonEmpty(name, "Metric name is required.");
|
|
@@ -481,20 +629,40 @@ class LoadStrikeCounter {
|
|
|
481
629
|
? 0
|
|
482
630
|
: (Number.isFinite(initialValueOrUnit) ? Number(initialValueOrUnit) : 0);
|
|
483
631
|
}
|
|
632
|
+
/**
|
|
633
|
+
* Adds a value to the current metric.
|
|
634
|
+
* Use this when a counter or gauge should be incremented by an explicit delta.
|
|
635
|
+
*/
|
|
484
636
|
add(value) {
|
|
485
637
|
const next = Number.isFinite(value) ? Number(value) : 0;
|
|
486
638
|
this.current += next;
|
|
487
639
|
return this.current;
|
|
488
640
|
}
|
|
641
|
+
/**
|
|
642
|
+
* Increments the current metric by one.
|
|
643
|
+
* Use this when events should simply be counted.
|
|
644
|
+
*/
|
|
489
645
|
increment(by = 1) {
|
|
490
646
|
return this.add(by);
|
|
491
647
|
}
|
|
648
|
+
/**
|
|
649
|
+
* Returns the current metric value.
|
|
650
|
+
* Use this when custom metric state needs to be inspected inside user code.
|
|
651
|
+
*/
|
|
492
652
|
value() {
|
|
493
653
|
return this.current;
|
|
494
654
|
}
|
|
655
|
+
/**
|
|
656
|
+
* Adds a value to the current metric.
|
|
657
|
+
* Use this when a counter or gauge should be incremented by an explicit delta.
|
|
658
|
+
*/
|
|
495
659
|
Add(value) {
|
|
496
660
|
return this.add(value);
|
|
497
661
|
}
|
|
662
|
+
/**
|
|
663
|
+
* Increments the current metric by one.
|
|
664
|
+
* Use this when events should simply be counted.
|
|
665
|
+
*/
|
|
498
666
|
Increment(by = 1) {
|
|
499
667
|
return this.increment(by);
|
|
500
668
|
}
|
|
@@ -510,6 +678,10 @@ class LoadStrikeCounter {
|
|
|
510
678
|
}
|
|
511
679
|
exports.LoadStrikeCounter = LoadStrikeCounter;
|
|
512
680
|
class LoadStrikeGauge {
|
|
681
|
+
/**
|
|
682
|
+
* Exposes the public constructor operation.
|
|
683
|
+
* Use this when the surrounding wrapper type makes this operation the clearest way to express your intent.
|
|
684
|
+
*/
|
|
513
685
|
constructor(name, initialValueOrUnit = 0, unitOfMeasure = "") {
|
|
514
686
|
this.type = "gauge";
|
|
515
687
|
this.name = requireNonEmpty(name, "Metric name is required.");
|
|
@@ -520,33 +692,69 @@ class LoadStrikeGauge {
|
|
|
520
692
|
? 0
|
|
521
693
|
: (Number.isFinite(initialValueOrUnit) ? Number(initialValueOrUnit) : 0);
|
|
522
694
|
}
|
|
695
|
+
/**
|
|
696
|
+
* Sets the current gauge value.
|
|
697
|
+
* Use this when the latest observed value should replace the previous one.
|
|
698
|
+
*/
|
|
523
699
|
set(value) {
|
|
524
700
|
this.current = Number.isFinite(value) ? Number(value) : 0;
|
|
525
701
|
return this.current;
|
|
526
702
|
}
|
|
703
|
+
/**
|
|
704
|
+
* Adds a value to the current metric.
|
|
705
|
+
* Use this when a counter or gauge should be incremented by an explicit delta.
|
|
706
|
+
*/
|
|
527
707
|
add(value) {
|
|
528
708
|
const next = Number.isFinite(value) ? Number(value) : 0;
|
|
529
709
|
this.current += next;
|
|
530
710
|
return this.current;
|
|
531
711
|
}
|
|
712
|
+
/**
|
|
713
|
+
* Increments the current metric by one.
|
|
714
|
+
* Use this when events should simply be counted.
|
|
715
|
+
*/
|
|
532
716
|
increment(by = 1) {
|
|
533
717
|
return this.add(by);
|
|
534
718
|
}
|
|
719
|
+
/**
|
|
720
|
+
* Decrements the current metric by one.
|
|
721
|
+
* Use this when a gauge should move down by a single unit.
|
|
722
|
+
*/
|
|
535
723
|
decrement(by = 1) {
|
|
536
724
|
return this.add(-by);
|
|
537
725
|
}
|
|
726
|
+
/**
|
|
727
|
+
* Returns the current metric value.
|
|
728
|
+
* Use this when custom metric state needs to be inspected inside user code.
|
|
729
|
+
*/
|
|
538
730
|
value() {
|
|
539
731
|
return this.current;
|
|
540
732
|
}
|
|
733
|
+
/**
|
|
734
|
+
* Sets the current gauge value.
|
|
735
|
+
* Use this when the latest observed value should replace the previous one.
|
|
736
|
+
*/
|
|
541
737
|
Set(value) {
|
|
542
738
|
return this.set(value);
|
|
543
739
|
}
|
|
740
|
+
/**
|
|
741
|
+
* Adds a value to the current metric.
|
|
742
|
+
* Use this when a counter or gauge should be incremented by an explicit delta.
|
|
743
|
+
*/
|
|
544
744
|
Add(value) {
|
|
545
745
|
return this.add(value);
|
|
546
746
|
}
|
|
747
|
+
/**
|
|
748
|
+
* Increments the current metric by one.
|
|
749
|
+
* Use this when events should simply be counted.
|
|
750
|
+
*/
|
|
547
751
|
Increment(by = 1) {
|
|
548
752
|
return this.increment(by);
|
|
549
753
|
}
|
|
754
|
+
/**
|
|
755
|
+
* Decrements the current metric by one.
|
|
756
|
+
* Use this when a gauge should move down by a single unit.
|
|
757
|
+
*/
|
|
550
758
|
Decrement(by = 1) {
|
|
551
759
|
return this.decrement(by);
|
|
552
760
|
}
|
|
@@ -562,21 +770,45 @@ class LoadStrikeGauge {
|
|
|
562
770
|
}
|
|
563
771
|
exports.LoadStrikeGauge = LoadStrikeGauge;
|
|
564
772
|
class LoadStrikeMetric {
|
|
773
|
+
/**
|
|
774
|
+
* Creates a counter metric.
|
|
775
|
+
* Use this when a scenario should accumulate a monotonically increasing custom metric.
|
|
776
|
+
*/
|
|
565
777
|
static counter(name, initialValueOrUnit = 0, unitOfMeasure = "") {
|
|
566
778
|
return new LoadStrikeCounter(name, initialValueOrUnit, unitOfMeasure);
|
|
567
779
|
}
|
|
780
|
+
/**
|
|
781
|
+
* Creates a gauge metric.
|
|
782
|
+
* Use this when a scenario should track the latest value of a custom metric.
|
|
783
|
+
*/
|
|
568
784
|
static gauge(name, initialValueOrUnit = 0, unitOfMeasure = "") {
|
|
569
785
|
return new LoadStrikeGauge(name, initialValueOrUnit, unitOfMeasure);
|
|
570
786
|
}
|
|
787
|
+
/**
|
|
788
|
+
* Creates a counter metric.
|
|
789
|
+
* Use this when a scenario should accumulate a monotonically increasing custom metric.
|
|
790
|
+
*/
|
|
571
791
|
static Counter(name, initialValueOrUnit = 0, unitOfMeasure = "") {
|
|
572
792
|
return LoadStrikeMetric.counter(name, initialValueOrUnit, unitOfMeasure);
|
|
573
793
|
}
|
|
794
|
+
/**
|
|
795
|
+
* Creates a gauge metric.
|
|
796
|
+
* Use this when a scenario should track the latest value of a custom metric.
|
|
797
|
+
*/
|
|
574
798
|
static Gauge(name, initialValueOrUnit = 0, unitOfMeasure = "") {
|
|
575
799
|
return LoadStrikeMetric.gauge(name, initialValueOrUnit, unitOfMeasure);
|
|
576
800
|
}
|
|
801
|
+
/**
|
|
802
|
+
* Creates a counter metric.
|
|
803
|
+
* Use this when a scenario should accumulate a monotonically increasing custom metric.
|
|
804
|
+
*/
|
|
577
805
|
static CreateCounter(name, unitOfMeasure = "") {
|
|
578
806
|
return new LoadStrikeCounter(name, 0, unitOfMeasure);
|
|
579
807
|
}
|
|
808
|
+
/**
|
|
809
|
+
* Creates a gauge metric.
|
|
810
|
+
* Use this when a scenario should track the latest value of a custom metric.
|
|
811
|
+
*/
|
|
580
812
|
static CreateGauge(name, unitOfMeasure = "") {
|
|
581
813
|
return new LoadStrikeGauge(name, 0, unitOfMeasure);
|
|
582
814
|
}
|
|
@@ -701,15 +933,31 @@ class LoadStrikeContext {
|
|
|
701
933
|
this.registeredScenarios = [...registeredScenarios];
|
|
702
934
|
this.runArgs = [...runArgs];
|
|
703
935
|
}
|
|
936
|
+
/**
|
|
937
|
+
* Creates a new instance of this public SDK type.
|
|
938
|
+
* Use this when you are starting a run definition from scratch.
|
|
939
|
+
*/
|
|
704
940
|
static create() {
|
|
705
941
|
return new LoadStrikeContext();
|
|
706
942
|
}
|
|
943
|
+
/**
|
|
944
|
+
* Exposes the public toObject operation.
|
|
945
|
+
* Use this when the surrounding wrapper type makes this operation the clearest way to express your intent.
|
|
946
|
+
*/
|
|
707
947
|
toObject() {
|
|
708
948
|
return { ...this.values };
|
|
709
949
|
}
|
|
950
|
+
/**
|
|
951
|
+
* Builds the current configuration into a runnable context.
|
|
952
|
+
* Use this when you want to inspect or reuse the final run settings before execution.
|
|
953
|
+
*/
|
|
710
954
|
buildContext() {
|
|
711
955
|
return this;
|
|
712
956
|
}
|
|
957
|
+
/**
|
|
958
|
+
* Builds the current configuration into a runnable context.
|
|
959
|
+
* Use this when you want to inspect or reuse the final run settings before execution.
|
|
960
|
+
*/
|
|
713
961
|
BuildContext() {
|
|
714
962
|
return this.buildContext();
|
|
715
963
|
}
|
|
@@ -731,6 +979,10 @@ class LoadStrikeContext {
|
|
|
731
979
|
const args = normalizeRunArgsInput(argsOrSingleArray);
|
|
732
980
|
return this.run(args);
|
|
733
981
|
}
|
|
982
|
+
/**
|
|
983
|
+
* Exposes the public toRunnerOptions operation.
|
|
984
|
+
* Use this when the surrounding wrapper type makes this operation the clearest way to express your intent.
|
|
985
|
+
*/
|
|
734
986
|
toRunnerOptions() {
|
|
735
987
|
const normalizedValues = normalizeRunContextCollectionShapes(this.values);
|
|
736
988
|
return {
|
|
@@ -803,27 +1055,59 @@ class LoadStrikeContext {
|
|
|
803
1055
|
Configure(input) {
|
|
804
1056
|
return this.configure(input);
|
|
805
1057
|
}
|
|
1058
|
+
/**
|
|
1059
|
+
* Copies settings from an existing context snapshot.
|
|
1060
|
+
* Use this when a runner should inherit configuration that was already assembled elsewhere.
|
|
1061
|
+
*/
|
|
806
1062
|
configureContext(context) {
|
|
807
1063
|
return this.configure(context);
|
|
808
1064
|
}
|
|
1065
|
+
/**
|
|
1066
|
+
* Copies settings from an existing context snapshot.
|
|
1067
|
+
* Use this when a runner should inherit configuration that was already assembled elsewhere.
|
|
1068
|
+
*/
|
|
809
1069
|
ConfigureContext(context) {
|
|
810
1070
|
return this.configureContext(context);
|
|
811
1071
|
}
|
|
1072
|
+
/**
|
|
1073
|
+
* Toggles realtime console metric output.
|
|
1074
|
+
* Use this when a local run or CI log should stream live throughput and latency updates.
|
|
1075
|
+
*/
|
|
812
1076
|
displayConsoleMetrics(enable) {
|
|
813
1077
|
return this.DisplayConsoleMetrics(enable);
|
|
814
1078
|
}
|
|
1079
|
+
/**
|
|
1080
|
+
* Toggles realtime console metric output.
|
|
1081
|
+
* Use this when a local run or CI log should stream live throughput and latency updates.
|
|
1082
|
+
*/
|
|
815
1083
|
DisplayConsoleMetrics(enable) {
|
|
816
1084
|
return this.mergeValues({ ConsoleMetricsEnabled: Boolean(enable) });
|
|
817
1085
|
}
|
|
1086
|
+
/**
|
|
1087
|
+
* Toggles local development cluster mode.
|
|
1088
|
+
* Use this when you want to simulate coordinator and agent behavior on a single machine.
|
|
1089
|
+
*/
|
|
818
1090
|
enableLocalDevCluster(enable) {
|
|
819
1091
|
return this.EnableLocalDevCluster(enable);
|
|
820
1092
|
}
|
|
1093
|
+
/**
|
|
1094
|
+
* Toggles local development cluster mode.
|
|
1095
|
+
* Use this when you want to simulate coordinator and agent behavior on a single machine.
|
|
1096
|
+
*/
|
|
821
1097
|
EnableLocalDevCluster(enable) {
|
|
822
1098
|
return this.mergeValues({ LocalDevClusterEnabled: Boolean(enable) });
|
|
823
1099
|
}
|
|
1100
|
+
/**
|
|
1101
|
+
* Loads run settings from a JSON config file.
|
|
1102
|
+
* Use this when configuration should come from a checked-in or generated config document.
|
|
1103
|
+
*/
|
|
824
1104
|
loadConfig(path) {
|
|
825
1105
|
return this.LoadConfig(path);
|
|
826
1106
|
}
|
|
1107
|
+
/**
|
|
1108
|
+
* Loads run settings from a JSON config file.
|
|
1109
|
+
* Use this when configuration should come from a checked-in or generated config document.
|
|
1110
|
+
*/
|
|
827
1111
|
LoadConfig(path) {
|
|
828
1112
|
const configPath = requireNonEmpty(path, "Config path must be provided.");
|
|
829
1113
|
const loaded = loadJsonObject(configPath);
|
|
@@ -833,9 +1117,17 @@ class LoadStrikeContext {
|
|
|
833
1117
|
...extractContextOverridesFromConfig(loaded)
|
|
834
1118
|
});
|
|
835
1119
|
}
|
|
1120
|
+
/**
|
|
1121
|
+
* Loads infrastructure settings for sinks, plugins, or transport dependencies.
|
|
1122
|
+
* Use this when runtime integrations depend on external connection details.
|
|
1123
|
+
*/
|
|
836
1124
|
loadInfraConfig(path) {
|
|
837
1125
|
return this.LoadInfraConfig(path);
|
|
838
1126
|
}
|
|
1127
|
+
/**
|
|
1128
|
+
* Loads infrastructure settings for sinks, plugins, or transport dependencies.
|
|
1129
|
+
* Use this when runtime integrations depend on external connection details.
|
|
1130
|
+
*/
|
|
839
1131
|
LoadInfraConfig(path) {
|
|
840
1132
|
const infraConfigPath = requireNonEmpty(path, "Infra config path must be provided.");
|
|
841
1133
|
return this.mergeValues({
|
|
@@ -843,87 +1135,191 @@ class LoadStrikeContext {
|
|
|
843
1135
|
InfraConfig: loadJsonObject(infraConfigPath)
|
|
844
1136
|
});
|
|
845
1137
|
}
|
|
1138
|
+
/**
|
|
1139
|
+
* Sets the agent group for this node or run.
|
|
1140
|
+
* Use this when only a subset of agents should pick up a particular workload.
|
|
1141
|
+
*/
|
|
846
1142
|
withAgentGroup(agentGroup) {
|
|
847
1143
|
return this.WithAgentGroup(agentGroup);
|
|
848
1144
|
}
|
|
1145
|
+
/**
|
|
1146
|
+
* Sets the agent group for this node or run.
|
|
1147
|
+
* Use this when only a subset of agents should pick up a particular workload.
|
|
1148
|
+
*/
|
|
849
1149
|
WithAgentGroup(agentGroup) {
|
|
850
1150
|
return this.mergeValues({ AgentGroup: requireNonEmpty(agentGroup, "Agent group must be provided.") });
|
|
851
1151
|
}
|
|
1152
|
+
/**
|
|
1153
|
+
* Sets the requested agent count.
|
|
1154
|
+
* Use this when a coordinator should fan work out across a specific number of agents.
|
|
1155
|
+
*/
|
|
852
1156
|
withAgentsCount(agentsCount) {
|
|
853
1157
|
return this.WithAgentsCount(agentsCount);
|
|
854
1158
|
}
|
|
1159
|
+
/**
|
|
1160
|
+
* Sets the requested agent count.
|
|
1161
|
+
* Use this when a coordinator should fan work out across a specific number of agents.
|
|
1162
|
+
*/
|
|
855
1163
|
WithAgentsCount(agentsCount) {
|
|
856
1164
|
if (!Number.isFinite(agentsCount) || agentsCount <= 0) {
|
|
857
1165
|
throw new RangeError("Agents count should be greater than zero.");
|
|
858
1166
|
}
|
|
859
1167
|
return this.mergeValues({ AgentsCount: Math.trunc(agentsCount) });
|
|
860
1168
|
}
|
|
1169
|
+
/**
|
|
1170
|
+
* Targets a shared set of scenarios.
|
|
1171
|
+
* Use this when only selected scenarios should execute for the current node or run.
|
|
1172
|
+
*/
|
|
861
1173
|
withTargetScenarios(...scenarioNames) {
|
|
862
1174
|
return this.WithTargetScenarios(...scenarioNames);
|
|
863
1175
|
}
|
|
1176
|
+
/**
|
|
1177
|
+
* Targets a shared set of scenarios.
|
|
1178
|
+
* Use this when only selected scenarios should execute for the current node or run.
|
|
1179
|
+
*/
|
|
864
1180
|
WithTargetScenarios(...scenarioNames) {
|
|
865
1181
|
return this.mergeValues({ TargetScenarios: validateScenarioNames(scenarioNames) });
|
|
866
1182
|
}
|
|
1183
|
+
/**
|
|
1184
|
+
* Targets scenarios for agent nodes only.
|
|
1185
|
+
* Use this when agents should execute only a subset of the registered scenarios.
|
|
1186
|
+
*/
|
|
867
1187
|
withAgentTargetScenarios(...scenarioNames) {
|
|
868
1188
|
return this.WithAgentTargetScenarios(...scenarioNames);
|
|
869
1189
|
}
|
|
1190
|
+
/**
|
|
1191
|
+
* Targets scenarios for agent nodes only.
|
|
1192
|
+
* Use this when agents should execute only a subset of the registered scenarios.
|
|
1193
|
+
*/
|
|
870
1194
|
WithAgentTargetScenarios(...scenarioNames) {
|
|
871
1195
|
return this.mergeValues({ AgentTargetScenarios: validateScenarioNames(scenarioNames) });
|
|
872
1196
|
}
|
|
1197
|
+
/**
|
|
1198
|
+
* Targets scenarios for the coordinator only.
|
|
1199
|
+
* Use this when orchestration or control-node work should run on the coordinator itself.
|
|
1200
|
+
*/
|
|
873
1201
|
withCoordinatorTargetScenarios(...scenarioNames) {
|
|
874
1202
|
return this.WithCoordinatorTargetScenarios(...scenarioNames);
|
|
875
1203
|
}
|
|
1204
|
+
/**
|
|
1205
|
+
* Targets scenarios for the coordinator only.
|
|
1206
|
+
* Use this when orchestration or control-node work should run on the coordinator itself.
|
|
1207
|
+
*/
|
|
876
1208
|
WithCoordinatorTargetScenarios(...scenarioNames) {
|
|
877
1209
|
return this.mergeValues({ CoordinatorTargetScenarios: validateScenarioNames(scenarioNames) });
|
|
878
1210
|
}
|
|
1211
|
+
/**
|
|
1212
|
+
* Sets the runner key used for licensing validation.
|
|
1213
|
+
* Use this when the run must authenticate against the licensing API before it starts.
|
|
1214
|
+
*/
|
|
879
1215
|
withRunnerKey(runnerKey) {
|
|
880
1216
|
return this.WithRunnerKey(runnerKey);
|
|
881
1217
|
}
|
|
1218
|
+
/**
|
|
1219
|
+
* Sets the runner key used for licensing validation.
|
|
1220
|
+
* Use this when the run must authenticate against the licensing API before it starts.
|
|
1221
|
+
*/
|
|
882
1222
|
WithRunnerKey(runnerKey) {
|
|
883
1223
|
return this.mergeValues({ RunnerKey: requireNonEmpty(runnerKey, "Runner key must be provided.") });
|
|
884
1224
|
}
|
|
1225
|
+
/**
|
|
1226
|
+
* Sets how long the SDK waits for licensing validation to complete.
|
|
1227
|
+
* Use this when control-plane latency or private networking requires a longer validation window.
|
|
1228
|
+
*/
|
|
885
1229
|
withLicenseValidationTimeout(timeoutSeconds) {
|
|
886
1230
|
return this.WithLicenseValidationTimeout(timeoutSeconds);
|
|
887
1231
|
}
|
|
1232
|
+
/**
|
|
1233
|
+
* Sets how long the SDK waits for licensing validation to complete.
|
|
1234
|
+
* Use this when control-plane latency or private networking requires a longer validation window.
|
|
1235
|
+
*/
|
|
888
1236
|
WithLicenseValidationTimeout(timeoutSeconds) {
|
|
889
1237
|
if (!Number.isFinite(timeoutSeconds) || timeoutSeconds <= 0) {
|
|
890
1238
|
throw new RangeError("License validation timeout should be greater than zero.");
|
|
891
1239
|
}
|
|
892
1240
|
return this.mergeValues({ LicenseValidationTimeoutSeconds: timeoutSeconds });
|
|
893
1241
|
}
|
|
1242
|
+
/**
|
|
1243
|
+
* Sets the runtime node type.
|
|
1244
|
+
* Use this when a process should behave as a single node, coordinator, or agent.
|
|
1245
|
+
*/
|
|
894
1246
|
withNodeType(nodeType) {
|
|
895
1247
|
return this.WithNodeType(nodeType);
|
|
896
1248
|
}
|
|
1249
|
+
/**
|
|
1250
|
+
* Sets the runtime node type.
|
|
1251
|
+
* Use this when a process should behave as a single node, coordinator, or agent.
|
|
1252
|
+
*/
|
|
897
1253
|
WithNodeType(nodeType) {
|
|
898
1254
|
return this.mergeValues({ NodeType: parseNodeTypeToken(nodeType) });
|
|
899
1255
|
}
|
|
1256
|
+
/**
|
|
1257
|
+
* Sets the NATS server URL used for distributed cluster coordination.
|
|
1258
|
+
* Use this when coordinator and agent nodes communicate over NATS.
|
|
1259
|
+
*/
|
|
900
1260
|
withNatsServerUrl(natsUrl) {
|
|
901
1261
|
return this.WithNatsServerUrl(natsUrl);
|
|
902
1262
|
}
|
|
1263
|
+
/**
|
|
1264
|
+
* Sets the NATS server URL used for distributed cluster coordination.
|
|
1265
|
+
* Use this when coordinator and agent nodes communicate over NATS.
|
|
1266
|
+
*/
|
|
903
1267
|
WithNatsServerUrl(natsUrl) {
|
|
904
1268
|
return this.mergeValues({ NatsServerUrl: requireNonEmpty(natsUrl, "NATS server URL must be provided.") });
|
|
905
1269
|
}
|
|
1270
|
+
/**
|
|
1271
|
+
* Disables local report generation.
|
|
1272
|
+
* Use this when reports are unnecessary or should be handled exclusively by sinks.
|
|
1273
|
+
*/
|
|
906
1274
|
withoutReports() {
|
|
907
1275
|
return this.WithoutReports();
|
|
908
1276
|
}
|
|
1277
|
+
/**
|
|
1278
|
+
* Disables local report generation.
|
|
1279
|
+
* Use this when reports are unnecessary or should be handled exclusively by sinks.
|
|
1280
|
+
*/
|
|
909
1281
|
WithoutReports() {
|
|
910
1282
|
return this.mergeValues({ ReportsEnabled: false });
|
|
911
1283
|
}
|
|
1284
|
+
/**
|
|
1285
|
+
* Sets the base file name for generated reports.
|
|
1286
|
+
* Use this when exported reports should use a predictable naming convention.
|
|
1287
|
+
*/
|
|
912
1288
|
withReportFileName(reportFileName) {
|
|
913
1289
|
return this.WithReportFileName(reportFileName);
|
|
914
1290
|
}
|
|
1291
|
+
/**
|
|
1292
|
+
* Sets the base file name for generated reports.
|
|
1293
|
+
* Use this when exported reports should use a predictable naming convention.
|
|
1294
|
+
*/
|
|
915
1295
|
WithReportFileName(reportFileName) {
|
|
916
1296
|
return this.mergeValues({ ReportFileName: requireNonEmpty(reportFileName, "Report file name must be provided.") });
|
|
917
1297
|
}
|
|
1298
|
+
/**
|
|
1299
|
+
* Sets the output folder for generated reports.
|
|
1300
|
+
* Use this when report files should land in a specific directory.
|
|
1301
|
+
*/
|
|
918
1302
|
withReportFolder(reportFolderPath) {
|
|
919
1303
|
return this.WithReportFolder(reportFolderPath);
|
|
920
1304
|
}
|
|
1305
|
+
/**
|
|
1306
|
+
* Sets the output folder for generated reports.
|
|
1307
|
+
* Use this when report files should land in a specific directory.
|
|
1308
|
+
*/
|
|
921
1309
|
WithReportFolder(reportFolderPath) {
|
|
922
1310
|
return this.mergeValues({ ReportFolderPath: requireNonEmpty(reportFolderPath, "Report folder path must be provided.") });
|
|
923
1311
|
}
|
|
1312
|
+
/**
|
|
1313
|
+
* Restricts generated reports to specific formats.
|
|
1314
|
+
* Use this when you want only selected report artifacts such as HTML, CSV, or Markdown.
|
|
1315
|
+
*/
|
|
924
1316
|
withReportFormats(...reportFormats) {
|
|
925
1317
|
return this.WithReportFormats(...reportFormats);
|
|
926
1318
|
}
|
|
1319
|
+
/**
|
|
1320
|
+
* Restricts generated reports to specific formats.
|
|
1321
|
+
* Use this when you want only selected report artifacts such as HTML, CSV, or Markdown.
|
|
1322
|
+
*/
|
|
927
1323
|
WithReportFormats(...reportFormats) {
|
|
928
1324
|
if (!reportFormats.length) {
|
|
929
1325
|
throw new Error("At least one report format should be provided.");
|
|
@@ -934,18 +1330,34 @@ class LoadStrikeContext {
|
|
|
934
1330
|
}
|
|
935
1331
|
return this.mergeValues({ ReportFormats: normalized });
|
|
936
1332
|
}
|
|
1333
|
+
/**
|
|
1334
|
+
* Sets the realtime reporting cadence.
|
|
1335
|
+
* Use this when sinks or dashboards should receive updates at a controlled interval.
|
|
1336
|
+
*/
|
|
937
1337
|
withReportingInterval(intervalSeconds) {
|
|
938
1338
|
return this.WithReportingInterval(intervalSeconds);
|
|
939
1339
|
}
|
|
1340
|
+
/**
|
|
1341
|
+
* Sets the realtime reporting cadence.
|
|
1342
|
+
* Use this when sinks or dashboards should receive updates at a controlled interval.
|
|
1343
|
+
*/
|
|
940
1344
|
WithReportingInterval(intervalSeconds) {
|
|
941
1345
|
if (!Number.isFinite(intervalSeconds) || intervalSeconds <= 0) {
|
|
942
1346
|
throw new RangeError("Reporting interval should be greater than zero.");
|
|
943
1347
|
}
|
|
944
1348
|
return this.mergeValues({ ReportingIntervalSeconds: intervalSeconds });
|
|
945
1349
|
}
|
|
1350
|
+
/**
|
|
1351
|
+
* Registers one or more reporting sinks.
|
|
1352
|
+
* Use this when run results must be pushed to external observability or storage systems.
|
|
1353
|
+
*/
|
|
946
1354
|
withReportingSinks(...sinks) {
|
|
947
1355
|
return this.WithReportingSinks(...sinks);
|
|
948
1356
|
}
|
|
1357
|
+
/**
|
|
1358
|
+
* Registers one or more reporting sinks.
|
|
1359
|
+
* Use this when run results must be pushed to external observability or storage systems.
|
|
1360
|
+
*/
|
|
949
1361
|
WithReportingSinks(...sinks) {
|
|
950
1362
|
if (!sinks.length) {
|
|
951
1363
|
throw new Error("At least one reporting sink should be provided.");
|
|
@@ -956,9 +1368,17 @@ class LoadStrikeContext {
|
|
|
956
1368
|
validateNamedReportingSinks(sinks);
|
|
957
1369
|
return this.mergeValues({ ReportingSinks: sinks });
|
|
958
1370
|
}
|
|
1371
|
+
/**
|
|
1372
|
+
* Registers runtime policies for the run.
|
|
1373
|
+
* Use this when scenario selection or step execution should obey policy callbacks.
|
|
1374
|
+
*/
|
|
959
1375
|
withRuntimePolicies(...policies) {
|
|
960
1376
|
return this.WithRuntimePolicies(...policies);
|
|
961
1377
|
}
|
|
1378
|
+
/**
|
|
1379
|
+
* Registers runtime policies for the run.
|
|
1380
|
+
* Use this when scenario selection or step execution should obey policy callbacks.
|
|
1381
|
+
*/
|
|
962
1382
|
WithRuntimePolicies(...policies) {
|
|
963
1383
|
if (!policies.length) {
|
|
964
1384
|
throw new Error("At least one runtime policy should be provided.");
|
|
@@ -968,17 +1388,33 @@ class LoadStrikeContext {
|
|
|
968
1388
|
}
|
|
969
1389
|
return this.mergeValues({ RuntimePolicies: policies });
|
|
970
1390
|
}
|
|
1391
|
+
/**
|
|
1392
|
+
* Sets how runtime policy failures are handled.
|
|
1393
|
+
* Use this when policy errors should either fail fast or be tolerated.
|
|
1394
|
+
*/
|
|
971
1395
|
withRuntimePolicyErrorMode(mode) {
|
|
972
1396
|
return this.WithRuntimePolicyErrorMode(mode);
|
|
973
1397
|
}
|
|
1398
|
+
/**
|
|
1399
|
+
* Sets how runtime policy failures are handled.
|
|
1400
|
+
* Use this when policy errors should either fail fast or be tolerated.
|
|
1401
|
+
*/
|
|
974
1402
|
WithRuntimePolicyErrorMode(mode) {
|
|
975
1403
|
return this.mergeValues({
|
|
976
1404
|
RuntimePolicyErrorMode: normalizedRuntimePolicyErrorMode(mode)
|
|
977
1405
|
});
|
|
978
1406
|
}
|
|
1407
|
+
/**
|
|
1408
|
+
* Registers worker plugins for the run.
|
|
1409
|
+
* Use this when custom plugin data should be collected alongside run results.
|
|
1410
|
+
*/
|
|
979
1411
|
withWorkerPlugins(...plugins) {
|
|
980
1412
|
return this.WithWorkerPlugins(...plugins);
|
|
981
1413
|
}
|
|
1414
|
+
/**
|
|
1415
|
+
* Registers worker plugins for the run.
|
|
1416
|
+
* Use this when custom plugin data should be collected alongside run results.
|
|
1417
|
+
*/
|
|
982
1418
|
WithWorkerPlugins(...plugins) {
|
|
983
1419
|
if (!plugins.length) {
|
|
984
1420
|
throw new Error("At least one worker plugin should be provided.");
|
|
@@ -989,71 +1425,143 @@ class LoadStrikeContext {
|
|
|
989
1425
|
validateNamedWorkerPlugins(plugins);
|
|
990
1426
|
return this.mergeValues({ WorkerPlugins: plugins });
|
|
991
1427
|
}
|
|
1428
|
+
/**
|
|
1429
|
+
* Sets the minimum runtime log level.
|
|
1430
|
+
* Use this when the run should emit less or more operational detail.
|
|
1431
|
+
*/
|
|
992
1432
|
withMinimumLogLevel(minimumLogLevel) {
|
|
993
1433
|
return this.WithMinimumLogLevel(minimumLogLevel);
|
|
994
1434
|
}
|
|
1435
|
+
/**
|
|
1436
|
+
* Sets the minimum runtime log level.
|
|
1437
|
+
* Use this when the run should emit less or more operational detail.
|
|
1438
|
+
*/
|
|
995
1439
|
WithMinimumLogLevel(minimumLogLevel) {
|
|
996
1440
|
return this.mergeValues({
|
|
997
1441
|
MinimumLogLevel: parseMinimumLogLevelToken(requireNonEmpty(minimumLogLevel, "Minimum log level must be provided."))
|
|
998
1442
|
});
|
|
999
1443
|
}
|
|
1444
|
+
/**
|
|
1445
|
+
* Supplies a custom logger configuration factory.
|
|
1446
|
+
* Use this when the default runtime logging output is not enough for your environment.
|
|
1447
|
+
*/
|
|
1000
1448
|
withLoggerConfig(loggerConfig) {
|
|
1001
1449
|
return this.WithLoggerConfig(loggerConfig);
|
|
1002
1450
|
}
|
|
1451
|
+
/**
|
|
1452
|
+
* Supplies a custom logger configuration factory.
|
|
1453
|
+
* Use this when the default runtime logging output is not enough for your environment.
|
|
1454
|
+
*/
|
|
1003
1455
|
WithLoggerConfig(loggerConfig) {
|
|
1004
1456
|
if (typeof loggerConfig !== "function") {
|
|
1005
1457
|
throw new TypeError("Logger config must be provided.");
|
|
1006
1458
|
}
|
|
1007
1459
|
return this.mergeValues({ LoggerConfig: loggerConfig });
|
|
1008
1460
|
}
|
|
1461
|
+
/**
|
|
1462
|
+
* Sets the timeout for scenario completion.
|
|
1463
|
+
* Use this when long-running scenarios need an explicit completion window.
|
|
1464
|
+
*/
|
|
1009
1465
|
withScenarioCompletionTimeout(timeoutSeconds) {
|
|
1010
1466
|
return this.WithScenarioCompletionTimeout(timeoutSeconds);
|
|
1011
1467
|
}
|
|
1468
|
+
/**
|
|
1469
|
+
* Sets the timeout for scenario completion.
|
|
1470
|
+
* Use this when long-running scenarios need an explicit completion window.
|
|
1471
|
+
*/
|
|
1012
1472
|
WithScenarioCompletionTimeout(timeoutSeconds) {
|
|
1013
1473
|
if (!Number.isFinite(timeoutSeconds) || timeoutSeconds <= 0) {
|
|
1014
1474
|
throw new RangeError("Scenario completion timeout should be greater than zero.");
|
|
1015
1475
|
}
|
|
1016
1476
|
return this.mergeValues({ ScenarioCompletionTimeoutSeconds: timeoutSeconds });
|
|
1017
1477
|
}
|
|
1478
|
+
/**
|
|
1479
|
+
* Sets the timeout for cluster command round-trips.
|
|
1480
|
+
* Use this when distributed control messages need a tighter or looser deadline.
|
|
1481
|
+
*/
|
|
1018
1482
|
withClusterCommandTimeout(timeoutSeconds) {
|
|
1019
1483
|
return this.WithClusterCommandTimeout(timeoutSeconds);
|
|
1020
1484
|
}
|
|
1485
|
+
/**
|
|
1486
|
+
* Sets the timeout for cluster command round-trips.
|
|
1487
|
+
* Use this when distributed control messages need a tighter or looser deadline.
|
|
1488
|
+
*/
|
|
1021
1489
|
WithClusterCommandTimeout(timeoutSeconds) {
|
|
1022
1490
|
if (!Number.isFinite(timeoutSeconds) || timeoutSeconds <= 0) {
|
|
1023
1491
|
throw new RangeError("Cluster command timeout should be greater than zero.");
|
|
1024
1492
|
}
|
|
1025
1493
|
return this.mergeValues({ ClusterCommandTimeoutSeconds: timeoutSeconds });
|
|
1026
1494
|
}
|
|
1495
|
+
/**
|
|
1496
|
+
* Sets the retry limit for restartable failed iterations.
|
|
1497
|
+
* Use this when transient failures should be retried a fixed number of times.
|
|
1498
|
+
*/
|
|
1027
1499
|
withRestartIterationMaxAttempts(attempts) {
|
|
1028
1500
|
return this.WithRestartIterationMaxAttempts(attempts);
|
|
1029
1501
|
}
|
|
1502
|
+
/**
|
|
1503
|
+
* Sets the retry limit for restartable failed iterations.
|
|
1504
|
+
* Use this when transient failures should be retried a fixed number of times.
|
|
1505
|
+
*/
|
|
1030
1506
|
WithRestartIterationMaxAttempts(attempts) {
|
|
1031
1507
|
if (!Number.isFinite(attempts) || attempts < 0) {
|
|
1032
1508
|
throw new RangeError("Restart iteration max attempts should be zero or greater.");
|
|
1033
1509
|
}
|
|
1034
1510
|
return this.mergeValues({ RestartIterationMaxAttempts: Math.trunc(attempts) });
|
|
1035
1511
|
}
|
|
1512
|
+
/**
|
|
1513
|
+
* Sets the session identifier for this run.
|
|
1514
|
+
* Use this when downstream logs, reports, or external systems need a stable session id.
|
|
1515
|
+
*/
|
|
1036
1516
|
withSessionId(sessionId) {
|
|
1037
1517
|
return this.WithSessionId(sessionId);
|
|
1038
1518
|
}
|
|
1519
|
+
/**
|
|
1520
|
+
* Sets the session identifier for this run.
|
|
1521
|
+
* Use this when downstream logs, reports, or external systems need a stable session id.
|
|
1522
|
+
*/
|
|
1039
1523
|
WithSessionId(sessionId) {
|
|
1040
1524
|
return this.mergeValues({ SessionId: requireNonEmpty(sessionId, "Session id must be provided.") });
|
|
1041
1525
|
}
|
|
1526
|
+
/**
|
|
1527
|
+
* Sets the test suite label for the run.
|
|
1528
|
+
* Use this when related tests should be grouped under a suite name.
|
|
1529
|
+
*/
|
|
1042
1530
|
withTestSuite(testSuite) {
|
|
1043
1531
|
return this.WithTestSuite(testSuite);
|
|
1044
1532
|
}
|
|
1533
|
+
/**
|
|
1534
|
+
* Sets the test suite label for the run.
|
|
1535
|
+
* Use this when related tests should be grouped under a suite name.
|
|
1536
|
+
*/
|
|
1045
1537
|
WithTestSuite(testSuite) {
|
|
1046
1538
|
return this.mergeValues({ TestSuite: requireNonEmpty(testSuite, "Test suite must be provided.") });
|
|
1047
1539
|
}
|
|
1540
|
+
/**
|
|
1541
|
+
* Sets the test name label for the run.
|
|
1542
|
+
* Use this when reports and logs should expose a human-readable test identifier.
|
|
1543
|
+
*/
|
|
1048
1544
|
withTestName(testName) {
|
|
1049
1545
|
return this.WithTestName(testName);
|
|
1050
1546
|
}
|
|
1547
|
+
/**
|
|
1548
|
+
* Sets the test name label for the run.
|
|
1549
|
+
* Use this when reports and logs should expose a human-readable test identifier.
|
|
1550
|
+
*/
|
|
1051
1551
|
WithTestName(testName) {
|
|
1052
1552
|
return this.mergeValues({ TestName: requireNonEmpty(testName, "Test name must be provided.") });
|
|
1053
1553
|
}
|
|
1554
|
+
/**
|
|
1555
|
+
* Sets the cluster identifier for this run.
|
|
1556
|
+
* Use this when multiple cluster nodes must join the same distributed execution.
|
|
1557
|
+
*/
|
|
1054
1558
|
withClusterId(clusterId) {
|
|
1055
1559
|
return this.WithClusterId(clusterId);
|
|
1056
1560
|
}
|
|
1561
|
+
/**
|
|
1562
|
+
* Sets the cluster identifier for this run.
|
|
1563
|
+
* Use this when multiple cluster nodes must join the same distributed execution.
|
|
1564
|
+
*/
|
|
1057
1565
|
WithClusterId(clusterId) {
|
|
1058
1566
|
return this.mergeValues({ ClusterId: requireNonEmpty(clusterId, "Cluster id must be provided.") });
|
|
1059
1567
|
}
|
|
@@ -1066,13 +1574,17 @@ class LoadStrikeContext {
|
|
|
1066
1574
|
this.runArgs = [...runArgs];
|
|
1067
1575
|
return this;
|
|
1068
1576
|
}
|
|
1577
|
+
/**
|
|
1578
|
+
* Configures registered scenarios for this SDK object.
|
|
1579
|
+
* Use this when registered scenarios should be set explicitly before the run starts.
|
|
1580
|
+
*/
|
|
1069
1581
|
withRegisteredScenarios(...scenarios) {
|
|
1070
1582
|
return this.assignState(this.values, scenarios, this.runArgs);
|
|
1071
1583
|
}
|
|
1072
1584
|
}
|
|
1073
1585
|
exports.LoadStrikeContext = LoadStrikeContext;
|
|
1074
1586
|
class LoadStrikeScenario {
|
|
1075
|
-
constructor(name, runHandler, initHandler, cleanHandler, loadSimulations, thresholds, trackingConfiguration, maxFailCount, withoutWarmUpValue, warmUpDurationSeconds, weight, restartIterationOnFail) {
|
|
1587
|
+
constructor(name, runHandler, initHandler, cleanHandler, loadSimulations, thresholds, trackingConfiguration, maxFailCount, withoutWarmUpValue, warmUpDurationSeconds, weight, restartIterationOnFail, internalLicenseFeatures = []) {
|
|
1076
1588
|
this.name = name;
|
|
1077
1589
|
this.runHandler = runHandler;
|
|
1078
1590
|
this.initHandler = initHandler;
|
|
@@ -1085,6 +1597,7 @@ class LoadStrikeScenario {
|
|
|
1085
1597
|
this.warmUpDurationSeconds = warmUpDurationSeconds;
|
|
1086
1598
|
this.weight = weight;
|
|
1087
1599
|
this.restartIterationOnFail = restartIterationOnFail;
|
|
1600
|
+
this.internalLicenseFeatures = normalizeStringArray(internalLicenseFeatures);
|
|
1088
1601
|
}
|
|
1089
1602
|
static create(name, runHandler) {
|
|
1090
1603
|
const scenarioName = requireNonEmpty(name, "Scenario name must be provided.");
|
|
@@ -1102,57 +1615,105 @@ class LoadStrikeScenario {
|
|
|
1102
1615
|
static CreateAsync(name, runHandler) {
|
|
1103
1616
|
return LoadStrikeScenario.createAsync(name, runHandler);
|
|
1104
1617
|
}
|
|
1618
|
+
/**
|
|
1619
|
+
* Creates a placeholder scenario that returns the default success reply.
|
|
1620
|
+
* Use this when you want a scenario shell before adding setup, cleanup, or more detailed behavior.
|
|
1621
|
+
*/
|
|
1105
1622
|
static empty(name) {
|
|
1106
1623
|
return LoadStrikeScenario.create(name, () => LoadStrikeResponse.ok());
|
|
1107
1624
|
}
|
|
1625
|
+
/**
|
|
1626
|
+
* Creates a placeholder scenario that returns the default success reply.
|
|
1627
|
+
* Use this when you want a scenario shell before adding setup, cleanup, or more detailed behavior.
|
|
1628
|
+
*/
|
|
1108
1629
|
static Empty(name) {
|
|
1109
1630
|
return LoadStrikeScenario.empty(name);
|
|
1110
1631
|
}
|
|
1111
1632
|
get Name() {
|
|
1112
1633
|
return this.name;
|
|
1113
1634
|
}
|
|
1635
|
+
/**
|
|
1636
|
+
* Configures init for this SDK object.
|
|
1637
|
+
* Use this when init should be set explicitly before the run starts.
|
|
1638
|
+
*/
|
|
1114
1639
|
withInit(handler) {
|
|
1115
1640
|
if (typeof handler !== "function") {
|
|
1116
1641
|
throw new TypeError("Init handler must be provided.");
|
|
1117
1642
|
}
|
|
1118
|
-
return new LoadStrikeScenario(this.name, this.runHandler, handler, this.cleanHandler, this.loadSimulations, this.thresholds, this.trackingConfiguration, this.maxFailCount, this.withoutWarmUpValue, this.warmUpDurationSeconds, this.weight, this.restartIterationOnFail);
|
|
1643
|
+
return new LoadStrikeScenario(this.name, this.runHandler, handler, this.cleanHandler, this.loadSimulations, this.thresholds, this.trackingConfiguration, this.maxFailCount, this.withoutWarmUpValue, this.warmUpDurationSeconds, this.weight, this.restartIterationOnFail, this.internalLicenseFeatures);
|
|
1119
1644
|
}
|
|
1645
|
+
/**
|
|
1646
|
+
* Configures init async for this SDK object.
|
|
1647
|
+
* Use this when init async should be set explicitly before the run starts.
|
|
1648
|
+
*/
|
|
1120
1649
|
withInitAsync(handler) {
|
|
1121
1650
|
return this.withInit(handler);
|
|
1122
1651
|
}
|
|
1652
|
+
/**
|
|
1653
|
+
* Configures clean for this SDK object.
|
|
1654
|
+
* Use this when clean should be set explicitly before the run starts.
|
|
1655
|
+
*/
|
|
1123
1656
|
withClean(handler) {
|
|
1124
1657
|
if (typeof handler !== "function") {
|
|
1125
1658
|
throw new TypeError("Clean handler must be provided.");
|
|
1126
1659
|
}
|
|
1127
|
-
return new LoadStrikeScenario(this.name, this.runHandler, this.initHandler, handler, this.loadSimulations, this.thresholds, this.trackingConfiguration, this.maxFailCount, this.withoutWarmUpValue, this.warmUpDurationSeconds, this.weight, this.restartIterationOnFail);
|
|
1660
|
+
return new LoadStrikeScenario(this.name, this.runHandler, this.initHandler, handler, this.loadSimulations, this.thresholds, this.trackingConfiguration, this.maxFailCount, this.withoutWarmUpValue, this.warmUpDurationSeconds, this.weight, this.restartIterationOnFail, this.internalLicenseFeatures);
|
|
1128
1661
|
}
|
|
1662
|
+
/**
|
|
1663
|
+
* Configures clean async for this SDK object.
|
|
1664
|
+
* Use this when clean async should be set explicitly before the run starts.
|
|
1665
|
+
*/
|
|
1129
1666
|
withCleanAsync(handler) {
|
|
1130
1667
|
return this.withClean(handler);
|
|
1131
1668
|
}
|
|
1669
|
+
/**
|
|
1670
|
+
* Configures max fail count for this SDK object.
|
|
1671
|
+
* Use this when max fail count should be set explicitly before the run starts.
|
|
1672
|
+
*/
|
|
1132
1673
|
withMaxFailCount(maxFailCount) {
|
|
1133
1674
|
if (!Number.isFinite(maxFailCount)) {
|
|
1134
1675
|
throw new RangeError("maxFailCount should be a finite number.");
|
|
1135
1676
|
}
|
|
1136
|
-
return new LoadStrikeScenario(this.name, this.runHandler, this.initHandler, this.cleanHandler, this.loadSimulations, this.thresholds, this.trackingConfiguration, Math.trunc(maxFailCount), this.withoutWarmUpValue, this.warmUpDurationSeconds, this.weight, this.restartIterationOnFail);
|
|
1677
|
+
return new LoadStrikeScenario(this.name, this.runHandler, this.initHandler, this.cleanHandler, this.loadSimulations, this.thresholds, this.trackingConfiguration, Math.trunc(maxFailCount), this.withoutWarmUpValue, this.warmUpDurationSeconds, this.weight, this.restartIterationOnFail, this.internalLicenseFeatures);
|
|
1137
1678
|
}
|
|
1679
|
+
/**
|
|
1680
|
+
* Configures out warm up for this SDK object.
|
|
1681
|
+
* Use this when out warm up should be set explicitly before the run starts.
|
|
1682
|
+
*/
|
|
1138
1683
|
withoutWarmUp() {
|
|
1139
|
-
return new LoadStrikeScenario(this.name, this.runHandler, this.initHandler, this.cleanHandler, this.loadSimulations, this.thresholds, this.trackingConfiguration, this.maxFailCount, true, this.warmUpDurationSeconds, this.weight, this.restartIterationOnFail);
|
|
1684
|
+
return new LoadStrikeScenario(this.name, this.runHandler, this.initHandler, this.cleanHandler, this.loadSimulations, this.thresholds, this.trackingConfiguration, this.maxFailCount, true, this.warmUpDurationSeconds, this.weight, this.restartIterationOnFail, this.internalLicenseFeatures);
|
|
1140
1685
|
}
|
|
1686
|
+
/**
|
|
1687
|
+
* Configures warm up duration for this SDK object.
|
|
1688
|
+
* Use this when warm up duration should be set explicitly before the run starts.
|
|
1689
|
+
*/
|
|
1141
1690
|
withWarmUpDuration(durationSeconds) {
|
|
1142
1691
|
if (!Number.isFinite(durationSeconds)) {
|
|
1143
1692
|
throw new RangeError("Warmup duration should be a finite number.");
|
|
1144
1693
|
}
|
|
1145
|
-
return new LoadStrikeScenario(this.name, this.runHandler, this.initHandler, this.cleanHandler, this.loadSimulations, this.thresholds, this.trackingConfiguration, this.maxFailCount, this.withoutWarmUpValue, durationSeconds, this.weight, this.restartIterationOnFail);
|
|
1694
|
+
return new LoadStrikeScenario(this.name, this.runHandler, this.initHandler, this.cleanHandler, this.loadSimulations, this.thresholds, this.trackingConfiguration, this.maxFailCount, this.withoutWarmUpValue, durationSeconds, this.weight, this.restartIterationOnFail, this.internalLicenseFeatures);
|
|
1146
1695
|
}
|
|
1696
|
+
/**
|
|
1697
|
+
* Configures weight for this SDK object.
|
|
1698
|
+
* Use this when weight should be set explicitly before the run starts.
|
|
1699
|
+
*/
|
|
1147
1700
|
withWeight(weight) {
|
|
1148
1701
|
if (!Number.isFinite(weight)) {
|
|
1149
1702
|
throw new RangeError("Weight should be a finite number.");
|
|
1150
1703
|
}
|
|
1151
|
-
return new LoadStrikeScenario(this.name, this.runHandler, this.initHandler, this.cleanHandler, this.loadSimulations, this.thresholds, this.trackingConfiguration, this.maxFailCount, this.withoutWarmUpValue, this.warmUpDurationSeconds, Math.trunc(weight), this.restartIterationOnFail);
|
|
1704
|
+
return new LoadStrikeScenario(this.name, this.runHandler, this.initHandler, this.cleanHandler, this.loadSimulations, this.thresholds, this.trackingConfiguration, this.maxFailCount, this.withoutWarmUpValue, this.warmUpDurationSeconds, Math.trunc(weight), this.restartIterationOnFail, this.internalLicenseFeatures);
|
|
1152
1705
|
}
|
|
1706
|
+
/**
|
|
1707
|
+
* Configures restart iteration on fail for this SDK object.
|
|
1708
|
+
* Use this when restart iteration on fail should be set explicitly before the run starts.
|
|
1709
|
+
*/
|
|
1153
1710
|
withRestartIterationOnFail(shouldRestart) {
|
|
1154
|
-
return new LoadStrikeScenario(this.name, this.runHandler, this.initHandler, this.cleanHandler, this.loadSimulations, this.thresholds, this.trackingConfiguration, this.maxFailCount, this.withoutWarmUpValue, this.warmUpDurationSeconds, this.weight, Boolean(shouldRestart));
|
|
1711
|
+
return new LoadStrikeScenario(this.name, this.runHandler, this.initHandler, this.cleanHandler, this.loadSimulations, this.thresholds, this.trackingConfiguration, this.maxFailCount, this.withoutWarmUpValue, this.warmUpDurationSeconds, this.weight, Boolean(shouldRestart), this.internalLicenseFeatures);
|
|
1155
1712
|
}
|
|
1713
|
+
/**
|
|
1714
|
+
* Configures cross platform tracking for this SDK object.
|
|
1715
|
+
* Use this when cross platform tracking should be set explicitly before the run starts.
|
|
1716
|
+
*/
|
|
1156
1717
|
withCrossPlatformTracking(configuration) {
|
|
1157
1718
|
if (!configuration || typeof configuration !== "object" || Array.isArray(configuration)) {
|
|
1158
1719
|
throw new TypeError("Tracking configuration must be provided.");
|
|
@@ -1168,44 +1729,91 @@ class LoadStrikeScenario {
|
|
|
1168
1729
|
? mapRuntimeTrackingEndpointSpec(destinationSpec)
|
|
1169
1730
|
: null;
|
|
1170
1731
|
validateRuntimeTrackingConfiguration(copied, sourceEndpoint, destinationEndpoint);
|
|
1171
|
-
return new LoadStrikeScenario(this.name, this.runHandler, this.initHandler, this.cleanHandler, this.loadSimulations, this.thresholds, copied, this.maxFailCount, this.withoutWarmUpValue, this.warmUpDurationSeconds, this.weight, this.restartIterationOnFail);
|
|
1732
|
+
return new LoadStrikeScenario(this.name, this.runHandler, this.initHandler, this.cleanHandler, this.loadSimulations, this.thresholds, copied, this.maxFailCount, this.withoutWarmUpValue, this.warmUpDurationSeconds, this.weight, this.restartIterationOnFail, this.internalLicenseFeatures);
|
|
1172
1733
|
}
|
|
1734
|
+
/**
|
|
1735
|
+
* Configures load simulations for this SDK object.
|
|
1736
|
+
* Use this when load simulations should be set explicitly before the run starts.
|
|
1737
|
+
*/
|
|
1173
1738
|
withLoadSimulations(...simulations) {
|
|
1174
1739
|
if (!simulations.length) {
|
|
1175
1740
|
throw new Error("At least one load simulation should be provided.");
|
|
1176
1741
|
}
|
|
1177
|
-
return new LoadStrikeScenario(this.name, this.runHandler, this.initHandler, this.cleanHandler, simulations.map((simulation) => attachLoadSimulationProjection({ ...simulation })), this.thresholds, this.trackingConfiguration, this.maxFailCount, this.withoutWarmUpValue, this.warmUpDurationSeconds, this.weight, this.restartIterationOnFail);
|
|
1742
|
+
return new LoadStrikeScenario(this.name, this.runHandler, this.initHandler, this.cleanHandler, simulations.map((simulation) => attachLoadSimulationProjection({ ...simulation })), this.thresholds, this.trackingConfiguration, this.maxFailCount, this.withoutWarmUpValue, this.warmUpDurationSeconds, this.weight, this.restartIterationOnFail, this.internalLicenseFeatures);
|
|
1178
1743
|
}
|
|
1744
|
+
/**
|
|
1745
|
+
* Configures thresholds for this SDK object.
|
|
1746
|
+
* Use this when thresholds should be set explicitly before the run starts.
|
|
1747
|
+
*/
|
|
1179
1748
|
withThresholds(...thresholds) {
|
|
1180
1749
|
if (!thresholds.length) {
|
|
1181
1750
|
throw new Error("At least one threshold should be provided.");
|
|
1182
1751
|
}
|
|
1183
|
-
return new LoadStrikeScenario(this.name, this.runHandler, this.initHandler, this.cleanHandler, this.loadSimulations, thresholds.map((threshold) => ({ ...threshold })), this.trackingConfiguration, this.maxFailCount, this.withoutWarmUpValue, this.warmUpDurationSeconds, this.weight, this.restartIterationOnFail);
|
|
1752
|
+
return new LoadStrikeScenario(this.name, this.runHandler, this.initHandler, this.cleanHandler, this.loadSimulations, thresholds.map((threshold) => ({ ...threshold })), this.trackingConfiguration, this.maxFailCount, this.withoutWarmUpValue, this.warmUpDurationSeconds, this.weight, this.restartIterationOnFail, this.internalLicenseFeatures);
|
|
1184
1753
|
}
|
|
1754
|
+
/**
|
|
1755
|
+
* Returns simulations.
|
|
1756
|
+
* Use this when simulations is required for branching, logging, or assertions.
|
|
1757
|
+
*/
|
|
1185
1758
|
getSimulations() {
|
|
1186
1759
|
return this.loadSimulations.map((simulation) => attachLoadSimulationProjection({ ...simulation }));
|
|
1187
1760
|
}
|
|
1761
|
+
/**
|
|
1762
|
+
* Returns thresholds.
|
|
1763
|
+
* Use this when thresholds is required for branching, logging, or assertions.
|
|
1764
|
+
*/
|
|
1188
1765
|
getThresholds() {
|
|
1189
1766
|
return this.thresholds;
|
|
1190
1767
|
}
|
|
1768
|
+
/**
|
|
1769
|
+
* Returns tracking configuration.
|
|
1770
|
+
* Use this when tracking configuration is required for branching, logging, or assertions.
|
|
1771
|
+
*/
|
|
1191
1772
|
getTrackingConfiguration() {
|
|
1192
1773
|
return this.trackingConfiguration ? { ...this.trackingConfiguration } : undefined;
|
|
1193
1774
|
}
|
|
1775
|
+
/**
|
|
1776
|
+
* Returns max fail count.
|
|
1777
|
+
* Use this when max fail count is required for branching, logging, or assertions.
|
|
1778
|
+
*/
|
|
1194
1779
|
getMaxFailCount() {
|
|
1195
1780
|
return this.maxFailCount;
|
|
1196
1781
|
}
|
|
1782
|
+
/**
|
|
1783
|
+
* Exposes the public isWithoutWarmUp operation.
|
|
1784
|
+
* Use this when the surrounding wrapper type makes this operation the clearest way to express your intent.
|
|
1785
|
+
*/
|
|
1197
1786
|
isWithoutWarmUp() {
|
|
1198
1787
|
return this.withoutWarmUpValue;
|
|
1199
1788
|
}
|
|
1789
|
+
/**
|
|
1790
|
+
* Returns warm up duration seconds.
|
|
1791
|
+
* Use this when warm up duration seconds is required for branching, logging, or assertions.
|
|
1792
|
+
*/
|
|
1200
1793
|
getWarmUpDurationSeconds() {
|
|
1201
1794
|
return this.warmUpDurationSeconds;
|
|
1202
1795
|
}
|
|
1796
|
+
/**
|
|
1797
|
+
* Returns weight.
|
|
1798
|
+
* Use this when weight is required for branching, logging, or assertions.
|
|
1799
|
+
*/
|
|
1203
1800
|
getWeight() {
|
|
1204
1801
|
return this.weight;
|
|
1205
1802
|
}
|
|
1803
|
+
/**
|
|
1804
|
+
* Exposes the public shouldRestartIterationOnFail operation.
|
|
1805
|
+
* Use this when the surrounding wrapper type makes this operation the clearest way to express your intent.
|
|
1806
|
+
*/
|
|
1206
1807
|
shouldRestartIterationOnFail() {
|
|
1207
1808
|
return this.restartIterationOnFail;
|
|
1208
1809
|
}
|
|
1810
|
+
__loadStrikeInternalLicenseFeatures() {
|
|
1811
|
+
return [...this.internalLicenseFeatures];
|
|
1812
|
+
}
|
|
1813
|
+
__loadStrikeWithInternalLicenseFeatures(...features) {
|
|
1814
|
+
const merged = Array.from(new Set([...this.internalLicenseFeatures, ...normalizeStringArray(features)]));
|
|
1815
|
+
return new LoadStrikeScenario(this.name, this.runHandler, this.initHandler, this.cleanHandler, this.loadSimulations, this.thresholds, this.trackingConfiguration, this.maxFailCount, this.withoutWarmUpValue, this.warmUpDurationSeconds, this.weight, this.restartIterationOnFail, merged);
|
|
1816
|
+
}
|
|
1209
1817
|
async invokeInit(context) {
|
|
1210
1818
|
if (this.initHandler) {
|
|
1211
1819
|
await this.initHandler(context);
|
|
@@ -1228,39 +1836,87 @@ class LoadStrikeScenario {
|
|
|
1228
1836
|
return LoadStrikeResponse.fail("exception", resolveRuntimeErrorMessage(error, "scenario failed"), 0);
|
|
1229
1837
|
}
|
|
1230
1838
|
}
|
|
1839
|
+
/**
|
|
1840
|
+
* Configures cross platform tracking for this SDK object.
|
|
1841
|
+
* Use this when cross platform tracking should be set explicitly before the run starts.
|
|
1842
|
+
*/
|
|
1231
1843
|
WithCrossPlatformTracking(configuration) {
|
|
1232
1844
|
return this.withCrossPlatformTracking(configuration);
|
|
1233
1845
|
}
|
|
1846
|
+
/**
|
|
1847
|
+
* Configures init for this SDK object.
|
|
1848
|
+
* Use this when init should be set explicitly before the run starts.
|
|
1849
|
+
*/
|
|
1234
1850
|
WithInit(handler) {
|
|
1235
1851
|
return this.withInit(handler);
|
|
1236
1852
|
}
|
|
1853
|
+
/**
|
|
1854
|
+
* Configures init async for this SDK object.
|
|
1855
|
+
* Use this when init async should be set explicitly before the run starts.
|
|
1856
|
+
*/
|
|
1237
1857
|
WithInitAsync(handler) {
|
|
1238
1858
|
return this.withInitAsync(handler);
|
|
1239
1859
|
}
|
|
1860
|
+
/**
|
|
1861
|
+
* Configures clean for this SDK object.
|
|
1862
|
+
* Use this when clean should be set explicitly before the run starts.
|
|
1863
|
+
*/
|
|
1240
1864
|
WithClean(handler) {
|
|
1241
1865
|
return this.withClean(handler);
|
|
1242
1866
|
}
|
|
1867
|
+
/**
|
|
1868
|
+
* Configures clean async for this SDK object.
|
|
1869
|
+
* Use this when clean async should be set explicitly before the run starts.
|
|
1870
|
+
*/
|
|
1243
1871
|
WithCleanAsync(handler) {
|
|
1244
1872
|
return this.withCleanAsync(handler);
|
|
1245
1873
|
}
|
|
1874
|
+
/**
|
|
1875
|
+
* Configures load simulations for this SDK object.
|
|
1876
|
+
* Use this when load simulations should be set explicitly before the run starts.
|
|
1877
|
+
*/
|
|
1246
1878
|
WithLoadSimulations(...simulations) {
|
|
1247
1879
|
return this.withLoadSimulations(...simulations);
|
|
1248
1880
|
}
|
|
1881
|
+
/**
|
|
1882
|
+
* Configures max fail count for this SDK object.
|
|
1883
|
+
* Use this when max fail count should be set explicitly before the run starts.
|
|
1884
|
+
*/
|
|
1249
1885
|
WithMaxFailCount(maxFailCount) {
|
|
1250
1886
|
return this.withMaxFailCount(maxFailCount);
|
|
1251
1887
|
}
|
|
1888
|
+
/**
|
|
1889
|
+
* Configures out warm up for this SDK object.
|
|
1890
|
+
* Use this when out warm up should be set explicitly before the run starts.
|
|
1891
|
+
*/
|
|
1252
1892
|
WithoutWarmUp() {
|
|
1253
1893
|
return this.withoutWarmUp();
|
|
1254
1894
|
}
|
|
1895
|
+
/**
|
|
1896
|
+
* Configures restart iteration on fail for this SDK object.
|
|
1897
|
+
* Use this when restart iteration on fail should be set explicitly before the run starts.
|
|
1898
|
+
*/
|
|
1255
1899
|
WithRestartIterationOnFail(shouldRestart) {
|
|
1256
1900
|
return this.withRestartIterationOnFail(shouldRestart);
|
|
1257
1901
|
}
|
|
1902
|
+
/**
|
|
1903
|
+
* Configures thresholds for this SDK object.
|
|
1904
|
+
* Use this when thresholds should be set explicitly before the run starts.
|
|
1905
|
+
*/
|
|
1258
1906
|
WithThresholds(...thresholds) {
|
|
1259
1907
|
return this.withThresholds(...thresholds);
|
|
1260
1908
|
}
|
|
1909
|
+
/**
|
|
1910
|
+
* Configures warm up duration for this SDK object.
|
|
1911
|
+
* Use this when warm up duration should be set explicitly before the run starts.
|
|
1912
|
+
*/
|
|
1261
1913
|
WithWarmUpDuration(durationSeconds) {
|
|
1262
1914
|
return this.withWarmUpDuration(durationSeconds);
|
|
1263
1915
|
}
|
|
1916
|
+
/**
|
|
1917
|
+
* Configures weight for this SDK object.
|
|
1918
|
+
* Use this when weight should be set explicitly before the run starts.
|
|
1919
|
+
*/
|
|
1264
1920
|
WithWeight(weight) {
|
|
1265
1921
|
return this.withWeight(weight);
|
|
1266
1922
|
}
|
|
@@ -1272,115 +1928,251 @@ class LoadStrikeRunner {
|
|
|
1272
1928
|
this.options = normalizeRunnerOptionCollectionShapes(options);
|
|
1273
1929
|
this.contextConfigurators = [...contextConfigurators];
|
|
1274
1930
|
}
|
|
1931
|
+
/**
|
|
1932
|
+
* Creates a new instance of this public SDK type.
|
|
1933
|
+
* Use this when you are starting a run definition from scratch.
|
|
1934
|
+
*/
|
|
1275
1935
|
static create() {
|
|
1276
1936
|
return new LoadStrikeRunner([], {});
|
|
1277
1937
|
}
|
|
1938
|
+
/**
|
|
1939
|
+
* Creates a new instance of this public SDK type.
|
|
1940
|
+
* Use this when you are starting a run definition from scratch.
|
|
1941
|
+
*/
|
|
1278
1942
|
static Create() {
|
|
1279
1943
|
return LoadStrikeRunner.create();
|
|
1280
1944
|
}
|
|
1945
|
+
/**
|
|
1946
|
+
* Registers one or more scenarios on a fresh runnable context.
|
|
1947
|
+
* Use this when you want a context immediately without composing a runner first.
|
|
1948
|
+
*/
|
|
1281
1949
|
static registerScenarios(...scenarios) {
|
|
1282
1950
|
validateRegisteredScenarios(scenarios);
|
|
1283
1951
|
return new LoadStrikeContext({}, scenarios);
|
|
1284
1952
|
}
|
|
1953
|
+
/**
|
|
1954
|
+
* Registers one or more scenarios on a fresh runnable context.
|
|
1955
|
+
* Use this when you want a context immediately without composing a runner first.
|
|
1956
|
+
*/
|
|
1285
1957
|
static RegisterScenarios(...scenarios) {
|
|
1286
1958
|
return LoadStrikeRunner.registerScenarios(...scenarios);
|
|
1287
1959
|
}
|
|
1960
|
+
/**
|
|
1961
|
+
* Toggles realtime console metric output.
|
|
1962
|
+
* Use this when a local run or CI log should stream live throughput and latency updates.
|
|
1963
|
+
*/
|
|
1288
1964
|
static DisplayConsoleMetrics(context, enable) {
|
|
1289
1965
|
return context.DisplayConsoleMetrics(enable);
|
|
1290
1966
|
}
|
|
1967
|
+
/**
|
|
1968
|
+
* Toggles local development cluster mode.
|
|
1969
|
+
* Use this when you want to simulate coordinator and agent behavior on a single machine.
|
|
1970
|
+
*/
|
|
1291
1971
|
static EnableLocalDevCluster(context, enable) {
|
|
1292
1972
|
return context.EnableLocalDevCluster(enable);
|
|
1293
1973
|
}
|
|
1974
|
+
/**
|
|
1975
|
+
* Loads run settings from a JSON config file.
|
|
1976
|
+
* Use this when configuration should come from a checked-in or generated config document.
|
|
1977
|
+
*/
|
|
1294
1978
|
static LoadConfig(context, path) {
|
|
1295
1979
|
return context.LoadConfig(path);
|
|
1296
1980
|
}
|
|
1981
|
+
/**
|
|
1982
|
+
* Loads infrastructure settings for sinks, plugins, or transport dependencies.
|
|
1983
|
+
* Use this when runtime integrations depend on external connection details.
|
|
1984
|
+
*/
|
|
1297
1985
|
static LoadInfraConfig(context, path) {
|
|
1298
1986
|
return context.LoadInfraConfig(path);
|
|
1299
1987
|
}
|
|
1988
|
+
/**
|
|
1989
|
+
* Executes the configured workload through the SDK runtime.
|
|
1990
|
+
* Use this when configuration is complete and you are ready to start the run.
|
|
1991
|
+
*/
|
|
1300
1992
|
static Run(context, ...args) {
|
|
1301
1993
|
return context.Run(args);
|
|
1302
1994
|
}
|
|
1995
|
+
/**
|
|
1996
|
+
* Sets the agent group for this node or run.
|
|
1997
|
+
* Use this when only a subset of agents should pick up a particular workload.
|
|
1998
|
+
*/
|
|
1303
1999
|
static WithAgentGroup(context, agentGroup) {
|
|
1304
2000
|
return context.WithAgentGroup(agentGroup);
|
|
1305
2001
|
}
|
|
2002
|
+
/**
|
|
2003
|
+
* Sets the requested agent count.
|
|
2004
|
+
* Use this when a coordinator should fan work out across a specific number of agents.
|
|
2005
|
+
*/
|
|
1306
2006
|
static WithAgentsCount(context, agentsCount) {
|
|
1307
2007
|
return context.WithAgentsCount(agentsCount);
|
|
1308
2008
|
}
|
|
2009
|
+
/**
|
|
2010
|
+
* Targets scenarios for agent nodes only.
|
|
2011
|
+
* Use this when agents should execute only a subset of the registered scenarios.
|
|
2012
|
+
*/
|
|
1309
2013
|
static WithAgentTargetScenarios(context, ...scenarioNames) {
|
|
1310
2014
|
return context.WithAgentTargetScenarios(...scenarioNames);
|
|
1311
2015
|
}
|
|
2016
|
+
/**
|
|
2017
|
+
* Sets the cluster identifier for this run.
|
|
2018
|
+
* Use this when multiple cluster nodes must join the same distributed execution.
|
|
2019
|
+
*/
|
|
1312
2020
|
static WithClusterId(context, clusterId) {
|
|
1313
2021
|
return context.WithClusterId(clusterId);
|
|
1314
2022
|
}
|
|
2023
|
+
/**
|
|
2024
|
+
* Targets scenarios for the coordinator only.
|
|
2025
|
+
* Use this when orchestration or control-node work should run on the coordinator itself.
|
|
2026
|
+
*/
|
|
1315
2027
|
static WithCoordinatorTargetScenarios(context, ...scenarioNames) {
|
|
1316
2028
|
return context.WithCoordinatorTargetScenarios(...scenarioNames);
|
|
1317
2029
|
}
|
|
2030
|
+
/**
|
|
2031
|
+
* Sets the runner key used for licensing validation.
|
|
2032
|
+
* Use this when the run must authenticate against the licensing API before it starts.
|
|
2033
|
+
*/
|
|
1318
2034
|
static WithRunnerKey(context, runnerKey) {
|
|
1319
2035
|
return context.WithRunnerKey(runnerKey);
|
|
1320
2036
|
}
|
|
2037
|
+
/**
|
|
2038
|
+
* Sets how long the SDK waits for licensing validation to complete.
|
|
2039
|
+
* Use this when control-plane latency or private networking requires a longer validation window.
|
|
2040
|
+
*/
|
|
1321
2041
|
static WithLicenseValidationTimeout(context, timeoutSeconds) {
|
|
1322
2042
|
return context.WithLicenseValidationTimeout(timeoutSeconds);
|
|
1323
2043
|
}
|
|
2044
|
+
/**
|
|
2045
|
+
* Supplies a custom logger configuration factory.
|
|
2046
|
+
* Use this when the default runtime logging output is not enough for your environment.
|
|
2047
|
+
*/
|
|
1324
2048
|
static WithLoggerConfig(context, loggerConfig) {
|
|
1325
2049
|
return context.WithLoggerConfig(loggerConfig);
|
|
1326
2050
|
}
|
|
2051
|
+
/**
|
|
2052
|
+
* Sets the minimum runtime log level.
|
|
2053
|
+
* Use this when the run should emit less or more operational detail.
|
|
2054
|
+
*/
|
|
1327
2055
|
static WithMinimumLogLevel(context, minimumLogLevel) {
|
|
1328
2056
|
return context.WithMinimumLogLevel(minimumLogLevel);
|
|
1329
2057
|
}
|
|
2058
|
+
/**
|
|
2059
|
+
* Sets the NATS server URL used for distributed cluster coordination.
|
|
2060
|
+
* Use this when coordinator and agent nodes communicate over NATS.
|
|
2061
|
+
*/
|
|
1330
2062
|
static WithNatsServerUrl(context, natsUrl) {
|
|
1331
2063
|
return context.WithNatsServerUrl(natsUrl);
|
|
1332
2064
|
}
|
|
1333
2065
|
static WithNodeType(context, nodeType) {
|
|
1334
2066
|
return context.WithNodeType(nodeType);
|
|
1335
2067
|
}
|
|
2068
|
+
/**
|
|
2069
|
+
* Disables local report generation.
|
|
2070
|
+
* Use this when reports are unnecessary or should be handled exclusively by sinks.
|
|
2071
|
+
*/
|
|
1336
2072
|
static WithoutReports(context) {
|
|
1337
2073
|
return context.WithoutReports();
|
|
1338
2074
|
}
|
|
2075
|
+
/**
|
|
2076
|
+
* Sets the base file name for generated reports.
|
|
2077
|
+
* Use this when exported reports should use a predictable naming convention.
|
|
2078
|
+
*/
|
|
1339
2079
|
static WithReportFileName(context, reportFileName) {
|
|
1340
2080
|
return context.WithReportFileName(reportFileName);
|
|
1341
2081
|
}
|
|
2082
|
+
/**
|
|
2083
|
+
* Sets the output folder for generated reports.
|
|
2084
|
+
* Use this when report files should land in a specific directory.
|
|
2085
|
+
*/
|
|
1342
2086
|
static WithReportFolder(context, reportFolderPath) {
|
|
1343
2087
|
return context.WithReportFolder(reportFolderPath);
|
|
1344
2088
|
}
|
|
1345
2089
|
static WithReportFormats(context, ...reportFormats) {
|
|
1346
2090
|
return context.WithReportFormats(...reportFormats);
|
|
1347
2091
|
}
|
|
2092
|
+
/**
|
|
2093
|
+
* Sets the realtime reporting cadence.
|
|
2094
|
+
* Use this when sinks or dashboards should receive updates at a controlled interval.
|
|
2095
|
+
*/
|
|
1348
2096
|
static WithReportingInterval(context, intervalSeconds) {
|
|
1349
2097
|
return context.WithReportingInterval(intervalSeconds);
|
|
1350
2098
|
}
|
|
2099
|
+
/**
|
|
2100
|
+
* Registers one or more reporting sinks.
|
|
2101
|
+
* Use this when run results must be pushed to external observability or storage systems.
|
|
2102
|
+
*/
|
|
1351
2103
|
static WithReportingSinks(context, ...sinks) {
|
|
1352
2104
|
return context.WithReportingSinks(...sinks);
|
|
1353
2105
|
}
|
|
2106
|
+
/**
|
|
2107
|
+
* Registers runtime policies for the run.
|
|
2108
|
+
* Use this when scenario selection or step execution should obey policy callbacks.
|
|
2109
|
+
*/
|
|
1354
2110
|
static WithRuntimePolicies(context, ...policies) {
|
|
1355
2111
|
return context.WithRuntimePolicies(...policies);
|
|
1356
2112
|
}
|
|
1357
2113
|
static WithRuntimePolicyErrorMode(context, mode) {
|
|
1358
2114
|
return context.WithRuntimePolicyErrorMode(mode);
|
|
1359
2115
|
}
|
|
2116
|
+
/**
|
|
2117
|
+
* Sets the timeout for scenario completion.
|
|
2118
|
+
* Use this when long-running scenarios need an explicit completion window.
|
|
2119
|
+
*/
|
|
1360
2120
|
static WithScenarioCompletionTimeout(context, timeoutSeconds) {
|
|
1361
2121
|
return context.WithScenarioCompletionTimeout(timeoutSeconds);
|
|
1362
2122
|
}
|
|
2123
|
+
/**
|
|
2124
|
+
* Sets the timeout for cluster command round-trips.
|
|
2125
|
+
* Use this when distributed control messages need a tighter or looser deadline.
|
|
2126
|
+
*/
|
|
1363
2127
|
static WithClusterCommandTimeout(context, timeoutSeconds) {
|
|
1364
2128
|
return context.WithClusterCommandTimeout(timeoutSeconds);
|
|
1365
2129
|
}
|
|
2130
|
+
/**
|
|
2131
|
+
* Sets the retry limit for restartable failed iterations.
|
|
2132
|
+
* Use this when transient failures should be retried a fixed number of times.
|
|
2133
|
+
*/
|
|
1366
2134
|
static WithRestartIterationMaxAttempts(context, attempts) {
|
|
1367
2135
|
return context.WithRestartIterationMaxAttempts(attempts);
|
|
1368
2136
|
}
|
|
2137
|
+
/**
|
|
2138
|
+
* Sets the session identifier for this run.
|
|
2139
|
+
* Use this when downstream logs, reports, or external systems need a stable session id.
|
|
2140
|
+
*/
|
|
1369
2141
|
static WithSessionId(context, sessionId) {
|
|
1370
2142
|
return context.WithSessionId(sessionId);
|
|
1371
2143
|
}
|
|
2144
|
+
/**
|
|
2145
|
+
* Targets a shared set of scenarios.
|
|
2146
|
+
* Use this when only selected scenarios should execute for the current node or run.
|
|
2147
|
+
*/
|
|
1372
2148
|
static WithTargetScenarios(context, ...scenarioNames) {
|
|
1373
2149
|
return context.WithTargetScenarios(...scenarioNames);
|
|
1374
2150
|
}
|
|
2151
|
+
/**
|
|
2152
|
+
* Sets the test name label for the run.
|
|
2153
|
+
* Use this when reports and logs should expose a human-readable test identifier.
|
|
2154
|
+
*/
|
|
1375
2155
|
static WithTestName(context, testName) {
|
|
1376
2156
|
return context.WithTestName(testName);
|
|
1377
2157
|
}
|
|
2158
|
+
/**
|
|
2159
|
+
* Sets the test suite label for the run.
|
|
2160
|
+
* Use this when related tests should be grouped under a suite name.
|
|
2161
|
+
*/
|
|
1378
2162
|
static WithTestSuite(context, testSuite) {
|
|
1379
2163
|
return context.WithTestSuite(testSuite);
|
|
1380
2164
|
}
|
|
2165
|
+
/**
|
|
2166
|
+
* Registers worker plugins for the run.
|
|
2167
|
+
* Use this when custom plugin data should be collected alongside run results.
|
|
2168
|
+
*/
|
|
1381
2169
|
static WithWorkerPlugins(context, ...plugins) {
|
|
1382
2170
|
return context.WithWorkerPlugins(...plugins);
|
|
1383
2171
|
}
|
|
2172
|
+
/**
|
|
2173
|
+
* Adds a scenario to the current runner.
|
|
2174
|
+
* Use this when the run should include one more scenario definition.
|
|
2175
|
+
*/
|
|
1384
2176
|
addScenario(scenario) {
|
|
1385
2177
|
if (!(scenario instanceof LoadStrikeScenario)) {
|
|
1386
2178
|
throw new TypeError("Scenario must be provided.");
|
|
@@ -1388,9 +2180,17 @@ class LoadStrikeRunner {
|
|
|
1388
2180
|
this.scenarios = [...this.scenarios, scenario];
|
|
1389
2181
|
return this;
|
|
1390
2182
|
}
|
|
2183
|
+
/**
|
|
2184
|
+
* Adds a scenario to the current runner.
|
|
2185
|
+
* Use this when the run should include one more scenario definition.
|
|
2186
|
+
*/
|
|
1391
2187
|
AddScenario(scenario) {
|
|
1392
2188
|
return this.addScenario(scenario);
|
|
1393
2189
|
}
|
|
2190
|
+
/**
|
|
2191
|
+
* Adds multiple scenarios to the current runner.
|
|
2192
|
+
* Use this when the run should execute a batch of scenario definitions together.
|
|
2193
|
+
*/
|
|
1394
2194
|
addScenarios(...scenarios) {
|
|
1395
2195
|
if (!scenarios.length) {
|
|
1396
2196
|
throw new Error("At least one scenario must be provided.");
|
|
@@ -1401,9 +2201,17 @@ class LoadStrikeRunner {
|
|
|
1401
2201
|
this.scenarios = [...this.scenarios, ...scenarios];
|
|
1402
2202
|
return this;
|
|
1403
2203
|
}
|
|
2204
|
+
/**
|
|
2205
|
+
* Adds multiple scenarios to the current runner.
|
|
2206
|
+
* Use this when the run should execute a batch of scenario definitions together.
|
|
2207
|
+
*/
|
|
1404
2208
|
AddScenarios(...scenarios) {
|
|
1405
2209
|
return this.addScenarios(...scenarios);
|
|
1406
2210
|
}
|
|
2211
|
+
/**
|
|
2212
|
+
* Applies a grouped configuration change to the current builder or context.
|
|
2213
|
+
* Use this when several related settings should be supplied in one step.
|
|
2214
|
+
*/
|
|
1407
2215
|
configure(options) {
|
|
1408
2216
|
if (!options || typeof options !== "object" || Array.isArray(options)) {
|
|
1409
2217
|
throw new TypeError("Configure options must be a non-null object.");
|
|
@@ -1430,6 +2238,10 @@ class LoadStrikeRunner {
|
|
|
1430
2238
|
}
|
|
1431
2239
|
return this.configure(input);
|
|
1432
2240
|
}
|
|
2241
|
+
/**
|
|
2242
|
+
* Copies settings from an existing context snapshot.
|
|
2243
|
+
* Use this when a runner should inherit configuration that was already assembled elsewhere.
|
|
2244
|
+
*/
|
|
1433
2245
|
configureContext(context) {
|
|
1434
2246
|
if (!context || typeof context !== "object" || Array.isArray(context)) {
|
|
1435
2247
|
throw new TypeError("Configure context must be a LoadStrikeContext or run context object.");
|
|
@@ -1439,66 +2251,138 @@ class LoadStrikeRunner {
|
|
|
1439
2251
|
: new LoadStrikeContext(context);
|
|
1440
2252
|
return this.configure(runtimeContext.toRunnerOptions());
|
|
1441
2253
|
}
|
|
2254
|
+
/**
|
|
2255
|
+
* Copies settings from an existing context snapshot.
|
|
2256
|
+
* Use this when a runner should inherit configuration that was already assembled elsewhere.
|
|
2257
|
+
*/
|
|
1442
2258
|
ConfigureContext(context) {
|
|
1443
2259
|
return this.configureContext(context);
|
|
1444
2260
|
}
|
|
2261
|
+
/**
|
|
2262
|
+
* Sets the test suite label for the run.
|
|
2263
|
+
* Use this when related tests should be grouped under a suite name.
|
|
2264
|
+
*/
|
|
1445
2265
|
withTestSuite(testSuite) {
|
|
1446
2266
|
return this.configure({ testSuite: requireNonEmpty(testSuite, "Test suite must be provided.") });
|
|
1447
2267
|
}
|
|
2268
|
+
/**
|
|
2269
|
+
* Sets the test suite label for the run.
|
|
2270
|
+
* Use this when related tests should be grouped under a suite name.
|
|
2271
|
+
*/
|
|
1448
2272
|
WithTestSuite(testSuite) {
|
|
1449
2273
|
return this.withTestSuite(testSuite);
|
|
1450
2274
|
}
|
|
2275
|
+
/**
|
|
2276
|
+
* Sets the test name label for the run.
|
|
2277
|
+
* Use this when reports and logs should expose a human-readable test identifier.
|
|
2278
|
+
*/
|
|
1451
2279
|
withTestName(testName) {
|
|
1452
2280
|
return this.configure({ testName: requireNonEmpty(testName, "Test name must be provided.") });
|
|
1453
2281
|
}
|
|
2282
|
+
/**
|
|
2283
|
+
* Sets the test name label for the run.
|
|
2284
|
+
* Use this when reports and logs should expose a human-readable test identifier.
|
|
2285
|
+
*/
|
|
1454
2286
|
WithTestName(testName) {
|
|
1455
2287
|
return this.withTestName(testName);
|
|
1456
2288
|
}
|
|
2289
|
+
/**
|
|
2290
|
+
* Sets the session identifier for this run.
|
|
2291
|
+
* Use this when downstream logs, reports, or external systems need a stable session id.
|
|
2292
|
+
*/
|
|
1457
2293
|
withSessionId(sessionId) {
|
|
1458
2294
|
return this.configure({ sessionId: requireNonEmpty(sessionId, "Session id must be provided.") });
|
|
1459
2295
|
}
|
|
2296
|
+
/**
|
|
2297
|
+
* Sets the session identifier for this run.
|
|
2298
|
+
* Use this when downstream logs, reports, or external systems need a stable session id.
|
|
2299
|
+
*/
|
|
1460
2300
|
WithSessionId(sessionId) {
|
|
1461
2301
|
return this.withSessionId(sessionId);
|
|
1462
2302
|
}
|
|
2303
|
+
/**
|
|
2304
|
+
* Sets the output folder for generated reports.
|
|
2305
|
+
* Use this when report files should land in a specific directory.
|
|
2306
|
+
*/
|
|
1463
2307
|
withReportFolder(reportFolderPath) {
|
|
1464
2308
|
return this.configure({ reportFolderPath: requireNonEmpty(reportFolderPath, "Report folder path must be provided.") });
|
|
1465
2309
|
}
|
|
2310
|
+
/**
|
|
2311
|
+
* Sets the output folder for generated reports.
|
|
2312
|
+
* Use this when report files should land in a specific directory.
|
|
2313
|
+
*/
|
|
1466
2314
|
WithReportFolder(reportFolderPath) {
|
|
1467
2315
|
return this.withReportFolder(reportFolderPath);
|
|
1468
2316
|
}
|
|
2317
|
+
/**
|
|
2318
|
+
* Sets the realtime reporting cadence.
|
|
2319
|
+
* Use this when sinks or dashboards should receive updates at a controlled interval.
|
|
2320
|
+
*/
|
|
1469
2321
|
withReportingInterval(intervalSeconds) {
|
|
1470
2322
|
if (!Number.isFinite(intervalSeconds) || intervalSeconds <= 0) {
|
|
1471
2323
|
throw new RangeError("Reporting interval should be greater than zero.");
|
|
1472
2324
|
}
|
|
1473
2325
|
return this.configure({ reportingIntervalSeconds: intervalSeconds });
|
|
1474
2326
|
}
|
|
2327
|
+
/**
|
|
2328
|
+
* Sets the realtime reporting cadence.
|
|
2329
|
+
* Use this when sinks or dashboards should receive updates at a controlled interval.
|
|
2330
|
+
*/
|
|
1475
2331
|
WithReportingInterval(intervalSeconds) {
|
|
1476
2332
|
return this.withReportingInterval(intervalSeconds);
|
|
1477
2333
|
}
|
|
2334
|
+
/**
|
|
2335
|
+
* Sets the timeout for cluster command round-trips.
|
|
2336
|
+
* Use this when distributed control messages need a tighter or looser deadline.
|
|
2337
|
+
*/
|
|
1478
2338
|
withClusterCommandTimeout(timeoutSeconds) {
|
|
1479
2339
|
if (!Number.isFinite(timeoutSeconds) || timeoutSeconds <= 0) {
|
|
1480
2340
|
throw new RangeError("Cluster command timeout should be greater than zero.");
|
|
1481
2341
|
}
|
|
1482
2342
|
return this.configure({ clusterCommandTimeoutSeconds: timeoutSeconds });
|
|
1483
2343
|
}
|
|
2344
|
+
/**
|
|
2345
|
+
* Sets the timeout for cluster command round-trips.
|
|
2346
|
+
* Use this when distributed control messages need a tighter or looser deadline.
|
|
2347
|
+
*/
|
|
1484
2348
|
WithClusterCommandTimeout(timeoutSeconds) {
|
|
1485
2349
|
return this.withClusterCommandTimeout(timeoutSeconds);
|
|
1486
2350
|
}
|
|
2351
|
+
/**
|
|
2352
|
+
* Sets the retry limit for restartable failed iterations.
|
|
2353
|
+
* Use this when transient failures should be retried a fixed number of times.
|
|
2354
|
+
*/
|
|
1487
2355
|
withRestartIterationMaxAttempts(attempts) {
|
|
1488
2356
|
if (!Number.isFinite(attempts) || attempts < 0) {
|
|
1489
2357
|
throw new RangeError("Restart iteration max attempts should be zero or greater.");
|
|
1490
2358
|
}
|
|
1491
2359
|
return this.configure({ restartIterationMaxAttempts: Math.trunc(attempts) });
|
|
1492
2360
|
}
|
|
2361
|
+
/**
|
|
2362
|
+
* Sets the retry limit for restartable failed iterations.
|
|
2363
|
+
* Use this when transient failures should be retried a fixed number of times.
|
|
2364
|
+
*/
|
|
1493
2365
|
WithRestartIterationMaxAttempts(attempts) {
|
|
1494
2366
|
return this.withRestartIterationMaxAttempts(attempts);
|
|
1495
2367
|
}
|
|
2368
|
+
/**
|
|
2369
|
+
* Disables local report generation.
|
|
2370
|
+
* Use this when reports are unnecessary or should be handled exclusively by sinks.
|
|
2371
|
+
*/
|
|
1496
2372
|
withoutReports() {
|
|
1497
2373
|
return this.configure({ reportsEnabled: false });
|
|
1498
2374
|
}
|
|
2375
|
+
/**
|
|
2376
|
+
* Disables local report generation.
|
|
2377
|
+
* Use this when reports are unnecessary or should be handled exclusively by sinks.
|
|
2378
|
+
*/
|
|
1499
2379
|
WithoutReports() {
|
|
1500
2380
|
return this.withoutReports();
|
|
1501
2381
|
}
|
|
2382
|
+
/**
|
|
2383
|
+
* Builds the current configuration into a runnable context.
|
|
2384
|
+
* Use this when you want to inspect or reuse the final run settings before execution.
|
|
2385
|
+
*/
|
|
1502
2386
|
buildContext() {
|
|
1503
2387
|
if (!this.scenarios.length) {
|
|
1504
2388
|
throw new Error("At least one scenario must be added before building the runner context.");
|
|
@@ -1513,6 +2397,10 @@ class LoadStrikeRunner {
|
|
|
1513
2397
|
}
|
|
1514
2398
|
return context;
|
|
1515
2399
|
}
|
|
2400
|
+
/**
|
|
2401
|
+
* Builds the current configuration into a runnable context.
|
|
2402
|
+
* Use this when you want to inspect or reuse the final run settings before execution.
|
|
2403
|
+
*/
|
|
1516
2404
|
BuildContext() {
|
|
1517
2405
|
return this.buildContext();
|
|
1518
2406
|
}
|
|
@@ -1569,14 +2457,17 @@ class LoadStrikeRunner {
|
|
|
1569
2457
|
const selectedScenarios = clusterMode === "local-coordinator" || clusterMode === "nats-coordinator"
|
|
1570
2458
|
? await this.filterScenariosWithPolicies(this.scenarios, policies, policyErrors, runtimePolicyErrorMode)
|
|
1571
2459
|
: await this.selectScenarios(policies, policyErrors, runtimePolicyErrorMode);
|
|
1572
|
-
|
|
2460
|
+
if (clusterMode === "nats-agent") {
|
|
2461
|
+
return this.runAgentWithNats(createdUtc, testInfo, nodeInfo);
|
|
2462
|
+
}
|
|
2463
|
+
licensePayload = buildLicenseValidationPayload({
|
|
2464
|
+
...this.options,
|
|
2465
|
+
sessionId: testInfo.sessionId
|
|
2466
|
+
}, this.scenarios);
|
|
1573
2467
|
licenseClient = new local_js_1.LoadStrikeLocalClient({
|
|
1574
2468
|
licenseValidationTimeoutMs: Math.max((this.options.licenseValidationTimeoutSeconds ?? 10) * 1000, 1)
|
|
1575
2469
|
});
|
|
1576
2470
|
licenseSession = await licenseClient.acquireLicenseLease(licensePayload);
|
|
1577
|
-
if (clusterMode === "nats-agent") {
|
|
1578
|
-
return this.runAgentWithNats(createdUtc, testInfo, nodeInfo);
|
|
1579
|
-
}
|
|
1580
2471
|
const loggerSetup = createLoggerSetup(this.options.loggerConfig, this.options.minimumLogLevel, this.options, testInfo, nodeInfo);
|
|
1581
2472
|
const runLogger = loggerSetup.logger;
|
|
1582
2473
|
const scenarioStartInfos = selectedScenarios.map((scenario, index) => {
|
|
@@ -1666,12 +2557,12 @@ class LoadStrikeRunner {
|
|
|
1666
2557
|
let result;
|
|
1667
2558
|
let metricStats;
|
|
1668
2559
|
if (clusterMode === "local-coordinator") {
|
|
1669
|
-
const aggregated = await this.runCoordinatorWithLocalAgents(selectedScenarios, testInfo, nodeInfo);
|
|
2560
|
+
const aggregated = await this.runCoordinatorWithLocalAgents(selectedScenarios, testInfo, nodeInfo, licenseClient, licenseSession);
|
|
1670
2561
|
metricStats = aggregated.metrics;
|
|
1671
2562
|
result = toDetailedRunResultFromNodeStats(aggregated, started.toISOString(), sinkErrors, policyErrors);
|
|
1672
2563
|
}
|
|
1673
2564
|
else if (clusterMode === "nats-coordinator") {
|
|
1674
|
-
const aggregated = await this.runCoordinatorWithNats(selectedScenarios, testInfo, nodeInfo);
|
|
2565
|
+
const aggregated = await this.runCoordinatorWithNats(selectedScenarios, testInfo, nodeInfo, licenseClient, licenseSession);
|
|
1675
2566
|
metricStats = aggregated.metrics;
|
|
1676
2567
|
result = toDetailedRunResultFromNodeStats(aggregated, started.toISOString(), sinkErrors, policyErrors);
|
|
1677
2568
|
}
|
|
@@ -1818,8 +2709,8 @@ class LoadStrikeRunner {
|
|
|
1818
2709
|
natsServerUrl: undefined,
|
|
1819
2710
|
reportFolderPath: (0, node_path_1.resolve)(this.options.reportFolderPath ?? "./reports", sanitizeReportFileName(machineName)),
|
|
1820
2711
|
targetScenarios,
|
|
1821
|
-
agentTargetScenarios:
|
|
1822
|
-
coordinatorTargetScenarios:
|
|
2712
|
+
agentTargetScenarios: undefined,
|
|
2713
|
+
coordinatorTargetScenarios: undefined,
|
|
1823
2714
|
reportsEnabled: false,
|
|
1824
2715
|
displayConsoleMetrics: false,
|
|
1825
2716
|
reportingSinks: includeWorkerExtensions ? this.options.reportingSinks : [],
|
|
@@ -1837,16 +2728,40 @@ class LoadStrikeRunner {
|
|
|
1837
2728
|
logFiles: [...(childResult.logFiles ?? [])]
|
|
1838
2729
|
};
|
|
1839
2730
|
}
|
|
1840
|
-
async runCoordinatorWithLocalAgents(scenarios, testInfo, nodeInfo) {
|
|
2731
|
+
async runCoordinatorWithLocalAgents(scenarios, testInfo, nodeInfo, licenseClient, licenseSession) {
|
|
2732
|
+
if (!licenseClient) {
|
|
2733
|
+
throw new Error("Coordinator agent execution authorization requires an initialized licensing client.");
|
|
2734
|
+
}
|
|
2735
|
+
const controllerRunToken = stringValueOrDefault(licenseSession?.runToken, "").trim();
|
|
2736
|
+
if (!controllerRunToken) {
|
|
2737
|
+
throw new Error("Coordinator agent execution authorization requires an active controller run token.");
|
|
2738
|
+
}
|
|
1841
2739
|
const assignments = planRuntimeClusterAssignments(scenarios, Math.max(this.options.agentsCount ?? 1, 1), this.options.targetScenarios ?? [], this.options.agentTargetScenarios ?? []);
|
|
1842
|
-
const nodeResults = await Promise.all(assignments.map((targetScenarios, index) =>
|
|
2740
|
+
const nodeResults = await Promise.all(assignments.map(async (targetScenarios, index) => {
|
|
2741
|
+
const commandId = (0, node_crypto_1.randomBytes)(16).toString("hex");
|
|
2742
|
+
const agentExecutionToken = await licenseClient.createAgentExecutionToken(controllerRunToken, testInfo.sessionId, commandId, index, assignments.length, targetScenarios);
|
|
2743
|
+
return this.runClusterChildNode(targetScenarios, "Agent", `local-agent-${index + 1}`, false, {
|
|
2744
|
+
sessionId: testInfo.sessionId,
|
|
2745
|
+
testSuite: testInfo.testSuite,
|
|
2746
|
+
testName: testInfo.testName,
|
|
2747
|
+
agentCommandId: commandId,
|
|
2748
|
+
agentExecutionToken
|
|
2749
|
+
});
|
|
2750
|
+
}));
|
|
1843
2751
|
const coordinatorTargets = [...(this.options.coordinatorTargetScenarios ?? [])];
|
|
1844
2752
|
if (coordinatorTargets.length) {
|
|
1845
2753
|
nodeResults.push(await this.runClusterChildNode(coordinatorTargets, "Coordinator", nodeInfo.machineName, false));
|
|
1846
2754
|
}
|
|
1847
2755
|
return aggregateNodeStats(testInfo, { ...nodeInfo, nodeType: "Coordinator" }, nodeResults);
|
|
1848
2756
|
}
|
|
1849
|
-
async runCoordinatorWithNats(scenarios, testInfo, nodeInfo) {
|
|
2757
|
+
async runCoordinatorWithNats(scenarios, testInfo, nodeInfo, licenseClient, licenseSession) {
|
|
2758
|
+
if (!licenseClient) {
|
|
2759
|
+
throw new Error("Coordinator agent execution authorization requires an initialized licensing client.");
|
|
2760
|
+
}
|
|
2761
|
+
const controllerRunToken = stringValueOrDefault(licenseSession?.runToken, "").trim();
|
|
2762
|
+
if (!controllerRunToken) {
|
|
2763
|
+
throw new Error("Coordinator agent execution authorization requires an active controller run token.");
|
|
2764
|
+
}
|
|
1850
2765
|
const assignments = planRuntimeClusterAssignments(scenarios, Math.max(this.options.agentsCount ?? 1, 1), this.options.targetScenarios ?? [], this.options.agentTargetScenarios ?? []);
|
|
1851
2766
|
const coordinator = new cluster_js_1.DistributedClusterCoordinator({
|
|
1852
2767
|
clusterId: this.options.clusterId ?? "local",
|
|
@@ -1860,7 +2775,7 @@ class LoadStrikeRunner {
|
|
|
1860
2775
|
? { ServerUrl: this.options.natsServerUrl }
|
|
1861
2776
|
: undefined
|
|
1862
2777
|
});
|
|
1863
|
-
const dispatch = await coordinator.dispatch(assignments);
|
|
2778
|
+
const dispatch = await coordinator.dispatch(assignments, (command) => licenseClient.createAgentExecutionToken(controllerRunToken, testInfo.sessionId, command.commandId, command.agentIndex, command.agentCount, command.targetScenarios));
|
|
1864
2779
|
const nodes = dispatch.nodeResults.map((value) => clusterNodeResultToNodeStats(value, testInfo, { ...nodeInfo, nodeType: "Agent" }));
|
|
1865
2780
|
const coordinatorTargets = [...(this.options.coordinatorTargetScenarios ?? [])];
|
|
1866
2781
|
if (coordinatorTargets.length) {
|
|
@@ -1890,7 +2805,9 @@ class LoadStrikeRunner {
|
|
|
1890
2805
|
handledStats = await this.runClusterChildNode(dispatch.scenarioNames, "Agent", nodeInfo.machineName, true, {
|
|
1891
2806
|
sessionId: testInfo.sessionId,
|
|
1892
2807
|
testSuite: testInfo.testSuite,
|
|
1893
|
-
testName: testInfo.testName
|
|
2808
|
+
testName: testInfo.testName,
|
|
2809
|
+
agentCommandId: dispatch.commandId,
|
|
2810
|
+
agentExecutionToken: dispatch.agentRunToken
|
|
1894
2811
|
});
|
|
1895
2812
|
return {
|
|
1896
2813
|
nodeId: handledStats.nodeInfo.machineName,
|
|
@@ -6533,10 +7450,16 @@ function toRunContext(options) {
|
|
|
6533
7450
|
RestartIterationMaxAttempts: normalized.restartIterationMaxAttempts,
|
|
6534
7451
|
WorkerPlugins: normalized.workerPlugins,
|
|
6535
7452
|
CustomSettings: normalized.customSettings,
|
|
6536
|
-
GlobalCustomSettings: normalized.globalCustomSettings
|
|
7453
|
+
GlobalCustomSettings: normalized.globalCustomSettings,
|
|
7454
|
+
AgentExecutionToken: normalized.agentExecutionToken,
|
|
7455
|
+
AgentCommandId: normalized.agentCommandId
|
|
6537
7456
|
};
|
|
6538
7457
|
}
|
|
6539
7458
|
class RuntimePolicyCallbackError extends Error {
|
|
7459
|
+
/**
|
|
7460
|
+
* Exposes the public constructor operation.
|
|
7461
|
+
* Use this when the surrounding wrapper type makes this operation the clearest way to express your intent.
|
|
7462
|
+
*/
|
|
6540
7463
|
constructor(message) {
|
|
6541
7464
|
super(message);
|
|
6542
7465
|
this.name = "RuntimePolicyCallbackError";
|
|
@@ -6560,17 +7483,24 @@ function buildLicenseValidationPayload(options, scenarios) {
|
|
|
6560
7483
|
const context = {
|
|
6561
7484
|
...toRunContext(options)
|
|
6562
7485
|
};
|
|
6563
|
-
const scenarioSpecs = scenarios.map((scenario) =>
|
|
6564
|
-
|
|
6565
|
-
|
|
6566
|
-
|
|
6567
|
-
|
|
6568
|
-
|
|
6569
|
-
|
|
6570
|
-
|
|
6571
|
-
|
|
6572
|
-
|
|
6573
|
-
|
|
7486
|
+
const scenarioSpecs = scenarios.map((scenario) => {
|
|
7487
|
+
const row = {
|
|
7488
|
+
Name: scenario.name,
|
|
7489
|
+
MaxFailCount: scenario.getMaxFailCount(),
|
|
7490
|
+
RestartIterationOnFail: scenario.shouldRestartIterationOnFail(),
|
|
7491
|
+
WithoutWarmUp: scenario.isWithoutWarmUp(),
|
|
7492
|
+
WarmUpDurationSeconds: scenario.getWarmUpDurationSeconds(),
|
|
7493
|
+
Weight: scenario.getWeight(),
|
|
7494
|
+
LoadSimulations: [...scenario.getSimulations()],
|
|
7495
|
+
Thresholds: [...scenario.getThresholds()],
|
|
7496
|
+
Tracking: scenario.getTrackingConfiguration() ?? {}
|
|
7497
|
+
};
|
|
7498
|
+
const internalLicenseFeatures = scenario.__loadStrikeInternalLicenseFeatures();
|
|
7499
|
+
if (internalLicenseFeatures.length > 0) {
|
|
7500
|
+
row.InternalLicenseFeatures = internalLicenseFeatures;
|
|
7501
|
+
}
|
|
7502
|
+
return row;
|
|
7503
|
+
});
|
|
6574
7504
|
return {
|
|
6575
7505
|
Context: context,
|
|
6576
7506
|
Scenarios: scenarioSpecs,
|