Skip to content
Snippets Groups Projects
Commit 52bc0f91 authored by Benedikt Wetzel's avatar Benedikt Wetzel Committed by Sören Henning
Browse files

Add more test for TheodoliteController

parent ca0152f1
No related branches found
No related tags found
4 merge requests!159Re-implementation of Theodolite with Kotlin/Quarkus,!157Update Graal Image in CI pipeline,!154Add more Kuberntes related tests,!83WIP: Re-implementation of Theodolite with Kotlin/Quarkus
package theodolite.execution.operator
import theodolite.benchmark.KubernetesBenchmark
import theodolite.model.crd.BenchmarkCRD
import theodolite.util.KafkaConfig
class BenchmarkCRDummy(name: String) {
private val benchmark = KubernetesBenchmark()
private val benchmarkCR = BenchmarkCRD(benchmark)
fun getCR(): BenchmarkCRD {
return benchmarkCR
}
init {
val kafkaConfig = KafkaConfig()
kafkaConfig.bootstrapServer = ""
kafkaConfig.topics = emptyList()
benchmarkCR.spec = benchmark
benchmarkCR.metadata.name = name
benchmarkCR.kind = "Benchmark"
benchmarkCR.apiVersion = "v1"
benchmark.appResource = emptyList()
benchmark.loadGenResource = emptyList()
benchmark.resourceTypes = emptyList()
benchmark.loadTypes = emptyList()
benchmark.kafkaConfig = kafkaConfig
benchmark.name = benchmarkCR.metadata.name
}
}
\ No newline at end of file
package theodolite.execution.operator
import io.fabric8.kubernetes.client.NamespacedKubernetesClient
import io.fabric8.kubernetes.client.dsl.MixedOperation
import io.fabric8.kubernetes.client.dsl.Resource
import io.fabric8.kubernetes.internal.KubernetesDeserializer
import theodolite.k8s.K8sContextFactory
import theodolite.model.crd.*
private const val SCOPE = "Namespaced"
private const val EXECUTION_SINGULAR = "execution"
private const val EXECUTION_PLURAL = "executions"
private const val BENCHMARK_SINGULAR = "benchmark"
private const val BENCHMARK_PLURAL = "benchmarks"
private const val API_VERSION = "v1"
private const val RESYNC_PERIOD = 10 * 60 * 1000.toLong()
private const val GROUP = "theodolite.com"
class ControllerDummy(val client: NamespacedKubernetesClient) {
private lateinit var controller: TheodoliteController
fun getController(): TheodoliteController {
return this.controller
}
init {
KubernetesDeserializer.registerCustomKind(
"$GROUP/$API_VERSION",
EXECUTION_SINGULAR,
ExecutionCRD::class.java
)
KubernetesDeserializer.registerCustomKind(
"$GROUP/$API_VERSION",
BENCHMARK_SINGULAR,
BenchmarkCRD::class.java
)
val contextFactory = K8sContextFactory()
val executionContext =
contextFactory
.create(
API_VERSION,
SCOPE,
GROUP,
EXECUTION_PLURAL
)
val benchmarkContext =
contextFactory
.create(
API_VERSION,
SCOPE,
GROUP,
BENCHMARK_PLURAL
)
val executionCRDClient: MixedOperation<
ExecutionCRD,
BenchmarkExecutionList,
DoneableExecution,
Resource<ExecutionCRD, DoneableExecution>> = client.customResources(
executionContext,
ExecutionCRD::class.java,
BenchmarkExecutionList::class.java,
DoneableExecution::class.java
)
val benchmarkCRDClient = client.customResources(
benchmarkContext,
BenchmarkCRD::class.java,
KubernetesBenchmarkList::class.java,
DoneableBenchmark::class.java
)
val executionStateHandler = ExecutionStateHandler(
context = executionContext,
client = client
)
val appResource = System.getenv("THEODOLITE_APP_RESOURCES") ?: "./config"
this.controller =
TheodoliteController(
namespace = client.namespace,
path = appResource,
benchmarkCRDClient = benchmarkCRDClient,
executionCRDClient = executionCRDClient,
executionStateHandler = executionStateHandler
)
}
}
\ No newline at end of file
...@@ -3,108 +3,62 @@ package theodolite.execution.operator ...@@ -3,108 +3,62 @@ package theodolite.execution.operator
import com.google.gson.Gson import com.google.gson.Gson
import com.google.gson.GsonBuilder import com.google.gson.GsonBuilder
import io.fabric8.kubernetes.client.CustomResourceList import io.fabric8.kubernetes.client.CustomResourceList
import io.fabric8.kubernetes.client.dsl.MixedOperation
import io.fabric8.kubernetes.client.dsl.Resource
import io.fabric8.kubernetes.client.server.mock.KubernetesServer import io.fabric8.kubernetes.client.server.mock.KubernetesServer
import io.fabric8.kubernetes.internal.KubernetesDeserializer
import io.quarkus.test.junit.QuarkusTest import io.quarkus.test.junit.QuarkusTest
import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import theodolite.benchmark.BenchmarkExecution
import theodolite.benchmark.KubernetesBenchmark import theodolite.benchmark.KubernetesBenchmark
import theodolite.k8s.K8sContextFactory import theodolite.model.crd.BenchmarkCRD
import theodolite.model.crd.* import theodolite.model.crd.ExecutionCRD
import theodolite.util.KafkaConfig
private const val DEFAULT_NAMESPACE = "default"
private const val SCOPE = "Namespaced"
private const val EXECUTION_SINGULAR = "execution"
private const val EXECUTION_PLURAL = "executions"
private const val BENCHMARK_SINGULAR = "benchmark"
private const val BENCHMARK_PLURAL = "benchmarks"
private const val API_VERSION = "v1"
private const val RESYNC_PERIOD = 10 * 60 * 1000.toLong()
private const val GROUP = "theodolite.com"
@QuarkusTest @QuarkusTest
class ControllerTest { class ControllerTest {
private final val server = KubernetesServer(false, false) private final val server = KubernetesServer(false, false)
private final val testResourcePath = "./src/test/resources/k8s-resource-files/"
lateinit var controller: TheodoliteController lateinit var controller: TheodoliteController
lateinit var benchmarkCRDClient: MixedOperation<BenchmarkCRD, KubernetesBenchmarkList, DoneableBenchmark, Resource<BenchmarkCRD, DoneableBenchmark>>
private val gson: Gson = GsonBuilder().enableComplexMapKeySerialization().create() private val gson: Gson = GsonBuilder().enableComplexMapKeySerialization().create()
private val kafkaConfig = KafkaConfig() private var benchmark = KubernetesBenchmark()
private val benchmark = KubernetesBenchmark() private var execution = BenchmarkExecution()
private val benchmarkResourceList = CustomResourceList<BenchmarkCRD>()
private val executionResourceList = CustomResourceList<ExecutionCRD>()
@BeforeEach @BeforeEach
fun setUp() { fun setUp() {
server.before() server.before()
this.controller = ControllerDummy(server.client).getController()
KubernetesDeserializer.registerCustomKind(
"$GROUP/$API_VERSION", // benchmark
EXECUTION_SINGULAR, val benchmark1 = BenchmarkCRDummy(name = "Test-Benchmark")
ExecutionCRD::class.java val benchmark2 = BenchmarkCRDummy(name = "Test-Benchmark-123")
) benchmarkResourceList.items = listOf(benchmark1.getCR(), benchmark2.getCR())
KubernetesDeserializer.registerCustomKind( // execution
"$GROUP/$API_VERSION", val execution1 = ExecutionCRDummy(name = "matching-execution", benchmark = "Test-Benchmark")
BENCHMARK_SINGULAR, val execution2 = ExecutionCRDummy(name = "non-matching-execution", benchmark = "Test-Benchmark-456")
BenchmarkCRD::class.java val execution3 = ExecutionCRDummy(name = "second-matching-execution", benchmark = "Test-Benchmark")
) executionResourceList.items = listOf(execution1.getCR(), execution2.getCR(), execution3.getCR())
val contextFactory = K8sContextFactory() this.benchmark = benchmark1.getCR().spec
val executionContext = contextFactory.create(API_VERSION, SCOPE, GROUP, EXECUTION_PLURAL) this.execution = execution1.getCR().spec
val benchmarkContext = contextFactory.create(API_VERSION, SCOPE, GROUP, BENCHMARK_PLURAL)
server
val executionCRDClient: MixedOperation< .expect()
ExecutionCRD, .get()
BenchmarkExecutionList, .withPath("/apis/theodolite.com/v1/namespaces/test/benchmarks")
DoneableExecution, .andReturn(200, benchmarkResourceList)
Resource<ExecutionCRD, DoneableExecution>> = server.client.customResources( .always()
executionContext,
ExecutionCRD::class.java, server
BenchmarkExecutionList::class.java, .expect()
DoneableExecution::class.java .get()
) .withPath("/apis/theodolite.com/v1/namespaces/test/executions")
.andReturn(200, executionResourceList)
this.benchmarkCRDClient = server.client.customResources( .always()
benchmarkContext,
BenchmarkCRD::class.java,
KubernetesBenchmarkList::class.java,
DoneableBenchmark::class.java
)
val executionStateHandler = ExecutionStateHandler(
context = executionContext,
client = server.client
)
val appResource = System.getenv("THEODOLITE_APP_RESOURCES") ?: "./config"
this.controller =
TheodoliteController(
namespace = server.client.namespace,
path = appResource,
benchmarkCRDClient = benchmarkCRDClient,
executionCRDClient = executionCRDClient,
executionStateHandler = executionStateHandler
)
// create benchmarks
kafkaConfig.bootstrapServer = ""
kafkaConfig.topics = emptyList()
benchmark.name = "Test-Benchmark"
benchmark.appResource = emptyList()
benchmark.loadGenResource = emptyList()
benchmark.resourceTypes = emptyList()
benchmark.loadTypes = emptyList()
benchmark.kafkaConfig = kafkaConfig
} }
@AfterEach @AfterEach
...@@ -113,22 +67,66 @@ class ControllerTest { ...@@ -113,22 +67,66 @@ class ControllerTest {
} }
@Test @Test
fun test() { fun getBenchmarksTest() {
val crd = BenchmarkCRD(benchmark) val method = controller
crd.spec = benchmark .javaClass
crd.metadata.name = "Test-Benchmark" .getDeclaredMethod("getBenchmarks")
crd.kind = "Benchmark" method.isAccessible = true
crd.apiVersion = "v1"
val list = CustomResourceList<BenchmarkCRD>() val result = method.invoke(controller) as List<KubernetesBenchmark>
list.items = listOf(crd)
server.expect().get().withPath("/apis/theodolite.com/v1/namespaces/test/benchmarks").andReturn(200, list).always() assertEquals(2, result.size)
assertEquals(
gson.toJson(benchmark),
gson.toJson(result.firstOrNull()))
}
val method = controller.javaClass.getDeclaredMethod("getBenchmarks") @Test
fun getNextExecution() {
val method = controller
.javaClass
.getDeclaredMethod("getNextExecution")
method.isAccessible = true method.isAccessible = true
benchmark.name = crd.metadata.name
val result = method.invoke(controller) as List<KubernetesBenchmark> val result = method.invoke(controller) as BenchmarkExecution?
assertEquals(gson.toJson(result[0]), gson.toJson(benchmark))
assertEquals(
gson.toJson(this.execution),
gson.toJson(result))
}
@Test
fun setAdditionalLabelsTest() {
val method = controller
.javaClass
.getDeclaredMethod("setAdditionalLabels",
String::class.java,
String::class.java,
List::class.java,
BenchmarkExecution::class.java)
method.isAccessible = true
this.benchmark.appResource = listOf("test-resource.yaml")
method.invoke(controller,
"test-value",
"test-name",
this.benchmark.appResource,
this.execution
) as BenchmarkExecution?
assertEquals(
"test-name",
this.execution
.configOverrides.firstOrNull()
?.patcher
?.properties
?.get("variableName")
)
assertEquals(
"test-value",
this.execution
.configOverrides.firstOrNull()
?.value)
} }
} }
\ No newline at end of file
package theodolite.execution.operator
import theodolite.benchmark.BenchmarkExecution
import theodolite.model.crd.ExecutionCRD
import theodolite.model.crd.ExecutionStatus
import theodolite.model.crd.States
class ExecutionCRDummy(name: String, benchmark: String) {
private val execution = BenchmarkExecution()
private val executionState = ExecutionStatus()
private val executionCR = ExecutionCRD(execution, executionState)
fun getCR(): ExecutionCRD {
return this.executionCR
}
init {
// configure metadata
executionCR.spec = execution
executionCR.metadata.name = name
executionCR.kind = "Execution"
executionCR.apiVersion = "v1"
// configure execution
val loadType = BenchmarkExecution.LoadDefinition()
loadType.loadType = ""
loadType.loadValues = emptyList()
val resourceDef = BenchmarkExecution.ResourceDefinition()
resourceDef.resourceType = ""
resourceDef.resourceValues = emptyList()
val exec = BenchmarkExecution.Execution()
exec.afterTeardownDelay = 0
exec.duration = 0
exec.loadGenerationDelay = 0
exec.repetitions = 1
exec.restrictions = emptyList()
exec.strategy = ""
execution.benchmark = benchmark
execution.load = loadType
execution.resources = resourceDef
execution.slos = emptyList()
execution.execution = exec
execution.configOverrides = mutableListOf()
execution.name = executionCR.metadata.name
executionState.executionState = States.PENDING.value
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment