k6ctl 1.1.0 → 1.3.0
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 +168 -4
- package/dist/cli.js +10 -5
- package/dist/cli.js.map +1 -1
- package/dist/commands/delete.d.ts +4 -1
- package/dist/commands/delete.d.ts.map +1 -1
- package/dist/commands/delete.js +26 -5
- package/dist/commands/delete.js.map +1 -1
- package/dist/commands/list.js +6 -6
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/run.d.ts +2 -0
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +191 -1
- package/dist/commands/run.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +4 -0
- package/dist/commands/status.js.map +1 -1
- package/dist/services/kubernetes.service.d.ts +12 -5
- package/dist/services/kubernetes.service.d.ts.map +1 -1
- package/dist/services/kubernetes.service.js +134 -6
- package/dist/services/kubernetes.service.js.map +1 -1
- package/dist/services/script.service.d.ts +3 -1
- package/dist/services/script.service.d.ts.map +1 -1
- package/dist/services/script.service.js +115 -1
- package/dist/services/script.service.js.map +1 -1
- package/dist/types/kubernetes.types.d.ts +5 -0
- package/dist/types/kubernetes.types.d.ts.map +1 -1
- package/dist/types/lastRun.types.d.ts +2 -1
- package/dist/types/lastRun.types.d.ts.map +1 -1
- package/dist/types/script.types.d.ts +39 -0
- package/dist/types/script.types.d.ts.map +1 -1
- package/dist/types/testRunManifest.types.d.ts +2 -4
- package/dist/types/testRunManifest.types.d.ts.map +1 -1
- package/dist/utils/testRunManifestBuilder.d.ts +14 -1
- package/dist/utils/testRunManifestBuilder.d.ts.map +1 -1
- package/dist/utils/testRunManifestBuilder.js +70 -14
- package/dist/utils/testRunManifestBuilder.js.map +1 -1
- package/package.json +2 -1
- package/src/cli.ts +10 -5
- package/src/commands/delete.ts +35 -8
- package/src/commands/list.ts +7 -7
- package/src/commands/run.ts +216 -2
- package/src/commands/status.ts +4 -0
- package/src/services/kubernetes.service.ts +161 -16
- package/src/services/script.service.ts +102 -4
- package/src/types/kubernetes.types.ts +6 -0
- package/src/types/lastRun.types.ts +2 -1
- package/src/types/script.types.ts +40 -0
- package/src/types/testRunManifest.types.ts +3 -4
- package/src/utils/testRunManifestBuilder.ts +80 -18
- package/test/integration/kubernetes.service.test.ts +63 -9
- package/test/unit/kubernetes.service.test.ts +15 -7
- package/test/unit/script.service.test.ts +11 -4
package/README.md
CHANGED
|
@@ -20,23 +20,187 @@ npx k6ctl run path/to/test.js
|
|
|
20
20
|
|
|
21
21
|
## Configuration
|
|
22
22
|
|
|
23
|
-
Create a `k6ctl.config.
|
|
23
|
+
Create a `k6ctl.config.json` file in the root of your project (or pass another file with `--config`).
|
|
24
|
+
|
|
25
|
+
Example:
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
{
|
|
29
|
+
"namespace": "default",
|
|
30
|
+
"parallelism": 1,
|
|
31
|
+
"arguments": ["--summary-mode=full"],
|
|
32
|
+
"cleanup": false,
|
|
33
|
+
"quiet": true,
|
|
34
|
+
"separate": false,
|
|
35
|
+
"runner": {
|
|
36
|
+
"image": "grafana/k6:latest",
|
|
37
|
+
"resources": {
|
|
38
|
+
"limits": {
|
|
39
|
+
"cpu": "500m",
|
|
40
|
+
"memory": "512Mi"
|
|
41
|
+
},
|
|
42
|
+
"requests": {
|
|
43
|
+
"cpu": "250m",
|
|
44
|
+
"memory": "256Mi"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"prometheus": {
|
|
49
|
+
"serverUrl": "http://prometheus-server.monitoring.svc.cluster.local:9090/api/v1/write",
|
|
50
|
+
"trendStats": ["avg", "p(95)", "p(99)", "min", "max"]
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
If this file does not exist, `k6ctl` falls back to defaults.
|
|
24
56
|
|
|
25
57
|
## Usage
|
|
26
58
|
|
|
27
|
-
|
|
59
|
+
### Step-by-step workflow
|
|
60
|
+
|
|
61
|
+
1. Prepare your test scripts and config.
|
|
62
|
+
2. Run a test with `k6ctl run ...`.
|
|
63
|
+
3. Inspect state with `k6ctl status`.
|
|
64
|
+
4. Read pod output with `k6ctl logs`.
|
|
65
|
+
5. List resources with `k6ctl list`.
|
|
66
|
+
6. Clean up with `k6ctl delete`.
|
|
67
|
+
|
|
68
|
+
`k6ctl run` stores run metadata in `.k6ctl-last-run.json` in your current directory. Commands like `status`, `logs`, and default `delete` use this file.
|
|
69
|
+
|
|
70
|
+
### Run command
|
|
71
|
+
|
|
72
|
+
Run a specific test file:
|
|
28
73
|
|
|
29
74
|
```bash
|
|
30
75
|
k6ctl run large-test-1.js
|
|
31
76
|
```
|
|
32
77
|
|
|
33
|
-
|
|
78
|
+
Run with a custom scripts directory for interactive selection:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
k6ctl run -d dist/tests
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
When no script argument is provided, `k6ctl` scans the folder provided by `-d, --dir` (default: `dist/tests`) and prompts you to choose a `.js` script.
|
|
85
|
+
|
|
86
|
+
Run with smart analysis enabled:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
k6ctl run large-test-1.js --smart
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
`--smart` analyzes supported scenarios (currently `ramping-arrival-rate`) and automatically adjusts values such as recommended VUs and parallelism before submission.
|
|
93
|
+
|
|
94
|
+
Run options:
|
|
95
|
+
|
|
96
|
+
- `-c, --config <path>`: Path to config file (default: `k6ctl.config.json`)
|
|
97
|
+
- `-n, --namespace <namespace>`: Kubernetes namespace
|
|
98
|
+
- `-p, --parallelism <number>`: Number of parallel test pods
|
|
99
|
+
- `-v, --verbose`: Enable debug logging
|
|
100
|
+
- `-d, --dir <path>`: Folder to search for `.js` test files (default: `dist/tests`)
|
|
101
|
+
- `--smart`: Enable smart scenario analysis
|
|
102
|
+
|
|
103
|
+
### List command
|
|
104
|
+
|
|
105
|
+
List all supported resource types in namespace `default`:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
k6ctl list
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
List only pods:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
k6ctl list pods -n load-tests
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
List command syntax:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
k6ctl list [pods|testruns|configmaps] [-n <namespace>]
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
If no type is provided, `all` is used.
|
|
124
|
+
|
|
125
|
+
### Status command
|
|
126
|
+
|
|
127
|
+
Show the status of the last saved run:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
k6ctl status
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Override namespace:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
k6ctl status -n load-tests
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
This prints TestRun details and related pod status.
|
|
140
|
+
|
|
141
|
+
### Logs command
|
|
142
|
+
|
|
143
|
+
Show logs for pods linked to the last saved run:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
k6ctl logs
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Specify namespace and container:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
k6ctl logs -n load-tests -c runner
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Logs command options:
|
|
156
|
+
|
|
157
|
+
- `-n, --namespace <namespace>`: Override namespace stored in last run
|
|
158
|
+
- `-c, --container <name>`: Container name to fetch logs from
|
|
159
|
+
|
|
160
|
+
### Delete command
|
|
34
161
|
|
|
35
|
-
|
|
162
|
+
Delete the last run and its associated script resource (ConfigMap or PVC):
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
k6ctl delete
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Delete last TestRun but keep script resource:
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
k6ctl delete --keep-script
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Delete specific resources directly:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
k6ctl delete -p <pod-name> -n load-tests
|
|
178
|
+
k6ctl delete -t <testrun-name> -n load-tests
|
|
179
|
+
k6ctl delete -c <configmap-name> -n load-tests
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Delete command options:
|
|
183
|
+
|
|
184
|
+
- `-n, --namespace <namespace>`: Kubernetes namespace
|
|
185
|
+
- `--keep-script`: Skip deletion of associated script ConfigMap/PVC
|
|
186
|
+
- `-p, --pod <name>`: Delete a specific pod
|
|
187
|
+
- `-t, --testrun <name>`: Delete a specific TestRun
|
|
188
|
+
- `-c, --configmap <name>`: Delete a specific ConfigMap
|
|
189
|
+
|
|
190
|
+
## Command summary
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
k6ctl run [script] [options]
|
|
194
|
+
k6ctl list [type] [-n <namespace>]
|
|
195
|
+
k6ctl status [-n <namespace>]
|
|
196
|
+
k6ctl logs [-n <namespace>] [-c <container>]
|
|
197
|
+
k6ctl delete [--keep-script] [-n <namespace>] [-p <pod>] [-t <testrun>] [-c <configmap>]
|
|
198
|
+
```
|
|
36
199
|
|
|
37
200
|
## Requirements
|
|
38
201
|
|
|
39
202
|
- Node.js >= 18.0.0
|
|
203
|
+
- k6 CLI available on PATH
|
|
40
204
|
- kubectl configured with access to your Kubernetes cluster
|
|
41
205
|
- k6-operator installed in your cluster
|
|
42
206
|
|
package/dist/cli.js
CHANGED
|
@@ -14,12 +14,14 @@ program
|
|
|
14
14
|
.description('CLI tool to run k6 tests on Kubernetes using k6-operator')
|
|
15
15
|
.version(package_json_1.version);
|
|
16
16
|
program
|
|
17
|
-
.command('run
|
|
18
|
-
.description('Run a k6 test script')
|
|
19
|
-
.option('-c, --config <path>', 'Path to config file', 'k6ctl.config.
|
|
17
|
+
.command('run [script]')
|
|
18
|
+
.description('Run a k6 test script (omit to select interactively from ${pwd}/dist/tests)')
|
|
19
|
+
.option('-c, --config <path>', 'Path to config file', 'k6ctl.config.json')
|
|
20
20
|
.option('-n, --namespace <namespace>', 'Kubernetes namespace')
|
|
21
21
|
.option('-p, --parallelism <number>', 'Number of parallel test pods')
|
|
22
22
|
.option('-v, --verbose', 'enable debug logging')
|
|
23
|
+
.option('-d, --dir <path>', 'Folder to search for .js test files', 'dist/tests')
|
|
24
|
+
.option('--smart', 'Enable smart scenario analysis')
|
|
23
25
|
.action(run_1.runTest);
|
|
24
26
|
program
|
|
25
27
|
.command('list')
|
|
@@ -40,9 +42,12 @@ program
|
|
|
40
42
|
.action(status_1.status);
|
|
41
43
|
program
|
|
42
44
|
.command('delete')
|
|
43
|
-
.description('Delete the last test run (TestRun +
|
|
45
|
+
.description('Delete the last test run (TestRun + script)')
|
|
44
46
|
.option('-n, --namespace <namespace>', 'Kubernetes namespace (overrides saved value)')
|
|
45
|
-
.option('--keep-
|
|
47
|
+
.option('--keep-script', 'Skip deletion of the associated script in ConfigMap or PVC')
|
|
48
|
+
.option('-p, --pod <name>', 'Delete a specific pod instead of those associated with the last TestRun')
|
|
49
|
+
.option('-t, --testrun <name>', 'Delete a specific TestRun by name instead of the last one')
|
|
50
|
+
.option('-c, --configmap <name>', 'Delete a specific ConfigMap by name instead of the one associated with the last TestRun')
|
|
46
51
|
.action(delete_1.deleteLastRun);
|
|
47
52
|
program.parse();
|
|
48
53
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AAEA,yCAA8C;AAC9C,wCAAyC;AACzC,0CAAuC;AACvC,0CAAuC;AACvC,8CAA2C;AAC3C,8CAAkD;AAClD,kDAA0C;AAE1C,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,0DAA0D,CAAC;KACvE,OAAO,CAAC,sBAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,cAAc,CAAC;KACvB,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AAEA,yCAA8C;AAC9C,wCAAyC;AACzC,0CAAuC;AACvC,0CAAuC;AACvC,8CAA2C;AAC3C,8CAAkD;AAClD,kDAA0C;AAE1C,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,0DAA0D,CAAC;KACvE,OAAO,CAAC,sBAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,cAAc,CAAC;KACvB,WAAW,CAAC,4EAA4E,CAAC;KACzF,MAAM,CAAC,qBAAqB,EAAE,qBAAqB,EAAE,mBAAmB,CAAC;KACzE,MAAM,CAAC,6BAA6B,EAAE,sBAAsB,CAAC;KAC7D,MAAM,CAAC,4BAA4B,EAAE,8BAA8B,CAAC;KACpE,MAAM,CAAC,eAAe,EAAE,sBAAsB,CAAC;KAC/C,MAAM,CAAC,kBAAkB,EAAE,qCAAqC,EAAE,YAAY,CAAC;KAC/E,MAAM,CAAC,SAAS,EAAE,gCAAgC,CAAC;KACnD,MAAM,CAAC,aAAO,CAAC,CAAC;AAEnB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,oBAAoB,CAAC;KACjC,WAAW,CAAC,IAAI,oBAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;KAC/G,MAAM,CAAC,6BAA6B,EAAE,sBAAsB,EAAE,SAAS,CAAC;KACxE,MAAM,CAAC,WAAI,CAAC,CAAC;AAEhB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,uCAAuC,CAAC;KACpD,MAAM,CAAC,6BAA6B,EAAE,8CAA8C,CAAC;KACrF,MAAM,CAAC,wBAAwB,EAAE,mCAAmC,CAAC;KACrE,MAAM,CAAC,WAAI,CAAC,CAAC;AAEhB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,kCAAkC,CAAC;KAC/C,MAAM,CAAC,6BAA6B,EAAE,8CAA8C,CAAC;KACrF,MAAM,CAAC,eAAM,CAAC,CAAC;AAElB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,6CAA6C,CAAC;KAC1D,MAAM,CAAC,6BAA6B,EAAE,8CAA8C,CAAC;KACrF,MAAM,CAAC,eAAe,EAAE,4DAA4D,CAAC;KACrF,MAAM,CAAC,kBAAkB,EAAE,yEAAyE,CAAC;KACrG,MAAM,CAAC,sBAAsB,EAAE,2DAA2D,CAAC;KAC3F,MAAM,CAAC,wBAAwB,EAAE,yFAAyF,CAAC;KAC3H,MAAM,CAAC,sBAAa,CAAC,CAAC;AAEzB,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../src/commands/delete.ts"],"names":[],"mappings":"AAIA,UAAU,aAAa;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,
|
|
1
|
+
{"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../src/commands/delete.ts"],"names":[],"mappings":"AAIA,UAAU,aAAa;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,iBA6CzD"}
|
package/dist/commands/delete.js
CHANGED
|
@@ -8,18 +8,39 @@ const kubernetes_service_1 = require("../services/kubernetes.service");
|
|
|
8
8
|
const lastRunStore_1 = require("../utils/lastRunStore");
|
|
9
9
|
const logger_1 = __importDefault(require("../utils/logger"));
|
|
10
10
|
async function deleteLastRun(options) {
|
|
11
|
+
const kubernetesService = (0, kubernetes_service_1.createDefaultKubernetesService)();
|
|
11
12
|
const lastRun = await (0, lastRunStore_1.loadLastRun)();
|
|
13
|
+
const namespace = options.namespace ?? lastRun?.namespace ?? 'default';
|
|
14
|
+
if (options.pod) {
|
|
15
|
+
logger_1.default.info(`Deleting Pod: ${options.pod} (namespace: ${namespace})`);
|
|
16
|
+
await kubernetesService.deletePodByName(options.pod, namespace);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
if (options.testrun) {
|
|
20
|
+
logger_1.default.info(`Deleting TestRun: ${options.testrun} (namespace: ${namespace})`);
|
|
21
|
+
await kubernetesService.deleteTestRunByName(options.testrun, namespace);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (options.configmap) {
|
|
25
|
+
logger_1.default.info(`Deleting ConfigMap: ${options.configmap} (namespace: ${namespace})`);
|
|
26
|
+
await kubernetesService.deleteConfigMap(options.configmap, namespace);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
12
29
|
if (!lastRun) {
|
|
13
30
|
logger_1.default.error('No last run found. Run a test first with: k6ctl run <script>');
|
|
14
31
|
process.exit(1);
|
|
15
32
|
}
|
|
16
|
-
const namespace = options.namespace ?? lastRun.namespace;
|
|
17
33
|
logger_1.default.info(`Deleting TestRun: ${lastRun.testRunName} (namespace: ${namespace})`);
|
|
18
|
-
const kubernetesService = (0, kubernetes_service_1.createDefaultKubernetesService)();
|
|
19
34
|
await kubernetesService.deleteTestRunByName(lastRun.testRunName, namespace);
|
|
20
|
-
if (!options.
|
|
21
|
-
|
|
22
|
-
|
|
35
|
+
if (!options.keepScript) {
|
|
36
|
+
if (lastRun.configMapName) {
|
|
37
|
+
logger_1.default.info(`Deleting ConfigMap: ${lastRun.configMapName} (namespace: ${namespace})`);
|
|
38
|
+
await kubernetesService.deleteConfigMap(lastRun.configMapName, namespace);
|
|
39
|
+
}
|
|
40
|
+
if (lastRun.volumeClaimName) {
|
|
41
|
+
logger_1.default.info(`Deleting PVC: ${lastRun.volumeClaimName} (namespace: ${namespace})`);
|
|
42
|
+
await kubernetesService.deleteVolumeClaimByName(lastRun.volumeClaimName, namespace);
|
|
43
|
+
}
|
|
23
44
|
}
|
|
24
45
|
await (0, lastRunStore_1.clearLastRun)();
|
|
25
46
|
logger_1.default.info('Last run state cleared.');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delete.js","sourceRoot":"","sources":["../../src/commands/delete.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"delete.js","sourceRoot":"","sources":["../../src/commands/delete.ts"],"names":[],"mappings":";;;;;AAYA,sCA6CC;AAzDD,uEAAgF;AAChF,wDAAkE;AAClE,6DAAqC;AAU9B,KAAK,UAAU,aAAa,CAAC,OAAsB;IACxD,MAAM,iBAAiB,GAAG,IAAA,mDAA8B,GAAE,CAAC;IAE3D,MAAM,OAAO,GAAG,MAAM,IAAA,0BAAW,GAAE,CAAC;IACpC,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,OAAO,EAAE,SAAS,IAAI,SAAS,CAAC;IAEvE,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,gBAAM,CAAC,IAAI,CAAC,iBAAiB,OAAO,CAAC,GAAG,gBAAgB,SAAS,GAAG,CAAC,CAAC;QACtE,MAAM,iBAAiB,CAAC,eAAe,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAChE,OAAO;IACT,CAAC;IAED,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,gBAAM,CAAC,IAAI,CAAC,qBAAqB,OAAO,CAAC,OAAO,gBAAgB,SAAS,GAAG,CAAC,CAAC;QAC9E,MAAM,iBAAiB,CAAC,mBAAmB,CAAC,OAAO,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QACxE,OAAO;IACT,CAAC;IAED,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACtB,gBAAM,CAAC,IAAI,CAAC,uBAAuB,OAAO,CAAC,SAAS,gBAAgB,SAAS,GAAG,CAAC,CAAC;QAClF,MAAM,iBAAiB,CAAC,eAAe,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QACtE,OAAO;IACT,CAAC;IAED,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,gBAAM,CAAC,KAAK,CAAC,8DAA8D,CAAC,CAAC;QAC7E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,gBAAM,CAAC,IAAI,CAAC,qBAAqB,OAAO,CAAC,WAAW,gBAAgB,SAAS,GAAG,CAAC,CAAC;IAClF,MAAM,iBAAiB,CAAC,mBAAmB,CAAC,OAAO,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAE5E,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;QACxB,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;YAC1B,gBAAM,CAAC,IAAI,CAAC,uBAAuB,OAAO,CAAC,aAAa,gBAAgB,SAAS,GAAG,CAAC,CAAC;YACtF,MAAM,iBAAiB,CAAC,eAAe,CAAC,OAAO,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;QAC5E,CAAC;QACD,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;YAC5B,gBAAM,CAAC,IAAI,CAAC,iBAAiB,OAAO,CAAC,eAAe,gBAAgB,SAAS,GAAG,CAAC,CAAC;YAClF,MAAM,iBAAiB,CAAC,uBAAuB,CAAC,OAAO,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;QACtF,CAAC;IACH,CAAC;IAED,MAAM,IAAA,2BAAY,GAAE,CAAC;IACrB,gBAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;AACzC,CAAC"}
|
package/dist/commands/list.js
CHANGED
|
@@ -11,21 +11,21 @@ async function list(type, options) {
|
|
|
11
11
|
switch (type) {
|
|
12
12
|
case 'all':
|
|
13
13
|
logger_1.default.debug(`Listing all resources in namespace: ${options.namespace}`);
|
|
14
|
-
await kubernetesService.listTestRuns(options.namespace);
|
|
15
|
-
await kubernetesService.listPods(options.namespace);
|
|
16
|
-
await kubernetesService.listConfigMaps(options.namespace);
|
|
14
|
+
(0, kubernetes_service_1.printTestRunsTable)(await kubernetesService.listTestRuns(options.namespace));
|
|
15
|
+
(0, kubernetes_service_1.printPodsTable)(await kubernetesService.listPods(options.namespace));
|
|
16
|
+
(0, kubernetes_service_1.printConfigMapsTable)(await kubernetesService.listConfigMaps(options.namespace));
|
|
17
17
|
break;
|
|
18
18
|
case 'pods':
|
|
19
19
|
logger_1.default.debug(`Listing Pods in namespace: ${options.namespace}`);
|
|
20
|
-
await kubernetesService.listPods(options.namespace);
|
|
20
|
+
(0, kubernetes_service_1.printPodsTable)(await kubernetesService.listPods(options.namespace));
|
|
21
21
|
break;
|
|
22
22
|
case 'testruns':
|
|
23
23
|
logger_1.default.debug(`Listing TestRuns in namespace: ${options.namespace}`);
|
|
24
|
-
await kubernetesService.listTestRuns(options.namespace);
|
|
24
|
+
(0, kubernetes_service_1.printTestRunsTable)(await kubernetesService.listTestRuns(options.namespace));
|
|
25
25
|
break;
|
|
26
26
|
case 'configmaps':
|
|
27
27
|
logger_1.default.debug(`Listing ConfigMaps in namespace: ${options.namespace}`);
|
|
28
|
-
await kubernetesService.listConfigMaps(options.namespace);
|
|
28
|
+
(0, kubernetes_service_1.printConfigMapsTable)(await kubernetesService.listConfigMaps(options.namespace));
|
|
29
29
|
break;
|
|
30
30
|
default:
|
|
31
31
|
logger_1.default.debug(`Listing ${type} in namespace: ${options.namespace}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":";;;;;AAGA,oBAyBC;AA5BD,6DAAsD;AACtD,
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":";;;;;AAGA,oBAyBC;AA5BD,6DAAsD;AACtD,uEAA0I;AAEnI,KAAK,UAAU,IAAI,CAAC,IAAY,EAAE,OAA+B;IACtE,MAAM,iBAAiB,GAAG,IAAA,mDAA8B,GAAE,CAAC;IAC3D,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,KAAK;YACR,gBAAM,CAAC,KAAK,CAAC,uCAAuC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;YACzE,IAAA,uCAAkB,EAAC,MAAM,iBAAiB,CAAC,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;YAC5E,IAAA,mCAAc,EAAC,MAAM,iBAAiB,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;YACpE,IAAA,yCAAoB,EAAC,MAAM,iBAAiB,CAAC,cAAc,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;YAChF,MAAM;QACR,KAAK,MAAM;YACT,gBAAM,CAAC,KAAK,CAAC,8BAA8B,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;YAChE,IAAA,mCAAc,EAAC,MAAM,iBAAiB,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;YACpE,MAAM;QACR,KAAK,UAAU;YACb,gBAAM,CAAC,KAAK,CAAC,kCAAkC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;YACpE,IAAA,uCAAkB,EAAC,MAAM,iBAAiB,CAAC,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;YAC5E,MAAM;QACR,KAAK,YAAY;YACf,gBAAM,CAAC,KAAK,CAAC,oCAAoC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;YACtE,IAAA,yCAAoB,EAAC,MAAM,iBAAiB,CAAC,cAAc,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;YAChF,MAAM;QACR;YACE,gBAAM,CAAC,KAAK,CAAC,WAAW,IAAI,kBAAkB,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;YACnE,MAAM;IACV,CAAC;AACH,CAAC"}
|
package/dist/commands/run.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AAuDA,UAAU,UAAU;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wBAAsB,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,iBAmHpE"}
|
package/dist/commands/run.js
CHANGED
|
@@ -34,6 +34,9 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.runTest = runTest;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const readline = __importStar(require("readline"));
|
|
37
40
|
const kubernetes_service_1 = require("../services/kubernetes.service");
|
|
38
41
|
const script_service_1 = require("../services/script.service");
|
|
39
42
|
const configLoader_1 = require("../utils/configLoader");
|
|
@@ -41,9 +44,62 @@ const env_1 = require("../utils/env");
|
|
|
41
44
|
const logger_1 = __importStar(require("../utils/logger"));
|
|
42
45
|
const testRunManifestBuilder_1 = require("../utils/testRunManifestBuilder");
|
|
43
46
|
const lastRunStore_1 = require("../utils/lastRunStore");
|
|
47
|
+
const DEFAULT_VUS_PER_POD = process.env.DEFAULT_VUS_PER_POD ? parseInt(process.env.DEFAULT_VUS_PER_POD, 10) : 100;
|
|
48
|
+
const MAX_ITERATION_DURATION_SECONDS = process.env.MAX_ITERATION_DURATION_SECONDS ? parseInt(process.env.MAX_ITERATION_DURATION_SECONDS, 10) : 60;
|
|
49
|
+
function listTestFiles(dir) {
|
|
50
|
+
if (!fs.existsSync(dir)) {
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
const results = [];
|
|
54
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
55
|
+
const fullPath = path.join(dir, entry.name);
|
|
56
|
+
if (entry.isDirectory()) {
|
|
57
|
+
results.push(...listTestFiles(fullPath));
|
|
58
|
+
}
|
|
59
|
+
else if (entry.isFile() && entry.name.endsWith('.js')) {
|
|
60
|
+
results.push(fullPath);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return results;
|
|
64
|
+
}
|
|
65
|
+
function promptSelection(files, dir) {
|
|
66
|
+
return new Promise((resolve, reject) => {
|
|
67
|
+
console.log('\nAvailable test scripts:');
|
|
68
|
+
files.forEach((file, i) => {
|
|
69
|
+
const relative = path.relative(dir, file);
|
|
70
|
+
console.log(` [${String(i + 1).padStart(2)}] ${relative}`);
|
|
71
|
+
});
|
|
72
|
+
console.log('');
|
|
73
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
74
|
+
rl.question(`Select a test (1-${files.length}): `, answer => {
|
|
75
|
+
rl.close();
|
|
76
|
+
const index = parseInt(answer.trim(), 10) - 1;
|
|
77
|
+
if (isNaN(index) || index < 0 || index >= files.length) {
|
|
78
|
+
reject(new Error(`Invalid selection: "${answer}"`));
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
resolve(files[index]);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
}
|
|
44
86
|
async function runTest(scriptPath, options) {
|
|
45
87
|
if (options.verbose)
|
|
46
88
|
(0, logger_1.setLogLevel)('debug');
|
|
89
|
+
if (!scriptPath) {
|
|
90
|
+
const files = listTestFiles(options.dir);
|
|
91
|
+
if (files.length === 0) {
|
|
92
|
+
logger_1.default.error(`No .js test files found in ${options.dir}`);
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
try {
|
|
96
|
+
scriptPath = await promptSelection(files, options.dir);
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
logger_1.default.error(error instanceof Error ? error.message : String(error));
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
47
103
|
logger_1.default.debug(`Running k6 test: ${scriptPath}`);
|
|
48
104
|
logger_1.default.debug(`Using config: ${JSON.stringify(options.config, null, 2)}`);
|
|
49
105
|
try {
|
|
@@ -51,9 +107,38 @@ async function runTest(scriptPath, options) {
|
|
|
51
107
|
const scriptService = new script_service_1.ScriptService();
|
|
52
108
|
const kubernetesService = (0, kubernetes_service_1.createDefaultKubernetesService)();
|
|
53
109
|
// Load test script
|
|
54
|
-
|
|
110
|
+
let archive = await scriptService.archiveTest(scriptPath);
|
|
55
111
|
// Load config
|
|
56
112
|
const config = (0, configLoader_1.loadK6Config)(options.config);
|
|
113
|
+
// Analyze script if smart option is enabled
|
|
114
|
+
if (options.smart) {
|
|
115
|
+
logger_1.default.info(`Analyzing script: ${scriptPath}`);
|
|
116
|
+
const inspectResult = await scriptService.inspectScript(scriptPath);
|
|
117
|
+
const scenarioMetrics = await analyzeScript(inspectResult);
|
|
118
|
+
if (scenarioMetrics) {
|
|
119
|
+
const estimatedTotalIterations = scenarioMetrics.reduce((sum, metrics) => sum + (metrics?.totalIterations ?? 0), 0);
|
|
120
|
+
const totalRecommendedMaxVUs = scenarioMetrics.reduce((sum, metrics) => sum + (metrics?.recommendedMaxVUs ?? 0), 0);
|
|
121
|
+
const parallelism = Math.ceil(totalRecommendedMaxVUs / DEFAULT_VUS_PER_POD) || 1;
|
|
122
|
+
const peakTps = scenarioMetrics.reduce((max, metrics) => Math.max(max, metrics?.peakTps ?? 0), 0);
|
|
123
|
+
config.parallelism = parallelism;
|
|
124
|
+
logger_1.default.info(`Total recommendedMaxVUs: ${Math.ceil(totalRecommendedMaxVUs)}
|
|
125
|
+
based on scenario analysis and MAX_ITERATION_DURATION_SECONDS=${MAX_ITERATION_DURATION_SECONDS} seconds
|
|
126
|
+
per iteration assumption with a safety factor of 1.2 applied to account for variability in iteration duration and ensure we have enough VUs
|
|
127
|
+
to meet the target TPS. This is an estimate and actual resource needs may vary based on the specific workload and environment.
|
|
128
|
+
Consider monitoring the test run and adjusting resources as needed.`);
|
|
129
|
+
logger_1.default.info(`Calculated parallelism: ${parallelism} (based on DEFAULT_VUS_PER_POD=${DEFAULT_VUS_PER_POD})`);
|
|
130
|
+
logger_1.default.info(`Peak TPS: ${peakTps.toFixed(2)}`);
|
|
131
|
+
logger_1.default.info(`Estimated Total Iterations: ${Math.round(estimatedTotalIterations)}`);
|
|
132
|
+
logger_1.default.info(`Using MAX_ITERATION_DURATION_SECONDS=${MAX_ITERATION_DURATION_SECONDS} seconds`);
|
|
133
|
+
logger_1.default.info(`Using safety factor of 1.2 to calculate recommended VUs.`);
|
|
134
|
+
logger_1.default.info(`Using DEFAULT_VUS_PER_POD=${DEFAULT_VUS_PER_POD} to calculate parallelism.`);
|
|
135
|
+
// Extract, modify, and recompress the archive
|
|
136
|
+
archive = await scriptService.extractModifyAndRecompress(archive, scenarioMetrics);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
logger_1.default.info('Smart scenario analysis is disabled. Running test without previous analysis.');
|
|
141
|
+
}
|
|
57
142
|
// Load environment variables
|
|
58
143
|
let envVars;
|
|
59
144
|
try {
|
|
@@ -63,6 +148,22 @@ async function runTest(scriptPath, options) {
|
|
|
63
148
|
logger_1.default.warn("Warning: no environment variables loaded, continuing anyway.");
|
|
64
149
|
logger_1.default.debug(`Error loading environment variables: ${error instanceof Error ? error.message : String(error)}`);
|
|
65
150
|
}
|
|
151
|
+
if (archive.archiveSize > 1024 * 1024) {
|
|
152
|
+
// Volume flow
|
|
153
|
+
logger_1.default.info(`Test script archive size (${(archive.archiveSize / (1024 * 1024)).toFixed(2)} MB) exceeds 1 MB, using volume flow.`);
|
|
154
|
+
const volumeClaimResult = await kubernetesService.createPVCWithArchive(archive, config.namespace);
|
|
155
|
+
const testRunManifest = (0, testRunManifestBuilder_1.buildTestRunManifestWithVolumeClaim)(volumeClaimResult, config, envVars);
|
|
156
|
+
await kubernetesService.createTestRun(testRunManifest);
|
|
157
|
+
await (0, lastRunStore_1.saveLastRun)({
|
|
158
|
+
testRunName: testRunManifest.metadata.name,
|
|
159
|
+
namespace: testRunManifest.metadata.namespace,
|
|
160
|
+
volumeClaimName: volumeClaimResult.volumeClaimName,
|
|
161
|
+
scriptPath,
|
|
162
|
+
createdAt: new Date().toISOString(),
|
|
163
|
+
});
|
|
164
|
+
logger_1.default.info(`Last run saved: ${testRunManifest.metadata.name} (namespace: ${testRunManifest.metadata.namespace})`);
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
66
167
|
// Create configmap for test script
|
|
67
168
|
const configMap = await kubernetesService.createConfigMap(archive, config.namespace);
|
|
68
169
|
// Build testrun
|
|
@@ -83,4 +184,93 @@ async function runTest(scriptPath, options) {
|
|
|
83
184
|
logger_1.default.error(`Error running test: ${error instanceof Error ? error.message : String(error)}`);
|
|
84
185
|
}
|
|
85
186
|
}
|
|
187
|
+
async function analyzeScript(inspectResult) {
|
|
188
|
+
if (!inspectResult.scenarios) {
|
|
189
|
+
logger_1.default.info('No scenarios found in the script. Smart analysis cannot be performed.');
|
|
190
|
+
return [];
|
|
191
|
+
}
|
|
192
|
+
const allMetrics = Object.entries(inspectResult.scenarios).map(([name, scenario]) => {
|
|
193
|
+
return calculateScenarioMetrics(name, scenario);
|
|
194
|
+
});
|
|
195
|
+
return allMetrics;
|
|
196
|
+
}
|
|
197
|
+
function calculateScenarioMetrics(name, scenario, avgIterationDurationSeconds = MAX_ITERATION_DURATION_SECONDS, safetyFactor = 1.2) {
|
|
198
|
+
if (scenario.executor !== 'ramping-arrival-rate') {
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
if (!scenario.stages || scenario.stages.length === 0) {
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
const timeUnitSeconds = parseTimeUnitToSeconds(scenario.timeUnit);
|
|
205
|
+
let previousRate = scenario.startRate ?? 0;
|
|
206
|
+
let peakTps = previousRate / timeUnitSeconds;
|
|
207
|
+
let totalIterations = 0;
|
|
208
|
+
const stageMetrics = scenario.stages.map((stage, index) => {
|
|
209
|
+
const durationSeconds = parseDurationToSeconds(stage.duration);
|
|
210
|
+
const fromTps = previousRate / timeUnitSeconds;
|
|
211
|
+
const toTps = stage.target / timeUnitSeconds;
|
|
212
|
+
const avgTps = (fromTps + toTps) / 2;
|
|
213
|
+
const estimatedIterations = avgTps * durationSeconds;
|
|
214
|
+
totalIterations += estimatedIterations;
|
|
215
|
+
peakTps = Math.max(peakTps, toTps);
|
|
216
|
+
const requiredVUsAtTarget = toTps * avgIterationDurationSeconds;
|
|
217
|
+
const recommendedVUsAtTarget = requiredVUsAtTarget * safetyFactor;
|
|
218
|
+
previousRate = stage.target;
|
|
219
|
+
return {
|
|
220
|
+
stageIndex: index + 1,
|
|
221
|
+
duration: stage.duration,
|
|
222
|
+
durationSeconds,
|
|
223
|
+
fromTps,
|
|
224
|
+
toTps,
|
|
225
|
+
avgTps,
|
|
226
|
+
estimatedIterations,
|
|
227
|
+
requiredVUsAtTarget,
|
|
228
|
+
recommendedVUsAtTarget,
|
|
229
|
+
};
|
|
230
|
+
});
|
|
231
|
+
const requiredMaxVUs = peakTps * avgIterationDurationSeconds;
|
|
232
|
+
const recommendedMaxVUs = requiredMaxVUs * safetyFactor;
|
|
233
|
+
return {
|
|
234
|
+
name,
|
|
235
|
+
peakTps,
|
|
236
|
+
totalIterations,
|
|
237
|
+
requiredMaxVUs,
|
|
238
|
+
recommendedMaxVUs,
|
|
239
|
+
stageMetrics,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
function parseDurationToSeconds(duration) {
|
|
243
|
+
const regex = /(\d+)(ms|s|m|h)/g;
|
|
244
|
+
let match;
|
|
245
|
+
let totalMs = 0;
|
|
246
|
+
while ((match = regex.exec(duration)) !== null) {
|
|
247
|
+
const value = Number(match[1]);
|
|
248
|
+
const unit = match[2];
|
|
249
|
+
switch (unit) {
|
|
250
|
+
case 'h':
|
|
251
|
+
totalMs += value * 60 * 60 * 1000;
|
|
252
|
+
break;
|
|
253
|
+
case 'm':
|
|
254
|
+
totalMs += value * 60 * 1000;
|
|
255
|
+
break;
|
|
256
|
+
case 's':
|
|
257
|
+
totalMs += value * 1000;
|
|
258
|
+
break;
|
|
259
|
+
case 'ms':
|
|
260
|
+
totalMs += value;
|
|
261
|
+
break;
|
|
262
|
+
default:
|
|
263
|
+
throw new Error(`Unsupported duration unit: ${unit}`);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
if (totalMs === 0) {
|
|
267
|
+
throw new Error(`Invalid duration format: ${duration}`);
|
|
268
|
+
}
|
|
269
|
+
return totalMs / 1000;
|
|
270
|
+
}
|
|
271
|
+
function parseTimeUnitToSeconds(timeUnit) {
|
|
272
|
+
if (!timeUnit)
|
|
273
|
+
return 1;
|
|
274
|
+
return parseDurationToSeconds(timeUnit);
|
|
275
|
+
}
|
|
86
276
|
//# sourceMappingURL=run.js.map
|
package/dist/commands/run.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAKA,UAAU,aAAa;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,MAAM,CAAC,OAAO,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAKA,UAAU,aAAa;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,MAAM,CAAC,OAAO,EAAE,aAAa,iBAsBlD"}
|
package/dist/commands/status.js
CHANGED
|
@@ -19,6 +19,10 @@ async function status(options) {
|
|
|
19
19
|
logger_1.default.info(`Script: ${lastRun.scriptPath} | Started: ${lastRun.createdAt}`);
|
|
20
20
|
const kubernetesService = (0, kubernetes_service_1.createDefaultKubernetesService)();
|
|
21
21
|
const testRun = await kubernetesService.getTestRun(lastRun.testRunName, namespace);
|
|
22
|
+
if (!testRun) {
|
|
23
|
+
logger_1.default.error(`TestRun ${lastRun.testRunName} not found in namespace ${namespace}. It may have been deleted externally.`);
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
22
26
|
(0, kubernetes_service_2.printTestRunsTable)([testRun]);
|
|
23
27
|
const podList = await kubernetesService.getPodsForTestRun(lastRun.testRunName, namespace);
|
|
24
28
|
(0, kubernetes_service_2.printPodsTable)(podList);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":";;;;;AASA,
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":";;;;;AASA,wBAsBC;AA/BD,uEAAgF;AAChF,uEAAoF;AACpF,wDAAoD;AACpD,6DAAqC;AAM9B,KAAK,UAAU,MAAM,CAAC,OAAsB;IACjD,MAAM,OAAO,GAAG,MAAM,IAAA,0BAAW,GAAE,CAAC;IACpC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,gBAAM,CAAC,KAAK,CAAC,8DAA8D,CAAC,CAAC;QAC7E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS,CAAC;IACzD,gBAAM,CAAC,IAAI,CAAC,uBAAuB,OAAO,CAAC,WAAW,gBAAgB,SAAS,GAAG,CAAC,CAAC;IACpF,gBAAM,CAAC,IAAI,CAAC,WAAW,OAAO,CAAC,UAAU,iBAAiB,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IAE/E,MAAM,iBAAiB,GAAG,IAAA,mDAA8B,GAAE,CAAC;IAE3D,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,UAAU,CAAC,OAAO,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IACnF,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,gBAAM,CAAC,KAAK,CAAC,WAAW,OAAO,CAAC,WAAW,2BAA2B,SAAS,wCAAwC,CAAC,CAAC;QACzH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,IAAA,uCAAkB,EAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IAE9B,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,iBAAiB,CAAC,OAAO,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAC1F,IAAA,mCAAc,EAAC,OAAO,CAAC,CAAC;AAC1B,CAAC"}
|