@@ -17,6 +17,7 @@ import (
17
17
"github.com/pkg/errors"
18
18
"github.com/stretchr/testify/require"
19
19
"golang.org/x/exp/rand"
20
+ corev1 "k8s.io/api/core/v1"
20
21
)
21
22
22
23
const (
@@ -46,15 +47,22 @@ var (
46
47
clientPath = ciliumManifestsDir + "client-ds.yaml"
47
48
)
48
49
49
- // TestLRP tests if the local redirect policy in a cilium cluster is functioning
50
- // The test assumes the current kubeconfig points to a cluster with cilium (1.16+), cns,
51
- // and kube-dns already installed. The lrp feature flag should be enabled in the cilium config
52
- // Resources created are automatically cleaned up
53
- // From the lrp folder, run: go test ./lrp_test.go -v -tags "lrp" -run ^TestLRP$
54
- func TestLRP (t * testing.T ) {
55
- config := kubernetes .MustGetRestConfig ()
56
- ctx := context .Background ()
50
+ func setupLRP (t * testing.T , ctx context.Context ) (* corev1.Pod , func ()) {
51
+ var cleanUpFns []func ()
52
+ success := false
53
+ cleanupFn := func () {
54
+ for len (cleanUpFns ) > 0 {
55
+ cleanUpFns [len (cleanUpFns )- 1 ]()
56
+ cleanUpFns = cleanUpFns [:len (cleanUpFns )- 1 ]
57
+ }
58
+ }
59
+ defer func () {
60
+ if ! success {
61
+ cleanupFn ()
62
+ }
63
+ }()
57
64
65
+ config := kubernetes .MustGetRestConfig ()
58
66
cs := kubernetes .MustGetClientset ()
59
67
60
68
ciliumCS , err := ciliumClientset .NewForConfig (config )
@@ -90,14 +98,14 @@ func TestLRP(t *testing.T) {
90
98
91
99
// deploy node local dns preqreqs and pods
92
100
_ , cleanupConfigMap := kubernetes .MustSetupConfigMap (ctx , cs , nodeLocalDNSConfigMapPath )
93
- defer cleanupConfigMap ( )
101
+ cleanUpFns = append ( cleanUpFns , cleanupConfigMap )
94
102
_ , cleanupServiceAccount := kubernetes .MustSetupServiceAccount (ctx , cs , nodeLocalDNSServiceAccountPath )
95
- defer cleanupServiceAccount ( )
103
+ cleanUpFns = append ( cleanUpFns , cleanupServiceAccount )
96
104
_ , cleanupService := kubernetes .MustSetupService (ctx , cs , nodeLocalDNSServicePath )
97
- defer cleanupService ( )
105
+ cleanUpFns = append ( cleanUpFns , cleanupService )
98
106
nodeLocalDNSDS , cleanupNodeLocalDNS := kubernetes .MustSetupDaemonset (ctx , cs , tempNodeLocalDNSDaemonsetPath )
99
- defer cleanupNodeLocalDNS ( )
100
- err = kubernetes .WaitForPodsRunning (ctx , cs , nodeLocalDNSDS .Namespace , nodeLocalDNSLabelSelector )
107
+ cleanUpFns = append ( cleanUpFns , cleanupNodeLocalDNS )
108
+ kubernetes .WaitForPodDaemonset (ctx , cs , nodeLocalDNSDS .Namespace , nodeLocalDNSDS . Name , nodeLocalDNSLabelSelector )
101
109
require .NoError (t , err )
102
110
// select a local dns pod after they start running
103
111
pods , err := kubernetes .GetPodsByNode (ctx , cs , nodeLocalDNSDS .Namespace , nodeLocalDNSLabelSelector , selectedNode )
@@ -106,19 +114,19 @@ func TestLRP(t *testing.T) {
106
114
107
115
// deploy lrp
108
116
_ , cleanupLRP := kubernetes .MustSetupLRP (ctx , ciliumCS , lrpPath )
109
- defer cleanupLRP ( )
117
+ cleanUpFns = append ( cleanUpFns , cleanupLRP )
110
118
111
119
// create client pods
112
120
clientDS , cleanupClient := kubernetes .MustSetupDaemonset (ctx , cs , clientPath )
113
- defer cleanupClient ( )
114
- err = kubernetes .WaitForPodsRunning (ctx , cs , clientDS .Namespace , clientLabelSelector )
121
+ cleanUpFns = append ( cleanUpFns , cleanupClient )
122
+ kubernetes .WaitForPodDaemonset (ctx , cs , clientDS .Namespace , clientDS . Name , clientLabelSelector )
115
123
require .NoError (t , err )
116
124
// select a client pod after they start running
117
125
clientPods , err := kubernetes .GetPodsByNode (ctx , cs , clientDS .Namespace , clientLabelSelector , selectedNode )
118
126
require .NoError (t , err )
119
- selectedClientPod := TakeOne (clientPods .Items ). Name
127
+ selectedClientPod := TakeOne (clientPods .Items )
120
128
121
- t .Logf ("Selected node: %s, node local dns pod: %s, client pod: %s\n " , selectedNode , selectedLocalDNSPod , selectedClientPod )
129
+ t .Logf ("Selected node: %s, node local dns pod: %s, client pod: %s\n " , selectedNode , selectedLocalDNSPod , selectedClientPod . Name )
122
130
123
131
// port forward to local dns pod on same node (separate thread)
124
132
pf , err := k8s .NewPortForwarder (config , k8s.PortForwardingOpts {
@@ -130,17 +138,27 @@ func TestLRP(t *testing.T) {
130
138
require .NoError (t , err )
131
139
pctx := context .Background ()
132
140
portForwardCtx , cancel := context .WithTimeout (pctx , (retryAttempts + 1 )* retryDelay )
133
- defer cancel ( )
141
+ cleanUpFns = append ( cleanUpFns , cancel )
134
142
135
143
err = defaultRetrier .Do (portForwardCtx , func () error {
136
144
t .Logf ("attempting port forward to a pod with label %s, in namespace %s..." , nodeLocalDNSLabelSelector , nodeLocalDNSDS .Namespace )
137
145
return errors .Wrap (pf .Forward (portForwardCtx ), "could not start port forward" )
138
146
})
139
147
require .NoError (t , err , "could not start port forward within %d" , (retryAttempts + 1 )* retryDelay )
140
- defer pf .Stop ( )
148
+ cleanUpFns = append ( cleanUpFns , pf .Stop )
141
149
142
150
t .Log ("started port forward" )
143
151
152
+ success = true
153
+ return & selectedClientPod , cleanupFn
154
+ }
155
+
156
+ func testLRPCase (t * testing.T , ctx context.Context , clientPod corev1.Pod , clientCmd []string , expectResponse , expectErrMsg string ,
157
+ shouldError , countShouldIncrease bool ) {
158
+
159
+ config := kubernetes .MustGetRestConfig ()
160
+ cs := kubernetes .MustGetClientset ()
161
+
144
162
// labels for target lrp metric
145
163
metricLabels := map [string ]string {
146
164
"family" : "1" ,
@@ -153,24 +171,48 @@ func TestLRP(t *testing.T) {
153
171
beforeMetric , err := prometheus .GetMetric (promAddress , coreDNSRequestCountTotal , metricLabels )
154
172
require .NoError (t , err )
155
173
156
- t .Log ("calling nslookup from client" )
157
- // nslookup to 10.0.0.10 (coredns)
158
- val , err := kubernetes .ExecCmdOnPod (ctx , cs , clientDS .Namespace , selectedClientPod , clientContainer , []string {
159
- "nslookup" , "google.com" , "10.0.0.10" ,
160
- }, config )
161
- require .NoError (t , err , string (val ))
162
- // can connect
163
- require .Contains (t , string (val ), "Server:" )
174
+ t .Log ("calling command from client" )
175
+
176
+ val , errMsg , err := kubernetes .ExecCmdOnPod (ctx , cs , clientPod .Namespace , clientPod .Name , clientContainer , clientCmd , config , false )
177
+ if shouldError {
178
+ require .Error (t , err , "stdout: %s, stderr: %s" , string (val ), string (errMsg ))
179
+ } else {
180
+ require .NoError (t , err , "stdout: %s, stderr: %s" , string (val ), string (errMsg ))
181
+ }
182
+
183
+ require .Contains (t , string (val ), expectResponse )
184
+ require .Contains (t , string (errMsg ), expectErrMsg )
164
185
165
186
// in case there is time to propagate
166
- time .Sleep (1 * time .Second )
187
+ time .Sleep (500 * time .Millisecond )
167
188
168
- // curl again and see count increases
189
+ // curl again and see count diff
169
190
afterMetric , err := prometheus .GetMetric (promAddress , coreDNSRequestCountTotal , metricLabels )
170
191
require .NoError (t , err )
171
192
172
- // count should go up
173
- require .Greater (t , afterMetric .GetCounter ().GetValue (), beforeMetric .GetCounter ().GetValue (), "dns metric count did not increase after nslookup" )
193
+ if countShouldIncrease {
194
+ require .Greater (t , afterMetric .GetCounter ().GetValue (), beforeMetric .GetCounter ().GetValue (), "dns metric count did not increase after command" )
195
+ } else {
196
+ require .Equal (t , afterMetric .GetCounter ().GetValue (), beforeMetric .GetCounter ().GetValue (), "dns metric count increased after command" )
197
+ }
198
+ }
199
+
200
+ // TestLRP tests if the local redirect policy in a cilium cluster is functioning
201
+ // The test assumes the current kubeconfig points to a cluster with cilium (1.16+), cns,
202
+ // and kube-dns already installed. The lrp feature flag should be enabled in the cilium config
203
+ // Does not check if cluster is in a stable state
204
+ // Resources created are automatically cleaned up
205
+ // From the lrp folder, run: go test ./ -v -tags "lrp" -run ^TestLRP$
206
+ func TestLRP (t * testing.T ) {
207
+ ctx := context .Background ()
208
+
209
+ selectedPod , cleanupFn := setupLRP (t , ctx )
210
+ defer cleanupFn ()
211
+ require .NotNil (t , selectedPod )
212
+
213
+ testLRPCase (t , ctx , * selectedPod , []string {
214
+ "nslookup" , "google.com" , "10.0.0.10" ,
215
+ }, "" , "" , false , true )
174
216
}
175
217
176
218
// TakeOne takes one item from the slice randomly; if empty, it returns the empty value for the type
0 commit comments