Source file
src/net/dnsconfig_unix_test.go
Documentation: net
1
2
3
4
5
6
7
8 package net
9
10 import (
11 "errors"
12 "io/fs"
13 "os"
14 "reflect"
15 "strings"
16 "testing"
17 "time"
18 )
19
20 var dnsReadConfigTests = []struct {
21 name string
22 want *dnsConfig
23 }{
24 {
25 name: "testdata/resolv.conf",
26 want: &dnsConfig{
27 servers: []string{"8.8.8.8:53", "[2001:4860:4860::8888]:53", "[fe80::1%lo0]:53"},
28 search: []string{"localdomain."},
29 ndots: 5,
30 timeout: 10 * time.Second,
31 attempts: 3,
32 rotate: true,
33 unknownOpt: true,
34 },
35 },
36 {
37 name: "testdata/domain-resolv.conf",
38 want: &dnsConfig{
39 servers: []string{"8.8.8.8:53"},
40 search: []string{"localdomain."},
41 ndots: 1,
42 timeout: 5 * time.Second,
43 attempts: 2,
44 },
45 },
46 {
47 name: "testdata/search-resolv.conf",
48 want: &dnsConfig{
49 servers: []string{"8.8.8.8:53"},
50 search: []string{"test.", "invalid."},
51 ndots: 1,
52 timeout: 5 * time.Second,
53 attempts: 2,
54 },
55 },
56 {
57 name: "testdata/empty-resolv.conf",
58 want: &dnsConfig{
59 servers: defaultNS,
60 ndots: 1,
61 timeout: 5 * time.Second,
62 attempts: 2,
63 search: []string{"domain.local."},
64 },
65 },
66 {
67 name: "testdata/invalid-ndots-resolv.conf",
68 want: &dnsConfig{
69 servers: defaultNS,
70 ndots: 0,
71 timeout: 5 * time.Second,
72 attempts: 2,
73 search: []string{"domain.local."},
74 },
75 },
76 {
77 name: "testdata/large-ndots-resolv.conf",
78 want: &dnsConfig{
79 servers: defaultNS,
80 ndots: 15,
81 timeout: 5 * time.Second,
82 attempts: 2,
83 search: []string{"domain.local."},
84 },
85 },
86 {
87 name: "testdata/negative-ndots-resolv.conf",
88 want: &dnsConfig{
89 servers: defaultNS,
90 ndots: 0,
91 timeout: 5 * time.Second,
92 attempts: 2,
93 search: []string{"domain.local."},
94 },
95 },
96 {
97 name: "testdata/openbsd-resolv.conf",
98 want: &dnsConfig{
99 ndots: 1,
100 timeout: 5 * time.Second,
101 attempts: 2,
102 lookup: []string{"file", "bind"},
103 servers: []string{"169.254.169.254:53", "10.240.0.1:53"},
104 search: []string{"c.symbolic-datum-552.internal."},
105 },
106 },
107 {
108 name: "testdata/single-request-resolv.conf",
109 want: &dnsConfig{
110 servers: defaultNS,
111 ndots: 1,
112 singleRequest: true,
113 timeout: 5 * time.Second,
114 attempts: 2,
115 search: []string{"domain.local."},
116 },
117 },
118 {
119 name: "testdata/single-request-reopen-resolv.conf",
120 want: &dnsConfig{
121 servers: defaultNS,
122 ndots: 1,
123 singleRequest: true,
124 timeout: 5 * time.Second,
125 attempts: 2,
126 search: []string{"domain.local."},
127 },
128 },
129 {
130 name: "testdata/linux-use-vc-resolv.conf",
131 want: &dnsConfig{
132 servers: defaultNS,
133 ndots: 1,
134 useTCP: true,
135 timeout: 5 * time.Second,
136 attempts: 2,
137 search: []string{"domain.local."},
138 },
139 },
140 {
141 name: "testdata/freebsd-usevc-resolv.conf",
142 want: &dnsConfig{
143 servers: defaultNS,
144 ndots: 1,
145 useTCP: true,
146 timeout: 5 * time.Second,
147 attempts: 2,
148 search: []string{"domain.local."},
149 },
150 },
151 {
152 name: "testdata/openbsd-tcp-resolv.conf",
153 want: &dnsConfig{
154 servers: defaultNS,
155 ndots: 1,
156 useTCP: true,
157 timeout: 5 * time.Second,
158 attempts: 2,
159 search: []string{"domain.local."},
160 },
161 },
162 }
163
164 func TestDNSReadConfig(t *testing.T) {
165 origGetHostname := getHostname
166 defer func() { getHostname = origGetHostname }()
167 getHostname = func() (string, error) { return "host.domain.local", nil }
168
169 for _, tt := range dnsReadConfigTests {
170 conf := dnsReadConfig(tt.name)
171 if conf.err != nil {
172 t.Fatal(conf.err)
173 }
174 conf.mtime = time.Time{}
175 if !reflect.DeepEqual(conf, tt.want) {
176 t.Errorf("%s:\ngot: %+v\nwant: %+v", tt.name, conf, tt.want)
177 }
178 }
179 }
180
181 func TestDNSReadMissingFile(t *testing.T) {
182 origGetHostname := getHostname
183 defer func() { getHostname = origGetHostname }()
184 getHostname = func() (string, error) { return "host.domain.local", nil }
185
186 conf := dnsReadConfig("a-nonexistent-file")
187 if !os.IsNotExist(conf.err) {
188 t.Errorf("missing resolv.conf:\ngot: %v\nwant: %v", conf.err, fs.ErrNotExist)
189 }
190 conf.err = nil
191 want := &dnsConfig{
192 servers: defaultNS,
193 ndots: 1,
194 timeout: 5 * time.Second,
195 attempts: 2,
196 search: []string{"domain.local."},
197 }
198 if !reflect.DeepEqual(conf, want) {
199 t.Errorf("missing resolv.conf:\ngot: %+v\nwant: %+v", conf, want)
200 }
201 }
202
203 var dnsDefaultSearchTests = []struct {
204 name string
205 err error
206 want []string
207 }{
208 {
209 name: "host.long.domain.local",
210 want: []string{"long.domain.local."},
211 },
212 {
213 name: "host.local",
214 want: []string{"local."},
215 },
216 {
217 name: "host",
218 want: nil,
219 },
220 {
221 name: "host.domain.local",
222 err: errors.New("errored"),
223 want: nil,
224 },
225 {
226
227
228 name: "foo.",
229 want: nil,
230 },
231 }
232
233 func TestDNSDefaultSearch(t *testing.T) {
234 origGetHostname := getHostname
235 defer func() { getHostname = origGetHostname }()
236
237 for _, tt := range dnsDefaultSearchTests {
238 getHostname = func() (string, error) { return tt.name, tt.err }
239 got := dnsDefaultSearch()
240 if !reflect.DeepEqual(got, tt.want) {
241 t.Errorf("dnsDefaultSearch with hostname %q and error %+v = %q, wanted %q", tt.name, tt.err, got, tt.want)
242 }
243 }
244 }
245
246 func TestDNSNameLength(t *testing.T) {
247 origGetHostname := getHostname
248 defer func() { getHostname = origGetHostname }()
249 getHostname = func() (string, error) { return "host.domain.local", nil }
250
251 var char63 = ""
252 for i := 0; i < 63; i++ {
253 char63 += "a"
254 }
255 longDomain := strings.Repeat(char63+".", 5) + "example"
256
257 for _, tt := range dnsReadConfigTests {
258 conf := dnsReadConfig(tt.name)
259 if conf.err != nil {
260 t.Fatal(conf.err)
261 }
262
263 var shortestSuffix int
264 for _, suffix := range tt.want.search {
265 if shortestSuffix == 0 || len(suffix) < shortestSuffix {
266 shortestSuffix = len(suffix)
267 }
268 }
269
270
271
272 longName := longDomain[len(longDomain)-254+1+shortestSuffix:]
273 if longName[0] == '.' || longName[1] == '.' {
274 longName = "aa." + longName[3:]
275 }
276 for _, fqdn := range conf.nameList(longName) {
277 if len(fqdn) > 254 {
278 t.Errorf("got %d; want less than or equal to 254", len(fqdn))
279 }
280 }
281
282
283 unsuffixable := "a." + longName[1:]
284 unsuffixableResults := conf.nameList(unsuffixable)
285 if len(unsuffixableResults) != 1 {
286 t.Errorf("suffixed names %v; want []", unsuffixableResults[1:])
287 }
288
289
290 tooLong := "a." + longDomain
291 tooLongResults := conf.nameList(tooLong)
292 if tooLongResults != nil {
293 t.Errorf("suffixed names %v; want nil", tooLongResults)
294 }
295 }
296 }
297
View as plain text