@cloudbeat/atlas-cli 0.3.0 → 0.4.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 +46 -19
- package/dist/api.js +20 -0
- package/dist/cli.js +34 -6
- package/dist/commands/analyze.js +118 -0
- package/dist/commands/capacity.js +99 -0
- package/dist/commands/docs.js +57 -0
- package/dist/commands/files.js +18 -4
- package/dist/commands/plan.js +100 -0
- package/dist/commands/record.js +11 -1
- package/dist/commands/results.js +13 -7
- package/dist/commands/schema.js +86 -0
- package/dist/commands/skills.js +111 -0
- package/dist/commands/tests.js +73 -0
- package/dist/docs/agent-setup.md +109 -0
- package/dist/docs/agent-tasks.md +169 -0
- package/dist/docs/ai-agents.md +90 -0
- package/dist/docs/auth.md +74 -0
- package/dist/docs/automation.md +150 -0
- package/dist/docs/ci.md +105 -0
- package/dist/docs/clusters.md +48 -0
- package/dist/docs/commands.md +155 -0
- package/dist/docs/files.md +86 -0
- package/dist/docs/generators.md +52 -0
- package/dist/docs/getting-started.md +85 -0
- package/dist/docs/index.json +110 -0
- package/dist/docs/projects.md +50 -0
- package/dist/docs/recorder.md +143 -0
- package/dist/docs/results.md +79 -0
- package/dist/docs/running.md +80 -0
- package/dist/docs/skills.md +88 -0
- package/dist/docs/test-plans.md +92 -0
- package/dist/docs/troubleshooting.md +79 -0
- package/dist/plan.js +250 -0
- package/dist/skills/AGENTS.md +70 -0
- package/dist/skills/atlas-analyze/SKILL.md +104 -0
- package/dist/skills/atlas-correlate/SKILL.md +89 -0
- package/dist/skills/atlas-load-test/SKILL.md +154 -0
- package/dist/skills/atlas-record/SKILL.md +167 -0
- package/dist/skills/atlas-run/SKILL.md +109 -0
- package/dist/skills/atlas-test-plan/SKILL.md +281 -0
- package/package.json +5 -3
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: atlas-correlate
|
|
3
|
+
description: Handle dynamic values in a recorded load-test scenario - CSRF tokens, session ids, anything the server issues per session - by reviewing what the Atlas recorder detected and pinning the rest. Use when a recorded test plan fails on replay, returns login pages or 403s under load, or when someone asks about correlation or parameterisation.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Dynamic values
|
|
7
|
+
|
|
8
|
+
A recording captures literals. If the server issued a value for that one session
|
|
9
|
+
— a CSRF token, a session id, an order reference — replaying the literal fails,
|
|
10
|
+
usually as a 403, a redirect back to the login page, or an application error that
|
|
11
|
+
only appears when the test runs.
|
|
12
|
+
|
|
13
|
+
The recorder already handles this on evidence: a value a request sends is
|
|
14
|
+
correlated only if that exact value appeared in an **earlier response**. That rule
|
|
15
|
+
keeps it from rewriting things that merely look dynamic, but it also means it
|
|
16
|
+
cannot catch a value the browser computed on its own.
|
|
17
|
+
|
|
18
|
+
## Review what it found
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
atlas-rec suggest flow.capture.json
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Each suggestion shows the variable, the value, **where it came from** (the
|
|
25
|
+
response that defined it, and how it will be extracted) and **who sends it**.
|
|
26
|
+
Judge them:
|
|
27
|
+
|
|
28
|
+
- Source is the application, extraction looks stable, consumers make sense →
|
|
29
|
+
keep it.
|
|
30
|
+
- The value is a fixed application constant that merely appeared in a response
|
|
31
|
+
(a country code, a page size) → correlating it is harmless but pointless.
|
|
32
|
+
- A value that is sent but appears in **no** earlier response → the recorder
|
|
33
|
+
cannot correlate it, and it is exactly the kind that breaks. Find out what it
|
|
34
|
+
is: generated in the browser (a timestamp, a random id, a fingerprint), or
|
|
35
|
+
supposed to vary per user (a login, an account number).
|
|
36
|
+
|
|
37
|
+
## Pin the rest yourself
|
|
38
|
+
|
|
39
|
+
Write a rules file mapping parameter names to what should be sent instead:
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"authToken": "${authToken}",
|
|
44
|
+
"username": "${user}",
|
|
45
|
+
"requestId": "${__UUID()}"
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
- `${user}` — a variable the plan reads from a data file. Per-user data belongs
|
|
50
|
+
in a CSV, not in the plan.
|
|
51
|
+
- `${__UUID()}`, `${__time()}` — JMeter functions, for values that just have to
|
|
52
|
+
be fresh and unique.
|
|
53
|
+
- A literal — when the value genuinely is a constant.
|
|
54
|
+
|
|
55
|
+
Timestamps are already replaced with `${__time()}` automatically; `--no-timestamps`
|
|
56
|
+
turns that off.
|
|
57
|
+
|
|
58
|
+
Then rebuild the plan from the same capture — no re-recording:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
atlas-rec generate flow.capture.json -o flow.jmx --correlations rules.json
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Preset rules win over auto-correlation for the same parameter name, so a rule is
|
|
65
|
+
how you override a detection you disagree with. `--no-correlate` turns detection
|
|
66
|
+
off entirely and replays everything literally; that is a debugging tool, rarely
|
|
67
|
+
what you want.
|
|
68
|
+
|
|
69
|
+
## Prove it before scaling
|
|
70
|
+
|
|
71
|
+
Correlation is not verified until the plan runs against the application. Upload
|
|
72
|
+
it and smoke-run it (see `atlas-load-test`), then:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
atlas errors <testId> --full
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Read the actual responses. The tells that correlation is still wrong:
|
|
79
|
+
|
|
80
|
+
- 403 / 419 / "invalid token" / "session expired" on requests that worked while
|
|
81
|
+
recording.
|
|
82
|
+
- A 200 that returns the **login page** — technically a success, functionally a
|
|
83
|
+
failed test. Response-time numbers from a run like that are meaningless, and
|
|
84
|
+
they look good, which is the dangerous part.
|
|
85
|
+
- The first iteration passes and later ones fail: something is being reused that
|
|
86
|
+
should be re-fetched per iteration.
|
|
87
|
+
|
|
88
|
+
Run it with two users and two iterations rather than one of each — a single pass
|
|
89
|
+
hides exactly this class of bug.
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: atlas-load-test
|
|
3
|
+
description: Run a load test with Atlas end to end - record or pick a test plan, upload test data, size the run, do a smoke test, run it, and report the results. Use when someone asks to load-test an application, create or run a performance test, check whether a site handles N users, or interpret a test that has already run.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Load testing with Atlas
|
|
7
|
+
|
|
8
|
+
This is the ordered flow. Work through it in order, stop at each **Ask** and wait
|
|
9
|
+
for an answer, and never skip the smoke run. Other skills cover the detail:
|
|
10
|
+
`atlas-record` (capturing a scenario), `atlas-test-plan` (downloading, editing
|
|
11
|
+
and uploading plans and data files), `atlas-correlate` (dynamic values),
|
|
12
|
+
`atlas-run` (sizing and gates), `atlas-analyze` (reading results).
|
|
13
|
+
|
|
14
|
+
A load test costs real machine time on someone's account. Treat starting one the
|
|
15
|
+
way you would treat a deploy: confirm before you spend.
|
|
16
|
+
|
|
17
|
+
## 0. Check the ground
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
atlas whoami --json # who, which account, which instance
|
|
21
|
+
atlas projects --json # what this credential can see
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
If `whoami` fails with exit code 2, the person needs to authenticate — tell them
|
|
25
|
+
to run `atlas login --token <token>` with a token from their Profile page. Do not
|
|
26
|
+
ask for their password.
|
|
27
|
+
|
|
28
|
+
If `atlas` itself is missing: `npm install -g @cloudbeat/atlas-cli`.
|
|
29
|
+
|
|
30
|
+
## 1. Pick the project
|
|
31
|
+
|
|
32
|
+
**Ask** which project, if it is not obvious from the request or already set
|
|
33
|
+
(`atlas config get`). Projects are the unit that owns test plans, data files and
|
|
34
|
+
run history. Do not create one — that is done in the web interface.
|
|
35
|
+
|
|
36
|
+
## 2. Get a test plan
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
atlas files list -p <project> --json
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Three cases, and **ask** which one applies if the request does not already say:
|
|
43
|
+
|
|
44
|
+
- **Use an existing plan as it is.** When several exist, ask which — `--jmx`
|
|
45
|
+
chooses, and the project's default may not be the one they mean.
|
|
46
|
+
- **Change an existing plan**, or add a new scenario to it. Follow
|
|
47
|
+
`atlas-test-plan`: download it first, because uploading replaces the stored
|
|
48
|
+
file and there is no version history.
|
|
49
|
+
- **Record a new one.** Follow `atlas-record`, then `atlas-test-plan` to check
|
|
50
|
+
and upload it.
|
|
51
|
+
|
|
52
|
+
## 3. Test data and a plan that will actually run
|
|
53
|
+
|
|
54
|
+
Plans usually read a CSV or TXT file per user (logins, search terms, IDs). Check
|
|
55
|
+
the plan against what the project holds, rather than assuming:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
atlas plan check -p <project> --jmx <plan>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
That reports a data file the plan reads but the project does not have — the
|
|
62
|
+
failure that makes an entire thread group disappear from the results with **no
|
|
63
|
+
errors at all**. Upload whatever is missing, and anything that has gone stale:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
atlas files upload -p <project> ./users.csv ./search-terms.txt
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Worth saying out loud, because it surprises people: data files are **divided
|
|
70
|
+
between machines**, not copied to each. Ten thousand rows across five machines is
|
|
71
|
+
two thousand rows each. If every machine must see every row, the run needs
|
|
72
|
+
`--no-split`. The rest of the file lifecycle is in `atlas-test-plan`.
|
|
73
|
+
|
|
74
|
+
## 4. Size the run
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
atlas capacity --json
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
This gives machines, clusters, how many are free, and how much usage allowance is
|
|
81
|
+
left. Read it **before** asking, so the question is grounded in real numbers.
|
|
82
|
+
|
|
83
|
+
**Ask** three things:
|
|
84
|
+
|
|
85
|
+
1. How many concurrent users should the test reach?
|
|
86
|
+
2. How long should it run, and over how long should users ramp up?
|
|
87
|
+
3. Fixed machines or a cluster? (Only if both are available.)
|
|
88
|
+
|
|
89
|
+
Then do the arithmetic and show your working: **each machine runs the whole plan
|
|
90
|
+
independently**, so total users = users-in-the-plan x machines. A plan with 100
|
|
91
|
+
users on 5 machines is 500 users. A plan recorded with the recorder exposes its
|
|
92
|
+
size as a run-time setting, so you can size it without editing the file:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
atlas run -p <project> --jmx flow.jmx --servers 5 --args "-Jthreads=100 -Jrampup=300"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
If the plan was not written that way, the thread counts are fixed inside the
|
|
99
|
+
file, and machines are the only dial you have. Say so rather than silently
|
|
100
|
+
running the wrong size.
|
|
101
|
+
|
|
102
|
+
## 5. Smoke run first
|
|
103
|
+
|
|
104
|
+
Never go straight to the full run. One machine, a couple of users, a minute or
|
|
105
|
+
two:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
atlas run -p <project> --jmx <plan> --servers 1 --args "-Jthreads=2 -Jloops=2" --wait
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Then check it actually worked, which the exit code alone does not tell you:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
atlas results <testId> --json
|
|
115
|
+
atlas errors <testId> --json
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Look for: every thread group present, requests actually sent, errors understood.
|
|
119
|
+
A smoke run that finishes in seconds with no data is a broken plan, not a fast
|
|
120
|
+
application — `atlas-analyze` lists the usual causes. Fix that before scaling up.
|
|
121
|
+
|
|
122
|
+
**Ask** for confirmation before the full run, showing what you are about to
|
|
123
|
+
start: plan, machines, users, duration, and the smoke result.
|
|
124
|
+
|
|
125
|
+
## 6. The full run
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
atlas run -p <project> --jmx <plan> --servers <n> \
|
|
129
|
+
--args "-Jthreads=<per machine> -Jrampup=<seconds>" \
|
|
130
|
+
--wait --gate "error_rate<1,p95<2000"
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
`--wait` blocks until it finishes; `--gate` turns the result into a pass or fail
|
|
134
|
+
(exit code 1 when a threshold is breached). Tell the person the test id and the
|
|
135
|
+
dashboard link as soon as the run starts, so they can watch it themselves.
|
|
136
|
+
|
|
137
|
+
If they do not want to wait, drop `--wait` and poll `atlas status <testId>`.
|
|
138
|
+
|
|
139
|
+
## 7. Report
|
|
140
|
+
|
|
141
|
+
Follow `atlas-analyze`. A useful report answers: did it pass, what was the
|
|
142
|
+
response time under load, where did it start to degrade, what failed and why, and
|
|
143
|
+
what to do next. Percentiles matter more than averages, and the error detail
|
|
144
|
+
matters more than the error rate.
|
|
145
|
+
|
|
146
|
+
## Guardrails
|
|
147
|
+
|
|
148
|
+
- **Confirm before starting a full run.** Machines get powered on and billed.
|
|
149
|
+
- **Never stop someone else's run.** `atlas tests -p <project>` shows what is
|
|
150
|
+
running; if something is already going, ask before touching it.
|
|
151
|
+
- **Report what happened, not what should have happened.** If a thread group is
|
|
152
|
+
missing or a gate failed, say so plainly with the numbers.
|
|
153
|
+
- **`atlas stop` can come back unconfirmed.** If it reports machines it could not
|
|
154
|
+
reach, the test may still be running — say that rather than "stopped".
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: atlas-record
|
|
3
|
+
description: Record a browser scenario into a JMeter test plan with the Atlas recorder, including driving the browser yourself - open pages, click, fill forms, name transactions - and rebuilding the plan from a capture afterwards. Use when someone wants to create a load-test scenario from a real user flow, or asks you to click through an application and turn it into a test.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Recording a scenario
|
|
7
|
+
|
|
8
|
+
The recorder watches a real browser session and writes a JMeter plan from it.
|
|
9
|
+
A person can click through the flow themselves, or you can do the clicking. Both
|
|
10
|
+
are recorded the same way, and both can happen in the same session.
|
|
11
|
+
|
|
12
|
+
Requires `@cloudbeat/atlas-recorder` (`npm install -g @cloudbeat/atlas-recorder`).
|
|
13
|
+
It downloads its own browser on install.
|
|
14
|
+
|
|
15
|
+
## Which mode
|
|
16
|
+
|
|
17
|
+
**Ask** which the person wants, unless the request already says:
|
|
18
|
+
|
|
19
|
+
- **They click** — `atlas-rec record <url> -o flow.jmx`. Blocks until they press
|
|
20
|
+
Stop. Use this when the flow needs a human: a password only they know, a 2FA
|
|
21
|
+
prompt, a decision about what to test.
|
|
22
|
+
- **You click** — the commands below. Use this when the flow is mechanical and
|
|
23
|
+
they have told you what to do.
|
|
24
|
+
|
|
25
|
+
Either way the window is visible and they can watch, or take over.
|
|
26
|
+
|
|
27
|
+
## Driving it yourself
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
atlas-rec start https://shop.example.com -o flow.jmx -n "Checkout"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Returns JSON with a `sessionId`. The browser is now open and recording. Later
|
|
34
|
+
commands find the session automatically when only one is running; pass
|
|
35
|
+
`--session <id>` when more than one is.
|
|
36
|
+
|
|
37
|
+
**Look before you act.** `snapshot` gives the page as an accessibility tree —
|
|
38
|
+
what is there and what can be clicked:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
atlas-rec snapshot
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Then act. Prefer the target the snapshot actually showed you:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
atlas-rec click --role button --name "Find Flights"
|
|
48
|
+
atlas-rec click --text "Choose This Flight" # by visible text
|
|
49
|
+
atlas-rec fill "you@example.com" --selector "#email"
|
|
50
|
+
atlas-rec select "Rome" --selector "select[name=toPort]"
|
|
51
|
+
atlas-rec press Enter --selector "#search"
|
|
52
|
+
atlas-rec wait --selector "table" # or --url, or --ms
|
|
53
|
+
atlas-rec goto https://shop.example.com/cart
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Add `--nth <n>` when several things match. Snapshot again after anything that
|
|
57
|
+
changes the page — do not assume the click landed where you expected.
|
|
58
|
+
|
|
59
|
+
## Name the steps as you go
|
|
60
|
+
|
|
61
|
+
Each user action becomes a transaction in the plan, and transaction names are
|
|
62
|
+
what the results are reported against. Auto-generated names like "Rome" are
|
|
63
|
+
useless in a report. Name the step **before** you perform it:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
atlas-rec tx new "Search flights"
|
|
67
|
+
atlas-rec click --role button --name "Find Flights"
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Check what has been captured at any point:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
atlas-rec state # one line per transaction
|
|
74
|
+
atlas-rec state --full # every captured request
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Housekeeping while recording:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
atlas-rec tx rename t3 "Add to cart"
|
|
81
|
+
atlas-rec req exclude r12 # keep a request out of the plan
|
|
82
|
+
atlas-rec req delete r12 # drop it from the recording entirely
|
|
83
|
+
atlas-rec pause / atlas-rec resume
|
|
84
|
+
atlas-rec scenario "Checkout"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Finishing
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
atlas-rec stop
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
This writes the plan and a capture file beside it, and returns both paths. The
|
|
94
|
+
plan is also written if the window is closed or the process is interrupted — a
|
|
95
|
+
recording is not lost by closing the browser.
|
|
96
|
+
|
|
97
|
+
## Signing in
|
|
98
|
+
|
|
99
|
+
Three options, in order of preference:
|
|
100
|
+
|
|
101
|
+
- `--cookies <file>` — exported cookies, so the recording starts already signed
|
|
102
|
+
in. Accepts Cookie-Editor, Netscape, a raw `Cookie:` header, or a storage-state
|
|
103
|
+
file.
|
|
104
|
+
- `--profile <file>` — saves the signed-in session on stop and reuses it next
|
|
105
|
+
time. Good for repeated recordings against the same app.
|
|
106
|
+
- Record the login itself — but then the plan contains one user's credentials and
|
|
107
|
+
every simulated user will send them. That is usually wrong: a real test needs a
|
|
108
|
+
data file of users. Say so.
|
|
109
|
+
|
|
110
|
+
Never ask for a password to type into the browser yourself. If the flow needs
|
|
111
|
+
credentials, hand the window back to the person for that step: they can type it
|
|
112
|
+
while the recording is live, and it is captured like anything else.
|
|
113
|
+
|
|
114
|
+
## After the recording
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
atlas-rec inspect flow.capture.json # transactions, hosts, response codes
|
|
118
|
+
atlas-rec suggest flow.capture.json # values that change per session
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Read `inspect` before declaring success. Things to check:
|
|
122
|
+
|
|
123
|
+
- Every step you performed has a transaction, and the count of included requests
|
|
124
|
+
is not zero.
|
|
125
|
+
- No 4xx/5xx in `statusCodes` that you did not expect — a failed request recorded
|
|
126
|
+
as-is becomes a failing request in the test.
|
|
127
|
+
- Hosts are the application's, not a third party's. Analytics and CDN traffic is
|
|
128
|
+
filtered out already, but an embedded widget may not be.
|
|
129
|
+
|
|
130
|
+
## Then stop and agree the next step
|
|
131
|
+
|
|
132
|
+
A recording is a draft, not a test. When you have stopped, **report what you
|
|
133
|
+
captured and ask what to do with it** — do not upload it, and do not start
|
|
134
|
+
editing it, before the person has answered.
|
|
135
|
+
|
|
136
|
+
Say what is there: the scenario name, each transaction with its request count,
|
|
137
|
+
any unexpected status codes, and where the plan and capture files are. Then work
|
|
138
|
+
through the stages with them — flow, test data, dynamic values, checks, upload —
|
|
139
|
+
asking rather than deciding. Those stages are in `atlas-test-plan`, under
|
|
140
|
+
"Turning a recording into a test"; **read it before suggesting what comes next**,
|
|
141
|
+
because the question it insists on (which recorded values every simulated user
|
|
142
|
+
would otherwise repeat) is what separates a load test from a replay.
|
|
143
|
+
|
|
144
|
+
Rebuild the plan from the capture rather than re-recording whenever the change is
|
|
145
|
+
in how the plan is generated:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
atlas-rec generate flow.capture.json -o flow.jmx --correlations rules.json
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
The same capture always produces the same plan, so this is safe to repeat.
|
|
152
|
+
|
|
153
|
+
## Things that will bite you
|
|
154
|
+
|
|
155
|
+
- **Never trigger a native dialog** (`alert`, `confirm`, a file picker). They
|
|
156
|
+
block the browser and the session stops responding. Avoid clicking anything
|
|
157
|
+
that might delete or confirm.
|
|
158
|
+
- **One click can record two requests** when a page redirects, so a step can hit
|
|
159
|
+
its destination twice per iteration. Check `inspect` and exclude the duplicate.
|
|
160
|
+
- **Everything before the first action is one transaction** — redirects, an SSO
|
|
161
|
+
hop, a failed load. Rename it to something meaningful.
|
|
162
|
+
- **The recording is one pass.** A cookie banner, an A/B variant or a retry that
|
|
163
|
+
did not happen while you clicked is not in the plan.
|
|
164
|
+
- **Recorded values are literal.** A search term, a product id, a date you picked
|
|
165
|
+
will be sent by every simulated user unless it is parameterised from a data
|
|
166
|
+
file. Flag this to the person; it is usually the difference between a realistic
|
|
167
|
+
test and a cached one.
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: atlas-run
|
|
3
|
+
description: Start and size an Atlas load test - how many machines or cluster units, how users map onto them, ramp-up, pass/fail gates, exit codes and CI usage. Use when someone asks to run a test, asks how many machines they need, wants a test to fail a build on a threshold, or is waiting on a queued run.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Running and sizing
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
atlas run -p <project> --jmx <plan> --servers 5 --wait --gate "error_rate<1,p95<2000"
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## How load adds up
|
|
13
|
+
|
|
14
|
+
**Each machine runs the whole plan independently.** There is no controller
|
|
15
|
+
splitting users between them. So:
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
total users = users in the plan x number of machines
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
A plan with 100 users on 5 machines is 500 concurrent users. This is the single
|
|
22
|
+
most common thing to get wrong, and it is wrong by a factor of the fleet size.
|
|
23
|
+
|
|
24
|
+
A plan produced by the recorder exposes its size as run-time settings, so you can
|
|
25
|
+
scale it without editing the file:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
atlas run -p SHOP --jmx flow.jmx --servers 5 --args "-Jthreads=100 -Jrampup=300 -Jloops=-1"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
- `-Jthreads` — users **per machine**
|
|
32
|
+
- `-Jrampup` — seconds to start them all; ramping 500 users instantly tests your
|
|
33
|
+
own patience, not the application
|
|
34
|
+
- `-Jloops` — iterations per user; `-1` is continuous
|
|
35
|
+
|
|
36
|
+
An older or hand-written plan usually has fixed numbers inside it. Then machines
|
|
37
|
+
are the only dial, and a plan with 2 users cannot be made into a 500-user test by
|
|
38
|
+
asking for 5 machines. Say so instead of running it anyway.
|
|
39
|
+
|
|
40
|
+
## Where it runs
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
atlas capacity --json
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
- `--servers <n>` — n available machines
|
|
47
|
+
- `--server <name...>` — specific machines by name
|
|
48
|
+
- `--cluster <name> --units <n>` — elastic capacity: n containers created for the
|
|
49
|
+
test and destroyed afterwards
|
|
50
|
+
|
|
51
|
+
Machines that are off are fine: they are powered on for the run and powered off
|
|
52
|
+
afterwards. That is also why a run costs money — confirm before starting a large
|
|
53
|
+
one.
|
|
54
|
+
|
|
55
|
+
If every machine is busy, the run is **queued** rather than rejected, and starts
|
|
56
|
+
when they free up. `atlas run` says so; with `--wait` it waits through the queue.
|
|
57
|
+
|
|
58
|
+
## Data files
|
|
59
|
+
|
|
60
|
+
Data files are **divided** between machines by default — 10,000 rows across 5
|
|
61
|
+
machines is 2,000 each, so no two users get the same row. Use `--no-split` when
|
|
62
|
+
every machine must see the whole file (a small lookup table, a list of products
|
|
63
|
+
every user should hit).
|
|
64
|
+
|
|
65
|
+
## Gates
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
--gate "error_rate<1,p95<2000" --gate "throughput>50"
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Metrics: `error_rate`, `avg`, `p90`, `p95`, `p99`, `max`, `throughput`,
|
|
72
|
+
`requests`, with `<`, `<=`, `>`, `>=`. They are evaluated against the whole test.
|
|
73
|
+
`--gate` and `--junit` imply `--wait`, because there is nothing to judge until
|
|
74
|
+
the run has finished.
|
|
75
|
+
|
|
76
|
+
## Exit codes
|
|
77
|
+
|
|
78
|
+
| Code | Meaning |
|
|
79
|
+
|---|---|
|
|
80
|
+
| 0 | ran, every gate passed |
|
|
81
|
+
| 1 | ran, a gate was breached |
|
|
82
|
+
| 2 | usage error: bad flags, unknown project, not authenticated |
|
|
83
|
+
| 3 | the run failed or timed out, or the server was unreachable |
|
|
84
|
+
|
|
85
|
+
1 and 3 are different in the way that matters for CI: 1 is a result, 3 is a
|
|
86
|
+
failure to get a result. Do not paper over either.
|
|
87
|
+
|
|
88
|
+
## In CI
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
atlas run -p SHOP --jmx flow.jmx --servers 3 --wait \
|
|
92
|
+
--gate "error_rate<1,p95<2000" --junit results.xml
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Authenticate with a token in `ATLAS_TOKEN` — never a password. A token acts as
|
|
96
|
+
its owner in one account, and it stops working the moment that user is removed.
|
|
97
|
+
|
|
98
|
+
## While it runs, and stopping
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
atlas status <testId> # still going? headline numbers
|
|
102
|
+
atlas tests -p <project> # recent runs, including anything running now
|
|
103
|
+
atlas stop <testId>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
`atlas stop` only reports success once it has **confirmed** the process is gone
|
|
107
|
+
on every machine. If it comes back with machines it could not reach, the test may
|
|
108
|
+
well still be running and reporting: say that, and retry. Treating an unconfirmed
|
|
109
|
+
stop as a stop is how a runaway test goes unnoticed for hours.
|