netmap_test.go 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. // Copyright (c) 2020 Tailscale Inc & AUTHORS All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package netmap
  5. import (
  6. "encoding/hex"
  7. "testing"
  8. "inet.af/netaddr"
  9. "tailscale.com/tailcfg"
  10. )
  11. func testNodeKey(b byte) (ret tailcfg.NodeKey) {
  12. for i := range ret {
  13. ret[i] = b
  14. }
  15. return
  16. }
  17. func testDiscoKey(hexPrefix string) (ret tailcfg.DiscoKey) {
  18. b, err := hex.DecodeString(hexPrefix)
  19. if err != nil {
  20. panic(err)
  21. }
  22. copy(ret[:], b)
  23. return
  24. }
  25. func TestNetworkMapConcise(t *testing.T) {
  26. for _, tt := range []struct {
  27. name string
  28. nm *NetworkMap
  29. want string
  30. }{
  31. {
  32. name: "basic",
  33. nm: &NetworkMap{
  34. NodeKey: testNodeKey(1),
  35. Peers: []*tailcfg.Node{
  36. {
  37. Key: testNodeKey(2),
  38. DERP: "127.3.3.40:2",
  39. Endpoints: []string{"192.168.0.100:12", "192.168.0.100:12354"},
  40. },
  41. {
  42. Key: testNodeKey(3),
  43. DERP: "127.3.3.40:4",
  44. Endpoints: []string{"10.2.0.100:12", "10.1.0.100:12345"},
  45. },
  46. },
  47. },
  48. want: "netmap: self: [AQEBA] auth=machine-unknown u=? []\n [AgICA] D2 : 192.168.0.100:12 192.168.0.100:12354\n [AwMDA] D4 : 10.2.0.100:12 10.1.0.100:12345\n",
  49. },
  50. {
  51. name: "debug_non_nil",
  52. nm: &NetworkMap{
  53. NodeKey: testNodeKey(1),
  54. Debug: &tailcfg.Debug{},
  55. },
  56. want: "netmap: self: [AQEBA] auth=machine-unknown u=? debug={} []\n",
  57. },
  58. {
  59. name: "debug_values",
  60. nm: &NetworkMap{
  61. NodeKey: testNodeKey(1),
  62. Debug: &tailcfg.Debug{LogHeapPprof: true},
  63. },
  64. want: "netmap: self: [AQEBA] auth=machine-unknown u=? debug={\"LogHeapPprof\":true} []\n",
  65. },
  66. } {
  67. t.Run(tt.name, func(t *testing.T) {
  68. var got string
  69. n := int(testing.AllocsPerRun(1000, func() {
  70. got = tt.nm.Concise()
  71. }))
  72. t.Logf("Allocs = %d", n)
  73. if got != tt.want {
  74. t.Errorf("Wrong output\n Got: %q\nWant: %q\n## Got (unescaped):\n%s\n## Want (unescaped):\n%s\n", got, tt.want, got, tt.want)
  75. }
  76. })
  77. }
  78. }
  79. func TestConciseDiffFrom(t *testing.T) {
  80. for _, tt := range []struct {
  81. name string
  82. a, b *NetworkMap
  83. want string
  84. }{
  85. {
  86. name: "no_change",
  87. a: &NetworkMap{
  88. NodeKey: testNodeKey(1),
  89. Peers: []*tailcfg.Node{
  90. {
  91. Key: testNodeKey(2),
  92. DERP: "127.3.3.40:2",
  93. Endpoints: []string{"192.168.0.100:12", "192.168.0.100:12354"},
  94. },
  95. },
  96. },
  97. b: &NetworkMap{
  98. NodeKey: testNodeKey(1),
  99. Peers: []*tailcfg.Node{
  100. {
  101. Key: testNodeKey(2),
  102. DERP: "127.3.3.40:2",
  103. Endpoints: []string{"192.168.0.100:12", "192.168.0.100:12354"},
  104. },
  105. },
  106. },
  107. want: "",
  108. },
  109. {
  110. name: "header_change",
  111. a: &NetworkMap{
  112. NodeKey: testNodeKey(1),
  113. Peers: []*tailcfg.Node{
  114. {
  115. Key: testNodeKey(2),
  116. DERP: "127.3.3.40:2",
  117. Endpoints: []string{"192.168.0.100:12", "192.168.0.100:12354"},
  118. },
  119. },
  120. },
  121. b: &NetworkMap{
  122. NodeKey: testNodeKey(2),
  123. Peers: []*tailcfg.Node{
  124. {
  125. Key: testNodeKey(2),
  126. DERP: "127.3.3.40:2",
  127. Endpoints: []string{"192.168.0.100:12", "192.168.0.100:12354"},
  128. },
  129. },
  130. },
  131. want: "-netmap: self: [AQEBA] auth=machine-unknown u=? []\n+netmap: self: [AgICA] auth=machine-unknown u=? []\n",
  132. },
  133. {
  134. name: "peer_add",
  135. a: &NetworkMap{
  136. NodeKey: testNodeKey(1),
  137. Peers: []*tailcfg.Node{
  138. {
  139. ID: 2,
  140. Key: testNodeKey(2),
  141. DERP: "127.3.3.40:2",
  142. Endpoints: []string{"192.168.0.100:12", "192.168.0.100:12354"},
  143. },
  144. },
  145. },
  146. b: &NetworkMap{
  147. NodeKey: testNodeKey(1),
  148. Peers: []*tailcfg.Node{
  149. {
  150. ID: 1,
  151. Key: testNodeKey(1),
  152. DERP: "127.3.3.40:1",
  153. Endpoints: []string{"192.168.0.100:12", "192.168.0.100:12354"},
  154. },
  155. {
  156. ID: 2,
  157. Key: testNodeKey(2),
  158. DERP: "127.3.3.40:2",
  159. Endpoints: []string{"192.168.0.100:12", "192.168.0.100:12354"},
  160. },
  161. {
  162. ID: 3,
  163. Key: testNodeKey(3),
  164. DERP: "127.3.3.40:3",
  165. Endpoints: []string{"192.168.0.100:12", "192.168.0.100:12354"},
  166. },
  167. },
  168. },
  169. want: "+ [AQEBA] D1 : 192.168.0.100:12 192.168.0.100:12354\n+ [AwMDA] D3 : 192.168.0.100:12 192.168.0.100:12354\n",
  170. },
  171. {
  172. name: "peer_remove",
  173. a: &NetworkMap{
  174. NodeKey: testNodeKey(1),
  175. Peers: []*tailcfg.Node{
  176. {
  177. ID: 1,
  178. Key: testNodeKey(1),
  179. DERP: "127.3.3.40:1",
  180. Endpoints: []string{"192.168.0.100:12", "192.168.0.100:12354"},
  181. },
  182. {
  183. ID: 2,
  184. Key: testNodeKey(2),
  185. DERP: "127.3.3.40:2",
  186. Endpoints: []string{"192.168.0.100:12", "192.168.0.100:12354"},
  187. },
  188. {
  189. ID: 3,
  190. Key: testNodeKey(3),
  191. DERP: "127.3.3.40:3",
  192. Endpoints: []string{"192.168.0.100:12", "192.168.0.100:12354"},
  193. },
  194. },
  195. },
  196. b: &NetworkMap{
  197. NodeKey: testNodeKey(1),
  198. Peers: []*tailcfg.Node{
  199. {
  200. ID: 2,
  201. Key: testNodeKey(2),
  202. DERP: "127.3.3.40:2",
  203. Endpoints: []string{"192.168.0.100:12", "192.168.0.100:12354"},
  204. },
  205. },
  206. },
  207. want: "- [AQEBA] D1 : 192.168.0.100:12 192.168.0.100:12354\n- [AwMDA] D3 : 192.168.0.100:12 192.168.0.100:12354\n",
  208. },
  209. {
  210. name: "peer_port_change",
  211. a: &NetworkMap{
  212. NodeKey: testNodeKey(1),
  213. Peers: []*tailcfg.Node{
  214. {
  215. ID: 2,
  216. Key: testNodeKey(2),
  217. DERP: "127.3.3.40:2",
  218. Endpoints: []string{"192.168.0.100:12", "1.1.1.1:1"},
  219. },
  220. },
  221. },
  222. b: &NetworkMap{
  223. NodeKey: testNodeKey(1),
  224. Peers: []*tailcfg.Node{
  225. {
  226. ID: 2,
  227. Key: testNodeKey(2),
  228. DERP: "127.3.3.40:2",
  229. Endpoints: []string{"192.168.0.100:12", "1.1.1.1:2"},
  230. },
  231. },
  232. },
  233. want: "- [AgICA] D2 : 192.168.0.100:12 1.1.1.1:1 \n+ [AgICA] D2 : 192.168.0.100:12 1.1.1.1:2 \n",
  234. },
  235. {
  236. name: "disco_key_only_change",
  237. a: &NetworkMap{
  238. NodeKey: testNodeKey(1),
  239. Peers: []*tailcfg.Node{
  240. {
  241. ID: 2,
  242. Key: testNodeKey(2),
  243. DERP: "127.3.3.40:2",
  244. Endpoints: []string{"192.168.0.100:41641", "1.1.1.1:41641"},
  245. DiscoKey: testDiscoKey("f00f00f00f"),
  246. AllowedIPs: []netaddr.IPPrefix{netaddr.IPPrefixFrom(netaddr.IPv4(100, 102, 103, 104), 32)},
  247. },
  248. },
  249. },
  250. b: &NetworkMap{
  251. NodeKey: testNodeKey(1),
  252. Peers: []*tailcfg.Node{
  253. {
  254. ID: 2,
  255. Key: testNodeKey(2),
  256. DERP: "127.3.3.40:2",
  257. Endpoints: []string{"192.168.0.100:41641", "1.1.1.1:41641"},
  258. DiscoKey: testDiscoKey("ba4ba4ba4b"),
  259. AllowedIPs: []netaddr.IPPrefix{netaddr.IPPrefixFrom(netaddr.IPv4(100, 102, 103, 104), 32)},
  260. },
  261. },
  262. },
  263. want: "- [AgICA] d:f00f00f00f000000 D2 100.102.103.104 : 192.168.0.100:41641 1.1.1.1:41641\n+ [AgICA] d:ba4ba4ba4b000000 D2 100.102.103.104 : 192.168.0.100:41641 1.1.1.1:41641\n",
  264. },
  265. } {
  266. t.Run(tt.name, func(t *testing.T) {
  267. var got string
  268. n := int(testing.AllocsPerRun(50, func() {
  269. got = tt.b.ConciseDiffFrom(tt.a)
  270. }))
  271. t.Logf("Allocs = %d", n)
  272. if got != tt.want {
  273. t.Errorf("Wrong output\n Got: %q\nWant: %q\n## Got (unescaped):\n%s\n## Want (unescaped):\n%s\n", got, tt.want, got, tt.want)
  274. }
  275. })
  276. }
  277. }