github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/grpc/internal/hierarchy/hierarchy_test.go (about) 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 19 package hierarchy 20 21 import ( 22 "testing" 23 24 "github.com/google/go-cmp/cmp" 25 "github.com/hxx258456/ccgo/grpc/attributes" 26 "github.com/hxx258456/ccgo/grpc/resolver" 27 ) 28 29 func TestGet(t *testing.T) { 30 tests := []struct { 31 name string 32 addr resolver.Address 33 want []string 34 }{ 35 { 36 name: "not set", 37 addr: resolver.Address{}, 38 want: nil, 39 }, 40 { 41 name: "set", 42 addr: resolver.Address{ 43 BalancerAttributes: attributes.New(pathKey, pathValue{"a", "b"}), 44 }, 45 want: []string{"a", "b"}, 46 }, 47 } 48 for _, tt := range tests { 49 t.Run(tt.name, func(t *testing.T) { 50 if got := Get(tt.addr); !cmp.Equal(got, tt.want) { 51 t.Errorf("Get() = %v, want %v", got, tt.want) 52 } 53 }) 54 } 55 } 56 57 func TestSet(t *testing.T) { 58 tests := []struct { 59 name string 60 addr resolver.Address 61 path []string 62 }{ 63 { 64 name: "before is not set", 65 addr: resolver.Address{}, 66 path: []string{"a", "b"}, 67 }, 68 { 69 name: "before is set", 70 addr: resolver.Address{ 71 BalancerAttributes: attributes.New(pathKey, pathValue{"before", "a", "b"}), 72 }, 73 path: []string{"a", "b"}, 74 }, 75 } 76 for _, tt := range tests { 77 t.Run(tt.name, func(t *testing.T) { 78 newAddr := Set(tt.addr, tt.path) 79 newPath := Get(newAddr) 80 if !cmp.Equal(newPath, tt.path) { 81 t.Errorf("path after Set() = %v, want %v", newPath, tt.path) 82 } 83 }) 84 } 85 } 86 87 func TestGroup(t *testing.T) { 88 tests := []struct { 89 name string 90 addrs []resolver.Address 91 want map[string][]resolver.Address 92 }{ 93 { 94 name: "all with hierarchy", 95 addrs: []resolver.Address{ 96 {Addr: "a0", BalancerAttributes: attributes.New(pathKey, pathValue{"a"})}, 97 {Addr: "a1", BalancerAttributes: attributes.New(pathKey, pathValue{"a"})}, 98 {Addr: "b0", BalancerAttributes: attributes.New(pathKey, pathValue{"b"})}, 99 {Addr: "b1", BalancerAttributes: attributes.New(pathKey, pathValue{"b"})}, 100 }, 101 want: map[string][]resolver.Address{ 102 "a": { 103 {Addr: "a0", BalancerAttributes: attributes.New(pathKey, pathValue{})}, 104 {Addr: "a1", BalancerAttributes: attributes.New(pathKey, pathValue{})}, 105 }, 106 "b": { 107 {Addr: "b0", BalancerAttributes: attributes.New(pathKey, pathValue{})}, 108 {Addr: "b1", BalancerAttributes: attributes.New(pathKey, pathValue{})}, 109 }, 110 }, 111 }, 112 { 113 // Addresses without hierarchy are ignored. 114 name: "without hierarchy", 115 addrs: []resolver.Address{ 116 {Addr: "a0", BalancerAttributes: attributes.New(pathKey, pathValue{"a"})}, 117 {Addr: "a1", BalancerAttributes: attributes.New(pathKey, pathValue{"a"})}, 118 {Addr: "b0", BalancerAttributes: nil}, 119 {Addr: "b1", BalancerAttributes: nil}, 120 }, 121 want: map[string][]resolver.Address{ 122 "a": { 123 {Addr: "a0", BalancerAttributes: attributes.New(pathKey, pathValue{})}, 124 {Addr: "a1", BalancerAttributes: attributes.New(pathKey, pathValue{})}, 125 }, 126 }, 127 }, 128 { 129 // If hierarchy is set to a wrong type (which should never happen), 130 // the address is ignored. 131 name: "wrong type", 132 addrs: []resolver.Address{ 133 {Addr: "a0", BalancerAttributes: attributes.New(pathKey, pathValue{"a"})}, 134 {Addr: "a1", BalancerAttributes: attributes.New(pathKey, pathValue{"a"})}, 135 {Addr: "b0", BalancerAttributes: attributes.New(pathKey, "b")}, 136 {Addr: "b1", BalancerAttributes: attributes.New(pathKey, 314)}, 137 }, 138 want: map[string][]resolver.Address{ 139 "a": { 140 {Addr: "a0", BalancerAttributes: attributes.New(pathKey, pathValue{})}, 141 {Addr: "a1", BalancerAttributes: attributes.New(pathKey, pathValue{})}, 142 }, 143 }, 144 }, 145 } 146 for _, tt := range tests { 147 t.Run(tt.name, func(t *testing.T) { 148 if got := Group(tt.addrs); !cmp.Equal(got, tt.want, cmp.AllowUnexported(attributes.Attributes{})) { 149 t.Errorf("Group() = %v, want %v", got, tt.want) 150 t.Errorf("diff: %v", cmp.Diff(got, tt.want, cmp.AllowUnexported(attributes.Attributes{}))) 151 } 152 }) 153 } 154 } 155 156 func TestGroupE2E(t *testing.T) { 157 hierarchy := map[string]map[string][]string{ 158 "p0": { 159 "wt0": {"addr0", "addr1"}, 160 "wt1": {"addr2", "addr3"}, 161 }, 162 "p1": { 163 "wt10": {"addr10", "addr11"}, 164 "wt11": {"addr12", "addr13"}, 165 }, 166 } 167 168 var addrsWithHierarchy []resolver.Address 169 for p, wts := range hierarchy { 170 path1 := pathValue{p} 171 for wt, addrs := range wts { 172 path2 := append(pathValue(nil), path1...) 173 path2 = append(path2, wt) 174 for _, addr := range addrs { 175 a := resolver.Address{ 176 Addr: addr, 177 BalancerAttributes: attributes.New(pathKey, path2), 178 } 179 addrsWithHierarchy = append(addrsWithHierarchy, a) 180 } 181 } 182 } 183 184 gotHierarchy := make(map[string]map[string][]string) 185 for p1, wts := range Group(addrsWithHierarchy) { 186 gotHierarchy[p1] = make(map[string][]string) 187 for p2, addrs := range Group(wts) { 188 for _, addr := range addrs { 189 gotHierarchy[p1][p2] = append(gotHierarchy[p1][p2], addr.Addr) 190 } 191 } 192 } 193 194 if !cmp.Equal(gotHierarchy, hierarchy) { 195 t.Errorf("diff: %v", cmp.Diff(gotHierarchy, hierarchy)) 196 } 197 }