diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/ExternalSloChecker.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/ExternalSloChecker.kt index 01b21c845a614ba42581c182d975da5ad645b474..3a76fa7c0d9511b8989d3e444cbefe5c8a50b285 100644 --- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/ExternalSloChecker.kt +++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/ExternalSloChecker.kt @@ -11,8 +11,8 @@ import java.net.ConnectException * @param metadata metadata passed to the external SLO checker. */ class ExternalSloChecker( - private val externalSlopeURL: String, - private val metadata: Map<String, Any> + val externalSlopeURL: String, + val metadata: Map<String, Any> ) : SloChecker { private val RETRIES = 2 diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloCheckerFactory.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloCheckerFactory.kt index 810675f159169f31314289d08a59fcc15bf8a243..a789050a106f1b95be7c1d55043cc9d46a15ffbf 100644 --- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloCheckerFactory.kt +++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/SloCheckerFactory.kt @@ -41,7 +41,7 @@ class SloCheckerFactory { */ fun create( sloType: String, - properties: MutableMap<String, String>, + properties: Map<String, String>, load: Int, resource: Int, metric: Metric @@ -58,7 +58,7 @@ class SloCheckerFactory { "repetitionAggregation" to (properties["repetitionAggregation"] ?: throw IllegalArgumentException("repetitionAggregation expected")), "operator" to (properties["operator"] ?: throw IllegalArgumentException("operator expected")), - "threshold" to (properties["threshold"]?.toInt() + "threshold" to (properties["threshold"]?.toDouble() ?: throw IllegalArgumentException("threshold expected")) ) ) @@ -67,7 +67,7 @@ class SloCheckerFactory { ?: throw IllegalArgumentException("externalSloUrl expected"), metadata = mapOf( "warmup" to (properties["warmup"]?.toInt() ?: throw IllegalArgumentException("warmup expected")), - "threshold" to (properties["threshold"]?.toInt() + "threshold" to (properties["threshold"]?.toDouble() ?: throw IllegalArgumentException("threshold expected")) ) ) @@ -78,8 +78,8 @@ class SloCheckerFactory { if (thresholdRatio < 0.0) { throw IllegalArgumentException("Threshold ratio needs to be an Double greater or equal 0.0") } - // cast to int, as rounding is not really necessary - val threshold = (load * thresholdRatio).toInt() + + val threshold = (load * thresholdRatio) ExternalSloChecker( externalSlopeURL = properties["externalSloUrl"] diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/slo/ExternalSloCheckerTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/slo/ExternalSloCheckerTest.kt index 1ea422c93a32e6ab360853b1b9f6e7532c3641d3..2c0b1119402c3c443537367091ce99e601d6c2bd 100644 --- a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/slo/ExternalSloCheckerTest.kt +++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/slo/ExternalSloCheckerTest.kt @@ -23,18 +23,15 @@ internal class ExternalSloCheckerTest { @AfterEach fun stop() { - wireMockServer?.let { - it.stop() - } + wireMockServer?.stop() } @Test fun testExternalTrueResult() { - stubFor( + this.wireMockServer!!.stubFor( post(urlEqualTo("/")) .willReturn( - aResponse() - .withJsonBody(BooleanNode.getTrue()) + aResponse().withJsonBody(BooleanNode.getTrue()) ) ) @@ -48,11 +45,10 @@ internal class ExternalSloCheckerTest { @Test fun testExternalFalseResult() { - stubFor( + this.wireMockServer!!.stubFor( post(urlEqualTo("/")) .willReturn( - aResponse() - .withJsonBody(BooleanNode.getFalse()) + aResponse().withJsonBody(BooleanNode.getFalse()) ) ) diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/slo/SloCheckerFactoryTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/slo/SloCheckerFactoryTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..a61119bbe0e5be180ccf3ca2c54ac2829eb4558d --- /dev/null +++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/slo/SloCheckerFactoryTest.kt @@ -0,0 +1,298 @@ +package rocks.theodolite.kubernetes.slo + +import io.quarkus.test.junit.QuarkusTest +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import rocks.theodolite.core.strategies.Metric + +@QuarkusTest +internal class SloCheckerFactoryTest { + + @Test + fun testCreateGenericSloWithoutUrl() { + val factory = SloCheckerFactory() + assertThrows<IllegalArgumentException> { + factory.create( + SloTypes.GENERIC.value, + mapOf( + "warmup" to "60", + "queryAggregation" to "median", + "repetitionAggregation" to "median", + "operator" to "lte", + "threshold" to "1234" + ), + 100, + 5, + Metric.DEMAND + ) + } + } + + @Test + fun testCreateGenericSloWithoutWarmup() { + val factory = SloCheckerFactory() + assertThrows<IllegalArgumentException> { + factory.create( + SloTypes.GENERIC.value, + mapOf( + "externalSloUrl" to "http://localhost:1234", + "queryAggregation" to "median", + "repetitionAggregation" to "median", + "operator" to "lte", + "threshold" to "1234" + ), + 100, + 5, + Metric.DEMAND + ) + } + } + + @Test + fun testCreateGenericSloWithoutQueryAggregation() { + val factory = SloCheckerFactory() + assertThrows<IllegalArgumentException> { + factory.create( + SloTypes.GENERIC.value, + mapOf( + "externalSloUrl" to "http://localhost:1234", + "warmup" to "60", + "repetitionAggregation" to "median", + "operator" to "lte", + "threshold" to "1234" + ), + 100, + 5, + Metric.DEMAND + ) + } + } + + @Test + fun testCreateGenericSloWithoutRepetitionAggregation() { + val factory = SloCheckerFactory() + assertThrows<IllegalArgumentException> { + factory.create( + SloTypes.GENERIC.value, + mapOf( + "externalSloUrl" to "http://localhost:1234", + "warmup" to "60", + "queryAggregation" to "median", + "operator" to "lte", + "threshold" to "1234" + ), + 100, + 5, + Metric.DEMAND + ) + } + } + + @Test + fun testCreateGenericSloWithoutOperator() { + val factory = SloCheckerFactory() + assertThrows<IllegalArgumentException> { + factory.create( + SloTypes.GENERIC.value, + mapOf( + "externalSloUrl" to "http://localhost:1234", + "warmup" to "60", + "queryAggregation" to "median", + "repetitionAggregation" to "median", + "threshold" to "1234" + ), + 100, + 5, + Metric.DEMAND + ) + } + } + + @Test + fun testCreateGenericSloWithoutThreshold() { + val factory = SloCheckerFactory() + assertThrows<IllegalArgumentException> { + factory.create( + SloTypes.GENERIC.value, + mapOf( + "externalSloUrl" to "http://localhost:1234", + "warmup" to "60", + "queryAggregation" to "median", + "repetitionAggregation" to "median", + "operator" to "lte", + ), + 100, + 5, + Metric.DEMAND + ) + } + } + + @Test + fun testCreateGenericSloFloatThreshold() { + val factory = SloCheckerFactory() + val sloChecker = 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 "12.34" + ), + 100, + 5, + Metric.DEMAND + ) + assertInstanceOf(ExternalSloChecker::class.java, sloChecker) + val threshold = (sloChecker as ExternalSloChecker).metadata["threshold"] + assertTrue(threshold is Double, "Expected threshold to be Double.") + assertEquals(12.34, threshold as Double, 0.01) + } + + @Test + fun testCreateLagTrendSloWithoutUrl() { + val factory = SloCheckerFactory() + assertThrows<IllegalArgumentException> { + factory.create( + SloTypes.LAG_TREND.value, + mapOf( + "warmup" to "60", + "threshold" to "1234" + ), + 100, + 5, + Metric.DEMAND + ) + } + } + + @Test + fun testCreateLagTrendSloWithoutWarmup() { + val factory = SloCheckerFactory() + assertThrows<IllegalArgumentException> { + factory.create( + SloTypes.LAG_TREND.value, + mapOf( + "externalSloUrl" to "http://localhost:1234", + "threshold" to "1234" + ), + 100, + 5, + Metric.DEMAND + ) + } + } + + + @Test + fun testCreateLagTrendSloWithoutThreshold() { + val factory = SloCheckerFactory() + assertThrows<IllegalArgumentException> { + factory.create( + SloTypes.LAG_TREND.value, + mapOf( + "externalSloUrl" to "http://localhost:1234", + "warmup" to "60", + ), + 100, + 5, + Metric.DEMAND + ) + } + } + + @Test + fun testCreateLagTrendSloFloatThreshold() { + val factory = SloCheckerFactory() + val sloChecker = factory.create( + SloTypes.LAG_TREND.value, + mapOf( + "externalSloUrl" to "http://localhost:1234", + "warmup" to "60", + "threshold" to "12.34" + ), + 100, + 5, + Metric.DEMAND + ) + assertInstanceOf(ExternalSloChecker::class.java, sloChecker) + val threshold = (sloChecker as ExternalSloChecker).metadata["threshold"] + assertTrue(threshold is Double, "Expected threshold to be Double.") + assertEquals(12.34, threshold as Double, 0.01) + } + + @Test + fun testCreateLagTrendRatioSloWithoutUrl() { + val factory = SloCheckerFactory() + assertThrows<IllegalArgumentException> { + factory.create( + SloTypes.LAG_TREND_RATIO.value, + mapOf( + "warmup" to "60", + "ratio" to "0.123" + ), + 100, + 5, + Metric.DEMAND + ) + } + } + + @Test + fun testCreateLagTrendRatioSloWithoutWarmup() { + val factory = SloCheckerFactory() + assertThrows<IllegalArgumentException> { + factory.create( + SloTypes.LAG_TREND_RATIO.value, + mapOf( + "externalSloUrl" to "http://localhost:1234", + "ratio" to "0.123" + ), + 100, + 5, + Metric.DEMAND + ) + } + } + + + @Test + fun testCreateLagTrendRatioSloWithoutRatioThreshold() { + val factory = SloCheckerFactory() + assertThrows<IllegalArgumentException> { + factory.create( + SloTypes.LAG_TREND_RATIO.value, + mapOf( + "externalSloUrl" to "http://localhost:1234", + "warmup" to "60", + ), + 100, + 5, + Metric.DEMAND + ) + } + } + + @Test + fun testCreateLagTrendRatioSloFloatThreshold() { + val factory = SloCheckerFactory() + val sloChecker = factory.create( + SloTypes.LAG_TREND_RATIO.value, + mapOf( + "externalSloUrl" to "http://localhost:1234", + "warmup" to "60", + "ratio" to "0.123" + ), + 100, + 5, + Metric.DEMAND + ) + assertInstanceOf(ExternalSloChecker::class.java, sloChecker) + val threshold = (sloChecker as ExternalSloChecker).metadata["threshold"] + assertTrue(threshold is Double, "Expected threshold to be Double.") + assertEquals(12.3, threshold as Double, 0.01) + } +} \ No newline at end of file