Repository: kubernetes-sigs/security-profiles-operator
Pull request #386 (2021-03-22 09:57:12)

Add recording webhook unit tests
#### What type of PR is this?


/kind cleanup


#### What this PR does / why we need it:
We now add a sufficient amount of unit tests for the profile recording
webhook.

#### Which issue(s) this PR fixes:

<!--
*Automatically closes linked issue when PR is merged.
Usage: `Fixes #<issue number>`, or `Fixes (paste link of issue)`.

Fixes #

or

None
-->
None
#### Does this PR have test?
Yes
<!--
If tests aren't applicable just write N/A.
-->

#### Special notes for your reviewer:
None
#### Does this PR introduce a user-facing change?

<!--
If no, just write "NONE" in the release-note block below.
If yes, a release note is required:
Enter your extended release note in the block below. If the PR requires additional action from users switching to the new release, include the string "action required".

For more information on release notes see: https://git.k8s.io/community/contributors/guide/release-notes.md
-->

```release-note
None
```


k8s-ci-robot: @saschagrunert: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-security-profiles-operator-test-e2e | 1c288fe6394ac31abc79c89b1992f24630d073f9 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_security-profiles-operator/386/pull-security-profiles-operator-test-e2e/1373936794684362752) | `/test pull-security-profiles-operator-test-e2e`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=security-profiles-operator&pr=386). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Asaschagrunert). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/security-profiles-operator/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
saschagrunert: /test pull-security-profiles-operator-test-e2e
k8s-ci-robot: @saschagrunert: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-security-profiles-operator-test-e2e | 1c288fe6394ac31abc79c89b1992f24630d073f9 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_security-profiles-operator/386/pull-security-profiles-operator-test-e2e/1373938851688484864) | `/test pull-security-profiles-operator-test-e2e`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=security-profiles-operator&pr=386). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Asaschagrunert). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/security-profiles-operator/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
saschagrunert: /test pull-security-profiles-operator-test-e2e
k8s-ci-robot: @saschagrunert: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-security-profiles-operator-test-e2e | 1c288fe6394ac31abc79c89b1992f24630d073f9 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_security-profiles-operator/386/pull-security-profiles-operator-test-e2e/1373940892565508096) | `/test pull-security-profiles-operator-test-e2e`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=security-profiles-operator&pr=386). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Asaschagrunert). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/security-profiles-operator/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
saschagrunert: /retest
k8s-ci-robot: @saschagrunert: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-security-profiles-operator-test-e2e | 1c288fe6394ac31abc79c89b1992f24630d073f9 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_security-profiles-operator/386/pull-security-profiles-operator-test-e2e/1373956990383951872) | `/test pull-security-profiles-operator-test-e2e`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=security-profiles-operator&pr=386). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Asaschagrunert). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/security-profiles-operator/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
k8s-ci-robot: @saschagrunert: PR needs rebase.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository.
</details>
saschagrunert: Rebased on the latest master branch.

Patch:
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 1d9a29127..326fdb1cc 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -20,10 +20,11 @@ jobs:
     steps:
       - uses: actions/checkout@v2
       - uses: cachix/install-nix-action@v12
-      - uses: cachix/cachix-action@v8
+      - uses: cachix/cachix-action@v10
         with:
           name: security-profiles-operator
           authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
+          pushFilter: security-profiles-operator
       - run: make nix nix-arm64
 
   image:
