123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- /*
- *
- * Copyright 2020 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
- package hierarchy
- import (
- "testing"
- "github.com/google/go-cmp/cmp"
- "google.golang.org/grpc/attributes"
- "google.golang.org/grpc/resolver"
- )
- func TestGet(t *testing.T) {
- tests := []struct {
- name string
- addr resolver.Address
- want []string
- }{
- {
- name: "not set",
- addr: resolver.Address{},
- want: nil,
- },
- {
- name: "set",
- addr: resolver.Address{
- BalancerAttributes: attributes.New(pathKey, pathValue{"a", "b"}),
- },
- want: []string{"a", "b"},
- },
- }
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- if got := Get(tt.addr); !cmp.Equal(got, tt.want) {
- t.Errorf("Get() = %v, want %v", got, tt.want)
- }
- })
- }
- }
- func TestSet(t *testing.T) {
- tests := []struct {
- name string
- addr resolver.Address
- path []string
- }{
- {
- name: "before is not set",
- addr: resolver.Address{},
- path: []string{"a", "b"},
- },
- {
- name: "before is set",
- addr: resolver.Address{
- BalancerAttributes: attributes.New(pathKey, pathValue{"before", "a", "b"}),
- },
- path: []string{"a", "b"},
- },
- }
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- newAddr := Set(tt.addr, tt.path)
- newPath := Get(newAddr)
- if !cmp.Equal(newPath, tt.path) {
- t.Errorf("path after Set() = %v, want %v", newPath, tt.path)
- }
- })
- }
- }
- func TestGroup(t *testing.T) {
- tests := []struct {
- name string
- addrs []resolver.Address
- want map[string][]resolver.Address
- }{
- {
- name: "all with hierarchy",
- addrs: []resolver.Address{
- {Addr: "a0", BalancerAttributes: attributes.New(pathKey, pathValue{"a"})},
- {Addr: "a1", BalancerAttributes: attributes.New(pathKey, pathValue{"a"})},
- {Addr: "b0", BalancerAttributes: attributes.New(pathKey, pathValue{"b"})},
- {Addr: "b1", BalancerAttributes: attributes.New(pathKey, pathValue{"b"})},
- },
- want: map[string][]resolver.Address{
- "a": {
- {Addr: "a0", BalancerAttributes: attributes.New(pathKey, pathValue{})},
- {Addr: "a1", BalancerAttributes: attributes.New(pathKey, pathValue{})},
- },
- "b": {
- {Addr: "b0", BalancerAttributes: attributes.New(pathKey, pathValue{})},
- {Addr: "b1", BalancerAttributes: attributes.New(pathKey, pathValue{})},
- },
- },
- },
- {
- // Addresses without hierarchy are ignored.
- name: "without hierarchy",
- addrs: []resolver.Address{
- {Addr: "a0", BalancerAttributes: attributes.New(pathKey, pathValue{"a"})},
- {Addr: "a1", BalancerAttributes: attributes.New(pathKey, pathValue{"a"})},
- {Addr: "b0", BalancerAttributes: nil},
- {Addr: "b1", BalancerAttributes: nil},
- },
- want: map[string][]resolver.Address{
- "a": {
- {Addr: "a0", BalancerAttributes: attributes.New(pathKey, pathValue{})},
- {Addr: "a1", BalancerAttributes: attributes.New(pathKey, pathValue{})},
- },
- },
- },
- {
- // If hierarchy is set to a wrong type (which should never happen),
- // the address is ignored.
- name: "wrong type",
- addrs: []resolver.Address{
- {Addr: "a0", BalancerAttributes: attributes.New(pathKey, pathValue{"a"})},
- {Addr: "a1", BalancerAttributes: attributes.New(pathKey, pathValue{"a"})},
- {Addr: "b0", BalancerAttributes: attributes.New(pathKey, "b")},
- {Addr: "b1", BalancerAttributes: attributes.New(pathKey, 314)},
- },
- want: map[string][]resolver.Address{
- "a": {
- {Addr: "a0", BalancerAttributes: attributes.New(pathKey, pathValue{})},
- {Addr: "a1", BalancerAttributes: attributes.New(pathKey, pathValue{})},
- },
- },
- },
- }
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- if got := Group(tt.addrs); !cmp.Equal(got, tt.want, cmp.AllowUnexported(attributes.Attributes{})) {
- t.Errorf("Group() = %v, want %v", got, tt.want)
- t.Errorf("diff: %v", cmp.Diff(got, tt.want, cmp.AllowUnexported(attributes.Attributes{})))
- }
- })
- }
- }
- func TestGroupE2E(t *testing.T) {
- hierarchy := map[string]map[string][]string{
- "p0": {
- "wt0": {"addr0", "addr1"},
- "wt1": {"addr2", "addr3"},
- },
- "p1": {
- "wt10": {"addr10", "addr11"},
- "wt11": {"addr12", "addr13"},
- },
- }
- var addrsWithHierarchy []resolver.Address
- for p, wts := range hierarchy {
- path1 := pathValue{p}
- for wt, addrs := range wts {
- path2 := append(pathValue(nil), path1...)
- path2 = append(path2, wt)
- for _, addr := range addrs {
- a := resolver.Address{
- Addr: addr,
- BalancerAttributes: attributes.New(pathKey, path2),
- }
- addrsWithHierarchy = append(addrsWithHierarchy, a)
- }
- }
- }
- gotHierarchy := make(map[string]map[string][]string)
- for p1, wts := range Group(addrsWithHierarchy) {
- gotHierarchy[p1] = make(map[string][]string)
- for p2, addrs := range Group(wts) {
- for _, addr := range addrs {
- gotHierarchy[p1][p2] = append(gotHierarchy[p1][p2], addr.Addr)
- }
- }
- }
- if !cmp.Equal(gotHierarchy, hierarchy) {
- t.Errorf("diff: %v", cmp.Diff(gotHierarchy, hierarchy))
- }
- }
|