📘 Student Guide - PerfShop¶
Welcome!¶
This guide accompanies you in learning performance testing with PerfShop.
🎯 Learning Objectives¶
By the end of this training, you will know how to: 1. Identify common performance issues 2. Use monitoring tools 3. Analyze system metrics 4. Write load test scripts 5. Propose optimization solutions
📚 Lab 1: Discovering the Application¶
Objective¶
Understand how PerfShop works without any anomaly
Steps¶
- Access the application (URL provided by the instructor)
- Log in with
user1@perfshop.com/password1 - Explore the product catalog
- Add 3 products to the cart
- Complete the checkout process
- Write down the order number
Questions¶
- How long did the complete process take?
- How many steps before the order confirmation?
- What information is requested?
🔥 Lab 2: First Anomaly — Memory Leak¶
Objective¶
Observe and understand a memory leak
Prerequisites¶
- Open the monitoring (URL provided by the instructor)
- Open the Chaos Admin
Procedure¶
- Observe the baseline (without any anomaly)
- Look at the "JVM Heap Memory" chart
-
Note the stable value of used memory
-
Enable the memory leak
- Go to Chaos Admin
- Set the "Memory Leak" slider to 100%
-
Return to the monitoring
-
Observe the evolution
- Memory rises rapidly
- After ~20 seconds: application crash
-
Charts stop refreshing
-
Restore the application
- Ask the instructor to restart it
- Or via SSH:
docker compose restart perfshop-app
Analysis¶
- What was the maximum available memory?
- How fast did memory increase?
- Why did the application crash?
- How can this problem be avoided in production?
🗄️ Lab 3: DB Connection Pool Saturation¶
Objective¶
Understand the impact of a DB pool that is too small
Procedure¶
- Normal configuration
- Observe "Database Connection Pool": 0-2 active connections
-
Browse normally: everything works
-
Enable the saturation
- Chaos Admin → "DB Pool Saturation" at 80%
-
Requests become slow
-
Test with load
- Open 5 browser tabs
- Browse simultaneously in each tab
-
Observe the slowdowns
-
Observe the metrics
- Pool saturated: all connections in use
- Requests waiting
- Possible timeouts
Analysis¶
- How many max connections in the pool?
- What happens when no more connections are available?
- What is the solution to improve performance?
⚡ Lab 4: CPU Intensive¶
Objective¶
Identify a CPU issue
Procedure¶
- CPU baseline
- CPU usage: 0-5%
-
Fast responses
-
Enable CPU chaos at 50%
- Observe the CPU increase
-
Slower navigation
-
Analyze the impact
- Measure page load time
- Compare with/without anomaly
Analysis¶
- Where is the CPU being used? (see code in GitLab)
- How can these computations be optimized?
💼 Lab 5: Business Chaos — Functional Anomalies¶
Objective¶
Identify silent anomalies in e-commerce logic — incorrect prices, inconsistent stock, unexpected behaviors — with no visible error message.
Prerequisites¶
- Be logged in with
user1@perfshop.com/password1 - Open Chaos Admin → 💼 Business Chaos tab
Procedure¶
Step 1 — Junior Level (A1, A2, A3)¶
- Chaos Admin → 🟢 Junior (level 1)
- Pick a product at €99.99 and note the displayed price — it will be rounded to €99.00 in the cart (A2)
- Place the order and record the displayed total including tax
- Manually calculate
net_amount × 1.20— the gap reveals a VAT of 19.6% instead of 20% (A1) - Go back to the ordered product page — stock is unchanged (A3)
Step 2 — Confirmed Level (+A4, A5, A6, A7)¶
- Chaos Admin → 🟡 Confirmed (level 2)
- Double-click quickly on "Order" — check "My orders": two identical orders appear (A5)
- In the order form, enter the promo code
TOTO123— it is accepted without error and without discount (A6) - Observe the confirmation email received — shipping fees are absent from the summary (A4)
Step 3 — Expert Level (+A8, A9, A10, A11)¶
- Chaos Admin → 🔴 Expert (level 3)
- Place several orders, then compare the total shown in "My orders" with the sum of orders — the total is wrong (A10)
- Log out, then within 30 seconds call
GET /api/auth/status—graceActive: trueindicates the session is still usable (A11) - Observe the 🎯 Business tab of the monitoring — A1-A11 counters and
WARN [BusinessChaos]logs appear in real time
Analysis¶
- Which anomalies are visible in the interface? Which ones are only detectable via logs?
- Which anomaly would be the most severe in production? Why?
- How would an automated regression test have detected A1 (VAT)?
⚡ Lab 5b: Functional APM Chaos — Real Java Exceptions¶
Objective¶
Use an APM tool (Tempo) to identify JVM exceptions injected into the code, locate the faulty method, and understand the causality chain.
Prerequisites¶
- Access to Grafana → STUDENT APM or INSTRUCTOR APM dashboard
- Access to Grafana → Tempo data source (traces)
- Chaos Admin → ⚡ Functional Chaos tab
Junior Level — F1 NullPointerException (Level 1)¶
- Chaos Admin → 🟢 Junior (level 1)
- Try to place an order → HTTP 500
- Open Grafana → Tempo → filter:
{span.http.method = "POST"} | status = error - Click on the red trace → identify the span in error
- Read
exception.typeandexception.messagein the span attributes - Document: which method threw the exception? what is the real simulated cause?
Confirmed Level — F2 StackOverflowError (Level 2)¶
- Chaos Admin → 🟡 Confirmed (level 2)
- Place an order → HTTP 500, truncated stacktrace
- In Tempo, compare the F1 trace and the F2 trace: is the error span the same? the duration?
- Count the repetitive frames in the stacktrace → this is the signature of infinite recursion
- Document the difference between NPE and SOE in terms of APM diagnosis
Expert Level — F3 OutOfMemoryError (Level 3)¶
- Chaos Admin → 🔴 Expert (level 3)
- Call
GET /api/productsmultiple times — observe the heap rise in Grafana - In Grafana → Pyroscope →
memory:alloc_objectsprofile → identifyapplyF3CatalogOom - Correlate: GC pause (
jvm_gc_pause_seconds_sum) vs heap (jvm_memory_used_bytes) - Document: why can the monitoring detect F3 but not F4?
Master Level — F4 Silent Corruption (Level 4)¶
The APM paradox
At this level, all traces are green in Tempo. No exceptions. HTTP 200 everywhere. Yet the shop is dysfunctional. Your mission: find the problem without any alert.
- Chaos Admin → ⭐ Master (level 4)
- Browse the shop → some prices look strange, some products appear out of stock
- Check in Tempo: no red trace — everything is green
- Call the API directly:
- Compare with the DB data (via the instructor or SSH)
- Identify the divergence point: the anomaly is in
GET /api/products/{id} - Check the container logs:
[FunctionalChaos][F4]confirms the corruptions - Observe the Grafana F4 Silent Corruptions counter → it rises on every product visit
Final analysis — F4 vs F1/F2/F3¶
| Criterion | F1/F2/F3 | F4 |
|---|---|---|
| Tempo traces | 🔴 Visible error | ✅ Green — invisible |
| HTTP status | 500 | 200 |
| Monitoring detection | Immediate | Impossible without payload inspection |
| User impact | Functional crash | Wrong data — purchase at the wrong price |
| Production severity | High (visible) | Very high (silent) |
Questions¶
- Which tool allowed you to detect F4 if monitoring sees nothing?
- How could an automated regression test (Selenium/k6) have detected F4?
- What is the difference between a "noisy" anomaly (F1-F3) and a "silent" one (F4) in terms of business risk?
🔧 Lab 6: Scripting Chaos — Dynamic HTTP Tokens¶
Objective¶
Learn to handle dynamic HTTP tokens in a test script, just as in a real enterprise API.
Prerequisites¶
- Be logged in with a test account (
user1@perfshop.com/password1) - Have JMeter or k6 installed
- Open the Chaos Admin
Procedure¶
Step 1 — Junior Level (Level 1)¶
- Chaos Admin → 🔐 Scripting Chaos tab → click 🟢 Junior
- In your test tool, create a scenario with the 3 steps:
POST /api/auth/login→ extractX-Session-Tokenfrom the responsePOST /api/cart/add→ injectX-Session-Token+X-Request-ID(generated UUID)POST /api/orders→ same headers- Without the headers → the API responds
400 Missing header: X-Session-Token - With the right headers →
200 OKon the cart,201 Createdon the order
Step 2 — Confirmed Level (Level 2)¶
- Chaos Admin → 🟡 Confirmed
- Adapt the script: also extract
X-Action-Tokenat login - Observe: after 30s without a call, the
X-Action-Tokenexpires →401 Action token expired - Implement the renewal logic (automatic re-login if > 28s)
Step 3 — Expert Level (Level 3)¶
- Chaos Admin → 🔴 Expert
- Extract 5 tokens at login:
X-Session-Token,X-Action-Token,X-CSRF-Token,X-Step-Token,X-Signature - After each successful call, update CSRF, Step and Signature from the response
- Respect the sequence: cart (
step1) before order (step2) - Everything must happen in less than 15 seconds between two calls
Expert error codes to know¶
| Code | Cause | Solution |
|---|---|---|
E-CSRF-01 |
CSRF missing or already used | Extract the new CSRF from the previous response |
E-STEP-04 |
Step out of sequence | Check the order: cart before order |
E-SIG-07 |
Invalid signature | Recompute from the current tokens |
E-TKN-99 |
Chain expired (15s) | Re-login to obtain a new chain |
Questions¶
- What is the difference between correlation and extraction?
- How do you handle expiration in a load test with 100 concurrent users?
- Why are Expert level errors intentionally cryptic?
🔐 Lab 7: Security Chaos — OWASP Vulnerabilities¶
Objective¶
Identify, exploit, and document classic web security flaws injected into PerfShop, following the OWASP Top 10 methodology.
Prerequisites¶
- Have Burp Suite Community or curl installed
- Open Chaos Admin → 🔒 Security Chaos tab
- Open the monitoring → 🔐 Security Chaos tab (real-time attack feed)
Pedagogical use only
These techniques must never be used on real systems.
Junior Level — S1, S2, S3¶
- Chaos Admin → 🟢 Junior (level 1)
- S1 — SQL Injection: call
GET /api/products/search?q=' OR '1'='1— observe whether all products are returned - S2 — IDOR: place an order, note the ID, log out, log back in with
user2@perfshop.com— accessGET /api/orders/<user1_id>— the response must be200instead of403 - S3 — Exposed hash: call
GET /api/auth/meafter login — observe thepasswordfield in the response
Confirmed Level — +S4, S5, S6¶
- Chaos Admin → 🟡 Confirmed (level 2)
- S4 — XSS: place an order with the address
<script>alert('XSS')</script>— check that the value is stored as-is in the response - S5 — Price: intercept
POST /api/orderswith Burp Suite, changeunitPriceto0.01— check thetotalAmountin the response - S6 — Timing: measure the response times of
POST /api/auth/loginfor an existing vs non-existing email — the ~300ms gap reveals the account's existence
Expert Level — +S7, S8, S9¶
- Chaos Admin → 🔴 Expert (level 3)
- S7 — HMAC token: log in, capture the
X-Debug-Tokenheader in the response, decode the left part in Base64url, change theuserId, re-sign with the keysecret123 - S8 — Path Traversal: call
GET /api/orders/1/invoice?format=../../etc/passwd— observe the simulated content returned - S9 — Mass Assignment: send
PUT /api/auth/mewith{"email": "new@email.com", "password": "hacked"}— check whether the changes are applied
Master Level — Chained scenario S10 → S11 → S12¶
- Chaos Admin → ⭐ Master (level 4)
- Discovery: analyze the shop's JS bundle (DevTools → Sources) or fuzz the routes — find
/admin - S10:
GET /api/admin/portal/stats(no token) — retrieve theadminContactemail - S11:
POST /api/admin/portal/loginwith{"email": "admin' OR '1'='1' --", "password": "x"}— retrieve theadminToken - S12:
PUT /api/admin/portal/accounts/1/promotewith headerX-Admin-Token: <token>— observeisSuperAdmin: true - Use the token to access chaos-admin and the monitoring
Analysis¶
- Which flaw is the easiest to detect with an automated scanner?
- Which flaw requires manual intervention? Why?
- In the Master scenario, which flaw is the "pivot" (without which the next ones are impossible)?
- Which HTTP header reveals the presence of level 3 chaos?
🎓 Lab 8: Complete Scenario (Advanced)¶
Objective¶
Diagnose a problem without knowing which anomaly is active
Situation¶
The instructor has enabled 2-3 anomalies. You must: 1. Identify the symptoms 2. Consult the monitoring 3. Formulate hypotheses 4. Validate with the metrics 5. Propose solutions
Methodology¶
- Observe the user symptoms
- Slow pages?
- Errors?
-
Timeouts?
-
Consult the monitoring
- Which metric is abnormal?
-
Are there any spikes?
-
Correlate the data
- High memory + frequent GC = memory leak
- CPU 100% + blocked threads = CPU intensive
-
Saturated DB connections = pool too small
-
Check the logs (via SSH)
-
Propose a solution
- Increase the pool?
- Optimize the code?
- Add more RAM?
🛠️ Tools and Resources¶
URLs (provided by the instructor)¶
- Application: frontend
- Monitoring: real-time dashboard
- Chaos Admin: anomaly control panel
- Grafana: metrics dashboards
Test Accounts¶
- user1 to user10:
userN@perfshop.com/passwordN - Perf tests:
perf.test1@perfshop.com/TestPerf123!
Useful Commands (SSH)¶
# View the logs
docker compose logs -f perfshop-app
# Restart the app
docker compose restart perfshop-app
# Reset everything
docker compose down
docker compose up -d
📊 Metrics to Watch¶
JVM¶
- Heap Memory: Used memory / Max
- GC Pauses: Garbage collector frequency
- Live Threads: Number of active threads
Tomcat¶
- Busy Threads: Threads currently running
- Request Count: Number of processed requests
Database¶
- Active Connections: DB connections in use
- Idle Connections: Available connections
HTTP¶
- Response Time p95: 95% of requests below X ms
- Error Rate: Percentage of errors
🎯 Diagnostic Tips¶
- Always start with the monitoring
- Look for visual anomalies (spikes, saturation)
- Correlate several metrics (don't rely on just one)
- Reproduce the problem to confirm it
- Test the solution before concluding
📝 Expected Deliverables¶
For each lab, write a report containing: 1. Description of the observed problem 2. Metrics collected 3. Root cause hypothesis 4. Validation of the hypothesis 5. Proposed solution 6. Result after correction
❓ FAQ¶
Q: The application is unresponsive, what should I do?
A: Ask the instructor to restart, or via SSH: docker compose restart perfshop-app
Q: How do I reset the anomalies? A: Chaos Admin → "Reset All to 0%" button
Q: Can I modify the code? A: Yes (Bac+4/5 level), the code is on GitLab. Clone, modify, rebuild.
Q: JMeter won't connect? A: Check the API URL provided by the instructor
Happy learning! 🚀