diff --git a/internal/pkg/webhooks/recording/impl.go b/internal/pkg/webhooks/recording/impl.go
index 8e921ce3d..acd7e31a4 100644
--- a/internal/pkg/webhooks/recording/impl.go
+++ b/internal/pkg/webhooks/recording/impl.go
@@ -22,6 +22,8 @@ import (
 	"github.com/go-logr/logr"
 	"github.com/pkg/errors"
 	corev1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/labels"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
@@ -41,6 +43,7 @@ type impl interface {
 	UpdateResource(context.Context, logr.Logger, client.Object, string) error
 	SetDecoder(*admission.Decoder)
 	DecodePod(admission.Request) (*corev1.Pod, error)
+	LabelSelectorAsSelector(*metav1.LabelSelector) (labels.Selector, error)
 }
 
 func (d *defaultImpl) ListProfileRecordings(
@@ -70,3 +73,9 @@ func (d *defaultImpl) DecodePod(req admission.Request) (*corev1.Pod, error) {
 	err := d.decoder.Decode(req, pod)
 	return pod, errors.Wrap(err, "decode pod")
 }
+
+func (*defaultImpl) LabelSelectorAsSelector(
+	ps *metav1.LabelSelector,
+) (labels.Selector, error) {
+	return metav1.LabelSelectorAsSelector(ps)
+}
diff --git a/internal/pkg/webhooks/recording/recording.go b/internal/pkg/webhooks/recording/recording.go
index 003f6d896..5881c16d1 100644
--- a/internal/pkg/webhooks/recording/recording.go
+++ b/internal/pkg/webhooks/recording/recording.go
@@ -29,7 +29,6 @@ import (
 	"github.com/pkg/errors"
 	admissionv1 "k8s.io/api/admission/v1"
 	corev1 "k8s.io/api/core/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/labels"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
@@ -116,7 +115,7 @@ func (p *podSeccompRecorder) Handle(
 			continue
 		}
 
-		selector, err := metav1.LabelSelectorAsSelector(
+		selector, err := p.impl.LabelSelectorAsSelector(
 			&item.Spec.PodSelector,
 		)
 		if err != nil {
diff --git a/internal/pkg/webhooks/recording/recordingfakes/fake_impl.go b/internal/pkg/webhooks/recording/recordingfakes/fake_impl.go
index a9c25f4d0..8fa8e3b8f 100644
--- a/internal/pkg/webhooks/recording/recordingfakes/fake_impl.go
+++ b/internal/pkg/webhooks/recording/recordingfakes/fake_impl.go
@@ -23,6 +23,8 @@ import (
 
 	"github.com/go-logr/logr"
 	v1 "k8s.io/api/core/v1"
+	v1a "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/labels"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 	"sigs.k8s.io/security-profiles-operator/api/profilerecording/v1alpha1"
@@ -42,6 +44,19 @@ type FakeImpl struct {
 		result1 *v1.Pod
 		result2 error
 	}
+	LabelSelectorAsSelectorStub        func(*v1a.LabelSelector) (labels.Selector, error)
+	labelSelectorAsSelectorMutex       sync.RWMutex
+	labelSelectorAsSelectorArgsForCall []struct {
+		arg1 *v1a.LabelSelector
+	}
+	labelSelectorAsSelectorReturns struct {
+		result1 labels.Selector
+		result2 error
+	}
+	labelSelectorAsSelectorReturnsOnCall map[int]struct {
+		result1 labels.Selector
+		result2 error
+	}
 	ListProfileRecordingsStub        func(context.Context, ...client.ListOption) (*v1alpha1.ProfileRecordingList, error)
 	listProfileRecordingsMutex       sync.RWMutex
 	listProfileRecordingsArgsForCall []struct {
@@ -143,6 +158,70 @@ func (fake *FakeImpl) DecodePodReturnsOnCall(i int, result1 *v1.Pod, result2 err
 	}{result1, result2}
 }
 
+func (fake *FakeImpl) LabelSelectorAsSelector(arg1 *v1a.LabelSelector) (labels.Selector, error) {
+	fake.labelSelectorAsSelectorMutex.Lock()
+	ret, specificReturn := fake.labelSelectorAsSelectorReturnsOnCall[len(fake.labelSelectorAsSelectorArgsForCall)]
+	fake.labelSelectorAsSelectorArgsForCall = append(fake.labelSelectorAsSelectorArgsForCall, struct {
+		arg1 *v1a.LabelSelector
+	}{arg1})
+	stub := fake.LabelSelectorAsSelectorStub
+	fakeReturns := fake.labelSelectorAsSelectorReturns
+	fake.recordInvocation("LabelSelectorAsSelector", []interface{}{arg1})
+	fake.labelSelectorAsSelectorMutex.Unlock()
+	if stub != nil {
+		return stub(arg1)
+	}
+	if specificReturn {
+		return ret.result1, ret.result2
+	}
+	return fakeReturns.result1, fakeReturns.result2
+}
+
+func (fake *FakeImpl) LabelSelectorAsSelectorCallCount() int {
+	fake.labelSelectorAsSelectorMutex.RLock()
+	defer fake.labelSelectorAsSelectorMutex.RUnlock()
+	return len(fake.labelSelectorAsSelectorArgsForCall)
+}
+
+func (fake *FakeImpl) LabelSelectorAsSelectorCalls(stub func(*v1a.LabelSelector) (labels.Selector, error)) {
+	fake.labelSelectorAsSelectorMutex.Lock()
+	defer fake.labelSelectorAsSelectorMutex.Unlock()
+	fake.LabelSelectorAsSelectorStub = stub
+}
+
+func (fake *FakeImpl) LabelSelectorAsSelectorArgsForCall(i int) *v1a.LabelSelector {
+	fake.labelSelectorAsSelectorMutex.RLock()
+	defer fake.labelSelectorAsSelectorMutex.RUnlock()
+	argsForCall := fake.labelSelectorAsSelectorArgsForCall[i]
+	return argsForCall.arg1
+}
+
+func (fake *FakeImpl) LabelSelectorAsSelectorReturns(result1 labels.Selector, result2 error) {
+	fake.labelSelectorAsSelectorMutex.Lock()
+	defer fake.labelSelectorAsSelectorMutex.Unlock()
+	fake.LabelSelectorAsSelectorStub = nil
+	fake.labelSelectorAsSelectorReturns = struct {
+		result1 labels.Selector
+		result2 error
+	}{result1, result2}
+}
+
+func (fake *FakeImpl) LabelSelectorAsSelectorReturnsOnCall(i int, result1 labels.Selector, result2 error) {
+	fake.labelSelectorAsSelectorMutex.Lock()
+	defer fake.labelSelectorAsSelectorMutex.Unlock()
+	fake.LabelSelectorAsSelectorStub = nil
+	if fake.labelSelectorAsSelectorReturnsOnCall == nil {
+		fake.labelSelectorAsSelectorReturnsOnCall = make(map[int]struct {
+			result1 labels.Selector
+			result2 error
+		})
+	}
+	fake.labelSelectorAsSelectorReturnsOnCall[i] = struct {
+		result1 labels.Selector
+		result2 error
+	}{result1, result2}
+}
+
 func (fake *FakeImpl) ListProfileRecordings(arg1 context.Context, arg2 ...client.ListOption) (*v1alpha1.ProfileRecordingList, error) {
 	fake.listProfileRecordingsMutex.Lock()
 	ret, specificReturn := fake.listProfileRecordingsReturnsOnCall[len(fake.listProfileRecordingsArgsForCall)]
@@ -309,6 +388,8 @@ func (fake *FakeImpl) Invocations() map[string][][]interface{} {
 	defer fake.invocationsMutex.RUnlock()
 	fake.decodePodMutex.RLock()
 	defer fake.decodePodMutex.RUnlock()
+	fake.labelSelectorAsSelectorMutex.RLock()
+	defer fake.labelSelectorAsSelectorMutex.RUnlock()
 	fake.listProfileRecordingsMutex.RLock()
 	defer fake.listProfileRecordingsMutex.RUnlock()
 	fake.setDecoderMutex.RLock()


Test patch:
diff --git a/internal/pkg/webhooks/recording/recording_test.go b/internal/pkg/webhooks/recording/recording_test.go
index 1a35d845f..42770e8d3 100644
--- a/internal/pkg/webhooks/recording/recording_test.go
+++ b/internal/pkg/webhooks/recording/recording_test.go
@@ -18,21 +18,39 @@ package recording
 
 import (
 	"context"
+	"encoding/json"
 	"errors"
 	"net/http"
 	"testing"
 
 	"github.com/go-logr/logr"
 	"github.com/stretchr/testify/require"
+	admissionv1 "k8s.io/api/admission/v1"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/labels"
+	"k8s.io/apimachinery/pkg/runtime"
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
 	"sigs.k8s.io/security-profiles-operator/api/profilerecording/v1alpha1"
 	"sigs.k8s.io/security-profiles-operator/internal/pkg/webhooks/recording/recordingfakes"
 )
 
-var errTest = errors.New("error")
+var (
+	errTest = errors.New("error")
+	testPod = &corev1.Pod{
+		ObjectMeta: metav1.ObjectMeta{
+			GenerateName: "pod-",
+		},
+		Spec: corev1.PodSpec{
+			Containers: []corev1.Container{
+				{
+					Name: "container",
+				},
+			},
+		},
+	}
+)
 
 func TestHandle(t *testing.T) {
 	t.Parallel()
@@ -70,12 +88,195 @@ func TestHandle(t *testing.T) {
 				require.Equal(t, http.StatusBadRequest, int(resp.Result.Code))
 			},
 		},
+		{ // success pod changed
+			prepare: func(mock *recordingfakes.FakeImpl) {
+				mock.ListProfileRecordingsReturns(&v1alpha1.ProfileRecordingList{
+					Items: []v1alpha1.ProfileRecording{
+						{
+							Spec: v1alpha1.ProfileRecordingSpec{
+								Kind: "SeccompProfile",
+							},
+						},
+					},
+				}, nil)
+				mock.DecodePodReturns(testPod.DeepCopy(), nil)
+				mock.LabelSelectorAsSelectorReturns(labels.Everything(), nil)
+			},
+			request: admission.Request{
+				AdmissionRequest: admissionv1.AdmissionRequest{
+					Object: runtime.RawExtension{
+						Raw: func() []byte {
+							b, err := json.Marshal(testPod.DeepCopy())
+							require.Nil(t, err)
+							return b
+						}(),
+					},
+				},
+			},
+			assert: func(resp admission.Response) {
+				require.True(t, resp.AdmissionResponse.Allowed)
+				require.Len(t, resp.Patches, 1)
+			},
+		},
+		{ // success no seccomp profile
+			prepare: func(mock *recordingfakes.FakeImpl) {
+				mock.ListProfileRecordingsReturns(&v1alpha1.ProfileRecordingList{
+					Items: []v1alpha1.ProfileRecording{
+						{
+							Spec: v1alpha1.ProfileRecordingSpec{
+								Kind: "OtherProfile",
+							},
+						},
+					},
+				}, nil)
+				mock.DecodePodReturns(testPod.DeepCopy(), nil)
+			},
+			assert: func(resp admission.Response) {
+				require.True(t, resp.AdmissionResponse.Allowed)
+				require.Empty(t, resp.Patches)
+			},
+		},
+		{ // failure LabelSelectorAsSelector
+			prepare: func(mock *recordingfakes.FakeImpl) {
+				mock.ListProfileRecordingsReturns(&v1alpha1.ProfileRecordingList{
+					Items: []v1alpha1.ProfileRecording{
+						{
+							Spec: v1alpha1.ProfileRecordingSpec{
+								Kind: "SeccompProfile",
+							},
+						},
+					},
+				}, nil)
+				mock.DecodePodReturns(testPod.DeepCopy(), nil)
+				mock.LabelSelectorAsSelectorReturns(nil, errTest)
+			},
+			assert: func(resp admission.Response) {
+				require.Equal(t, http.StatusInternalServerError, int(resp.Result.Code))
+			},
+		},
+		{ // failure UpdateResource
+			prepare: func(mock *recordingfakes.FakeImpl) {
+				mock.ListProfileRecordingsReturns(&v1alpha1.ProfileRecordingList{
+					Items: []v1alpha1.ProfileRecording{
+						{
+							Spec: v1alpha1.ProfileRecordingSpec{
+								Kind: "SeccompProfile",
+							},
+						},
+					},
+				}, nil)
+				mock.DecodePodReturns(testPod.DeepCopy(), nil)
+				mock.LabelSelectorAsSelectorReturns(labels.Everything(), nil)
+				mock.UpdateResourceReturns(errTest)
+			},
+			request: admission.Request{
+				AdmissionRequest: admissionv1.AdmissionRequest{
+					Object: runtime.RawExtension{
+						Raw: func() []byte {
+							b, err := json.Marshal(testPod.DeepCopy())
+							require.Nil(t, err)
+							return b
+						}(),
+					},
+				},
+			},
+			assert: func(resp admission.Response) {
+				require.Equal(t, http.StatusInternalServerError, int(resp.Result.Code))
+			},
+		},
+		{ // success pod already tracked
+			prepare: func(mock *recordingfakes.FakeImpl) {
+				mock.ListProfileRecordingsReturns(&v1alpha1.ProfileRecordingList{
+					Items: []v1alpha1.ProfileRecording{
+						{
+							Spec: v1alpha1.ProfileRecordingSpec{
+								Kind: "SeccompProfile",
+							},
+						},
+					},
+				}, nil)
+				pod := testPod.DeepCopy()
+				pod.Annotations = map[string]string{
+					"io.containers.trace-syscall/container": "of:/some/path.json",
+				}
+				mock.DecodePodReturns(pod, nil)
+				mock.LabelSelectorAsSelectorReturns(labels.Everything(), nil)
+			},
+			request: admission.Request{
+				AdmissionRequest: admissionv1.AdmissionRequest{
+					Object: runtime.RawExtension{
+						Raw: func() []byte {
+							b, err := json.Marshal(testPod.DeepCopy())
+							require.Nil(t, err)
+							return b
+						}(),
+					},
+				},
+			},
+			assert: func(resp admission.Response) {
+				require.True(t, resp.AdmissionResponse.Allowed)
+				require.Len(t, resp.Patches, 0)
+			},
+		},
+		{ // success pod deleted
+			prepare: func(mock *recordingfakes.FakeImpl) {
+				mock.ListProfileRecordingsReturns(&v1alpha1.ProfileRecordingList{
+					Items: []v1alpha1.ProfileRecording{
+						{
+							Spec: v1alpha1.ProfileRecordingSpec{
+								Kind: "SeccompProfile",
+							},
+							Status: v1alpha1.ProfileRecordingStatus{
+								ActiveWorkloads: []string{"1", "2", "3"},
+							},
+						},
+					},
+				}, nil)
+				mock.DecodePodReturns(testPod.DeepCopy(), nil)
+				mock.LabelSelectorAsSelectorReturns(labels.Everything(), nil)
+			},
+			request: admission.Request{
+				AdmissionRequest: admissionv1.AdmissionRequest{
+					Operation: admissionv1.Delete,
+				},
+			},
+			assert: func(resp admission.Response) {
+				require.True(t, resp.AdmissionResponse.Allowed)
+			},
+		},
+		{ // failure pod deleted on UpdateResource
+			prepare: func(mock *recordingfakes.FakeImpl) {
+				mock.ListProfileRecordingsReturns(&v1alpha1.ProfileRecordingList{
+					Items: []v1alpha1.ProfileRecording{
+						{
+							Spec: v1alpha1.ProfileRecordingSpec{
+								Kind: "SeccompProfile",
+							},
+							Status: v1alpha1.ProfileRecordingStatus{
+								ActiveWorkloads: []string{"1", "2", "3"},
+							},
+						},
+					},
+				}, nil)
+				mock.DecodePodReturns(testPod.DeepCopy(), nil)
+				mock.LabelSelectorAsSelectorReturns(labels.Everything(), nil)
+				mock.UpdateResourceReturns(errTest)
+			},
+			request: admission.Request{
+				AdmissionRequest: admissionv1.AdmissionRequest{
+					Operation: admissionv1.Delete,
+				},
+			},
+			assert: func(resp admission.Response) {
+				require.Equal(t, http.StatusInternalServerError, int(resp.Result.Code))
+			},
+		},
 	} {
 		mock := &recordingfakes.FakeImpl{}
 		tc.prepare(mock)
 
 		recorder := podSeccompRecorder{impl: mock, log: logr.Discard()}
-		resp := recorder.Handle(context.Background(), admission.Request{})
+		resp := recorder.Handle(context.Background(), tc.request)
 		tc.assert(resp)
 	}
 }