diff options
24 files changed, 181 insertions, 337 deletions
diff --git a/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt b/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt index 059f9cd9..a6258845 100644 --- a/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt +++ b/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt @@ -26,9 +26,6 @@ import io.mockk.* import io.opentelemetry.api.metrics.MeterProvider import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.delay -import kotlinx.coroutines.test.TestCoroutineScope -import kotlinx.coroutines.test.runBlockingTest -import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertNull import org.junit.jupiter.api.BeforeEach @@ -43,7 +40,8 @@ import org.opendc.compute.service.scheduler.FilterScheduler import org.opendc.compute.service.scheduler.filters.ComputeCapabilitiesFilter import org.opendc.compute.service.scheduler.filters.ComputeFilter import org.opendc.compute.service.scheduler.weights.MemoryWeigher -import org.opendc.simulator.core.DelayControllerClockAdapter +import org.opendc.simulator.core.SimulationCoroutineScope +import org.opendc.simulator.core.runBlockingSimulation import java.util.* /** @@ -51,13 +49,13 @@ import java.util.* */ @OptIn(ExperimentalCoroutinesApi::class) internal class ComputeServiceTest { - lateinit var scope: TestCoroutineScope + lateinit var scope: SimulationCoroutineScope lateinit var service: ComputeService @BeforeEach fun setUp() { - scope = TestCoroutineScope() - val clock = DelayControllerClockAdapter(scope) + scope = SimulationCoroutineScope() + val clock = scope.clock val computeScheduler = FilterScheduler( filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()), weighers = listOf(MemoryWeigher() to -1.0) @@ -66,13 +64,8 @@ internal class ComputeServiceTest { service = ComputeService(scope.coroutineContext, clock, meter, computeScheduler) } - @AfterEach - fun tearDown() { - scope.cleanupTestCoroutines() - } - @Test - fun testClientClose() = scope.runBlockingTest { + fun testClientClose() = scope.runBlockingSimulation { val client = service.newClient() assertEquals(emptyList<Flavor>(), client.queryFlavors()) @@ -95,7 +88,7 @@ internal class ComputeServiceTest { } @Test - fun testClientCreate() = scope.runBlockingTest { + fun testClientCreate() = scope.runBlockingSimulation { val client = service.newClient() val flavor = client.newFlavor("test", 1, 1024) @@ -121,7 +114,7 @@ internal class ComputeServiceTest { } @Test - fun testClientOnClose() = scope.runBlockingTest { + fun testClientOnClose() = scope.runBlockingSimulation { service.close() assertThrows<IllegalStateException> { service.newClient() @@ -129,7 +122,7 @@ internal class ComputeServiceTest { } @Test - fun testAddHost() = scope.runBlockingTest { + fun testAddHost() = scope.runBlockingSimulation { val host = mockk<Host>(relaxUnitFun = true) every { host.model } returns HostModel(4, 2048) @@ -151,7 +144,7 @@ internal class ComputeServiceTest { } @Test - fun testAddHostDouble() = scope.runBlockingTest { + fun testAddHostDouble() = scope.runBlockingSimulation { val host = mockk<Host>(relaxUnitFun = true) every { host.model } returns HostModel(4, 2048) @@ -167,7 +160,7 @@ internal class ComputeServiceTest { } @Test - fun testServerStartWithoutEnoughCpus() = scope.runBlockingTest { + fun testServerStartWithoutEnoughCpus() = scope.runBlockingSimulation { val client = service.newClient() val flavor = client.newFlavor("test", 1, 0) val image = client.newImage("test") @@ -180,7 +173,7 @@ internal class ComputeServiceTest { } @Test - fun testServerStartWithoutEnoughMemory() = scope.runBlockingTest { + fun testServerStartWithoutEnoughMemory() = scope.runBlockingSimulation { val client = service.newClient() val flavor = client.newFlavor("test", 0, 1024) val image = client.newImage("test") @@ -193,7 +186,7 @@ internal class ComputeServiceTest { } @Test - fun testServerStartWithoutEnoughResources() = scope.runBlockingTest { + fun testServerStartWithoutEnoughResources() = scope.runBlockingSimulation { val client = service.newClient() val flavor = client.newFlavor("test", 1, 1024) val image = client.newImage("test") @@ -206,7 +199,7 @@ internal class ComputeServiceTest { } @Test - fun testServerCancelRequest() = scope.runBlockingTest { + fun testServerCancelRequest() = scope.runBlockingSimulation { val client = service.newClient() val flavor = client.newFlavor("test", 1, 1024) val image = client.newImage("test") @@ -220,7 +213,7 @@ internal class ComputeServiceTest { } @Test - fun testServerCannotFitOnHost() = scope.runBlockingTest { + fun testServerCannotFitOnHost() = scope.runBlockingSimulation { val host = mockk<Host>(relaxUnitFun = true) every { host.model } returns HostModel(4, 2048) @@ -243,7 +236,7 @@ internal class ComputeServiceTest { } @Test - fun testHostAvailableAfterSomeTime() = scope.runBlockingTest { + fun testHostAvailableAfterSomeTime() = scope.runBlockingSimulation { val host = mockk<Host>(relaxUnitFun = true) val listeners = mutableListOf<HostListener>() @@ -274,7 +267,7 @@ internal class ComputeServiceTest { } @Test - fun testHostUnavailableAfterSomeTime() = scope.runBlockingTest { + fun testHostUnavailableAfterSomeTime() = scope.runBlockingSimulation { val host = mockk<Host>(relaxUnitFun = true) val listeners = mutableListOf<HostListener>() @@ -305,7 +298,7 @@ internal class ComputeServiceTest { } @Test - fun testServerInvalidType() = scope.runBlockingTest { + fun testServerInvalidType() = scope.runBlockingSimulation { val host = mockk<Host>(relaxUnitFun = true) val listeners = mutableListOf<HostListener>() @@ -328,7 +321,7 @@ internal class ComputeServiceTest { } @Test - fun testServerDeploy() = scope.runBlockingTest { + fun testServerDeploy() = scope.runBlockingSimulation { val host = mockk<Host>(relaxUnitFun = true) val listeners = mutableListOf<HostListener>() @@ -371,7 +364,7 @@ internal class ComputeServiceTest { } @Test - fun testServerDeployFailure() = scope.runBlockingTest { + fun testServerDeployFailure() = scope.runBlockingSimulation { val host = mockk<Host>(relaxUnitFun = true) val listeners = mutableListOf<HostListener>() diff --git a/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalServerTest.kt b/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalServerTest.kt index 81cb45df..20ea8d20 100644 --- a/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalServerTest.kt +++ b/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalServerTest.kt @@ -24,7 +24,6 @@ package org.opendc.compute.service import io.mockk.* import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.test.runBlockingTest import kotlinx.coroutines.yield import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.Test @@ -36,6 +35,7 @@ import org.opendc.compute.service.internal.ComputeServiceImpl import org.opendc.compute.service.internal.InternalFlavor import org.opendc.compute.service.internal.InternalImage import org.opendc.compute.service.internal.InternalServer +import org.opendc.simulator.core.runBlockingSimulation import java.util.* /** @@ -95,7 +95,7 @@ class InternalServerTest { } @Test - fun testStartTerminatedServer() = runBlockingTest { + fun testStartTerminatedServer() = runBlockingSimulation { val service = mockk<ComputeServiceImpl>() val uid = UUID.randomUUID() val flavor = mockk<InternalFlavor>() @@ -111,7 +111,7 @@ class InternalServerTest { } @Test - fun testStartDeletedServer() = runBlockingTest { + fun testStartDeletedServer() = runBlockingSimulation { val service = mockk<ComputeServiceImpl>() val uid = UUID.randomUUID() val flavor = mockk<InternalFlavor>() @@ -124,7 +124,7 @@ class InternalServerTest { } @Test - fun testStartProvisioningServer() = runBlockingTest { + fun testStartProvisioningServer() = runBlockingSimulation { val service = mockk<ComputeServiceImpl>() val uid = UUID.randomUUID() val flavor = mockk<InternalFlavor>() @@ -139,7 +139,7 @@ class InternalServerTest { } @Test - fun testStartRunningServer() = runBlockingTest { + fun testStartRunningServer() = runBlockingSimulation { val service = mockk<ComputeServiceImpl>() val uid = UUID.randomUUID() val flavor = mockk<InternalFlavor>() @@ -154,7 +154,7 @@ class InternalServerTest { } @Test - fun testStopProvisioningServer() = runBlockingTest { + fun testStopProvisioningServer() = runBlockingSimulation { val service = mockk<ComputeServiceImpl>() val uid = UUID.randomUUID() val flavor = mockk<InternalFlavor>() @@ -172,7 +172,7 @@ class InternalServerTest { } @Test - fun testStopTerminatedServer() = runBlockingTest { + fun testStopTerminatedServer() = runBlockingSimulation { val service = mockk<ComputeServiceImpl>() val uid = UUID.randomUUID() val flavor = mockk<InternalFlavor>() @@ -186,7 +186,7 @@ class InternalServerTest { } @Test - fun testStopDeletedServer() = runBlockingTest { + fun testStopDeletedServer() = runBlockingSimulation { val service = mockk<ComputeServiceImpl>() val uid = UUID.randomUUID() val flavor = mockk<InternalFlavor>() @@ -200,7 +200,7 @@ class InternalServerTest { } @Test - fun testStopRunningServer() = runBlockingTest { + fun testStopRunningServer() = runBlockingSimulation { val service = mockk<ComputeServiceImpl>() val uid = UUID.randomUUID() val flavor = mockk<InternalFlavor>() @@ -217,7 +217,7 @@ class InternalServerTest { } @Test - fun testDeleteProvisioningServer() = runBlockingTest { + fun testDeleteProvisioningServer() = runBlockingSimulation { val service = mockk<ComputeServiceImpl>(relaxUnitFun = true) val uid = UUID.randomUUID() val flavor = mockk<InternalFlavor>() @@ -236,7 +236,7 @@ class InternalServerTest { } @Test - fun testDeleteTerminatedServer() = runBlockingTest { + fun testDeleteTerminatedServer() = runBlockingSimulation { val service = mockk<ComputeServiceImpl>(relaxUnitFun = true) val uid = UUID.randomUUID() val flavor = mockk<InternalFlavor>() @@ -252,7 +252,7 @@ class InternalServerTest { } @Test - fun testDeleteDeletedServer() = runBlockingTest { + fun testDeleteDeletedServer() = runBlockingSimulation { val service = mockk<ComputeServiceImpl>(relaxUnitFun = true) val uid = UUID.randomUUID() val flavor = mockk<InternalFlavor>() @@ -266,7 +266,7 @@ class InternalServerTest { } @Test - fun testDeleteRunningServer() = runBlockingTest { + fun testDeleteRunningServer() = runBlockingSimulation { val service = mockk<ComputeServiceImpl>(relaxUnitFun = true) val uid = UUID.randomUUID() val flavor = mockk<InternalFlavor>() diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt b/simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt index cdbdd58b..5594fd59 100644 --- a/simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt +++ b/simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt @@ -29,7 +29,6 @@ import io.opentelemetry.sdk.metrics.data.MetricData import io.opentelemetry.sdk.metrics.export.MetricExporter import io.opentelemetry.sdk.metrics.export.MetricProducer import kotlinx.coroutines.* -import kotlinx.coroutines.test.runBlockingTest import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -47,7 +46,7 @@ import org.opendc.simulator.compute.model.MemoryUnit import org.opendc.simulator.compute.model.ProcessingNode import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.compute.workload.SimTraceWorkload -import org.opendc.simulator.core.DelayControllerClockAdapter +import org.opendc.simulator.core.runBlockingSimulation import org.opendc.telemetry.sdk.metrics.export.CoroutineMetricReader import org.opendc.telemetry.sdk.toOtelClock import java.util.UUID @@ -74,8 +73,7 @@ internal class SimHostTest { * Test overcommitting of resources by the hypervisor. */ @Test - fun testOvercommitted() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testOvercommitted() = runBlockingSimulation { var requestedWork = 0L var grantedWork = 0L var overcommittedWork = 0L @@ -165,7 +163,7 @@ internal class SimHostTest { { assertEquals(4197600, requestedWork, "Requested work does not match") }, { assertEquals(2157600, grantedWork, "Granted work does not match") }, { assertEquals(2040000, overcommittedWork, "Overcommitted work does not match") }, - { assertEquals(1500001, currentTime) } + { assertEquals(1500001, clock.millis()) } ) } diff --git a/simulator/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt b/simulator/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt index ee048cb0..b969366c 100644 --- a/simulator/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt +++ b/simulator/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/Portfolio.kt @@ -28,7 +28,6 @@ import io.opentelemetry.sdk.metrics.export.MetricProducer import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.cancel import kotlinx.coroutines.channels.Channel -import kotlinx.coroutines.test.runBlockingTest import mu.KotlinLogging import org.opendc.compute.service.scheduler.* import org.opendc.compute.service.scheduler.filters.ComputeCapabilitiesFilter @@ -45,7 +44,7 @@ import org.opendc.format.environment.sc20.Sc20ClusterEnvironmentReader import org.opendc.format.trace.PerformanceInterferenceModelReader import org.opendc.harness.dsl.Experiment import org.opendc.harness.dsl.anyOf -import org.opendc.simulator.core.DelayControllerClockAdapter +import org.opendc.simulator.core.runBlockingSimulation import org.opendc.telemetry.sdk.toOtelClock import java.io.File import java.util.* @@ -117,8 +116,7 @@ public abstract class Portfolio(name: String) : Experiment(name) { * Perform a single trial for this portfolio. */ @OptIn(ExperimentalCoroutinesApi::class) - override fun doRun(repeat: Int): Unit = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + override fun doRun(repeat: Int): Unit = runBlockingSimulation { val seeder = Random(repeat.toLong()) val environment = Sc20ClusterEnvironmentReader(File(environmentPath, "${topology.name}.txt")) diff --git a/simulator/opendc-experiments/opendc-experiments-energy21/src/main/kotlin/org/opendc/experiments/energy21/EnergyExperiment.kt b/simulator/opendc-experiments/opendc-experiments-energy21/src/main/kotlin/org/opendc/experiments/energy21/EnergyExperiment.kt index e687ad92..e974428c 100644 --- a/simulator/opendc-experiments/opendc-experiments-energy21/src/main/kotlin/org/opendc/experiments/energy21/EnergyExperiment.kt +++ b/simulator/opendc-experiments/opendc-experiments-energy21/src/main/kotlin/org/opendc/experiments/energy21/EnergyExperiment.kt @@ -29,7 +29,6 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.test.runBlockingTest import mu.KotlinLogging import org.opendc.compute.service.ComputeService import org.opendc.compute.service.scheduler.ComputeScheduler @@ -50,7 +49,7 @@ import org.opendc.simulator.compute.model.MemoryUnit import org.opendc.simulator.compute.model.ProcessingNode import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.compute.power.* -import org.opendc.simulator.core.DelayControllerClockAdapter +import org.opendc.simulator.core.runBlockingSimulation import org.opendc.telemetry.sdk.toOtelClock import java.io.File import java.time.Clock @@ -87,8 +86,7 @@ public class EnergyExperiment : Experiment("Energy Modeling 2021") { private val powerModel by anyOf(PowerModelType.LINEAR, PowerModelType.CUBIC, PowerModelType.INTERPOLATION) @OptIn(ExperimentalCoroutinesApi::class) - override fun doRun(repeat: Int): Unit = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + override fun doRun(repeat: Int): Unit = runBlockingSimulation { val chan = Channel<Unit>(Channel.CONFLATED) val allocationPolicy = FilterScheduler( diff --git a/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/ServerlessExperiment.kt b/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/ServerlessExperiment.kt index 5967c2d9..67b5ea54 100644 --- a/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/ServerlessExperiment.kt +++ b/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/ServerlessExperiment.kt @@ -28,7 +28,6 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch -import kotlinx.coroutines.test.runBlockingTest import mu.KotlinLogging import org.opendc.experiments.serverless.trace.FunctionTraceWorkload import org.opendc.experiments.serverless.trace.ServerlessTraceReader @@ -43,7 +42,7 @@ import org.opendc.simulator.compute.SimMachineModel import org.opendc.simulator.compute.model.MemoryUnit import org.opendc.simulator.compute.model.ProcessingNode import org.opendc.simulator.compute.model.ProcessingUnit -import org.opendc.simulator.core.DelayControllerClockAdapter +import org.opendc.simulator.core.runBlockingSimulation import org.opendc.telemetry.sdk.toOtelClock import java.io.File import java.util.* @@ -80,8 +79,7 @@ public class ServerlessExperiment : Experiment("Serverless") { private val coldStartModel by anyOf(ColdStartModel.LAMBDA, ColdStartModel.AZURE, ColdStartModel.GOOGLE) @OptIn(ExperimentalCoroutinesApi::class) - override fun doRun(repeat: Int): Unit = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + override fun doRun(repeat: Int): Unit = runBlockingSimulation { val meterProvider: MeterProvider = SdkMeterProvider .builder() .setClock(clock.toOtelClock()) diff --git a/simulator/opendc-runner-web/src/main/kotlin/org/opendc/runner/web/Main.kt b/simulator/opendc-runner-web/src/main/kotlin/org/opendc/runner/web/Main.kt index 31f5c5a5..0368a2f8 100644 --- a/simulator/opendc-runner-web/src/main/kotlin/org/opendc/runner/web/Main.kt +++ b/simulator/opendc-runner-web/src/main/kotlin/org/opendc/runner/web/Main.kt @@ -39,7 +39,6 @@ import io.opentelemetry.sdk.metrics.SdkMeterProvider import io.opentelemetry.sdk.metrics.export.MetricProducer import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel -import kotlinx.coroutines.test.runBlockingTest import mu.KotlinLogging import org.bson.Document import org.bson.types.ObjectId @@ -52,7 +51,7 @@ import org.opendc.experiments.capelin.model.Workload import org.opendc.experiments.capelin.trace.Sc20ParquetTraceReader import org.opendc.experiments.capelin.trace.Sc20RawParquetTraceReader import org.opendc.format.trace.sc20.Sc20PerformanceInterferenceReader -import org.opendc.simulator.core.DelayControllerClockAdapter +import org.opendc.simulator.core.runBlockingSimulation import org.opendc.telemetry.sdk.toOtelClock import java.io.File import kotlin.random.Random @@ -208,14 +207,13 @@ public class RunnerCli : CliktCommand(name = "runner") { val monitor = WebExperimentMonitor() try { - runBlockingTest { + runBlockingSimulation { val seed = repeat val traceDocument = scenario.get("trace", Document::class.java) val workloadName = traceDocument.getString("traceId") val workloadFraction = traceDocument.get("loadSamplingFraction", Number::class.java).toDouble() val seeder = Random(seed) - val clock = DelayControllerClockAdapter(this) val chan = Channel<Unit>(Channel.CONFLATED) diff --git a/simulator/opendc-serverless/opendc-serverless-service/src/test/kotlin/org/opendc/serverless/service/ServerlessServiceTest.kt b/simulator/opendc-serverless/opendc-serverless-service/src/test/kotlin/org/opendc/serverless/service/ServerlessServiceTest.kt index 1ab2d033..d9f5ee81 100644 --- a/simulator/opendc-serverless/opendc-serverless-service/src/test/kotlin/org/opendc/serverless/service/ServerlessServiceTest.kt +++ b/simulator/opendc-serverless/opendc-serverless-service/src/test/kotlin/org/opendc/serverless/service/ServerlessServiceTest.kt @@ -25,7 +25,6 @@ package org.opendc.serverless.service import io.mockk.* import io.opentelemetry.api.metrics.MeterProvider import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.test.runBlockingTest import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertDoesNotThrow @@ -34,7 +33,7 @@ import org.opendc.serverless.api.ServerlessFunction import org.opendc.serverless.service.deployer.FunctionDeployer import org.opendc.serverless.service.deployer.FunctionInstance import org.opendc.serverless.service.deployer.FunctionInstanceState -import org.opendc.simulator.core.DelayControllerClockAdapter +import org.opendc.simulator.core.runBlockingSimulation import java.util.* /** @@ -44,9 +43,8 @@ import java.util.* internal class ServerlessServiceTest { @Test - fun testClientState() = runBlockingTest { + fun testClientState() = runBlockingSimulation { val meter = MeterProvider.noop().get("opendc-serverless") - val clock = DelayControllerClockAdapter(this) val service = ServerlessService(coroutineContext, clock, meter, mockk(), mockk()) val client = assertDoesNotThrow { service.newClient() } @@ -60,9 +58,8 @@ internal class ServerlessServiceTest { } @Test - fun testClientInvokeUnknown() = runBlockingTest { + fun testClientInvokeUnknown() = runBlockingSimulation { val meter = MeterProvider.noop().get("opendc-serverless") - val clock = DelayControllerClockAdapter(this) val service = ServerlessService(coroutineContext, clock, meter, mockk(), mockk()) val client = service.newClient() @@ -71,9 +68,8 @@ internal class ServerlessServiceTest { } @Test - fun testClientFunctionCreation() = runBlockingTest { + fun testClientFunctionCreation() = runBlockingSimulation { val meter = MeterProvider.noop().get("opendc-serverless") - val clock = DelayControllerClockAdapter(this) val service = ServerlessService(coroutineContext, clock, meter, mockk(), mockk()) val client = service.newClient() @@ -84,9 +80,8 @@ internal class ServerlessServiceTest { } @Test - fun testClientFunctionQuery() = runBlockingTest { + fun testClientFunctionQuery() = runBlockingSimulation { val meter = MeterProvider.noop().get("opendc-serverless") - val clock = DelayControllerClockAdapter(this) val service = ServerlessService(coroutineContext, clock, meter, mockk(), mockk()) val client = service.newClient() @@ -99,9 +94,8 @@ internal class ServerlessServiceTest { } @Test - fun testClientFunctionFindById() = runBlockingTest { + fun testClientFunctionFindById() = runBlockingSimulation { val meter = MeterProvider.noop().get("opendc-serverless") - val clock = DelayControllerClockAdapter(this) val service = ServerlessService(coroutineContext, clock, meter, mockk(), mockk()) val client = service.newClient() @@ -114,9 +108,8 @@ internal class ServerlessServiceTest { } @Test - fun testClientFunctionFindByName() = runBlockingTest { + fun testClientFunctionFindByName() = runBlockingSimulation { val meter = MeterProvider.noop().get("opendc-serverless") - val clock = DelayControllerClockAdapter(this) val service = ServerlessService(coroutineContext, clock, meter, mockk(), mockk()) val client = service.newClient() @@ -129,9 +122,8 @@ internal class ServerlessServiceTest { } @Test - fun testClientFunctionDuplicateName() = runBlockingTest { + fun testClientFunctionDuplicateName() = runBlockingSimulation { val meter = MeterProvider.noop().get("opendc-serverless") - val clock = DelayControllerClockAdapter(this) val service = ServerlessService(coroutineContext, clock, meter, mockk(), mockk()) val client = service.newClient() @@ -142,9 +134,8 @@ internal class ServerlessServiceTest { } @Test - fun testClientFunctionDelete() = runBlockingTest { + fun testClientFunctionDelete() = runBlockingSimulation { val meter = MeterProvider.noop().get("opendc-serverless") - val clock = DelayControllerClockAdapter(this) val service = ServerlessService(coroutineContext, clock, meter, mockk(), mockk()) val client = service.newClient() @@ -158,9 +149,8 @@ internal class ServerlessServiceTest { } @Test - fun testClientFunctionCannotInvokeDeleted() = runBlockingTest { + fun testClientFunctionCannotInvokeDeleted() = runBlockingSimulation { val meter = MeterProvider.noop().get("opendc-serverless") - val clock = DelayControllerClockAdapter(this) val service = ServerlessService(coroutineContext, clock, meter, mockk(), mockk()) val client = service.newClient() @@ -172,9 +162,8 @@ internal class ServerlessServiceTest { } @Test - fun testClientFunctionInvoke() = runBlockingTest { + fun testClientFunctionInvoke() = runBlockingSimulation { val meter = MeterProvider.noop().get("opendc-serverless") - val clock = DelayControllerClockAdapter(this) val deployer = mockk<FunctionDeployer>() val service = ServerlessService(coroutineContext, clock, meter, deployer, mockk()) diff --git a/simulator/opendc-serverless/opendc-serverless-simulator/src/test/kotlin/org/opendc/serverless/simulator/SimServerlessServiceTest.kt b/simulator/opendc-serverless/opendc-serverless-simulator/src/test/kotlin/org/opendc/serverless/simulator/SimServerlessServiceTest.kt index 7411ffa1..9592d870 100644 --- a/simulator/opendc-serverless/opendc-serverless-simulator/src/test/kotlin/org/opendc/serverless/simulator/SimServerlessServiceTest.kt +++ b/simulator/opendc-serverless/opendc-serverless-simulator/src/test/kotlin/org/opendc/serverless/simulator/SimServerlessServiceTest.kt @@ -27,7 +27,6 @@ import io.mockk.spyk import io.opentelemetry.api.metrics.MeterProvider import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.delay -import kotlinx.coroutines.test.runBlockingTest import kotlinx.coroutines.yield import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -42,7 +41,7 @@ import org.opendc.simulator.compute.model.ProcessingNode import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.compute.workload.SimFlopsWorkload import org.opendc.simulator.compute.workload.SimWorkload -import org.opendc.simulator.core.DelayControllerClockAdapter +import org.opendc.simulator.core.runBlockingSimulation /** * A test suite for the [ServerlessService] implementation under simulated conditions. @@ -63,9 +62,8 @@ internal class SimServerlessServiceTest { } @Test - fun testSmoke() = runBlockingTest { + fun testSmoke() = runBlockingSimulation { val meter = MeterProvider.noop().get("opendc-serverless") - val clock = DelayControllerClockAdapter(this) val workload = spyk(object : SimServerlessWorkload, SimWorkload by SimFlopsWorkload(1000) { override suspend fun invoke() {} }) diff --git a/simulator/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt b/simulator/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt index 99a5fa02..7b97a665 100644 --- a/simulator/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt +++ b/simulator/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt @@ -25,8 +25,6 @@ package org.opendc.simulator.compute import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch -import kotlinx.coroutines.test.TestCoroutineScope -import kotlinx.coroutines.test.runBlockingTest import org.opendc.simulator.compute.cpufreq.PerformanceScalingGovernor import org.opendc.simulator.compute.cpufreq.SimpleScalingDriver import org.opendc.simulator.compute.model.MemoryUnit @@ -34,7 +32,8 @@ import org.opendc.simulator.compute.model.ProcessingNode import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.compute.power.ConstantPowerModel import org.opendc.simulator.compute.workload.SimWorkload -import org.opendc.simulator.core.DelayControllerClockAdapter +import org.opendc.simulator.core.SimulationCoroutineScope +import org.opendc.simulator.core.runBlockingSimulation import org.opendc.utils.TimerScheduler import org.openjdk.jmh.annotations.* import java.time.Clock @@ -46,15 +45,14 @@ import java.util.concurrent.TimeUnit @Measurement(iterations = 5, time = 3, timeUnit = TimeUnit.SECONDS) @OptIn(ExperimentalCoroutinesApi::class) class SimMachineBenchmarks { - private lateinit var scope: TestCoroutineScope + private lateinit var scope: SimulationCoroutineScope private lateinit var clock: Clock private lateinit var scheduler: TimerScheduler<Any> private lateinit var machineModel: SimMachineModel @Setup fun setUp() { - scope = TestCoroutineScope() - clock = DelayControllerClockAdapter(scope) + scope = SimulationCoroutineScope() scheduler = TimerScheduler(scope.coroutineContext, clock) val cpuNode = ProcessingNode("Intel", "Xeon", "amd64", 2) @@ -77,18 +75,18 @@ class SimMachineBenchmarks { @Benchmark fun benchmarkBareMetal(state: Workload) { - return scope.runBlockingTest { + return scope.runBlockingSimulation { val machine = SimBareMetalMachine( coroutineContext, clock, machineModel, PerformanceScalingGovernor(), SimpleScalingDriver(ConstantPowerModel(0.0)) ) - return@runBlockingTest machine.run(state.workloads[0]) + return@runBlockingSimulation machine.run(state.workloads[0]) } } @Benchmark fun benchmarkSpaceSharedHypervisor(state: Workload) { - return scope.runBlockingTest { + return scope.runBlockingSimulation { val machine = SimBareMetalMachine( coroutineContext, clock, machineModel, PerformanceScalingGovernor(), SimpleScalingDriver(ConstantPowerModel(0.0)) @@ -100,7 +98,7 @@ class SimMachineBenchmarks { val vm = hypervisor.createMachine(machineModel) try { - return@runBlockingTest vm.run(state.workloads[0]) + return@runBlockingSimulation vm.run(state.workloads[0]) } finally { vm.close() machine.close() @@ -110,7 +108,7 @@ class SimMachineBenchmarks { @Benchmark fun benchmarkFairShareHypervisorSingle(state: Workload) { - return scope.runBlockingTest { + return scope.runBlockingSimulation { val machine = SimBareMetalMachine( coroutineContext, clock, machineModel, PerformanceScalingGovernor(), SimpleScalingDriver(ConstantPowerModel(0.0)) @@ -122,7 +120,7 @@ class SimMachineBenchmarks { val vm = hypervisor.createMachine(machineModel) try { - return@runBlockingTest vm.run(state.workloads[0]) + return@runBlockingSimulation vm.run(state.workloads[0]) } finally { vm.close() machine.close() @@ -132,7 +130,7 @@ class SimMachineBenchmarks { @Benchmark fun benchmarkFairShareHypervisorDouble(state: Workload) { - return scope.runBlockingTest { + return scope.runBlockingSimulation { val machine = SimBareMetalMachine( coroutineContext, clock, machineModel, PerformanceScalingGovernor(), SimpleScalingDriver(ConstantPowerModel(0.0)) diff --git a/simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimHypervisorTest.kt b/simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimHypervisorTest.kt index 2c87421f..a067dd2e 100644 --- a/simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimHypervisorTest.kt +++ b/simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimHypervisorTest.kt @@ -26,7 +26,6 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.toList import kotlinx.coroutines.launch -import kotlinx.coroutines.test.runBlockingTest import kotlinx.coroutines.yield import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.BeforeEach @@ -39,7 +38,7 @@ import org.opendc.simulator.compute.model.ProcessingNode import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.compute.power.ConstantPowerModel import org.opendc.simulator.compute.workload.SimTraceWorkload -import org.opendc.simulator.core.DelayControllerClockAdapter +import org.opendc.simulator.core.runBlockingSimulation /** * Test suite for the [SimHypervisor] class. @@ -61,8 +60,7 @@ internal class SimHypervisorTest { * Test overcommitting of resources via the hypervisor with a single VM. */ @Test - fun testOvercommittedSingle() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testOvercommittedSingle() = runBlockingSimulation { val listener = object : SimHypervisor.Listener { var totalRequestedWork = 0L var totalGrantedWork = 0L @@ -116,7 +114,7 @@ internal class SimHypervisorTest { { assertEquals(1023300, listener.totalGrantedWork, "Granted Burst does not match") }, { assertEquals(90000, listener.totalOvercommittedWork, "Overcommissioned Burst does not match") }, { assertEquals(listOf(0.0, 0.00875, 1.0, 0.0, 0.0571875, 0.0), res) { "VM usage is correct" } }, - { assertEquals(1200000, currentTime) { "Current time is correct" } } + { assertEquals(1200000, clock.millis()) { "Current time is correct" } } ) } @@ -124,8 +122,7 @@ internal class SimHypervisorTest { * Test overcommitting of resources via the hypervisor with two VMs. */ @Test - fun testOvercommittedDual() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testOvercommittedDual() = runBlockingSimulation { val listener = object : SimHypervisor.Listener { var totalRequestedWork = 0L var totalGrantedWork = 0L @@ -195,7 +192,7 @@ internal class SimHypervisorTest { { assertEquals(2082000, listener.totalRequestedWork, "Requested Burst does not match") }, { assertEquals(1062000, listener.totalGrantedWork, "Granted Burst does not match") }, { assertEquals(1020000, listener.totalOvercommittedWork, "Overcommissioned Burst does not match") }, - { assertEquals(1200000, currentTime) } + { assertEquals(1200000, clock.millis()) } ) } } diff --git a/simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt b/simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt index 64524452..205f2eca 100644 --- a/simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt +++ b/simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt @@ -24,7 +24,6 @@ package org.opendc.simulator.compute import kotlinx.coroutines.* import kotlinx.coroutines.flow.toList -import kotlinx.coroutines.test.runBlockingTest import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -37,7 +36,7 @@ import org.opendc.simulator.compute.model.ProcessingNode import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.compute.power.ConstantPowerModel import org.opendc.simulator.compute.workload.SimFlopsWorkload -import org.opendc.simulator.core.DelayControllerClockAdapter +import org.opendc.simulator.core.runBlockingSimulation /** * Test suite for the [SimBareMetalMachine] class. @@ -57,23 +56,21 @@ class SimMachineTest { } @Test - fun testFlopsWorkload() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testFlopsWorkload() = runBlockingSimulation { val machine = SimBareMetalMachine(coroutineContext, clock, machineModel, PerformanceScalingGovernor(), SimpleScalingDriver(ConstantPowerModel(0.0))) try { machine.run(SimFlopsWorkload(2_000, utilization = 1.0)) // Two cores execute 1000 MFlOps per second (1000 ms) - assertEquals(1000, currentTime) + assertEquals(1000, clock.millis()) } finally { machine.close() } } @Test - fun testDualSocketMachine() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testDualSocketMachine() = runBlockingSimulation { val cpuNode = machineModel.cpus[0].node val machineModel = SimMachineModel( cpus = List(cpuNode.coreCount * 2) { ProcessingUnit(cpuNode, it % 2, 1000.0) }, @@ -85,15 +82,14 @@ class SimMachineTest { machine.run(SimFlopsWorkload(2_000, utilization = 1.0)) // Two sockets with two cores execute 2000 MFlOps per second (500 ms) - assertEquals(500, currentTime) + assertEquals(500, clock.millis()) } finally { machine.close() } } @Test - fun testUsage() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testUsage() = runBlockingSimulation { val machine = SimBareMetalMachine(coroutineContext, clock, machineModel, PerformanceScalingGovernor(), SimpleScalingDriver(ConstantPowerModel(0.0))) val res = mutableListOf<Double>() @@ -110,8 +106,7 @@ class SimMachineTest { } @Test - fun testClose() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testClose() = runBlockingSimulation { val machine = SimBareMetalMachine(coroutineContext, clock, machineModel, PerformanceScalingGovernor(), SimpleScalingDriver(ConstantPowerModel(0.0))) machine.close() diff --git a/simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimSpaceSharedHypervisorTest.kt b/simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimSpaceSharedHypervisorTest.kt index fc2bc720..ef6f536d 100644 --- a/simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimSpaceSharedHypervisorTest.kt +++ b/simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimSpaceSharedHypervisorTest.kt @@ -25,7 +25,6 @@ package org.opendc.simulator.compute import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.toList import kotlinx.coroutines.launch -import kotlinx.coroutines.test.runBlockingTest import kotlinx.coroutines.yield import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.BeforeEach @@ -40,7 +39,7 @@ import org.opendc.simulator.compute.power.ConstantPowerModel import org.opendc.simulator.compute.workload.SimFlopsWorkload import org.opendc.simulator.compute.workload.SimRuntimeWorkload import org.opendc.simulator.compute.workload.SimTraceWorkload -import org.opendc.simulator.core.DelayControllerClockAdapter +import org.opendc.simulator.core.runBlockingSimulation /** * A test suite for the [SimSpaceSharedHypervisor]. @@ -62,8 +61,7 @@ internal class SimSpaceSharedHypervisorTest { * Test a trace workload. */ @Test - fun testTrace() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testTrace() = runBlockingSimulation { val usagePm = mutableListOf<Double>() val usageVm = mutableListOf<Double>() @@ -103,7 +101,7 @@ internal class SimSpaceSharedHypervisorTest { { assertEquals(listOf(0.0, 0.00875, 1.0, 0.0, 0.0571875, 0.0), usagePm) { "Correct PM usage" } }, // Temporary limitation is that VMs do not emit usage information // { assertEquals(listOf(0.0, 0.00875, 1.0, 0.0, 0.0571875, 0.0), usageVm) { "Correct VM usage" } }, - { assertEquals(5 * 60L * 4000, currentTime) { "Took enough time" } } + { assertEquals(5 * 60L * 4000, clock.millis()) { "Took enough time" } } ) } @@ -111,8 +109,7 @@ internal class SimSpaceSharedHypervisorTest { * Test runtime workload on hypervisor. */ @Test - fun testRuntimeWorkload() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testRuntimeWorkload() = runBlockingSimulation { val duration = 5 * 60L * 1000 val workload = SimRuntimeWorkload(duration) val machine = SimBareMetalMachine( @@ -128,16 +125,14 @@ internal class SimSpaceSharedHypervisorTest { vm.close() machine.close() - assertEquals(duration, currentTime) { "Took enough time" } + assertEquals(duration, clock.millis()) { "Took enough time" } } /** * Test FLOPs workload on hypervisor. */ @Test - fun testFlopsWorkload() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) - + fun testFlopsWorkload() = runBlockingSimulation { val duration = 5 * 60L * 1000 val workload = SimFlopsWorkload((duration * 3.2).toLong(), 1.0) val machine = SimBareMetalMachine( @@ -152,15 +147,14 @@ internal class SimSpaceSharedHypervisorTest { vm.run(workload) machine.close() - assertEquals(duration, currentTime) { "Took enough time" } + assertEquals(duration, clock.millis()) { "Took enough time" } } /** * Test two workloads running sequentially. */ @Test - fun testTwoWorkloads() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testTwoWorkloads() = runBlockingSimulation { val duration = 5 * 60L * 1000 val machine = SimBareMetalMachine( coroutineContext, clock, machineModel, PerformanceScalingGovernor(), @@ -180,15 +174,14 @@ internal class SimSpaceSharedHypervisorTest { vm2.close() machine.close() - assertEquals(duration * 2, currentTime) { "Took enough time" } + assertEquals(duration * 2, clock.millis()) { "Took enough time" } } /** * Test concurrent workloads on the machine. */ @Test - fun testConcurrentWorkloadFails() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testConcurrentWorkloadFails() = runBlockingSimulation { val machine = SimBareMetalMachine( coroutineContext, clock, machineModel, PerformanceScalingGovernor(), SimpleScalingDriver(ConstantPowerModel(0.0)) @@ -212,8 +205,7 @@ internal class SimSpaceSharedHypervisorTest { * Test concurrent workloads on the machine. */ @Test - fun testConcurrentWorkloadSucceeds() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testConcurrentWorkloadSucceeds() = runBlockingSimulation { val machine = SimBareMetalMachine( coroutineContext, clock, machineModel, PerformanceScalingGovernor(), SimpleScalingDriver(ConstantPowerModel(0.0)) diff --git a/simulator/opendc-simulator/opendc-simulator-core/build.gradle.kts b/simulator/opendc-simulator/opendc-simulator-core/build.gradle.kts index 309afb19..3ba0d8c3 100644 --- a/simulator/opendc-simulator/opendc-simulator-core/build.gradle.kts +++ b/simulator/opendc-simulator/opendc-simulator-core/build.gradle.kts @@ -29,5 +29,5 @@ plugins { dependencies { api(platform(project(":opendc-platform"))) - api("org.jetbrains.kotlinx:kotlinx-coroutines-test") + api("org.jetbrains.kotlinx:kotlinx-coroutines-core") } diff --git a/simulator/opendc-simulator/opendc-simulator-core/src/main/kotlin/org/opendc/simulator/core/DelayControllerClockAdapter.kt b/simulator/opendc-simulator/opendc-simulator-core/src/main/kotlin/org/opendc/simulator/core/DelayControllerClockAdapter.kt deleted file mode 100644 index a81a16e3..00000000 --- a/simulator/opendc-simulator/opendc-simulator-core/src/main/kotlin/org/opendc/simulator/core/DelayControllerClockAdapter.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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.simulator.core - -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.test.DelayController -import java.time.Clock -import java.time.Instant -import java.time.ZoneId - -/** - * A virtual [Clock] that abstracts accesses to [DelayController]'s virtual clock. - */ -@OptIn(ExperimentalCoroutinesApi::class) -public class DelayControllerClockAdapter( - private val delayController: DelayController, - private val zone: ZoneId = ZoneId.systemDefault() -) : Clock() { - override fun getZone(): ZoneId = zone - - override fun withZone(zone: ZoneId): Clock = DelayControllerClockAdapter(delayController, zone) - - override fun instant(): Instant = Instant.ofEpochMilli(millis()) - - override fun millis(): Long = delayController.currentTime -} diff --git a/simulator/opendc-simulator/opendc-simulator-resources/src/jmh/kotlin/org/opendc/simulator/resources/SimResourceBenchmarks.kt b/simulator/opendc-simulator/opendc-simulator-resources/src/jmh/kotlin/org/opendc/simulator/resources/SimResourceBenchmarks.kt index ab0abe23..beda3eaa 100644 --- a/simulator/opendc-simulator/opendc-simulator-resources/src/jmh/kotlin/org/opendc/simulator/resources/SimResourceBenchmarks.kt +++ b/simulator/opendc-simulator/opendc-simulator-resources/src/jmh/kotlin/org/opendc/simulator/resources/SimResourceBenchmarks.kt @@ -24,12 +24,10 @@ package org.opendc.simulator.resources import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.launch -import kotlinx.coroutines.test.TestCoroutineScope -import kotlinx.coroutines.test.runBlockingTest -import org.opendc.simulator.core.DelayControllerClockAdapter +import org.opendc.simulator.core.SimulationCoroutineScope +import org.opendc.simulator.core.runBlockingSimulation import org.opendc.utils.TimerScheduler import org.openjdk.jmh.annotations.* -import java.time.Clock import java.util.concurrent.TimeUnit @State(Scope.Thread) @@ -38,15 +36,13 @@ import java.util.concurrent.TimeUnit @Measurement(iterations = 5, time = 3, timeUnit = TimeUnit.SECONDS) @OptIn(ExperimentalCoroutinesApi::class) class SimResourceBenchmarks { - private lateinit var scope: TestCoroutineScope - private lateinit var clock: Clock + private lateinit var scope: SimulationCoroutineScope private lateinit var scheduler: TimerScheduler<Any> @Setup fun setUp() { - scope = TestCoroutineScope() - clock = DelayControllerClockAdapter(scope) - scheduler = TimerScheduler(scope.coroutineContext, clock) + scope = SimulationCoroutineScope() + scheduler = TimerScheduler(scope.coroutineContext, scope.clock) } @State(Scope.Thread) @@ -61,38 +57,38 @@ class SimResourceBenchmarks { @Benchmark fun benchmarkSource(state: Workload) { - return scope.runBlockingTest { + return scope.runBlockingSimulation { val provider = SimResourceSource(4200.0, clock, scheduler) - return@runBlockingTest provider.consume(state.consumers[0]) + return@runBlockingSimulation provider.consume(state.consumers[0]) } } @Benchmark fun benchmarkForwardOverhead(state: Workload) { - return scope.runBlockingTest { + return scope.runBlockingSimulation { val provider = SimResourceSource(4200.0, clock, scheduler) val forwarder = SimResourceForwarder() provider.startConsumer(forwarder) - return@runBlockingTest forwarder.consume(state.consumers[0]) + return@runBlockingSimulation forwarder.consume(state.consumers[0]) } } @Benchmark fun benchmarkSwitchMaxMinSingleConsumer(state: Workload) { - return scope.runBlockingTest { + return scope.runBlockingSimulation { val switch = SimResourceSwitchMaxMin(clock) switch.addInput(SimResourceSource(3000.0, clock, scheduler)) switch.addInput(SimResourceSource(3000.0, clock, scheduler)) val provider = switch.addOutput(3500.0) - return@runBlockingTest provider.consume(state.consumers[0]) + return@runBlockingSimulation provider.consume(state.consumers[0]) } } @Benchmark fun benchmarkSwitchMaxMinTripleConsumer(state: Workload) { - return scope.runBlockingTest { + return scope.runBlockingSimulation { val switch = SimResourceSwitchMaxMin(clock) switch.addInput(SimResourceSource(3000.0, clock, scheduler)) @@ -109,20 +105,20 @@ class SimResourceBenchmarks { @Benchmark fun benchmarkSwitchExclusiveSingleConsumer(state: Workload) { - return scope.runBlockingTest { + return scope.runBlockingSimulation { val switch = SimResourceSwitchExclusive() switch.addInput(SimResourceSource(3000.0, clock, scheduler)) switch.addInput(SimResourceSource(3000.0, clock, scheduler)) val provider = switch.addOutput(3500.0) - return@runBlockingTest provider.consume(state.consumers[0]) + return@runBlockingSimulation provider.consume(state.consumers[0]) } } @Benchmark fun benchmarkSwitchExclusiveTripleConsumer(state: Workload) { - return scope.runBlockingTest { + return scope.runBlockingSimulation { val switch = SimResourceSwitchExclusive() switch.addInput(SimResourceSource(3000.0, clock, scheduler)) diff --git a/simulator/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMinTest.kt b/simulator/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMinTest.kt index cc85d5d9..e272abb8 100644 --- a/simulator/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMinTest.kt +++ b/simulator/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceAggregatorMaxMinTest.kt @@ -26,12 +26,11 @@ import io.mockk.every import io.mockk.mockk import io.mockk.verify import kotlinx.coroutines.* -import kotlinx.coroutines.test.runBlockingTest import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertAll import org.junit.jupiter.api.assertThrows -import org.opendc.simulator.core.DelayControllerClockAdapter +import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.resources.consumer.SimSpeedConsumerAdapter import org.opendc.simulator.resources.consumer.SimWorkConsumer import org.opendc.utils.TimerScheduler @@ -42,8 +41,7 @@ import org.opendc.utils.TimerScheduler @OptIn(ExperimentalCoroutinesApi::class) internal class SimResourceAggregatorMaxMinTest { @Test - fun testSingleCapacity() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testSingleCapacity() = runBlockingSimulation { val scheduler = TimerScheduler<Any>(coroutineContext, clock) val aggregator = SimResourceAggregatorMaxMin(clock) @@ -65,7 +63,7 @@ internal class SimResourceAggregatorMaxMinTest { yield() assertAll( - { assertEquals(1000, currentTime) }, + { assertEquals(1000, clock.millis()) }, { assertEquals(listOf(0.0, 0.5, 0.0), usage) } ) } finally { @@ -74,8 +72,7 @@ internal class SimResourceAggregatorMaxMinTest { } @Test - fun testDoubleCapacity() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testDoubleCapacity() = runBlockingSimulation { val scheduler = TimerScheduler<Any>(coroutineContext, clock) val aggregator = SimResourceAggregatorMaxMin(clock) @@ -93,7 +90,7 @@ internal class SimResourceAggregatorMaxMinTest { aggregator.output.consume(adapter) yield() assertAll( - { assertEquals(1000, currentTime) }, + { assertEquals(1000, clock.millis()) }, { assertEquals(listOf(0.0, 2.0, 0.0), usage) } ) } finally { @@ -102,8 +99,7 @@ internal class SimResourceAggregatorMaxMinTest { } @Test - fun testOvercommit() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testOvercommit() = runBlockingSimulation { val scheduler = TimerScheduler<Any>(coroutineContext, clock) val aggregator = SimResourceAggregatorMaxMin(clock) @@ -121,7 +117,7 @@ internal class SimResourceAggregatorMaxMinTest { try { aggregator.output.consume(consumer) yield() - assertEquals(1000, currentTime) + assertEquals(1000, clock.millis()) verify(exactly = 2) { consumer.onNext(any()) } } finally { @@ -130,8 +126,7 @@ internal class SimResourceAggregatorMaxMinTest { } @Test - fun testException() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testException() = runBlockingSimulation { val scheduler = TimerScheduler<Any>(coroutineContext, clock) val aggregator = SimResourceAggregatorMaxMin(clock) @@ -156,8 +151,7 @@ internal class SimResourceAggregatorMaxMinTest { } @Test - fun testAdjustCapacity() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testAdjustCapacity() = runBlockingSimulation { val scheduler = TimerScheduler<Any>(coroutineContext, clock) val aggregator = SimResourceAggregatorMaxMin(clock) @@ -175,15 +169,14 @@ internal class SimResourceAggregatorMaxMinTest { sources[0].capacity = 0.5 } yield() - assertEquals(2334, currentTime) + assertEquals(2334, clock.millis()) } finally { aggregator.output.close() } } @Test - fun testFailOverCapacity() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testFailOverCapacity() = runBlockingSimulation { val scheduler = TimerScheduler<Any>(coroutineContext, clock) val aggregator = SimResourceAggregatorMaxMin(clock) @@ -201,7 +194,7 @@ internal class SimResourceAggregatorMaxMinTest { sources[0].capacity = 0.5 } yield() - assertEquals(1000, currentTime) + assertEquals(1000, clock.millis()) } finally { aggregator.output.close() } diff --git a/simulator/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceContextTest.kt b/simulator/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceContextTest.kt index c8c1a9d7..be909556 100644 --- a/simulator/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceContextTest.kt +++ b/simulator/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceContextTest.kt @@ -24,9 +24,8 @@ package org.opendc.simulator.resources import io.mockk.* import kotlinx.coroutines.* -import kotlinx.coroutines.test.runBlockingTest import org.junit.jupiter.api.* -import org.opendc.simulator.core.DelayControllerClockAdapter +import org.opendc.simulator.core.runBlockingSimulation /** * A test suite for the [SimAbstractResourceContext] class. @@ -34,9 +33,7 @@ import org.opendc.simulator.core.DelayControllerClockAdapter @OptIn(ExperimentalCoroutinesApi::class) class SimResourceContextTest { @Test - fun testFlushWithoutCommand() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) - + fun testFlushWithoutCommand() = runBlockingSimulation { val consumer = mockk<SimResourceConsumer>(relaxUnitFun = true) every { consumer.onNext(any()) } returns SimResourceCommand.Consume(10.0, 1.0) andThen SimResourceCommand.Exit @@ -50,9 +47,7 @@ class SimResourceContextTest { } @Test - fun testIntermediateFlush() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) - + fun testIntermediateFlush() = runBlockingSimulation { val consumer = mockk<SimResourceConsumer>(relaxUnitFun = true) every { consumer.onNext(any()) } returns SimResourceCommand.Consume(10.0, 1.0) andThen SimResourceCommand.Exit @@ -70,9 +65,7 @@ class SimResourceContextTest { } @Test - fun testIntermediateFlushIdle() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) - + fun testIntermediateFlushIdle() = runBlockingSimulation { val consumer = mockk<SimResourceConsumer>(relaxUnitFun = true) every { consumer.onNext(any()) } returns SimResourceCommand.Idle(10) andThen SimResourceCommand.Exit @@ -95,9 +88,7 @@ class SimResourceContextTest { } @Test - fun testDoubleStart() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) - + fun testDoubleStart() = runBlockingSimulation { val consumer = mockk<SimResourceConsumer>(relaxUnitFun = true) every { consumer.onNext(any()) } returns SimResourceCommand.Idle(10) andThen SimResourceCommand.Exit diff --git a/simulator/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSourceTest.kt b/simulator/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSourceTest.kt index 06b1b87b..39f74481 100644 --- a/simulator/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSourceTest.kt +++ b/simulator/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSourceTest.kt @@ -27,10 +27,9 @@ import io.mockk.mockk import io.mockk.spyk import io.mockk.verify import kotlinx.coroutines.* -import kotlinx.coroutines.test.runBlockingTest import org.junit.jupiter.api.* import org.junit.jupiter.api.Assertions.assertEquals -import org.opendc.simulator.core.DelayControllerClockAdapter +import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.resources.consumer.SimSpeedConsumerAdapter import org.opendc.simulator.resources.consumer.SimWorkConsumer import org.opendc.utils.TimerScheduler @@ -41,8 +40,7 @@ import org.opendc.utils.TimerScheduler @OptIn(ExperimentalCoroutinesApi::class) class SimResourceSourceTest { @Test - fun testSpeed() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testSpeed() = runBlockingSimulation { val scheduler = TimerScheduler<Any>(coroutineContext, clock) val capacity = 4200.0 val provider = SimResourceSource(capacity, clock, scheduler) @@ -66,8 +64,7 @@ class SimResourceSourceTest { } @Test - fun testAdjustCapacity() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testAdjustCapacity() = runBlockingSimulation { val scheduler = TimerScheduler<Any>(coroutineContext, clock) val provider = SimResourceSource(1.0, clock, scheduler) @@ -79,7 +76,7 @@ class SimResourceSourceTest { delay(1000) provider.capacity = 0.5 } - assertEquals(3000, currentTime) + assertEquals(3000, clock.millis()) verify(exactly = 1) { consumer.onCapacityChanged(any(), true) } } finally { scheduler.close() @@ -88,8 +85,7 @@ class SimResourceSourceTest { } @Test - fun testSpeedLimit() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testSpeedLimit() = runBlockingSimulation { val scheduler = TimerScheduler<Any>(coroutineContext, clock) val capacity = 4200.0 val provider = SimResourceSource(capacity, clock, scheduler) @@ -117,8 +113,7 @@ class SimResourceSourceTest { * [SimResourceConsumer.onNext]. */ @Test - fun testIntermediateInterrupt() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testIntermediateInterrupt() = runBlockingSimulation { val scheduler = TimerScheduler<Any>(coroutineContext, clock) val capacity = 4200.0 val provider = SimResourceSource(capacity, clock, scheduler) @@ -142,8 +137,7 @@ class SimResourceSourceTest { } @Test - fun testInterrupt() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testInterrupt() = runBlockingSimulation { val scheduler = TimerScheduler<Any>(coroutineContext, clock) val capacity = 4200.0 val provider = SimResourceSource(capacity, clock, scheduler) @@ -173,7 +167,7 @@ class SimResourceSourceTest { } provider.consume(consumer) - assertEquals(0, currentTime) + assertEquals(0, clock.millis()) } finally { scheduler.close() provider.close() @@ -181,8 +175,7 @@ class SimResourceSourceTest { } @Test - fun testFailure() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testFailure() = runBlockingSimulation { val scheduler = TimerScheduler<Any>(coroutineContext, clock) val capacity = 4200.0 val provider = SimResourceSource(capacity, clock, scheduler) @@ -202,8 +195,7 @@ class SimResourceSourceTest { } @Test - fun testExceptionPropagationOnNext() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testExceptionPropagationOnNext() = runBlockingSimulation { val scheduler = TimerScheduler<Any>(coroutineContext, clock) val capacity = 4200.0 val provider = SimResourceSource(capacity, clock, scheduler) @@ -224,8 +216,7 @@ class SimResourceSourceTest { } @Test - fun testConcurrentConsumption() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testConcurrentConsumption() = runBlockingSimulation { val scheduler = TimerScheduler<Any>(coroutineContext, clock) val capacity = 4200.0 val provider = SimResourceSource(capacity, clock, scheduler) @@ -249,8 +240,7 @@ class SimResourceSourceTest { } @Test - fun testClosedConsumption() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testClosedConsumption() = runBlockingSimulation { val scheduler = TimerScheduler<Any>(coroutineContext, clock) val capacity = 4200.0 val provider = SimResourceSource(capacity, clock, scheduler) @@ -272,8 +262,7 @@ class SimResourceSourceTest { } @Test - fun testCloseDuringConsumption() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testCloseDuringConsumption() = runBlockingSimulation { val scheduler = TimerScheduler<Any>(coroutineContext, clock) val capacity = 4200.0 val provider = SimResourceSource(capacity, clock, scheduler) @@ -288,7 +277,7 @@ class SimResourceSourceTest { delay(500) provider.close() - assertEquals(500, currentTime) + assertEquals(500, clock.millis()) } finally { scheduler.close() provider.close() @@ -296,8 +285,7 @@ class SimResourceSourceTest { } @Test - fun testIdle() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testIdle() = runBlockingSimulation { val scheduler = TimerScheduler<Any>(coroutineContext, clock) val capacity = 4200.0 val provider = SimResourceSource(capacity, clock, scheduler) @@ -310,7 +298,7 @@ class SimResourceSourceTest { try { provider.consume(consumer) - assertEquals(500, currentTime) + assertEquals(500, clock.millis()) } finally { scheduler.close() provider.close() @@ -320,8 +308,7 @@ class SimResourceSourceTest { @Test fun testInfiniteSleep() { assertThrows<IllegalStateException> { - runBlockingTest { - val clock = DelayControllerClockAdapter(this) + runBlockingSimulation { val scheduler = TimerScheduler<Any>(coroutineContext, clock) val capacity = 4200.0 val provider = SimResourceSource(capacity, clock, scheduler) @@ -342,8 +329,7 @@ class SimResourceSourceTest { } @Test - fun testIncorrectDeadline() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testIncorrectDeadline() = runBlockingSimulation { val scheduler = TimerScheduler<Any>(coroutineContext, clock) val capacity = 4200.0 val provider = SimResourceSource(capacity, clock, scheduler) diff --git a/simulator/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusiveTest.kt b/simulator/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusiveTest.kt index 3acad3f7..f7d17867 100644 --- a/simulator/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusiveTest.kt +++ b/simulator/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusiveTest.kt @@ -25,13 +25,12 @@ package org.opendc.simulator.resources import io.mockk.every import io.mockk.mockk import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.test.runBlockingTest import kotlinx.coroutines.yield import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertAll import org.junit.jupiter.api.assertThrows -import org.opendc.simulator.core.DelayControllerClockAdapter +import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.resources.consumer.SimSpeedConsumerAdapter import org.opendc.simulator.resources.consumer.SimTraceConsumer import org.opendc.utils.TimerScheduler @@ -45,8 +44,7 @@ internal class SimResourceSwitchExclusiveTest { * Test a trace workload. */ @Test - fun testTrace() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testTrace() = runBlockingSimulation { val scheduler = TimerScheduler<Any>(coroutineContext, clock) val speed = mutableListOf<Double>() @@ -80,7 +78,7 @@ internal class SimResourceSwitchExclusiveTest { assertAll( { assertEquals(listOf(0.0, 28.0, 3200.0, 0.0, 183.0, 0.0), speed) { "Correct speed" } }, - { assertEquals(5 * 60L * 4000, currentTime) { "Took enough time" } } + { assertEquals(5 * 60L * 4000, clock.millis()) { "Took enough time" } } ) } @@ -88,8 +86,7 @@ internal class SimResourceSwitchExclusiveTest { * Test runtime workload on hypervisor. */ @Test - fun testRuntimeWorkload() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testRuntimeWorkload() = runBlockingSimulation { val scheduler = TimerScheduler<Any>(coroutineContext, clock) val duration = 5 * 60L * 1000 @@ -109,15 +106,14 @@ internal class SimResourceSwitchExclusiveTest { } finally { provider.close() } - assertEquals(duration, currentTime) { "Took enough time" } + assertEquals(duration, clock.millis()) { "Took enough time" } } /** * Test two workloads running sequentially. */ @Test - fun testTwoWorkloads() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testTwoWorkloads() = runBlockingSimulation { val scheduler = TimerScheduler<Any>(coroutineContext, clock) val duration = 5 * 60L * 1000 @@ -152,15 +148,14 @@ internal class SimResourceSwitchExclusiveTest { } finally { provider.close() } - assertEquals(duration * 2, currentTime) { "Took enough time" } + assertEquals(duration * 2, clock.millis()) { "Took enough time" } } /** * Test concurrent workloads on the machine. */ @Test - fun testConcurrentWorkloadFails() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testConcurrentWorkloadFails() = runBlockingSimulation { val scheduler = TimerScheduler<Any>(coroutineContext, clock) val duration = 5 * 60L * 1000 diff --git a/simulator/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMinTest.kt b/simulator/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMinTest.kt index 59e80e56..7416f277 100644 --- a/simulator/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMinTest.kt +++ b/simulator/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMinTest.kt @@ -27,11 +27,10 @@ import io.mockk.mockk import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch -import kotlinx.coroutines.test.runBlockingTest import kotlinx.coroutines.yield import org.junit.jupiter.api.* import org.junit.jupiter.api.Assertions.assertEquals -import org.opendc.simulator.core.DelayControllerClockAdapter +import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.resources.consumer.SimTraceConsumer import org.opendc.utils.TimerScheduler @@ -41,8 +40,7 @@ import org.opendc.utils.TimerScheduler @OptIn(ExperimentalCoroutinesApi::class) internal class SimResourceSwitchMaxMinTest { @Test - fun testSmoke() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testSmoke() = runBlockingSimulation { val scheduler = TimerScheduler<Any>(coroutineContext, clock) val switch = SimResourceSwitchMaxMin(clock) @@ -67,8 +65,7 @@ internal class SimResourceSwitchMaxMinTest { * Test overcommitting of resources via the hypervisor with a single VM. */ @Test - fun testOvercommittedSingle() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testOvercommittedSingle() = runBlockingSimulation { val scheduler = TimerScheduler<Any>(coroutineContext, clock) val listener = object : SimResourceSwitchMaxMin.Listener { @@ -118,7 +115,7 @@ internal class SimResourceSwitchMaxMinTest { { assertEquals(1113300, listener.totalRequestedWork, "Requested Burst does not match") }, { assertEquals(1023300, listener.totalGrantedWork, "Granted Burst does not match") }, { assertEquals(90000, listener.totalOvercommittedWork, "Overcommissioned Burst does not match") }, - { assertEquals(1200000, currentTime) } + { assertEquals(1200000, clock.millis()) } ) } @@ -126,8 +123,7 @@ internal class SimResourceSwitchMaxMinTest { * Test overcommitting of resources via the hypervisor with two VMs. */ @Test - fun testOvercommittedDual() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testOvercommittedDual() = runBlockingSimulation { val scheduler = TimerScheduler<Any>(coroutineContext, clock) val listener = object : SimResourceSwitchMaxMin.Listener { @@ -191,7 +187,7 @@ internal class SimResourceSwitchMaxMinTest { { assertEquals(2082000, listener.totalRequestedWork, "Requested Burst does not match") }, { assertEquals(1062000, listener.totalGrantedWork, "Granted Burst does not match") }, { assertEquals(1020000, listener.totalOvercommittedWork, "Overcommissioned Burst does not match") }, - { assertEquals(1200000, currentTime) } + { assertEquals(1200000, clock.millis()) } ) } } diff --git a/simulator/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceTransformerTest.kt b/simulator/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceTransformerTest.kt index aeaab6af..d2ad73bc 100644 --- a/simulator/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceTransformerTest.kt +++ b/simulator/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimResourceTransformerTest.kt @@ -27,11 +27,10 @@ import io.mockk.mockk import io.mockk.spyk import io.mockk.verify import kotlinx.coroutines.* -import kotlinx.coroutines.test.runBlockingTest import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows -import org.opendc.simulator.core.DelayControllerClockAdapter +import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.resources.consumer.SimWorkConsumer import org.opendc.utils.TimerScheduler @@ -41,9 +40,8 @@ import org.opendc.utils.TimerScheduler @OptIn(ExperimentalCoroutinesApi::class) internal class SimResourceTransformerTest { @Test - fun testExitImmediately() = runBlockingTest { + fun testExitImmediately() = runBlockingSimulation { val forwarder = SimResourceForwarder() - val clock = DelayControllerClockAdapter(this) val scheduler = TimerScheduler<Any>(coroutineContext, clock) val source = SimResourceSource(2000.0, clock, scheduler) @@ -63,9 +61,8 @@ internal class SimResourceTransformerTest { } @Test - fun testExit() = runBlockingTest { + fun testExit() = runBlockingSimulation { val forwarder = SimResourceForwarder() - val clock = DelayControllerClockAdapter(this) val scheduler = TimerScheduler<Any>(coroutineContext, clock) val source = SimResourceSource(2000.0, clock, scheduler) @@ -91,7 +88,7 @@ internal class SimResourceTransformerTest { } @Test - fun testState() = runBlockingTest { + fun testState() = runBlockingSimulation { val forwarder = SimResourceForwarder() val consumer = object : SimResourceConsumer { override fun onNext(ctx: SimResourceContext): SimResourceCommand = SimResourceCommand.Exit @@ -112,7 +109,7 @@ internal class SimResourceTransformerTest { } @Test - fun testCancelPendingDelegate() = runBlockingTest { + fun testCancelPendingDelegate() = runBlockingSimulation { val forwarder = SimResourceForwarder() val consumer = mockk<SimResourceConsumer>(relaxUnitFun = true) @@ -125,9 +122,8 @@ internal class SimResourceTransformerTest { } @Test - fun testCancelStartedDelegate() = runBlockingTest { + fun testCancelStartedDelegate() = runBlockingSimulation { val forwarder = SimResourceForwarder() - val clock = DelayControllerClockAdapter(this) val scheduler = TimerScheduler<Any>(coroutineContext, clock) val source = SimResourceSource(2000.0, clock, scheduler) @@ -145,9 +141,8 @@ internal class SimResourceTransformerTest { } @Test - fun testCancelPropagation() = runBlockingTest { + fun testCancelPropagation() = runBlockingSimulation { val forwarder = SimResourceForwarder() - val clock = DelayControllerClockAdapter(this) val scheduler = TimerScheduler<Any>(coroutineContext, clock) val source = SimResourceSource(2000.0, clock, scheduler) @@ -165,9 +160,8 @@ internal class SimResourceTransformerTest { } @Test - fun testExitPropagation() = runBlockingTest { + fun testExitPropagation() = runBlockingSimulation { val forwarder = SimResourceForwarder(isCoupled = true) - val clock = DelayControllerClockAdapter(this) val scheduler = TimerScheduler<Any>(coroutineContext, clock) val source = SimResourceSource(2000.0, clock, scheduler) @@ -182,9 +176,8 @@ internal class SimResourceTransformerTest { } @Test - fun testAdjustCapacity() = runBlockingTest { + fun testAdjustCapacity() = runBlockingSimulation { val forwarder = SimResourceForwarder() - val clock = DelayControllerClockAdapter(this) val scheduler = TimerScheduler<Any>(coroutineContext, clock) val source = SimResourceSource(1.0, clock, scheduler) @@ -197,14 +190,13 @@ internal class SimResourceTransformerTest { source.capacity = 0.5 } - assertEquals(3000, currentTime) + assertEquals(3000, clock.millis()) verify(exactly = 1) { consumer.onCapacityChanged(any(), true) } } @Test - fun testTransformExit() = runBlockingTest { + fun testTransformExit() = runBlockingSimulation { val forwarder = SimResourceTransformer { _, _ -> SimResourceCommand.Exit } - val clock = DelayControllerClockAdapter(this) val scheduler = TimerScheduler<Any>(coroutineContext, clock) val source = SimResourceSource(1.0, clock, scheduler) @@ -212,7 +204,7 @@ internal class SimResourceTransformerTest { source.startConsumer(forwarder) forwarder.consume(consumer) - assertEquals(0, currentTime) + assertEquals(0, clock.millis()) verify(exactly = 1) { consumer.onNext(any()) } } } diff --git a/simulator/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimWorkConsumerTest.kt b/simulator/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimWorkConsumerTest.kt index 38dc0d48..bf58b1b6 100644 --- a/simulator/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimWorkConsumerTest.kt +++ b/simulator/opendc-simulator/opendc-simulator-resources/src/test/kotlin/org/opendc/simulator/resources/SimWorkConsumerTest.kt @@ -23,10 +23,9 @@ package org.opendc.simulator.resources import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.test.runBlockingTest import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test -import org.opendc.simulator.core.DelayControllerClockAdapter +import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.resources.consumer.SimWorkConsumer import org.opendc.utils.TimerScheduler @@ -36,8 +35,7 @@ import org.opendc.utils.TimerScheduler @OptIn(ExperimentalCoroutinesApi::class) internal class SimWorkConsumerTest { @Test - fun testSmoke() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testSmoke() = runBlockingSimulation { val scheduler = TimerScheduler<Any>(coroutineContext, clock) val provider = SimResourceSource(1.0, clock, scheduler) @@ -45,15 +43,14 @@ internal class SimWorkConsumerTest { try { provider.consume(consumer) - assertEquals(1000, currentTime) + assertEquals(1000, clock.millis()) } finally { provider.close() } } @Test - fun testUtilization() = runBlockingTest { - val clock = DelayControllerClockAdapter(this) + fun testUtilization() = runBlockingSimulation { val scheduler = TimerScheduler<Any>(coroutineContext, clock) val provider = SimResourceSource(1.0, clock, scheduler) @@ -61,7 +58,7 @@ internal class SimWorkConsumerTest { try { provider.consume(consumer) - assertEquals(2000, currentTime) + assertEquals(2000, clock.millis()) } finally { provider.close() } diff --git a/simulator/opendc-utils/src/test/kotlin/org/opendc/utils/TimerSchedulerTest.kt b/simulator/opendc-utils/src/test/kotlin/org/opendc/utils/TimerSchedulerTest.kt index 314b3faa..101a6546 100644 --- a/simulator/opendc-utils/src/test/kotlin/org/opendc/utils/TimerSchedulerTest.kt +++ b/simulator/opendc-utils/src/test/kotlin/org/opendc/utils/TimerSchedulerTest.kt @@ -23,11 +23,10 @@ package org.opendc.utils import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.test.runBlockingTest import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows -import org.opendc.simulator.core.DelayControllerClockAdapter +import org.opendc.simulator.core.runBlockingSimulation /** * A test suite for the [TimerScheduler] class. @@ -36,8 +35,7 @@ import org.opendc.simulator.core.DelayControllerClockAdapter internal class TimerSchedulerTest { @Test fun testBasicTimer() { - runBlockingTest { - val clock = DelayControllerClockAdapter(this) + runBlockingSimulation { val scheduler = TimerScheduler<Int>(coroutineContext, clock) scheduler.startSingleTimer(0, 1000) { @@ -49,8 +47,7 @@ internal class TimerSchedulerTest { @Test fun testCancelNonExisting() { - runBlockingTest { - val clock = DelayControllerClockAdapter(this) + runBlockingSimulation { val scheduler = TimerScheduler<Int>(coroutineContext, clock) scheduler.cancel(1) @@ -60,8 +57,7 @@ internal class TimerSchedulerTest { @Test fun testCancelExisting() { - runBlockingTest { - val clock = DelayControllerClockAdapter(this) + runBlockingSimulation { val scheduler = TimerScheduler<Int>(coroutineContext, clock) scheduler.startSingleTimer(0, 1000) { @@ -79,8 +75,7 @@ internal class TimerSchedulerTest { @Test fun testCancelAll() { - runBlockingTest { - val clock = DelayControllerClockAdapter(this) + runBlockingSimulation { val scheduler = TimerScheduler<Int>(coroutineContext, clock) scheduler.startSingleTimer(0, 1000) { @@ -97,8 +92,7 @@ internal class TimerSchedulerTest { @Test fun testOverride() { - runBlockingTest { - val clock = DelayControllerClockAdapter(this) + runBlockingSimulation { val scheduler = TimerScheduler<Int>(coroutineContext, clock) scheduler.startSingleTimer(0, 1000) { @@ -115,8 +109,7 @@ internal class TimerSchedulerTest { @Test fun testStopped() { - runBlockingTest { - val clock = DelayControllerClockAdapter(this) + runBlockingSimulation { val scheduler = TimerScheduler<Int>(coroutineContext, clock) scheduler.close() @@ -131,8 +124,7 @@ internal class TimerSchedulerTest { @Test fun testNegativeDelay() { - runBlockingTest { - val clock = DelayControllerClockAdapter(this) + runBlockingSimulation { val scheduler = TimerScheduler<Int>(coroutineContext, clock) assertThrows<IllegalArgumentException> { |
