mirror of
https://github.com/juanfont/headscale.git
synced 2026-07-17 16:36:02 +00:00
52 lines
1.1 KiB
Go
52 lines
1.1 KiB
Go
package db
|
|
|
|
import (
|
|
"net/netip"
|
|
"sync"
|
|
"testing"
|
|
|
|
"github.com/juanfont/headscale/hscontrol/types"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// TestAllocatorConcurrentNextAndBackfillNoRace exercises the registration path
|
|
// (Next) concurrently with the backfill allocation path (allocateNext) on
|
|
// the same allocator. Backfill used to read prev4/prev6 in the caller's frame
|
|
// without the lock, racing Next's writes; both must now take i.mu. Run with
|
|
// -race.
|
|
func TestAllocatorConcurrentNextAndBackfillNoRace(t *testing.T) {
|
|
p4 := netip.MustParsePrefix("100.64.0.0/10")
|
|
p6 := netip.MustParsePrefix("fd7a:115c:a1e0::/48")
|
|
|
|
alloc, err := NewIPAllocator(nil, &p4, &p6, types.IPAllocationStrategySequential)
|
|
require.NoError(t, err)
|
|
|
|
const iterations = 2000
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
wg.Go(func() {
|
|
for range iterations {
|
|
_, _, err := alloc.Next()
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
})
|
|
|
|
wg.Go(func() {
|
|
for range iterations {
|
|
_, err := alloc.allocateNext(&alloc.prev4, alloc.prefix4)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
_, err = alloc.allocateNext(&alloc.prev6, alloc.prefix6)
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
})
|
|
|
|
wg.Wait()
|
|
}
|