1package daemon
2
3import (
4 "runtime"
5 "testing"
6 "time"
7
8 "github.com/stretchr/testify/require"
9
10 "github.com/bnema/vev/internal/domain"
11)
12
13func TestResizeAndRetryCallbacksRejectSameObjectLeaseReplacement(t *testing.T) {
14 for _, tc := range []struct {
15 name string
16 schedule func(*renderCoordinator, *attachedClient, *attachmentLease, func())
17 done func(*testing.T, *renderCoordinator) <-chan struct{}
18 }{
19 {
20 name: "resize",
21 schedule: func(rc *renderCoordinator, ac *attachedClient, lease *attachmentLease, run func()) {
22 rc.scheduleResizeForLease(domain.Size{Cols: 100, Rows: 30}, ac, lease, func(uint64) { run() })
23 },
24 done: captureResizeCallbackDone,
25 },
26 {
27 name: "retry",
28 schedule: func(rc *renderCoordinator, ac *attachedClient, lease *attachmentLease, run func()) {
29 epoch := rc.recordResizeRequestForLease(domain.Size{Cols: 100, Rows: 30}, ac, lease)
30 require.NotZero(t, epoch)
31 require.True(t, rc.resizeCurrentForLease(epoch, ac, lease, true))
32 rc.scheduleResizeRetryForLease(epoch, ac, lease, run)
33 },
34 done: func(t *testing.T, rc *renderCoordinator) <-chan struct{} {
35 t.Helper()
36 rc.mu.Lock()
37 defer rc.mu.Unlock()
38 if rc.retryLane.token == nil {
39 t.Fatal("coordinator did not publish a retry callback completion")
40 }
41 return rc.retryLane.token.done
42 },
43 },
44 } {
45 t.Run(tc.name, func(t *testing.T) {
46 clock := newCoordinatorMockClock(t, 1)
47 rc := newRenderCoordinator(renderCoordinatorOptions{clock: clock.clock})
48 ac := &attachedClient{}
49 rc.attach(ac)
50 lease := rc.attachmentLease(ac)
51 ran := false
52 tc.schedule(rc, ac, lease, func() { ran = true })
53 timer := awaitCoordinatorScheduledTimer(t, clock)
54 done := tc.done(t, rc)
55 require.NotNil(t, done)
56
57 rc.noteDetach(ac)
58 rc.attach(ac) // resume the exact same object under a new incarnation
59 timer.ch <- time.Time{}
60 awaitTestCompletion(t, done, "stale callback did not complete")
61 for range 32 {
62 runtime.Gosched()
63 }
64 require.False(t, ran, "stale %s callback ran after lease replacement", tc.name)
65 })
66 }
67}