Skip to content
Snippets Groups Projects
Commit c3acad6c authored by Benedikt Wetzel's avatar Benedikt Wetzel
Browse files

minor code changes/enhancements

parent 9808367c
No related branches found
No related tags found
1 merge request!168Enhance Code Quality
...@@ -18,7 +18,7 @@ import kotlin.properties.Delegates ...@@ -18,7 +18,7 @@ import kotlin.properties.Delegates
* - An [execution] that encapsulates: the strategy, the duration, and the restrictions * - An [execution] that encapsulates: the strategy, the duration, and the restrictions
* for the execution of the benchmark. * for the execution of the benchmark.
* - [configOverrides] additional configurations. * - [configOverrides] additional configurations.
* This class is used for parsing(in [theodolite.execution.TheodoliteYamlExecutor]) and * This class is used for parsing(in [theodolite.execution.TheodoliteStandalone]) and
* for the deserializing in the [theodolite.execution.operator.TheodoliteOperator]. * for the deserializing in the [theodolite.execution.operator.TheodoliteOperator].
* @constructor construct an empty BenchmarkExecution. * @constructor construct an empty BenchmarkExecution.
*/ */
......
...@@ -2,8 +2,6 @@ package theodolite.benchmark ...@@ -2,8 +2,6 @@ package theodolite.benchmark
import com.fasterxml.jackson.databind.annotation.JsonDeserialize import com.fasterxml.jackson.databind.annotation.JsonDeserialize
import io.fabric8.kubernetes.api.model.KubernetesResource import io.fabric8.kubernetes.api.model.KubernetesResource
import io.fabric8.kubernetes.api.model.Namespaced
import io.fabric8.kubernetes.client.CustomResource
import io.fabric8.kubernetes.client.DefaultKubernetesClient import io.fabric8.kubernetes.client.DefaultKubernetesClient
import io.quarkus.runtime.annotations.RegisterForReflection import io.quarkus.runtime.annotations.RegisterForReflection
import mu.KotlinLogging import mu.KotlinLogging
...@@ -14,6 +12,7 @@ import theodolite.util.* ...@@ -14,6 +12,7 @@ import theodolite.util.*
private val logger = KotlinLogging.logger {} private val logger = KotlinLogging.logger {}
private var DEFAULT_NAMESPACE = "default" private var DEFAULT_NAMESPACE = "default"
private var DEFAULT_THEODOLITE_APP_RESOURCES = "./config"
/** /**
* Represents a benchmark in Kubernetes. An example for this is the BenchmarkType.yaml * Represents a benchmark in Kubernetes. An example for this is the BenchmarkType.yaml
...@@ -27,7 +26,7 @@ private var DEFAULT_NAMESPACE = "default" ...@@ -27,7 +26,7 @@ private var DEFAULT_NAMESPACE = "default"
* - [namespace] for the client, * - [namespace] for the client,
* - [path] under which the resource yamls can be found. * - [path] under which the resource yamls can be found.
* *
* This class is used for the parsing(in the [theodolite.execution.TheodoliteYamlExecutor]) and * This class is used for the parsing(in the [theodolite.execution.TheodoliteStandalone]) and
* for the deserializing in the [theodolite.execution.operator.TheodoliteOperator]. * for the deserializing in the [theodolite.execution.operator.TheodoliteOperator].
* @constructor construct an empty Benchmark. * @constructor construct an empty Benchmark.
*/ */
...@@ -41,7 +40,6 @@ class KubernetesBenchmark: KubernetesResource, Benchmark{ ...@@ -41,7 +40,6 @@ class KubernetesBenchmark: KubernetesResource, Benchmark{
lateinit var loadTypes: List<TypeName> lateinit var loadTypes: List<TypeName>
lateinit var kafkaConfig: KafkaConfig lateinit var kafkaConfig: KafkaConfig
var namespace = System.getenv("NAMESPACE") ?: DEFAULT_NAMESPACE var namespace = System.getenv("NAMESPACE") ?: DEFAULT_NAMESPACE
var path = System.getenv("THEODOLITE_APP_RESOURCES") ?: "./config"
/** /**
...@@ -50,8 +48,11 @@ class KubernetesBenchmark: KubernetesResource, Benchmark{ ...@@ -50,8 +48,11 @@ class KubernetesBenchmark: KubernetesResource, Benchmark{
* the [K8sResourceLoader] * the [K8sResourceLoader]
*/ */
private fun loadKubernetesResources(resources: List<String>): List<Pair<String, KubernetesResource>> { private fun loadKubernetesResources(resources: List<String>): List<Pair<String, KubernetesResource>> {
val path = System.getenv("THEODOLITE_APP_RESOURCES") ?: DEFAULT_THEODOLITE_APP_RESOURCES
logger.info { "Using $path as resource path." }
val parser = YamlParser() val parser = YamlParser()
val loader = K8sResourceLoader(DefaultKubernetesClient().inNamespace(namespace)) val loader = K8sResourceLoader(DefaultKubernetesClient())
return resources return resources
.map { resource -> .map { resource ->
val resourcePath = "$path/$resource" val resourcePath = "$path/$resource"
...@@ -78,7 +79,6 @@ class KubernetesBenchmark: KubernetesResource, Benchmark{ ...@@ -78,7 +79,6 @@ class KubernetesBenchmark: KubernetesResource, Benchmark{
afterTeardownDelay: Long afterTeardownDelay: Long
): BenchmarkDeployment { ): BenchmarkDeployment {
logger.info { "Using $namespace as namespace." } logger.info { "Using $namespace as namespace." }
logger.info { "Using $path as resource path." }
val appResources = loadKubernetesResources(this.appResource) val appResources = loadKubernetesResources(this.appResource)
val loadGenResources = loadKubernetesResources(this.loadGenResource) val loadGenResources = loadKubernetesResources(this.loadGenResource)
...@@ -100,7 +100,6 @@ class KubernetesBenchmark: KubernetesResource, Benchmark{ ...@@ -100,7 +100,6 @@ class KubernetesBenchmark: KubernetesResource, Benchmark{
} }
} }
return KubernetesBenchmarkDeployment( return KubernetesBenchmarkDeployment(
namespace = namespace,
appResources = appResources.map { it.second }, appResources = appResources.map { it.second },
loadGenResources = loadGenResources.map { it.second }, loadGenResources = loadGenResources.map { it.second },
loadGenerationDelay = loadGenerationDelay, loadGenerationDelay = loadGenerationDelay,
......
...@@ -22,7 +22,6 @@ private val logger = KotlinLogging.logger {} ...@@ -22,7 +22,6 @@ private val logger = KotlinLogging.logger {}
*/ */
@RegisterForReflection @RegisterForReflection
class KubernetesBenchmarkDeployment( class KubernetesBenchmarkDeployment(
val namespace: String,
val appResources: List<KubernetesResource>, val appResources: List<KubernetesResource>,
val loadGenResources: List<KubernetesResource>, val loadGenResources: List<KubernetesResource>,
private val loadGenerationDelay: Long, private val loadGenerationDelay: Long,
...@@ -60,7 +59,7 @@ class KubernetesBenchmarkDeployment( ...@@ -60,7 +59,7 @@ class KubernetesBenchmarkDeployment(
loadGenResources.forEach { kubernetesManager.remove(it) } loadGenResources.forEach { kubernetesManager.remove(it) }
appResources.forEach { kubernetesManager.remove(it) } appResources.forEach { kubernetesManager.remove(it) }
kafkaController.removeTopics(this.topics.map { topic -> topic.name }) kafkaController.removeTopics(this.topics.map { topic -> topic.name })
KafkaLagExporterRemover(client).remove(LAG_EXPORTER_POD_LABEL) ResourceByLabelRemover(client).removePod(LAG_EXPORTER_POD_LABEL)
logger.info { "Teardown complete. Wait $afterTeardownDelay ms to let everything come down." } logger.info { "Teardown complete. Wait $afterTeardownDelay ms to let everything come down." }
Thread.sleep(Duration.ofSeconds(afterTeardownDelay).toMillis()) Thread.sleep(Duration.ofSeconds(afterTeardownDelay).toMillis())
} }
......
...@@ -9,13 +9,15 @@ private val logger = KotlinLogging.logger {} ...@@ -9,13 +9,15 @@ private val logger = KotlinLogging.logger {}
* Used to reset the KafkaLagExporter by deleting the pod. * Used to reset the KafkaLagExporter by deleting the pod.
* @param client NamespacedKubernetesClient used for the deletion. * @param client NamespacedKubernetesClient used for the deletion.
*/ */
class KafkaLagExporterRemover(private val client: NamespacedKubernetesClient) { // TODO(Maybe we can add support to delete arbitrary resources (kinds),
// then we can use this class also inside the ClusterSetup class instead of the clearByLabel function.)
class ResourceByLabelRemover(private val client: NamespacedKubernetesClient) {
/** /**
* Deletes all pods with the selected label. * Deletes all pods with the selected label.
* @param [label] of the pod that should be deleted. * @param [label] of the pod that should be deleted.
*/ */
fun remove(label: String) { fun removePod(label: String) {
this.client.pods().withLabel(label).delete() this.client.pods().withLabel(label).delete()
logger.info { "Pod with label: $label deleted" } logger.info { "Pod with label: $label deleted" }
} }
......
...@@ -12,6 +12,7 @@ import java.util.* ...@@ -12,6 +12,7 @@ import java.util.*
import java.util.regex.Pattern import java.util.regex.Pattern
private val logger = KotlinLogging.logger {} private val logger = KotlinLogging.logger {}
private val RECORD_LAG_QUERY = "sum by(group)(kafka_consumergroup_group_lag >= 0)"
/** /**
* Contains the analysis. Fetches a metric from Prometheus, documents it, and evaluates it. * Contains the analysis. Fetches a metric from Prometheus, documents it, and evaluates it.
...@@ -32,7 +33,7 @@ class AnalysisExecutor( ...@@ -32,7 +33,7 @@ class AnalysisExecutor(
* First fetches data from prometheus, then documents them and afterwards evaluate it via a [slo]. * First fetches data from prometheus, then documents them and afterwards evaluate it via a [slo].
* @param load of the experiment. * @param load of the experiment.
* @param res of the experiment. * @param res of the experiment.
* @param executionDuration of the experiment. * @param executionIntervals list of start and end points of experiments
* @return true if the experiment succeeded. * @return true if the experiment succeeded.
*/ */
fun analyze(load: LoadDimension, res: Resource, executionIntervals: List<Pair<Instant, Instant>>): Boolean { fun analyze(load: LoadDimension, res: Resource, executionIntervals: List<Pair<Instant, Instant>>): Boolean {
...@@ -48,7 +49,7 @@ class AnalysisExecutor( ...@@ -48,7 +49,7 @@ class AnalysisExecutor(
.map { interval -> fetcher.fetchMetric( .map { interval -> fetcher.fetchMetric(
start = interval.first, start = interval.first,
end = interval.second, end = interval.second,
query = "sum by(group)(kafka_consumergroup_group_lag >= 0)") } query = RECORD_LAG_QUERY) }
prometheusData.forEach{ data -> prometheusData.forEach{ data ->
ioHandler.writeToCSVFile( ioHandler.writeToCSVFile(
...@@ -67,6 +68,7 @@ class AnalysisExecutor( ...@@ -67,6 +68,7 @@ class AnalysisExecutor(
result = sloChecker.evaluate(prometheusData) result = sloChecker.evaluate(prometheusData)
} catch (e: Exception) { } catch (e: Exception) {
// TODO(throw exception in order to make it possible to mark an experiment as unsuccessfully)
logger.error { "Evaluation failed for resource '${res.get()}' and load '${load.get()}'. Error: $e" } logger.error { "Evaluation failed for resource '${res.get()}' and load '${load.get()}'. Error: $e" }
} }
return result return result
...@@ -75,7 +77,7 @@ class AnalysisExecutor( ...@@ -75,7 +77,7 @@ class AnalysisExecutor(
private val NONLATIN: Pattern = Pattern.compile("[^\\w-]") private val NONLATIN: Pattern = Pattern.compile("[^\\w-]")
private val WHITESPACE: Pattern = Pattern.compile("[\\s]") private val WHITESPACE: Pattern = Pattern.compile("[\\s]")
fun String.toSlug(): String { private fun String.toSlug(): String {
val noWhitespace: String = WHITESPACE.matcher(this).replaceAll("-") val noWhitespace: String = WHITESPACE.matcher(this).replaceAll("-")
val normalized: String = Normalizer.normalize(noWhitespace, Normalizer.Form.NFD) val normalized: String = Normalizer.normalize(noWhitespace, Normalizer.Form.NFD)
val slug: String = NONLATIN.matcher(normalized).replaceAll("") val slug: String = NONLATIN.matcher(normalized).replaceAll("")
......
...@@ -5,7 +5,6 @@ import khttp.post ...@@ -5,7 +5,6 @@ import khttp.post
import mu.KotlinLogging import mu.KotlinLogging
import theodolite.util.PrometheusResponse import theodolite.util.PrometheusResponse
import java.net.ConnectException import java.net.ConnectException
import java.time.Instant
/** /**
* [SloChecker] that uses an external source for the concrete evaluation. * [SloChecker] that uses an external source for the concrete evaluation.
......
...@@ -8,13 +8,10 @@ import theodolite.util.PrometheusResponse ...@@ -8,13 +8,10 @@ import theodolite.util.PrometheusResponse
*/ */
interface SloChecker { interface SloChecker {
/** /**
* Evaluates [fetchedData] and returns if the experiment was successful. * Evaluates [fetchedData] and returns if the experiments were successful.
* Returns if the evaluated experiment was successful.
* *
* @param start of the experiment
* @param end of the experiment
* @param fetchedData from Prometheus that will be evaluated. * @param fetchedData from Prometheus that will be evaluated.
* @return true if experiment was successful. Otherwise false. * @return true if experiments were successful. Otherwise false.
*/ */
fun evaluate(fetchedData: List<PrometheusResponse>): Boolean fun evaluate(fetchedData: List<PrometheusResponse>): Boolean
} }
...@@ -25,6 +25,7 @@ private val logger = KotlinLogging.logger {} ...@@ -25,6 +25,7 @@ private val logger = KotlinLogging.logger {}
* *
* @constructor Create empty Theodolite yaml executor * @constructor Create empty Theodolite yaml executor
*/ */
// TODO(rename class to standaloneMode or similar)
class TheodoliteYamlExecutor { class TheodoliteYamlExecutor {
private val parser = YamlParser() private val parser = YamlParser()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment