@@ -17,6 +17,7 @@ import (
1717 "github.com/pkg/errors"
1818 "github.com/stretchr/testify/require"
1919 "golang.org/x/exp/rand"
20+ corev1 "k8s.io/api/core/v1"
2021)
2122
2223const (
@@ -46,15 +47,22 @@ var (
4647 clientPath = ciliumManifestsDir + "client-ds.yaml"
4748)
4849
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+ }()
5764
65+ config := kubernetes .MustGetRestConfig ()
5866 cs := kubernetes .MustGetClientset ()
5967
6068 ciliumCS , err := ciliumClientset .NewForConfig (config )
@@ -90,14 +98,14 @@ func TestLRP(t *testing.T) {
9098
9199 // deploy node local dns preqreqs and pods
92100 _ , cleanupConfigMap := kubernetes .MustSetupConfigMap (ctx , cs , nodeLocalDNSConfigMapPath )
93- defer cleanupConfigMap ( )
101+ cleanUpFns = append ( cleanUpFns , cleanupConfigMap )
94102 _ , cleanupServiceAccount := kubernetes .MustSetupServiceAccount (ctx , cs , nodeLocalDNSServiceAccountPath )
95- defer cleanupServiceAccount ( )
103+ cleanUpFns = append ( cleanUpFns , cleanupServiceAccount )
96104 _ , cleanupService := kubernetes .MustSetupService (ctx , cs , nodeLocalDNSServicePath )
97- defer cleanupService ( )
105+ cleanUpFns = append ( cleanUpFns , cleanupService )
98106 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 )
101109 require .NoError (t , err )
102110 // select a local dns pod after they start running
103111 pods , err := kubernetes .GetPodsByNode (ctx , cs , nodeLocalDNSDS .Namespace , nodeLocalDNSLabelSelector , selectedNode )
@@ -106,19 +114,19 @@ func TestLRP(t *testing.T) {
106114
107115 // deploy lrp
108116 _ , cleanupLRP := kubernetes .MustSetupLRP (ctx , ciliumCS , lrpPath )
109- defer cleanupLRP ( )
117+ cleanUpFns = append ( cleanUpFns , cleanupLRP )
110118
111119 // create client pods
112120 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 )
115123 require .NoError (t , err )
116124 // select a client pod after they start running
117125 clientPods , err := kubernetes .GetPodsByNode (ctx , cs , clientDS .Namespace , clientLabelSelector , selectedNode )
118126 require .NoError (t , err )
119- selectedClientPod := TakeOne (clientPods .Items ). Name
127+ selectedClientPod := TakeOne (clientPods .Items )
120128
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 )
122130
123131 // port forward to local dns pod on same node (separate thread)
124132 pf , err := k8s .NewPortForwarder (config , k8s.PortForwardingOpts {
@@ -130,17 +138,27 @@ func TestLRP(t *testing.T) {
130138 require .NoError (t , err )
131139 pctx := context .Background ()
132140 portForwardCtx , cancel := context .WithTimeout (pctx , (retryAttempts + 1 )* retryDelay )
133- defer cancel ( )
141+ cleanUpFns = append ( cleanUpFns , cancel )
134142
135143 err = defaultRetrier .Do (portForwardCtx , func () error {
136144 t .Logf ("attempting port forward to a pod with label %s, in namespace %s..." , nodeLocalDNSLabelSelector , nodeLocalDNSDS .Namespace )
137145 return errors .Wrap (pf .Forward (portForwardCtx ), "could not start port forward" )
138146 })
139147 require .NoError (t , err , "could not start port forward within %d" , (retryAttempts + 1 )* retryDelay )
140- defer pf .Stop ( )
148+ cleanUpFns = append ( cleanUpFns , pf .Stop )
141149
142150 t .Log ("started port forward" )
143151
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+
144162 // labels for target lrp metric
145163 metricLabels := map [string ]string {
146164 "family" : "1" ,
@@ -153,24 +171,48 @@ func TestLRP(t *testing.T) {
153171 beforeMetric , err := prometheus .GetMetric (promAddress , coreDNSRequestCountTotal , metricLabels )
154172 require .NoError (t , err )
155173
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 )
164185
165186 // in case there is time to propagate
166- time .Sleep (1 * time .Second )
187+ time .Sleep (500 * time .Millisecond )
167188
168- // curl again and see count increases
189+ // curl again and see count diff
169190 afterMetric , err := prometheus .GetMetric (promAddress , coreDNSRequestCountTotal , metricLabels )
170191 require .NoError (t , err )
171192
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 )
174216}
175217
176218// TakeOne takes one item from the slice randomly; if empty, it returns the empty value for the type
0 commit comments