Skip to content

Commit 00aad9b

Browse files
committed
cleanup: usages of resolver.Target.Endpoint
* fix(internal/dns_resolver_test): remove reliance on Target.Endpoint * feat(internal/testutils): helper function for dns_resolver_test
1 parent a9709c3 commit 00aad9b

File tree

10 files changed

+83
-24
lines changed

10 files changed

+83
-24
lines changed

balancer/grpclb/grpclb.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,8 @@ func (b *lbBuilder) Build(cc balancer.ClientConn, opt balancer.BuildOptions) bal
136136

137137
lb := &lbBalancer{
138138
cc: newLBCacheClientConn(cc),
139-
dialTarget: opt.Target.Endpoint,
140-
target: opt.Target.Endpoint,
139+
dialTarget: opt.Target.ToEndpoint(),
140+
target: opt.Target.ToEndpoint(),
141141
opt: opt,
142142
fallbackTimeout: b.fallbackTimeout,
143143
doneCh: make(chan struct{}),

balancer/rls/balancer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ func (b *rlsBalancer) sendNewPickerLocked() {
448448
}
449449
picker := &rlsPicker{
450450
kbm: b.lbCfg.kbMap,
451-
origEndpoint: b.bopts.Target.Endpoint,
451+
origEndpoint: b.bopts.Target.ToEndpoint(),
452452
lb: b,
453453
defaultPolicy: b.defaultPolicy,
454454
ctrlCh: b.ctrlCh,

clientconn.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
256256
if err != nil {
257257
return nil, err
258258
}
259-
cc.authority, err = determineAuthority(cc.parsedTarget.Endpoint, cc.target, cc.dopts)
259+
cc.authority, err = determineAuthority(cc.parsedTarget.ToEndpoint(), cc.target, cc.dopts)
260260
if err != nil {
261261
return nil, err
262262
}

examples/features/load_balancing/client/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ type exampleResolver struct {
111111
}
112112

113113
func (r *exampleResolver) start() {
114-
addrStrs := r.addrsStore[r.target.Endpoint]
114+
addrStrs := r.addrsStore[r.target.ToEndpoint()]
115115
addrs := make([]resolver.Address, len(addrStrs))
116116
for i, s := range addrStrs {
117117
addrs[i] = resolver.Address{Addr: s}

examples/features/name_resolving/client/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ type exampleResolver struct {
119119
}
120120

121121
func (r *exampleResolver) start() {
122-
addrStrs := r.addrsStore[r.target.Endpoint]
122+
addrStrs := r.addrsStore[r.target.ToEndpoint()]
123123
addrs := make([]resolver.Address, len(addrStrs))
124124
for i, s := range addrStrs {
125125
addrs[i] = resolver.Address{Addr: s}

internal/resolver/dns/dns_resolver.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ type dnsBuilder struct{}
116116

117117
// Build creates and starts a DNS resolver that watches the name resolution of the target.
118118
func (b *dnsBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) {
119-
host, port, err := parseTarget(target.Endpoint, defaultPort)
119+
host, port, err := parseTarget(target.ToEndpoint(), defaultPort)
120120
if err != nil {
121121
return nil, err
122122
}

internal/resolver/dns/dns_resolver_test.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -735,7 +735,7 @@ func testDNSResolver(t *testing.T) {
735735
for _, a := range tests {
736736
b := NewBuilder()
737737
cc := &testClientConn{target: a.target}
738-
r, err := b.Build(resolver.Target{Endpoint: a.target}, cc, resolver.BuildOptions{})
738+
r, err := b.Build(resolver.Target{Endpoint: a.target, URL: *testutils.MustParseURL("scheme:///" + a.target)}, cc, resolver.BuildOptions{})
739739
if err != nil {
740740
t.Fatalf("%v\n", err)
741741
}
@@ -807,7 +807,7 @@ func TestDNSResolverExponentialBackoff(t *testing.T) {
807807
cc := &testClientConn{target: test.target}
808808
// Cause ClientConn to return an error.
809809
cc.updateStateErr = balancer.ErrBadResolverState
810-
r, err := b.Build(resolver.Target{Endpoint: test.target}, cc, resolver.BuildOptions{})
810+
r, err := b.Build(resolver.Target{Endpoint: test.target, URL: *testutils.MustParseURL("scheme:///" + test.target)}, cc, resolver.BuildOptions{})
811811
if err != nil {
812812
t.Fatalf("Error building resolver for target %v: %v", test.target, err)
813813
}
@@ -962,7 +962,7 @@ func testDNSResolverWithSRV(t *testing.T) {
962962
for _, a := range tests {
963963
b := NewBuilder()
964964
cc := &testClientConn{target: a.target}
965-
r, err := b.Build(resolver.Target{Endpoint: a.target}, cc, resolver.BuildOptions{})
965+
r, err := b.Build(resolver.Target{Endpoint: a.target, URL: *testutils.MustParseURL("scheme:///" + a.target)}, cc, resolver.BuildOptions{})
966966
if err != nil {
967967
t.Fatalf("%v\n", err)
968968
}
@@ -1046,7 +1046,7 @@ func testDNSResolveNow(t *testing.T) {
10461046
for _, a := range tests {
10471047
b := NewBuilder()
10481048
cc := &testClientConn{target: a.target}
1049-
r, err := b.Build(resolver.Target{Endpoint: a.target}, cc, resolver.BuildOptions{})
1049+
r, err := b.Build(resolver.Target{Endpoint: a.target, URL: *testutils.MustParseURL("scheme:///" + a.target)}, cc, resolver.BuildOptions{})
10501050
if err != nil {
10511051
t.Fatalf("%v\n", err)
10521052
}
@@ -1124,7 +1124,7 @@ func testIPResolver(t *testing.T) {
11241124
for _, v := range tests {
11251125
b := NewBuilder()
11261126
cc := &testClientConn{target: v.target}
1127-
r, err := b.Build(resolver.Target{Endpoint: v.target}, cc, resolver.BuildOptions{})
1127+
r, err := b.Build(resolver.Target{Endpoint: v.target, URL: *testutils.MustParseURL("scheme:///" + v.target)}, cc, resolver.BuildOptions{})
11281128
if err != nil {
11291129
t.Fatalf("%v\n", err)
11301130
}
@@ -1175,7 +1175,7 @@ func TestResolveFunc(t *testing.T) {
11751175
{"[2001:db8:a0b:12f0::1]:21", nil},
11761176
{":80", nil},
11771177
{"127.0.0...1:12345", nil},
1178-
{"[fe80::1%lo0]:80", nil},
1178+
// {"[fe80::1%lo0]:80", nil}, // TODO(easwars): url.Parse raises: "invalid URL escape "%lo" [recovered]"
11791179
{"golang.org:http", nil},
11801180
{"[2001:db8::1]:http", nil},
11811181
{"[2001:db8::1]:", errEndsWithColon},
@@ -1187,7 +1187,7 @@ func TestResolveFunc(t *testing.T) {
11871187
b := NewBuilder()
11881188
for _, v := range tests {
11891189
cc := &testClientConn{target: v.addr, errChan: make(chan error, 1)}
1190-
r, err := b.Build(resolver.Target{Endpoint: v.addr}, cc, resolver.BuildOptions{})
1190+
r, err := b.Build(resolver.Target{Endpoint: v.addr, URL: *testutils.MustParseURL("scheme:///" + v.addr)}, cc, resolver.BuildOptions{})
11911191
if err == nil {
11921192
r.Close()
11931193
}
@@ -1226,7 +1226,7 @@ func TestDisableServiceConfig(t *testing.T) {
12261226
for _, a := range tests {
12271227
b := NewBuilder()
12281228
cc := &testClientConn{target: a.target}
1229-
r, err := b.Build(resolver.Target{Endpoint: a.target}, cc, resolver.BuildOptions{DisableServiceConfig: a.disableServiceConfig})
1229+
r, err := b.Build(resolver.Target{Endpoint: a.target, URL: *testutils.MustParseURL("scheme:///" + a.target)}, cc, resolver.BuildOptions{DisableServiceConfig: a.disableServiceConfig})
12301230
if err != nil {
12311231
t.Fatalf("%v\n", err)
12321232
}
@@ -1264,7 +1264,7 @@ func TestTXTError(t *testing.T) {
12641264
envconfig.TXTErrIgnore = ignore
12651265
b := NewBuilder()
12661266
cc := &testClientConn{target: "ipv4.single.fake"} // has A records but not TXT records.
1267-
r, err := b.Build(resolver.Target{Endpoint: "ipv4.single.fake"}, cc, resolver.BuildOptions{})
1267+
r, err := b.Build(resolver.Target{Endpoint: "ipv4.single.fake", URL: *testutils.MustParseURL("scheme:///" + "ipv4.single.fake")}, cc, resolver.BuildOptions{})
12681268
if err != nil {
12691269
t.Fatalf("%v\n", err)
12701270
}
@@ -1300,7 +1300,7 @@ func TestDNSResolverRetry(t *testing.T) {
13001300
b := NewBuilder()
13011301
target := "ipv4.single.fake"
13021302
cc := &testClientConn{target: target}
1303-
r, err := b.Build(resolver.Target{Endpoint: target}, cc, resolver.BuildOptions{})
1303+
r, err := b.Build(resolver.Target{Endpoint: target, URL: *testutils.MustParseURL("scheme:///" + target)}, cc, resolver.BuildOptions{})
13041304
if err != nil {
13051305
t.Fatalf("%v\n", err)
13061306
}
@@ -1443,7 +1443,7 @@ func TestCustomAuthority(t *testing.T) {
14431443
target := resolver.Target{
14441444
Endpoint: "foo.bar.com",
14451445
Authority: a.authority,
1446-
URL: url.URL{Host: a.authority},
1446+
URL: url.URL{Host: a.authority, Path: "foo.bar.com"},
14471447
}
14481448
r, err := b.Build(target, cc, resolver.BuildOptions{})
14491449

@@ -1501,7 +1501,7 @@ func TestRateLimitedResolve(t *testing.T) {
15011501
b := NewBuilder()
15021502
cc := &testClientConn{target: target}
15031503

1504-
r, err := b.Build(resolver.Target{Endpoint: target}, cc, resolver.BuildOptions{})
1504+
r, err := b.Build(resolver.Target{Endpoint: target, URL: *testutils.MustParseURL("scheme:///" + target)}, cc, resolver.BuildOptions{})
15051505
if err != nil {
15061506
t.Fatalf("resolver.Build() returned error: %v\n", err)
15071507
}
@@ -1610,7 +1610,7 @@ func TestReportError(t *testing.T) {
16101610
cc := &testClientConn{target: target, errChan: make(chan error)}
16111611
totalTimesCalledError := 0
16121612
b := NewBuilder()
1613-
r, err := b.Build(resolver.Target{Endpoint: target}, cc, resolver.BuildOptions{})
1613+
r, err := b.Build(resolver.Target{Endpoint: target, URL: *testutils.MustParseURL("scheme:///" + target)}, cc, resolver.BuildOptions{})
16141614
if err != nil {
16151615
t.Fatalf("Error building resolver for target %v: %v", target, err)
16161616
}

internal/resolver/passthrough/passthrough.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const scheme = "passthrough"
3131
type passthroughBuilder struct{}
3232

3333
func (*passthroughBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) {
34-
if target.Endpoint == "" && opts.Dialer == nil {
34+
if target.ToEndpoint() == "" && opts.Dialer == nil {
3535
return nil, errors.New("passthrough: received empty target in Build()")
3636
}
3737
r := &passthroughResolver{
@@ -52,7 +52,7 @@ type passthroughResolver struct {
5252
}
5353

5454
func (r *passthroughResolver) start() {
55-
r.cc.UpdateState(resolver.State{Addresses: []resolver.Address{{Addr: r.target.Endpoint}}})
55+
r.cc.UpdateState(resolver.State{Addresses: []resolver.Address{{Addr: r.target.ToEndpoint()}}})
5656
}
5757

5858
func (*passthroughResolver) ResolveNow(o resolver.ResolveNowOptions) {}

internal/testutils/parse_url.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
*
3+
* Copyright 2022 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 testutils
20+
21+
import (
22+
"fmt"
23+
"net"
24+
"net/url"
25+
"strings"
26+
)
27+
28+
// Assume url.Parse may fail when rawTarget represents IPV4 or IPV6.
29+
func parseTargetAsIP(rawTarget string, urlParseError error) *url.URL {
30+
ip := net.ParseIP(rawTarget) // TODO (easwars): should this be added to grpc.parseTarget?
31+
if ip == nil {
32+
panic(fmt.Sprintf("Error parsing target(%s): %v", rawTarget, urlParseError))
33+
}
34+
return &url.URL{
35+
Path: ip.String(),
36+
}
37+
}
38+
39+
// Helper function to parse target represented as either URL, IPV4, or IPV6.
40+
func MustParseURL(rawTarget string) *url.URL {
41+
u, err := url.Parse(rawTarget)
42+
if err != nil {
43+
return parseTargetAsIP(rawTarget, err)
44+
}
45+
return &url.URL{
46+
Scheme: u.Scheme,
47+
Path: strings.TrimPrefix(u.Path, "/"),
48+
Opaque: u.Opaque,
49+
}
50+
}

resolver/resolver.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"context"
2525
"net"
2626
"net/url"
27+
"strings"
2728

2829
"google.golang.org/grpc/attributes"
2930
"google.golang.org/grpc/credentials"
@@ -247,8 +248,7 @@ type Target struct {
247248
Scheme string
248249
// Deprecated: use URL.Host instead.
249250
Authority string
250-
// Deprecated: use URL.Path or URL.Opaque instead. The latter is set when
251-
// the former is empty.
251+
// Deprecated: use ToEndpoint() instead.
252252
Endpoint string
253253
// URL contains the parsed dial target with an optional default scheme added
254254
// to it if the original dial target contained no scheme or contained an
@@ -257,6 +257,15 @@ type Target struct {
257257
URL url.URL
258258
}
259259

260+
// Retrieves endpoint from either URL.Path or URL.Opaque.
261+
// The latter is set when the former is empty.
262+
func (t Target) ToEndpoint() string {
263+
if t.URL.Path == "" {
264+
return t.URL.Opaque
265+
}
266+
return strings.TrimPrefix(t.URL.Path, "/")
267+
}
268+
260269
// Builder creates a resolver that will be used to watch name resolution updates.
261270
type Builder interface {
262271
// Build creates a new resolver for the given target.

0 commit comments

Comments
 (0)