derp_test.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. package prober
  4. import (
  5. "context"
  6. "encoding/json"
  7. "net/http"
  8. "net/http/httptest"
  9. "testing"
  10. "tailscale.com/tailcfg"
  11. )
  12. func TestDerpProber(t *testing.T) {
  13. dm := &tailcfg.DERPMap{
  14. Regions: map[int]*tailcfg.DERPRegion{
  15. 0: {
  16. RegionID: 0,
  17. RegionCode: "zero",
  18. Nodes: []*tailcfg.DERPNode{
  19. {
  20. Name: "n1",
  21. RegionID: 0,
  22. HostName: "derpn1.tailscale.test",
  23. IPv4: "1.1.1.1",
  24. IPv6: "::1",
  25. },
  26. {
  27. Name: "n2",
  28. RegionID: 0,
  29. HostName: "derpn2.tailscale.test",
  30. IPv4: "1.1.1.1",
  31. IPv6: "::1",
  32. },
  33. },
  34. },
  35. },
  36. }
  37. srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  38. resp, err := json.Marshal(dm)
  39. if err != nil {
  40. t.Fatal(err)
  41. }
  42. w.Write(resp)
  43. }))
  44. defer srv.Close()
  45. clk := newFakeTime()
  46. p := newForTest(clk.Now, clk.NewTicker)
  47. dp := &derpProber{
  48. p: p,
  49. derpMapURL: srv.URL,
  50. tlsProbeFn: func(_ string) ProbeFunc { return func(context.Context) error { return nil } },
  51. udpProbeFn: func(_ string, _ int) ProbeFunc { return func(context.Context) error { return nil } },
  52. meshProbeFn: func(_, _ string) ProbeFunc { return func(context.Context) error { return nil } },
  53. nodes: make(map[string]*tailcfg.DERPNode),
  54. probes: make(map[string]*Probe),
  55. }
  56. if err := dp.ProbeMap(context.Background()); err != nil {
  57. t.Errorf("unexpected ProbeMap() error: %s", err)
  58. }
  59. if len(dp.nodes) != 2 || dp.nodes["derpn1.tailscale.test"] == nil || dp.nodes["derpn2.tailscale.test"] == nil {
  60. t.Errorf("unexpected nodes: %+v", dp.nodes)
  61. }
  62. // Probes expected for two nodes:
  63. // - 3 regular probes per node (TLS, UDPv4, UDPv6)
  64. // - 4 mesh probes (N1->N2, N1->N1, N2->N1, N2->N2)
  65. if len(dp.probes) != 10 {
  66. t.Errorf("unexpected probes: %+v", dp.probes)
  67. }
  68. // Add one more node and check that probes got created.
  69. dm.Regions[0].Nodes = append(dm.Regions[0].Nodes, &tailcfg.DERPNode{
  70. Name: "n3",
  71. RegionID: 0,
  72. HostName: "derpn3.tailscale.test",
  73. IPv4: "1.1.1.1",
  74. IPv6: "::1",
  75. })
  76. if err := dp.ProbeMap(context.Background()); err != nil {
  77. t.Errorf("unexpected ProbeMap() error: %s", err)
  78. }
  79. if len(dp.nodes) != 3 {
  80. t.Errorf("unexpected nodes: %+v", dp.nodes)
  81. }
  82. // 9 regular probes + 9 mesh probes
  83. if len(dp.probes) != 18 {
  84. t.Errorf("unexpected probes: %+v", dp.probes)
  85. }
  86. // Remove 2 nodes and check that probes have been destroyed.
  87. dm.Regions[0].Nodes = dm.Regions[0].Nodes[:1]
  88. if err := dp.ProbeMap(context.Background()); err != nil {
  89. t.Errorf("unexpected ProbeMap() error: %s", err)
  90. }
  91. if len(dp.nodes) != 1 {
  92. t.Errorf("unexpected nodes: %+v", dp.nodes)
  93. }
  94. // 3 regular probes + 1 mesh probe
  95. if len(dp.probes) != 4 {
  96. t.Errorf("unexpected probes: %+v", dp.probes)
  97. }
  98. }