<< All versions

Skill v1.0.0

currentAutomated scan100/100
mejbaurbahar/software-tester-skills/concurrency-race-condition-testing
──Details
PublishedOctober 3, 2026 at 07:53 AM
Content Hashsha256:339b023335c660ab...
Git SHA
──Files
Files (1 file, 3.2 KB)
SKILL.md3.2 KBactive
SKILL.md · 61 lines · 3.2 KB

version: "1.0.0" name: concurrency-race-condition-testing description: Use when testing thread-safety, race conditions, deadlocks, double-submit, idempotency, optimistic/pessimistic locking, async ordering bugs, and flaky concurrency failures — with TSan, go -race, stress loops, barrier-based harnesses and parallel API calls. license: MIT metadata: category: code-level version: "2.0" tags: concurrency, race-condition, deadlock, idempotency, thread-safety, tsan, locking


Concurrency & Race-Condition Testing

Races don't fail on demand. You must force interleavings and detect violations.

Bug catalog (what to hunt)

Lost update (read-modify-write) · double spend / oversell (check-then-act) · duplicate submit / retry storms · deadlock (lock ordering) · livelock/starvation · stale cache after write · non-atomic multi-step DB ops · async callbacks out of order · TOCTOU file/permission checks · unsafe shared state in singletons · connection/thread-pool exhaustion.

Detection tools

StackTool
Gogo test -race -count=100 ./...
C/C++/RustThreadSanitizer (-fsanitize=thread), loom (Rust)
Javajcstress, -XX:+..., Thread dumps, jstack deadlock detection
Pythonpytest-xdist, threading.Barrier, asyncio.gather stress
JS/TSPromise.all bursts, jest --runInBand vs parallel diff
DBTwo sessions + pg_sleep/SLEEP() to widen windows; isolation-level tests
Systemstress-ng, k6/Locust with identical concurrent requests

Force the interleaving

python
# Fire N identical requests at the same instant (double-spend probe)
import threading, requests
N = 20; barrier = threading.Barrier(N); results = []
def hit():
barrier.wait()
results.append(requests.post(URL, json={"coupon":"ONCE"}, headers=H).status_code)
ts = [threading.Thread(target=hit) for _ in range(N)]
[t.start() for t in ts]; [t.join() for t in ts]
assert results.count(200) == 1, results # coupon must apply exactly once
bash
# bash/curl burst against an idempotent endpoint
seq 1 20 | xargs -P20 -I{} curl -s -o /dev/null -w "%{http_code}\n" -X POST -H "Idempotency-Key: k1" $URL | sort | uniq -c

What to assert

  • Exactly-once: inventory never < 0; balance conserved; one row per idempotency key; unique constraints hold.
  • Isolation: no dirty/non-repeatable/phantom reads at the level you claim (READ COMMITTED vs SERIALIZABLE).
  • Liveness: operations finish under contention (timeouts, no deadlock); lock timeouts surface clean errors.
  • Ordering: events processed in key order; consumers tolerate redelivery.

Fix patterns to recommend

Atomic SQL (UPDATE … SET qty = qty-1 WHERE qty>0) · optimistic locking (version column/ETag If-Match) · unique constraints + idempotency keys · advisory locks/SELECT … FOR UPDATE · consistent lock ordering · queue partitioning by key · immutable data.

Reporting

Include seed/iteration count, concurrency level, exact interleaving/log lines, and expected vs observed invariant. Rate by blast radius (money/data loss = Sev1).

Related

api-testing, database-testing, flaky-test-management, chaos-resilience-testing, event-driven-messaging-testing

All versions