dns_test.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. package prober
  4. import (
  5. "context"
  6. "fmt"
  7. "net/netip"
  8. "slices"
  9. "sync"
  10. "testing"
  11. "tailscale.com/syncs"
  12. )
  13. func TestForEachAddr(t *testing.T) {
  14. clk := newFakeTime()
  15. p := newForTest(clk.Now, clk.NewTicker)
  16. opts := ForEachAddrOpts{
  17. Logf: t.Logf,
  18. Networks: []string{"ip4", "ip6"},
  19. }
  20. var (
  21. addr4_1 = netip.MustParseAddr("76.76.21.21")
  22. addr4_2 = netip.MustParseAddr("127.0.0.1")
  23. addr6_1 = netip.MustParseAddr("2600:9000:a602:b1e6:5b89:50a1:7cf7:67b8")
  24. addr6_2 = netip.MustParseAddr("2600:9000:a51d:27c1:6748:d035:a989:fb3c")
  25. )
  26. var resolverAddrs4, resolverAddrs6 syncs.AtomicValue[[]netip.Addr]
  27. resolverAddrs4.Store([]netip.Addr{addr4_1})
  28. resolverAddrs6.Store([]netip.Addr{addr6_1, addr6_2})
  29. opts.LookupNetIP = func(_ context.Context, network string, _ string) ([]netip.Addr, error) {
  30. if network == "ip4" {
  31. return resolverAddrs4.Load(), nil
  32. } else if network == "ip6" {
  33. return resolverAddrs6.Load(), nil
  34. }
  35. return nil, fmt.Errorf("unknown network %q", network)
  36. }
  37. var (
  38. mu sync.Mutex // protects following
  39. registered []netip.Addr
  40. )
  41. newProbe := func(addr netip.Addr) []*Probe {
  42. // Called to register a new prober
  43. t.Logf("called to register new probe for %v", addr)
  44. mu.Lock()
  45. defer mu.Unlock()
  46. registered = append(registered, addr)
  47. // Return a probe that does nothing; we don't care about what this does.
  48. probe := p.Run(fmt.Sprintf("website/%s", addr), probeInterval, nil, FuncProbe(func(_ context.Context) error {
  49. return nil
  50. }))
  51. return []*Probe{probe}
  52. }
  53. fep := makeForEachAddr("tailscale.com", newProbe, opts)
  54. // Mimic a call from the prober; we do this ourselves instead of
  55. // calling it via p.Run so we know that the probe has actually run.
  56. ctx := context.Background()
  57. if err := fep.run(ctx); err != nil {
  58. t.Fatalf("run: %v", err)
  59. }
  60. mu.Lock()
  61. wantAddrs := []netip.Addr{addr4_1, addr6_1, addr6_2}
  62. if !slices.Equal(registered, wantAddrs) {
  63. t.Errorf("got registered addrs %v; want %v", registered, wantAddrs)
  64. }
  65. mu.Unlock()
  66. // Now, update our IP addresses to force the prober to close and
  67. // re-create our probes.
  68. resolverAddrs4.Store([]netip.Addr{addr4_2})
  69. resolverAddrs6.Store([]netip.Addr{addr6_2})
  70. // Clear out our test data.
  71. mu.Lock()
  72. registered = nil
  73. mu.Unlock()
  74. // Run our individual prober again manually (so we don't have to wait
  75. // or coordinate with the created probers).
  76. if err := fep.run(ctx); err != nil {
  77. t.Fatalf("run: %v", err)
  78. }
  79. // Ensure that we only registered our net-new address (addr4_2).
  80. mu.Lock()
  81. wantAddrs = []netip.Addr{addr4_2}
  82. if !slices.Equal(registered, wantAddrs) {
  83. t.Errorf("got registered addrs %v; want %v", registered, wantAddrs)
  84. }
  85. mu.Unlock()
  86. // Check that we don't have a probe for the addresses that we expect to
  87. // have been removed (addr4_1 and addr6_1).
  88. p.mu.Lock()
  89. for _, addr := range []netip.Addr{addr4_1, addr6_1} {
  90. _, ok := fep.probes[addr]
  91. if ok {
  92. t.Errorf("probe for %v still exists", addr)
  93. }
  94. }
  95. p.mu.Unlock()
  96. }