diff --git a/theodolite/build.gradle b/theodolite/build.gradle
index 5b98e2ace9e9fd040642c566800de35e67f8f4ef..e9f47df879c09b746cbed2e816e711299902cdfd 100644
--- a/theodolite/build.gradle
+++ b/theodolite/build.gradle
@@ -35,9 +35,11 @@ dependencies {
     // compile 'junit:junit:4.12'
 
     testImplementation 'io.quarkus:quarkus-junit5'
+    testImplementation 'io.quarkus:quarkus-test-kubernetes-client'
     testImplementation 'io.rest-assured:rest-assured'
     testImplementation 'org.junit-pioneer:junit-pioneer:1.5.0'
-    testImplementation 'io.fabric8:kubernetes-server-mock:5.10.1'
+    //testImplementation 'io.fabric8:kubernetes-server-mock:5.10.1'
+    testImplementation "org.mockito.kotlin:mockito-kotlin:4.0.0"
 }
 
 group 'theodolite'
diff --git a/theodolite/src/main/kotlin/theodolite/execution/operator/AbstractStateHandler.kt b/theodolite/src/main/kotlin/theodolite/execution/operator/AbstractStateHandler.kt
index 7b17f508465522bee82e538bc25e9165eb6cb65f..8cd469394ac8f2b67d73a0b3d2565cd0f37d7318 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/operator/AbstractStateHandler.kt
+++ b/theodolite/src/main/kotlin/theodolite/execution/operator/AbstractStateHandler.kt
@@ -12,30 +12,30 @@ import mu.KotlinLogging
 import java.lang.Thread.sleep
 private val logger = KotlinLogging.logger {}
 
