diff --git a/theodolite/crd/crd-execution.yaml b/theodolite/crd/crd-execution.yaml index 185b0b494617f2714051b3d5dbe1d01adb039777..fb90402be25b4d49cb9db7497175da6d77959852 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 6f07c7a3bd210f52fff77fcc806d2517743e5887..cd6e05e49b30ed8605ad547d52ad194b9ea5324a 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 b27533419a1e1d08eb52aa2deaa834462f2b5c27..b5dd15623a288a79288603a91e91ee428b1e0916 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 d41618cbc546327457e89aadc417f2fcac49b7c2..cb5433a4d4dcc6e2cde6e613c87dc32e89b80f90 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 6ae360e0de455837610d2436be0bf64171125d05..b46fc474ffc672010bfdb0878e8db3308dcecab8 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 64f9110cd931feef41dc65f88d6623e82f4e03a2..96893c4deaaccb9c0c68af37ba6d20043722cb47 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 fb6c7201910cb23f054fc42a254e36dff6886421..470f63fcdb939e74b7c2b87043da6867481400a0 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 f51a4a8420eaf833339d51a2d4810ef6094cb2ce..733e3ea61396eba34febc92d96b5a868dd84cb7f 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 a8a5a43bed375c1e322ab5ccb414c842487e0597..f9f4b03356ffbaa847c008db4613a61efeca090b 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 4be0d94cb6670f49fdb4aed0aa934043f67b8e0c..8d5cfaf468c3660cf9be2de30d80df2b9cdf615b 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 875e3e57f4720b84962454ff68f81bc84d7b8b14..5f9bb6a330398f4f6d7001b01b1e2ad7dea53e9b 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 02ffea74ead668e97b718609bfec1145606a85d3..6849d74fd5caf09077922fdefca7cabda87128a0 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 a1fe97a1e8523ef3fbf6a9d1212535d470fb7401..963da39e9dc30955a6300f240b9d293ebe1ee15c 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 62bf12e2d795edd645cfaa55014af4cb1126ab69..8aaa893b070caef0dcfbf6bbe33d99eb84f589e3 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 304297147e463f3a431b9c0da826fa45350f99ff..7f9158853fd77264686f54c47f0ef60633d30d35 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 68d42714a1f2e9cf1a8f95c49d55b5b80fef2c21..f0686975e1fb8f1ac29592621ab4f4b6d04ca3ae 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 56e57dde856a572ed800eeea7e49a1029eccaf60..dd74b7e19dc291f200c0144fba3de4d603115061 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 0e8aaf6ddb05ca171f8d2da157b5bd1010159449..c4497934b91ce958b497e8749b78b5ce6f9f0620 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 250f25b1e77d6667eb0b1de4ae55c2f6a30ee69a..bc18982f15fcf642a35f1d300264c53afab5dfeb 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 fa18785f92e63efcc172977ee321aef6c90a05ad..8394e47391793f8c0c1855ac6e5fb859650428a2 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 961c71d0edcc3885eb9dae2d308cfce4cee9dc75..31f9deed59283698085cc31090029c7f3730492e 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 9b9cd81a8352a0843b5ee8c7dba770df750a054f..00ccaf339f83c80623c89cf5408f985ad8390c32 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 cf26da979b05f0a2bd82289ce371715ea0d67c93..0000000000000000000000000000000000000000 --- 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 6315913a489113e059646fb98d119dda023df92f..0000000000000000000000000000000000000000 --- 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 8ed951b2b7e5bea225be165c0c810880e32b355d..c1d6ce8fda3b8eb4e5ace7d748d715224845586f 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 93816132a7e52ee266c3bd473b861aa89964c4e1..fa68adeb2fee6e785194c295afb84c09d3163de5 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 aeeaa19a11c856b8310c435b301af4f79f8f3ade..13d6b8fafba4d8a35406f934752f4482c9c211f0 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 16e3293ab17a4cf6c05ddb740c1cf0a1173752fe..335b0f8c59ac7642c30a12e494890e8f2c52ccda 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 e7e943efbbbe75f58eab04f865b415a35bac16d0..a5346896f6d20b6d9c0a828d2d3798c70c0861c4 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 51347d41b396bf375c14d5580b0f2619ce5b518c..8f3fcf78885d8a369d1370dd7ef0713d87244dfb 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 0ee4eab2891599403017437b9e7aa3a66052b5f4..78d69cc8b4301ee7c966300adfcf2a5a8e389b6b 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 3960e52dd842f978114c841d60a816576f2e802d..3bebd8432dd6abe550a775165be8307794b72fc3 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 0cdcf8631052fde8bcfd2c36a416632fea6510a6..9bce37a3c4227d25b2eb7531d3c27b1fe1ea51c3 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) }