Skip to content

Commit f335812

Browse files
committed
unittests: Fixes unit tests for Windows (part 5)
Currently, there are some unit tests that are failing on Windows due to various reasons: - getHostDNSConfig is reading a resolv.conf file. However, we don't have that on Windows. Instead, we can get the DNS server list and the DNS suffix list from Windows itself. On Windows, getHostDNSConfig will now return the host's DNS configuration if the given resolverConfig is "Host". If it's not "Host" or an empty string, an error will be returned. Based on the code from kubernetes/test/images/agnhost/dns/dns_windows.go
1 parent eb4e2a2 commit f335812

File tree

6 files changed

+372
-59
lines changed

6 files changed

+372
-59
lines changed

pkg/kubelet/network/dns/dns.go

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,10 @@ const (
5959

6060
// Configurer is used for setting up DNS resolver configuration when launching pods.
6161
type Configurer struct {
62-
recorder record.EventRecorder
63-
nodeRef *v1.ObjectReference
64-
nodeIPs []net.IP
62+
recorder record.EventRecorder
63+
getHostDNSConfig func(string) (*runtimeapi.DNSConfig, error)
64+
nodeRef *v1.ObjectReference
65+
nodeIPs []net.IP
6566

6667
// If non-nil, use this for container DNS server.
6768
clusterDNS []net.IP
@@ -76,12 +77,13 @@ type Configurer struct {
7677
// NewConfigurer returns a DNS configurer for launching pods.
7778
func NewConfigurer(recorder record.EventRecorder, nodeRef *v1.ObjectReference, nodeIPs []net.IP, clusterDNS []net.IP, clusterDomain, resolverConfig string) *Configurer {
7879
return &Configurer{
79-
recorder: recorder,
80-
nodeRef: nodeRef,
81-
nodeIPs: nodeIPs,
82-
clusterDNS: clusterDNS,
83-
ClusterDomain: clusterDomain,
84-
ResolverConfig: resolverConfig,
80+
recorder: recorder,
81+
getHostDNSConfig: getHostDNSConfig,
82+
nodeRef: nodeRef,
83+
nodeIPs: nodeIPs,
84+
clusterDNS: clusterDNS,
85+
ClusterDomain: clusterDomain,
86+
ResolverConfig: resolverConfig,
8587
}
8688
}
8789

@@ -279,28 +281,6 @@ func parseResolvConf(reader io.Reader) (nameservers []string, searches []string,
279281
return nameservers, searches, options, utilerrors.NewAggregate(allErrors)
280282
}
281283

282-
func (c *Configurer) getHostDNSConfig() (*runtimeapi.DNSConfig, error) {
283-
var hostDNS, hostSearch, hostOptions []string
284-
// Get host DNS settings
285-
if c.ResolverConfig != "" {
286-
f, err := os.Open(c.ResolverConfig)
287-
if err != nil {
288-
return nil, err
289-
}
290-
defer f.Close()
291-
292-
hostDNS, hostSearch, hostOptions, err = parseResolvConf(f)
293-
if err != nil {
294-
return nil, err
295-
}
296-
}
297-
return &runtimeapi.DNSConfig{
298-
Servers: hostDNS,
299-
Searches: hostSearch,
300-
Options: hostOptions,
301-
}, nil
302-
}
303-
304284
func getPodDNSType(pod *v1.Pod) (podDNSType, error) {
305285
dnsPolicy := pod.Spec.DNSPolicy
306286
switch dnsPolicy {
@@ -384,7 +364,7 @@ func appendDNSConfig(existingDNSConfig *runtimeapi.DNSConfig, dnsConfig *v1.PodD
384364

385365
// GetPodDNS returns DNS settings for the pod.
386366
func (c *Configurer) GetPodDNS(pod *v1.Pod) (*runtimeapi.DNSConfig, error) {
387-
dnsConfig, err := c.getHostDNSConfig()
367+
dnsConfig, err := c.getHostDNSConfig(c.ResolverConfig)
388368
if err != nil {
389369
return nil, err
390370
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//go:build !windows
2+
// +build !windows
3+
4+
/*
5+
Copyright 2023 The Kubernetes Authors.
6+
7+
Licensed under the Apache License, Version 2.0 (the "License");
8+
you may not use this file except in compliance with the License.
9+
You may obtain a copy of the License at
10+
11+
http://www.apache.org/licenses/LICENSE-2.0
12+
13+
Unless required by applicable law or agreed to in writing, software
14+
distributed under the License is distributed on an "AS IS" BASIS,
15+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
See the License for the specific language governing permissions and
17+
limitations under the License.
18+
*/
19+
20+
package dns
21+
22+
import (
23+
"fmt"
24+
"os"
25+
26+
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
27+
"k8s.io/klog/v2"
28+
)
29+
30+
func getHostDNSConfig(resolverConfig string) (*runtimeapi.DNSConfig, error) {
31+
var hostDNS, hostSearch, hostOptions []string
32+
// Get host DNS settings
33+
if resolverConfig != "" {
34+
f, err := os.Open(resolverConfig)
35+
if err != nil {
36+
klog.ErrorS(err, "Could not open resolv conf file.")
37+
return nil, err
38+
}
39+
defer f.Close()
40+
41+
hostDNS, hostSearch, hostOptions, err = parseResolvConf(f)
42+
if err != nil {
43+
err := fmt.Errorf("Encountered error while parsing resolv conf file. Error: %w", err)
44+
klog.ErrorS(err, "Could not parse resolv conf file.")
45+
return nil, err
46+
}
47+
}
48+
return &runtimeapi.DNSConfig{
49+
Servers: hostDNS,
50+
Searches: hostSearch,
51+
Options: hostOptions,
52+
}, nil
53+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//go:build !windows
2+
// +build !windows
3+
4+
/*
5+
Copyright 2023 The Kubernetes Authors.
6+
7+
Licensed under the Apache License, Version 2.0 (the "License");
8+
you may not use this file except in compliance with the License.
9+
You may obtain a copy of the License at
10+
11+
http://www.apache.org/licenses/LICENSE-2.0
12+
13+
Unless required by applicable law or agreed to in writing, software
14+
distributed under the License is distributed on an "AS IS" BASIS,
15+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
See the License for the specific language governing permissions and
17+
limitations under the License.
18+
*/
19+
20+
package dns
21+
22+
import (
23+
"fmt"
24+
"os"
25+
"testing"
26+
)
27+
28+
var (
29+
defaultResolvConf = "/etc/resolv.conf"
30+
// configurer.getHostDNSConfig is faked on Windows, while it is not faked on Linux.
31+
fakeGetHostDNSConfigCustom = getHostDNSConfig
32+
)
33+
34+
// getResolvConf returns a temporary resolv.conf file containing the testHostNameserver nameserver and
35+
// testHostDomain search field, and a cleanup function for the temporary file.
36+
func getResolvConf(t *testing.T) (string, func()) {
37+
resolvConfContent := []byte(fmt.Sprintf("nameserver %s\nsearch %s\n", testHostNameserver, testHostDomain))
38+
tmpfile, err := os.CreateTemp("", "tmpResolvConf")
39+
if err != nil {
40+
t.Fatal(err)
41+
}
42+
43+
cleanup := func() {
44+
os.Remove(tmpfile.Name())
45+
}
46+
47+
if _, err := tmpfile.Write(resolvConfContent); err != nil {
48+
cleanup()
49+
t.Fatal(err)
50+
}
51+
if err := tmpfile.Close(); err != nil {
52+
cleanup()
53+
t.Fatal(err)
54+
}
55+
56+
return tmpfile.Name(), cleanup
57+
}

pkg/kubelet/network/dns/dns_test.go

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ package dns
1919
import (
2020
"fmt"
2121
"net"
22-
"os"
23-
goruntime "runtime"
2422
"strconv"
2523
"strings"
2624
"testing"
@@ -42,7 +40,10 @@ import (
4240
)
4341

4442
var (
45-
fetchEvent = func(recorder *record.FakeRecorder) string {
43+
// testHostNameserver and testHostDomain are also being used in dns_windows_test.go.
44+
testHostNameserver = "8.8.8.8"
45+
testHostDomain = "host.domain"
46+
fetchEvent = func(recorder *record.FakeRecorder) string {
4647
select {
4748
case event := <-recorder.Events:
4849
return event
@@ -457,26 +458,19 @@ func TestGetPodDNS(t *testing.T) {
457458
testCases := []struct {
458459
desc string
459460
expandedDNSConfig bool
460-
skipOnWindows bool
461461
}{
462462
{
463463
desc: "Not ExpandedDNSConfig",
464464
expandedDNSConfig: false,
465-
skipOnWindows: true,
466465
},
467466
{
468467
desc: "ExpandedDNSConfig",
469468
expandedDNSConfig: true,
470-
skipOnWindows: true,
471469
},
472470
}
473471

474472
for _, tc := range testCases {
475473
t.Run(tc.desc, func(t *testing.T) {
476-
// Skip tests that fail on Windows, as discussed during the SIG Testing meeting from January 10, 2023
477-
if tc.skipOnWindows && goruntime.GOOS == "windows" {
478-
t.Skip("Skipping test that fails on Windows")
479-
}
480474
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExpandedDNSConfig, tc.expandedDNSConfig)()
481475
testGetPodDNS(t)
482476
})
@@ -541,8 +535,7 @@ func testGetPodDNS(t *testing.T) {
541535
t.Errorf("expected search \".\", got %+v", options[3].DNSSearch)
542536
}
543537

544-
testResolverConfig := "/etc/resolv.conf"
545-
configurer = NewConfigurer(recorder, nodeRef, nil, testClusterDNS, testClusterDNSDomain, testResolverConfig)
538+
configurer = NewConfigurer(recorder, nodeRef, nil, testClusterDNS, testClusterDNSDomain, defaultResolvConf)
546539
for i, pod := range pods {
547540
var err error
548541
dnsConfig, err := configurer.GetPodDNS(pod)
@@ -599,8 +592,6 @@ func TestGetPodDNSCustom(t *testing.T) {
599592
testSvcDomain := fmt.Sprintf("svc.%s", testClusterDNSDomain)
600593
testNsSvcDomain := fmt.Sprintf("%s.svc.%s", testPodNamespace, testClusterDNSDomain)
601594
testNdotsOptionValue := "3"
602-
testHostNameserver := "8.8.8.8"
603-
testHostDomain := "host.domain"
604595

605596
testPod := &v1.Pod{
606597
ObjectMeta: metav1.ObjectMeta{
@@ -609,20 +600,11 @@ func TestGetPodDNSCustom(t *testing.T) {
609600
},
610601
}
611602

612-
resolvConfContent := []byte(fmt.Sprintf("nameserver %s\nsearch %s\n", testHostNameserver, testHostDomain))
613-
tmpfile, err := os.CreateTemp("", "tmpResolvConf")
614-
if err != nil {
615-
t.Fatal(err)
616-
}
617-
defer os.Remove(tmpfile.Name())
618-
if _, err := tmpfile.Write(resolvConfContent); err != nil {
619-
t.Fatal(err)
620-
}
621-
if err := tmpfile.Close(); err != nil {
622-
t.Fatal(err)
623-
}
603+
resolvConf, cleanup := getResolvConf(t)
604+
defer cleanup()
624605

625-
configurer := NewConfigurer(recorder, nodeRef, nil, []net.IP{netutils.ParseIPSloppy(testClusterNameserver)}, testClusterDNSDomain, tmpfile.Name())
606+
configurer := NewConfigurer(recorder, nodeRef, nil, []net.IP{netutils.ParseIPSloppy(testClusterNameserver)}, testClusterDNSDomain, resolvConf)
607+
configurer.getHostDNSConfig = fakeGetHostDNSConfigCustom
626608

627609
testCases := []struct {
628610
desc string

0 commit comments

Comments
 (0)