summaryrefslogtreecommitdiff
path: root/opendc-compute/opendc-compute-simulator/src/test
diff options
context:
space:
mode:
authorFabian Mastenbroek <mail.fabianm@gmail.com>2021-09-10 16:54:46 +0200
committerFabian Mastenbroek <mail.fabianm@gmail.com>2021-09-10 16:54:46 +0200
commitf142be8c2afd1f19bdec183f1169639b7cd1a472 (patch)
tree205bf08e503bc8b8bb2d5af77f0b4aee819f862b /opendc-compute/opendc-compute-simulator/src/test
parent36be169ae8a159a824a2b20cc0eb0e04b569fa09 (diff)
test(compute): Add test suite for fault injector
Diffstat (limited to 'opendc-compute/opendc-compute-simulator/src/test')
-rw-r--r--opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/failure/HostFaultInjectorTest.kt111
1 files changed, 111 insertions, 0 deletions
diff --git a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/failure/HostFaultInjectorTest.kt b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/failure/HostFaultInjectorTest.kt
new file mode 100644
index 00000000..f240a25f
--- /dev/null
+++ b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/failure/HostFaultInjectorTest.kt
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2021 AtLarge Research
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package org.opendc.compute.simulator.failure
+
+import io.mockk.coVerify
+import io.mockk.mockk
+import kotlinx.coroutines.delay
+import org.apache.commons.math3.distribution.LogNormalDistribution
+import org.apache.commons.math3.random.Well19937c
+import org.junit.jupiter.api.Test
+import org.opendc.compute.simulator.SimHost
+import org.opendc.simulator.core.runBlockingSimulation
+import java.time.Clock
+import java.time.Duration
+import kotlin.coroutines.CoroutineContext
+import kotlin.math.ln
+
+/**
+ * Test suite for [HostFaultInjector] class.
+ */
+internal class HostFaultInjectorTest {
+ /**
+ * Simple test case to test that nothing happens when the injector is not started.
+ */
+ @Test
+ fun testInjectorNotStarted() = runBlockingSimulation {
+ val host = mockk<SimHost>(relaxUnitFun = true)
+
+ val injector = createSimpleInjector(coroutineContext, clock, setOf(host))
+
+ coVerify(exactly = 0) { host.fail() }
+ coVerify(exactly = 0) { host.recover() }
+
+ injector.close()
+ }
+
+ /**
+ * Simple test case to test a start stop fault where the machine is stopped and started after some time.
+ */
+ @Test
+ fun testInjectorStopsMachine() = runBlockingSimulation {
+ val host = mockk<SimHost>(relaxUnitFun = true)
+
+ val injector = createSimpleInjector(coroutineContext, clock, setOf(host))
+
+ injector.start()
+
+ delay(Duration.ofDays(55).toMillis())
+
+ injector.close()
+
+ coVerify(exactly = 1) { host.fail() }
+ coVerify(exactly = 1) { host.recover() }
+ }
+
+ /**
+ * Simple test case to test a start stop fault where multiple machines are stopped.
+ */
+ @Test
+ fun testInjectorStopsMultipleMachines() = runBlockingSimulation {
+ val hosts = listOf<SimHost>(
+ mockk(relaxUnitFun = true),
+ mockk(relaxUnitFun = true)
+ )
+
+ val injector = createSimpleInjector(coroutineContext, clock, hosts.toSet())
+
+ injector.start()
+
+ delay(Duration.ofDays(55).toMillis())
+
+ injector.close()
+
+ coVerify(exactly = 1) { hosts[0].fail() }
+ coVerify(exactly = 1) { hosts[1].fail() }
+ coVerify(exactly = 1) { hosts[0].recover() }
+ coVerify(exactly = 1) { hosts[1].recover() }
+ }
+
+ /**
+ * Create a simple start stop fault injector.
+ */
+ private fun createSimpleInjector(context: CoroutineContext, clock: Clock, hosts: Set<SimHost>): HostFaultInjector {
+ val rng = Well19937c(0)
+ val iat = LogNormalDistribution(rng, ln(24 * 7.0), 1.03)
+ val selector = StochasticVictimSelector(LogNormalDistribution(rng, 1.88, 1.25))
+ val fault = StartStopHostFault(LogNormalDistribution(rng, 8.89, 2.71))
+
+ return HostFaultInjector(context, clock, hosts, iat, selector, fault)
+ }
+}