Skip to content
Snippets Groups Projects
Commit cbf2f3d2 authored by Marcel Samir Becker's avatar Marcel Samir Becker
Browse files

Restructured yaml and associated changes to TheodoliteExecutor

parent 5c33a0ab
Branches
Tags
1 merge request!215Redesign Strategy, Load, and Resources data types
......@@ -81,10 +81,24 @@ spec:
description: Defines the overall parameter for the execution.
type: object
required: ["strategy", "duration", "repetitions", "restrictions"]
properties:
metric:
default: "demand"
type: string
oneOf:
- "demand"
- "capacity"
strategy:
description: Defines the used strategy for the execution, either 'LinearSearch' or 'BinarySearch'
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:
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
......
......
......@@ -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.
......
......
......@@ -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"
)
}
......
......
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) {
......
......
......@@ -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>
......
......
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
)
......@@ -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?> =
......
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment