summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDante Niewenhuis <d.niewenhuis@hotmail.com>2025-05-20 11:06:12 +0200
committerGitHub <noreply@github.com>2025-05-20 11:06:12 +0200
commitc7e303ad1b5217e2ff24cee9538ac841d6149706 (patch)
tree317df3b3a1643e23c45beef891e99edc9a40da66
parente9a1b6078e366a8ee071f5d423a1874608618e4d (diff)
Fixed bug when not providing a Carbon Model (#339)
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/ServiceRegistry.kt25
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltTaskExportColumns.kt14
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReader.kt2
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReaderImpl.kt18
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/ExperimentCli.kt4
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/ScenarioRunner.kt38
-rw-r--r--opendc-experiments/opendc-experiments-base/src/test/kotlin/org/opendc/experiments/base/ExperimentRunnerTest.kt46
-rw-r--r--opendc-experiments/opendc-experiments-base/src/test/resources/experiments/experiment_1.json23
-rw-r--r--opendc-experiments/opendc-experiments-base/src/test/resources/topologies/single_50_big.json28
-rw-r--r--opendc-experiments/opendc-experiments-base/src/test/resources/topologies/single_50_big_BE.json31
10 files changed, 196 insertions, 33 deletions
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/ServiceRegistry.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/ServiceRegistry.kt
index e2f6c9d0..36e413d9 100644
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/ServiceRegistry.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/ServiceRegistry.kt
@@ -32,8 +32,29 @@ public class ServiceRegistry(private val registry: MutableMap<String, MutableMap
): T? {
val servicesForName = registry[name] ?: return null
- @Suppress("UNCHECKED_CAST")
- return servicesForName[type] as T?
+ val service = servicesForName[type]
+
+ if (service == null) {
+ throw IllegalStateException("Service $type not registered for name $name")
+ }
+
+ try {
+ @Suppress("UNCHECKED_CAST")
+ return service as T?
+ } catch (e: ClassCastException) {
+ throw IllegalStateException("Service $type registered for name $name is not of the given type")
+ }
+ }
+
+ public fun <T : Any> hasService(
+ name: String,
+ type: Class<T>,
+ ): Boolean {
+ val servicesForName = registry[name] ?: return false
+
+ servicesForName[type] ?: return false
+
+ return true
}
public fun <T : Any> register(
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltTaskExportColumns.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltTaskExportColumns.kt
index 5c3ef3bf..f862a843 100644
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltTaskExportColumns.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltTaskExportColumns.kt
@@ -80,7 +80,12 @@ public object DfltTaskExportColumns {
Types.required(BINARY)
.`as`(LogicalTypeAnnotation.stringType())
.named("host_name"),
- ) { Binary.fromString(it.host?.name) }
+ ) {
+ if (it.hostInfo == null) {
+ return@ExportColumn Binary.fromString("")
+ }
+ return@ExportColumn Binary.fromString(it.hostInfo!!.name)
+ }
public val MEM_CAPACITY: ExportColumn<TaskTableReader> =
ExportColumn(
@@ -168,7 +173,12 @@ public object DfltTaskExportColumns {
Types.optional(BINARY)
.`as`(LogicalTypeAnnotation.stringType())
.named("task_state"),
- ) { Binary.fromString(it.taskState?.name) }
+ ) {
+ if (it.taskState == null) {
+ return@ExportColumn Binary.fromString("")
+ }
+ return@ExportColumn Binary.fromString(it.taskState!!.name)
+ }
/**
* The columns that are always included in the output file.
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReader.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReader.kt
index 771ced37..8861eabb 100644
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReader.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReader.kt
@@ -58,7 +58,7 @@ public interface TaskTableReader : Exportable {
/**
* The [HostInfo] of the host on which the task is hosted or `null` if it has no host.
*/
- public val host: HostInfo?
+ public val hostInfo: HostInfo?
/**
* The uptime of the host since last time in ms.
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReaderImpl.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReaderImpl.kt
index 881b9916..f6a52759 100644
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReaderImpl.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReaderImpl.kt
@@ -50,7 +50,7 @@ public class TaskTableReaderImpl(
}
override fun setValues(table: TaskTableReader) {
- host = table.host
+ hostInfo = table.hostInfo
_timestamp = table.timestamp
_timestampAbsolute = table.timestampAbsolute
@@ -90,8 +90,8 @@ public class TaskTableReaderImpl(
/**
* The [HostInfo] of the host on which the task is hosted.
*/
- override var host: HostInfo? = null
- private var _host: SimHost? = null
+ override var hostInfo: HostInfo? = null
+ private var simHost: SimHost? = null
private var _timestamp = Instant.MIN
override val timestamp: Instant
@@ -172,9 +172,9 @@ public class TaskTableReaderImpl(
*/
override fun record(now: Instant) {
val newHost = service.lookupHost(task)
- if (newHost != null && newHost.getName() != _host?.getName()) {
- _host = newHost
- host =
+ if (newHost != null && newHost.getName() != simHost?.getName()) {
+ simHost = newHost
+ hostInfo =
HostInfo(
newHost.getName(),
newHost.getClusterName(),
@@ -185,8 +185,8 @@ public class TaskTableReaderImpl(
)
}
- val cpuStats = _host?.getCpuStats(task)
- val sysStats = _host?.getSystemStats(task)
+ val cpuStats = simHost?.getCpuStats(task)
+ val sysStats = simHost?.getSystemStats(task)
_timestamp = now
_timestampAbsolute = now + startTime
@@ -221,7 +221,7 @@ public class TaskTableReaderImpl(
previousCpuStealTime = _cpuStealTime
previousCpuLostTime = _cpuLostTime
- _host = null
+ simHost = null
_cpuLimit = 0.0
}
}
diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/ExperimentCli.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/ExperimentCli.kt
index f4df7991..d231b93b 100644
--- a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/ExperimentCli.kt
+++ b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/ExperimentCli.kt
@@ -43,12 +43,12 @@ internal class ExperimentCommand : CliktCommand(name = "experiment") {
/**
* The path to the environment directory.
*/
- private val scenarioPath by option("--experiment-path", help = "path to experiment file")
+ private val experimentPath by option("--experiment-path", help = "path to experiment file")
.file(canBeDir = false, canBeFile = true)
.defaultLazy { File("resources/experiment.json") }
override fun run() {
- val experiment = getExperiment(scenarioPath)
+ val experiment = getExperiment(experimentPath)
runExperiment(experiment)
}
}
diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/ScenarioRunner.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/ScenarioRunner.kt
index 15445450..f7c444ea 100644
--- a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/ScenarioRunner.kt
+++ b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/ScenarioRunner.kt
@@ -131,23 +131,27 @@ public fun runScenario(
service.setTasksExpected(workload.size)
service.setMetricReader(provisioner.getMonitor())
- val carbonModel = provisioner.registry.resolve(serviceDomain, CarbonModel::class.java)!!
- val computeScheduler = provisioner.registry.resolve(serviceDomain, ComputeScheduler::class.java)!!
- if (computeScheduler is CarbonReceiver) {
- carbonModel.addReceiver(computeScheduler)
- }
- carbonModel.addReceiver(service)
-
- if (scenario.allocationPolicySpec is TimeShiftAllocationPolicySpec) {
- val taskStopper =
- createTaskStopper(
- scenario.allocationPolicySpec.taskStopper,
- coroutineContext,
- timeSource,
- )
- if (taskStopper != null) {
- taskStopper.setService(service)
- carbonModel.addReceiver(taskStopper)
+ var carbonModel: CarbonModel? = null
+ if (provisioner.registry.hasService(serviceDomain, CarbonModel::class.java)) {
+ carbonModel = provisioner.registry.resolve(serviceDomain, CarbonModel::class.java)!!
+
+ val computeScheduler = provisioner.registry.resolve(serviceDomain, ComputeScheduler::class.java)!!
+ if (computeScheduler is CarbonReceiver) {
+ carbonModel.addReceiver(computeScheduler)
+ carbonModel.addReceiver(service)
+ }
+
+ if (scenario.allocationPolicySpec is TimeShiftAllocationPolicySpec) {
+ val taskStopper =
+ createTaskStopper(
+ scenario.allocationPolicySpec.taskStopper,
+ coroutineContext,
+ timeSource,
+ )
+ if (taskStopper != null) {
+ taskStopper.setService(service)
+ carbonModel.addReceiver(taskStopper)
+ }
}
}
diff --git a/opendc-experiments/opendc-experiments-base/src/test/kotlin/org/opendc/experiments/base/ExperimentRunnerTest.kt b/opendc-experiments/opendc-experiments-base/src/test/kotlin/org/opendc/experiments/base/ExperimentRunnerTest.kt
new file mode 100644
index 00000000..6365f60d
--- /dev/null
+++ b/opendc-experiments/opendc-experiments-base/src/test/kotlin/org/opendc/experiments/base/ExperimentRunnerTest.kt
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+package org.opendc.experiments.base
+
+import org.junit.jupiter.api.Test
+import org.opendc.experiments.base.runner.ExperimentCommand
+import java.io.File
+
+/**
+ * An integration test suite for the Experiment Runner.
+ */
+class ExperimentRunnerTest {
+ /**
+ * ExperimentRunner test 1
+ * This test runs the experiment defined in the experiment_1.json file.
+ *
+ * In this test, the bitbrains-small workload is executed with and without a carbon trace.
+ */
+ @Test
+ fun testExperimentRunner1() {
+ ExperimentCommand().main(arrayOf("--experiment-path", "src/test/resources/experiments/experiment_1.json"))
+
+ val someDir = File("output")
+ someDir.deleteRecursively()
+ }
+}
diff --git a/opendc-experiments/opendc-experiments-base/src/test/resources/experiments/experiment_1.json b/opendc-experiments/opendc-experiments-base/src/test/resources/experiments/experiment_1.json
new file mode 100644
index 00000000..48ae75ce
--- /dev/null
+++ b/opendc-experiments/opendc-experiments-base/src/test/resources/experiments/experiment_1.json
@@ -0,0 +1,23 @@
+{
+ "topologies": [
+ {"pathToFile": "src/test/resources/topologies/single_50_big.json"},
+ {"pathToFile": "src/test/resources/topologies/single_50_big_BE.json"}
+ ],
+ "workloads": [{
+ "pathToFile": "src/test/resources/workloadTraces/bitbrains-small",
+ "type": "ComputeWorkload",
+ "submissionTime": "2024-03-01T00:00:00"
+ }],
+ "allocationPolicies": [
+ {
+ "type": "prefab",
+ "policyName": "Mem"
+ }
+ ],
+ "exportModels": [
+ {
+ "exportInterval": 3600,
+ "printFrequency": 24
+ }
+ ]
+}
diff --git a/opendc-experiments/opendc-experiments-base/src/test/resources/topologies/single_50_big.json b/opendc-experiments/opendc-experiments-base/src/test/resources/topologies/single_50_big.json
new file mode 100644
index 00000000..676d4f3d
--- /dev/null
+++ b/opendc-experiments/opendc-experiments-base/src/test/resources/topologies/single_50_big.json
@@ -0,0 +1,28 @@
+{
+ "clusters":
+ [
+ {
+ "name": "C01",
+ "hosts" :
+ [
+ {
+ "name": "H01",
+ "cpu":
+ {
+ "coreCount": 64,
+ "coreSpeed": 2000
+ },
+ "memory": {
+ "memorySize": 140457600000
+ },
+ "powerModel": {
+ "modelType": "linear",
+ "power": 400.0,
+ "idlePower": 100.0,
+ "maxPower": 200.0
+ }
+ }
+ ]
+ }
+ ]
+}
diff --git a/opendc-experiments/opendc-experiments-base/src/test/resources/topologies/single_50_big_BE.json b/opendc-experiments/opendc-experiments-base/src/test/resources/topologies/single_50_big_BE.json
new file mode 100644
index 00000000..d2c19861
--- /dev/null
+++ b/opendc-experiments/opendc-experiments-base/src/test/resources/topologies/single_50_big_BE.json
@@ -0,0 +1,31 @@
+{
+ "clusters":
+ [
+ {
+ "name": "C01",
+ "hosts" :
+ [
+ {
+ "name": "H01",
+ "cpu":
+ {
+ "coreCount": 64,
+ "coreSpeed": 2000
+ },
+ "memory": {
+ "memorySize": 140457600000
+ },
+ "powerModel": {
+ "modelType": "linear",
+ "power": 400.0,
+ "idlePower": 100.0,
+ "maxPower": 200.0
+ }
+ }
+ ],
+ "powerSource": {
+ "carbonTracePath": "src/test/resources/carbonTraces/2022-01-01_2022-12-31_BE.parquet"
+ }
+ }
+ ]
+}