summaryrefslogtreecommitdiff
path: root/opendc-compute/opendc-compute-simulator
diff options
context:
space:
mode:
Diffstat (limited to 'opendc-compute/opendc-compute-simulator')
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt29
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt1
-rw-r--r--opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt37
3 files changed, 32 insertions, 35 deletions
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt
index ee607066..b3e56f38 100644
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt
@@ -22,7 +22,6 @@
package org.opendc.compute.simulator
-import kotlinx.coroutines.yield
import org.opendc.compute.api.Flavor
import org.opendc.compute.api.Server
import org.opendc.compute.api.ServerState
@@ -132,8 +131,8 @@ public class SimHost(
return sufficientMemory && enoughCpus && canFit
}
- override suspend fun spawn(server: Server, start: Boolean) {
- val guest = guests.computeIfAbsent(server) { key ->
+ override fun spawn(server: Server) {
+ guests.computeIfAbsent(server) { key ->
require(canFit(key)) { "Server does not fit" }
val machine = hypervisor.newMachine(key.flavor.toMachineModel())
@@ -150,27 +149,23 @@ public class SimHost(
_guests.add(newGuest)
newGuest
}
-
- if (start) {
- guest.start()
- }
}
override fun contains(server: Server): Boolean {
return server in guests
}
- override suspend fun start(server: Server) {
+ override fun start(server: Server) {
val guest = requireNotNull(guests[server]) { "Unknown server ${server.uid} at host $uid" }
guest.start()
}
- override suspend fun stop(server: Server) {
+ override fun stop(server: Server) {
val guest = requireNotNull(guests[server]) { "Unknown server ${server.uid} at host $uid" }
guest.stop()
}
- override suspend fun delete(server: Server) {
+ override fun delete(server: Server) {
val guest = guests[server] ?: return
guest.delete()
}
@@ -266,17 +261,10 @@ public class SimHost(
}
}
- public suspend fun recover() {
+ public fun recover() {
updateUptime()
launch()
-
- // Wait for the hypervisor to launch before recovering the guests
- yield()
-
- for (guest in _guests) {
- guest.recover()
- }
}
/**
@@ -298,6 +286,11 @@ public class SimHost(
_bootTime = clock.instant()
_state = HostState.UP
hypervisor.onStart(ctx)
+
+ // Recover the guests that were running on the hypervisor.
+ for (guest in _guests) {
+ guest.recover()
+ }
} catch (cause: Throwable) {
_state = HostState.ERROR
throw cause
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt
index 6d3a5bc7..c12e6fad 100644
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt
@@ -60,6 +60,7 @@ internal class Guest(
* a server.
*/
var state: ServerState = ServerState.TERMINATED
+ private set
/**
* Start the guest.
diff --git a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt
index 27151422..fc581d3e 100644
--- a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt
+++ b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt
@@ -24,7 +24,6 @@ package org.opendc.compute.simulator
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
-import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.BeforeEach
@@ -107,20 +106,19 @@ internal class SimHostTest {
val flavor = MockFlavor(2, 0)
- coroutineScope {
- launch { host.spawn(MockServer(UUID.randomUUID(), "a", flavor, vmImage)) }
+ suspendCancellableCoroutine { cont ->
+ host.addListener(object : HostListener {
+ private var finished = 0
- suspendCancellableCoroutine { cont ->
- host.addListener(object : HostListener {
- private var finished = 0
-
- override fun onStateChanged(host: Host, server: Server, newState: ServerState) {
- if (newState == ServerState.TERMINATED && ++finished == 1) {
- cont.resume(Unit)
- }
+ override fun onStateChanged(host: Host, server: Server, newState: ServerState) {
+ if (newState == ServerState.TERMINATED && ++finished == 1) {
+ cont.resume(Unit)
}
- })
- }
+ }
+ })
+ val server = MockServer(UUID.randomUUID(), "a", flavor, vmImage)
+ host.spawn(server)
+ host.start(server)
}
// Ensure last cycle is collected
@@ -190,9 +188,6 @@ internal class SimHostTest {
val flavor = MockFlavor(2, 0)
coroutineScope {
- launch { host.spawn(MockServer(UUID.randomUUID(), "a", flavor, vmImageA)) }
- launch { host.spawn(MockServer(UUID.randomUUID(), "b", flavor, vmImageB)) }
-
suspendCancellableCoroutine { cont ->
host.addListener(object : HostListener {
private var finished = 0
@@ -203,6 +198,13 @@ internal class SimHostTest {
}
}
})
+ val serverA = MockServer(UUID.randomUUID(), "a", flavor, vmImageA)
+ host.spawn(serverA)
+ val serverB = MockServer(UUID.randomUUID(), "b", flavor, vmImageB)
+ host.spawn(serverB)
+
+ host.start(serverA)
+ host.start(serverB)
}
}
@@ -259,12 +261,13 @@ internal class SimHostTest {
coroutineScope {
host.spawn(server)
+ host.start(server)
delay(5000L)
host.fail()
delay(duration * 1000)
host.recover()
- suspendCancellableCoroutine<Unit> { cont ->
+ suspendCancellableCoroutine { cont ->
host.addListener(object : HostListener {
override fun onStateChanged(host: Host, server: Server, newState: ServerState) {
if (newState == ServerState.TERMINATED) {