From cb3d1ba027ce0fc91edffe693271b7bff7e8c759 Mon Sep 17 00:00:00 2001
From: "stu126940@mail.uni-kiel.de" <stu126940@mail.uni-kiel.de>
Date: Wed, 8 Dec 2021 00:45:21 +0100
Subject: [PATCH] Add basic test for actions and action commands

---
 .../theodolite/benchmark/ActionCommand.kt     |   5 +-
 .../theodolite/benchmark/ActionCommandTest.kt | 115 +++++++++++++++++-
 2 files changed, 115 insertions(+), 5 deletions(-)

diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/ActionCommand.kt b/theodolite/src/main/kotlin/theodolite/benchmark/ActionCommand.kt
index 55c87074a..f1feeaeb4 100644
--- a/theodolite/src/main/kotlin/theodolite/benchmark/ActionCommand.kt
+++ b/theodolite/src/main/kotlin/theodolite/benchmark/ActionCommand.kt
@@ -63,12 +63,11 @@ class ActionCommand(val client: NamespacedKubernetesClient) {
             Thread.currentThread().interrupt();
             throw ActionCommandFailedException("Interrupted while waiting for the exec", e)
         }
-
         logger.info { "Action command finished with code ${exitCode.code}" }
         return exitCode.code
     }
 
-    private fun getPodName(matchLabels: MutableMap<String, String>, tries: Int): String {
+    fun getPodName(matchLabels: MutableMap<String, String>, tries: Int): String {
         for (i in 1..tries) {
 
             try {
@@ -81,7 +80,7 @@ class ActionCommand(val client: NamespacedKubernetesClient) {
         throw ActionCommandFailedException("Couldn't find any pod that matches the specified labels.")
     }
 
-    private fun getPodName(matchLabels: MutableMap<String, String>): String {
+    fun getPodName(matchLabels: MutableMap<String, String>): String {
         return try {
             val podNames = this.client
                 .pods()
diff --git a/theodolite/src/test/kotlin/theodolite/benchmark/ActionCommandTest.kt b/theodolite/src/test/kotlin/theodolite/benchmark/ActionCommandTest.kt
index ef73d8973..9abc5ae5a 100644
--- a/theodolite/src/test/kotlin/theodolite/benchmark/ActionCommandTest.kt
+++ b/theodolite/src/test/kotlin/theodolite/benchmark/ActionCommandTest.kt
@@ -1,14 +1,125 @@
 package theodolite.benchmark
 
-import io.fabric8.kubernetes.client.DefaultKubernetesClient
+import com.google.gson.Gson
+import com.google.gson.GsonBuilder
+import io.fabric8.kubernetes.api.model.Pod
+import io.fabric8.kubernetes.api.model.PodBuilder
+import io.fabric8.kubernetes.api.model.PodListBuilder
+import io.fabric8.kubernetes.client.CustomResourceList
+import io.fabric8.kubernetes.client.server.mock.KubernetesServer
+import io.fabric8.kubernetes.client.server.mock.OutputStreamMessage
+import io.fabric8.kubernetes.client.utils.Utils
 import io.quarkus.test.junit.QuarkusTest
-import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.*
+import theodolite.execution.operator.TheodoliteController
+import theodolite.execution.operator.TheodoliteOperator
+import theodolite.model.crd.BenchmarkCRD
+import theodolite.model.crd.ExecutionCRD
+import theodolite.util.ActionCommandFailedException
 
 
 @QuarkusTest
 class ActionCommandTest {
+    private val server = KubernetesServer(false, false)
+    lateinit var controller: TheodoliteController
+    private val gson: Gson = GsonBuilder().enableComplexMapKeySerialization().create()
+
+    private var benchmark = KubernetesBenchmark()
+    private var execution = BenchmarkExecution()
+
+    private val benchmarkResourceList = CustomResourceList<BenchmarkCRD>()
+    private val executionResourceList = CustomResourceList<ExecutionCRD>()
+
+
+    @BeforeEach
+    fun setUp() {
+        server.before()
+        val operator = TheodoliteOperator()
+        this.controller = operator.getController(
+            client = server.client,
+            executionStateHandler = operator.getExecutionStateHandler(client = server.client),
+            benchmarkStateChecker = operator.getBenchmarkStateChecker(client = server.client)
+        )
+
+        val pod: Pod = PodBuilder().withNewMetadata()
+            .withName("pod1")
+            .withResourceVersion("1")
+            .withLabels<String, String>(mapOf("app" to "pod"))
+            .withNamespace("test").and()
+            .build()
+
+        val ready: Pod = createReadyFrom(pod, "True")
+
+        val podList = PodListBuilder().build()
+        podList.items.add(0, ready)
+
+
+        server
+            .expect()
+            .withPath("/api/v1/namespaces/test/pods?labelSelector=${Utils.toUrlEncoded("app=pod")}")
+            .andReturn(200, podList)
+            .always()
+
+        server
+            .expect()
+            .get()
+            .withPath("/api/v1/namespaces/test/pods/pod1")
+            .andReturn(200, ready)
+            .always()
+
+        server
+            .expect()
+            .withPath("/api/v1/namespaces/test/pods/pod1/exec?command=ls&stdout=true&stderr=true")
+            .andUpgradeToWebSocket()
+            .open(OutputStreamMessage("Test ByteStream"))
+            .done()
+            .always()
+    }
+
+    /**
+     * Copied from fabric8 Kubernetes Client repository
+     *
+     * @param pod
+     * @param status
+     * @return
+     */
+    fun createReadyFrom(pod: Pod, status: String): Pod {
+        return PodBuilder(pod)
+            .withNewStatus()
+            .addNewCondition()
+            .withType("Ready")
+            .withStatus(status)
+            .endCondition()
+            .endStatus()
+            .build()
+    }
+
+    @AfterEach
+    fun tearDown() {
+        server.after()
+    }
+
+    @Test
+    fun testGetPodName() {
+        Assertions.assertEquals("pod1", ActionCommand(client = server.client).getPodName(mutableMapOf("app" to "pod")))
+    }
+
+    @Test
+    fun testActionCommandExec() {
+        Assertions.assertEquals(1000, ActionCommand(client = server.client)
+            .exec(mutableMapOf("app" to "pod"), command = arrayOf("ls"), timeout = 30))
+    }
 
     @Test
     fun testAction() {
+        val action = Action()
+        action.selector = ActionSelector()
+        action.selector.pod = PodSelector()
+        action.selector.pod.matchLabels = mutableMapOf("app" to "pod")
+        action.exec = Command()
+        action.exec.command = arrayOf("ls")
+        action.exec.timeout = 10L
+
+        assertThrows<ActionCommandFailedException> { run { action.exec(server.client) } }
     }
 }
\ No newline at end of file
-- 
GitLab