/* * * Copyright 2023 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 grpc import ( "context" "fmt" "net" "testing" "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/resolver" ) type wrapResolverBuilder struct { resolver.Builder scheme string } func (w *wrapResolverBuilder) Scheme() string { return w.scheme } func init() { resolver.Register(&wrapResolverBuilder{Builder: resolver.Get("passthrough"), scheme: "casetest"}) resolver.Register(&wrapResolverBuilder{Builder: resolver.Get("dns"), scheme: "caseTest"}) } func (s) TestResolverCaseSensitivity(t *testing.T) { // This should find the "casetest" resolver instead of the "caseTest" // resolver, even though the latter was registered later. "casetest" is // "passthrough" and "caseTest" is "dns". With "passthrough" the dialer // should see the target's address directly, but "dns" would be converted // into a loopback IP (v4 or v6) address. target := "caseTest:///localhost:1234" addrCh := make(chan string, 1) customDialer := func(ctx context.Context, addr string) (net.Conn, error) { select { case addrCh <- addr: default: } return nil, fmt.Errorf("not dialing with custom dialer") } cc, err := Dial(target, WithContextDialer(customDialer), WithTransportCredentials(insecure.NewCredentials())) if err != nil { t.Fatalf("Unexpected Dial(%q) error: %v", target, err) } cc.Connect() if got, want := <-addrCh, "localhost:1234"; got != want { cc.Close() t.Fatalf("Dialer got address %q; wanted %q", got, want) } cc.Close() // Clear addrCh for future use. select { case <-addrCh: default: } res := &wrapResolverBuilder{Builder: resolver.Get("dns"), scheme: "caseTest2"} // This should not find the injected resolver due to the case not matching. // This results in "passthrough" being used with the address as the whole // target. target = "caseTest2:///localhost:1234" cc, err = Dial(target, WithContextDialer(customDialer), WithResolvers(res), WithTransportCredentials(insecure.NewCredentials())) if err != nil { t.Fatalf("Unexpected Dial(%q) error: %v", target, err) } cc.Connect() if got, want := <-addrCh, target; got != want { cc.Close() t.Fatalf("Dialer got address %q; wanted %q", got, want) } cc.Close() }