Skip to content

Commit 94d2896

Browse files
committed
chore: add e2e test
1. Add e2e test for finalizer 2. Clean up e2e test Signed-off-by: Kyle Dong <kyle.dong@suse.com>
1 parent c6c14fd commit 94d2896

6 files changed

Lines changed: 209 additions & 22 deletions

File tree

internal/controller/workloadpolicyproposal_controller.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ func (r *WorkloadPolicyProposalReconciler) Reconcile(
6161

6262
_, err = controllerutil.CreateOrPatch(ctx, r.Client, &policy, func() error {
6363
policy.Spec = policyProposal.Spec.IntoWorkloadPolicySpec()
64+
// Avoid sending null for array fields like tags, which the schema rejects.
65+
if policy.Spec.Tags == nil {
66+
policy.Spec.Tags = []string{}
67+
}
68+
6469
err = controllerutil.SetControllerReference(&policyProposal, &policy, r.Scheme)
6570
if err != nil {
6671
return fmt.Errorf("failed to set controller reference: %w", err)

test/e2e/enforcement_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ func getEnforcementTest() types.Feature {
5454
Assess("required resources become available", IfRequiredResourcesAreCreated).
5555
Assess("a namespace-scoped policy can be enforced correctly",
5656
func(ctx context.Context, t *testing.T, _ *envconf.Config) context.Context {
57-
t.Log("create a security policy")
57+
t.Log("create a policy")
5858

5959
r := ctx.Value(key("client")).(*resources.Resources)
6060

test/e2e/learning_mode_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ func getLearningModeTest() types.Feature {
5757
return ctx
5858
}).
5959
Assess("required resources become available", IfRequiredResourcesAreCreated).
60-
Assess("the workload security proposal is created successfully for each supported resource",
60+
Assess("the workload policy proposal is created successfully for each supported resource",
6161
func(ctx context.Context, t *testing.T, _ *envconf.Config) context.Context {
6262
r := ctx.Value(key("client")).(*resources.Resources)
6363

test/e2e/main_test.go

Lines changed: 194 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@ package e2e_test
33
import (
44
"bytes"
55
"context"
6+
"slices"
67
"strings"
78
"testing"
9+
"time"
810

911
"github.com/neuvector/runtime-enforcer/api/v1alpha1"
12+
"github.com/neuvector/runtime-enforcer/internal/policygenerator"
1013
"github.com/stretchr/testify/assert"
1114
"github.com/stretchr/testify/require"
1215
corev1 "k8s.io/api/core/v1"
@@ -55,7 +58,7 @@ func getMainTest() types.Feature {
5558
return ctx
5659
}).
5760
Assess("required resources become available", IfRequiredResourcesAreCreated).
58-
Assess("the workload security proposal is created successfully for the ubuntu pod",
61+
Assess("the workload policy proposal is created successfully for the ubuntu pod",
5962
func(ctx context.Context, t *testing.T, _ *envconf.Config) context.Context {
6063
r := ctx.Value(key("client")).(*resources.Resources)
6164

@@ -86,7 +89,7 @@ func getMainTest() types.Feature {
8689
id := ctx.Value(key("group")).(string)
8790
r := ctx.Value(key("client")).(*resources.Resources)
8891

89-
t.Log("waiting for security policy proposal to be created: ", id)
92+
t.Log("waiting for workload policy proposal to be created: ", id)
9093

9194
proposal := v1alpha1.WorkloadPolicyProposal{
9295
ObjectMeta: metav1.ObjectMeta{
@@ -113,9 +116,9 @@ func getMainTest() types.Feature {
113116

114117
return context.WithValue(ctx, key("proposal"), &proposal)
115118
}).
116-
Assess("a proposal is promoted to a security policy and the WP is created",
119+
Assess("a proposal is promoted to a workload policy and the WP is created",
117120
func(ctx context.Context, t *testing.T, _ *envconf.Config) context.Context {
118-
t.Log("create a security policy")
121+
t.Log("create a workload policy")
119122

120123
r := ctx.Value(key("client")).(*resources.Resources)
121124
proposal := ctx.Value(key("proposal")).(*v1alpha1.WorkloadPolicyProposal)
@@ -129,7 +132,7 @@ func getMainTest() types.Feature {
129132
Mode: "protect",
130133
Selector: proposal.Spec.Selector,
131134
RulesByContainer: map[string]*v1alpha1.WorkloadPolicyRules{
132-
"ubuntu": &v1alpha1.WorkloadPolicyRules{
135+
"ubuntu": {
133136
Executables: v1alpha1.WorkloadPolicyExecutables{
134137
Allowed: proposal.Spec.RulesByContainer["ubuntu"].Executables.Allowed,
135138
AllowedPrefixes: proposal.Spec.RulesByContainer["ubuntu"].Executables.AllowedPrefixes,
@@ -173,15 +176,194 @@ func getMainTest() types.Feature {
173176

174177
return ctx
175178
}).
176-
Assess("delete security policy", func(ctx context.Context, t *testing.T, _ *envconf.Config) context.Context {
177-
r := ctx.Value(key("client")).(*resources.Resources)
178-
policy := ctx.Value(key("policy")).(*v1alpha1.WorkloadPolicy)
179+
Assess("the WorkloadPolicy has the finalizer set",
180+
func(ctx context.Context, t *testing.T, _ *envconf.Config) context.Context {
181+
r := ctx.Value(key("client")).(*resources.Resources)
182+
policy := &v1alpha1.WorkloadPolicy{
183+
ObjectMeta: metav1.ObjectMeta{
184+
Name: "test-policy",
185+
Namespace: workloadNamespace,
186+
},
187+
}
188+
189+
err := wait.For(
190+
conditions.New(r).ResourceMatch(
191+
policy,
192+
func(obj k8s.Object) bool {
193+
wp := obj.(*v1alpha1.WorkloadPolicy)
194+
return slices.Contains(wp.Finalizers, v1alpha1.WorkloadPolicyFinalizer)
195+
},
196+
),
197+
wait.WithTimeout(DefaultOperationTimeout),
198+
)
199+
require.NoError(t, err, "WorkloadPolicy finalizer is not set")
179200

180-
err := r.Delete(ctx, policy)
181-
require.NoError(t, err)
201+
return ctx
202+
}).
203+
Assess("Verify a non-referenced WorkloadPolicy can be deleted",
204+
func(ctx context.Context, t *testing.T, _ *envconf.Config) context.Context {
205+
var err error
206+
r := ctx.Value(key("client")).(*resources.Resources)
207+
nonReferencedPolicyName := "non-referenced-wp"
182208

183-
return ctx
184-
}).
209+
// Create a new WorkloadPolicy
210+
nonReferencedPolicy := v1alpha1.WorkloadPolicy{
211+
ObjectMeta: metav1.ObjectMeta{
212+
Name: nonReferencedPolicyName,
213+
Namespace: workloadNamespace,
214+
},
215+
Spec: v1alpha1.WorkloadPolicySpec{
216+
Mode: "monitor",
217+
RulesByContainer: map[string]*v1alpha1.WorkloadPolicyRules{
218+
"ubuntu": {
219+
Executables: v1alpha1.WorkloadPolicyExecutables{
220+
Allowed: []string{"/bin/true"},
221+
},
222+
},
223+
},
224+
Severity: 9,
225+
Message: "non-referenced-wp",
226+
Tags: []string{"non-referenced-wp-policy"},
227+
},
228+
}
229+
require.NoError(
230+
t,
231+
r.Create(ctx, &nonReferencedPolicy),
232+
"failed to create non-referenced WorkloadPolicy",
233+
)
234+
235+
err = r.Delete(ctx, &nonReferencedPolicy)
236+
require.NoError(t, err, "failed to delete non-referenced WorkloadPolicy")
237+
238+
// Wait for the WorkloadPolicy to be deleted
239+
err = wait.For(
240+
conditions.New(r).ResourceDeleted(&nonReferencedPolicy),
241+
wait.WithTimeout(time.Minute*2),
242+
wait.WithInterval(time.Second*5),
243+
)
244+
require.NoError(
245+
t,
246+
err,
247+
"policy was not deleted within timeout",
248+
)
249+
250+
return ctx
251+
}).
252+
Assess("Verify a referenced WorkloadPolicy cannot be deleted",
253+
func(ctx context.Context, t *testing.T, _ *envconf.Config) context.Context {
254+
var err error
255+
r := ctx.Value(key("client")).(*resources.Resources)
256+
referencedPolicyName := "referenced-wp"
257+
podName := "referenced-wp-pod"
258+
259+
// Create a new WorkloadPolicy
260+
referencedPolicy := v1alpha1.WorkloadPolicy{
261+
ObjectMeta: metav1.ObjectMeta{
262+
Name: referencedPolicyName,
263+
Namespace: workloadNamespace,
264+
},
265+
Spec: v1alpha1.WorkloadPolicySpec{
266+
Mode: "monitor",
267+
RulesByContainer: map[string]*v1alpha1.WorkloadPolicyRules{
268+
"ubuntu": {
269+
Executables: v1alpha1.WorkloadPolicyExecutables{
270+
Allowed: []string{"/bin/true"},
271+
},
272+
},
273+
},
274+
Severity: 9,
275+
Message: "referenced-wp",
276+
Tags: []string{"referenced-wp-policy"},
277+
},
278+
}
279+
require.NoError(
280+
t,
281+
r.Create(ctx, &referencedPolicy),
282+
"failed to create referenced WorkloadPolicy",
283+
)
284+
285+
pod := corev1.Pod{
286+
ObjectMeta: metav1.ObjectMeta{
287+
Name: podName,
288+
Namespace: workloadNamespace,
289+
Labels: map[string]string{
290+
policygenerator.PolicyLabelKey: referencedPolicyName,
291+
},
292+
},
293+
Spec: corev1.PodSpec{
294+
Containers: []corev1.Container{
295+
{
296+
Name: "pause",
297+
Image: "registry.k8s.io/pause",
298+
},
299+
},
300+
},
301+
}
302+
require.NoError(
303+
t,
304+
r.Create(ctx, &pod),
305+
"failed to create Pod",
306+
)
307+
308+
// Try to delete the referenced policy
309+
require.NoError(
310+
t,
311+
r.Delete(ctx, &referencedPolicy),
312+
"failed to issue delete request for WorkloadPolicy",
313+
)
314+
315+
// Verify the policy still exists (should not be deleted due to finalizer)
316+
err = wait.For(
317+
conditions.New(r).ResourceMatch(
318+
&referencedPolicy,
319+
func(obj k8s.Object) bool {
320+
wp := obj.(*v1alpha1.WorkloadPolicy)
321+
return wp.DeletionTimestamp != nil &&
322+
slices.Contains(wp.Finalizers, v1alpha1.WorkloadPolicyFinalizer)
323+
},
324+
),
325+
wait.WithTimeout(30*time.Second),
326+
wait.WithInterval(5*time.Second),
327+
)
328+
require.NoError(
329+
t,
330+
err,
331+
"WorkloadPolicy should still exist while referenced by Pod",
332+
)
333+
334+
// Clean up pod, then policy should be deleted automatically
335+
require.NoError(
336+
t,
337+
r.Delete(ctx, &pod),
338+
"failed to delete Pod",
339+
)
340+
341+
// Wait for the pod to be deleted
342+
err = wait.For(
343+
conditions.New(r).ResourceDeleted(&pod),
344+
wait.WithTimeout(2*time.Minute),
345+
wait.WithInterval(5*time.Second),
346+
)
347+
require.NoError(
348+
t,
349+
err,
350+
"Pod was not deleted within timeout",
351+
)
352+
353+
// Now the policy should be deleted automatically
354+
err = wait.For(
355+
conditions.New(r).ResourceDeleted(&referencedPolicy),
356+
wait.WithTimeout(2*time.Minute),
357+
wait.WithInterval(5*time.Second),
358+
)
359+
require.NoError(
360+
t,
361+
err,
362+
"WorkloadPolicy should be deleted after Pod is removed",
363+
)
364+
365+
return ctx
366+
}).
185367
Teardown(func(ctx context.Context, t *testing.T, _ *envconf.Config) context.Context {
186368
t.Log("uninstalling test resources")
187369

test/e2e/monitoring_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ func getMonitoringTest() types.Feature {
266266
Assess("required resources become available", IfRequiredResourcesAreCreated).
267267
Assess("a namespace-scoped policy can monitor behaviors correctly",
268268
func(ctx context.Context, t *testing.T, _ *envconf.Config) context.Context {
269-
t.Log("create a security policy")
269+
t.Log("create a policy")
270270
namespace := ctx.Value(key("namespace")).(string)
271271

272272
policy := &v1alpha1.WorkloadPolicy{
@@ -277,7 +277,7 @@ func getMonitoringTest() types.Feature {
277277
Spec: v1alpha1.WorkloadPolicySpec{
278278
Mode: "monitor",
279279
RulesByContainer: map[string]*v1alpha1.WorkloadPolicyRules{
280-
"ubuntu": &v1alpha1.WorkloadPolicyRules{
280+
"ubuntu": {
281281
Executables: v1alpha1.WorkloadPolicyExecutables{
282282
Allowed: []string{
283283
"/usr/bin/ls",

test/e2e/promotion_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func getPromotionTest() types.Feature {
5555
return ctx
5656
}).
5757
Assess("required resources become available", IfRequiredResourcesAreCreated).
58-
Assess("the workload security proposal is created successfully for the ubuntu pod",
58+
Assess("the workload proposal is created successfully for the ubuntu pod",
5959
func(ctx context.Context, t *testing.T, _ *envconf.Config) context.Context {
6060
r := ctx.Value(key("client")).(*resources.Resources)
6161

@@ -86,7 +86,7 @@ func getPromotionTest() types.Feature {
8686
id := ctx.Value(key("group")).(string)
8787
r := ctx.Value(key("client")).(*resources.Resources)
8888

89-
t.Log("waiting for security policy proposal to be created: ", id)
89+
t.Log("waiting for policy proposal to be created: ", id)
9090

9191
proposal := v1alpha1.WorkloadPolicyProposal{
9292
ObjectMeta: metav1.ObjectMeta{
@@ -117,9 +117,9 @@ func getPromotionTest() types.Feature {
117117

118118
return context.WithValue(ctx, key("proposal"), &proposal)
119119
}).
120-
Assess("a proposal is promoted to a security policy through labeling and the workloadPolicy is created",
120+
Assess("a proposal is promoted to a policy through labeling and the workloadPolicy is created",
121121
func(ctx context.Context, t *testing.T, _ *envconf.Config) context.Context {
122-
t.Log("create a security policy")
122+
t.Log("create a policy")
123123

124124
r := ctx.Value(key("client")).(*resources.Resources)
125125
proposal := ctx.Value(key("proposal")).(*v1alpha1.WorkloadPolicyProposal)
@@ -147,7 +147,7 @@ func getPromotionTest() types.Feature {
147147
Spec: v1alpha1.WorkloadPolicySpec{
148148
Mode: "monitor",
149149
RulesByContainer: map[string]*v1alpha1.WorkloadPolicyRules{
150-
"ubuntu": &v1alpha1.WorkloadPolicyRules{
150+
"ubuntu": {
151151
Executables: v1alpha1.WorkloadPolicyExecutables{
152152
Allowed: proposal.Spec.RulesByContainer["ubuntu"].Executables.Allowed,
153153
AllowedPrefixes: proposal.Spec.RulesByContainer["ubuntu"].Executables.AllowedPrefixes,
@@ -190,7 +190,7 @@ func getPromotionTest() types.Feature {
190190

191191
return ctx
192192
}).
193-
Assess("delete security policy", func(ctx context.Context, t *testing.T, _ *envconf.Config) context.Context {
193+
Assess("delete policy", func(ctx context.Context, t *testing.T, _ *envconf.Config) context.Context {
194194
r := ctx.Value(key("client")).(*resources.Resources)
195195
policy := ctx.Value(key("policy")).(*v1alpha1.WorkloadPolicy)
196196
proposal := ctx.Value(key("proposal")).(*v1alpha1.WorkloadPolicyProposal)

0 commit comments

Comments
 (0)