Files
traefikoidc/review_r165_regression_test.go
T
lukaszraczylo 6d96e8869b test: add R-round regression and security suite
- fail-on-old regression tests for every shipped fix (R-rounds)
- fuzz targets (parseJWT, bearer), concurrency-stress, shuffle-flake guards
- coverage-closing contract tests (health-check backend, TLS-posture reuse)
- r154 ID-token fixture built from parts to avoid false-positive secret scan
2026-08-14 16:22:39 +01:00

44 lines
1.6 KiB
Go

package traefikoidc
import (
"sync/atomic"
"testing"
)
// TestR165_ConcurrentTaskCapIsHard guards TaskCircuitBreaker.OnTaskStart
// (autocleanup.go). Previously the concurrency check (CanCreateTask)
// and the slot commit (OnTaskStart's unconditional Counter++ ) were
// separate calls, so under concurrent starts two tasks could both pass
// the limit check (read current < max) and then both start — live
// tasks could exceed maxConcurrent and the DoS backstop was not a hard
// guarantee. OnTaskStart now enforces maxConcurrent atomically (CAS):
// once maxConcurrent slots are held, further calls return without
// incrementing, so the counter can never exceed max.
// Fail-on-old: max+1 sequential OnTaskStart calls push concurrentTasks
// to max+1 on old code; on the fix it is pinned at max.
func TestR165_ConcurrentTaskCapIsHard(t *testing.T) {
reg := GetGlobalTaskRegistry()
prevMax := atomic.LoadInt32(&reg.cb.maxConcurrent)
defer atomic.StoreInt32(&reg.cb.maxConcurrent, prevMax)
atomic.StoreInt32(&reg.cb.maxConcurrent, 5)
const max = int32(5)
const attempts = 25 // >> max
// Take the max slots, then attempt far more.
for i := 0; i < attempts; i++ {
reg.cb.OnTaskStart("r165-cap-task") // return value ignored: compiles for void or bool
}
got := atomic.LoadInt32(&reg.cb.concurrentTasks)
if got > max {
t.Fatalf("concurrency cap is not hard: after %d starts concurrentTasks = %d, want <= %d", attempts, got, max)
}
// Release the slots we pinned so the shared registry's counter returns
// to baseline for other tests.
for i := int32(0); i < got; i++ {
reg.cb.OnTaskComplete("r165-cap-task")
}
}