aboutsummaryrefslogtreecommitdiff
path: root/test/kubernetes_test.go
blob: 55939e350dd6665d2225f86b4a872959acddc136 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
// +build k8s

package test

import (
	"fmt"
	"io/ioutil"
	"log"
	"testing"

	"github.com/miekg/coredns/middleware/kubernetes/k8stest"
	"github.com/miekg/dns"
)

// Test data for A records
var testdataLookupA = []struct {
	Query            string
	TotalAnswerCount int
	ARecordCount     int
}{
	// Matching queries
	{"mynginx.demo.coredns.local.", 1, 1}, // One A record, should exist

	// Failure queries
	{"mynginx.test.coredns.local.", 0, 0},                     // One A record, is not exposed
	{"someservicethatdoesnotexist.demo.coredns.local.", 0, 0}, // Record does not exist

	// Namespace wildcards
	{"mynginx.*.coredns.local.", 1, 1},                       // One A record, via wildcard namespace
	{"mynginx.any.coredns.local.", 1, 1},                     // One A record, via wildcard namespace
	{"someservicethatdoesnotexist.*.coredns.local.", 0, 0},   // Record does not exist with wildcard for namespace
	{"someservicethatdoesnotexist.any.coredns.local.", 0, 0}, // Record does not exist with wildcard for namespace
	{"*.demo.coredns.local.", 2, 2},                          // Two A records, via wildcard
	{"any.demo.coredns.local.", 2, 2},                        // Two A records, via wildcard
	{"*.test.coredns.local.", 0, 0},                          // Two A record, via wildcard that is not exposed
	{"any.test.coredns.local.", 0, 0},                        // Two A record, via wildcard that is not exposed
	{"*.*.coredns.local.", 2, 2},                             // Two A records, via namespace and service wildcard
}

// Test data for SRV records
var testdataLookupSRV = []struct {
	Query            string
	TotalAnswerCount int
	//	ARecordCount     int
	SRVRecordCount int
}{
	// Matching queries
	{"mynginx.demo.coredns.local.", 1, 1}, // One SRV record, should exist

	// Failure queries
	{"mynginx.test.coredns.local.", 0, 0},                     // One SRV record, is not exposed
	{"someservicethatdoesnotexist.demo.coredns.local.", 0, 0}, // Record does not exist

	// Namespace wildcards
	{"mynginx.*.coredns.local.", 1, 1},                       // One SRV record, via wildcard namespace
	{"mynginx.any.coredns.local.", 1, 1},                     // One SRV record, via wildcard namespace
	{"someservicethatdoesnotexist.*.coredns.local.", 0, 0},   // Record does not exist with wildcard for namespace
	{"someservicethatdoesnotexist.any.coredns.local.", 0, 0}, // Record does not exist with wildcard for namespace
	{"*.demo.coredns.local.", 1, 1},                          // One SRV record, via wildcard
	{"any.demo.coredns.local.", 1, 1},                        // One SRV record, via wildcard
	{"*.test.coredns.local.", 0, 0},                          // One SRV record, via wildcard that is not exposed
	{"any.test.coredns.local.", 0, 0},                        // One SRV record, via wildcard that is not exposed
	{"*.*.coredns.local.", 1, 1},                             // One SRV record, via namespace and service wildcard
}

func TestK8sIntegration(t *testing.T) {
	t.Log("   === RUN testLookupA")
	testLookupA(t)
	t.Log("   === RUN testLookupSRV")
	testLookupSRV(t)
}

func testLookupA(t *testing.T) {
	if !k8stest.CheckKubernetesRunning() {
		t.Skip("Skipping Kubernetes Integration tests. Kubernetes is not running")
	}

	coreFile :=
		`.:0 {
    kubernetes coredns.local {
		endpoint http://localhost:8080
		namespaces demo
    }
`

	server, _, udp, err := Server(t, coreFile)
	if err != nil {
		t.Fatal("Could not get server: %s", err)
	}
	defer server.Stop()

	log.SetOutput(ioutil.Discard)

	for _, testData := range testdataLookupA {
		t.Logf("[log] Testing query string: '%v'\n", testData.Query)
		dnsClient := new(dns.Client)
		dnsMessage := new(dns.Msg)

		dnsMessage.SetQuestion(testData.Query, dns.TypeA)
		dnsMessage.SetEdns0(4096, true)

		res, _, err := dnsClient.Exchange(dnsMessage, udp)
		if err != nil {
			t.Fatal("Could not send query: %s", err)
		}
		// Count A records in the answer section
		ARecordCount := 0
		for _, a := range res.Answer {
			if a.Header().Rrtype == dns.TypeA {
				ARecordCount++
			}
		}

		if ARecordCount != testData.ARecordCount {
			t.Errorf("Expected '%v' A records in response. Instead got '%v' A records. Test query string: '%v'", testData.ARecordCount, ARecordCount, testData.Query)
		}
		if len(res.Answer) != testData.TotalAnswerCount {
			t.Errorf("Expected '%v' records in answer section. Instead got '%v' records in answer section. Test query string: '%v'", testData.TotalAnswerCount, len(res.Answer), testData.Query)
		}
	}
}

func testLookupSRV(t *testing.T) {
	if !k8stest.CheckKubernetesRunning() {
		t.Skip("Skipping Kubernetes Integration tests. Kubernetes is not running")
	}

	coreFile :=
		`.:0 {
    kubernetes coredns.local {
		endpoint http://localhost:8080
		namespaces demo
    }
`

	server, _, udp, err := Server(t, coreFile)
	if err != nil {
		t.Fatal("Could not get server: %s", err)
	}
	defer server.Stop()

	log.SetOutput(ioutil.Discard)

	// TODO: Add checks for A records in additional section

	for _, testData := range testdataLookupSRV {
		t.Logf("[log] Testing query string: '%v'\n", testData.Query)
		dnsClient := new(dns.Client)
		dnsMessage := new(dns.Msg)

		dnsMessage.SetQuestion(testData.Query, dns.TypeSRV)
		dnsMessage.SetEdns0(4096, true)

		res, _, err := dnsClient.Exchange(dnsMessage, udp)
		if err != nil {
			t.Fatal("Could not send query: %s", err)
		}
		// Count SRV records in the answer section
		srvRecordCount := 0
		for _, a := range res.Answer {
			fmt.Printf("RR: %v\n", a)
			if a.Header().Rrtype == dns.TypeSRV {
				srvRecordCount++
			}
		}

		if srvRecordCount != testData.SRVRecordCount {
			t.Errorf("Expected '%v' SRV records in response. Instead got '%v' SRV records. Test query string: '%v'", testData.SRVRecordCount, srvRecordCount, testData.Query)
		}
		if len(res.Answer) != testData.TotalAnswerCount {
			t.Errorf("Expected '%v' records in answer section. Instead got '%v' records in answer section. Test query string: '%v'", testData.TotalAnswerCount, len(res.Answer), testData.Query)
		}
	}
}