diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt b/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt index 6857b9bf8918593dbe5085f40eb28fd8bd809d85..272da07e9f8edab6200dea47725b65829178d9bc 100644 --- a/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt +++ b/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt @@ -8,6 +8,7 @@ import io.fabric8.kubernetes.client.NamespacedKubernetesClient import io.quarkus.runtime.annotations.RegisterForReflection import mu.KotlinLogging import theodolite.k8s.K8sManager +import theodolite.patcher.PatchHandler import theodolite.patcher.PatcherFactory import theodolite.util.* @@ -21,13 +22,13 @@ private var DEFAULT_THEODOLITE_APP_RESOURCES = "./benchmark-resources" * Represents a benchmark in Kubernetes. An example for this is the BenchmarkType.yaml * Contains a of: * - [name] of the benchmark, - * - [appResource] list of the resources that have to be deployed for the benchmark, - * - [loadGenResource] resource that generates the load, + * - [infrastructure] resources that have to be deployed for the benchmark infrastructure + * - [sut] list of the resources that have to be deployed for the benchmark, + * - [loadGenerator] resource that generates the load, * - [resourceTypes] types of scaling resources, * - [loadTypes] types of loads that can be scaled for the benchmark, * - [kafkaConfig] for the [theodolite.k8s.TopicManager], * - [namespace] for the client, - * - [path] under which the resource yamls can be found. * * This class is used for the parsing(in the [theodolite.execution.TheodoliteStandalone]) and * for the deserializing in the [theodolite.execution.operator.TheodoliteOperator]. @@ -65,6 +66,7 @@ class KubernetesBenchmark : KubernetesResource, Benchmark { override fun setupInfrastructure() { this.infrastructure.beforeActions.forEach { it.exec(client = client) } val kubernetesManager = K8sManager(this.client) + loadResources(this.infrastructure.resources) .map { it.second } .forEach { kubernetesManager.deploy(it) } @@ -72,6 +74,7 @@ class KubernetesBenchmark : KubernetesResource, Benchmark { override fun teardownInfrastructure() { val kubernetesManager = K8sManager(this.client) + loadResources(this.infrastructure.resources) .map { it.second } .forEach { kubernetesManager.remove(it) } @@ -92,27 +95,33 @@ class KubernetesBenchmark : KubernetesResource, Benchmark { res: Resource, configurationOverrides: List<ConfigurationOverride?>, loadGenerationDelay: Long, - afterTeardownDelay: Long + afterTeardownDelay: Long, ): BenchmarkDeployment { logger.info { "Using $namespace as namespace." } - val appResources = loadResources(this.sut.resources) - val loadGenResources = loadResources(this.loadGenerator.resources) - val patcherFactory = PatcherFactory() + val appResources = loadResources(this.sut.resources).toResourceMap() + val loadGenResources = loadResources(this.loadGenerator.resources).toResourceMap() - // patch the load dimension the resources load.getType().forEach { patcherDefinition -> - patcherFactory.createPatcher(patcherDefinition, loadGenResources).patch(load.get().toString()) + loadGenResources[patcherDefinition.resource] = + PatchHandler.patchResource(loadGenResources, patcherDefinition, load.get().toString()) } + res.getType().forEach { patcherDefinition -> - patcherFactory.createPatcher(patcherDefinition, appResources).patch(res.get().toString()) + appResources[patcherDefinition.resource] = + PatchHandler.patchResource(appResources, patcherDefinition, res.get().toString()) } - // Patch the given overrides configurationOverrides.forEach { override -> override?.let { - patcherFactory.createPatcher(it.patcher, appResources + loadGenResources).patch(override.value) + if (appResources.keys.contains(it.patcher.resource)) { + appResources[it.patcher.resource] = + PatchHandler.patchResource(appResources, override.patcher, override.value) + } else { + loadGenResources[it.patcher.resource] = + PatchHandler.patchResource(loadGenResources, override.patcher, override.value) + } } } @@ -123,8 +132,8 @@ class KubernetesBenchmark : KubernetesResource, Benchmark { sutAfterActions = sut.afterActions, loadGenBeforeActions = loadGenerator.beforeActions, loadGenAfterActions = loadGenerator.afterActions, - appResources = appResources.map { it.second }, - loadGenResources = loadGenResources.map { it.second }, + appResources = appResources.toList().flatMap { it.second }, + loadGenResources = loadGenResources.toList().flatMap { it.second }, loadGenerationDelay = loadGenerationDelay, afterTeardownDelay = afterTeardownDelay, kafkaConfig = if (kafkaConfig != null) mapOf("bootstrap.servers" to kafkaConfig.bootstrapServer) else mapOf(), @@ -142,3 +151,11 @@ class KubernetesBenchmark : KubernetesResource, Benchmark { this.client = client } } + +private fun Collection<Pair<String, HasMetadata>>.toResourceMap(): MutableMap<String, List<HasMetadata>> { + return this.toMap() + .toMutableMap() + .map { Pair(it.key, listOf(it.value)) } + .toMap() + .toMutableMap() +} diff --git a/theodolite/src/main/kotlin/theodolite/patcher/AbstractPatcher.kt b/theodolite/src/main/kotlin/theodolite/patcher/AbstractPatcher.kt index df80e9cbd2503685a7dbed35db5319920dfc42cb..1d9425410cadf2fe5015eaec91e6116050feed7c 100644 --- a/theodolite/src/main/kotlin/theodolite/patcher/AbstractPatcher.kt +++ b/theodolite/src/main/kotlin/theodolite/patcher/AbstractPatcher.kt @@ -1,6 +1,8 @@ package theodolite.patcher +import io.fabric8.kubernetes.api.model.HasMetadata import io.fabric8.kubernetes.api.model.KubernetesResource +import io.fabric8.kubernetes.client.utils.Serialization /** * A Patcher is able to modify values of a Kubernetes resource, see [Patcher]. @@ -19,6 +21,14 @@ import io.fabric8.kubernetes.api.model.KubernetesResource * variableName: `NUM_SENSORS` * */ -abstract class AbstractPatcher( - k8sResource: KubernetesResource -) : Patcher +abstract class AbstractPatcher : Patcher { + + override fun patch(resources: List<HasMetadata>, value: String) : List<HasMetadata> { + return resources + .map { Serialization.clone(it)} + .map { patchSingeResource(it, value) } + } + + abstract fun patchSingeResource(resource: HasMetadata, value: String): HasMetadata + +} \ No newline at end of file diff --git a/theodolite/src/main/kotlin/theodolite/patcher/DataVolumeLoadGeneratorReplicaPatcher.kt b/theodolite/src/main/kotlin/theodolite/patcher/DataVolumeLoadGeneratorReplicaPatcher.kt index bdc107910edc8ddfb41e7757c775977086a25a26..2eb047467303cda9e00a1d5265db373bab338e42 100644 --- a/theodolite/src/main/kotlin/theodolite/patcher/DataVolumeLoadGeneratorReplicaPatcher.kt +++ b/theodolite/src/main/kotlin/theodolite/patcher/DataVolumeLoadGeneratorReplicaPatcher.kt @@ -1,5 +1,6 @@ package theodolite.patcher +import io.fabric8.kubernetes.api.model.HasMetadata import io.fabric8.kubernetes.api.model.KubernetesResource /** @@ -16,23 +17,24 @@ import io.fabric8.kubernetes.api.model.KubernetesResource * @property variableName Name of the environment variable to be patched. */ class DataVolumeLoadGeneratorReplicaPatcher( - k8sResource: KubernetesResource, private val maxVolume: Int, - container: String, - variableName: String -) : AbstractPatcher(k8sResource) { + private val container: String, + private val variableName: String +) : Patcher { - private val replicaPatcher = ReplicaPatcher(k8sResource) - private val envVarPatcher = EnvVarPatcher(k8sResource, container, variableName) + override fun patch(resources: List<HasMetadata>, value: String) : List<HasMetadata> { + return resources.flatMap { patchSingeResource(it, value)} + } - override fun <T> patch(value: T) { + fun patchSingeResource(k8sResource: HasMetadata, value: String): List<HasMetadata> { + var resource = k8sResource // calculate number of load generator instances and load per instance - val load = Integer.parseInt(value.toString()) + val load = Integer.parseInt(value) val loadGenInstances = (load + maxVolume - 1) / maxVolume val loadPerInstance = load / loadGenInstances // Patch instance values and load value of generators - replicaPatcher.patch(loadGenInstances.toString()) - envVarPatcher.patch(loadPerInstance.toString()) + val resourceList = ReplicaPatcher().patch(listOf(resource), loadGenInstances.toString()) + return EnvVarPatcher(this.container, this.variableName).patch(resourceList, loadPerInstance.toString()) } } diff --git a/theodolite/src/main/kotlin/theodolite/patcher/EnvVarPatcher.kt b/theodolite/src/main/kotlin/theodolite/patcher/EnvVarPatcher.kt index 416aec74a3af9b74594f5e6cd018682bf91cbf63..d1f8778d77d801854dd9f4672d6cf5801558e68f 100644 --- a/theodolite/src/main/kotlin/theodolite/patcher/EnvVarPatcher.kt +++ b/theodolite/src/main/kotlin/theodolite/patcher/EnvVarPatcher.kt @@ -2,8 +2,10 @@ package theodolite.patcher import io.fabric8.kubernetes.api.model.Container import io.fabric8.kubernetes.api.model.EnvVar +import io.fabric8.kubernetes.api.model.HasMetadata import io.fabric8.kubernetes.api.model.KubernetesResource import io.fabric8.kubernetes.api.model.apps.Deployment +import io.fabric8.kubernetes.client.utils.Serialization /** * The EnvVarPatcher allows to modify the value of an environment variable @@ -13,18 +15,20 @@ import io.fabric8.kubernetes.api.model.apps.Deployment * @property variableName Name of the environment variable to be patched. */ class EnvVarPatcher( - private val k8sResource: KubernetesResource, private val container: String, private val variableName: String -) : AbstractPatcher(k8sResource) { +) : AbstractPatcher() { - override fun <String> patch(value: String) { - if (k8sResource is Deployment) { + + override fun patchSingeResource(resource: HasMetadata, value: String): HasMetadata { + if (resource is Deployment) { this.setEnv( - k8sResource, this.container, - mapOf(this.variableName to value) as Map<kotlin.String, kotlin.String> + resource, this.container, + mapOf(this.variableName to value) ) + return resource } + return resource } /** diff --git a/theodolite/src/main/kotlin/theodolite/patcher/ImagePatcher.kt b/theodolite/src/main/kotlin/theodolite/patcher/ImagePatcher.kt index 8f6753372076c119324dc962112928253633b6b0..8997ac2d3bb3037ab555db1b85bc4874d9dc0ec1 100644 --- a/theodolite/src/main/kotlin/theodolite/patcher/ImagePatcher.kt +++ b/theodolite/src/main/kotlin/theodolite/patcher/ImagePatcher.kt @@ -1,8 +1,10 @@ package theodolite.patcher +import io.fabric8.kubernetes.api.model.HasMetadata import io.fabric8.kubernetes.api.model.KubernetesResource import io.fabric8.kubernetes.api.model.apps.Deployment import io.fabric8.kubernetes.api.model.apps.StatefulSet +import io.fabric8.kubernetes.client.utils.Serialization /** * The Image patcher allows to change the image of a container. @@ -10,18 +12,28 @@ import io.fabric8.kubernetes.api.model.apps.StatefulSet * @param k8sResource Kubernetes resource to be patched. * @param container Container to be patched. */ -class ImagePatcher(private val k8sResource: KubernetesResource, private val container: String) : - AbstractPatcher(k8sResource) { +class ImagePatcher( + private val container: String) : + AbstractPatcher() { - override fun <String> patch(imagePath: String) { - if (k8sResource is Deployment) { - k8sResource.spec.template.spec.containers.filter { it.name == container }.forEach { - it.image = imagePath as kotlin.String + override fun patch(resources: List<HasMetadata>, value: String) : List<HasMetadata> { + return resources + .map { Serialization.clone(it) } + .map { patchSingeResource(it, value as kotlin.String) } + } + + override fun patchSingeResource(resource: HasMetadata, value: String): HasMetadata { + if (resource is Deployment) { + (resource).spec.template.spec.containers.filter { it.name == container }.forEach { + it.image = value } - } else if (k8sResource is StatefulSet) { - k8sResource.spec.template.spec.containers.filter { it.name == container }.forEach { - it.image = imagePath as kotlin.String + return resource + } else if (resource is StatefulSet) { + (resource).spec.template.spec.containers.filter { it.name == container }.forEach { + it.image = value } + return resource } + return resource } } diff --git a/theodolite/src/main/kotlin/theodolite/patcher/LabelPatcher.kt b/theodolite/src/main/kotlin/theodolite/patcher/LabelPatcher.kt index 2f8c703afa9e826a79f0785abef493d2d448ac74..2639cadc3cd917dab9dee0d27ac1a55b6006352e 100644 --- a/theodolite/src/main/kotlin/theodolite/patcher/LabelPatcher.kt +++ b/theodolite/src/main/kotlin/theodolite/patcher/LabelPatcher.kt @@ -1,49 +1,52 @@ package theodolite.patcher import io.fabric8.kubernetes.api.model.ConfigMap +import io.fabric8.kubernetes.api.model.HasMetadata import io.fabric8.kubernetes.api.model.KubernetesResource 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.CustomResource +import io.fabric8.kubernetes.client.utils.Serialization -class LabelPatcher(private val k8sResource: KubernetesResource, val variableName: String) : - AbstractPatcher(k8sResource) { +class LabelPatcher( + val variableName: String) : + AbstractPatcher() { - override fun <String> patch(labelValue: String) { - if (labelValue is kotlin.String) { - when (k8sResource) { - is Deployment -> { - if (k8sResource.metadata.labels == null) { - k8sResource.metadata.labels = mutableMapOf() - } - k8sResource.metadata.labels[this.variableName] = labelValue + override fun patchSingeResource(resource: HasMetadata, value: String): HasMetadata { + when (resource) { + is Deployment -> { + if (resource.metadata.labels == null) { + resource.metadata.labels = mutableMapOf() } - is StatefulSet -> { - if (k8sResource.metadata.labels == null) { - k8sResource.metadata.labels = mutableMapOf() - } - k8sResource.metadata.labels[this.variableName] = labelValue + resource.metadata.labels[this.variableName] = value + } + is StatefulSet -> { + if (resource.metadata.labels == null) { + resource.metadata.labels = mutableMapOf() } - is Service -> { - if (k8sResource.metadata.labels == null) { - k8sResource.metadata.labels = mutableMapOf() - } - k8sResource.metadata.labels[this.variableName] = labelValue + resource.metadata.labels[this.variableName] = value + } + is Service -> { + if (resource.metadata.labels == null) { + resource.metadata.labels = mutableMapOf() } - is ConfigMap -> { - if (k8sResource.metadata.labels == null) { - k8sResource.metadata.labels = mutableMapOf() - } - k8sResource.metadata.labels[this.variableName] = labelValue + resource.metadata.labels[this.variableName] = value + + } + is ConfigMap -> { + if (resource.metadata.labels == null) { + resource.metadata.labels = mutableMapOf() } - is CustomResource<*, *> -> { - if (k8sResource.metadata.labels == null) { - k8sResource.metadata.labels = mutableMapOf() - } - k8sResource.metadata.labels[this.variableName] = labelValue + resource.metadata.labels[this.variableName] = value + } + is CustomResource<*, *> -> { + if (resource.metadata.labels == null) { + resource.metadata.labels = mutableMapOf() } + resource.metadata.labels[this.variableName] = value } } + return resource } } \ No newline at end of file diff --git a/theodolite/src/main/kotlin/theodolite/patcher/MatchLabelPatcher.kt b/theodolite/src/main/kotlin/theodolite/patcher/MatchLabelPatcher.kt index 30ff73b5da3b551119ad085adbc982180e4fc066..9da00cd9a1658110fb0dc09fccfb0d622c392253 100644 --- a/theodolite/src/main/kotlin/theodolite/patcher/MatchLabelPatcher.kt +++ b/theodolite/src/main/kotlin/theodolite/patcher/MatchLabelPatcher.kt @@ -1,8 +1,10 @@ package theodolite.patcher +import io.fabric8.kubernetes.api.model.HasMetadata import io.fabric8.kubernetes.api.model.KubernetesResource import io.fabric8.kubernetes.api.model.apps.Deployment import io.fabric8.kubernetes.api.model.apps.StatefulSet +import io.fabric8.kubernetes.client.utils.Serialization /** * This patcher is able to set the `spec.selector.matchLabels` for a `Deployment` or `StatefulSet` Kubernetes resource. @@ -10,25 +12,25 @@ import io.fabric8.kubernetes.api.model.apps.StatefulSet * @property k8sResource The Kubernetes manifests to patch * @property variableName The matchLabel which should be set */ -class MatchLabelPatcher(private val k8sResource: KubernetesResource, val variableName: String) : - AbstractPatcher(k8sResource) { +class MatchLabelPatcher( + val variableName: String) : + AbstractPatcher() { - override fun <String> patch(labelValue: String) { - if (labelValue is kotlin.String) { - when (k8sResource) { - is Deployment -> { - if (k8sResource.spec.selector.matchLabels == null) { - k8sResource.spec.selector.matchLabels = mutableMapOf() - } - k8sResource.spec.selector.matchLabels[this.variableName] = labelValue + override fun patchSingeResource(resource: HasMetadata, value: String): HasMetadata { + when (resource) { + is Deployment -> { + if (resource.spec.selector.matchLabels == null) { + resource.spec.selector.matchLabels = mutableMapOf() } - is StatefulSet -> { - if (k8sResource.spec.selector.matchLabels == null) { - k8sResource.spec.selector.matchLabels = mutableMapOf() - } - k8sResource.spec.selector.matchLabels[this.variableName] = labelValue + resource.spec.selector.matchLabels[this.variableName] = value + } + is StatefulSet -> { + if (resource.spec.selector.matchLabels == null) { + resource.spec.selector.matchLabels = mutableMapOf() } + resource.spec.selector.matchLabels[this.variableName] = value } } + return resource } } \ No newline at end of file diff --git a/theodolite/src/main/kotlin/theodolite/patcher/NamePatcher.kt b/theodolite/src/main/kotlin/theodolite/patcher/NamePatcher.kt new file mode 100644 index 0000000000000000000000000000000000000000..e703c38c06ccdf6f359dfb44bd46402fc4a18bff --- /dev/null +++ b/theodolite/src/main/kotlin/theodolite/patcher/NamePatcher.kt @@ -0,0 +1,38 @@ +package theodolite.patcher + +import io.fabric8.kubernetes.api.model.ConfigMap +import io.fabric8.kubernetes.api.model.HasMetadata +import io.fabric8.kubernetes.api.model.KubernetesResource +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.CustomResource +import io.fabric8.kubernetes.client.utils.Serialization + +class NamePatcher : AbstractPatcher() { + + override fun patchSingeResource(resource: HasMetadata, value: String): HasMetadata { + when (resource) { + is Deployment -> { + resource.metadata.name = value + } + is StatefulSet -> { + resource.metadata.name = value + } + is Service -> { + resource.metadata.name = value + } + is ConfigMap -> { + resource.metadata.name = value + } + is io.fabric8.kubernetes.api.model.networking.v1.Ingress -> { + resource.metadata.name = value + } + is CustomResource<*, *> -> { + // TODO(How to clone custom resources?) + resource.metadata.name = value + } + } + return resource + } +} \ No newline at end of file diff --git a/theodolite/src/main/kotlin/theodolite/patcher/NodeSelectorPatcher.kt b/theodolite/src/main/kotlin/theodolite/patcher/NodeSelectorPatcher.kt index 0e8cd553a6c6a9ed6fa2c8cc1b84e4cfebe79d73..4743ca6058cafe275db59b2fa931d50e89bcf791 100644 --- a/theodolite/src/main/kotlin/theodolite/patcher/NodeSelectorPatcher.kt +++ b/theodolite/src/main/kotlin/theodolite/patcher/NodeSelectorPatcher.kt @@ -1,7 +1,9 @@ package theodolite.patcher +import io.fabric8.kubernetes.api.model.HasMetadata import io.fabric8.kubernetes.api.model.KubernetesResource import io.fabric8.kubernetes.api.model.apps.Deployment +import io.fabric8.kubernetes.client.utils.Serialization /** * The Node selector patcher make it possible to set the NodeSelector of a Kubernetes deployment. @@ -9,11 +11,15 @@ import io.fabric8.kubernetes.api.model.apps.Deployment * @param k8sResource Kubernetes resource to be patched. * @param variableName The `label-key` of the node for which the `label-value` is to be patched. */ -class NodeSelectorPatcher(private val k8sResource: KubernetesResource, private val variableName: String) : - AbstractPatcher(k8sResource) { - override fun <String> patch(value: String) { - if (k8sResource is Deployment) { - k8sResource.spec.template.spec.nodeSelector = mapOf(variableName to value as kotlin.String) +class NodeSelectorPatcher( + private val variableName: String) : + AbstractPatcher() { + + + override fun patchSingeResource(resource: HasMetadata, value: String): HasMetadata { + if (resource is Deployment) { + resource.spec.template.spec.nodeSelector = mapOf(variableName to value) } + return resource } } diff --git a/theodolite/src/main/kotlin/theodolite/patcher/NumNestedGroupsLoadGeneratorReplicaPatcher.kt b/theodolite/src/main/kotlin/theodolite/patcher/NumNestedGroupsLoadGeneratorReplicaPatcher.kt index c617917e6894c3a30779dd4257a96365ded35481..f35bd6a1a3aeacea5dfc417cb0e5c20ff227681c 100644 --- a/theodolite/src/main/kotlin/theodolite/patcher/NumNestedGroupsLoadGeneratorReplicaPatcher.kt +++ b/theodolite/src/main/kotlin/theodolite/patcher/NumNestedGroupsLoadGeneratorReplicaPatcher.kt @@ -1,23 +1,25 @@ package theodolite.patcher +import io.fabric8.kubernetes.api.model.HasMetadata import io.fabric8.kubernetes.api.model.KubernetesResource import io.fabric8.kubernetes.api.model.apps.Deployment +import io.fabric8.kubernetes.client.utils.Serialization import kotlin.math.pow class NumNestedGroupsLoadGeneratorReplicaPatcher( - private val k8sResource: KubernetesResource, private val numSensors: String, - private val loadGenMaxRecords: String -) : - AbstractPatcher(k8sResource) { - override fun <String> patch(value: String) { - if (k8sResource is Deployment) { - if (value is kotlin.String) { - val approxNumSensors = numSensors.toDouble().pow(Integer.parseInt(value).toDouble()) - val loadGenInstances = - (approxNumSensors + loadGenMaxRecords.toDouble() - 1) / loadGenMaxRecords.toDouble() - this.k8sResource.spec.replicas = loadGenInstances.toInt() - } + private val loadGenMaxRecords: String, +) : AbstractPatcher() { + + override fun patchSingeResource(resource: HasMetadata, value: String): HasMetadata { + if (resource is Deployment) { + val approxNumSensors = numSensors.toDouble().pow(Integer.parseInt(value).toDouble()) + val loadGenInstances = + (approxNumSensors + loadGenMaxRecords.toDouble() - 1) / loadGenMaxRecords.toDouble() + resource.spec.replicas = loadGenInstances.toInt() + } + return resource } } + diff --git a/theodolite/src/main/kotlin/theodolite/patcher/NumSensorsLoadGeneratorReplicaPatcher.kt b/theodolite/src/main/kotlin/theodolite/patcher/NumSensorsLoadGeneratorReplicaPatcher.kt index 86bb37db3cb9fd0d3bca1690d5eb4e622329a9bc..81a30d6194d258a1d3e706c59301588990922842 100644 --- a/theodolite/src/main/kotlin/theodolite/patcher/NumSensorsLoadGeneratorReplicaPatcher.kt +++ b/theodolite/src/main/kotlin/theodolite/patcher/NumSensorsLoadGeneratorReplicaPatcher.kt @@ -1,21 +1,23 @@ package theodolite.patcher +import io.fabric8.kubernetes.api.model.HasMetadata import io.fabric8.kubernetes.api.model.KubernetesResource import io.fabric8.kubernetes.api.model.apps.Deployment +import io.fabric8.kubernetes.client.utils.Serialization class NumSensorsLoadGeneratorReplicaPatcher( - private val k8sResource: KubernetesResource, - private val loadGenMaxRecords: String -) : - AbstractPatcher(k8sResource) { - override fun <String> patch(value: String) { - if (k8sResource is Deployment) { - if (value is kotlin.String) { - val loadGenInstances = - (Integer.parseInt(value) + loadGenMaxRecords.toInt() - 1) / loadGenMaxRecords.toInt() - this.k8sResource.spec.replicas = loadGenInstances - } + private val loadGenMaxRecords: String, +) : AbstractPatcher() { + + override fun patchSingeResource(resource: HasMetadata, value: String): HasMetadata { + if (resource is Deployment) { + val loadGenInstances = + (Integer.parseInt(value) + loadGenMaxRecords.toInt() - 1) / loadGenMaxRecords.toInt() + resource.spec.replicas = loadGenInstances + } + return resource } + } diff --git a/theodolite/src/main/kotlin/theodolite/patcher/PatchHandler.kt b/theodolite/src/main/kotlin/theodolite/patcher/PatchHandler.kt new file mode 100644 index 0000000000000000000000000000000000000000..73f2f2435b42c59a1b0a294c67bbd0c726ffc209 --- /dev/null +++ b/theodolite/src/main/kotlin/theodolite/patcher/PatchHandler.kt @@ -0,0 +1,26 @@ +package theodolite.patcher + +import io.fabric8.kubernetes.api.model.HasMetadata +import theodolite.util.InvalidPatcherConfigurationException +import theodolite.util.PatcherDefinition + +class PatchHandler { + + companion object { + + private fun getResourcesToPatch(resources: MutableMap<String, List<HasMetadata>>, patcherDefinition: PatcherDefinition): List<HasMetadata> { + return resources[patcherDefinition.resource] + ?: throw InvalidPatcherConfigurationException("Could not find resource ${patcherDefinition.resource}") + + } + + fun patchResource( + resources: MutableMap<String, List<HasMetadata>>, + patcherDefinition: PatcherDefinition, + value: String, + ): List<HasMetadata> { + val resToPatch = getResourcesToPatch(resources, patcherDefinition) + return PatcherFactory.createPatcher(patcherDefinition).patch(resToPatch,value) + } + } +} \ No newline at end of file diff --git a/theodolite/src/main/kotlin/theodolite/patcher/Patcher.kt b/theodolite/src/main/kotlin/theodolite/patcher/Patcher.kt index 84b886cb4f06b3e667eb8b8aeaa622e1ee54852e..bf6b75fdcf0010e33ba6fe683eb85fe5152196f3 100644 --- a/theodolite/src/main/kotlin/theodolite/patcher/Patcher.kt +++ b/theodolite/src/main/kotlin/theodolite/patcher/Patcher.kt @@ -1,5 +1,7 @@ package theodolite.patcher +import io.fabric8.kubernetes.api.model.HasMetadata +import io.fabric8.kubernetes.api.model.KubernetesResource import io.quarkus.runtime.annotations.RegisterForReflection /** @@ -16,5 +18,5 @@ interface Patcher { * @param T The type of value * @param value The value to be used. */ - fun <T> patch(value: T) + fun patch(resources: List<HasMetadata>, value: String) : List<HasMetadata> } diff --git a/theodolite/src/main/kotlin/theodolite/patcher/PatcherFactory.kt b/theodolite/src/main/kotlin/theodolite/patcher/PatcherFactory.kt index e92de4dba7de298c9df76600f2c6785f5878103e..b92249897b18881424d1728eb4cdc99de7576a5a 100644 --- a/theodolite/src/main/kotlin/theodolite/patcher/PatcherFactory.kt +++ b/theodolite/src/main/kotlin/theodolite/patcher/PatcherFactory.kt @@ -1,5 +1,6 @@ package theodolite.patcher +import io.fabric8.kubernetes.api.model.HasMetadata import io.fabric8.kubernetes.api.model.KubernetesResource import theodolite.util.InvalidPatcherConfigurationException import theodolite.util.PatcherDefinition @@ -10,94 +11,84 @@ import theodolite.util.PatcherDefinition * @constructor Creates an empty PatcherFactory. */ class PatcherFactory { - /** - * Create patcher based on the given [PatcherDefinition] and - * the list of KubernetesResources. - * - * @param patcherDefinition The [PatcherDefinition] for which are - * [Patcher] should be created. - * @param k8sResources List of all available Kubernetes resources. - * This is a list of pairs<String, KubernetesResource>: - * The frist corresponds to the filename where the resource is defined. - * The second corresponds to the concrete [KubernetesResource] that should be patched. - * @return The created [Patcher]. - * @throws IllegalArgumentException if no patcher can be created. - */ - fun createPatcher( - patcherDefinition: PatcherDefinition, - k8sResources: Collection<Pair<String, KubernetesResource>> - ): Patcher { - val resource = - k8sResources.filter { it.first == patcherDefinition.resource } - .map { resource -> resource.second } - .firstOrNull() - ?: throw InvalidPatcherConfigurationException("Could not find resource ${patcherDefinition.resource}") - return try { - when (patcherDefinition.type) { - "ReplicaPatcher" -> ReplicaPatcher( - k8sResource = resource - ) - "NumNestedGroupsLoadGeneratorReplicaPatcher" -> NumNestedGroupsLoadGeneratorReplicaPatcher( - k8sResource = resource, - loadGenMaxRecords = patcherDefinition.properties["loadGenMaxRecords"]!!, - numSensors = patcherDefinition.properties["numSensors"]!! - ) - "NumSensorsLoadGeneratorReplicaPatcher" -> NumSensorsLoadGeneratorReplicaPatcher( - k8sResource = resource, - loadGenMaxRecords = patcherDefinition.properties["loadGenMaxRecords"]!! - ) - "DataVolumeLoadGeneratorReplicaPatcher" -> DataVolumeLoadGeneratorReplicaPatcher( - k8sResource = resource, - maxVolume = patcherDefinition.properties["maxVolume"]!!.toInt(), - container = patcherDefinition.properties["container"]!!, - variableName = patcherDefinition.properties["variableName"]!! - ) - "EnvVarPatcher" -> EnvVarPatcher( - k8sResource = resource, - container = patcherDefinition.properties["container"]!!, - variableName = patcherDefinition.properties["variableName"]!! - ) - "NodeSelectorPatcher" -> NodeSelectorPatcher( - k8sResource = resource, - variableName = patcherDefinition.properties["variableName"]!! - ) - "ResourceLimitPatcher" -> ResourceLimitPatcher( - k8sResource = resource, - container = patcherDefinition.properties["container"]!!, - limitedResource = patcherDefinition.properties["limitedResource"]!! - ) - "ResourceRequestPatcher" -> ResourceRequestPatcher( - k8sResource = resource, - container = patcherDefinition.properties["container"]!!, - requestedResource = patcherDefinition.properties["requestedResource"]!! - ) - "SchedulerNamePatcher" -> SchedulerNamePatcher( - k8sResource = resource - ) - "LabelPatcher" -> LabelPatcher( - k8sResource = resource, - variableName = patcherDefinition.properties["variableName"]!! - ) - "MatchLabelPatcher" -> MatchLabelPatcher( - k8sResource = resource, - variableName = patcherDefinition.properties["variableName"]!! - ) - "TemplateLabelPatcher" -> TemplateLabelPatcher( - k8sResource = resource, - variableName = patcherDefinition.properties["variableName"]!! - ) - "ImagePatcher" -> ImagePatcher( - k8sResource = resource, - container = patcherDefinition.properties["container"]!! + companion object { + /** + * Create patcher based on the given [PatcherDefinition] and + * the list of KubernetesResources. + * + * @param patcherDefinition The [PatcherDefinition] for which are + * [Patcher] should be created. + * @param k8sResources List of all available Kubernetes resources. + * This is a list of pairs<String, KubernetesResource>: + * The frist corresponds to the filename where the resource is defined. + * The second corresponds to the concrete [KubernetesResource] that should be patched. + * @return The created [Patcher]. + * @throws IllegalArgumentException if no patcher can be created. + */ + fun createPatcher( + patcherDefinition: PatcherDefinition, + ): Patcher { + + return try { + when (patcherDefinition.type) { + "ReplicaPatcher" -> ReplicaPatcher( + ) + "NumNestedGroupsLoadGeneratorReplicaPatcher" -> NumNestedGroupsLoadGeneratorReplicaPatcher( + loadGenMaxRecords = patcherDefinition.properties["loadGenMaxRecords"]!!, + numSensors = patcherDefinition.properties["numSensors"]!! + ) + "NumSensorsLoadGeneratorReplicaPatcher" -> NumSensorsLoadGeneratorReplicaPatcher( + loadGenMaxRecords = patcherDefinition.properties["loadGenMaxRecords"]!! + ) + "DataVolumeLoadGeneratorReplicaPatcher" -> DataVolumeLoadGeneratorReplicaPatcher( + maxVolume = patcherDefinition.properties["maxVolume"]!!.toInt(), + container = patcherDefinition.properties["container"]!!, + variableName = patcherDefinition.properties["variableName"]!! + ) + "EnvVarPatcher" -> EnvVarPatcher( + container = patcherDefinition.properties["container"]!!, + variableName = patcherDefinition.properties["variableName"]!! + ) + "NodeSelectorPatcher" -> NodeSelectorPatcher( + variableName = patcherDefinition.properties["variableName"]!! + ) + "ResourceLimitPatcher" -> ResourceLimitPatcher( + container = patcherDefinition.properties["container"]!!, + limitedResource = patcherDefinition.properties["limitedResource"]!! + ) + "ResourceRequestPatcher" -> ResourceRequestPatcher( + container = patcherDefinition.properties["container"]!!, + requestedResource = patcherDefinition.properties["requestedResource"]!! + ) + "SchedulerNamePatcher" -> SchedulerNamePatcher() + "LabelPatcher" -> LabelPatcher( + variableName = patcherDefinition.properties["variableName"]!! + ) + "MatchLabelPatcher" -> MatchLabelPatcher( + variableName = patcherDefinition.properties["variableName"]!! + ) + "TemplateLabelPatcher" -> TemplateLabelPatcher( + variableName = patcherDefinition.properties["variableName"]!! + ) + "ImagePatcher" -> ImagePatcher( + container = patcherDefinition.properties["container"]!! + ) + "NamePatcher" -> NamePatcher() + "ServiceSelectorPatcher" -> ServiceSelectorPatcher( + variableName = patcherDefinition.properties["label"]!! + ) + "theodolite.patcher.VolumesConfigMapPatcher" -> VolumesConfigMapPatcher( + volumeName = patcherDefinition.properties["volumeName"]!! + ) + else -> throw InvalidPatcherConfigurationException("Patcher type ${patcherDefinition.type} not found.") + } + } catch (e: NullPointerException) { + throw InvalidPatcherConfigurationException( + "Could not create patcher with type ${patcherDefinition.type}" + + " Probably a required patcher argument was not specified.", e ) - else -> throw InvalidPatcherConfigurationException("Patcher type ${patcherDefinition.type} not found.") } - } catch (e: NullPointerException) { - throw InvalidPatcherConfigurationException( - "Could not create patcher with type ${patcherDefinition.type}" + - " Probably a required patcher argument was not specified.", e - ) } } } diff --git a/theodolite/src/main/kotlin/theodolite/patcher/ReplicaPatcher.kt b/theodolite/src/main/kotlin/theodolite/patcher/ReplicaPatcher.kt index 4cc35f2ed74f9e366c266c3f98f1b3d36d4ba1b8..9b273acee34ab0f2989856f859eb713ec65a121c 100644 --- a/theodolite/src/main/kotlin/theodolite/patcher/ReplicaPatcher.kt +++ b/theodolite/src/main/kotlin/theodolite/patcher/ReplicaPatcher.kt @@ -1,19 +1,20 @@ package theodolite.patcher +import io.fabric8.kubernetes.api.model.HasMetadata import io.fabric8.kubernetes.api.model.KubernetesResource import io.fabric8.kubernetes.api.model.apps.Deployment +import io.fabric8.kubernetes.client.utils.Serialization /** * The Replica [Patcher] modifies the number of replicas for the given Kubernetes deployment. * - * @param k8sResource Kubernetes resource to be patched. */ -class ReplicaPatcher(private val k8sResource: KubernetesResource) : AbstractPatcher(k8sResource) { - override fun <String> patch(value: String) { - if (k8sResource is Deployment) { - if (value is kotlin.String) { - this.k8sResource.spec.replicas = Integer.parseInt(value) - } +class ReplicaPatcher : AbstractPatcher() { + + override fun patchSingeResource(resource: HasMetadata, value: String): HasMetadata { + if (resource is Deployment) { + resource.spec.replicas = Integer.parseInt(value) } + return resource } -} +} \ No newline at end of file diff --git a/theodolite/src/main/kotlin/theodolite/patcher/ResourceLimitPatcher.kt b/theodolite/src/main/kotlin/theodolite/patcher/ResourceLimitPatcher.kt index 9dcdffa0407dd4fdaf2d9b0a898bcdf6cebe5a8b..774b080d014a9dfadbd1eec99341931c1d5e9313 100644 --- a/theodolite/src/main/kotlin/theodolite/patcher/ResourceLimitPatcher.kt +++ b/theodolite/src/main/kotlin/theodolite/patcher/ResourceLimitPatcher.kt @@ -1,11 +1,9 @@ package theodolite.patcher -import io.fabric8.kubernetes.api.model.Container -import io.fabric8.kubernetes.api.model.KubernetesResource -import io.fabric8.kubernetes.api.model.Quantity -import io.fabric8.kubernetes.api.model.ResourceRequirements +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.utils.Serialization import theodolite.util.InvalidPatcherConfigurationException /** @@ -16,30 +14,31 @@ import theodolite.util.InvalidPatcherConfigurationException * @param limitedResource The resource to be limited (e.g. **cpu or memory**) */ class ResourceLimitPatcher( - private val k8sResource: KubernetesResource, private val container: String, private val limitedResource: String -) : AbstractPatcher(k8sResource) { +) : AbstractPatcher() { - override fun <String> patch(value: String) { - when (k8sResource) { + override fun patchSingeResource(resource: HasMetadata, value: String): HasMetadata { + when (resource) { is Deployment -> { - k8sResource.spec.template.spec.containers.filter { it.name == container }.forEach { - setLimits(it, value as kotlin.String) + resource.spec.template.spec.containers.filter { it.name == container }.forEach { + setLimits(it, value) } } is StatefulSet -> { - k8sResource.spec.template.spec.containers.filter { it.name == container }.forEach { - setLimits(it, value as kotlin.String) + resource.spec.template.spec.containers.filter { it.name == container }.forEach { + setLimits(it, value) } } else -> { - throw InvalidPatcherConfigurationException("ResourceLimitPatcher not applicable for $k8sResource") + throw InvalidPatcherConfigurationException("ResourceLimitPatcher is not applicable for $resource") } } + return resource } - private fun setLimits(container: Container, value: String) { + + private fun setLimits(container: Container, value: String) { when { container.resources == null -> { val resource = ResourceRequirements() diff --git a/theodolite/src/main/kotlin/theodolite/patcher/ResourceRequestPatcher.kt b/theodolite/src/main/kotlin/theodolite/patcher/ResourceRequestPatcher.kt index 24cdde40f7f78bd67d115b2dc44f47e180f51ee2..d347fa68667797e2ac082758764a99686944ec6e 100644 --- a/theodolite/src/main/kotlin/theodolite/patcher/ResourceRequestPatcher.kt +++ b/theodolite/src/main/kotlin/theodolite/patcher/ResourceRequestPatcher.kt @@ -1,11 +1,9 @@ package theodolite.patcher -import io.fabric8.kubernetes.api.model.Container -import io.fabric8.kubernetes.api.model.KubernetesResource -import io.fabric8.kubernetes.api.model.Quantity -import io.fabric8.kubernetes.api.model.ResourceRequirements +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.utils.Serialization import theodolite.util.InvalidPatcherConfigurationException /** @@ -16,29 +14,29 @@ import theodolite.util.InvalidPatcherConfigurationException * @param requestedResource The resource to be requested (e.g. **cpu or memory**) */ class ResourceRequestPatcher( - private val k8sResource: KubernetesResource, private val container: String, private val requestedResource: String -) : AbstractPatcher(k8sResource) { +) : AbstractPatcher() { - override fun <String> patch(value: String) { - when (k8sResource) { + + override fun patchSingeResource(resource: HasMetadata, value: String): HasMetadata { + when (resource) { is Deployment -> { - k8sResource.spec.template.spec.containers.filter { it.name == container }.forEach { - setRequests(it, value as kotlin.String) + resource.spec.template.spec.containers.filter { it.name == container }.forEach { + setRequests(it, value) } } is StatefulSet -> { - k8sResource.spec.template.spec.containers.filter { it.name == container }.forEach { - setRequests(it, value as kotlin.String) + resource.spec.template.spec.containers.filter { it.name == container }.forEach { + setRequests(it, value) } } else -> { - throw InvalidPatcherConfigurationException("ResourceRequestPatcher not applicable for $k8sResource") + throw InvalidPatcherConfigurationException("ResourceRequestPatcher is not applicable for $resource") } } + return resource } - private fun setRequests(container: Container, value: String) { when { container.resources == null -> { diff --git a/theodolite/src/main/kotlin/theodolite/patcher/SchedulerNamePatcher.kt b/theodolite/src/main/kotlin/theodolite/patcher/SchedulerNamePatcher.kt index 348f0c50090a34c91221d3e099c3532375a578da..130afd8cffca5c1fd1ed6daedb34e076637d83ee 100644 --- a/theodolite/src/main/kotlin/theodolite/patcher/SchedulerNamePatcher.kt +++ b/theodolite/src/main/kotlin/theodolite/patcher/SchedulerNamePatcher.kt @@ -1,17 +1,22 @@ package theodolite.patcher +import io.fabric8.kubernetes.api.model.HasMetadata import io.fabric8.kubernetes.api.model.KubernetesResource import io.fabric8.kubernetes.api.model.apps.Deployment +import io.fabric8.kubernetes.client.utils.Serialization /** * The Scheduler name [Patcher] make it possible to set the scheduler which should * be used to deploy the given deployment. * @param k8sResource Kubernetes resource to be patched. */ -class SchedulerNamePatcher(private val k8sResource: KubernetesResource) : Patcher { - override fun <String> patch(value: String) { - if (k8sResource is Deployment) { - k8sResource.spec.template.spec.schedulerName = value as kotlin.String +class SchedulerNamePatcher : AbstractPatcher() { + + + override fun patchSingeResource(resource: HasMetadata, value: String): HasMetadata { + if (resource is Deployment) { + resource.spec.template.spec.schedulerName = value } + return resource } } diff --git a/theodolite/src/main/kotlin/theodolite/patcher/ServiceSelectorPatcher.kt b/theodolite/src/main/kotlin/theodolite/patcher/ServiceSelectorPatcher.kt new file mode 100644 index 0000000000000000000000000000000000000000..86e34a04370b908b2ff6e9d2c24a962ae4764951 --- /dev/null +++ b/theodolite/src/main/kotlin/theodolite/patcher/ServiceSelectorPatcher.kt @@ -0,0 +1,21 @@ +package theodolite.patcher + +import io.fabric8.kubernetes.api.model.HasMetadata +import io.fabric8.kubernetes.api.model.KubernetesResource +import io.fabric8.kubernetes.api.model.Service +import io.fabric8.kubernetes.client.utils.Serialization + +class ServiceSelectorPatcher( + private var variableName: String + ) : AbstractPatcher() { + + override fun patchSingeResource(resource: HasMetadata, value: String): HasMetadata { + if (resource is Service) { + if (resource.spec.selector == null) { + resource.spec.selector = mutableMapOf() + } + resource.spec.selector[this.variableName] = value + } + return resource + } + } \ No newline at end of file diff --git a/theodolite/src/main/kotlin/theodolite/patcher/TemplateLabelPatcher.kt b/theodolite/src/main/kotlin/theodolite/patcher/TemplateLabelPatcher.kt index a524e5c40f90ccf98dc95003cc33dcfceb6f8598..3b905b07e2385c465ee195b6e7f95c31728ea058 100644 --- a/theodolite/src/main/kotlin/theodolite/patcher/TemplateLabelPatcher.kt +++ b/theodolite/src/main/kotlin/theodolite/patcher/TemplateLabelPatcher.kt @@ -1,34 +1,36 @@ package theodolite.patcher +import io.fabric8.kubernetes.api.model.HasMetadata import io.fabric8.kubernetes.api.model.KubernetesResource import io.fabric8.kubernetes.api.model.apps.Deployment import io.fabric8.kubernetes.api.model.apps.StatefulSet +import io.fabric8.kubernetes.client.utils.Serialization /** * This patcher is able to set the field `spec.template.metadata.labels` for a `Deployment` or `StatefulSet` Kubernetes resource. * - * @property k8sResource The Kubernetes manifests to patch * @property variableName The label which should be set */ -class TemplateLabelPatcher(private val k8sResource: KubernetesResource, val variableName: String) : - AbstractPatcher(k8sResource) { +class TemplateLabelPatcher( + val variableName: String) : + AbstractPatcher() { - override fun <String> patch(labelValue: String) { - if (labelValue is kotlin.String) { - when (k8sResource) { - is Deployment -> { - if (k8sResource.spec.template.metadata.labels == null) { - k8sResource.spec.template.metadata.labels = mutableMapOf() - } - k8sResource.spec.template.metadata.labels[this.variableName] = labelValue + + override fun patchSingeResource(resource: HasMetadata, value: String): HasMetadata { + when (resource) { + is Deployment -> { + if (resource.spec.template.metadata.labels == null) { + resource.spec.template.metadata.labels = mutableMapOf() } - is StatefulSet -> { - if (k8sResource.spec.template.metadata.labels == null) { - k8sResource.spec.template.metadata.labels = mutableMapOf() - } - k8sResource.spec.template.metadata.labels[this.variableName] = labelValue + resource.spec.template.metadata.labels[this.variableName] = value + } + is StatefulSet -> { + if (resource.spec.template.metadata.labels == null) { + resource.spec.template.metadata.labels = mutableMapOf() } + resource.spec.template.metadata.labels[this.variableName] = value } } + return resource } } \ No newline at end of file diff --git a/theodolite/src/main/kotlin/theodolite/patcher/VolumesConfigMapPatcher.kt b/theodolite/src/main/kotlin/theodolite/patcher/VolumesConfigMapPatcher.kt new file mode 100644 index 0000000000000000000000000000000000000000..dc113499c2a733ccf571f3427f93484860df401c --- /dev/null +++ b/theodolite/src/main/kotlin/theodolite/patcher/VolumesConfigMapPatcher.kt @@ -0,0 +1,46 @@ +package theodolite.patcher + +import io.fabric8.kubernetes.api.model.HasMetadata +import io.fabric8.kubernetes.api.model.KubernetesResource +import io.fabric8.kubernetes.api.model.apps.Deployment +import io.fabric8.kubernetes.api.model.apps.StatefulSet +import io.fabric8.kubernetes.client.utils.Serialization + +class VolumesConfigMapPatcher(private var volumeName: String +) : AbstractPatcher() { + + override fun patchSingeResource(resource: HasMetadata, value: String): HasMetadata { + if (resource is Deployment) { + if (resource.spec.template.spec.volumes == null) { + resource.spec.template.spec.volumes = mutableListOf() + } + val volumeMounts = resource.spec.template.spec.volumes + + for (mount in volumeMounts) { + try { + if (mount.configMap.name == volumeName) { + mount.configMap.name = value + } + } catch (_: NullPointerException) { + } + } + } + if (resource is StatefulSet) { + if (resource.spec.template.spec.volumes == null) { + resource.spec.template.spec.volumes = mutableListOf() + } + val volumeMounts = resource.spec.template.spec.volumes + + for (mount in volumeMounts) { + try { + if (mount.configMap.name == volumeName) { + mount.configMap.name = value + } + } catch (_: NullPointerException) { + } + } + } + + return resource + } +} \ No newline at end of file diff --git a/theodolite/src/test/kotlin/theodolite/patcher/AbstractPatcherTest.kt b/theodolite/src/test/kotlin/theodolite/patcher/AbstractPatcherTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..05bb9588a2de5656b9c0b39d16d2160f691bbe91 --- /dev/null +++ b/theodolite/src/test/kotlin/theodolite/patcher/AbstractPatcherTest.kt @@ -0,0 +1,101 @@ +package theodolite.patcher + +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.quarkus.test.junit.QuarkusTest +import org.junit.jupiter.api.Test +import theodolite.util.PatcherDefinition + +@QuarkusTest +abstract class AbstractPatcherTest { + + lateinit var resource: List<HasMetadata> + lateinit var patcher: Patcher + lateinit var value: String + + fun createDeployment(): HasMetadata { + return DeploymentBuilder() + .withNewMetadata() + .withName("dummy") + .endMetadata() + .withNewSpec() + .withNewSelector() + .withMatchLabels<String, String>(mapOf("labelName" to "labelValue")) + .endSelector() + .withNewTemplate() + .withNewMetadata() + .withLabels<String, String>(mapOf("labelName" to "labelValue")) + .endMetadata() + .withNewSpec() + .withContainers( + ContainerBuilder() + .withName("container") + .withImage("test-image") + .build()) + .addNewVolume() + .withName("test-volume") + .withNewConfigMap() + .withName("test-configmap") + .endConfigMap() + .endVolume() + .endSpec() + .endTemplate() + .endSpec() + .build() + } + + fun createStateFulSet(): HasMetadata { + return StatefulSetBuilder() + .withNewMetadata() + .withName("dummy") + .endMetadata() + .withNewSpec() + .withNewSelector() + .withMatchLabels<String, String>(mapOf("labelName" to "labelValue")) + .endSelector() + .withNewTemplate() + .withNewMetadata() + .withLabels<String, String>(mapOf("labelName" to "labelValue")) + .endMetadata() + .withNewSpec() + .addNewVolume() + .withName("test-volume") + .withNewConfigMap() + .withName("test-configmap") + .endConfigMap() + .endVolume() + .endSpec() + .endTemplate() + .endSpec() + .build() + } + + fun createService(): HasMetadata { + return ServiceBuilder() + .withNewMetadata() + .withName("dummy") + .endMetadata() + .build() + } + + fun createConfigMap(): HasMetadata { + return ConfigMapBuilder() + .withNewMetadata() + .withName("dummy") + .endMetadata() + .withData<String, String>(mapOf("application.properties" to "propA = valueA")) + .build() + } + + fun patch() { + resource = patcher.patch(resource, value) + } + + @Test + abstract fun validate() + + +} \ No newline at end of file diff --git a/theodolite/src/test/kotlin/theodolite/patcher/DataVolumeLoadGeneratorReplicaPatcherTest.kt b/theodolite/src/test/kotlin/theodolite/patcher/DataVolumeLoadGeneratorReplicaPatcherTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..e55767ea79f1925a3825aca11eb74a8641c17a90 --- /dev/null +++ b/theodolite/src/test/kotlin/theodolite/patcher/DataVolumeLoadGeneratorReplicaPatcherTest.kt @@ -0,0 +1,28 @@ +package theodolite.patcher + +import io.fabric8.kubernetes.api.model.apps.Deployment +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 org.junit.jupiter.api.Assertions.* + +@QuarkusTest +internal class DataVolumeLoadGeneratorReplicaPatcherTest: AbstractPatcherTest() { + + @BeforeEach + fun setUp() { + resource = listOf(createDeployment()) + patcher = VolumesConfigMapPatcher((resource.first() as Deployment).spec.template.spec.volumes[0].configMap.name) + value = "new-configMapName" + } + + @Test + override fun validate() { + patch() + resource.forEach { + assert((it as Deployment).spec.template.spec.volumes[0].configMap.name == value) + } + } +} \ No newline at end of file diff --git a/theodolite/src/test/kotlin/theodolite/patcher/EnvVarPatcherTest.kt b/theodolite/src/test/kotlin/theodolite/patcher/EnvVarPatcherTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..cc46347acf5b005ed05170fe27a40de3ca69599d --- /dev/null +++ b/theodolite/src/test/kotlin/theodolite/patcher/EnvVarPatcherTest.kt @@ -0,0 +1,35 @@ +package theodolite.patcher + +import io.fabric8.kubernetes.api.model.EnvVar +import io.fabric8.kubernetes.api.model.EnvVarBuilder +import io.fabric8.kubernetes.api.model.apps.Deployment +import io.quarkus.test.junit.QuarkusTest +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.Test + +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.BeforeEach + +@QuarkusTest +internal class EnvVarPatcherTest : AbstractPatcherTest() { + + @BeforeEach + fun setUp() { + resource = listOf(createDeployment()) + patcher = EnvVarPatcher(variableName = "testEnv", container = "container") + value = "testValue" + } + + @AfterEach + fun tearDown() { + } + + @Test + override fun validate() { + patch() + val envVar = EnvVarBuilder().withName("testEnv").withValue("testValue").build() + resource.forEach { + assertTrue((it as Deployment).spec.template.spec.containers[0].env.contains(envVar)) + } + } +} \ No newline at end of file diff --git a/theodolite/src/test/kotlin/theodolite/patcher/ImagePatcherTest.kt b/theodolite/src/test/kotlin/theodolite/patcher/ImagePatcherTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..6592f65934716bfd74d562c5a3fb52ddb40c8b86 --- /dev/null +++ b/theodolite/src/test/kotlin/theodolite/patcher/ImagePatcherTest.kt @@ -0,0 +1,32 @@ +package theodolite.patcher + +import io.fabric8.kubernetes.api.model.apps.Deployment +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 org.junit.jupiter.api.Assertions.* + +@QuarkusTest +internal class ImagePatcherTest: AbstractPatcherTest(){ + + @BeforeEach + fun setUp() { + resource = listOf(createDeployment()) + patcher = ImagePatcher(container = "container") + value = "testValue" + } + + @AfterEach + fun tearDown() { + } + + @Test + override fun validate() { + patch() + resource.forEach { + assertTrue((it as Deployment).spec.template.spec.containers[0].image == value) + } + } +} \ No newline at end of file diff --git a/theodolite/src/test/kotlin/theodolite/patcher/LabelPatcherTest.kt b/theodolite/src/test/kotlin/theodolite/patcher/LabelPatcherTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..64583e4be67282543a44d09b36e657eede2f9eac --- /dev/null +++ b/theodolite/src/test/kotlin/theodolite/patcher/LabelPatcherTest.kt @@ -0,0 +1,37 @@ +package theodolite.patcher + +import io.fabric8.kubernetes.api.model.apps.Deployment +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 org.junit.jupiter.api.Assertions.* + +@QuarkusTest +internal class LabelPatcherTest: AbstractPatcherTest() { + + @BeforeEach + fun setUp() { + resource = listOf(createDeployment()) + patcher = LabelPatcher("labelName") + value = "labelValue" + } + + @AfterEach + fun tearDown() { + } + + @Test + override fun validate() { + patch() + resource.forEach { + assertTrue((it as Deployment).metadata.labels.containsKey("labelName")) + assertTrue(it.metadata.labels.get("labelName")=="labelValue") + } + } + + @Test + fun getVariableName() { + } +} \ No newline at end of file diff --git a/theodolite/src/test/kotlin/theodolite/patcher/MatchLabelPatcherTest.kt b/theodolite/src/test/kotlin/theodolite/patcher/MatchLabelPatcherTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..796f2ffeb6f4c22b9d00218b91f0fbe2ee9f6567 --- /dev/null +++ b/theodolite/src/test/kotlin/theodolite/patcher/MatchLabelPatcherTest.kt @@ -0,0 +1,37 @@ +package theodolite.patcher + +import io.fabric8.kubernetes.api.model.apps.Deployment +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 org.junit.jupiter.api.Assertions.* + +@QuarkusTest +internal class MatchLabelPatcherTest: AbstractPatcherTest() { + + @BeforeEach + fun setUp() { + resource = listOf(createDeployment()) + patcher = MatchLabelPatcher("labelName") + value = "labelValue" + } + + @AfterEach + fun tearDown() { + } + + @Test + override fun validate() { + patch() + resource.forEach { + assertTrue((it as Deployment).spec.selector.matchLabels.containsKey("labelName")) + assertTrue(it.spec.selector.matchLabels.get("labelName")=="labelValue") + } + } + + @Test + fun getVariableName() { + } +} \ No newline at end of file diff --git a/theodolite/src/test/kotlin/theodolite/patcher/NamePatcherTest.kt b/theodolite/src/test/kotlin/theodolite/patcher/NamePatcherTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..5ae75c5b0dca038b8e351683bfd0ee2a40d217eb --- /dev/null +++ b/theodolite/src/test/kotlin/theodolite/patcher/NamePatcherTest.kt @@ -0,0 +1,33 @@ +package theodolite.patcher + +import io.fabric8.kubernetes.api.model.KubernetesResource +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 org.junit.jupiter.api.Assertions.* + +@QuarkusTest +internal class NamePatcherTest: AbstractPatcherTest() { + + @BeforeEach + fun setUp() { + resource = listOf(createDeployment()) + patcher = NamePatcher() + value = "newName" + } + + @AfterEach + fun tearDown() { + } + + @Test + override fun validate() { + patch() + resource.forEach { + println(it.toString()) + assertTrue(it.toString().contains("name=$value")) + } + } +} \ No newline at end of file diff --git a/theodolite/src/test/kotlin/theodolite/patcher/NodeSelectorPatcherTest.kt b/theodolite/src/test/kotlin/theodolite/patcher/NodeSelectorPatcherTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..a042faf8484eb0ce7e1e21a6069be2beeff0b693 --- /dev/null +++ b/theodolite/src/test/kotlin/theodolite/patcher/NodeSelectorPatcherTest.kt @@ -0,0 +1,36 @@ +package theodolite.patcher + +import io.fabric8.kubernetes.api.model.apps.Deployment +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 org.junit.jupiter.api.Assertions.* +import org.mockito.kotlin.reset + +@QuarkusTest +internal class NodeSelectorPatcherTest: AbstractPatcherTest() { + + @BeforeEach + fun setUp() { + resource = listOf(createDeployment()) + patcher = NodeSelectorPatcher("nodeName") + value = "nodeValue" + + } + + @AfterEach + fun tearDown() { + } + + @Test + override fun validate() { + patch() + resource.forEach { + assertTrue((it as Deployment).spec.template.spec.nodeSelector.containsKey("nodeName")) + assertTrue(it.spec.template.spec.nodeSelector["nodeName"] == value) + } + } + +} \ No newline at end of file diff --git a/theodolite/src/test/kotlin/theodolite/patcher/NumNestedGroupsLoadGeneratorReplicaPatcherTest.kt b/theodolite/src/test/kotlin/theodolite/patcher/NumNestedGroupsLoadGeneratorReplicaPatcherTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..6b2a639285b134c0efcaaf5b296f18779f4f8322 --- /dev/null +++ b/theodolite/src/test/kotlin/theodolite/patcher/NumNestedGroupsLoadGeneratorReplicaPatcherTest.kt @@ -0,0 +1,32 @@ +package theodolite.patcher + +import io.fabric8.kubernetes.api.model.apps.Deployment +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 org.junit.jupiter.api.Assertions.* + +@QuarkusTest +internal class NumNestedGroupsLoadGeneratorReplicaPatcherTest : AbstractPatcherTest(){ + + @BeforeEach + fun setUp() { + resource = listOf(createDeployment()) + patcher = NumNestedGroupsLoadGeneratorReplicaPatcher("10", "500") + value = "2" + } + + @AfterEach + fun tearDown() { + } + + @Test + override fun validate() { + patch() + resource.forEach { + assertTrue((it as Deployment).spec.replicas == 1) + } + } +} \ No newline at end of file diff --git a/theodolite/src/test/kotlin/theodolite/patcher/NumSensorsLoadGeneratorReplicaPatcherTest.kt b/theodolite/src/test/kotlin/theodolite/patcher/NumSensorsLoadGeneratorReplicaPatcherTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..50d122e60104ad0239824e5b4471ade8b3ff7bfb --- /dev/null +++ b/theodolite/src/test/kotlin/theodolite/patcher/NumSensorsLoadGeneratorReplicaPatcherTest.kt @@ -0,0 +1,32 @@ +package theodolite.patcher + +import io.fabric8.kubernetes.api.model.apps.Deployment +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 org.junit.jupiter.api.Assertions.* + +@QuarkusTest +internal class NumSensorsLoadGeneratorReplicaPatcherTest: AbstractPatcherTest() { + + @BeforeEach + fun setUp() { + resource = listOf(createDeployment()) + patcher = NumSensorsLoadGeneratorReplicaPatcher("10") + value = "2" + } + + @AfterEach + fun tearDown() { + } + + @Test + override fun validate() { + patch() + resource.forEach { + assertTrue((it as Deployment).spec.replicas == 1) + } + } +} \ No newline at end of file diff --git a/theodolite/src/test/kotlin/theodolite/patcher/PatcherDefinitionFactoryTest.kt b/theodolite/src/test/kotlin/theodolite/patcher/PatcherDefinitionFactoryTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..4696e646726f9ed6ad3e4c5cda1631ded42930e4 --- /dev/null +++ b/theodolite/src/test/kotlin/theodolite/patcher/PatcherDefinitionFactoryTest.kt @@ -0,0 +1,22 @@ +package theodolite.patcher + +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test + +import org.junit.jupiter.api.Assertions.* + +internal class PatcherDefinitionFactoryTest { + + @BeforeEach + fun setUp() { + } + + @AfterEach + fun tearDown() { + } + + @Test + fun createPatcherDefinition() { + } +} \ No newline at end of file diff --git a/theodolite/src/test/kotlin/theodolite/patcher/PatcherFactoryTest.kt b/theodolite/src/test/kotlin/theodolite/patcher/PatcherFactoryTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..1c3ecffa06f91d1d6c87706bb3fb28e94c414c35 --- /dev/null +++ b/theodolite/src/test/kotlin/theodolite/patcher/PatcherFactoryTest.kt @@ -0,0 +1,17 @@ +package theodolite.patcher + +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.BeforeEach + +import org.junit.jupiter.api.Assertions.* + +internal class PatcherFactoryTest { + + @BeforeEach + fun setUp() { + } + + @AfterEach + fun tearDown() { + } +} \ No newline at end of file diff --git a/theodolite/src/test/kotlin/theodolite/patcher/ReplicaPatcherTest.kt b/theodolite/src/test/kotlin/theodolite/patcher/ReplicaPatcherTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..0e01dead66509e40237952e4d65ea3a377943c5b --- /dev/null +++ b/theodolite/src/test/kotlin/theodolite/patcher/ReplicaPatcherTest.kt @@ -0,0 +1,32 @@ +package theodolite.patcher + +import io.fabric8.kubernetes.api.model.apps.Deployment +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 org.junit.jupiter.api.Assertions.* + +@QuarkusTest +internal class ReplicaPatcherTest: AbstractPatcherTest() { + + @BeforeEach + fun setUp() { + resource = listOf(createDeployment()) + patcher = ReplicaPatcher() + value = "5" + } + + @AfterEach + fun tearDown() { + } + + @Test + override fun validate() { + patch() + resource.forEach { + assertTrue((it as Deployment).spec.replicas == 5) + } + } +} \ No newline at end of file diff --git a/theodolite/src/test/kotlin/theodolite/patcher/ResourceLimitPatcherTest.kt b/theodolite/src/test/kotlin/theodolite/patcher/ResourceLimitPatcherTest.kt index 2769f2fef607a03d820b0821969db98894944cb3..b794ec6ed983dba92526aff67ecb3cab915871eb 100644 --- a/theodolite/src/test/kotlin/theodolite/patcher/ResourceLimitPatcherTest.kt +++ b/theodolite/src/test/kotlin/theodolite/patcher/ResourceLimitPatcherTest.kt @@ -1,5 +1,6 @@ package theodolite.patcher +import io.fabric8.kubernetes.api.model.HasMetadata import io.fabric8.kubernetes.client.server.mock.KubernetesServer import io.quarkus.test.junit.QuarkusTest import io.quarkus.test.kubernetes.client.KubernetesTestServer @@ -7,7 +8,6 @@ import io.quarkus.test.kubernetes.client.WithKubernetesTestServer import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test -import theodolite.patcher.PatcherFactory import theodolite.util.PatcherDefinition /** @@ -25,8 +25,6 @@ import theodolite.util.PatcherDefinition @Disabled class ResourceLimitPatcherTest { - val patcherFactory = PatcherFactory() - @KubernetesTestServer private lateinit var server: KubernetesServer @@ -51,15 +49,8 @@ class ResourceLimitPatcherTest { "container" to "uc-application" ) - patcherFactory.createPatcher( - patcherDefinition = defCPU, - k8sResources = listOf(Pair("/cpu-memory-deployment.yaml", k8sResource)) - ).patch(value = cpuValue) - - patcherFactory.createPatcher( - patcherDefinition = defMEM, - k8sResources = listOf(Pair("/cpu-memory-deployment.yaml", k8sResource)) - ).patch(value = memValue) + PatchHandler.patchResource(mutableMapOf(Pair("cpu-memory-deployment.yaml", listOf(k8sResource as HasMetadata))), defCPU, cpuValue) + PatchHandler.patchResource(mutableMapOf(Pair("cpu-memory-deployment.yaml", listOf(k8sResource as HasMetadata))), defMEM, memValue) k8sResource.spec.template.spec.containers.filter { it.name == defCPU.properties["container"]!! } .forEach { diff --git a/theodolite/src/test/kotlin/theodolite/patcher/ResourceRequestPatcherTest.kt b/theodolite/src/test/kotlin/theodolite/patcher/ResourceRequestPatcherTest.kt index dba91eb65d4474d38f64d7fdd7f7ab981f8eb30f..300397a96abd34f17f1a4a3d2b3c76e2d9da13ea 100644 --- a/theodolite/src/test/kotlin/theodolite/patcher/ResourceRequestPatcherTest.kt +++ b/theodolite/src/test/kotlin/theodolite/patcher/ResourceRequestPatcherTest.kt @@ -25,8 +25,6 @@ class ResourceRequestPatcherTest { @KubernetesTestServer private lateinit var server: KubernetesServer - val patcherFactory = PatcherFactory() - fun applyTest(fileName: String) { val cpuValue = "50m" val memValue = "3Gi" @@ -48,14 +46,8 @@ class ResourceRequestPatcherTest { "container" to "application" ) - patcherFactory.createPatcher( - patcherDefinition = defCPU, - k8sResources = listOf(Pair("/cpu-memory-deployment.yaml", k8sResource)) - ).patch(value = cpuValue) - patcherFactory.createPatcher( - patcherDefinition = defMEM, - k8sResources = listOf(Pair("/cpu-memory-deployment.yaml", k8sResource)) - ).patch(value = memValue) + PatchHandler.patchResource(mutableMapOf(Pair("/cpu-memory-deployment.yaml", listOf(k8sResource))), defCPU, cpuValue) + PatchHandler.patchResource(mutableMapOf(Pair("/cpu-memory-deployment.yaml", listOf(k8sResource))), defMEM, memValue) k8sResource.spec.template.spec.containers.filter { it.name == defCPU.properties["container"]!! } .forEach { @@ -87,4 +79,4 @@ class ResourceRequestPatcherTest { // Case 4: In the given YAML declaration neither `Resource Request` nor `Request Limit` is defined applyTest("/no-resources-deployment.yaml") } -} +} \ No newline at end of file diff --git a/theodolite/src/test/kotlin/theodolite/patcher/SchedulerNamePatcherTest.kt b/theodolite/src/test/kotlin/theodolite/patcher/SchedulerNamePatcherTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..8b6f3e9b1371bce3e17cbbc6e399d425baffd699 --- /dev/null +++ b/theodolite/src/test/kotlin/theodolite/patcher/SchedulerNamePatcherTest.kt @@ -0,0 +1,32 @@ +package theodolite.patcher + +import io.fabric8.kubernetes.api.model.apps.Deployment +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 org.junit.jupiter.api.Assertions.* + +@QuarkusTest +internal class SchedulerNamePatcherTest : AbstractPatcherTest(){ + + @BeforeEach + fun setUp() { + resource = listOf(createDeployment()) + patcher = SchedulerNamePatcher() + value = "testScheduler" + } + + @AfterEach + fun tearDown() { + } + + @Test + override fun validate() { + patch() + resource.forEach { + assertTrue((it as Deployment).spec.template.spec.schedulerName == value) + } + } +} \ No newline at end of file diff --git a/theodolite/src/test/kotlin/theodolite/patcher/ServiceSelectorPatcherTest.kt b/theodolite/src/test/kotlin/theodolite/patcher/ServiceSelectorPatcherTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..caffb7eaf37c3930dbbb8a043ccd1cb7bbfd8d74 --- /dev/null +++ b/theodolite/src/test/kotlin/theodolite/patcher/ServiceSelectorPatcherTest.kt @@ -0,0 +1,22 @@ +package theodolite.patcher + +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test + +import org.junit.jupiter.api.Assertions.* + +internal class ServiceSelectorPatcherTest { + + @BeforeEach + fun setUp() { + } + + @AfterEach + fun tearDown() { + } + + @Test + fun patch() { + } +} \ No newline at end of file diff --git a/theodolite/src/test/kotlin/theodolite/patcher/TemplateLabelPatcherTest.kt b/theodolite/src/test/kotlin/theodolite/patcher/TemplateLabelPatcherTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..ebfe147e7b503defe14439fb1b954b9dd269ea3e --- /dev/null +++ b/theodolite/src/test/kotlin/theodolite/patcher/TemplateLabelPatcherTest.kt @@ -0,0 +1,34 @@ +package theodolite.patcher + +import io.fabric8.kubernetes.api.model.apps.Deployment +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 org.junit.jupiter.api.Assertions.* + +@QuarkusTest +internal class TemplateLabelPatcherTest: AbstractPatcherTest() { + + @BeforeEach + fun setUp() { + resource = listOf(createDeployment()) + patcher = TemplateLabelPatcher( "labelName") + value = "labelValue" + } + + + @Test + override fun validate() { + patch() + resource.forEach { + assertTrue((it as Deployment).spec.template.metadata.labels.containsKey("labelName")) + assertTrue(it.spec.template.metadata.labels["labelName"] =="labelValue") + } + } + + @Test + fun getVariableName() { + } +} \ No newline at end of file diff --git a/theodolite/src/test/kotlin/theodolite/patcher/VolumesConfigMapPatcherTest.kt b/theodolite/src/test/kotlin/theodolite/patcher/VolumesConfigMapPatcherTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..5628fd7c50336dc620dec79945c69fd9856a9c91 --- /dev/null +++ b/theodolite/src/test/kotlin/theodolite/patcher/VolumesConfigMapPatcherTest.kt @@ -0,0 +1,33 @@ +package theodolite.patcher + +import io.fabric8.kubernetes.api.model.apps.Deployment +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 org.junit.jupiter.api.Assertions.* + +@QuarkusTest +internal class VolumesConfigMapPatcherTest: AbstractPatcherTest() { + + @BeforeEach + fun setUp() { + resource = listOf(createDeployment()) + patcher = VolumesConfigMapPatcher("test-configmap") + value = "patchedVolumeName" + } + + @AfterEach + fun tearDown() { + } + + @Test + override fun validate() { + patch() + resource.forEach { + println((it as Deployment).spec.template.spec.volumes[0].configMap.name) + assertTrue((it as Deployment).spec.template.spec.volumes[0].configMap.name == value) + } + } +} \ No newline at end of file