summaryrefslogtreecommitdiff
path: root/simulator/opendc-compute
diff options
context:
space:
mode:
authorFabian Mastenbroek <mail.fabianm@gmail.com>2021-01-11 20:13:46 +0100
committerGitHub <noreply@github.com>2021-01-11 20:13:46 +0100
commitbf558fe36c9de52310e85044ee4447b45bd50b75 (patch)
treebea8e47037660c88df42e04105e7a0b7f709173a /simulator/opendc-compute
parent42e9a5b5b610f41a03e68f6fc781c54b9402925b (diff)
parent9dbb7bbcc2202955c715aaa3b28c70641a2fbd5b (diff)
Merge pull request #71 from atlarge-research/perf/workload
Convert to pull-based workload model
Diffstat (limited to 'simulator/opendc-compute')
-rw-r--r--simulator/opendc-compute/opendc-compute-core/src/main/kotlin/org/opendc/compute/core/virt/driver/VirtDriver.kt8
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/build.gradle.kts4
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimBareMetalDriver.kt23
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimVirtDriver.kt109
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimVirtDriverWorkload.kt38
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimVirtProvisioningService.kt44
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimBareMetalDriverTest.kt4
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimProvisioningServiceTest.kt2
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimVirtDriverTest.kt52
9 files changed, 158 insertions, 126 deletions
diff --git a/simulator/opendc-compute/opendc-compute-core/src/main/kotlin/org/opendc/compute/core/virt/driver/VirtDriver.kt b/simulator/opendc-compute/opendc-compute-core/src/main/kotlin/org/opendc/compute/core/virt/driver/VirtDriver.kt
index 5ecfd357..68cc7b50 100644
--- a/simulator/opendc-compute/opendc-compute-core/src/main/kotlin/org/opendc/compute/core/virt/driver/VirtDriver.kt
+++ b/simulator/opendc-compute/opendc-compute-core/src/main/kotlin/org/opendc/compute/core/virt/driver/VirtDriver.kt
@@ -23,6 +23,7 @@
package org.opendc.compute.core.virt.driver
import kotlinx.coroutines.flow.Flow
+import org.opendc.compute.core.Flavor
import org.opendc.compute.core.Server
import org.opendc.compute.core.image.Image
import org.opendc.compute.core.virt.HypervisorEvent
@@ -40,6 +41,11 @@ public interface VirtDriver {
public val events: Flow<HypervisorEvent>
/**
+ * Determine whether the specified [flavor] can still fit on this driver.
+ */
+ public fun canFit(flavor: Flavor): Boolean
+
+ /**
* Spawn the given [Image] on the compute resource of this driver.
*
* @param name The name of the server to spawn.
@@ -50,7 +56,7 @@ public interface VirtDriver {
public suspend fun spawn(
name: String,
image: Image,
- flavor: org.opendc.compute.core.Flavor
+ flavor: Flavor
): Server
public companion object Key : AbstractServiceKey<VirtDriver>(UUID.randomUUID(), "virtual-driver")
diff --git a/simulator/opendc-compute/opendc-compute-simulator/build.gradle.kts b/simulator/opendc-compute/opendc-compute-simulator/build.gradle.kts
index d7570e54..dc93e956 100644
--- a/simulator/opendc-compute/opendc-compute-simulator/build.gradle.kts
+++ b/simulator/opendc-compute/opendc-compute-simulator/build.gradle.kts
@@ -29,10 +29,10 @@ plugins {
dependencies {
api(project(":opendc-compute:opendc-compute-core"))
+ api(project(":opendc-simulator:opendc-simulator-compute"))
+ api(project(":opendc-simulator:opendc-simulator-failures"))
implementation(project(":opendc-utils"))
implementation("io.github.microutils:kotlin-logging:1.7.9")
- implementation(project(":opendc-simulator:opendc-simulator-compute"))
- api(project(":opendc-simulator:opendc-simulator-failures"))
testImplementation(project(":opendc-simulator:opendc-simulator-core"))
testRuntimeOnly("org.slf4j:slf4j-simple:${Library.SLF4J}")
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimBareMetalDriver.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimBareMetalDriver.kt
index 97f550ba..7a978a53 100644
--- a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimBareMetalDriver.kt
+++ b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimBareMetalDriver.kt
@@ -41,6 +41,7 @@ import org.opendc.core.services.ServiceRegistry
import org.opendc.simulator.compute.SimBareMetalMachine
import org.opendc.simulator.compute.SimExecutionContext
import org.opendc.simulator.compute.SimMachineModel
+import org.opendc.simulator.compute.workload.SimResourceCommand
import org.opendc.simulator.compute.workload.SimWorkload
import org.opendc.simulator.failures.FailureDomain
import org.opendc.utils.flow.EventFlow
@@ -139,15 +140,31 @@ public class SimBareMetalDriver(
events
)
+ val delegate = (node.image as SimWorkloadImage).workload
// Wrap the workload to pass in a ComputeSimExecutionContext
val workload = object : SimWorkload {
- override suspend fun run(ctx: SimExecutionContext) {
- val wrappedCtx = object : ComputeSimExecutionContext, SimExecutionContext by ctx {
+ lateinit var wrappedCtx: ComputeSimExecutionContext
+
+ override fun onStart(ctx: SimExecutionContext) {
+ wrappedCtx = object : ComputeSimExecutionContext, SimExecutionContext by ctx {
override val server: Server
get() = nodeState.value.server!!
+
+ override fun toString(): String = "WrappedSimExecutionContext"
}
- (node.image as SimWorkloadImage).workload.run(wrappedCtx)
+
+ delegate.onStart(wrappedCtx)
+ }
+
+ override fun onStart(ctx: SimExecutionContext, cpu: Int): SimResourceCommand {
+ return delegate.onStart(wrappedCtx, cpu)
+ }
+
+ override fun onNext(ctx: SimExecutionContext, cpu: Int, remainingWork: Double): SimResourceCommand {
+ return delegate.onNext(wrappedCtx, cpu, remainingWork)
}
+
+ override fun toString(): String = "SimWorkloadWrapper(delegate=$delegate)"
}
job = coroutineScope.launch {
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimVirtDriver.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimVirtDriver.kt
index 249979a8..d7a8a8b2 100644
--- a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimVirtDriver.kt
+++ b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimVirtDriver.kt
@@ -36,25 +36,25 @@ import org.opendc.simulator.compute.*
import org.opendc.simulator.compute.interference.IMAGE_PERF_INTERFERENCE_MODEL
import org.opendc.simulator.compute.interference.PerformanceInterferenceModel
import org.opendc.simulator.compute.model.MemoryUnit
+import org.opendc.simulator.compute.workload.SimResourceCommand
import org.opendc.simulator.compute.workload.SimWorkload
import org.opendc.utils.flow.EventFlow
-import java.time.Clock
import java.util.*
/**
* A [VirtDriver] that is simulates virtual machines on a physical machine using [SimHypervisor].
*/
-public class SimVirtDriver(
- private val coroutineScope: CoroutineScope,
- clock: Clock,
- private val ctx: SimExecutionContext
-) : VirtDriver {
+public class SimVirtDriver(private val coroutineScope: CoroutineScope, hypervisor: SimHypervisorProvider) : VirtDriver, SimWorkload {
+ /**
+ * The execution context in which the [VirtDriver] runs.
+ */
+ private lateinit var ctx: ComputeSimExecutionContext
/**
* The server hosting this hypervisor.
*/
public val server: Server
- get() = (ctx as ComputeSimExecutionContext).server
+ get() = ctx.server
/**
* The [EventFlow] to emit the events.
@@ -66,35 +66,33 @@ public class SimVirtDriver(
/**
* Current total memory use of the images on this hypervisor.
*/
- private var availableMemory: Long = ctx.machine.memory.map { it.size }.sum()
+ private var availableMemory: Long = 0
/**
* The hypervisor to run multiple workloads.
*/
- private val hypervisor = SimFairSharedHypervisor(
- coroutineScope,
- clock,
+ private val hypervisor = hypervisor.create(
object : SimHypervisor.Listener {
override fun onSliceFinish(
hypervisor: SimHypervisor,
- requestedBurst: Long,
- grantedBurst: Long,
- overcommissionedBurst: Long,
- interferedBurst: Long,
+ requestedWork: Long,
+ grantedWork: Long,
+ overcommittedWork: Long,
+ interferedWork: Long,
cpuUsage: Double,
cpuDemand: Double
) {
eventFlow.emit(
HypervisorEvent.SliceFinished(
this@SimVirtDriver,
- requestedBurst,
- grantedBurst,
- overcommissionedBurst,
- interferedBurst,
+ requestedWork,
+ grantedWork,
+ overcommittedWork,
+ interferedWork,
cpuUsage,
cpuDemand,
vms.size,
- (ctx as ComputeSimExecutionContext).server
+ ctx.server
)
)
}
@@ -106,6 +104,14 @@ public class SimVirtDriver(
*/
private val vms = HashSet<VirtualMachine>()
+ override fun canFit(flavor: Flavor): Boolean {
+ val sufficientMemory = availableMemory > flavor.memorySize
+ val enoughCpus = ctx.machine.cpus.size >= flavor.cpuCount
+ val canFit = hypervisor.canFit(flavor.toMachineModel())
+
+ return sufficientMemory && enoughCpus && canFit
+ }
+
override suspend fun spawn(name: String, image: Image, flavor: Flavor): Server {
val requiredMemory = flavor.memorySize
if (availableMemory - requiredMemory < 0) {
@@ -126,19 +132,25 @@ public class SimVirtDriver(
)
availableMemory -= requiredMemory
- val originalCpu = ctx.machine.cpus[0]
- val processingNode = originalCpu.node.copy(coreCount = flavor.cpuCount)
- val processingUnits = (0 until flavor.cpuCount).map { originalCpu.copy(id = it, node = processingNode) }
- val memoryUnits = listOf(MemoryUnit("Generic", "Generic", 3200.0, flavor.memorySize))
-
- val machine = SimMachineModel(processingUnits, memoryUnits)
- val vm = VirtualMachine(server, events, hypervisor.createMachine(machine))
+ val vm = VirtualMachine(server, events, hypervisor.createMachine(flavor.toMachineModel()))
vms.add(vm)
vmStarted(vm)
eventFlow.emit(HypervisorEvent.VmsUpdated(this, vms.size, availableMemory))
return server
}
+ /**
+ * Convert flavor to machine model.
+ */
+ private fun Flavor.toMachineModel(): SimMachineModel {
+ val originalCpu = ctx.machine.cpus[0]
+ val processingNode = originalCpu.node.copy(coreCount = cpuCount)
+ val processingUnits = (0 until cpuCount).map { originalCpu.copy(id = it, node = processingNode) }
+ val memoryUnits = listOf(MemoryUnit("Generic", "Generic", 3200.0, memorySize))
+
+ return SimMachineModel(processingUnits, memoryUnits)
+ }
+
private fun vmStarted(vm: VirtualMachine) {
vms.forEach { it ->
vm.performanceInterferenceModel?.onStart(it.server.image.name)
@@ -154,18 +166,35 @@ public class SimVirtDriver(
/**
* A virtual machine instance that the driver manages.
*/
- private inner class VirtualMachine(server: Server, val events: EventFlow<ServerEvent>, machine: SimMachine) {
+ private inner class VirtualMachine(server: Server, val events: EventFlow<ServerEvent>, val machine: SimMachine) {
val performanceInterferenceModel: PerformanceInterferenceModel? = server.image.tags[IMAGE_PERF_INTERFERENCE_MODEL] as? PerformanceInterferenceModel?
val job = coroutineScope.launch {
+ val delegate = (server.image as SimWorkloadImage).workload
+ // Wrap the workload to pass in a ComputeSimExecutionContext
val workload = object : SimWorkload {
- override suspend fun run(ctx: SimExecutionContext) {
- val wrappedCtx = object : ComputeSimExecutionContext, SimExecutionContext by ctx {
+ lateinit var wrappedCtx: ComputeSimExecutionContext
+
+ override fun onStart(ctx: SimExecutionContext) {
+ wrappedCtx = object : ComputeSimExecutionContext, SimExecutionContext by ctx {
override val server: Server
- get() = this@VirtualMachine.server
+ get() = server
+
+ override fun toString(): String = "WrappedSimExecutionContext"
}
- (server.image as SimWorkloadImage).workload.run(wrappedCtx)
+
+ delegate.onStart(wrappedCtx)
+ }
+
+ override fun onStart(ctx: SimExecutionContext, cpu: Int): SimResourceCommand {
+ return delegate.onStart(wrappedCtx, cpu)
+ }
+
+ override fun onNext(ctx: SimExecutionContext, cpu: Int, remainingWork: Double): SimResourceCommand {
+ return delegate.onNext(wrappedCtx, cpu, remainingWork)
}
+
+ override fun toString(): String = "SimWorkloadWrapper(delegate=$delegate)"
}
delay(1) // TODO Introduce boot time
@@ -175,6 +204,8 @@ public class SimVirtDriver(
exit(null)
} catch (cause: Throwable) {
exit(cause)
+ } finally {
+ machine.close()
}
}
@@ -206,7 +237,17 @@ public class SimVirtDriver(
}
}
- public suspend fun run() {
- hypervisor.run(ctx)
+ override fun onStart(ctx: SimExecutionContext) {
+ this.ctx = ctx as ComputeSimExecutionContext
+ this.availableMemory = ctx.machine.memory.map { it.size }.sum()
+ this.hypervisor.onStart(ctx)
+ }
+
+ override fun onStart(ctx: SimExecutionContext, cpu: Int): SimResourceCommand {
+ return hypervisor.onStart(ctx, cpu)
+ }
+
+ override fun onNext(ctx: SimExecutionContext, cpu: Int, remainingWork: Double): SimResourceCommand {
+ return hypervisor.onNext(ctx, cpu, remainingWork)
}
}
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimVirtDriverWorkload.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimVirtDriverWorkload.kt
deleted file mode 100644
index 58b9408a..00000000
--- a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimVirtDriverWorkload.kt
+++ /dev/null
@@ -1,38 +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.compute.simulator
-
-import kotlinx.coroutines.coroutineScope
-import org.opendc.simulator.compute.SimExecutionContext
-import org.opendc.simulator.compute.workload.SimWorkload
-
-public class SimVirtDriverWorkload : SimWorkload {
- public lateinit var driver: SimVirtDriver
-
- override suspend fun run(ctx: SimExecutionContext) {
- coroutineScope {
- driver = SimVirtDriver(this, ctx.clock, ctx)
- driver.run()
- }
- }
-}
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimVirtProvisioningService.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimVirtProvisioningService.kt
index 17de3de7..defea888 100644
--- a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimVirtProvisioningService.kt
+++ b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimVirtProvisioningService.kt
@@ -40,7 +40,9 @@ import org.opendc.compute.core.virt.service.VirtProvisioningEvent
import org.opendc.compute.core.virt.service.VirtProvisioningService
import org.opendc.compute.core.virt.service.events.*
import org.opendc.compute.simulator.allocation.AllocationPolicy
+import org.opendc.simulator.compute.SimHypervisorProvider
import org.opendc.trace.core.EventTracer
+import org.opendc.utils.TimerScheduler
import org.opendc.utils.flow.EventFlow
import java.time.Clock
import java.util.*
@@ -55,7 +57,8 @@ public class SimVirtProvisioningService(
private val provisioningService: ProvisioningService,
public val allocationPolicy: AllocationPolicy,
private val tracer: EventTracer,
- private val schedulingQuantum: Long = 300000 // 5 minutes in milliseconds
+ private val hypervisor: SimHypervisorProvider,
+ private val schedulingQuantum: Long = 300000, // 5 minutes in milliseconds
) : VirtProvisioningService {
/**
* The logger instance to use.
@@ -75,7 +78,7 @@ public class SimVirtProvisioningService(
/**
* The incoming images to be processed by the provisioner.
*/
- private val incomingImages: MutableSet<ImageView> = mutableSetOf()
+ private val incomingImages: Deque<ImageView> = ArrayDeque()
/**
* The active images in the system.
@@ -103,11 +106,16 @@ public class SimVirtProvisioningService(
override val events: Flow<VirtProvisioningEvent> = eventFlow
+ /**
+ * The [TimerScheduler] to use for scheduling the scheduler cycles.
+ */
+ private var scheduler: TimerScheduler<Unit> = TimerScheduler(coroutineScope, clock)
+
init {
coroutineScope.launch {
val provisionedNodes = provisioningService.nodes()
provisionedNodes.forEach { node ->
- val workload = SimVirtDriverWorkload()
+ val workload = SimVirtDriver(coroutineScope, hypervisor)
val hypervisorImage = SimWorkloadImage(UUID.randomUUID(), "vmm", emptyMap(), workload)
launch {
var init = false
@@ -125,7 +133,7 @@ public class SimVirtProvisioningService(
}.launchIn(this)
delay(1)
- onHypervisorAvailable(server, workload.driver)
+ onHypervisorAvailable(server, workload)
}
}
}
@@ -169,10 +177,9 @@ public class SimVirtProvisioningService(
provisionedNodes.forEach { node -> provisioningService.stop(node) }
}
- private var call: Job? = null
-
private fun requestCycle() {
- if (call != null) {
+ // Bail out in case we have already requested a new cycle.
+ if (scheduler.isTimerActive(Unit)) {
return
}
@@ -181,22 +188,20 @@ public class SimVirtProvisioningService(
// We calculate here the delay until the next scheduling slot.
val delay = schedulingQuantum - (clock.millis() % schedulingQuantum)
- val call = coroutineScope.launch {
- delay(delay)
- this@SimVirtProvisioningService.call = null
- schedule()
+ scheduler.startSingleTimer(Unit, delay) {
+ coroutineScope.launch { schedule() }
}
- this.call = call
}
private suspend fun schedule() {
- val imagesToBeScheduled = incomingImages.toSet()
-
- for (imageInstance in imagesToBeScheduled) {
+ while (incomingImages.isNotEmpty()) {
+ val imageInstance = incomingImages.peekFirst()
val requiredMemory = imageInstance.flavor.memorySize
val selectedHv = allocationLogic.select(availableHypervisors, imageInstance)
- if (selectedHv == null) {
+ if (selectedHv == null || !selectedHv.driver.canFit(imageInstance.flavor)) {
+ logger.trace { "Image ${imageInstance.image} selected for scheduling but no capacity available for it." }
+
if (requiredMemory > maxMemory || imageInstance.flavor.cpuCount > maxCores) {
tracer.commit(VmSubmissionInvalidEvent(imageInstance.name))
@@ -208,12 +213,13 @@ public class SimVirtProvisioningService(
submittedVms,
runningVms,
finishedVms,
- queuedVms,
+ --queuedVms,
++unscheduledVms
)
)
- incomingImages -= imageInstance
+ // Remove the incoming image
+ incomingImages.poll()
logger.warn("Failed to spawn ${imageInstance.image}: does not fit [${clock.millis()}]")
continue
@@ -224,7 +230,7 @@ public class SimVirtProvisioningService(
try {
logger.info { "[${clock.millis()}] Spawning ${imageInstance.image} on ${selectedHv.server.uid} ${selectedHv.server.name} ${selectedHv.server.flavor}" }
- incomingImages -= imageInstance
+ incomingImages.poll()
// Speculatively update the hypervisor view information to prevent other images in the queue from
// deciding on stale values.
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimBareMetalDriverTest.kt b/simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimBareMetalDriverTest.kt
index 0f1bd444..fb8a5f47 100644
--- a/simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimBareMetalDriverTest.kt
+++ b/simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimBareMetalDriverTest.kt
@@ -64,7 +64,7 @@ internal class SimBareMetalDriverTest {
testScope.launch {
val driver = SimBareMetalDriver(this, clock, UUID.randomUUID(), "test", emptyMap(), machineModel)
- val image = SimWorkloadImage(UUID.randomUUID(), "<unnamed>", emptyMap(), SimFlopsWorkload(4_000, 2, utilization = 1.0))
+ val image = SimWorkloadImage(UUID.randomUUID(), "<unnamed>", emptyMap(), SimFlopsWorkload(4_000, utilization = 1.0))
// Batch driver commands
withContext(coroutineContext) {
@@ -84,6 +84,6 @@ internal class SimBareMetalDriverTest {
testScope.advanceUntilIdle()
assertEquals(ServerState.SHUTOFF, finalState)
- assertEquals(1001, finalTime)
+ assertEquals(501, finalTime)
}
}
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimProvisioningServiceTest.kt b/simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimProvisioningServiceTest.kt
index def78ce7..a33a4e5f 100644
--- a/simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimProvisioningServiceTest.kt
+++ b/simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimProvisioningServiceTest.kt
@@ -64,7 +64,7 @@ internal class SimProvisioningServiceTest {
val clock = DelayControllerClockAdapter(testScope)
testScope.launch {
- val image = SimWorkloadImage(UUID.randomUUID(), "<unnamed>", emptyMap(), SimFlopsWorkload(1000, 2))
+ val image = SimWorkloadImage(UUID.randomUUID(), "<unnamed>", emptyMap(), SimFlopsWorkload(1000))
val driver = SimBareMetalDriver(this, clock, UUID.randomUUID(), "test", emptyMap(), machineModel)
val provisioner = SimpleProvisioningService()
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimVirtDriverTest.kt b/simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimVirtDriverTest.kt
index 394e87c6..1831eae0 100644
--- a/simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimVirtDriverTest.kt
+++ b/simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimVirtDriverTest.kt
@@ -34,6 +34,7 @@ import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertAll
import org.opendc.compute.core.Flavor
import org.opendc.compute.core.virt.HypervisorEvent
+import org.opendc.simulator.compute.SimFairShareHypervisorProvider
import org.opendc.simulator.compute.SimMachineModel
import org.opendc.simulator.compute.model.MemoryUnit
import org.opendc.simulator.compute.model.ProcessingNode
@@ -66,17 +67,17 @@ internal class SimVirtDriverTest {
}
/**
- * Test overcommissioning of a hypervisor.
+ * Test overcommitting of resources by the hypervisor.
*/
@Test
- fun overcommission() {
- var requestedBurst = 0L
- var grantedBurst = 0L
- var overcommissionedBurst = 0L
+ fun testOvercommitted() {
+ var requestedWork = 0L
+ var grantedWork = 0L
+ var overcommittedWork = 0L
scope.launch {
- val virtDriverWorkload = SimVirtDriverWorkload()
- val vmm = SimWorkloadImage(UUID.randomUUID(), "vmm", emptyMap(), virtDriverWorkload)
+ val virtDriver = SimVirtDriver(this, SimFairShareHypervisorProvider())
+ val vmm = SimWorkloadImage(UUID.randomUUID(), "vmm", emptyMap(), virtDriver)
val duration = 5 * 60L
val vmImageA = SimWorkloadImage(
UUID.randomUUID(),
@@ -84,10 +85,10 @@ internal class SimVirtDriverTest {
emptyMap(),
SimTraceWorkload(
sequenceOf(
- SimTraceWorkload.Fragment(0, 28L * duration, duration * 1000, 28.0, 2),
- SimTraceWorkload.Fragment(0, 3500L * duration, duration * 1000, 3500.0, 2),
- SimTraceWorkload.Fragment(0, 0, duration * 1000, 0.0, 2),
- SimTraceWorkload.Fragment(0, 183L * duration, duration * 1000, 183.0, 2)
+ SimTraceWorkload.Fragment(duration * 1000, 28.0, 2),
+ SimTraceWorkload.Fragment(duration * 1000, 3500.0, 2),
+ SimTraceWorkload.Fragment(duration * 1000, 0.0, 2),
+ SimTraceWorkload.Fragment(duration * 1000, 183.0, 2)
),
)
)
@@ -97,10 +98,10 @@ internal class SimVirtDriverTest {
emptyMap(),
SimTraceWorkload(
sequenceOf(
- SimTraceWorkload.Fragment(0, 28L * duration, duration * 1000, 28.0, 2),
- SimTraceWorkload.Fragment(0, 3100L * duration, duration * 1000, 3100.0, 2),
- SimTraceWorkload.Fragment(0, 0, duration * 1000, 0.0, 2),
- SimTraceWorkload.Fragment(0, 73L * duration, duration * 1000, 73.0, 2)
+ SimTraceWorkload.Fragment(duration * 1000, 28.0, 2),
+ SimTraceWorkload.Fragment(duration * 1000, 3100.0, 2),
+ SimTraceWorkload.Fragment(duration * 1000, 0.0, 2),
+ SimTraceWorkload.Fragment(duration * 1000, 73.0, 2)
)
),
)
@@ -115,31 +116,30 @@ internal class SimVirtDriverTest {
delay(5)
val flavor = Flavor(2, 0)
- val vmDriver = virtDriverWorkload.driver
- vmDriver.events
+ virtDriver.events
.onEach { event ->
when (event) {
is HypervisorEvent.SliceFinished -> {
- requestedBurst += event.requestedBurst
- grantedBurst += event.grantedBurst
- overcommissionedBurst += event.overcommissionedBurst
+ requestedWork += event.requestedBurst
+ grantedWork += event.grantedBurst
+ overcommittedWork += event.overcommissionedBurst
}
}
}
.launchIn(this)
- vmDriver.spawn("a", vmImageA, flavor)
- vmDriver.spawn("b", vmImageB, flavor)
+ virtDriver.spawn("a", vmImageA, flavor)
+ virtDriver.spawn("b", vmImageB, flavor)
}
scope.advanceUntilIdle()
assertAll(
{ assertEquals(emptyList<Throwable>(), scope.uncaughtExceptions, "No errors") },
- { assertEquals(2082000, requestedBurst, "Requested Burst does not match") },
- { assertEquals(2013600, grantedBurst, "Granted Burst does not match") },
- { assertEquals(60000, overcommissionedBurst, "Overcommissioned Burst does not match") },
- { assertEquals(1200007, scope.currentTime) }
+ { assertEquals(4197600, requestedWork, "Requested work does not match") },
+ { assertEquals(3057600, grantedWork, "Granted work does not match") },
+ { assertEquals(1140000, overcommittedWork, "Overcommitted work does not match") },
+ { assertEquals(1200006, scope.currentTime) }
)
}
}