From 83f73ac21ed976b783e9d15f8eec8619c08ba1a6 Mon Sep 17 00:00:00 2001 From: Menghan Li Date: Thu, 2 Apr 2020 11:11:25 -0700 Subject: [PATCH 1/5] [balancer_hierarchy] balancer: support hierarchical paths in addresses balancer/base.SplitHierarchicalAddresses --- balancer/base/hierarchical.go | 96 ++++++++++++++ balancer/base/hierarchical_test.go | 197 +++++++++++++++++++++++++++++ 2 files changed, 293 insertions(+) create mode 100644 balancer/base/hierarchical.go create mode 100644 balancer/base/hierarchical_test.go diff --git a/balancer/base/hierarchical.go b/balancer/base/hierarchical.go new file mode 100644 index 000000000000..1e4a080a5a44 --- /dev/null +++ b/balancer/base/hierarchical.go @@ -0,0 +1,96 @@ +/* + * + * 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 base + +import ( + "google.golang.org/grpc/attributes" + "google.golang.org/grpc/resolver" +) + +type hierarchicalPathKeyType string + +const hierarchicalPathKey = hierarchicalPathKeyType("grpc.internal.address.hierarchical_path") + +// RetrieveHierarchicalPath returns the hierarchical path of addr. +func RetrieveHierarchicalPath(addr resolver.Address) []string { + attrs := addr.Attributes + if attrs == nil { + return nil + } + path, ok := attrs.Value(hierarchicalPathKey).([]string) + if !ok { + return nil + } + return path +} + +// OverrideHierarchicalPath overrides the hierarchical path in addr with path. +func OverrideHierarchicalPath(addr resolver.Address, path []string) resolver.Address { + if addr.Attributes == nil { + addr.Attributes = attributes.New(hierarchicalPathKey, path) + return addr + } + addr.Attributes = addr.Attributes.WithValues(hierarchicalPathKey, path) + return addr +} + +// SplitHierarchicalAddresses splits a slice of addresses into groups based on +// the first hierarchy path. The first hierarchy path will be removed from the +// result. +// +// Input: +// [ +// {addr0, path: [p0, wt0]} +// {addr1, path: [p0, wt1]} +// {addr2, path: [p1, wt2]} +// {addr3, path: [p1, wt3]} +// ] +// +// Addresses will be split into p0/p1, and the p0/p1 will be removed from the +// path. +// +// Output: +// { +// p0: [ +// {addr0, path: [wt0]}, +// {addr1, path: [wt1]}, +// ], +// p1: [ +// {addr2, path: [wt2]}, +// {addr3, path: [wt3]}, +// ], +// } +func SplitHierarchicalAddresses(addrs []resolver.Address) map[string][]resolver.Address { + ret := make(map[string][]resolver.Address) + for _, addr := range addrs { + oldPath := RetrieveHierarchicalPath(addr) + if len(oldPath) == 0 { + // When hierarchical path is not set, or has no path in it, skip the + // address. Another option is to return this address with path "", + // this shouldn't conflict with anything because "" isn't a valid + // path. + continue + } + curPath := oldPath[0] + newPath := oldPath[1:] + newAddr := OverrideHierarchicalPath(addr, newPath) + ret[curPath] = append(ret[curPath], newAddr) + } + return ret +} diff --git a/balancer/base/hierarchical_test.go b/balancer/base/hierarchical_test.go new file mode 100644 index 000000000000..b9aeec455bda --- /dev/null +++ b/balancer/base/hierarchical_test.go @@ -0,0 +1,197 @@ +/* + * + * 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 base + +import ( + "testing" + + "github.com/google/go-cmp/cmp" + "google.golang.org/grpc/attributes" + "google.golang.org/grpc/resolver" +) + +func TestRetrieveHierarchicalPath(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{ + Attributes: attributes.New(hierarchicalPathKey, []string{"a", "b"}), + }, + want: []string{"a", "b"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := RetrieveHierarchicalPath(tt.addr); !cmp.Equal(got, tt.want) { + t.Errorf("RetrieveHierarchicalPath() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestOverrideHierarchicalPath(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{ + Attributes: attributes.New(hierarchicalPathKey, []string{"before", "a", "b"}), + }, + path: []string{"a", "b"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + newAddr := OverrideHierarchicalPath(tt.addr, tt.path) + newPath := RetrieveHierarchicalPath(newAddr) + if !cmp.Equal(newPath, tt.path) { + t.Errorf("path after OverrideHierarchicalPath() = %v, want %v", newPath, tt.path) + } + }) + } +} + +func TestSplitHierarchicalAddresses(t *testing.T) { + tests := []struct { + name string + addrs []resolver.Address + want map[string][]resolver.Address + }{ + { + name: "all with hierarchy", + addrs: []resolver.Address{ + {Addr: "a0", Attributes: attributes.New(hierarchicalPathKey, []string{"a"})}, + {Addr: "a1", Attributes: attributes.New(hierarchicalPathKey, []string{"a"})}, + {Addr: "b0", Attributes: attributes.New(hierarchicalPathKey, []string{"b"})}, + {Addr: "b1", Attributes: attributes.New(hierarchicalPathKey, []string{"b"})}, + }, + want: map[string][]resolver.Address{ + "a": []resolver.Address{ + {Addr: "a0", Attributes: attributes.New(hierarchicalPathKey, []string{})}, + {Addr: "a1", Attributes: attributes.New(hierarchicalPathKey, []string{})}, + }, + "b": []resolver.Address{ + {Addr: "b0", Attributes: attributes.New(hierarchicalPathKey, []string{})}, + {Addr: "b1", Attributes: attributes.New(hierarchicalPathKey, []string{})}, + }, + }, + }, + { + // Addresses without hierarchy are ignored. + name: "without hierarchy", + addrs: []resolver.Address{ + {Addr: "a0", Attributes: attributes.New(hierarchicalPathKey, []string{"a"})}, + {Addr: "a1", Attributes: attributes.New(hierarchicalPathKey, []string{"a"})}, + {Addr: "b0", Attributes: nil}, + {Addr: "b1", Attributes: nil}, + }, + want: map[string][]resolver.Address{ + "a": []resolver.Address{ + {Addr: "a0", Attributes: attributes.New(hierarchicalPathKey, []string{})}, + {Addr: "a1", Attributes: attributes.New(hierarchicalPathKey, []string{})}, + }, + }, + }, + { + // If hierarchy is set to a wrong type (which should never happen), + // the address is ignored. + name: "wrong type", + addrs: []resolver.Address{ + {Addr: "a0", Attributes: attributes.New(hierarchicalPathKey, []string{"a"})}, + {Addr: "a1", Attributes: attributes.New(hierarchicalPathKey, []string{"a"})}, + {Addr: "b0", Attributes: attributes.New(hierarchicalPathKey, "b")}, + {Addr: "b1", Attributes: attributes.New(hierarchicalPathKey, 314)}, + }, + want: map[string][]resolver.Address{ + "a": []resolver.Address{ + {Addr: "a0", Attributes: attributes.New(hierarchicalPathKey, []string{})}, + {Addr: "a1", Attributes: attributes.New(hierarchicalPathKey, []string{})}, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := SplitHierarchicalAddresses(tt.addrs); !cmp.Equal(got, tt.want, cmp.AllowUnexported(attributes.Attributes{})) { + t.Errorf("SplitHierarchicalAddresses() = %v, want %v", got, tt.want) + t.Errorf("diff: %v", cmp.Diff(got, tt.want, cmp.AllowUnexported(attributes.Attributes{}))) + } + }) + } +} + +func TestSplitHierarchicalAddressesE2E(t *testing.T) { + hierarchy := map[string]map[string][]string{ + "p0": map[string][]string{ + "wt0": []string{"addr0", "addr1"}, + "wt1": []string{"addr2", "addr3"}, + }, + "p1": map[string][]string{ + "wt10": []string{"addr10", "addr11"}, + "wt11": []string{"addr12", "addr13"}, + }, + } + + var addrsWithHierarchy []resolver.Address + for p, wts := range hierarchy { + path1 := []string{p} + for wt, addrs := range wts { + path2 := append([]string(nil), path1...) + path2 = append(path2, wt) + for _, addr := range addrs { + a := resolver.Address{ + Addr: addr, + Attributes: attributes.New(hierarchicalPathKey, path2), + } + addrsWithHierarchy = append(addrsWithHierarchy, a) + } + } + } + + gotHierarchy := make(map[string]map[string][]string) + for p1, wts := range SplitHierarchicalAddresses(addrsWithHierarchy) { + gotHierarchy[p1] = make(map[string][]string) + for p2, addrs := range SplitHierarchicalAddresses(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)) + } +} From 36e5aff54c9b18070dd1479529b90432ef677e39 Mon Sep 17 00:00:00 2001 From: Menghan Li Date: Thu, 2 Apr 2020 17:01:41 -0700 Subject: [PATCH 2/5] [balancer_hierarchy] short --- balancer/base/hierarchical_test.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/balancer/base/hierarchical_test.go b/balancer/base/hierarchical_test.go index b9aeec455bda..2cef160b3aa6 100644 --- a/balancer/base/hierarchical_test.go +++ b/balancer/base/hierarchical_test.go @@ -99,11 +99,11 @@ func TestSplitHierarchicalAddresses(t *testing.T) { {Addr: "b1", Attributes: attributes.New(hierarchicalPathKey, []string{"b"})}, }, want: map[string][]resolver.Address{ - "a": []resolver.Address{ + "a": { {Addr: "a0", Attributes: attributes.New(hierarchicalPathKey, []string{})}, {Addr: "a1", Attributes: attributes.New(hierarchicalPathKey, []string{})}, }, - "b": []resolver.Address{ + "b": { {Addr: "b0", Attributes: attributes.New(hierarchicalPathKey, []string{})}, {Addr: "b1", Attributes: attributes.New(hierarchicalPathKey, []string{})}, }, @@ -119,7 +119,7 @@ func TestSplitHierarchicalAddresses(t *testing.T) { {Addr: "b1", Attributes: nil}, }, want: map[string][]resolver.Address{ - "a": []resolver.Address{ + "a": { {Addr: "a0", Attributes: attributes.New(hierarchicalPathKey, []string{})}, {Addr: "a1", Attributes: attributes.New(hierarchicalPathKey, []string{})}, }, @@ -136,7 +136,7 @@ func TestSplitHierarchicalAddresses(t *testing.T) { {Addr: "b1", Attributes: attributes.New(hierarchicalPathKey, 314)}, }, want: map[string][]resolver.Address{ - "a": []resolver.Address{ + "a": { {Addr: "a0", Attributes: attributes.New(hierarchicalPathKey, []string{})}, {Addr: "a1", Attributes: attributes.New(hierarchicalPathKey, []string{})}, }, @@ -155,13 +155,13 @@ func TestSplitHierarchicalAddresses(t *testing.T) { func TestSplitHierarchicalAddressesE2E(t *testing.T) { hierarchy := map[string]map[string][]string{ - "p0": map[string][]string{ - "wt0": []string{"addr0", "addr1"}, - "wt1": []string{"addr2", "addr3"}, + "p0": { + "wt0": {"addr0", "addr1"}, + "wt1": {"addr2", "addr3"}, }, - "p1": map[string][]string{ - "wt10": []string{"addr10", "addr11"}, - "wt11": []string{"addr12", "addr13"}, + "p1": { + "wt10": {"addr10", "addr11"}, + "wt11": {"addr12", "addr13"}, }, } From 8e3b29d98ee81a25a5e8120dbabb546a4a90d85c Mon Sep 17 00:00:00 2001 From: Menghan Li Date: Wed, 15 Apr 2020 14:26:55 -0700 Subject: [PATCH 3/5] [balancer_hierarchy] rename --- .../hierarchy.go} | 18 ++++++------ .../hierarchy_test.go} | 28 +++++++++---------- 2 files changed, 23 insertions(+), 23 deletions(-) rename balancer/base/{hierarchical.go => hierarchy/hierarchy.go} (78%) rename balancer/base/{hierarchical_test.go => hierarchy/hierarchy_test.go} (84%) diff --git a/balancer/base/hierarchical.go b/balancer/base/hierarchy/hierarchy.go similarity index 78% rename from balancer/base/hierarchical.go rename to balancer/base/hierarchy/hierarchy.go index 1e4a080a5a44..11d6b6d89f1c 100644 --- a/balancer/base/hierarchical.go +++ b/balancer/base/hierarchy/hierarchy.go @@ -16,7 +16,7 @@ * */ -package base +package hierarchy import ( "google.golang.org/grpc/attributes" @@ -27,8 +27,8 @@ type hierarchicalPathKeyType string const hierarchicalPathKey = hierarchicalPathKeyType("grpc.internal.address.hierarchical_path") -// RetrieveHierarchicalPath returns the hierarchical path of addr. -func RetrieveHierarchicalPath(addr resolver.Address) []string { +// Get returns the hierarchical path of addr. +func Get(addr resolver.Address) []string { attrs := addr.Attributes if attrs == nil { return nil @@ -40,8 +40,8 @@ func RetrieveHierarchicalPath(addr resolver.Address) []string { return path } -// OverrideHierarchicalPath overrides the hierarchical path in addr with path. -func OverrideHierarchicalPath(addr resolver.Address, path []string) resolver.Address { +// Set overrides the hierarchical path in addr with path. +func Set(addr resolver.Address, path []string) resolver.Address { if addr.Attributes == nil { addr.Attributes = attributes.New(hierarchicalPathKey, path) return addr @@ -50,7 +50,7 @@ func OverrideHierarchicalPath(addr resolver.Address, path []string) resolver.Add return addr } -// SplitHierarchicalAddresses splits a slice of addresses into groups based on +// Group splits a slice of addresses into groups based on // the first hierarchy path. The first hierarchy path will be removed from the // result. // @@ -76,10 +76,10 @@ func OverrideHierarchicalPath(addr resolver.Address, path []string) resolver.Add // {addr3, path: [wt3]}, // ], // } -func SplitHierarchicalAddresses(addrs []resolver.Address) map[string][]resolver.Address { +func Group(addrs []resolver.Address) map[string][]resolver.Address { ret := make(map[string][]resolver.Address) for _, addr := range addrs { - oldPath := RetrieveHierarchicalPath(addr) + oldPath := Get(addr) if len(oldPath) == 0 { // When hierarchical path is not set, or has no path in it, skip the // address. Another option is to return this address with path "", @@ -89,7 +89,7 @@ func SplitHierarchicalAddresses(addrs []resolver.Address) map[string][]resolver. } curPath := oldPath[0] newPath := oldPath[1:] - newAddr := OverrideHierarchicalPath(addr, newPath) + newAddr := Set(addr, newPath) ret[curPath] = append(ret[curPath], newAddr) } return ret diff --git a/balancer/base/hierarchical_test.go b/balancer/base/hierarchy/hierarchy_test.go similarity index 84% rename from balancer/base/hierarchical_test.go rename to balancer/base/hierarchy/hierarchy_test.go index 2cef160b3aa6..63f0befa4c11 100644 --- a/balancer/base/hierarchical_test.go +++ b/balancer/base/hierarchy/hierarchy_test.go @@ -16,7 +16,7 @@ * */ -package base +package hierarchy import ( "testing" @@ -26,7 +26,7 @@ import ( "google.golang.org/grpc/resolver" ) -func TestRetrieveHierarchicalPath(t *testing.T) { +func TestGet(t *testing.T) { tests := []struct { name string addr resolver.Address @@ -47,14 +47,14 @@ func TestRetrieveHierarchicalPath(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := RetrieveHierarchicalPath(tt.addr); !cmp.Equal(got, tt.want) { - t.Errorf("RetrieveHierarchicalPath() = %v, want %v", got, tt.want) + if got := Get(tt.addr); !cmp.Equal(got, tt.want) { + t.Errorf("Get() = %v, want %v", got, tt.want) } }) } } -func TestOverrideHierarchicalPath(t *testing.T) { +func TestSet(t *testing.T) { tests := []struct { name string addr resolver.Address @@ -75,16 +75,16 @@ func TestOverrideHierarchicalPath(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - newAddr := OverrideHierarchicalPath(tt.addr, tt.path) - newPath := RetrieveHierarchicalPath(newAddr) + newAddr := Set(tt.addr, tt.path) + newPath := Get(newAddr) if !cmp.Equal(newPath, tt.path) { - t.Errorf("path after OverrideHierarchicalPath() = %v, want %v", newPath, tt.path) + t.Errorf("path after Set() = %v, want %v", newPath, tt.path) } }) } } -func TestSplitHierarchicalAddresses(t *testing.T) { +func TestGroup(t *testing.T) { tests := []struct { name string addrs []resolver.Address @@ -145,15 +145,15 @@ func TestSplitHierarchicalAddresses(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := SplitHierarchicalAddresses(tt.addrs); !cmp.Equal(got, tt.want, cmp.AllowUnexported(attributes.Attributes{})) { - t.Errorf("SplitHierarchicalAddresses() = %v, want %v", got, tt.want) + 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 TestSplitHierarchicalAddressesE2E(t *testing.T) { +func TestGroupE2E(t *testing.T) { hierarchy := map[string]map[string][]string{ "p0": { "wt0": {"addr0", "addr1"}, @@ -182,9 +182,9 @@ func TestSplitHierarchicalAddressesE2E(t *testing.T) { } gotHierarchy := make(map[string]map[string][]string) - for p1, wts := range SplitHierarchicalAddresses(addrsWithHierarchy) { + for p1, wts := range Group(addrsWithHierarchy) { gotHierarchy[p1] = make(map[string][]string) - for p2, addrs := range SplitHierarchicalAddresses(wts) { + for p2, addrs := range Group(wts) { for _, addr := range addrs { gotHierarchy[p1][p2] = append(gotHierarchy[p1][p2], addr.Addr) } From 9798b655fd5b171a78608edabb31d2742ffe8837 Mon Sep 17 00:00:00 2001 From: Menghan Li Date: Wed, 15 Apr 2020 16:52:14 -0700 Subject: [PATCH 4/5] [balancer_hierarchy] package comment --- balancer/base/hierarchy/hierarchy.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/balancer/base/hierarchy/hierarchy.go b/balancer/base/hierarchy/hierarchy.go index 11d6b6d89f1c..d7093708b78c 100644 --- a/balancer/base/hierarchy/hierarchy.go +++ b/balancer/base/hierarchy/hierarchy.go @@ -16,6 +16,8 @@ * */ +// Package hierarchy contains functions to set and get hierarchy string from +// addresses. package hierarchy import ( From 177d1d160bd65abdb54aa4e2dc71151dac842404 Mon Sep 17 00:00:00 2001 From: Menghan Li Date: Thu, 16 Apr 2020 10:54:56 -0700 Subject: [PATCH 5/5] [balancer_hierarchy] c2 --- .../base => internal}/hierarchy/hierarchy.go | 19 +++++---- .../hierarchy/hierarchy_test.go | 42 +++++++++---------- 2 files changed, 31 insertions(+), 30 deletions(-) rename {balancer/base => internal}/hierarchy/hierarchy.go (79%) rename {balancer/base => internal}/hierarchy/hierarchy_test.go (70%) diff --git a/balancer/base/hierarchy/hierarchy.go b/internal/hierarchy/hierarchy.go similarity index 79% rename from balancer/base/hierarchy/hierarchy.go rename to internal/hierarchy/hierarchy.go index d7093708b78c..17185d95d38e 100644 --- a/balancer/base/hierarchy/hierarchy.go +++ b/internal/hierarchy/hierarchy.go @@ -18,6 +18,8 @@ // Package hierarchy contains functions to set and get hierarchy string from // addresses. +// +// This package is experimental. package hierarchy import ( @@ -25,9 +27,9 @@ import ( "google.golang.org/grpc/resolver" ) -type hierarchicalPathKeyType string +type pathKeyType string -const hierarchicalPathKey = hierarchicalPathKeyType("grpc.internal.address.hierarchical_path") +const pathKey = pathKeyType("grpc.internal.address.hierarchical_path") // Get returns the hierarchical path of addr. func Get(addr resolver.Address) []string { @@ -35,7 +37,7 @@ func Get(addr resolver.Address) []string { if attrs == nil { return nil } - path, ok := attrs.Value(hierarchicalPathKey).([]string) + path, ok := attrs.Value(pathKey).([]string) if !ok { return nil } @@ -45,10 +47,10 @@ func Get(addr resolver.Address) []string { // Set overrides the hierarchical path in addr with path. func Set(addr resolver.Address, path []string) resolver.Address { if addr.Attributes == nil { - addr.Attributes = attributes.New(hierarchicalPathKey, path) + addr.Attributes = attributes.New(pathKey, path) return addr } - addr.Attributes = addr.Attributes.WithValues(hierarchicalPathKey, path) + addr.Attributes = addr.Attributes.WithValues(pathKey, path) return addr } @@ -78,15 +80,14 @@ func Set(addr resolver.Address, path []string) resolver.Address { // {addr3, path: [wt3]}, // ], // } +// +// If hierarchical path is not set, or has no path in it, the address is +// dropped. func Group(addrs []resolver.Address) map[string][]resolver.Address { ret := make(map[string][]resolver.Address) for _, addr := range addrs { oldPath := Get(addr) if len(oldPath) == 0 { - // When hierarchical path is not set, or has no path in it, skip the - // address. Another option is to return this address with path "", - // this shouldn't conflict with anything because "" isn't a valid - // path. continue } curPath := oldPath[0] diff --git a/balancer/base/hierarchy/hierarchy_test.go b/internal/hierarchy/hierarchy_test.go similarity index 70% rename from balancer/base/hierarchy/hierarchy_test.go rename to internal/hierarchy/hierarchy_test.go index 63f0befa4c11..fc62f82b0850 100644 --- a/balancer/base/hierarchy/hierarchy_test.go +++ b/internal/hierarchy/hierarchy_test.go @@ -40,7 +40,7 @@ func TestGet(t *testing.T) { { name: "set", addr: resolver.Address{ - Attributes: attributes.New(hierarchicalPathKey, []string{"a", "b"}), + Attributes: attributes.New(pathKey, []string{"a", "b"}), }, want: []string{"a", "b"}, }, @@ -68,7 +68,7 @@ func TestSet(t *testing.T) { { name: "before is set", addr: resolver.Address{ - Attributes: attributes.New(hierarchicalPathKey, []string{"before", "a", "b"}), + Attributes: attributes.New(pathKey, []string{"before", "a", "b"}), }, path: []string{"a", "b"}, }, @@ -93,19 +93,19 @@ func TestGroup(t *testing.T) { { name: "all with hierarchy", addrs: []resolver.Address{ - {Addr: "a0", Attributes: attributes.New(hierarchicalPathKey, []string{"a"})}, - {Addr: "a1", Attributes: attributes.New(hierarchicalPathKey, []string{"a"})}, - {Addr: "b0", Attributes: attributes.New(hierarchicalPathKey, []string{"b"})}, - {Addr: "b1", Attributes: attributes.New(hierarchicalPathKey, []string{"b"})}, + {Addr: "a0", Attributes: attributes.New(pathKey, []string{"a"})}, + {Addr: "a1", Attributes: attributes.New(pathKey, []string{"a"})}, + {Addr: "b0", Attributes: attributes.New(pathKey, []string{"b"})}, + {Addr: "b1", Attributes: attributes.New(pathKey, []string{"b"})}, }, want: map[string][]resolver.Address{ "a": { - {Addr: "a0", Attributes: attributes.New(hierarchicalPathKey, []string{})}, - {Addr: "a1", Attributes: attributes.New(hierarchicalPathKey, []string{})}, + {Addr: "a0", Attributes: attributes.New(pathKey, []string{})}, + {Addr: "a1", Attributes: attributes.New(pathKey, []string{})}, }, "b": { - {Addr: "b0", Attributes: attributes.New(hierarchicalPathKey, []string{})}, - {Addr: "b1", Attributes: attributes.New(hierarchicalPathKey, []string{})}, + {Addr: "b0", Attributes: attributes.New(pathKey, []string{})}, + {Addr: "b1", Attributes: attributes.New(pathKey, []string{})}, }, }, }, @@ -113,15 +113,15 @@ func TestGroup(t *testing.T) { // Addresses without hierarchy are ignored. name: "without hierarchy", addrs: []resolver.Address{ - {Addr: "a0", Attributes: attributes.New(hierarchicalPathKey, []string{"a"})}, - {Addr: "a1", Attributes: attributes.New(hierarchicalPathKey, []string{"a"})}, + {Addr: "a0", Attributes: attributes.New(pathKey, []string{"a"})}, + {Addr: "a1", Attributes: attributes.New(pathKey, []string{"a"})}, {Addr: "b0", Attributes: nil}, {Addr: "b1", Attributes: nil}, }, want: map[string][]resolver.Address{ "a": { - {Addr: "a0", Attributes: attributes.New(hierarchicalPathKey, []string{})}, - {Addr: "a1", Attributes: attributes.New(hierarchicalPathKey, []string{})}, + {Addr: "a0", Attributes: attributes.New(pathKey, []string{})}, + {Addr: "a1", Attributes: attributes.New(pathKey, []string{})}, }, }, }, @@ -130,15 +130,15 @@ func TestGroup(t *testing.T) { // the address is ignored. name: "wrong type", addrs: []resolver.Address{ - {Addr: "a0", Attributes: attributes.New(hierarchicalPathKey, []string{"a"})}, - {Addr: "a1", Attributes: attributes.New(hierarchicalPathKey, []string{"a"})}, - {Addr: "b0", Attributes: attributes.New(hierarchicalPathKey, "b")}, - {Addr: "b1", Attributes: attributes.New(hierarchicalPathKey, 314)}, + {Addr: "a0", Attributes: attributes.New(pathKey, []string{"a"})}, + {Addr: "a1", Attributes: attributes.New(pathKey, []string{"a"})}, + {Addr: "b0", Attributes: attributes.New(pathKey, "b")}, + {Addr: "b1", Attributes: attributes.New(pathKey, 314)}, }, want: map[string][]resolver.Address{ "a": { - {Addr: "a0", Attributes: attributes.New(hierarchicalPathKey, []string{})}, - {Addr: "a1", Attributes: attributes.New(hierarchicalPathKey, []string{})}, + {Addr: "a0", Attributes: attributes.New(pathKey, []string{})}, + {Addr: "a1", Attributes: attributes.New(pathKey, []string{})}, }, }, }, @@ -174,7 +174,7 @@ func TestGroupE2E(t *testing.T) { for _, addr := range addrs { a := resolver.Address{ Addr: addr, - Attributes: attributes.New(hierarchicalPathKey, path2), + Attributes: attributes.New(pathKey, path2), } addrsWithHierarchy = append(addrsWithHierarchy, a) }