mirror of
https://github.com/juanfont/headscale.git
synced 2026-09-26 02:04:53 +09:00
5a70a72988
The watcher write raced per-client map builds cloning ExtraRecords.
61 lines
1.4 KiB
Go
61 lines
1.4 KiB
Go
package mapper
|
|
|
|
import (
|
|
"sync"
|
|
"testing"
|
|
|
|
"github.com/juanfont/headscale/hscontrol/types"
|
|
"tailscale.com/tailcfg"
|
|
)
|
|
|
|
// TestExtraRecordsConcurrentUpdateNoRace exercises the extra-records watcher
|
|
// write path (Config.SetExtraRecords) concurrently with per-client DNS config
|
|
// builds (generateDNSConfig -> Config.CloneTailcfgDNSConfig). Both must go
|
|
// through the shared lock so the run is race-free under -race.
|
|
func TestExtraRecordsConcurrentUpdateNoRace(t *testing.T) {
|
|
uid := uint(1)
|
|
cfg := &types.Config{
|
|
TailcfgDNSConfig: &tailcfg.DNSConfig{
|
|
ExtraRecords: []tailcfg.DNSRecord{
|
|
{Name: "initial.example.com", Type: "A", Value: "100.64.0.1"},
|
|
},
|
|
},
|
|
}
|
|
|
|
node := (&types.Node{
|
|
Hostname: "race-node",
|
|
UserID: &uid,
|
|
User: &types.User{Name: "racer"},
|
|
}).View()
|
|
|
|
const iterations = 2000
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
// Writer: the extra-records update path.
|
|
wg.Go(func() {
|
|
for i := range iterations {
|
|
recs := []tailcfg.DNSRecord{{Name: "a.example.com", Type: "A", Value: "100.64.0.2"}}
|
|
if i%2 == 0 {
|
|
recs = append(recs, tailcfg.DNSRecord{Name: "b.example.com", Type: "A", Value: "100.64.0.3"})
|
|
}
|
|
|
|
cfg.SetExtraRecords(recs)
|
|
}
|
|
})
|
|
|
|
// Readers: the per-client map build path.
|
|
const readers = 8
|
|
for range readers {
|
|
wg.Go(func() {
|
|
for range iterations {
|
|
if d := generateDNSConfig(cfg, node, nil); d != nil {
|
|
_ = len(d.ExtraRecords)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
wg.Wait()
|
|
}
|