perf-skills 1.0.3 → 2.0.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.
@@ -1,251 +1,251 @@
1
- # JMeter Reference
2
-
3
- > Targets: JMeter 5.6+, Plugins Manager 1.10+
4
-
5
- Apache JMeter is the most widely used open-source performance testing tool. It supports a broad range of protocols and is extended through a rich plugin ecosystem.
6
-
7
- ---
8
-
9
- ## Core Concepts
10
-
11
- | Concept | Description |
12
- |---|---|
13
- | **Test Plan** | Root container — the `.jmx` file |
14
- | **Thread Group** | Defines VU count, ramp-up, and loop count |
15
- | **Sampler** | Makes a request (HTTP, JDBC, JMS, TCP, etc.) |
16
- | **Controller** | Logic: Loop, If, While, Throughput |
17
- | **Config Element** | HTTP Defaults, CSV Data Set, Cache Manager |
18
- | **Pre/Post Processor** | Run before/after a sampler (BeanShell, JSR223) |
19
- | **Assertion** | Validates the response (Response Code, Duration, JSON) |
20
- | **Listener** | Collects and displays results (View Results Tree, Summary) |
21
- | **Timer** | Adds think time (Constant, Gaussian, Synchronizing) |
22
-
23
- ---
24
-
25
- ## Thread Group Configuration Patterns
26
-
27
- ### Standard load ramp
28
- ```
29
- Thread Group:
30
- Number of Threads (users): 100
31
- Ramp-Up Period (seconds): 120 ← 1 VU every 1.2s, avoids thundering herd
32
- Loop Count: -1 ← run forever until duration
33
- Duration: 600 ← 10 minutes
34
- Startup Delay: 0
35
- ```
36
-
37
- ### Stepping Thread Group (requires JMeter Plugins)
38
- Use `jp@gc - Stepping Thread Group` for staged load:
39
- - Start 10 VUs, hold 60s → add 10 every 30s → max 100 VUs → hold 300s → ramp down
40
-
41
- ### Concurrency Thread Group (preferred for modern tests)
42
- Use `jp@gc - Concurrency Thread Group` for target-concurrency model:
43
- - Maintains a target concurrency level dynamically, compensates for slow VUs
44
-
45
- ---
46
-
47
- ## HTTP Sampler Best Practices
48
-
49
- - Always use **HTTP Request Defaults** config element for base URL/port/protocol — never hardcode in individual samplers.
50
- - Set **Content-Type** header in an HTTP Header Manager at Thread Group level, not per sampler.
51
- - Use **KeepAlive** (default on) for realistic connection reuse.
52
- - Use **Follow Redirects** only when your app requires it; disable otherwise for accuracy.
53
- - Avoid using **View Results Tree** listener in load tests — it's memory-intensive; use it only during script development.
54
-
55
- ---
56
-
57
- ## Correlation: Extracting Dynamic Values
58
-
59
- Correlation is the #1 cause of script failures in session-heavy apps.
60
-
61
- ### Regular Expression Extractor
62
- ```
63
- Reference Name: csrf_token
64
- Regular Expression: name="_token" value="(.+?)"
65
- Template: $1$
66
- Match No.: 1
67
- Default Value: NOT_FOUND
68
- ```
69
-
70
- ### JSON Extractor (REST APIs)
71
- ```
72
- Reference Name: access_token
73
- JSON Path: $.data.token
74
- Match No.: 1
75
- Default Value: NOT_FOUND
76
- ```
77
-
78
- ### Boundary Extractor (fastest, no regex overhead)
79
- ```
80
- Reference Name: session_id
81
- Left Boundary: "sessionId":"
82
- Right Boundary: "
83
- ```
84
-
85
- ### Using Extracted Values
86
- Reference with `${variable_name}` in subsequent requests.
87
-
88
- Always add an assertion on the extracted value:
89
- ```
90
- Response Assertion → Variable: ${csrf_token} → Pattern: NOT_FOUND → Negate
91
- ```
92
-
93
- ---
94
-
95
- ## CSV Data Set Config
96
-
97
- ```
98
- Filename: ${__P(data.dir,./data)}/users.csv
99
- Variable Names: username,password,account_id
100
- Delimiter: ,
101
- Allow Quoted Data: true
102
- Recycle on EOF: true
103
- Stop Thread on EOF: false
104
- Sharing Mode: All Threads ← or "Current Thread Group" if isolated data needed
105
- ```
106
-
107
- **Tips:**
108
- - Use `${__P(data.dir,...)}` property for portable paths across environments.
109
- - For high VU counts, ensure the CSV has at least as many rows as peak VU count to avoid data collisions.
110
- - In distributed tests, the CSV file must exist on **each injector node**, not just the controller.
111
-
112
- ---
113
-
114
- ## JSR223 Scripting (Groovy)
115
-
116
- Always use **JSR223** over BeanShell — Groovy is compiled and cached, BeanShell is not.
117
-
118
- ### Pre-processor: Generate a dynamic timestamp
119
- ```groovy
120
- import java.time.Instant
121
- vars.put("timestamp", Instant.now().toEpochMilli().toString())
122
- ```
123
-
124
- ### Post-processor: Parse JSON response
125
- ```groovy
126
- import groovy.json.JsonSlurper
127
- def json = new JsonSlurper().parseText(prev.getResponseDataAsString())
128
- vars.put("userId", json.data.id.toString())
129
- ```
130
-
131
- ### Pre-processor: Compute HMAC signature
132
- ```groovy
133
- import javax.crypto.Mac
134
- import javax.crypto.spec.SecretKeySpec
135
- def key = vars.get("api_secret")
136
- def data = vars.get("request_body")
137
- def mac = Mac.getInstance("HmacSHA256")
138
- mac.init(new SecretKeySpec(key.bytes, "HmacSHA256"))
139
- vars.put("signature", mac.doFinal(data.bytes).encodeHex().toString())
140
- ```
141
-
142
- ---
143
-
144
- ## Assertions
145
-
146
- ### Response Code Assertion
147
- ```
148
- Field to Test: Response Code
149
- Pattern: 200
150
- ```
151
-
152
- ### JSON Assertion
153
- ```
154
- JSON Path: $.status
155
- Expected Value: success
156
- ```
157
-
158
- ### Duration Assertion
159
- ```
160
- Duration to assert: 2000 ← flag any response > 2000ms
161
- ```
162
-
163
- ### Response Size Assertion
164
- Use to detect incomplete responses — flag if body < 100 bytes unexpectedly.
165
-
166
- **Important:** Add assertions to the **transaction controller level** where possible, not individual samplers, to get meaningful business-transaction-level validation.
167
-
168
- ---
169
-
170
- ## Transaction Controllers
171
-
172
- Wrap related HTTP samplers in Transaction Controllers to measure end-to-end business transaction time:
173
-
174
- ```
175
- Transaction Controller: Login Flow
176
- ├── HTTP Sampler: GET /login
177
- ├── HTTP Sampler: POST /authenticate
178
- └── HTTP Sampler: GET /dashboard
179
- ```
180
-
181
- Set **Generate Parent Sample = true** to log only the aggregate transaction (not individual child requests) in results.
182
-
183
- ---
184
-
185
- ## Timers (Think Time)
186
-
187
- | Timer | Use Case |
188
- |---|---|
189
- | Constant Timer | Simple fixed think time |
190
- | Uniform Random Timer | Range between min–max |
191
- | Gaussian Random Timer | Bell-curve distribution — most realistic |
192
- | Throughput Shaping Timer | Target a specific RPS regardless of VU count |
193
-
194
- Gaussian formula: `delay = Constant + Gaussian(deviation)`
195
- Realistic web-app think time: Gaussian with constant=3000ms, deviation=1500ms.
196
-
197
- ---
198
-
199
- ## Running JMeter Non-GUI (Command Line)
200
-
201
- > For distributed testing architecture and setup, see `../topics/test-execution.md`.
202
-
203
- Always run load tests in non-GUI mode:
204
- ```bash
205
- jmeter -n \
206
- -t test.jmx \
207
- -l results/results.jtl \
208
- -e -o results/dashboard \
209
- -Jenv=staging \
210
- -Jthreads=100 \
211
- -Jduration=600
212
- ```
213
-
214
- | Flag | Purpose |
215
- |---|---|
216
- | `-n` | Non-GUI mode |
217
- | `-t` | Test plan path |
218
- | `-l` | JTL results file |
219
- | `-e -o` | Generate HTML dashboard after run |
220
- | `-J` | Set JMeter property (use `${__P(env,dev)}` in plan) |
221
- | `-G` | Set global property (available to remote engines) |
222
-
223
- ---
224
-
225
- ## Key Plugins (JMeter Plugins Manager)
226
-
227
- | Plugin | Purpose |
228
- |---|---|
229
- | `Concurrency Thread Group` | Maintain target concurrency |
230
- | `Stepping Thread Group` | Step-ramp load profile |
231
- | `Throughput Shaping Timer` | Control RPS exactly |
232
- | `PerfMon` | Collect server-side CPU/memory via agent |
233
- | `3 Basic Graphs` | Lightweight real-time charting |
234
- | `JDBC Connection Configuration` | Database load testing |
235
- | `WebSocket Sampler` | WS protocol support |
236
- | `gRPC Sampler` | gRPC protocol support |
237
-
238
- Install plugins via: **Options → Plugins Manager → Available Plugins**
239
-
240
- ---
241
-
242
- ## JMeter-Specific Tips
243
-
244
- - **Always run in non-GUI mode** for load tests — GUI mode consumes JMeter's own resources and distorts results.
245
- - **Use HTTP Request Defaults** — hardcoded hosts make environment switching painful.
246
- - **Never put listeners inside loops** — View Results Tree in a loop will OOM the JVM.
247
- - **Use JSR223 (Groovy) over BeanShell** — Groovy is compiled and cached; BeanShell is interpreted per invocation.
248
- - **Set JVM heap** for large tests: `JVM_ARGS="-Xms2g -Xmx4g" jmeter -n -t test.jmx`
249
-
250
- > For CI/CD integration (Maven, GitHub Actions, GitLab, Jenkins), see `../topics/test-execution.md`.
251
- > For anti-patterns, assertions, think time, and parameterization principles, see **Key Principles** in `SKILL.md`.
1
+ # JMeter Reference
2
+
3
+ > Targets: JMeter 5.6+, Plugins Manager 1.10+
4
+
5
+ Apache JMeter is the most widely used open-source performance testing tool. It supports a broad range of protocols and is extended through a rich plugin ecosystem.
6
+
7
+ ---
8
+
9
+ ## Core Concepts
10
+
11
+ | Concept | Description |
12
+ |---|---|
13
+ | **Test Plan** | Root container - the `.jmx` file |
14
+ | **Thread Group** | Defines VU count, ramp-up, and loop count |
15
+ | **Sampler** | Makes a request (HTTP, JDBC, JMS, TCP, etc.) |
16
+ | **Controller** | Logic: Loop, If, While, Throughput |
17
+ | **Config Element** | HTTP Defaults, CSV Data Set, Cache Manager |
18
+ | **Pre/Post Processor** | Run before/after a sampler (BeanShell, JSR223) |
19
+ | **Assertion** | Validates the response (Response Code, Duration, JSON) |
20
+ | **Listener** | Collects and displays results (View Results Tree, Summary) |
21
+ | **Timer** | Adds think time (Constant, Gaussian, Synchronizing) |
22
+
23
+ ---
24
+
25
+ ## Thread Group Configuration Patterns
26
+
27
+ ### Standard load ramp
28
+ ```
29
+ Thread Group:
30
+ Number of Threads (users): 100
31
+ Ramp-Up Period (seconds): 120 ← 1 VU every 1.2s, avoids thundering herd
32
+ Loop Count: -1 ← run forever until duration
33
+ Duration: 600 ← 10 minutes
34
+ Startup Delay: 0
35
+ ```
36
+
37
+ ### Stepping Thread Group (requires JMeter Plugins)
38
+ Use `jp@gc - Stepping Thread Group` for staged load:
39
+ - Start 10 VUs, hold 60s → add 10 every 30s → max 100 VUs → hold 300s → ramp down
40
+
41
+ ### Concurrency Thread Group (preferred for modern tests)
42
+ Use `jp@gc - Concurrency Thread Group` for target-concurrency model:
43
+ - Maintains a target concurrency level dynamically, compensates for slow VUs
44
+
45
+ ---
46
+
47
+ ## HTTP Sampler Best Practices
48
+
49
+ - Always use **HTTP Request Defaults** config element for base URL/port/protocol - never hardcode in individual samplers.
50
+ - Set **Content-Type** header in an HTTP Header Manager at Thread Group level, not per sampler.
51
+ - Use **KeepAlive** (default on) for realistic connection reuse.
52
+ - Use **Follow Redirects** only when your app requires it; disable otherwise for accuracy.
53
+ - Avoid using **View Results Tree** listener in load tests - it's memory-intensive; use it only during script development.
54
+
55
+ ---
56
+
57
+ ## Correlation: Extracting Dynamic Values
58
+
59
+ Correlation is the #1 cause of script failures in session-heavy apps.
60
+
61
+ ### Regular Expression Extractor
62
+ ```
63
+ Reference Name: csrf_token
64
+ Regular Expression: name="_token" value="(.+?)"
65
+ Template: $1$
66
+ Match No.: 1
67
+ Default Value: NOT_FOUND
68
+ ```
69
+
70
+ ### JSON Extractor (REST APIs)
71
+ ```
72
+ Reference Name: access_token
73
+ JSON Path: $.data.token
74
+ Match No.: 1
75
+ Default Value: NOT_FOUND
76
+ ```
77
+
78
+ ### Boundary Extractor (fastest, no regex overhead)
79
+ ```
80
+ Reference Name: session_id
81
+ Left Boundary: "sessionId":"
82
+ Right Boundary: "
83
+ ```
84
+
85
+ ### Using Extracted Values
86
+ Reference with `${variable_name}` in subsequent requests.
87
+
88
+ Always add an assertion on the extracted value:
89
+ ```
90
+ Response Assertion → Variable: ${csrf_token} → Pattern: NOT_FOUND → Negate
91
+ ```
92
+
93
+ ---
94
+
95
+ ## CSV Data Set Config
96
+
97
+ ```
98
+ Filename: ${__P(data.dir,./data)}/users.csv
99
+ Variable Names: username,password,account_id
100
+ Delimiter: ,
101
+ Allow Quoted Data: true
102
+ Recycle on EOF: true
103
+ Stop Thread on EOF: false
104
+ Sharing Mode: All Threads ← or "Current Thread Group" if isolated data needed
105
+ ```
106
+
107
+ **Tips:**
108
+ - Use `${__P(data.dir,...)}` property for portable paths across environments.
109
+ - For high VU counts, ensure the CSV has at least as many rows as peak VU count to avoid data collisions.
110
+ - In distributed tests, the CSV file must exist on **each injector node**, not just the controller.
111
+
112
+ ---
113
+
114
+ ## JSR223 Scripting (Groovy)
115
+
116
+ Always use **JSR223** over BeanShell - Groovy is compiled and cached, BeanShell is not.
117
+
118
+ ### Pre-processor: Generate a dynamic timestamp
119
+ ```groovy
120
+ import java.time.Instant
121
+ vars.put("timestamp", Instant.now().toEpochMilli().toString())
122
+ ```
123
+
124
+ ### Post-processor: Parse JSON response
125
+ ```groovy
126
+ import groovy.json.JsonSlurper
127
+ def json = new JsonSlurper().parseText(prev.getResponseDataAsString())
128
+ vars.put("userId", json.data.id.toString())
129
+ ```
130
+
131
+ ### Pre-processor: Compute HMAC signature
132
+ ```groovy
133
+ import javax.crypto.Mac
134
+ import javax.crypto.spec.SecretKeySpec
135
+ def key = vars.get("api_secret")
136
+ def data = vars.get("request_body")
137
+ def mac = Mac.getInstance("HmacSHA256")
138
+ mac.init(new SecretKeySpec(key.bytes, "HmacSHA256"))
139
+ vars.put("signature", mac.doFinal(data.bytes).encodeHex().toString())
140
+ ```
141
+
142
+ ---
143
+
144
+ ## Assertions
145
+
146
+ ### Response Code Assertion
147
+ ```
148
+ Field to Test: Response Code
149
+ Pattern: 200
150
+ ```
151
+
152
+ ### JSON Assertion
153
+ ```
154
+ JSON Path: $.status
155
+ Expected Value: success
156
+ ```
157
+
158
+ ### Duration Assertion
159
+ ```
160
+ Duration to assert: 2000 ← flag any response > 2000ms
161
+ ```
162
+
163
+ ### Response Size Assertion
164
+ Use to detect incomplete responses - flag if body < 100 bytes unexpectedly.
165
+
166
+ **Important:** Add assertions to the **transaction controller level** where possible, not individual samplers, to get meaningful business-transaction-level validation.
167
+
168
+ ---
169
+
170
+ ## Transaction Controllers
171
+
172
+ Wrap related HTTP samplers in Transaction Controllers to measure end-to-end business transaction time:
173
+
174
+ ```
175
+ Transaction Controller: Login Flow
176
+ ├── HTTP Sampler: GET /login
177
+ ├── HTTP Sampler: POST /authenticate
178
+ └── HTTP Sampler: GET /dashboard
179
+ ```
180
+
181
+ Set **Generate Parent Sample = true** to log only the aggregate transaction (not individual child requests) in results.
182
+
183
+ ---
184
+
185
+ ## Timers (Think Time)
186
+
187
+ | Timer | Use Case |
188
+ |---|---|
189
+ | Constant Timer | Simple fixed think time |
190
+ | Uniform Random Timer | Range between min–max |
191
+ | Gaussian Random Timer | Bell-curve distribution - most realistic |
192
+ | Throughput Shaping Timer | Target a specific RPS regardless of VU count |
193
+
194
+ Gaussian formula: `delay = Constant + Gaussian(deviation)`
195
+ Realistic web-app think time: Gaussian with constant=3000ms, deviation=1500ms.
196
+
197
+ ---
198
+
199
+ ## Running JMeter Non-GUI (Command Line)
200
+
201
+ > For distributed testing architecture and setup, see `../topics/test-execution.md`.
202
+
203
+ Always run load tests in non-GUI mode:
204
+ ```bash
205
+ jmeter -n \
206
+ -t test.jmx \
207
+ -l results/results.jtl \
208
+ -e -o results/dashboard \
209
+ -Jenv=staging \
210
+ -Jthreads=100 \
211
+ -Jduration=600
212
+ ```
213
+
214
+ | Flag | Purpose |
215
+ |---|---|
216
+ | `-n` | Non-GUI mode |
217
+ | `-t` | Test plan path |
218
+ | `-l` | JTL results file |
219
+ | `-e -o` | Generate HTML dashboard after run |
220
+ | `-J` | Set JMeter property (use `${__P(env,dev)}` in plan) |
221
+ | `-G` | Set global property (available to remote engines) |
222
+
223
+ ---
224
+
225
+ ## Key Plugins (JMeter Plugins Manager)
226
+
227
+ | Plugin | Purpose |
228
+ |---|---|
229
+ | `Concurrency Thread Group` | Maintain target concurrency |
230
+ | `Stepping Thread Group` | Step-ramp load profile |
231
+ | `Throughput Shaping Timer` | Control RPS exactly |
232
+ | `PerfMon` | Collect server-side CPU/memory via agent |
233
+ | `3 Basic Graphs` | Lightweight real-time charting |
234
+ | `JDBC Connection Configuration` | Database load testing |
235
+ | `WebSocket Sampler` | WS protocol support |
236
+ | `gRPC Sampler` | gRPC protocol support |
237
+
238
+ Install plugins via: **Options → Plugins Manager → Available Plugins**
239
+
240
+ ---
241
+
242
+ ## JMeter-Specific Tips
243
+
244
+ - **Always run in non-GUI mode** for load tests - GUI mode consumes JMeter's own resources and distorts results.
245
+ - **Use HTTP Request Defaults** - hardcoded hosts make environment switching painful.
246
+ - **Never put listeners inside loops** - View Results Tree in a loop will OOM the JVM.
247
+ - **Use JSR223 (Groovy) over BeanShell** - Groovy is compiled and cached; BeanShell is interpreted per invocation.
248
+ - **Set JVM heap** for large tests: `JVM_ARGS="-Xms2g -Xmx4g" jmeter -n -t test.jmx`
249
+
250
+ > For CI/CD integration (Maven, GitHub Actions, GitLab, Jenkins), see `../topics/test-execution.md`.
251
+ > For anti-patterns, assertions, think time, and parameterization principles, see **Key Principles** in `SKILL.md`.