Skip to content

Commit a7dfe3d

Browse files
committed
internal/lsp: attempt to make TestDebouncer more robust
CL 309276 added logic to retry TestDebouncer if its execution was determined to be invalid. Unfortunately it also reduced the delay period, which increases the likelihood of a flake on any individual execution. This appears to have more than offset any robustness resulting from the retries. This CL does a few things to try to improve the test: - Remove t.Parallel: we want goroutines to be scheduled quickly. - Increase the debouncing delay. - Improve the logic for determining if a test was invalid. - Guard the valid variable with a mutex, since this was actually racy. For golang/go#45085 Change-Id: Ib96c9a215d58606d3341f90774706945fcf9b06c Reviewed-on: https://go-review.googlesource.com/c/tools/+/333349 Trust: Robert Findley <[email protected]> gopls-CI: kokoro <[email protected]> Run-TryBot: Robert Findley <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Rebecca Stambler <[email protected]>
1 parent 980829d commit a7dfe3d

File tree

1 file changed

+13
-11
lines changed

1 file changed

+13
-11
lines changed

internal/lsp/debounce_test.go

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ func TestDebouncer(t *testing.T) {
1818
t.Parallel()
1919

2020
const evtWait = 30 * time.Millisecond
21-
const initialDelay = 100 * time.Millisecond
21+
const initialDelay = 400 * time.Millisecond
2222

2323
type event struct {
2424
key string
@@ -65,26 +65,28 @@ func TestDebouncer(t *testing.T) {
6565
for _, test := range tests {
6666
test := test
6767
t.Run(test.label, func(t *testing.T) {
68-
t.Parallel()
69-
7068
try := func(delay time.Duration) (bool, error) {
7169
d := newDebouncer()
7270
var wg sync.WaitGroup
71+
var validMu sync.Mutex
7372
valid := true
73+
prev := -1
7474
for i, e := range test.events {
7575
wg.Add(1)
76-
start := time.Now()
77-
go func(e *event) {
78-
if time.Since(start) > evtWait {
79-
// Due to slow scheduling this event is likely to have fired out
80-
// of order, so mark this attempt as invalid.
76+
go func(i int, e *event) {
77+
// Check if goroutines were not scheduled in the intended order.
78+
validMu.Lock()
79+
if prev != i-1 {
8180
valid = false
8281
}
82+
prev = i
83+
validMu.Unlock()
84+
8385
d.debounce(e.key, e.order, delay, func() {
8486
e.fired = true
8587
})
8688
wg.Done()
87-
}(e)
89+
}(i, e)
8890
// For a bit more fidelity, sleep to try to make things actually
8991
// execute in order. This shouldn't have to be perfect: as long as we
9092
// don't have extreme pauses the test should still pass.
@@ -93,6 +95,7 @@ func TestDebouncer(t *testing.T) {
9395
}
9496
}
9597
wg.Wait()
98+
9699
var errs []string
97100
for _, event := range test.events {
98101
if event.fired != event.wantFired {
@@ -105,11 +108,10 @@ func TestDebouncer(t *testing.T) {
105108
if len(errs) > 0 {
106109
err = errors.New(strings.Join(errs, "\n"))
107110
}
108-
// If the test took less than maxwait, no event before the
109111
return valid, err
110112
}
111113

112-
if err := retryInvalid(100*time.Millisecond, try); err != nil {
114+
if err := retryInvalid(initialDelay, try); err != nil {
113115
t.Error(err)
114116
}
115117
})

0 commit comments

Comments
 (0)