summaryrefslogtreecommitdiff
path: root/simulator/opendc-compute
diff options
context:
space:
mode:
Diffstat (limited to 'simulator/opendc-compute')
-rw-r--r--simulator/opendc-compute/build.gradle.kts23
-rw-r--r--simulator/opendc-compute/opendc-compute-api/build.gradle.kts32
-rw-r--r--simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/ComputeClient.kt120
-rw-r--r--simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/Flavor.kt44
-rw-r--r--simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/Image.kt33
-rw-r--r--simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/InsufficientServerCapacityException.kt29
-rw-r--r--simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/Resource.kt55
-rw-r--r--simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/Server.kt81
-rw-r--r--simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/ServerState.kt53
-rw-r--r--simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/ServerWatcher.kt39
-rw-r--r--simulator/opendc-compute/opendc-compute-service/build.gradle.kts41
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/ComputeService.kt85
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/Host.kt103
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/HostListener.kt41
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/HostModel.kt31
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/HostState.kt38
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ClientFlavor.kt68
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ClientImage.kt61
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ClientServer.kt113
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt500
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/HostView.kt44
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/InternalFlavor.kt66
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/InternalImage.kt56
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/InternalServer.kt153
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ComputeScheduler.kt50
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt66
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ReplayScheduler.kt64
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeCapabilitiesFilter.kt40
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeFilter.kt38
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/HostFilter.kt38
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/InstanceCountFilter.kt39
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/CoreMemoryWeigher.kt37
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/HostWeigher.kt37
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/InstanceCountWeigher.kt37
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/MemoryWeigher.kt37
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/ProvisionedCoresWeigher.kt37
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/RandomWeigher.kt36
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt391
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalFlavorTest.kt80
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalImageTest.kt81
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalServerTest.kt285
-rw-r--r--simulator/opendc-compute/opendc-compute-service/src/test/resources/log4j2.xml38
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/build.gradle.kts43
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt423
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimMetaWorkloadMapper.kt35
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimWorkloadMapper.kt36
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt227
47 files changed, 0 insertions, 4104 deletions
diff --git a/simulator/opendc-compute/build.gradle.kts b/simulator/opendc-compute/build.gradle.kts
deleted file mode 100644
index bf920306..00000000
--- a/simulator/opendc-compute/build.gradle.kts
+++ /dev/null
@@ -1,23 +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.
- */
-
-description = "Cloud computing fabric controller of OpenDC"
diff --git a/simulator/opendc-compute/opendc-compute-api/build.gradle.kts b/simulator/opendc-compute/opendc-compute-api/build.gradle.kts
deleted file mode 100644
index 835dbbb8..00000000
--- a/simulator/opendc-compute/opendc-compute-api/build.gradle.kts
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2021 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.
- */
-
-description = "API interface for the OpenDC Compute service"
-
-/* Build configuration */
-plugins {
- `kotlin-library-conventions`
-}
-
-dependencies {
- api(platform(project(":opendc-platform")))
-}
diff --git a/simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/ComputeClient.kt b/simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/ComputeClient.kt
deleted file mode 100644
index baa1ba2f..00000000
--- a/simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/ComputeClient.kt
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (c) 2021 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.api
-
-import java.util.UUID
-
-/**
- * A client interface for the OpenDC Compute service.
- */
-public interface ComputeClient : AutoCloseable {
- /**
- * Obtain the list of [Flavor]s accessible by the requesting user.
- */
- public suspend fun queryFlavors(): List<Flavor>
-
- /**
- * Obtain a [Flavor] by its unique identifier.
- *
- * @param id The identifier of the flavor.
- */
- public suspend fun findFlavor(id: UUID): Flavor?
-
- /**
- * Create a new [Flavor] instance at this compute service.
- *
- * @param name The name of the flavor.
- * @param cpuCount The amount of CPU cores for this flavor.
- * @param memorySize The size of the memory.
- * @param labels The identifying labels of the image.
- * @param meta The non-identifying meta-data of the image.
- */
- public suspend fun newFlavor(
- name: String,
- cpuCount: Int,
- memorySize: Long,
- labels: Map<String, String> = emptyMap(),
- meta: Map<String, Any> = emptyMap()
- ): Flavor
-
- /**
- * Obtain the list of [Image]s accessible by the requesting user.
- */
- public suspend fun queryImages(): List<Image>
-
- /**
- * Obtain a [Image] by its unique identifier.
- *
- * @param id The identifier of the image.
- */
- public suspend fun findImage(id: UUID): Image?
-
- /**
- * Create a new [Image] instance at this compute service.
- *
- * @param name The name of the image.
- * @param labels The identifying labels of the image.
- * @param meta The non-identifying meta-data of the image.
- */
- public suspend fun newImage(
- name: String,
- labels: Map<String, String> = emptyMap(),
- meta: Map<String, Any> = emptyMap()
- ): Image
-
- /**
- * Obtain the list of [Server]s accessible by the requesting user.
- */
- public suspend fun queryServers(): List<Server>
-
- /**
- * Obtain a [Server] by its unique identifier.
- *
- * @param id The identifier of the server.
- */
- public suspend fun findServer(id: UUID): Server?
-
- /**
- * Create a new [Server] instance at this compute service.
- *
- * @param name The name of the server to deploy.
- * @param image The image to be deployed.
- * @param flavor The flavor of the machine instance to run this [image] on.
- * @param labels The identifying labels of the server.
- * @param meta The non-identifying meta-data of the server.
- * @param start A flag to indicate that the server should be started immediately.
- */
- public suspend fun newServer(
- name: String,
- image: Image,
- flavor: Flavor,
- labels: Map<String, String> = emptyMap(),
- meta: Map<String, Any> = emptyMap(),
- start: Boolean = true
- ): Server
-
- /**
- * Release the resources associated with this client, preventing any further API calls.
- */
- public override fun close()
-}
diff --git a/simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/Flavor.kt b/simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/Flavor.kt
deleted file mode 100644
index 5f511f91..00000000
--- a/simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/Flavor.kt
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2021 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.api
-
-/**
- * Flavors define the compute and memory capacity of [Server] instance. To put it simply, a flavor is an available
- * hardware configuration for a server. It defines the size of a virtual server that can be launched.
- */
-public interface Flavor : Resource {
- /**
- * The number of (virtual) processing cores to use.
- */
- public val cpuCount: Int
-
- /**
- * The amount of RAM available to the server (in MB).
- */
- public val memorySize: Long
-
- /**
- * Delete the flavor instance.
- */
- public suspend fun delete()
-}
diff --git a/simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/Image.kt b/simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/Image.kt
deleted file mode 100644
index 83e63b81..00000000
--- a/simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/Image.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2021 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.api
-
-/**
- * An image containing a bootable operating system that can directly be executed by physical or virtual server.
- */
-public interface Image : Resource {
- /**
- * Delete the image instance.
- */
- public suspend fun delete()
-}
diff --git a/simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/InsufficientServerCapacityException.kt b/simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/InsufficientServerCapacityException.kt
deleted file mode 100644
index 8fbb7308..00000000
--- a/simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/InsufficientServerCapacityException.kt
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2021 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.api
-
-/**
- * This exception is thrown to indicate that the compute service does not have enough capacity at the moment to
- * fulfill a launch request.
- */
-public class InsufficientServerCapacityException(override val cause: Throwable? = null) : Exception("There was insufficient capacity available to satisfy the launch request")
diff --git a/simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/Resource.kt b/simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/Resource.kt
deleted file mode 100644
index 08120848..00000000
--- a/simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/Resource.kt
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2021 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.api
-
-import java.util.UUID
-
-/**
- * A generic resource provided by the OpenDC Compute service.
- */
-public interface Resource {
- /**
- * The unique identifier of the resource.
- */
- public val uid: UUID
-
- /**
- * The name of the resource.
- */
- public val name: String
-
- /**
- * The identifying labels attached to the resource.
- */
- public val labels: Map<String, String>
-
- /**
- * The non-identifying metadata attached to the resource.
- */
- public val meta: Map<String, Any>
-
- /**
- * Refresh the local state of the resource.
- */
- public suspend fun refresh()
-}
diff --git a/simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/Server.kt b/simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/Server.kt
deleted file mode 100644
index b508a9f8..00000000
--- a/simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/Server.kt
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2021 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.api
-
-/**
- * A stateful object representing a server instance that is running on some physical or virtual machine.
- */
-public interface Server : Resource {
- /**
- * The flavor of the server.
- */
- public val flavor: Flavor
-
- /**
- * The image of the server.
- */
- public val image: Image
-
- /**
- * The last known state of the server.
- */
- public val state: ServerState
-
- /**
- * Request the server to be started.
- *
- * This method is guaranteed to return after the request was acknowledged, but might return before the server was
- * started.
- */
- public suspend fun start()
-
- /**
- * Request the server to be stopped.
- *
- * This method is guaranteed to return after the request was acknowledged, but might return before the server was
- * stopped.
- */
- public suspend fun stop()
-
- /**
- * Request the server to be deleted.
- *
- * This method is guaranteed to return after the request was acknowledged, but might return before the server was
- * deleted.
- */
- public suspend fun delete()
-
- /**
- * Register the specified [ServerWatcher] to watch the state of the server.
- *
- * @param watcher The watcher to register for the server.
- */
- public fun watch(watcher: ServerWatcher)
-
- /**
- * De-register the specified [ServerWatcher] from the server to stop it from receiving events.
- *
- * @param watcher The watcher to de-register from the server.
- */
- public fun unwatch(watcher: ServerWatcher)
-}
diff --git a/simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/ServerState.kt b/simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/ServerState.kt
deleted file mode 100644
index a4d7d7d7..00000000
--- a/simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/ServerState.kt
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2021 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.api
-
-/**
- * An enumeration describing the possible states of a server.
- */
-public enum class ServerState {
- /**
- * Resources are being allocated for the instance. The instance is not running yet.
- */
- PROVISIONING,
-
- /**
- * A user shut down the instance.
- */
- TERMINATED,
-
- /**
- * The server instance is booting up or running.
- */
- RUNNING,
-
- /**
- * The server is in an error state.
- */
- ERROR,
-
- /**
- * The server has been deleted and cannot be started later on.
- */
- DELETED,
-}
diff --git a/simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/ServerWatcher.kt b/simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/ServerWatcher.kt
deleted file mode 100644
index 48a17b30..00000000
--- a/simulator/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/ServerWatcher.kt
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2021 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.api
-
-/**
- * An interface used to watch the state of [Server] instances.
- */
-public interface ServerWatcher {
- /**
- * This method is invoked when the state of a [Server] changes.
- *
- * Note that the state of [server] might not reflect the state as reported by the invocation, as a call to
- * [Server.refresh] is required to update its state.
- *
- * @param server The server whose state has changed.
- * @param newState The new state of the server.
- */
- public fun onStateChanged(server: Server, newState: ServerState) {}
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/build.gradle.kts b/simulator/opendc-compute/opendc-compute-service/build.gradle.kts
deleted file mode 100644
index 909e2dcd..00000000
--- a/simulator/opendc-compute/opendc-compute-service/build.gradle.kts
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2021 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.
- */
-
-description = "OpenDC Compute Service implementation"
-
-/* Build configuration */
-plugins {
- `kotlin-library-conventions`
- `testing-conventions`
- `jacoco-conventions`
-}
-
-dependencies {
- api(platform(project(":opendc-platform")))
- api(project(":opendc-compute:opendc-compute-api"))
- api(project(":opendc-telemetry:opendc-telemetry-api"))
- implementation(project(":opendc-utils"))
- implementation("io.github.microutils:kotlin-logging")
-
- testImplementation(project(":opendc-simulator:opendc-simulator-core"))
- testRuntimeOnly("org.apache.logging.log4j:log4j-slf4j-impl")
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/ComputeService.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/ComputeService.kt
deleted file mode 100644
index 1873eb99..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/ComputeService.kt
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2021 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.service
-
-import io.opentelemetry.api.metrics.Meter
-import org.opendc.compute.api.ComputeClient
-import org.opendc.compute.service.driver.Host
-import org.opendc.compute.service.internal.ComputeServiceImpl
-import org.opendc.compute.service.scheduler.ComputeScheduler
-import java.time.Clock
-import kotlin.coroutines.CoroutineContext
-
-/**
- * The [ComputeService] hosts the API implementation of the OpenDC Compute service.
- */
-public interface ComputeService : AutoCloseable {
- /**
- * The hosts that are used by the compute service.
- */
- public val hosts: Set<Host>
-
- /**
- * The number of hosts available in the system.
- */
- public val hostCount: Int
-
- /**
- * Create a new [ComputeClient] to control the compute service.
- */
- public fun newClient(): ComputeClient
-
- /**
- * Add a [host] to the scheduling pool of the compute service.
- */
- public fun addHost(host: Host)
-
- /**
- * Remove a [host] from the scheduling pool of the compute service.
- */
- public fun removeHost(host: Host)
-
- /**
- * Terminate the lifecycle of the compute service, stopping all running instances.
- */
- public override fun close()
-
- public companion object {
- /**
- * Construct a new [ComputeService] implementation.
- *
- * @param context The [CoroutineContext] to use in the service.
- * @param clock The clock instance to use.
- * @param scheduler The scheduler implementation to use.
- */
- public operator fun invoke(
- context: CoroutineContext,
- clock: Clock,
- meter: Meter,
- scheduler: ComputeScheduler,
- schedulingQuantum: Long = 300000,
- ): ComputeService {
- return ComputeServiceImpl(context, clock, meter, scheduler, schedulingQuantum)
- }
- }
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/Host.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/Host.kt
deleted file mode 100644
index bed15dfd..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/Host.kt
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (c) 2021 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.service.driver
-
-import org.opendc.compute.api.Server
-import java.util.*
-
-/**
- * Base interface for representing compute resources that host virtualized [Server] instances.
- */
-public interface Host {
- /**
- * A unique identifier representing the host.
- */
- public val uid: UUID
-
- /**
- * The name of this host.
- */
- public val name: String
-
- /**
- * The machine model of the host.
- */
- public val model: HostModel
-
- /**
- * The state of the host.
- */
- public val state: HostState
-
- /**
- * Meta-data associated with the host.
- */
- public val meta: Map<String, Any>
-
- /**
- * Determine whether the specified [instance][server] can still fit on this host.
- */
- public fun canFit(server: Server): Boolean
-
- /**
- * Register the specified [instance][server] on the host.
- *
- * Once the method returns, the instance should be running if [start] is true or else the instance should be
- * stopped.
- */
- public suspend fun spawn(server: Server, start: Boolean = true)
-
- /**
- * Determine whether the specified [instance][server] exists on the host.
- */
- public operator fun contains(server: Server): Boolean
-
- /**
- * Start the server [instance][server] if it is currently not running on this host.
- *
- * @throws IllegalArgumentException if the server is not present on the host.
- */
- public suspend fun start(server: Server)
-
- /**
- * Stop the server [instance][server] if it is currently running on this host.
- *
- * @throws IllegalArgumentException if the server is not present on the host.
- */
- public suspend fun stop(server: Server)
-
- /**
- * Delete the specified [instance][server] on this host and cleanup all resources associated with it.
- */
- public suspend fun delete(server: Server)
-
- /**
- * Add a [HostListener] to this host.
- */
- public fun addListener(listener: HostListener)
-
- /**
- * Remove a [HostListener] from this host.
- */
- public fun removeListener(listener: HostListener)
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/HostListener.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/HostListener.kt
deleted file mode 100644
index f076cae3..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/HostListener.kt
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2021 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.service.driver
-
-import org.opendc.compute.api.Server
-import org.opendc.compute.api.ServerState
-
-/**
- * Listener interface for events originating from a [Host].
- */
-public interface HostListener {
- /**
- * This method is invoked when the state of an [instance][server] on [host] changes.
- */
- public fun onStateChanged(host: Host, server: Server, newState: ServerState) {}
-
- /**
- * This method is invoked when the state of a [Host] has changed.
- */
- public fun onStateChanged(host: Host, newState: HostState) {}
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/HostModel.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/HostModel.kt
deleted file mode 100644
index 5632a55e..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/HostModel.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2021 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.service.driver
-
-/**
- * Describes the static machine properties of the host.
- *
- * @property vcpuCount The number of logical processing cores available for this host.
- * @property memorySize The amount of memory available for this host in MB.
- */
-public data class HostModel(public val cpuCount: Int, public val memorySize: Long)
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/HostState.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/HostState.kt
deleted file mode 100644
index 6d85ee2d..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/HostState.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2021 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.service.driver
-
-/**
- * The state of a host.
- */
-public enum class HostState {
- /**
- * The host is up.
- */
- UP,
-
- /**
- * The host is down.
- */
- DOWN
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ClientFlavor.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ClientFlavor.kt
deleted file mode 100644
index 4a8d3046..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ClientFlavor.kt
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2021 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.service.internal
-
-import org.opendc.compute.api.Flavor
-import java.util.UUID
-
-/**
- * A [Flavor] implementation that is passed to clients but delegates its implementation to another class.
- */
-internal class ClientFlavor(private val delegate: Flavor) : Flavor {
- override val uid: UUID = delegate.uid
-
- override var name: String = delegate.name
- private set
-
- override var cpuCount: Int = delegate.cpuCount
- private set
-
- override var memorySize: Long = delegate.memorySize
- private set
-
- override var labels: Map<String, String> = delegate.labels.toMap()
- private set
-
- override var meta: Map<String, Any> = delegate.meta.toMap()
- private set
-
- override suspend fun delete() {
- delegate.delete()
- }
-
- override suspend fun refresh() {
- delegate.refresh()
-
- name = delegate.name
- cpuCount = delegate.cpuCount
- memorySize = delegate.memorySize
- labels = delegate.labels
- meta = delegate.meta
- }
-
- override fun equals(other: Any?): Boolean = other is Flavor && other.uid == uid
-
- override fun hashCode(): Int = uid.hashCode()
-
- override fun toString(): String = "Flavor[uid=$uid,name=$name]"
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ClientImage.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ClientImage.kt
deleted file mode 100644
index e0b5c171..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ClientImage.kt
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2021 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.service.internal
-
-import org.opendc.compute.api.Image
-import java.util.*
-
-/**
- * An [Image] implementation that is passed to clients but delegates its implementation to another class.
- */
-internal class ClientImage(private val delegate: Image) : Image {
- override val uid: UUID = delegate.uid
-
- override var name: String = delegate.name
- private set
-
- override var labels: Map<String, String> = delegate.labels.toMap()
- private set
-
- override var meta: Map<String, Any> = delegate.meta.toMap()
- private set
-
- override suspend fun delete() {
- delegate.delete()
- refresh()
- }
-
- override suspend fun refresh() {
- delegate.refresh()
-
- name = delegate.name
- labels = delegate.labels
- meta = delegate.meta
- }
-
- override fun equals(other: Any?): Boolean = other is Image && other.uid == uid
-
- override fun hashCode(): Int = uid.hashCode()
-
- override fun toString(): String = "Image[uid=$uid,name=$name]"
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ClientServer.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ClientServer.kt
deleted file mode 100644
index f2929bf3..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ClientServer.kt
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2021 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.service.internal
-
-import org.opendc.compute.api.Flavor
-import org.opendc.compute.api.Image
-import org.opendc.compute.api.Server
-import org.opendc.compute.api.ServerState
-import org.opendc.compute.api.ServerWatcher
-import java.util.*
-
-/**
- * A [Server] implementation that is passed to clients but delegates its implementation to another class.
- */
-internal class ClientServer(private val delegate: Server) : Server, ServerWatcher {
- private val watchers = mutableListOf<ServerWatcher>()
-
- override val uid: UUID = delegate.uid
-
- override var name: String = delegate.name
- private set
-
- override var flavor: Flavor = delegate.flavor
- private set
-
- override var image: Image = delegate.image
- private set
-
- override var labels: Map<String, String> = delegate.labels.toMap()
- private set
-
- override var meta: Map<String, Any> = delegate.meta.toMap()
- private set
-
- override var state: ServerState = delegate.state
- private set
-
- override suspend fun start() {
- delegate.start()
- refresh()
- }
-
- override suspend fun stop() {
- delegate.stop()
- refresh()
- }
-
- override suspend fun delete() {
- delegate.delete()
- refresh()
- }
-
- override fun watch(watcher: ServerWatcher) {
- if (watchers.isEmpty()) {
- delegate.watch(this)
- }
-
- watchers += watcher
- }
-
- override fun unwatch(watcher: ServerWatcher) {
- watchers += watcher
-
- if (watchers.isEmpty()) {
- delegate.unwatch(this)
- }
- }
-
- override suspend fun refresh() {
- delegate.refresh()
-
- name = delegate.name
- flavor = delegate.flavor
- image = delegate.image
- labels = delegate.labels
- meta = delegate.meta
- state = delegate.state
- }
-
- override fun onStateChanged(server: Server, newState: ServerState) {
- val watchers = watchers
-
- for (watcher in watchers) {
- watcher.onStateChanged(this, newState)
- }
- }
-
- override fun equals(other: Any?): Boolean = other is Server && other.uid == uid
-
- override fun hashCode(): Int = uid.hashCode()
-
- override fun toString(): String = "Server[uid=$uid,name=$name,state=$state]"
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt
deleted file mode 100644
index 8af5f86e..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt
+++ /dev/null
@@ -1,500 +0,0 @@
-/*
- * Copyright (c) 2021 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.service.internal
-
-import io.opentelemetry.api.metrics.Meter
-import kotlinx.coroutines.*
-import mu.KotlinLogging
-import org.opendc.compute.api.*
-import org.opendc.compute.service.ComputeService
-import org.opendc.compute.service.driver.Host
-import org.opendc.compute.service.driver.HostListener
-import org.opendc.compute.service.driver.HostState
-import org.opendc.compute.service.scheduler.ComputeScheduler
-import org.opendc.utils.TimerScheduler
-import java.time.Clock
-import java.util.*
-import kotlin.coroutines.CoroutineContext
-import kotlin.math.max
-
-/**
- * Internal implementation of the OpenDC Compute service.
- *
- * @param context The [CoroutineContext] to use.
- * @param clock The clock instance to keep track of time.
- */
-internal class ComputeServiceImpl(
- private val context: CoroutineContext,
- private val clock: Clock,
- private val meter: Meter,
- private val scheduler: ComputeScheduler,
- private val schedulingQuantum: Long
-) : ComputeService, HostListener {
- /**
- * The [CoroutineScope] of the service bounded by the lifecycle of the service.
- */
- private val scope = CoroutineScope(context + Job())
-
- /**
- * The logger instance of this server.
- */
- private val logger = KotlinLogging.logger {}
-
- /**
- * The [Random] instance used to generate unique identifiers for the objects.
- */
- private val random = Random(0)
-
- /**
- * A mapping from host to host view.
- */
- private val hostToView = mutableMapOf<Host, HostView>()
-
- /**
- * The available hypervisors.
- */
- private val availableHosts: MutableSet<HostView> = mutableSetOf()
-
- /**
- * The servers that should be launched by the service.
- */
- private val queue: Deque<SchedulingRequest> = ArrayDeque()
-
- /**
- * The active servers in the system.
- */
- private val activeServers: MutableMap<Server, Host> = mutableMapOf()
-
- /**
- * The registered flavors for this compute service.
- */
- internal val flavors = mutableMapOf<UUID, InternalFlavor>()
-
- /**
- * The registered images for this compute service.
- */
- internal val images = mutableMapOf<UUID, InternalImage>()
-
- /**
- * The registered servers for this compute service.
- */
- private val servers = mutableMapOf<UUID, InternalServer>()
-
- private var maxCores = 0
- private var maxMemory = 0L
-
- /**
- * The number of servers that have been submitted to the service for provisioning.
- */
- private val _submittedServers = meter.longCounterBuilder("servers.submitted")
- .setDescription("Number of start requests")
- .setUnit("1")
- .build()
-
- /**
- * The number of servers that failed to be scheduled.
- */
- private val _unscheduledServers = meter.longCounterBuilder("servers.unscheduled")
- .setDescription("Number of unscheduled servers")
- .setUnit("1")
- .build()
-
- /**
- * The number of servers that are waiting to be provisioned.
- */
- private val _waitingServers = meter.longUpDownCounterBuilder("servers.waiting")
- .setDescription("Number of servers waiting to be provisioned")
- .setUnit("1")
- .build()
-
- /**
- * The number of servers that are waiting to be provisioned.
- */
- private val _runningServers = meter.longUpDownCounterBuilder("servers.active")
- .setDescription("Number of servers currently running")
- .setUnit("1")
- .build()
-
- /**
- * The number of servers that have finished running.
- */
- private val _finishedServers = meter.longCounterBuilder("servers.finished")
- .setDescription("Number of servers that finished running")
- .setUnit("1")
- .build()
-
- /**
- * The number of hosts registered at the compute service.
- */
- private val _hostCount = meter.longUpDownCounterBuilder("hosts.total")
- .setDescription("Number of hosts")
- .setUnit("1")
- .build()
-
- /**
- * The number of available hosts registered at the compute service.
- */
- private val _availableHostCount = meter.longUpDownCounterBuilder("hosts.available")
- .setDescription("Number of available hosts")
- .setUnit("1")
- .build()
-
- /**
- * The [TimerScheduler] to use for scheduling the scheduler cycles.
- */
- private var timerScheduler: TimerScheduler<Unit> = TimerScheduler(scope.coroutineContext, clock)
-
- override val hosts: Set<Host>
- get() = hostToView.keys
-
- override val hostCount: Int
- get() = hostToView.size
-
- override fun newClient(): ComputeClient {
- check(scope.isActive) { "Service is already closed" }
- return object : ComputeClient {
- private var isClosed: Boolean = false
-
- override suspend fun queryFlavors(): List<Flavor> {
- check(!isClosed) { "Client is already closed" }
-
- return flavors.values.map { ClientFlavor(it) }
- }
-
- override suspend fun findFlavor(id: UUID): Flavor? {
- check(!isClosed) { "Client is already closed" }
-
- return flavors[id]?.let { ClientFlavor(it) }
- }
-
- override suspend fun newFlavor(
- name: String,
- cpuCount: Int,
- memorySize: Long,
- labels: Map<String, String>,
- meta: Map<String, Any>
- ): Flavor {
- check(!isClosed) { "Client is already closed" }
-
- val uid = UUID(clock.millis(), random.nextLong())
- val flavor = InternalFlavor(
- this@ComputeServiceImpl,
- uid,
- name,
- cpuCount,
- memorySize,
- labels,
- meta
- )
-
- flavors[uid] = flavor
-
- return ClientFlavor(flavor)
- }
-
- override suspend fun queryImages(): List<Image> {
- check(!isClosed) { "Client is already closed" }
-
- return images.values.map { ClientImage(it) }
- }
-
- override suspend fun findImage(id: UUID): Image? {
- check(!isClosed) { "Client is already closed" }
-
- return images[id]?.let { ClientImage(it) }
- }
-
- override suspend fun newImage(name: String, labels: Map<String, String>, meta: Map<String, Any>): Image {
- check(!isClosed) { "Client is already closed" }
-
- val uid = UUID(clock.millis(), random.nextLong())
- val image = InternalImage(this@ComputeServiceImpl, uid, name, labels, meta)
-
- images[uid] = image
-
- return ClientImage(image)
- }
-
- override suspend fun newServer(
- name: String,
- image: Image,
- flavor: Flavor,
- labels: Map<String, String>,
- meta: Map<String, Any>,
- start: Boolean
- ): Server {
- check(!isClosed) { "Client is closed" }
-
- val uid = UUID(clock.millis(), random.nextLong())
- val server = InternalServer(
- this@ComputeServiceImpl,
- uid,
- name,
- requireNotNull(flavors[flavor.uid]) { "Unknown flavor" },
- requireNotNull(images[image.uid]) { "Unknown image" },
- labels.toMutableMap(),
- meta.toMutableMap()
- )
-
- servers[uid] = server
-
- if (start) {
- server.start()
- }
-
- return ClientServer(server)
- }
-
- override suspend fun findServer(id: UUID): Server? {
- check(!isClosed) { "Client is already closed" }
-
- return servers[id]?.let { ClientServer(it) }
- }
-
- override suspend fun queryServers(): List<Server> {
- check(!isClosed) { "Client is already closed" }
-
- return servers.values.map { ClientServer(it) }
- }
-
- override fun close() {
- isClosed = true
- }
-
- override fun toString(): String = "ComputeClient"
- }
- }
-
- override fun addHost(host: Host) {
- // Check if host is already known
- if (host in hostToView) {
- return
- }
-
- val hv = HostView(host)
- maxCores = max(maxCores, host.model.cpuCount)
- maxMemory = max(maxMemory, host.model.memorySize)
- hostToView[host] = hv
-
- if (host.state == HostState.UP) {
- _availableHostCount.add(1)
- availableHosts += hv
- }
-
- scheduler.addHost(hv)
- _hostCount.add(1)
- host.addListener(this)
- }
-
- override fun removeHost(host: Host) {
- val view = hostToView.remove(host)
- if (view != null) {
- if (availableHosts.remove(view)) {
- _availableHostCount.add(-1)
- }
- scheduler.removeHost(view)
- host.removeListener(this)
- _hostCount.add(-1)
- }
- }
-
- override fun close() {
- scope.cancel()
- }
-
- internal fun schedule(server: InternalServer): SchedulingRequest {
- logger.debug { "Enqueueing server ${server.uid} to be assigned to host." }
-
- val request = SchedulingRequest(server)
- queue.add(request)
- _submittedServers.add(1)
- _waitingServers.add(1)
- requestSchedulingCycle()
- return request
- }
-
- internal fun delete(flavor: InternalFlavor) {
- flavors.remove(flavor.uid)
- }
-
- internal fun delete(image: InternalImage) {
- images.remove(image.uid)
- }
-
- internal fun delete(server: InternalServer) {
- servers.remove(server.uid)
- }
-
- /**
- * Indicate that a new scheduling cycle is needed due to a change to the service's state.
- */
- private fun requestSchedulingCycle() {
- // Bail out in case we have already requested a new cycle or the queue is empty.
- if (timerScheduler.isTimerActive(Unit) || queue.isEmpty()) {
- return
- }
-
- // We assume that the provisioner runs at a fixed slot every time quantum (e.g t=0, t=60, t=120).
- // This is important because the slices of the VMs need to be aligned.
- // We calculate here the delay until the next scheduling slot.
- val delay = schedulingQuantum - (clock.millis() % schedulingQuantum)
-
- timerScheduler.startSingleTimer(Unit, delay) {
- doSchedule()
- }
- }
-
- /**
- * Run a single scheduling iteration.
- */
- private fun doSchedule() {
- while (queue.isNotEmpty()) {
- val request = queue.peek()
-
- if (request.isCancelled) {
- queue.poll()
- _waitingServers.add(-1)
- continue
- }
-
- val server = request.server
- val hv = scheduler.select(request.server)
- if (hv == null || !hv.host.canFit(server)) {
- logger.trace { "Server $server selected for scheduling but no capacity available for it at the moment" }
-
- if (server.flavor.memorySize > maxMemory || server.flavor.cpuCount > maxCores) {
- // Remove the incoming image
- queue.poll()
- _waitingServers.add(-1)
- _unscheduledServers.add(1)
-
- logger.warn("Failed to spawn $server: does not fit [${clock.millis()}]")
-
- server.state = ServerState.ERROR
- continue
- } else {
- break
- }
- }
-
- val host = hv.host
-
- // Remove request from queue
- queue.poll()
- _waitingServers.add(-1)
-
- logger.info { "Assigned server $server to host $host." }
-
- // Speculatively update the hypervisor view information to prevent other images in the queue from
- // deciding on stale values.
- hv.instanceCount++
- hv.provisionedCores += server.flavor.cpuCount
- hv.availableMemory -= server.flavor.memorySize // XXX Temporary hack
-
- scope.launch {
- try {
- server.host = host
- host.spawn(server)
- activeServers[server] = host
- } catch (e: Throwable) {
- logger.error("Failed to deploy VM", e)
-
- hv.instanceCount--
- hv.provisionedCores -= server.flavor.cpuCount
- hv.availableMemory += server.flavor.memorySize
- }
- }
- }
- }
-
- /**
- * A request to schedule an [InternalServer] onto one of the [Host]s.
- */
- internal data class SchedulingRequest(val server: InternalServer) {
- /**
- * A flag to indicate that the request is cancelled.
- */
- var isCancelled: Boolean = false
- }
-
- override fun onStateChanged(host: Host, newState: HostState) {
- when (newState) {
- HostState.UP -> {
- logger.debug { "[${clock.millis()}] Host ${host.uid} state changed: $newState" }
-
- val hv = hostToView[host]
- if (hv != null) {
- // Corner case for when the hypervisor already exists
- availableHosts += hv
- _availableHostCount.add(1)
- }
-
- // Re-schedule on the new machine
- requestSchedulingCycle()
- }
- HostState.DOWN -> {
- logger.debug { "[${clock.millis()}] Host ${host.uid} state changed: $newState" }
-
- val hv = hostToView[host] ?: return
- availableHosts -= hv
- _availableHostCount.add(-1)
-
- requestSchedulingCycle()
- }
- }
- }
-
- override fun onStateChanged(host: Host, server: Server, newState: ServerState) {
- require(server is InternalServer) { "Invalid server type passed to service" }
-
- if (server.host != host) {
- // This can happen when a server is rescheduled and started on another machine, while being deleted from
- // the old machine.
- return
- }
-
- server.state = newState
-
- if (newState == ServerState.RUNNING) {
- _runningServers.add(1)
- } else if (newState == ServerState.TERMINATED || newState == ServerState.DELETED) {
- logger.info { "[${clock.millis()}] Server ${server.uid} ${server.name} ${server.flavor} finished." }
-
- activeServers -= server
- _runningServers.add(-1)
- _finishedServers.add(1)
-
- val hv = hostToView[host]
- if (hv != null) {
- hv.provisionedCores -= server.flavor.cpuCount
- hv.instanceCount--
- hv.availableMemory += server.flavor.memorySize
- } else {
- logger.error { "Unknown host $host" }
- }
-
- // Try to reschedule if needed
- requestSchedulingCycle()
- }
- }
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/HostView.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/HostView.kt
deleted file mode 100644
index e2f33f11..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/HostView.kt
+++ /dev/null
@@ -1,44 +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.service.internal
-
-import org.opendc.compute.service.ComputeService
-import org.opendc.compute.service.driver.Host
-import java.util.UUID
-
-/**
- * A view of a [Host] as seen from the [ComputeService]
- */
-public class HostView(public val host: Host) {
- /**
- * The unique identifier of the host.
- */
- public val uid: UUID
- get() = host.uid
-
- public var instanceCount: Int = 0
- public var availableMemory: Long = host.model.memorySize
- public var provisionedCores: Int = 0
-
- override fun toString(): String = "HostView[host=$host]"
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/InternalFlavor.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/InternalFlavor.kt
deleted file mode 100644
index b8fb6279..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/InternalFlavor.kt
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2021 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.service.internal
-
-import org.opendc.compute.api.Flavor
-import java.util.*
-
-/**
- * Internal stateful representation of a [Flavor].
- */
-internal class InternalFlavor(
- private val service: ComputeServiceImpl,
- override val uid: UUID,
- name: String,
- cpuCount: Int,
- memorySize: Long,
- labels: Map<String, String>,
- meta: Map<String, Any>
-) : Flavor {
- override var name: String = name
- private set
-
- override var cpuCount: Int = cpuCount
- private set
-
- override var memorySize: Long = memorySize
- private set
-
- override val labels: MutableMap<String, String> = labels.toMutableMap()
-
- override val meta: MutableMap<String, Any> = meta.toMutableMap()
-
- override suspend fun refresh() {
- // No-op: this object is the source-of-truth
- }
-
- override suspend fun delete() {
- service.delete(this)
- }
-
- override fun equals(other: Any?): Boolean = other is Flavor && uid == other.uid
-
- override fun hashCode(): Int = uid.hashCode()
-
- override fun toString(): String = "Flavor[uid=$uid,name=$name]"
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/InternalImage.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/InternalImage.kt
deleted file mode 100644
index d9ed5896..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/InternalImage.kt
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2021 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.service.internal
-
-import org.opendc.compute.api.Image
-import java.util.*
-
-/**
- * Internal stateful representation of an [Image].
- */
-internal class InternalImage(
- private val service: ComputeServiceImpl,
- override val uid: UUID,
- override val name: String,
- labels: Map<String, String>,
- meta: Map<String, Any>
-) : Image {
-
- override val labels: MutableMap<String, String> = labels.toMutableMap()
-
- override val meta: MutableMap<String, Any> = meta.toMutableMap()
-
- override suspend fun refresh() {
- // No-op: this object is the source-of-truth
- }
-
- override suspend fun delete() {
- service.delete(this)
- }
-
- override fun equals(other: Any?): Boolean = other is Image && uid == other.uid
-
- override fun hashCode(): Int = uid.hashCode()
-
- override fun toString(): String = "Image[uid=$uid,name=$name]"
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/InternalServer.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/InternalServer.kt
deleted file mode 100644
index d9d0f3fc..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/InternalServer.kt
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (c) 2021 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.service.internal
-
-import mu.KotlinLogging
-import org.opendc.compute.api.*
-import org.opendc.compute.service.driver.Host
-import java.util.UUID
-
-/**
- * Internal implementation of the [Server] interface.
- */
-internal class InternalServer(
- private val service: ComputeServiceImpl,
- override val uid: UUID,
- override val name: String,
- override val flavor: InternalFlavor,
- override val image: InternalImage,
- override val labels: MutableMap<String, String>,
- override val meta: MutableMap<String, Any>
-) : Server {
- /**
- * The logger instance of this server.
- */
- private val logger = KotlinLogging.logger {}
-
- /**
- * The watchers of this server object.
- */
- private val watchers = mutableListOf<ServerWatcher>()
-
- /**
- * The [Host] that has been assigned to host the server.
- */
- internal var host: Host? = null
-
- /**
- * The current scheduling request.
- */
- private var request: ComputeServiceImpl.SchedulingRequest? = null
-
- override suspend fun start() {
- when (state) {
- ServerState.RUNNING -> {
- logger.debug { "User tried to start server but server is already running" }
- return
- }
- ServerState.PROVISIONING -> {
- logger.debug { "User tried to start server but request is already pending: doing nothing" }
- return
- }
- ServerState.DELETED -> {
- logger.warn { "User tried to start terminated server" }
- throw IllegalStateException("Server is terminated")
- }
- else -> {
- logger.info { "User requested to start server $uid" }
- state = ServerState.PROVISIONING
- assert(request == null) { "Scheduling request already active" }
- request = service.schedule(this)
- }
- }
- }
-
- override suspend fun stop() {
- when (state) {
- ServerState.PROVISIONING -> {
- cancelProvisioningRequest()
- state = ServerState.TERMINATED
- }
- ServerState.RUNNING, ServerState.ERROR -> {
- val host = checkNotNull(host) { "Server not running" }
- host.stop(this)
- }
- ServerState.TERMINATED, ServerState.DELETED -> {} // No work needed
- }
- }
-
- override suspend fun delete() {
- when (state) {
- ServerState.PROVISIONING, ServerState.TERMINATED -> {
- cancelProvisioningRequest()
- service.delete(this)
- state = ServerState.DELETED
- }
- ServerState.RUNNING, ServerState.ERROR -> {
- val host = checkNotNull(host) { "Server not running" }
- host.delete(this)
- service.delete(this)
- state = ServerState.DELETED
- }
- else -> {} // No work needed
- }
- }
-
- override fun watch(watcher: ServerWatcher) {
- watchers += watcher
- }
-
- override fun unwatch(watcher: ServerWatcher) {
- watchers -= watcher
- }
-
- override suspend fun refresh() {
- // No-op: this object is the source-of-truth
- }
-
- override var state: ServerState = ServerState.TERMINATED
- set(value) {
- if (value != field) {
- watchers.forEach { it.onStateChanged(this, value) }
- }
-
- field = value
- }
-
- /**
- * Cancel the provisioning request if active.
- */
- private fun cancelProvisioningRequest() {
- val request = request
- if (request != null) {
- this.request = null
- request.isCancelled = true
- }
- }
-
- override fun equals(other: Any?): Boolean = other is Server && uid == other.uid
-
- override fun hashCode(): Int = uid.hashCode()
-
- override fun toString(): String = "Server[uid=$uid,state=$state]"
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ComputeScheduler.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ComputeScheduler.kt
deleted file mode 100644
index a2ab3a2e..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ComputeScheduler.kt
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2021 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.service.scheduler
-
-import org.opendc.compute.api.Server
-import org.opendc.compute.service.ComputeService
-import org.opendc.compute.service.internal.HostView
-
-/**
- * A generic scheduler interface used by the [ComputeService] to select hosts to place [Server]s on.
- */
-public interface ComputeScheduler {
- /**
- * Register the specified [host] to be used for scheduling.
- */
- public fun addHost(host: HostView)
-
- /**
- * Remove the specified [host] to be removed from the scheduling pool.
- */
- public fun removeHost(host: HostView)
-
- /**
- * Select a host for the specified [server].
- *
- * @param server The server to select a host for.
- * @return The host to schedule the server on or `null` if no server is available.
- */
- public fun select(server: Server): HostView?
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt
deleted file mode 100644
index 0fd5b2a4..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2021 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.service.scheduler
-
-import org.opendc.compute.api.Server
-import org.opendc.compute.service.internal.HostView
-import org.opendc.compute.service.scheduler.filters.HostFilter
-import org.opendc.compute.service.scheduler.weights.HostWeigher
-
-/**
- * A [ComputeScheduler] implementation that uses filtering and weighing passes to select
- * the host to schedule a [Server] on.
- *
- * This implementation is based on the filter scheduler from OpenStack Nova.
- * See: https://docs.openstack.org/nova/latest/user/filter-scheduler.html
- */
-public class FilterScheduler(private val filters: List<HostFilter>, private val weighers: List<Pair<HostWeigher, Double>>) : ComputeScheduler {
- /**
- * The pool of hosts available to the scheduler.
- */
- private val hosts = mutableListOf<HostView>()
-
- override fun addHost(host: HostView) {
- hosts.add(host)
- }
-
- override fun removeHost(host: HostView) {
- hosts.remove(host)
- }
-
- override fun select(server: Server): HostView? {
- return hosts.asSequence()
- .filter { host ->
- for (filter in filters) {
- if (!filter.test(host, server))
- return@filter false
- }
-
- true
- }
- .sortedByDescending { host ->
- weighers.sumByDouble { (weigher, factor) -> weigher.getWeight(host, server) * factor }
- }
- .firstOrNull()
- }
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ReplayScheduler.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ReplayScheduler.kt
deleted file mode 100644
index 284c1f91..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ReplayScheduler.kt
+++ /dev/null
@@ -1,64 +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.service.scheduler
-
-import mu.KotlinLogging
-import org.opendc.compute.api.Server
-import org.opendc.compute.service.internal.HostView
-
-/**
- * Policy replaying VM-cluster assignment.
- *
- * Within each cluster, the active servers on each node determine which node gets
- * assigned the VM image.
- */
-public class ReplayScheduler(private val vmPlacements: Map<String, String>) : ComputeScheduler {
- private val logger = KotlinLogging.logger {}
-
- /**
- * The pool of hosts available to the scheduler.
- */
- private val hosts = mutableListOf<HostView>()
-
- override fun addHost(host: HostView) {
- hosts.add(host)
- }
-
- override fun removeHost(host: HostView) {
- hosts.remove(host)
- }
-
- 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 machinesInCluster = hosts.filter { it.host.name.contains(clusterName) }
-
- if (machinesInCluster.isEmpty()) {
- logger.info { "Could not find any machines belonging to cluster $clusterName for image ${server.name}, assigning randomly." }
- return hosts.maxByOrNull { it.availableMemory }
- }
-
- return machinesInCluster.maxByOrNull { it.availableMemory }
- ?: throw IllegalStateException("Cloud not find any machine and could not randomly assign")
- }
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeCapabilitiesFilter.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeCapabilitiesFilter.kt
deleted file mode 100644
index 072440c5..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeCapabilitiesFilter.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2021 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.service.scheduler.filters
-
-import org.opendc.compute.api.Server
-import org.opendc.compute.service.internal.HostView
-
-/**
- * A [HostFilter] that checks whether the capabilities provided by the host satisfies the requirements of the server
- * flavor.
- */
-public class ComputeCapabilitiesFilter : HostFilter {
- override fun test(host: HostView, server: Server): Boolean {
- val fitsMemory = host.availableMemory >= server.flavor.memorySize
- val fitsCpu = host.host.model.cpuCount >= server.flavor.cpuCount
- return fitsMemory && fitsCpu
- }
-
- override fun toString(): String = "ComputeCapabilitiesFilter"
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeFilter.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeFilter.kt
deleted file mode 100644
index fb842415..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeFilter.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2021 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.service.scheduler.filters
-
-import org.opendc.compute.api.Server
-import org.opendc.compute.service.driver.HostState
-import org.opendc.compute.service.internal.HostView
-
-/**
- * A [HostFilter] that filters on active hosts.
- */
-public class ComputeFilter : HostFilter {
- override fun test(host: HostView, server: Server): Boolean {
- return host.host.state == HostState.UP
- }
-
- override fun toString(): String = "ComputeFilter"
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/HostFilter.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/HostFilter.kt
deleted file mode 100644
index 9e909ca6..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/HostFilter.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2021 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.service.scheduler.filters
-
-import org.opendc.compute.api.Server
-import org.opendc.compute.service.internal.HostView
-import org.opendc.compute.service.scheduler.FilterScheduler
-
-/**
- * A filter used by the [FilterScheduler] to filter hosts.
- */
-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
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/InstanceCountFilter.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/InstanceCountFilter.kt
deleted file mode 100644
index ed6674b1..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/InstanceCountFilter.kt
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2021 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.service.scheduler.filters
-
-import org.opendc.compute.api.Server
-import org.opendc.compute.service.internal.HostView
-
-/**
- * A [HostFilter] that filters hosts based on the number of instances on the host.
- *
- * @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 {
- return host.instanceCount < limit
- }
-
- override fun toString(): String = "InstanceCountFilter[limit=$limit]"
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/CoreMemoryWeigher.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/CoreMemoryWeigher.kt
deleted file mode 100644
index 12e6510e..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/CoreMemoryWeigher.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2021 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.service.scheduler.weights
-
-import org.opendc.compute.api.Server
-import org.opendc.compute.service.internal.HostView
-
-/**
- * A [HostWeigher] that weighs the hosts based on the available memory per core on the host.
- */
-public class CoreMemoryWeigher : HostWeigher {
- override fun getWeight(host: HostView, server: Server): Double {
- return host.availableMemory.toDouble() / host.host.model.cpuCount
- }
-
- override fun toString(): String = "CoreMemoryWeigher"
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/HostWeigher.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/HostWeigher.kt
deleted file mode 100644
index d48ee9e0..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/HostWeigher.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2021 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.service.scheduler.weights
-
-import org.opendc.compute.api.Server
-import org.opendc.compute.service.internal.HostView
-import org.opendc.compute.service.scheduler.FilterScheduler
-
-/**
- * An interface used by the [FilterScheduler] to weigh the pool of host for a scheduling request.
- */
-public fun interface HostWeigher {
- /**
- * Obtain the weight of the specified [host] when scheduling the specified [server].
- */
- public fun getWeight(host: HostView, server: Server): Double
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/InstanceCountWeigher.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/InstanceCountWeigher.kt
deleted file mode 100644
index 2ef733e5..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/InstanceCountWeigher.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2021 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.service.scheduler.weights
-
-import org.opendc.compute.api.Server
-import org.opendc.compute.service.internal.HostView
-
-/**
- * A [HostWeigher] that weighs the hosts based on the number of instances on the host.
- */
-public class InstanceCountWeigher : HostWeigher {
- override fun getWeight(host: HostView, server: Server): Double {
- return host.instanceCount.toDouble()
- }
-
- override fun toString(): String = "InstanceCountWeigher"
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/MemoryWeigher.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/MemoryWeigher.kt
deleted file mode 100644
index 115d8e4d..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/MemoryWeigher.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2021 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.service.scheduler.weights
-
-import org.opendc.compute.api.Server
-import org.opendc.compute.service.internal.HostView
-
-/**
- * A [HostWeigher] that weighs the hosts based on the available memory on the host.
- */
-public class MemoryWeigher : HostWeigher {
- override fun getWeight(host: HostView, server: Server): Double {
- return host.availableMemory.toDouble()
- }
-
- override fun toString(): String = "MemoryWeigher"
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/ProvisionedCoresWeigher.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/ProvisionedCoresWeigher.kt
deleted file mode 100644
index df5bcd6e..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/ProvisionedCoresWeigher.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2021 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.service.scheduler.weights
-
-import org.opendc.compute.api.Server
-import org.opendc.compute.service.internal.HostView
-
-/**
- * A [HostWeigher] that weighs the hosts based on the number of provisioned cores on the host.
- */
-public class ProvisionedCoresWeigher : HostWeigher {
- override fun getWeight(host: HostView, server: Server): Double {
- return host.provisionedCores.toDouble()
- }
-
- override fun toString(): String = "ProvisionedCoresWeigher"
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/RandomWeigher.kt b/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/RandomWeigher.kt
deleted file mode 100644
index 1615df3a..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/RandomWeigher.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2021 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.service.scheduler.weights
-
-import org.opendc.compute.api.Server
-import org.opendc.compute.service.internal.HostView
-import java.util.*
-
-/**
- * A [HostWeigher] that assigns random weights to each host every selection.
- */
-public class RandomWeigher(private val random: Random) : HostWeigher {
- override fun getWeight(host: HostView, server: Server): Double = random.nextDouble()
-
- override fun toString(): String = "RandomWeigher"
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt b/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt
deleted file mode 100644
index a6258845..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- * Copyright (c) 2021 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.service
-
-import io.mockk.*
-import io.opentelemetry.api.metrics.MeterProvider
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.delay
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertNull
-import org.junit.jupiter.api.BeforeEach
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.assertThrows
-import org.opendc.compute.api.*
-import org.opendc.compute.service.driver.Host
-import org.opendc.compute.service.driver.HostListener
-import org.opendc.compute.service.driver.HostModel
-import org.opendc.compute.service.driver.HostState
-import org.opendc.compute.service.scheduler.FilterScheduler
-import org.opendc.compute.service.scheduler.filters.ComputeCapabilitiesFilter
-import org.opendc.compute.service.scheduler.filters.ComputeFilter
-import org.opendc.compute.service.scheduler.weights.MemoryWeigher
-import org.opendc.simulator.core.SimulationCoroutineScope
-import org.opendc.simulator.core.runBlockingSimulation
-import java.util.*
-
-/**
- * Test suite for the [ComputeService] interface.
- */
-@OptIn(ExperimentalCoroutinesApi::class)
-internal class ComputeServiceTest {
- lateinit var scope: SimulationCoroutineScope
- lateinit var service: ComputeService
-
- @BeforeEach
- fun setUp() {
- scope = SimulationCoroutineScope()
- val clock = scope.clock
- val computeScheduler = FilterScheduler(
- filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()),
- weighers = listOf(MemoryWeigher() to -1.0)
- )
- val meter = MeterProvider.noop().get("opendc-compute")
- service = ComputeService(scope.coroutineContext, clock, meter, computeScheduler)
- }
-
- @Test
- fun testClientClose() = scope.runBlockingSimulation {
- val client = service.newClient()
-
- assertEquals(emptyList<Flavor>(), client.queryFlavors())
- assertEquals(emptyList<Image>(), client.queryImages())
- assertEquals(emptyList<Server>(), client.queryServers())
-
- client.close()
-
- 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.newFlavor("test", 1, 2) }
- assertThrows<IllegalStateException> { client.newImage("test") }
- assertThrows<IllegalStateException> { client.newServer("test", mockk(), mockk()) }
- }
-
- @Test
- fun testClientCreate() = scope.runBlockingSimulation {
- 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.runBlockingSimulation {
- service.close()
- assertThrows<IllegalStateException> {
- service.newClient()
- }
- }
-
- @Test
- fun testAddHost() = scope.runBlockingSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
-
- every { host.model } returns HostModel(4, 2048)
- every { host.state } returns HostState.UP
-
- assertEquals(0, service.hostCount)
- assertEquals(emptySet<Host>(), service.hosts)
-
- service.addHost(host)
-
- verify(exactly = 1) { host.addListener(any()) }
-
- assertEquals(1, service.hostCount)
- assertEquals(1, service.hosts.size)
-
- service.removeHost(host)
-
- verify(exactly = 1) { host.removeListener(any()) }
- }
-
- @Test
- fun testAddHostDouble() = scope.runBlockingSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
-
- every { host.model } returns HostModel(4, 2048)
- every { host.state } returns HostState.DOWN
-
- assertEquals(0, service.hostCount)
- assertEquals(emptySet<Host>(), service.hosts)
-
- service.addHost(host)
- service.addHost(host)
-
- verify(exactly = 1) { host.addListener(any()) }
- }
-
- @Test
- fun testServerStartWithoutEnoughCpus() = scope.runBlockingSimulation {
- 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(5 * 60 * 1000)
- server.refresh()
- assertEquals(ServerState.ERROR, server.state)
- }
-
- @Test
- fun testServerStartWithoutEnoughMemory() = scope.runBlockingSimulation {
- 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(5 * 60 * 1000)
- server.refresh()
- assertEquals(ServerState.ERROR, server.state)
- }
-
- @Test
- fun testServerStartWithoutEnoughResources() = scope.runBlockingSimulation {
- 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(5 * 60 * 1000)
- server.refresh()
- assertEquals(ServerState.ERROR, server.state)
- }
-
- @Test
- fun testServerCancelRequest() = scope.runBlockingSimulation {
- 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(5 * 60 * 1000)
- server.refresh()
- assertEquals(ServerState.TERMINATED, server.state)
- }
-
- @Test
- fun testServerCannotFitOnHost() = scope.runBlockingSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
-
- every { host.model } returns HostModel(4, 2048)
- every { host.state } returns HostState.UP
- every { host.canFit(any()) } returns false
-
- 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(10 * 60 * 1000)
- server.refresh()
- assertEquals(ServerState.PROVISIONING, server.state)
-
- verify { host.canFit(server) }
- }
-
- @Test
- fun testHostAvailableAfterSomeTime() = scope.runBlockingSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
- val listeners = mutableListOf<HostListener>()
-
- every { host.uid } returns UUID.randomUUID()
- every { host.model } returns HostModel(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)
-
- 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(5 * 60 * 1000)
-
- every { host.state } returns HostState.UP
- listeners.forEach { it.onStateChanged(host, HostState.UP) }
-
- delay(5 * 60 * 1000)
- server.refresh()
- assertEquals(ServerState.PROVISIONING, server.state)
-
- verify { host.canFit(server) }
- }
-
- @Test
- fun testHostUnavailableAfterSomeTime() = scope.runBlockingSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
- val listeners = mutableListOf<HostListener>()
-
- every { host.uid } returns UUID.randomUUID()
- every { host.model } returns HostModel(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)
-
- 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(5 * 60 * 1000)
-
- every { host.state } returns HostState.DOWN
- listeners.forEach { it.onStateChanged(host, HostState.DOWN) }
-
- server.start()
- delay(5 * 60 * 1000)
- server.refresh()
- assertEquals(ServerState.PROVISIONING, server.state)
-
- verify(exactly = 0) { host.canFit(server) }
- }
-
- @Test
- fun testServerInvalidType() = scope.runBlockingSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
- val listeners = mutableListOf<HostListener>()
-
- every { host.uid } returns UUID.randomUUID()
- every { host.model } returns HostModel(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)
-
- 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)
-
- assertThrows<IllegalArgumentException> {
- listeners.forEach { it.onStateChanged(host, server, ServerState.RUNNING) }
- }
- }
-
- @Test
- fun testServerDeploy() = scope.runBlockingSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
- val listeners = mutableListOf<HostListener>()
-
- every { host.uid } returns UUID.randomUUID()
- every { host.model } returns HostModel(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)
-
- 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)
-
- // Start server
- server.start()
- delay(5 * 60 * 1000)
- coVerify { host.spawn(capture(slot), true) }
-
- listeners.forEach { it.onStateChanged(host, slot.captured, ServerState.RUNNING) }
-
- server.refresh()
- assertEquals(ServerState.RUNNING, server.state)
-
- verify { watcher.onStateChanged(server, ServerState.RUNNING) }
-
- // Stop server
- listeners.forEach { it.onStateChanged(host, slot.captured, ServerState.TERMINATED) }
-
- server.refresh()
- assertEquals(ServerState.TERMINATED, server.state)
-
- verify { watcher.onStateChanged(server, ServerState.TERMINATED) }
- }
-
- @Test
- fun testServerDeployFailure() = scope.runBlockingSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
- val listeners = mutableListOf<HostListener>()
-
- every { host.uid } returns UUID.randomUUID()
- every { host.model } returns HostModel(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(), true) } 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(5 * 60 * 1000)
-
- server.refresh()
- assertEquals(ServerState.PROVISIONING, server.state)
- }
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalFlavorTest.kt b/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalFlavorTest.kt
deleted file mode 100644
index 18d698c6..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalFlavorTest.kt
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2021 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.service
-
-import io.mockk.*
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertNotEquals
-import org.junit.jupiter.api.Test
-import org.opendc.compute.api.Flavor
-import org.opendc.compute.service.internal.ComputeServiceImpl
-import org.opendc.compute.service.internal.InternalFlavor
-import java.util.*
-
-/**
- * Test suite for the [InternalFlavor] implementation.
- */
-class InternalFlavorTest {
- @Test
- fun testEquality() {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val a = InternalFlavor(service, uid, "test", 1, 1024, mutableMapOf(), mutableMapOf())
- val b = InternalFlavor(service, uid, "test", 1, 1024, mutableMapOf(), mutableMapOf())
-
- assertEquals(a, b)
- }
-
- @Test
- fun testEqualityWithDifferentType() {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val a = InternalFlavor(service, uid, "test", 1, 1024, mutableMapOf(), mutableMapOf())
-
- val b = mockk<Flavor>(relaxUnitFun = true)
- every { b.uid } returns uid
-
- assertEquals(a, b)
- }
-
- @Test
- fun testInequalityWithDifferentType() {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val a = InternalFlavor(service, uid, "test", 1, 1024, mutableMapOf(), mutableMapOf())
-
- val b = mockk<Flavor>(relaxUnitFun = true)
- every { b.uid } returns UUID.randomUUID()
-
- assertNotEquals(a, b)
- }
-
- @Test
- fun testInequalityWithIncorrectType() {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val a = InternalFlavor(service, uid, "test", 1, 1024, mutableMapOf(), mutableMapOf())
-
- assertNotEquals(a, Unit)
- }
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalImageTest.kt b/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalImageTest.kt
deleted file mode 100644
index e1cb0128..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalImageTest.kt
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2021 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.service
-
-import io.mockk.*
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertNotEquals
-import org.junit.jupiter.api.Test
-import org.opendc.compute.api.Image
-import org.opendc.compute.service.internal.ComputeServiceImpl
-import org.opendc.compute.service.internal.InternalFlavor
-import org.opendc.compute.service.internal.InternalImage
-import java.util.*
-
-/**
- * Test suite for the [InternalFlavor] implementation.
- */
-class InternalImageTest {
- @Test
- fun testEquality() {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val a = InternalImage(service, uid, "test", mutableMapOf(), mutableMapOf())
- val b = InternalImage(service, uid, "test", mutableMapOf(), mutableMapOf())
-
- assertEquals(a, b)
- }
-
- @Test
- fun testEqualityWithDifferentType() {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val a = InternalImage(service, uid, "test", mutableMapOf(), mutableMapOf())
-
- val b = mockk<Image>(relaxUnitFun = true)
- every { b.uid } returns uid
-
- assertEquals(a, b)
- }
-
- @Test
- fun testInequalityWithDifferentType() {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val a = InternalImage(service, uid, "test", mutableMapOf(), mutableMapOf())
-
- val b = mockk<Image>(relaxUnitFun = true)
- every { b.uid } returns UUID.randomUUID()
-
- assertNotEquals(a, b)
- }
-
- @Test
- fun testInequalityWithIncorrectType() {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val a = InternalImage(service, uid, "test", mutableMapOf(), mutableMapOf())
-
- assertNotEquals(a, Unit)
- }
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalServerTest.kt b/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalServerTest.kt
deleted file mode 100644
index 20ea8d20..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/InternalServerTest.kt
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Copyright (c) 2021 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.service
-
-import io.mockk.*
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.yield
-import org.junit.jupiter.api.Assertions.*
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.assertThrows
-import org.opendc.compute.api.Server
-import org.opendc.compute.api.ServerState
-import org.opendc.compute.service.driver.Host
-import org.opendc.compute.service.internal.ComputeServiceImpl
-import org.opendc.compute.service.internal.InternalFlavor
-import org.opendc.compute.service.internal.InternalImage
-import org.opendc.compute.service.internal.InternalServer
-import org.opendc.simulator.core.runBlockingSimulation
-import java.util.*
-
-/**
- * Test suite for the [InternalServer] implementation.
- */
-@OptIn(ExperimentalCoroutinesApi::class)
-class InternalServerTest {
- @Test
- fun testEquality() {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val a = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
- val b = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
-
- assertEquals(a, b)
- }
-
- @Test
- fun testEqualityWithDifferentType() {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val a = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
-
- val b = mockk<Server>(relaxUnitFun = true)
- every { b.uid } returns uid
-
- assertEquals(a, b)
- }
-
- @Test
- fun testInequalityWithDifferentType() {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val a = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
-
- val b = mockk<Server>(relaxUnitFun = true)
- every { b.uid } returns UUID.randomUUID()
-
- assertNotEquals(a, b)
- }
-
- @Test
- fun testInequalityWithIncorrectType() {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val a = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
-
- assertNotEquals(a, Unit)
- }
-
- @Test
- fun testStartTerminatedServer() = runBlockingSimulation {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
-
- every { service.schedule(any()) } answers { ComputeServiceImpl.SchedulingRequest(it.invocation.args[0] as InternalServer) }
-
- server.start()
-
- verify(exactly = 1) { service.schedule(server) }
- assertEquals(ServerState.PROVISIONING, server.state)
- }
-
- @Test
- fun testStartDeletedServer() = runBlockingSimulation {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
-
- server.state = ServerState.DELETED
-
- assertThrows<IllegalStateException> { server.start() }
- }
-
- @Test
- fun testStartProvisioningServer() = runBlockingSimulation {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
-
- server.state = ServerState.PROVISIONING
-
- server.start()
-
- assertEquals(ServerState.PROVISIONING, server.state)
- }
-
- @Test
- fun testStartRunningServer() = runBlockingSimulation {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
-
- server.state = ServerState.RUNNING
-
- server.start()
-
- assertEquals(ServerState.RUNNING, server.state)
- }
-
- @Test
- fun testStopProvisioningServer() = runBlockingSimulation {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
- val request = ComputeServiceImpl.SchedulingRequest(server)
-
- every { service.schedule(any()) } returns request
-
- server.start()
- server.stop()
-
- assertTrue(request.isCancelled)
- assertEquals(ServerState.TERMINATED, server.state)
- }
-
- @Test
- fun testStopTerminatedServer() = runBlockingSimulation {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
-
- server.state = ServerState.TERMINATED
- server.stop()
-
- assertEquals(ServerState.TERMINATED, server.state)
- }
-
- @Test
- fun testStopDeletedServer() = runBlockingSimulation {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
-
- server.state = ServerState.DELETED
- server.stop()
-
- assertEquals(ServerState.DELETED, server.state)
- }
-
- @Test
- fun testStopRunningServer() = runBlockingSimulation {
- val service = mockk<ComputeServiceImpl>()
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
- val host = mockk<Host>(relaxUnitFun = true)
-
- server.state = ServerState.RUNNING
- server.host = host
- server.stop()
- yield()
-
- coVerify { host.stop(server) }
- }
-
- @Test
- fun testDeleteProvisioningServer() = runBlockingSimulation {
- val service = mockk<ComputeServiceImpl>(relaxUnitFun = true)
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
- val request = ComputeServiceImpl.SchedulingRequest(server)
-
- every { service.schedule(any()) } returns request
-
- server.start()
- server.delete()
-
- assertTrue(request.isCancelled)
- assertEquals(ServerState.DELETED, server.state)
- verify { service.delete(server) }
- }
-
- @Test
- fun testDeleteTerminatedServer() = runBlockingSimulation {
- val service = mockk<ComputeServiceImpl>(relaxUnitFun = true)
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
-
- server.state = ServerState.TERMINATED
- server.delete()
-
- assertEquals(ServerState.DELETED, server.state)
-
- verify { service.delete(server) }
- }
-
- @Test
- fun testDeleteDeletedServer() = runBlockingSimulation {
- val service = mockk<ComputeServiceImpl>(relaxUnitFun = true)
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
-
- server.state = ServerState.DELETED
- server.delete()
-
- assertEquals(ServerState.DELETED, server.state)
- }
-
- @Test
- fun testDeleteRunningServer() = runBlockingSimulation {
- val service = mockk<ComputeServiceImpl>(relaxUnitFun = true)
- val uid = UUID.randomUUID()
- val flavor = mockk<InternalFlavor>()
- val image = mockk<InternalImage>()
- val server = InternalServer(service, uid, "test", flavor, image, mutableMapOf(), mutableMapOf())
- val host = mockk<Host>(relaxUnitFun = true)
-
- server.state = ServerState.RUNNING
- server.host = host
- server.delete()
- yield()
-
- coVerify { host.delete(server) }
- verify { service.delete(server) }
- }
-}
diff --git a/simulator/opendc-compute/opendc-compute-service/src/test/resources/log4j2.xml b/simulator/opendc-compute/opendc-compute-service/src/test/resources/log4j2.xml
deleted file mode 100644
index 0dfb75f2..00000000
--- a/simulator/opendc-compute/opendc-compute-service/src/test/resources/log4j2.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2021 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.
- -->
-
-<Configuration status="WARN" packages="org.apache.logging.log4j.core">
- <Appenders>
- <Console name="Console" target="SYSTEM_OUT">
- <PatternLayout pattern="%d{HH:mm:ss.SSS} [%highlight{%-5level}] %logger{36} - %msg%n" disableAnsi="false"/>
- </Console>
- </Appenders>
- <Loggers>
- <Logger name="org.opendc" level="trace" additivity="false">
- <AppenderRef ref="Console"/>
- </Logger>
- <Root level="info">
- <AppenderRef ref="Console"/>
- </Root>
- </Loggers>
-</Configuration>
diff --git a/simulator/opendc-compute/opendc-compute-simulator/build.gradle.kts b/simulator/opendc-compute/opendc-compute-simulator/build.gradle.kts
deleted file mode 100644
index 3bf8a114..00000000
--- a/simulator/opendc-compute/opendc-compute-simulator/build.gradle.kts
+++ /dev/null
@@ -1,43 +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.
- */
-
-description = "Simulator for OpenDC Compute"
-
-/* Build configuration */
-plugins {
- `kotlin-library-conventions`
- `testing-conventions`
- `jacoco-conventions`
-}
-
-dependencies {
- api(platform(project(":opendc-platform")))
- api(project(":opendc-compute:opendc-compute-service"))
- api(project(":opendc-simulator:opendc-simulator-compute"))
- api(project(":opendc-simulator:opendc-simulator-failures"))
- implementation(project(":opendc-utils"))
- implementation("io.github.microutils:kotlin-logging")
-
- testImplementation(project(":opendc-simulator:opendc-simulator-core"))
- testImplementation(project(":opendc-telemetry:opendc-telemetry-sdk"))
- testRuntimeOnly("org.slf4j:slf4j-simple:${versions.slf4j}")
-}
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt
deleted file mode 100644
index 6d87e444..00000000
--- a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt
+++ /dev/null
@@ -1,423 +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 io.opentelemetry.api.metrics.Meter
-import io.opentelemetry.api.metrics.common.Labels
-import kotlinx.coroutines.*
-import mu.KotlinLogging
-import org.opendc.compute.api.Flavor
-import org.opendc.compute.api.Server
-import org.opendc.compute.api.ServerState
-import org.opendc.compute.service.driver.*
-import org.opendc.simulator.compute.*
-import org.opendc.simulator.compute.cpufreq.PerformanceScalingGovernor
-import org.opendc.simulator.compute.cpufreq.ScalingDriver
-import org.opendc.simulator.compute.cpufreq.ScalingGovernor
-import org.opendc.simulator.compute.cpufreq.SimpleScalingDriver
-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.power.ConstantPowerModel
-import org.opendc.simulator.compute.power.PowerModel
-import org.opendc.simulator.failures.FailureDomain
-import java.time.Clock
-import java.util.*
-import kotlin.coroutines.CoroutineContext
-import kotlin.coroutines.resume
-
-/**
- * A [Host] that is simulates virtual machines on a physical machine using [SimHypervisor].
- */
-public class SimHost(
- override val uid: UUID,
- override val name: String,
- model: SimMachineModel,
- override val meta: Map<String, Any>,
- context: CoroutineContext,
- clock: Clock,
- meter: Meter,
- hypervisor: SimHypervisorProvider,
- scalingGovernor: ScalingGovernor,
- scalingDriver: ScalingDriver,
- private val mapper: SimWorkloadMapper = SimMetaWorkloadMapper(),
-) : Host, FailureDomain, AutoCloseable {
-
- public constructor(
- uid: UUID,
- name: String,
- model: SimMachineModel,
- meta: Map<String, Any>,
- context: CoroutineContext,
- clock: Clock,
- meter: Meter,
- hypervisor: SimHypervisorProvider,
- powerModel: PowerModel = ConstantPowerModel(0.0),
- mapper: SimWorkloadMapper = SimMetaWorkloadMapper(),
- ) : this(uid, name, model, meta, context, clock, meter, hypervisor, PerformanceScalingGovernor(), SimpleScalingDriver(powerModel), mapper)
-
- /**
- * The [CoroutineScope] of the host bounded by the lifecycle of the host.
- */
- override val scope: CoroutineScope = CoroutineScope(context + Job())
-
- /**
- * The logger instance of this server.
- */
- private val logger = KotlinLogging.logger {}
-
- /**
- * The event listeners registered with this host.
- */
- private val listeners = mutableListOf<HostListener>()
-
- /**
- * Current total memory use of the images on this hypervisor.
- */
- private var availableMemory: Long = model.memory.map { it.size }.sum()
-
- /**
- * The machine to run on.
- */
- public val machine: SimBareMetalMachine = SimBareMetalMachine(context, clock, model, scalingGovernor, scalingDriver)
-
- /**
- * The hypervisor to run multiple workloads.
- */
- public val hypervisor: SimHypervisor = hypervisor.create(
- object : SimHypervisor.Listener {
- override fun onSliceFinish(
- hypervisor: SimHypervisor,
- requestedWork: Long,
- grantedWork: Long,
- overcommittedWork: Long,
- interferedWork: Long,
- cpuUsage: Double,
- cpuDemand: Double
- ) {
-
- _batch.put(_cpuWork, requestedWork.toDouble())
- _batch.put(_cpuWorkGranted, grantedWork.toDouble())
- _batch.put(_cpuWorkOvercommit, overcommittedWork.toDouble())
- _batch.put(_cpuWorkInterference, interferedWork.toDouble())
- _batch.put(_cpuUsage, cpuUsage)
- _batch.put(_cpuDemand, cpuDemand)
- _batch.put(_cpuPower, machine.powerDraw)
- _batch.record()
- }
- }
- )
-
- /**
- * The virtual machines running on the hypervisor.
- */
- private val guests = HashMap<Server, Guest>()
-
- override val state: HostState
- get() = _state
- private var _state: HostState = HostState.DOWN
- set(value) {
- if (value != field) {
- listeners.forEach { it.onStateChanged(this, value) }
- }
- field = value
- }
-
- override val model: HostModel = HostModel(model.cpus.size, model.memory.map { it.size }.sum())
-
- /**
- * The number of guests on the host.
- */
- private val _guests = meter.longUpDownCounterBuilder("guests.total")
- .setDescription("Number of guests")
- .setUnit("1")
- .build()
- .bind(Labels.of("host", uid.toString()))
-
- /**
- * The number of active guests on the host.
- */
- private val _activeGuests = meter.longUpDownCounterBuilder("guests.active")
- .setDescription("Number of active guests")
- .setUnit("1")
- .build()
- .bind(Labels.of("host", uid.toString()))
-
- /**
- * The CPU usage on the host.
- */
- private val _cpuUsage = meter.doubleValueRecorderBuilder("cpu.usage")
- .setDescription("The amount of CPU resources used by the host")
- .setUnit("MHz")
- .build()
-
- /**
- * The CPU demand on the host.
- */
- private val _cpuDemand = meter.doubleValueRecorderBuilder("cpu.demand")
- .setDescription("The amount of CPU resources the guests would use if there were no CPU contention or CPU limits")
- .setUnit("MHz")
- .build()
-
- /**
- * The requested work for the CPU.
- */
- private val _cpuPower = meter.doubleValueRecorderBuilder("power.usage")
- .setDescription("The amount of power used by the CPU")
- .setUnit("W")
- .build()
-
- /**
- * The requested work for the CPU.
- */
- private val _cpuWork = meter.doubleValueRecorderBuilder("cpu.work.total")
- .setDescription("The amount of work supplied to the CPU")
- .setUnit("1")
- .build()
-
- /**
- * The work actually performed by the CPU.
- */
- private val _cpuWorkGranted = meter.doubleValueRecorderBuilder("cpu.work.granted")
- .setDescription("The amount of work performed by the CPU")
- .setUnit("1")
- .build()
-
- /**
- * The work that could not be performed by the CPU due to overcommitting resource.
- */
- private val _cpuWorkOvercommit = meter.doubleValueRecorderBuilder("cpu.work.overcommit")
- .setDescription("The amount of work not performed by the CPU due to overcommitment")
- .setUnit("1")
- .build()
-
- /**
- * The work that could not be performed by the CPU due to interference.
- */
- private val _cpuWorkInterference = meter.doubleValueRecorderBuilder("cpu.work.interference")
- .setDescription("The amount of work not performed by the CPU due to interference")
- .setUnit("1")
- .build()
-
- /**
- * The batch recorder used to record multiple metrics atomically.
- */
- private val _batch = meter.newBatchRecorder("host", uid.toString())
-
- init {
- // Launch hypervisor onto machine
- scope.launch {
- try {
- _state = HostState.UP
- machine.run(this@SimHost.hypervisor, emptyMap())
- } catch (_: CancellationException) {
- // Ignored
- } catch (cause: Throwable) {
- logger.error(cause) { "Host failed" }
- throw cause
- } finally {
- _state = HostState.DOWN
- }
- }
- }
-
- override fun canFit(server: Server): Boolean {
- val sufficientMemory = availableMemory > server.flavor.memorySize
- val enoughCpus = machine.model.cpus.size >= server.flavor.cpuCount
- val canFit = hypervisor.canFit(server.flavor.toMachineModel())
-
- return sufficientMemory && enoughCpus && canFit
- }
-
- override suspend fun spawn(server: Server, start: Boolean) {
- // Return if the server already exists on this host
- if (server in this) {
- return
- }
-
- require(canFit(server)) { "Server does not fit" }
- val guest = Guest(server, hypervisor.createMachine(server.flavor.toMachineModel()))
- guests[server] = guest
- _guests.add(1)
-
- if (start) {
- guest.start()
- }
- }
-
- override fun contains(server: Server): Boolean {
- return server in guests
- }
-
- override suspend fun start(server: Server) {
- val guest = requireNotNull(guests[server]) { "Unknown server ${server.uid} at host $uid" }
- guest.start()
- }
-
- override suspend fun stop(server: Server) {
- val guest = requireNotNull(guests[server]) { "Unknown server ${server.uid} at host $uid" }
- guest.stop()
- }
-
- override suspend fun delete(server: Server) {
- val guest = guests.remove(server) ?: return
- guest.terminate()
- _guests.add(-1)
- }
-
- override fun addListener(listener: HostListener) {
- listeners.add(listener)
- }
-
- override fun removeListener(listener: HostListener) {
- listeners.remove(listener)
- }
-
- override fun close() {
- scope.cancel()
- machine.close()
- }
-
- override fun toString(): String = "SimHost[uid=$uid,name=$name,model=$model]"
-
- /**
- * Convert flavor to machine model.
- */
- private fun Flavor.toMachineModel(): SimMachineModel {
- val originalCpu = machine.model.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 onGuestStart(vm: Guest) {
- guests.forEach { (_, guest) ->
- if (guest.state == ServerState.RUNNING) {
- vm.performanceInterferenceModel?.onStart(vm.server.image.name)
- }
- }
-
- _activeGuests.add(1)
- listeners.forEach { it.onStateChanged(this, vm.server, vm.state) }
- }
-
- private fun onGuestStop(vm: Guest) {
- guests.forEach { (_, guest) ->
- if (guest.state == ServerState.RUNNING) {
- vm.performanceInterferenceModel?.onStop(vm.server.image.name)
- }
- }
-
- _activeGuests.add(-1)
- listeners.forEach { it.onStateChanged(this, vm.server, vm.state) }
- }
-
- override suspend fun fail() {
- _state = HostState.DOWN
- }
-
- override suspend fun recover() {
- _state = HostState.UP
- }
-
- /**
- * A virtual machine instance that the driver manages.
- */
- private inner class Guest(val server: Server, val machine: SimMachine) {
- val performanceInterferenceModel: PerformanceInterferenceModel? = server.meta[IMAGE_PERF_INTERFERENCE_MODEL] as? PerformanceInterferenceModel?
-
- var state: ServerState = ServerState.TERMINATED
-
- suspend fun start() {
- when (state) {
- ServerState.TERMINATED -> {
- logger.info { "User requested to start server ${server.uid}" }
- launch()
- }
- ServerState.RUNNING -> return
- ServerState.DELETED -> {
- logger.warn { "User tried to start terminated server" }
- throw IllegalArgumentException("Server is terminated")
- }
- else -> assert(false) { "Invalid state transition" }
- }
- }
-
- suspend fun stop() {
- when (state) {
- ServerState.RUNNING, ServerState.ERROR -> {
- val job = job ?: throw IllegalStateException("Server should be active")
- job.cancel()
- job.join()
- }
- ServerState.TERMINATED, ServerState.DELETED -> return
- else -> assert(false) { "Invalid state transition" }
- }
- }
-
- suspend fun terminate() {
- stop()
- state = ServerState.DELETED
- }
-
- private var job: Job? = null
-
- private suspend fun launch() = suspendCancellableCoroutine<Unit> { cont ->
- assert(job == null) { "Concurrent job running" }
- val workload = mapper.createWorkload(server)
-
- job = scope.launch {
- delay(1) // TODO Introduce boot time
- init()
- cont.resume(Unit)
- try {
- machine.run(workload, mapOf("driver" to this@SimHost, "server" to server))
- exit(null)
- } catch (cause: Throwable) {
- exit(cause)
- } finally {
- machine.close()
- job = null
- }
- }
- }
-
- private fun init() {
- state = ServerState.RUNNING
- onGuestStart(this)
- }
-
- private fun exit(cause: Throwable?) {
- state =
- if (cause == null)
- ServerState.TERMINATED
- else
- ServerState.ERROR
-
- availableMemory += server.flavor.memorySize
- onGuestStop(this)
- }
- }
-}
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimMetaWorkloadMapper.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimMetaWorkloadMapper.kt
deleted file mode 100644
index c05f1a2c..00000000
--- a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimMetaWorkloadMapper.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2021 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 org.opendc.compute.api.Server
-import org.opendc.simulator.compute.workload.SimWorkload
-
-/**
- * A [SimWorkloadMapper] that maps a [Server] to a workload via the meta-data.
- */
-public class SimMetaWorkloadMapper(private val key: String = "workload") : SimWorkloadMapper {
- override fun createWorkload(server: Server): SimWorkload {
- return requireNotNull(server.meta[key] ?: server.image.meta[key]) as SimWorkload
- }
-}
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimWorkloadMapper.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimWorkloadMapper.kt
deleted file mode 100644
index 7082c5cf..00000000
--- a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimWorkloadMapper.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2021 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 org.opendc.compute.api.Server
-import org.opendc.simulator.compute.workload.SimWorkload
-
-/**
- * A [SimWorkloadMapper] is responsible for mapping a [Server] and [Image] to a [SimWorkload] that can be simulated.
- */
-public fun interface SimWorkloadMapper {
- /**
- * Map the specified [server] to a [SimWorkload] that can be simulated.
- */
- public fun createWorkload(server: Server): SimWorkload
-}
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt b/simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt
deleted file mode 100644
index 5594fd59..00000000
--- a/simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt
+++ /dev/null
@@ -1,227 +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 io.opentelemetry.api.metrics.MeterProvider
-import io.opentelemetry.sdk.common.CompletableResultCode
-import io.opentelemetry.sdk.metrics.SdkMeterProvider
-import io.opentelemetry.sdk.metrics.data.MetricData
-import io.opentelemetry.sdk.metrics.export.MetricExporter
-import io.opentelemetry.sdk.metrics.export.MetricProducer
-import kotlinx.coroutines.*
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.BeforeEach
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.assertAll
-import org.opendc.compute.api.Flavor
-import org.opendc.compute.api.Image
-import org.opendc.compute.api.Server
-import org.opendc.compute.api.ServerState
-import org.opendc.compute.api.ServerWatcher
-import org.opendc.compute.service.driver.Host
-import org.opendc.compute.service.driver.HostListener
-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
-import org.opendc.simulator.compute.model.ProcessingUnit
-import org.opendc.simulator.compute.workload.SimTraceWorkload
-import org.opendc.simulator.core.runBlockingSimulation
-import org.opendc.telemetry.sdk.metrics.export.CoroutineMetricReader
-import org.opendc.telemetry.sdk.toOtelClock
-import java.util.UUID
-import kotlin.coroutines.resume
-
-/**
- * Basic test-suite for the hypervisor.
- */
-@OptIn(ExperimentalCoroutinesApi::class)
-internal class SimHostTest {
- private lateinit var machineModel: SimMachineModel
-
- @BeforeEach
- fun setUp() {
- val cpuNode = ProcessingNode("Intel", "Xeon", "amd64", 2)
-
- machineModel = SimMachineModel(
- cpus = List(cpuNode.coreCount) { ProcessingUnit(cpuNode, it, 3200.0) },
- memory = List(4) { MemoryUnit("Crucial", "MTA18ASF4G72AZ-3G2B1", 3200.0, 32_000) }
- )
- }
-
- /**
- * Test overcommitting of resources by the hypervisor.
- */
- @Test
- fun testOvercommitted() = runBlockingSimulation {
- var requestedWork = 0L
- var grantedWork = 0L
- var overcommittedWork = 0L
-
- val meterProvider: MeterProvider = SdkMeterProvider
- .builder()
- .setClock(clock.toOtelClock())
- .build()
-
- val virtDriver = SimHost(UUID.randomUUID(), "test", machineModel, emptyMap(), coroutineContext, clock, meterProvider.get("opendc-compute-simulator"), SimFairShareHypervisorProvider())
- val duration = 5 * 60L
- val vmImageA = MockImage(
- UUID.randomUUID(),
- "<unnamed>",
- emptyMap(),
- mapOf(
- "workload" to SimTraceWorkload(
- sequenceOf(
- SimTraceWorkload.Fragment(duration * 1000, 2 * 28.0, 2),
- SimTraceWorkload.Fragment(duration * 1000, 2 * 3500.0, 2),
- SimTraceWorkload.Fragment(duration * 1000, 0.0, 2),
- SimTraceWorkload.Fragment(duration * 1000, 2 * 183.0, 2)
- ),
- )
- )
- )
- val vmImageB = MockImage(
- UUID.randomUUID(),
- "<unnamed>",
- emptyMap(),
- mapOf(
- "workload" to SimTraceWorkload(
- sequenceOf(
- SimTraceWorkload.Fragment(duration * 1000, 2 * 28.0, 2),
- SimTraceWorkload.Fragment(duration * 1000, 2 * 3100.0, 2),
- SimTraceWorkload.Fragment(duration * 1000, 0.0, 2),
- SimTraceWorkload.Fragment(duration * 1000, 2 * 73.0, 2)
- )
- )
- )
- )
-
- val flavor = MockFlavor(2, 0)
-
- // Setup metric reader
- val reader = CoroutineMetricReader(
- this, listOf(meterProvider as MetricProducer),
- object : MetricExporter {
- override fun export(metrics: Collection<MetricData>): CompletableResultCode {
- val metricsByName = metrics.associateBy { it.name }
- requestedWork += metricsByName.getValue("cpu.work.total").doubleSummaryData.points.first().sum.toLong()
- grantedWork += metricsByName.getValue("cpu.work.granted").doubleSummaryData.points.first().sum.toLong()
- overcommittedWork += metricsByName.getValue("cpu.work.overcommit").doubleSummaryData.points.first().sum.toLong()
- return CompletableResultCode.ofSuccess()
- }
-
- override fun flush(): CompletableResultCode = CompletableResultCode.ofSuccess()
-
- override fun shutdown(): CompletableResultCode = CompletableResultCode.ofSuccess()
- },
- exportInterval = duration * 1000
- )
-
- coroutineScope {
- launch { virtDriver.spawn(MockServer(UUID.randomUUID(), "a", flavor, vmImageA)) }
- launch { virtDriver.spawn(MockServer(UUID.randomUUID(), "b", flavor, vmImageB)) }
-
- suspendCancellableCoroutine<Unit> { cont ->
- virtDriver.addListener(object : HostListener {
- private var finished = 0
-
- override fun onStateChanged(host: Host, server: Server, newState: ServerState) {
- if (newState == ServerState.TERMINATED && ++finished == 2) {
- cont.resume(Unit)
- }
- }
- })
- }
- }
-
- // Ensure last cycle is collected
- delay(1000 * duration)
- virtDriver.close()
- reader.close()
-
- assertAll(
- { assertEquals(4197600, requestedWork, "Requested work does not match") },
- { assertEquals(2157600, grantedWork, "Granted work does not match") },
- { assertEquals(2040000, overcommittedWork, "Overcommitted work does not match") },
- { assertEquals(1500001, clock.millis()) }
- )
- }
-
- private class MockFlavor(
- override val cpuCount: Int,
- override val memorySize: Long
- ) : Flavor {
- override val uid: UUID = UUID.randomUUID()
- override val name: String = "test"
- override val labels: Map<String, String> = emptyMap()
- override val meta: Map<String, Any> = emptyMap()
-
- override suspend fun delete() {
- throw NotImplementedError()
- }
-
- override suspend fun refresh() {
- throw NotImplementedError()
- }
- }
-
- private class MockImage(
- override val uid: UUID,
- override val name: String,
- override val labels: Map<String, String>,
- override val meta: Map<String, Any>
- ) : Image {
- override suspend fun delete() {
- throw NotImplementedError()
- }
-
- override suspend fun refresh() {
- throw NotImplementedError()
- }
- }
-
- private class MockServer(
- override val uid: UUID,
- override val name: String,
- override val flavor: Flavor,
- override val image: Image
- ) : Server {
- override val labels: Map<String, String> = emptyMap()
-
- override val meta: Map<String, Any> = emptyMap()
-
- override val state: ServerState = ServerState.TERMINATED
-
- override suspend fun start() {}
-
- override suspend fun stop() {}
-
- override suspend fun delete() {}
-
- override fun watch(watcher: ServerWatcher) {}
-
- override fun unwatch(watcher: ServerWatcher) {}
-
- override suspend fun refresh() {}
- }
-}