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
No related branches found
No related tags found
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 register or to comment