remote_list_test.go 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. package nebula
  2. import (
  3. "net"
  4. "testing"
  5. "github.com/stretchr/testify/assert"
  6. )
  7. func TestRemoteList_Rebuild(t *testing.T) {
  8. rl := NewRemoteList()
  9. rl.unlockedSetV4(
  10. 0,
  11. 0,
  12. []*Ip4AndPort{
  13. {Ip: ip2int(net.ParseIP("70.199.182.92")), Port: 1475}, // this is duped
  14. {Ip: ip2int(net.ParseIP("172.17.0.182")), Port: 10101},
  15. {Ip: ip2int(net.ParseIP("172.17.1.1")), Port: 10101}, // this is duped
  16. {Ip: ip2int(net.ParseIP("172.18.0.1")), Port: 10101}, // this is duped
  17. {Ip: ip2int(net.ParseIP("172.18.0.1")), Port: 10101}, // this is a dupe
  18. {Ip: ip2int(net.ParseIP("172.19.0.1")), Port: 10101},
  19. {Ip: ip2int(net.ParseIP("172.31.0.1")), Port: 10101},
  20. {Ip: ip2int(net.ParseIP("172.17.1.1")), Port: 10101}, // this is a dupe
  21. {Ip: ip2int(net.ParseIP("70.199.182.92")), Port: 1476}, // almost dupe of 0 with a diff port
  22. {Ip: ip2int(net.ParseIP("70.199.182.92")), Port: 1475}, // this is a dupe
  23. },
  24. func(uint32, *Ip4AndPort) bool { return true },
  25. )
  26. rl.unlockedSetV6(
  27. 1,
  28. 1,
  29. []*Ip6AndPort{
  30. NewIp6AndPort(net.ParseIP("1::1"), 1), // this is duped
  31. NewIp6AndPort(net.ParseIP("1::1"), 2), // almost dupe of 0 with a diff port, also gets duped
  32. NewIp6AndPort(net.ParseIP("1:100::1"), 1),
  33. NewIp6AndPort(net.ParseIP("1::1"), 1), // this is a dupe
  34. NewIp6AndPort(net.ParseIP("1::1"), 2), // this is a dupe
  35. },
  36. func(uint32, *Ip6AndPort) bool { return true },
  37. )
  38. rl.Rebuild([]*net.IPNet{})
  39. assert.Len(t, rl.addrs, 10, "addrs contains too many entries")
  40. // ipv6 first, sorted lexically within
  41. assert.Equal(t, "[1::1]:1", rl.addrs[0].String())
  42. assert.Equal(t, "[1::1]:2", rl.addrs[1].String())
  43. assert.Equal(t, "[1:100::1]:1", rl.addrs[2].String())
  44. // ipv4 last, sorted by public first, then private, lexically within them
  45. assert.Equal(t, "70.199.182.92:1475", rl.addrs[3].String())
  46. assert.Equal(t, "70.199.182.92:1476", rl.addrs[4].String())
  47. assert.Equal(t, "172.17.0.182:10101", rl.addrs[5].String())
  48. assert.Equal(t, "172.17.1.1:10101", rl.addrs[6].String())
  49. assert.Equal(t, "172.18.0.1:10101", rl.addrs[7].String())
  50. assert.Equal(t, "172.19.0.1:10101", rl.addrs[8].String())
  51. assert.Equal(t, "172.31.0.1:10101", rl.addrs[9].String())
  52. // Now ensure we can hoist ipv4 up
  53. _, ipNet, err := net.ParseCIDR("0.0.0.0/0")
  54. assert.NoError(t, err)
  55. rl.Rebuild([]*net.IPNet{ipNet})
  56. assert.Len(t, rl.addrs, 10, "addrs contains too many entries")
  57. // ipv4 first, public then private, lexically within them
  58. assert.Equal(t, "70.199.182.92:1475", rl.addrs[0].String())
  59. assert.Equal(t, "70.199.182.92:1476", rl.addrs[1].String())
  60. assert.Equal(t, "172.17.0.182:10101", rl.addrs[2].String())
  61. assert.Equal(t, "172.17.1.1:10101", rl.addrs[3].String())
  62. assert.Equal(t, "172.18.0.1:10101", rl.addrs[4].String())
  63. assert.Equal(t, "172.19.0.1:10101", rl.addrs[5].String())
  64. assert.Equal(t, "172.31.0.1:10101", rl.addrs[6].String())
  65. // ipv6 last, sorted by public first, then private, lexically within them
  66. assert.Equal(t, "[1::1]:1", rl.addrs[7].String())
  67. assert.Equal(t, "[1::1]:2", rl.addrs[8].String())
  68. assert.Equal(t, "[1:100::1]:1", rl.addrs[9].String())
  69. // Ensure we can hoist a specific ipv4 range over anything else
  70. _, ipNet, err = net.ParseCIDR("172.17.0.0/16")
  71. assert.NoError(t, err)
  72. rl.Rebuild([]*net.IPNet{ipNet})
  73. assert.Len(t, rl.addrs, 10, "addrs contains too many entries")
  74. // Preferred ipv4 first
  75. assert.Equal(t, "172.17.0.182:10101", rl.addrs[0].String())
  76. assert.Equal(t, "172.17.1.1:10101", rl.addrs[1].String())
  77. // ipv6 next
  78. assert.Equal(t, "[1::1]:1", rl.addrs[2].String())
  79. assert.Equal(t, "[1::1]:2", rl.addrs[3].String())
  80. assert.Equal(t, "[1:100::1]:1", rl.addrs[4].String())
  81. // the remaining ipv4 last
  82. assert.Equal(t, "70.199.182.92:1475", rl.addrs[5].String())
  83. assert.Equal(t, "70.199.182.92:1476", rl.addrs[6].String())
  84. assert.Equal(t, "172.18.0.1:10101", rl.addrs[7].String())
  85. assert.Equal(t, "172.19.0.1:10101", rl.addrs[8].String())
  86. assert.Equal(t, "172.31.0.1:10101", rl.addrs[9].String())
  87. }
  88. func BenchmarkFullRebuild(b *testing.B) {
  89. rl := NewRemoteList()
  90. rl.unlockedSetV4(
  91. 0,
  92. 0,
  93. []*Ip4AndPort{
  94. {Ip: ip2int(net.ParseIP("70.199.182.92")), Port: 1475},
  95. {Ip: ip2int(net.ParseIP("172.17.0.182")), Port: 10101},
  96. {Ip: ip2int(net.ParseIP("172.17.1.1")), Port: 10101},
  97. {Ip: ip2int(net.ParseIP("172.18.0.1")), Port: 10101},
  98. {Ip: ip2int(net.ParseIP("172.19.0.1")), Port: 10101},
  99. {Ip: ip2int(net.ParseIP("172.31.0.1")), Port: 10101},
  100. {Ip: ip2int(net.ParseIP("172.17.1.1")), Port: 10101}, // this is a dupe
  101. {Ip: ip2int(net.ParseIP("70.199.182.92")), Port: 1476}, // dupe of 0 with a diff port
  102. },
  103. func(uint32, *Ip4AndPort) bool { return true },
  104. )
  105. rl.unlockedSetV6(
  106. 0,
  107. 0,
  108. []*Ip6AndPort{
  109. NewIp6AndPort(net.ParseIP("1::1"), 1),
  110. NewIp6AndPort(net.ParseIP("1::1"), 2), // dupe of 0 with a diff port
  111. NewIp6AndPort(net.ParseIP("1:100::1"), 1),
  112. NewIp6AndPort(net.ParseIP("1::1"), 1), // this is a dupe
  113. },
  114. func(uint32, *Ip6AndPort) bool { return true },
  115. )
  116. b.Run("no preferred", func(b *testing.B) {
  117. for i := 0; i < b.N; i++ {
  118. rl.shouldRebuild = true
  119. rl.Rebuild([]*net.IPNet{})
  120. }
  121. })
  122. _, ipNet, err := net.ParseCIDR("172.17.0.0/16")
  123. assert.NoError(b, err)
  124. b.Run("1 preferred", func(b *testing.B) {
  125. for i := 0; i < b.N; i++ {
  126. rl.shouldRebuild = true
  127. rl.Rebuild([]*net.IPNet{ipNet})
  128. }
  129. })
  130. _, ipNet2, err := net.ParseCIDR("70.0.0.0/8")
  131. assert.NoError(b, err)
  132. b.Run("2 preferred", func(b *testing.B) {
  133. for i := 0; i < b.N; i++ {
  134. rl.shouldRebuild = true
  135. rl.Rebuild([]*net.IPNet{ipNet, ipNet2})
  136. }
  137. })
  138. _, ipNet3, err := net.ParseCIDR("0.0.0.0/0")
  139. assert.NoError(b, err)
  140. b.Run("3 preferred", func(b *testing.B) {
  141. for i := 0; i < b.N; i++ {
  142. rl.shouldRebuild = true
  143. rl.Rebuild([]*net.IPNet{ipNet, ipNet2, ipNet3})
  144. }
  145. })
  146. }
  147. func BenchmarkSortRebuild(b *testing.B) {
  148. rl := NewRemoteList()
  149. rl.unlockedSetV4(
  150. 0,
  151. 0,
  152. []*Ip4AndPort{
  153. {Ip: ip2int(net.ParseIP("70.199.182.92")), Port: 1475},
  154. {Ip: ip2int(net.ParseIP("172.17.0.182")), Port: 10101},
  155. {Ip: ip2int(net.ParseIP("172.17.1.1")), Port: 10101},
  156. {Ip: ip2int(net.ParseIP("172.18.0.1")), Port: 10101},
  157. {Ip: ip2int(net.ParseIP("172.19.0.1")), Port: 10101},
  158. {Ip: ip2int(net.ParseIP("172.31.0.1")), Port: 10101},
  159. {Ip: ip2int(net.ParseIP("172.17.1.1")), Port: 10101}, // this is a dupe
  160. {Ip: ip2int(net.ParseIP("70.199.182.92")), Port: 1476}, // dupe of 0 with a diff port
  161. },
  162. func(uint32, *Ip4AndPort) bool { return true },
  163. )
  164. rl.unlockedSetV6(
  165. 0,
  166. 0,
  167. []*Ip6AndPort{
  168. NewIp6AndPort(net.ParseIP("1::1"), 1),
  169. NewIp6AndPort(net.ParseIP("1::1"), 2), // dupe of 0 with a diff port
  170. NewIp6AndPort(net.ParseIP("1:100::1"), 1),
  171. NewIp6AndPort(net.ParseIP("1::1"), 1), // this is a dupe
  172. },
  173. func(uint32, *Ip6AndPort) bool { return true },
  174. )
  175. b.Run("no preferred", func(b *testing.B) {
  176. for i := 0; i < b.N; i++ {
  177. rl.shouldRebuild = true
  178. rl.Rebuild([]*net.IPNet{})
  179. }
  180. })
  181. _, ipNet, err := net.ParseCIDR("172.17.0.0/16")
  182. rl.Rebuild([]*net.IPNet{ipNet})
  183. assert.NoError(b, err)
  184. b.Run("1 preferred", func(b *testing.B) {
  185. for i := 0; i < b.N; i++ {
  186. rl.Rebuild([]*net.IPNet{ipNet})
  187. }
  188. })
  189. _, ipNet2, err := net.ParseCIDR("70.0.0.0/8")
  190. rl.Rebuild([]*net.IPNet{ipNet, ipNet2})
  191. assert.NoError(b, err)
  192. b.Run("2 preferred", func(b *testing.B) {
  193. for i := 0; i < b.N; i++ {
  194. rl.Rebuild([]*net.IPNet{ipNet, ipNet2})
  195. }
  196. })
  197. _, ipNet3, err := net.ParseCIDR("0.0.0.0/0")
  198. rl.Rebuild([]*net.IPNet{ipNet, ipNet2, ipNet3})
  199. assert.NoError(b, err)
  200. b.Run("3 preferred", func(b *testing.B) {
  201. for i := 0; i < b.N; i++ {
  202. rl.Rebuild([]*net.IPNet{ipNet, ipNet2, ipNet3})
  203. }
  204. })
  205. }