From 06b19fbf17b9e6d8024ba36e0f2533b2db0dd7de Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 2 Sep 2022 22:01:13 +0200 Subject: refactor(sim/compute): Move VM interference model into compute simulator This change moves the core of the VM interference model from the flow module into the compute simulator. This logic can be contained in the compute simulator and does not need to leak into the flow-level simulator. --- .../kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'opendc-experiments/opendc-experiments-capelin/src/test') diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index d7b7caad..368b0086 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -209,7 +209,7 @@ class CapelinIntegrationTest { { assertEquals(6028050, this@CapelinIntegrationTest.monitor.idleTime) { "Idle time incorrect" } }, { assertEquals(14712749, this@CapelinIntegrationTest.monitor.activeTime) { "Active time incorrect" } }, { assertEquals(12532907, this@CapelinIntegrationTest.monitor.stealTime) { "Steal time incorrect" } }, - { assertEquals(467963, this@CapelinIntegrationTest.monitor.lostTime) { "Lost time incorrect" } } + { assertEquals(477068, this@CapelinIntegrationTest.monitor.lostTime) { "Lost time incorrect" } } ) } -- cgit v1.2.3 From 6171ab09f1df2ab3475a7b28ece383a9f87a77c5 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 22 Sep 2022 10:28:37 +0200 Subject: refactor(sim/compute): Extract Random dependency from interference model This change moves the Random dependency outside the interference model, to allow the interference model to be completely immutable and passable between different simulations. --- .../experiments/capelin/CapelinIntegrationTest.kt | 37 ++++++++++++---------- 1 file changed, 21 insertions(+), 16 deletions(-) (limited to 'opendc-experiments/opendc-experiments-capelin/src/test') diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index 368b0086..ff9faef7 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -81,11 +81,13 @@ class CapelinIntegrationTest { */ @Test fun testLarge() = runBlockingSimulation { - val (workload, _) = createTestWorkload(1.0) + val seed = 0L + val (workload, _) = createTestWorkload(1.0, seed) val runner = ComputeServiceHelper( coroutineContext, clock, - computeScheduler + computeScheduler, + seed, ) val topology = createTopology() @@ -94,7 +96,7 @@ class CapelinIntegrationTest { try { runner.apply(topology) - runner.run(workload, 0, servers) + runner.run(workload, servers) val serviceMetrics = runner.service.getSchedulerStats() println( @@ -129,12 +131,13 @@ class CapelinIntegrationTest { */ @Test fun testSmall() = runBlockingSimulation { - val seed = 1 + val seed = 1L val (workload, _) = createTestWorkload(0.25, seed) val runner = ComputeServiceHelper( coroutineContext, clock, - computeScheduler + computeScheduler, + seed, ) val topology = createTopology("single") val servers = mutableListOf() @@ -142,7 +145,7 @@ class CapelinIntegrationTest { try { runner.apply(topology) - runner.run(workload, seed.toLong(), servers) + runner.run(workload, servers) val serviceMetrics = runner.service.getSchedulerStats() println( @@ -173,14 +176,15 @@ class CapelinIntegrationTest { */ @Test fun testInterference() = runBlockingSimulation { - val seed = 0 + val seed = 0L val (workload, interferenceModel) = createTestWorkload(1.0, seed) val simulator = ComputeServiceHelper( coroutineContext, clock, computeScheduler, - interferenceModel = interferenceModel?.withSeed(seed.toLong()) + seed, + interferenceModel = interferenceModel ) val topology = createTopology("single") val servers = mutableListOf() @@ -188,7 +192,7 @@ class CapelinIntegrationTest { try { simulator.apply(topology) - simulator.run(workload, seed.toLong(), servers) + simulator.run(workload, servers) val serviceMetrics = simulator.service.getSchedulerStats() println( @@ -218,11 +222,12 @@ class CapelinIntegrationTest { */ @Test fun testFailures() = runBlockingSimulation { - val seed = 1 + val seed = 0L val simulator = ComputeServiceHelper( coroutineContext, clock, computeScheduler, + seed, grid5000(Duration.ofDays(7)) ) val topology = createTopology("single") @@ -232,7 +237,7 @@ class CapelinIntegrationTest { try { simulator.apply(topology) - simulator.run(workload, seed.toLong(), servers) + simulator.run(workload, servers) val serviceMetrics = simulator.service.getSchedulerStats() println( @@ -250,20 +255,20 @@ class CapelinIntegrationTest { // Note that these values have been verified beforehand assertAll( - { assertEquals(10867345, monitor.idleTime) { "Idle time incorrect" } }, - { assertEquals(9607095, monitor.activeTime) { "Active time incorrect" } }, + { assertEquals(10982026, monitor.idleTime) { "Idle time incorrect" } }, + { assertEquals(9740058, monitor.activeTime) { "Active time incorrect" } }, { assertEquals(0, monitor.stealTime) { "Steal time incorrect" } }, { assertEquals(0, monitor.lostTime) { "Lost time incorrect" } }, - { assertEquals(2559305056, monitor.uptime) { "Uptime incorrect" } } + { assertEquals(2590260605, monitor.uptime) { "Uptime incorrect" } }, ) } /** * Obtain the trace reader for the test. */ - private fun createTestWorkload(fraction: Double, seed: Int = 0): ComputeWorkload.Resolved { + private fun createTestWorkload(fraction: Double, seed: Long): ComputeWorkload.Resolved { val source = trace("bitbrains-small").sampleByLoad(fraction) - return source.resolve(workloadLoader, Random(seed.toLong())) + return source.resolve(workloadLoader, Random(seed)) } /** -- cgit v1.2.3 From 17fa7619f1d7e96680e018d3f12f333fb75cdac1 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 22 Sep 2022 14:45:12 +0200 Subject: refactor(sim/compute): Make interference domain independent of profile This change updates the virtual machine performance interference model so that the interference domain can be constructed independently of the interference profile. As a consequence, the construction of the topology now does not depend anymore on the interference profile. --- .../experiments/capelin/CapelinIntegrationTest.kt | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'opendc-experiments/opendc-experiments-capelin/src/test') diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index ff9faef7..af846dd6 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -82,7 +82,7 @@ class CapelinIntegrationTest { @Test fun testLarge() = runBlockingSimulation { val seed = 0L - val (workload, _) = createTestWorkload(1.0, seed) + val workload = createTestWorkload(1.0, seed) val runner = ComputeServiceHelper( coroutineContext, clock, @@ -132,7 +132,7 @@ class CapelinIntegrationTest { @Test fun testSmall() = runBlockingSimulation { val seed = 1L - val (workload, _) = createTestWorkload(0.25, seed) + val workload = createTestWorkload(0.25, seed) val runner = ComputeServiceHelper( coroutineContext, clock, @@ -177,14 +177,13 @@ class CapelinIntegrationTest { @Test fun testInterference() = runBlockingSimulation { val seed = 0L - val (workload, interferenceModel) = createTestWorkload(1.0, seed) + val workload = createTestWorkload(1.0, seed) val simulator = ComputeServiceHelper( coroutineContext, clock, computeScheduler, - seed, - interferenceModel = interferenceModel + seed ) val topology = createTopology("single") val servers = mutableListOf() @@ -192,7 +191,7 @@ class CapelinIntegrationTest { try { simulator.apply(topology) - simulator.run(workload, servers) + simulator.run(workload, servers, interference = true) val serviceMetrics = simulator.service.getSchedulerStats() println( @@ -213,7 +212,7 @@ class CapelinIntegrationTest { { assertEquals(6028050, this@CapelinIntegrationTest.monitor.idleTime) { "Idle time incorrect" } }, { assertEquals(14712749, this@CapelinIntegrationTest.monitor.activeTime) { "Active time incorrect" } }, { assertEquals(12532907, this@CapelinIntegrationTest.monitor.stealTime) { "Steal time incorrect" } }, - { assertEquals(477068, this@CapelinIntegrationTest.monitor.lostTime) { "Lost time incorrect" } } + { assertEquals(485510, this@CapelinIntegrationTest.monitor.lostTime) { "Lost time incorrect" } } ) } @@ -231,7 +230,7 @@ class CapelinIntegrationTest { grid5000(Duration.ofDays(7)) ) val topology = createTopology("single") - val (workload, _) = createTestWorkload(0.25, seed) + val workload = createTestWorkload(0.25, seed) val servers = mutableListOf() val reader = ComputeMetricReader(this, clock, simulator.service, servers, monitor) @@ -266,7 +265,7 @@ class CapelinIntegrationTest { /** * Obtain the trace reader for the test. */ - private fun createTestWorkload(fraction: Double, seed: Long): ComputeWorkload.Resolved { + private fun createTestWorkload(fraction: Double, seed: Long): List { val source = trace("bitbrains-small").sampleByLoad(fraction) return source.resolve(workloadLoader, Random(seed)) } -- cgit v1.2.3 From d97356cf696dedb6c26fc42d9d7c44a977264dcd Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 22 Sep 2022 22:39:33 +0200 Subject: refactor(compute): Pass failure model during workload evaluation This change updates the `ComputeServiceHelper` class to provide the failure model via a parameter to the `run` method instead of constructor parameter. This separates the construction of the topology from the simulation of the workload. --- .../kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'opendc-experiments/opendc-experiments-capelin/src/test') diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index af846dd6..bf8c2758 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -226,8 +226,7 @@ class CapelinIntegrationTest { coroutineContext, clock, computeScheduler, - seed, - grid5000(Duration.ofDays(7)) + seed ) val topology = createTopology("single") val workload = createTestWorkload(0.25, seed) @@ -236,7 +235,7 @@ class CapelinIntegrationTest { try { simulator.apply(topology) - simulator.run(workload, servers) + simulator.run(workload, servers, failureModel = grid5000(Duration.ofDays(7))) val serviceMetrics = simulator.service.getSchedulerStats() println( -- cgit v1.2.3 From 3d5eb562227dcad5a8a60f31b96e6d68f7774fb2 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 23 Sep 2022 12:27:09 +0200 Subject: refactor(compute): Provide access to instances in compute service This change updates the interface of `ComputeService` to provide access to the instances (servers) that have been registered with the compute service. This allows metric collectors to query the metrics of the servers that are currently running. --- .../experiments/capelin/CapelinIntegrationTest.kt | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) (limited to 'opendc-experiments/opendc-experiments-capelin/src/test') diff --git a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt index bf8c2758..eae3c993 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/test/kotlin/org/opendc/experiments/capelin/CapelinIntegrationTest.kt @@ -26,7 +26,6 @@ import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertAll -import org.opendc.compute.api.Server import org.opendc.compute.service.scheduler.FilterScheduler import org.opendc.compute.service.scheduler.filters.ComputeFilter import org.opendc.compute.service.scheduler.filters.RamFilter @@ -90,13 +89,11 @@ class CapelinIntegrationTest { seed, ) val topology = createTopology() - - val servers = mutableListOf() - val reader = ComputeMetricReader(this, clock, runner.service, servers, monitor) + val reader = ComputeMetricReader(this, clock, runner.service, monitor) try { runner.apply(topology) - runner.run(workload, servers) + runner.run(workload) val serviceMetrics = runner.service.getSchedulerStats() println( @@ -140,12 +137,11 @@ class CapelinIntegrationTest { seed, ) val topology = createTopology("single") - val servers = mutableListOf() - val reader = ComputeMetricReader(this, clock, runner.service, servers, monitor) + val reader = ComputeMetricReader(this, clock, runner.service, monitor) try { runner.apply(topology) - runner.run(workload, servers) + runner.run(workload) val serviceMetrics = runner.service.getSchedulerStats() println( @@ -186,12 +182,11 @@ class CapelinIntegrationTest { seed ) val topology = createTopology("single") - val servers = mutableListOf() - val reader = ComputeMetricReader(this, clock, simulator.service, servers, monitor) + val reader = ComputeMetricReader(this, clock, simulator.service, monitor) try { simulator.apply(topology) - simulator.run(workload, servers, interference = true) + simulator.run(workload, interference = true) val serviceMetrics = simulator.service.getSchedulerStats() println( @@ -230,12 +225,11 @@ class CapelinIntegrationTest { ) val topology = createTopology("single") val workload = createTestWorkload(0.25, seed) - val servers = mutableListOf() - val reader = ComputeMetricReader(this, clock, simulator.service, servers, monitor) + val reader = ComputeMetricReader(this, clock, simulator.service, monitor) try { simulator.apply(topology) - simulator.run(workload, servers, failureModel = grid5000(Duration.ofDays(7))) + simulator.run(workload, failureModel = grid5000(Duration.ofDays(7))) val serviceMetrics = simulator.service.getSchedulerStats() println( -- cgit v1.2.3