Repository: kubernetes-sigs/security-profiles-operator
Pull request #297 (2021-02-12 12:10:03)

Add profile recording e2e test

#### What type of PR is this?

/kind cleanup


#### What this PR does / why we need it:
We now add an OCI hook based recording test to our e2e test suite.

#### 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: Adding the "do-not-merge/release-note-label-needed" label because no release-note block was detected, please follow our [release note process](https://git.k8s.io/community/contributors/guide/release-notes.md) to remove it.

<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>
k8s-ci-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubernetes-sigs/security-profiles-operator/pull/297#" title="Author self-approved">saschagrunert</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes-sigs%2Fsecurity-profiles-operator).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/kubernetes-sigs/security-profiles-operator/blob/master/OWNERS)~~ [saschagrunert]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
codecov-io: # [Codecov](https://codecov.io/gh/kubernetes-sigs/security-profiles-operator/pull/297?src=pr&el=h1) Report
> Merging [#297](https://codecov.io/gh/kubernetes-sigs/security-profiles-operator/pull/297?src=pr&el=desc) (5aaf02d) into [master](https://codecov.io/gh/kubernetes-sigs/security-profiles-operator/commit/319679ee8895471b611c0f8f958539e89075cbad?el=desc) (319679e) will **not change** coverage.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/kubernetes-sigs/security-profiles-operator/pull/297/graphs/tree.svg?width=650&height=150&src=pr&token=37VIWSZ1ZT)](https://codecov.io/gh/kubernetes-sigs/security-profiles-operator/pull/297?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##           master     #297   +/-   ##
=======================================
  Coverage   25.48%   25.48%           
=======================================
  Files           8        8           
  Lines         616      616           
=======================================
  Hits          157      157           
  Misses        441      441           
  Partials       18       18           
```

| Flag | Coverage Δ | |
|---|---|---|
| unittests | `25.48% <ø> (ø)` | |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags#carryforward-flags-in-the-pull-request-comment) to find out more.


------

[Continue to review full report at Codecov](https://codecov.io/gh/kubernetes-sigs/security-profiles-operator/pull/297?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/kubernetes-sigs/security-profiles-operator/pull/297?src=pr&el=footer). Last update [319679e...5aaf02d](https://codecov.io/gh/kubernetes-sigs/security-profiles-operator/pull/297?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

saschagrunert: This works now and is ready for review.
saschagrunert: Or not
/hold
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 | d542550e62aa4049e67e24a5927de8e04d4af854 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_security-profiles-operator/297/pull-security-profiles-operator-test-e2e/1360222284823924736) | `/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=297). [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 | d542550e62aa4049e67e24a5927de8e04d4af854 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_security-profiles-operator/297/pull-security-profiles-operator-test-e2e/1360233039107461120) | `/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=297). [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: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-security-profiles-operator-test-e2e | 5a1870d8c394c320faff193ea4295d72ffed7358 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_security-profiles-operator/297/pull-security-profiles-operator-test-e2e/1361269387322986496) | `/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=297). [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 | 5a1870d8c394c320faff193ea4295d72ffed7358 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_security-profiles-operator/297/pull-security-profiles-operator-test-e2e/1361285646534053888) | `/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=297). [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: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-security-profiles-operator-test-e2e | 065d44bd3c3be43c3d139204b5d2c1a30903da00 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_security-profiles-operator/297/pull-security-profiles-operator-test-e2e/1361312101196369920) | `/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=297). [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 | 099ca6bebfac56af904bcf79c4334a53f2ca86de | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_security-profiles-operator/297/pull-security-profiles-operator-test-e2e/1361326868426395648) | `/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=297). [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: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-security-profiles-operator-test-e2e | 63da537a5906417f7359af174c0c83d11ab8c57e | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_security-profiles-operator/297/pull-security-profiles-operator-test-e2e/1361975104661098496) | `/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=297). [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 | cb91e3b9b5368bcd3ff987e6e6cf905e78aacfae | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_security-profiles-operator/297/pull-security-profiles-operator-test-e2e/1361994452259835904) | `/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=297). [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 -->
JAORMX: /lgtm
saschagrunert: /hold cancel

Patch:
diff --git a/Makefile b/Makefile
index 687eb6eb6..982dea8e7 100644
--- a/Makefile
+++ b/Makefile
@@ -226,7 +226,7 @@ test-unit: $(BUILD_DIR) ## Run the unit tests
 
 .PHONY: test-e2e
 test-e2e: ## Run the end-to-end tests
-	$(GO) test -parallel 1 -timeout 40m -count=1 ./test/... -v
+	$(GO) test -parallel 1 -timeout 80m -count=1 ./test/... -v
 
 # Generate CRD manifests
 manifests: $(CONTROLLER_GEN)


Test patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 8877eff6c..2667d5894 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -47,7 +47,7 @@ jobs:
   e2e:
     needs: image
     runs-on: macos-10.15
-    timeout-minutes: 40
+    timeout-minutes: 80
     env:
       RUN: ./hack/ci/run.sh
     steps:
diff --git a/hack/ci/e2e.sh b/hack/ci/e2e.sh
index 1a705c039..929469cbe 100755
--- a/hack/ci/e2e.sh
+++ b/hack/ci/e2e.sh
@@ -22,5 +22,6 @@ export E2E_TEST_SELINUX=true
 # No need to test them here.
 export E2E_TEST_SECCOMP=false
 export E2E_TEST_PROFILE_BINDING=false
+export E2E_TEST_PROFILE_RECORDING=true
 
 make test-e2e
diff --git a/test/e2e_test.go b/test/e2e_test.go
index 89f20fdb8..2c80e8fce 100644
--- a/test/e2e_test.go
+++ b/test/e2e_test.go
@@ -31,6 +31,7 @@ const (
 	certmanager       = "https://github.com/jetstack/cert-manager/releases/download/v1.1.0/cert-manager.yaml"
 	manifest          = "deploy/operator.yaml"
 	namespaceManifest = "deploy/namespace-operator.yaml"
+	webhookManifest   = "deploy/webhook.yaml"
 	testNamespace     = "test-ns"
 	defaultNamespace  = "default"
 	// NOTE(jaosorior): We should be able to decrease this once we
@@ -92,12 +93,23 @@ func (e *e2e) TestSecurityProfilesOperator() {
 		})
 	}
 
+	if e.testProfileBinding || e.testProfileRecording {
+		e.deployWebhook(webhookManifest)
+		defer e.run("git", "checkout", webhookManifest)
+	}
+
 	// TODO(jaosorior): Re-introduce this to the namespaced tests once we
 	// fix the issue with the certs.
 	e.Run("cluster-wide: Seccomp: Verify profile binding", func() {
 		e.testCaseProfileBinding(nodes)
 	})
 
+	e.Run("cluster-wide: Seccomp: Verify profile recording", func() {
+		e.testCaseProfileRecording(nodes)
+	})
+
+	e.cleanupWebhook(webhookManifest)
+
 	// Clean up cluster-wide deployment to prepare for namespace deployment
 	e.cleanupOperator(manifest)
 
@@ -178,6 +190,36 @@ func (e *e2e) cleanupOperator(manifest string) {
 	e.kubectl("delete", "-f", manifest)
 }
 
+func (e *e2e) deployWebhook(manifest string) {
+	// Deploy prerequisites
+	e.logf("Deploying cert-manager")
+	e.kubectl("apply", "-f", certmanager)
+	e.waitFor(
+		"condition=ready",
+		"--namespace", "cert-manager",
+		"pod", "-l", "app.kubernetes.io/instance=cert-manager",
+	)
+	e.run(
+		"sed", "-i", fmt.Sprintf("s;image: .*gcr.io/.*;image: %s;g", e.testImage),
+		manifest,
+	)
+	e.run(
+		"sed", "-i",
+		fmt.Sprintf("s;imagePullPolicy: Always;imagePullPolicy: %s;g", e.pullPolicy),
+		manifest,
+	)
+	e.logf("Deploying webhook")
+	e.kubectl("create", "-f", manifest)
+	e.waitInOperatorNSFor("condition=ready", "pod", "-l", "name=security-profiles-operator-webhook")
+	e.waitInOperatorNSFor("condition=ready", "certificate", "webhook-cert")
+}
+
+func (e *e2e) cleanupWebhook(manifest string) {
+	e.logf("Cleaning up webhook")
+	e.kubectl("delete", "-f", manifest)
+	e.kubectl("delete", "-f", certmanager)
+}
+
 func (e *e2e) getWorkerNodes() []string {
 	e.logf("Getting worker nodes")
 	nodesOutput := e.kubectl(
diff --git a/test/suite_test.go b/test/suite_test.go
index 991f78692..ae3303a3a 100644
--- a/test/suite_test.go
+++ b/test/suite_test.go
@@ -44,13 +44,14 @@ const (
 )
 
 var (
-	clusterType                   = os.Getenv("E2E_CLUSTER_TYPE")
-	envSkipBuildImages            = os.Getenv("E2E_SKIP_BUILD_IMAGES")
-	envTestImage                  = os.Getenv("E2E_SPO_IMAGE")
-	envSelinuxTestsEnabled        = os.Getenv("E2E_TEST_SELINUX")
-	envSeccompTestsEnabled        = os.Getenv("E2E_TEST_SECCOMP")
-	envProfileBindingTestsEnabled = os.Getenv("E2E_TEST_PROFILE_BINDING")
-	containerRuntime              = os.Getenv("CONTAINER_RUNTIME")
+	clusterType                     = os.Getenv("E2E_CLUSTER_TYPE")
+	envSkipBuildImages              = os.Getenv("E2E_SKIP_BUILD_IMAGES")
+	envTestImage                    = os.Getenv("E2E_SPO_IMAGE")
+	envSelinuxTestsEnabled          = os.Getenv("E2E_TEST_SELINUX")
+	envSeccompTestsEnabled          = os.Getenv("E2E_TEST_SECCOMP")
+	envProfileBindingTestsEnabled   = os.Getenv("E2E_TEST_PROFILE_BINDING")
+	envProfileRecordingTestsEnabled = os.Getenv("E2E_TEST_PROFILE_RECORDING")
+	containerRuntime                = os.Getenv("CONTAINER_RUNTIME")
 )
 
 const (
@@ -61,15 +62,16 @@ const (
 
 type e2e struct {
 	suite.Suite
-	kubectlPath        string
-	testImage          string
-	selinuxdImage      string
-	pullPolicy         string
-	selinuxEnabled     bool
-	testSeccomp        bool
-	testProfileBinding bool
-	logger             logr.Logger
-	execNode           func(node string, args ...string) string
+	kubectlPath          string
+	testImage            string
+	selinuxdImage        string
+	pullPolicy           string
+	selinuxEnabled       bool
+	testSeccomp          bool
+	testProfileBinding   bool
+	testProfileRecording bool
+	logger               logr.Logger
+	execNode             func(node string, args ...string) string
 }
 
 type kinde2e struct {
@@ -109,6 +111,10 @@ func TestSuite(t *testing.T) {
 	if err != nil {
 		testProfileBinding = true
 	}
+	testProfileRecording, err := strconv.ParseBool(envProfileRecordingTestsEnabled)
+	if err != nil {
+		testProfileRecording = false
+	}
 	selinuxdImage := "quay.io/jaosorior/selinuxd"
 	switch {
 	case clusterType == "" || strings.EqualFold(clusterType, clusterTypeKind):
@@ -117,13 +123,14 @@ func TestSuite(t *testing.T) {
 		}
 		suite.Run(t, &kinde2e{
 			e2e{
-				logger:             klogr.New(),
-				pullPolicy:         "Never",
-				testImage:          testImage,
-				selinuxEnabled:     selinuxEnabled,
-				testSeccomp:        testSeccomp,
-				testProfileBinding: testProfileBinding,
-				selinuxdImage:      selinuxdImage,
+				logger:               klogr.New(),
+				pullPolicy:           "Never",
+				testImage:            testImage,
+				selinuxEnabled:       selinuxEnabled,
+				testSeccomp:          testSeccomp,
+				testProfileBinding:   testProfileBinding,
+				testProfileRecording: testProfileRecording,
+				selinuxdImage:        selinuxdImage,
 			},
 			"", "",
 		})
@@ -141,12 +148,13 @@ func TestSuite(t *testing.T) {
 				logger: klogr.New(),
 				// Need to pull the image as it'll be uploaded to the cluster OCP
 				// image registry and not on the nodes.
-				pullPolicy:         "Always",
-				testImage:          testImage,
-				selinuxEnabled:     selinuxEnabled,
-				testSeccomp:        testSeccomp,
-				testProfileBinding: testProfileBinding,
-				selinuxdImage:      selinuxdImage,
+				pullPolicy:           "Always",
+				testImage:            testImage,
+				selinuxEnabled:       selinuxEnabled,
+				testSeccomp:          testSeccomp,
+				testProfileBinding:   testProfileBinding,
+				testProfileRecording: testProfileRecording,
+				selinuxdImage:        selinuxdImage,
 			},
 			skipBuildImages,
 			skipPushImages,
@@ -158,13 +166,14 @@ func TestSuite(t *testing.T) {
 		selinuxdImage = "quay.io/jaosorior/selinuxd-fedora"
 		suite.Run(t, &vanilla{
 			e2e{
-				logger:             klogr.New(),
-				pullPolicy:         "Never",
-				testImage:          testImage,
-				selinuxEnabled:     selinuxEnabled,
-				testSeccomp:        testSeccomp,
-				testProfileBinding: testProfileBinding,
-				selinuxdImage:      selinuxdImage,
+				logger:               klogr.New(),
+				pullPolicy:           "Never",
+				testImage:            testImage,
+				selinuxEnabled:       selinuxEnabled,
+				testSeccomp:          testSeccomp,
+				testProfileBinding:   testProfileBinding,
+				testProfileRecording: testProfileRecording,
+				selinuxdImage:        selinuxdImage,
 			},
 		})
 	default:
@@ -453,3 +462,9 @@ func (e *e2e) profileBindingTestCase() {
 		e.T().Skip("Skipping Profile-Binding-related test")
 	}
 }
+
+func (e *e2e) profileRecordingTestCase() {
+	if !e.testProfileRecording {
+		e.T().Skip("Skipping Profile-Recording-related test")
+	}
+}
diff --git a/test/tc_profilebindings_test.go b/test/tc_profilebindings_test.go
index 6de36e201..84bd67104 100644
--- a/test/tc_profilebindings_test.go
+++ b/test/tc_profilebindings_test.go
@@ -49,11 +49,6 @@ spec:
     resources: {}
   restartPolicy: Never
 `
