From 3eb2802292a599068a9be05bf00591a3dc86f0a9 Mon Sep 17 00:00:00 2001 From: Marcel Becker <stu117960@mail.uni-kiel.de> Date: Tue, 25 Jan 2022 13:50:00 +0100 Subject: [PATCH] Restructured Loads and Resources and deleted LoadDimension and Resource classes --- theodolite/crd/crd-execution.yaml | 2 +- .../kotlin/theodolite/benchmark/Benchmark.kt | 11 +++-- .../benchmark/BenchmarkExecution.kt | 3 +- .../benchmark/KubernetesBenchmark.kt | 15 +++--- .../theodolite/evaluation/AnalysisExecutor.kt | 11 ++--- .../evaluation/SloCheckerFactory.kt | 5 +- .../theodolite/execution/BenchmarkExecutor.kt | 9 ++-- .../execution/BenchmarkExecutorImpl.kt | 28 ++++++----- .../kotlin/theodolite/execution/Shutdown.kt | 8 ++-- .../execution/TheodoliteExecutor.kt | 18 ++++--- .../theodolite/strategies/StrategyFactory.kt | 2 +- .../restriction/LowerBoundRestriction.kt | 5 +- .../restriction/RestrictionStrategy.kt | 8 ++-- .../strategies/searchstrategy/BinarySearch.kt | 13 ++--- .../strategies/searchstrategy/FullSearch.kt | 13 ++--- .../searchstrategy/GuessStrategy.kt | 3 +- .../InitialGuessSearchStrategy.kt | 14 +++--- .../strategies/searchstrategy/LinearSearch.kt | 12 ++--- .../searchstrategy/PrevResourceMinGuess.kt | 3 +- .../searchstrategy/RestrictionSearch.kt | 8 ++-- .../searchstrategy/SearchStrategy.kt | 15 +++--- .../src/main/kotlin/theodolite/util/Config.kt | 10 ++-- .../kotlin/theodolite/util/LoadDimension.kt | 26 ---------- .../main/kotlin/theodolite/util/Resources.kt | 31 ------------ .../main/kotlin/theodolite/util/Results.kt | 33 +++++++------ .../InitialGuessSearchStrategyTest.kt | 7 ++- .../theodolite/RestrictionSearchTest.kt | 41 ++++++++++++++-- .../test/kotlin/theodolite/TestBenchmark.kt | 9 ++-- .../theodolite/TestBenchmarkExecutorImpl.kt | 12 ++--- .../execution/operator/ExecutionCRDummy.kt | 12 ++++- .../restriction/LowerBoundRestrictionTest.kt | 48 +++++-------------- .../kotlin/theodolite/util/IOHandlerTest.kt | 6 +-- .../kotlin/theodolite/util/ResultsTest.kt | 22 ++++----- 33 files changed, 205 insertions(+), 258 deletions(-) delete mode 100644 theodolite/src/main/kotlin/theodolite/util/LoadDimension.kt delete mode 100644 theodolite/src/main/kotlin/theodolite/util/Resources.kt diff --git a/theodolite/crd/crd-execution.yaml b/theodolite/crd/crd-execution.yaml index 185b0b494..fb90402be 100644 --- a/theodolite/crd/crd-execution.yaml +++ b/theodolite/crd/crd-execution.yaml @@ -98,7 +98,7 @@ spec: items: type: string guessStrategy: string - searchStrategy: object + searchStrategy: string properties: duration: description: Defines the duration of each experiment in seconds. diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/Benchmark.kt b/theodolite/src/main/kotlin/theodolite/benchmark/Benchmark.kt index 6f07c7a3b..cd6e05e49 100644 --- a/theodolite/src/main/kotlin/theodolite/benchmark/Benchmark.kt +++ b/theodolite/src/main/kotlin/theodolite/benchmark/Benchmark.kt @@ -2,12 +2,11 @@ package theodolite.benchmark import io.quarkus.runtime.annotations.RegisterForReflection import theodolite.util.ConfigurationOverride -import theodolite.util.LoadDimension -import theodolite.util.Resources +import theodolite.util.PatcherDefinition /** * A Benchmark contains: - * - The [Resources]s that can be scaled for the benchmark. + * - The [Resource]s that can be scaled for the benchmark. * - The [LoadDimension]s that can be scaled the benchmark. * - additional [ConfigurationOverride]s. */ @@ -22,8 +21,10 @@ interface Benchmark { * @return a BenchmarkDeployment. */ fun buildDeployment( - load: LoadDimension, - res: Resources, + load: Int, + loadPatcherDefinitions: List<PatcherDefinition>, + resource: Int, + resourcePatcherDefinitions: List<PatcherDefinition>, configurationOverrides: List<ConfigurationOverride?>, loadGenerationDelay: Long, afterTeardownDelay: Long diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/BenchmarkExecution.kt b/theodolite/src/main/kotlin/theodolite/benchmark/BenchmarkExecution.kt index b27533419..b5dd15623 100644 --- a/theodolite/src/main/kotlin/theodolite/benchmark/BenchmarkExecution.kt +++ b/theodolite/src/main/kotlin/theodolite/benchmark/BenchmarkExecution.kt @@ -3,7 +3,6 @@ package theodolite.benchmark import com.fasterxml.jackson.databind.annotation.JsonDeserialize import io.fabric8.kubernetes.api.model.KubernetesResource import io.quarkus.runtime.annotations.RegisterForReflection -import theodolite.strategies.searchstrategy.SearchStrategy import theodolite.util.ConfigurationOverride import kotlin.properties.Delegates @@ -14,7 +13,7 @@ import kotlin.properties.Delegates * - A [name]. * - The [benchmark] that should be executed. * - The [load] that should be checked in the benchmark. - * - The [resources] that should be checked in the benchmark. + * - The resources that should be checked in the benchmark. * - A list of [slos] that are used for the evaluation of the experiments. * - An [execution] that encapsulates: the strategy, the duration, and the restrictions * for the execution of the benchmark. diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt b/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt index d41618cbc..cb5433a4d 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.quarkus.runtime.annotations.RegisterForReflection import mu.KotlinLogging import theodolite.k8s.K8sManager import theodolite.k8s.resourceLoader.K8sResourceLoader +import theodolite.patcher.Patcher import theodolite.patcher.PatcherFactory import theodolite.util.* @@ -81,8 +82,10 @@ class KubernetesBenchmark : KubernetesResource, Benchmark { * @return a [BenchmarkDeployment] */ override fun buildDeployment( - load: LoadDimension, - res: theodolite.util.Resources, + load: Int, + loadPatcherDefinitions: List<PatcherDefinition>, + resource: Int, + resourcePatcherDefinitions: List<PatcherDefinition>, configurationOverrides: List<ConfigurationOverride?>, loadGenerationDelay: Long, afterTeardownDelay: Long @@ -95,11 +98,11 @@ class KubernetesBenchmark : KubernetesResource, Benchmark { val patcherFactory = PatcherFactory() // patch the load dimension the resources - load.getType().forEach { patcherDefinition -> - patcherFactory.createPatcher(patcherDefinition, loadGenResources).patch(load.get().toString()) + loadPatcherDefinitions.forEach { patcherDefinition -> + patcherFactory.createPatcher(patcherDefinition, loadGenResources).patch(load.toString()) } - res.getType().forEach { patcherDefinition -> - patcherFactory.createPatcher(patcherDefinition, appResources).patch(res.get().toString()) + resourcePatcherDefinitions.forEach { patcherDefinition -> + patcherFactory.createPatcher(patcherDefinition, appResources).patch(resource.toString()) } // Patch the given overrides diff --git a/theodolite/src/main/kotlin/theodolite/evaluation/AnalysisExecutor.kt b/theodolite/src/main/kotlin/theodolite/evaluation/AnalysisExecutor.kt index 6ae360e0d..b46fc474f 100644 --- a/theodolite/src/main/kotlin/theodolite/evaluation/AnalysisExecutor.kt +++ b/theodolite/src/main/kotlin/theodolite/evaluation/AnalysisExecutor.kt @@ -4,8 +4,6 @@ import mu.KotlinLogging import theodolite.benchmark.BenchmarkExecution import theodolite.util.EvaluationFailedException import theodolite.util.IOHandler -import theodolite.util.LoadDimension -import theodolite.util.Resources import java.text.Normalizer import java.time.Duration import java.time.Instant @@ -32,18 +30,18 @@ class AnalysisExecutor( * Analyses an experiment via prometheus data. * First fetches data from prometheus, then documents them and afterwards evaluate it via a [slo]. * @param load of the experiment. - * @param res of the experiment. + * @param resource of the experiment. * @param executionIntervals list of start and end points of experiments * @return true if the experiment succeeded. */ - fun analyze(load: LoadDimension, res: Int, executionIntervals: List<Pair<Instant, Instant>>): Boolean { + fun analyze(load: Int, resource: Int, executionIntervals: List<Pair<Instant, Instant>>): Boolean { var result: Boolean var repetitionCounter = 1 try { val ioHandler = IOHandler() val resultsFolder: String = ioHandler.getResultFolderURL() - val fileURL = "${resultsFolder}exp${executionId}_${load.get()}_${res}_${slo.sloType.toSlug()}" + val fileURL = "${resultsFolder}exp${executionId}_${load}_${resource}_${slo.sloType.toSlug()}" val prometheusData = executionIntervals .map { interval -> @@ -62,6 +60,7 @@ class AnalysisExecutor( ) } + //TODO: CHECK WHETHER WE NEED TO DIFFERENTIATE BETWEEN METRICS AND HAVE SOME NEW KIND OF SLOCHECKER WHICH GETS RESOURCE AS PARAMETER val sloChecker = SloCheckerFactory().create( sloType = slo.sloType, properties = slo.properties, @@ -71,7 +70,7 @@ class AnalysisExecutor( result = sloChecker.evaluate(prometheusData) } catch (e: Exception) { - throw EvaluationFailedException("Evaluation failed for resource '${res}' and load '${load.get()} ", e) + throw EvaluationFailedException("Evaluation failed for resource '$resource' and load '$load ", e) } return result } diff --git a/theodolite/src/main/kotlin/theodolite/evaluation/SloCheckerFactory.kt b/theodolite/src/main/kotlin/theodolite/evaluation/SloCheckerFactory.kt index 64f9110cd..96893c4de 100644 --- a/theodolite/src/main/kotlin/theodolite/evaluation/SloCheckerFactory.kt +++ b/theodolite/src/main/kotlin/theodolite/evaluation/SloCheckerFactory.kt @@ -1,6 +1,5 @@ package theodolite.evaluation -import theodolite.util.LoadDimension /** * Factory used to potentially create different [SloChecker]s. @@ -41,7 +40,7 @@ class SloCheckerFactory { fun create( sloType: String, properties: MutableMap<String, String>, - load: LoadDimension + load: Int ): SloChecker { return when (sloType.toLowerCase()) { SloTypes.LAG_TREND.value, SloTypes.DROPPED_RECORDS.value -> ExternalSloChecker( @@ -59,7 +58,7 @@ class SloCheckerFactory { throw IllegalArgumentException("Threshold ratio needs to be an Double greater or equal 0.0") } // cast to int, as rounding is not really necessary - val threshold = (load.get() * thresholdRatio).toInt() + val threshold = (load * thresholdRatio).toInt() ExternalSloChecker( externalSlopeURL = properties["externalSloUrl"] diff --git a/theodolite/src/main/kotlin/theodolite/execution/BenchmarkExecutor.kt b/theodolite/src/main/kotlin/theodolite/execution/BenchmarkExecutor.kt index fb6c72019..470f63fcd 100644 --- a/theodolite/src/main/kotlin/theodolite/execution/BenchmarkExecutor.kt +++ b/theodolite/src/main/kotlin/theodolite/execution/BenchmarkExecutor.kt @@ -4,8 +4,7 @@ import mu.KotlinLogging import theodolite.benchmark.Benchmark import theodolite.benchmark.BenchmarkExecution import theodolite.util.ConfigurationOverride -import theodolite.util.LoadDimension -import theodolite.util.Resources +import theodolite.util.PatcherDefinition import theodolite.util.Results import java.time.Duration import java.util.concurrent.atomic.AtomicBoolean @@ -30,7 +29,9 @@ abstract class BenchmarkExecutor( val executionId: Int, val loadGenerationDelay: Long, val afterTeardownDelay: Long, - val executionName: String + val executionName: String, + val loadPatcherDefinitions: List<PatcherDefinition>, + val resourcePatcherDefinitions: List<PatcherDefinition> ) { var run: AtomicBoolean = AtomicBoolean(true) @@ -44,7 +45,7 @@ abstract class BenchmarkExecutor( * @return True, if the number of resources are suitable for the * given load, false otherwise. */ - abstract fun runExperiment(load: LoadDimension, res: Int): Boolean + abstract fun runExperiment(load: Int, resource: Int): Boolean /** * Wait while the benchmark is running and log the number of minutes executed every 1 minute. diff --git a/theodolite/src/main/kotlin/theodolite/execution/BenchmarkExecutorImpl.kt b/theodolite/src/main/kotlin/theodolite/execution/BenchmarkExecutorImpl.kt index f51a4a842..733e3ea61 100644 --- a/theodolite/src/main/kotlin/theodolite/execution/BenchmarkExecutorImpl.kt +++ b/theodolite/src/main/kotlin/theodolite/execution/BenchmarkExecutorImpl.kt @@ -23,7 +23,9 @@ class BenchmarkExecutorImpl( executionId: Int, loadGenerationDelay: Long, afterTeardownDelay: Long, - executionName: String + executionName: String, + loadPatcherDefinitions: List<PatcherDefinition>, + resourcePatcherDefinitions: List<PatcherDefinition> ) : BenchmarkExecutor( benchmark, results, @@ -34,19 +36,22 @@ class BenchmarkExecutorImpl( executionId, loadGenerationDelay, afterTeardownDelay, - executionName + executionName, + loadPatcherDefinitions, + resourcePatcherDefinitions ) { private val eventCreator = EventCreator() private val mode = Configuration.EXECUTION_MODE - override fun runExperiment(load: LoadDimension, res: Int): Boolean { + override fun runExperiment(load: Int, resource: Int): Boolean { var result = false val executionIntervals: MutableList<Pair<Instant, Instant>> = ArrayList() for (i in 1.rangeTo(repetitions)) { if (this.run.get()) { logger.info { "Run repetition $i/$repetitions" } - executionIntervals.add(runSingleExperiment(load, res)) + executionIntervals.add(runSingleExperiment( + load, resource)) } else { break } @@ -60,13 +65,13 @@ class BenchmarkExecutorImpl( AnalysisExecutor(slo = it, executionId = executionId) .analyze( load = load, - res = res, + resource = resource, executionIntervals = executionIntervals ) } result = (false !in experimentResults) - this.results.setResult(Pair(load, res), result) + this.results.setResult(Pair(load, resource), result) } if(!this.run.get()) { @@ -76,11 +81,12 @@ class BenchmarkExecutorImpl( return result } - private fun runSingleExperiment(load: LoadDimension, res: Int): Pair<Instant, Instant> { - // TODO res muss eigentlich eine Resource (Int) + Patcher sein + private fun runSingleExperiment(load: Int, resource: Int): Pair<Instant, Instant> { val benchmarkDeployment = benchmark.buildDeployment( load, - res, + this.loadPatcherDefinitions, + resource, + this.resourcePatcherDefinitions, this.configurationOverrides, this.loadGenerationDelay, this.afterTeardownDelay @@ -95,7 +101,7 @@ class BenchmarkExecutorImpl( executionName = executionName, type = "NORMAL", reason = "Start experiment", - message = "load: ${load.get()}, resources: $res") + message = "load: $load, resources: $resource") } } catch (e: Exception) { this.run.set(false) @@ -105,7 +111,7 @@ class BenchmarkExecutorImpl( executionName = executionName, type = "WARNING", reason = "Start experiment failed", - message = "load: ${load.get()}, resources: $res") + message = "load: $load, resources: $resource") } throw ExecutionFailedException("Error during setup the experiment", e) } diff --git a/theodolite/src/main/kotlin/theodolite/execution/Shutdown.kt b/theodolite/src/main/kotlin/theodolite/execution/Shutdown.kt index a8a5a43be..f9f4b0335 100644 --- a/theodolite/src/main/kotlin/theodolite/execution/Shutdown.kt +++ b/theodolite/src/main/kotlin/theodolite/execution/Shutdown.kt @@ -3,8 +3,6 @@ package theodolite.execution import mu.KotlinLogging import theodolite.benchmark.BenchmarkExecution import theodolite.benchmark.KubernetesBenchmark -import theodolite.util.LoadDimension -import theodolite.util.Resources private val logger = KotlinLogging.logger {} @@ -27,8 +25,10 @@ class Shutdown(private val benchmarkExecution: BenchmarkExecution, private val b logger.info { "Received shutdown signal -> Shutting down" } val deployment = benchmark.buildDeployment( - load = LoadDimension(0, emptyList()), - res = Resources(listOf(0), emptyList()), + load = 0, + loadPatcherDefinitions = emptyList(), + resource = 0, + resourcePatcherDefinitions = emptyList(), configurationOverrides = benchmarkExecution.configOverrides, loadGenerationDelay = 0L, afterTeardownDelay = 5L diff --git a/theodolite/src/main/kotlin/theodolite/execution/TheodoliteExecutor.kt b/theodolite/src/main/kotlin/theodolite/execution/TheodoliteExecutor.kt index 4be0d94cb..8d5cfaf46 100644 --- a/theodolite/src/main/kotlin/theodolite/execution/TheodoliteExecutor.kt +++ b/theodolite/src/main/kotlin/theodolite/execution/TheodoliteExecutor.kt @@ -32,8 +32,8 @@ class TheodoliteExecutor( /** * Creates all required components to start Theodolite. * - * @return a [Config], that contains a list of [LoadDimension]s, - * a list of [Resource]s , and the [restrictionSearch]. + * @return a [Config], that contains a list of LoadDimension s, + * a list of Resource s , and the [restrictionSearch]. * The [searchStrategy] is configured and able to find the minimum required resource for the given load. */ private fun buildConfig(): Config { @@ -65,7 +65,9 @@ class TheodoliteExecutor( executionId = config.executionId, loadGenerationDelay = config.execution.loadGenerationDelay, afterTeardownDelay = config.execution.afterTeardownDelay, - executionName = config.name + executionName = config.name, + loadPatcherDefinitions = loadDimensionPatcherDefinition, + resourcePatcherDefinitions = resourcePatcherDefinition ) if (config.load.loadValues != config.load.loadValues.sorted()) { @@ -85,8 +87,10 @@ class TheodoliteExecutor( } return Config( - loads = config.load.loadValues.map { load -> LoadDimension(load, loadDimensionPatcherDefinition) }, - resources = Resources(config.resources.resourceValues, resourcePatcherDefinition), + loads = config.load.loadValues, + loadPatcherDefinitions = loadDimensionPatcherDefinition, + resources = config.resources.resourceValues, + resourcePatcherDefinitions = resourcePatcherDefinition, searchStrategy = strategyFactory.createSearchStrategy(executor, config.execution.strategy, results), metric = config.execution.metric ) @@ -120,12 +124,12 @@ class TheodoliteExecutor( //demand metric for (load in config.loads) { if (executor.run.get()) { - config.searchStrategy.findSuitableResource(load, config.resources.get()) + config.searchStrategy.findSuitableResource(load, config.resources) } } } else { //capacity metric - for (resource in config.resources.get()) { + for (resource in config.resources) { if (executor.run.get()) { config.searchStrategy.findSuitableLoad(resource, config.loads) } diff --git a/theodolite/src/main/kotlin/theodolite/strategies/StrategyFactory.kt b/theodolite/src/main/kotlin/theodolite/strategies/StrategyFactory.kt index 875e3e57f..5f9bb6a33 100644 --- a/theodolite/src/main/kotlin/theodolite/strategies/StrategyFactory.kt +++ b/theodolite/src/main/kotlin/theodolite/strategies/StrategyFactory.kt @@ -50,7 +50,7 @@ class StrategyFactory { * * @param results The [Results] saves the state of the Theodolite benchmark run. * @param restrictionStrings Specifies the list of [RestrictionStrategy] that are used to restrict the amount - * of [theodolite.util.Resources] for a fixed LoadDimension. Must equal the string + * of Resource for a fixed LoadDimension. Must equal the string * 'LowerBound'. * * @throws IllegalArgumentException if param searchStrategyString was not one of the allowed options. diff --git a/theodolite/src/main/kotlin/theodolite/strategies/restriction/LowerBoundRestriction.kt b/theodolite/src/main/kotlin/theodolite/strategies/restriction/LowerBoundRestriction.kt index 02ffea74e..6849d74fd 100644 --- a/theodolite/src/main/kotlin/theodolite/strategies/restriction/LowerBoundRestriction.kt +++ b/theodolite/src/main/kotlin/theodolite/strategies/restriction/LowerBoundRestriction.kt @@ -1,6 +1,5 @@ package theodolite.strategies.restriction -import theodolite.util.LoadDimension import theodolite.util.Results /** @@ -11,8 +10,8 @@ import theodolite.util.Results */ class LowerBoundRestriction(results: Results) : RestrictionStrategy(results) { - override fun apply(load: LoadDimension, resources: List<Int>): List<Int> { - val maxLoad: LoadDimension? = this.results.getMaxBenchmarkedLoad(load) + override fun apply(load: Int, resources: List<Int>): List<Int> { + val maxLoad: Int? = this.results.getMaxBenchmarkedLoad(load) var lowerBound: Int? = this.results.getMinRequiredInstances(maxLoad) if (lowerBound == null) { lowerBound = resources[0] diff --git a/theodolite/src/main/kotlin/theodolite/strategies/restriction/RestrictionStrategy.kt b/theodolite/src/main/kotlin/theodolite/strategies/restriction/RestrictionStrategy.kt index a1fe97a1e..963da39e9 100644 --- a/theodolite/src/main/kotlin/theodolite/strategies/restriction/RestrictionStrategy.kt +++ b/theodolite/src/main/kotlin/theodolite/strategies/restriction/RestrictionStrategy.kt @@ -1,8 +1,6 @@ package theodolite.strategies.restriction import io.quarkus.runtime.annotations.RegisterForReflection -import theodolite.util.LoadDimension -import theodolite.util.Resources import theodolite.util.Results /** @@ -16,10 +14,10 @@ abstract class RestrictionStrategy(val results: Results) { /** * Apply the restriction of the given resource list for the given load based on the results object. * - * @param load [LoadDimension] for which a subset of resources are required. - * @param resources List of [Resources]s to be restricted. + * @param load LoadDimension for which a subset of resources are required. + * @param resources List of Resource s to be restricted. * @return Returns a list containing only elements that have not been filtered out by the * restriction (possibly empty). */ - abstract fun apply(load: LoadDimension, resources: List<Int>): List<Int> + abstract fun apply(load: Int, resources: List<Int>): List<Int> } diff --git a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/BinarySearch.kt b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/BinarySearch.kt index 62bf12e2d..8aaa893b0 100644 --- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/BinarySearch.kt +++ b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/BinarySearch.kt @@ -1,10 +1,7 @@ package theodolite.strategies.searchstrategy import mu.KotlinLogging -import org.apache.kafka.common.protocol.types.Field import theodolite.execution.BenchmarkExecutor -import theodolite.util.LoadDimension -import theodolite.util.Resources private val logger = KotlinLogging.logger {} @@ -14,7 +11,7 @@ private val logger = KotlinLogging.logger {} * @param benchmarkExecutor Benchmark executor which runs the individual benchmarks. */ class BinarySearch(benchmarkExecutor: BenchmarkExecutor) : SearchStrategy(benchmarkExecutor) { - override fun findSuitableResource(load: LoadDimension, resources: List<Int>): Int? { + override fun findSuitableResource(load: Int, resources: List<Int>): Int? { val result = binarySearch(load, resources, 0, resources.size - 1, true) if (result == -1) { return null @@ -22,7 +19,7 @@ class BinarySearch(benchmarkExecutor: BenchmarkExecutor) : SearchStrategy(benchm return resources[result] } - override fun findSuitableLoad(resource: Int, loads: List<LoadDimension>): LoadDimension? { + override fun findSuitableLoad(resource: Int, loads: List<Int>): Int? { // TODO return null } @@ -35,7 +32,7 @@ class BinarySearch(benchmarkExecutor: BenchmarkExecutor) : SearchStrategy(benchm * @param lower lower bound for binary search (inclusive) * @param upper upper bound for binary search (inclusive) */ - private fun binarySearch(load: LoadDimension, resources: List<Int>, lower: Int, upper: Int, + private fun binarySearch(load: Int, resources: List<Int>, lower: Int, upper: Int, demand: Boolean): Int { if (lower > upper) { throw IllegalArgumentException() @@ -43,7 +40,7 @@ class BinarySearch(benchmarkExecutor: BenchmarkExecutor) : SearchStrategy(benchm // special case: length == 1 or 2 if (lower == upper) { val res = resources[lower] - logger.info { "Running experiment with load '${load.get()}' and resources '$res'" } + logger.info { "Running experiment with load '${load}' and resources '$res'" } if (this.benchmarkExecutor.runExperiment(load, resources[lower])) return lower else { if (lower + 1 == resources.size) return -1 @@ -54,7 +51,7 @@ class BinarySearch(benchmarkExecutor: BenchmarkExecutor) : SearchStrategy(benchm // length > 2 and adjust upper and lower depending on the result for `resources[mid]` val mid = (upper + lower) / 2 val res = resources[mid] - logger.info { "Running experiment with load '${load.get()}' and resources '$res'" } + logger.info { "Running experiment with load '${load}' and resources '$res'" } if (this.benchmarkExecutor.runExperiment(load, resources[mid])) { if (mid == lower) { return lower diff --git a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/FullSearch.kt b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/FullSearch.kt index 304297147..7f9158853 100644 --- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/FullSearch.kt +++ b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/FullSearch.kt @@ -2,8 +2,6 @@ package theodolite.strategies.searchstrategy import mu.KotlinLogging import theodolite.execution.BenchmarkExecutor -import theodolite.util.LoadDimension -import theodolite.util.Resources private val logger = KotlinLogging.logger {} @@ -17,12 +15,11 @@ private val logger = KotlinLogging.logger {} */ class FullSearch(benchmarkExecutor: BenchmarkExecutor) : SearchStrategy(benchmarkExecutor) { - override fun findSuitableResource(load: LoadDimension, resources: List<Int>): Int? { + override fun findSuitableResource(load: Int, resources: List<Int>): Int? { var minimalSuitableResources: Int? = null for (res in resources) { - logger.info { "Running experiment with load '${load.get()}' and resources '$res'" } + logger.info { "Running experiment with load '$load' and resources '$res'" } val result = this.benchmarkExecutor.runExperiment(load, res) - //TODO: that actually doesnt make sense no? Shouldnt it be == null? if (result && minimalSuitableResources == null) { minimalSuitableResources = res } @@ -30,10 +27,10 @@ class FullSearch(benchmarkExecutor: BenchmarkExecutor) : SearchStrategy(benchmar return minimalSuitableResources } - override fun findSuitableLoad(resource: Int, loads: List<LoadDimension>): LoadDimension? { - var maxSuitableLoad: LoadDimension? = null + override fun findSuitableLoad(resource: Int, loads: List<Int>): Int? { + var maxSuitableLoad: Int? = null for (load in loads) { - logger.info { "Running experiment with resources '$resource' and load '${load.get()}'" } + logger.info { "Running experiment with resources '$resource' and load '$load'" } if (this.benchmarkExecutor.runExperiment(load, resource)) maxSuitableLoad = load } return maxSuitableLoad diff --git a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/GuessStrategy.kt b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/GuessStrategy.kt index 68d42714a..f0686975e 100644 --- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/GuessStrategy.kt +++ b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/GuessStrategy.kt @@ -1,7 +1,6 @@ package theodolite.strategies.searchstrategy import io.quarkus.runtime.annotations.RegisterForReflection -import theodolite.util.Resources /** * Base class for the implementation of Guess strategies. Guess strategies are strategies to determine the resource @@ -13,7 +12,7 @@ abstract class GuessStrategy { /** * Computing the resource demand for the initial guess search strategy to start with. * - * @param resources List of all possible [Resources]s. + * @param resources List of all possible resources. * @param lastLowestResource Previous resource demand needed for the given load. * * @return Returns the resource demand to start the initial guess search strategy with or null diff --git a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/InitialGuessSearchStrategy.kt b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/InitialGuessSearchStrategy.kt index 56e57dde8..dd74b7e19 100644 --- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/InitialGuessSearchStrategy.kt +++ b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/InitialGuessSearchStrategy.kt @@ -2,8 +2,6 @@ package theodolite.strategies.searchstrategy import mu.KotlinLogging import theodolite.execution.BenchmarkExecutor -import theodolite.util.LoadDimension -import theodolite.util.Resources import theodolite.util.Results private val logger = KotlinLogging.logger {} @@ -19,7 +17,7 @@ private val logger = KotlinLogging.logger {} class InitialGuessSearchStrategy(benchmarkExecutor: BenchmarkExecutor, guessStrategy: GuessStrategy, results: Results) : SearchStrategy(benchmarkExecutor, guessStrategy, results) { - override fun findSuitableResource(load: LoadDimension, resources: List<Int>): Int? { + override fun findSuitableResource(load: Int, resources: List<Int>): Int? { if(resources.isEmpty()) { logger.info { "You need to specify resources to be checked for the InitialGuessSearchStrategy to work." } @@ -41,7 +39,7 @@ class InitialGuessSearchStrategy(benchmarkExecutor: BenchmarkExecutor, guessStra // Getting the lastLowestResource from results and calling firstGuess() with it if (!results.isEmpty()) { - val maxLoad: LoadDimension? = this.results.getMaxBenchmarkedLoad(load) + val maxLoad: Int? = this.results.getMaxBenchmarkedLoad(load) lastLowestResource = this.results.getMinRequiredInstances(maxLoad) if (lastLowestResource == Int.MAX_VALUE) lastLowestResource = null } @@ -51,7 +49,7 @@ class InitialGuessSearchStrategy(benchmarkExecutor: BenchmarkExecutor, guessStra val resourcesToCheck: List<Int> val startIndex: Int = resources.indexOf(lastLowestResource) - logger.info { "Running experiment with load '${load.get()}' and resources '$lastLowestResource'" } + logger.info { "Running experiment with load '${load}' and resources '$lastLowestResource'" } // If the first experiment passes, starting downward linear search // otherwise starting upward linear search @@ -63,7 +61,7 @@ class InitialGuessSearchStrategy(benchmarkExecutor: BenchmarkExecutor, guessStra var currentMin: Int = lastLowestResource for (res in resourcesToCheck) { - logger.info { "Running experiment with load '${load.get()}' and resources '$res'" } + logger.info { "Running experiment with load '${load}' and resources '$res'" } if (this.benchmarkExecutor.runExperiment(load, res)) { currentMin = res } @@ -79,7 +77,7 @@ class InitialGuessSearchStrategy(benchmarkExecutor: BenchmarkExecutor, guessStra for (res in resourcesToCheck) { - logger.info { "Running experiment with load '${load.get()}' and resources '$res'" } + logger.info { "Running experiment with load '${load}' and resources '$res'" } if (this.benchmarkExecutor.runExperiment(load, res)) return res } } @@ -91,7 +89,7 @@ class InitialGuessSearchStrategy(benchmarkExecutor: BenchmarkExecutor, guessStra return null } - override fun findSuitableLoad(resource: Int, loads: List<LoadDimension>): LoadDimension? { + override fun findSuitableLoad(resource: Int, loads: List<Int>): Int? { TODO("Not yet implemented") } } \ No newline at end of file diff --git a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/LinearSearch.kt b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/LinearSearch.kt index 0e8aaf6dd..c4497934b 100644 --- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/LinearSearch.kt +++ b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/LinearSearch.kt @@ -2,8 +2,6 @@ package theodolite.strategies.searchstrategy import mu.KotlinLogging import theodolite.execution.BenchmarkExecutor -import theodolite.util.LoadDimension -import theodolite.util.Resources private val logger = KotlinLogging.logger {} @@ -14,9 +12,9 @@ private val logger = KotlinLogging.logger {} */ class LinearSearch(benchmarkExecutor: BenchmarkExecutor) : SearchStrategy(benchmarkExecutor) { - override fun findSuitableResource(load: LoadDimension, resources: List<Int>): Int? { + override fun findSuitableResource(load: Int, resources: List<Int>): Int? { for (res in resources) { - logger.info { "Running experiment with load '${load.get()}' and resources '$res'" } + logger.info { "Running experiment with load '$load' and resources '$res'" } if (this.benchmarkExecutor.runExperiment(load, res)) return res } return null @@ -24,10 +22,10 @@ class LinearSearch(benchmarkExecutor: BenchmarkExecutor) : SearchStrategy(benchm // Stops after having the first load which is not possible anymore with the current resource, maybe some later load still possible tho // kinda like GuessSearchStrat case -> differentiate or is it fine like that? - override fun findSuitableLoad(resource: Int, loads: List<LoadDimension>): LoadDimension? { - var maxSuitableLoad: LoadDimension? = null + override fun findSuitableLoad(resource: Int, loads: List<Int>): Int? { + var maxSuitableLoad: Int? = null for (load in loads) { - logger.info { "Running experiment with resources '$resource' and load '${load.get()}'" } + logger.info { "Running experiment with resources '$resource' and load '$load'" } if (this.benchmarkExecutor.runExperiment(load, resource)) { maxSuitableLoad = load } else break diff --git a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/PrevResourceMinGuess.kt b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/PrevResourceMinGuess.kt index 250f25b1e..bc18982f1 100644 --- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/PrevResourceMinGuess.kt +++ b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/PrevResourceMinGuess.kt @@ -1,6 +1,5 @@ package theodolite.strategies.searchstrategy -import theodolite.util.Resources /** * This Guess strategy takes the minimal resource demand of the previous load, which is given as an argument for the @@ -10,7 +9,7 @@ import theodolite.util.Resources class PrevResourceMinGuess() : GuessStrategy(){ /** - * @param resources List of all possible [Resources]s. + * @param resources List of all possible Resources. * @param lastLowestResource Previous resource demand needed for the given load. * * @return the value of lastLowestResource if given otherwise the first element of the resource list or null diff --git a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/RestrictionSearch.kt b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/RestrictionSearch.kt index fa18785f9..8394e4739 100644 --- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/RestrictionSearch.kt +++ b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/RestrictionSearch.kt @@ -3,14 +3,12 @@ package theodolite.strategies.searchstrategy import io.quarkus.runtime.annotations.RegisterForReflection import theodolite.execution.BenchmarkExecutor import theodolite.strategies.restriction.RestrictionStrategy -import theodolite.util.LoadDimension -import theodolite.util.Resources /** * Strategy that combines a SearchStrategy and a set of RestrictionStrategy. * * @param searchStrategy the [SearchStrategy] that is executed as part of this [RestrictionSearch]. - * @param restrictionStrategies the set of [RestrictionStrategy] that are connected conjunctive to restrict the [Resources] + * @param restrictionStrategies the set of [RestrictionStrategy] that are connected conjunctive to restrict the Resource * @param benchmarkExecutor Benchmark executor which runs the individual benchmarks. */ @RegisterForReflection @@ -20,7 +18,7 @@ class RestrictionSearch( val restrictionStrategies: Set<RestrictionStrategy> ) : SearchStrategy(benchmarkExecutor) { - override fun findSuitableResource(load: LoadDimension, resources: List<Int>): Int? { + override fun findSuitableResource(load: Int, resources: List<Int>): Int? { var restrictedResources = resources for (strategy in this.restrictionStrategies) { restrictedResources = restrictedResources.intersect(strategy.apply(load, resources)).toList() @@ -29,7 +27,7 @@ class RestrictionSearch( } //TODO: not sure if it makes sense but actually doing the same as for finding suitable resource with the restrictions - override fun findSuitableLoad(resource: Int, loads: List<LoadDimension>): LoadDimension? { + override fun findSuitableLoad(resource: Int, loads: List<Int>): Int? { //erste Zeile komisch, wird auch bei resource so gemacht aber warum? das ist doch ne liste warum also toList? TODO("Not yet implemented") } diff --git a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/SearchStrategy.kt b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/SearchStrategy.kt index 961c71d0e..31f9deed5 100644 --- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/SearchStrategy.kt +++ b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/SearchStrategy.kt @@ -2,8 +2,6 @@ package theodolite.strategies.searchstrategy import io.quarkus.runtime.annotations.RegisterForReflection import theodolite.execution.BenchmarkExecutor -import theodolite.util.LoadDimension -import theodolite.util.Resources import theodolite.util.Results /** @@ -19,20 +17,21 @@ abstract class SearchStrategy(val benchmarkExecutor: BenchmarkExecutor, val gues /** * Find smallest suitable resource from the specified resource list for the given load. * - * @param load the [LoadDimension] to be tested. - * @param resources List of all possible [Resource]s. + * @param load the load to be tested. + * @param resources List of all possible resources. * * @return suitable resource for the specified load, or null if no suitable resource exists. */ - abstract fun findSuitableResource(load: LoadDimension, resources: List<Int>): Int? + abstract fun findSuitableResource(load: Int, resources: List<Int>): Int? + // TODO findSuitableLoad und findSuitableResource zusammenfuehren? /** * Find biggest suitable load from the specified load list for the given resource amount. * - * @param resource the [Resource] to be tested. - * @param loads List of all possible [LoadDimension]s. + * @param resource the resource to be tested. + * @param loads List of all possible loads. * * @return suitable load for the specified resource amount, or null if no suitable load exists. */ - abstract fun findSuitableLoad(resource: Int, loads: List<LoadDimension>) : LoadDimension? + abstract fun findSuitableLoad(resource: Int, loads: List<Int>) : Int? } diff --git a/theodolite/src/main/kotlin/theodolite/util/Config.kt b/theodolite/src/main/kotlin/theodolite/util/Config.kt index 9b9cd81a8..00ccaf339 100644 --- a/theodolite/src/main/kotlin/theodolite/util/Config.kt +++ b/theodolite/src/main/kotlin/theodolite/util/Config.kt @@ -6,15 +6,17 @@ import theodolite.strategies.searchstrategy.SearchStrategy /** * Config class that represents a configuration of a theodolite run. * - * @param loads the [LoadDimension] of the execution - * @param resources the [Resources] of the execution + * @param loads the LoadDimension of the execution + * @param resources the Resource of the execution * @param searchStrategy the [SearchStrategy] of the execution * @param metric the Metric of the execution */ @RegisterForReflection data class Config( - val loads: List<LoadDimension>, - val resources: Resources, + val loads: List<Int>, + val loadPatcherDefinitions : List<PatcherDefinition>, + val resources: List<Int>, + val resourcePatcherDefinitions : List<PatcherDefinition>, val searchStrategy: SearchStrategy, val metric: String ) diff --git a/theodolite/src/main/kotlin/theodolite/util/LoadDimension.kt b/theodolite/src/main/kotlin/theodolite/util/LoadDimension.kt deleted file mode 100644 index cf26da979..000000000 --- a/theodolite/src/main/kotlin/theodolite/util/LoadDimension.kt +++ /dev/null @@ -1,26 +0,0 @@ -package theodolite.util - -import io.quarkus.runtime.annotations.RegisterForReflection - -/** - * Representation of the load dimensions for a execution of theodolite. - * - * @param number the value of this [LoadDimension] - * @param type [PatcherDefinition] of this [LoadDimension] - */ -@RegisterForReflection -data class LoadDimension(private val number: Int, private val type: List<PatcherDefinition>) { - /** - * @return the value of this load dimension. - */ - fun get(): Int { - return this.number - } - - /** - * @return the list of [PatcherDefinition] - */ - fun getType(): List<PatcherDefinition> { - return this.type - } -} diff --git a/theodolite/src/main/kotlin/theodolite/util/Resources.kt b/theodolite/src/main/kotlin/theodolite/util/Resources.kt deleted file mode 100644 index 6315913a4..000000000 --- a/theodolite/src/main/kotlin/theodolite/util/Resources.kt +++ /dev/null @@ -1,31 +0,0 @@ -package theodolite.util - -import io.quarkus.runtime.annotations.RegisterForReflection - -/** - * Representation of the resources for an execution of Theodolite. - */ -@RegisterForReflection -data class Resources(private val resourceList: List<Int>, private val type: List<PatcherDefinition>) { - - /** - * @return the list of resources. - */ - fun get(): List<Int> { - return this.resourceList - } - - /** - * @return the resource at a given Index. - */ - fun getIndex(i: Int): Int { - return this.resourceList[i] - } - - /** - * @return the list of [PatcherDefinition] - */ - fun getType(): List<PatcherDefinition> { - return this.type - } -} diff --git a/theodolite/src/main/kotlin/theodolite/util/Results.kt b/theodolite/src/main/kotlin/theodolite/util/Results.kt index 8ed951b2b..c1d6ce8fd 100644 --- a/theodolite/src/main/kotlin/theodolite/util/Results.kt +++ b/theodolite/src/main/kotlin/theodolite/util/Results.kt @@ -9,42 +9,41 @@ import io.quarkus.runtime.annotations.RegisterForReflection */ @RegisterForReflection class Results { - private val results: MutableMap<Pair<LoadDimension, Int>, Boolean> = mutableMapOf() + private val results: MutableMap<Pair<Int, Int>, Boolean> = mutableMapOf() /** * Set the result for an experiment. * - * @param experiment A pair that identifies the experiment by the [LoadDimension] and [Resources]. + * @param experiment A pair that identifies the experiment by the LoadDimension and Resource. * @param successful the result of the experiment. Successful == true and Unsuccessful == false. */ - fun setResult(experiment: Pair<LoadDimension, Int>, successful: Boolean) { + fun setResult(experiment: Pair<Int, Int>, successful: Boolean) { this.results[experiment] = successful } /** * Get the result for an experiment. * - * @param experiment A pair that identifies the experiment by the [LoadDimension] and [Resources]. + * @param experiment A pair that identifies the experiment by the LoadDimension and Resource. * @return true if the experiment was successful and false otherwise. If the result has not been reported so far, * null is returned. * - * @see Resources */ - fun getResult(experiment: Pair<LoadDimension, Int>): Boolean? { + fun getResult(experiment: Pair<Int, Int>): Boolean? { return this.results[experiment] } /** - * Get the smallest suitable number of instances for a specified [LoadDimension]. + * Get the smallest suitable number of instances for a specified LoadDimension. * - * @param load the [LoadDimension] + * @param load the LoadDimension * * @return the smallest suitable number of resources. If the experiment was not executed yet, * a @see Resource with the constant Int.MAX_VALUE as value is returned. * If no experiments have been marked as either successful or unsuccessful * yet, a Resource with the constant value Int.MIN_VALUE is returned. */ - fun getMinRequiredInstances(load: LoadDimension?): Int { + fun getMinRequiredInstances(load: Int?): Int { if (this.results.isEmpty()) { return Int.MIN_VALUE } @@ -63,20 +62,20 @@ class Results { } /** - * Get the largest [LoadDimension] that has been reported executed successfully (or unsuccessfully) so far, for a - * [LoadDimension] and is smaller than the given [LoadDimension]. + * Get the largest LoadDimension that has been reported executed successfully (or unsuccessfully) so far, for a + * LoadDimension and is smaller than the given LoadDimension. * - * @param load the [LoadDimension] + * @param load the LoadDimension * - * @return the largest [LoadDimension] or null, if there is none for this [LoadDimension] + * @return the largest LoadDimension or null, if there is none for this LoadDimension */ - fun getMaxBenchmarkedLoad(load: LoadDimension): LoadDimension? { - var maxBenchmarkedLoad: LoadDimension? = null + fun getMaxBenchmarkedLoad(load: Int): Int? { + var maxBenchmarkedLoad: Int? = null for (experiment in results) { - if (experiment.key.first.get() <= load.get()) { + if (experiment.key.first <= load) { if (maxBenchmarkedLoad == null) { maxBenchmarkedLoad = experiment.key.first - } else if (maxBenchmarkedLoad.get() < experiment.key.first.get()) { + } else if (maxBenchmarkedLoad < experiment.key.first) { maxBenchmarkedLoad = experiment.key.first } } diff --git a/theodolite/src/test/kotlin/theodolite/InitialGuessSearchStrategyTest.kt b/theodolite/src/test/kotlin/theodolite/InitialGuessSearchStrategyTest.kt index 93816132a..fa68adeb2 100644 --- a/theodolite/src/test/kotlin/theodolite/InitialGuessSearchStrategyTest.kt +++ b/theodolite/src/test/kotlin/theodolite/InitialGuessSearchStrategyTest.kt @@ -5,7 +5,6 @@ import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test import theodolite.benchmark.BenchmarkExecution import theodolite.strategies.searchstrategy.InitialGuessSearchStrategy -import theodolite.util.LoadDimension import theodolite.util.Results import mu.KotlinLogging import theodolite.strategies.searchstrategy.PrevResourceMinGuess @@ -26,7 +25,7 @@ class InitialGuessSearchStrategyTest { arrayOf(false, false, false, false, false, false, true), arrayOf(false, false, false, false, false, false, false) ) - val mockLoads: List<LoadDimension> = (0..6).map { number -> LoadDimension(number, emptyList()) } + val mockLoads: List<Int> = (0..6).toList() val mockResources: List<Int> = (0..6).toList() val results = Results() val benchmark = TestBenchmark() @@ -64,7 +63,7 @@ class InitialGuessSearchStrategyTest { arrayOf(false, false, false, false, false, false, true), arrayOf(false, false, false, false, false, false, false) ) - val mockLoads: List<LoadDimension> = (0..6).map { number -> LoadDimension(number, emptyList()) } + val mockLoads: List<Int> = (0..6).toList() val mockResources: List<Int> = (0..6).toList() val results = Results() val benchmark = TestBenchmark() @@ -102,7 +101,7 @@ class InitialGuessSearchStrategyTest { arrayOf(false, false, false, false, false, false, true), arrayOf(false, false, false, false, false, false, false) ) - val mockLoads: List<LoadDimension> = (0..6).map { number -> LoadDimension(number, emptyList()) } + val mockLoads: List<Int> = (0..6).toList() val mockResources: List<Int> = (0..6).toList() val results = Results() val benchmark = TestBenchmark() diff --git a/theodolite/src/test/kotlin/theodolite/RestrictionSearchTest.kt b/theodolite/src/test/kotlin/theodolite/RestrictionSearchTest.kt index aeeaa19a1..13d6b8faf 100644 --- a/theodolite/src/test/kotlin/theodolite/RestrictionSearchTest.kt +++ b/theodolite/src/test/kotlin/theodolite/RestrictionSearchTest.kt @@ -6,9 +6,9 @@ import org.junit.jupiter.api.Test import theodolite.benchmark.BenchmarkExecution import theodolite.strategies.restriction.LowerBoundRestriction import theodolite.strategies.searchstrategy.BinarySearch +import theodolite.strategies.searchstrategy.FullSearch import theodolite.strategies.searchstrategy.RestrictionSearch import theodolite.strategies.searchstrategy.LinearSearch -import theodolite.util.LoadDimension import theodolite.util.Results @QuarkusTest @@ -26,7 +26,7 @@ class RestrictionSearchTest { arrayOf(false, false, false, false, false, false, true), arrayOf(false, false, false, false, false, false, false) ) - val mockLoads: List<LoadDimension> = (0..6).map { number -> LoadDimension(number, emptyList()) } + val mockLoads: List<Int> = (0..6).toList() val mockResources: List<Int> = (0..6).toList() val results = Results() val benchmark = TestBenchmark() @@ -48,6 +48,39 @@ class RestrictionSearchTest { assertEquals(actual, expected) } + @Test + fun restrictionSearchTestFullSearch() { + val mockResults = arrayOf( + arrayOf(true, true, true, true, true, true, true), + arrayOf(false, false, true, true, true, true, true), + arrayOf(false, false, true, true, true, true, true), + arrayOf(false, false, false, true, true, true, true), + arrayOf(false, false, false, false, true, true, true), + arrayOf(false, false, false, false, false, false, true), + arrayOf(false, false, false, false, false, false, false) + ) + val mockLoads: List<Int> = (0..6).toList() + val mockResources: List<Int> = (0..6).toList() + val results = Results() + val benchmark = TestBenchmark() + val sloChecker: BenchmarkExecution.Slo = BenchmarkExecution.Slo() + val benchmarkExecutor = TestBenchmarkExecutorImpl(mockResults, benchmark, results, listOf(sloChecker), 0, 0, 5) + val fullSearch = FullSearch(benchmarkExecutor) + val lowerBoundRestriction = LowerBoundRestriction(results) + val strategy = + RestrictionSearch(benchmarkExecutor, fullSearch, setOf(lowerBoundRestriction)) + + val actual: ArrayList<Int?> = ArrayList() + val expected: ArrayList<Int?> = ArrayList(listOf(0, 2, 2, 3, 4, 6)) + expected.add(null) + + for (load in mockLoads) { + actual.add(strategy.findSuitableResource(load, mockResources)) + } + + assertEquals(actual, expected) + } + @Test fun restrictionSearchTestBinarySearch() { val mockResults = arrayOf( @@ -59,7 +92,7 @@ class RestrictionSearchTest { arrayOf(false, false, false, false, false, false, true), arrayOf(false, false, false, false, false, false, false) ) - val mockLoads: List<LoadDimension> = (0..6).map { number -> LoadDimension(number, emptyList()) } + val mockLoads: List<Int> = (0..6).toList() val mockResources: List<Int> = (0..6).toList() val results = Results() val benchmark = TestBenchmark() @@ -92,7 +125,7 @@ class RestrictionSearchTest { arrayOf(false, false, false, false, false, false, true, true), arrayOf(false, false, false, false, false, false, false, true) ) - val mockLoads: List<LoadDimension> = (0..6).map { number -> LoadDimension(number, emptyList()) } + val mockLoads: List<Int> = (0..6).toList() val mockResources: List<Int> = (0..7).toList() val results = Results() val benchmark = TestBenchmark() diff --git a/theodolite/src/test/kotlin/theodolite/TestBenchmark.kt b/theodolite/src/test/kotlin/theodolite/TestBenchmark.kt index 16e3293ab..335b0f8c5 100644 --- a/theodolite/src/test/kotlin/theodolite/TestBenchmark.kt +++ b/theodolite/src/test/kotlin/theodolite/TestBenchmark.kt @@ -3,8 +3,7 @@ package theodolite import theodolite.benchmark.Benchmark import theodolite.benchmark.BenchmarkDeployment import theodolite.util.ConfigurationOverride -import theodolite.util.LoadDimension -import theodolite.util.Resources +import theodolite.util.PatcherDefinition class TestBenchmark : Benchmark { @@ -15,8 +14,10 @@ class TestBenchmark : Benchmark { } override fun buildDeployment( - load: LoadDimension, - res: Resources, + load: Int, + loadPatcherDefinitions: List<PatcherDefinition>, + resource: Int, + resourcePatcherDefinitions: List<PatcherDefinition>, configurationOverrides: List<ConfigurationOverride?>, loadGenerationDelay: Long, afterTeardownDelay: Long diff --git a/theodolite/src/test/kotlin/theodolite/TestBenchmarkExecutorImpl.kt b/theodolite/src/test/kotlin/theodolite/TestBenchmarkExecutorImpl.kt index e7e943efb..a5346896f 100644 --- a/theodolite/src/test/kotlin/theodolite/TestBenchmarkExecutorImpl.kt +++ b/theodolite/src/test/kotlin/theodolite/TestBenchmarkExecutorImpl.kt @@ -3,8 +3,6 @@ package theodolite import theodolite.benchmark.Benchmark import theodolite.benchmark.BenchmarkExecution import theodolite.execution.BenchmarkExecutor -import theodolite.util.LoadDimension -import theodolite.util.Resources import theodolite.util.Results import java.time.Duration @@ -27,12 +25,14 @@ class TestBenchmarkExecutorImpl( executionId = executionId, loadGenerationDelay = loadGenerationDelay, afterTeardownDelay = afterTeardownDelay, - executionName = "test-execution" + executionName = "test-execution", + loadPatcherDefinitions = emptyList(), + resourcePatcherDefinitions = emptyList() ) { - override fun runExperiment(load: LoadDimension, res: Resources): Boolean { - val result = this.mockResults[load.get()][res.get()] - this.results.setResult(Pair(load, res), result) + override fun runExperiment(load: Int, resource: Int): Boolean { + val result = this.mockResults[load][resource] + this.results.setResult(Pair(load, resource), result) return result } } diff --git a/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionCRDummy.kt b/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionCRDummy.kt index 51347d41b..8f3fcf788 100644 --- a/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionCRDummy.kt +++ b/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionCRDummy.kt @@ -35,13 +35,21 @@ class ExecutionCRDummy(name: String, benchmark: String) { resourceDef.resourceType = "" resourceDef.resourceValues = emptyList() + val strat = BenchmarkExecution.Strategy() + strat.name = "" + strat.restrictions = emptyList() + strat.guessStrategy = "" + strat.searchStrategy = "" + + val exec = BenchmarkExecution.Execution() exec.afterTeardownDelay = 0 exec.duration = 0 exec.loadGenerationDelay = 0 exec.repetitions = 1 - exec.restrictions = emptyList() - exec.strategy = "" + exec.metric = "" + exec.strategy = strat + execution.benchmark = benchmark execution.load = loadType diff --git a/theodolite/src/test/kotlin/theodolite/strategies/restriction/LowerBoundRestrictionTest.kt b/theodolite/src/test/kotlin/theodolite/strategies/restriction/LowerBoundRestrictionTest.kt index 0ee4eab28..78d69cc8b 100644 --- a/theodolite/src/test/kotlin/theodolite/strategies/restriction/LowerBoundRestrictionTest.kt +++ b/theodolite/src/test/kotlin/theodolite/strategies/restriction/LowerBoundRestrictionTest.kt @@ -4,8 +4,6 @@ import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertNotNull import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test -import theodolite.util.LoadDimension -import theodolite.util.Resources import theodolite.util.Results internal class LowerBoundRestrictionTest { @@ -14,12 +12,8 @@ internal class LowerBoundRestrictionTest { fun testNoPreviousResults() { val results = Results() val strategy = LowerBoundRestriction(results) - val load = buildLoadDimension(10000) - val resources = listOf( - buildResourcesDimension(1), - buildResourcesDimension(2), - buildResourcesDimension(3) - ) + val load = 10000 + val resources = listOf(1, 2, 3) val restriction = strategy.apply(load, resources) assertEquals(3, restriction.size) @@ -33,12 +27,8 @@ internal class LowerBoundRestrictionTest { results.setResult(20000, 1, false) results.setResult(20000, 2, true) val strategy = LowerBoundRestriction(results) - val load = buildLoadDimension(30000) - val resources = listOf( - buildResourcesDimension(1), - buildResourcesDimension(2), - buildResourcesDimension(3) - ) + val load = 30000 + val resources = listOf(1, 2, 3) val restriction = strategy.apply(load, resources) assertEquals(2, restriction.size) @@ -55,16 +45,12 @@ internal class LowerBoundRestrictionTest { results.setResult(20000, 2, false) results.setResult(20000, 3, false) val strategy = LowerBoundRestriction(results) - val load = buildLoadDimension(30000) - val resources = listOf( - buildResourcesDimension(1), - buildResourcesDimension(2), - buildResourcesDimension(3) - ) + val load = 30000 + val resources = listOf(1, 2, 3) val restriction = strategy.apply(load, resources) assertEquals(0, restriction.size) - assertEquals(emptyList<Resources>(), restriction) + assertEquals(emptyList<Int>(), restriction) } @@ -76,7 +62,7 @@ internal class LowerBoundRestrictionTest { results.setResult(10000, 1, false) results.setResult(20000, 2, true) - val minRequiredInstances = results.getMinRequiredInstances(LoadDimension(20000, emptyList())) + val minRequiredInstances = results.getMinRequiredInstances(20000) assertNotNull(minRequiredInstances) assertEquals(2, minRequiredInstances!!) @@ -92,27 +78,15 @@ internal class LowerBoundRestrictionTest { results.setResult(10000, 1, false) results.setResult(20000, 2, false) - val minRequiredInstances = results.getMinRequiredInstances(LoadDimension(20000, emptyList())) + val minRequiredInstances = results.getMinRequiredInstances(20000) assertNotNull(minRequiredInstances) assertEquals(2, minRequiredInstances!!) } - private fun buildLoadDimension(load: Int): LoadDimension { - return LoadDimension(load, emptyList()) - } - private fun buildResourcesDimension(resources: Int): Int { - return resources - } - private fun Results.setResult(load: Int, resources: Int, successful: Boolean) { - this.setResult( - Pair( - buildLoadDimension(load), - buildResourcesDimension(resources) - ), - successful - ) + private fun Results.setResult(load: Int, resource: Int, successful: Boolean) { + this.setResult(Pair(load, resource),successful) } } diff --git a/theodolite/src/test/kotlin/theodolite/util/IOHandlerTest.kt b/theodolite/src/test/kotlin/theodolite/util/IOHandlerTest.kt index 3960e52dd..3bebd8432 100644 --- a/theodolite/src/test/kotlin/theodolite/util/IOHandlerTest.kt +++ b/theodolite/src/test/kotlin/theodolite/util/IOHandlerTest.kt @@ -69,14 +69,14 @@ internal class IOHandlerTest { fun testWriteToJSONFile() { temporaryFolder.create() val folder = temporaryFolder.newFolder(FOLDER_URL) - val testContent = Resources(0, emptyList()) + val testContentResource = 0 IOHandler().writeToJSONFile( fileURL = "${folder.absolutePath}/test-file.json", - objectToSave = testContent + objectToSave = testContentResource ) - val expected = GsonBuilder().enableComplexMapKeySerialization().setPrettyPrinting().create().toJson(testContent) + val expected = GsonBuilder().enableComplexMapKeySerialization().setPrettyPrinting().create().toJson(testContentResource) assertEquals( expected, diff --git a/theodolite/src/test/kotlin/theodolite/util/ResultsTest.kt b/theodolite/src/test/kotlin/theodolite/util/ResultsTest.kt index 0cdcf8631..9bce37a3c 100644 --- a/theodolite/src/test/kotlin/theodolite/util/ResultsTest.kt +++ b/theodolite/src/test/kotlin/theodolite/util/ResultsTest.kt @@ -17,10 +17,10 @@ internal class ResultsTest { results.setResult(20000, 1, false) results.setResult(20000, 2, true) - val minRequiredInstances = results.getMinRequiredInstances(LoadDimension(20000, emptyList())) + val minRequiredInstances = results.getMinRequiredInstances(20000) assertNotNull(minRequiredInstances) - assertEquals(2, minRequiredInstances!!.get()) + assertEquals(2, minRequiredInstances!!) } @Test @@ -33,20 +33,14 @@ internal class ResultsTest { results.setResult(20000, 1, false) results.setResult(20000, 2, false) - val minRequiredInstances = results.getMinRequiredInstances(LoadDimension(20000, emptyList())) + val minRequiredInstances = results.getMinRequiredInstances(20000) assertNotNull(minRequiredInstances) - assertEquals(2, minRequiredInstances!!.get()) + assertEquals(2, minRequiredInstances!!) } - private fun Results.setResult(load: Int, resources: Int, successful: Boolean) { - this.setResult( - Pair( - LoadDimension(load, emptyList()), - Resources(resources, emptyList()) - ), - successful - ) + private fun Results.setResult(load: Int, resource: Int, successful: Boolean) { + this.setResult(Pair(load, resource), successful) } @@ -56,7 +50,7 @@ internal class ResultsTest { results.setResult(10000, 1, true) results.setResult(10000, 2, true) - val test1 = results.getMaxBenchmarkedLoad(LoadDimension(100000, emptyList()))!!.get() + val test1 = results.getMaxBenchmarkedLoad(100000)!! assertEquals(10000, test1) } @@ -68,7 +62,7 @@ internal class ResultsTest { results.setResult(10000, 2, true) results.setResult(20000, 1, false) - val test2 = results.getMaxBenchmarkedLoad(LoadDimension(100000, emptyList()))!!.get() + val test2 = results.getMaxBenchmarkedLoad(100000)!! assertEquals(20000, test2) } -- GitLab