mirror of
https://github.com/therootcompany/golib.git
synced 2026-03-29 03:24:07 +00:00
test(auth/csvauth): regression test for Authenticate token deadlock
Guards against the v1.2.4 bug (fixed in c32acd5) where Authenticate
held a.mux via defer for its full duration, then called
loadAndVerifyToken which also tries to acquire a.mux — deadlock on
every token auth request.
TestAuthenticateTokenNoDeadlock exercises both the bare-token
("", token) and named-username ("api", token) forms with a 1s
timeout, so a regression fails fast rather than hanging the suite.
This commit is contained in:
parent
a4cb1e3bfd
commit
a854fef67e
@ -5,8 +5,59 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// TestAuthenticateTokenNoDeadlock guards against the v1.2.4 regression where
|
||||
// Authenticate held a.mux via defer and then called loadAndVerifyToken, which
|
||||
// also tried to acquire a.mux — causing a deadlock on all token auth requests.
|
||||
// Fixed in c32acd5 (ref(auth/csvauth): don't hold mutex longer than necessary).
|
||||
func TestAuthenticateTokenNoDeadlock(t *testing.T) {
|
||||
var key [16]byte
|
||||
a := New(key[:])
|
||||
|
||||
const secret = "supersecrettoken"
|
||||
c := a.NewCredential(PurposeToken, "ci-bot", secret, []string{"plain"}, []string{"deploy"}, "")
|
||||
if err := a.CacheCredential(*c); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
type result struct {
|
||||
p any
|
||||
err error
|
||||
}
|
||||
|
||||
// Authenticate("", token) — the token-as-password form
|
||||
ch := make(chan result, 1)
|
||||
go func() {
|
||||
p, err := a.Authenticate("", secret)
|
||||
ch <- result{p, err}
|
||||
}()
|
||||
select {
|
||||
case r := <-ch:
|
||||
if r.err != nil {
|
||||
t.Fatalf("Authenticate(\"\", token): unexpected error: %v", r.err)
|
||||
}
|
||||
case <-time.After(time.Second):
|
||||
t.Fatal("Authenticate deadlocked — mutex was not released before calling loadAndVerifyToken")
|
||||
}
|
||||
|
||||
// Authenticate("api", token) — the named-token-username form
|
||||
ch2 := make(chan result, 1)
|
||||
go func() {
|
||||
p, err := a.Authenticate("api", secret)
|
||||
ch2 <- result{p, err}
|
||||
}()
|
||||
select {
|
||||
case r := <-ch2:
|
||||
if r.err != nil {
|
||||
t.Fatalf("Authenticate(\"api\", token): unexpected error: %v", r.err)
|
||||
}
|
||||
case <-time.After(time.Second):
|
||||
t.Fatal("Authenticate deadlocked — mutex was not released before calling loadAndVerifyToken")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCredentialCreationAndVerification(t *testing.T) {
|
||||
type testCase struct {
|
||||
purpose string
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user