remote_list_test.go 7.4 KB

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