@calltelemetry/cli 0.4.5 → 0.4.7
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/dist/commands/diag.d.ts.map +1 -1
- package/dist/commands/diag.js +8 -2
- package/dist/commands/diag.js.map +1 -1
- package/dist/commands/loadtest.d.ts +3 -0
- package/dist/commands/loadtest.d.ts.map +1 -0
- package/dist/commands/loadtest.js +22 -0
- package/dist/commands/loadtest.js.map +1 -0
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/curri-xml.d.ts +21 -0
- package/dist/lib/curri-xml.d.ts.map +1 -0
- package/dist/lib/curri-xml.js +53 -0
- package/dist/lib/curri-xml.js.map +1 -0
- package/dist/lib/loadtest-stats.d.ts +91 -0
- package/dist/lib/loadtest-stats.d.ts.map +1 -0
- package/dist/lib/loadtest-stats.js +23 -0
- package/dist/lib/loadtest-stats.js.map +1 -0
- package/dist/lib/loadtest.d.ts +14 -0
- package/dist/lib/loadtest.d.ts.map +1 -0
- package/dist/lib/loadtest.js +112 -0
- package/dist/lib/loadtest.js.map +1 -0
- package/dist/lib/rpc-scripts.d.ts +6 -0
- package/dist/lib/rpc-scripts.d.ts.map +1 -1
- package/dist/lib/rpc-scripts.js +139 -0
- package/dist/lib/rpc-scripts.js.map +1 -1
- package/dist/lib/rpc.d.ts +2 -0
- package/dist/lib/rpc.d.ts.map +1 -1
- package/dist/lib/rpc.js +17 -6
- package/dist/lib/rpc.js.map +1 -1
- package/dist/lib/showtech-steps.d.ts +1 -1
- package/dist/lib/showtech-steps.d.ts.map +1 -1
- package/dist/lib/showtech-steps.js +54 -3
- package/dist/lib/showtech-steps.js.map +1 -1
- package/dist/ui/components/Sparkline.d.ts +15 -0
- package/dist/ui/components/Sparkline.d.ts.map +1 -0
- package/dist/ui/components/Sparkline.js +21 -0
- package/dist/ui/components/Sparkline.js.map +1 -0
- package/dist/ui/components/index.d.ts +1 -0
- package/dist/ui/components/index.d.ts.map +1 -1
- package/dist/ui/components/index.js +1 -0
- package/dist/ui/components/index.js.map +1 -1
- package/dist/ui/hooks/index.d.ts +2 -0
- package/dist/ui/hooks/index.d.ts.map +1 -1
- package/dist/ui/hooks/index.js +1 -0
- package/dist/ui/hooks/index.js.map +1 -1
- package/dist/ui/hooks/useLoadTest.d.ts +11 -0
- package/dist/ui/hooks/useLoadTest.d.ts.map +1 -0
- package/dist/ui/hooks/useLoadTest.js +38 -0
- package/dist/ui/hooks/useLoadTest.js.map +1 -0
- package/dist/ui/views/DiagShowTechView.d.ts +3 -1
- package/dist/ui/views/DiagShowTechView.d.ts.map +1 -1
- package/dist/ui/views/DiagShowTechView.js +30 -9
- package/dist/ui/views/DiagShowTechView.js.map +1 -1
- package/dist/ui/views/LoadTestConfigView.d.ts +31 -0
- package/dist/ui/views/LoadTestConfigView.d.ts.map +1 -0
- package/dist/ui/views/LoadTestConfigView.js +111 -0
- package/dist/ui/views/LoadTestConfigView.js.map +1 -0
- package/dist/ui/views/LoadTestRunView.d.ts +10 -0
- package/dist/ui/views/LoadTestRunView.d.ts.map +1 -0
- package/dist/ui/views/LoadTestRunView.js +71 -0
- package/dist/ui/views/LoadTestRunView.js.map +1 -0
- package/dist/ui/views/LoadTestSummaryView.d.ts +9 -0
- package/dist/ui/views/LoadTestSummaryView.d.ts.map +1 -0
- package/dist/ui/views/LoadTestSummaryView.js +72 -0
- package/dist/ui/views/LoadTestSummaryView.js.map +1 -0
- package/dist/ui/views/LoadTestView.d.ts +8 -0
- package/dist/ui/views/LoadTestView.d.ts.map +1 -0
- package/dist/ui/views/LoadTestView.js +43 -0
- package/dist/ui/views/LoadTestView.js.map +1 -0
- package/dist/ui/views/MainMenu.d.ts.map +1 -1
- package/dist/ui/views/MainMenu.js +84 -22
- package/dist/ui/views/MainMenu.js.map +1 -1
- package/dist/ui/views/StatusView.d.ts.map +1 -1
- package/dist/ui/views/StatusView.js +177 -28
- package/dist/ui/views/StatusView.js.map +1 -1
- package/package.json +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diag.d.ts","sourceRoot":"","sources":["../../src/commands/diag.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"diag.d.ts","sourceRoot":"","sources":["../../src/commands/diag.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,QA4InD"}
|
package/dist/commands/diag.js
CHANGED
|
@@ -30,8 +30,14 @@ export function registerDiagCommand(program) {
|
|
|
30
30
|
});
|
|
31
31
|
diag.command('showtech')
|
|
32
32
|
.description('Collect support bundle (logs, diagnostics, config)')
|
|
33
|
-
.
|
|
34
|
-
|
|
33
|
+
.option('--policy-minutes <minutes>', 'Include policy history for last N minutes (skips prompt)')
|
|
34
|
+
.action(async (opts) => {
|
|
35
|
+
const policyMinutes = opts.policyMinutes ? parseInt(opts.policyMinutes, 10) : undefined;
|
|
36
|
+
const props = {};
|
|
37
|
+
if (policyMinutes !== undefined && !isNaN(policyMinutes)) {
|
|
38
|
+
props.policyMinutes = policyMinutes;
|
|
39
|
+
}
|
|
40
|
+
const { waitUntilExit } = render(React.createElement(DiagShowTechView, props));
|
|
35
41
|
await waitUntilExit();
|
|
36
42
|
});
|
|
37
43
|
diag.command('tesla <mode> <url>')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diag.js","sourceRoot":"","sources":["../../src/commands/diag.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,GAAG,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAEnE,MAAM,UAAU,mBAAmB,CAAC,OAAgB;IAClD,MAAM,IAAI,GAAG,OAAO;SACjB,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,qBAAqB,CAAC,CAAC;IAEtC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;SACpB,WAAW,CAAC,uCAAuC,CAAC;SACpD,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC,CAAC;QACvE,MAAM,aAAa,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IAEL,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;SACpB,WAAW,CAAC,4CAA4C,CAAC;SACzD,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC,CAAC;QACvE,MAAM,aAAa,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IAEL,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;SACrB,WAAW,CAAC,wCAAwC,CAAC;SACrD,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC,CAAC;QACxE,MAAM,aAAa,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IAEL,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;SACrB,WAAW,CAAC,oDAAoD,CAAC;SACjE,MAAM,CAAC,KAAK,IAAI,EAAE;
|
|
1
|
+
{"version":3,"file":"diag.js","sourceRoot":"","sources":["../../src/commands/diag.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadtest.d.ts","sourceRoot":"","sources":["../../src/commands/loadtest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,QAmBvD"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { render } from 'ink';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { LoadTestView } from '../ui/views/LoadTestView.js';
|
|
4
|
+
export function registerLoadtestCommand(program) {
|
|
5
|
+
program
|
|
6
|
+
.command('loadtest')
|
|
7
|
+
.description('CURRI policy load tester with live metrics')
|
|
8
|
+
.option('--policy <name>', 'Policy name (skip selection)')
|
|
9
|
+
.option('--rate <n>', 'Target requests per second')
|
|
10
|
+
.option('--duration <n>', 'Test duration in seconds')
|
|
11
|
+
.option('--connections <n>', 'Number of connections')
|
|
12
|
+
.option('--calling <number>', 'Override calling number')
|
|
13
|
+
.option('--called <number>', 'Override called number')
|
|
14
|
+
.option('--device <name>', 'Override device name')
|
|
15
|
+
.option('--trigger <type>', 'Trigger point type')
|
|
16
|
+
.option('--url <url>', 'CURRI endpoint URL (auto-detected)')
|
|
17
|
+
.action(async (opts) => {
|
|
18
|
+
const { waitUntilExit } = render(React.createElement(LoadTestView, { cliOptions: opts }));
|
|
19
|
+
await waitUntilExit();
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=loadtest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadtest.js","sourceRoot":"","sources":["../../src/commands/loadtest.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAE3D,MAAM,UAAU,uBAAuB,CAAC,OAAgB;IACtD,OAAO;SACJ,OAAO,CAAC,UAAU,CAAC;SACnB,WAAW,CAAC,4CAA4C,CAAC;SACzD,MAAM,CAAC,iBAAiB,EAAE,8BAA8B,CAAC;SACzD,MAAM,CAAC,YAAY,EAAE,4BAA4B,CAAC;SAClD,MAAM,CAAC,gBAAgB,EAAE,0BAA0B,CAAC;SACpD,MAAM,CAAC,mBAAmB,EAAE,uBAAuB,CAAC;SACpD,MAAM,CAAC,oBAAoB,EAAE,yBAAyB,CAAC;SACvD,MAAM,CAAC,mBAAmB,EAAE,wBAAwB,CAAC;SACrD,MAAM,CAAC,iBAAiB,EAAE,sBAAsB,CAAC;SACjD,MAAM,CAAC,kBAAkB,EAAE,oBAAoB,CAAC;SAChD,MAAM,CAAC,aAAa,EAAE,oCAAoC,CAAC;SAC3D,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAC9B,KAAK,CAAC,aAAa,CAAC,YAAY,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CACxD,CAAC;QACF,MAAM,aAAa,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;AACP,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const VERSION = '0.4.
|
|
2
|
+
const VERSION = '0.4.7';
|
|
3
3
|
import { Command } from 'commander';
|
|
4
4
|
import { registerStatusCommand } from './commands/status.js';
|
|
5
5
|
import { registerUpdateCommand } from './commands/update.js';
|
|
@@ -14,6 +14,7 @@ import { registerSecretsCommand } from './commands/secrets.js';
|
|
|
14
14
|
import { registerUsersCommand } from './commands/users.js';
|
|
15
15
|
import { registerServicesCommand } from './commands/services.js';
|
|
16
16
|
import { registerSelfUpdateCommand } from './commands/self-update.js';
|
|
17
|
+
import { registerLoadtestCommand } from './commands/loadtest.js';
|
|
17
18
|
import { LOGO } from './lib/brand.js';
|
|
18
19
|
import { setVerbose, setGlobalLevel } from './lib/log.js';
|
|
19
20
|
import { loadPrefs } from './lib/prefs.js';
|
|
@@ -53,6 +54,7 @@ registerSecretsCommand(program);
|
|
|
53
54
|
registerUsersCommand(program);
|
|
54
55
|
registerServicesCommand(program);
|
|
55
56
|
registerSelfUpdateCommand(program);
|
|
57
|
+
registerLoadtestCommand(program);
|
|
56
58
|
// Interactive menu when `ct` is run with no arguments on a TTY
|
|
57
59
|
// Flags like --debug and --verbose are not commands; only positional args count
|
|
58
60
|
const nonFlagArgs = process.argv.slice(2).filter(a => !a.startsWith('-'));
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,MAAM,OAAO,GAAG,OAAO,CAAC;AAExB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,IAAI,CAAC;KACV,WAAW,CAAC,wCAAwC,CAAC;KACrD,OAAO,CAAC,OAAO,CAAC;KAChB,MAAM,CAAC,eAAe,EAAE,6BAA6B,CAAC;KACtD,MAAM,CAAC,SAAS,EAAE,4BAA4B,CAAC;KAC/C,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,EAAE;IAC7B,wCAAwC;IACxC,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK;QAAE,cAAc,CAAC,OAAO,CAAC,CAAC;SAC7C,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,OAAO;QAAE,UAAU,CAAC,IAAI,CAAC,CAAC;IAClD,qDAAqD;IACrD,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,+BAA+B,CAAC,CAAC;IACtD,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,iEAAiE;IACjE,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;IAC1B,IAAI,KAAK,EAAE,UAAU,EAAE,CAAC;QACtB,kBAAkB,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAC3B,sBAAsB,CAAC,OAAO,CAAC,CAAC;AAChC,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,sBAAsB,CAAC,OAAO,CAAC,CAAC;AAChC,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,sBAAsB,CAAC,OAAO,CAAC,CAAC;AAChC,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,uBAAuB,CAAC,OAAO,CAAC,CAAC;AACjC,yBAAyB,CAAC,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** XACML 2.0 XML builder for CURRI load testing. */
|
|
2
|
+
export interface CurriXmlOptions {
|
|
3
|
+
callingNumber: string;
|
|
4
|
+
calledNumber: string;
|
|
5
|
+
deviceName: string;
|
|
6
|
+
triggerType: string;
|
|
7
|
+
}
|
|
8
|
+
/** Generate a random 10-digit US phone number. */
|
|
9
|
+
export declare function randomPhoneNumber(): string;
|
|
10
|
+
/** Generate a random Cisco device MAC name (SEP + 12 hex chars). */
|
|
11
|
+
export declare function randomDeviceName(): string;
|
|
12
|
+
/** Build XACML 2.0 XML for a CURRI policy request. */
|
|
13
|
+
export declare function buildCurriXml(opts: CurriXmlOptions): string;
|
|
14
|
+
/** Build CURRI XML with random or custom values based on config. */
|
|
15
|
+
export declare function buildCurriXmlFromConfig(config: {
|
|
16
|
+
callingNumber: string;
|
|
17
|
+
calledNumber: string;
|
|
18
|
+
deviceName: string;
|
|
19
|
+
triggerType: string;
|
|
20
|
+
}): string;
|
|
21
|
+
//# sourceMappingURL=curri-xml.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"curri-xml.d.ts","sourceRoot":"","sources":["../../src/lib/curri-xml.ts"],"names":[],"mappings":"AAAA,oDAAoD;AAEpD,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,kDAAkD;AAClD,wBAAgB,iBAAiB,IAAI,MAAM,CAK1C;AAED,oEAAoE;AACpE,wBAAgB,gBAAgB,IAAI,MAAM,CAKzC;AAED,sDAAsD;AACtD,wBAAgB,aAAa,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,CA4B3D;AAED,oEAAoE;AACpE,wBAAgB,uBAAuB,CAAC,MAAM,EAAE;IAC9C,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,MAAM,CAOT"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/** XACML 2.0 XML builder for CURRI load testing. */
|
|
2
|
+
/** Generate a random 10-digit US phone number. */
|
|
3
|
+
export function randomPhoneNumber() {
|
|
4
|
+
const areaCode = 200 + Math.floor(Math.random() * 800); // 200-999
|
|
5
|
+
const exchange = 200 + Math.floor(Math.random() * 800); // 200-999
|
|
6
|
+
const subscriber = Math.floor(Math.random() * 10000);
|
|
7
|
+
return `${areaCode}${exchange}${subscriber.toString().padStart(4, '0')}`;
|
|
8
|
+
}
|
|
9
|
+
/** Generate a random Cisco device MAC name (SEP + 12 hex chars). */
|
|
10
|
+
export function randomDeviceName() {
|
|
11
|
+
const hex = Array.from({ length: 12 }, () => Math.floor(Math.random() * 16).toString(16).toUpperCase()).join('');
|
|
12
|
+
return `SEP${hex}`;
|
|
13
|
+
}
|
|
14
|
+
/** Build XACML 2.0 XML for a CURRI policy request. */
|
|
15
|
+
export function buildCurriXml(opts) {
|
|
16
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
17
|
+
<Request xmlns="urn:oasis:names:tc:xacml:2.0:context:schema:os">
|
|
18
|
+
<Subject SubjectCategory="urn:oasis:names:tc:xacml:1.0:Subject-Category:access-Subject">
|
|
19
|
+
<Attribute AttributeId="urn:Cisco:uc:1.0:callingnumber">
|
|
20
|
+
<AttributeValue>${opts.callingNumber}</AttributeValue>
|
|
21
|
+
</Attribute>
|
|
22
|
+
<Attribute AttributeId="urn:Cisco:uc:1.0:callednumber">
|
|
23
|
+
<AttributeValue>${opts.calledNumber}</AttributeValue>
|
|
24
|
+
</Attribute>
|
|
25
|
+
<Attribute AttributeId="urn:Cisco:uc:1.0:callingdevicename">
|
|
26
|
+
<AttributeValue>${opts.deviceName}</AttributeValue>
|
|
27
|
+
</Attribute>
|
|
28
|
+
<Attribute AttributeId="urn:Cisco:uc:1.0:triggerpointtype">
|
|
29
|
+
<AttributeValue>${opts.triggerType}</AttributeValue>
|
|
30
|
+
</Attribute>
|
|
31
|
+
</Subject>
|
|
32
|
+
<Resource>
|
|
33
|
+
<Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:Resource:Resource-Id">
|
|
34
|
+
<AttributeValue>CISCO:UC:VoiceOrVideoCall</AttributeValue>
|
|
35
|
+
</Attribute>
|
|
36
|
+
</Resource>
|
|
37
|
+
<action>
|
|
38
|
+
<Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-Id">
|
|
39
|
+
<AttributeValue>any</AttributeValue>
|
|
40
|
+
</Attribute>
|
|
41
|
+
</action>
|
|
42
|
+
</Request>`;
|
|
43
|
+
}
|
|
44
|
+
/** Build CURRI XML with random or custom values based on config. */
|
|
45
|
+
export function buildCurriXmlFromConfig(config) {
|
|
46
|
+
return buildCurriXml({
|
|
47
|
+
callingNumber: config.callingNumber === 'random' ? randomPhoneNumber() : config.callingNumber,
|
|
48
|
+
calledNumber: config.calledNumber === 'random' ? randomPhoneNumber() : config.calledNumber,
|
|
49
|
+
deviceName: config.deviceName === 'random' ? randomDeviceName() : config.deviceName,
|
|
50
|
+
triggerType: config.triggerType,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=curri-xml.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"curri-xml.js","sourceRoot":"","sources":["../../src/lib/curri-xml.ts"],"names":[],"mappings":"AAAA,oDAAoD;AASpD,kDAAkD;AAClD,MAAM,UAAU,iBAAiB;IAC/B,MAAM,QAAQ,GAAG,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,UAAU;IAClE,MAAM,QAAQ,GAAG,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,UAAU;IAClE,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC;IACrD,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;AAC3E,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,gBAAgB;IAC9B,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,CAC1C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAC1D,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACX,OAAO,MAAM,GAAG,EAAE,CAAC;AACrB,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,aAAa,CAAC,IAAqB;IACjD,OAAO;;;;wBAIe,IAAI,CAAC,aAAa;;;wBAGlB,IAAI,CAAC,YAAY;;;wBAGjB,IAAI,CAAC,UAAU;;;wBAGf,IAAI,CAAC,WAAW;;;;;;;;;;;;;WAa7B,CAAC;AACZ,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,uBAAuB,CAAC,MAKvC;IACC,OAAO,aAAa,CAAC;QACnB,aAAa,EAAE,MAAM,CAAC,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa;QAC7F,YAAY,EAAE,MAAM,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY;QAC1F,UAAU,EAAE,MAAM,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU;QACnF,WAAW,EAAE,MAAM,CAAC,WAAW;KAChC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/** Types for the CURRI load testing engine. */
|
|
2
|
+
export interface LoadTestConfig {
|
|
3
|
+
/** CURRI endpoint URL (e.g., http://127.0.0.1:4080) */
|
|
4
|
+
url: string;
|
|
5
|
+
/** Policy API key for ?api_key= param */
|
|
6
|
+
apiKey: string;
|
|
7
|
+
/** Policy name for display */
|
|
8
|
+
policyName: string;
|
|
9
|
+
/** Target requests per second */
|
|
10
|
+
rate: number;
|
|
11
|
+
/** Test duration in seconds */
|
|
12
|
+
duration: number;
|
|
13
|
+
/** Number of HTTP connections */
|
|
14
|
+
connections: number;
|
|
15
|
+
/** Override calling number (or 'random') */
|
|
16
|
+
callingNumber: string;
|
|
17
|
+
/** Override called number (or 'random') */
|
|
18
|
+
calledNumber: string;
|
|
19
|
+
/** Override device name (or 'random') */
|
|
20
|
+
deviceName: string;
|
|
21
|
+
/** Trigger point type */
|
|
22
|
+
triggerType: string;
|
|
23
|
+
}
|
|
24
|
+
export interface LoadTestSnapshot {
|
|
25
|
+
/** Elapsed seconds */
|
|
26
|
+
elapsed: number;
|
|
27
|
+
/** Requests completed in this interval */
|
|
28
|
+
requestsInInterval: number;
|
|
29
|
+
/** Cumulative totals */
|
|
30
|
+
totalRequests: number;
|
|
31
|
+
successCount: number;
|
|
32
|
+
errorCount: number;
|
|
33
|
+
timeoutCount: number;
|
|
34
|
+
/** Latency percentiles in ms */
|
|
35
|
+
p50: number;
|
|
36
|
+
p95: number;
|
|
37
|
+
p99: number;
|
|
38
|
+
max: number;
|
|
39
|
+
mean: number;
|
|
40
|
+
/** Rate history for sparkline (last N intervals) */
|
|
41
|
+
rateHistory: number[];
|
|
42
|
+
}
|
|
43
|
+
export interface LoadTestResults {
|
|
44
|
+
config: LoadTestConfig;
|
|
45
|
+
duration: number;
|
|
46
|
+
totalRequests: number;
|
|
47
|
+
successCount: number;
|
|
48
|
+
errorCount: number;
|
|
49
|
+
timeoutCount: number;
|
|
50
|
+
bytesRead: number;
|
|
51
|
+
bytesSent: number;
|
|
52
|
+
latency: {
|
|
53
|
+
p50: number;
|
|
54
|
+
p95: number;
|
|
55
|
+
p99: number;
|
|
56
|
+
p999: number;
|
|
57
|
+
max: number;
|
|
58
|
+
mean: number;
|
|
59
|
+
stddev: number;
|
|
60
|
+
};
|
|
61
|
+
throughput: {
|
|
62
|
+
average: number;
|
|
63
|
+
max: number;
|
|
64
|
+
min: number;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
export interface CurriPolicy {
|
|
68
|
+
id: number;
|
|
69
|
+
name: string;
|
|
70
|
+
api_key: string;
|
|
71
|
+
org_id: number;
|
|
72
|
+
org_name: string;
|
|
73
|
+
}
|
|
74
|
+
/** Maximum number of rate samples kept in the sparkline history. */
|
|
75
|
+
export declare const MAX_RATE_HISTORY = 30;
|
|
76
|
+
/** Build a LoadTestSnapshot from autocannon tick data. */
|
|
77
|
+
export declare function buildSnapshot(counter: {
|
|
78
|
+
counter: number;
|
|
79
|
+
bytes: number;
|
|
80
|
+
}, elapsed: number, rateHistory: number[], latencyData: {
|
|
81
|
+
p50: number;
|
|
82
|
+
p95: number;
|
|
83
|
+
p99: number;
|
|
84
|
+
max: number;
|
|
85
|
+
mean: number;
|
|
86
|
+
}, totals: {
|
|
87
|
+
requests: number;
|
|
88
|
+
errors: number;
|
|
89
|
+
timeouts: number;
|
|
90
|
+
}): LoadTestSnapshot;
|
|
91
|
+
//# sourceMappingURL=loadtest-stats.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadtest-stats.d.ts","sourceRoot":"","sources":["../../src/lib/loadtest-stats.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAE/C,MAAM,WAAW,cAAc;IAC7B,uDAAuD;IACvD,GAAG,EAAE,MAAM,CAAC;IACZ,yCAAyC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,iCAAiC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,aAAa,EAAE,MAAM,CAAC;IACtB,2CAA2C;IAC3C,YAAY,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,0CAA0C;IAC1C,kBAAkB,EAAE,MAAM,CAAC;IAC3B,wBAAwB;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,gCAAgC;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE;QACP,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,UAAU,EAAE;QACV,OAAO,EAAE,MAAM,CAAC;QAChB,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;CACH;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,oEAAoE;AACpE,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAEnC,0DAA0D;AAC1D,wBAAgB,aAAa,CAC3B,OAAO,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAC3C,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EAAE,EACrB,WAAW,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EACjF,MAAM,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC7D,gBAAgB,CAkBlB"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Types for the CURRI load testing engine. */
|
|
2
|
+
/** Maximum number of rate samples kept in the sparkline history. */
|
|
3
|
+
export const MAX_RATE_HISTORY = 30;
|
|
4
|
+
/** Build a LoadTestSnapshot from autocannon tick data. */
|
|
5
|
+
export function buildSnapshot(counter, elapsed, rateHistory, latencyData, totals) {
|
|
6
|
+
const requestsInInterval = counter.counter;
|
|
7
|
+
const updatedHistory = [...rateHistory, requestsInInterval].slice(-MAX_RATE_HISTORY);
|
|
8
|
+
return {
|
|
9
|
+
elapsed,
|
|
10
|
+
requestsInInterval,
|
|
11
|
+
totalRequests: totals.requests,
|
|
12
|
+
successCount: totals.requests - totals.errors - totals.timeouts,
|
|
13
|
+
errorCount: totals.errors,
|
|
14
|
+
timeoutCount: totals.timeouts,
|
|
15
|
+
p50: latencyData.p50,
|
|
16
|
+
p95: latencyData.p95,
|
|
17
|
+
p99: latencyData.p99,
|
|
18
|
+
max: latencyData.max,
|
|
19
|
+
mean: latencyData.mean,
|
|
20
|
+
rateHistory: updatedHistory,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=loadtest-stats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadtest-stats.js","sourceRoot":"","sources":["../../src/lib/loadtest-stats.ts"],"names":[],"mappings":"AAAA,+CAA+C;AA8E/C,oEAAoE;AACpE,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAEnC,0DAA0D;AAC1D,MAAM,UAAU,aAAa,CAC3B,OAA2C,EAC3C,OAAe,EACf,WAAqB,EACrB,WAAiF,EACjF,MAA8D;IAE9D,MAAM,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC;IAC3C,MAAM,cAAc,GAAG,CAAC,GAAG,WAAW,EAAE,kBAAkB,CAAC,CAAC,KAAK,CAAC,CAAC,gBAAgB,CAAC,CAAC;IAErF,OAAO;QACL,OAAO;QACP,kBAAkB;QAClB,aAAa,EAAE,MAAM,CAAC,QAAQ;QAC9B,YAAY,EAAE,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,QAAQ;QAC/D,UAAU,EAAE,MAAM,CAAC,MAAM;QACzB,YAAY,EAAE,MAAM,CAAC,QAAQ;QAC7B,GAAG,EAAE,WAAW,CAAC,GAAG;QACpB,GAAG,EAAE,WAAW,CAAC,GAAG;QACpB,GAAG,EAAE,WAAW,CAAC,GAAG;QACpB,GAAG,EAAE,WAAW,CAAC,GAAG;QACpB,IAAI,EAAE,WAAW,CAAC,IAAI;QACtB,WAAW,EAAE,cAAc;KAC5B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** CURRI load test engine wrapping autocannon. */
|
|
2
|
+
import type { LoadTestConfig, LoadTestResults, LoadTestSnapshot } from './loadtest-stats.js';
|
|
3
|
+
export type { LoadTestConfig, LoadTestResults, LoadTestSnapshot } from './loadtest-stats.js';
|
|
4
|
+
/** Default CURRI endpoint URL. */
|
|
5
|
+
export declare const DEFAULT_CURRI_URL = "http://127.0.0.1:4080";
|
|
6
|
+
export interface LoadTestHandle {
|
|
7
|
+
/** Promise that resolves when the test completes. */
|
|
8
|
+
promise: Promise<LoadTestResults>;
|
|
9
|
+
/** Stop the load test early. */
|
|
10
|
+
stop: () => void;
|
|
11
|
+
}
|
|
12
|
+
/** Start a CURRI load test with live progress callbacks. */
|
|
13
|
+
export declare function startLoadTest(config: LoadTestConfig, onProgress: (snapshot: LoadTestSnapshot) => void): LoadTestHandle;
|
|
14
|
+
//# sourceMappingURL=loadtest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadtest.d.ts","sourceRoot":"","sources":["../../src/lib/loadtest.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAIlD,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAO7F,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE7F,kCAAkC;AAClC,eAAO,MAAM,iBAAiB,0BAA0B,CAAC;AAEzD,MAAM,WAAW,cAAc;IAC7B,qDAAqD;IACrD,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IAClC,gCAAgC;IAChC,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,4DAA4D;AAC5D,wBAAgB,aAAa,CAC3B,MAAM,EAAE,cAAc,EACtB,UAAU,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,GAC/C,cAAc,CA4GhB"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/** CURRI load test engine wrapping autocannon. */
|
|
2
|
+
import { createRequire } from 'module';
|
|
3
|
+
import { buildCurriXmlFromConfig } from './curri-xml.js';
|
|
4
|
+
import { MAX_RATE_HISTORY } from './loadtest-stats.js';
|
|
5
|
+
// autocannon is CJS — use createRequire for ESM compatibility
|
|
6
|
+
const require = createRequire(import.meta.url);
|
|
7
|
+
const autocannon = require('autocannon');
|
|
8
|
+
/** Default CURRI endpoint URL. */
|
|
9
|
+
export const DEFAULT_CURRI_URL = 'http://127.0.0.1:4080';
|
|
10
|
+
/** Start a CURRI load test with live progress callbacks. */
|
|
11
|
+
export function startLoadTest(config, onProgress) {
|
|
12
|
+
let elapsed = 0;
|
|
13
|
+
let totalRequests = 0;
|
|
14
|
+
let totalErrors = 0;
|
|
15
|
+
let totalTimeouts = 0;
|
|
16
|
+
const rateHistory = [];
|
|
17
|
+
// Latest latency data from tick events
|
|
18
|
+
let latencyP50 = 0;
|
|
19
|
+
let latencyP95 = 0;
|
|
20
|
+
let latencyP99 = 0;
|
|
21
|
+
let latencyMax = 0;
|
|
22
|
+
let latencyMean = 0;
|
|
23
|
+
const instance = autocannon({
|
|
24
|
+
url: `${config.url}/api/policy?api_key=${config.apiKey}`,
|
|
25
|
+
method: 'POST',
|
|
26
|
+
headers: { 'content-type': 'application/xml' },
|
|
27
|
+
connections: config.connections,
|
|
28
|
+
duration: config.duration,
|
|
29
|
+
overallRate: config.rate,
|
|
30
|
+
timeout: 10,
|
|
31
|
+
setupRequest(req) {
|
|
32
|
+
req.body = buildCurriXmlFromConfig({
|
|
33
|
+
callingNumber: config.callingNumber,
|
|
34
|
+
calledNumber: config.calledNumber,
|
|
35
|
+
deviceName: config.deviceName,
|
|
36
|
+
triggerType: config.triggerType,
|
|
37
|
+
});
|
|
38
|
+
return req;
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
// Suppress autocannon's built-in progress output
|
|
42
|
+
autocannon.track(instance, {
|
|
43
|
+
renderProgressBar: false,
|
|
44
|
+
renderResultsTable: false,
|
|
45
|
+
renderLatencyTable: false,
|
|
46
|
+
});
|
|
47
|
+
// Track individual responses for latency info
|
|
48
|
+
instance.on('response', (_client, statusCode, _resBytes, responseTime) => {
|
|
49
|
+
totalRequests++;
|
|
50
|
+
if (statusCode >= 400)
|
|
51
|
+
totalErrors++;
|
|
52
|
+
// Update rolling latency estimates (rough, tick gives better data)
|
|
53
|
+
void responseTime;
|
|
54
|
+
void statusCode;
|
|
55
|
+
});
|
|
56
|
+
instance.on('tick', (value) => {
|
|
57
|
+
elapsed++;
|
|
58
|
+
const requestsInInterval = value.counter;
|
|
59
|
+
rateHistory.push(requestsInInterval);
|
|
60
|
+
if (rateHistory.length > MAX_RATE_HISTORY)
|
|
61
|
+
rateHistory.shift();
|
|
62
|
+
const snapshot = {
|
|
63
|
+
elapsed,
|
|
64
|
+
requestsInInterval,
|
|
65
|
+
totalRequests,
|
|
66
|
+
successCount: totalRequests - totalErrors - totalTimeouts,
|
|
67
|
+
errorCount: totalErrors,
|
|
68
|
+
timeoutCount: totalTimeouts,
|
|
69
|
+
p50: latencyP50,
|
|
70
|
+
p95: latencyP95,
|
|
71
|
+
p99: latencyP99,
|
|
72
|
+
max: latencyMax,
|
|
73
|
+
mean: latencyMean,
|
|
74
|
+
rateHistory: [...rateHistory],
|
|
75
|
+
};
|
|
76
|
+
onProgress(snapshot);
|
|
77
|
+
});
|
|
78
|
+
const promise = new Promise((resolve, reject) => {
|
|
79
|
+
instance.on('done', (result) => {
|
|
80
|
+
resolve({
|
|
81
|
+
config,
|
|
82
|
+
duration: result.duration,
|
|
83
|
+
totalRequests: result['2xx'] + result['3xx'] + result['4xx'] + result['5xx'] + result['1xx'],
|
|
84
|
+
successCount: result['2xx'] + result['3xx'],
|
|
85
|
+
errorCount: result.errors + result['4xx'] + result['5xx'],
|
|
86
|
+
timeoutCount: result.timeouts,
|
|
87
|
+
bytesRead: result.throughput.totalCount,
|
|
88
|
+
bytesSent: 0, // autocannon doesn't track sent bytes
|
|
89
|
+
latency: {
|
|
90
|
+
p50: result.latency.p50,
|
|
91
|
+
p95: result.latency.p97_5,
|
|
92
|
+
p99: result.latency.p99,
|
|
93
|
+
p999: result.latency.p99_9,
|
|
94
|
+
max: result.latency.max,
|
|
95
|
+
mean: result.latency.mean,
|
|
96
|
+
stddev: result.latency.stddev,
|
|
97
|
+
},
|
|
98
|
+
throughput: {
|
|
99
|
+
average: result.requests.average,
|
|
100
|
+
max: result.requests.max,
|
|
101
|
+
min: result.requests.min,
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
instance.on('error', reject);
|
|
106
|
+
});
|
|
107
|
+
return {
|
|
108
|
+
promise,
|
|
109
|
+
stop: () => instance.stop(),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=loadtest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadtest.js","sourceRoot":"","sources":["../../src/lib/loadtest.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAElD,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAEzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,8DAA8D;AAC9D,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,UAAU,GAAG,OAAO,CAAC,YAAY,CAAgC,CAAC;AAIxE,kCAAkC;AAClC,MAAM,CAAC,MAAM,iBAAiB,GAAG,uBAAuB,CAAC;AASzD,4DAA4D;AAC5D,MAAM,UAAU,aAAa,CAC3B,MAAsB,EACtB,UAAgD;IAEhD,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,MAAM,WAAW,GAAa,EAAE,CAAC;IAEjC,uCAAuC;IACvC,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,WAAW,GAAG,CAAC,CAAC;IAEpB,MAAM,QAAQ,GAAG,UAAU,CAAC;QAC1B,GAAG,EAAE,GAAG,MAAM,CAAC,GAAG,uBAAuB,MAAM,CAAC,MAAM,EAAE;QACxD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,iBAAiB,EAAE;QAC9C,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,WAAW,EAAE,MAAM,CAAC,IAAI;QACxB,OAAO,EAAE,EAAE;QACX,YAAY,CAAC,GAAG;YACd,GAAG,CAAC,IAAI,GAAG,uBAAuB,CAAC;gBACjC,aAAa,EAAE,MAAM,CAAC,aAAa;gBACnC,YAAY,EAAE,MAAM,CAAC,YAAY;gBACjC,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,WAAW,EAAE,MAAM,CAAC,WAAW;aAChC,CAAC,CAAC;YACH,OAAO,GAAG,CAAC;QACb,CAAC;KACF,CAAC,CAAC;IAEH,iDAAiD;IACjD,UAAU,CAAC,KAAK,CAAC,QAAQ,EAAE;QACzB,iBAAiB,EAAE,KAAK;QACxB,kBAAkB,EAAE,KAAK;QACzB,kBAAkB,EAAE,KAAK;KAC1B,CAAC,CAAC;IAEH,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,EAAE;QACvE,aAAa,EAAE,CAAC;QAChB,IAAI,UAAU,IAAI,GAAG;YAAE,WAAW,EAAE,CAAC;QACrC,mEAAmE;QACnE,KAAK,YAAY,CAAC;QAClB,KAAK,UAAU,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;QAC5B,OAAO,EAAE,CAAC;QACV,MAAM,kBAAkB,GAAG,KAAK,CAAC,OAAO,CAAC;QACzC,WAAW,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACrC,IAAI,WAAW,CAAC,MAAM,GAAG,gBAAgB;YAAE,WAAW,CAAC,KAAK,EAAE,CAAC;QAE/D,MAAM,QAAQ,GAAqB;YACjC,OAAO;YACP,kBAAkB;YAClB,aAAa;YACb,YAAY,EAAE,aAAa,GAAG,WAAW,GAAG,aAAa;YACzD,UAAU,EAAE,WAAW;YACvB,YAAY,EAAE,aAAa;YAC3B,GAAG,EAAE,UAAU;YACf,GAAG,EAAE,UAAU;YACf,GAAG,EAAE,UAAU;YACf,GAAG,EAAE,UAAU;YACf,IAAI,EAAE,WAAW;YACjB,WAAW,EAAE,CAAC,GAAG,WAAW,CAAC;SAC9B,CAAC;QAEF,UAAU,CAAC,QAAQ,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,IAAI,OAAO,CAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC/D,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;YAC7B,OAAO,CAAC;gBACN,MAAM;gBACN,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,aAAa,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC;gBAC5F,YAAY,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC;gBAC3C,UAAU,EAAE,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC;gBACzD,YAAY,EAAE,MAAM,CAAC,QAAQ;gBAC7B,SAAS,EAAE,MAAM,CAAC,UAAU,CAAC,UAAU;gBACvC,SAAS,EAAE,CAAC,EAAE,sCAAsC;gBACpD,OAAO,EAAE;oBACP,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG;oBACvB,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK;oBACzB,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG;oBACvB,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK;oBAC1B,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG;oBACvB,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI;oBACzB,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM;iBAC9B;gBACD,UAAU,EAAE;oBACV,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,OAAO;oBAChC,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,GAAG;oBACxB,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,GAAG;iBACzB;aACF,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,OAAO;QACP,IAAI,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE;KAC5B,CAAC;AACJ,CAAC"}
|
|
@@ -1,2 +1,8 @@
|
|
|
1
|
+
/** RPC: List all CURRI policies for all orgs (for load testing). */
|
|
2
|
+
export declare const CURRI_POLICIES_RPC = "\n alias Cdrcisco.Identity\n alias Cdrcisco.Policies\n\n try do\n orgs = Identity.get_all_orgs()\n\n result = Enum.flat_map(orgs, fn org ->\n Policies.list_policies_by_org(org.id)\n |> Enum.map(fn p ->\n %{\n id: p.id,\n name: p.name,\n api_key: p.api_key,\n org_id: org.id,\n org_name: org.name\n }\n end)\n end)\n\n Jason.encode!(%{policies: result, count: length(result)})\n |> IO.puts()\n rescue\n e ->\n Jason.encode!(%{error: inspect(e), policies: [], count: 0})\n |> IO.puts()\n end\n";
|
|
3
|
+
/** RPC: List all greeting policies for all orgs with rules. */
|
|
4
|
+
export declare const GREETING_POLICIES_RPC = "\n alias Cdrcisco.Identity\n alias Cdrcisco.JtapiGreeting.GreetingPolicies\n\n try do\n orgs = Identity.get_all_orgs()\n\n result = Enum.flat_map(orgs, fn org ->\n policies = GreetingPolicies.list_greeting_policies(org.id,\n preload: [:default_audio_file, rules: [:audio_file]]\n )\n\n Enum.map(policies, fn p ->\n %{\n org_id: org.id,\n org_name: org.name,\n id: p.id,\n name: p.name,\n description: p.description,\n enabled: p.enabled,\n injection_target: p.injection_target,\n injection_mode: p.injection_mode,\n trigger_timing: p.trigger_timing,\n max_duration_seconds: p.max_duration_seconds,\n skip_key: p.skip_key,\n call_direction: p.call_direction,\n default_audio_file: case p.default_audio_file do\n nil -> nil\n f -> %{id: f.id, name: f.name}\n end,\n rules: Enum.map(p.rules || [], fn r ->\n %{\n id: r.id,\n name: r.name,\n priority: r.priority,\n enabled: r.enabled,\n calling_pattern: r.calling_pattern,\n called_pattern: r.called_pattern,\n call_direction: r.call_direction,\n injection_target: r.injection_target,\n injection_mode: r.injection_mode,\n audio_file: case r.audio_file do\n nil -> nil\n f -> %{id: f.id, name: f.name}\n end\n }\n end),\n rules_count: length(p.rules || []),\n inserted_at: p.inserted_at,\n updated_at: p.updated_at\n }\n end)\n end)\n\n Jason.encode!(%{policies: result, count: length(result), collected_at: DateTime.utc_now()})\n |> IO.puts()\n rescue\n e ->\n Jason.encode!(%{error: inspect(e), policies: [], count: 0})\n |> IO.puts()\n end\n";
|
|
5
|
+
/** Generate RPC code for policy history with a time window in minutes. */
|
|
6
|
+
export declare function policyHistoryRpc(minutes: number): string;
|
|
1
7
|
export declare const MIGRATION_STATUS_RPC = "\n alias Cdrcisco.Repo\n import Ecto.Query\n\n try do\n migrations = Ecto.Migrator.migrations(Repo)\n ordered = Enum.sort_by(migrations, fn {_, version, _} -> version end)\n {applied, pending} = Enum.split_with(ordered, fn {status, _, _} -> status == :up end)\n total = length(ordered)\n applied_count = length(applied)\n pending_count = length(pending)\n\n percent = if total == 0, do: 100.0, else: Float.round(applied_count / total * 100, 1)\n\n latest = Repo.one(\n from sm in \"schema_migrations\",\n order_by: [desc: sm.version],\n limit: 1,\n select: %{version: sm.version, inserted_at: sm.inserted_at}\n )\n\n IO.puts(\"=== Migration Progress ===\")\n IO.puts(\"Applied migrations: #{applied_count}/#{total} (#{percent}%)\")\n IO.puts(\"Pending migrations: #{pending_count}\")\n\n case latest do\n %{version: version, inserted_at: timestamp} ->\n IO.puts(\"Latest applied: #{version} @ #{timestamp}\")\n _ ->\n IO.puts(\"Latest applied: none recorded\")\n end\n\n IO.puts(\"\")\n\n if pending_count > 0 do\n {_, next_version, next_name} = hd(pending)\n IO.puts(\"Next pending: #{next_version} - #{next_name}\")\n IO.puts(\"\")\n IO.puts(\"=== Pending Queue ===\")\n Enum.with_index(pending, 1)\n |> Enum.each(fn {{_, version, name}, idx} ->\n IO.puts(\"[#{idx}/#{pending_count}] #{version} - #{name}\")\n end)\n else\n IO.puts(\"All migrations are up to date!\")\n end\n\n IO.puts(\"::pending_count=#{pending_count}\")\n rescue\n e ->\n IO.puts(\"Error checking migrations: #{inspect(e)}\")\n IO.puts(\"::pending_count=error\")\n end\n";
|
|
2
8
|
//# sourceMappingURL=rpc-scripts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc-scripts.d.ts","sourceRoot":"","sources":["../../src/lib/rpc-scripts.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,urDAqDhC,CAAC"}
|
|
1
|
+
{"version":3,"file":"rpc-scripts.d.ts","sourceRoot":"","sources":["../../src/lib/rpc-scripts.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,eAAO,MAAM,kBAAkB,2lBA2B9B,CAAC;AAEF,+DAA+D;AAC/D,eAAO,MAAM,qBAAqB,s6DA6DjC,CAAC;AAEF,0EAA0E;AAC1E,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CA6CxD;AAED,eAAO,MAAM,oBAAoB,urDAqDhC,CAAC"}
|
package/dist/lib/rpc-scripts.js
CHANGED
|
@@ -1,3 +1,142 @@
|
|
|
1
|
+
/** RPC: List all CURRI policies for all orgs (for load testing). */
|
|
2
|
+
export const CURRI_POLICIES_RPC = `
|
|
3
|
+
alias Cdrcisco.Identity
|
|
4
|
+
alias Cdrcisco.Policies
|
|
5
|
+
|
|
6
|
+
try do
|
|
7
|
+
orgs = Identity.get_all_orgs()
|
|
8
|
+
|
|
9
|
+
result = Enum.flat_map(orgs, fn org ->
|
|
10
|
+
Policies.list_policies_by_org(org.id)
|
|
11
|
+
|> Enum.map(fn p ->
|
|
12
|
+
%{
|
|
13
|
+
id: p.id,
|
|
14
|
+
name: p.name,
|
|
15
|
+
api_key: p.api_key,
|
|
16
|
+
org_id: org.id,
|
|
17
|
+
org_name: org.name
|
|
18
|
+
}
|
|
19
|
+
end)
|
|
20
|
+
end)
|
|
21
|
+
|
|
22
|
+
Jason.encode!(%{policies: result, count: length(result)})
|
|
23
|
+
|> IO.puts()
|
|
24
|
+
rescue
|
|
25
|
+
e ->
|
|
26
|
+
Jason.encode!(%{error: inspect(e), policies: [], count: 0})
|
|
27
|
+
|> IO.puts()
|
|
28
|
+
end
|
|
29
|
+
`;
|
|
30
|
+
/** RPC: List all greeting policies for all orgs with rules. */
|
|
31
|
+
export const GREETING_POLICIES_RPC = `
|
|
32
|
+
alias Cdrcisco.Identity
|
|
33
|
+
alias Cdrcisco.JtapiGreeting.GreetingPolicies
|
|
34
|
+
|
|
35
|
+
try do
|
|
36
|
+
orgs = Identity.get_all_orgs()
|
|
37
|
+
|
|
38
|
+
result = Enum.flat_map(orgs, fn org ->
|
|
39
|
+
policies = GreetingPolicies.list_greeting_policies(org.id,
|
|
40
|
+
preload: [:default_audio_file, rules: [:audio_file]]
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
Enum.map(policies, fn p ->
|
|
44
|
+
%{
|
|
45
|
+
org_id: org.id,
|
|
46
|
+
org_name: org.name,
|
|
47
|
+
id: p.id,
|
|
48
|
+
name: p.name,
|
|
49
|
+
description: p.description,
|
|
50
|
+
enabled: p.enabled,
|
|
51
|
+
injection_target: p.injection_target,
|
|
52
|
+
injection_mode: p.injection_mode,
|
|
53
|
+
trigger_timing: p.trigger_timing,
|
|
54
|
+
max_duration_seconds: p.max_duration_seconds,
|
|
55
|
+
skip_key: p.skip_key,
|
|
56
|
+
call_direction: p.call_direction,
|
|
57
|
+
default_audio_file: case p.default_audio_file do
|
|
58
|
+
nil -> nil
|
|
59
|
+
f -> %{id: f.id, name: f.name}
|
|
60
|
+
end,
|
|
61
|
+
rules: Enum.map(p.rules || [], fn r ->
|
|
62
|
+
%{
|
|
63
|
+
id: r.id,
|
|
64
|
+
name: r.name,
|
|
65
|
+
priority: r.priority,
|
|
66
|
+
enabled: r.enabled,
|
|
67
|
+
calling_pattern: r.calling_pattern,
|
|
68
|
+
called_pattern: r.called_pattern,
|
|
69
|
+
call_direction: r.call_direction,
|
|
70
|
+
injection_target: r.injection_target,
|
|
71
|
+
injection_mode: r.injection_mode,
|
|
72
|
+
audio_file: case r.audio_file do
|
|
73
|
+
nil -> nil
|
|
74
|
+
f -> %{id: f.id, name: f.name}
|
|
75
|
+
end
|
|
76
|
+
}
|
|
77
|
+
end),
|
|
78
|
+
rules_count: length(p.rules || []),
|
|
79
|
+
inserted_at: p.inserted_at,
|
|
80
|
+
updated_at: p.updated_at
|
|
81
|
+
}
|
|
82
|
+
end)
|
|
83
|
+
end)
|
|
84
|
+
|
|
85
|
+
Jason.encode!(%{policies: result, count: length(result), collected_at: DateTime.utc_now()})
|
|
86
|
+
|> IO.puts()
|
|
87
|
+
rescue
|
|
88
|
+
e ->
|
|
89
|
+
Jason.encode!(%{error: inspect(e), policies: [], count: 0})
|
|
90
|
+
|> IO.puts()
|
|
91
|
+
end
|
|
92
|
+
`;
|
|
93
|
+
/** Generate RPC code for policy history with a time window in minutes. */
|
|
94
|
+
export function policyHistoryRpc(minutes) {
|
|
95
|
+
return `
|
|
96
|
+
alias Cdrcisco.Identity
|
|
97
|
+
alias Cdrcisco.Analytics.PolicyHistoryHybrid
|
|
98
|
+
|
|
99
|
+
try do
|
|
100
|
+
orgs = Identity.get_all_orgs()
|
|
101
|
+
start_dt = DateTime.utc_now() |> DateTime.add(-${minutes}, :minute)
|
|
102
|
+
start_iso = DateTime.to_iso8601(start_dt)
|
|
103
|
+
end_iso = DateTime.utc_now() |> DateTime.add(60, :second) |> DateTime.to_iso8601()
|
|
104
|
+
|
|
105
|
+
result = Enum.flat_map(orgs, fn org ->
|
|
106
|
+
search_params = %{
|
|
107
|
+
org_id: org.id,
|
|
108
|
+
query: "",
|
|
109
|
+
filters: %{"start_date" => start_iso, "end_date" => end_iso},
|
|
110
|
+
page: "1",
|
|
111
|
+
sort_by: "inserted_at",
|
|
112
|
+
descending: true,
|
|
113
|
+
rowsPerPage: "10000"
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
case PolicyHistoryHybrid.search_hybrid(search_params) do
|
|
117
|
+
%{datas: datas} ->
|
|
118
|
+
Enum.map(datas, fn row ->
|
|
119
|
+
row_map = if is_struct(row), do: Map.from_struct(row) |> Map.drop([:__meta__]), else: row
|
|
120
|
+
Map.put(row_map, :org_id, org.id)
|
|
121
|
+
end)
|
|
122
|
+
_ -> []
|
|
123
|
+
end
|
|
124
|
+
end)
|
|
125
|
+
|
|
126
|
+
Jason.encode!(%{
|
|
127
|
+
rows: result,
|
|
128
|
+
count: length(result),
|
|
129
|
+
time_range_minutes: ${minutes},
|
|
130
|
+
collected_at: DateTime.utc_now()
|
|
131
|
+
})
|
|
132
|
+
|> IO.puts()
|
|
133
|
+
rescue
|
|
134
|
+
e ->
|
|
135
|
+
Jason.encode!(%{error: inspect(e), rows: [], count: 0, time_range_minutes: ${minutes}})
|
|
136
|
+
|> IO.puts()
|
|
137
|
+
end
|
|
138
|
+
`;
|
|
139
|
+
}
|
|
1
140
|
export const MIGRATION_STATUS_RPC = `
|
|
2
141
|
alias Cdrcisco.Repo
|
|
3
142
|
import Ecto.Query
|