mirror of
https://github.com/profullstack/agentbbs.git
synced 2026-08-13 22:37:28 +00:00
test(games): reproduce duplicate queue deadlock
This commit is contained in:
parent
be75744248
commit
97ce177dd3
1 changed files with 40 additions and 0 deletions
|
|
@ -2,6 +2,7 @@ package games
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"math"
|
||||
"sync"
|
||||
"testing"
|
||||
|
|
@ -133,3 +134,42 @@ func TestMatchmakerUnknownGame(t *testing.T) {
|
|||
t.Fatalf("want ErrUnknownGame, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMatchmakerRejectsDuplicateWaiter(t *testing.T) {
|
||||
mm := NewMatchmaker(Catalog(), nil, time.Second, time.Minute)
|
||||
firstCtx, cancelFirst := context.WithCancel(context.Background())
|
||||
firstDone := make(chan error, 1)
|
||||
go func() {
|
||||
firstDone <- mm.Play(firstCtx, "ttt", &firstLegalPlayer{name: "same-agent"})
|
||||
}()
|
||||
|
||||
deadline := time.Now().Add(time.Second)
|
||||
for {
|
||||
mm.mu.Lock()
|
||||
queued := mm.queue["ttt"] != nil
|
||||
mm.mu.Unlock()
|
||||
if queued {
|
||||
break
|
||||
}
|
||||
if time.Now().After(deadline) {
|
||||
t.Fatal("first player never entered the queue")
|
||||
}
|
||||
time.Sleep(time.Millisecond)
|
||||
}
|
||||
|
||||
duplicateCtx, cancelDuplicate := context.WithTimeout(context.Background(), 50*time.Millisecond)
|
||||
defer cancelDuplicate()
|
||||
if err := mm.Play(duplicateCtx, "ttt", &firstLegalPlayer{name: "same-agent"}); err == nil || errors.Is(err, context.DeadlineExceeded) {
|
||||
t.Fatalf("duplicate Play error = %v, want immediate already-queued rejection", err)
|
||||
}
|
||||
|
||||
cancelFirst()
|
||||
select {
|
||||
case err := <-firstDone:
|
||||
if !errors.Is(err, context.Canceled) {
|
||||
t.Fatalf("first Play error = %v, want context.Canceled", err)
|
||||
}
|
||||
case <-time.After(100 * time.Millisecond):
|
||||
t.Fatal("first player remained blocked after its context was canceled")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue