diff --git a/theodolite/examples/operator/example-benchmark.yaml b/theodolite/examples/operator/example-benchmark.yaml index 7bcfee9932b65cf66b8d8dd457d10d65848eff91..c59ea42171d8ca9e8d4ece7a815de057cccf479d 100644 --- a/theodolite/examples/operator/example-benchmark.yaml +++ b/theodolite/examples/operator/example-benchmark.yaml @@ -21,7 +21,7 @@ spec: properties: loadGenMaxRecords: "15000" kafkaConfig: - bootstrapServer: "theodolite-cp-kafka:9092" + bootstrapServer: "localhost:9092" # "theodolite-cp-kafka:9092" topics: - name: "input" numPartitions: 40 @@ -32,15 +32,22 @@ spec: replicationFactor: 0 appResourceSets: - FileSystemResourceSet: - path: ./config - files: - - "uc1-kstreams-deployment.yaml" - - "aggregation-service.yaml" - - "jmx-configmap.yaml" - - "uc1-service-monitor.yaml" + path: ./../../../../config + files: + - "uc1-kstreams-deployment.yaml" + - "aggregation-service.yaml" + - "jmx-configmap.yaml" + - "uc1-service-monitor.yaml" + # - ConfigMapResourceSet: + # configmap: "test-configmap" + # files: + # - "uc1-kstreams-deployment.yaml" + # - "aggregation-service.yaml" + # - "jmx-configmap.yaml" + # - "uc1-service-monitor.yaml" loadGenResourceSets: - - ConfigMapResourceSet: - configmap: "test-configmap" + - FileSystemResourceSet: + path: ./../../../../config files: - uc1-load-generator-service.yaml - uc1-load-generator-deployment.yaml diff --git a/theodolite/examples/operator/example-execution.yaml b/theodolite/examples/operator/example-execution.yaml index 48452dee509aa57b36d4d76a8c4646996630a5c2..256b3c31ca3bc234b7a7137768c7f046728065c5 100644 --- a/theodolite/examples/operator/example-execution.yaml +++ b/theodolite/examples/operator/example-execution.yaml @@ -13,7 +13,7 @@ spec: slos: - sloType: "lag trend" threshold: 2000 - prometheusUrl: "http://prometheus-operated:9090" + prometheusUrl: "http://localhost:9090" # "http://prometheus-operated:9090" externalSloUrl: "http://localhost:80/evaluate-slope" offset: 0 warmup: 60 # in seconds diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/ConfigMapResourceSet.kt b/theodolite/src/main/kotlin/theodolite/benchmark/ConfigMapResourceSet.kt index ac9e9898061cac2b232c5a4ff3fe9dc1973e9f8d..582a4745eb89789ebe24719497dc9026e25142dd 100644 --- a/theodolite/src/main/kotlin/theodolite/benchmark/ConfigMapResourceSet.kt +++ b/theodolite/src/main/kotlin/theodolite/benchmark/ConfigMapResourceSet.kt @@ -7,10 +7,10 @@ import io.fabric8.kubernetes.client.NamespacedKubernetesClient import io.quarkus.runtime.annotations.RegisterForReflection import mu.KotlinLogging import theodolite.k8s.resourceLoader.K8sResourceLoaderFromString +import theodolite.util.DeploymentFailedException import theodolite.util.YamlParserFromString private val logger = KotlinLogging.logger {} -private const val DEFAULT_NAMESPACE = "default" @RegisterForReflection @JsonDeserialize @@ -19,19 +19,21 @@ class ConfigMapResourceSet: ResourceSet, KubernetesResource { lateinit var files: List<String> // load all files, iff files is not set @OptIn(ExperimentalStdlibApi::class) - override fun getResourceSet(): List<Pair<String, KubernetesResource>> { - val namespace = System.getenv("NAMESPACE") ?: DEFAULT_NAMESPACE - val client: NamespacedKubernetesClient = DefaultKubernetesClient().inNamespace(namespace) + override fun getResourceSet(client: NamespacedKubernetesClient): List<Pair<String, KubernetesResource>> { val loader = K8sResourceLoaderFromString(client) - var resources = client + logger.info {"use namespace: ${client.namespace} in configmap resource set" } + + var resources = emptyMap<String,String>() + + try { + resources = client .configMaps() .withName(configmap) .get() .data .filter { it.key.endsWith(".yaml") } // consider only yaml files, e.g. ignore readme files - if (::files.isInitialized){ resources = resources .filter { files.contains(it.key) } @@ -45,6 +47,10 @@ class ConfigMapResourceSet: ResourceSet, KubernetesResource { Pair( it.second.key, loader.loadK8sResource(it.first, it.second.value)) } + }catch ( e: Exception) { + logger.error { e.message } + throw DeploymentFailedException("could not create resource set from configMap $configmap") + } } private fun getKind(resource: String): String { @@ -55,7 +61,7 @@ class ConfigMapResourceSet: ResourceSet, KubernetesResource { resourceAsMap?.get("kind")!! } catch (e: Exception) { logger.error { "Could not find field kind of Kubernetes resource: ${resourceAsMap?.get("name")}" } - "" + throw e } } } \ No newline at end of file diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/FileSystemResourceSet.kt b/theodolite/src/main/kotlin/theodolite/benchmark/FileSystemResourceSet.kt index dbedee6c85111b6ed72a640f66611fab4bdde823..8d654b9795c79adadc1f504dd64d56555af1a718 100644 --- a/theodolite/src/main/kotlin/theodolite/benchmark/FileSystemResourceSet.kt +++ b/theodolite/src/main/kotlin/theodolite/benchmark/FileSystemResourceSet.kt @@ -3,6 +3,7 @@ package theodolite.benchmark import com.fasterxml.jackson.databind.annotation.JsonDeserialize import io.fabric8.kubernetes.api.model.KubernetesResource import io.fabric8.kubernetes.client.DefaultKubernetesClient +import io.fabric8.kubernetes.client.NamespacedKubernetesClient import io.quarkus.runtime.annotations.RegisterForReflection import mu.KotlinLogging import theodolite.k8s.resourceLoader.K8sResourceLoaderFromFile @@ -11,7 +12,6 @@ import theodolite.util.YamlParserFromFile import java.io.File private val logger = KotlinLogging.logger {} -private const val DEFAULT_NAMESPACE = "default" @RegisterForReflection @JsonDeserialize @@ -19,13 +19,17 @@ class FileSystemResourceSet: ResourceSet, KubernetesResource { lateinit var path: String lateinit var files: List<String> - override fun getResourceSet(): List<Pair<String, KubernetesResource>> { + override fun getResourceSet(client: NamespacedKubernetesClient): List<Pair<String, KubernetesResource>> { //if files is set ... if(::files.isInitialized){ - return files - .map { loadSingleResource(it) - } + return try { + files + .map { loadSingleResource(resourceURL = it, client = client) } + } catch (e: Exception) { + throw DeploymentFailedException("Could not load files located in $path") + + } } return try { @@ -33,21 +37,24 @@ class FileSystemResourceSet: ResourceSet, KubernetesResource { .list() !! .filter { it.endsWith(".yaml") } // consider only yaml files, e.g. ignore readme files .map { - loadSingleResource(it) + loadSingleResource(resourceURL = it, client = client) } } catch (e: Exception) { throw DeploymentFailedException("Could not load files located in $path") } } - private fun loadSingleResource(resourceURL: String): Pair<String, KubernetesResource> { + private fun loadSingleResource(resourceURL: String, client: NamespacedKubernetesClient): Pair<String, KubernetesResource> { val parser = YamlParserFromFile() - val namespace = System.getenv("NAMESPACE") ?: DEFAULT_NAMESPACE - val loader = K8sResourceLoaderFromFile(DefaultKubernetesClient().inNamespace(namespace)) - + val loader = K8sResourceLoaderFromFile(client) val resourcePath = "$path/$resourceURL" - val kind = parser.parse(resourcePath, HashMap<String, String>()::class.java)?.get("kind")!! - val k8sResource = loader.loadK8sResource(kind, resourcePath) - return Pair(resourceURL, k8sResource) + return try { + val kind = parser.parse(resourcePath, HashMap<String, String>()::class.java)?.get("kind")!! + val k8sResource = loader.loadK8sResource(kind, resourcePath) + Pair(resourceURL, k8sResource) + } catch (e: Exception) { + logger.error { "could not load resource: $resourcePath, caused by exception: $e" } + throw e + } } } \ No newline at end of file diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt b/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt index 309cd9513752850db2bd1a90eecff6139f9c7c24..4c0ad72e85d1888f38e9ba30ebe992881f1c83bc 100644 --- a/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt +++ b/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt @@ -48,7 +48,7 @@ class KubernetesBenchmark : KubernetesResource, Benchmark { * the [K8sResourceLoader] */ fun loadKubernetesResources(resourceSet: List<ResourceSets>): List<Pair<String, KubernetesResource>> { - return resourceSet.flatMap { it.loadResourceSet() } + return resourceSet.flatMap { it.loadResourceSet(DefaultKubernetesClient().inNamespace(namespace)) } } /** diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/ResourceSet.kt b/theodolite/src/main/kotlin/theodolite/benchmark/ResourceSet.kt index 974e06858e0f761f5e7b370cb14cdb2dc5c345af..f6174e1b5ae2ee4124ec0c575c77007aebb337b0 100644 --- a/theodolite/src/main/kotlin/theodolite/benchmark/ResourceSet.kt +++ b/theodolite/src/main/kotlin/theodolite/benchmark/ResourceSet.kt @@ -2,11 +2,12 @@ package theodolite.benchmark import com.fasterxml.jackson.databind.annotation.JsonDeserialize import io.fabric8.kubernetes.api.model.KubernetesResource +import io.fabric8.kubernetes.client.NamespacedKubernetesClient import io.quarkus.runtime.annotations.RegisterForReflection @RegisterForReflection @JsonDeserialize interface ResourceSet: KubernetesResource { - fun getResourceSet(): List<Pair<String, KubernetesResource>> + fun getResourceSet(client: NamespacedKubernetesClient): List<Pair<String, KubernetesResource>> } \ No newline at end of file diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/ResourceSets.kt b/theodolite/src/main/kotlin/theodolite/benchmark/ResourceSets.kt index f7b3dac8025b3d5e93a2ae52a13fdd8743037a46..b634c0fb15bdaba63662226e8f7c4dcde8edacb4 100644 --- a/theodolite/src/main/kotlin/theodolite/benchmark/ResourceSets.kt +++ b/theodolite/src/main/kotlin/theodolite/benchmark/ResourceSets.kt @@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.databind.annotation.JsonDeserialize import io.fabric8.kubernetes.api.model.KubernetesResource +import io.fabric8.kubernetes.client.NamespacedKubernetesClient import io.quarkus.runtime.annotations.RegisterForReflection import mu.KotlinLogging import theodolite.util.DeploymentFailedException @@ -18,12 +19,12 @@ class ResourceSets: KubernetesResource { @JsonProperty("FileSystemResourceSet") lateinit var FileSystemResourceSet: FileSystemResourceSet - fun loadResourceSet(): List<Pair<String, KubernetesResource>> { + fun loadResourceSet(client: NamespacedKubernetesClient): List<Pair<String, KubernetesResource>> { return try { if (::ConfigMapResourceSet.isInitialized) { - ConfigMapResourceSet.getResourceSet() + ConfigMapResourceSet.getResourceSet(client= client) } else if (::FileSystemResourceSet.isInitialized) { - FileSystemResourceSet.getResourceSet() + FileSystemResourceSet.getResourceSet(client= client ) } else { throw DeploymentFailedException("could not load resourceSet.") } diff --git a/theodolite/src/main/kotlin/theodolite/k8s/CustomResourceWrapper.kt b/theodolite/src/main/kotlin/theodolite/k8s/CustomResourceWrapper.kt index ab355677ec53216072fb58a170610aa5f12dba28..a7f18ce6f0f860865a18e0ac324ea5819c61c918 100644 --- a/theodolite/src/main/kotlin/theodolite/k8s/CustomResourceWrapper.kt +++ b/theodolite/src/main/kotlin/theodolite/k8s/CustomResourceWrapper.kt @@ -8,7 +8,7 @@ import mu.KotlinLogging private val logger = KotlinLogging.logger {} class CustomResourceWrapper( - private val crAsMap: Map<String, String>, + val crAsMap: Map<String, String>, private val context: CustomResourceDefinitionContext ) : KubernetesResource { /** diff --git a/theodolite/src/main/kotlin/theodolite/k8s/resourceLoader/K8sAbstractLoader.kt b/theodolite/src/main/kotlin/theodolite/k8s/resourceLoader/K8sAbstractLoader.kt index bfd183ae1d9fa999bb0c269ffb5daaf99e58dd5d..d2617e29349cc684e3acbff67a9ddb63114ddf52 100644 --- a/theodolite/src/main/kotlin/theodolite/k8s/resourceLoader/K8sAbstractLoader.kt +++ b/theodolite/src/main/kotlin/theodolite/k8s/resourceLoader/K8sAbstractLoader.kt @@ -9,10 +9,8 @@ private val logger = KotlinLogging.logger {} abstract class AbstractK8sLoader: K8sResourceLoader { - abstract fun loadCustomResourceWrapper(resource: String, context: CustomResourceDefinitionContext): KubernetesResource - fun loadK8sResource(kind: String, resourceString: String): KubernetesResource { - return when (kind) { + return when (kind.replaceFirst(kind[0],kind[0].toUpperCase())) { "Deployment" -> loadDeployment(resourceString) "Service" -> loadService(resourceString) "ServiceMonitor" -> loadServiceMonitor(resourceString) @@ -21,7 +19,7 @@ abstract class AbstractK8sLoader: K8sResourceLoader { "Execution" -> loadExecution(resourceString) "Benchmark" -> loadBenchmark(resourceString) else -> { - logger.error { "Error during loading of unspecified resource Kind" } + logger.error { "Error during loading of unspecified resource Kind $kind" } throw java.lang.IllegalArgumentException("error while loading resource with kind: $kind") } } @@ -33,12 +31,11 @@ abstract class AbstractK8sLoader: K8sResourceLoader { try { resource = f(resourceString) } catch (e: Exception) { - logger.warn { "You potentially misspelled the path: ....1" } logger.warn { e } } if (resource == null) { - throw IllegalArgumentException("The Resource: ....1 could not be loaded") + throw IllegalArgumentException("The Resource: $resourceString could not be loaded") } return resource } diff --git a/theodolite/src/main/kotlin/theodolite/k8s/resourceLoader/K8sResourceLoader.kt b/theodolite/src/main/kotlin/theodolite/k8s/resourceLoader/K8sResourceLoader.kt index 5f8643717913cb2e9e9598f8861f522b48d2f3ee..c123ab2958132cb43ad188136f738b561e91310b 100644 --- a/theodolite/src/main/kotlin/theodolite/k8s/resourceLoader/K8sResourceLoader.kt +++ b/theodolite/src/main/kotlin/theodolite/k8s/resourceLoader/K8sResourceLoader.kt @@ -1,6 +1,7 @@ package theodolite.k8s.resourceLoader import io.fabric8.kubernetes.api.model.KubernetesResource +import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext interface K8sResourceLoader { fun loadDeployment(resource: String): KubernetesResource @@ -10,4 +11,5 @@ interface K8sResourceLoader { fun loadBenchmark(resource: String): KubernetesResource fun loadConfigmap(resource: String): KubernetesResource fun loadServiceMonitor(resource: String): KubernetesResource + fun loadCustomResourceWrapper(resource: String, context: CustomResourceDefinitionContext): KubernetesResource } \ No newline at end of file diff --git a/theodolite/src/test/kotlin/theodolite/benchmark/ConfigMapResourceSetTest.kt b/theodolite/src/test/kotlin/theodolite/benchmark/ConfigMapResourceSetTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..a40e257b1b9bf41ecc3941a6ff1aee917a7e87cb --- /dev/null +++ b/theodolite/src/test/kotlin/theodolite/benchmark/ConfigMapResourceSetTest.kt @@ -0,0 +1,234 @@ +package theodolite.benchmark + +import com.google.gson.Gson +import io.fabric8.kubernetes.api.model.* +import io.fabric8.kubernetes.api.model.apps.Deployment +import io.fabric8.kubernetes.api.model.apps.DeploymentBuilder +import io.fabric8.kubernetes.api.model.apps.StatefulSet +import io.fabric8.kubernetes.api.model.apps.StatefulSetBuilder +import io.fabric8.kubernetes.client.server.mock.KubernetesServer +import io.quarkus.test.junit.QuarkusTest +import io.smallrye.common.constraint.Assert.assertTrue +import junit.framework.Assert.assertEquals +import mu.KotlinLogging +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junitpioneer.jupiter.SetEnvironmentVariable +import theodolite.execution.operator.ExecutionCRDummy +import theodolite.execution.operator.TheodoliteOperator +import theodolite.k8s.CustomResourceWrapper +import theodolite.k8s.resourceLoader.K8sResourceLoaderFromFile +import theodolite.model.crd.ExecutionCRD +import theodolite.util.DeploymentFailedException +import java.lang.IllegalStateException + +private val testResourcePath = "./src/test/resources/k8s-resource-files/" + +@QuarkusTest +class ConfigMapResourceSetTest { + private val server = KubernetesServer(false, true) + + @BeforeEach + fun setUp() { + server.before() + } + + @AfterEach + fun tearDown() { + server.after() + } + + fun deployAndGetResource(resource: String): List<Pair<String, KubernetesResource>> { + val configMap1 = ConfigMapBuilder() + .withNewMetadata().withName("test-configmap").endMetadata() + .addToData("test-resource.yaml",resource) + .build() + + server.client.configMaps().createOrReplace(configMap1) + + val resourceSet = ConfigMapResourceSet() + resourceSet.configmap = "test-configmap" + + return resourceSet.getResourceSet(server.client) + } + + + @Test + fun testLoadDeployment() { + val resourceBuilder = DeploymentBuilder() + resourceBuilder.withNewSpec().endSpec() + resourceBuilder.withNewMetadata().endMetadata() + val resource = resourceBuilder.build() + resource.metadata.name = "test-deployment" + + val createdResource = deployAndGetResource(resource = Gson().toJson(resource)) + assertEquals(1, createdResource.size) + assertTrue(createdResource[0].second is Deployment) + assertTrue(createdResource[0].second.toString().contains(other = resource.metadata.name)) + } + + @Test + fun testLoadStateFulSet() { + val resourceBuilder = StatefulSetBuilder() + resourceBuilder.withNewSpec().endSpec() + resourceBuilder.withNewMetadata().endMetadata() + val resource = resourceBuilder.build() + resource.metadata.name = "test-resource" + + val createdResource = deployAndGetResource(resource = Gson().toJson(resource)) + assertEquals(1, createdResource.size) + assertTrue(createdResource[0].second is StatefulSet) + assertTrue(createdResource[0].second.toString().contains(other = resource.metadata.name)) + } + + @Test + fun testLoadService() { + val resourceBuilder = ServiceBuilder() + resourceBuilder.withNewSpec().endSpec() + resourceBuilder.withNewMetadata().endMetadata() + val resource = resourceBuilder.build() + resource.metadata.name = "test-resource" + + val createdResource = deployAndGetResource(resource = Gson().toJson(resource)) + assertEquals(1, createdResource.size) + assertTrue(createdResource[0].second is Service) + assertTrue(createdResource[0].second.toString().contains(other = resource.metadata.name)) + } + + @Test + fun testLoadConfigMap() { + val resourceBuilder = ConfigMapBuilder() + resourceBuilder.withNewMetadata().endMetadata() + val resource = resourceBuilder.build() + resource.metadata.name = "test-resource" + + val createdResource = deployAndGetResource(resource = Gson().toJson(resource)) + assertEquals(1, createdResource.size) + assertTrue(createdResource[0].second is ConfigMap) + assertTrue(createdResource[0].second.toString().contains(other = resource.metadata.name)) + } + + @Test + fun testLoadExecution() { + val loader = K8sResourceLoaderFromFile(server.client) + val resource = loader.loadK8sResource("Execution", testResourcePath + "test-execution.yaml") as CustomResourceWrapper + val createdResource = deployAndGetResource(resource = Gson().toJson(resource.crAsMap)) + + assertEquals(1, createdResource.size) + assertTrue(createdResource[0].second is CustomResourceWrapper) + + val loadedResource = createdResource[0].second + if (loadedResource is CustomResourceWrapper){ + assertTrue(loadedResource.getName() == "example-execution") + } + } + + @Test + fun testLoadBenchmark() { + val loader = K8sResourceLoaderFromFile(server.client) + val resource = loader.loadK8sResource("Benchmark", testResourcePath + "test-benchmark.yaml") as CustomResourceWrapper + val createdResource = deployAndGetResource(resource = Gson().toJson(resource.crAsMap)) + + assertEquals(1, createdResource.size) + assertTrue(createdResource[0].second is CustomResourceWrapper) + + val loadedResource = createdResource[0].second + if (loadedResource is CustomResourceWrapper){ + assertTrue(loadedResource.getName() == "example-benchmark") + } + } + + @Test + fun testLoadServiceMonitor() { + val loader = K8sResourceLoaderFromFile(server.client) + val resource = loader.loadK8sResource("ServiceMonitor", testResourcePath + "test-service-monitor.yaml") as CustomResourceWrapper + val createdResource = deployAndGetResource(resource = Gson().toJson(resource.crAsMap)) + + assertEquals(1, createdResource.size) + assertTrue(createdResource[0].second is CustomResourceWrapper) + + val loadedResource = createdResource[0].second + if (loadedResource is CustomResourceWrapper){ + assertTrue(loadedResource.getName() == "test-service-monitor") + } + } + + @Test + fun testMultipleFiles(){ + val resourceBuilder = DeploymentBuilder() + resourceBuilder.withNewSpec().endSpec() + resourceBuilder.withNewMetadata().endMetadata() + val resource = resourceBuilder.build() + resource.metadata.name = "test-deployment" + + val resourceBuilder1 = ConfigMapBuilder() + resourceBuilder1.withNewMetadata().endMetadata() + val resource1 = resourceBuilder1.build() + resource1.metadata.name = "test-configmap" + + val configMap1 = ConfigMapBuilder() + .withNewMetadata().withName("test-configmap").endMetadata() + .addToData("test-deployment.yaml",Gson().toJson(resource)) + .addToData("test-configmap.yaml",Gson().toJson(resource1)) + .build() + + server.client.configMaps().createOrReplace(configMap1) + + val resourceSet = ConfigMapResourceSet() + resourceSet.configmap = "test-configmap" + + val createdResourcesSet = resourceSet.getResourceSet(server.client) + + assertEquals(2,createdResourcesSet.size ) + assert(createdResourcesSet[0].second is Deployment) + assert(createdResourcesSet[1].second is ConfigMap) + } + + @Test + fun testFileIsSet(){ + val resourceBuilder = DeploymentBuilder() + resourceBuilder.withNewSpec().endSpec() + resourceBuilder.withNewMetadata().endMetadata() + val resource = resourceBuilder.build() + resource.metadata.name = "test-deployment" + + val resourceBuilder1 = ConfigMapBuilder() + resourceBuilder1.withNewMetadata().endMetadata() + val resource1 = resourceBuilder1.build() + resource1.metadata.name = "test-configmap" + + val configMap1 = ConfigMapBuilder() + .withNewMetadata().withName("test-configmap").endMetadata() + .addToData("test-deployment.yaml",Gson().toJson(resource)) + .addToData("test-configmap.yaml",Gson().toJson(resource1)) + .build() + + server.client.configMaps().createOrReplace(configMap1) + + val resourceSet = ConfigMapResourceSet() + resourceSet.configmap = "test-configmap" + resourceSet.files = listOf("test-deployment.yaml") + + val createdResourcesSet = resourceSet.getResourceSet(server.client) + + assertEquals(1,createdResourcesSet.size ) + assert(createdResourcesSet[0].second is Deployment) + } + + + @Test() + fun testConfigMapNotExist() { + val resourceSet = ConfigMapResourceSet() + resourceSet.configmap = "test-configmap1" + lateinit var ex: Exception + try { + resourceSet.getResourceSet(server.client) + } catch (e: Exception) { + println(e) + ex = e + } + assertTrue(ex is DeploymentFailedException) + } +} \ 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 new file mode 100644 index 0000000000000000000000000000000000000000..1c92b9b5498f064b8216185451072afe9718180f --- /dev/null +++ b/theodolite/src/test/kotlin/theodolite/benchmark/FileSystemResourceSetTest.kt @@ -0,0 +1,115 @@ +package theodolite.benchmark + +import io.fabric8.kubernetes.api.model.ConfigMap +import io.fabric8.kubernetes.api.model.Service +import io.fabric8.kubernetes.api.model.apps.Deployment +import io.fabric8.kubernetes.api.model.apps.StatefulSet +import io.fabric8.kubernetes.client.server.mock.KubernetesServer +import io.smallrye.common.constraint.Assert.assertTrue +import junit.framework.Assert.assertEquals +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import theodolite.k8s.CustomResourceWrapper +import theodolite.util.DeploymentFailedException +import java.lang.IllegalStateException + +private val testResourcePath = "./src/test/resources/k8s-resource-files/" + +class FileSystemResourceSetTest { + + private val server = KubernetesServer(false, true) + + @BeforeEach + fun setUp() { + server.before() + } + + @AfterEach + fun tearDown() { + server.after() + } + + @Test + fun testLoadDeployment() { + val resourceSet = FileSystemResourceSet() + resourceSet.path = testResourcePath + resourceSet.files = listOf("test-deployment.yaml") + assertEquals(1,resourceSet.getResourceSet(server.client).size) + assertTrue(resourceSet.getResourceSet(server.client)[0].second is Deployment) + } + + @Test + fun testLoadService() { + val resourceSet = FileSystemResourceSet() + resourceSet.path = testResourcePath + resourceSet.files = listOf("test-service.yaml") + assertEquals(1,resourceSet.getResourceSet(server.client).size) + assertTrue(resourceSet.getResourceSet(server.client)[0].second is Service) + } + + @Test + fun testLoadStatefulSet() { + val resourceSet = FileSystemResourceSet() + resourceSet.path = testResourcePath + resourceSet.files = listOf("test-statefulset.yaml") + assertEquals(1,resourceSet.getResourceSet(server.client).size) + assertTrue(resourceSet.getResourceSet(server.client)[0].second is StatefulSet) + } + + @Test + fun testLoadConfigMap() { + val resourceSet = FileSystemResourceSet() + resourceSet.path = testResourcePath + resourceSet.files = listOf("test-configmap.yaml") + assertEquals(1,resourceSet.getResourceSet(server.client).size) + assertTrue(resourceSet.getResourceSet(server.client)[0].second is ConfigMap) + } + + @Test + fun testLoadServiceMonitor() { + val resourceSet = FileSystemResourceSet() + resourceSet.path = testResourcePath + resourceSet.files = listOf("test-service-monitor.yaml") + assertEquals(1,resourceSet.getResourceSet(server.client).size) + assertTrue(resourceSet.getResourceSet(server.client)[0].second is CustomResourceWrapper) + } + + @Test + fun testLoadBenchmark() { + val resourceSet = FileSystemResourceSet() + resourceSet.path = testResourcePath + resourceSet.files = listOf("test-benchmark.yaml") + assertEquals(1,resourceSet.getResourceSet(server.client).size) + assertTrue(resourceSet.getResourceSet(server.client)[0].second is CustomResourceWrapper) + } + + @Test + fun testLoadExecution() { + val resourceSet = FileSystemResourceSet() + resourceSet.path = testResourcePath + resourceSet.files = listOf("test-execution.yaml") + assertEquals(1,resourceSet.getResourceSet(server.client).size) + assertTrue(resourceSet.getResourceSet(server.client)[0].second is CustomResourceWrapper) + } + + @Test + fun testFilesNotSet() { + val resourceSet = FileSystemResourceSet() + resourceSet.path = testResourcePath + assertEquals(9,resourceSet.getResourceSet(server.client).size) + } + + @Test + fun testWrongPath() { + val resourceSet = FileSystemResourceSet() + resourceSet.path = "/abc/not-exist" + lateinit var ex: Exception + try { + resourceSet.getResourceSet(server.client) + } catch (e: Exception) { + println(e) + ex = e + } + assertTrue(ex is DeploymentFailedException) } +} \ No newline at end of file diff --git a/theodolite/src/test/kotlin/theodolite/benchmark/bugReport.kt b/theodolite/src/test/kotlin/theodolite/benchmark/bugReport.kt new file mode 100644 index 0000000000000000000000000000000000000000..69a30a5a46c0c839453726363182c115282c5d7d --- /dev/null +++ b/theodolite/src/test/kotlin/theodolite/benchmark/bugReport.kt @@ -0,0 +1,37 @@ +package theodolite.benchmark + +import io.fabric8.kubernetes.api.model.apps.DeploymentBuilder +import io.fabric8.kubernetes.client.server.mock.KubernetesServer +import io.quarkus.test.junit.QuarkusTest +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import java.io.ByteArrayInputStream + +@QuarkusTest +class bugReport { + + private val server = KubernetesServer(false, true) + + @BeforeEach + fun setUp() { + server.before() + } + + @AfterEach + fun tearDown() { + server.after() + } + + @OptIn(ExperimentalStdlibApi::class) + @Test + fun method() { + + val deploymentString = "{\"apiVersion\":\"apps/v1\",\"kind\":\"Deployment\",\"metadata\":{\"finalizers\":[],\"managedFields\":[],\"ownerReferences\":[],\"additionalProperties\":{}},\"spec\":{\"additionalProperties\":{}},\"additionalProperties\":{}}\n" + val stream = ByteArrayInputStream(deploymentString.encodeToByteArray()) + val deployment = server.client.apps().deployments().load(stream).get() + println(deploymentString) + println(deployment) + + } +} \ No newline at end of file diff --git a/theodolite/src/test/resources/k8s-resource-files/test-execution-1.yaml b/theodolite/src/test/resources/k8s-resource-files/test-execution-1.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1407a9952b7454053d204454841d51cfb4d7dbf4 --- /dev/null +++ b/theodolite/src/test/resources/k8s-resource-files/test-execution-1.yaml @@ -0,0 +1,28 @@ +apiVersion: theodolite.com/v1 +kind: Execution +metadata: + name: example-execution +spec: + name: test + benchmark: "uc1-kstreams" + load: + loadType: "NumSensors" + loadValues: [25000, 50000, 75000, 100000, 125000, 150000] + resources: + resourceType: "Instances" + resourceValues: [1, 2, 3, 4, 5] + slos: + - sloType: "lag trend" + threshold: 2000 + prometheusUrl: "http://prometheus-operated:9090" + externalSloUrl: "http://localhost:80/evaluate-slope" + offset: 0 + warmup: 60 # in seconds + execution: + strategy: "LinearSearch" + duration: 300 # in seconds + repetitions: 1 + loadGenerationDelay: 30 # in seconds + restrictions: + - "LowerBound" + configOverrides: []