1// Copyright 2015 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package net
6
7import (
8	"context"
9	"runtime"
10	"testing"
11)
12
13func allResolvers(t *testing.T, f func(t *testing.T)) {
14	t.Run("default resolver", f)
15	t.Run("forced go resolver", func(t *testing.T) {
16		// On plan9 the forceGoDNS might not force the go resolver, currently
17		// it is only forced when the Resolver.Dial field is populated.
18		// See conf.go mustUseGoResolver.
19		defer forceGoDNS()()
20		f(t)
21	})
22	t.Run("forced cgo resolver", func(t *testing.T) {
23		defer forceCgoDNS()()
24		f(t)
25	})
26}
27
28// forceGoDNS forces the resolver configuration to use the pure Go resolver
29// and returns a fixup function to restore the old settings.
30func forceGoDNS() func() {
31	c := systemConf()
32	oldGo := c.netGo
33	oldCgo := c.netCgo
34	fixup := func() {
35		c.netGo = oldGo
36		c.netCgo = oldCgo
37	}
38	c.netGo = true
39	c.netCgo = false
40	return fixup
41}
42
43// forceCgoDNS forces the resolver configuration to use the cgo resolver
44// and returns a fixup function to restore the old settings.
45func forceCgoDNS() func() {
46	c := systemConf()
47	oldGo := c.netGo
48	oldCgo := c.netCgo
49	fixup := func() {
50		c.netGo = oldGo
51		c.netCgo = oldCgo
52	}
53	c.netGo = false
54	c.netCgo = true
55	return fixup
56}
57
58func TestForceCgoDNS(t *testing.T) {
59	if !cgoAvailable {
60		t.Skip("cgo resolver not available")
61	}
62	defer forceCgoDNS()()
63	order, _ := systemConf().hostLookupOrder(nil, "go.dev")
64	if order != hostLookupCgo {
65		t.Fatalf("hostLookupOrder returned: %v, want cgo", order)
66	}
67	order, _ = systemConf().addrLookupOrder(nil, "192.0.2.1")
68	if order != hostLookupCgo {
69		t.Fatalf("addrLookupOrder returned: %v, want cgo", order)
70	}
71	if systemConf().mustUseGoResolver(nil) {
72		t.Fatal("mustUseGoResolver = true, want false")
73	}
74}
75
76func TestForceGoDNS(t *testing.T) {
77	var resolver *Resolver
78	if runtime.GOOS == "plan9" {
79		resolver = &Resolver{
80			Dial: func(_ context.Context, _, _ string) (Conn, error) {
81				panic("unreachable")
82			},
83		}
84	}
85	defer forceGoDNS()()
86	order, _ := systemConf().hostLookupOrder(resolver, "go.dev")
87	if order == hostLookupCgo {
88		t.Fatalf("hostLookupOrder returned: %v, want go resolver order", order)
89	}
90	order, _ = systemConf().addrLookupOrder(resolver, "192.0.2.1")
91	if order == hostLookupCgo {
92		t.Fatalf("addrLookupOrder returned: %v, want go resolver order", order)
93	}
94	if !systemConf().mustUseGoResolver(resolver) {
95		t.Fatal("mustUseGoResolver = false, want true")
96	}
97}
98