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  }