summaryrefslogtreecommitdiff
path: root/opendc-compute/opendc-compute-failure/src/main
diff options
context:
space:
mode:
authorDante Niewenhuis <d.niewenhuis@hotmail.com>2024-05-07 12:33:39 +0200
committerGitHub <noreply@github.com>2024-05-07 12:33:39 +0200
commitad20465a5df47b49561bb0afbdda5cd65c5da4b8 (patch)
tree268f0fde5924b71ca2750dbbbba4cbe24c361f12 /opendc-compute/opendc-compute-failure/src/main
parent7c0691eb6c348d2e49da3ef354b652cf26604905 (diff)
Revamped failure models (#228)
Diffstat (limited to 'opendc-compute/opendc-compute-failure/src/main')
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/hostfault/HostFault.kt41
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/hostfault/StartStopHostFault.kt62
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/models/FailureModel.kt85
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/models/SampleBasedFailureModel.kt77
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/models/TraceBasedFailureModel.kt125
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/G5k06.kt115
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Lanl05.kt115
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Ldns04.kt115
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Microsoft99.kt115
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Nd07cpu.kt115
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Overnet03.kt115
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Pl05.kt115
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/PrefabFailureModelFactory.kt140
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Skype06.kt115
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Websites02.kt115
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/victimselector/StochasticVictimSelector.kt82
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/victimselector/VictimSelector.kt47
17 files changed, 1694 insertions, 0 deletions
diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/hostfault/HostFault.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/hostfault/HostFault.kt
new file mode 100644
index 00000000..4134c58a
--- /dev/null
+++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/hostfault/HostFault.kt
@@ -0,0 +1,41 @@
+/*
+ * 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.failure.hostfault
+
+import org.opendc.compute.service.ComputeService
+import org.opendc.compute.simulator.SimHost
+
+/**
+ * Interface responsible for applying the fault to a host.
+ */
+public abstract class HostFault(
+ private val service: ComputeService,
+) {
+ /**
+ * Apply the fault to the specified [victims].
+ */
+ public abstract suspend fun apply(
+ victims: List<SimHost>,
+ faultDuration: Long,
+ )
+}
diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/hostfault/StartStopHostFault.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/hostfault/StartStopHostFault.kt
new file mode 100644
index 00000000..85138025
--- /dev/null
+++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/hostfault/StartStopHostFault.kt
@@ -0,0 +1,62 @@
+/*
+ * 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.failure.hostfault
+
+import kotlinx.coroutines.delay
+import org.opendc.compute.api.ComputeClient
+import org.opendc.compute.service.ComputeService
+import org.opendc.compute.simulator.SimHost
+import org.opendc.simulator.compute.workload.SimWorkload
+
+/**
+ * A type of [HostFault] where the hosts are stopped and recover after a given amount of time.
+ */
+public class StartStopHostFault(
+ private val service: ComputeService,
+) : HostFault(service) {
+ override suspend fun apply(
+ victims: List<SimHost>,
+ faultDuration: Long,
+ ) {
+ val client: ComputeClient = service.newClient()
+
+ for (host in victims) {
+ val servers = host.instances
+
+ val snapshots = servers.map { (it.meta["workload"] as SimWorkload).snapshot() }
+ host.fail()
+
+ for ((server, snapshot) in servers.zip(snapshots)) {
+ client.rescheduleServer(server, snapshot)
+ }
+ }
+
+ delay(faultDuration)
+
+ for (host in victims) {
+ host.recover()
+ }
+ }
+
+ override fun toString(): String = "StartStopHostFault"
+}
diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/models/FailureModel.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/models/FailureModel.kt
new file mode 100644
index 00000000..5f05d96c
--- /dev/null
+++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/models/FailureModel.kt
@@ -0,0 +1,85 @@
+/*
+ * 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.failure.models
+
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.cancel
+import kotlinx.coroutines.launch
+import org.opendc.compute.failure.hostfault.HostFault
+import org.opendc.compute.failure.hostfault.StartStopHostFault
+import org.opendc.compute.failure.victimselector.StochasticVictimSelector
+import org.opendc.compute.service.ComputeService
+import org.opendc.compute.simulator.SimHost
+import java.time.InstantSource
+import java.util.random.RandomGenerator
+import kotlin.coroutines.CoroutineContext
+
+/**
+ * Factory interface for constructing [FailureModel] for modeling failures of compute service hosts.
+ */
+public abstract class FailureModel(
+ context: CoroutineContext,
+ protected val clock: InstantSource,
+ protected val service: ComputeService,
+ protected val random: RandomGenerator,
+) : AutoCloseable {
+ protected val scope: CoroutineScope = CoroutineScope(context + Job())
+
+ // TODO: could at some point be extended to different types of faults
+ protected val fault: HostFault = StartStopHostFault(service)
+
+ // TODO: could at some point be extended to different types of victim selectors
+ protected val victimSelector: StochasticVictimSelector = StochasticVictimSelector(random)
+
+ protected val hosts: Set<SimHost> = service.hosts.map { it as SimHost }.toSet()
+
+ /**
+ * The [Job] that awaits the nearest fault in the system.
+ */
+ private var job: Job? = null
+
+ /**
+ * Start the fault injection into the system.
+ */
+ public fun start() {
+ if (job != null) {
+ return
+ }
+
+ job =
+ scope.launch {
+ runInjector()
+ job = null
+ }
+ }
+
+ public abstract suspend fun runInjector()
+
+ /**
+ * Stop the fault injector.
+ */
+ public override fun close() {
+ scope.cancel()
+ }
+}
diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/models/SampleBasedFailureModel.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/models/SampleBasedFailureModel.kt
new file mode 100644
index 00000000..3ae66f6f
--- /dev/null
+++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/models/SampleBasedFailureModel.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2024 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.failure.models
+
+import kotlinx.coroutines.delay
+import org.apache.commons.math3.distribution.RealDistribution
+import org.opendc.compute.service.ComputeService
+import java.time.InstantSource
+import java.util.random.RandomGenerator
+import kotlin.coroutines.CoroutineContext
+import kotlin.math.max
+import kotlin.math.min
+import kotlin.math.roundToLong
+
+/**
+ * Sample based failure model
+ *
+ * @property context
+ * @property clock
+ * @property service
+ * @property random
+ * @property iatSampler A distribution from which the time until the next fault is sampled in ms
+ * @property durationSampler A distribution from which the duration of a fault is sampled in s
+ * @property nohSampler A distribution from which the number of hosts that fault is sampled.
+ */
+public class SampleBasedFailureModel(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+ private val iatSampler: RealDistribution,
+ private val durationSampler: RealDistribution,
+ private val nohSampler: RealDistribution,
+) : FailureModel(context, clock, service, random) {
+ override suspend fun runInjector() {
+ while (true) {
+ val iatSample = max(0.0, iatSampler.sample())
+ val intervalDuration = (iatSample * 3.6e6).roundToLong()
+
+ // Handle long overflow
+ if (clock.millis() + intervalDuration <= 0) {
+ return
+ }
+
+ delay(intervalDuration)
+
+ val numberOfHosts = min(1.0, max(0.0, nohSampler.sample()))
+ val victims = victimSelector.select(hosts, numberOfHosts)
+
+ val durationSample = max(0.0, durationSampler.sample())
+ val faultDuration = (durationSample * 3.6e6).toLong()
+ fault.apply(victims, faultDuration)
+
+ break
+ }
+ }
+}
diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/models/TraceBasedFailureModel.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/models/TraceBasedFailureModel.kt
new file mode 100644
index 00000000..db8bb1ec
--- /dev/null
+++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/models/TraceBasedFailureModel.kt
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2024 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.failure.models
+
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+import org.opendc.compute.service.ComputeService
+import org.opendc.trace.Trace
+import org.opendc.trace.conv.FAILURE_DURATION
+import org.opendc.trace.conv.FAILURE_INTENSITY
+import org.opendc.trace.conv.FAILURE_INTERVAL
+import org.opendc.trace.conv.TABLE_FAILURES
+import java.io.File
+import java.time.InstantSource
+import java.util.random.RandomGenerator
+import kotlin.coroutines.CoroutineContext
+
+/**
+ * A definition of a Failure
+ *
+ * @property failureInterval The time between this and the previous failure in ms
+ * @property failureDuration The Duration of the failure in ms
+ * @property failureIntensity The ratio of hosts affected by the failure
+ * @constructor Create empty Failure
+ */
+public data class Failure(
+ val failureInterval: Long,
+ val failureDuration: Long,
+ val failureIntensity: Double,
+) {
+ init {
+ require(failureInterval >= 0.0) { "A failure cannot start at a negative time" }
+ require(failureDuration >= 0.0) { "A failure can not have a duration of 0 or less" }
+ require(failureIntensity > 0.0 && failureIntensity <= 1.0) { "The intensity of a failure has to be in the range (0.0, 1.0]" }
+ }
+}
+
+/**
+ * A [FailureModel] based on a provided parquet file
+ * The file provides a list of [Failure] objects
+ *
+ *
+ * @param context
+ * @param clock
+ * @param service
+ * @param random
+ * @param pathToTrace The path to the parquet file as a [String]
+ */
+public class TraceBasedFailureModel(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+ pathToTrace: String,
+ private val repeat: Boolean = false,
+) : FailureModel(context, clock, service, random) {
+ private val failureList = loadTrace(pathToTrace)
+
+ override suspend fun runInjector() {
+ do {
+ for (failure in failureList) {
+ delay(failure.failureInterval - clock.millis())
+
+ val victims = victimSelector.select(hosts, failure.failureIntensity)
+ scope.launch {
+ fault.apply(victims, failure.failureDuration)
+ }
+ }
+ } while (repeat)
+ }
+
+ /**
+ * Load a list [Failure] objects from the provided [pathToFile]
+ *
+ * @param pathToFile
+ */
+ private fun loadTrace(pathToFile: String): List<Failure> {
+ val trace = Trace.open(File(pathToFile), "failure")
+
+ val reader = checkNotNull(trace.getTable(TABLE_FAILURES)).newReader()
+
+ val failureStartTimeCol = reader.resolve(FAILURE_INTERVAL)
+ val failureDurationCol = reader.resolve(FAILURE_DURATION)
+ val failureIntensityCol = reader.resolve(FAILURE_INTENSITY)
+
+ val entries = mutableListOf<Failure>()
+
+ try {
+ while (reader.nextRow()) {
+ val failureStartTime = reader.getLong(failureStartTimeCol)
+ val failureDuration = reader.getLong(failureDurationCol)
+ val failureIntensity = reader.getDouble(failureIntensityCol)
+
+ entries.add(Failure(failureStartTime, failureDuration, failureIntensity))
+ }
+
+ return entries
+ } catch (e: Exception) {
+ e.printStackTrace()
+ throw e
+ } finally {
+ reader.close()
+ }
+ }
+}
diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/G5k06.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/G5k06.kt
new file mode 100644
index 00000000..da58250d
--- /dev/null
+++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/G5k06.kt
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2024 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.failure.prefab
+
+import org.apache.commons.math3.distribution.ExponentialDistribution
+import org.apache.commons.math3.distribution.GammaDistribution
+import org.apache.commons.math3.distribution.LogNormalDistribution
+import org.apache.commons.math3.distribution.UniformRealDistribution
+import org.apache.commons.math3.distribution.WeibullDistribution
+import org.apache.commons.math3.random.Well19937c
+import org.opendc.compute.failure.models.SampleBasedFailureModel
+import org.opendc.compute.service.ComputeService
+import java.time.InstantSource
+import java.util.random.RandomGenerator
+import kotlin.coroutines.CoroutineContext
+
+/**
+ * Failure models based on values taken from "The Failure Trace Archive: Enabling the comparison of failure measurements and models of distributed systems"
+ * Which can be found at https://www-sciencedirect-com.vu-nl.idm.oclc.org/science/article/pii/S0743731513000634
+ */
+public fun createG5k06Exp(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ ExponentialDistribution(rng, 32.41),
+ ExponentialDistribution(rng, 7.41),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
+
+public fun createG5k06Wbl(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ WeibullDistribution(rng, 0.48, 14.37),
+ WeibullDistribution(rng, 0.35, 0.47),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
+
+public fun createG5k06LogN(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ LogNormalDistribution(rng, 1.51, 2.42),
+ LogNormalDistribution(rng, -2.0, 2.2),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
+
+public fun createG5k06Gam(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ GammaDistribution(rng, 0.34, 94.35),
+ GammaDistribution(rng, 0.19, 39.92),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Lanl05.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Lanl05.kt
new file mode 100644
index 00000000..3e722630
--- /dev/null
+++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Lanl05.kt
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2024 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.failure.prefab
+
+import org.apache.commons.math3.distribution.ExponentialDistribution
+import org.apache.commons.math3.distribution.GammaDistribution
+import org.apache.commons.math3.distribution.LogNormalDistribution
+import org.apache.commons.math3.distribution.UniformRealDistribution
+import org.apache.commons.math3.distribution.WeibullDistribution
+import org.apache.commons.math3.random.Well19937c
+import org.opendc.compute.failure.models.SampleBasedFailureModel
+import org.opendc.compute.service.ComputeService
+import java.time.InstantSource
+import java.util.random.RandomGenerator
+import kotlin.coroutines.CoroutineContext
+
+/**
+ * Failure models based on values taken from "The Failure Trace Archive: Enabling the comparison of failure measurements and models of distributed systems"
+ * Which can be found at https://www-sciencedirect-com.vu-nl.idm.oclc.org/science/article/pii/S0743731513000634
+ */
+public fun createLanl05Exp(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ ExponentialDistribution(rng, 1779.99),
+ ExponentialDistribution(rng, 5.92),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
+
+public fun createLanl05Wbl(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ WeibullDistribution(rng, 0.48, 816.60),
+ WeibullDistribution(rng, 0.58, 2.18),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
+
+public fun createLanl05LogN(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ LogNormalDistribution(rng, 5.56, 2.39),
+ LogNormalDistribution(rng, 0.05, 1.42),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
+
+public fun createLanl05Gam(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ GammaDistribution(rng, 0.35, 5102.71),
+ GammaDistribution(rng, 0.38, 15.44),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Ldns04.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Ldns04.kt
new file mode 100644
index 00000000..4a8b3c0f
--- /dev/null
+++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Ldns04.kt
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2024 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.failure.prefab
+
+import org.apache.commons.math3.distribution.ExponentialDistribution
+import org.apache.commons.math3.distribution.GammaDistribution
+import org.apache.commons.math3.distribution.LogNormalDistribution
+import org.apache.commons.math3.distribution.UniformRealDistribution
+import org.apache.commons.math3.distribution.WeibullDistribution
+import org.apache.commons.math3.random.Well19937c
+import org.opendc.compute.failure.models.SampleBasedFailureModel
+import org.opendc.compute.service.ComputeService
+import java.time.InstantSource
+import java.util.random.RandomGenerator
+import kotlin.coroutines.CoroutineContext
+
+/**
+ * Failure models based on values taken from "The Failure Trace Archive: Enabling the comparison of failure measurements and models of distributed systems"
+ * Which can be found at https://www-sciencedirect-com.vu-nl.idm.oclc.org/science/article/pii/S0743731513000634
+ */
+public fun createLdns04Exp(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ ExponentialDistribution(rng, 141.06),
+ ExponentialDistribution(rng, 8.61),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
+
+public fun createLdns04Wbl(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ WeibullDistribution(rng, 0.51, 79.30),
+ WeibullDistribution(rng, 0.63, 5.62),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
+
+public fun createLdns04LogN(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ LogNormalDistribution(rng, 3.25, 2.33),
+ LogNormalDistribution(rng, 0.91, 1.64),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
+
+public fun createLdns04Gam(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ GammaDistribution(rng, 0.39, 362.43),
+ GammaDistribution(rng, 0.51, 16.87),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Microsoft99.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Microsoft99.kt
new file mode 100644
index 00000000..725f6622
--- /dev/null
+++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Microsoft99.kt
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2024 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.failure.prefab
+
+import org.apache.commons.math3.distribution.ExponentialDistribution
+import org.apache.commons.math3.distribution.GammaDistribution
+import org.apache.commons.math3.distribution.LogNormalDistribution
+import org.apache.commons.math3.distribution.UniformRealDistribution
+import org.apache.commons.math3.distribution.WeibullDistribution
+import org.apache.commons.math3.random.Well19937c
+import org.opendc.compute.failure.models.SampleBasedFailureModel
+import org.opendc.compute.service.ComputeService
+import java.time.InstantSource
+import java.util.random.RandomGenerator
+import kotlin.coroutines.CoroutineContext
+
+/**
+ * Failure models based on values taken from "The Failure Trace Archive: Enabling the comparison of failure measurements and models of distributed systems"
+ * Which can be found at https://www-sciencedirect-com.vu-nl.idm.oclc.org/science/article/pii/S0743731513000634
+ */
+public fun createMicrosoft99Exp(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ ExponentialDistribution(rng, 67.01),
+ ExponentialDistribution(rng, 16.49),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
+
+public fun createMicrosoft99Wbl(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ WeibullDistribution(rng, 0.55, 35.30),
+ WeibullDistribution(rng, 0.60, 9.34),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
+
+public fun createMicrosoft99LogN(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ LogNormalDistribution(rng, 2.62, 1.84),
+ LogNormalDistribution(rng, 1.42, 1.54),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
+
+public fun createMicrosoft99Gam(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ GammaDistribution(rng, 0.41, 162.19),
+ GammaDistribution(rng, 0.46, 35.52),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Nd07cpu.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Nd07cpu.kt
new file mode 100644
index 00000000..100a3a8d
--- /dev/null
+++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Nd07cpu.kt
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2024 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.failure.prefab
+
+import org.apache.commons.math3.distribution.ExponentialDistribution
+import org.apache.commons.math3.distribution.GammaDistribution
+import org.apache.commons.math3.distribution.LogNormalDistribution
+import org.apache.commons.math3.distribution.UniformRealDistribution
+import org.apache.commons.math3.distribution.WeibullDistribution
+import org.apache.commons.math3.random.Well19937c
+import org.opendc.compute.failure.models.SampleBasedFailureModel
+import org.opendc.compute.service.ComputeService
+import java.time.InstantSource
+import java.util.random.RandomGenerator
+import kotlin.coroutines.CoroutineContext
+
+/**
+ * Failure models based on values taken from "The Failure Trace Archive: Enabling the comparison of failure measurements and models of distributed systems"
+ * Which can be found at https://www-sciencedirect-com.vu-nl.idm.oclc.org/science/article/pii/S0743731513000634
+ */
+public fun createNd07cpuExp(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ ExponentialDistribution(rng, 13.73),
+ ExponentialDistribution(rng, 4.25),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
+
+public fun createNd07cpuWbl(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ WeibullDistribution(rng, 0.45, 4.16),
+ WeibullDistribution(rng, 0.51, 0.74),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
+
+public fun createNd07cpuLogN(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ LogNormalDistribution(rng, 0.30, 2.20),
+ LogNormalDistribution(rng, -1.02, 1.27),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
+
+public fun createNd07cpuGam(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ GammaDistribution(rng, 0.30, 46.16),
+ GammaDistribution(rng, 0.28, 15.07),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Overnet03.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Overnet03.kt
new file mode 100644
index 00000000..4f5e3f84
--- /dev/null
+++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Overnet03.kt
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2024 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.failure.prefab
+
+import org.apache.commons.math3.distribution.ExponentialDistribution
+import org.apache.commons.math3.distribution.GammaDistribution
+import org.apache.commons.math3.distribution.LogNormalDistribution
+import org.apache.commons.math3.distribution.UniformRealDistribution
+import org.apache.commons.math3.distribution.WeibullDistribution
+import org.apache.commons.math3.random.Well19937c
+import org.opendc.compute.failure.models.SampleBasedFailureModel
+import org.opendc.compute.service.ComputeService
+import java.time.InstantSource
+import java.util.random.RandomGenerator
+import kotlin.coroutines.CoroutineContext
+
+/**
+ * Failure models based on values taken from "The Failure Trace Archive: Enabling the comparison of failure measurements and models of distributed systems"
+ * Which can be found at https://www-sciencedirect-com.vu-nl.idm.oclc.org/science/article/pii/S0743731513000634
+ */
+public fun createOvernet03Exp(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ ExponentialDistribution(rng, 2.29),
+ ExponentialDistribution(rng, 12.00),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
+
+public fun createOvernet03Wbl(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ WeibullDistribution(rng, 0.85, 2.04),
+ WeibullDistribution(rng, 0.44, 2.98),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
+
+public fun createOvernet03LogN(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ LogNormalDistribution(rng, 0.19, 0.98),
+ LogNormalDistribution(rng, 0.08, 1.80),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
+
+public fun createOvernet03Gam(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ GammaDistribution(rng, 0.91, 2.53),
+ GammaDistribution(rng, 0.29, 41.64),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Pl05.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Pl05.kt
new file mode 100644
index 00000000..3e1f1b58
--- /dev/null
+++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Pl05.kt
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2024 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.failure.prefab
+
+import org.apache.commons.math3.distribution.ExponentialDistribution
+import org.apache.commons.math3.distribution.GammaDistribution
+import org.apache.commons.math3.distribution.LogNormalDistribution
+import org.apache.commons.math3.distribution.UniformRealDistribution
+import org.apache.commons.math3.distribution.WeibullDistribution
+import org.apache.commons.math3.random.Well19937c
+import org.opendc.compute.failure.models.SampleBasedFailureModel
+import org.opendc.compute.service.ComputeService
+import java.time.InstantSource
+import java.util.random.RandomGenerator
+import kotlin.coroutines.CoroutineContext
+
+/**
+ * Failure models based on values taken from "The Failure Trace Archive: Enabling the comparison of failure measurements and models of distributed systems"
+ * Which can be found at https://www-sciencedirect-com.vu-nl.idm.oclc.org/science/article/pii/S0743731513000634
+ */
+public fun createPl05Exp(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ ExponentialDistribution(rng, 159.49),
+ ExponentialDistribution(rng, 49.61),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
+
+public fun createPl05Wbl(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ WeibullDistribution(rng, 0.33, 19.35),
+ WeibullDistribution(rng, 0.36, 5.59),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
+
+public fun createPl05LogN(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ LogNormalDistribution(rng, 1.44, 2.86),
+ LogNormalDistribution(rng, 0.40, 2.45),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
+
+public fun createPl05Gam(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ GammaDistribution(rng, 0.20, 788.03),
+ GammaDistribution(rng, 0.21, 237.65),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/PrefabFailureModelFactory.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/PrefabFailureModelFactory.kt
new file mode 100644
index 00000000..477f3ac4
--- /dev/null
+++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/PrefabFailureModelFactory.kt
@@ -0,0 +1,140 @@
+/*
+ * 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.
+ */
+
+@file:JvmName("FailureModels")
+
+package org.opendc.compute.failure.prefab
+
+import org.opendc.compute.failure.models.SampleBasedFailureModel
+import org.opendc.compute.service.ComputeService
+import java.time.InstantSource
+import java.util.random.RandomGenerator
+import kotlin.coroutines.CoroutineContext
+
+public enum class FailurePrefab {
+ G5k06Exp,
+ G5k06Wbl,
+ G5k06LogN,
+ G5k06Gam,
+ Lanl05Exp,
+ Lanl05Wbl,
+ Lanl05LogN,
+ Lanl05Gam,
+ Ldns04Exp,
+ Ldns04Wbl,
+ Ldns04LogN,
+ Ldns04Gam,
+ Microsoft99Exp,
+ Microsoft99Wbl,
+ Microsoft99LogN,
+ Microsoft99Gam,
+ Nd07cpuExp,
+ Nd07cpuWbl,
+ Nd07cpuLogN,
+ Nd07cpuGam,
+ Overnet03Exp,
+ Overnet03Wbl,
+ Overnet03LogN,
+ Overnet03Gam,
+ Pl05Exp,
+ Pl05Wbl,
+ Pl05LogN,
+ Pl05Gam,
+ Skype06Exp,
+ Skype06Wbl,
+ Skype06LogN,
+ Skype06Gam,
+ Websites02Exp,
+ Websites02Wbl,
+ Websites02LogN,
+ Websites02Gam,
+}
+
+/**
+ * Get a [SampleBasedFailureModel] based on the provided prefab.
+ * All Failure models are based on values taken from "The Failure Trace Archive: Enabling the comparison of failure measurements and models of distributed systems"
+ * Which can be found at https://www-sciencedirect-com.vu-nl.idm.oclc.org/science/article/pii/S0743731513000634
+ *
+ *
+ * @param context
+ * @param clock
+ * @param service
+ * @param random
+ * @param prefab The name of the failure model prefab
+ * @return
+ */
+public fun createFailureModelPrefab(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+ prefab: FailurePrefab,
+): SampleBasedFailureModel {
+ when (prefab) {
+ FailurePrefab.G5k06Exp -> return createG5k06Exp(context, clock, service, random)
+ FailurePrefab.G5k06Wbl -> return createG5k06Wbl(context, clock, service, random)
+ FailurePrefab.G5k06LogN -> return createG5k06LogN(context, clock, service, random)
+ FailurePrefab.G5k06Gam -> return createG5k06Gam(context, clock, service, random)
+
+ FailurePrefab.Lanl05Exp -> return createLanl05Exp(context, clock, service, random)
+ FailurePrefab.Lanl05Wbl -> return createLanl05Wbl(context, clock, service, random)
+ FailurePrefab.Lanl05LogN -> return createLanl05LogN(context, clock, service, random)
+ FailurePrefab.Lanl05Gam -> return createLanl05Gam(context, clock, service, random)
+
+ FailurePrefab.Ldns04Exp -> return createLdns04Exp(context, clock, service, random)
+ FailurePrefab.Ldns04Wbl -> return createLdns04Wbl(context, clock, service, random)
+ FailurePrefab.Ldns04LogN -> return createLdns04LogN(context, clock, service, random)
+ FailurePrefab.Ldns04Gam -> return createLdns04Gam(context, clock, service, random)
+
+ FailurePrefab.Microsoft99Exp -> return createMicrosoft99Exp(context, clock, service, random)
+ FailurePrefab.Microsoft99Wbl -> return createMicrosoft99Wbl(context, clock, service, random)
+ FailurePrefab.Microsoft99LogN -> return createMicrosoft99LogN(context, clock, service, random)
+ FailurePrefab.Microsoft99Gam -> return createMicrosoft99Gam(context, clock, service, random)
+
+ FailurePrefab.Nd07cpuExp -> return createNd07cpuExp(context, clock, service, random)
+ FailurePrefab.Nd07cpuWbl -> return createNd07cpuWbl(context, clock, service, random)
+ FailurePrefab.Nd07cpuLogN -> return createNd07cpuLogN(context, clock, service, random)
+ FailurePrefab.Nd07cpuGam -> return createNd07cpuGam(context, clock, service, random)
+
+ FailurePrefab.Overnet03Exp -> return createOvernet03Exp(context, clock, service, random)
+ FailurePrefab.Overnet03Wbl -> return createOvernet03Wbl(context, clock, service, random)
+ FailurePrefab.Overnet03LogN -> return createOvernet03LogN(context, clock, service, random)
+ FailurePrefab.Overnet03Gam -> return createOvernet03Gam(context, clock, service, random)
+
+ FailurePrefab.Pl05Exp -> return createPl05Exp(context, clock, service, random)
+ FailurePrefab.Pl05Wbl -> return createPl05Wbl(context, clock, service, random)
+ FailurePrefab.Pl05LogN -> return createPl05LogN(context, clock, service, random)
+ FailurePrefab.Pl05Gam -> return createPl05Gam(context, clock, service, random)
+
+ FailurePrefab.Skype06Exp -> return createSkype06Exp(context, clock, service, random)
+ FailurePrefab.Skype06Wbl -> return createSkype06Wbl(context, clock, service, random)
+ FailurePrefab.Skype06LogN -> return createSkype06LogN(context, clock, service, random)
+ FailurePrefab.Skype06Gam -> return createSkype06Gam(context, clock, service, random)
+
+ FailurePrefab.Websites02Exp -> return createWebsites02Exp(context, clock, service, random)
+ FailurePrefab.Websites02Wbl -> return createWebsites02Wbl(context, clock, service, random)
+ FailurePrefab.Websites02LogN -> return createWebsites02LogN(context, clock, service, random)
+ FailurePrefab.Websites02Gam -> return createWebsites02Gam(context, clock, service, random)
+
+ else -> error("Unknown failure prefab: $prefab")
+ }
+}
diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Skype06.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Skype06.kt
new file mode 100644
index 00000000..7495bf66
--- /dev/null
+++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Skype06.kt
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2024 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.failure.prefab
+
+import org.apache.commons.math3.distribution.ExponentialDistribution
+import org.apache.commons.math3.distribution.GammaDistribution
+import org.apache.commons.math3.distribution.LogNormalDistribution
+import org.apache.commons.math3.distribution.UniformRealDistribution
+import org.apache.commons.math3.distribution.WeibullDistribution
+import org.apache.commons.math3.random.Well19937c
+import org.opendc.compute.failure.models.SampleBasedFailureModel
+import org.opendc.compute.service.ComputeService
+import java.time.InstantSource
+import java.util.random.RandomGenerator
+import kotlin.coroutines.CoroutineContext
+
+/**
+ * Failure models based on values taken from "The Failure Trace Archive: Enabling the comparison of failure measurements and models of distributed systems"
+ * Which can be found at https://www-sciencedirect-com.vu-nl.idm.oclc.org/science/article/pii/S0743731513000634
+ */
+public fun createSkype06Exp(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ ExponentialDistribution(rng, 16.27),
+ ExponentialDistribution(rng, 14.31),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
+
+public fun createSkype06Wbl(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ WeibullDistribution(rng, 0.64, 10.86),
+ WeibullDistribution(rng, 0.63, 9.48),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
+
+public fun createSkype06LogN(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ LogNormalDistribution(rng, 1.60, 1.57),
+ LogNormalDistribution(rng, 1.40, 1.73),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
+
+public fun createSkype06Gam(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ GammaDistribution(rng, 0.53, 30.79),
+ GammaDistribution(rng, 0.50, 28.53),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Websites02.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Websites02.kt
new file mode 100644
index 00000000..77bb0d64
--- /dev/null
+++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Websites02.kt
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2024 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.failure.prefab
+
+import org.apache.commons.math3.distribution.ExponentialDistribution
+import org.apache.commons.math3.distribution.GammaDistribution
+import org.apache.commons.math3.distribution.LogNormalDistribution
+import org.apache.commons.math3.distribution.UniformRealDistribution
+import org.apache.commons.math3.distribution.WeibullDistribution
+import org.apache.commons.math3.random.Well19937c
+import org.opendc.compute.failure.models.SampleBasedFailureModel
+import org.opendc.compute.service.ComputeService
+import java.time.InstantSource
+import java.util.random.RandomGenerator
+import kotlin.coroutines.CoroutineContext
+
+/**
+ * Failure models based on values taken from "The Failure Trace Archive: Enabling the comparison of failure measurements and models of distributed systems"
+ * Which can be found at https://www-sciencedirect-com.vu-nl.idm.oclc.org/science/article/pii/S0743731513000634
+ */
+public fun createWebsites02Exp(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ ExponentialDistribution(rng, 11.85),
+ ExponentialDistribution(rng, 1.18),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
+
+public fun createWebsites02Wbl(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ WeibullDistribution(rng, 0.46, 3.68),
+ WeibullDistribution(rng, 0.65, 0.61),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
+
+public fun createWebsites02LogN(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ LogNormalDistribution(rng, 0.23, 2.02),
+ LogNormalDistribution(rng, -1.12, 1.13),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
+
+public fun createWebsites02Gam(
+ context: CoroutineContext,
+ clock: InstantSource,
+ service: ComputeService,
+ random: RandomGenerator,
+): SampleBasedFailureModel {
+ val rng = Well19937c(random.nextLong())
+
+ return SampleBasedFailureModel(
+ context,
+ clock,
+ service,
+ random,
+ GammaDistribution(rng, 0.31, 38.67),
+ GammaDistribution(rng, 0.50, 2.37),
+ UniformRealDistribution(0.0, 1.0),
+ )
+}
diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/victimselector/StochasticVictimSelector.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/victimselector/StochasticVictimSelector.kt
new file mode 100644
index 00000000..fef60eb3
--- /dev/null
+++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/victimselector/StochasticVictimSelector.kt
@@ -0,0 +1,82 @@
+/*
+ * 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.failure.victimselector
+
+import org.opendc.compute.simulator.SimHost
+import java.util.SplittableRandom
+import java.util.random.RandomGenerator
+import kotlin.math.max
+import kotlin.math.min
+
+/**
+ * A [VictimSelector] that stochastically selects a set of hosts to be failed.
+ */
+public class StochasticVictimSelector(
+ private val random: RandomGenerator = SplittableRandom(0),
+) : VictimSelector {
+ override fun select(numberOfHosts: Int): List<SimHost> {
+ error("select with only int cannot be used in this type of VictimSelector")
+ }
+
+ override fun select(
+ hosts: Set<SimHost>,
+ numberOfHosts: Int,
+ ): List<SimHost> {
+ val result = ArrayList<SimHost>(numberOfHosts)
+
+ val random = random
+ var samplesNeeded = numberOfHosts
+ var remainingHosts = hosts.size
+ val iterator = hosts.iterator()
+
+ while (iterator.hasNext() && samplesNeeded > 0) {
+ val host = iterator.next()
+
+ if (random.nextInt(remainingHosts) < samplesNeeded) {
+ result.add(host)
+ samplesNeeded--
+ }
+
+ remainingHosts--
+ }
+
+ return result
+ }
+
+ override fun select(failureIntensity: Double): List<SimHost> {
+ error("select with only int cannot be used in this type of VictimSelector")
+ }
+
+ override fun select(
+ hosts: Set<SimHost>,
+ failureIntensity: Double,
+ ): List<SimHost> {
+ // clamp value between 0.0 and 1.0
+ val intensity = min(1.0, max(0.0, failureIntensity))
+ val numberOfHosts = (hosts.size * intensity).toInt()
+
+ return hosts.asSequence().shuffled().take(numberOfHosts).toList()
+ }
+
+ override fun toString(): String = "StochasticVictimSelector"
+}
diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/victimselector/VictimSelector.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/victimselector/VictimSelector.kt
new file mode 100644
index 00000000..955cbced
--- /dev/null
+++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/victimselector/VictimSelector.kt
@@ -0,0 +1,47 @@
+/*
+ * 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.failure.victimselector
+
+import org.opendc.compute.simulator.SimHost
+
+/**
+ * Interface responsible for selecting the victim(s) for fault injection.
+ */
+public interface VictimSelector {
+ /**
+ * Select the hosts from [hosts] where a fault will be injected.
+ */
+ public fun select(
+ hosts: Set<SimHost>,
+ numberOfHosts: Int,
+ ): List<SimHost>
+
+ public fun select(numberOfHosts: Int): List<SimHost>
+
+ public fun select(failureIntensity: Double): List<SimHost>
+
+ public fun select(
+ hosts: Set<SimHost>,
+ failureIntensity: Double,
+ ): List<SimHost>
+}