Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • she/theodolite
1 result
Show changes
Showing
with 339 additions and 129 deletions
......@@ -5,9 +5,9 @@ import io.fabric8.kubernetes.client.server.mock.KubernetesServer
import io.quarkus.test.junit.QuarkusTest
import io.quarkus.test.kubernetes.client.KubernetesTestServer
import io.quarkus.test.kubernetes.client.WithKubernetesTestServer
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
@QuarkusTest
@WithKubernetesTestServer
class ResourceLimitPatcherTest {
......
......@@ -7,6 +7,7 @@ import io.quarkus.test.kubernetes.client.KubernetesTestServer
import io.quarkus.test.kubernetes.client.WithKubernetesTestServer
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
@QuarkusTest
@WithKubernetesTestServer
class ResourceRequestPatcherTest {
......
package rocks.theodolite.kubernetes.patcher
import io.fabric8.kubernetes.api.model.Pod
import io.fabric8.kubernetes.api.model.apps.Deployment
import io.fabric8.kubernetes.api.model.apps.StatefulSet
import io.quarkus.test.junit.QuarkusTest
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.Assertions.*
@QuarkusTest
internal class SchedulerNamePatcherTest : AbstractPatcherTest(){
internal class SchedulerNamePatcherTest : AbstractPatcherTest() {
@BeforeEach
fun setUp() {
resource = listOf(createDeployment())
patcher = SchedulerNamePatcher()
value = "testScheduler"
@Test
fun testDeployment() {
val sourceResource = createDeployment()
val patcher = SchedulerNamePatcher()
val patchedResources = patcher.patch(listOf(sourceResource), "testScheduler")
patchedResources.forEach {
assertEquals("testScheduler", (it as Deployment).spec.template.spec.schedulerName)
}
}
@AfterEach
fun tearDown() {
@Test
fun testStatefulSet() {
val sourceResource = createStatefulSet()
val patcher = SchedulerNamePatcher()
val patchedResources = patcher.patch(listOf(sourceResource), "testScheduler")
patchedResources.forEach {
assertEquals("testScheduler", (it as StatefulSet).spec.template.spec.schedulerName)
}
}
@Test
override fun validate() {
patch()
resource.forEach {
assertTrue((it as Deployment).spec.template.spec.schedulerName == value)
fun testPod() {
val sourceResource = createPod()
val patcher = SchedulerNamePatcher()
val patchedResources = patcher.patch(listOf(sourceResource), "testScheduler")
patchedResources.forEach {
assertEquals("testScheduler", (it as Pod).spec.schedulerName)
}
}
}
\ No newline at end of file
package rocks.theodolite.kubernetes.patcher
import io.fabric8.kubernetes.api.model.Service
import io.quarkus.test.junit.QuarkusTest
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
@QuarkusTest
internal class ServiceSelectorPatcherTest: AbstractPatcherTest() {
@Test
fun testService() {
val sourceResource = createService()
val patcher = ServiceSelectorPatcher("some-label")
val patchedResources = patcher.patch(listOf(sourceResource), "some-value")
patchedResources.forEach {
assertTrue((it as Service).spec.selector.containsKey("some-label"))
assertEquals("some-value", it.spec.selector["some-label"])
}
}
}
\ No newline at end of file
package rocks.theodolite.kubernetes.patcher
import io.fabric8.kubernetes.api.model.apps.Deployment
import io.fabric8.kubernetes.api.model.apps.StatefulSet
import io.quarkus.test.junit.QuarkusTest
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.Assertions.*
......@@ -10,21 +10,27 @@ import org.junit.jupiter.api.Assertions.*
@QuarkusTest
internal class TemplateLabelPatcherTest: AbstractPatcherTest() {
@BeforeEach
fun setUp() {
resource = listOf(createDeployment())
patcher = TemplateLabelPatcher( "labelName")
value = "labelValue"
@Test
fun testDeployment() {
val sourceResource = createDeployment()
val patcher = TemplateLabelPatcher("some-label")
val patchedResources = patcher.patch(listOf(sourceResource), "some-value")
patchedResources.forEach {
assertTrue((it as Deployment).spec.template.metadata.labels.containsKey("some-label"))
assertEquals("some-value", it.spec.template.metadata.labels["some-label"])
}
}
@Test
override fun validate() {
patch()
resource.forEach {
assertTrue((it as Deployment).spec.template.metadata.labels.containsKey("labelName"))
assertTrue(it.spec.template.metadata.labels["labelName"] =="labelValue")
fun testStatefulSet() {
val sourceResource = createStatefulSet()
val patcher = TemplateLabelPatcher("some-label")
val patchedResources = patcher.patch(listOf(sourceResource), "some-value")
patchedResources.forEach {
assertTrue((it as StatefulSet).spec.template.metadata.labels.containsKey("some-label"))
assertEquals("some-value", it.spec.template.metadata.labels["some-label"])
}
}
}
\ No newline at end of file
......@@ -11,23 +11,15 @@ import org.junit.jupiter.api.Assertions.*
@QuarkusTest
internal class VolumesConfigMapPatcherTest: AbstractPatcherTest() {
@BeforeEach
fun setUp() {
resource = listOf(createDeployment())
patcher = VolumesConfigMapPatcher("test-configmap")
value = "patchedVolumeName"
}
@AfterEach
fun tearDown() {
}
@Test
override fun validate() {
patch()
resource.forEach {
println((it as Deployment).spec.template.spec.volumes[0].configMap.name)
assertTrue((it as Deployment).spec.template.spec.volumes[0].configMap.name == value)
fun testDeployment() {
val sourceResource = createDeployment()
val patcher = VolumesConfigMapPatcher("test-configmap")
val patchedResources = patcher.patch(listOf(sourceResource), "patchedVolumeName")
patchedResources.forEach {
assertEquals(
"patchedVolumeName",
(it as Deployment).spec.template.spec.volumes[0].configMap.name)
}
}
}
\ No newline at end of file
......@@ -9,11 +9,12 @@ import rocks.theodolite.core.strategies.Metric
@QuarkusTest
internal class SloCheckerFactoryTest {
private val factory = SloCheckerFactory()
@Test
fun testCreateGenericSloWithoutUrl() {
val factory = SloCheckerFactory()
assertThrows<IllegalArgumentException> {
factory.create(
this.factory.create(
SloTypes.GENERIC.value,
mapOf(
"warmup" to "60",
......@@ -31,9 +32,8 @@ internal class SloCheckerFactoryTest {
@Test
fun testCreateGenericSloWithoutWarmup() {
val factory = SloCheckerFactory()
assertThrows<IllegalArgumentException> {
factory.create(
this.factory.create(
SloTypes.GENERIC.value,
mapOf(
"externalSloUrl" to "http://localhost:1234",
......@@ -51,9 +51,8 @@ internal class SloCheckerFactoryTest {
@Test
fun testCreateGenericSloWithoutQueryAggregation() {
val factory = SloCheckerFactory()
assertThrows<IllegalArgumentException> {
factory.create(
this.factory.create(
SloTypes.GENERIC.value,
mapOf(
"externalSloUrl" to "http://localhost:1234",
......@@ -71,9 +70,8 @@ internal class SloCheckerFactoryTest {
@Test
fun testCreateGenericSloWithoutRepetitionAggregation() {
val factory = SloCheckerFactory()
assertThrows<IllegalArgumentException> {
factory.create(
this.factory.create(
SloTypes.GENERIC.value,
mapOf(
"externalSloUrl" to "http://localhost:1234",
......@@ -91,9 +89,8 @@ internal class SloCheckerFactoryTest {
@Test
fun testCreateGenericSloWithoutOperator() {
val factory = SloCheckerFactory()
assertThrows<IllegalArgumentException> {
factory.create(
this.factory.create(
SloTypes.GENERIC.value,
mapOf(
"externalSloUrl" to "http://localhost:1234",
......@@ -111,9 +108,8 @@ internal class SloCheckerFactoryTest {
@Test
fun testCreateGenericSloWithoutThreshold() {
val factory = SloCheckerFactory()
assertThrows<IllegalArgumentException> {
factory.create(
this.factory.create(
SloTypes.GENERIC.value,
mapOf(
"externalSloUrl" to "http://localhost:1234",
......@@ -131,8 +127,7 @@ internal class SloCheckerFactoryTest {
@Test
fun testCreateGenericSloFloatThreshold() {
val factory = SloCheckerFactory()
val sloChecker = factory.create(
val sloChecker = this.factory.create(
SloTypes.GENERIC.value,
mapOf(
"externalSloUrl" to "http://localhost:1234",
......@@ -152,11 +147,143 @@ internal class SloCheckerFactoryTest {
assertEquals(12.34, threshold as Double, 0.01)
}
@Test
fun testCreateGenericSloWithThresholdRelToLoad() {
val sloChecker = this.factory.create(
SloTypes.GENERIC.value,
mapOf(
"externalSloUrl" to "http://localhost:1234",
"warmup" to "60",
"queryAggregation" to "median",
"repetitionAggregation" to "median",
"operator" to "lte",
"thresholdRelToLoad" to "0.1"
),
100,
5,
Metric.DEMAND
)
assertTrue(sloChecker is ExternalSloChecker)
val computedThreshold = (sloChecker as ExternalSloChecker).metadata["threshold"]
assertTrue(computedThreshold is Double)
assertEquals(10.0, computedThreshold as Double, 0.001)
}
@Test
fun testCreateGenericSloWithThresholdRelToLoadAndInvalidThreshold() {
val sloChecker = this.factory.create(
SloTypes.GENERIC.value,
mapOf(
"externalSloUrl" to "http://localhost:1234",
"warmup" to "60",
"queryAggregation" to "median",
"repetitionAggregation" to "median",
"operator" to "lte",
"threshold" to "",
"thresholdRelToLoad" to "0.1"
),
100,
5,
Metric.DEMAND
)
assertTrue(sloChecker is ExternalSloChecker)
val computedThreshold = (sloChecker as ExternalSloChecker).metadata["threshold"]
assertTrue(computedThreshold is Double)
assertEquals(10.0, computedThreshold as Double, 0.001)
}
@Test
fun testCreateGenericSloWithThresholdRelToResources() {
val sloChecker = this.factory.create(
SloTypes.GENERIC.value,
mapOf(
"externalSloUrl" to "http://localhost:1234",
"warmup" to "60",
"queryAggregation" to "median",
"repetitionAggregation" to "median",
"operator" to "lte",
"thresholdRelToResources" to "0.1"
),
100,
5,
Metric.DEMAND
)
assertTrue(sloChecker is ExternalSloChecker)
val computedThreshold = (sloChecker as ExternalSloChecker).metadata["threshold"]
assertTrue(computedThreshold is Double)
assertEquals(0.5, computedThreshold as Double, 0.001)
}
@Test
fun testCreateGenericSloWithConstantThresholdFromExpression() {
val sloChecker = this.factory.create(
SloTypes.GENERIC.value,
mapOf(
"externalSloUrl" to "http://localhost:1234",
"warmup" to "60",
"queryAggregation" to "median",
"repetitionAggregation" to "median",
"operator" to "lte",
"thresholdFromExpression" to "1111"
),
8,
5,
Metric.DEMAND
)
assertTrue(sloChecker is ExternalSloChecker)
val computedThreshold = (sloChecker as ExternalSloChecker).metadata["threshold"]
assertTrue(computedThreshold is Double)
assertEquals(1111.0, computedThreshold as Double, 0.001)
}
@Test
fun testCreateGenericSloWithSimpleThresholdFromExpression() {
val sloChecker = this.factory.create(
SloTypes.GENERIC.value,
mapOf(
"externalSloUrl" to "http://localhost:1234",
"warmup" to "60",
"queryAggregation" to "median",
"repetitionAggregation" to "median",
"operator" to "lte",
"thresholdFromExpression" to "L*5"
),
8,
5,
Metric.DEMAND
)
assertTrue(sloChecker is ExternalSloChecker)
val computedThreshold = (sloChecker as ExternalSloChecker).metadata["threshold"]
assertTrue(computedThreshold is Double)
assertEquals(40.0, computedThreshold as Double, 0.001)
}
@Test
fun testCreateGenericSloWithComplexThresholdFromExpression() {
val sloChecker = this.factory.create(
SloTypes.GENERIC.value,
mapOf(
"externalSloUrl" to "http://localhost:1234",
"warmup" to "60",
"queryAggregation" to "median",
"repetitionAggregation" to "median",
"operator" to "lte",
"thresholdFromExpression" to "R*((2^L+4)-60)+111"
),
8,
5,
Metric.DEMAND
)
assertTrue(sloChecker is ExternalSloChecker)
val computedThreshold = (sloChecker as ExternalSloChecker).metadata["threshold"]
assertTrue(computedThreshold is Double)
assertEquals(1111.0, computedThreshold as Double, 0.001)
}
@Test
fun testCreateLagTrendSloWithoutUrl() {
val factory = SloCheckerFactory()
assertThrows<IllegalArgumentException> {
factory.create(
this.factory.create(
SloTypes.LAG_TREND.value,
mapOf(
"warmup" to "60",
......@@ -171,9 +298,8 @@ internal class SloCheckerFactoryTest {
@Test
fun testCreateLagTrendSloWithoutWarmup() {
val factory = SloCheckerFactory()
assertThrows<IllegalArgumentException> {
factory.create(
this.factory.create(
SloTypes.LAG_TREND.value,
mapOf(
"externalSloUrl" to "http://localhost:1234",
......@@ -189,9 +315,8 @@ internal class SloCheckerFactoryTest {
@Test
fun testCreateLagTrendSloWithoutThreshold() {
val factory = SloCheckerFactory()
assertThrows<IllegalArgumentException> {
factory.create(
this.factory.create(
SloTypes.LAG_TREND.value,
mapOf(
"externalSloUrl" to "http://localhost:1234",
......@@ -206,8 +331,7 @@ internal class SloCheckerFactoryTest {
@Test
fun testCreateLagTrendSloFloatThreshold() {
val factory = SloCheckerFactory()
val sloChecker = factory.create(
val sloChecker = this.factory.create(
SloTypes.LAG_TREND.value,
mapOf(
"externalSloUrl" to "http://localhost:1234",
......@@ -224,11 +348,68 @@ internal class SloCheckerFactoryTest {
assertEquals(12.34, threshold as Double, 0.01)
}
@Test
fun testCreateLagTrendSloWithThresholdRelToLoad() {
val sloChecker = this.factory.create(
SloTypes.LAG_TREND.value,
mapOf(
"externalSloUrl" to "http://localhost:1234",
"warmup" to "60",
"thresholdRelToLoad" to "0.1"
),
100,
5,
Metric.DEMAND
)
assertTrue(sloChecker is ExternalSloChecker)
val computedThreshold = (sloChecker as ExternalSloChecker).metadata["threshold"]
assertTrue(computedThreshold is Double)
assertEquals(10.0, computedThreshold as Double, 0.001)
}
@Test
fun testCreateLagTrendSloWithThresholdRelToLoadAndInvalidThreshold() {
val sloChecker = this.factory.create(
SloTypes.LAG_TREND.value,
mapOf(
"externalSloUrl" to "http://localhost:1234",
"warmup" to "60",
"threshold" to "",
"thresholdRelToLoad" to "0.1"
),
100,
5,
Metric.DEMAND
)
assertTrue(sloChecker is ExternalSloChecker)
val computedThreshold = (sloChecker as ExternalSloChecker).metadata["threshold"]
assertTrue(computedThreshold is Double)
assertEquals(10.0, computedThreshold as Double, 0.001)
}
@Test
fun testCreateLagTrendSloWithThresholdRelToResources() {
val sloChecker = this.factory.create(
SloTypes.LAG_TREND.value,
mapOf(
"externalSloUrl" to "http://localhost:1234",
"warmup" to "60",
"thresholdRelToResources" to "0.1"
),
100,
5,
Metric.DEMAND
)
assertTrue(sloChecker is ExternalSloChecker)
val computedThreshold = (sloChecker as ExternalSloChecker).metadata["threshold"]
assertTrue(computedThreshold is Double)
assertEquals(0.5, computedThreshold as Double, 0.001)
}
@Test
fun testCreateLagTrendRatioSloWithoutUrl() {
val factory = SloCheckerFactory()
assertThrows<IllegalArgumentException> {
factory.create(
this.factory.create(
SloTypes.LAG_TREND_RATIO.value,
mapOf(
"warmup" to "60",
......@@ -243,9 +424,8 @@ internal class SloCheckerFactoryTest {
@Test
fun testCreateLagTrendRatioSloWithoutWarmup() {
val factory = SloCheckerFactory()
assertThrows<IllegalArgumentException> {
factory.create(
this.factory.create(
SloTypes.LAG_TREND_RATIO.value,
mapOf(
"externalSloUrl" to "http://localhost:1234",
......@@ -261,9 +441,8 @@ internal class SloCheckerFactoryTest {
@Test
fun testCreateLagTrendRatioSloWithoutRatioThreshold() {
val factory = SloCheckerFactory()
assertThrows<IllegalArgumentException> {
factory.create(
this.factory.create(
SloTypes.LAG_TREND_RATIO.value,
mapOf(
"externalSloUrl" to "http://localhost:1234",
......@@ -278,8 +457,7 @@ internal class SloCheckerFactoryTest {
@Test
fun testCreateLagTrendRatioSloFloatThreshold() {
val factory = SloCheckerFactory()
val sloChecker = factory.create(
val sloChecker = this.factory.create(
SloTypes.LAG_TREND_RATIO.value,
mapOf(
"externalSloUrl" to "http://localhost:1234",
......
......@@ -9,50 +9,47 @@ import rocks.theodolite.kubernetes.model.KubernetesBenchmark
@QuarkusTest
internal class SloFactoryTest {
private val sloFactory = SloFactory()
private val benchmark = KubernetesBenchmark().also { bench ->
bench.slos = mutableListOf(
KubernetesBenchmark.Slo().also {
it.name = "test"
it.sloType = "lag trend"
it.prometheusUrl = "test.de"
it.offset = 0
it.properties = mutableMapOf(
"threshold" to "2000",
"externalSloUrl" to "http://localhost:80/evaluate-slope",
"warmup" to "60"
)
}
)
}
@Test
fun overwriteSloTest() {
val benchmark = KubernetesBenchmark()
val execution = BenchmarkExecution()
// Define Benchmark SLOs
val slo = KubernetesBenchmark.Slo()
slo.name="test"
slo.sloType="lag trend"
slo.prometheusUrl="test.de"
slo.offset=0
val benchmarkSloProperties = mutableMapOf<String, String>()
benchmarkSloProperties["threshold"] = "2000"
benchmarkSloProperties["externalSloUrl"] = "http://localhost:80/evaluate-slope"
benchmarkSloProperties["warmup"] = "60"
slo.properties=benchmarkSloProperties
benchmark.slos = mutableListOf(slo)
// Define Execution SLOs, benchmark SLO values for these properties should be overwritten
val sloConfig = BenchmarkExecution.SloConfiguration()
sloConfig.name = "test"
val executionSloProperties = mutableMapOf<String, String>()
// overwriting properties 'threshold' and 'warmup' and adding property 'extensionTest'
executionSloProperties["threshold"] = "3000"
executionSloProperties["warmup"] = "80"
executionSloProperties["extensionTest"] = "extended"
sloConfig.properties = executionSloProperties
// SLO has 'name' that isn't defined in the benchmark, therefore it will be ignored by the SloFactory
val sloConfig2 = BenchmarkExecution.SloConfiguration()
sloConfig2.name = "test2"
sloConfig2.properties = executionSloProperties
execution.slos = listOf(sloConfig, sloConfig2)
val sloFactory = SloFactory()
val combinedSlos = sloFactory.createSlos(execution,benchmark)
val execution = BenchmarkExecution().also { exec ->
exec.slos = listOf(
// SLOs, which should override benchmark SLO values for these properties
BenchmarkExecution.SloConfiguration(). also {
it.name = "test"
it.properties = mutableMapOf(
// overwriting properties 'threshold' and 'warmup' and adding property 'extensionTest'
"threshold" to "3000",
"warmup" to "80",
"extensionTest" to "extended"
)
},
// SLO with name that isn't defined in the benchmark, therefore it should be ignored by the SloFactory
BenchmarkExecution.SloConfiguration().also {
it.name = "test2"
it.properties = mutableMapOf() // No properties
}
)
}
val combinedSlos = this.sloFactory.createSlos(execution, this.benchmark)
Assertions.assertEquals(1, combinedSlos.size)
Assertions.assertEquals("test", combinedSlos[0].name)
......@@ -66,4 +63,5 @@ internal class SloFactoryTest {
Assertions.assertEquals("80", combinedSlos[0].properties["warmup"])
Assertions.assertEquals("extended", combinedSlos[0].properties["extensionTest"])
}
}
\ No newline at end of file
......@@ -26,8 +26,6 @@ spec:
value: "http://my-confluent-cp-schema-registry:8081"
- name: JAVA_OPTS
value: "-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=5555"
- name: COMMIT_INTERVAL_MS # Set as default for the applications
value: "100"
resources:
limits:
cpu: 1000m
......
......@@ -26,8 +26,6 @@ spec:
value: "http://my-confluent-cp-schema-registry:8081"
- name: JAVA_OPTS
value: "-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=5555"
- name: COMMIT_INTERVAL_MS # Set as default for the applications
value: "100"
resources:
limits:
memory: 4Gi
......
......@@ -4,4 +4,11 @@ metadata:
labels:
app: titan-ccp-aggregation
appScope: titan-ccp
name: test-service-monitor
\ No newline at end of file
name: test-service-monitor
spec:
selector:
matchLabels:
app: flink
endpoints:
- port: metrics
interval: 10s
\ No newline at end of file
......@@ -26,8 +26,6 @@ spec:
value: "http://my-confluent-cp-schema-registry:8081"
- name: JAVA_OPTS
value: "-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=5555"
- name: COMMIT_INTERVAL_MS # Set as default for the applications
value: "100"
resources:
limits:
memory: 4Gi
......
......@@ -26,8 +26,6 @@ spec:
value: "http://my-confluent-cp-schema-registry:8081"
- name: JAVA_OPTS
value: "-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=5555"
- name: COMMIT_INTERVAL_MS # Set as default for the applications
value: "100"
- name: prometheus-jmx-exporter
image: "solsson/kafka-prometheus-jmx-exporter@sha256:6f82e2b0464f50da8104acd7363fb9b995001ddff77d248379f8788e78946143"
command:
......
# Theodolite Random Scheduler
This directory contains the Theodolite Random Scheduler that schedules pods on random nodes.
## Build and Push
## Build and Publish
Run the following commands
- `docker build -t theodolite-random-scheduler .`
- `docker tag theodolite-random-scheduler <user>/theodolite-random-scheduler`
- `docker push <user>/theodolite-random-scheduler`
- `docker tag theodolite-random-scheduler <repo>/theodolite-random-scheduler`
- `docker push <repo>/theodolite-random-scheduler`
## Deployment
Deploy the `deployment.yaml` file into Kubernetes. Note, that the `TARGET_NAMESPACE` environment variable specifies the operating namespace of the random scheduler.