Files
neural-hunt/internal/auth/auth_test.go
jbergner 005fd6ca51
Some checks failed
release-tag / release-image (push) Failing after 1m18s
RC-1
2026-08-10 05:48:55 +02:00

81 lines
1.8 KiB
Go

package auth
import (
"context"
"fmt"
"sync"
"testing"
)
func TestConcurrentChallengesSameIdentityDoNotOverwrite(t *testing.T) {
m := New(nil, "test-secret")
ctx := context.Background()
c1, err := m.NewChallenge(ctx, "client-a")
if err != nil {
t.Fatal(err)
}
c2, err := m.NewChallenge(ctx, "client-a")
if err != nil {
t.Fatal(err)
}
if c1 == c2 {
t.Fatal("expected unique challenges")
}
if err := m.ConsumeChallenge(ctx, "client-a", c1); err != nil {
t.Fatalf("first challenge should remain valid: %v", err)
}
if err := m.ConsumeChallenge(ctx, "client-a", c2); err != nil {
t.Fatalf("second challenge should remain valid: %v", err)
}
}
func TestChallengeIsOneShotAndIdentityBound(t *testing.T) {
m := New(nil, "test-secret")
ctx := context.Background()
c, err := m.NewChallenge(ctx, "client-a")
if err != nil {
t.Fatal(err)
}
if err := m.ConsumeChallenge(ctx, "client-b", c); err == nil {
t.Fatal("challenge must not be consumable by another identity")
}
if err := m.ConsumeChallenge(ctx, "client-a", c); err == nil {
t.Fatal("challenge must be one-shot after a consume attempt")
}
}
func TestManyConcurrentChallenges(t *testing.T) {
m := New(nil, "test-secret")
ctx := context.Background()
const n = 64
type item struct{ cid, challenge string }
out := make(chan item, n)
errCh := make(chan error, n)
var wg sync.WaitGroup
for i := 0; i < n; i++ {
i := i
wg.Add(1)
go func() {
defer wg.Done()
cid := fmt.Sprintf("client-%d", i)
c, err := m.NewChallenge(ctx, cid)
if err != nil {
errCh <- err
return
}
out <- item{cid: cid, challenge: c}
}()
}
wg.Wait()
close(out)
close(errCh)
for err := range errCh {
t.Fatal(err)
}
for x := range out {
if err := m.ConsumeChallenge(ctx, x.cid, x.challenge); err != nil {
t.Fatalf("consume %s: %v", x.cid, err)
}
}
}