check / check (push) Successful in 57s
The live-DNS retry and concurrency limit is only for tests, but nothing stopped program code from importing it and compiling it into the binary. Its directory name now ends in test, and its import path is on the test-support deny list in .golangci.yml, so make lint fails when a file that is not a test imports it. Every import and mention is updated to the new name. Model: opus-5-5
104 lines
1.8 KiB
Go
104 lines
1.8 KiB
Go
package livednstest_test
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"sneak.berlin/go/dnswatcher/internal/livednstest"
|
|
)
|
|
|
|
// Tests for the retry and the concurrency limit themselves. They
|
|
// perform no DNS resolution of any kind.
|
|
|
|
func TestRetryRecoversFromTransientFailure(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
const wantAttempts = 2
|
|
|
|
attempts := 0
|
|
|
|
livednstest.Retry(t, "transient", func(_ context.Context) error {
|
|
attempts++
|
|
|
|
if attempts < wantAttempts {
|
|
return livednstest.ErrNoAnswer
|
|
}
|
|
|
|
return nil
|
|
})
|
|
|
|
assert.Equal(t, wantAttempts, attempts)
|
|
}
|
|
|
|
func TestRetryGivesEachAttemptADeadline(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
livednstest.Retry(t, "deadline", func(ctx context.Context) error {
|
|
deadline, ok := ctx.Deadline()
|
|
assert.True(t, ok, "attempt should carry a deadline")
|
|
|
|
remaining := time.Until(deadline)
|
|
|
|
assert.LessOrEqual(t, remaining, livednstest.AttemptTimeout)
|
|
|
|
// Lower bound too: without one this passes for a
|
|
// deadline far shorter than intended, which would
|
|
// silently turn every live attempt into an instant
|
|
// timeout.
|
|
assert.Greater(t, remaining, livednstest.AttemptTimeout/2)
|
|
|
|
return nil
|
|
})
|
|
}
|
|
|
|
func TestRunBoundsConcurrency(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
const workers = 24
|
|
|
|
var (
|
|
mu sync.Mutex
|
|
wg sync.WaitGroup
|
|
inFlight int
|
|
maxSeen int
|
|
)
|
|
|
|
wg.Add(workers)
|
|
|
|
for range workers {
|
|
go func() {
|
|
defer wg.Done()
|
|
|
|
_ = livednstest.Run(func(_ context.Context) error {
|
|
mu.Lock()
|
|
inFlight++
|
|
|
|
if inFlight > maxSeen {
|
|
maxSeen = inFlight
|
|
}
|
|
mu.Unlock()
|
|
|
|
time.Sleep(time.Millisecond)
|
|
|
|
mu.Lock()
|
|
inFlight--
|
|
mu.Unlock()
|
|
|
|
return nil
|
|
})
|
|
}()
|
|
}
|
|
|
|
wg.Wait()
|
|
|
|
assert.Positive(t, maxSeen)
|
|
assert.LessOrEqual(
|
|
t, maxSeen, livednstest.Concurrency,
|
|
"live queries must stay under the package-wide gate",
|
|
)
|
|
}
|