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