-abstract class AbstractStateHandler<T, L, D>(
+private const val MAX_RETRIES: Int = 5
+
+abstract class AbstractStateHandler<T : HasMetadata>(
     private val client: NamespacedKubernetesClient,
-    private val crd: Class<T>,
-    private val crdList: Class<L>
-) : StateHandler<T> where T : CustomResource<*, *>?, T : HasMetadata, T : Namespaced, L : KubernetesResourceList<T> {
+    private val crd: Class<T>
+) {
 
-    private val crdClient: MixedOperation<T, L, Resource<T>> =
-        this.client.customResources(this.crd, this.crdList)
+    private val crdClient: MixedOperation<T, KubernetesResourceList<T>, Resource<T>> = this.client.resources(this.crd)
 
     @Synchronized
-    override fun setState(resourceName: String, f: (T) -> T?) {
+    fun setState(resourceName: String, f: (T) -> T?) {
         try {
-            this.crdClient
-                .list().items
-                .filter { it.metadata.name == resourceName }
-                .map { customResource -> f(customResource) }
-                .forEach { this.crdClient.updateStatus(it) }
+            val resource = this.crdClient.withName(resourceName).get()
+            if (resource != null) {
+                val resourcePatched = f(resource)
+                this.crdClient.patchStatus(resourcePatched)
+            }
         } catch (e: KubernetesClientException) {
-            logger.warn { "Status cannot be set for resource $resourceName" }
+            logger.warn(e) { "Status cannot be set for resource $resourceName." }
         }
     }
 
     @Synchronized
-    override fun getState(resourceName: String, f: (T) -> String?): String? {
+    fun getState(resourceName: String, f: (T) -> String?): String? {
         return this.crdClient
             .list().items
             .filter { it.metadata.name == resourceName }
@@ -44,11 +44,11 @@ abstract class AbstractStateHandler<T, L, D>(
     }
 
     @Synchronized
-    override fun blockUntilStateIsSet(
+    fun blockUntilStateIsSet(
         resourceName: String,
         desiredStatusString: String,
         f: (T) -> String?,
-        maxRetries: Int
+        maxRetries: Int = MAX_RETRIES
     ): Boolean {
         for (i in 0.rangeTo(maxRetries)) {
             val currentStatus = getState(resourceName, f)
diff --git a/theodolite/src/main/kotlin/theodolite/execution/operator/BenchmarkStateHandler.kt b/theodolite/src/main/kotlin/theodolite/execution/operator/BenchmarkStateHandler.kt
index adca2a8b7fdb9b3e610f15e57c011679869df14c..80cee0a3a30c0734ff2e12ef0d0291015d157f9c 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/operator/BenchmarkStateHandler.kt
+++ b/theodolite/src/main/kotlin/theodolite/execution/operator/BenchmarkStateHandler.kt
@@ -4,10 +4,9 @@ import io.fabric8.kubernetes.client.NamespacedKubernetesClient
 import theodolite.model.crd.*
 
 class BenchmarkStateHandler(val client: NamespacedKubernetesClient) :
-    AbstractStateHandler<BenchmarkCRD, KubernetesBenchmarkList, ExecutionStatus>(
+    AbstractStateHandler<BenchmarkCRD>(
         client = client,
-        crd = BenchmarkCRD::class.java,
-        crdList = KubernetesBenchmarkList::class.java
+        crd = BenchmarkCRD::class.java
     ) {
 
     private fun getBenchmarkResourceState() = { cr: BenchmarkCRD -> cr.status.resourceSetsState }
diff --git a/theodolite/src/main/kotlin/theodolite/execution/operator/ExecutionEventHandler.kt b/theodolite/src/main/kotlin/theodolite/execution/operator/ExecutionEventHandler.kt
index 16c4ea98ba614bb3dcdd7d9f486f4e65ae70d380..86276af35dd13457cb6c971144153612705dc420 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/operator/ExecutionEventHandler.kt
+++ b/theodolite/src/main/kotlin/theodolite/execution/operator/ExecutionEventHandler.kt
@@ -17,20 +17,21 @@ private val logger = KotlinLogging.logger {}
  * @see TheodoliteController
  * @see BenchmarkExecution
  */
-class ExecutionHandler(
+class ExecutionEventHandler(
     private val controller: TheodoliteController,
     private val stateHandler: ExecutionStateHandler
 ) : ResourceEventHandler<ExecutionCRD> {
+
     private val gson: Gson = GsonBuilder().enableComplexMapKeySerialization().create()
 
     /**
-     * Add an execution to the end of the queue of the TheodoliteController.
+     * Adds an execution to the end of the queue of the TheodoliteController.
      *
-     * @param ExecutionCRD the execution to add
+     * @param execution the execution to add
      */
     @Synchronized
     override fun onAdd(execution: ExecutionCRD) {
-        logger.info { "Add execution ${execution.metadata.name}" }
+        logger.info { "Add execution ${execution.metadata.name}." }
         execution.spec.name = execution.metadata.name
         when (this.stateHandler.getExecutionState(execution.metadata.name)) {
             ExecutionStates.NO_STATE -> this.stateHandler.setExecutionState(execution.spec.name, ExecutionStates.PENDING)
@@ -44,19 +45,19 @@ class ExecutionHandler(
     }
 
     /**
-     * Updates an execution. If this execution is running at the time this function is called, it is stopped and
+     * To be called on update of an execution. If this execution is running at the time this function is called, it is stopped and
      * added to the beginning of the queue of the TheodoliteController.
      * Otherwise, it is just added to the beginning of the queue.
      *
-     * @param oldExecutionCRD the old execution
-     * @param newExecutionCRD the new execution
+     * @param oldExecution the old execution
+     * @param newExecution the new execution
      */
     @Synchronized
     override fun onUpdate(oldExecution: ExecutionCRD, newExecution: ExecutionCRD) {
         newExecution.spec.name = newExecution.metadata.name
         oldExecution.spec.name = oldExecution.metadata.name
         if (gson.toJson(oldExecution.spec) != gson.toJson(newExecution.spec)) {
-            logger.info { "Receive update event for execution ${oldExecution.metadata.name}" }
+            logger.info { "Receive update event for execution ${oldExecution.metadata.name}." }
             when (this.stateHandler.getExecutionState(newExecution.metadata.name)) {
                 ExecutionStates.RUNNING -> {
                     this.stateHandler.setExecutionState(newExecution.spec.name, ExecutionStates.RESTART)
@@ -74,11 +75,11 @@ class ExecutionHandler(
     /**
      * Delete an execution from the queue of the TheodoliteController.
      *
-     * @param ExecutionCRD the execution to delete
+     * @param execution the execution to delete
      */
     @Synchronized
-    override fun onDelete(execution: ExecutionCRD, b: Boolean) {
-        logger.info { "Delete execution ${execution.metadata.name}" }
+    override fun onDelete(execution: ExecutionCRD, deletedFinalStateUnknown: Boolean) {
+        logger.info { "Delete execution ${execution.metadata.name}." }
         if (execution.status.executionState == ExecutionStates.RUNNING.value
             && this.controller.isExecutionRunning(execution.metadata.name)
         ) {
diff --git a/theodolite/src/main/kotlin/theodolite/execution/operator/ExecutionStateHandler.kt b/theodolite/src/main/kotlin/theodolite/execution/operator/ExecutionStateHandler.kt
index 9f49cf3ee4f9f62e7006dbf6697340e1af152f27..a412805621fc7868d1efc215cdf4ff81b52d914e 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/operator/ExecutionStateHandler.kt
+++ b/theodolite/src/main/kotlin/theodolite/execution/operator/ExecutionStateHandler.kt
@@ -11,10 +11,9 @@ import java.time.Instant
 import java.util.concurrent.atomic.AtomicBoolean
 
 class ExecutionStateHandler(val client: NamespacedKubernetesClient) :
-    AbstractStateHandler<ExecutionCRD, BenchmarkExecutionList, ExecutionStatus>(
+    AbstractStateHandler<ExecutionCRD>(
         client = client,
-        crd = ExecutionCRD::class.java,
-        crdList = BenchmarkExecutionList::class.java
+        crd = ExecutionCRD::class.java
     ) {
 
     private var runExecutionDurationTimer: AtomicBoolean = AtomicBoolean(false)
@@ -24,7 +23,7 @@ class ExecutionStateHandler(val client: NamespacedKubernetesClient) :
     private fun getDurationLambda() = { cr: ExecutionCRD -> cr.status.executionDuration }
 
     fun setExecutionState(resourceName: String, status: ExecutionStates): Boolean {
-        setState(resourceName) { cr -> cr.status.executionState = status.value; cr }
+        super.setState(resourceName) { cr -> cr.status.executionState = status.value; cr }
         return blockUntilStateIsSet(resourceName, status.value, getExecutionLambda())
     }
 
@@ -44,11 +43,7 @@ class ExecutionStateHandler(val client: NamespacedKubernetesClient) :
 
     fun getDurationState(resourceName: String): String {
         val status = getState(resourceName, getDurationLambda())
-        return if (status.isNullOrBlank()) {
-            "-"
-        } else {
-            status
-        }
+        return if (status.isNullOrBlank()) "-" else status
     }
 
     private fun durationToK8sString(duration: Duration): String {
diff --git a/theodolite/src/main/kotlin/theodolite/execution/operator/StateHandler.kt b/theodolite/src/main/kotlin/theodolite/execution/operator/StateHandler.kt
index ba8b22f02db9fb4a741dc8892eafeb5fa090da71..28563ac5a640d0226224b812a8e0691cde83942a 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/operator/StateHandler.kt
+++ b/theodolite/src/main/kotlin/theodolite/execution/operator/StateHandler.kt
@@ -2,6 +2,7 @@ package theodolite.execution.operator
 
 private const val MAX_RETRIES: Int = 5
 
+@Deprecated("should not be needed")
 interface StateHandler<T> {
 
     fun setState(resourceName: String, f: (T) -> T?)
diff --git a/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteController.kt b/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteController.kt
index 70e30cf84ef40796eb085a0d68eb2e323232fde9..5c2665f30235eb85aab8f7f3551c3d7a70517b81 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteController.kt
+++ b/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteController.kt
@@ -22,7 +22,6 @@ const val CREATED_BY_LABEL_VALUE = "theodolite"
  *
  * @see BenchmarkExecution
  * @see KubernetesBenchmark
- * @see ConcurrentLinkedDeque
  */
 
 class TheodoliteController(
@@ -34,7 +33,6 @@ class TheodoliteController(
     lateinit var executor: TheodoliteExecutor
 
     /**
-     *
      * Runs the TheodoliteController forever.
      */
     fun run() {
diff --git a/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteOperator.kt b/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteOperator.kt
index 26219f62197c2c9cf4897f26991c8047cc2530b8..11e1763292abb52796527013e6d863c24bb7d486 100644
--- a/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteOperator.kt
+++ b/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteOperator.kt
@@ -90,7 +90,7 @@ class TheodoliteOperator {
             ExecutionCRD::class.java,
             RESYNC_PERIOD
         ).addEventHandler(
-            ExecutionHandler(
+            ExecutionEventHandler(
                 controller = controller,
                 stateHandler = ExecutionStateHandler(client)
             )
diff --git a/theodolite/src/main/kotlin/theodolite/k8s/ResourceByLabelHandler.kt b/theodolite/src/main/kotlin/theodolite/k8s/ResourceByLabelHandler.kt
index c7197ce07beb5540f30b728f17d40de29cab8eb0..518b8eae211dd064e3c12b0713382bf3b12bb1ba 100644
--- a/theodolite/src/main/kotlin/theodolite/k8s/ResourceByLabelHandler.kt
+++ b/theodolite/src/main/kotlin/theodolite/k8s/ResourceByLabelHandler.kt
@@ -96,10 +96,9 @@ class ResourceByLabelHandler(private val client: NamespacedKubernetesClient) {
     /**
      * Block until all pods with are deleted
      *
-     * @param [labelName] the label name
-     * @param [labelValue] the value of this label
+     * @param matchLabels Map of label keys to label values to be deleted
      * */
-    fun blockUntilPodsDeleted(matchLabels: MutableMap<String, String>) {
+    fun blockUntilPodsDeleted(matchLabels: Map<String, String>) {
         while (
             !this.client
                 .pods()
diff --git a/theodolite/src/main/kotlin/theodolite/model/crd/BenchmarkCRD.kt b/theodolite/src/main/kotlin/theodolite/model/crd/BenchmarkCRD.kt
index b6468fff523e57b124e144d5b9fef6477973655a..2e9ffafb83734b3daceb3e9e523e900b887d785a 100644
--- a/theodolite/src/main/kotlin/theodolite/model/crd/BenchmarkCRD.kt
+++ b/theodolite/src/main/kotlin/theodolite/model/crd/BenchmarkCRD.kt
@@ -7,13 +7,21 @@ import io.fabric8.kubernetes.client.CustomResource
 import io.fabric8.kubernetes.model.annotation.Group
 import io.fabric8.kubernetes.model.annotation.Kind
 import io.fabric8.kubernetes.model.annotation.Version
+import theodolite.benchmark.BenchmarkExecution
 import theodolite.benchmark.KubernetesBenchmark
 
 @JsonDeserialize
 @Version("v1")
 @Group("theodolite.com")
 @Kind("benchmark")
-class BenchmarkCRD(
-    var spec: KubernetesBenchmark = KubernetesBenchmark(),
-    var status: BenchmarkStatus = BenchmarkStatus()
-) : CustomResource<KubernetesBenchmark, BenchmarkStatus>(), Namespaced, HasMetadata
\ No newline at end of file
+class BenchmarkCRD : CustomResource<KubernetesBenchmark, BenchmarkStatus>(), Namespaced, HasMetadata {
+
+    override fun initSpec(): KubernetesBenchmark {
+        return KubernetesBenchmark()
+    }
+
+    override fun initStatus(): BenchmarkStatus {
+        return BenchmarkStatus()
+    }
+
+}
\ No newline at end of file
diff --git a/theodolite/src/main/kotlin/theodolite/model/crd/ExecutionCRD.kt b/theodolite/src/main/kotlin/theodolite/model/crd/ExecutionCRD.kt
index 659621e8c3b1d5308a10d81240575dd3d432b53f..3be0aaf2a30cd4ef279edd34854eb936cc6e7e7c 100644
--- a/theodolite/src/main/kotlin/theodolite/model/crd/ExecutionCRD.kt
+++ b/theodolite/src/main/kotlin/theodolite/model/crd/ExecutionCRD.kt
@@ -12,7 +12,14 @@ import theodolite.benchmark.BenchmarkExecution
 @Version("v1")
 @Group("theodolite.com")
 @Kind("execution")
-class ExecutionCRD(
-    var spec: BenchmarkExecution = BenchmarkExecution(),
-    var status: ExecutionStatus = ExecutionStatus()
-) : CustomResource<BenchmarkExecution, ExecutionStatus>(), Namespaced
+class ExecutionCRD: CustomResource<BenchmarkExecution, ExecutionStatus>(), Namespaced {
+
+    override fun initSpec(): BenchmarkExecution {
+        return BenchmarkExecution()
+    }
+
+    override fun initStatus(): ExecutionStatus {
+         return ExecutionStatus()
+    }
+
+}
diff --git a/theodolite/src/main/kotlin/theodolite/model/crd/ExecutionStates.kt b/theodolite/src/main/kotlin/theodolite/model/crd/ExecutionStates.kt
index ad68bf380b18af1a654c201817bb7fc982804c8b..368fc39a3cba1bc702f1f0831c96637a61548358 100644
--- a/theodolite/src/main/kotlin/theodolite/model/crd/ExecutionStates.kt
+++ b/theodolite/src/main/kotlin/theodolite/model/crd/ExecutionStates.kt
@@ -1,7 +1,6 @@
 package theodolite.model.crd
 
 enum class ExecutionStates(val value: String) {
-    // Execution states
     RUNNING("Running"),
     PENDING("Pending"),
     FAILURE("Failure"),
diff --git a/theodolite/src/test/kotlin/theodolite/execution/operator/BenchmarkCRDummy.kt b/theodolite/src/test/kotlin/theodolite/execution/operator/BenchmarkCRDummy.kt
index e294ea539ea60104cc00e9f73de790302ad52670..9b11b31404d2d858db8c75f5880bd47441555814 100644
--- a/theodolite/src/test/kotlin/theodolite/execution/operator/BenchmarkCRDummy.kt
+++ b/theodolite/src/test/kotlin/theodolite/execution/operator/BenchmarkCRDummy.kt
@@ -8,7 +8,7 @@ import theodolite.util.KafkaConfig
 class BenchmarkCRDummy(name: String) {
 
     private val benchmark = KubernetesBenchmark()
-    private val benchmarkCR = BenchmarkCRD(benchmark)
+    private val benchmarkCR = BenchmarkCRD()
 
     fun getCR(): BenchmarkCRD {
         return benchmarkCR
diff --git a/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionCRDummy.kt b/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionCRDummy.kt
index 51347d41b396bf375c14d5580b0f2619ce5b518c..e8010f345140f41dc2edfbe387316f6d21511915 100644
--- a/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionCRDummy.kt
+++ b/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionCRDummy.kt
@@ -9,7 +9,7 @@ class ExecutionCRDummy(name: String, benchmark: String) {
 
     private val execution = BenchmarkExecution()
     private val executionState = ExecutionStatus()
-    private val executionCR = ExecutionCRD(execution, executionState)
+    private val executionCR = ExecutionCRD()
 
     fun getCR(): ExecutionCRD {
         return this.executionCR
@@ -25,6 +25,7 @@ class ExecutionCRDummy(name: String, benchmark: String) {
         executionCR.metadata.name = name
         executionCR.kind = "Execution"
         executionCR.apiVersion = "v1"
+        executionCR.status = executionState
 
         // configure execution
         val loadType = BenchmarkExecution.LoadDefinition()
diff --git a/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionEventHandlerTest.kt b/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionEventHandlerTest.kt
index 15af0d28a3171c29f832ea44222ea01b69dcd07d..ec14d7d8fefb384efc53d79f3b9772c4ccc1e270 100644
--- a/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionEventHandlerTest.kt
+++ b/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionEventHandlerTest.kt
@@ -1,227 +1,266 @@
 package theodolite.execution.operator
 
-import io.fabric8.kubernetes.api.model.KubernetesResource
-import io.fabric8.kubernetes.client.informers.SharedInformerFactory
+import io.fabric8.kubernetes.api.model.KubernetesResourceList
+import io.fabric8.kubernetes.client.dsl.MixedOperation
+import io.fabric8.kubernetes.client.dsl.Resource
 import io.fabric8.kubernetes.client.server.mock.KubernetesServer
 import io.quarkus.test.junit.QuarkusTest
+import io.quarkus.test.kubernetes.client.KubernetesTestServer
+import io.quarkus.test.kubernetes.client.WithKubernetesTestServer
 import org.junit.jupiter.api.AfterEach
-import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Assertions.*
 import org.junit.jupiter.api.BeforeEach
 import org.junit.jupiter.api.DisplayName
 import org.junit.jupiter.api.Test
-import theodolite.k8s.K8sManager
-import theodolite.k8s.resourceLoader.K8sResourceLoaderFromFile
+import org.junit.jupiter.params.ParameterizedTest
+import org.junit.jupiter.params.provider.Arguments
+import org.junit.jupiter.params.provider.MethodSource
+import org.mockito.kotlin.*
+import theodolite.model.crd.ExecutionCRD
 import theodolite.model.crd.ExecutionStates
+import theodolite.model.crd.ExecutionStatus
+import java.io.FileInputStream
 import java.lang.Thread.sleep
+import java.util.stream.Stream
 
+// TODO move somewhere else
+typealias ExecutionClient = MixedOperation<ExecutionCRD, KubernetesResourceList<ExecutionCRD>, Resource<ExecutionCRD>>
 
-private const val SLEEP_AFTER_REQUEST_MS = 500L
-
-
+@WithKubernetesTestServer
 @QuarkusTest
 class ExecutionEventHandlerTest {
-    private final val server = KubernetesServer(false, true)
-    private val testResourcePath = "./src/test/resources/k8s-resource-files/"
-    private final val executionName = "example-execution"
-    lateinit var factory: SharedInformerFactory
-    lateinit var executionVersion1: KubernetesResource
-    lateinit var executionVersion2: KubernetesResource
-    lateinit var stateHandler: ExecutionStateHandler
-    lateinit var manager: K8sManager
+
+    @KubernetesTestServer
+    private lateinit var server: KubernetesServer
+
+    lateinit var executionClient: ExecutionClient
+
     lateinit var controller: TheodoliteController
 
+    lateinit var stateHandler: ExecutionStateHandler
+
+    lateinit var eventHandler: ExecutionEventHandler
+
     @BeforeEach
     fun setUp() {
         server.before()
-        val operator = TheodoliteOperator()
-        this.controller = operator.getController(
-            client = server.client,
-            executionStateHandler = ExecutionStateHandler(client = server.client),
-            benchmarkStateHandler = BenchmarkStateHandler(client = server.client)
-        )
-
-        this.factory = operator.getExecutionEventHandler(this.controller, server.client)
-        this.stateHandler = TheodoliteOperator().getExecutionStateHandler(client = server.client)
-
-        this.executionVersion1 = K8sResourceLoaderFromFile(server.client)
-            .loadK8sResource("Execution", testResourcePath + "test-execution.yaml")
 
-        this.executionVersion2 = K8sResourceLoaderFromFile(server.client)
-            .loadK8sResource("Execution", testResourcePath + "test-execution-update.yaml")
+        this.server.client
+            .apiextensions().v1()
+            .customResourceDefinitions()
+            .load(FileInputStream("crd/crd-execution.yaml"))
+            .create()
 
-        this.stateHandler = operator.getExecutionStateHandler(server.client)
+        this.executionClient = this.server.client.resources(ExecutionCRD::class.java)
 
-        this.manager = K8sManager((server.client))
+        this.controller = mock()
+        this.stateHandler = ExecutionStateHandler(server.client)
+        this.eventHandler = ExecutionEventHandler(this.controller, this.stateHandler)
     }
 
     @AfterEach
     fun tearDown() {
         server.after()
-        factory.stopAllRegisteredInformers()
     }
 
     @Test
-    @DisplayName("Check namespaced property of informers")
-    fun testNamespaced() {
-        manager.deploy(executionVersion1)
-        factory.startAllRegisteredInformers()
-        server.lastRequest
-        // the second request must be namespaced (this is the first `GET` request)
-        assert(
-            server
-                .lastRequest
-                .toString()
-                .contains("namespaces")
-        )
+    fun testCrdRegistered() {
+        val crds = this.server.client.apiextensions().v1().customResourceDefinitions().list();
+        assertEquals(1, crds.items.size)
+        assertEquals("execution", crds.items[0].spec.names.kind)
     }
 
     @Test
-    @DisplayName("Test onAdd method for executions without execution state")
-    fun testWithoutState() {
-        manager.deploy(executionVersion1)
-        factory.startAllRegisteredInformers()
-        sleep(SLEEP_AFTER_REQUEST_MS)
-        assertEquals(
-            ExecutionStates.PENDING,
-            stateHandler.getExecutionState(
-                resourceName = executionName
-            )
-        )
+    fun testExecutionDeploy() {
+        getExecutionFromSystemResource("k8s-resource-files/test-execution.yaml").create()
+
+        val executions = executionClient.list().items
+        assertEquals(1, executions.size)
     }
 
     @Test
-    @DisplayName("Test onAdd method for executions with execution state `RUNNING`")
-    fun testWithStateIsRunning() {
-        manager.deploy(executionVersion1)
-        stateHandler
-            .setExecutionState(
-                resourceName = executionName,
-                status = ExecutionStates.RUNNING
-            )
-        factory.startAllRegisteredInformers()
-        sleep(SLEEP_AFTER_REQUEST_MS)
-        assertEquals(
-            ExecutionStates.RESTART,
-            stateHandler.getExecutionState(
-                resourceName = executionName
-            )
-        )
+    fun testStatusSet() {
+        val execCreated = getExecutionFromSystemResource("k8s-resource-files/test-execution.yaml").create()
+        assertNotNull(execCreated.status)
+        val execResponse = this.executionClient.withName(execCreated.metadata.name)
+        val execResponseItem = execResponse.get()
+        assertNotNull(execResponseItem.status)
     }
 
     @Test
-    @DisplayName("Test onUpdate method for execution with execution state `PENDING`")
-    fun testOnUpdatePending() {
-        manager.deploy(executionVersion1)
-
-        factory.startAllRegisteredInformers()
-        sleep(SLEEP_AFTER_REQUEST_MS)
+    @DisplayName("Test onAdd method for executions without execution state")
+    fun testOnAddWithoutStatus() {
+        // Create first version of execution resource
+        val executionResource = getExecutionFromSystemResource("k8s-resource-files/test-execution.yaml")
+        val execution = executionResource.create()
+        val executionName = execution.metadata.name
 
-        assertEquals(
-            ExecutionStates.PENDING,
-            stateHandler.getExecutionState(
-                resourceName = executionName
-            )
-        )
+        // Get execution from server
+        val executionResponse = this.executionClient.withName(executionName).get()
+        this.eventHandler.onAdd(executionResponse)
 
-        manager.deploy(executionVersion2)
-        assertEquals(
-            ExecutionStates.PENDING,
-            stateHandler.getExecutionState(
-                resourceName = executionName
-            )
-        )
+        assertEquals(ExecutionStates.PENDING.value, this.executionClient.withName(executionName).get().status.executionState)
     }
 
     @Test
-    @DisplayName("Test onUpdate method for execution with execution state `FINISHED`")
-    fun testOnUpdateFinished() {
-        manager.deploy(executionVersion1)
-        factory.startAllRegisteredInformers()
-        sleep(SLEEP_AFTER_REQUEST_MS)
-
-        stateHandler.setExecutionState(
-            resourceName = executionName,
-            status = ExecutionStates.FINISHED
-        )
-
-        manager.deploy(executionVersion2)
-        sleep(SLEEP_AFTER_REQUEST_MS)
-
-        assertEquals(
-            ExecutionStates.PENDING,
-            stateHandler.getExecutionState(
-                resourceName = executionName
-            )
-        )
+    @DisplayName("Test onAdd method for executions with execution state `RUNNING`")
+    fun testOnAddWithStatusRunning() {
+        // Create first version of execution resource
+        val executionResource = getExecutionFromSystemResource("k8s-resource-files/test-execution.yaml")
+        val execution = executionResource.create()
+        val executionName = execution.metadata.name
+        stateHandler.setExecutionState(executionName, ExecutionStates.RUNNING)
+
+        // Update status of execution
+        execution.status.executionState = ExecutionStates.RUNNING.value
+        executionResource.patchStatus(execution)
+
+
+        // Get execution from server
+        val executionResponse = this.executionClient.withName(executionName).get()
+        // Assert that status at server matches set status
+        assertEquals(ExecutionStates.RUNNING.value, this.executionClient.withName(executionName).get().status.executionState)
+
+        whenever(this.controller.isExecutionRunning(executionName)).thenReturn(true)
+
+        this.eventHandler.onAdd(executionResponse)
+
+        verify(this.controller).stop(true)
+        assertEquals(ExecutionStates.RESTART.value, this.executionClient.withName(executionName).get().status.executionState)
     }
 
     @Test
-    @DisplayName("Test onUpdate method for execution with execution state `FAILURE`")
-    fun testOnUpdateFailure() {
-        manager.deploy(executionVersion1)
-        factory.startAllRegisteredInformers()
-        sleep(SLEEP_AFTER_REQUEST_MS)
-
-        stateHandler.setExecutionState(
-            resourceName = executionName,
-            status = ExecutionStates.FAILURE
-        )
-
-        manager.deploy(executionVersion2)
-        sleep(SLEEP_AFTER_REQUEST_MS)
-
-        assertEquals(
-            ExecutionStates.PENDING,
-            stateHandler.getExecutionState(
-                resourceName = executionName
-            )
-        )
+    @DisplayName("Test onUpdate method for execution with no status")
+    fun testOnUpdateWithoutStatus() {
+        // Create first version of execution resource
+        val firstExecutionResource = getExecutionFromSystemResource("k8s-resource-files/test-execution.yaml")
+        val firstExecution = firstExecutionResource.create()
+        val executionName = firstExecution.metadata.name
+
+        // Get execution from server
+        val firstExecutionResponse = this.executionClient.withName(executionName).get()
+        // Assert that execution at server has no status
+        assertEquals("", firstExecutionResponse.status.executionState)
+
+        // Create new version of execution and update at server
+        getExecutionFromSystemResource("k8s-resource-files/test-execution-update.yaml").createOrReplace()
+        // Get execution from server
+        val secondExecutionResponse = this.executionClient.withName(executionName).get()
+
+        this.eventHandler.onUpdate(firstExecutionResponse, secondExecutionResponse)
+
+        // Get execution from server and assert that new status matches expected one
+        assertEquals(ExecutionStates.PENDING.value, this.executionClient.withName(executionName).get().status.executionState)
     }
 
+    @ParameterizedTest
+    @MethodSource("provideOnUpdateTestArguments")
+    @DisplayName("Test onUpdate method for execution with different status")
+    fun testOnUpdateWithStatus(beforeState: ExecutionStates, expectedState: ExecutionStates) {
+        // Create first version of execution resource
+        val firstExecutionResource = getExecutionFromSystemResource("k8s-resource-files/test-execution.yaml")
+        val firstExecution = firstExecutionResource.create()
+        val executionName = firstExecution.metadata.name
+
+        // Update status of execution
+        firstExecution.status.executionState = beforeState.value
+        firstExecutionResource.patchStatus(firstExecution)
+
+        // Get execution from server
+        val firstExecutionResponse = this.executionClient.withName(executionName).get()
+        // Assert that status at server matches set status
+        assertEquals(beforeState.value, firstExecutionResponse.status.executionState)
+
+        // Create new version of execution and update at server
+        getExecutionFromSystemResource("k8s-resource-files/test-execution-update.yaml").createOrReplace()
+        // Get execution from server
+        val secondExecutionResponse = this.executionClient.withName(executionName).get()
+
+        this.eventHandler.onUpdate(firstExecutionResponse, secondExecutionResponse)
+
+        // Get execution from server and assert that new status matches expected one
+        assertEquals(expectedState.value, this.executionClient.withName(executionName).get().status.executionState)
+    }
 
     @Test
-    @DisplayName("Test onUpdate method for execution with execution state `RUNNING`")
-    fun testOnUpdateRunning() {
-        manager.deploy(executionVersion1)
-        factory.startAllRegisteredInformers()
-        sleep(SLEEP_AFTER_REQUEST_MS)
-
-        stateHandler.setExecutionState(
-            resourceName = executionName,
-            status = ExecutionStates.RUNNING
-        )
-
-        manager.deploy(executionVersion2)
-        sleep(SLEEP_AFTER_REQUEST_MS)
-
-        assertEquals(
-            ExecutionStates.RESTART,
-            stateHandler.getExecutionState(
-                resourceName = executionName
-            )
-        )
+    fun testOnDeleteWithExecutionRunning() {
+        // Create first version of execution resource
+        val firstExecutionResource = getExecutionFromSystemResource("k8s-resource-files/test-execution.yaml")
+        val firstExecution = firstExecutionResource.create()
+        val executionName = firstExecution.metadata.name
+
+        // Update status of execution to be running
+        firstExecution.status.executionState = ExecutionStates.RUNNING.value
+        firstExecutionResource.patchStatus(firstExecution)
+
+        // Get execution from server
+        val firstExecutionResponse = this.executionClient.withName(executionName).get()
+        // Assert that execution created at server
+        assertNotNull(firstExecutionResponse)
+
+        // Delete execution
+        this.executionClient.delete(firstExecutionResponse)
+
+        // Get execution from server
+        val secondExecutionResponse = this.executionClient.withName(executionName).get()
+        // Assert that execution created at server
+        assertNull(secondExecutionResponse)
+
+        // We consider execution to be running
+        whenever(this.controller.isExecutionRunning(executionName)).thenReturn(true)
+
+        this.eventHandler.onDelete(firstExecutionResponse, true)
+
+        verify(this.controller).stop(false)
     }
 
     @Test
-    @DisplayName("Test onUpdate method for execution with execution state `RESTART`")
-    fun testOnUpdateRestart() {
-        manager.deploy(executionVersion1)
-        factory.startAllRegisteredInformers()
-        sleep(SLEEP_AFTER_REQUEST_MS)
-
-        stateHandler.setExecutionState(
-            resourceName = executionName,
-            status = ExecutionStates.RESTART
-        )
-
-        manager.deploy(executionVersion2)
-        sleep(SLEEP_AFTER_REQUEST_MS)
-
-        assertEquals(
-            ExecutionStates.RESTART,
-            stateHandler.getExecutionState(
-                resourceName = executionName
+    fun testOnDeleteWithExecutionNotRunning() {
+        // Create first version of execution resource
+        val firstExecutionResource = getExecutionFromSystemResource("k8s-resource-files/test-execution.yaml")
+        val firstExecution = firstExecutionResource.create()
+        val executionName = firstExecution.metadata.name
+
+        // Update status of execution to be running
+        firstExecution.status.executionState = ExecutionStates.RUNNING.value
+        firstExecutionResource.patchStatus(firstExecution)
+
+        // Get execution from server
+        val firstExecutionResponse = this.executionClient.withName(executionName).get()
+        // Assert that execution created at server
+        assertNotNull(firstExecutionResponse)
+
+        // Delete execution
+        this.executionClient.delete(firstExecutionResponse)
+
+        // Get execution from server
+        val secondExecutionResponse = this.executionClient.withName(executionName).get()
+        // Assert that execution created at server
+        assertNull(secondExecutionResponse)
+
+        // We consider execution to be running
+        whenever(this.controller.isExecutionRunning(executionName)).thenReturn(false)
+        
+        this.eventHandler.onDelete(firstExecutionResponse, true)
+
+        verify(this.controller, never()).stop(false)
+    }
+
+    private fun getExecutionFromSystemResource(resourceName: String): Resource<ExecutionCRD> {
+        return executionClient.load(ClassLoader.getSystemResourceAsStream(resourceName))
+    }
+
+    companion object {
+        @JvmStatic
+        fun provideOnUpdateTestArguments(): Stream<Arguments> =
+            Stream.of(
+                // before state -> expected state
+                Arguments.of(ExecutionStates.PENDING, ExecutionStates.PENDING),
+                Arguments.of(ExecutionStates.FINISHED, ExecutionStates.PENDING),
+                Arguments.of(ExecutionStates.FAILURE, ExecutionStates.PENDING),
+                Arguments.of(ExecutionStates.RUNNING, ExecutionStates.RESTART),
+                Arguments.of(ExecutionStates.RESTART, ExecutionStates.RESTART)
             )
-        )
     }
+
 }
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionEventHandlerTestWithInformer.kt b/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionEventHandlerTestWithInformer.kt
new file mode 100644
index 0000000000000000000000000000000000000000..b0904fdb7319a31a1845efa5c71282f03e490381
--- /dev/null
+++ b/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionEventHandlerTestWithInformer.kt
@@ -0,0 +1,282 @@
+package theodolite.execution.operator
+
+import io.fabric8.kubernetes.client.dsl.Resource
+import io.fabric8.kubernetes.client.server.mock.KubernetesServer
+import io.quarkus.test.junit.QuarkusTest
+import io.quarkus.test.kubernetes.client.KubernetesTestServer
+import io.quarkus.test.kubernetes.client.WithKubernetesTestServer
+import org.junit.jupiter.api.*
+import org.junit.jupiter.api.Assertions.*
+import org.junit.jupiter.params.ParameterizedTest
+import org.junit.jupiter.params.provider.Arguments
+import org.junit.jupiter.params.provider.MethodSource
+import org.mockito.kotlin.*
+import theodolite.model.crd.ExecutionCRD
+import theodolite.model.crd.ExecutionStates
+import java.io.FileInputStream
+import java.util.concurrent.CountDownLatch
+import java.util.stream.Stream
+
+@WithKubernetesTestServer
+@QuarkusTest
+class ExecutionEventHandlerTestWithInformer {
+
+    @KubernetesTestServer
+    private lateinit var server: KubernetesServer
+
+    lateinit var executionClient: ExecutionClient
+
+    lateinit var controller: TheodoliteController
+
+    lateinit var stateHandler: ExecutionStateHandler
+
+    lateinit var addCountDownLatch: CountDownLatch
+    lateinit var updateCountDownLatch: CountDownLatch
+    lateinit var deleteCountDownLatch: CountDownLatch
+
+    lateinit var eventHandler: ExecutionEventHandlerWrapper
+
+    @BeforeEach
+    fun setUp() {
+        server.before()
+
+        this.server.client
+            .apiextensions().v1()
+            .customResourceDefinitions()
+            .load(FileInputStream("crd/crd-execution.yaml"))
+            .create()
+
+        this.executionClient = this.server.client.resources(ExecutionCRD::class.java)
+
+        this.controller = mock()
+        this.stateHandler = ExecutionStateHandler(server.client)
+        this.addCountDownLatch = CountDownLatch(1)
+        this.updateCountDownLatch = CountDownLatch(2)
+        this.deleteCountDownLatch = CountDownLatch(1)
+        this.eventHandler = ExecutionEventHandlerWrapper(
+            ExecutionEventHandler(this.controller, this.stateHandler),
+            { addCountDownLatch.countDown() },
+            { updateCountDownLatch.countDown() },
+            { deleteCountDownLatch.countDown() }
+        )
+    }
+
+    @AfterEach
+    fun tearDown() {
+        server.after()
+        this.server.client.informers().stopAllRegisteredInformers()
+    }
+
+    @Test
+    fun testCrdRegistered() {
+        val crds = this.server.client.apiextensions().v1().customResourceDefinitions().list();
+        assertEquals(1, crds.items.size)
+        assertEquals("execution", crds.items[0].spec.names.kind)
+    }
+
+    @Test
+    fun testExecutionDeploy() {
+        getExecutionFromSystemResource("k8s-resource-files/test-execution.yaml").create()
+
+        val executions = executionClient.list().items
+        assertEquals(1, executions.size)
+    }
+
+    @Test
+    fun testStatusSet() {
+        val execCreated = getExecutionFromSystemResource("k8s-resource-files/test-execution.yaml").create()
+        assertNotNull(execCreated.status)
+        val execResponse = this.executionClient.withName(execCreated.metadata.name)
+        val execResponseItem = execResponse.get()
+        assertNotNull(execResponseItem.status)
+    }
+
+    @Test
+    @DisplayName("Test onAdd method for executions without execution state")
+    fun testOnAddWithoutStatus() {
+        // Create first version of execution resource
+        val executionResource = getExecutionFromSystemResource("k8s-resource-files/test-execution.yaml")
+        val execution = executionResource.create()
+        val executionName = execution.metadata.name
+
+        // Start informer
+        this.executionClient.inform(eventHandler)
+
+        // Await informer called
+        this.addCountDownLatch.await()
+        assertEquals(ExecutionStates.PENDING.value, this.executionClient.withName(executionName).get().status.executionState)
+    }
+
+    @Test
+    @DisplayName("Test onAdd method for executions with execution state `RUNNING`")
+    fun testOnAddWithStatusRunning() {
+        // Create first version of execution resource
+        val executionResource = getExecutionFromSystemResource("k8s-resource-files/test-execution.yaml")
+        val executionName = executionResource.get().metadata.name
+
+        whenever(this.controller.isExecutionRunning(executionName)).thenReturn(true)
+
+        // Start informer
+        this.executionClient.inform(eventHandler)
+
+        val execution = executionResource.create()
+
+        // Update status of execution
+        execution.status.executionState = ExecutionStates.RUNNING.value
+        executionResource.patchStatus(execution)
+
+        // Assert that status at server matches set status
+        // assertEquals(ExecutionStates.RUNNING.value, this.executionClient.withName(executionName).get().status.executionState)
+
+        // Await informer called
+        this.addCountDownLatch.await()
+        verify(this.controller).stop(true)
+        assertEquals(ExecutionStates.RESTART.value, this.executionClient.withName(executionName).get().status.executionState)
+    }
+
+    @Test
+    @DisplayName("Test onUpdate method for execution with no status")
+    fun testOnUpdateWithoutStatus() {
+        // Create first version of execution resource
+        val firstExecutionResource = getExecutionFromSystemResource("k8s-resource-files/test-execution.yaml")
+        val firstExecution = firstExecutionResource.create()
+        val executionName = firstExecution.metadata.name
+
+        // Start informer
+        this.executionClient.inform(eventHandler)
+
+        // Get execution from server
+        val firstExecutionResponse = this.executionClient.withName(executionName).get()
+        // Assert that execution at server has pending status
+        assertEquals(ExecutionStates.PENDING.value, firstExecutionResponse.status.executionState)
+
+        // Create new version of execution and update at server
+        getExecutionFromSystemResource("k8s-resource-files/test-execution-update.yaml").createOrReplace()
+
+        // Await informer called
+        this.updateCountDownLatch.await()
+        // Get execution from server and assert that new status matches expected one
+        assertEquals(ExecutionStates.PENDING.value, this.executionClient.withName(executionName).get().status.executionState)
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideOnUpdateTestArguments")
+    @DisplayName("Test onUpdate method for execution with different status")
+    fun testOnUpdateWithStatus(beforeState: ExecutionStates, expectedState: ExecutionStates) {
+        // Create first version of execution resource
+        val firstExecutionResource = getExecutionFromSystemResource("k8s-resource-files/test-execution.yaml")
+        val firstExecution = firstExecutionResource.create()
+        val executionName = firstExecution.metadata.name
+
+        // Update status of execution
+        firstExecution.status.executionState = beforeState.value
+        firstExecutionResource.patchStatus(firstExecution)
+
+        // Start informer
+        this.executionClient.inform(eventHandler)
+
+        // Get execution from server
+        val firstExecutionResponse = this.executionClient.withName(executionName).get()
+        // Assert that status at server matches set status
+        assertEquals(beforeState.value, firstExecutionResponse.status.executionState)
+
+        // Create new version of execution and update at server
+        getExecutionFromSystemResource("k8s-resource-files/test-execution-update.yaml").createOrReplace()
+
+        // Await informer called
+        this.updateCountDownLatch.await()
+        // Get execution from server and assert that new status matches expected one
+        assertEquals(expectedState.value, this.executionClient.withName(executionName).get().status.executionState)
+    }
+
+    @Test
+    @Disabled("Informer also called onAdd and changes status")
+    fun testOnDeleteWithExecutionRunning() {
+        // Create first version of execution resource
+        val firstExecutionResource = getExecutionFromSystemResource("k8s-resource-files/test-execution.yaml")
+        val firstExecution = firstExecutionResource.create()
+        val executionName = firstExecution.metadata.name
+
+        // Update status of execution to be running
+        firstExecution.status.executionState = ExecutionStates.RUNNING.value
+        firstExecutionResource.patchStatus(firstExecution)
+
+        // Get execution from server
+        val firstExecutionResponse = this.executionClient.withName(executionName).get()
+        // Assert that execution created at server
+        assertNotNull(firstExecutionResponse)
+
+        // Start informer
+        this.executionClient.inform(eventHandler)
+
+        // We consider execution to be running
+        whenever(this.controller.isExecutionRunning(executionName)).thenReturn(true)
+
+        // Delete execution
+        this.executionClient.delete(firstExecutionResponse)
+
+        // Get execution from server
+        val secondExecutionResponse = this.executionClient.withName(executionName).get()
+        // Assert that execution deleted at server
+        assertNull(secondExecutionResponse)
+
+        // Await informer called
+        this.deleteCountDownLatch.await()
+
+        verify(this.controller).stop(false)
+    }
+
+    @Test
+    fun testOnDeleteWithExecutionNotRunning() {
+        // Create first version of execution resource
+        val firstExecutionResource = getExecutionFromSystemResource("k8s-resource-files/test-execution.yaml")
+        val firstExecution = firstExecutionResource.create()
+        val executionName = firstExecution.metadata.name
+
+        // Update status of execution to be running
+        firstExecution.status.executionState = ExecutionStates.RUNNING.value
+        firstExecutionResource.patchStatus(firstExecution)
+
+        // Get execution from server
+        val firstExecutionResponse = this.executionClient.withName(executionName).get()
+        // Assert that execution created at server
+        assertNotNull(firstExecutionResponse)
+
+        // Start informer
+        this.executionClient.inform(eventHandler)
+
+        // We consider execution to be running
+        whenever(this.controller.isExecutionRunning(executionName)).thenReturn(false)
+
+        // Delete execution
+        this.executionClient.delete(firstExecutionResponse)
+
+        // Get execution from server
+        val secondExecutionResponse = this.executionClient.withName(executionName).get()
+        // Assert that execution created at server
+        assertNull(secondExecutionResponse)
+
+        // Await informer called
+        this.deleteCountDownLatch.await()
+
+        verify(this.controller, never()).stop(false)
+    }
+
+    private fun getExecutionFromSystemResource(resourceName: String): Resource<ExecutionCRD> {
+        return executionClient.load(ClassLoader.getSystemResourceAsStream(resourceName))
+    }
+
+    companion object {
+        @JvmStatic
+        fun provideOnUpdateTestArguments(): Stream<Arguments> =
+            Stream.of(
+                // before state -> expected state
+                Arguments.of(ExecutionStates.PENDING, ExecutionStates.PENDING),
+                Arguments.of(ExecutionStates.FINISHED, ExecutionStates.PENDING),
+                Arguments.of(ExecutionStates.FAILURE, ExecutionStates.PENDING),
+                // Arguments.of(ExecutionStates.RUNNING, ExecutionStates.RESTART), // see testOnDeleteWithExecutionRunning
+                Arguments.of(ExecutionStates.RESTART, ExecutionStates.RESTART)
+            )
+    }
+
+}
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionEventHandlerWrapper.kt b/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionEventHandlerWrapper.kt
new file mode 100644
index 0000000000000000000000000000000000000000..5dbc515a7799dd51e6395153f13d80650587d7fa
--- /dev/null
+++ b/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionEventHandlerWrapper.kt
@@ -0,0 +1,27 @@
+package theodolite.execution.operator
+
+import io.fabric8.kubernetes.client.informers.ResourceEventHandler
+import theodolite.model.crd.ExecutionCRD
+
+class ExecutionEventHandlerWrapper(
+    private val executionEventHandler: ExecutionEventHandler,
+    private val afterOnAddCallback: () -> Unit,
+    private val afterOnUpdateCallback: () -> Unit,
+    private val afterOnDeleteCallback: () -> Unit
+) : ResourceEventHandler<ExecutionCRD> {
+
+    override fun onAdd(execution: ExecutionCRD) {
+        this.executionEventHandler.onAdd(execution)
+        this.afterOnAddCallback()
+    }
+
+    override fun onUpdate(oldExecution: ExecutionCRD, newExecution: ExecutionCRD) {
+        this.executionEventHandler.onUpdate(oldExecution, newExecution)
+        this.afterOnUpdateCallback()
+    }
+
+    override fun onDelete(execution: ExecutionCRD, deletedFinalStateUnknown: Boolean) {
+        this.executionEventHandler.onDelete(execution, deletedFinalStateUnknown)
+        this.afterOnDeleteCallback()
+    }
+}
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/theodolite/execution/operator/StateHandlerTest.kt b/theodolite/src/test/kotlin/theodolite/execution/operator/StateHandlerTest.kt
index a54f4ed6db559f8f7f15ae82deecf3fedf8b4abe..44b6fce2796222d33c7f49091e4b61c79da770b8 100644
--- a/theodolite/src/test/kotlin/theodolite/execution/operator/StateHandlerTest.kt
+++ b/theodolite/src/test/kotlin/theodolite/execution/operator/StateHandlerTest.kt
@@ -1,6 +1,9 @@
 package theodolite.execution.operator
 
 import io.fabric8.kubernetes.client.server.mock.KubernetesServer
+import io.quarkus.test.junit.QuarkusTest
+import io.quarkus.test.kubernetes.client.KubernetesTestServer
+import io.quarkus.test.kubernetes.client.WithKubernetesTestServer
 import org.junit.jupiter.api.AfterEach
 import org.junit.jupiter.api.Assertions.assertEquals
 import org.junit.jupiter.api.Assertions.assertTrue
@@ -12,9 +15,13 @@ import theodolite.k8s.resourceLoader.K8sResourceLoaderFromFile
 import theodolite.model.crd.ExecutionStates
 import java.time.Duration
 
+@WithKubernetesTestServer
+@QuarkusTest
 class StateHandlerTest {
     private val testResourcePath = "./src/test/resources/k8s-resource-files/"
-    private val server = KubernetesServer(false, true)
+
+    @KubernetesTestServer
+    private lateinit var server: KubernetesServer
 
     @BeforeEach
     fun setUp() {
diff --git a/theodolite/src/test/kotlin/theodolite/util/ExecutionStateComparatorTest.kt b/theodolite/src/test/kotlin/theodolite/util/ExecutionStateComparatorTest.kt
index 7332e53f9e1814f28b8ff37a595b31b0eb931ea7..5d50514857a7a206a64a0612c2270936fe01aa3b 100644
--- a/theodolite/src/test/kotlin/theodolite/util/ExecutionStateComparatorTest.kt
+++ b/theodolite/src/test/kotlin/theodolite/util/ExecutionStateComparatorTest.kt
@@ -19,7 +19,6 @@ class ExecutionStateComparatorTest {
         execution2.getStatus().executionState = ExecutionStates.PENDING.value
         val list = listOf(execution2.getCR(), execution1.getCR())
 
-
         assertEquals(
             list.reversed(),
             list.sortedWith(comparator)
diff --git a/theodolite/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/theodolite/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
new file mode 100644
index 0000000000000000000000000000000000000000..1f0955d450f0dc49ca715b1a0a88a5aa746ee11e
--- /dev/null
+++ b/theodolite/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
@@ -0,0 +1 @@
+mock-maker-inline