hierarchy_test.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /*
  2. *
  3. * Copyright 2020 gRPC authors.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. package hierarchy
  19. import (
  20. "testing"
  21. "github.com/google/go-cmp/cmp"
  22. "google.golang.org/grpc/attributes"
  23. "google.golang.org/grpc/resolver"
  24. )
  25. func TestGet(t *testing.T) {
  26. tests := []struct {
  27. name string
  28. addr resolver.Address
  29. want []string
  30. }{
  31. {
  32. name: "not set",
  33. addr: resolver.Address{},
  34. want: nil,
  35. },
  36. {
  37. name: "set",
  38. addr: resolver.Address{
  39. BalancerAttributes: attributes.New(pathKey, pathValue{"a", "b"}),
  40. },
  41. want: []string{"a", "b"},
  42. },
  43. }
  44. for _, tt := range tests {
  45. t.Run(tt.name, func(t *testing.T) {
  46. if got := Get(tt.addr); !cmp.Equal(got, tt.want) {
  47. t.Errorf("Get() = %v, want %v", got, tt.want)
  48. }
  49. })
  50. }
  51. }
  52. func TestSet(t *testing.T) {
  53. tests := []struct {
  54. name string
  55. addr resolver.Address
  56. path []string
  57. }{
  58. {
  59. name: "before is not set",
  60. addr: resolver.Address{},
  61. path: []string{"a", "b"},
  62. },
  63. {
  64. name: "before is set",
  65. addr: resolver.Address{
  66. BalancerAttributes: attributes.New(pathKey, pathValue{"before", "a", "b"}),
  67. },
  68. path: []string{"a", "b"},
  69. },
  70. }
  71. for _, tt := range tests {
  72. t.Run(tt.name, func(t *testing.T) {
  73. newAddr := Set(tt.addr, tt.path)
  74. newPath := Get(newAddr)
  75. if !cmp.Equal(newPath, tt.path) {
  76. t.Errorf("path after Set() = %v, want %v", newPath, tt.path)
  77. }
  78. })
  79. }
  80. }
  81. func TestGroup(t *testing.T) {
  82. tests := []struct {
  83. name string
  84. addrs []resolver.Address
  85. want map[string][]resolver.Address
  86. }{
  87. {
  88. name: "all with hierarchy",
  89. addrs: []resolver.Address{
  90. {Addr: "a0", BalancerAttributes: attributes.New(pathKey, pathValue{"a"})},
  91. {Addr: "a1", BalancerAttributes: attributes.New(pathKey, pathValue{"a"})},
  92. {Addr: "b0", BalancerAttributes: attributes.New(pathKey, pathValue{"b"})},
  93. {Addr: "b1", BalancerAttributes: attributes.New(pathKey, pathValue{"b"})},
  94. },
  95. want: map[string][]resolver.Address{
  96. "a": {
  97. {Addr: "a0", BalancerAttributes: attributes.New(pathKey, pathValue{})},
  98. {Addr: "a1", BalancerAttributes: attributes.New(pathKey, pathValue{})},
  99. },
  100. "b": {
  101. {Addr: "b0", BalancerAttributes: attributes.New(pathKey, pathValue{})},
  102. {Addr: "b1", BalancerAttributes: attributes.New(pathKey, pathValue{})},
  103. },
  104. },
  105. },
  106. {
  107. // Addresses without hierarchy are ignored.
  108. name: "without hierarchy",
  109. addrs: []resolver.Address{
  110. {Addr: "a0", BalancerAttributes: attributes.New(pathKey, pathValue{"a"})},
  111. {Addr: "a1", BalancerAttributes: attributes.New(pathKey, pathValue{"a"})},
  112. {Addr: "b0", BalancerAttributes: nil},
  113. {Addr: "b1", BalancerAttributes: nil},
  114. },
  115. want: map[string][]resolver.Address{
  116. "a": {
  117. {Addr: "a0", BalancerAttributes: attributes.New(pathKey, pathValue{})},
  118. {Addr: "a1", BalancerAttributes: attributes.New(pathKey, pathValue{})},
  119. },
  120. },
  121. },
  122. {
  123. // If hierarchy is set to a wrong type (which should never happen),
  124. // the address is ignored.
  125. name: "wrong type",
  126. addrs: []resolver.Address{
  127. {Addr: "a0", BalancerAttributes: attributes.New(pathKey, pathValue{"a"})},
  128. {Addr: "a1", BalancerAttributes: attributes.New(pathKey, pathValue{"a"})},
  129. {Addr: "b0", BalancerAttributes: attributes.New(pathKey, "b")},
  130. {Addr: "b1", BalancerAttributes: attributes.New(pathKey, 314)},
  131. },
  132. want: map[string][]resolver.Address{
  133. "a": {
  134. {Addr: "a0", BalancerAttributes: attributes.New(pathKey, pathValue{})},
  135. {Addr: "a1", BalancerAttributes: attributes.New(pathKey, pathValue{})},
  136. },
  137. },
  138. },
  139. }
  140. for _, tt := range tests {
  141. t.Run(tt.name, func(t *testing.T) {
  142. if got := Group(tt.addrs); !cmp.Equal(got, tt.want, cmp.AllowUnexported(attributes.Attributes{})) {
  143. t.Errorf("Group() = %v, want %v", got, tt.want)
  144. t.Errorf("diff: %v", cmp.Diff(got, tt.want, cmp.AllowUnexported(attributes.Attributes{})))
  145. }
  146. })
  147. }
  148. }
  149. func TestGroupE2E(t *testing.T) {
  150. hierarchy := map[string]map[string][]string{
  151. "p0": {
  152. "wt0": {"addr0", "addr1"},
  153. "wt1": {"addr2", "addr3"},
  154. },
  155. "p1": {
  156. "wt10": {"addr10", "addr11"},
  157. "wt11": {"addr12", "addr13"},
  158. },
  159. }
  160. var addrsWithHierarchy []resolver.Address
  161. for p, wts := range hierarchy {
  162. path1 := pathValue{p}
  163. for wt, addrs := range wts {
  164. path2 := append(pathValue(nil), path1...)
  165. path2 = append(path2, wt)
  166. for _, addr := range addrs {
  167. a := resolver.Address{
  168. Addr: addr,
  169. BalancerAttributes: attributes.New(pathKey, path2),
  170. }
  171. addrsWithHierarchy = append(addrsWithHierarchy, a)
  172. }
  173. }
  174. }
  175. gotHierarchy := make(map[string]map[string][]string)
  176. for p1, wts := range Group(addrsWithHierarchy) {
  177. gotHierarchy[p1] = make(map[string][]string)
  178. for p2, addrs := range Group(wts) {
  179. for _, addr := range addrs {
  180. gotHierarchy[p1][p2] = append(gotHierarchy[p1][p2], addr.Addr)
  181. }
  182. }
  183. }
  184. if !cmp.Equal(gotHierarchy, hierarchy) {
  185. t.Errorf("diff: %v", cmp.Diff(gotHierarchy, hierarchy))
  186. }
  187. }