regions_test.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. package allregions
  2. import (
  3. "testing"
  4. "github.com/stretchr/testify/assert"
  5. )
  6. func makeRegions(addrs []*EdgeAddr, mode ConfigIPVersion) Regions {
  7. r1addrs := make([]*EdgeAddr, 0)
  8. r2addrs := make([]*EdgeAddr, 0)
  9. for i, addr := range addrs {
  10. if i%2 == 0 {
  11. r1addrs = append(r1addrs, addr)
  12. } else {
  13. r2addrs = append(r2addrs, addr)
  14. }
  15. }
  16. r1 := NewRegion(r1addrs, mode)
  17. r2 := NewRegion(r2addrs, mode)
  18. return Regions{region1: r1, region2: r2}
  19. }
  20. func TestRegions_AddrUsedBy(t *testing.T) {
  21. tests := []struct {
  22. name string
  23. addrs []*EdgeAddr
  24. mode ConfigIPVersion
  25. }{
  26. {
  27. name: "IPv4 addresses with IPv4Only",
  28. addrs: v4Addrs,
  29. mode: IPv4Only,
  30. },
  31. {
  32. name: "IPv6 addresses with IPv6Only",
  33. addrs: v6Addrs,
  34. mode: IPv6Only,
  35. },
  36. }
  37. for _, tt := range tests {
  38. t.Run(tt.name, func(t *testing.T) {
  39. rs := makeRegions(tt.addrs, tt.mode)
  40. addr1 := rs.GetUnusedAddr(nil, 1)
  41. assert.Equal(t, addr1, rs.AddrUsedBy(1))
  42. addr2 := rs.GetUnusedAddr(nil, 2)
  43. assert.Equal(t, addr2, rs.AddrUsedBy(2))
  44. addr3 := rs.GetUnusedAddr(nil, 3)
  45. assert.Equal(t, addr3, rs.AddrUsedBy(3))
  46. })
  47. }
  48. }
  49. func TestRegions_Giveback_Region1(t *testing.T) {
  50. tests := []struct {
  51. name string
  52. addrs []*EdgeAddr
  53. mode ConfigIPVersion
  54. }{
  55. {
  56. name: "IPv4 addresses with IPv4Only",
  57. addrs: v4Addrs,
  58. mode: IPv4Only,
  59. },
  60. {
  61. name: "IPv6 addresses with IPv6Only",
  62. addrs: v6Addrs,
  63. mode: IPv6Only,
  64. },
  65. }
  66. for _, tt := range tests {
  67. t.Run(tt.name, func(t *testing.T) {
  68. rs := makeRegions(tt.addrs, tt.mode)
  69. addr := rs.region1.AssignAnyAddress(0, nil)
  70. rs.region1.AssignAnyAddress(1, nil)
  71. rs.region2.AssignAnyAddress(2, nil)
  72. rs.region2.AssignAnyAddress(3, nil)
  73. assert.Equal(t, 0, rs.AvailableAddrs())
  74. rs.GiveBack(addr, false)
  75. assert.Equal(t, addr, rs.GetUnusedAddr(nil, 0))
  76. })
  77. }
  78. }
  79. func TestRegions_Giveback_Region2(t *testing.T) {
  80. tests := []struct {
  81. name string
  82. addrs []*EdgeAddr
  83. mode ConfigIPVersion
  84. }{
  85. {
  86. name: "IPv4 addresses with IPv4Only",
  87. addrs: v4Addrs,
  88. mode: IPv4Only,
  89. },
  90. {
  91. name: "IPv6 addresses with IPv6Only",
  92. addrs: v6Addrs,
  93. mode: IPv6Only,
  94. },
  95. }
  96. for _, tt := range tests {
  97. t.Run(tt.name, func(t *testing.T) {
  98. rs := makeRegions(tt.addrs, tt.mode)
  99. rs.region1.AssignAnyAddress(0, nil)
  100. rs.region1.AssignAnyAddress(1, nil)
  101. addr := rs.region2.AssignAnyAddress(2, nil)
  102. rs.region2.AssignAnyAddress(3, nil)
  103. assert.Equal(t, 0, rs.AvailableAddrs())
  104. rs.GiveBack(addr, false)
  105. assert.Equal(t, addr, rs.GetUnusedAddr(nil, 2))
  106. })
  107. }
  108. }
  109. func TestRegions_GetUnusedAddr_OneAddrLeft(t *testing.T) {
  110. tests := []struct {
  111. name string
  112. addrs []*EdgeAddr
  113. mode ConfigIPVersion
  114. }{
  115. {
  116. name: "IPv4 addresses with IPv4Only",
  117. addrs: v4Addrs,
  118. mode: IPv4Only,
  119. },
  120. {
  121. name: "IPv6 addresses with IPv6Only",
  122. addrs: v6Addrs,
  123. mode: IPv6Only,
  124. },
  125. }
  126. for _, tt := range tests {
  127. t.Run(tt.name, func(t *testing.T) {
  128. rs := makeRegions(tt.addrs, tt.mode)
  129. rs.region1.AssignAnyAddress(0, nil)
  130. rs.region1.AssignAnyAddress(1, nil)
  131. rs.region2.AssignAnyAddress(2, nil)
  132. addr := rs.region2.active.GetUnusedIP(nil)
  133. assert.Equal(t, 1, rs.AvailableAddrs())
  134. assert.Equal(t, addr, rs.GetUnusedAddr(nil, 3))
  135. })
  136. }
  137. }
  138. func TestRegions_GetUnusedAddr_Excluding_Region1(t *testing.T) {
  139. tests := []struct {
  140. name string
  141. addrs []*EdgeAddr
  142. mode ConfigIPVersion
  143. }{
  144. {
  145. name: "IPv4 addresses with IPv4Only",
  146. addrs: v4Addrs,
  147. mode: IPv4Only,
  148. },
  149. {
  150. name: "IPv6 addresses with IPv6Only",
  151. addrs: v6Addrs,
  152. mode: IPv6Only,
  153. },
  154. }
  155. for _, tt := range tests {
  156. t.Run(tt.name, func(t *testing.T) {
  157. rs := makeRegions(tt.addrs, tt.mode)
  158. rs.region1.AssignAnyAddress(0, nil)
  159. rs.region1.AssignAnyAddress(1, nil)
  160. addr := rs.region2.active.GetUnusedIP(nil)
  161. a2 := rs.region2.active.GetUnusedIP(addr)
  162. assert.Equal(t, 2, rs.AvailableAddrs())
  163. assert.Equal(t, addr, rs.GetUnusedAddr(a2, 3))
  164. })
  165. }
  166. }
  167. func TestRegions_GetUnusedAddr_Excluding_Region2(t *testing.T) {
  168. tests := []struct {
  169. name string
  170. addrs []*EdgeAddr
  171. mode ConfigIPVersion
  172. }{
  173. {
  174. name: "IPv4 addresses with IPv4Only",
  175. addrs: v4Addrs,
  176. mode: IPv4Only,
  177. },
  178. {
  179. name: "IPv6 addresses with IPv6Only",
  180. addrs: v6Addrs,
  181. mode: IPv6Only,
  182. },
  183. }
  184. for _, tt := range tests {
  185. t.Run(tt.name, func(t *testing.T) {
  186. rs := makeRegions(tt.addrs, tt.mode)
  187. rs.region2.AssignAnyAddress(0, nil)
  188. rs.region2.AssignAnyAddress(1, nil)
  189. addr := rs.region1.active.GetUnusedIP(nil)
  190. a2 := rs.region1.active.GetUnusedIP(addr)
  191. assert.Equal(t, 2, rs.AvailableAddrs())
  192. assert.Equal(t, addr, rs.GetUnusedAddr(a2, 1))
  193. })
  194. }
  195. }
  196. func TestNewNoResolveBalancesRegions(t *testing.T) {
  197. type args struct {
  198. addrs []*EdgeAddr
  199. }
  200. tests := []struct {
  201. name string
  202. args args
  203. }{
  204. {
  205. name: "one address",
  206. args: args{addrs: []*EdgeAddr{&addr0}},
  207. },
  208. {
  209. name: "two addresses",
  210. args: args{addrs: []*EdgeAddr{&addr0, &addr1}},
  211. },
  212. }
  213. for _, tt := range tests {
  214. t.Run(tt.name, func(t *testing.T) {
  215. regions := NewNoResolve(tt.args.addrs)
  216. RegionsIsBalanced(t, regions)
  217. })
  218. }
  219. }
  220. func TestGetRegionalServiceName(t *testing.T) {
  221. // Empty region should just go to origintunneld
  222. globalServiceName := getRegionalServiceName("")
  223. assert.Equal(t, srvService, globalServiceName)
  224. // Non-empty region should go to the regional origintunneld variant
  225. for _, region := range []string{"us", "pt", "am"} {
  226. regionalServiceName := getRegionalServiceName(region)
  227. assert.Equal(t, region+"-"+srvService, regionalServiceName)
  228. }
  229. }
  230. func RegionsIsBalanced(t *testing.T, rs *Regions) {
  231. delta := rs.region1.AvailableAddrs() - rs.region2.AvailableAddrs()
  232. assert.True(t, abs(delta) <= 1)
  233. }
  234. func abs(x int) int {
  235. if x >= 0 {
  236. return x
  237. }
  238. return -x
  239. }