summaryrefslogtreecommitdiff
path: root/simulator/opendc-compute
diff options
context:
space:
mode:
authorHongyu <39747921+HongyuHe@users.noreply.github.com>2021-03-06 19:36:46 +0100
committerGitHub <noreply@github.com>2021-03-06 19:36:46 +0100
commit2977dd8a5f1d742193eae79364a284e68269f7b5 (patch)
tree3fb378be396d728d30b2769a4610c652cfb71507 /simulator/opendc-compute
parentd72ac4b1df32dd5e6bd3faa4fa528dbf8a03f6f1 (diff)
sim: Implement energy models from CloudSim (#79)
This commit implements the energy models that are present in CloudSim: 1. Constant 2. Linear 3. Cubic 4. Square root 5. Interpolation based on data.
Diffstat (limited to 'simulator/opendc-compute')
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimBareMetalDriver.kt12
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/PowerModel.kt32
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/PowerModels.kt42
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/api/CpuPowerModel.kt31
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/api/Powerable.kt (renamed from simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/Powerable.kt)2
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/ConstantPowerModel.kt10
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/CubicPowerModel.kt26
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/InterpolationPowerModel.kt34
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/LinearPowerModel.kt25
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/SqrtPowerModel.kt26
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/SquarePowerModel.kt26
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/ZeroIdlePowerDecorator.kt14
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/package-info.java12
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/power/CpuPowerModelTest.kt75
14 files changed, 286 insertions, 81 deletions
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimBareMetalDriver.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimBareMetalDriver.kt
index 7a978a53..1e459e6f 100644
--- a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimBareMetalDriver.kt
+++ b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimBareMetalDriver.kt
@@ -34,9 +34,9 @@ import org.opendc.compute.core.metal.Node
import org.opendc.compute.core.metal.NodeEvent
import org.opendc.compute.core.metal.NodeState
import org.opendc.compute.core.metal.driver.BareMetalDriver
-import org.opendc.compute.simulator.power.ConstantPowerModel
-import org.opendc.compute.simulator.power.PowerModel
-import org.opendc.compute.simulator.power.Powerable
+import org.opendc.compute.simulator.power.api.CpuPowerModel
+import org.opendc.compute.simulator.power.api.Powerable
+import org.opendc.compute.simulator.power.models.ConstantPowerModel
import org.opendc.core.services.ServiceRegistry
import org.opendc.simulator.compute.SimBareMetalMachine
import org.opendc.simulator.compute.SimExecutionContext
@@ -59,7 +59,7 @@ import kotlin.random.Random
* @param name An optional name of the machine.
* @param metadata The initial metadata of the node.
* @param machine The machine model to simulate.
- * @param powerModel The power model of this machine.
+ * @param cpuPowerModel The CPU power model of this machine.
*/
@OptIn(ExperimentalCoroutinesApi::class)
public class SimBareMetalDriver(
@@ -69,7 +69,7 @@ public class SimBareMetalDriver(
name: String,
metadata: Map<String, Any>,
machine: SimMachineModel,
- powerModel: PowerModel<SimBareMetalDriver> = ConstantPowerModel(0.0)
+ cpuPowerModel: CpuPowerModel = ConstantPowerModel(0.0),
) : BareMetalDriver, FailureDomain, Powerable {
/**
* The flavor that corresponds to this machine.
@@ -100,7 +100,7 @@ public class SimBareMetalDriver(
override val usage: Flow<Double>
get() = this.machine.usage
- override val powerDraw: Flow<Double> = powerModel(this)
+ override val powerDraw: Flow<Double> = cpuPowerModel.getPowerDraw(this)
/**
* The internal random instance.
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/PowerModel.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/PowerModel.kt
deleted file mode 100644
index 174a510b..00000000
--- a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/PowerModel.kt
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2020 atlarge-research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.simulator.power
-
-import kotlinx.coroutines.flow.Flow
-
-/**
- * A model for computing the power draw based on some value.
- */
-public typealias PowerModel<T> = (T) -> Flow<Double>
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/PowerModels.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/PowerModels.kt
deleted file mode 100644
index 651eba6e..00000000
--- a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/PowerModels.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2020 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.simulator.power
-
-import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.flow.map
-import org.opendc.compute.core.metal.driver.BareMetalDriver
-
-/**
- * A power model which emits a single value.
- */
-public fun ConstantPowerModel(value: Double): PowerModel<BareMetalDriver> = { _ -> flowOf(value) }
-
-/**
- * A power model that assumes a naive linear relation between power usage and host CPU utilization.
- *
- * @param idle The power draw in Watts on idle.
- * @param max The maximum power draw in Watts of the server.
- */
-public fun LinearLoadPowerModel(idle: Double, max: Double): PowerModel<BareMetalDriver> = { driver ->
- driver.usage.map { load -> (max - idle) * load + idle }
-}
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/api/CpuPowerModel.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/api/CpuPowerModel.kt
new file mode 100644
index 00000000..ee9e130b
--- /dev/null
+++ b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/api/CpuPowerModel.kt
@@ -0,0 +1,31 @@
+package org.opendc.compute.simulator.power.api
+
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.map
+import org.opendc.compute.core.metal.driver.BareMetalDriver
+
+public interface CpuPowerModel {
+ /**
+ * Computes CPU power consumption for each host.
+ *
+ * @param cpuUtil The CPU utilization percentage.
+ * @return A [Double] value of CPU power consumption.
+ * @throws IllegalArgumentException Will throw an error if [cpuUtil] is out of range.
+ */
+ @Throws(IllegalArgumentException::class)
+ public fun computeCpuPower(cpuUtil: Double): Double
+
+ /**
+ * Emits the values of power consumption for servers.
+ *
+ * @param driver A [BareMetalDriver] that offers host CPU utilization.
+ * @param withoutIdle A [Boolean] flag indicates whether (false) add a constant
+ * power consumption value when the server is idle or (true) not
+ * with a default value being false.
+ * @return A [Flow] of values representing the server power draw.
+ */
+ public fun getPowerDraw(driver: BareMetalDriver, withoutIdle: Boolean = false): Flow<Double> =
+ driver.usage.map {
+ computeCpuPower(it)
+ }
+}
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/Powerable.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/api/Powerable.kt
index dcf74468..780f2a29 100644
--- a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/Powerable.kt
+++ b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/api/Powerable.kt
@@ -22,7 +22,7 @@
* SOFTWARE.
*/
-package org.opendc.compute.simulator.power
+package org.opendc.compute.simulator.power.api
import kotlinx.coroutines.flow.Flow
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/ConstantPowerModel.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/ConstantPowerModel.kt
new file mode 100644
index 00000000..5e80827b
--- /dev/null
+++ b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/ConstantPowerModel.kt
@@ -0,0 +1,10 @@
+package org.opendc.compute.simulator.power.models
+
+import org.opendc.compute.simulator.power.api.CpuPowerModel
+
+/**
+ * A power model which produces a constant value [constant].
+ */
+public class ConstantPowerModel(private val constant: Double) : CpuPowerModel {
+ public override fun computeCpuPower(cpuUtil: Double): Double = constant
+}
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/CubicPowerModel.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/CubicPowerModel.kt
new file mode 100644
index 00000000..9008a987
--- /dev/null
+++ b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/CubicPowerModel.kt
@@ -0,0 +1,26 @@
+package org.opendc.compute.simulator.power.models
+
+import org.opendc.compute.simulator.power.api.CpuPowerModel
+import kotlin.math.pow
+
+/**
+ * The cubic power model partially adapted from CloudSim.
+ *
+ * @param maxPower The maximum power draw in Watts of the server.
+ * @param staticPowerPercent The static power percentage.
+ * @property staticPower The static power consumption that is not dependent on resource usage.
+ * It is the amount of energy consumed even when the host is idle.
+ * @property constPower The constant power consumption for each fraction of resource used.
+ */
+public class CubicPowerModel(
+ private var maxPower: Double,
+ staticPowerPercent: Double
+) : CpuPowerModel {
+ private var staticPower: Double = staticPowerPercent * maxPower
+ private var constPower: Double = (maxPower - staticPower) / 100.0.pow(3)
+
+ public override fun computeCpuPower(cpuUtil: Double): Double {
+ require(cpuUtil in 0.0..1.0) { "CPU utilization must be in [0, 1]" }
+ return staticPower + constPower * (cpuUtil * 100).pow(3)
+ }
+}
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/InterpolationPowerModel.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/InterpolationPowerModel.kt
new file mode 100644
index 00000000..b01957e4
--- /dev/null
+++ b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/InterpolationPowerModel.kt
@@ -0,0 +1,34 @@
+package org.opendc.compute.simulator.power.models
+
+import org.opendc.compute.simulator.power.api.CpuPowerModel
+import kotlin.math.ceil
+import kotlin.math.floor
+
+/**
+ * The linear interpolation power model partially adapted from CloudSim.
+ *
+ * @param maxPower The maximum power draw in Watts of the server.
+ * @param staticPowerPercent The static power percentage.
+ * @property staticPower The static power consumption that is not dependent on resource usage.
+ * It is the amount of energy consumed even when the host is idle.
+ * @property constPower The constant power consumption for each fraction of resource used.
+ */
+public abstract class InterpolationPowerModel : CpuPowerModel {
+
+ public override fun computeCpuPower(cpuUtil: Double): Double {
+ require(cpuUtil in 0.0..1.0) { "CPU utilization must be in [0, 1]" }
+
+ val cpuUtilFlr = floor(cpuUtil * 10).toInt()
+ val cpuUtilCil = ceil(cpuUtil * 10).toInt()
+ val power1: Double = getPowerData(cpuUtilFlr)
+ val power2: Double = getPowerData(cpuUtilCil)
+ val delta = (power2 - power1) / 10
+
+ return if (cpuUtil % 0.1 == 0.0)
+ getPowerData((cpuUtil * 10).toInt())
+ else
+ power1 + delta * (cpuUtil - cpuUtilFlr.toDouble() / 10) * 100
+ }
+
+ public abstract fun getPowerData(index: Int): Double
+}
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/LinearPowerModel.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/LinearPowerModel.kt
new file mode 100644
index 00000000..913095ad
--- /dev/null
+++ b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/LinearPowerModel.kt
@@ -0,0 +1,25 @@
+package org.opendc.compute.simulator.power.models
+
+import org.opendc.compute.simulator.power.api.CpuPowerModel
+
+/**
+ * The linear power model partially adapted from CloudSim.
+ *
+ * @param maxPower The maximum power draw in Watts of the server.
+ * @param staticPowerPercent The static power percentage.
+ * @property staticPower The static power consumption that is not dependent on resource usage.
+ * It is the amount of energy consumed even when the host is idle.
+ * @property constPower The constant power consumption for each fraction of resource used.
+ */
+public class LinearPowerModel(
+ private var maxPower: Double,
+ staticPowerPercent: Double
+) : CpuPowerModel {
+ private var staticPower: Double = staticPowerPercent * maxPower
+ private var constPower: Double = (maxPower - staticPower) / 100
+
+ public override fun computeCpuPower(cpuUtil: Double): Double {
+ require(cpuUtil in 0.0..1.0) { "CPU utilization must be in [0, 1]" }
+ return staticPower + constPower * cpuUtil * 100
+ }
+}
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/SqrtPowerModel.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/SqrtPowerModel.kt
new file mode 100644
index 00000000..85d94ffc
--- /dev/null
+++ b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/SqrtPowerModel.kt
@@ -0,0 +1,26 @@
+package org.opendc.compute.simulator.power.models
+
+import org.opendc.compute.simulator.power.api.CpuPowerModel
+import kotlin.math.sqrt
+
+/**
+ * The square root power model partially adapted from CloudSim.
+ *
+ * @param maxPower The maximum power draw in Watts of the server.
+ * @param staticPowerPercent The static power percentage.
+ * @property staticPower The static power consumption that is not dependent on resource usage.
+ * It is the amount of energy consumed even when the host is idle.
+ * @property constPower The constant power consumption for each fraction of resource used.
+ */
+public class SqrtPowerModel(
+ private var maxPower: Double,
+ staticPowerPercent: Double
+) : CpuPowerModel {
+ private var staticPower: Double = staticPowerPercent * maxPower
+ private var constPower: Double = (maxPower - staticPower) / sqrt(100.0)
+
+ override fun computeCpuPower(cpuUtil: Double): Double {
+ require(cpuUtil in 0.0..1.0) { "CPU utilization must be in [0, 1]" }
+ return staticPower + constPower * sqrt(cpuUtil * 100)
+ }
+}
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/SquarePowerModel.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/SquarePowerModel.kt
new file mode 100644
index 00000000..5f44aa3c
--- /dev/null
+++ b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/SquarePowerModel.kt
@@ -0,0 +1,26 @@
+package org.opendc.compute.simulator.power.models
+
+import org.opendc.compute.simulator.power.api.CpuPowerModel
+import kotlin.math.pow
+
+/**
+ * The square power model partially adapted from CloudSim.
+ *
+ * @param maxPower The maximum power draw in Watts of the server.
+ * @param staticPowerPercent The static power percentage.
+ * @property staticPower The static power consumption that is not dependent on resource usage.
+ * It is the amount of energy consumed even when the host is idle.
+ * @property constPower The constant power consumption for each fraction of resource used.
+ */
+public class SquarePowerModel(
+ private var maxPower: Double,
+ staticPowerPercent: Double
+) : CpuPowerModel {
+ private var staticPower: Double = staticPowerPercent * maxPower
+ private var constPower: Double = (maxPower - staticPower) / 100.0.pow(2)
+
+ override fun computeCpuPower(cpuUtil: Double): Double {
+ require(cpuUtil in 0.0..1.0) { "CPU utilization must be in [0, 1]" }
+ return staticPower + constPower * (cpuUtil * 100).pow(2)
+ }
+}
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/ZeroIdlePowerDecorator.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/ZeroIdlePowerDecorator.kt
new file mode 100644
index 00000000..938e5607
--- /dev/null
+++ b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/ZeroIdlePowerDecorator.kt
@@ -0,0 +1,14 @@
+package org.opendc.compute.simulator.power.models
+
+import org.opendc.compute.simulator.power.api.CpuPowerModel
+
+/**
+ * A decorator for ignoring the idle power when computing energy consumption of components.
+ *
+ * @param cpuModelWrappee The wrappe of a [CpuPowerModel].
+ */
+public class ZeroIdlePowerDecorator(private val cpuModelWrappee: CpuPowerModel) : CpuPowerModel {
+ override fun computeCpuPower(cpuUtil: Double): Double {
+ return if (cpuUtil == 0.0) 0.0 else cpuModelWrappee.computeCpuPower(cpuUtil)
+ }
+}
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/package-info.java b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/package-info.java
new file mode 100644
index 00000000..9354f1f9
--- /dev/null
+++ b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/power/models/package-info.java
@@ -0,0 +1,12 @@
+/**
+ * Contains a set of energy models, which are developed based on that of the following cloud simulators.
+ * N.B. Different configurations and new features may have been introduced.
+ *
+ * CloudSim:
+ * @see <a href="http://dx.doi.org/10.1002/cpe.1867">Anton Beloglazov, and Rajkumar Buyya, "Optimal Online Deterministic
+ * Algorithms and Adaptive Heuristics for Energy and Performance Efficient Dynamic Consolidation of Virtual Machines in
+ * Cloud Data Centers", Concurrency and Computation: Practice and Experience (CCPE), Volume 24,
+ * Issue 13, Pages: 1397-1420, John Wiley & Sons, Ltd, New York, USA, 2012</a>
+ */
+package org.opendc.compute.simulator.power.models;
+// rest of the file is empty
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/power/CpuPowerModelTest.kt b/simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/power/CpuPowerModelTest.kt
new file mode 100644
index 00000000..7b0c7515
--- /dev/null
+++ b/simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/power/CpuPowerModelTest.kt
@@ -0,0 +1,75 @@
+package org.opendc.compute.simulator.power
+
+import io.mockk.*
+import kotlinx.coroutines.flow.*
+import kotlinx.coroutines.runBlocking
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.params.ParameterizedTest
+import org.junit.jupiter.params.provider.Arguments
+import org.junit.jupiter.params.provider.MethodSource
+import org.opendc.compute.core.metal.driver.BareMetalDriver
+import org.opendc.compute.simulator.power.api.CpuPowerModel
+import org.opendc.compute.simulator.power.models.*
+import java.util.stream.Stream
+import kotlin.math.pow
+
+internal class CpuPowerModelTest {
+ private val epsilon = 10.0.pow(-3)
+ private val cpuUtil = .9
+
+ @ParameterizedTest
+ @MethodSource("cpuPowerModelArgs")
+ fun `compute power consumption given CPU loads`(
+ powerModel: CpuPowerModel,
+ expectedPowerConsumption: Double
+ ) {
+ val computedPowerConsumption = powerModel.computeCpuPower(cpuUtil)
+ assertEquals(expectedPowerConsumption, computedPowerConsumption, epsilon)
+ }
+
+ @ParameterizedTest
+ @MethodSource("cpuPowerModelArgs")
+ fun `ignore idle power when computing power consumptions`(
+ powerModel: CpuPowerModel,
+ expectedPowerConsumption: Double
+ ) {
+ val zeroPowerModel = ZeroIdlePowerDecorator(powerModel)
+ val computedPowerConsumption = zeroPowerModel.computeCpuPower(0.0)
+ assertEquals(0.0, computedPowerConsumption)
+ }
+
+ @ParameterizedTest
+ @MethodSource("cpuPowerModelArgs")
+ fun `emit power draw for hosts by different models`(
+ powerModel: CpuPowerModel,
+ expectedPowerConsumption: Double
+ ) {
+ val cpuLoads = flowOf(cpuUtil, cpuUtil, cpuUtil)
+ val bareMetalDriver = mockkClass(BareMetalDriver::class)
+ every { bareMetalDriver.usage } returns cpuLoads
+
+ runBlocking {
+ val serverPowerDraw = powerModel.getPowerDraw(bareMetalDriver)
+
+ assertEquals(serverPowerDraw.count(), cpuLoads.count())
+ assertEquals(
+ serverPowerDraw.first().toDouble(),
+ flowOf(expectedPowerConsumption).first().toDouble(),
+ epsilon
+ )
+ }
+ verify(exactly = 1) { bareMetalDriver.usage }
+ }
+
+ @Suppress("unused")
+ private companion object {
+ @JvmStatic
+ fun cpuPowerModelArgs(): Stream<Arguments> = Stream.of(
+ Arguments.of(ConstantPowerModel(0.0), 0.0),
+ Arguments.of(LinearPowerModel(350.0, 200 / 350.0), 335.0),
+ Arguments.of(SquarePowerModel(350.0, 200 / 350.0), 321.5),
+ Arguments.of(CubicPowerModel(350.0, 200 / 350.0), 309.35),
+ Arguments.of(SqrtPowerModel(350.0, 200 / 350.0), 342.302),
+ )
+ }
+}