-	const manifest = "deploy/webhook.yaml"
-
-	e.deployWebhook(manifest)
-	defer e.run("git", "checkout", manifest)
-	defer e.cleanupWebhook(manifest)
 
 	e.kubectl("create", "-f", exampleProfilePath)
 	defer e.kubectl("delete", "-f", exampleProfilePath)
@@ -122,33 +117,3 @@ spec:
 
 	e.Contains(output, "in-use-by-active-pods")
 }
-
-func (e *e2e) deployWebhook(manifest string) {
-	// Deploy prerequisites
-	e.logf("Deploying cert-manager")
-	e.kubectl("apply", "-f", certmanager)
-	e.waitFor(
-		"condition=ready",
-		"--namespace", "cert-manager",
-		"pod", "-l", "app.kubernetes.io/instance=cert-manager",
-	)
-	e.run(
-		"sed", "-i", fmt.Sprintf("s;image: .*gcr.io/.*;image: %s;g", e.testImage),
-		manifest,
-	)
-	e.run(
-		"sed", "-i",
-		fmt.Sprintf("s;imagePullPolicy: Always;imagePullPolicy: %s;g", e.pullPolicy),
-		manifest,
-	)
-	e.logf("Deploying webhook")
-	e.kubectl("create", "-f", manifest)
-	e.waitInOperatorNSFor("condition=ready", "pod", "-l", "name=security-profiles-operator-webhook")
-	e.waitInOperatorNSFor("condition=ready", "certificate", "webhook-cert")
-}
-
-func (e *e2e) cleanupWebhook(manifest string) {
-	e.logf("Cleaning up webhook")
-	e.kubectl("delete", "-f", manifest)
-	e.kubectl("delete", "-f", certmanager)
-}
diff --git a/test/tc_profilerecordings_test.go b/test/tc_profilerecordings_test.go
new file mode 100644
index 000000000..57cd0e57f
--- /dev/null
+++ b/test/tc_profilerecordings_test.go
@@ -0,0 +1,63 @@
+/*
+Copyright 2021 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package e2e_test
+
+import (
+	"io/ioutil"
+	"os"
+)
+
+func (e *e2e) testCaseProfileRecording([]string) {
+	e.profileRecordingTestCase()
+
+	const exampleRecordingPath = "examples/profilerecording.yaml"
+
+	e.logf("Creating recording")
+	e.kubectl("create", "-f", exampleRecordingPath)
+	defer e.kubectl("delete", "-f", exampleRecordingPath)
+
+	e.logf("Creating test pod")
+	const testPod = `
+apiVersion: v1
+kind: Pod
+metadata:
+  name: recording
+  labels:
+    app: alpine
+spec:
+  containers:
+  - image: quay.io/security-profiles-operator/test-nginx:1.19.1
+    name: recording
+    resources: {}
+  restartPolicy: Never
+`
+	testPodFile, err := ioutil.TempFile(os.TempDir(), "recording-pod*.yaml")
+	e.Nil(err)
+	defer os.Remove(testPodFile.Name())
+	_, err = testPodFile.Write([]byte(testPod))
+	e.Nil(err)
+	err = testPodFile.Close()
+	e.Nil(err)
+	e.kubectl("create", "-f", testPodFile.Name())
+
+	e.logf("Waiting for test pod to be initialized")
+	e.waitFor("condition=ready", "pod", "recording")
+	e.kubectl("delete", "pod", "recording")
+
+	profile := e.kubectl("get", "sp", "test-recording", "-o", "yaml")
+	e.Contains(profile, "mkdir")
+}