summaryrefslogtreecommitdiff
path: root/opendc-compute/opendc-compute-service/src
diff options
context:
space:
mode:
authorDante Niewenhuis <d.niewenhuis@hotmail.com>2024-03-05 13:23:57 +0100
committerGitHub <noreply@github.com>2024-03-05 13:23:57 +0100
commit5864cbcbfe2eb8c36ca05c3a39c7e5916aeecaec (patch)
tree5b2773b8dc21c2e1b526fb70f829c376dd80532a /opendc-compute/opendc-compute-service/src
parentd28002a3c151d198298574312f32f1cb43f3a660 (diff)
Updated package versions, updated web server tests. (#207)
* Updated all package versions including kotlin. Updated all web-server tests to run. * Changed the java version of the tests. OpenDC now only supports java 19. * small update * test update * new update * updated docker version to 19 * updated docker version to 19
Diffstat (limited to 'opendc-compute/opendc-compute-service/src')
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ComputeSchedulers.kt91
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt51
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ReplayScheduler.kt5
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeFilter.kt5
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/DifferentHostFilter.kt5
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/HostFilter.kt5
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/InstanceCountFilter.kt5
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/RamFilter.kt5
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/SameHostFilter.kt5
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/VCpuCapacityFilter.kt5
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/VCpuFilter.kt5
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/CoreRamWeigher.kt5
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/HostWeigher.kt12
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/InstanceCountWeigher.kt5
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/RamWeigher.kt5
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/VCpuCapacityWeigher.kt6
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/VCpuWeigher.kt6
-rw-r--r--opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt471
-rw-r--r--opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ServiceServerTest.kt290
-rw-r--r--opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/scheduler/FilterSchedulerTest.kt165
20 files changed, 627 insertions, 525 deletions
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ComputeSchedulers.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ComputeSchedulers.kt
index 2f071c13..18947146 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ComputeSchedulers.kt
+++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ComputeSchedulers.kt
@@ -37,48 +37,61 @@ import java.util.random.RandomGenerator
/**
* Create a [ComputeScheduler] for the experiment.
*/
-public fun createComputeScheduler(name: String, seeder: RandomGenerator, placements: Map<String, String> = emptyMap()): ComputeScheduler {
+public fun createComputeScheduler(
+ name: String,
+ seeder: RandomGenerator,
+ placements: Map<String, String> = emptyMap(),
+): ComputeScheduler {
val cpuAllocationRatio = 16.0
val ramAllocationRatio = 1.5
return when (name) {
- "mem" -> FilterScheduler(
- filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)),
- weighers = listOf(RamWeigher(multiplier = 1.0))
- )
- "mem-inv" -> FilterScheduler(
- filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)),
- weighers = listOf(RamWeigher(multiplier = -1.0))
- )
- "core-mem" -> FilterScheduler(
- filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)),
- weighers = listOf(CoreRamWeigher(multiplier = 1.0))
- )
- "core-mem-inv" -> FilterScheduler(
- filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)),
- weighers = listOf(CoreRamWeigher(multiplier = -1.0))
- )
- "active-servers" -> FilterScheduler(
- filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)),
- weighers = listOf(InstanceCountWeigher(multiplier = -1.0))
- )
- "active-servers-inv" -> FilterScheduler(
- filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)),
- weighers = listOf(InstanceCountWeigher(multiplier = 1.0))
- )
- "provisioned-cores" -> FilterScheduler(
- filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)),
- weighers = listOf(VCpuWeigher(cpuAllocationRatio, multiplier = 1.0))
- )
- "provisioned-cores-inv" -> FilterScheduler(
- filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)),
- weighers = listOf(VCpuWeigher(cpuAllocationRatio, multiplier = -1.0))
- )
- "random" -> FilterScheduler(
- filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)),
- weighers = emptyList(),
- subsetSize = Int.MAX_VALUE,
- random = SplittableRandom(seeder.nextLong())
- )
+ "mem" ->
+ FilterScheduler(
+ filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)),
+ weighers = listOf(RamWeigher(multiplier = 1.0)),
+ )
+ "mem-inv" ->
+ FilterScheduler(
+ filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)),
+ weighers = listOf(RamWeigher(multiplier = -1.0)),
+ )
+ "core-mem" ->
+ FilterScheduler(
+ filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)),
+ weighers = listOf(CoreRamWeigher(multiplier = 1.0)),
+ )
+ "core-mem-inv" ->
+ FilterScheduler(
+ filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)),
+ weighers = listOf(CoreRamWeigher(multiplier = -1.0)),
+ )
+ "active-servers" ->
+ FilterScheduler(
+ filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)),
+ weighers = listOf(InstanceCountWeigher(multiplier = -1.0)),
+ )
+ "active-servers-inv" ->
+ FilterScheduler(
+ filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)),
+ weighers = listOf(InstanceCountWeigher(multiplier = 1.0)),
+ )
+ "provisioned-cores" ->
+ FilterScheduler(
+ filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)),
+ weighers = listOf(VCpuWeigher(cpuAllocationRatio, multiplier = 1.0)),
+ )
+ "provisioned-cores-inv" ->
+ FilterScheduler(
+ filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)),
+ weighers = listOf(VCpuWeigher(cpuAllocationRatio, multiplier = -1.0)),
+ )
+ "random" ->
+ FilterScheduler(
+ filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)),
+ weighers = emptyList(),
+ subsetSize = Int.MAX_VALUE,
+ random = SplittableRandom(seeder.nextLong()),
+ )
"replay" -> ReplayScheduler(placements)
else -> throw IllegalArgumentException("Unknown policy $name")
}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt
index 18a319e9..cdcd1af0 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt
+++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt
@@ -46,7 +46,7 @@ public class FilterScheduler(
private val filters: List<HostFilter>,
private val weighers: List<HostWeigher>,
private val subsetSize: Int = 1,
- private val random: RandomGenerator = SplittableRandom(0)
+ private val random: RandomGenerator = SplittableRandom(0),
) : ComputeScheduler {
/**
* The pool of hosts available to the scheduler.
@@ -69,36 +69,37 @@ public class FilterScheduler(
val hosts = hosts
val filteredHosts = hosts.filter { host -> filters.all { filter -> filter.test(host, server) } }
- val subset = if (weighers.isNotEmpty()) {
- val results = weighers.map { it.getWeights(filteredHosts, server) }
- val weights = DoubleArray(filteredHosts.size)
+ val subset =
+ if (weighers.isNotEmpty()) {
+ val results = weighers.map { it.getWeights(filteredHosts, server) }
+ val weights = DoubleArray(filteredHosts.size)
- for (result in results) {
- val min = result.min
- val range = (result.max - min)
+ for (result in results) {
+ val min = result.min
+ val range = (result.max - min)
- // Skip result if all weights are the same
- if (range == 0.0) {
- continue
- }
+ // Skip result if all weights are the same
+ if (range == 0.0) {
+ continue
+ }
- val multiplier = result.multiplier
- val factor = multiplier / range
+ val multiplier = result.multiplier
+ val factor = multiplier / range
- for ((i, weight) in result.weights.withIndex()) {
- weights[i] += factor * (weight - min)
+ for ((i, weight) in result.weights.withIndex()) {
+ weights[i] += factor * (weight - min)
+ }
}
- }
- weights.indices
- .asSequence()
- .sortedByDescending { weights[it] }
- .map { filteredHosts[it] }
- .take(subsetSize)
- .toList()
- } else {
- filteredHosts
- }
+ weights.indices
+ .asSequence()
+ .sortedByDescending { weights[it] }
+ .map { filteredHosts[it] }
+ .take(subsetSize)
+ .toList()
+ } else {
+ filteredHosts
+ }
return when (val maxSize = min(subsetSize, subset.size)) {
0 -> null
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ReplayScheduler.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ReplayScheduler.kt
index 4339b3de..a6703c89 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ReplayScheduler.kt
+++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ReplayScheduler.kt
@@ -49,8 +49,9 @@ public class ReplayScheduler(private val vmPlacements: Map<String, String>) : Co
}
override fun select(server: Server): HostView? {
- val clusterName = vmPlacements[server.name]
- ?: throw IllegalStateException("Could not find placement data in VM placement file for VM ${server.name}")
+ val clusterName =
+ vmPlacements[server.name]
+ ?: throw IllegalStateException("Could not find placement data in VM placement file for VM ${server.name}")
val machinesInCluster = hosts.filter { it.host.name.contains(clusterName) }
if (machinesInCluster.isEmpty()) {
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeFilter.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeFilter.kt
index b562f838..23590c13 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeFilter.kt
+++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeFilter.kt
@@ -30,7 +30,10 @@ import org.opendc.compute.service.driver.HostState
* A [HostFilter] that filters on active hosts.
*/
public class ComputeFilter : HostFilter {
- override fun test(host: HostView, server: Server): Boolean {
+ override fun test(
+ host: HostView,
+ server: Server,
+ ): Boolean {
return host.host.state == HostState.UP
}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/DifferentHostFilter.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/DifferentHostFilter.kt
index 4a9f41c5..df67a19f 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/DifferentHostFilter.kt
+++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/DifferentHostFilter.kt
@@ -30,7 +30,10 @@ import java.util.UUID
* A [HostFilter] that ensures an instance is scheduled on a different host from a set of instances.
*/
public class DifferentHostFilter : HostFilter {
- override fun test(host: HostView, server: Server): Boolean {
+ override fun test(
+ host: HostView,
+ server: Server,
+ ): Boolean {
@Suppress("UNCHECKED_CAST")
val affinityUUIDs = server.meta["scheduler_hint:different_host"] as? Set<UUID> ?: return true
return host.host.instances.none { it.uid in affinityUUIDs }
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/HostFilter.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/HostFilter.kt
index 78010fee..902c760e 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/HostFilter.kt
+++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/HostFilter.kt
@@ -34,5 +34,8 @@ public fun interface HostFilter {
* Test whether the specified [host] should be included in the selection
* for scheduling the specified [server].
*/
- public fun test(host: HostView, server: Server): Boolean
+ public fun test(
+ host: HostView,
+ server: Server,
+ ): Boolean
}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/InstanceCountFilter.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/InstanceCountFilter.kt
index 5aa38a88..d9348802 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/InstanceCountFilter.kt
+++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/InstanceCountFilter.kt
@@ -31,7 +31,10 @@ import org.opendc.compute.service.HostView
* @param limit The maximum number of instances on the host.
*/
public class InstanceCountFilter(private val limit: Int) : HostFilter {
- override fun test(host: HostView, server: Server): Boolean {
+ override fun test(
+ host: HostView,
+ server: Server,
+ ): Boolean {
return host.instanceCount < limit
}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/RamFilter.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/RamFilter.kt
index 275e8f1c..4792a7a0 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/RamFilter.kt
+++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/RamFilter.kt
@@ -31,7 +31,10 @@ import org.opendc.compute.service.HostView
* @param allocationRatio Virtual RAM to physical RAM allocation ratio.
*/
public class RamFilter(private val allocationRatio: Double) : HostFilter {
- override fun test(host: HostView, server: Server): Boolean {
+ override fun test(
+ host: HostView,
+ server: Server,
+ ): Boolean {
val requested = server.flavor.memorySize
val available = host.availableMemory
val total = host.host.model.memoryCapacity
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/SameHostFilter.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/SameHostFilter.kt
index c3753866..4c31c66a 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/SameHostFilter.kt
+++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/SameHostFilter.kt
@@ -30,7 +30,10 @@ import java.util.UUID
* A [HostFilter] that ensures an instance is scheduled on the same host as all other instances in a set of instances.
*/
public class SameHostFilter : HostFilter {
- override fun test(host: HostView, server: Server): Boolean {
+ override fun test(
+ host: HostView,
+ server: Server,
+ ): Boolean {
@Suppress("UNCHECKED_CAST")
val affinityUUIDs = server.meta["scheduler_hint:same_host"] as? Set<UUID> ?: return true
return host.host.instances.any { it.uid in affinityUUIDs }
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/VCpuCapacityFilter.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/VCpuCapacityFilter.kt
index d4dff76b..e3397e50 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/VCpuCapacityFilter.kt
+++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/VCpuCapacityFilter.kt
@@ -30,7 +30,10 @@ import org.opendc.compute.service.HostView
* capacity on the host.
*/
public class VCpuCapacityFilter : HostFilter {
- override fun test(host: HostView, server: Server): Boolean {
+ override fun test(
+ host: HostView,
+ server: Server,
+ ): Boolean {
val requiredCapacity = server.flavor.meta["cpu-capacity"] as? Double
val hostModel = host.host.model
val availableCapacity = hostModel.cpuCapacity / hostModel.cpuCount
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/VCpuFilter.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/VCpuFilter.kt
index 448a6189..5d02873f 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/VCpuFilter.kt
+++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/VCpuFilter.kt
@@ -31,7 +31,10 @@ import org.opendc.compute.service.HostView
* @param allocationRatio Virtual CPU to physical CPU allocation ratio.
*/
public class VCpuFilter(private val allocationRatio: Double) : HostFilter {
- override fun test(host: HostView, server: Server): Boolean {
+ override fun test(
+ host: HostView,
+ server: Server,
+ ): Boolean {
val requested = server.flavor.cpuCount
val total = host.host.model.cpuCount
val limit = total * allocationRatio
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/CoreRamWeigher.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/CoreRamWeigher.kt
index f79d6d88..d6aafbc7 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/CoreRamWeigher.kt
+++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/CoreRamWeigher.kt
@@ -33,7 +33,10 @@ import org.opendc.compute.service.HostView
* memory.
*/
public class CoreRamWeigher(override val multiplier: Double = 1.0) : HostWeigher {
- override fun getWeight(host: HostView, server: Server): Double {
+ override fun getWeight(
+ host: HostView,
+ server: Server,
+ ): Double {
return host.availableMemory.toDouble() / host.host.model.cpuCount
}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/HostWeigher.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/HostWeigher.kt
index 01799122..825cfff9 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/HostWeigher.kt
+++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/HostWeigher.kt
@@ -38,12 +38,18 @@ public interface HostWeigher {
/**
* Obtain the weight of the specified [host] when scheduling the specified [server].
*/
- public fun getWeight(host: HostView, server: Server): Double
+ public fun getWeight(
+ host: HostView,
+ server: Server,
+ ): Double
/**
* Obtain the weights for [hosts] when scheduling the specified [server].
*/
- public fun getWeights(hosts: List<HostView>, server: Server): Result {
+ public fun getWeights(
+ hosts: List<HostView>,
+ server: Server,
+ ): Result {
val weights = DoubleArray(hosts.size)
var min = Double.MAX_VALUE
var max = Double.MIN_VALUE
@@ -70,6 +76,6 @@ public interface HostWeigher {
public val weights: DoubleArray,
public val min: Double,
public val max: Double,
- public val multiplier: Double
+ public val multiplier: Double,
)
}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/InstanceCountWeigher.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/InstanceCountWeigher.kt
index bfb583a2..9e0a9517 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/InstanceCountWeigher.kt
+++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/InstanceCountWeigher.kt
@@ -29,7 +29,10 @@ import org.opendc.compute.service.HostView
* A [HostWeigher] that weighs the hosts based on the number of instances on the host.
*/
public class InstanceCountWeigher(override val multiplier: Double = 1.0) : HostWeigher {
- override fun getWeight(host: HostView, server: Server): Double {
+ override fun getWeight(
+ host: HostView,
+ server: Server,
+ ): Double {
return host.instanceCount.toDouble()
}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/RamWeigher.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/RamWeigher.kt
index bb837fbe..fca2e893 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/RamWeigher.kt
+++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/RamWeigher.kt
@@ -32,7 +32,10 @@ import org.opendc.compute.service.HostView
* available memory, and a negative number will result in the scheduler preferring hosts with less memory.
*/
public class RamWeigher(override val multiplier: Double = 1.0) : HostWeigher {
- override fun getWeight(host: HostView, server: Server): Double {
+ override fun getWeight(
+ host: HostView,
+ server: Server,
+ ): Double {
return host.availableMemory.toDouble()
}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/VCpuCapacityWeigher.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/VCpuCapacityWeigher.kt
index f15f60c9..2912ce49 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/VCpuCapacityWeigher.kt
+++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/VCpuCapacityWeigher.kt
@@ -29,8 +29,10 @@ import org.opendc.compute.service.HostView
* A [HostWeigher] that weighs the hosts based on the difference required vCPU capacity and the available CPU capacity.
*/
public class VCpuCapacityWeigher(override val multiplier: Double = 1.0) : HostWeigher {
-
- override fun getWeight(host: HostView, server: Server): Double {
+ override fun getWeight(
+ host: HostView,
+ server: Server,
+ ): Double {
val model = host.host.model
val requiredCapacity = server.flavor.meta["cpu-capacity"] as? Double ?: 0.0
return model.cpuCapacity / model.cpuCount - requiredCapacity / server.flavor.cpuCount
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/VCpuWeigher.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/VCpuWeigher.kt
index 169ad8cb..be93458f 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/VCpuWeigher.kt
+++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/VCpuWeigher.kt
@@ -31,12 +31,14 @@ import org.opendc.compute.service.HostView
* @param allocationRatio Virtual CPU to physical CPU allocation ratio.
*/
public class VCpuWeigher(private val allocationRatio: Double, override val multiplier: Double = 1.0) : HostWeigher {
-
init {
require(allocationRatio > 0.0) { "Allocation ratio must be greater than zero" }
}
- override fun getWeight(host: HostView, server: Server): Double {
+ override fun getWeight(
+ host: HostView,
+ server: Server,
+ ): Double {
return host.host.model.cpuCount * allocationRatio - host.provisionedCores
}
diff --git a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt b/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt
index 4dc1cfa8..52caea0c 100644
--- a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt
+++ b/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt
@@ -63,309 +63,324 @@ internal class ComputeServiceTest {
@BeforeEach
fun setUp() {
scope = SimulationCoroutineScope()
- val computeScheduler = FilterScheduler(
- filters = listOf(ComputeFilter(), VCpuFilter(allocationRatio = 1.0), RamFilter(allocationRatio = 1.0)),
- weighers = listOf(RamWeigher())
- )
+ val computeScheduler =
+ FilterScheduler(
+ filters = listOf(ComputeFilter(), VCpuFilter(allocationRatio = 1.0), RamFilter(allocationRatio = 1.0)),
+ weighers = listOf(RamWeigher()),
+ )
service = ComputeService(scope.dispatcher, computeScheduler, Duration.ofMinutes(5))
}
@Test
- fun testClientClose() = scope.runSimulation {
- val client = service.newClient()
+ fun testClientClose() =
+ scope.runSimulation {
+ val client = service.newClient()
- assertEquals(emptyList<Flavor>(), client.queryFlavors())
- assertEquals(emptyList<Image>(), client.queryImages())
- assertEquals(emptyList<Server>(), client.queryServers())
+ assertEquals(emptyList<Flavor>(), client.queryFlavors())
+ assertEquals(emptyList<Image>(), client.queryImages())
+ assertEquals(emptyList<Server>(), client.queryServers())
- client.close()
+ client.close()
- assertThrows<IllegalStateException> { client.queryFlavors() }
- assertThrows<IllegalStateException> { client.queryImages() }
- assertThrows<IllegalStateException> { client.queryServers() }
+ assertThrows<IllegalStateException> { client.queryFlavors() }
+ assertThrows<IllegalStateException> { client.queryImages() }
+ assertThrows<IllegalStateException> { client.queryServers() }
- assertThrows<IllegalStateException> { client.findFlavor(UUID.randomUUID()) }
- assertThrows<IllegalStateException> { client.findImage(UUID.randomUUID()) }
- assertThrows<IllegalStateException> { client.findServer(UUID.randomUUID()) }
+ assertThrows<IllegalStateException> { client.findFlavor(UUID.randomUUID()) }
+ assertThrows<IllegalStateException> { client.findImage(UUID.randomUUID()) }
+ assertThrows<IllegalStateException> { client.findServer(UUID.randomUUID()) }
- assertThrows<IllegalStateException> { client.newFlavor("test", 1, 2) }
- assertThrows<IllegalStateException> { client.newImage("test") }
- assertThrows<IllegalStateException> { client.newServer("test", mockk(), mockk()) }
- }
+ assertThrows<IllegalStateException> { client.newFlavor("test", 1, 2) }
+ assertThrows<IllegalStateException> { client.newImage("test") }
+ assertThrows<IllegalStateException> { client.newServer("test", mockk(), mockk()) }
+ }
@Test
- fun testClientCreate() = scope.runSimulation {
- val client = service.newClient()
-
- val flavor = client.newFlavor("test", 1, 1024)
- assertEquals(listOf(flavor), client.queryFlavors())
- assertEquals(flavor, client.findFlavor(flavor.uid))
- val image = client.newImage("test")
- assertEquals(listOf(image), client.queryImages())
- assertEquals(image, client.findImage(image.uid))
- val server = client.newServer("test", image, flavor, start = false)
- assertEquals(listOf(server), client.queryServers())
- assertEquals(server, client.findServer(server.uid))
-
- server.delete()
- assertNull(client.findServer(server.uid))
-
- image.delete()
- assertNull(client.findImage(image.uid))
-
- flavor.delete()
- assertNull(client.findFlavor(flavor.uid))
-
- assertThrows<IllegalStateException> { server.start() }
- }
+ fun testClientCreate() =
+ scope.runSimulation {
+ val client = service.newClient()
+
+ val flavor = client.newFlavor("test", 1, 1024)
+ assertEquals(listOf(flavor), client.queryFlavors())
+ assertEquals(flavor, client.findFlavor(flavor.uid))
+ val image = client.newImage("test")
+ assertEquals(listOf(image), client.queryImages())
+ assertEquals(image, client.findImage(image.uid))
+ val server = client.newServer("test", image, flavor, start = false)
+ assertEquals(listOf(server), client.queryServers())
+ assertEquals(server, client.findServer(server.uid))
+
+ server.delete()
+ assertNull(client.findServer(server.uid))
+
+ image.delete()
+ assertNull(client.findImage(image.uid))
+
+ flavor.delete()
+ assertNull(client.findFlavor(flavor.uid))
+
+ assertThrows<IllegalStateException> { server.start() }
+ }
@Test
- fun testClientOnClose() = scope.runSimulation {
- service.close()
- assertThrows<IllegalStateException> {
- service.newClient()
+ fun testClientOnClose() =
+ scope.runSimulation {
+ service.close()
+ assertThrows<IllegalStateException> {
+ service.newClient()
+ }
}
- }
@Test
- fun testAddHost() = scope.runSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
+ fun testAddHost() =
+ scope.runSimulation {
+ val host = mockk<Host>(relaxUnitFun = true)
- every { host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { host.state } returns HostState.UP
+ every { host.model } returns HostModel(4 * 2600.0, 4, 2048)
+ every { host.state } returns HostState.UP
- assertEquals(emptySet<Host>(), service.hosts)
+ assertEquals(emptySet<Host>(), service.hosts)
- service.addHost(host)
+ service.addHost(host)
- verify(exactly = 1) { host.addListener(any()) }
+ verify(exactly = 1) { host.addListener(any()) }
- assertEquals(1, service.hosts.size)
+ assertEquals(1, service.hosts.size)
- service.removeHost(host)
+ service.removeHost(host)
- verify(exactly = 1) { host.removeListener(any()) }
- }
+ verify(exactly = 1) { host.removeListener(any()) }
+ }
@Test
- fun testAddHostDouble() = scope.runSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
+ fun testAddHostDouble() =
+ scope.runSimulation {
+ val host = mockk<Host>(relaxUnitFun = true)
- every { host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { host.state } returns HostState.DOWN
+ every { host.model } returns HostModel(4 * 2600.0, 4, 2048)
+ every { host.state } returns HostState.DOWN
- assertEquals(emptySet<Host>(), service.hosts)
+ assertEquals(emptySet<Host>(), service.hosts)
- service.addHost(host)
- service.addHost(host)
+ service.addHost(host)
+ service.addHost(host)
- verify(exactly = 1) { host.addListener(any()) }
- }
+ verify(exactly = 1) { host.addListener(any()) }
+ }
@Test
- fun testServerStartWithoutEnoughCpus() = scope.runSimulation {
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 0)
- val image = client.newImage("test")
- val server = client.newServer("test", image, flavor, start = false)
-
- server.start()
- delay(5L * 60 * 1000)
- server.reload()
- assertEquals(ServerState.TERMINATED, server.state)
- }
+ fun testServerStartWithoutEnoughCpus() =
+ scope.runSimulation {
+ val client = service.newClient()
+ val flavor = client.newFlavor("test", 1, 0)
+ val image = client.newImage("test")
+ val server = client.newServer("test", image, flavor, start = false)
+
+ server.start()
+ delay(5L * 60 * 1000)
+ server.reload()
+ assertEquals(ServerState.TERMINATED, server.state)
+ }
@Test
- fun testServerStartWithoutEnoughMemory() = scope.runSimulation {
- val client = service.newClient()
- val flavor = client.newFlavor("test", 0, 1024)
- val image = client.newImage("test")
- val server = client.newServer("test", image, flavor, start = false)
-
- server.start()
- delay(5L * 60 * 1000)
- server.reload()
- assertEquals(ServerState.TERMINATED, server.state)
- }
+ fun testServerStartWithoutEnoughMemory() =
+ scope.runSimulation {
+ val client = service.newClient()
+ val flavor = client.newFlavor("test", 0, 1024)
+ val image = client.newImage("test")
+ val server = client.newServer("test", image, flavor, start = false)
+
+ server.start()
+ delay(5L * 60 * 1000)
+ server.reload()
+ assertEquals(ServerState.TERMINATED, server.state)
+ }
@Test
- fun testServerStartWithoutEnoughResources() = scope.runSimulation {
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 1024)
- val image = client.newImage("test")
- val server = client.newServer("test", image, flavor, start = false)
-
- server.start()
- delay(5L * 60 * 1000)
- server.reload()
- assertEquals(ServerState.TERMINATED, server.state)
- }
+ fun testServerStartWithoutEnoughResources() =
+ scope.runSimulation {
+ val client = service.newClient()
+ val flavor = client.newFlavor("test", 1, 1024)
+ val image = client.newImage("test")
+ val server = client.newServer("test", image, flavor, start = false)
+
+ server.start()
+ delay(5L * 60 * 1000)
+ server.reload()
+ assertEquals(ServerState.TERMINATED, server.state)
+ }
@Test
- fun testServerCancelRequest() = scope.runSimulation {
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 1024)
- val image = client.newImage("test")
- val server = client.newServer("test", image, flavor, start = false)
-
- server.start()
- server.stop()
- delay(5L * 60 * 1000)
- server.reload()
- assertEquals(ServerState.TERMINATED, server.state)
- }
+ fun testServerCancelRequest() =
+ scope.runSimulation {
+ val client = service.newClient()
+ val flavor = client.newFlavor("test", 1, 1024)
+ val image = client.newImage("test")
+ val server = client.newServer("test", image, flavor, start = false)
+
+ server.start()
+ server.stop()
+ delay(5L * 60 * 1000)
+ server.reload()
+ assertEquals(ServerState.TERMINATED, server.state)
+ }
@Test
- fun testServerCannotFitOnHost() = scope.runSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
+ fun testServerCannotFitOnHost() =
+ scope.runSimulation {
+ val host = mockk<Host>(relaxUnitFun = true)
- every { host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { host.state } returns HostState.UP
- every { host.canFit(any()) } returns false
+ every { host.model } returns HostModel(4 * 2600.0, 4, 2048)
+ every { host.state } returns HostState.UP
+ every { host.canFit(any()) } returns false
- service.addHost(host)
+ service.addHost(host)
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 1024)
- val image = client.newImage("test")
- val server = client.newServer("test", image, flavor, start = false)
+ val client = service.newClient()
+ val flavor = client.newFlavor("test", 1, 1024)
+ val image = client.newImage("test")
+ val server = client.newServer("test", image, flavor, start = false)
- server.start()
- delay(10L * 60 * 1000)
- server.reload()
- assertEquals(ServerState.PROVISIONING, server.state)
+ server.start()
+ delay(10L * 60 * 1000)
+ server.reload()
+ assertEquals(ServerState.PROVISIONING, server.state)
- verify { host.canFit(server) }
- }
+ verify { host.canFit(server) }
+ }
@Test
- fun testHostAvailableAfterSomeTime() = scope.runSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
- val listeners = mutableListOf<HostListener>()
+ fun testHostAvailableAfterSomeTime() =
+ scope.runSimulation {
+ val host = mockk<Host>(relaxUnitFun = true)
+ val listeners = mutableListOf<HostListener>()
- every { host.uid } returns UUID.randomUUID()
- every { host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { host.state } returns HostState.DOWN
- every { host.addListener(any()) } answers { listeners.add(it.invocation.args[0] as HostListener) }
- every { host.canFit(any()) } returns false
+ every { host.uid } returns UUID.randomUUID()
+ every { host.model } returns HostModel(4 * 2600.0, 4, 2048)
+ every { host.state } returns HostState.DOWN
+ every { host.addListener(any()) } answers { listeners.add(it.invocation.args[0] as HostListener) }
+ every { host.canFit(any()) } returns false
- service.addHost(host)
+ service.addHost(host)
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 1024)
- val image = client.newImage("test")
- val server = client.newServer("test", image, flavor, start = false)
+ val client = service.newClient()
+ val flavor = client.newFlavor("test", 1, 1024)
+ val image = client.newImage("test")
+ val server = client.newServer("test", image, flavor, start = false)
- server.start()
- delay(5L * 60 * 1000)
+ server.start()
+ delay(5L * 60 * 1000)
- every { host.state } returns HostState.UP
- listeners.forEach { it.onStateChanged(host, HostState.UP) }
+ every { host.state } returns HostState.UP
+ listeners.forEach { it.onStateChanged(host, HostState.UP) }
- delay(5L * 60 * 1000)
- server.reload()
- assertEquals(ServerState.PROVISIONING, server.state)
+ delay(5L * 60 * 1000)
+ server.reload()
+ assertEquals(ServerState.PROVISIONING, server.state)
- verify { host.canFit(server) }
- }
+ verify { host.canFit(server) }
+ }
@Test
- fun testHostUnavailableAfterSomeTime() = scope.runSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
- val listeners = mutableListOf<HostListener>()
+ fun testHostUnavailableAfterSomeTime() =
+ scope.runSimulation {
+ val host = mockk<Host>(relaxUnitFun = true)
+ val listeners = mutableListOf<HostListener>()
- every { host.uid } returns UUID.randomUUID()
- every { host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { host.state } returns HostState.UP
- every { host.addListener(any()) } answers { listeners.add(it.invocation.args[0] as HostListener) }
- every { host.canFit(any()) } returns false
+ every { host.uid } returns UUID.randomUUID()
+ every { host.model } returns HostModel(4 * 2600.0, 4, 2048)
+ every { host.state } returns HostState.UP
+ every { host.addListener(any()) } answers { listeners.add(it.invocation.args[0] as HostListener) }
+ every { host.canFit(any()) } returns false
- service.addHost(host)
+ service.addHost(host)
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 1024)
- val image = client.newImage("test")
- val server = client.newServer("test", image, flavor, start = false)
+ val client = service.newClient()
+ val flavor = client.newFlavor("test", 1, 1024)
+ val image = client.newImage("test")
+ val server = client.newServer("test", image, flavor, start = false)
- delay(5L * 60 * 1000)
+ delay(5L * 60 * 1000)
- every { host.state } returns HostState.DOWN
- listeners.forEach { it.onStateChanged(host, HostState.DOWN) }
+ every { host.state } returns HostState.DOWN
+ listeners.forEach { it.onStateChanged(host, HostState.DOWN) }
- server.start()
- delay(5L * 60 * 1000)
- server.reload()
- assertEquals(ServerState.PROVISIONING, server.state)
+ server.start()
+ delay(5L * 60 * 1000)
+ server.reload()
+ assertEquals(ServerState.PROVISIONING, server.state)
- verify(exactly = 0) { host.canFit(server) }
- }
+ verify(exactly = 0) { host.canFit(server) }
+ }
@Test
- fun testServerDeploy() = scope.runSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
- val listeners = mutableListOf<HostListener>()
+ fun testServerDeploy() =
+ scope.runSimulation {
+ val host = mockk<Host>(relaxUnitFun = true)
+ val listeners = mutableListOf<HostListener>()
- every { host.uid } returns UUID.randomUUID()
- every { host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { host.state } returns HostState.UP
- every { host.canFit(any()) } returns true
- every { host.addListener(any()) } answers { listeners.add(it.invocation.args[0] as HostListener) }
+ every { host.uid } returns UUID.randomUUID()
+ every { host.model } returns HostModel(4 * 2600.0, 4, 2048)
+ every { host.state } returns HostState.UP
+ every { host.canFit(any()) } returns true
+ every { host.addListener(any()) } answers { listeners.add(it.invocation.args[0] as HostListener) }
- service.addHost(host)
+ service.addHost(host)
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 1024)
- val image = client.newImage("test")
- val server = client.newServer("test", image, flavor, start = false)
- val slot = slot<Server>()
+ val client = service.newClient()
+ val flavor = client.newFlavor("test", 1, 1024)
+ val image = client.newImage("test")
+ val server = client.newServer("test", image, flavor, start = false)
+ val slot = slot<Server>()
- val watcher = mockk<ServerWatcher>(relaxUnitFun = true)
- server.watch(watcher)
+ val watcher = mockk<ServerWatcher>(relaxUnitFun = true)
+ server.watch(watcher)
- // Start server
- server.start()
- delay(5L * 60 * 1000)
- coVerify { host.spawn(capture(slot)) }
+ // Start server
+ server.start()
+ delay(5L * 60 * 1000)
+ coVerify { host.spawn(capture(slot)) }
- listeners.forEach { it.onStateChanged(host, slot.captured, ServerState.RUNNING) }
+ listeners.forEach { it.onStateChanged(host, slot.captured, ServerState.RUNNING) }
- server.reload()
- assertEquals(ServerState.RUNNING, server.state)
+ server.reload()
+ assertEquals(ServerState.RUNNING, server.state)
- verify { watcher.onStateChanged(server, ServerState.RUNNING) }
+ verify { watcher.onStateChanged(server, ServerState.RUNNING) }
- // Stop server
- listeners.forEach { it.onStateChanged(host, slot.captured, ServerState.TERMINATED) }
+ // Stop server
+ listeners.forEach { it.onStateChanged(host, slot.captured, ServerState.TERMINATED) }
- server.reload()
- assertEquals(ServerState.TERMINATED, server.state)
+ server.reload()
+ assertEquals(ServerState.TERMINATED, server.state)
- verify { watcher.onStateChanged(server, ServerState.TERMINATED) }
- }
+ verify { watcher.onStateChanged(server, ServerState.TERMINATED) }
+ }
@Test
- fun testServerDeployFailure() = scope.runSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
- val listeners = mutableListOf<HostListener>()
-
- every { host.uid } returns UUID.randomUUID()
- every { host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { host.state } returns HostState.UP
- every { host.canFit(any()) } returns true
- every { host.addListener(any()) } answers { listeners.add(it.invocation.args[0] as HostListener) }
- coEvery { host.spawn(any()) } throws IllegalStateException()
-
- service.addHost(host)
-
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 1024)
- val image = client.newImage("test")
- val server = client.newServer("test", image, flavor, start = false)
-
- server.start()
- delay(5L * 60 * 1000)
-
- server.reload()
- assertEquals(ServerState.PROVISIONING, server.state)
- }
+ fun testServerDeployFailure() =
+ scope.runSimulation {
+ val host = mockk<Host>(relaxUnitFun = true)
+ val listeners = mutableListOf<HostListener>()
+
+ every { host.uid } returns UUID.randomUUID()
+ every { host.model } returns HostModel(4 * 2600.0, 4, 2048)
+ every { host.state } returns HostState.UP
+ every { host.canFit(any()) } returns true
+ every { host.addListener(any()) } answers { listeners.add(it.invocation.args[0] as HostListener) }
+ coEvery { host.spawn(any()) } throws IllegalStateException()
+
+ service.addHost(host)
+
+ val client = service.newClient()
+ val flavor = client.newFlavor("test", 1, 1024)
+ val image = client.newImage("test")
+ val server = client.newServer("test", image, flavor, start = false)
+
+ server.start()
+ delay(5L * 60 * 1000)
+
+ server.reload()
+ assertEquals(ServerState.PROVISIONING, server.state)
+ }
}
diff --git a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ServiceServerTest.kt b/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ServiceServerTest.kt
index f9fcd27b..6e0f11b3 100644
--- a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ServiceServerTest.kt
+++ b/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ServiceServerTest.kt
@@ -80,193 +80,205 @@ class ServiceServerTest {
}
@Test
- fun testStartTerminatedServer() = runSimulation {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server = ServiceServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf<String, Any>())
+ fun testStartTerminatedServer() =
+ runSimulation {
+ val service = mockk<ComputeService>()
+ val uid = UUID.randomUUID()
+ val flavor = mockFlavor()
+ val image = mockImage()
+ val server = ServiceServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf<String, Any>())
- every { service.schedule(any()) } answers { ComputeService.SchedulingRequest(it.invocation.args[0] as ServiceServer, 0) }
+ every { service.schedule(any()) } answers { ComputeService.SchedulingRequest(it.invocation.args[0] as ServiceServer, 0) }
- server.start()
+ server.start()
- verify(exactly = 1) { service.schedule(server) }
- assertEquals(ServerState.PROVISIONING, server.state)
- }
+ verify(exactly = 1) { service.schedule(server) }
+ assertEquals(ServerState.PROVISIONING, server.state)
+ }
@Test
- fun testStartDeletedServer() = runSimulation {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server = ServiceServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf<String, Any>())
+ fun testStartDeletedServer() =
+ runSimulation {
+ val service = mockk<ComputeService>()
+ val uid = UUID.randomUUID()
+ val flavor = mockFlavor()
+ val image = mockImage()
+ val server = ServiceServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf<String, Any>())
- server.setState(ServerState.DELETED)
+ server.setState(ServerState.DELETED)
- assertThrows<IllegalStateException> { server.start() }
- }
+ assertThrows<IllegalStateException> { server.start() }
+ }
@Test
- fun testStartProvisioningServer() = runSimulation {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server = ServiceServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf<String, Any>())
+ fun testStartProvisioningServer() =
+ runSimulation {
+ val service = mockk<ComputeService>()
+ val uid = UUID.randomUUID()
+ val flavor = mockFlavor()
+ val image = mockImage()
+ val server = ServiceServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf<String, Any>())
- server.setState(ServerState.PROVISIONING)
+ server.setState(ServerState.PROVISIONING)
- server.start()
+ server.start()
- assertEquals(ServerState.PROVISIONING, server.state)
- }
+ assertEquals(ServerState.PROVISIONING, server.state)
+ }
@Test
- fun testStartRunningServer() = runSimulation {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server = ServiceServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf<String, Any>())
+ fun testStartRunningServer() =
+ runSimulation {
+ val service = mockk<ComputeService>()
+ val uid = UUID.randomUUID()
+ val flavor = mockFlavor()
+ val image = mockImage()
+ val server = ServiceServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf<String, Any>())
- server.setState(ServerState.RUNNING)
+ server.setState(ServerState.RUNNING)
- server.start()
+ server.start()
- assertEquals(ServerState.RUNNING, server.state)
- }
+ assertEquals(ServerState.RUNNING, server.state)
+ }
@Test
- fun testStopProvisioningServer() = runSimulation {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server = ServiceServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf<String, Any>())
- val request = ComputeService.SchedulingRequest(server, 0)
+ fun testStopProvisioningServer() =
+ runSimulation {
+ val service = mockk<ComputeService>()
+ val uid = UUID.randomUUID()
+ val flavor = mockFlavor()
+ val image = mockImage()
+ val server = ServiceServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf<String, Any>())
+ val request = ComputeService.SchedulingRequest(server, 0)
- every { service.schedule(any()) } returns request
+ every { service.schedule(any()) } returns request
- server.start()
- server.stop()
+ server.start()
+ server.stop()
- assertTrue(request.isCancelled)
- assertEquals(ServerState.TERMINATED, server.state)
- }
+ assertTrue(request.isCancelled)
+ assertEquals(ServerState.TERMINATED, server.state)
+ }
@Test
- fun testStopTerminatedServer() = runSimulation {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server = ServiceServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf<String, Any>())
+ fun testStopTerminatedServer() =
+ runSimulation {
+ val service = mockk<ComputeService>()
+ val uid = UUID.randomUUID()
+ val flavor = mockFlavor()
+ val image = mockImage()
+ val server = ServiceServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf<String, Any>())
- server.setState(ServerState.TERMINATED)
- server.stop()
+ server.setState(ServerState.TERMINATED)
+ server.stop()
- assertEquals(ServerState.TERMINATED, server.state)
- }
+ assertEquals(ServerState.TERMINATED, server.state)
+ }
@Test
- fun testStopDeletedServer() = runSimulation {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server = ServiceServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf<String, Any>())
+ fun testStopDeletedServer() =
+ runSimulation {
+ val service = mockk<ComputeService>()
+ val uid = UUID.randomUUID()
+ val flavor = mockFlavor()
+ val image = mockImage()
+ val server = ServiceServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf<String, Any>())
- server.setState(ServerState.DELETED)
- server.stop()
+ server.setState(ServerState.DELETED)
+ server.stop()
- assertEquals(ServerState.DELETED, server.state)
- }
+ assertEquals(ServerState.DELETED, server.state)
+ }
@Test
- fun testStopRunningServer() = runSimulation {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server = ServiceServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf<String, Any>())
- val host = mockk<Host>(relaxUnitFun = true)
-
- server.setState(ServerState.RUNNING)
- server.host = host
- server.stop()
- yield()
-
- verify { host.stop(server) }
- }
+ fun testStopRunningServer() =
+ runSimulation {
+ val service = mockk<ComputeService>()
+ val uid = UUID.randomUUID()
+ val flavor = mockFlavor()
+ val image = mockImage()
+ val server = ServiceServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf<String, Any>())
+ val host = mockk<Host>(relaxUnitFun = true)
+
+ server.setState(ServerState.RUNNING)
+ server.host = host
+ server.stop()
+ yield()
+
+ verify { host.stop(server) }
+ }
@Test
- fun testDeleteProvisioningServer() = runSimulation {
- val service = mockk<ComputeService>(relaxUnitFun = true)
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server = ServiceServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf<String, Any>())
- val request = ComputeService.SchedulingRequest(server, 0)
+ fun testDeleteProvisioningServer() =
+ runSimulation {
+ val service = mockk<ComputeService>(relaxUnitFun = true)
+ val uid = UUID.randomUUID()
+ val flavor = mockFlavor()
+ val image = mockImage()
+ val server = ServiceServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf<String, Any>())
+ val request = ComputeService.SchedulingRequest(server, 0)
- every { service.schedule(any()) } returns request
+ every { service.schedule(any()) } returns request
- server.start()
- server.delete()
+ server.start()
+ server.delete()
- assertTrue(request.isCancelled)
- assertEquals(ServerState.DELETED, server.state)
- verify { service.delete(server) }
- }
+ assertTrue(request.isCancelled)
+ assertEquals(ServerState.DELETED, server.state)
+ verify { service.delete(server) }
+ }
@Test
- fun testDeleteTerminatedServer() = runSimulation {
- val service = mockk<ComputeService>(relaxUnitFun = true)
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server = ServiceServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf<String, Any>())
+ fun testDeleteTerminatedServer() =
+ runSimulation {
+ val service = mockk<ComputeService>(relaxUnitFun = true)
+ val uid = UUID.randomUUID()
+ val flavor = mockFlavor()
+ val image = mockImage()
+ val server = ServiceServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf<String, Any>())
- server.setState(ServerState.TERMINATED)
- server.delete()
+ server.setState(ServerState.TERMINATED)
+ server.delete()
- assertEquals(ServerState.DELETED, server.state)
+ assertEquals(ServerState.DELETED, server.state)
- verify { service.delete(server) }
- }
+ verify { service.delete(server) }
+ }
@Test
- fun testDeleteDeletedServer() = runSimulation {
- val service = mockk<ComputeService>(relaxUnitFun = true)
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server = ServiceServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf<String, Any>())
+ fun testDeleteDeletedServer() =
+ runSimulation {
+ val service = mockk<ComputeService>(relaxUnitFun = true)
+ val uid = UUID.randomUUID()
+ val flavor = mockFlavor()
+ val image = mockImage()
+ val server = ServiceServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf<String, Any>())
- server.setState(ServerState.DELETED)
- server.delete()
+ server.setState(ServerState.DELETED)
+ server.delete()
- assertEquals(ServerState.DELETED, server.state)
- }
+ assertEquals(ServerState.DELETED, server.state)
+ }
@Test
- fun testDeleteRunningServer() = runSimulation {
- val service = mockk<ComputeService>(relaxUnitFun = true)
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server = ServiceServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf<String, Any>())
- val host = mockk<Host>(relaxUnitFun = true)
-
- server.setState(ServerState.RUNNING)
- server.host = host
- server.delete()
- yield()
-
- verify { host.delete(server) }
- verify { service.delete(server) }
- }
+ fun testDeleteRunningServer() =
+ runSimulation {
+ val service = mockk<ComputeService>(relaxUnitFun = true)
+ val uid = UUID.randomUUID()
+ val flavor = mockFlavor()
+ val image = mockImage()
+ val server = ServiceServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf<String, Any>())
+ val host = mockk<Host>(relaxUnitFun = true)
+
+ server.setState(ServerState.RUNNING)
+ server.host = host
+ server.delete()
+ yield()
+
+ verify { host.delete(server) }
+ verify { service.delete(server) }
+ }
private fun mockFlavor(): ServiceFlavor {
val flavor = mockk<ServiceFlavor>()
diff --git a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/scheduler/FilterSchedulerTest.kt b/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/scheduler/FilterSchedulerTest.kt
index 4af6f7ec..a48052a1 100644
--- a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/scheduler/FilterSchedulerTest.kt
+++ b/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/scheduler/FilterSchedulerTest.kt
@@ -57,7 +57,7 @@ internal class FilterSchedulerTest {
FilterScheduler(
filters = emptyList(),
weighers = emptyList(),
- subsetSize = 0
+ subsetSize = 0,
)
}
@@ -65,17 +65,18 @@ internal class FilterSchedulerTest {
FilterScheduler(
filters = emptyList(),
weighers = emptyList(),
- subsetSize = -2
+ subsetSize = -2,
)
}
}
@Test
fun testNoHosts() {
- val scheduler = FilterScheduler(
- filters = emptyList(),
- weighers = emptyList()
- )
+ val scheduler =
+ FilterScheduler(
+ filters = emptyList(),
+ weighers = emptyList(),
+ )
val server = mockk<Server>()
every { server.flavor.cpuCount } returns 2
@@ -86,10 +87,11 @@ internal class FilterSchedulerTest {
@Test
fun testNoFiltersAndSchedulers() {
- val scheduler = FilterScheduler(
- filters = emptyList(),
- weighers = emptyList()
- )
+ val scheduler =
+ FilterScheduler(
+ filters = emptyList(),
+ weighers = emptyList(),
+ )
val hostA = mockk<HostView>()
every { hostA.host.state } returns HostState.DOWN
@@ -107,18 +109,19 @@ internal class FilterSchedulerTest {
// Make sure we get the first host both times
assertAll(
{ assertEquals(hostA, scheduler.select(server)) },
- { assertEquals(hostA, scheduler.select(server)) }
+ { assertEquals(hostA, scheduler.select(server)) },
)
}
@Test
fun testNoFiltersAndSchedulersRandom() {
- val scheduler = FilterScheduler(
- filters = emptyList(),
- weighers = emptyList(),
- subsetSize = Int.MAX_VALUE,
- random = Random(1)
- )
+ val scheduler =
+ FilterScheduler(
+ filters = emptyList(),
+ weighers = emptyList(),
+ subsetSize = Int.MAX_VALUE,
+ random = Random(1),
+ )
val hostA = mockk<HostView>()
every { hostA.host.state } returns HostState.DOWN
@@ -136,16 +139,17 @@ internal class FilterSchedulerTest {
// Make sure we get the first host both times
assertAll(
{ assertEquals(hostB, scheduler.select(server)) },
- { assertEquals(hostA, scheduler.select(server)) }
+ { assertEquals(hostA, scheduler.select(server)) },
)
}
@Test
fun testHostIsDown() {
- val scheduler = FilterScheduler(
- filters = listOf(ComputeFilter()),
- weighers = emptyList()
- )
+ val scheduler =
+ FilterScheduler(
+ filters = listOf(ComputeFilter()),
+ weighers = emptyList(),
+ )
val host = mockk<HostView>()
every { host.host.state } returns HostState.DOWN
@@ -161,10 +165,11 @@ internal class FilterSchedulerTest {
@Test
fun testHostIsUp() {
- val scheduler = FilterScheduler(
- filters = listOf(ComputeFilter()),
- weighers = emptyList()
- )
+ val scheduler =
+ FilterScheduler(
+ filters = listOf(ComputeFilter()),
+ weighers = emptyList(),
+ )
val host = mockk<HostView>()
every { host.host.state } returns HostState.UP
@@ -180,10 +185,11 @@ internal class FilterSchedulerTest {
@Test
fun testRamFilter() {
- val scheduler = FilterScheduler(
- filters = listOf(RamFilter(1.0)),
- weighers = emptyList()
- )
+ val scheduler =
+ FilterScheduler(
+ filters = listOf(RamFilter(1.0)),
+ weighers = emptyList(),
+ )
val hostA = mockk<HostView>()
every { hostA.host.state } returns HostState.UP
@@ -207,10 +213,11 @@ internal class FilterSchedulerTest {
@Test
fun testRamFilterOvercommit() {
- val scheduler = FilterScheduler(
- filters = listOf(RamFilter(1.5)),
- weighers = emptyList()
- )
+ val scheduler =
+ FilterScheduler(
+ filters = listOf(RamFilter(1.5)),
+ weighers = emptyList(),
+ )
val host = mockk<HostView>()
every { host.host.state } returns HostState.UP
@@ -228,10 +235,11 @@ internal class FilterSchedulerTest {
@Test
fun testVCpuFilter() {
- val scheduler = FilterScheduler(
- filters = listOf(VCpuFilter(1.0)),
- weighers = emptyList()
- )
+ val scheduler =
+ FilterScheduler(
+ filters = listOf(VCpuFilter(1.0)),
+ weighers = emptyList(),
+ )
val hostA = mockk<HostView>()
every { hostA.host.state } returns HostState.UP
@@ -255,10 +263,11 @@ internal class FilterSchedulerTest {
@Test
fun testVCpuFilterOvercommit() {
- val scheduler = FilterScheduler(
- filters = listOf(VCpuFilter(16.0)),
- weighers = emptyList()
- )
+ val scheduler =
+ FilterScheduler(
+ filters = listOf(VCpuFilter(16.0)),
+ weighers = emptyList(),
+ )
val host = mockk<HostView>()
every { host.host.state } returns HostState.UP
@@ -276,10 +285,11 @@ internal class FilterSchedulerTest {
@Test
fun testVCpuCapacityFilter() {
- val scheduler = FilterScheduler(
- filters = listOf(VCpuCapacityFilter()),
- weighers = emptyList()
- )
+ val scheduler =
+ FilterScheduler(
+ filters = listOf(VCpuCapacityFilter()),
+ weighers = emptyList(),
+ )
val hostA = mockk<HostView>()
every { hostA.host.state } returns HostState.UP
@@ -304,10 +314,11 @@ internal class FilterSchedulerTest {
@Test
fun testInstanceCountFilter() {
- val scheduler = FilterScheduler(
- filters = listOf(InstanceCountFilter(limit = 2)),
- weighers = emptyList()
- )
+ val scheduler =
+ FilterScheduler(
+ filters = listOf(InstanceCountFilter(limit = 2)),
+ weighers = emptyList(),
+ )
val hostA = mockk<HostView>()
every { hostA.host.state } returns HostState.UP
@@ -331,10 +342,11 @@ internal class FilterSchedulerTest {
@Test
fun testAffinityFilter() {
- val scheduler = FilterScheduler(
- filters = listOf(SameHostFilter()),
- weighers = emptyList()
- )
+ val scheduler =
+ FilterScheduler(
+ filters = listOf(SameHostFilter()),
+ weighers = emptyList(),
+ )
val serverA = mockk<Server>()
every { serverA.uid } returns UUID.randomUUID()
@@ -370,10 +382,11 @@ internal class FilterSchedulerTest {
@Test
fun testAntiAffinityFilter() {
- val scheduler = FilterScheduler(
- filters = listOf(DifferentHostFilter()),
- weighers = emptyList()
- )
+ val scheduler =
+ FilterScheduler(
+ filters = listOf(DifferentHostFilter()),
+ weighers = emptyList(),
+ )
val serverA = mockk<Server>()
every { serverA.uid } returns UUID.randomUUID()
@@ -409,10 +422,11 @@ internal class FilterSchedulerTest {
@Test
fun testRamWeigher() {
- val scheduler = FilterScheduler(
- filters = emptyList(),
- weighers = listOf(RamWeigher(1.5))
- )
+ val scheduler =
+ FilterScheduler(
+ filters = emptyList(),
+ weighers = listOf(RamWeigher(1.5)),
+ )
val hostA = mockk<HostView>()
every { hostA.host.state } returns HostState.UP
@@ -436,10 +450,11 @@ internal class FilterSchedulerTest {
@Test
fun testCoreRamWeigher() {
- val scheduler = FilterScheduler(
- filters = emptyList(),
- weighers = listOf(CoreRamWeigher(1.5))
- )
+ val scheduler =
+ FilterScheduler(
+ filters = emptyList(),
+ weighers = listOf(CoreRamWeigher(1.5)),
+ )
val hostA = mockk<HostView>()
every { hostA.host.state } returns HostState.UP
@@ -463,10 +478,11 @@ internal class FilterSchedulerTest {
@Test
fun testVCpuWeigher() {
- val scheduler = FilterScheduler(
- filters = emptyList(),
- weighers = listOf(VCpuWeigher(16.0))
- )
+ val scheduler =
+ FilterScheduler(
+ filters = emptyList(),
+ weighers = listOf(VCpuWeigher(16.0)),
+ )
val hostA = mockk<HostView>()
every { hostA.host.state } returns HostState.UP
@@ -490,10 +506,11 @@ internal class FilterSchedulerTest {
@Test
fun testInstanceCountWeigher() {
- val scheduler = FilterScheduler(
- filters = emptyList(),
- weighers = listOf(InstanceCountWeigher(multiplier = -1.0))
- )
+ val scheduler =
+ FilterScheduler(
+ filters = emptyList(),
+ weighers = listOf(InstanceCountWeigher(multiplier = -1.0)),
+ )
val hostA = mockk<HostView>()
every { hostA.host.state } returns HostState.UP