From 61654c2b42f78c3b9277887bd6d497da2cace0cf Mon Sep 17 00:00:00 2001 From: "stu126940@mail.uni-kiel.de" <stu126940@mail.uni-kiel.de> Date: Tue, 16 Feb 2021 19:40:50 +0100 Subject: [PATCH] Enable loading of configurations from yaml load yaml BenchmarkContext load yaml BenchmarkType load K8s resourcs based on the the loaded configurations --- .../kotlin/theodolite/benchmark/Benchmark.kt | 2 +- .../theodolite/benchmark/BenchmarkContext.kt | 26 +++++++ .../benchmark/BenchmarkYamlParser.kt | 8 +-- .../benchmark/KubernetesBenchmark.kt | 35 +++++++++- .../kotlin/theodolite/benchmark/Parser.kt | 4 +- .../benchmark/TheodoliteBenchmarkExecutor.kt | 70 +++++++++++++++++++ .../benchmark/TheodoliteYamlExecutor.kt | 18 ++++- .../theodolite/execution/BenchmarkExecutor.kt | 5 +- .../execution/BenchmarkExecutorImpl.kt | 9 ++- .../execution/TestBenchmarkExecutorImpl.kt | 8 ++- .../execution/TheodoliteExecutor.kt | 3 +- .../main/kotlin/theodolite/k8s/YamlLoader.kt | 12 ++++ .../kotlin/theodolite/util/TestBenchmark.kt | 13 +++- 13 files changed, 193 insertions(+), 20 deletions(-) create mode 100644 theodolite-quarkus/src/main/kotlin/theodolite/benchmark/BenchmarkContext.kt create mode 100644 theodolite-quarkus/src/main/kotlin/theodolite/benchmark/TheodoliteBenchmarkExecutor.kt diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/Benchmark.kt b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/Benchmark.kt index 8ec30b157..1c8b98f81 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/Benchmark.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/Benchmark.kt @@ -4,5 +4,5 @@ import theodolite.util.LoadDimension import theodolite.util.Resource interface Benchmark { - fun buildDeployment(load: LoadDimension, res: Resource): BenchmarkDeployment + fun buildDeployment(load: LoadDimension, res: Resource, override: Map<String, String>): BenchmarkDeployment } \ No newline at end of file diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/BenchmarkContext.kt b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/BenchmarkContext.kt new file mode 100644 index 000000000..1680e2173 --- /dev/null +++ b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/BenchmarkContext.kt @@ -0,0 +1,26 @@ +package theodolite.benchmark + +import kotlin.properties.Delegates + + +class BenchmarkContext() { + lateinit var name: String + lateinit var benchmark: String + lateinit var loads: List<Int> + lateinit var resources: List<Int> + lateinit var slos: List<Slo> + lateinit var execution: Execution + lateinit var configOverrides: Map<String, String> + + class Execution() { + lateinit var strategy: String + var duration by Delegates.notNull<Long>() + var repititions by Delegates.notNull<Int>() + lateinit var restrictions: List<String> + } + + class Slo(){ + lateinit var sloType: String + var threshold by Delegates.notNull<Int>() + } +} diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/BenchmarkYamlParser.kt b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/BenchmarkYamlParser.kt index 9e5b4456f..723898d76 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/BenchmarkYamlParser.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/BenchmarkYamlParser.kt @@ -8,10 +8,10 @@ import java.io.FileInputStream import java.io.InputStream -class BenchmarkYamlParser<T>: Parser<T> { - override fun parse(path: String): KubernetesBenchmark? { +class BenchmarkYamlParser: Parser { + override fun <T> parse(path: String, E: Class<T>): T? { val input: InputStream = FileInputStream(File(path)) - val parser = Yaml(Constructor(KubernetesBenchmark::class.java)) - return parser.loadAs(input, KubernetesBenchmark::class.java) + val parser = Yaml(Constructor(E)) + return parser.loadAs(input, E) } } \ No newline at end of file diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt index 9ca479693..09e820e51 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt @@ -1,12 +1,43 @@ package theodolite.benchmark +import io.fabric8.kubernetes.api.model.KubernetesResource +import io.fabric8.kubernetes.client.DefaultKubernetesClient +import org.yaml.snakeyaml.Yaml +import theodolite.k8s.YamlLoader import theodolite.util.LoadDimension import theodolite.util.Resource +import java.io.File +import java.io.FileInputStream +import java.io.InputStream class KubernetesBenchmark(): Benchmark { lateinit var name: String + lateinit var appResource: List<String> + lateinit var loadGenResource: List<String> - override fun buildDeployment(load: LoadDimension, res: Resource): BenchmarkDeployment { - TODO("Not yet implemented") + + private fun loadKubernetesResources(): List<KubernetesResource?> { + val basePath = "./../../../resources/main/yaml/" + var parser = theodolite.benchmark.BenchmarkYamlParser() + val loader = YamlLoader(DefaultKubernetesClient().inNamespace("default")) + return this.appResource + .map { resource -> "$basePath/$resource" } + .map { resourcePath -> + val kind = parser.parse(resourcePath, HashMap<String, String>()::class.java) !! + kind["kind"]?.let { loader.loadK8sResource(it, resourcePath) } + } + } + + private fun patchKubernetesResources() { + + } + + + override fun buildDeployment(load: LoadDimension, res: Resource, override: Map<String, String>): BenchmarkDeployment { + // TODO("") + val resources = loadKubernetesResources() + resources.forEach {x -> println(x.toString())} + // Return KubernetesBenchmarkDeployment with individual parametrisation + return KubernetesBenchmarkDeployment(emptyList(), hashMapOf<String, Any>(), "", emptyList() ) } } \ No newline at end of file diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/Parser.kt b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/Parser.kt index df6655b7e..93bf4a795 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/Parser.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/Parser.kt @@ -1,5 +1,5 @@ package theodolite.benchmark -interface Parser<T> { - fun parse(path: String): KubernetesBenchmark? //Yaml +interface Parser { + fun <T> parse(path: String, E:Class<T>): T? //Yaml } \ No newline at end of file diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/TheodoliteBenchmarkExecutor.kt b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/TheodoliteBenchmarkExecutor.kt new file mode 100644 index 000000000..a56eeee1a --- /dev/null +++ b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/TheodoliteBenchmarkExecutor.kt @@ -0,0 +1,70 @@ +package theodolite.benchmark + +import theodolite.execution.BenchmarkExecutor +import theodolite.execution.BenchmarkExecutorImpl +import theodolite.strategies.restriction.LowerBoundRestriction +import theodolite.strategies.restriction.RestrictionStrategy +import theodolite.strategies.searchstrategy.BinarySearch +import theodolite.strategies.searchstrategy.CompositeStrategy +import theodolite.strategies.searchstrategy.LinearSearch +import theodolite.strategies.searchstrategy.SearchStrategy +import theodolite.util.Config +import theodolite.util.LoadDimension +import theodolite.util.Resource +import theodolite.util.Results +import java.lang.IllegalArgumentException +import java.time.Duration + +class TheodoliteBenchmarkExecutor( + private val benchmarkContext: BenchmarkContext, + private val kubernetesBenchmark: KubernetesBenchmark) +{ + private fun createSearchStrategy(executor: BenchmarkExecutor): SearchStrategy { + return when (this.benchmarkContext.execution.strategy) { + "LinearSearch" -> LinearSearch(executor) + "BinarySearch" -> BinarySearch(executor) + else -> throw IllegalArgumentException("Search Strategy ${this.benchmarkContext.execution.strategy} not found") + } + } + + private fun createRestrictionStrategy(results: Results): Set<RestrictionStrategy> { + var strategies = emptyList<RestrictionStrategy>() + strategies = this.benchmarkContext.execution.restrictions.map { restriction -> + when (restriction) { + "LowerBound" -> LowerBoundRestriction(results) + else -> throw IllegalArgumentException("Restriction Strategy ${this.benchmarkContext.execution.restrictions} not found") + } + } + return strategies.toSet() + } + + private fun buildConfig(): Config{ + val results = Results() + val executionDuration = Duration.ofSeconds(this.benchmarkContext.execution.duration) + val executor: BenchmarkExecutor = BenchmarkExecutorImpl(kubernetesBenchmark, results, executionDuration, this.benchmarkContext.configOverrides) + + return Config( + loads = benchmarkContext.loads.map { number -> LoadDimension(number) }, + resources = benchmarkContext.resources.map { number -> Resource(number) }, + compositeStrategy = CompositeStrategy( + benchmarkExecutor = executor, + searchStrategy = createSearchStrategy(executor), + restrictionStrategies = createRestrictionStrategy(results) + ), + executionDuration = executionDuration + ) + + } + + + + fun run() { + val config = buildConfig() + + // execute benchmarks for each load + for (load in config.loads) { + config.compositeStrategy.findSuitableResource(load, config.resources) + } + + } +} diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/TheodoliteYamlExecutor.kt b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/TheodoliteYamlExecutor.kt index 04d0bd306..e80f98de8 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/TheodoliteYamlExecutor.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/TheodoliteYamlExecutor.kt @@ -2,8 +2,20 @@ package theodolite.benchmark class TheodoliteYamlExecutor { fun run() { - val parser = theodolite.benchmark.BenchmarkYamlParser<KubernetesBenchmark>() - val benchmark= parser.parse("./../../../resources/main/yaml/test.yaml") - System.out.println(benchmark?.name) + + // load the Benchmark context and the benchmark type + var parser = theodolite.benchmark.BenchmarkYamlParser() + val benchmarkContext = parser.parse("./../../../resources/main/yaml/testContext.yaml", BenchmarkContext::class.java) !! + val benchmark = parser.parse("./../../../resources/main/yaml/testBenchmarkType.yaml", KubernetesBenchmark::class.java) !! + + // TheodoliteExecutor benchmarkContext, benchmark + val executor = TheodoliteBenchmarkExecutor(benchmarkContext, benchmark) + executor.run() + + + + System.out.println(benchmark.name) + System.out.println(benchmarkContext.name) + } } \ No newline at end of file diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/execution/BenchmarkExecutor.kt b/theodolite-quarkus/src/main/kotlin/theodolite/execution/BenchmarkExecutor.kt index 82a409089..4905766d3 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/execution/BenchmarkExecutor.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/execution/BenchmarkExecutor.kt @@ -1,6 +1,8 @@ package theodolite.execution import mu.KotlinLogging +import theodolite.benchmark.Benchmark +import theodolite.benchmark.KubernetesBenchmark import theodolite.util.AbstractBenchmark import theodolite.util.LoadDimension import theodolite.util.Resource @@ -17,7 +19,8 @@ private val logger = KotlinLogging.logger {} * @property executionDuration * @constructor Create empty Benchmark executor */ -abstract class BenchmarkExecutor(val benchmark: AbstractBenchmark, val results: Results, val executionDuration: Duration) { +abstract class BenchmarkExecutor(val benchmark: Benchmark, val results: Results, val executionDuration: Duration, override: Map<String, String>) { + /** * Run a experiment for the given parametrization, evaluate the experiment and save the result. * diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/execution/BenchmarkExecutorImpl.kt b/theodolite-quarkus/src/main/kotlin/theodolite/execution/BenchmarkExecutorImpl.kt index a975085bf..d782ed9a5 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/execution/BenchmarkExecutorImpl.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/execution/BenchmarkExecutorImpl.kt @@ -1,16 +1,19 @@ package theodolite.execution +import theodolite.benchmark.Benchmark +import theodolite.benchmark.KubernetesBenchmark import theodolite.util.AbstractBenchmark import theodolite.util.LoadDimension import theodolite.util.Resource import theodolite.util.Results import java.time.Duration -class BenchmarkExecutorImpl(benchmark: AbstractBenchmark, results: Results, executionDuration: Duration) : BenchmarkExecutor(benchmark, results, executionDuration) { +class BenchmarkExecutorImpl(benchmark: Benchmark, results: Results, executionDuration: Duration, private val overrides: Map<String, String>) : BenchmarkExecutor(benchmark, results, executionDuration, overrides) { override fun runExperiment(load: LoadDimension, res: Resource): Boolean { - benchmark.start(load, res) + val benchmarkDeployment = benchmark.buildDeployment(load, res, this.overrides) + benchmarkDeployment.setup() this.waitAndLog() - benchmark.clearClusterEnvironment() + benchmarkDeployment.teardown() // todo evaluate val result = false // if success else false this.results.setResult(Pair(load, res), result) diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/execution/TestBenchmarkExecutorImpl.kt b/theodolite-quarkus/src/main/kotlin/theodolite/execution/TestBenchmarkExecutorImpl.kt index 9823c4dd5..db2084a85 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/execution/TestBenchmarkExecutorImpl.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/execution/TestBenchmarkExecutorImpl.kt @@ -1,13 +1,17 @@ package theodolite.execution +import theodolite.benchmark.Benchmark +import theodolite.benchmark.KubernetesBenchmark import theodolite.util.AbstractBenchmark import theodolite.util.LoadDimension import theodolite.util.Resource import theodolite.util.Results import java.time.Duration -class TestBenchmarkExecutorImpl(private val mockResults: Array<Array<Boolean>>, benchmark: AbstractBenchmark, results: Results): - BenchmarkExecutor(benchmark, results, executionDuration = Duration.ofSeconds(1)) { +class TestBenchmarkExecutorImpl(private val mockResults: Array<Array<Boolean>>, benchmark: Benchmark, results: Results): + BenchmarkExecutor(benchmark, results, executionDuration = Duration.ofSeconds(1), + override = emptyMap<String,String>() + ) { override fun runExperiment(load: LoadDimension, res: Resource): Boolean { val result = this.mockResults[load.get()][res.get()] diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/execution/TheodoliteExecutor.kt b/theodolite-quarkus/src/main/kotlin/theodolite/execution/TheodoliteExecutor.kt index ed5a65159..3db21a87a 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/execution/TheodoliteExecutor.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/execution/TheodoliteExecutor.kt @@ -1,5 +1,5 @@ package theodolite.execution - +/* import mu.KotlinLogging import theodolite.k8s.UC1Benchmark import theodolite.strategies.restriction.LowerBoundRestriction @@ -66,3 +66,4 @@ class TheodoliteExecutor() { } } } +*/ diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/k8s/YamlLoader.kt b/theodolite-quarkus/src/main/kotlin/theodolite/k8s/YamlLoader.kt index 5e37e97df..1624c6d4e 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/k8s/YamlLoader.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/k8s/YamlLoader.kt @@ -1,9 +1,11 @@ package theodolite.k8s import io.fabric8.kubernetes.api.model.ConfigMap +import io.fabric8.kubernetes.api.model.KubernetesResource import io.fabric8.kubernetes.api.model.Service import io.fabric8.kubernetes.api.model.apiextensions.v1beta1.CustomResourceDefinition import io.fabric8.kubernetes.api.model.apps.Deployment +import io.fabric8.kubernetes.api.model.apps.StatefulSet import io.fabric8.kubernetes.client.NamespacedKubernetesClient import mu.KotlinLogging @@ -68,4 +70,14 @@ class YamlLoader(private val client: NamespacedKubernetesClient) { return resource } + + public fun loadK8sResource(kind: String, path: String): KubernetesResource { + return when (kind){ + "Deployment" -> loadDeployment(path) + "Service" -> loadService(path) + "ServiceMonitor" -> loadServiceMonitor(path) + "ConfigMap" -> loadConfigmap(path) + else -> return loadConfigmap(path) // throw java.lang.IllegalArgumentException("Resource typ $kind not known") + } + } } diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/util/TestBenchmark.kt b/theodolite-quarkus/src/main/kotlin/theodolite/util/TestBenchmark.kt index 0358ff1a6..a5bc49c6c 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/util/TestBenchmark.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/util/TestBenchmark.kt @@ -1,5 +1,8 @@ package theodolite.util +import theodolite.benchmark.Benchmark +import theodolite.benchmark.BenchmarkDeployment + class TestBenchmark : AbstractBenchmark( AbstractBenchmark.Config( clusterZookeeperConnectionString = "", @@ -17,7 +20,7 @@ class TestBenchmark : AbstractBenchmark( ucImageURL = "", wgImageURL = "" ) -) { +), Benchmark { override fun initializeClusterEnvironment() { TODO("Not yet implemented") @@ -34,4 +37,12 @@ class TestBenchmark : AbstractBenchmark( override fun startWorkloadGenerator(load: LoadDimension) { TODO("Not yet implemented") } + + override fun buildDeployment( + load: LoadDimension, + res: Resource, + override: Map<String, String> + ): BenchmarkDeployment { + TODO("Not yet implemented") + } } -- GitLab