google.golang.org/grpc@v1.72.2/resolver/map_test.go (about) 1 /* 2 * 3 * Copyright 2021 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 resolver 20 21 import ( 22 "fmt" 23 "sort" 24 "testing" 25 26 "github.com/google/go-cmp/cmp" 27 "google.golang.org/grpc/attributes" 28 ) 29 30 // Note: each address is different from addr1 by one value. addr7 matches 31 // addr1, since the only difference is BalancerAttributes, which are not 32 // compared. 33 var ( 34 addr1 = Address{Addr: "a1", Attributes: attributes.New("a1", 3), ServerName: "s1"} 35 addr2 = Address{Addr: "a2", Attributes: attributes.New("a1", 3), ServerName: "s1"} 36 addr3 = Address{Addr: "a1", Attributes: attributes.New("a2", 3), ServerName: "s1"} 37 addr4 = Address{Addr: "a1", Attributes: attributes.New("a1", 2), ServerName: "s1"} 38 addr5 = Address{Addr: "a1", Attributes: attributes.New("a1", "3"), ServerName: "s1"} 39 addr6 = Address{Addr: "a1", Attributes: attributes.New("a1", 3), ServerName: "s2"} 40 addr7 = Address{Addr: "a1", Attributes: attributes.New("a1", 3), ServerName: "s1", BalancerAttributes: attributes.New("xx", 3)} 41 42 endpoint1 = Endpoint{Addresses: []Address{{Addr: "addr1"}}} 43 endpoint2 = Endpoint{Addresses: []Address{{Addr: "addr2"}}} 44 endpoint3 = Endpoint{Addresses: []Address{{Addr: "addr3"}}} 45 endpoint4 = Endpoint{Addresses: []Address{{Addr: "addr4"}}} 46 endpoint5 = Endpoint{Addresses: []Address{{Addr: "addr5"}}} 47 endpoint6 = Endpoint{Addresses: []Address{{Addr: "addr6"}}} 48 endpoint7 = Endpoint{Addresses: []Address{{Addr: "addr7"}}} 49 endpoint12 = Endpoint{Addresses: []Address{{Addr: "addr1"}, {Addr: "addr2"}}} 50 endpoint21 = Endpoint{Addresses: []Address{{Addr: "addr2"}, {Addr: "addr1"}}} 51 endpoint123 = Endpoint{Addresses: []Address{{Addr: "addr1"}, {Addr: "addr2"}, {Addr: "addr3"}}} 52 ) 53 54 func (s) TestAddressMap_Length(t *testing.T) { 55 addrMap := NewAddressMapV2[any]() 56 if got := addrMap.Len(); got != 0 { 57 t.Fatalf("addrMap.Len() = %v; want 0", got) 58 } 59 for i := 0; i < 10; i++ { 60 addrMap.Set(addr1, nil) 61 if got, want := addrMap.Len(), 1; got != want { 62 t.Fatalf("addrMap.Len() = %v; want %v", got, want) 63 } 64 addrMap.Set(addr7, nil) // aliases addr1 65 } 66 for i := 0; i < 10; i++ { 67 addrMap.Set(addr2, nil) 68 if got, want := addrMap.Len(), 2; got != want { 69 t.Fatalf("addrMap.Len() = %v; want %v", got, want) 70 } 71 } 72 } 73 74 func (s) TestAddressMap_Get(t *testing.T) { 75 addrMap := NewAddressMapV2[int]() 76 addrMap.Set(addr1, 1) 77 78 if got, ok := addrMap.Get(addr2); ok || got != 0 { 79 t.Fatalf("addrMap.Get(addr1) = %v, %v; want 0, false", got, ok) 80 } 81 82 addrMap.Set(addr2, 2) 83 addrMap.Set(addr3, 3) 84 addrMap.Set(addr4, 4) 85 addrMap.Set(addr5, 5) 86 addrMap.Set(addr6, 6) 87 addrMap.Set(addr7, 7) // aliases addr1 88 if got, ok := addrMap.Get(addr1); !ok || got != 7 { 89 t.Fatalf("addrMap.Get(addr1) = %v, %v; want %v, true", got, ok, 7) 90 } 91 if got, ok := addrMap.Get(addr2); !ok || got != 2 { 92 t.Fatalf("addrMap.Get(addr2) = %v, %v; want %v, true", got, ok, 2) 93 } 94 if got, ok := addrMap.Get(addr3); !ok || got != 3 { 95 t.Fatalf("addrMap.Get(addr3) = %v, %v; want %v, true", got, ok, 3) 96 } 97 if got, ok := addrMap.Get(addr4); !ok || got != 4 { 98 t.Fatalf("addrMap.Get(addr4) = %v, %v; want %v, true", got, ok, 4) 99 } 100 if got, ok := addrMap.Get(addr5); !ok || got != 5 { 101 t.Fatalf("addrMap.Get(addr5) = %v, %v; want %v, true", got, ok, 5) 102 } 103 if got, ok := addrMap.Get(addr6); !ok || got != 6 { 104 t.Fatalf("addrMap.Get(addr6) = %v, %v; want %v, true", got, ok, 6) 105 } 106 if got, ok := addrMap.Get(addr7); !ok || got != 7 { 107 t.Fatalf("addrMap.Get(addr7) = %v, %v; want %v, true", got, ok, 7) 108 } 109 } 110 111 func (s) TestAddressMap_Delete(t *testing.T) { 112 addrMap := NewAddressMapV2[any]() 113 addrMap.Set(addr1, 1) 114 addrMap.Set(addr2, 2) 115 if got, want := addrMap.Len(), 2; got != want { 116 t.Fatalf("addrMap.Len() = %v; want %v", got, want) 117 } 118 addrMap.Delete(addr3) 119 addrMap.Delete(addr4) 120 addrMap.Delete(addr5) 121 addrMap.Delete(addr6) 122 addrMap.Delete(addr7) // aliases addr1 123 if got, ok := addrMap.Get(addr1); ok || got != nil { 124 t.Fatalf("addrMap.Get(addr1) = %v, %v; want nil, false", got, ok) 125 } 126 if got, ok := addrMap.Get(addr7); ok || got != nil { 127 t.Fatalf("addrMap.Get(addr7) = %v, %v; want nil, false", got, ok) 128 } 129 if got, ok := addrMap.Get(addr2); !ok || got.(int) != 2 { 130 t.Fatalf("addrMap.Get(addr2) = %v, %v; want %v, true", got, ok, 2) 131 } 132 } 133 134 func (s) TestAddressMap_Keys(t *testing.T) { 135 addrMap := NewAddressMapV2[int]() 136 addrMap.Set(addr1, 1) 137 addrMap.Set(addr2, 2) 138 addrMap.Set(addr3, 3) 139 addrMap.Set(addr4, 4) 140 addrMap.Set(addr5, 5) 141 addrMap.Set(addr6, 6) 142 addrMap.Set(addr7, 7) // aliases addr1 143 144 want := []Address{addr1, addr2, addr3, addr4, addr5, addr6} 145 got := addrMap.Keys() 146 if d := cmp.Diff(want, got, cmp.Transformer("sort", func(in []Address) []Address { 147 out := append([]Address(nil), in...) 148 sort.Slice(out, func(i, j int) bool { return fmt.Sprint(out[i]) < fmt.Sprint(out[j]) }) 149 return out 150 })); d != "" { 151 t.Fatalf("addrMap.Keys returned unexpected elements (-want, +got):\n%v", d) 152 } 153 } 154 155 func (s) TestAddressMap_Values(t *testing.T) { 156 addrMap := NewAddressMapV2[int]() 157 addrMap.Set(addr1, 1) 158 addrMap.Set(addr2, 2) 159 addrMap.Set(addr3, 3) 160 addrMap.Set(addr4, 4) 161 addrMap.Set(addr5, 5) 162 addrMap.Set(addr6, 6) 163 addrMap.Set(addr7, 7) // aliases addr1 164 165 want := []int{2, 3, 4, 5, 6, 7} 166 got := addrMap.Values() 167 sort.Ints(got) 168 if diff := cmp.Diff(want, got); diff != "" { 169 t.Fatalf("addrMap.Values returned unexpected elements (-want, +got):\n%v", diff) 170 } 171 } 172 173 func (s) TestEndpointMap_Length(t *testing.T) { 174 em := NewEndpointMap[struct{}]() 175 // Should be empty at creation time. 176 if got := em.Len(); got != 0 { 177 t.Fatalf("em.Len() = %v; want 0", got) 178 } 179 // Add two endpoints with the same unordered set of addresses. This should 180 // amount to one endpoint. It should also not take into account attributes. 181 em.Set(endpoint12, struct{}{}) 182 em.Set(endpoint21, struct{}{}) 183 184 if got := em.Len(); got != 1 { 185 t.Fatalf("em.Len() = %v; want 1", got) 186 } 187 188 // Add another unique endpoint. This should cause the length to be 2. 189 em.Set(endpoint123, struct{}{}) 190 if got := em.Len(); got != 2 { 191 t.Fatalf("em.Len() = %v; want 2", got) 192 } 193 } 194 195 func (s) TestEndpointMap_Get(t *testing.T) { 196 em := NewEndpointMap[int]() 197 em.Set(endpoint1, 1) 198 // The second endpoint endpoint21 should override. 199 em.Set(endpoint12, 1) 200 em.Set(endpoint21, 2) 201 em.Set(endpoint3, 3) 202 em.Set(endpoint4, 4) 203 em.Set(endpoint5, 5) 204 em.Set(endpoint6, 6) 205 em.Set(endpoint7, 7) 206 207 if got, ok := em.Get(endpoint1); !ok || got != 1 { 208 t.Fatalf("em.Get(endpoint1) = %v, %v; want %v, true", got, ok, 1) 209 } 210 if got, ok := em.Get(endpoint12); !ok || got != 2 { 211 t.Fatalf("em.Get(endpoint12) = %v, %v; want %v, true", got, ok, 2) 212 } 213 if got, ok := em.Get(endpoint21); !ok || got != 2 { 214 t.Fatalf("em.Get(endpoint21) = %v, %v; want %v, true", got, ok, 2) 215 } 216 if got, ok := em.Get(endpoint3); !ok || got != 3 { 217 t.Fatalf("em.Get(endpoint1) = %v, %v; want %v, true", got, ok, 3) 218 } 219 if got, ok := em.Get(endpoint4); !ok || got != 4 { 220 t.Fatalf("em.Get(endpoint1) = %v, %v; want %v, true", got, ok, 4) 221 } 222 if got, ok := em.Get(endpoint5); !ok || got != 5 { 223 t.Fatalf("em.Get(endpoint1) = %v, %v; want %v, true", got, ok, 5) 224 } 225 if got, ok := em.Get(endpoint6); !ok || got != 6 { 226 t.Fatalf("em.Get(endpoint1) = %v, %v; want %v, true", got, ok, 6) 227 } 228 if got, ok := em.Get(endpoint7); !ok || got != 7 { 229 t.Fatalf("em.Get(endpoint1) = %v, %v; want %v, true", got, ok, 7) 230 } 231 if _, ok := em.Get(endpoint123); ok { 232 t.Fatalf("em.Get(endpoint123) = _, %v; want _, false", ok) 233 } 234 } 235 236 func (s) TestEndpointMap_Delete(t *testing.T) { 237 em := NewEndpointMap[struct{}]() 238 // Initial state of system: [1, 2, 3, 12] 239 em.Set(endpoint1, struct{}{}) 240 em.Set(endpoint2, struct{}{}) 241 em.Set(endpoint3, struct{}{}) 242 em.Set(endpoint12, struct{}{}) 243 // Delete: [2, 21] 244 em.Delete(endpoint2) 245 em.Delete(endpoint21) 246 247 // [1, 3] should be present: 248 if _, ok := em.Get(endpoint1); !ok { 249 t.Fatalf("em.Get(endpoint1) = %v, want true", ok) 250 } 251 if _, ok := em.Get(endpoint3); !ok { 252 t.Fatalf("em.Get(endpoint3) = %v, want true", ok) 253 } 254 // [2, 12] should not be present: 255 if _, ok := em.Get(endpoint2); ok { 256 t.Fatalf("em.Get(endpoint2) = %v, want false", ok) 257 } 258 if _, ok := em.Get(endpoint12); ok { 259 t.Fatalf("em.Get(endpoint12) = %v, want false", ok) 260 } 261 if _, ok := em.Get(endpoint21); ok { 262 t.Fatalf("em.Get(endpoint21) = %v, want false", ok) 263 } 264 } 265 266 func (s) TestEndpointMap_Values(t *testing.T) { 267 em := NewEndpointMap[int]() 268 em.Set(endpoint1, 1) 269 // The second endpoint endpoint21 should override. 270 em.Set(endpoint12, 1) 271 em.Set(endpoint21, 2) 272 em.Set(endpoint3, 3) 273 em.Set(endpoint4, 4) 274 em.Set(endpoint5, 5) 275 em.Set(endpoint6, 6) 276 em.Set(endpoint7, 7) 277 want := []int{1, 2, 3, 4, 5, 6, 7} 278 got := em.Values() 279 sort.Ints(got) 280 if diff := cmp.Diff(want, got); diff != "" { 281 t.Fatalf("em.Values() returned unexpected elements (-want, +got):\n%v", diff) 282 } 283 } 284 285 // BenchmarkEndpointMap benchmarks map operations that are expected to run 286 // faster than O(n). This test doesn't run O(n) operations including listing 287 // keys and values. 288 func BenchmarkEndpointMap(b *testing.B) { 289 em := NewEndpointMap[any]() 290 for i := range b.N { 291 em.Set(Endpoint{ 292 Addresses: []Address{{Addr: fmt.Sprintf("%d.%d.%d.%d", i, i, i, i)}}, 293 }, i) 294 } 295 for i := range b.N { 296 em.Get(Endpoint{ 297 Addresses: []Address{{Addr: fmt.Sprintf("%d.%d.%d.%d", i, i, i, i)}}, 298 }) 299 } 300 for i := range b.N { 301 em.Delete(Endpoint{ 302 Addresses: []Address{{Addr: fmt.Sprintf("%d.%d.%d.%d", i, i, i, i)}}, 303 }) 304 } 305 }