From cbf2f3d2cdc94341a9eff79a3780357d8de7335c Mon Sep 17 00:00:00 2001 From: Marcel Becker <stu117960@mail.uni-kiel.de> Date: Sun, 19 Dec 2021 16:56:42 +0100 Subject: [PATCH] Restructured yaml and associated changes to TheodoliteExecutor --- theodolite/crd/crd-execution.yaml | 25 +++++++++++++------ .../benchmark/BenchmarkExecution.kt | 16 ++++++++++-- .../execution/TheodoliteExecutor.kt | 20 ++++++--------- .../theodolite/strategies/StrategyFactory.kt | 23 +++++++++++------ ...positeStrategy.kt => RestrictionSearch.kt} | 8 +++--- .../src/main/kotlin/theodolite/util/Config.kt | 7 +++--- ...rategyTest.kt => RestrictionSearchTest.kt} | 18 ++++++------- 7 files changed, 70 insertions(+), 47 deletions(-) rename theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/{CompositeStrategy.kt => RestrictionSearch.kt} (88%) rename theodolite/src/test/kotlin/theodolite/{CompositeStrategyTest.kt => RestrictionSearchTest.kt} (91%) diff --git a/theodolite/crd/crd-execution.yaml b/theodolite/crd/crd-execution.yaml index d9cd41903..fde590bbb 100644 --- a/theodolite/crd/crd-execution.yaml +++ b/theodolite/crd/crd-execution.yaml @@ -81,10 +81,24 @@ spec: description: Defines the overall parameter for the execution. type: object required: ["strategy", "duration", "repetitions", "restrictions"] + metric: + default: "demand" + type: string + oneOf: + - "demand" + - "capacity" + strategy: + description: Defines the used strategy for the execution, either 'LinearSearch', 'BinarySearch' or 'InitialGuessSearch' + type: object + name: string + properties: + restrictions: + description: List of restriction strategys used to delimit the search space. + type: array + items: + type: string + guessStrategy: string properties: - strategy: - description: Defines the used strategy for the execution, either 'LinearSearch' or 'BinarySearch' - type: string duration: description: Defines the duration of each experiment in seconds. type: integer @@ -94,11 +108,6 @@ spec: loadGenerationDelay: description: Seconds to wait between the start of the SUT and the load generator. type: integer - restrictions: - description: List of restriction strategys used to delimit the search space. - type: array - items: - type: string configOverrides: description: List of patchers that are used to override existing configurations. type: array diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/BenchmarkExecution.kt b/theodolite/src/main/kotlin/theodolite/benchmark/BenchmarkExecution.kt index f2dda487d..168daa457 100644 --- a/theodolite/src/main/kotlin/theodolite/benchmark/BenchmarkExecution.kt +++ b/theodolite/src/main/kotlin/theodolite/benchmark/BenchmarkExecution.kt @@ -3,6 +3,7 @@ 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 @@ -41,14 +42,25 @@ class BenchmarkExecution : KubernetesResource { @JsonDeserialize @RegisterForReflection class Execution : KubernetesResource { - lateinit var strategy: String + lateinit var metric: String + lateinit var strategy: Strategy var duration by Delegates.notNull<Long>() var repetitions by Delegates.notNull<Int>() - lateinit var restrictions: List<String> var loadGenerationDelay = 0L var afterTeardownDelay = 5L } + /** + * This Strategy encapsulates the [restrictions] which is used for restricting the resources. + */ + @JsonDeserialize + @RegisterForReflection + class Strategy : KubernetesResource { + lateinit var name: String + lateinit var restrictions: List<String> + lateinit var guessStrategy: String + } + /** * Measurable metric. * [sloType] determines the type of the metric. diff --git a/theodolite/src/main/kotlin/theodolite/execution/TheodoliteExecutor.kt b/theodolite/src/main/kotlin/theodolite/execution/TheodoliteExecutor.kt index 315d1cf1a..4091a058e 100644 --- a/theodolite/src/main/kotlin/theodolite/execution/TheodoliteExecutor.kt +++ b/theodolite/src/main/kotlin/theodolite/execution/TheodoliteExecutor.kt @@ -5,7 +5,6 @@ import theodolite.benchmark.BenchmarkExecution import theodolite.benchmark.KubernetesBenchmark import theodolite.patcher.PatcherDefinitionFactory import theodolite.strategies.StrategyFactory -import theodolite.strategies.searchstrategy.CompositeStrategy import theodolite.util.* import java.io.File import java.time.Duration @@ -34,8 +33,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 [CompositeStrategy]. - * The [CompositeStrategy] is configured and able to find the minimum required resource for the given load. + * 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 { val results = Results() @@ -93,14 +92,7 @@ class TheodoliteExecutor( resourcePatcherDefinition ) }, - compositeStrategy = CompositeStrategy( - benchmarkExecutor = executor, - searchStrategy = strategyFactory.createSearchStrategy(executor, config.execution.strategy), - restrictionStrategies = strategyFactory.createRestrictionStrategy( - results, - config.execution.restrictions - ) - ) + searchStrategy = strategyFactory.createSearchStrategy(executor, config.execution.strategy, results) ) } @@ -125,16 +117,18 @@ class TheodoliteExecutor( ) val config = buildConfig() + //TODO: Differentiate metrics here + // execute benchmarks for each load try { for (load in config.loads) { if (executor.run.get()) { - config.compositeStrategy.findSuitableResource(load, config.resources) + config.searchStrategy.findSuitableResource(load, config.resources) } } } finally { ioHandler.writeToJSONFile( - config.compositeStrategy.benchmarkExecutor.results, + config.searchStrategy.benchmarkExecutor.results, "${resultsFolder}exp${this.config.executionId}-result" ) } diff --git a/theodolite/src/main/kotlin/theodolite/strategies/StrategyFactory.kt b/theodolite/src/main/kotlin/theodolite/strategies/StrategyFactory.kt index 829370e8c..7de70c5d2 100644 --- a/theodolite/src/main/kotlin/theodolite/strategies/StrategyFactory.kt +++ b/theodolite/src/main/kotlin/theodolite/strategies/StrategyFactory.kt @@ -1,12 +1,10 @@ package theodolite.strategies +import theodolite.benchmark.BenchmarkExecution import theodolite.execution.BenchmarkExecutor import theodolite.strategies.restriction.LowerBoundRestriction import theodolite.strategies.restriction.RestrictionStrategy -import theodolite.strategies.searchstrategy.BinarySearch -import theodolite.strategies.searchstrategy.FullSearch -import theodolite.strategies.searchstrategy.LinearSearch -import theodolite.strategies.searchstrategy.SearchStrategy +import theodolite.strategies.searchstrategy.* import theodolite.util.Results /** @@ -23,13 +21,22 @@ class StrategyFactory { * * @throws IllegalArgumentException if the [SearchStrategy] was not one of the allowed options. */ - fun createSearchStrategy(executor: BenchmarkExecutor, searchStrategyString: String): SearchStrategy { - return when (searchStrategyString) { + fun createSearchStrategy(executor: BenchmarkExecutor, searchStrategyObject: BenchmarkExecution.Strategy, results: Results): SearchStrategy { + + var strategy : SearchStrategy = when (searchStrategyObject.name) { "FullSearch" -> FullSearch(executor) "LinearSearch" -> LinearSearch(executor) "BinarySearch" -> BinarySearch(executor) - else -> throw IllegalArgumentException("Search Strategy $searchStrategyString not found") + "InitialGuessSearch" -> when (searchStrategyObject.guessStrategy){ + "PrevResourceMinGuess" -> InitialGuessSearchStrategy(executor,PrevResourceMinGuess(), results) + else -> throw IllegalArgumentException("Guess Strategy ${searchStrategyObject.guessStrategy} not found") + } + else -> throw IllegalArgumentException("Search Strategy $searchStrategyObject not found") + } + if(searchStrategyObject.restrictions.isNotEmpty()){ + strategy = RestrictionSearch(executor,strategy,createRestrictionStrategy(results, searchStrategyObject.restrictions)) } + return strategy } /** @@ -42,7 +49,7 @@ class StrategyFactory { * * @throws IllegalArgumentException if param searchStrategyString was not one of the allowed options. */ - fun createRestrictionStrategy(results: Results, restrictionStrings: List<String>): Set<RestrictionStrategy> { + private fun createRestrictionStrategy(results: Results, restrictionStrings: List<String>): Set<RestrictionStrategy> { return restrictionStrings .map { restriction -> when (restriction) { diff --git a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/CompositeStrategy.kt b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/RestrictionSearch.kt similarity index 88% rename from theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/CompositeStrategy.kt rename to theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/RestrictionSearch.kt index 41cc5c325..776cdeba5 100644 --- a/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/CompositeStrategy.kt +++ b/theodolite/src/main/kotlin/theodolite/strategies/searchstrategy/RestrictionSearch.kt @@ -7,14 +7,14 @@ import theodolite.util.LoadDimension import theodolite.util.Resource /** - * Composite strategy that combines a SearchStrategy and a set of RestrictionStrategy. + * Strategy that combines a SearchStrategy and a set of RestrictionStrategy. * - * @param searchStrategy the [SearchStrategy] that is executed as part of this [CompositeStrategy]. + * @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 [Resource] * @param benchmarkExecutor Benchmark executor which runs the individual benchmarks. */ @RegisterForReflection -class CompositeStrategy( +class RestrictionSearch( benchmarkExecutor: BenchmarkExecutor, private val searchStrategy: SearchStrategy, val restrictionStrategies: Set<RestrictionStrategy> @@ -27,4 +27,4 @@ class CompositeStrategy( } return this.searchStrategy.findSuitableResource(load, restrictedResources) } -} +} \ No newline at end of file diff --git a/theodolite/src/main/kotlin/theodolite/util/Config.kt b/theodolite/src/main/kotlin/theodolite/util/Config.kt index afbf784e9..e3fde8fcf 100644 --- a/theodolite/src/main/kotlin/theodolite/util/Config.kt +++ b/theodolite/src/main/kotlin/theodolite/util/Config.kt @@ -1,18 +1,19 @@ package theodolite.util import io.quarkus.runtime.annotations.RegisterForReflection -import theodolite.strategies.searchstrategy.CompositeStrategy +import theodolite.strategies.searchstrategy.RestrictionSearch +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 [Resource] of the execution - * @param compositeStrategy the [CompositeStrategy] of the execution + * @param searchStrategy the [SearchStrategy] of the execution */ @RegisterForReflection data class Config( val loads: List<LoadDimension>, val resources: List<Resource>, - val compositeStrategy: CompositeStrategy + val searchStrategy: SearchStrategy ) diff --git a/theodolite/src/test/kotlin/theodolite/CompositeStrategyTest.kt b/theodolite/src/test/kotlin/theodolite/RestrictionSearchTest.kt similarity index 91% rename from theodolite/src/test/kotlin/theodolite/CompositeStrategyTest.kt rename to theodolite/src/test/kotlin/theodolite/RestrictionSearchTest.kt index 580d9e747..965040e06 100644 --- a/theodolite/src/test/kotlin/theodolite/CompositeStrategyTest.kt +++ b/theodolite/src/test/kotlin/theodolite/RestrictionSearchTest.kt @@ -6,17 +6,18 @@ import org.junit.jupiter.api.Test import theodolite.benchmark.BenchmarkExecution import theodolite.strategies.restriction.LowerBoundRestriction import theodolite.strategies.searchstrategy.BinarySearch -import theodolite.strategies.searchstrategy.CompositeStrategy +import theodolite.strategies.searchstrategy.RestrictionSearch import theodolite.strategies.searchstrategy.LinearSearch import theodolite.util.LoadDimension import theodolite.util.Resource import theodolite.util.Results @QuarkusTest -class CompositeStrategyTest { +class RestrictionSearchTest { + @Test - fun testEnd2EndLinearSearch() { + fun restrictionSearchTestLinearSearch() { val mockResults = arrayOf( arrayOf(true, true, true, true, true, true, true), arrayOf(false, false, true, true, true, true, true), @@ -35,7 +36,7 @@ class CompositeStrategyTest { val linearSearch = LinearSearch(benchmarkExecutor) val lowerBoundRestriction = LowerBoundRestriction(results) val strategy = - CompositeStrategy(benchmarkExecutor, linearSearch, setOf(lowerBoundRestriction)) + RestrictionSearch(benchmarkExecutor, linearSearch, setOf(lowerBoundRestriction)) val actual: ArrayList<Resource?> = ArrayList() val expected: ArrayList<Resource?> = ArrayList(listOf(0, 2, 2, 3, 4, 6).map { x -> Resource(x, emptyList()) }) @@ -49,7 +50,7 @@ class CompositeStrategyTest { } @Test - fun testEnd2EndBinarySearch() { + fun restrictionSearchTestBinarySearch() { val mockResults = arrayOf( arrayOf(true, true, true, true, true, true, true), arrayOf(false, false, true, true, true, true, true), @@ -68,8 +69,7 @@ class CompositeStrategyTest { TestBenchmarkExecutorImpl(mockResults, benchmark, results, listOf(sloChecker), 0, 0, 0) val binarySearch = BinarySearch(benchmarkExecutorImpl) val lowerBoundRestriction = LowerBoundRestriction(results) - val strategy = - CompositeStrategy(benchmarkExecutorImpl, binarySearch, setOf(lowerBoundRestriction)) + val strategy = RestrictionSearch(benchmarkExecutorImpl, binarySearch, setOf(lowerBoundRestriction)) val actual: ArrayList<Resource?> = ArrayList() val expected: ArrayList<Resource?> = ArrayList(listOf(0, 2, 2, 3, 4, 6).map { x -> Resource(x, emptyList()) }) @@ -83,7 +83,7 @@ class CompositeStrategyTest { } @Test - fun testEnd2EndBinarySearch2() { + fun restrictionSearchTestBinarySearch2() { val mockResults = arrayOf( arrayOf(true, true, true, true, true, true, true, true), arrayOf(false, false, true, true, true, true, true, true), @@ -102,7 +102,7 @@ class CompositeStrategyTest { val binarySearch = BinarySearch(benchmarkExecutor) val lowerBoundRestriction = LowerBoundRestriction(results) val strategy = - CompositeStrategy(benchmarkExecutor, binarySearch, setOf(lowerBoundRestriction)) + RestrictionSearch(benchmarkExecutor, binarySearch, setOf(lowerBoundRestriction)) val actual: ArrayList<Resource?> = ArrayList() val expected: ArrayList<Resource?> = -- GitLab