mirror of
https://github.com/lukaszraczylo/traefikoidc.git
synced 2026-10-21 04:57:48 +00:00
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
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
package traefikoidc
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestServeHTTPConcurrentLive is a concurrency hammer on the REAL middleware
|
||||
// instance: many goroutines drive ServeHTTP through the shared hot path
|
||||
// (security headers, session pool, shouldBypass, limiter, requestState
|
||||
// capture) while others hit the callback branch, run under -race. Catches
|
||||
// shared-state races (session-pool bleed, limiter, header applier) that
|
||||
// sequential tests miss (R210).
|
||||
func TestServeHTTPConcurrentLive(t *testing.T) {
|
||||
next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
})
|
||||
|
||||
oidc := &TraefikOidc{
|
||||
next: next,
|
||||
logger: NewLogger("error"),
|
||||
initComplete: make(chan struct{}),
|
||||
sessionManager: createTestSessionManager(t),
|
||||
firstRequestStarted: 1,
|
||||
metadataRefreshStartedAtomic: 1,
|
||||
redirURLPath: "/callback",
|
||||
issuerURL: "https://provider.example.com",
|
||||
perSourceLimiter: newPerSourceAuthLimiter(1000),
|
||||
}
|
||||
close(oidc.initComplete)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
var ok, nonOK, callbackHits atomic.Int64
|
||||
for g := 0; g < 8; g++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for i := 0; i < 500; i++ {
|
||||
var (
|
||||
rw = httptest.NewRecorder()
|
||||
req *http.Request
|
||||
)
|
||||
if i%10 == 0 {
|
||||
req = httptest.NewRequest(http.MethodGet, "/callback?state=s&code=c", nil)
|
||||
callbackHits.Add(1)
|
||||
} else {
|
||||
req = httptest.NewRequest(http.MethodGet, "/protected", nil)
|
||||
}
|
||||
req.Header.Set("X-Forwarded-For", "8.8.8.8")
|
||||
oidc.ServeHTTP(rw, req)
|
||||
if rw.Code == http.StatusOK {
|
||||
ok.Add(1)
|
||||
} else {
|
||||
nonOK.Add(1)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
t.Logf("concurrent sweep: ok=%d nonOK=%d callback=%d", ok.Load(), nonOK.Load(), callbackHits.Load())
|
||||
if callbackHits.Load() == 0 {
|
||||
t.Fatal("expected callback branch to be exercised")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user