From a1bd335084d1ca325a30fbe9beb5234295d8ec2b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=B6ren=20Henning?= <soeren.henning@email.uni-kiel.de>
Date: Mon, 14 Mar 2022 13:51:03 +0100
Subject: [PATCH] Fix FileSystemResourceSet tests

---
 .../benchmark/FileSystemResourceSet.kt        |  60 ++++----
 .../benchmark/FileSystemResourceSetTest.kt    | 128 +++++++++++++-----
 2 files changed, 121 insertions(+), 67 deletions(-)

diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/FileSystemResourceSet.kt b/theodolite/src/main/kotlin/theodolite/benchmark/FileSystemResourceSet.kt
index 2537b47da..9b3997fbb 100644
--- a/theodolite/src/main/kotlin/theodolite/benchmark/FileSystemResourceSet.kt
+++ b/theodolite/src/main/kotlin/theodolite/benchmark/FileSystemResourceSet.kt
@@ -5,13 +5,17 @@ import io.fabric8.kubernetes.api.model.HasMetadata
 import io.fabric8.kubernetes.api.model.KubernetesResource
 import io.fabric8.kubernetes.client.NamespacedKubernetesClient
 import io.quarkus.runtime.annotations.RegisterForReflection
-import theodolite.k8s.resourceLoader.K8sResourceLoaderFromFile
 import theodolite.util.DeploymentFailedException
-import theodolite.util.YamlParserFromFile
-import java.io.File
+import java.io.BufferedReader
 import java.io.FileInputStream
 import java.io.FileNotFoundException
-import java.lang.IllegalArgumentException
+import java.io.InputStreamReader
+import java.nio.charset.StandardCharsets
+import java.nio.file.Path
+import java.nio.file.Paths
+import java.util.stream.Collectors
+import kotlin.io.path.listDirectoryEntries
+
 
 @RegisterForReflection
 @JsonDeserialize
