diff options
| author | Fabian Mastenbroek <mail.fabianm@gmail.com> | 2021-06-22 15:00:11 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-06-22 15:00:11 +0200 |
| commit | 8a2b475f082572033438eb5b8703d211323f1b52 (patch) | |
| tree | 76179cf3802a34d65829f4d8b9aa708c9a41eec1 | |
| parent | 147951f39de8f93eba6c7b0b7e6e5c9d2bce32e7 (diff) | |
| parent | dcd1bc82b9126b8122c671102d4d22843b73c847 (diff) | |
simulator: Add support for networking (v1)
This change adds support for networking in the simulator.
As outlined in #84, the network model doesn't model individual packets,
but instead considers dynamic flows between network devices.
This pull request adds the bare-minimum implementation necessary to model network traffic.
In the future, we will add advanced functionality such as routing and other L3 concepts.
* Add core model for network simulation
* Add model for network adapter that attaches to machine
* Add virtual network switch to bridge traffic between hosts.
62 files changed, 994 insertions, 103 deletions
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt index c9527bb6..be7bc667 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt @@ -31,10 +31,13 @@ import org.opendc.compute.api.Server import org.opendc.compute.api.ServerState import org.opendc.compute.service.driver.* import org.opendc.simulator.compute.* -import org.opendc.simulator.compute.cpufreq.PerformanceScalingGovernor -import org.opendc.simulator.compute.cpufreq.ScalingGovernor import org.opendc.simulator.compute.interference.IMAGE_PERF_INTERFERENCE_MODEL import org.opendc.simulator.compute.interference.PerformanceInterferenceModel +import org.opendc.simulator.compute.kernel.SimHypervisor +import org.opendc.simulator.compute.kernel.SimHypervisorProvider +import org.opendc.simulator.compute.kernel.cpufreq.PerformanceScalingGovernor +import org.opendc.simulator.compute.kernel.cpufreq.ScalingGovernor +import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.model.MemoryUnit import org.opendc.simulator.compute.power.ConstantPowerModel import org.opendc.simulator.compute.power.PowerDriver @@ -52,7 +55,7 @@ import kotlin.coroutines.resume public class SimHost( override val uid: UUID, override val name: String, - model: SimMachineModel, + model: MachineModel, override val meta: Map<String, Any>, context: CoroutineContext, interpreter: SimResourceInterpreter, @@ -66,7 +69,7 @@ public class SimHost( public constructor( uid: UUID, name: String, - model: SimMachineModel, + model: MachineModel, meta: Map<String, Any>, context: CoroutineContext, interpreter: SimResourceInterpreter, @@ -304,13 +307,13 @@ public class SimHost( /** * Convert flavor to machine model. */ - private fun Flavor.toMachineModel(): SimMachineModel { + private fun Flavor.toMachineModel(): MachineModel { val originalCpu = machine.model.cpus[0] val processingNode = originalCpu.node.copy(coreCount = cpuCount) val processingUnits = (0 until cpuCount).map { originalCpu.copy(id = it, node = processingNode) } val memoryUnits = listOf(MemoryUnit("Generic", "Generic", 3200.0, memorySize)) - return SimMachineModel(processingUnits, memoryUnits) + return MachineModel(processingUnits, memoryUnits) } private fun onGuestStart(vm: Guest) { diff --git a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt index 79489fdb..5414d042 100644 --- a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt +++ b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt @@ -40,8 +40,8 @@ import org.opendc.compute.api.ServerState import org.opendc.compute.api.ServerWatcher import org.opendc.compute.service.driver.Host import org.opendc.compute.service.driver.HostListener -import org.opendc.simulator.compute.SimFairShareHypervisorProvider -import org.opendc.simulator.compute.SimMachineModel +import org.opendc.simulator.compute.kernel.SimFairShareHypervisorProvider +import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.model.MemoryUnit import org.opendc.simulator.compute.model.ProcessingNode import org.opendc.simulator.compute.model.ProcessingUnit @@ -58,13 +58,13 @@ import kotlin.coroutines.resume */ @OptIn(ExperimentalCoroutinesApi::class) internal class SimHostTest { - private lateinit var machineModel: SimMachineModel + private lateinit var machineModel: MachineModel @BeforeEach fun setUp() { val cpuNode = ProcessingNode("Intel", "Xeon", "amd64", 2) - machineModel = SimMachineModel( + machineModel = MachineModel( cpus = List(cpuNode.coreCount) { ProcessingUnit(cpuNode, it, 3200.0) }, memory = List(4) { MemoryUnit("Crucial", "MTA18ASF4G72AZ-3G2B1", 3200.0, 32_000) } ) diff --git a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt index 0485415c..47f5f71e 100644 --- a/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt +++ b/opendc-experiments/opendc-experiments-capelin/src/main/kotlin/org/opendc/experiments/capelin/ExperimentHelpers.kt @@ -44,8 +44,8 @@ import org.opendc.experiments.capelin.monitor.ExperimentMonitor import org.opendc.experiments.capelin.trace.Sc20StreamingParquetTraceReader import org.opendc.format.environment.EnvironmentReader import org.opendc.format.trace.TraceReader -import org.opendc.simulator.compute.SimFairShareHypervisorProvider import org.opendc.simulator.compute.interference.PerformanceInterferenceModel +import org.opendc.simulator.compute.kernel.SimFairShareHypervisorProvider import org.opendc.simulator.compute.workload.SimTraceWorkload import org.opendc.simulator.compute.workload.SimWorkload import org.opendc.simulator.failures.CorrelatedFaultInjector diff --git a/opendc-experiments/opendc-experiments-energy21/src/main/kotlin/org/opendc/experiments/energy21/EnergyExperiment.kt b/opendc-experiments/opendc-experiments-energy21/src/main/kotlin/org/opendc/experiments/energy21/EnergyExperiment.kt index 2f14776a..28928dcb 100644 --- a/opendc-experiments/opendc-experiments-energy21/src/main/kotlin/org/opendc/experiments/energy21/EnergyExperiment.kt +++ b/opendc-experiments/opendc-experiments-energy21/src/main/kotlin/org/opendc/experiments/energy21/EnergyExperiment.kt @@ -41,9 +41,9 @@ import org.opendc.experiments.capelin.monitor.ParquetExperimentMonitor import org.opendc.experiments.capelin.trace.Sc20StreamingParquetTraceReader import org.opendc.harness.dsl.Experiment import org.opendc.harness.dsl.anyOf -import org.opendc.simulator.compute.SimFairShareHypervisorProvider -import org.opendc.simulator.compute.SimMachineModel -import org.opendc.simulator.compute.cpufreq.* +import org.opendc.simulator.compute.kernel.SimFairShareHypervisorProvider +import org.opendc.simulator.compute.kernel.cpufreq.PerformanceScalingGovernor +import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.model.MemoryUnit import org.opendc.simulator.compute.model.ProcessingNode import org.opendc.simulator.compute.model.ProcessingUnit @@ -156,12 +156,12 @@ public class EnergyExperiment : Experiment("Energy Modeling 2021") { /** * The machine model based on: https://www.spec.org/power_ssj2008/results/res2020q1/power_ssj2008-20191125-01012.html */ - private fun createMachineModel(): SimMachineModel { + private fun createMachineModel(): MachineModel { val node = ProcessingNode("AMD", "am64", "EPYC 7742", 64) val cpus = List(node.coreCount) { id -> ProcessingUnit(node, id, 3400.0) } val memory = List(8) { MemoryUnit("Samsung", "Unknown", 2933.0, 16_000) } - return SimMachineModel(cpus, memory) + return MachineModel(cpus, memory) } /** diff --git a/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/ServerlessExperiment.kt b/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/ServerlessExperiment.kt index 3a016491..231b491e 100644 --- a/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/ServerlessExperiment.kt +++ b/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/ServerlessExperiment.kt @@ -39,7 +39,7 @@ import org.opendc.faas.simulator.delay.ColdStartModel import org.opendc.faas.simulator.delay.StochasticDelayInjector import org.opendc.harness.dsl.Experiment import org.opendc.harness.dsl.anyOf -import org.opendc.simulator.compute.SimMachineModel +import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.model.MemoryUnit import org.opendc.simulator.compute.model.ProcessingNode import org.opendc.simulator.compute.model.ProcessingUnit @@ -122,10 +122,10 @@ public class ServerlessExperiment : Experiment("Serverless") { /** * Construct the machine model to test with. */ - private fun createMachineModel(): SimMachineModel { + private fun createMachineModel(): MachineModel { val cpuNode = ProcessingNode("Intel", "Xeon", "amd64", 2) - return SimMachineModel( + return MachineModel( cpus = List(cpuNode.coreCount) { ProcessingUnit(cpuNode, it, 1000.0) }, memory = List(4) { MemoryUnit("Crucial", "MTA18ASF4G72AZ-3G2B1", 3200.0, 32_000) } ) diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt index 92e7080a..d8f92155 100644 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt +++ b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt @@ -28,7 +28,7 @@ import kotlinx.coroutines.* import org.opendc.simulator.compute.SimBareMetalMachine import org.opendc.simulator.compute.SimMachine import org.opendc.simulator.compute.SimMachineContext -import org.opendc.simulator.compute.SimMachineModel +import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.model.MemoryUnit import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.compute.power.PowerModel @@ -63,7 +63,7 @@ public class SimTFDevice( * The [SimMachine] representing the device. */ private val machine = SimBareMetalMachine( - SimResourceInterpreter(scope.coroutineContext, clock), SimMachineModel(listOf(pu), listOf(memory)), + SimResourceInterpreter(scope.coroutineContext, clock), MachineModel(listOf(pu), listOf(memory)), SimplePowerDriver(powerModel) ) diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/util/MLEnvironmentReader.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/util/MLEnvironmentReader.kt index eea079fb..3e61f508 100644 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/util/MLEnvironmentReader.kt +++ b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/util/MLEnvironmentReader.kt @@ -27,7 +27,7 @@ import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.fasterxml.jackson.module.kotlin.readValue import org.opendc.format.environment.EnvironmentReader import org.opendc.format.environment.MachineDef -import org.opendc.simulator.compute.SimMachineModel +import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.model.MemoryUnit import org.opendc.simulator.compute.model.ProcessingNode import org.opendc.simulator.compute.model.ProcessingUnit @@ -100,7 +100,7 @@ public class MLEnvironmentReader(input: InputStream, mapper: ObjectMapper = jack UUID(0, counter.toLong()), "node-${counter++}", mapOf("gpu" to isGpuFlag), - SimMachineModel(cores, memories), + MachineModel(cores, memories), LinearPowerModel(maxPower, minPower) ) } diff --git a/opendc-faas/opendc-faas-simulator/src/main/kotlin/org/opendc/faas/simulator/SimFunctionDeployer.kt b/opendc-faas/opendc-faas-simulator/src/main/kotlin/org/opendc/faas/simulator/SimFunctionDeployer.kt index 602f1678..68bdc337 100644 --- a/opendc-faas/opendc-faas-simulator/src/main/kotlin/org/opendc/faas/simulator/SimFunctionDeployer.kt +++ b/opendc-faas/opendc-faas-simulator/src/main/kotlin/org/opendc/faas/simulator/SimFunctionDeployer.kt @@ -33,7 +33,7 @@ import org.opendc.faas.simulator.delay.DelayInjector import org.opendc.faas.simulator.workload.SimFaaSWorkloadMapper import org.opendc.simulator.compute.SimBareMetalMachine import org.opendc.simulator.compute.SimMachine -import org.opendc.simulator.compute.SimMachineModel +import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.power.ConstantPowerModel import org.opendc.simulator.compute.power.SimplePowerDriver import org.opendc.simulator.resources.SimResourceInterpreter @@ -49,7 +49,7 @@ import kotlin.coroutines.resumeWithException public class SimFunctionDeployer( private val clock: Clock, private val scope: CoroutineScope, - private val model: SimMachineModel, + private val model: MachineModel, private val delayInjector: DelayInjector, private val mapper: SimFaaSWorkloadMapper ) : FunctionDeployer { diff --git a/opendc-faas/opendc-faas-simulator/src/test/kotlin/org/opendc/faas/simulator/SimFaaSServiceTest.kt b/opendc-faas/opendc-faas-simulator/src/test/kotlin/org/opendc/faas/simulator/SimFaaSServiceTest.kt index ceb91e75..64f2551b 100644 --- a/opendc-faas/opendc-faas-simulator/src/test/kotlin/org/opendc/faas/simulator/SimFaaSServiceTest.kt +++ b/opendc-faas/opendc-faas-simulator/src/test/kotlin/org/opendc/faas/simulator/SimFaaSServiceTest.kt @@ -36,7 +36,7 @@ import org.opendc.faas.service.autoscaler.FunctionTerminationPolicyFixed import org.opendc.faas.service.router.RandomRoutingPolicy import org.opendc.faas.simulator.delay.ZeroDelayInjector import org.opendc.faas.simulator.workload.SimFaaSWorkload -import org.opendc.simulator.compute.SimMachineModel +import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.model.MemoryUnit import org.opendc.simulator.compute.model.ProcessingNode import org.opendc.simulator.compute.model.ProcessingUnit @@ -50,13 +50,13 @@ import org.opendc.simulator.core.runBlockingSimulation @OptIn(ExperimentalCoroutinesApi::class) internal class SimFaaSServiceTest { - private lateinit var machineModel: SimMachineModel + private lateinit var machineModel: MachineModel @BeforeEach fun setUp() { val cpuNode = ProcessingNode("Intel", "Xeon", "amd64", 2) - machineModel = SimMachineModel( + machineModel = MachineModel( cpus = List(cpuNode.coreCount) { ProcessingUnit(cpuNode, it, 1000.0) }, memory = List(4) { MemoryUnit("Crucial", "MTA18ASF4G72AZ-3G2B1", 3200.0, 32_000) } ) diff --git a/opendc-format/src/main/kotlin/org/opendc/format/environment/MachineDef.kt b/opendc-format/src/main/kotlin/org/opendc/format/environment/MachineDef.kt index 9b799cc2..f65c4880 100644 --- a/opendc-format/src/main/kotlin/org/opendc/format/environment/MachineDef.kt +++ b/opendc-format/src/main/kotlin/org/opendc/format/environment/MachineDef.kt @@ -22,7 +22,7 @@ package org.opendc.format.environment -import org.opendc.simulator.compute.SimMachineModel +import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.power.PowerModel import java.util.* @@ -30,6 +30,6 @@ public data class MachineDef( val uid: UUID, val name: String, val meta: Map<String, Any>, - val model: SimMachineModel, + val model: MachineModel, val powerModel: PowerModel ) diff --git a/opendc-format/src/main/kotlin/org/opendc/format/environment/sc18/Sc18EnvironmentReader.kt b/opendc-format/src/main/kotlin/org/opendc/format/environment/sc18/Sc18EnvironmentReader.kt index 1f080c2d..7780a98e 100644 --- a/opendc-format/src/main/kotlin/org/opendc/format/environment/sc18/Sc18EnvironmentReader.kt +++ b/opendc-format/src/main/kotlin/org/opendc/format/environment/sc18/Sc18EnvironmentReader.kt @@ -27,7 +27,7 @@ import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.fasterxml.jackson.module.kotlin.readValue import org.opendc.format.environment.EnvironmentReader import org.opendc.format.environment.MachineDef -import org.opendc.simulator.compute.SimMachineModel +import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.model.MemoryUnit import org.opendc.simulator.compute.model.ProcessingNode import org.opendc.simulator.compute.model.ProcessingUnit @@ -75,7 +75,7 @@ public class Sc18EnvironmentReader(input: InputStream, mapper: ObjectMapper = ja UUID(0L, counter++.toLong()), "node-$counter", emptyMap(), - SimMachineModel(cores, listOf(MemoryUnit("", "", 2300.0, 16000))), + MachineModel(cores, listOf(MemoryUnit("", "", 2300.0, 16000))), ConstantPowerModel(0.0) ) } diff --git a/opendc-format/src/main/kotlin/org/opendc/format/environment/sc20/Sc20ClusterEnvironmentReader.kt b/opendc-format/src/main/kotlin/org/opendc/format/environment/sc20/Sc20ClusterEnvironmentReader.kt index bef6b742..1efd2ddf 100644 --- a/opendc-format/src/main/kotlin/org/opendc/format/environment/sc20/Sc20ClusterEnvironmentReader.kt +++ b/opendc-format/src/main/kotlin/org/opendc/format/environment/sc20/Sc20ClusterEnvironmentReader.kt @@ -24,7 +24,7 @@ package org.opendc.format.environment.sc20 import org.opendc.format.environment.EnvironmentReader import org.opendc.format.environment.MachineDef -import org.opendc.simulator.compute.SimMachineModel +import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.model.MemoryUnit import org.opendc.simulator.compute.model.ProcessingNode import org.opendc.simulator.compute.model.ProcessingUnit @@ -97,7 +97,7 @@ public class Sc20ClusterEnvironmentReader( UUID(random.nextLong(), random.nextLong()), "node-$clusterId-$it", mapOf("cluster" to clusterId), - SimMachineModel( + MachineModel( List(coresPerHost) { coreId -> ProcessingUnit(unknownProcessingNode, coreId, speed) }, diff --git a/opendc-format/src/main/kotlin/org/opendc/format/environment/sc20/Sc20EnvironmentReader.kt b/opendc-format/src/main/kotlin/org/opendc/format/environment/sc20/Sc20EnvironmentReader.kt index 2fa1caab..9b77702e 100644 --- a/opendc-format/src/main/kotlin/org/opendc/format/environment/sc20/Sc20EnvironmentReader.kt +++ b/opendc-format/src/main/kotlin/org/opendc/format/environment/sc20/Sc20EnvironmentReader.kt @@ -27,7 +27,7 @@ import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.fasterxml.jackson.module.kotlin.readValue import org.opendc.format.environment.EnvironmentReader import org.opendc.format.environment.MachineDef -import org.opendc.simulator.compute.SimMachineModel +import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.model.MemoryUnit import org.opendc.simulator.compute.model.ProcessingNode import org.opendc.simulator.compute.model.ProcessingUnit @@ -80,7 +80,7 @@ public class Sc20EnvironmentReader(input: InputStream, mapper: ObjectMapper = ja UUID(0L, counter++.toLong()), "node-$counter", emptyMap(), - SimMachineModel(cores, memories), + MachineModel(cores, memories), // For now we assume a simple linear load model with an idle draw of ~200W and a maximum // power draw of 350W. // Source: https://stackoverflow.com/questions/6128960 diff --git a/opendc-simulator/opendc-simulator-compute/build.gradle.kts b/opendc-simulator/opendc-simulator-compute/build.gradle.kts index 41cdd40c..74384480 100644 --- a/opendc-simulator/opendc-simulator-compute/build.gradle.kts +++ b/opendc-simulator/opendc-simulator-compute/build.gradle.kts @@ -33,6 +33,7 @@ dependencies { api(platform(projects.opendcPlatform)) api(projects.opendcSimulator.opendcSimulatorResources) api(projects.opendcSimulator.opendcSimulatorPower) + api(projects.opendcSimulator.opendcSimulatorNetwork) implementation(projects.opendcSimulator.opendcSimulatorCore) implementation(projects.opendcUtils) implementation(libs.yaml) diff --git a/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt b/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt index fb753de2..8f60bf05 100644 --- a/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt +++ b/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt @@ -25,6 +25,9 @@ package org.opendc.simulator.compute import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch +import org.opendc.simulator.compute.kernel.SimFairShareHypervisor +import org.opendc.simulator.compute.kernel.SimSpaceSharedHypervisor +import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.model.MemoryUnit import org.opendc.simulator.compute.model.ProcessingNode import org.opendc.simulator.compute.model.ProcessingUnit @@ -45,7 +48,7 @@ import java.util.concurrent.TimeUnit class SimMachineBenchmarks { private lateinit var scope: SimulationCoroutineScope private lateinit var interpreter: SimResourceInterpreter - private lateinit var machineModel: SimMachineModel + private lateinit var machineModel: MachineModel @Setup fun setUp() { @@ -54,7 +57,7 @@ class SimMachineBenchmarks { val cpuNode = ProcessingNode("Intel", "Xeon", "amd64", 2) - machineModel = SimMachineModel( + machineModel = MachineModel( cpus = List(cpuNode.coreCount) { ProcessingUnit(cpuNode, it, 1000.0) }, memory = List(4) { MemoryUnit("Crucial", "MTA18ASF4G72AZ-3G2B1", 3200.0, 32_000) } ) diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt index 3a70680c..99f9397d 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt @@ -25,7 +25,11 @@ package org.opendc.simulator.compute import kotlinx.coroutines.* import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow +import org.opendc.simulator.compute.device.SimNetworkAdapter +import org.opendc.simulator.compute.device.SimPeripheral +import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.model.MemoryUnit +import org.opendc.simulator.compute.model.NetworkAdapter import org.opendc.simulator.compute.workload.SimWorkload import org.opendc.simulator.resources.* import kotlin.coroutines.Continuation @@ -41,7 +45,7 @@ import kotlin.coroutines.resume public abstract class SimAbstractMachine( protected val interpreter: SimResourceInterpreter, final override val parent: SimResourceSystem?, - final override val model: SimMachineModel + final override val model: MachineModel ) : SimMachine, SimResourceSystem { /** * A [StateFlow] representing the CPU usage of the simulated machine. @@ -68,6 +72,16 @@ public abstract class SimAbstractMachine( protected val memory: SimMemory = Memory(SimResourceSource(model.memory.sumOf { it.size }.toDouble(), interpreter), model.memory) /** + * The network interfaces available to the machine. + */ + protected val net: List<SimNetworkInterface> = model.net.mapIndexed { i, adapter -> NetworkAdapterImpl(adapter, i) } + + /** + * The peripherals of the machine. + */ + public override val peripherals: List<SimPeripheral> = net.map { it as SimNetworkAdapter } + + /** * A flag to indicate that the machine is terminated. */ private var isTerminated = false @@ -165,6 +179,8 @@ public abstract class SimAbstractMachine( override val memory: SimMemory = this@SimAbstractMachine.memory + override val net: List<SimNetworkInterface> = this@SimAbstractMachine.net + override fun close() = cancel() } @@ -174,4 +190,31 @@ public abstract class SimAbstractMachine( private class Memory(source: SimResourceSource, override val models: List<MemoryUnit>) : SimMemory, SimResourceProvider by source { override fun toString(): String = "SimAbstractMachine.Memory" } + + /** + * The [SimNetworkAdapter] implementation for a machine. + */ + private class NetworkAdapterImpl( + model: NetworkAdapter, + index: Int + ) : SimNetworkAdapter(), SimNetworkInterface { + override val name: String = "eth$index" + + override val bandwidth: Double = model.bandwidth + + override val provider: SimResourceProvider + get() = _rx + + override fun createConsumer(): SimResourceConsumer = _tx + + override val tx: SimResourceProvider + get() = _tx + private val _tx = SimResourceForwarder() + + override val rx: SimResourceConsumer + get() = _rx + private val _rx = SimResourceForwarder() + + override fun toString(): String = "SimAbstractMachine.NetworkAdapterImpl[name=$name,bandwidth=$bandwidth]" + } } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt index 7f416010..887f0885 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt @@ -22,6 +22,8 @@ package org.opendc.simulator.compute +import org.opendc.simulator.compute.device.SimPsu +import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.compute.power.PowerDriver import org.opendc.simulator.resources.* @@ -41,7 +43,7 @@ import org.opendc.simulator.resources.SimResourceInterpreter */ public class SimBareMetalMachine( interpreter: SimResourceInterpreter, - model: SimMachineModel, + model: MachineModel, powerDriver: PowerDriver, public val psu: SimPsu = SimPsu(500.0, mapOf(1.0 to 1.0)), parent: SimResourceSystem? = null, diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachine.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachine.kt index bfaa60bc..0f4674d5 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachine.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachine.kt @@ -23,6 +23,8 @@ package org.opendc.simulator.compute import kotlinx.coroutines.flow.StateFlow +import org.opendc.simulator.compute.device.SimPeripheral +import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.workload.SimWorkload /** @@ -32,7 +34,12 @@ public interface SimMachine : AutoCloseable { /** * The model of the machine containing its specifications. */ - public val model: SimMachineModel + public val model: MachineModel + + /** + * The peripherals attached to the machine. + */ + public val peripherals: List<SimPeripheral> /** * A [StateFlow] representing the CPU usage of the simulated machine. diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachineContext.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachineContext.kt index 391442ec..68a7fb63 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachineContext.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachineContext.kt @@ -51,6 +51,11 @@ public interface SimMachineContext : AutoCloseable { public val memory: SimMemory /** + * The network interfaces available to the workload. + */ + public val net: List<SimNetworkInterface> + + /** * Stop the workload. */ public override fun close() diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimNetworkInterface.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimNetworkInterface.kt new file mode 100644 index 00000000..1ac126ae --- /dev/null +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimNetworkInterface.kt @@ -0,0 +1,51 @@ +/* + * 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.simulator.compute + +import org.opendc.simulator.resources.SimResourceConsumer +import org.opendc.simulator.resources.SimResourceProvider + +/** + * A firmware interface to a network adapter. + */ +public interface SimNetworkInterface { + /** + * The name of the network interface. + */ + public val name: String + + /** + * The unidirectional bandwidth of the network interface in Mbps. + */ + public val bandwidth: Double + + /** + * The resource provider for the transmit channel of the network interface. + */ + public val tx: SimResourceProvider + + /** + * The resource consumer for the receive channel of the network interface. + */ + public val rx: SimResourceConsumer +} diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimNetworkAdapter.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimNetworkAdapter.kt new file mode 100644 index 00000000..dfb4ecf3 --- /dev/null +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimNetworkAdapter.kt @@ -0,0 +1,36 @@ +/* + * 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.simulator.compute.device + +import org.opendc.simulator.compute.SimMachine +import org.opendc.simulator.network.SimNetworkPort + +/** + * A simulated network interface card (NIC or network adapter) that can be attached to a [SimMachine]. + */ +public abstract class SimNetworkAdapter : SimNetworkPort(), SimPeripheral { + /** + * The unidirectional bandwidth of the network adapter in Mbps. + */ + public abstract val bandwidth: Double +} diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPeripheral.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPeripheral.kt new file mode 100644 index 00000000..268271be --- /dev/null +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPeripheral.kt @@ -0,0 +1,33 @@ +/* + * 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.simulator.compute.device + +import org.opendc.simulator.compute.SimMachine + +/** + * A component that can be attached to a [SimMachine]. + * + * This interface represents the physical view of the peripheral and should be used to configure the physical properties + * of the peripheral. + */ +public interface SimPeripheral diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimPsu.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt index 4ddad1c9..0a7dc40f 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimPsu.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/device/SimPsu.kt @@ -20,7 +20,7 @@ * SOFTWARE. */ -package org.opendc.simulator.compute +package org.opendc.simulator.compute.device import org.opendc.simulator.compute.power.PowerDriver import org.opendc.simulator.power.SimPowerInlet diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt index c560cd28..fb46dab4 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractHypervisor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt @@ -20,11 +20,13 @@ * SOFTWARE. */ -package org.opendc.simulator.compute +package org.opendc.simulator.compute.kernel -import org.opendc.simulator.compute.cpufreq.ScalingGovernor -import org.opendc.simulator.compute.cpufreq.ScalingPolicy +import org.opendc.simulator.compute.* import org.opendc.simulator.compute.interference.PerformanceInterferenceModel +import org.opendc.simulator.compute.kernel.cpufreq.ScalingGovernor +import org.opendc.simulator.compute.kernel.cpufreq.ScalingPolicy +import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.resources.* import org.opendc.simulator.resources.SimResourceSwitch @@ -69,7 +71,7 @@ public abstract class SimAbstractHypervisor( /** * Check whether the specified machine model fits on this hypervisor. */ - public abstract fun canFit(model: SimMachineModel, switch: SimResourceSwitch): Boolean + public abstract fun canFit(model: MachineModel, switch: SimResourceSwitch): Boolean /** * Trigger the governors to recompute the scaling limits. @@ -81,12 +83,12 @@ public abstract class SimAbstractHypervisor( } /* SimHypervisor */ - override fun canFit(model: SimMachineModel): Boolean { + override fun canFit(model: MachineModel): Boolean { return canFit(model, switch) } override fun createMachine( - model: SimMachineModel, + model: MachineModel, performanceInterferenceModel: PerformanceInterferenceModel? ): SimMachine { require(canFit(model)) { "Machine does not fit" } @@ -118,7 +120,7 @@ public abstract class SimAbstractHypervisor( * @property performanceInterferenceModel The performance interference model to utilize. */ private inner class VirtualMachine( - model: SimMachineModel, + model: MachineModel, val performanceInterferenceModel: PerformanceInterferenceModel? = null, ) : SimAbstractMachine(interpreter, parent = null, model) { /** diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimFairShareHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt index e7776c81..2ce51ea6 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimFairShareHypervisor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt @@ -20,9 +20,11 @@ * SOFTWARE. */ -package org.opendc.simulator.compute +package org.opendc.simulator.compute.kernel -import org.opendc.simulator.compute.cpufreq.ScalingGovernor +import org.opendc.simulator.compute.SimMachineContext +import org.opendc.simulator.compute.kernel.cpufreq.ScalingGovernor +import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.workload.SimWorkload import org.opendc.simulator.resources.SimResourceInterpreter import org.opendc.simulator.resources.SimResourceSwitch @@ -45,7 +47,7 @@ public class SimFairShareHypervisor( private val listener: SimHypervisor.Listener? = null ) : SimAbstractHypervisor(interpreter, scalingGovernor) { - override fun canFit(model: SimMachineModel, switch: SimResourceSwitch): Boolean = true + override fun canFit(model: MachineModel, switch: SimResourceSwitch): Boolean = true override fun createSwitch(ctx: SimMachineContext): SimResourceSwitch { return SwitchSystem(ctx).switch diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimFairShareHypervisorProvider.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorProvider.kt index 94c905b2..542cd0d2 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimFairShareHypervisorProvider.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorProvider.kt @@ -20,7 +20,7 @@ * SOFTWARE. */ -package org.opendc.simulator.compute +package org.opendc.simulator.compute.kernel import org.opendc.simulator.resources.SimResourceInterpreter import org.opendc.simulator.resources.SimResourceSystem diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisor.kt index 4a233fec..40402f5c 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimHypervisor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisor.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 AtLarge Research + * 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 @@ -20,9 +20,11 @@ * SOFTWARE. */ -package org.opendc.simulator.compute +package org.opendc.simulator.compute.kernel +import org.opendc.simulator.compute.SimMachine import org.opendc.simulator.compute.interference.PerformanceInterferenceModel +import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.workload.SimWorkload /** @@ -38,7 +40,7 @@ public interface SimHypervisor : SimWorkload { /** * Determine whether the specified machine characterized by [model] can fit on this hypervisor at this moment. */ - public fun canFit(model: SimMachineModel): Boolean + public fun canFit(model: MachineModel): Boolean /** * Create a [SimMachine] instance on which users may run a [SimWorkload]. @@ -47,7 +49,7 @@ public interface SimHypervisor : SimWorkload { * @param performanceInterferenceModel The performance interference model to use. */ public fun createMachine( - model: SimMachineModel, + model: MachineModel, performanceInterferenceModel: PerformanceInterferenceModel? = null ): SimMachine diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimHypervisorProvider.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorProvider.kt index 8e8c3698..cafd1ffc 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimHypervisorProvider.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorProvider.kt @@ -20,7 +20,7 @@ * SOFTWARE. */ -package org.opendc.simulator.compute +package org.opendc.simulator.compute.kernel import org.opendc.simulator.resources.SimResourceInterpreter import org.opendc.simulator.resources.SimResourceSystem diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimSpaceSharedHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisor.kt index f6ae18f7..3ceebb9a 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimSpaceSharedHypervisor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisor.kt @@ -20,8 +20,10 @@ * SOFTWARE. */ -package org.opendc.simulator.compute +package org.opendc.simulator.compute.kernel +import org.opendc.simulator.compute.SimMachineContext +import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.resources.SimResourceInterpreter import org.opendc.simulator.resources.SimResourceSwitch import org.opendc.simulator.resources.SimResourceSwitchExclusive @@ -30,7 +32,7 @@ import org.opendc.simulator.resources.SimResourceSwitchExclusive * A [SimHypervisor] that allocates its sub-resources exclusively for the virtual machine that it hosts. */ public class SimSpaceSharedHypervisor(interpreter: SimResourceInterpreter) : SimAbstractHypervisor(interpreter, null) { - override fun canFit(model: SimMachineModel, switch: SimResourceSwitch): Boolean { + override fun canFit(model: MachineModel, switch: SimResourceSwitch): Boolean { return switch.inputs.size - switch.outputs.size >= model.cpus.size } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimSpaceSharedHypervisorProvider.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorProvider.kt index 923b5bab..fb47d9e5 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimSpaceSharedHypervisorProvider.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorProvider.kt @@ -20,7 +20,7 @@ * SOFTWARE. */ -package org.opendc.simulator.compute +package org.opendc.simulator.compute.kernel import org.opendc.simulator.resources.SimResourceInterpreter import org.opendc.simulator.resources.SimResourceSystem diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/ConservativeScalingGovernor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/cpufreq/ConservativeScalingGovernor.kt index 562c0b73..1a03221d 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/ConservativeScalingGovernor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/cpufreq/ConservativeScalingGovernor.kt @@ -20,12 +20,13 @@ * SOFTWARE. */ -package org.opendc.simulator.compute.cpufreq +package org.opendc.simulator.compute.kernel.cpufreq /** * A CPUFreq [ScalingGovernor] that models the conservative scaling governor in the Linux kernel. */ -public class ConservativeScalingGovernor(public val threshold: Double = 0.8, private val stepSize: Double = -1.0) : ScalingGovernor { +public class ConservativeScalingGovernor(public val threshold: Double = 0.8, private val stepSize: Double = -1.0) : + ScalingGovernor { override fun createLogic(policy: ScalingPolicy): ScalingGovernor.Logic = object : ScalingGovernor.Logic { /** * The step size to use. diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/OnDemandScalingGovernor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/cpufreq/OnDemandScalingGovernor.kt index 2c4a83f1..aef15ce9 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/OnDemandScalingGovernor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/cpufreq/OnDemandScalingGovernor.kt @@ -20,7 +20,7 @@ * SOFTWARE. */ -package org.opendc.simulator.compute.cpufreq +package org.opendc.simulator.compute.kernel.cpufreq /** * A CPUFreq [ScalingGovernor] that models the on-demand scaling governor in the Linux kernel. diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/PerformanceScalingGovernor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/cpufreq/PerformanceScalingGovernor.kt index 8b1d49f6..13109a9a 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/PerformanceScalingGovernor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/cpufreq/PerformanceScalingGovernor.kt @@ -20,7 +20,7 @@ * SOFTWARE. */ -package org.opendc.simulator.compute.cpufreq +package org.opendc.simulator.compute.kernel.cpufreq /** * A CPUFreq [ScalingGovernor] that causes the highest possible frequency to be requested from the resource. diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/PowerSaveScalingGovernor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/cpufreq/PowerSaveScalingGovernor.kt index 0889980c..32c0703a 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/PowerSaveScalingGovernor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/cpufreq/PowerSaveScalingGovernor.kt @@ -20,7 +20,7 @@ * SOFTWARE. */ -package org.opendc.simulator.compute.cpufreq +package org.opendc.simulator.compute.kernel.cpufreq /** * A CPUFreq [ScalingGovernor] that causes the lowest possible frequency to be requested from the resource. diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/ScalingGovernor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/cpufreq/ScalingGovernor.kt index 3fb93ad9..d33827db 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/ScalingGovernor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/cpufreq/ScalingGovernor.kt @@ -20,7 +20,7 @@ * SOFTWARE. */ -package org.opendc.simulator.compute.cpufreq +package org.opendc.simulator.compute.kernel.cpufreq /** * A [ScalingGovernor] in the CPUFreq subsystem of OpenDC is responsible for scaling the frequency of simulated CPUs diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/ScalingPolicy.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/cpufreq/ScalingPolicy.kt index 0552d279..f9351896 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/ScalingPolicy.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/cpufreq/ScalingPolicy.kt @@ -20,7 +20,7 @@ * SOFTWARE. */ -package org.opendc.simulator.compute.cpufreq +package org.opendc.simulator.compute.kernel.cpufreq import org.opendc.simulator.compute.SimProcessingUnit diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachineModel.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/model/MachineModel.kt index 2b414540..d40aff53 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachineModel.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/model/MachineModel.kt @@ -20,15 +20,17 @@ * SOFTWARE. */ -package org.opendc.simulator.compute - -import org.opendc.simulator.compute.model.MemoryUnit -import org.opendc.simulator.compute.model.ProcessingUnit +package org.opendc.simulator.compute.model /** * A description of the physical or virtual machine on which a bootable image runs. * * @property cpus The list of processing units available to the image. * @property memory The list of memory units available to the image. + * @property net A list of network adapters available for the machine. */ -public data class SimMachineModel(public val cpus: List<ProcessingUnit>, public val memory: List<MemoryUnit>) +public data class MachineModel( + public val cpus: List<ProcessingUnit>, + public val memory: List<MemoryUnit>, + public val net: List<NetworkAdapter> = emptyList() +) diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/model/NetworkAdapter.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/model/NetworkAdapter.kt new file mode 100644 index 00000000..46472144 --- /dev/null +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/model/NetworkAdapter.kt @@ -0,0 +1,36 @@ +/* + * 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.simulator.compute.model + +/** + * A description of a network adapter that is + * + * @property vendor The vendor of the network adapter. + * @property modelName The model name of the network adapter. + * @property bandwidth The bandwidth of the network adapter in Mbps. + */ +public data class NetworkAdapter( + public val vendor: String, + public val modelName: String, + public val bandwidth: Double +) diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimFlopsWorkload.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimFlopsWorkload.kt index de6832ca..a01fa20c 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimFlopsWorkload.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimFlopsWorkload.kt @@ -23,7 +23,6 @@ package org.opendc.simulator.compute.workload import org.opendc.simulator.compute.SimMachineContext -import org.opendc.simulator.compute.util.SimWorkloadLifecycle import org.opendc.simulator.resources.consumer.SimWorkConsumer /** diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimRuntimeWorkload.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimRuntimeWorkload.kt index 318a6b49..4ee56689 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimRuntimeWorkload.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimRuntimeWorkload.kt @@ -23,7 +23,6 @@ package org.opendc.simulator.compute.workload import org.opendc.simulator.compute.SimMachineContext -import org.opendc.simulator.compute.util.SimWorkloadLifecycle import org.opendc.simulator.resources.consumer.SimWorkConsumer /** diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt index 6929f4d2..622bcd4d 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimTraceWorkload.kt @@ -24,7 +24,6 @@ package org.opendc.simulator.compute.workload import org.opendc.simulator.compute.SimMachineContext import org.opendc.simulator.compute.model.ProcessingUnit -import org.opendc.simulator.compute.util.SimWorkloadLifecycle import org.opendc.simulator.resources.SimResourceCommand import org.opendc.simulator.resources.SimResourceConsumer import org.opendc.simulator.resources.SimResourceContext diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/util/SimWorkloadLifecycle.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimWorkloadLifecycle.kt index 43662d93..5dd18271 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/util/SimWorkloadLifecycle.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/workload/SimWorkloadLifecycle.kt @@ -20,10 +20,9 @@ * SOFTWARE. */ -package org.opendc.simulator.compute.util +package org.opendc.simulator.compute.workload import org.opendc.simulator.compute.SimMachineContext -import org.opendc.simulator.compute.workload.SimWorkload import org.opendc.simulator.resources.SimResourceConsumer import org.opendc.simulator.resources.SimResourceContext import org.opendc.simulator.resources.SimResourceEvent diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt index b9cfb06b..47ae119c 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt @@ -30,16 +30,16 @@ import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertDoesNotThrow import org.junit.jupiter.api.assertThrows -import org.opendc.simulator.compute.model.MemoryUnit -import org.opendc.simulator.compute.model.ProcessingNode -import org.opendc.simulator.compute.model.ProcessingUnit +import org.opendc.simulator.compute.device.SimNetworkAdapter +import org.opendc.simulator.compute.model.* import org.opendc.simulator.compute.power.ConstantPowerModel import org.opendc.simulator.compute.power.LinearPowerModel import org.opendc.simulator.compute.power.SimplePowerDriver -import org.opendc.simulator.compute.util.SimWorkloadLifecycle import org.opendc.simulator.compute.workload.SimFlopsWorkload import org.opendc.simulator.compute.workload.SimWorkload +import org.opendc.simulator.compute.workload.SimWorkloadLifecycle import org.opendc.simulator.core.runBlockingSimulation +import org.opendc.simulator.network.SimNetworkSink import org.opendc.simulator.power.SimPowerSource import org.opendc.simulator.resources.SimResourceInterpreter import org.opendc.simulator.resources.consumer.SimWorkConsumer @@ -49,15 +49,16 @@ import org.opendc.simulator.resources.consumer.SimWorkConsumer */ @OptIn(ExperimentalCoroutinesApi::class) class SimMachineTest { - private lateinit var machineModel: SimMachineModel + private lateinit var machineModel: MachineModel @BeforeEach fun setUp() { val cpuNode = ProcessingNode("Intel", "Xeon", "amd64", 2) - machineModel = SimMachineModel( + machineModel = MachineModel( cpus = List(cpuNode.coreCount) { ProcessingUnit(cpuNode, it, 1000.0) }, - memory = List(4) { MemoryUnit("Crucial", "MTA18ASF4G72AZ-3G2B1", 3200.0, 32_000) } + memory = List(4) { MemoryUnit("Crucial", "MTA18ASF4G72AZ-3G2B1", 3200.0, 32_000) }, + net = listOf(NetworkAdapter("Mellanox", "ConnectX-5", 25000.0)) ) } @@ -82,7 +83,7 @@ class SimMachineTest { @Test fun testDualSocketMachine() = runBlockingSimulation { val cpuNode = machineModel.cpus[0].node - val machineModel = SimMachineModel( + val machineModel = MachineModel( cpus = List(cpuNode.coreCount * 2) { ProcessingUnit(cpuNode, it % 2, 1000.0) }, memory = List(4) { MemoryUnit("Crucial", "MTA18ASF4G72AZ-3G2B1", 3200.0, 32_000) } ) @@ -232,6 +233,33 @@ class SimMachineTest { } @Test + fun testNetUsage() = runBlockingSimulation { + val interpreter = SimResourceInterpreter(coroutineContext, clock) + val machine = SimBareMetalMachine( + interpreter, + machineModel, + SimplePowerDriver(ConstantPowerModel(0.0)) + ) + + val adapter = (machine.peripherals[0] as SimNetworkAdapter) + adapter.connect(SimNetworkSink(interpreter, adapter.bandwidth)) + + try { + machine.run(object : SimWorkload { + override fun onStart(ctx: SimMachineContext) { + val lifecycle = SimWorkloadLifecycle(ctx) + val iface = ctx.net[0] + iface.tx.startConsumer(lifecycle.waitFor(SimWorkConsumer(iface.bandwidth, utilization = 0.8))) + } + }) + + assertEquals(1250, clock.millis()) + } finally { + machine.close() + } + } + + @Test fun testCancellation() = runBlockingSimulation { val machine = SimBareMetalMachine( SimResourceInterpreter(coroutineContext, clock), diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimPsuTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/device/SimPsuTest.kt index e0ebdb73..6c9ec7bd 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimPsuTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/device/SimPsuTest.kt @@ -20,7 +20,7 @@ * SOFTWARE. */ -package org.opendc.simulator.compute +package org.opendc.simulator.compute.device import io.mockk.every import io.mockk.mockk diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimHypervisorTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorTest.kt index b15692ec..71d48a31 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimHypervisorTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 AtLarge Research + * 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 @@ -20,7 +20,7 @@ * SOFTWARE. */ -package org.opendc.simulator.compute +package org.opendc.simulator.compute.kernel import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.coroutineScope @@ -32,7 +32,9 @@ import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertAll import org.junit.jupiter.api.assertDoesNotThrow -import org.opendc.simulator.compute.cpufreq.PerformanceScalingGovernor +import org.opendc.simulator.compute.SimBareMetalMachine +import org.opendc.simulator.compute.kernel.cpufreq.PerformanceScalingGovernor +import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.model.MemoryUnit import org.opendc.simulator.compute.model.ProcessingNode import org.opendc.simulator.compute.model.ProcessingUnit @@ -47,12 +49,12 @@ import org.opendc.simulator.resources.SimResourceInterpreter */ @OptIn(ExperimentalCoroutinesApi::class) internal class SimHypervisorTest { - private lateinit var model: SimMachineModel + private lateinit var model: MachineModel @BeforeEach fun setUp() { val cpuNode = ProcessingNode("Intel", "Xeon", "amd64", 1) - model = SimMachineModel( + model = MachineModel( cpus = List(cpuNode.coreCount) { ProcessingUnit(cpuNode, it, 3200.0) }, memory = List(4) { MemoryUnit("Crucial", "MTA18ASF4G72AZ-3G2B1", 3200.0, 32_000) } ) @@ -202,7 +204,7 @@ internal class SimHypervisorTest { @Test fun testMultipleCPUs() = runBlockingSimulation { val cpuNode = ProcessingNode("Intel", "Xeon", "amd64", 2) - val model = SimMachineModel( + val model = MachineModel( cpus = List(cpuNode.coreCount) { ProcessingUnit(cpuNode, it, 3200.0) }, memory = List(4) { MemoryUnit("Crucial", "MTA18ASF4G72AZ-3G2B1", 3200.0, 32_000) } ) diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimSpaceSharedHypervisorTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorTest.kt index dba3e9a1..7c77b283 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimSpaceSharedHypervisorTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorTest.kt @@ -20,7 +20,7 @@ * SOFTWARE. */ -package org.opendc.simulator.compute +package org.opendc.simulator.compute.kernel import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.toList @@ -30,6 +30,8 @@ import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows +import org.opendc.simulator.compute.SimBareMetalMachine +import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.model.MemoryUnit import org.opendc.simulator.compute.model.ProcessingNode import org.opendc.simulator.compute.model.ProcessingUnit @@ -46,12 +48,12 @@ import org.opendc.simulator.resources.SimResourceInterpreter */ @OptIn(ExperimentalCoroutinesApi::class) internal class SimSpaceSharedHypervisorTest { - private lateinit var machineModel: SimMachineModel + private lateinit var machineModel: MachineModel @BeforeEach fun setUp() { val cpuNode = ProcessingNode("Intel", "Xeon", "amd64", 1) - machineModel = SimMachineModel( + machineModel = MachineModel( cpus = List(cpuNode.coreCount) { ProcessingUnit(cpuNode, it, 3200.0) }, memory = List(4) { MemoryUnit("Crucial", "MTA18ASF4G72AZ-3G2B1", 3200.0, 32_000) } ) diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/cpufreq/ConservativeScalingGovernorTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/cpufreq/ConservativeScalingGovernorTest.kt index 59817f1d..ef354569 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/cpufreq/ConservativeScalingGovernorTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/cpufreq/ConservativeScalingGovernorTest.kt @@ -20,7 +20,7 @@ * SOFTWARE. */ -package org.opendc.simulator.compute.cpufreq +package org.opendc.simulator.compute.kernel.cpufreq import io.mockk.every import io.mockk.mockk diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/cpufreq/OnDemandScalingGovernorTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/cpufreq/OnDemandScalingGovernorTest.kt index c0c25c97..ca759e39 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/cpufreq/OnDemandScalingGovernorTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/cpufreq/OnDemandScalingGovernorTest.kt @@ -20,7 +20,7 @@ * SOFTWARE. */ -package org.opendc.simulator.compute.cpufreq +package org.opendc.simulator.compute.kernel.cpufreq import io.mockk.every import io.mockk.mockk diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/cpufreq/PerformanceScalingGovernorTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/cpufreq/PerformanceScalingGovernorTest.kt index d7bd6193..a4bb24f2 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/cpufreq/PerformanceScalingGovernorTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/cpufreq/PerformanceScalingGovernorTest.kt @@ -20,7 +20,7 @@ * SOFTWARE. */ -package org.opendc.simulator.compute.cpufreq +package org.opendc.simulator.compute.kernel.cpufreq import io.mockk.every import io.mockk.spyk diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/cpufreq/PowerSaveScalingGovernorTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/cpufreq/PowerSaveScalingGovernorTest.kt index 8d841981..662d55fb 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/cpufreq/PowerSaveScalingGovernorTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/cpufreq/PowerSaveScalingGovernorTest.kt @@ -20,7 +20,7 @@ * SOFTWARE. */ -package org.opendc.simulator.compute.cpufreq +package org.opendc.simulator.compute.kernel.cpufreq import io.mockk.every import io.mockk.mockk diff --git a/opendc-simulator/opendc-simulator-network/build.gradle.kts b/opendc-simulator/opendc-simulator-network/build.gradle.kts new file mode 100644 index 00000000..eb9adcd1 --- /dev/null +++ b/opendc-simulator/opendc-simulator-network/build.gradle.kts @@ -0,0 +1,35 @@ +/* + * 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 = "Library for simulating datacenter network components" + +plugins { + `kotlin-library-conventions` + `testing-conventions` + `jacoco-conventions` +} + +dependencies { + api(platform(projects.opendcPlatform)) + api(projects.opendcSimulator.opendcSimulatorResources) + implementation(projects.opendcSimulator.opendcSimulatorCore) +} diff --git a/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkLink.kt b/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkLink.kt new file mode 100644 index 00000000..67562640 --- /dev/null +++ b/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkLink.kt @@ -0,0 +1,49 @@ +/* + * 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.simulator.network + +/** + * A physical bi-directional communication link between two [SimNetworkPort]s. + * + * @param left The first port of the link. + * @param right The second port of the link. + */ +public class SimNetworkLink(public val left: SimNetworkPort, public val right: SimNetworkPort) { + /** + * Determine whether the specified [port] participates in this network link. + */ + public operator fun contains(port: SimNetworkPort): Boolean = port == left || port == right + + /** + * Obtain the opposite port to which the specified [port] is connected through this link. + */ + public fun opposite(port: SimNetworkPort): SimNetworkPort { + return when (port) { + left -> right + right -> left + else -> throw IllegalArgumentException("Invalid port given") + } + } + + override fun toString(): String = "SimNetworkLink[left=$left,right=$right]" +} diff --git a/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkPort.kt b/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkPort.kt new file mode 100644 index 00000000..102e5625 --- /dev/null +++ b/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkPort.kt @@ -0,0 +1,91 @@ +/* + * 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.simulator.network + +import org.opendc.simulator.resources.SimResourceConsumer +import org.opendc.simulator.resources.SimResourceProvider + +/** + * A network port allows network devices to be connected to network through links. + */ +public abstract class SimNetworkPort { + /** + * A flag to indicate that the network port is connected to another port. + */ + public val isConnected: Boolean + get() = _link != null + + /** + * The network link which connects this port to another port. + */ + public val link: SimNetworkLink? + get() = _link + private var _link: SimNetworkLink? = null + + /** + * Connect this port to the specified [port]. + */ + public fun connect(port: SimNetworkPort) { + require(port !== this) { "Circular reference" } + check(!isConnected) { "Port already connected" } + check(!port.isConnected) { "Target port already connected" } + + val link = SimNetworkLink(this, port) + _link = link + port._link = link + + // Start bi-directional flow channel between the two ports + try { + provider.startConsumer(port.createConsumer()) + port.provider.startConsumer(createConsumer()) + } catch (e: Throwable) { + disconnect() + throw e + } + } + + /** + * Disconnect the current network link if it exists. + */ + public fun disconnect() { + val link = _link ?: return + val opposite = link.opposite(this) + _link = null + opposite._link = null + + provider.cancel() + opposite.provider.cancel() + } + + /** + * Create a [SimResourceConsumer] which generates the outgoing traffic of this port. + */ + protected abstract fun createConsumer(): SimResourceConsumer + + /** + * The [SimResourceProvider] which processes the ingoing traffic of this port. + */ + protected abstract val provider: SimResourceProvider + + override fun toString(): String = "SimNetworkPort[isConnected=$isConnected]" +} diff --git a/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSink.kt b/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSink.kt new file mode 100644 index 00000000..5efdbed9 --- /dev/null +++ b/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSink.kt @@ -0,0 +1,43 @@ +/* + * 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.simulator.network + +import org.opendc.simulator.resources.* + +/** + * A network sink which discards all received traffic and does not generate any traffic itself. + */ +public class SimNetworkSink( + interpreter: SimResourceInterpreter, + public val capacity: Double +) : SimNetworkPort() { + override fun createConsumer(): SimResourceConsumer = object : SimResourceConsumer { + override fun onNext(ctx: SimResourceContext): SimResourceCommand = SimResourceCommand.Idle() + + override fun toString(): String = "SimNetworkSink.Consumer" + } + + override val provider: SimResourceProvider = SimResourceSource(capacity, interpreter) + + override fun toString(): String = "SimNetworkSink[capacity=$capacity]" +} diff --git a/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSwitch.kt b/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSwitch.kt new file mode 100644 index 00000000..7dc249ab --- /dev/null +++ b/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSwitch.kt @@ -0,0 +1,33 @@ +/* + * 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.simulator.network + +/** + * A network device connects devices on a network by switching the traffic over its ports. + */ +public interface SimNetworkSwitch { + /** + * The ports of the switch. + */ + public val ports: List<SimNetworkPort> +} diff --git a/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSwitchVirtual.kt b/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSwitchVirtual.kt new file mode 100644 index 00000000..05daaa5c --- /dev/null +++ b/opendc-simulator/opendc-simulator-network/src/main/kotlin/org/opendc/simulator/network/SimNetworkSwitchVirtual.kt @@ -0,0 +1,77 @@ +/* + * 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.simulator.network + +import org.opendc.simulator.resources.* + +/** + * A [SimNetworkSwitch] that can support new networking ports on demand. + */ +public class SimNetworkSwitchVirtual(interpreter: SimResourceInterpreter) : SimNetworkSwitch { + /** + * The ports of this switch. + */ + override val ports: List<Port> + get() = _ports + private val _ports = mutableListOf<Port>() + + /** + * The [SimResourceSwitchMaxMin] to actually perform the switching. + */ + private val switch = SimResourceSwitchMaxMin(interpreter) + + /** + * Open a new port on the switch. + */ + public fun newPort(): Port { + val port = Port() + _ports.add(port) + return port + } + + /** + * A port on the network switch. + */ + public inner class Port : SimNetworkPort(), AutoCloseable { + /** + * A flag to indicate that this virtual port was removed from the switch. + */ + private var isClosed: Boolean = false + + override val provider: SimResourceProvider + get() = _provider + private val _provider = switch.newOutput() + + override fun createConsumer(): SimResourceConsumer { + val forwarder = SimResourceForwarder(isCoupled = true) + switch.addInput(forwarder) + return forwarder + } + + override fun close() { + isClosed = true + _provider.close() + _ports.remove(this) + } + } +} diff --git a/opendc-simulator/opendc-simulator-network/src/test/kotlin/org/opendc/simulator/network/SimNetworkLinkTest.kt b/opendc-simulator/opendc-simulator-network/src/test/kotlin/org/opendc/simulator/network/SimNetworkLinkTest.kt new file mode 100644 index 00000000..3480c9df --- /dev/null +++ b/opendc-simulator/opendc-simulator-network/src/test/kotlin/org/opendc/simulator/network/SimNetworkLinkTest.kt @@ -0,0 +1,89 @@ +/* + * 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.simulator.network + +import io.mockk.mockk +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows + +/** + * Test suite for [SimNetworkLink] class. + */ +class SimNetworkLinkTest { + @Test + fun testContainsLeft() { + val left = mockk<SimNetworkPort>() + val right = mockk<SimNetworkPort>() + + val link = SimNetworkLink(left, right) + assertTrue(left in link) + } + + @Test + fun testContainsRight() { + val left = mockk<SimNetworkPort>() + val right = mockk<SimNetworkPort>() + + val link = SimNetworkLink(left, right) + assertTrue(right in link) + } + + @Test + fun testContainsNone() { + val left = mockk<SimNetworkPort>() + val right = mockk<SimNetworkPort>() + val none = mockk<SimNetworkPort>() + + val link = SimNetworkLink(left, right) + assertFalse(none in link) + } + + @Test + fun testOppositeLeft() { + val left = mockk<SimNetworkPort>() + val right = mockk<SimNetworkPort>() + + val link = SimNetworkLink(left, right) + assertEquals(right, link.opposite(left)) + } + + @Test + fun testOppositeRight() { + val left = mockk<SimNetworkPort>() + val right = mockk<SimNetworkPort>() + + val link = SimNetworkLink(left, right) + assertEquals(left, link.opposite(right)) + } + + @Test + fun testOppositeNone() { + val left = mockk<SimNetworkPort>() + val right = mockk<SimNetworkPort>() + val none = mockk<SimNetworkPort>() + + val link = SimNetworkLink(left, right) + assertThrows<IllegalArgumentException> { link.opposite(none) } + } +} diff --git a/opendc-simulator/opendc-simulator-network/src/test/kotlin/org/opendc/simulator/network/SimNetworkSinkTest.kt b/opendc-simulator/opendc-simulator-network/src/test/kotlin/org/opendc/simulator/network/SimNetworkSinkTest.kt new file mode 100644 index 00000000..b8c4b00d --- /dev/null +++ b/opendc-simulator/opendc-simulator-network/src/test/kotlin/org/opendc/simulator/network/SimNetworkSinkTest.kt @@ -0,0 +1,137 @@ +/* + * 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.simulator.network + +import io.mockk.every +import io.mockk.mockk +import io.mockk.spyk +import io.mockk.verify +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertDoesNotThrow +import org.junit.jupiter.api.assertThrows +import org.opendc.simulator.core.runBlockingSimulation +import org.opendc.simulator.resources.* +import org.opendc.simulator.resources.consumer.SimWorkConsumer + +/** + * Test suite for the [SimNetworkSink] class. + */ +class SimNetworkSinkTest { + @Test + fun testInitialState() = runBlockingSimulation { + val interpreter = SimResourceInterpreter(coroutineContext, clock) + val sink = SimNetworkSink(interpreter, capacity = 100.0) + + assertFalse(sink.isConnected) + assertNull(sink.link) + assertEquals(100.0, sink.capacity) + } + + @Test + fun testDisconnectIdempotent() = runBlockingSimulation { + val interpreter = SimResourceInterpreter(coroutineContext, clock) + val sink = SimNetworkSink(interpreter, capacity = 100.0) + + assertDoesNotThrow { sink.disconnect() } + assertFalse(sink.isConnected) + } + + @Test + fun testConnectCircular() = runBlockingSimulation { + val interpreter = SimResourceInterpreter(coroutineContext, clock) + val sink = SimNetworkSink(interpreter, capacity = 100.0) + + assertThrows<IllegalArgumentException> { + sink.connect(sink) + } + } + + @Test + fun testConnectAlreadyConnectedTarget() = runBlockingSimulation { + val interpreter = SimResourceInterpreter(coroutineContext, clock) + val sink = SimNetworkSink(interpreter, capacity = 100.0) + val source = mockk<SimNetworkPort>(relaxUnitFun = true) + every { source.isConnected } returns true + + assertThrows<IllegalStateException> { + sink.connect(source) + } + } + + @Test + fun testConnectAlreadyConnected() = runBlockingSimulation { + val interpreter = SimResourceInterpreter(coroutineContext, clock) + val sink = SimNetworkSink(interpreter, capacity = 100.0) + val source1 = Source(interpreter) + + val source2 = mockk<SimNetworkPort>(relaxUnitFun = true) + + every { source2.isConnected } returns false + + sink.connect(source1) + assertThrows<IllegalStateException> { + sink.connect(source2) + } + } + + @Test + fun testConnect() = runBlockingSimulation { + val interpreter = SimResourceInterpreter(coroutineContext, clock) + val sink = SimNetworkSink(interpreter, capacity = 100.0) + val source = spyk(Source(interpreter)) + val consumer = source.consumer + + sink.connect(source) + + assertTrue(sink.isConnected) + assertTrue(source.isConnected) + + verify { source.createConsumer() } + verify { consumer.onEvent(any(), SimResourceEvent.Start) } + } + + @Test + fun testDisconnect() = runBlockingSimulation { + val interpreter = SimResourceInterpreter(coroutineContext, clock) + val sink = SimNetworkSink(interpreter, capacity = 100.0) + val source = spyk(Source(interpreter)) + val consumer = source.consumer + + sink.connect(source) + sink.disconnect() + + assertFalse(sink.isConnected) + assertFalse(source.isConnected) + + verify { consumer.onEvent(any(), SimResourceEvent.Exit) } + } + + private class Source(interpreter: SimResourceInterpreter) : SimNetworkPort() { + val consumer = spyk(SimWorkConsumer(Double.POSITIVE_INFINITY, utilization = 0.8)) + + public override fun createConsumer(): SimResourceConsumer = consumer + + override val provider: SimResourceProvider = SimResourceSource(0.0, interpreter) + } +} diff --git a/opendc-simulator/opendc-simulator-network/src/test/kotlin/org/opendc/simulator/network/SimNetworkSwitchVirtualTest.kt b/opendc-simulator/opendc-simulator-network/src/test/kotlin/org/opendc/simulator/network/SimNetworkSwitchVirtualTest.kt new file mode 100644 index 00000000..3a749bfe --- /dev/null +++ b/opendc-simulator/opendc-simulator-network/src/test/kotlin/org/opendc/simulator/network/SimNetworkSwitchVirtualTest.kt @@ -0,0 +1,77 @@ +/* + * 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.simulator.network + +import io.mockk.spyk +import io.mockk.verify +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import org.opendc.simulator.core.runBlockingSimulation +import org.opendc.simulator.resources.* +import org.opendc.simulator.resources.consumer.SimWorkConsumer + +/** + * Test suite for the [SimNetworkSwitchVirtual] class. + */ +class SimNetworkSwitchVirtualTest { + @Test + fun testConnect() = runBlockingSimulation { + val interpreter = SimResourceInterpreter(coroutineContext, clock) + val sink = SimNetworkSink(interpreter, capacity = 100.0) + val source = spyk(Source(interpreter)) + val switch = SimNetworkSwitchVirtual(interpreter) + val consumer = source.consumer + + switch.newPort().connect(sink) + switch.newPort().connect(source) + + assertTrue(sink.isConnected) + assertTrue(source.isConnected) + + verify { source.createConsumer() } + verify { consumer.onEvent(any(), SimResourceEvent.Start) } + } + + @Test + fun testConnectClosedPort() = runBlockingSimulation { + val interpreter = SimResourceInterpreter(coroutineContext, clock) + val sink = SimNetworkSink(interpreter, capacity = 100.0) + val switch = SimNetworkSwitchVirtual(interpreter) + + val port = switch.newPort() + port.close() + + assertThrows<IllegalStateException> { + port.connect(sink) + } + } + + private class Source(interpreter: SimResourceInterpreter) : SimNetworkPort() { + val consumer = spyk(SimWorkConsumer(Double.POSITIVE_INFINITY, utilization = 0.8)) + + public override fun createConsumer(): SimResourceConsumer = consumer + + override val provider: SimResourceProvider = SimResourceSource(0.0, interpreter) + } +} diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/runner/web/TopologyParser.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/runner/web/TopologyParser.kt index e96a681d..2135ee1d 100644 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/runner/web/TopologyParser.kt +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/runner/web/TopologyParser.kt @@ -32,7 +32,7 @@ import org.bson.Document import org.bson.types.ObjectId import org.opendc.format.environment.EnvironmentReader import org.opendc.format.environment.MachineDef -import org.opendc.simulator.compute.SimMachineModel +import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.model.MemoryUnit import org.opendc.simulator.compute.model.ProcessingNode import org.opendc.simulator.compute.model.ProcessingUnit @@ -80,7 +80,7 @@ public class TopologyParser(private val collection: MongoCollection<Document>) { UUID(random.nextLong(), random.nextLong()), "node-$clusterId-$position", mapOf("cluster" to clusterId), - SimMachineModel(processors, memoryUnits), + MachineModel(processors, memoryUnits), LinearPowerModel(2 * energyConsumptionW, energyConsumptionW * 0.5) ) ) diff --git a/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceIntegrationTest.kt b/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceIntegrationTest.kt index 6807572b..413112af 100644 --- a/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceIntegrationTest.kt +++ b/opendc-workflow/opendc-workflow-service/src/test/kotlin/org/opendc/workflow/service/WorkflowServiceIntegrationTest.kt @@ -41,7 +41,7 @@ import org.opendc.compute.service.scheduler.weights.ProvisionedCoresWeigher import org.opendc.compute.simulator.SimHost import org.opendc.format.environment.sc18.Sc18EnvironmentReader import org.opendc.format.trace.gwf.GwfTraceReader -import org.opendc.simulator.compute.SimSpaceSharedHypervisorProvider +import org.opendc.simulator.compute.kernel.SimSpaceSharedHypervisorProvider import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.resources.SimResourceInterpreter import org.opendc.telemetry.sdk.toOtelClock diff --git a/settings.gradle.kts b/settings.gradle.kts index 34b9bf36..d85c08f8 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -41,6 +41,7 @@ include(":opendc-web:opendc-web-runner") include(":opendc-simulator:opendc-simulator-core") include(":opendc-simulator:opendc-simulator-resources") include(":opendc-simulator:opendc-simulator-power") +include(":opendc-simulator:opendc-simulator-network") include(":opendc-simulator:opendc-simulator-compute") include(":opendc-simulator:opendc-simulator-failures") include(":opendc-telemetry:opendc-telemetry-api") |
