Repository: kubernetes-sigs/security-profiles-operator
Pull request #286 (2021-02-10 11:12:26)

Run e2e test in vagrant-based GH action e2e test
#### What type of PR is this?

/kind feature

#### What this PR does / why we need it:

This adds the e2e test run as part of the e2e GH action.

It introduces a "vanilla" kuberentes e2e cluster type which assumes that
a kubernetes cluster is already running and takes it into use.

Note that this also installs the oci hook for dynamically creating seccomp
profiles.

#### Which issue(s) this PR fixes:

None

#### Does this PR have test?

N/A.


#### Does this PR introduce a user-facing change?

```release-note
NONE
```

Co-Authored-By: Sascha Grunert <mail@saschagrunert.de>

k8s-ci-robot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubernetes-sigs/security-profiles-operator/pull/286#" title="Author self-approved">JAORMX</a>*
To complete the [pull request process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process), please assign **hasheddan** after the PR has been reviewed.
You can assign the PR to them by writing `/assign @hasheddan` in a comment when ready.

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).

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

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

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":["hasheddan"]} -->
codecov-io: # [Codecov](https://codecov.io/gh/kubernetes-sigs/security-profiles-operator/pull/286?src=pr&el=h1) Report
> Merging [#286](https://codecov.io/gh/kubernetes-sigs/security-profiles-operator/pull/286?src=pr&el=desc) (c3fe75d) into [master](https://codecov.io/gh/kubernetes-sigs/security-profiles-operator/commit/6b91c358e7599eaaecdbb692fd20c1a379a99d52?el=desc) (6b91c35) will **not change** coverage.
> The diff coverage is `n/a`.

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

```diff
@@           Coverage Diff           @@
##           master     #286   +/-   ##
=======================================
  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/286?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/286?src=pr&el=footer). Last update [6b91c35...c3fe75d](https://codecov.io/gh/kubernetes-sigs/security-profiles-operator/pull/286?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

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

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-security-profiles-operator-verify | e4c716102fc356f38d788af52826d77eb2a29650 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_security-profiles-operator/286/pull-security-profiles-operator-verify/1359531517432303616) | `/test pull-security-profiles-operator-verify`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=security-profiles-operator&pr=286). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3AJAORMX). 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 -->

Patch:
diff --git a/deploy/base/kustomization.yaml b/deploy/base/kustomization.yaml
index c1a90b4e2..5526d0f1e 100644
--- a/deploy/base/kustomization.yaml
+++ b/deploy/base/kustomization.yaml
@@ -24,7 +24,7 @@ patchesStrategicMerge:
           - name: security-profiles-operator
             env:
               - name: RELATED_IMAGE_NON_ROOT_ENABLER
-                value: bash:5.0
+                value: docker.io/bash:5.0
               - name: RELATED_IMAGE_SELINUXD
                 value: quay.io/jaosorior/selinuxd
 
diff --git a/deploy/namespace-operator.yaml b/deploy/namespace-operator.yaml
index e13450de6..dc167050b 100644
--- a/deploy/namespace-operator.yaml
+++ b/deploy/namespace-operator.yaml
@@ -533,7 +533,7 @@ spec:
         - name: RESTRICT_TO_NAMESPACE
           value: NS_REPLACE
         - name: RELATED_IMAGE_NON_ROOT_ENABLER
-          value: bash:5.0
+          value: docker.io/bash:5.0
         - name: RELATED_IMAGE_SELINUXD
           value: quay.io/jaosorior/selinuxd
         image: gcr.io/k8s-staging-sp-operator/security-profiles-operator:latest
diff --git a/deploy/operator.yaml b/deploy/operator.yaml
index 72690c796..0561265f8 100644
--- a/deploy/operator.yaml
+++ b/deploy/operator.yaml
@@ -530,7 +530,7 @@ spec:
         - manager
         env:
         - name: RELATED_IMAGE_NON_ROOT_ENABLER
-          value: bash:5.0
+          value: docker.io/bash:5.0
         - name: RELATED_IMAGE_SELINUXD
           value: quay.io/jaosorior/selinuxd
         image: gcr.io/k8s-staging-sp-operator/security-profiles-operator:latest
diff --git a/hack/ci/Vagrantfile b/hack/ci/Vagrantfile
index 04f731d12..572a0370d 100644
--- a/hack/ci/Vagrantfile
+++ b/hack/ci/Vagrantfile
@@ -4,7 +4,7 @@
 # Vagrant box for testing
 Vagrant.configure("2") do |config|
   config.vm.box = "fedora/33-cloud-base"
-  memory = 4096
+  memory = 6144
   cpus = 4
 
   config.vm.provider :virtualbox do |v|
@@ -27,7 +27,9 @@ Vagrant.configure("2") do |config|
         golang-go \
         iptables \
         make \
-        openssl
+        oci-seccomp-bpf-hook \
+        openssl \
+        podman
     SHELL
   end
 
diff --git a/hack/ci/install-cri-o.sh b/hack/ci/install-cri-o.sh
index 0bff6328c..994dbce26 100755
--- a/hack/ci/install-cri-o.sh
+++ b/hack/ci/install-cri-o.sh
@@ -47,14 +47,6 @@ chcon -R -u system_u -r object_r -t var_lib_t /var/lib/kubelet
 
 mkdir -p /etc/crio/crio.conf.d
 
-cat <<EOT >>/etc/crio/crio.conf.d/20-crun.conf
-[crio.runtime]
-default_runtime = "crun"
-
-[crio.runtime.runtimes.crun]
-runtime_path = "/usr/local/bin/crun"
-EOT
-
 cat <<EOT >>/etc/crio/crio.conf.d/30-cgroup-manager.conf
 [crio.runtime]
 conmon_cgroup = "pod"
diff --git a/hack/ci/run.sh b/hack/ci/run.sh
index 2b246a7ae..6967eb20b 100755
--- a/hack/ci/run.sh
+++ b/hack/ci/run.sh
@@ -15,4 +15,4 @@
 
 set -euo pipefail
 
-exec vagrant ssh -- sudo "bash -c '. /vagrant/hack/ci/env.sh && $*'"
+exec vagrant ssh -- sudo "bash -c 'cd /vagrant && . hack/ci/env.sh && $*'"
diff --git a/internal/pkg/controllers/spod/bindata/default_profiles.go b/internal/pkg/controllers/spod/bindata/default_profiles.go
index f6809bac8..df6abf378 100644
--- a/internal/pkg/controllers/spod/bindata/default_profiles.go
+++ b/internal/pkg/controllers/spod/bindata/default_profiles.go
@@ -90,8 +90,8 @@ func DefaultProfiles() []*v1alpha1.SeccompProfile {
 							"getppid",
 							"getrlimit",
 							"getuid",
-							"ioctl",
 							"io_setup",
+							"ioctl",
 							"listen",
 							"lseek",
 							"mkdir",
@@ -117,14 +117,17 @@ func DefaultProfiles() []*v1alpha1.SeccompProfile {
 							"rt_sigsuspend",
 							"sched_getaffinity",
 							"seccomp",
+							"select",
 							"sendfile",
 							"sendmsg",
+							"set_robust_list",
+							"set_tid_address",
 							"setgid",
 							"setgroups",
 							"setitimer",
-							"set_robust_list",
+							"setresgid",
+							"setresuid",
 							"setsockopt",
-							"set_tid_address",
 							"setuid",
 							"sigaltstack",
 							"socket",


Test patch:
diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml
index 332166ae1..7fd7a4889 100644
--- a/.github/workflows/e2e.yml
+++ b/.github/workflows/e2e.yml
@@ -7,7 +7,7 @@ on:
 jobs:
   test:
     runs-on: macos-10.15
-    timeout-minutes: 30
+    timeout-minutes: 40
     env:
       RUN: ./hack/ci/run.sh
     steps:
@@ -17,5 +17,6 @@ jobs:
           ln -sf hack/ci/Vagrantfile .
           vagrant up
       - name: Show environment information
-        run: |
-          $RUN kubectl get nodes -o wide
+        run: $RUN kubectl get nodes -o wide
+      - name: Run E2E tests
+        run: $RUN hack/ci/e2e.sh
diff --git a/hack/ci/e2e.sh b/hack/ci/e2e.sh
new file mode 100755
index 000000000..8ce716036
--- /dev/null
+++ b/hack/ci/e2e.sh
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+# 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.
+
+set -euo pipefail
+
+export E2E_CLUSTER_TYPE=vanilla
+#export E2E_TEST_SELINUX=true
+
+# These are already tested in the standard e2e test.
+# No need to test them here.
+export E2E_TEST_SECCOMP=false
+export E2E_TEST_PROFILE_BINDING=false
+
+make test-e2e
diff --git a/test/e2e_test.go b/test/e2e_test.go
index f63920b44..cd2b297f3 100644
--- a/test/e2e_test.go
+++ b/test/e2e_test.go
@@ -37,6 +37,7 @@ const (
 	// migrate to a single daemonset-based implementation for the
 	// SELinux pieces.
 	defaultSelinuxOpTimeout = "360s"
+	defaultWaitTimeout      = "60s"
 	defaultWaitTime         = 5 * time.Second
 )
 
@@ -158,12 +159,12 @@ func (e *e2e) deployOperator(manifest string) {
 	// Wait for the operator to be ready
 	e.logf("Waiting for operator to be ready")
 	// Wait for deployment
-	e.kubectlOperatorNS("wait", "--for", "condition=available", "deployment", "-l", "app=security-profiles-operator")
+	e.waitInOperatorNSFor("condition=available", "deployment", "-l", "app=security-profiles-operator")
 	// Wait for all pods in deployment
-	e.kubectlOperatorNS("wait", "--for", "condition=ready", "pod", "-l", "app=security-profiles-operator")
+	e.waitInOperatorNSFor("condition=ready", "pod", "-l", "app=security-profiles-operator")
 	// Wait for all pods in DaemonSet
 	time.Sleep(defaultWaitTime)
-	e.kubectlOperatorNS("wait", "--for", "condition=ready", "pod", "-l", "app=spod")
+	e.waitInOperatorNSFor("condition=ready", "pod", "-l", "app=spod")
 }
 
 func (e *e2e) cleanupOperator(manifest string) {
diff --git a/test/suite_test.go b/test/suite_test.go
index 1956718ce..e813dab7d 100644
--- a/test/suite_test.go
+++ b/test/suite_test.go
@@ -44,21 +44,25 @@ const (
 )
 
 var (
-	clusterType        = os.Getenv("E2E_CLUSTER_TYPE")
-	envSkipBuildImages = os.Getenv("E2E_SKIP_BUILD_IMAGES")
-	envTestImage       = os.Getenv("E2E_SPO_IMAGE")
-	envSelinuxEnabled  = os.Getenv("E2E_ENABLE_SELINUX")
-	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")
+	containerRuntime              = os.Getenv("CONTAINER_RUNTIME")
 )
 
 type e2e struct {
 	suite.Suite
-	kubectlPath    string
-	testImage      string
-	pullPolicy     string
-	selinuxEnabled bool
-	logger         logr.Logger
-	execNode       func(node string, args ...string) string
+	kubectlPath        string
+	testImage          string
+	pullPolicy         string
+	selinuxEnabled     bool
+	testSeccomp        bool
+	testProfileBinding bool
+	logger             logr.Logger
+	execNode           func(node string, args ...string) string
 }
 
 type kinde2e struct {
@@ -73,6 +77,10 @@ type openShifte2e struct {
 	skipPushImages  bool
 }
 
+type vanilla struct {
+	e2e
+}
+
 // We're unable to use parallel tests because of our usage of testify/suite.
 // See https://github.com/stretchr/testify/issues/187
 //
@@ -82,10 +90,18 @@ func TestSuite(t *testing.T) {
 	fmt.Printf("container-runtime: %s\n", containerRuntime)
 
 	testImage := envTestImage
-	selinuxEnabled, err := strconv.ParseBool(envSelinuxEnabled)
+	selinuxEnabled, err := strconv.ParseBool(envSelinuxTestsEnabled)
 	if err != nil {
 		selinuxEnabled = false
 	}
+	testSeccomp, err := strconv.ParseBool(envSeccompTestsEnabled)
+	if err != nil {
+		testSeccomp = true
+	}
+	testProfileBinding, err := strconv.ParseBool(envProfileBindingTestsEnabled)
+	if err != nil {
+		testProfileBinding = true
+	}
 	switch {
 	case clusterType == "" || strings.EqualFold(clusterType, "kind"):
 		if testImage == "" {
@@ -93,10 +109,12 @@ func TestSuite(t *testing.T) {
 		}
 		suite.Run(t, &kinde2e{
 			e2e{
-				logger:         klogr.New(),
-				pullPolicy:     "Never",
-				testImage:      testImage,
-				selinuxEnabled: selinuxEnabled,
+				logger:             klogr.New(),
+				pullPolicy:         "Never",
+				testImage:          testImage,
+				selinuxEnabled:     selinuxEnabled,
+				testSeccomp:        testSeccomp,
+				testProfileBinding: testProfileBinding,
 			},
 			"", "",
 		})
@@ -114,13 +132,29 @@ 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,
+				pullPolicy:         "Always",
+				testImage:          testImage,
+				selinuxEnabled:     selinuxEnabled,
+				testSeccomp:        testSeccomp,
+				testProfileBinding: testProfileBinding,
 			},
 			skipBuildImages,
 			skipPushImages,
 		})
+	case strings.EqualFold(clusterType, "vanilla"):
+		if testImage == "" {
+			testImage = "localhost/" + config.OperatorName + ":latest"
+		}
+		suite.Run(t, &vanilla{
+			e2e{
+				logger:             klogr.New(),
+				pullPolicy:         "Never",
+				testImage:          testImage,
+				selinuxEnabled:     selinuxEnabled,
+				testSeccomp:        testSeccomp,
+				testProfileBinding: testProfileBinding,
+			},
+		})
 	default:
 		t.Fatalf("Unknown cluster type.")
 	}
@@ -132,11 +166,7 @@ func (e *kinde2e) SetupSuite() {
 	command.SetGlobalVerbose(true)
 	// Override execNode function
 	e.e2e.execNode = e.execNodeKind
-	cwd, err := os.Getwd()
-	e.Nil(err)
-
-	parentCwd := filepath.Dir(cwd)
-	e.Nil(os.Chdir(parentCwd))
+	parentCwd := e.setWorkDir()
 	buildDir := filepath.Join(parentCwd, "build")
 	e.Nil(os.MkdirAll(buildDir, 0o755))
 
@@ -155,6 +185,7 @@ func (e *kinde2e) SetupSuite() {
 	e.downloadAndVerify(fmt.Sprintf("https://github.com/kubernetes-sigs/kind/releases/download/%s/%s",
 		kindVersion, kindOS), e.kindPath, SHA512)
 
+	var err error
 	e.kubectlPath, err = exec.LookPath("kubectl")
 	e.Nil(err)
 }
@@ -217,17 +248,12 @@ func (e *kinde2e) execNodeKind(node string, args ...string) string {
 }
 
 func (e *openShifte2e) SetupSuite() {
+	var err error
 	e.logf("Setting up suite")
 	command.SetGlobalVerbose(true)
 	// Override execNode function
 	e.e2e.execNode = e.execNodeOCP
-	cwd, err := os.Getwd()
-	e.Nil(err)
-
-	parentCwd := filepath.Dir(cwd)
-	e.Nil(os.Chdir(parentCwd))
-	buildDir := filepath.Join(parentCwd, "build")
-	e.Nil(os.MkdirAll(buildDir, 0o755))
+	e.setWorkDir()
 
 	e.kubectlPath, err = exec.LookPath("oc")
 	e.Nil(err)
@@ -235,7 +261,7 @@ func (e *openShifte2e) SetupSuite() {
 	e.logf("Using deployed OpenShift cluster")
 
 	e.logf("Waiting for cluster to be ready")
-	e.kubectl("wait", "--for", "condition=ready", "nodes", "--all")
+	e.waitFor("condition=ready", "nodes", "--all")
 
 	if !e.skipPushImages {
 		e.logf("pushing SPO image to openshift registry")
@@ -309,6 +335,41 @@ func (e *openShifte2e) execNodeOCP(node string, args ...string) string {
 	)
 }
 
+func (e *vanilla) SetupSuite() {
+	var err error
+	e.logf("Setting up suite")
+	e.setWorkDir()
+
+	e.e2e.execNode = e.execNodeVanilla
+	e.kubectlPath, err = exec.LookPath("kubectl")
+	e.Nil(err)
+}
+
+func (e *vanilla) SetupTest() {
+	// Build and load the test image
+	e.logf("Building operator container image")
+	e.run("make", "image", "IMAGE="+e.testImage)
+	e.run(
+		containerRuntime, "pull", "quay.io/jaosorior/selinuxd",
+	)
+}
+
+func (e *vanilla) TearDownTest() {
+}
+
+func (e *vanilla) execNodeVanilla(node string, args ...string) string {
+	return e.run(args[0], args[1:]...)
+}
+
+func (e *e2e) setWorkDir() string {
+	cwd, err := os.Getwd()
+	e.Nil(err)
+
+	parentCwd := filepath.Dir(cwd)
+	e.Nil(os.Chdir(parentCwd))
+	return parentCwd
+}
+
 func (e *e2e) run(cmd string, args ...string) string {
 	output, err := command.New(cmd, args...).RunSuccessOutput()
 	e.Nil(err)
@@ -352,12 +413,36 @@ func (e *e2e) kubectlOperatorNS(args ...string) {
 	)
 }
 
+func (e *e2e) waitFor(args ...string) {
+	e.kubectl(
+		append([]string{"wait", "--timeout", defaultWaitTimeout, "--for"}, args...)...,
+	)
+}
+
+func (e *e2e) waitInOperatorNSFor(args ...string) {
+	e.kubectlOperatorNS(
+		append([]string{"wait", "--timeout", defaultWaitTimeout, "--for"}, args...)...,
+	)
+}
+
 func (e *e2e) logf(format string, a ...interface{}) {
 	e.logger.Info(fmt.Sprintf(format, a...))
 }
 
 func (e *e2e) selinuxtOnlyTestCase() {
 	if !e.selinuxEnabled {
-		e.T().Skip("Skipping SELinux-related test from non-OpenShift cluster")
+		e.T().Skip("Skipping SELinux-related test")
+	}
+}
+
+func (e *e2e) seccompOnlyTestCase() {
+	if !e.testSeccomp {
+		e.T().Skip("Skipping Seccomp-related test")
+	}
+}
+
+func (e *e2e) profileBindingTestCase() {
+	if !e.testProfileBinding {
+		e.T().Skip("Skipping Profile-Binding-related test")
 	}
 }
diff --git a/test/tc_base_profiles_test.go b/test/tc_base_profiles_test.go
index 3250037d9..8e36208e8 100644
--- a/test/tc_base_profiles_test.go
+++ b/test/tc_base_profiles_test.go
@@ -24,6 +24,7 @@ import (
 )
 
 func (e *e2e) testCaseBaseProfile([]string) {
+	e.seccompOnlyTestCase()
 	const baseProfilePath = "examples/baseprofile.yaml"
 	const helloProfile = `
 apiVersion: security-profiles-operator.x-k8s.io/v1alpha1
@@ -85,7 +86,7 @@ spec:
 	defer e.kubectl("delete", "pod", "hello")
 
 	e.logf("Waiting for test pod to be initialized")
-	e.kubectl("wait", "--for", "condition=initialized", "pod", "hello")
+	e.waitFor("condition=initialized", "pod", "hello")
 
 	output := e.kubectl("get", "pod", "hello")
 	for strings.Contains(output, "ContainerCreating") {
diff --git a/test/tc_default_profiles_test.go b/test/tc_default_profiles_test.go
index 114bc078f..81aa15bfc 100644
--- a/test/tc_default_profiles_test.go
+++ b/test/tc_default_profiles_test.go
@@ -28,6 +28,7 @@ import (
 )
 
 func (e *e2e) testCaseDefaultAndExampleProfiles(nodes []string) {
+	e.seccompOnlyTestCase()
 	const exampleProfilePath = "examples/seccompprofile.yaml"
 	exampleProfileNames := [3]string{"profile-allow-unsafe", "profile-complain-unsafe", "profile-block-all"}
 	defaultProfileNames := [1]string{"nginx-1.19.1"}
diff --git a/test/tc_delete_profiles_test.go b/test/tc_delete_profiles_test.go
index db74ff815..f8050e1af 100644
--- a/test/tc_delete_profiles_test.go
+++ b/test/tc_delete_profiles_test.go
@@ -24,6 +24,7 @@ import (
 )
 
 func (e *e2e) testCaseDeleteProfiles(nodes []string) {
+	e.seccompOnlyTestCase()
 	const (
 		deleteProfile = `
 apiVersion: security-profiles-operator.x-k8s.io/v1alpha1
@@ -142,7 +143,7 @@ spec:
 		defer profileCleanup()
 		podCleanup := e.writeAndCreate(fmt.Sprintf(testCase.podManifest, namespace), "delete-pod*.yaml")
 		defer podCleanup()
-		e.kubectl("wait", "--for", "condition=ready", "pod", deletePodName)
+		e.waitFor("condition=ready", "pod", deletePodName)
 		e.logf("Ensuring profile cannot be deleted while pod is active")
 		e.kubectl("delete", "seccompprofile", deleteProfileName, "--wait=0")
 		output := e.kubectl("get", "seccompprofile", deleteProfileName)
diff --git a/test/tc_profilebindings_test.go b/test/tc_profilebindings_test.go
index 46615ce5d..6de36e201 100644
--- a/test/tc_profilebindings_test.go
+++ b/test/tc_profilebindings_test.go
@@ -24,6 +24,7 @@ import (
 )
 
 func (e *e2e) testCaseProfileBinding([]string) {
+	e.profileBindingTestCase()
 	const exampleProfilePath = "examples/seccompprofile.yaml"
 	const testBinding = `
 apiVersion: security-profiles-operator.x-k8s.io/v1alpha1
@@ -81,7 +82,7 @@ spec:
 	defer e.kubectl("delete", "pod", "hello")
 
 	e.logf("Waiting for test pod to be initialized")
-	e.kubectl("wait", "--for", "condition=initialized", "pod", "hello")
+	e.waitFor("condition=initialized", "pod", "hello")
 
 	output := e.kubectl("get", "pod", "hello")
 	for strings.Contains(output, "ContainerCreating") {
@@ -126,9 +127,9 @@ func (e *e2e) deployWebhook(manifest string) {
 	// Deploy prerequisites
 	e.logf("Deploying cert-manager")
 	e.kubectl("apply", "-f", certmanager)
-	e.kubectl(
+	e.waitFor(
+		"condition=ready",
 		"--namespace", "cert-manager",
-		"wait", "--for", "condition=ready",
 		"pod", "-l", "app.kubernetes.io/instance=cert-manager",
 	)
 	e.run(
@@ -142,8 +143,8 @@ func (e *e2e) deployWebhook(manifest string) {
 	)
 	e.logf("Deploying webhook")
 	e.kubectl("create", "-f", manifest)
-	e.kubectlOperatorNS("wait", "--for", "condition=ready", "pod", "-l", "name=security-profiles-operator-webhook")
-	e.kubectlOperatorNS("wait", "--for", "condition=ready", "certificate", "webhook-cert")
+	e.waitInOperatorNSFor("condition=ready", "pod", "-l", "name=security-profiles-operator-webhook")
+	e.waitInOperatorNSFor("condition=ready", "certificate", "webhook-cert")
 }
 
 func (e *e2e) cleanupWebhook(manifest string) {
diff --git a/test/tc_run_pod_test.go b/test/tc_run_pod_test.go
index 4af700f72..278ed90af 100644
--- a/test/tc_run_pod_test.go
+++ b/test/tc_run_pod_test.go
@@ -19,6 +19,7 @@ package e2e_test
 import "fmt"
 
 func (e *e2e) testCaseRunPod([]string) {
+	e.seccompOnlyTestCase()
 	const (
 		examplePodPath = "examples/pod.yaml"
 		examplePodName = "test-pod"
@@ -38,7 +39,7 @@ func (e *e2e) testCaseRunPod([]string) {
 	defer e.kubectl("delete", "-f", examplePodPath)
 
 	e.logf("Waiting for test pod to be ready")
-	e.kubectl("wait", "--for", "condition=ready", "pod", "--all")
+	e.waitFor("condition=ready", "pod", "--all")
 
 	e.logf("Testing that `rmdir` is not possible inside the pod")
 	failureOutput := e.kubectlFailure(
diff --git a/test/tc_selinux_base_usage_test.go b/test/tc_selinux_base_usage_test.go
index 57172e5db..a5b262c9d 100644
--- a/test/tc_selinux_base_usage_test.go
+++ b/test/tc_selinux_base_usage_test.go
@@ -108,7 +108,7 @@ spec:
 	podWithPolicy := fmt.Sprintf(podWithPolicyFmt, e.getSELinuxPolicyUsage("errorlogger"))
 	e.writeAndCreate(podWithPolicy, "pod-w-policy.yml")
 
-	e.kubectl("wait", "--for", "condition=ready", "pod", "errorlogger")
+	e.waitFor("condition=ready", "pod", "errorlogger")
 
 	e.logf("the workload should be running")
 	podWithPolicyPhase := e.kubectl(
diff --git a/test/tc_selinux_sanity_check_test.go b/test/tc_selinux_sanity_check_test.go
index 1497eb5b0..a04c3859c 100644
--- a/test/tc_selinux_sanity_check_test.go
+++ b/test/tc_selinux_sanity_check_test.go
@@ -48,7 +48,7 @@ spec:
 	e.logf("creating workload")
 	e.writeAndCreate(podWithoutPolicy, "pod-wo-policy.yml")
 
-	e.kubectl("wait", "--for", "condition=ready", "pod", "el-no-policy")
+	e.waitFor("condition=ready", "pod", "el-no-policy")
 
 	e.logf("the workload should have errored")
 	expectedLog := "/bin/bash: /var/log/test.log: Permission denied"