@@ -20,46 +24,36 @@ class FileSystemResourceSet: ResourceSet, KubernetesResource {
     lateinit var files: List<String>
 
     override fun getResourceSet(client: NamespacedKubernetesClient): Collection<Pair<String, HasMetadata>> {
-
-        //if files is set ...
+        // if files is set ...
         if(::files.isInitialized){
             return files
-                    .map { loadSingleResource(resourceURL = it, client = client) }
+                .map { Paths.get(path, it) }
+                .map { loadSingleResource(resource = it, client = client) }
         }
 
         return try {
-            File(path)
-                .list() !!
-                .filter { it.endsWith(".yaml") || it.endsWith(".yml") }
-                .map {
-                    loadSingleResource(resourceURL = it, client = client)
-                }
-        } catch (e: NullPointerException) {
+            Paths.get(path)
+                .listDirectoryEntries()
+                .filter { it.toString().endsWith(".yaml") || it.toString().endsWith(".yml") }
+                .map { loadSingleResource(resource = it, client = client) }
+        } catch (e: java.nio.file.NoSuchFileException) { // not to be confused with Kotlin exception
             throw  DeploymentFailedException("Could not load files located in $path", e)
         }
     }
 
-    private fun loadSingleResource(resourceURL: String, client: NamespacedKubernetesClient): Pair<String, HasMetadata> {
-        val parser = YamlParserFromFile()
-        val loader = K8sResourceLoaderFromFile(client)
-        val resourcePath = "$path/$resourceURL"
-        lateinit var kind: String
-
-        try {
-            kind = parser.parse(resourcePath, HashMap<String, String>()::class.java)?.get("kind")!!
-        } catch (e: NullPointerException) {
-            throw DeploymentFailedException("Can not get Kind from resource $resourcePath", e)
-        } catch (e: FileNotFoundException){
-            throw DeploymentFailedException("File $resourcePath not found", e)
-
-        }
-
+    private fun loadSingleResource(resource: Path, client: NamespacedKubernetesClient): Pair<String, HasMetadata> {
         return try {
-            // val k8sResource = loader.loadK8sResource(kind, resourcePath)
-            val k8sResource = client.load(FileInputStream(resourcePath)).get()[0]
-            Pair(resourceURL, k8sResource)
+            //val k8sResource = client.load(FileInputStream(resource.toFile())).get()[0]
+            val stream = FileInputStream(resource.toFile())
+            val text = BufferedReader(
+                InputStreamReader(stream, StandardCharsets.UTF_8)
+            ).lines().collect(Collectors.joining("\n"))
+            val k8sResource = client.resource(text).get()
+            Pair(resource.last().toString(), k8sResource)
+        } catch (e: FileNotFoundException){
+            throw DeploymentFailedException("File $resource not found.", e)
         } catch (e: IllegalArgumentException) {
-            throw DeploymentFailedException("Could not load resource: $resourcePath", e)
+            throw DeploymentFailedException("Could not load resource: $resource.", e)
         }
     }
 }
\ No newline at end of file
diff --git a/theodolite/src/test/kotlin/theodolite/benchmark/FileSystemResourceSetTest.kt b/theodolite/src/test/kotlin/theodolite/benchmark/FileSystemResourceSetTest.kt
index efc249b3d..bd20caf27 100644
--- a/theodolite/src/test/kotlin/theodolite/benchmark/FileSystemResourceSetTest.kt
+++ b/theodolite/src/test/kotlin/theodolite/benchmark/FileSystemResourceSetTest.kt
@@ -1,29 +1,56 @@
 package theodolite.benchmark
 
-import io.fabric8.kubernetes.api.model.ConfigMap
-import io.fabric8.kubernetes.api.model.GenericKubernetesResource
-import io.fabric8.kubernetes.api.model.Service
+import io.fabric8.kubernetes.api.model.*
 import io.fabric8.kubernetes.api.model.apps.Deployment
 import io.fabric8.kubernetes.api.model.apps.StatefulSet
+import io.fabric8.kubernetes.client.dsl.base.ResourceDefinitionContext
 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
 import org.junit.jupiter.api.BeforeEach
 import org.junit.jupiter.api.Test
 import org.junit.jupiter.api.assertThrows
-import theodolite.k8s.CustomResourceWrapper
+import org.junit.jupiter.api.io.TempDir
+import registerResource
+import theodolite.model.crd.BenchmarkCRD
+import theodolite.model.crd.ExecutionCRD
 import theodolite.util.DeploymentFailedException
+import java.io.FileInputStream
+import java.nio.file.Files
+import java.nio.file.Path
 
-private const val testResourcePath = "./src/test/resources/k8s-resource-files/"
-
+@QuarkusTest
+@WithKubernetesTestServer
 class FileSystemResourceSetTest {
 
-    private val server = KubernetesServer(false, true)
+    @KubernetesTestServer
+    private lateinit var server: KubernetesServer
+
+    @TempDir
+    @JvmField
+    final var tempDir: Path? = null
 
     @BeforeEach
     fun setUp() {
         server.before()
+        this.server.client
+            .apiextensions().v1()
+            .customResourceDefinitions()
+            .load(FileInputStream("crd/crd-execution.yaml"))
+            .create()
+        this.server.client
+            .apiextensions().v1()
+            .customResourceDefinitions()
+            .load(FileInputStream("crd/crd-benchmark.yaml"))
+            .create()
+
+        // Apparently we need create CRD clients once
+        this.server.client.resources(ExecutionCRD::class.java)
+        this.server.client.resources(BenchmarkCRD::class.java)
     }
 
     @AfterEach
@@ -31,80 +58,113 @@ class FileSystemResourceSetTest {
         server.after()
     }
 
+    private fun copyTestResourceFile(fileName: String, tempDir: Path) {
+        val stream = javaClass.getResourceAsStream("/k8s-resource-files/$fileName")
+            ?: throw IllegalArgumentException("File does not exist")
+        val target = tempDir.resolve(fileName)
+        Files.copy(stream, target)
+    }
+
     @Test
-    fun testLoadDeployment() {
+    fun testLoadDeployment(@TempDir tempDir: Path) {
+        copyTestResourceFile("test-deployment.yaml", tempDir)
+
         val resourceSet = FileSystemResourceSet()
-        resourceSet.path = testResourcePath
+        resourceSet.path = tempDir.toString()
         resourceSet.files = listOf("test-deployment.yaml")
-        assertEquals(1,resourceSet.getResourceSet(server.client).size)
+        assertEquals(1, resourceSet.getResourceSet(server.client).size)
         assertTrue(resourceSet.getResourceSet(server.client).toList().first().second is Deployment)
     }
 
     @Test
-    fun testLoadService() {
+    fun testLoadService(@TempDir tempDir: Path) {
+        copyTestResourceFile("test-service.yaml", tempDir)
+
         val resourceSet = FileSystemResourceSet()
-        resourceSet.path = testResourcePath
+        resourceSet.path = tempDir.toString()
         resourceSet.files = listOf("test-service.yaml")
-        assertEquals(1,resourceSet.getResourceSet(server.client).size)
+        assertEquals(1, resourceSet.getResourceSet(server.client).size)
         assertTrue(resourceSet.getResourceSet(server.client).toList().first().second is Service)
     }
 
     @Test
-    fun testLoadStatefulSet() {
+    fun testLoadStatefulSet(@TempDir tempDir: Path) {
+        copyTestResourceFile("test-statefulset.yaml", tempDir)
+
         val resourceSet = FileSystemResourceSet()
-        resourceSet.path = testResourcePath
+        resourceSet.path = tempDir.toString()
         resourceSet.files = listOf("test-statefulset.yaml")
-        assertEquals(1,resourceSet.getResourceSet(server.client).size)
+        assertEquals(1, resourceSet.getResourceSet(server.client).size)
         assertTrue(resourceSet.getResourceSet(server.client).toList().first().second is StatefulSet)
     }
 
     @Test
-    fun testLoadConfigMap() {
+    fun testLoadConfigMap(@TempDir tempDir: Path) {
+        copyTestResourceFile("test-configmap.yaml", tempDir)
+
         val resourceSet = FileSystemResourceSet()
-        resourceSet.path = testResourcePath
+        resourceSet.path = tempDir.toString()
         resourceSet.files = listOf("test-configmap.yaml")
-        assertEquals(1,resourceSet.getResourceSet(server.client).size)
+        assertEquals(1, resourceSet.getResourceSet(server.client).size)
         assertTrue(resourceSet.getResourceSet(server.client).toList().first().second is ConfigMap)
     }
 
     @Test
-    fun testLoadServiceMonitor() {
+    fun testLoadServiceMonitor(@TempDir tempDir: Path) {
+        val serviceMonitorContext = ResourceDefinitionContext.Builder()
+            .withGroup("monitoring.coreos.com")
+            .withKind("ServiceMonitor")
+            .withPlural("servicemonitors")
+            .withNamespaced(true)
+            .withVersion("v1")
+            .build()
+        server.registerResource(serviceMonitorContext)
+
+        copyTestResourceFile("test-service-monitor.yaml", tempDir)
+
         val resourceSet = FileSystemResourceSet()
-        resourceSet.path = testResourcePath
+        resourceSet.path = tempDir.toString()
         resourceSet.files = listOf("test-service-monitor.yaml")
         assertEquals(1, resourceSet.getResourceSet(server.client).size)
         assertTrue(resourceSet.getResourceSet(server.client).toList().first().second is GenericKubernetesResource)
     }
 
     @Test
-    fun testLoadBenchmark() {
+    fun testLoadBenchmark(@TempDir tempDir: Path) {
+        copyTestResourceFile("test-benchmark.yaml", tempDir)
+
         val resourceSet = FileSystemResourceSet()
-        resourceSet.path = testResourcePath
+        resourceSet.path = tempDir.toString()
         resourceSet.files = listOf("test-benchmark.yaml")
-        assertEquals(1,resourceSet.getResourceSet(server.client).size)
-        assertTrue(resourceSet.getResourceSet(server.client).toList().first().second is GenericKubernetesResource)
+        assertEquals(1, resourceSet.getResourceSet(server.client).size)
+        assertTrue(resourceSet.getResourceSet(server.client).toList().first().second is BenchmarkCRD)
     }
 
     @Test
-    fun testLoadExecution() {
+    fun testLoadExecution(@TempDir tempDir: Path) {
+        copyTestResourceFile("test-execution.yaml", tempDir)
+
         val resourceSet = FileSystemResourceSet()
-        resourceSet.path = testResourcePath
+        resourceSet.path = tempDir.toString()
         resourceSet.files = listOf("test-execution.yaml")
-        assertEquals(1,resourceSet.getResourceSet(server.client).size)
-        assertTrue(resourceSet.getResourceSet(server.client).toList().first().second is GenericKubernetesResource)
+        assertEquals(1, resourceSet.getResourceSet(server.client).size)
+        assertTrue(resourceSet.getResourceSet(server.client).toList().first().second is ExecutionCRD)
     }
 
     @Test
-    fun testFilesNotSet() {
+    fun testFilesNotSet(@TempDir tempDir: Path) {
+        copyTestResourceFile("test-deployment.yaml", tempDir)
+        copyTestResourceFile("test-service.yaml", tempDir)
+
         val resourceSet = FileSystemResourceSet()
-        resourceSet.path = testResourcePath
-        assertEquals(9,resourceSet.getResourceSet(server.client).size)
+        resourceSet.path = tempDir.toString()
+        assertEquals(2, resourceSet.getResourceSet(server.client).size)
     }
 
     @Test
-    fun testWrongPath() {
+    fun testWrongPath(@TempDir tempDir: Path) {
         val resourceSet = FileSystemResourceSet()
-        resourceSet.path = "/abc/not-exist"
+        resourceSet.path = "/not/existing/path"
         assertThrows<DeploymentFailedException> {
             resourceSet.getResourceSet(server.client)
         }
-- 
GitLab