summaryrefslogtreecommitdiff
path: root/opendc-compute/opendc-compute-service
diff options
context:
space:
mode:
Diffstat (limited to 'opendc-compute/opendc-compute-service')
-rw-r--r--opendc-compute/opendc-compute-service/build.gradle.kts40
-rw-r--r--opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ComputeService.java637
-rw-r--r--opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/HostView.java78
-rw-r--r--opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ServiceFlavor.java122
-rw-r--r--opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ServiceImage.java101
-rw-r--r--opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ServiceTask.java267
-rw-r--r--opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/Host.java137
-rw-r--r--opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/HostListener.java41
-rw-r--r--opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/HostModel.java32
-rw-r--r--opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/HostState.java43
-rw-r--r--opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/telemetry/GuestCpuStats.java43
-rw-r--r--opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/telemetry/GuestSystemStats.java35
-rw-r--r--opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/telemetry/HostCpuStats.java46
-rw-r--r--opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/telemetry/HostSystemStats.java50
-rw-r--r--opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/telemetry/SchedulerStats.java45
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ComputeScheduler.kt50
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ComputeSchedulers.kt118
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt111
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ReplayScheduler.kt65
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeFilter.kt42
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/DifferentHostFilter.kt41
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/HostFilter.kt41
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/InstanceCountFilter.kt42
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/RamFilter.kt55
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/SameHostFilter.kt41
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/VCpuCapacityFilter.kt43
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/VCpuFilter.kt50
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/CoreRamWeigher.kt44
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/HostWeigher.kt81
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/InstanceCountWeigher.kt40
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/RamWeigher.kt43
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/VCpuCapacityWeigher.kt42
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/VCpuWeigher.kt46
-rw-r--r--opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt386
-rw-r--r--opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ServiceFlavorTest.kt67
-rw-r--r--opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ServiceImageTest.kt67
-rw-r--r--opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ServiceTaskTest.kt442
-rw-r--r--opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/scheduler/FilterSchedulerTest.kt536
-rw-r--r--opendc-compute/opendc-compute-service/src/test/resources/log4j2.xml38
39 files changed, 0 insertions, 4248 deletions
diff --git a/opendc-compute/opendc-compute-service/build.gradle.kts b/opendc-compute/opendc-compute-service/build.gradle.kts
deleted file mode 100644
index cd25e05c..00000000
--- a/opendc-compute/opendc-compute-service/build.gradle.kts
+++ /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.
- */
-
-description = "OpenDC Compute Service implementation"
-
-// Build configuration
-plugins {
- `kotlin-library-conventions`
-}
-
-dependencies {
- api(projects.opendcCompute.opendcComputeApi)
- implementation(projects.opendcCommon)
- implementation(libs.kotlin.logging)
- implementation(project(mapOf("path" to ":opendc-simulator:opendc-simulator-compute")))
-
- testImplementation(projects.opendcSimulator.opendcSimulatorCore)
- testImplementation(libs.log4j.slf4j)
- testRuntimeOnly(libs.log4j.core)
- testRuntimeOnly(libs.log4j.slf4j)
-}
diff --git a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ComputeService.java b/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ComputeService.java
deleted file mode 100644
index ad01ee57..00000000
--- a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ComputeService.java
+++ /dev/null
@@ -1,637 +0,0 @@
-/*
- * Copyright (c) 2022 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 java.time.Duration;
-import java.time.Instant;
-import java.time.InstantSource;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Deque;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.SplittableRandom;
-import java.util.UUID;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.opendc.common.Dispatcher;
-import org.opendc.common.util.Pacer;
-import org.opendc.compute.api.ComputeClient;
-import org.opendc.compute.api.Flavor;
-import org.opendc.compute.api.Image;
-import org.opendc.compute.api.Task;
-import org.opendc.compute.api.TaskState;
-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.ComputeScheduler;
-import org.opendc.compute.service.telemetry.SchedulerStats;
-import org.opendc.simulator.compute.workload.SimWorkload;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The {@link ComputeService} hosts the API implementation of the OpenDC Compute Engine.
- */
-public final class ComputeService implements AutoCloseable {
- private static final Logger LOGGER = LoggerFactory.getLogger(ComputeService.class);
-
- /**
- * The {@link InstantSource} representing the clock tracking the (simulation) time.
- */
- private final InstantSource clock;
-
- /**
- * The {@link ComputeScheduler} responsible for placing the tasks onto hosts.
- */
- private final ComputeScheduler scheduler;
-
- /**
- * The {@link Pacer} used to pace the scheduling requests.
- */
- private final Pacer pacer;
-
- /**
- * The {@link SplittableRandom} used to generate the unique identifiers for the service resources.
- */
- private final SplittableRandom random = new SplittableRandom(0);
-
- private final int maxNumFailures;
-
- /**
- * A flag to indicate that the service is closed.
- */
- private boolean isClosed;
-
- /**
- * A mapping from host to host view.
- */
- private final Map<Host, HostView> hostToView = new HashMap<>();
-
- /**
- * The available hypervisors.
- */
- private final Set<HostView> availableHosts = new HashSet<>();
-
- /**
- * The tasks that should be launched by the service.
- */
- private final Deque<SchedulingRequest> taskQueue = new ArrayDeque<>();
-
- /**
- * The active tasks in the system.
- */
- private final Map<Task, Host> activeTasks = new HashMap<>();
-
- /**
- * The registered flavors for this compute service.
- */
- private final Map<UUID, ServiceFlavor> flavorById = new HashMap<>();
-
- private final List<ServiceFlavor> flavors = new ArrayList<>();
-
- /**
- * The registered images for this compute service.
- */
- private final Map<UUID, ServiceImage> imageById = new HashMap<>();
-
- private final List<ServiceImage> images = new ArrayList<>();
-
- /**
- * The registered tasks for this compute service.
- */
- private final Map<UUID, ServiceTask> taskById = new HashMap<>();
-
- private final List<ServiceTask> tasks = new ArrayList<>();
-
- /**
- * A [HostListener] used to track the active tasks.
- */
- private final HostListener hostListener = new HostListener() {
- @Override
- public void onStateChanged(@NotNull Host host, @NotNull HostState newState) {
- LOGGER.debug("Host {} state changed: {}", host, newState);
-
- final HostView hv = hostToView.get(host);
-
- if (hv != null) {
- if (newState == HostState.UP) {
- availableHosts.add(hv);
- } else {
- availableHosts.remove(hv);
- }
- }
-
- // Re-schedule on the new machine
- requestSchedulingCycle();
- }
-
- @Override
- public void onStateChanged(@NotNull Host host, @NotNull Task task, @NotNull TaskState newState) {
- final ServiceTask serviceTask = (ServiceTask) task;
-
- if (serviceTask.getHost() != host) {
- // This can happen when a task is rescheduled and started on another machine, while being deleted from
- // the old machine.
- return;
- }
-
- serviceTask.setState(newState);
-
- // TODO: move the removal of tasks when max Failures are reached to here
- if (newState == TaskState.TERMINATED || newState == TaskState.DELETED || newState == TaskState.ERROR) {
- LOGGER.info("task {} {} {} finished", task.getUid(), task.getName(), task.getFlavor());
-
- if (activeTasks.remove(task) != null) {
- tasksActive--;
- }
-
- HostView hv = hostToView.get(host);
- final ServiceFlavor flavor = serviceTask.getFlavor();
- if (hv != null) {
- hv.provisionedCores -= flavor.getCoreCount();
- hv.instanceCount--;
- hv.availableMemory += flavor.getMemorySize();
- } else {
- LOGGER.error("Unknown host {}", host);
- }
-
- // Try to reschedule if needed
- requestSchedulingCycle();
- }
- }
- };
-
- private int maxCores = 0;
- private long maxMemory = 0L;
- private long attemptsSuccess = 0L;
- private long attemptsFailure = 0L;
- private long attemptsError = 0L;
- private int tasksPending = 0;
- private int tasksActive = 0;
-
- /**
- * Construct a {@link ComputeService} instance.
- */
- ComputeService(Dispatcher dispatcher, ComputeScheduler scheduler, Duration quantum, int maxNumFailures) {
- this.clock = dispatcher.getTimeSource();
- this.scheduler = scheduler;
- this.pacer = new Pacer(dispatcher, quantum.toMillis(), (time) -> doSchedule());
- this.maxNumFailures = maxNumFailures;
- }
-
- /**
- * Create a new {@link Builder} instance.
- */
- public static Builder builder(Dispatcher dispatcher, ComputeScheduler scheduler) {
- return new Builder(dispatcher, scheduler);
- }
-
- /**
- * Create a new {@link ComputeClient} to control the compute service.
- */
- public ComputeClient newClient() {
- if (isClosed) {
- throw new IllegalStateException("Service is closed");
- }
- return new Client(this);
- }
-
- /**
- * Return the {@link Task}s hosted by this service.
- */
- public List<Task> getTasks() {
- return Collections.unmodifiableList(tasks);
- }
-
- /**
- * Add a {@link Host} to the scheduling pool of the compute service.
- */
- public void addHost(Host host) {
- // Check if host is already known
- if (hostToView.containsKey(host)) {
- return;
- }
-
- HostView hv = new HostView(host);
- HostModel model = host.getModel();
-
- maxCores = Math.max(maxCores, model.coreCount());
- maxMemory = Math.max(maxMemory, model.memoryCapacity());
- hostToView.put(host, hv);
-
- if (host.getState() == HostState.UP) {
- availableHosts.add(hv);
- }
-
- scheduler.addHost(hv);
- host.addListener(hostListener);
- }
-
- /**
- * Remove a {@link Host} from the scheduling pool of the compute service.
- */
- public void removeHost(Host host) {
- HostView view = hostToView.remove(host);
- if (view != null) {
- availableHosts.remove(view);
- scheduler.removeHost(view);
- host.removeListener(hostListener);
- }
- }
-
- /**
- * Lookup the {@link Host} that currently hosts the specified {@link Task}.
- */
- public Host lookupHost(Task task) {
- if (task instanceof ServiceTask) {
- return ((ServiceTask) task).getHost();
- }
-
- ServiceTask internal = Objects.requireNonNull(taskById.get(task.getUid()), "Invalid task passed to lookupHost");
- return internal.getHost();
- }
-
- /**
- * Return the {@link Host}s that are registered with this service.
- */
- public Set<Host> getHosts() {
- return Collections.unmodifiableSet(hostToView.keySet());
- }
-
- /**
- * Collect the statistics about the scheduler component of this service.
- */
- public SchedulerStats getSchedulerStats() {
- return new SchedulerStats(
- availableHosts.size(),
- hostToView.size() - availableHosts.size(),
- attemptsSuccess,
- attemptsFailure,
- attemptsError,
- tasks.size(),
- tasksPending,
- tasksActive);
- }
-
- @Override
- public void close() {
- if (isClosed) {
- return;
- }
-
- isClosed = true;
- pacer.cancel();
- }
-
- /**
- * Enqueue the specified [task] to be scheduled onto a host.
- */
- SchedulingRequest schedule(ServiceTask task) {
- LOGGER.debug("Enqueueing task {} to be assigned to host", task.getUid());
-
- long now = clock.millis();
- SchedulingRequest request = new SchedulingRequest(task, now);
-
- task.launchedAt = Instant.ofEpochMilli(now);
- taskQueue.add(request);
- tasksPending++;
- requestSchedulingCycle();
- return request;
- }
-
- void delete(ServiceFlavor flavor) {
- flavorById.remove(flavor.getUid());
- flavors.remove(flavor);
- }
-
- void delete(ServiceImage image) {
- imageById.remove(image.getUid());
- images.remove(image);
- }
-
- void delete(ServiceTask task) {
- taskById.remove(task.getUid());
- tasks.remove(task);
- }
-
- /**
- * Indicate that a new scheduling cycle is needed due to a change to the service's state.
- */
- private void requestSchedulingCycle() {
- // Bail out in case the queue is empty.
- if (taskQueue.isEmpty()) {
- return;
- }
-
- pacer.enqueue();
- }
-
- /**
- * Run a single scheduling iteration.
- */
- private void doSchedule() {
- // reorder tasks
-
- while (!taskQueue.isEmpty()) {
- SchedulingRequest request = taskQueue.peek();
-
- if (request.isCancelled) {
- taskQueue.poll();
- tasksPending--;
- continue;
- }
-
- final ServiceTask task = request.task;
-
- // Remove task from scheduling if it has failed too many times
- if (task.getNumFailures() > maxNumFailures) {
- LOGGER.warn("Failed to spawn {}: Task has failed more than the allowed {} times", task, maxNumFailures);
-
- taskQueue.poll();
- tasksPending--;
- task.setState(TaskState.TERMINATED);
- continue;
- }
-
- final ServiceFlavor flavor = task.getFlavor();
- final HostView hv = scheduler.select(request.task);
-
- if (hv == null || !hv.getHost().canFit(task)) {
- LOGGER.trace("Task {} selected for scheduling but no capacity available for it at the moment", task);
-
- if (flavor.getMemorySize() > maxMemory || flavor.getCoreCount() > maxCores) {
- // Remove the incoming image
- taskQueue.poll();
- tasksPending--;
- attemptsFailure++;
-
- LOGGER.warn("Failed to spawn {}: does not fit", task);
-
- task.setState(TaskState.TERMINATED);
- continue;
- } else {
- break;
- }
- }
-
- Host host = hv.getHost();
-
- // Remove request from queue
- taskQueue.poll();
- tasksPending--;
-
- LOGGER.info("Assigned task {} to host {}", task, host);
-
- try {
- task.host = host;
-
- host.spawn(task);
- host.start(task);
-
- tasksActive++;
- attemptsSuccess++;
-
- hv.instanceCount++;
- hv.provisionedCores += flavor.getCoreCount();
- hv.availableMemory -= flavor.getMemorySize();
-
- activeTasks.put(task, host);
- } catch (Exception cause) {
- LOGGER.error("Failed to deploy VM", cause);
- attemptsError++;
- }
- }
- }
-
- /**
- * Builder class for a {@link ComputeService}.
- */
- public static class Builder {
- private final Dispatcher dispatcher;
- private final ComputeScheduler computeScheduler;
- private Duration quantum = Duration.ofMinutes(5);
- private int maxNumFailures = 10;
-
- Builder(Dispatcher dispatcher, ComputeScheduler computeScheduler) {
- this.dispatcher = dispatcher;
- this.computeScheduler = computeScheduler;
- }
-
- /**
- * Set the scheduling quantum of the service.
- */
- public Builder withQuantum(Duration quantum) {
- this.quantum = quantum;
- return this;
- }
-
- public Builder withMaxNumFailures(int maxNumFailures) {
- this.maxNumFailures = maxNumFailures;
- return this;
- }
-
- /**
- * Build a {@link ComputeService}.
- */
- public ComputeService build() {
- return new ComputeService(dispatcher, computeScheduler, quantum, maxNumFailures);
- }
- }
-
- /**
- * Implementation of {@link ComputeClient} using a {@link ComputeService}.
- */
- private static class Client implements ComputeClient {
- private final ComputeService service;
- private boolean isClosed;
-
- Client(ComputeService service) {
- this.service = service;
- }
-
- /**
- * Method to check if the client is still open and throw an exception if it is not.
- */
- private void checkOpen() {
- if (isClosed) {
- throw new IllegalStateException("Client is already closed");
- }
- }
-
- @NotNull
- @Override
- public List<Flavor> queryFlavors() {
- checkOpen();
- return new ArrayList<>(service.flavors);
- }
-
- @Override
- public Flavor findFlavor(@NotNull UUID id) {
- checkOpen();
-
- return service.flavorById.get(id);
- }
-
- @NotNull
- @Override
- public Flavor newFlavor(
- @NotNull String name,
- int cpuCount,
- long memorySize,
- @NotNull Map<String, String> labels,
- @NotNull Map<String, ?> meta) {
- checkOpen();
-
- final ComputeService service = this.service;
- UUID uid = new UUID(service.clock.millis(), service.random.nextLong());
- ServiceFlavor flavor = new ServiceFlavor(service, uid, name, cpuCount, memorySize, labels, meta);
-
- service.flavorById.put(uid, flavor);
- service.flavors.add(flavor);
-
- return flavor;
- }
-
- @NotNull
- @Override
- public List<Image> queryImages() {
- checkOpen();
-
- return new ArrayList<>(service.images);
- }
-
- @Override
- public Image findImage(@NotNull UUID id) {
- checkOpen();
-
- return service.imageById.get(id);
- }
-
- @NotNull
- public Image newImage(@NotNull String name, @NotNull Map<String, String> labels, @NotNull Map<String, ?> meta) {
- checkOpen();
-
- final ComputeService service = this.service;
- UUID uid = new UUID(service.clock.millis(), service.random.nextLong());
-
- ServiceImage image = new ServiceImage(service, uid, name, labels, meta);
-
- service.imageById.put(uid, image);
- service.images.add(image);
-
- return image;
- }
-
- @NotNull
- @Override
- public Task newTask(
- @NotNull String name,
- @NotNull Image image,
- @NotNull Flavor flavor,
- @NotNull Map<String, String> labels,
- @NotNull Map<String, ?> meta,
- boolean start) {
- checkOpen();
-
- final ComputeService service = this.service;
- UUID uid = new UUID(service.clock.millis(), service.random.nextLong());
-
- final ServiceFlavor internalFlavor =
- Objects.requireNonNull(service.flavorById.get(flavor.getUid()), "Unknown flavor");
- final ServiceImage internalImage =
- Objects.requireNonNull(service.imageById.get(image.getUid()), "Unknown image");
-
- ServiceTask task = new ServiceTask(service, uid, name, internalFlavor, internalImage, labels, meta);
-
- service.taskById.put(uid, task);
- service.tasks.add(task);
-
- if (start) {
- task.start();
- }
-
- return task;
- }
-
- @Nullable
- @Override
- public Task findTask(@NotNull UUID id) {
- checkOpen();
- return service.taskById.get(id);
- }
-
- @NotNull
- @Override
- public List<Task> queryTasks() {
- checkOpen();
-
- return new ArrayList<>(service.tasks);
- }
-
- @Override
- public void close() {
- isClosed = true;
- }
-
- @Override
- public String toString() {
- return "ComputeService.Client";
- }
-
- @Nullable
- @Override
- public void rescheduleTask(@NotNull Task task, @NotNull SimWorkload workload) {
- ServiceTask internalTask = (ServiceTask) findTask(task.getUid());
- Host from = service.lookupHost(internalTask);
-
- from.delete(internalTask);
-
- internalTask.host = null;
-
- internalTask.setWorkload(workload);
- internalTask.start();
- }
- }
-
- /**
- * A request to schedule a {@link ServiceTask} onto one of the {@link Host}s.
- */
- static class SchedulingRequest {
- final ServiceTask task;
- final long submitTime;
-
- boolean isCancelled;
-
- SchedulingRequest(ServiceTask task, long submitTime) {
- this.task = task;
- this.submitTime = submitTime;
- }
- }
-}
diff --git a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/HostView.java b/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/HostView.java
deleted file mode 100644
index 6e2cdcb4..00000000
--- a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/HostView.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2022 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 org.opendc.compute.service.driver.Host;
-
-/**
- * A view of a {@link Host} as seen from the {@link ComputeService}.
- */
-public class HostView {
- private final Host host;
- int instanceCount;
- long availableMemory;
- int provisionedCores;
-
- /**
- * Construct a {@link HostView} instance.
- *
- * @param host The host to create a view of.
- */
- public HostView(Host host) {
- this.host = host;
- this.availableMemory = host.getModel().memoryCapacity();
- }
-
- /**
- * The {@link Host} this is a view of.
- */
- public Host getHost() {
- return host;
- }
-
- /**
- * Return the number of instances on this host.
- */
- public int getInstanceCount() {
- return instanceCount;
- }
-
- /**
- * Return the available memory of the host.
- */
- public long getAvailableMemory() {
- return availableMemory;
- }
-
- /**
- * Return the provisioned cores on the host.
- */
- public int getProvisionedCores() {
- return provisionedCores;
- }
-
- @Override
- public String toString() {
- return "HostView[host=" + host + "]";
- }
-}
diff --git a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ServiceFlavor.java b/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ServiceFlavor.java
deleted file mode 100644
index 0f434a6a..00000000
--- a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ServiceFlavor.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (c) 2022 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 java.util.Collections;
-import java.util.Map;
-import java.util.Objects;
-import java.util.UUID;
-import org.jetbrains.annotations.NotNull;
-import org.opendc.compute.api.Flavor;
-
-/**
- * Implementation of {@link Flavor} provided by {@link ComputeService}.
- */
-public final class ServiceFlavor implements Flavor {
- private final ComputeService service;
- private final UUID uid;
- private final String name;
- private final int coreCount;
- private final long memorySize;
- private final Map<String, String> labels;
- private final Map<String, ?> meta;
-
- ServiceFlavor(
- ComputeService service,
- UUID uid,
- String name,
- int coreCount,
- long memorySize,
- Map<String, String> labels,
- Map<String, ?> meta) {
- this.service = service;
- this.uid = uid;
- this.name = name;
- this.coreCount = coreCount;
- this.memorySize = memorySize;
- this.labels = labels;
- this.meta = meta;
- }
-
- @Override
- public int getCoreCount() {
- return coreCount;
- }
-
- @Override
- public long getMemorySize() {
- return memorySize;
- }
-
- @NotNull
- @Override
- public UUID getUid() {
- return uid;
- }
-
- @NotNull
- @Override
- public String getName() {
- return name;
- }
-
- @NotNull
- @Override
- public Map<String, String> getLabels() {
- return Collections.unmodifiableMap(labels);
- }
-
- @NotNull
- @Override
- public Map<String, Object> getMeta() {
- return Collections.unmodifiableMap(meta);
- }
-
- @Override
- public void reload() {
- // No-op: this object is the source-of-truth
- }
-
- @Override
- public void delete() {
- service.delete(this);
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- ServiceFlavor flavor = (ServiceFlavor) o;
- return service.equals(flavor.service) && uid.equals(flavor.uid);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(service, uid);
- }
-
- @Override
- public String toString() {
- return "Flavor[uid=" + uid + ",name=" + name + "]";
- }
-}
diff --git a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ServiceImage.java b/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ServiceImage.java
deleted file mode 100644
index 706be483..00000000
--- a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ServiceImage.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 2022 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 java.util.Collections;
-import java.util.Map;
-import java.util.Objects;
-import java.util.UUID;
-import org.jetbrains.annotations.NotNull;
-import org.opendc.compute.api.Image;
-
-/**
- * Implementation of {@link Image} provided by {@link ComputeService}.
- */
-public final class ServiceImage implements Image {
- private final ComputeService service;
- private final UUID uid;
- private final String name;
- private final Map<String, String> labels;
- private final Map<String, ?> meta;
-
- ServiceImage(ComputeService service, UUID uid, String name, Map<String, String> labels, Map<String, ?> meta) {
- this.service = service;
- this.uid = uid;
- this.name = name;
- this.labels = labels;
- this.meta = meta;
- }
-
- @NotNull
- @Override
- public UUID getUid() {
- return uid;
- }
-
- @NotNull
- @Override
- public String getName() {
- return name;
- }
-
- @NotNull
- @Override
- public Map<String, String> getLabels() {
- return Collections.unmodifiableMap(labels);
- }
-
- @NotNull
- @Override
- public Map<String, Object> getMeta() {
- return Collections.unmodifiableMap(meta);
- }
-
- @Override
- public void reload() {
- // No-op: this object is the source-of-truth
- }
-
- @Override
- public void delete() {
- service.delete(this);
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- ServiceImage image = (ServiceImage) o;
- return service.equals(image.service) && uid.equals(image.uid);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(service, uid);
- }
-
- @Override
- public String toString() {
- return "Image[uid=" + uid + ",name=" + name + "]";
- }
-}
diff --git a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ServiceTask.java b/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ServiceTask.java
deleted file mode 100644
index f0e2a82e..00000000
--- a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ServiceTask.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (c) 2022 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 java.time.Instant;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.UUID;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.opendc.compute.api.Task;
-import org.opendc.compute.api.TaskState;
-import org.opendc.compute.api.TaskWatcher;
-import org.opendc.compute.service.driver.Host;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Implementation of {@link Task} provided by {@link ComputeService}.
- */
-public final class ServiceTask implements Task {
- private static final Logger LOGGER = LoggerFactory.getLogger(ServiceTask.class);
-
- private final ComputeService service;
- private final UUID uid;
-
- private final String name;
- private final ServiceFlavor flavor;
- private final ServiceImage image;
- private final Map<String, String> labels;
- private Map<String, ?> meta;
-
- private final List<TaskWatcher> watchers = new ArrayList<>();
- private TaskState state = TaskState.TERMINATED;
- Instant launchedAt = null;
- Host host = null;
- private ComputeService.SchedulingRequest request = null;
-
- private int numFailures = 0;
-
- ServiceTask(
- ComputeService service,
- UUID uid,
- String name,
- ServiceFlavor flavor,
- ServiceImage image,
- Map<String, String> labels,
- Map<String, ?> meta) {
- this.service = service;
- this.uid = uid;
- this.name = name;
- this.flavor = flavor;
- this.image = image;
- this.labels = labels;
- this.meta = meta;
- }
-
- @NotNull
- @Override
- public UUID getUid() {
- return uid;
- }
-
- @NotNull
- @Override
- public String getName() {
- return name;
- }
-
- @NotNull
- @Override
- public ServiceFlavor getFlavor() {
- return flavor;
- }
-
- @NotNull
- @Override
- public ServiceImage getImage() {
- return image;
- }
-
- @NotNull
- @Override
- public Map<String, String> getLabels() {
- return Collections.unmodifiableMap(labels);
- }
-
- @NotNull
- @Override
- public Map<String, Object> getMeta() {
- return Collections.unmodifiableMap(meta);
- }
-
- public void setWorkload(Object _workload) {
- Map<String, Object> new_meta = new HashMap<String, Object>();
- new_meta.put("workload", _workload);
-
- meta = new_meta;
- }
-
- @NotNull
- @Override
- public TaskState getState() {
- return state;
- }
-
- @Nullable
- @Override
- public Instant getLaunchedAt() {
- return launchedAt;
- }
-
- /**
- * Return the {@link Host} on which the task is running or <code>null</code> if it is not running on a host.
- */
- public Host getHost() {
- return host;
- }
-
- @Override
- public void start() {
- switch (state) {
- case PROVISIONING:
- LOGGER.debug("User tried to start task but request is already pending: doing nothing");
- case RUNNING:
- LOGGER.debug("User tried to start task but task is already running");
- break;
- case DELETED:
- LOGGER.warn("User tried to start deleted task");
- throw new IllegalStateException("Task is deleted");
- default:
- LOGGER.info("User requested to start task {}", uid);
- setState(TaskState.PROVISIONING);
- assert request == null : "Scheduling request already active";
- request = service.schedule(this);
- break;
- }
- }
-
- @Override
- public void stop() {
- switch (state) {
- case PROVISIONING:
- cancelProvisioningRequest();
- setState(TaskState.TERMINATED);
- break;
- case RUNNING:
- case ERROR:
- final Host host = this.host;
- if (host == null) {
- throw new IllegalStateException("Task not running");
- }
- host.stop(this);
- break;
- }
- }
-
- @Override
- public void watch(@NotNull TaskWatcher watcher) {
- watchers.add(watcher);
- }
-
- @Override
- public void unwatch(@NotNull TaskWatcher watcher) {
- watchers.remove(watcher);
- }
-
- @Override
- public void reload() {
- // No-op: this object is the source-of-truth
- }
-
- @Override
- public void delete() {
- switch (state) {
- case PROVISIONING:
- case TERMINATED:
- cancelProvisioningRequest();
- service.delete(this);
- setState(TaskState.DELETED);
- break;
- case RUNNING:
- case ERROR:
- final Host host = this.host;
- if (host == null) {
- throw new IllegalStateException("Task not running");
- }
- host.delete(this);
- service.delete(this);
- setState(TaskState.DELETED);
- break;
- }
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- ServiceTask task = (ServiceTask) o;
- return service.equals(task.service) && uid.equals(task.uid);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(service, uid);
- }
-
- @Override
- public String toString() {
- return "Task[uid=" + uid + ",name=" + name + ",state=" + state + "]";
- }
-
- void setState(TaskState newState) {
- if (this.state == newState) {
- return;
- }
-
- for (TaskWatcher watcher : watchers) {
- watcher.onStateChanged(this, newState);
- }
- if (newState == TaskState.ERROR) {
- this.numFailures++;
- }
-
- this.state = newState;
- }
-
- /**
- * Cancel the provisioning request if active.
- */
- private void cancelProvisioningRequest() {
- final ComputeService.SchedulingRequest request = this.request;
- if (request != null) {
- this.request = null;
- request.isCancelled = true;
- }
- }
-
- @Override
- public int getNumFailures() {
- return this.numFailures;
- }
-}
diff --git a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/Host.java b/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/Host.java
deleted file mode 100644
index 546f774b..00000000
--- a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/Host.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (c) 2022 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 java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import org.opendc.compute.api.Task;
-import org.opendc.compute.service.driver.telemetry.GuestCpuStats;
-import org.opendc.compute.service.driver.telemetry.GuestSystemStats;
-import org.opendc.compute.service.driver.telemetry.HostCpuStats;
-import org.opendc.compute.service.driver.telemetry.HostSystemStats;
-
-/**
- * Base interface for representing compute resources that host virtualized {@link Task} instances.
- */
-public interface Host {
- /**
- * Return a unique identifier representing the host.
- */
- UUID getUid();
-
- /**
- * Return the name of this host.
- */
- String getName();
-
- /**
- * Return the machine model of the host.
- */
- HostModel getModel();
-
- /**
- * Return the state of the host.
- */
- HostState getState();
-
- /**
- * Return the meta-data associated with the host.
- */
- Map<String, ?> getMeta();
-
- /**
- * Return the {@link Task} instances known to the host.
- */
- Set<Task> getInstances();
-
- /**
- * Determine whether the specified <code>task</code> can still fit on this host.
- */
- boolean canFit(Task task);
-
- /**
- * Register the specified <code>task</code> on the host.
- */
- void spawn(Task task);
-
- /**
- * Determine whether the specified <code>task</code> exists on the host.
- */
- boolean contains(Task task);
-
- /**
- * Start the task if it is currently not running on this host.
- *
- * @throws IllegalArgumentException if the task is not present on the host.
- */
- void start(Task task);
-
- /**
- * Stop the task if it is currently running on this host.
- *
- * @throws IllegalArgumentException if the task is not present on the host.
- */
- void stop(Task task);
-
- /**
- * Delete the specified <code>task</code> on this host and cleanup all resources associated with it.
- */
- void delete(Task task);
-
- /**
- * Add a [HostListener] to this host.
- */
- void addListener(HostListener listener);
-
- /**
- * Remove a [HostListener] from this host.
- */
- void removeListener(HostListener listener);
-
- /**
- * Query the system statistics of the host.
- */
- HostSystemStats getSystemStats();
-
- /**
- * Query the system statistics of a {@link Task} that is located on this host.
- *
- * @param task The {@link Task} to obtain the system statistics of.
- * @throws IllegalArgumentException if the task is not present on the host.
- */
- GuestSystemStats getSystemStats(Task task);
-
- /**
- * Query the CPU statistics of the host.
- */
- HostCpuStats getCpuStats();
-
- /**
- * Query the CPU statistics of a {@link Task} that is located on this host.
- *
- * @param task The {@link Task} to obtain the CPU statistics of.
- * @throws IllegalArgumentException if the task is not present on the host.
- */
- GuestCpuStats getCpuStats(Task task);
-}
diff --git a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/HostListener.java b/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/HostListener.java
deleted file mode 100644
index 079c6cff..00000000
--- a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/HostListener.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2022 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.Task;
-import org.opendc.compute.api.TaskState;
-
-/**
- * Listener interface for events originating from a {@link Host}.
- */
-public interface HostListener {
- /**
- * This method is invoked when the state of <code>task</code> on <code>host</code> changes.
- */
- default void onStateChanged(Host host, Task task, TaskState newState) {}
-
- /**
- * This method is invoked when the state of a {@link Host} has changed.
- */
- default void onStateChanged(Host host, HostState newState) {}
-}
diff --git a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/HostModel.java b/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/HostModel.java
deleted file mode 100644
index 87464fe1..00000000
--- a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/HostModel.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2022 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;
-
-/**
- * Record describing the static machine properties of the host.
- *
- * @param cpuCapacity The total CPU capacity of the host in MHz.
- * @param coreCount The number of logical processing cores available for this host.
- * @param memoryCapacity The amount of memory available for this host in MB.
- */
-public record HostModel(double cpuCapacity, int coreCount, long memoryCapacity) {}
diff --git a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/HostState.java b/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/HostState.java
deleted file mode 100644
index ce12a67e..00000000
--- a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/HostState.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2022 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 HostState {
- /**
- * The host is up and able to host guests.
- */
- UP,
-
- /**
- * The host is in a (forced) down state and unable to host any guests.
- */
- DOWN,
-
- /**
- * The host is in an error state and unable to host any guests.
- */
- ERROR
-}
diff --git a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/telemetry/GuestCpuStats.java b/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/telemetry/GuestCpuStats.java
deleted file mode 100644
index 0b78c7ea..00000000
--- a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/telemetry/GuestCpuStats.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2022 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.telemetry;
-
-/**
- * Statistics about the CPUs of a guest.
- *
- * @param activeTime The cumulative time (in seconds) that the CPUs of the guest were actively running.
- * @param idleTime The cumulative time (in seconds) the CPUs of the guest were idle.
- * @param stealTime The cumulative CPU time (in seconds) that the guest was ready to run, but not granted time by the host.
- * @param lostTime The cumulative CPU time (in seconds) that was lost due to interference with other machines.
- * @param capacity The available CPU capacity of the guest (in MHz).
- * @param usage Amount of CPU resources (in MHz) actually used by the guest.
- * @param utilization The utilization of the CPU resources (in %) relative to the total CPU capacity.
- */
-public record GuestCpuStats(
- long activeTime,
- long idleTime,
- long stealTime,
- long lostTime,
- double capacity,
- double usage,
- double utilization) {}
diff --git a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/telemetry/GuestSystemStats.java b/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/telemetry/GuestSystemStats.java
deleted file mode 100644
index dbf98dd5..00000000
--- a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/telemetry/GuestSystemStats.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2022 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.telemetry;
-
-import java.time.Duration;
-import java.time.Instant;
-
-/**
- * System-level statistics of a guest.
- *
- * @param uptime The cumulative uptime of the guest since last boot (in ms).
- * @param downtime The cumulative downtime of the guest since last boot (in ms).
- * @param bootTime The time at which the guest booted.
- */
-public record GuestSystemStats(Duration uptime, Duration downtime, Instant bootTime) {}
diff --git a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/telemetry/HostCpuStats.java b/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/telemetry/HostCpuStats.java
deleted file mode 100644
index d1c2328b..00000000
--- a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/telemetry/HostCpuStats.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2022 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.telemetry;
-
-/**
- * Statistics about the CPUs of a host.
- *
- * @param activeTime The cumulative time (in seconds) that the CPUs of the host were actively running.
- * @param idleTime The cumulative time (in seconds) the CPUs of the host were idle.
- * @param stealTime The cumulative CPU time (in seconds) that virtual machines were ready to run, but were not able to.
- * @param lostTime The cumulative CPU time (in seconds) that was lost due to interference between virtual machines.
- * @param capacity The available CPU capacity of the host (in MHz).
- * @param demand Amount of CPU resources (in MHz) the guests would use if there were no CPU contention or CPU
- * limits.
- * @param usage Amount of CPU resources (in MHz) actually used by the host.
- * @param utilization The utilization of the CPU resources (in %) relative to the total CPU capacity.
- */
-public record HostCpuStats(
- long activeTime,
- long idleTime,
- long stealTime,
- long lostTime,
- double capacity,
- double demand,
- double usage,
- double utilization) {}
diff --git a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/telemetry/HostSystemStats.java b/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/telemetry/HostSystemStats.java
deleted file mode 100644
index c0713f3c..00000000
--- a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/telemetry/HostSystemStats.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2022 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.telemetry;
-
-import java.time.Duration;
-import java.time.Instant;
-
-/**
- * System-level statistics of a host.
- *
- * @param uptime The cumulative uptime of the host since last boot (in ms).
- * @param downtime The cumulative downtime of the host since last boot (in ms).
- * @param bootTime The time at which the task started.
- * @param powerDraw Instantaneous power draw of the system (in W).
- * @param energyUsage The cumulative energy usage of the system (in J).
- * @param guestsTerminated The number of guests that are in a terminated state.
- * @param guestsRunning The number of guests that are in a running state.
- * @param guestsError The number of guests that are in an error state.
- * @param guestsInvalid The number of guests that are in an unknown state.
- */
-public record HostSystemStats(
- Duration uptime,
- Duration downtime,
- Instant bootTime,
- double powerDraw,
- double energyUsage,
- int guestsTerminated,
- int guestsRunning,
- int guestsError,
- int guestsInvalid) {}
diff --git a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/telemetry/SchedulerStats.java b/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/telemetry/SchedulerStats.java
deleted file mode 100644
index fc044d8c..00000000
--- a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/telemetry/SchedulerStats.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2022 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.telemetry;
-
-/**
- * Statistics about the scheduling component of the [ComputeService].
- *
- * @param hostsAvailable The number of hosts currently available for scheduling.
- * @param hostsUnavailable The number of hosts unavailable for scheduling.
- * @param attemptsSuccess Scheduling attempts that resulted into an allocation onto a host.
- * @param attemptsFailure The number of failed scheduling attempt due to insufficient capacity at the moment.
- * @param attemptsError The number of scheduling attempts that failed due to system error.
- * @param tasksTotal The number of tasks registered with the service.
- * @param tasksPending The number of tasks that are pending to be scheduled.
- * @param tasksActive The number of tasks that are currently managed by the service and running.
- */
-public record SchedulerStats(
- int hostsAvailable,
- int hostsUnavailable,
- long attemptsSuccess,
- long attemptsFailure,
- long attemptsError,
- int tasksTotal,
- int tasksPending,
- int tasksActive) {}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ComputeScheduler.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ComputeScheduler.kt
deleted file mode 100644
index 42de9ebc..00000000
--- a/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.Task
-import org.opendc.compute.service.ComputeService
-import org.opendc.compute.service.HostView
-
-/**
- * A generic scheduler interface used by the [ComputeService] to select hosts to place [Task]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 [task].
- *
- * @param task 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(task: Task): HostView?
-}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ComputeSchedulers.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ComputeSchedulers.kt
deleted file mode 100644
index 7fcc670f..00000000
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ComputeSchedulers.kt
+++ /dev/null
@@ -1,118 +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.
- */
-
-@file:JvmName("ComputeSchedulers")
-
-package org.opendc.compute.service.scheduler
-
-import org.opendc.compute.service.scheduler.filters.ComputeFilter
-import org.opendc.compute.service.scheduler.filters.RamFilter
-import org.opendc.compute.service.scheduler.filters.VCpuFilter
-import org.opendc.compute.service.scheduler.weights.CoreRamWeigher
-import org.opendc.compute.service.scheduler.weights.InstanceCountWeigher
-import org.opendc.compute.service.scheduler.weights.RamWeigher
-import org.opendc.compute.service.scheduler.weights.VCpuWeigher
-import java.util.SplittableRandom
-import java.util.random.RandomGenerator
-
-public enum class ComputeSchedulerEnum {
- Mem,
- MemInv,
- CoreMem,
- CoreMemInv,
- ActiveServers,
- ActiveServersInv,
- ProvisionedCores,
- ProvisionedCoresInv,
- Random,
- Replay,
-}
-
-public fun createComputeScheduler(
- name: String,
- seeder: RandomGenerator,
- placements: Map<String, String> = emptyMap(),
-): ComputeScheduler {
- return createComputeScheduler(ComputeSchedulerEnum.valueOf(name.uppercase()), seeder, placements)
-}
-
-/**
- * Create a [ComputeScheduler] for the experiment.
- */
-public fun createComputeScheduler(
- name: ComputeSchedulerEnum,
- seeder: RandomGenerator,
- placements: Map<String, String> = emptyMap(),
-): ComputeScheduler {
- val cpuAllocationRatio = 1.0
- val ramAllocationRatio = 1.5
- return when (name) {
- ComputeSchedulerEnum.Mem ->
- FilterScheduler(
- filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)),
- weighers = listOf(RamWeigher(multiplier = 1.0)),
- )
- ComputeSchedulerEnum.MemInv ->
- FilterScheduler(
- filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)),
- weighers = listOf(RamWeigher(multiplier = -1.0)),
- )
- ComputeSchedulerEnum.CoreMem ->
- FilterScheduler(
- filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)),
- weighers = listOf(CoreRamWeigher(multiplier = 1.0)),
- )
- ComputeSchedulerEnum.CoreMemInv ->
- FilterScheduler(
- filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)),
- weighers = listOf(CoreRamWeigher(multiplier = -1.0)),
- )
- ComputeSchedulerEnum.ActiveServers ->
- FilterScheduler(
- filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)),
- weighers = listOf(InstanceCountWeigher(multiplier = -1.0)),
- )
- ComputeSchedulerEnum.ActiveServersInv ->
- FilterScheduler(
- filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)),
- weighers = listOf(InstanceCountWeigher(multiplier = 1.0)),
- )
- ComputeSchedulerEnum.ProvisionedCores ->
- FilterScheduler(
- filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)),
- weighers = listOf(VCpuWeigher(cpuAllocationRatio, multiplier = 1.0)),
- )
- ComputeSchedulerEnum.ProvisionedCoresInv ->
- FilterScheduler(
- filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)),
- weighers = listOf(VCpuWeigher(cpuAllocationRatio, multiplier = -1.0)),
- )
- ComputeSchedulerEnum.Random ->
- FilterScheduler(
- filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)),
- weighers = emptyList(),
- subsetSize = Int.MAX_VALUE,
- random = SplittableRandom(seeder.nextLong()),
- )
- ComputeSchedulerEnum.Replay -> ReplayScheduler(placements)
- }
-}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt
deleted file mode 100644
index 772a470d..00000000
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt
+++ /dev/null
@@ -1,111 +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.Task
-import org.opendc.compute.service.HostView
-import org.opendc.compute.service.scheduler.filters.HostFilter
-import org.opendc.compute.service.scheduler.weights.HostWeigher
-import java.util.SplittableRandom
-import java.util.random.RandomGenerator
-import kotlin.math.min
-
-/**
- * A [ComputeScheduler] implementation that uses filtering and weighing passes to select
- * the host to schedule a [Task] on.
- *
- * This implementation is based on the filter scheduler from OpenStack Nova.
- * See: https://docs.openstack.org/nova/latest/user/filter-scheduler.html
- *
- * @param filters The list of filters to apply when searching for an appropriate host.
- * @param weighers The list of weighers to apply when searching for an appropriate host.
- * @param subsetSize The size of the subset of best hosts from which a target is randomly chosen.
- * @param random A [RandomGenerator] instance for selecting
- */
-public class FilterScheduler(
- private val filters: List<HostFilter>,
- private val weighers: List<HostWeigher>,
- private val subsetSize: Int = 1,
- private val random: RandomGenerator = SplittableRandom(0),
-) : ComputeScheduler {
- /**
- * The pool of hosts available to the scheduler.
- */
- private val hosts = mutableListOf<HostView>()
-
- init {
- require(subsetSize >= 1) { "Subset size must be one or greater" }
- }
-
- override fun addHost(host: HostView) {
- hosts.add(host)
- }
-
- override fun removeHost(host: HostView) {
- hosts.remove(host)
- }
-
- override fun select(task: Task): HostView? {
- val hosts = hosts
- val filteredHosts = hosts.filter { host -> filters.all { filter -> filter.test(host, task) } }
-
- val subset =
- if (weighers.isNotEmpty()) {
- val results = weighers.map { it.getWeights(filteredHosts, task) }
- val weights = DoubleArray(filteredHosts.size)
-
- for (result in results) {
- val min = result.min
- val range = (result.max - min)
-
- // Skip result if all weights are the same
- if (range == 0.0) {
- continue
- }
-
- val multiplier = result.multiplier
- val factor = multiplier / range
-
- for ((i, weight) in result.weights.withIndex()) {
- weights[i] += factor * (weight - min)
- }
- }
-
- weights.indices
- .asSequence()
- .sortedByDescending { weights[it] }
- .map { filteredHosts[it] }
- .take(subsetSize)
- .toList()
- } else {
- filteredHosts
- }
-
- // fixme: currently finding no matching hosts can result in an error
- return when (val maxSize = min(subsetSize, subset.size)) {
- 0 -> null
- 1 -> subset[0]
- else -> subset[random.nextInt(maxSize)]
- }
- }
-}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ReplayScheduler.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ReplayScheduler.kt
deleted file mode 100644
index d1690ddf..00000000
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ReplayScheduler.kt
+++ /dev/null
@@ -1,65 +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.Task
-import org.opendc.compute.service.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(task: Task): HostView? {
- val clusterName =
- vmPlacements[task.name]
- ?: throw IllegalStateException("Could not find placement data in VM placement file for VM ${task.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 ${task.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/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeFilter.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeFilter.kt
deleted file mode 100644
index 2ad626f3..00000000
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeFilter.kt
+++ /dev/null
@@ -1,42 +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.Task
-import org.opendc.compute.service.HostView
-import org.opendc.compute.service.driver.HostState
-
-/**
- * A [HostFilter] that filters on active hosts.
- */
-public class ComputeFilter : HostFilter {
- override fun test(
- host: HostView,
- task: Task,
- ): Boolean {
- val result = host.host.state == HostState.UP
- return result
- }
-
- override fun toString(): String = "ComputeFilter"
-}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/DifferentHostFilter.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/DifferentHostFilter.kt
deleted file mode 100644
index ffafeaa9..00000000
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/DifferentHostFilter.kt
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2022 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.Task
-import org.opendc.compute.service.HostView
-import java.util.UUID
-
-/**
- * A [HostFilter] that ensures an instance is scheduled on a different host from a set of instances.
- */
-public class DifferentHostFilter : HostFilter {
- override fun test(
- host: HostView,
- task: Task,
- ): Boolean {
- @Suppress("UNCHECKED_CAST")
- val affinityUUIDs = task.meta["scheduler_hint:different_host"] as? Set<UUID> ?: return true
- return host.host.instances.none { it.uid in affinityUUIDs }
- }
-}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/HostFilter.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/HostFilter.kt
deleted file mode 100644
index f506127a..00000000
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/HostFilter.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.scheduler.filters
-
-import org.opendc.compute.api.Task
-import org.opendc.compute.service.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 [task].
- */
- public fun test(
- host: HostView,
- task: Task,
- ): Boolean
-}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/InstanceCountFilter.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/InstanceCountFilter.kt
deleted file mode 100644
index 7d5eb400..00000000
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/InstanceCountFilter.kt
+++ /dev/null
@@ -1,42 +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.Task
-import org.opendc.compute.service.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,
- task: Task,
- ): Boolean {
- return host.instanceCount < limit
- }
-
- override fun toString(): String = "InstanceCountFilter[limit=$limit]"
-}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/RamFilter.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/RamFilter.kt
deleted file mode 100644
index 0a28ccc6..00000000
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/RamFilter.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.service.scheduler.filters
-
-import org.opendc.compute.api.Task
-import org.opendc.compute.service.HostView
-
-/**
- * A [HostFilter] that filters hosts based on the memory requirements of a [Task] and the RAM available on the host.
- *
- * @param allocationRatio Virtual RAM to physical RAM allocation ratio.
- */
-public class RamFilter(private val allocationRatio: Double) : HostFilter {
- override fun test(
- host: HostView,
- task: Task,
- ): Boolean {
- val requestedMemory = task.flavor.memorySize
- val availableMemory = host.availableMemory
- val memoryCapacity = host.host.model.memoryCapacity
-
- // Do not allow an instance to overcommit against itself, only against
- // other instances.
- if (requestedMemory > memoryCapacity) {
- return false
- }
-
- val limit = memoryCapacity * allocationRatio
- val used = memoryCapacity - availableMemory
- val usable = limit - used
-
- val result = usable >= requestedMemory
- return result
- }
-}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/SameHostFilter.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/SameHostFilter.kt
deleted file mode 100644
index d8634285..00000000
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/SameHostFilter.kt
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2022 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.Task
-import org.opendc.compute.service.HostView
-import java.util.UUID
-
-/**
- * A [HostFilter] that ensures an instance is scheduled on the same host as all other instances in a set of instances.
- */
-public class SameHostFilter : HostFilter {
- override fun test(
- host: HostView,
- task: Task,
- ): Boolean {
- @Suppress("UNCHECKED_CAST")
- val affinityUUIDs = task.meta["scheduler_hint:same_host"] as? Set<UUID> ?: return true
- return host.host.instances.any { it.uid in affinityUUIDs }
- }
-}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/VCpuCapacityFilter.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/VCpuCapacityFilter.kt
deleted file mode 100644
index 5af7ccf0..00000000
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/VCpuCapacityFilter.kt
+++ /dev/null
@@ -1,43 +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.Task
-import org.opendc.compute.service.HostView
-
-/**
- * A [HostFilter] that filters hosts based on the vCPU speed requirements of a [Task] and the available
- * capacity on the host.
- */
-public class VCpuCapacityFilter : HostFilter {
- override fun test(
- host: HostView,
- task: Task,
- ): Boolean {
- val requiredCapacity = task.flavor.meta["cpu-capacity"] as? Double
- val hostModel = host.host.model
- val availableCapacity = hostModel.cpuCapacity
-
- return requiredCapacity == null || availableCapacity >= (requiredCapacity / task.flavor.coreCount)
- }
-}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/VCpuFilter.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/VCpuFilter.kt
deleted file mode 100644
index 442e58f6..00000000
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/VCpuFilter.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.filters
-
-import org.opendc.compute.api.Task
-import org.opendc.compute.service.HostView
-
-/**
- * A [HostFilter] that filters hosts based on the vCPU requirements of a [Task] and the available vCPUs on the host.
- *
- * @param allocationRatio Virtual CPU to physical CPU allocation ratio.
- */
-public class VCpuFilter(private val allocationRatio: Double) : HostFilter {
- override fun test(
- host: HostView,
- task: Task,
- ): Boolean {
- val requested = task.flavor.coreCount
- val totalCores = host.host.model.coreCount
- val limit = totalCores * allocationRatio
-
- // Do not allow an instance to overcommit against itself, only against other instances
- if (requested > totalCores) {
- return false
- }
-
- val availableCores = limit - host.provisionedCores
- return availableCores >= requested
- }
-}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/CoreRamWeigher.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/CoreRamWeigher.kt
deleted file mode 100644
index 6e320bf4..00000000
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/CoreRamWeigher.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.service.scheduler.weights
-
-import org.opendc.compute.api.Task
-import org.opendc.compute.service.HostView
-
-/**
- * A [HostWeigher] that weighs the hosts based on the available memory per core on the host.
- *
- * @param multiplier Weight multiplier ratio. A positive value will result in the scheduler preferring hosts with more
- * available core memory, and a negative number will result in the scheduler preferring hosts with less available core
- * memory.
- */
-public class CoreRamWeigher(override val multiplier: Double = 1.0) : HostWeigher {
- override fun getWeight(
- host: HostView,
- task: Task,
- ): Double {
- return host.availableMemory.toDouble()
- }
-
- override fun toString(): String = "CoreRamWeigher"
-}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/HostWeigher.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/HostWeigher.kt
deleted file mode 100644
index 3f2c4123..00000000
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/HostWeigher.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.scheduler.weights
-
-import org.opendc.compute.api.Task
-import org.opendc.compute.service.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 interface HostWeigher {
- /**
- * The multiplier for the weigher.
- */
- public val multiplier: Double
-
- /**
- * Obtain the weight of the specified [host] when scheduling the specified [task].
- */
- public fun getWeight(
- host: HostView,
- task: Task,
- ): Double
-
- /**
- * Obtain the weights for [hosts] when scheduling the specified [task].
- */
- public fun getWeights(
- hosts: List<HostView>,
- task: Task,
- ): Result {
- val weights = DoubleArray(hosts.size)
- var min = Double.MAX_VALUE
- var max = Double.MIN_VALUE
-
- for ((i, host) in hosts.withIndex()) {
- val weight = getWeight(host, task)
- weights[i] = weight
- min = kotlin.math.min(min, weight)
- max = kotlin.math.max(max, weight)
- }
-
- return Result(weights, min, max, multiplier)
- }
-
- /**
- * A result returned by the weigher.
- *
- * @param weights The weights returned by the weigher.
- * @param min The minimum weight returned.
- * @param max The maximum weight returned.
- * @param multiplier The weight multiplier to use.
- */
- public class Result(
- public val weights: DoubleArray,
- public val min: Double,
- public val max: Double,
- public val multiplier: Double,
- )
-}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/InstanceCountWeigher.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/InstanceCountWeigher.kt
deleted file mode 100644
index 0789f109..00000000
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/InstanceCountWeigher.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.weights
-
-import org.opendc.compute.api.Task
-import org.opendc.compute.service.HostView
-
-/**
- * A [HostWeigher] that weighs the hosts based on the number of instances on the host.
- */
-public class InstanceCountWeigher(override val multiplier: Double = 1.0) : HostWeigher {
- override fun getWeight(
- host: HostView,
- task: Task,
- ): Double {
- return host.instanceCount.toDouble()
- }
-
- override fun toString(): String = "InstanceCountWeigher"
-}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/RamWeigher.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/RamWeigher.kt
deleted file mode 100644
index fb03d064..00000000
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/RamWeigher.kt
+++ /dev/null
@@ -1,43 +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.Task
-import org.opendc.compute.service.HostView
-
-/**
- * A [HostWeigher] that weighs the hosts based on the available RAM (memory) on the host.
- *
- * @param multiplier Weight multiplier ratio. A positive value will result in the scheduler preferring hosts with more
- * available memory, and a negative number will result in the scheduler preferring hosts with less memory.
- */
-public class RamWeigher(override val multiplier: Double = 1.0) : HostWeigher {
- override fun getWeight(
- host: HostView,
- task: Task,
- ): Double {
- return host.availableMemory.toDouble()
- }
-
- override fun toString(): String = "RamWeigher"
-}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/VCpuCapacityWeigher.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/VCpuCapacityWeigher.kt
deleted file mode 100644
index 5f99cab3..00000000
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/VCpuCapacityWeigher.kt
+++ /dev/null
@@ -1,42 +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.Task
-import org.opendc.compute.service.HostView
-
-/**
- * A [HostWeigher] that weighs the hosts based on the difference required vCPU capacity and the available CPU capacity.
- */
-public class VCpuCapacityWeigher(override val multiplier: Double = 1.0) : HostWeigher {
- override fun getWeight(
- host: HostView,
- task: Task,
- ): Double {
- val model = host.host.model
- val requiredCapacity = task.flavor.meta["cpu-capacity"] as? Double ?: 0.0
- return model.cpuCapacity - requiredCapacity / task.flavor.coreCount
- }
-
- override fun toString(): String = "VCpuWeigher"
-}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/VCpuWeigher.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/VCpuWeigher.kt
deleted file mode 100644
index 0c3d9c21..00000000
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/VCpuWeigher.kt
+++ /dev/null
@@ -1,46 +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.Task
-import org.opendc.compute.service.HostView
-
-/**
- * A [HostWeigher] that weighs the hosts based on the remaining number of vCPUs available.
- *
- * @param allocationRatio Virtual CPU to physical CPU allocation ratio.
- */
-public class VCpuWeigher(private val allocationRatio: Double, override val multiplier: Double = 1.0) : HostWeigher {
- init {
- require(allocationRatio > 0.0) { "Allocation ratio must be greater than zero" }
- }
-
- override fun getWeight(
- host: HostView,
- task: Task,
- ): Double {
- return allocationRatio - host.provisionedCores
- }
-
- override fun toString(): String = "VCpuWeigher"
-}
diff --git a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt b/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt
deleted file mode 100644
index eb686faf..00000000
--- a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt
+++ /dev/null
@@ -1,386 +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.coEvery
-import io.mockk.coVerify
-import io.mockk.every
-import io.mockk.mockk
-import io.mockk.slot
-import io.mockk.verify
-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.Flavor
-import org.opendc.compute.api.Image
-import org.opendc.compute.api.Task
-import org.opendc.compute.api.TaskState
-import org.opendc.compute.api.TaskWatcher
-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.ComputeFilter
-import org.opendc.compute.service.scheduler.filters.RamFilter
-import org.opendc.compute.service.scheduler.filters.VCpuFilter
-import org.opendc.compute.service.scheduler.weights.RamWeigher
-import org.opendc.simulator.kotlin.SimulationCoroutineScope
-import org.opendc.simulator.kotlin.runSimulation
-import java.time.Duration
-import java.util.UUID
-
-/**
- * Test suite for the [ComputeService] interface.
- */
-internal class ComputeServiceTest {
- private lateinit var scope: SimulationCoroutineScope
- private lateinit var service: ComputeService
-
- @BeforeEach
- fun setUp() {
- scope = SimulationCoroutineScope()
- val computeScheduler =
- FilterScheduler(
- filters = listOf(ComputeFilter(), VCpuFilter(allocationRatio = 1.0), RamFilter(allocationRatio = 1.0)),
- weighers = listOf(RamWeigher()),
- )
- service = ComputeService(scope.dispatcher, computeScheduler, Duration.ofMinutes(5), 10)
- }
-
- @Test
- fun testClientClose() =
- scope.runSimulation {
- val client = service.newClient()
-
- assertEquals(emptyList<Flavor>(), client.queryFlavors())
- assertEquals(emptyList<Image>(), client.queryImages())
- assertEquals(emptyList<Task>(), client.queryTasks())
-
- client.close()
-
- assertThrows<IllegalStateException> { client.queryFlavors() }
- assertThrows<IllegalStateException> { client.queryImages() }
- assertThrows<IllegalStateException> { client.queryTasks() }
-
- assertThrows<IllegalStateException> { client.findFlavor(UUID.randomUUID()) }
- assertThrows<IllegalStateException> { client.findImage(UUID.randomUUID()) }
- assertThrows<IllegalStateException> { client.findTask(UUID.randomUUID()) }
-
- assertThrows<IllegalStateException> { client.newFlavor("test", 1, 2) }
- assertThrows<IllegalStateException> { client.newImage("test") }
- assertThrows<IllegalStateException> { client.newTask("test", mockk(), mockk()) }
- }
-
- @Test
- fun testClientCreate() =
- scope.runSimulation {
- val client = service.newClient()
-
- val flavor = client.newFlavor("test", 1, 1024)
- assertEquals(listOf(flavor), client.queryFlavors())
- assertEquals(flavor, client.findFlavor(flavor.uid))
- val image = client.newImage("test")
- assertEquals(listOf(image), client.queryImages())
- assertEquals(image, client.findImage(image.uid))
- val server = client.newTask("test", image, flavor, start = false)
- assertEquals(listOf(server), client.queryTasks())
- assertEquals(server, client.findTask(server.uid))
-
- server.delete()
- assertNull(client.findTask(server.uid))
-
- image.delete()
- assertNull(client.findImage(image.uid))
-
- flavor.delete()
- assertNull(client.findFlavor(flavor.uid))
-
- assertThrows<IllegalStateException> { server.start() }
- }
-
- @Test
- fun testClientOnClose() =
- scope.runSimulation {
- service.close()
- assertThrows<IllegalStateException> {
- service.newClient()
- }
- }
-
- @Test
- fun testAddHost() =
- scope.runSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
-
- every { host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { host.state } returns HostState.UP
-
- assertEquals(emptySet<Host>(), service.hosts)
-
- service.addHost(host)
-
- verify(exactly = 1) { host.addListener(any()) }
-
- assertEquals(1, service.hosts.size)
-
- service.removeHost(host)
-
- verify(exactly = 1) { host.removeListener(any()) }
- }
-
- @Test
- fun testAddHostDouble() =
- scope.runSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
-
- every { host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { host.state } returns HostState.DOWN
-
- assertEquals(emptySet<Host>(), service.hosts)
-
- service.addHost(host)
- service.addHost(host)
-
- verify(exactly = 1) { host.addListener(any()) }
- }
-
- @Test
- fun testServerStartWithoutEnoughCpus() =
- scope.runSimulation {
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 0)
- val image = client.newImage("test")
- val server = client.newTask("test", image, flavor, start = false)
-
- server.start()
- delay(5L * 60 * 1000)
- server.reload()
- assertEquals(TaskState.TERMINATED, server.state)
- }
-
- @Test
- fun testServerStartWithoutEnoughMemory() =
- scope.runSimulation {
- val client = service.newClient()
- val flavor = client.newFlavor("test", 0, 1024)
- val image = client.newImage("test")
- val server = client.newTask("test", image, flavor, start = false)
-
- server.start()
- delay(5L * 60 * 1000)
- server.reload()
- assertEquals(TaskState.TERMINATED, server.state)
- }
-
- @Test
- fun testServerStartWithoutEnoughResources() =
- scope.runSimulation {
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 1024)
- val image = client.newImage("test")
- val server = client.newTask("test", image, flavor, start = false)
-
- server.start()
- delay(5L * 60 * 1000)
- server.reload()
- assertEquals(TaskState.TERMINATED, server.state)
- }
-
- @Test
- fun testServerCancelRequest() =
- scope.runSimulation {
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 1024)
- val image = client.newImage("test")
- val server = client.newTask("test", image, flavor, start = false)
-
- server.start()
- server.stop()
- delay(5L * 60 * 1000)
- server.reload()
- assertEquals(TaskState.TERMINATED, server.state)
- }
-
- @Test
- fun testServerCannotFitOnHost() =
- scope.runSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
-
- every { host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { host.state } returns HostState.UP
- every { host.canFit(any()) } returns false
-
- service.addHost(host)
-
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 1024)
- val image = client.newImage("test")
- val server = client.newTask("test", image, flavor, start = false)
-
- server.start()
- delay(10L * 60 * 1000)
- server.reload()
- assertEquals(TaskState.PROVISIONING, server.state)
-
- verify { host.canFit(server) }
- }
-
- @Test
- fun testHostAvailableAfterSomeTime() =
- scope.runSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
- val listeners = mutableListOf<HostListener>()
-
- every { host.uid } returns UUID.randomUUID()
- every { host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { host.state } returns HostState.DOWN
- every { host.addListener(any()) } answers { listeners.add(it.invocation.args[0] as HostListener) }
- every { host.canFit(any()) } returns false
-
- service.addHost(host)
-
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 1024)
- val image = client.newImage("test")
- val server = client.newTask("test", image, flavor, start = false)
-
- server.start()
- delay(5L * 60 * 1000)
-
- every { host.state } returns HostState.UP
- listeners.forEach { it.onStateChanged(host, HostState.UP) }
-
- delay(5L * 60 * 1000)
- server.reload()
- assertEquals(TaskState.PROVISIONING, server.state)
-
- verify { host.canFit(server) }
- }
-
- @Test
- fun testHostUnavailableAfterSomeTime() =
- scope.runSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
- val listeners = mutableListOf<HostListener>()
-
- every { host.uid } returns UUID.randomUUID()
- every { host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { host.state } returns HostState.UP
- every { host.addListener(any()) } answers { listeners.add(it.invocation.args[0] as HostListener) }
- every { host.canFit(any()) } returns false
-
- service.addHost(host)
-
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 1024)
- val image = client.newImage("test")
- val server = client.newTask("test", image, flavor, start = false)
-
- delay(5L * 60 * 1000)
-
- every { host.state } returns HostState.DOWN
- listeners.forEach { it.onStateChanged(host, HostState.DOWN) }
-
- server.start()
- delay(5L * 60 * 1000)
- server.reload()
- assertEquals(TaskState.PROVISIONING, server.state)
-
- verify(exactly = 0) { host.canFit(server) }
- }
-
- @Test
- fun testServerDeploy() =
- scope.runSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
- val listeners = mutableListOf<HostListener>()
-
- every { host.uid } returns UUID.randomUUID()
- every { host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { host.state } returns HostState.UP
- every { host.canFit(any()) } returns true
- every { host.addListener(any()) } answers { listeners.add(it.invocation.args[0] as HostListener) }
-
- service.addHost(host)
-
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 1024)
- val image = client.newImage("test")
- val server = client.newTask("test", image, flavor, start = false)
- val slot = slot<Task>()
-
- val watcher = mockk<TaskWatcher>(relaxUnitFun = true)
- server.watch(watcher)
-
- // Start server
- server.start()
- delay(5L * 60 * 1000)
- coVerify { host.spawn(capture(slot)) }
-
- listeners.forEach { it.onStateChanged(host, slot.captured, TaskState.RUNNING) }
-
- server.reload()
- assertEquals(TaskState.RUNNING, server.state)
-
- verify { watcher.onStateChanged(server, TaskState.RUNNING) }
-
- // Stop server
- listeners.forEach { it.onStateChanged(host, slot.captured, TaskState.TERMINATED) }
-
- server.reload()
- assertEquals(TaskState.TERMINATED, server.state)
-
- verify { watcher.onStateChanged(server, TaskState.TERMINATED) }
- }
-
- @Test
- fun testServerDeployFailure() =
- scope.runSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
- val listeners = mutableListOf<HostListener>()
-
- every { host.uid } returns UUID.randomUUID()
- every { host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { host.state } returns HostState.UP
- every { host.canFit(any()) } returns true
- every { host.addListener(any()) } answers { listeners.add(it.invocation.args[0] as HostListener) }
- coEvery { host.spawn(any()) } throws IllegalStateException()
-
- service.addHost(host)
-
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 1024)
- val image = client.newImage("test")
- val server = client.newTask("test", image, flavor, start = false)
-
- server.start()
- delay(5L * 60 * 1000)
-
- server.reload()
- assertEquals(TaskState.PROVISIONING, server.state)
- }
-}
diff --git a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ServiceFlavorTest.kt b/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ServiceFlavorTest.kt
deleted file mode 100644
index 7938f789..00000000
--- a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ServiceFlavorTest.kt
+++ /dev/null
@@ -1,67 +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.every
-import io.mockk.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 java.util.UUID
-
-/**
- * Test suite for the [ServiceFlavor] implementation.
- */
-class ServiceFlavorTest {
- @Test
- fun testEquality() {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val a = ServiceFlavor(service, uid, "test", 1, 1024, mutableMapOf(), mutableMapOf<String, Any>())
- val b = ServiceFlavor(service, uid, "test", 1, 1024, mutableMapOf(), mutableMapOf<String, Any>())
-
- assertEquals(a, b)
- }
-
- @Test
- fun testInequalityWithDifferentType() {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val a = ServiceFlavor(service, uid, "test", 1, 1024, mutableMapOf(), mutableMapOf<String, Any>())
-
- val b = mockk<Flavor>(relaxUnitFun = true)
- every { b.uid } returns UUID.randomUUID()
-
- assertNotEquals(a, b)
- }
-
- @Test
- fun testInequalityWithIncorrectType() {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val a = ServiceFlavor(service, uid, "test", 1, 1024, mutableMapOf(), mutableMapOf<String, Any>())
-
- assertNotEquals(a, Unit)
- }
-}
diff --git a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ServiceImageTest.kt b/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ServiceImageTest.kt
deleted file mode 100644
index c36d75f4..00000000
--- a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ServiceImageTest.kt
+++ /dev/null
@@ -1,67 +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.every
-import io.mockk.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 java.util.UUID
-
-/**
- * Test suite for the [ServiceFlavor] implementation.
- */
-class ServiceImageTest {
- @Test
- fun testEquality() {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val a = ServiceImage(service, uid, "test", mutableMapOf(), mutableMapOf<String, Any>())
- val b = ServiceImage(service, uid, "test", mutableMapOf(), mutableMapOf<String, Any>())
-
- assertEquals(a, b)
- }
-
- @Test
- fun testInequalityWithDifferentType() {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val a = ServiceImage(service, uid, "test", mutableMapOf(), mutableMapOf<String, Any>())
-
- val b = mockk<Image>(relaxUnitFun = true)
- every { b.uid } returns UUID.randomUUID()
-
- assertNotEquals(a, b)
- }
-
- @Test
- fun testInequalityWithIncorrectType() {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val a = ServiceImage(service, uid, "test", mutableMapOf(), mutableMapOf<String, Any>())
-
- assertNotEquals(a, Unit)
- }
-}
diff --git a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ServiceTaskTest.kt b/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ServiceTaskTest.kt
deleted file mode 100644
index e77665fe..00000000
--- a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ServiceTaskTest.kt
+++ /dev/null
@@ -1,442 +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.every
-import io.mockk.mockk
-import io.mockk.verify
-import kotlinx.coroutines.yield
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertNotEquals
-import org.junit.jupiter.api.Assertions.assertTrue
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.assertThrows
-import org.opendc.compute.api.Task
-import org.opendc.compute.api.TaskState
-import org.opendc.compute.service.driver.Host
-import org.opendc.simulator.kotlin.runSimulation
-import java.util.UUID
-
-/**
- * Test suite for the [ServiceTask] implementation.
- */
-class ServiceTaskTest {
- @Test
- fun testEquality() {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
-
- val a =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
- val b =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
-
- assertEquals(a, b)
- }
-
- @Test
- fun testInequalityWithDifferentType() {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val a =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
-
- val b = mockk<Task>(relaxUnitFun = true)
- every { b.uid } returns UUID.randomUUID()
-
- assertNotEquals(a, b)
- }
-
- @Test
- fun testInequalityWithIncorrectType() {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val a =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
-
- assertNotEquals(a, Unit)
- }
-
- @Test
- fun testStartTerminatedServer() =
- runSimulation {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
-
- every { service.schedule(any()) } answers { ComputeService.SchedulingRequest(it.invocation.args[0] as ServiceTask, 0) }
-
- server.start()
-
- verify(exactly = 1) { service.schedule(server) }
- assertEquals(TaskState.PROVISIONING, server.state)
- }
-
- @Test
- fun testStartDeletedServer() =
- runSimulation {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
-
- server.setState(TaskState.DELETED)
-
- assertThrows<IllegalStateException> { server.start() }
- }
-
- @Test
- fun testStartProvisioningServer() =
- runSimulation {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
-
- server.setState(TaskState.PROVISIONING)
-
- server.start()
-
- assertEquals(TaskState.PROVISIONING, server.state)
- }
-
- @Test
- fun testStartRunningServer() =
- runSimulation {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
-
- server.setState(TaskState.RUNNING)
-
- server.start()
-
- assertEquals(TaskState.RUNNING, server.state)
- }
-
- @Test
- fun testStopProvisioningServer() =
- runSimulation {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
- val request = ComputeService.SchedulingRequest(server, 0)
-
- every { service.schedule(any()) } returns request
-
- server.start()
- server.stop()
-
- assertTrue(request.isCancelled)
- assertEquals(TaskState.TERMINATED, server.state)
- }
-
- @Test
- fun testStopTerminatedServer() =
- runSimulation {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
-
- server.setState(TaskState.TERMINATED)
- server.stop()
-
- assertEquals(TaskState.TERMINATED, server.state)
- }
-
- @Test
- fun testStopDeletedServer() =
- runSimulation {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
-
- server.setState(TaskState.DELETED)
- server.stop()
-
- assertEquals(TaskState.DELETED, server.state)
- }
-
- @Test
- fun testStopRunningServer() =
- runSimulation {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
- val host = mockk<Host>(relaxUnitFun = true)
-
- server.setState(TaskState.RUNNING)
- server.host = host
- server.stop()
- yield()
-
- verify { host.stop(server) }
- }
-
- @Test
- fun testDeleteProvisioningServer() =
- runSimulation {
- val service = mockk<ComputeService>(relaxUnitFun = true)
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
- val request = ComputeService.SchedulingRequest(server, 0)
-
- every { service.schedule(any()) } returns request
-
- server.start()
- server.delete()
-
- assertTrue(request.isCancelled)
- assertEquals(TaskState.DELETED, server.state)
- verify { service.delete(server) }
- }
-
- @Test
- fun testDeleteTerminatedServer() =
- runSimulation {
- val service = mockk<ComputeService>(relaxUnitFun = true)
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
-
- server.setState(TaskState.TERMINATED)
- server.delete()
-
- assertEquals(TaskState.DELETED, server.state)
-
- verify { service.delete(server) }
- }
-
- @Test
- fun testDeleteDeletedServer() =
- runSimulation {
- val service = mockk<ComputeService>(relaxUnitFun = true)
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
-
- server.setState(TaskState.DELETED)
- server.delete()
-
- assertEquals(TaskState.DELETED, server.state)
- }
-
- @Test
- fun testDeleteRunningServer() =
- runSimulation {
- val service = mockk<ComputeService>(relaxUnitFun = true)
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
- val host = mockk<Host>(relaxUnitFun = true)
-
- server.setState(TaskState.RUNNING)
- server.host = host
- server.delete()
- yield()
-
- verify { host.delete(server) }
- verify { service.delete(server) }
- }
-
- private fun mockFlavor(): ServiceFlavor {
- val flavor = mockk<ServiceFlavor>()
- every { flavor.name } returns "c5.large"
- every { flavor.uid } returns UUID.randomUUID()
- every { flavor.coreCount } returns 2
- every { flavor.memorySize } returns 4096
- return flavor
- }
-
- private fun mockImage(): ServiceImage {
- val image = mockk<ServiceImage>()
- every { image.name } returns "ubuntu-20.04"
- every { image.uid } returns UUID.randomUUID()
- return image
- }
-}
diff --git a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/scheduler/FilterSchedulerTest.kt b/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/scheduler/FilterSchedulerTest.kt
deleted file mode 100644
index add10f8f..00000000
--- a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/scheduler/FilterSchedulerTest.kt
+++ /dev/null
@@ -1,536 +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 io.mockk.every
-import io.mockk.mockk
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertNull
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.assertAll
-import org.junit.jupiter.api.assertThrows
-import org.opendc.compute.api.Task
-import org.opendc.compute.service.HostView
-import org.opendc.compute.service.driver.HostModel
-import org.opendc.compute.service.driver.HostState
-import org.opendc.compute.service.scheduler.filters.ComputeFilter
-import org.opendc.compute.service.scheduler.filters.DifferentHostFilter
-import org.opendc.compute.service.scheduler.filters.InstanceCountFilter
-import org.opendc.compute.service.scheduler.filters.RamFilter
-import org.opendc.compute.service.scheduler.filters.SameHostFilter
-import org.opendc.compute.service.scheduler.filters.VCpuCapacityFilter
-import org.opendc.compute.service.scheduler.filters.VCpuFilter
-import org.opendc.compute.service.scheduler.weights.CoreRamWeigher
-import org.opendc.compute.service.scheduler.weights.InstanceCountWeigher
-import org.opendc.compute.service.scheduler.weights.RamWeigher
-import org.opendc.compute.service.scheduler.weights.VCpuWeigher
-import java.util.Random
-import java.util.UUID
-
-/**
- * Test suite for the [FilterScheduler].
- */
-internal class FilterSchedulerTest {
- @Test
- fun testInvalidSubsetSize() {
- assertThrows<IllegalArgumentException> {
- FilterScheduler(
- filters = emptyList(),
- weighers = emptyList(),
- subsetSize = 0,
- )
- }
-
- assertThrows<IllegalArgumentException> {
- FilterScheduler(
- filters = emptyList(),
- weighers = emptyList(),
- subsetSize = -2,
- )
- }
- }
-
- @Test
- fun testNoHosts() {
- val scheduler =
- FilterScheduler(
- filters = emptyList(),
- weighers = emptyList(),
- )
-
- val task = mockk<Task>()
- every { task.flavor.coreCount } returns 2
- every { task.flavor.memorySize } returns 1024
-
- assertNull(scheduler.select(task))
- }
-
- @Test
- fun testNoFiltersAndSchedulers() {
- val scheduler =
- FilterScheduler(
- filters = emptyList(),
- weighers = emptyList(),
- )
-
- val hostA = mockk<HostView>()
- every { hostA.host.state } returns HostState.DOWN
-
- val hostB = mockk<HostView>()
- every { hostB.host.state } returns HostState.UP
-
- scheduler.addHost(hostA)
- scheduler.addHost(hostB)
-
- val task = mockk<Task>()
- every { task.flavor.coreCount } returns 2
- every { task.flavor.memorySize } returns 1024
-
- // Make sure we get the first host both times
- assertAll(
- { assertEquals(hostA, scheduler.select(task)) },
- { assertEquals(hostA, scheduler.select(task)) },
- )
- }
-
- @Test
- fun testNoFiltersAndSchedulersRandom() {
- val scheduler =
- FilterScheduler(
- filters = emptyList(),
- weighers = emptyList(),
- subsetSize = Int.MAX_VALUE,
- random = Random(1),
- )
-
- val hostA = mockk<HostView>()
- every { hostA.host.state } returns HostState.DOWN
-
- val hostB = mockk<HostView>()
- every { hostB.host.state } returns HostState.UP
-
- scheduler.addHost(hostA)
- scheduler.addHost(hostB)
-
- val task = mockk<Task>()
- every { task.flavor.coreCount } returns 2
- every { task.flavor.memorySize } returns 1024
-
- // Make sure we get the first host both times
- assertAll(
- { assertEquals(hostB, scheduler.select(task)) },
- { assertEquals(hostA, scheduler.select(task)) },
- )
- }
-
- @Test
- fun testHostIsDown() {
- val scheduler =
- FilterScheduler(
- filters = listOf(ComputeFilter()),
- weighers = emptyList(),
- )
-
- val host = mockk<HostView>()
- every { host.host.state } returns HostState.DOWN
-
- scheduler.addHost(host)
-
- val task = mockk<Task>()
- every { task.flavor.coreCount } returns 2
- every { task.flavor.memorySize } returns 1024
-
- assertNull(scheduler.select(task))
- }
-
- @Test
- fun testHostIsUp() {
- val scheduler =
- FilterScheduler(
- filters = listOf(ComputeFilter()),
- weighers = emptyList(),
- )
-
- val host = mockk<HostView>()
- every { host.host.state } returns HostState.UP
-
- scheduler.addHost(host)
-
- val task = mockk<Task>()
- every { task.flavor.coreCount } returns 2
- every { task.flavor.memorySize } returns 1024
-
- assertEquals(host, scheduler.select(task))
- }
-
- @Test
- fun testRamFilter() {
- val scheduler =
- FilterScheduler(
- filters = listOf(RamFilter(1.0)),
- weighers = emptyList(),
- )
-
- val hostA = mockk<HostView>()
- every { hostA.host.state } returns HostState.UP
- every { hostA.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostA.availableMemory } returns 512
-
- val hostB = mockk<HostView>()
- every { hostB.host.state } returns HostState.UP
- every { hostB.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostB.availableMemory } returns 2048
-
- scheduler.addHost(hostA)
- scheduler.addHost(hostB)
-
- val task = mockk<Task>()
- every { task.flavor.coreCount } returns 2
- every { task.flavor.memorySize } returns 1024
-
- assertEquals(hostB, scheduler.select(task))
- }
-
- @Test
- fun testRamFilterOvercommit() {
- val scheduler =
- FilterScheduler(
- filters = listOf(RamFilter(1.5)),
- weighers = emptyList(),
- )
-
- val host = mockk<HostView>()
- every { host.host.state } returns HostState.UP
- every { host.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { host.availableMemory } returns 2048
-
- scheduler.addHost(host)
-
- val task = mockk<Task>()
- every { task.flavor.coreCount } returns 2
- every { task.flavor.memorySize } returns 2300
-
- assertNull(scheduler.select(task))
- }
-
- @Test
- fun testVCpuFilter() {
- val scheduler =
- FilterScheduler(
- filters = listOf(VCpuFilter(1.0)),
- weighers = emptyList(),
- )
-
- val hostA = mockk<HostView>()
- every { hostA.host.state } returns HostState.UP
- every { hostA.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostA.provisionedCores } returns 3
-
- val hostB = mockk<HostView>()
- every { hostB.host.state } returns HostState.UP
- every { hostB.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostB.provisionedCores } returns 0
-
- scheduler.addHost(hostA)
- scheduler.addHost(hostB)
-
- val task = mockk<Task>()
- every { task.flavor.coreCount } returns 2
- every { task.flavor.memorySize } returns 1024
-
- assertEquals(hostB, scheduler.select(task))
- }
-
- @Test
- fun testVCpuFilterOvercommit() {
- val scheduler =
- FilterScheduler(
- filters = listOf(VCpuFilter(16.0)),
- weighers = emptyList(),
- )
-
- val host = mockk<HostView>()
- every { host.host.state } returns HostState.UP
- every { host.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { host.provisionedCores } returns 0
-
- scheduler.addHost(host)
-
- val task = mockk<Task>()
- every { task.flavor.coreCount } returns 8
- every { task.flavor.memorySize } returns 1024
-
- assertNull(scheduler.select(task))
- }
-
-// TODO: fix when schedulers are reworked
-// @Test
- fun testVCpuCapacityFilter() {
- val scheduler =
- FilterScheduler(
- filters = listOf(VCpuCapacityFilter()),
- weighers = emptyList(),
- )
-
- val hostA = mockk<HostView>()
- every { hostA.host.state } returns HostState.UP
- every { hostA.host.model } returns HostModel(8 * 2600.0, 8, 2048)
- every { hostA.availableMemory } returns 512
- scheduler.addHost(hostA)
-
- val hostB = mockk<HostView>()
- every { hostB.host.state } returns HostState.UP
- every { hostB.host.model } returns HostModel(4 * 3200.0, 4, 2048)
- every { hostB.availableMemory } returns 512
-
- scheduler.addHost(hostB)
-
- val task = mockk<Task>()
- every { task.flavor.coreCount } returns 2
- every { task.flavor.memorySize } returns 1024
- every { task.flavor.meta } returns mapOf("cpu-capacity" to 2 * 3200.0)
-
- assertEquals(hostB, scheduler.select(task))
- }
-
- @Test
- fun testInstanceCountFilter() {
- val scheduler =
- FilterScheduler(
- filters = listOf(InstanceCountFilter(limit = 2)),
- weighers = emptyList(),
- )
-
- val hostA = mockk<HostView>()
- every { hostA.host.state } returns HostState.UP
- every { hostA.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostA.instanceCount } returns 2
-
- val hostB = mockk<HostView>()
- every { hostB.host.state } returns HostState.UP
- every { hostB.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostB.instanceCount } returns 0
-
- scheduler.addHost(hostA)
- scheduler.addHost(hostB)
-
- val task = mockk<Task>()
- every { task.flavor.coreCount } returns 2
- every { task.flavor.memorySize } returns 1024
-
- assertEquals(hostB, scheduler.select(task))
- }
-
- @Test
- fun testAffinityFilter() {
- val scheduler =
- FilterScheduler(
- filters = listOf(SameHostFilter()),
- weighers = emptyList(),
- )
-
- val taskA = mockk<Task>()
- every { taskA.uid } returns UUID.randomUUID()
- every { taskA.flavor.coreCount } returns 2
- every { taskA.flavor.memorySize } returns 1024
-
- val hostA = mockk<HostView>()
- every { hostA.host.state } returns HostState.UP
- every { hostA.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostA.host.instances } returns emptySet()
- every { hostA.provisionedCores } returns 3
-
- val hostB = mockk<HostView>()
- every { hostB.host.state } returns HostState.UP
- every { hostB.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostB.host.instances } returns setOf(taskA)
- every { hostB.provisionedCores } returns 0
-
- scheduler.addHost(hostA)
- scheduler.addHost(hostB)
-
- val taskB = mockk<Task>()
- every { taskB.flavor.coreCount } returns 2
- every { taskB.flavor.memorySize } returns 1024
- every { taskB.meta } returns emptyMap()
-
- assertEquals(hostA, scheduler.select(taskB))
-
- every { taskB.meta } returns mapOf("scheduler_hint:same_host" to setOf(taskA.uid))
-
- assertEquals(hostB, scheduler.select(taskB))
- }
-
- @Test
- fun testAntiAffinityFilter() {
- val scheduler =
- FilterScheduler(
- filters = listOf(DifferentHostFilter()),
- weighers = emptyList(),
- )
-
- val taskA = mockk<Task>()
- every { taskA.uid } returns UUID.randomUUID()
- every { taskA.flavor.coreCount } returns 2
- every { taskA.flavor.memorySize } returns 1024
-
- val hostA = mockk<HostView>()
- every { hostA.host.state } returns HostState.UP
- every { hostA.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostA.host.instances } returns setOf(taskA)
- every { hostA.provisionedCores } returns 3
-
- val hostB = mockk<HostView>()
- every { hostB.host.state } returns HostState.UP
- every { hostB.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostB.host.instances } returns emptySet()
- every { hostB.provisionedCores } returns 0
-
- scheduler.addHost(hostA)
- scheduler.addHost(hostB)
-
- val taskB = mockk<Task>()
- every { taskB.flavor.coreCount } returns 2
- every { taskB.flavor.memorySize } returns 1024
- every { taskB.meta } returns emptyMap()
-
- assertEquals(hostA, scheduler.select(taskB))
-
- every { taskB.meta } returns mapOf("scheduler_hint:different_host" to setOf(taskA.uid))
-
- assertEquals(hostB, scheduler.select(taskB))
- }
-
- @Test
- fun testRamWeigher() {
- val scheduler =
- FilterScheduler(
- filters = emptyList(),
- weighers = listOf(RamWeigher(1.5)),
- )
-
- val hostA = mockk<HostView>()
- every { hostA.host.state } returns HostState.UP
- every { hostA.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostA.availableMemory } returns 1024
-
- val hostB = mockk<HostView>()
- every { hostB.host.state } returns HostState.UP
- every { hostB.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostB.availableMemory } returns 512
-
- scheduler.addHost(hostA)
- scheduler.addHost(hostB)
-
- val task = mockk<Task>()
- every { task.flavor.coreCount } returns 2
- every { task.flavor.memorySize } returns 1024
-
- assertEquals(hostA, scheduler.select(task))
- }
-
- // TODO: fix test when updating schedulers
-// @Test
- fun testCoreRamWeigher() {
- val scheduler =
- FilterScheduler(
- filters = emptyList(),
- weighers = listOf(CoreRamWeigher(1.5)),
- )
-
- val hostA = mockk<HostView>()
- every { hostA.host.state } returns HostState.UP
- every { hostA.host.model } returns HostModel(12 * 2600.0, 12, 2048)
- every { hostA.availableMemory } returns 1024
-
- val hostB = mockk<HostView>()
- every { hostB.host.state } returns HostState.UP
- every { hostB.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostB.availableMemory } returns 512
-
- scheduler.addHost(hostA)
- scheduler.addHost(hostB)
-
- val task = mockk<Task>()
- every { task.flavor.coreCount } returns 2
- every { task.flavor.memorySize } returns 1024
-
- assertEquals(hostB, scheduler.select(task))
- }
-
- @Test
- fun testVCpuWeigher() {
- val scheduler =
- FilterScheduler(
- filters = emptyList(),
- weighers = listOf(VCpuWeigher(16.0)),
- )
-
- val hostA = mockk<HostView>()
- every { hostA.host.state } returns HostState.UP
- every { hostA.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostA.provisionedCores } returns 2
-
- val hostB = mockk<HostView>()
- every { hostB.host.state } returns HostState.UP
- every { hostB.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostB.provisionedCores } returns 0
-
- scheduler.addHost(hostA)
- scheduler.addHost(hostB)
-
- val task = mockk<Task>()
- every { task.flavor.coreCount } returns 2
- every { task.flavor.memorySize } returns 1024
-
- assertEquals(hostB, scheduler.select(task))
- }
-
- @Test
- fun testInstanceCountWeigher() {
- val scheduler =
- FilterScheduler(
- filters = emptyList(),
- weighers = listOf(InstanceCountWeigher(multiplier = -1.0)),
- )
-
- val hostA = mockk<HostView>()
- every { hostA.host.state } returns HostState.UP
- every { hostA.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostA.instanceCount } returns 2
-
- val hostB = mockk<HostView>()
- every { hostB.host.state } returns HostState.UP
- every { hostB.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostB.instanceCount } returns 0
-
- scheduler.addHost(hostA)
- scheduler.addHost(hostB)
-
- val task = mockk<Task>()
- every { task.flavor.coreCount } returns 2
- every { task.flavor.memorySize } returns 1024
-
- assertEquals(hostB, scheduler.select(task))
- }
-}
diff --git a/opendc-compute/opendc-compute-service/src/test/resources/log4j2.xml b/opendc-compute/opendc-compute-service/src/test/resources/log4j2.xml
deleted file mode 100644
index 0dfb75f2..00000000
--- a/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>