From f24c53dd13c40f46ca03b040bda5fc992d6fa9e3 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 19 May 2020 23:20:18 +0200 Subject: test: Add test to verify slice batching behavior --- .../opendc/compute/core/execution/ServerContext.kt | 2 +- .../opendc/compute/virt/driver/SimpleVirtDriver.kt | 3 +- .../metal/driver/SimpleBareMetalDriverTest.kt | 3 +- .../atlarge/opendc/compute/virt/HypervisorTest.kt | 76 +++++++++++++++++++++- 4 files changed, 78 insertions(+), 6 deletions(-) (limited to 'opendc/opendc-compute/src') diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/execution/ServerContext.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/execution/ServerContext.kt index 027ba410..5a9e74a3 100644 --- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/execution/ServerContext.kt +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/execution/ServerContext.kt @@ -84,7 +84,7 @@ public interface ServerContext { batch: List, triggerMode: TriggerMode = TriggerMode.FIRST, merge: (Slice, Slice) -> Slice = { _, r -> r } - ) = select { onRun(batch, triggerMode, merge).invoke {} } + ) = select { onRun(batch, triggerMode, merge).invoke {} } /** * Ask the processor cores to run the specified [slice] and select when the trigger condition is met as specified diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/driver/SimpleVirtDriver.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/driver/SimpleVirtDriver.kt index b815a7ab..6c47ade7 100644 --- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/driver/SimpleVirtDriver.kt +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/driver/SimpleVirtDriver.kt @@ -482,7 +482,7 @@ class SimpleVirtDriver( */ fun consume(burst: Long): Boolean { this.burst = max(0, this.burst - burst) - return this.burst == 0L + return allocatedLimit > 0.0 && this.burst == 0L } /** @@ -511,7 +511,6 @@ class SimpleVirtDriver( "vCPU(vm=${vm.ctx.server.uid},id=$id,burst=$burst,limit=$limit,allocatedLimit=$allocatedLimit)" } - /** * The execution context in which a VM runs. * diff --git a/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriverTest.kt b/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriverTest.kt index 1b5d62a2..071c0626 100644 --- a/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriverTest.kt +++ b/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriverTest.kt @@ -70,12 +70,11 @@ internal class SimpleBareMetalDriverTest { server.events.collect { event -> when (event) { is ServerEvent.StateChanged -> { - println("${simulationContext.clock.millis()} $event"); + println("${simulationContext.clock.millis()} $event") finalState = event.server.state } } } - } } diff --git a/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/virt/HypervisorTest.kt b/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/virt/HypervisorTest.kt index 318fc279..939eebdd 100644 --- a/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/virt/HypervisorTest.kt +++ b/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/virt/HypervisorTest.kt @@ -29,6 +29,8 @@ import com.atlarge.opendc.compute.core.ProcessingUnit import com.atlarge.opendc.compute.core.Flavor import com.atlarge.opendc.compute.core.ProcessingNode import com.atlarge.opendc.compute.core.image.FlopsApplicationImage +import com.atlarge.opendc.compute.core.image.FlopsHistoryFragment +import com.atlarge.opendc.compute.core.image.VmImage import com.atlarge.opendc.compute.metal.driver.SimpleBareMetalDriver import com.atlarge.opendc.compute.virt.driver.VirtDriver import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -37,7 +39,9 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking +import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertAll import java.util.ServiceLoader import java.util.UUID @@ -71,7 +75,6 @@ internal class HypervisorTest { val node = metalDriver.start() node.server?.events?.onEach { println(it) }?.launchIn(this) - delay(5) val flavor = Flavor(1, 0) @@ -88,4 +91,75 @@ internal class HypervisorTest { system.terminate() } } + + /** + * Test overcommissioning of a hypervisor. + */ + @Test + fun overcommission() { + val provider = ServiceLoader.load(SimulationEngineProvider::class.java).first() + val system = provider("test") + val root = system.newDomain("root") + + var requestedBurst = 0L + var grantedBurst = 0L + var overcommissionedBurst = 0L + + root.launch { + val vmm = HypervisorImage + val duration = 5 * 60L + val vmImageA = VmImage(UUID.randomUUID(), "", emptyMap(), sequenceOf( + FlopsHistoryFragment(0, 28L * duration, duration * 1000, 28.0, 2), + FlopsHistoryFragment(0, 3500L * duration, duration * 1000, 3500.0, 2), + FlopsHistoryFragment(0, 0, duration * 1000, 0.0, 2), + FlopsHistoryFragment(0, 183L * duration, duration * 1000, 183.0, 2) + ), 2, 0) + val vmImageB = VmImage(UUID.randomUUID(), "", emptyMap(), sequenceOf( + FlopsHistoryFragment(0, 28L * duration, duration * 1000, 28.0, 2), + FlopsHistoryFragment(0, 3100L * duration, duration * 1000, 3100.0, 2), + FlopsHistoryFragment(0, 0, duration * 1000, 0.0, 2), + FlopsHistoryFragment(0, 73L * duration, duration * 1000, 73.0, 2) + ), 2, 0) + + val driverDom = root.newDomain("driver") + + val cpuNode = ProcessingNode("Intel", "Xeon", "amd64", 2) + val cpus = List(2) { ProcessingUnit(cpuNode, it, 3200.0) } + val metalDriver = SimpleBareMetalDriver(driverDom, UUID.randomUUID(), "test", emptyMap(), cpus, emptyList()) + + metalDriver.init() + metalDriver.setImage(vmm) + metalDriver.start() + + delay(5) + + val flavor = Flavor(2, 0) + val vmDriver = metalDriver.refresh().server!!.services[VirtDriver] + vmDriver.events + .onEach { event -> + when (event) { + is HypervisorEvent.SliceFinished -> { + requestedBurst += event.requestedBurst + grantedBurst += event.grantedBurst + overcommissionedBurst += event.overcommissionedBurst + } + } + } + .launchIn(this) + + vmDriver.spawn("a", vmImageA, flavor) + vmDriver.spawn("b", vmImageB, flavor) + } + + runBlocking { + system.run() + system.terminate() + } + + assertAll( + { assertEquals(2073600, requestedBurst, "Requested Burst does not match") }, + { assertEquals(2013600, grantedBurst, "Granted Burst does not match") }, + { assertEquals(60000, overcommissionedBurst, "Overcommissioned Burst does not match") } + ) + } } -- cgit v1.2.3