From 94783ff9d8cd81275fefd5804ac99f98e2dee3a4 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 30 Sep 2021 16:00:05 +0200 Subject: fix(simulator): Fix loss computation for UPS and PDU This change fixes the loss computation for both the UPS and PDU implementation that was broken due to the new pushing mechanism. We implement a new class FlowMapper that can be used to map the flow pushed by a `FlowSource` using a user-specified method. --- .../main/kotlin/org/opendc/simulator/power/SimPdu.kt | 16 ++++------------ .../kotlin/org/opendc/simulator/power/SimPowerInlet.kt | 2 +- .../org/opendc/simulator/power/SimPowerSource.kt | 2 +- .../main/kotlin/org/opendc/simulator/power/SimUps.kt | 18 +++++++----------- .../kotlin/org/opendc/simulator/power/SimPduTest.kt | 6 ++---- .../org/opendc/simulator/power/SimPowerSourceTest.kt | 6 +++--- .../kotlin/org/opendc/simulator/power/SimUpsTest.kt | 4 ++-- 7 files changed, 20 insertions(+), 34 deletions(-) (limited to 'opendc-simulator/opendc-simulator-power/src') diff --git a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt index c33f5186..d536f22d 100644 --- a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt +++ b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPdu.kt @@ -57,17 +57,9 @@ public class SimPdu( mux.addOutput(forwarder) } - override fun createConsumer(): FlowSource = object : FlowSource by forwarder { - override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { - val duration = forwarder.onPull(conn, now, delta) - val loss = computePowerLoss(conn.demand) - val newLimit = conn.demand + loss - - conn.push(newLimit) - return duration - } - - override fun toString(): String = "SimPdu.Consumer" + override fun createSource(): FlowSource = FlowMapper(forwarder) { _, rate -> + val loss = computePowerLoss(rate) + rate + loss } override fun toString(): String = "SimPdu" @@ -85,7 +77,7 @@ public class SimPdu( */ public class Outlet(private val switch: FlowMultiplexer, private val provider: FlowConsumer) : SimPowerOutlet(), AutoCloseable { override fun onConnect(inlet: SimPowerInlet) { - provider.startConsumer(inlet.createConsumer()) + provider.startConsumer(inlet.createSource()) } override fun onDisconnect(inlet: SimPowerInlet) { diff --git a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerInlet.kt b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerInlet.kt index 851b28a5..de587b7f 100644 --- a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerInlet.kt +++ b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerInlet.kt @@ -44,5 +44,5 @@ public abstract class SimPowerInlet { /** * Create a [FlowSource] which represents the consumption of electricity from the power outlet. */ - public abstract fun createConsumer(): FlowSource + public abstract fun createSource(): FlowSource } diff --git a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerSource.kt b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerSource.kt index 7faebd75..07e9f52e 100644 --- a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerSource.kt +++ b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimPowerSource.kt @@ -43,7 +43,7 @@ public class SimPowerSource(engine: FlowEngine, public val capacity: Double) : S get() = source.rate override fun onConnect(inlet: SimPowerInlet) { - source.startConsumer(inlet.createConsumer()) + source.startConsumer(inlet.createSource()) } override fun onDisconnect(inlet: SimPowerInlet) { diff --git a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt index 5eaa91af..312f1d0f 100644 --- a/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt +++ b/opendc-simulator/opendc-simulator-power/src/main/kotlin/org/opendc/simulator/power/SimUps.kt @@ -59,17 +59,13 @@ public class SimUps( } override fun onConnect(inlet: SimPowerInlet) { - val consumer = inlet.createConsumer() - provider.startConsumer(object : FlowSource by consumer { - override fun onPull(conn: FlowConnection, now: Long, delta: Long): Long { - val duration = consumer.onPull(conn, now, delta) - val loss = computePowerLoss(conn.demand) - val newLimit = conn.demand + loss + val source = inlet.createSource() + val mapper = FlowMapper(source) { _, rate -> + val loss = computePowerLoss(rate) + rate + loss + } - conn.push(newLimit) - return duration - } - }) + provider.startConsumer(mapper) } override fun onDisconnect(inlet: SimPowerInlet) { @@ -88,7 +84,7 @@ public class SimUps( * A UPS inlet. */ public inner class Inlet(private val forwarder: FlowForwarder) : SimPowerInlet(), AutoCloseable { - override fun createConsumer(): FlowSource = forwarder + override fun createSource(): FlowSource = forwarder /** * Remove the inlet from the PSU. diff --git a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPduTest.kt b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPduTest.kt index 85b9ab01..eb823eb1 100644 --- a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPduTest.kt +++ b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPduTest.kt @@ -25,7 +25,6 @@ package org.opendc.simulator.power import io.mockk.spyk import io.mockk.verify import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows import org.opendc.simulator.core.runBlockingSimulation @@ -79,7 +78,7 @@ internal class SimPduTest { source.connect(pdu) val consumer = spyk(FixedFlowSource(100.0, utilization = 1.0)) val inlet = object : SimPowerInlet() { - override fun createConsumer(): FlowSource = consumer + override fun createSource(): FlowSource = consumer } val outlet = pdu.newOutlet() @@ -90,7 +89,6 @@ internal class SimPduTest { } @Test - @Disabled fun testLoss() = runBlockingSimulation { val engine = FlowEngine(coroutineContext, clock) val source = SimPowerSource(engine, capacity = 100.0) @@ -116,6 +114,6 @@ internal class SimPduTest { } class SimpleInlet : SimPowerInlet() { - override fun createConsumer(): FlowSource = FixedFlowSource(100.0, utilization = 0.5) + override fun createSource(): FlowSource = FixedFlowSource(100.0, utilization = 0.5) } } diff --git a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPowerSourceTest.kt b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPowerSourceTest.kt index 20677633..76142103 100644 --- a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPowerSourceTest.kt +++ b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimPowerSourceTest.kt @@ -79,7 +79,7 @@ internal class SimPowerSourceTest { val source = SimPowerSource(engine, capacity = 100.0) val consumer = spyk(FixedFlowSource(100.0, utilization = 1.0)) val inlet = object : SimPowerInlet() { - override fun createConsumer(): FlowSource = consumer + override fun createSource(): FlowSource = consumer } source.connect(inlet) @@ -95,7 +95,7 @@ internal class SimPowerSourceTest { val inlet = mockk(relaxUnitFun = true) every { inlet.isConnected } returns false every { inlet._outlet } returns null - every { inlet.createConsumer() } returns FixedFlowSource(100.0, utilization = 1.0) + every { inlet.createSource() } returns FixedFlowSource(100.0, utilization = 1.0) source.connect(inlet) @@ -131,6 +131,6 @@ internal class SimPowerSourceTest { } class SimpleInlet : SimPowerInlet() { - override fun createConsumer(): FlowSource = FixedFlowSource(100.0, utilization = 1.0) + override fun createSource(): FlowSource = FixedFlowSource(100.0, utilization = 1.0) } } diff --git a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimUpsTest.kt b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimUpsTest.kt index c6e0605a..a764a368 100644 --- a/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimUpsTest.kt +++ b/opendc-simulator/opendc-simulator-power/src/test/kotlin/org/opendc/simulator/power/SimUpsTest.kt @@ -86,7 +86,7 @@ internal class SimUpsTest { source2.connect(ups.newInlet()) val consumer = spyk(FixedFlowSource(100.0, utilization = 1.0)) val inlet = object : SimPowerInlet() { - override fun createConsumer(): FlowSource = consumer + override fun createSource(): FlowSource = consumer } ups.connect(inlet) @@ -96,6 +96,6 @@ internal class SimUpsTest { } class SimpleInlet : SimPowerInlet() { - override fun createConsumer(): FlowSource = FixedFlowSource(100.0, utilization = 0.5) + override fun createSource(): FlowSource = FixedFlowSource(100.0, utilization = 0.5) } } -- cgit v1.2.3