summaryrefslogtreecommitdiff
path: root/opendc-experiments/opendc-experiments-base/src
diff options
context:
space:
mode:
authorDante Niewenhuis <d.niewenhuis@hotmail.com>2024-01-08 13:44:09 +0100
committerGitHub <noreply@github.com>2024-01-08 13:44:09 +0100
commit616017ba78a0882fe38b9b171b2b0f68e593cd8d (patch)
tree9cc4c20078ae10d169c90cbce5b898226a7eee9d /opendc-experiments/opendc-experiments-base/src
parentc57468c5040a838de6901972b6e49a8548d908d6 (diff)
refactored opendc-experiment-compute (#190)
* removed experiment-compute and integrated all components into opendc-compute * updated workflow gradle file * removed unneeded code
Diffstat (limited to 'opendc-experiments/opendc-experiments-base/src')
-rw-r--r--opendc-experiments/opendc-experiments-base/src/jmh/kotlin/org/opendc/experiments/capelin/CapelinBenchmarks.kt93
-rw-r--r--opendc-experiments/opendc-experiments-base/src/jmh/resources/log4j2.xml37
-rw-r--r--opendc-experiments/opendc-experiments-base/src/jmh/resources/topology.txt5
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/MutableServiceRegistry.kt58
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/portfolio/Portfolio.kt (renamed from opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/ServiceRegistry.kt)26
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/portfolio/model/OperationalPhenomena.kt31
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/portfolio/model/Scenario.kt (renamed from opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/provisioner/ProvisioningContext.kt)40
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/portfolio/model/Topology.kt28
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/portfolio/model/Workload.kt33
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/TraceHelpers.kt155
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/internal/ServiceRegistryImpl.kt68
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/provisioner/Provisioner.kt98
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/provisioner/ProvisioningStep.kt61
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/output/host/seed=0/data.parquetbin0 -> 553104 bytes
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/output/server/seed=0/data.parquetbin0 -> 719109 bytes
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/output/service/seed=0/data.parquetbin0 -> 2614 bytes
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/resources/bitbrains-small/interference-model.json21
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/resources/bitbrains-small/trace/meta.parquetbin0 -> 2723 bytes
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/resources/bitbrains-small/trace/trace.parquetbin0 -> 2163354 bytes
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/resources/env/multi.txt5
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/resources/env/single.txt3
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/resources/log4j2.xml43
-rw-r--r--opendc-experiments/opendc-experiments-base/src/test/kotlin/org/opendc/experiments/ServiceRegistryTest.kt114
-rw-r--r--opendc-experiments/opendc-experiments-base/src/test/resources/env/single.txt3
-rw-r--r--opendc-experiments/opendc-experiments-base/src/test/resources/env/topology.txt5
-rw-r--r--opendc-experiments/opendc-experiments-base/src/test/resources/trace/bitbrains-small/interference-model.json21
-rw-r--r--opendc-experiments/opendc-experiments-base/src/test/resources/trace/bitbrains-small/meta.parquetbin0 -> 2723 bytes
-rw-r--r--opendc-experiments/opendc-experiments-base/src/test/resources/trace/bitbrains-small/trace.parquetbin0 -> 2163354 bytes
28 files changed, 506 insertions, 442 deletions
diff --git a/opendc-experiments/opendc-experiments-base/src/jmh/kotlin/org/opendc/experiments/capelin/CapelinBenchmarks.kt b/opendc-experiments/opendc-experiments-base/src/jmh/kotlin/org/opendc/experiments/capelin/CapelinBenchmarks.kt
new file mode 100644
index 00000000..c3408226
--- /dev/null
+++ b/opendc-experiments/opendc-experiments-base/src/jmh/kotlin/org/opendc/experiments/capelin/CapelinBenchmarks.kt
@@ -0,0 +1,93 @@
+/*
+ * 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.experiments.capelin
+
+import org.opendc.compute.service.ComputeService
+import org.opendc.compute.service.scheduler.FilterScheduler
+import org.opendc.compute.service.scheduler.filters.ComputeFilter
+import org.opendc.compute.service.scheduler.filters.RamFilter
+import org.opendc.compute.service.scheduler.filters.VCpuFilter
+import org.opendc.compute.service.scheduler.weights.CoreRamWeigher
+import org.opendc.experiments.capelin.topology.clusterTopology
+import org.opendc.experiments.compute.ComputeWorkloadLoader
+import org.opendc.experiments.compute.VirtualMachine
+import org.opendc.experiments.compute.replay
+import org.opendc.experiments.compute.setupComputeService
+import org.opendc.experiments.compute.setupHosts
+import org.opendc.experiments.compute.topology.HostSpec
+import org.opendc.experiments.compute.trace
+import org.opendc.common.experiments.provisioner.Provisioner
+import org.opendc.simulator.kotlin.runSimulation
+import org.openjdk.jmh.annotations.Benchmark
+import org.openjdk.jmh.annotations.Fork
+import org.openjdk.jmh.annotations.Measurement
+import org.openjdk.jmh.annotations.Param
+import org.openjdk.jmh.annotations.Scope
+import org.openjdk.jmh.annotations.Setup
+import org.openjdk.jmh.annotations.State
+import org.openjdk.jmh.annotations.Warmup
+import java.io.File
+import java.util.Random
+import java.util.concurrent.TimeUnit
+
+/**
+ * Benchmark suite for the Capelin experiments.
+ */
+@State(Scope.Thread)
+@Fork(1)
+@Warmup(iterations = 2, time = 5, timeUnit = TimeUnit.SECONDS)
+@Measurement(iterations = 5, time = 5, timeUnit = TimeUnit.SECONDS)
+class CapelinBenchmarks {
+ private lateinit var vms: List<VirtualMachine>
+ private lateinit var topology: List<HostSpec>
+
+ @Param("true", "false")
+ private var isOptimized: Boolean = false
+
+ @Setup
+ fun setUp() {
+ val loader = ComputeWorkloadLoader(File("src/test/resources/trace"))
+ vms = trace("bitbrains-small").resolve(loader, Random(1L))
+ topology = checkNotNull(object {}.javaClass.getResourceAsStream("/topology.txt")).use { clusterTopology(it) }
+ }
+
+ @Benchmark
+ fun benchmarkCapelin() = runSimulation {
+ val serviceDomain = "compute.opendc.org"
+
+ Provisioner(dispatcher, seed = 0).use { provisioner ->
+ val computeScheduler = FilterScheduler(
+ filters = listOf(ComputeFilter(), VCpuFilter(16.0), RamFilter(1.0)),
+ weighers = listOf(CoreRamWeigher(multiplier = 1.0))
+ )
+
+ provisioner.runSteps(
+ setupComputeService(serviceDomain, { computeScheduler }),
+ setupHosts(serviceDomain, topology, optimize = isOptimized)
+ )
+
+ val service = provisioner.registry.resolve(serviceDomain, ComputeService::class.java)!!
+ service.replay(timeSource, vms, 0L, interference = true)
+ }
+ }
+}
diff --git a/opendc-experiments/opendc-experiments-base/src/jmh/resources/log4j2.xml b/opendc-experiments/opendc-experiments-base/src/jmh/resources/log4j2.xml
new file mode 100644
index 00000000..c496dd75
--- /dev/null
+++ b/opendc-experiments/opendc-experiments-base/src/jmh/resources/log4j2.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ MIT License
+ ~
+ ~ Copyright (c) 2020 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.
+ -->
+
+<Configuration status="WARN">
+ <Appenders>
+ <Console name="Console" target="SYSTEM_OUT">
+ <PatternLayout pattern="%d{HH:mm:ss.SSS} [%highlight{%-5level}] %logger{36} - %msg%n" disableAnsi="false"/>
+ </Console>
+ </Appenders>
+ <Loggers>
+ <Root level="warn">
+ <AppenderRef ref="Console"/>
+ </Root>
+ </Loggers>
+</Configuration>
diff --git a/opendc-experiments/opendc-experiments-base/src/jmh/resources/topology.txt b/opendc-experiments/opendc-experiments-base/src/jmh/resources/topology.txt
new file mode 100644
index 00000000..6b347bff
--- /dev/null
+++ b/opendc-experiments/opendc-experiments-base/src/jmh/resources/topology.txt
@@ -0,0 +1,5 @@
+ClusterID;ClusterName;Cores;Speed;Memory;numberOfHosts;memoryCapacityPerHost;coreCountPerHost
+A01;A01;32;3.2;2048;1;256;32
+B01;B01;48;2.93;1256;6;64;8
+C01;C01;32;3.2;2048;2;128;16
+
diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/MutableServiceRegistry.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/MutableServiceRegistry.kt
deleted file mode 100644
index 160dd393..00000000
--- a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/MutableServiceRegistry.kt
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2022 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.experiments
-
-/**
- * A mutable [ServiceRegistry].
- */
-public interface MutableServiceRegistry : ServiceRegistry {
- /**
- * Register [service] for the specified [name] in this registry.
- *
- * @param name The name of the service to register, which should follow the rules for domain names as defined by
- * DNS.
- * @param type The interface provided by the service.
- * @param service A reference to the actual implementation of the service.
- */
- public fun <T : Any> register(name: String, type: Class<T>, service: T)
-
- /**
- * Remove the service with [name] and [type] from this registry.
- *
- * @param name The name of the service to remove, which should follow the rules for domain names as defined by DNS.
- * @param type The type of the service to remove.
- */
- public fun remove(name: String, type: Class<*>)
-
- /**
- * Remove all services registered with [name].
- *
- * @param name The name of the services to remove, which should follow the rules for domain names as defined by DNS.
- */
- public fun remove(name: String)
-
- /**
- * Create a copy of the registry.
- */
- public override fun clone(): MutableServiceRegistry
-}
diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/ServiceRegistry.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/portfolio/Portfolio.kt
index e9d5b50e..961ae106 100644
--- a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/ServiceRegistry.kt
+++ b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/portfolio/Portfolio.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022 AtLarge Research
+ * 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
@@ -20,26 +20,16 @@
* SOFTWARE.
*/
-package org.opendc.experiments
+package org.opendc.experiments.base.portfolio
+
+import org.opendc.experiments.base.portfolio.model.Scenario
/**
- * A read-only registry of services used during experiments to resolve services.
- *
- * The service registry is similar conceptually to the Domain Name System (DNS), which is a naming system used to
- * identify computers reachable via the Internet. The service registry should be used in a similar fashion.
+ * A portfolio represents a collection of scenarios are tested for the work.
*/
-public interface ServiceRegistry {
- /**
- * Lookup the service with the specified [name] and [type].
- *
- * @param name The name of the service to resolve, which should follow the rules for domain names as defined by DNS.
- * @param type The type of the service to resolve, identified by the interface that is implemented by the service.
- * @return The service with specified [name] and implementing [type] or `null` if it does not exist.
- */
- public fun <T : Any> resolve(name: String, type: Class<T>): T?
-
+public interface Portfolio {
/**
- * Create a copy of the registry.
+ * The scenarios that belong to this portfolio.
*/
- public fun clone(): ServiceRegistry
+ public val scenarios: Iterable<Scenario>
}
diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/portfolio/model/OperationalPhenomena.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/portfolio/model/OperationalPhenomena.kt
new file mode 100644
index 00000000..ea78e556
--- /dev/null
+++ b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/portfolio/model/OperationalPhenomena.kt
@@ -0,0 +1,31 @@
+/*
+ * 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.experiments.base.portfolio.model
+
+/**
+ * Operation phenomena during experiments.
+ *
+ * @param failureFrequency The average time between failures in hours.
+ * @param hasInterference A flag to enable performance interference between VMs.
+ */
+public data class OperationalPhenomena(val failureFrequency: Double, val hasInterference: Boolean)
diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/provisioner/ProvisioningContext.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/portfolio/model/Scenario.kt
index e53044ce..66fc76e4 100644
--- a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/provisioner/ProvisioningContext.kt
+++ b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/portfolio/model/Scenario.kt
@@ -20,31 +20,21 @@
* SOFTWARE.
*/
-package org.opendc.experiments.provisioner
-
-import org.opendc.common.Dispatcher
-import org.opendc.experiments.MutableServiceRegistry
-import java.util.SplittableRandom
-import java.util.random.RandomGenerator
+package org.opendc.experiments.base.portfolio.model
/**
- * The [ProvisioningContext] class provides access to shared state between subsequent [ProvisioningStep]s, as well as
- * access to the simulation dispatcher, the virtual clock, and a randomness seeder to allow
- * the provisioning steps to initialize the (simulated) resources.
+ * A single scenario of a portfolio.
+ *
+ * @property topology The topology to test.
+ * @property workload The workload to test.
+ * @property operationalPhenomena The [OperationalPhenomena] to model.
+ * @property allocationPolicy The allocation policy of the scheduler.
+ * @property partitions The partition of the scenario.
*/
-public interface ProvisioningContext {
- /**
- * The [Dispatcher] provided by the provisioner to schedule future events during the simulation.
- */
- public val dispatcher: Dispatcher
-
- /**
- * A [SplittableRandom] instance used to seed the provisioners.
- */
- public val seeder: RandomGenerator
-
- /**
- * A [MutableServiceRegistry] where the provisioned services are registered.
- */
- public val registry: MutableServiceRegistry
-}
+public data class Scenario(
+ val topology: Topology,
+ val workload: Workload,
+ val operationalPhenomena: OperationalPhenomena,
+ val allocationPolicy: String,
+ val partitions: Map<String, String> = emptyMap()
+)
diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/portfolio/model/Topology.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/portfolio/model/Topology.kt
new file mode 100644
index 00000000..0053b541
--- /dev/null
+++ b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/portfolio/model/Topology.kt
@@ -0,0 +1,28 @@
+/*
+ * 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.experiments.base.portfolio.model
+
+/**
+ * The topology on which we simulate the workload.
+ */
+public data class Topology(val name: String)
diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/portfolio/model/Workload.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/portfolio/model/Workload.kt
new file mode 100644
index 00000000..0dd9df09
--- /dev/null
+++ b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/portfolio/model/Workload.kt
@@ -0,0 +1,33 @@
+/*
+ * 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.experiments.base.portfolio.model
+
+import org.opendc.compute.workload.ComputeWorkload
+
+/**
+ * A single workload originating from a trace.
+ *
+ * @param name the name of the workload.
+ * @param source The source of the workload data.
+ */
+public data class Workload(val name: String, val source: ComputeWorkload)
diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/TraceHelpers.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/TraceHelpers.kt
new file mode 100644
index 00000000..2afbd8a5
--- /dev/null
+++ b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/TraceHelpers.kt
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2022 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("TraceHelpers")
+
+package org.opendc.experiments.base.runner
+
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.sync.Mutex
+import kotlinx.coroutines.yield
+import org.opendc.compute.api.Server
+import org.opendc.compute.api.ServerState
+import org.opendc.compute.api.ServerWatcher
+import org.opendc.compute.service.ComputeService
+import org.opendc.compute.simulator.failure.FailureModel
+import org.opendc.compute.workload.VirtualMachine
+import java.time.InstantSource
+import java.util.Random
+import kotlin.coroutines.coroutineContext
+import kotlin.math.max
+
+/**
+ * A watcher that is locked and waits for a change in the server state to unlock
+ * @param unlockStates determine which [ServerState] triggers an unlock.
+ * Default values are TERMINATED, ERROR, and DELETED.
+ */
+public class RunningServerWatcher : ServerWatcher {
+ // TODO: make this changeable
+ private val unlockStates: List<ServerState> = listOf(ServerState.TERMINATED, ServerState.ERROR, ServerState.DELETED)
+
+ private val _mutex: Mutex = Mutex()
+
+ public suspend fun lock() {
+ _mutex.lock()
+ }
+
+ public suspend fun wait() {
+ this.lock()
+ }
+
+ override fun onStateChanged(server: Server, newState: ServerState) {
+ if (unlockStates.contains(newState)) {
+ _mutex.unlock()
+ }
+ }
+}
+
+/**
+ * Helper method to replay the specified list of [VirtualMachine] and suspend execution util all VMs have finished.
+ *
+ * @param clock The simulation clock.
+ * @param trace The trace to simulate.
+ * @param seed The seed to use for randomness.
+ * @param submitImmediately A flag to indicate that the servers are scheduled immediately (so not at their start time).
+ * @param failureModel A failure model to use for injecting failures.
+ * @param interference A flag to indicate that VM interference needs to be enabled.
+ */
+public suspend fun ComputeService.replay(
+ clock: InstantSource,
+ trace: List<VirtualMachine>,
+ seed: Long,
+ submitImmediately: Boolean = false,
+ failureModel: FailureModel? = null,
+ interference: Boolean = false
+) {
+ val injector = failureModel?.createInjector(coroutineContext, clock, this, Random(seed))
+ val client = newClient()
+
+ // Create new image for the virtual machine
+ val image = client.newImage("vm-image")
+
+ try {
+ coroutineScope {
+ // Start the fault injector
+ injector?.start()
+
+ var simulationOffset = Long.MIN_VALUE
+
+ for (entry in trace.sortedBy { it.startTime }) {
+ val now = clock.millis()
+ val start = entry.startTime.toEpochMilli()
+
+ // Set the simulationOffset based on the starting time of the first server
+ if (simulationOffset == Long.MIN_VALUE) {
+ simulationOffset = start - now
+ }
+
+ // Make sure the trace entries are ordered by submission time
+// assert(start - simulationOffset >= 0) { "Invalid trace order" }
+
+ // Delay the server based on the startTime given by the trace.
+ if (!submitImmediately) {
+ delay(max(0, (start - now - simulationOffset)))
+ }
+
+ val workload = entry.trace.createWorkload(start)
+ val meta = mutableMapOf<String, Any>("workload" to workload)
+
+ val interferenceProfile = entry.interferenceProfile
+ if (interference && interferenceProfile != null) {
+ meta["interference-profile"] = interferenceProfile
+ }
+
+ launch {
+ val server = client.newServer(
+ entry.name,
+ image,
+ client.newFlavor(
+ entry.name,
+ entry.cpuCount,
+ entry.memCapacity,
+ meta = if (entry.cpuCapacity > 0.0) mapOf("cpu-capacity" to entry.cpuCapacity) else emptyMap()
+ ),
+ meta = meta
+ )
+
+ val serverWatcher = RunningServerWatcher()
+ serverWatcher.lock()
+ server.watch(serverWatcher)
+
+ // Wait until the server is terminated
+ serverWatcher.wait()
+
+ // Stop the server after reaching the end-time of the virtual machine
+ server.delete()
+ }
+ }
+ }
+ yield()
+ } finally {
+ injector?.close()
+ client.close()
+ }
+}
diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/internal/ServiceRegistryImpl.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/internal/ServiceRegistryImpl.kt
deleted file mode 100644
index c2e91730..00000000
--- a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/internal/ServiceRegistryImpl.kt
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2022 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.experiments.internal
-
-import org.opendc.experiments.MutableServiceRegistry
-
-/**
- * Implementation of the [MutableServiceRegistry] interface.
- */
-internal class ServiceRegistryImpl(private val registry: MutableMap<String, MutableMap<Class<*>, Any>> = mutableMapOf()) :
- MutableServiceRegistry {
- override fun <T : Any> resolve(name: String, type: Class<T>): T? {
- val servicesForName = registry[name] ?: return null
-
- @Suppress("UNCHECKED_CAST")
- return servicesForName[type] as T?
- }
-
- override fun <T : Any> register(name: String, type: Class<T>, service: T) {
- val services = registry.computeIfAbsent(name) { mutableMapOf() }
-
- if (type in services) {
- throw IllegalStateException("Duplicate service $type registered for name $name")
- }
-
- services[type] = service
- }
-
- override fun remove(name: String, type: Class<*>) {
- val services = registry[name] ?: return
- services.remove(type)
- }
-
- override fun remove(name: String) {
- registry.remove(name)
- }
-
- override fun clone(): MutableServiceRegistry {
- val res = mutableMapOf<String, MutableMap<Class<*>, Any>>()
- registry.mapValuesTo(res) { (_, v) -> v.toMutableMap() }
- return ServiceRegistryImpl(res)
- }
-
- override fun toString(): String {
- val entries = registry.map { "${it.key}=${it.value}" }.joinToString()
- return "ServiceRegistry{$entries}"
- }
-}
diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/provisioner/Provisioner.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/provisioner/Provisioner.kt
deleted file mode 100644
index eae5806e..00000000
--- a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/provisioner/Provisioner.kt
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2022 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.experiments.provisioner
-
-import org.opendc.common.Dispatcher
-import org.opendc.experiments.MutableServiceRegistry
-import org.opendc.experiments.ServiceRegistry
-import org.opendc.experiments.internal.ServiceRegistryImpl
-import java.util.ArrayDeque
-import java.util.SplittableRandom
-
-/**
- * A helper class to set up the experimental environment in a reproducible manner.
- *
- * With this class, users describe the environment using multiple [ProvisioningStep]s. These re-usable
- * [ProvisioningStep]s are executed sequentially and ensure that the necessary infrastructure is configured and teared
- * down after the simulation completes.
- *
- * @param dispatcher The [Dispatcher] implementation for scheduling future tasks.
- * @param seed A seed for initializing the randomness of the environment.
- */
-public class Provisioner(dispatcher: Dispatcher, seed: Long) : AutoCloseable {
- /**
- * Implementation of [ProvisioningContext].
- */
- private val context = object : ProvisioningContext {
- override val dispatcher: Dispatcher = dispatcher
- override val seeder: SplittableRandom = SplittableRandom(seed)
- override val registry: MutableServiceRegistry = ServiceRegistryImpl()
-
- override fun toString(): String = "Provisioner.ProvisioningContext"
- }
-
- /**
- * The stack of handles to run during the clean-up process.
- */
- private val stack = ArrayDeque<AutoCloseable>()
-
- /**
- * The [ServiceRegistry] containing the services registered in this environment.
- */
- public val registry: ServiceRegistry
- get() = context.registry
-
- /**
- * Run a single [ProvisioningStep] for this environment.
- *
- * @param step The step to apply to the environment.
- */
- public fun runStep(step: ProvisioningStep) {
- val handle = step.apply(context)
- stack.push(handle)
- }
-
- /**
- * Run multiple [ProvisioningStep]s for this environment.
- *
- * @param steps The steps to apply to the environment.
- */
- public fun runSteps(vararg steps: ProvisioningStep) {
- val ctx = context
- val stack = stack
- for (step in steps) {
- val handle = step.apply(ctx)
- stack.push(handle)
- }
- }
-
- /**
- * Clean-up the environment.
- */
- override fun close() {
- val stack = stack
- while (stack.isNotEmpty()) {
- stack.pop().close()
- }
- }
-}
diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/provisioner/ProvisioningStep.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/provisioner/ProvisioningStep.kt
deleted file mode 100644
index e78f8d4f..00000000
--- a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/provisioner/ProvisioningStep.kt
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2022 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.experiments.provisioner
-
-import org.eclipse.microprofile.config.Config
-
-/**
- * A provisioning step is responsible for provisioning (acquiring or configuring) infrastructure necessary for a
- * simulation experiment.
- */
-public fun interface ProvisioningStep {
- /**
- * Apply the step by provisioning the required resources for the experiment using the specified
- * [ProvisioningContext][ctx].
- *
- * @param ctx The environment in which the resources should be provisioned.
- * @return A handle that is invoked once the simulation completes, so that the resources can be cleaned up.
- */
- public fun apply(ctx: ProvisioningContext): AutoCloseable
-
- /**
- * A factory interface for [ProvisioningStep] instances.
- *
- * @param S The type that describes the input for constructing a [ProvisioningStep].
- */
- public abstract class Provider<S>(public val type: Class<S>) {
- /**
- * The name that identifies the provisioning step.
- */
- public abstract val name: String
-
- /**
- * Construct a [ProvisioningStep] with the specified [spec].
- *
- * @param spec The specification that describes the provisioner to be created.
- * @param config The external configuration of the experiment runner.
- * @return The [ProvisioningStep] constructed according to [spec].
- */
- public abstract fun create(spec: S, config: Config): ProvisioningStep
- }
-}
diff --git a/opendc-experiments/opendc-experiments-base/src/main/output/host/seed=0/data.parquet b/opendc-experiments/opendc-experiments-base/src/main/output/host/seed=0/data.parquet
new file mode 100644
index 00000000..d3c19ab4
--- /dev/null
+++ b/opendc-experiments/opendc-experiments-base/src/main/output/host/seed=0/data.parquet
Binary files differ
diff --git a/opendc-experiments/opendc-experiments-base/src/main/output/server/seed=0/data.parquet b/opendc-experiments/opendc-experiments-base/src/main/output/server/seed=0/data.parquet
new file mode 100644
index 00000000..6049e8cb
--- /dev/null
+++ b/opendc-experiments/opendc-experiments-base/src/main/output/server/seed=0/data.parquet
Binary files differ
diff --git a/opendc-experiments/opendc-experiments-base/src/main/output/service/seed=0/data.parquet b/opendc-experiments/opendc-experiments-base/src/main/output/service/seed=0/data.parquet
new file mode 100644
index 00000000..969954bb
--- /dev/null
+++ b/opendc-experiments/opendc-experiments-base/src/main/output/service/seed=0/data.parquet
Binary files differ
diff --git a/opendc-experiments/opendc-experiments-base/src/main/resources/bitbrains-small/interference-model.json b/opendc-experiments/opendc-experiments-base/src/main/resources/bitbrains-small/interference-model.json
new file mode 100644
index 00000000..51fc6366
--- /dev/null
+++ b/opendc-experiments/opendc-experiments-base/src/main/resources/bitbrains-small/interference-model.json
@@ -0,0 +1,21 @@
+[
+ {
+ "vms": [
+ "141",
+ "379",
+ "851",
+ "116"
+ ],
+ "minServerLoad": 0.0,
+ "performanceScore": 0.8830158730158756
+ },
+ {
+ "vms": [
+ "205",
+ "116",
+ "463"
+ ],
+ "minServerLoad": 0.0,
+ "performanceScore": 0.7133055555552751
+ }
+]
diff --git a/opendc-experiments/opendc-experiments-base/src/main/resources/bitbrains-small/trace/meta.parquet b/opendc-experiments/opendc-experiments-base/src/main/resources/bitbrains-small/trace/meta.parquet
new file mode 100644
index 00000000..9cded35f
--- /dev/null
+++ b/opendc-experiments/opendc-experiments-base/src/main/resources/bitbrains-small/trace/meta.parquet
Binary files differ
diff --git a/opendc-experiments/opendc-experiments-base/src/main/resources/bitbrains-small/trace/trace.parquet b/opendc-experiments/opendc-experiments-base/src/main/resources/bitbrains-small/trace/trace.parquet
new file mode 100644
index 00000000..9d953956
--- /dev/null
+++ b/opendc-experiments/opendc-experiments-base/src/main/resources/bitbrains-small/trace/trace.parquet
Binary files differ
diff --git a/opendc-experiments/opendc-experiments-base/src/main/resources/env/multi.txt b/opendc-experiments/opendc-experiments-base/src/main/resources/env/multi.txt
new file mode 100644
index 00000000..6b347bff
--- /dev/null
+++ b/opendc-experiments/opendc-experiments-base/src/main/resources/env/multi.txt
@@ -0,0 +1,5 @@
+ClusterID;ClusterName;Cores;Speed;Memory;numberOfHosts;memoryCapacityPerHost;coreCountPerHost
+A01;A01;32;3.2;2048;1;256;32
+B01;B01;48;2.93;1256;6;64;8
+C01;C01;32;3.2;2048;2;128;16
+
diff --git a/opendc-experiments/opendc-experiments-base/src/main/resources/env/single.txt b/opendc-experiments/opendc-experiments-base/src/main/resources/env/single.txt
new file mode 100644
index 00000000..5642003d
--- /dev/null
+++ b/opendc-experiments/opendc-experiments-base/src/main/resources/env/single.txt
@@ -0,0 +1,3 @@
+ClusterID;ClusterName;Cores;Speed;Memory;numberOfHosts;memoryCapacityPerHost;coreCountPerHost
+A01;A01;8;3.2;128;1;128;8
+
diff --git a/opendc-experiments/opendc-experiments-base/src/main/resources/log4j2.xml b/opendc-experiments/opendc-experiments-base/src/main/resources/log4j2.xml
new file mode 100644
index 00000000..e479f2ca
--- /dev/null
+++ b/opendc-experiments/opendc-experiments-base/src/main/resources/log4j2.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ MIT License
+ ~
+ ~ Copyright (c) 2020 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.
+ -->
+
+<Configuration status="WARN">
+ <Appenders>
+ <Console name="Console" target="SYSTEM_OUT">
+ <PatternLayout pattern="%d{HH:mm:ss.SSS} [%highlight{%-5level}] %logger{36} - %msg%n" disableAnsi="false"/>
+ </Console>
+ </Appenders>
+ <Loggers>
+ <Logger name="org.opendc" level="warn" additivity="false">
+ <AppenderRef ref="Console"/>
+ </Logger>
+ <Logger name="org.apache.hadoop" level="warn" additivity="false">
+ <AppenderRef ref="Console"/>
+ </Logger>
+ <Root level="error">
+ <AppenderRef ref="Console"/>
+ </Root>
+ </Loggers>
+</Configuration>
diff --git a/opendc-experiments/opendc-experiments-base/src/test/kotlin/org/opendc/experiments/ServiceRegistryTest.kt b/opendc-experiments/opendc-experiments-base/src/test/kotlin/org/opendc/experiments/ServiceRegistryTest.kt
deleted file mode 100644
index f649b810..00000000
--- a/opendc-experiments/opendc-experiments-base/src/test/kotlin/org/opendc/experiments/ServiceRegistryTest.kt
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (c) 2022 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.experiments
-
-import org.junit.jupiter.api.Assertions.assertAll
-import org.junit.jupiter.api.Assertions.assertDoesNotThrow
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertNull
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.assertThrows
-import org.opendc.experiments.internal.ServiceRegistryImpl
-
-/**
- * Test suite for the [ServiceRegistry] implementation.
- */
-class ServiceRegistryTest {
- @Test
- fun testRetrievalSuccess() {
- val registry = ServiceRegistryImpl()
-
- registry.register("opendc.org", String::class.java, "Comment")
-
- assertEquals("Comment", registry.resolve("opendc.org", String::class.java))
- }
-
- @Test
- fun testRetrievalFailure() {
- val registry = ServiceRegistryImpl()
- assertNull(registry.resolve("opendc.org", String::class.java))
- }
-
- @Test
- fun testDuplicate() {
- val registry = ServiceRegistryImpl()
-
- registry.register("opendc.org", String::class.java, "Comment")
-
- assertThrows<IllegalStateException> { registry.register("opendc.org", String::class.java, "Comment2") }
- }
-
- @Test
- fun testRemove() {
- val registry = ServiceRegistryImpl()
-
- registry.register("opendc.org", String::class.java, "Comment")
- registry.remove("opendc.org", String::class.java)
-
- assertAll(
- { assertDoesNotThrow { registry.remove("opendc.org", String::class.java) } },
- { assertNull(registry.resolve("opendc.org", String::class.java)) }
- )
- }
-
- @Test
- fun testRemoveNonExistent() {
- val registry = ServiceRegistryImpl()
-
- assertAll(
- { assertNull(registry.resolve("opendc.org", String::class.java)) },
- { assertDoesNotThrow { registry.remove("opendc.org", String::class.java) } }
- )
- }
-
- @Test
- fun testRemoveAll() {
- val registry = ServiceRegistryImpl()
-
- registry.register("opendc.org", String::class.java, "Comment")
- registry.register("opendc.org", Int::class.java, 1)
-
- println(registry)
-
- registry.remove("opendc.org")
-
- assertAll(
- { assertNull(registry.resolve("opendc.org", String::class.java)) },
- { assertNull(registry.resolve("opendc.org", Int::class.java)) }
- )
- }
-
- @Test
- fun testClone() {
- val registry = ServiceRegistryImpl()
- registry.register("opendc.org", String::class.java, "Comment")
-
- val clone = registry.clone()
- clone.remove("opendc.org")
-
- assertAll(
- { assertEquals("Comment", registry.resolve("opendc.org", String::class.java)) },
- { assertNull(clone.resolve("opendc.org", String::class.java)) }
- )
- }
-}
diff --git a/opendc-experiments/opendc-experiments-base/src/test/resources/env/single.txt b/opendc-experiments/opendc-experiments-base/src/test/resources/env/single.txt
new file mode 100644
index 00000000..5642003d
--- /dev/null
+++ b/opendc-experiments/opendc-experiments-base/src/test/resources/env/single.txt
@@ -0,0 +1,3 @@
+ClusterID;ClusterName;Cores;Speed;Memory;numberOfHosts;memoryCapacityPerHost;coreCountPerHost
+A01;A01;8;3.2;128;1;128;8
+
diff --git a/opendc-experiments/opendc-experiments-base/src/test/resources/env/topology.txt b/opendc-experiments/opendc-experiments-base/src/test/resources/env/topology.txt
new file mode 100644
index 00000000..6b347bff
--- /dev/null
+++ b/opendc-experiments/opendc-experiments-base/src/test/resources/env/topology.txt
@@ -0,0 +1,5 @@
+ClusterID;ClusterName;Cores;Speed;Memory;numberOfHosts;memoryCapacityPerHost;coreCountPerHost
+A01;A01;32;3.2;2048;1;256;32
+B01;B01;48;2.93;1256;6;64;8
+C01;C01;32;3.2;2048;2;128;16
+
diff --git a/opendc-experiments/opendc-experiments-base/src/test/resources/trace/bitbrains-small/interference-model.json b/opendc-experiments/opendc-experiments-base/src/test/resources/trace/bitbrains-small/interference-model.json
new file mode 100644
index 00000000..51fc6366
--- /dev/null
+++ b/opendc-experiments/opendc-experiments-base/src/test/resources/trace/bitbrains-small/interference-model.json
@@ -0,0 +1,21 @@
+[
+ {
+ "vms": [
+ "141",
+ "379",
+ "851",
+ "116"
+ ],
+ "minServerLoad": 0.0,
+ "performanceScore": 0.8830158730158756
+ },
+ {
+ "vms": [
+ "205",
+ "116",
+ "463"
+ ],
+ "minServerLoad": 0.0,
+ "performanceScore": 0.7133055555552751
+ }
+]
diff --git a/opendc-experiments/opendc-experiments-base/src/test/resources/trace/bitbrains-small/meta.parquet b/opendc-experiments/opendc-experiments-base/src/test/resources/trace/bitbrains-small/meta.parquet
new file mode 100644
index 00000000..9cded35f
--- /dev/null
+++ b/opendc-experiments/opendc-experiments-base/src/test/resources/trace/bitbrains-small/meta.parquet
Binary files differ
diff --git a/opendc-experiments/opendc-experiments-base/src/test/resources/trace/bitbrains-small/trace.parquet b/opendc-experiments/opendc-experiments-base/src/test/resources/trace/bitbrains-small/trace.parquet
new file mode 100644
index 00000000..9d953956
--- /dev/null
+++ b/opendc-experiments/opendc-experiments-base/src/test/resources/trace/bitbrains-small/trace.parquet
Binary files differ