diff options
Diffstat (limited to 'opendc-experiments/opendc-experiments-greenifier/src')
6 files changed, 204 insertions, 183 deletions
diff --git a/opendc-experiments/opendc-experiments-greenifier/src/jmh/kotlin/org/opendc/experiments/greenifier/GreenifierBenchmarks.kt b/opendc-experiments/opendc-experiments-greenifier/src/jmh/kotlin/org/opendc/experiments/greenifier/GreenifierBenchmarks.kt index 7997d01c..6cc6df36 100644 --- a/opendc-experiments/opendc-experiments-greenifier/src/jmh/kotlin/org/opendc/experiments/greenifier/GreenifierBenchmarks.kt +++ b/opendc-experiments/opendc-experiments-greenifier/src/jmh/kotlin/org/opendc/experiments/greenifier/GreenifierBenchmarks.kt @@ -72,22 +72,24 @@ class GreenifierBenchmarks { } @Benchmark - fun benchmarkGreenifier() = runSimulation { - val serviceDomain = "compute.opendc.org" + fun benchmarkGreenifier() = + runSimulation { + val serviceDomain = "compute.opendc.org" - Provisioner(dispatcher, seed = 0).use { provisioner -> - val computeScheduler = FilterScheduler( - filters = listOf(ComputeFilter(), VCpuFilter(16.0), RamFilter(1.0)), - weighers = listOf(CoreRamWeigher(multiplier = 1.0)) - ) + Provisioner(dispatcher, seed = 0).use { provisioner -> + val computeScheduler = + FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(16.0), RamFilter(1.0)), + weighers = listOf(CoreRamWeigher(multiplier = 1.0)), + ) - provisioner.runSteps( - setupComputeService(serviceDomain, { computeScheduler }), - setupHosts(serviceDomain, topology, optimize = isOptimized) - ) + provisioner.runSteps( + setupComputeService(serviceDomain, { computeScheduler }), + setupHosts(serviceDomain, topology, optimize = isOptimized), + ) - val service = provisioner.registry.resolve(serviceDomain, ComputeService::class.java)!! - service.replay(timeSource, vms, 0L, interference = true) + val service = provisioner.registry.resolve(serviceDomain, ComputeService::class.java)!! + service.replay(timeSource, vms, 0L, interference = true) + } } - } } diff --git a/opendc-experiments/opendc-experiments-greenifier/src/main/kotlin/org/opendc/experiments/greenifier/GreenifierCli.kt b/opendc-experiments/opendc-experiments-greenifier/src/main/kotlin/org/opendc/experiments/greenifier/GreenifierCli.kt index efdc96cd..93557500 100644 --- a/opendc-experiments/opendc-experiments-greenifier/src/main/kotlin/org/opendc/experiments/greenifier/GreenifierCli.kt +++ b/opendc-experiments/opendc-experiments-greenifier/src/main/kotlin/org/opendc/experiments/greenifier/GreenifierCli.kt @@ -104,7 +104,7 @@ internal class GreenifierCommand : CliktCommand(name = "greenifier") { */ private val portfolio by argument(help = "portfolio to replay") .choice( - "greenifier" to { GreenifierPortfolio() } + "greenifier" to { GreenifierPortfolio() }, ) .default({ GreenifierPortfolio() }) @@ -131,12 +131,17 @@ internal class GreenifierCommand : CliktCommand(name = "greenifier") { /** * Run a single scenario. */ - private fun runScenario(runner: GreenifierRunner, pool: ForkJoinPool, scenario: Scenario) { - val pb = ProgressBarBuilder() - .setInitialMax(repeats.toLong()) - .setStyle(ProgressBarStyle.ASCII) - .setTaskName("Simulating...") - .build() + private fun runScenario( + runner: GreenifierRunner, + pool: ForkJoinPool, + scenario: Scenario, + ) { + val pb = + ProgressBarBuilder() + .setInitialMax(repeats.toLong()) + .setStyle(ProgressBarStyle.ASCII) + .setTaskName("Simulating...") + .build() pool.submit { LongStream.range(0, repeats.toLong()) diff --git a/opendc-experiments/opendc-experiments-greenifier/src/main/kotlin/org/opendc/experiments/greenifier/GreenifierPortfolio.kt b/opendc-experiments/opendc-experiments-greenifier/src/main/kotlin/org/opendc/experiments/greenifier/GreenifierPortfolio.kt index eee30b81..f7fd204f 100644 --- a/opendc-experiments/opendc-experiments-greenifier/src/main/kotlin/org/opendc/experiments/greenifier/GreenifierPortfolio.kt +++ b/opendc-experiments/opendc-experiments-greenifier/src/main/kotlin/org/opendc/experiments/greenifier/GreenifierPortfolio.kt @@ -34,26 +34,29 @@ import org.opendc.experiments.base.portfolio.model.Workload * A [Portfolio] that explores the difference between horizontal and vertical scaling. */ public class GreenifierPortfolio : Portfolio { - private val topologies = listOf( - Topology("single"), - Topology("multi") - ) + private val topologies = + listOf( + Topology("single"), + Topology("multi"), + ) - private val workloads = listOf( - Workload("bitbrains-small", trace("trace").sampleByLoad(1.0)) - ) + private val workloads = + listOf( + Workload("bitbrains-small", trace("trace").sampleByLoad(1.0)), + ) private val operationalPhenomena = OperationalPhenomena(0.0, false) private val allocationPolicy = "active-servers" - override val scenarios: Iterable<Scenario> = topologies.flatMap { topology -> - workloads.map { workload -> - Scenario( - topology, - workload, - operationalPhenomena, - allocationPolicy, - mapOf("topology" to topology.name, "workload" to workload.name) - ) + override val scenarios: Iterable<Scenario> = + topologies.flatMap { topology -> + workloads.map { workload -> + Scenario( + topology, + workload, + operationalPhenomena, + allocationPolicy, + mapOf("topology" to topology.name, "workload" to workload.name), + ) + } } - } } diff --git a/opendc-experiments/opendc-experiments-greenifier/src/main/kotlin/org/opendc/experiments/greenifier/GreenifierRunner.kt b/opendc-experiments/opendc-experiments-greenifier/src/main/kotlin/org/opendc/experiments/greenifier/GreenifierRunner.kt index 2c2962f3..6da35cd1 100644 --- a/opendc-experiments/opendc-experiments-greenifier/src/main/kotlin/org/opendc/experiments/greenifier/GreenifierRunner.kt +++ b/opendc-experiments/opendc-experiments-greenifier/src/main/kotlin/org/opendc/experiments/greenifier/GreenifierRunner.kt @@ -50,7 +50,7 @@ import kotlin.math.roundToLong public class GreenifierRunner( private val envPath: File, tracePath: File, - private val outputPath: File? + private val outputPath: File?, ) { /** * The [ComputeWorkloadLoader] to use for loading the traces. @@ -60,14 +60,17 @@ public class GreenifierRunner( /** * Run a single [scenario] with the specified seed. */ - fun runScenario(scenario: Scenario, seed: Long) = runSimulation { + fun runScenario( + scenario: Scenario, + seed: Long, + ) = runSimulation { val serviceDomain = "compute.opendc.org" val topology = clusterTopology(File(envPath, "${scenario.topology.name}.txt")) Provisioner(dispatcher, seed).use { provisioner -> provisioner.runSteps( setupComputeService(serviceDomain, { createComputeScheduler(scenario.allocationPolicy, Random(it.seeder.nextLong())) }), - setupHosts(serviceDomain, topology, optimize = true) + setupHosts(serviceDomain, topology, optimize = true), ) if (outputPath != null) { @@ -80,9 +83,9 @@ public class GreenifierRunner( ParquetComputeMonitor( outputPath, partition, - bufferSize = 4096 - ) - ) + bufferSize = 4096, + ), + ), ) } diff --git a/opendc-experiments/opendc-experiments-greenifier/src/test/kotlin/org/opendc/experiments/greenifier/GreenifierIntegrationTest.kt b/opendc-experiments/opendc-experiments-greenifier/src/test/kotlin/org/opendc/experiments/greenifier/GreenifierIntegrationTest.kt index dbf840a4..36b15ee0 100644 --- a/opendc-experiments/opendc-experiments-greenifier/src/test/kotlin/org/opendc/experiments/greenifier/GreenifierIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-greenifier/src/test/kotlin/org/opendc/experiments/greenifier/GreenifierIntegrationTest.kt @@ -77,10 +77,11 @@ class GreenifierIntegrationTest { @BeforeEach fun setUp() { monitor = TestComputeMonitor() - computeScheduler = FilterScheduler( - filters = listOf(ComputeFilter(), VCpuFilter(16.0), RamFilter(1.0)), - weighers = listOf(CoreRamWeigher(multiplier = 1.0)) - ) + computeScheduler = + FilterScheduler( + filters = listOf(ComputeFilter(), VCpuFilter(16.0), RamFilter(1.0)), + weighers = listOf(CoreRamWeigher(multiplier = 1.0)), + ) workloadLoader = ComputeWorkloadLoader(File("src/test/resources/trace")) } @@ -88,159 +89,166 @@ class GreenifierIntegrationTest { * Test a large simulation setup. */ @Test - fun testLarge() = runSimulation { - val seed = 0L - val workload = createTestWorkload(1.0, seed) - val topology = createTopology() - val monitor = monitor + fun testLarge() = + runSimulation { + val seed = 0L + val workload = createTestWorkload(1.0, seed) + val topology = createTopology() + val monitor = monitor - Provisioner(dispatcher, seed).use { provisioner -> - provisioner.runSteps( - setupComputeService(serviceDomain = "compute.opendc.org", { computeScheduler }), - registerComputeMonitor(serviceDomain = "compute.opendc.org", monitor), - setupHosts(serviceDomain = "compute.opendc.org", topology) - ) + Provisioner(dispatcher, seed).use { provisioner -> + provisioner.runSteps( + setupComputeService(serviceDomain = "compute.opendc.org", { computeScheduler }), + registerComputeMonitor(serviceDomain = "compute.opendc.org", monitor), + setupHosts(serviceDomain = "compute.opendc.org", topology), + ) - val service = provisioner.registry.resolve("compute.opendc.org", ComputeService::class.java)!! - service.replay(timeSource, workload, seed) - } + val service = provisioner.registry.resolve("compute.opendc.org", ComputeService::class.java)!! + service.replay(timeSource, workload, seed) + } - println( - "Scheduler " + - "Success=${monitor.attemptsSuccess} " + - "Failure=${monitor.attemptsFailure} " + - "Error=${monitor.attemptsError} " + - "Pending=${monitor.serversPending} " + - "Active=${monitor.serversActive}" - ) + println( + "Scheduler " + + "Success=${monitor.attemptsSuccess} " + + "Failure=${monitor.attemptsFailure} " + + "Error=${monitor.attemptsError} " + + "Pending=${monitor.serversPending} " + + "Active=${monitor.serversActive}", + ) - // Note that these values have been verified beforehand - assertAll( - { assertEquals(50, monitor.attemptsSuccess, "The scheduler should schedule 50 VMs") }, - { assertEquals(0, monitor.serversActive, "All VMs should finish after a run") }, - { assertEquals(0, monitor.attemptsFailure, "No VM should be unscheduled") }, - { assertEquals(0, monitor.serversPending, "No VM should not be in the queue") }, - { assertEquals(223379991650, monitor.idleTime) { "Incorrect idle time" } }, - { assertEquals(66977091124, monitor.activeTime) { "Incorrect active time" } }, - { assertEquals(3160267873, monitor.stealTime) { "Incorrect steal time" } }, - { assertEquals(0, monitor.lostTime) { "Incorrect lost time" } }, - { assertEquals(5.8407E9, monitor.energyUsage, 1E4) { "Incorrect power draw" } } - ) - } + // Note that these values have been verified beforehand + assertAll( + { assertEquals(50, monitor.attemptsSuccess, "The scheduler should schedule 50 VMs") }, + { assertEquals(0, monitor.serversActive, "All VMs should finish after a run") }, + { assertEquals(0, monitor.attemptsFailure, "No VM should be unscheduled") }, + { assertEquals(0, monitor.serversPending, "No VM should not be in the queue") }, + { assertEquals(223379991650, monitor.idleTime) { "Incorrect idle time" } }, + { assertEquals(66977091124, monitor.activeTime) { "Incorrect active time" } }, + { assertEquals(3160267873, monitor.stealTime) { "Incorrect steal time" } }, + { assertEquals(0, monitor.lostTime) { "Incorrect lost time" } }, + { assertEquals(5.8407E9, monitor.energyUsage, 1E4) { "Incorrect power draw" } }, + ) + } /** * Test a small simulation setup. */ @Test - fun testSmall() = runSimulation { - val seed = 1L - val workload = createTestWorkload(0.25, seed) - val topology = createTopology("single") - val monitor = monitor + fun testSmall() = + runSimulation { + val seed = 1L + val workload = createTestWorkload(0.25, seed) + val topology = createTopology("single") + val monitor = monitor - Provisioner(dispatcher, seed).use { provisioner -> - provisioner.runSteps( - setupComputeService(serviceDomain = "compute.opendc.org", { computeScheduler }), - registerComputeMonitor(serviceDomain = "compute.opendc.org", monitor), - setupHosts(serviceDomain = "compute.opendc.org", topology) - ) + Provisioner(dispatcher, seed).use { provisioner -> + provisioner.runSteps( + setupComputeService(serviceDomain = "compute.opendc.org", { computeScheduler }), + registerComputeMonitor(serviceDomain = "compute.opendc.org", monitor), + setupHosts(serviceDomain = "compute.opendc.org", topology), + ) - val service = provisioner.registry.resolve("compute.opendc.org", ComputeService::class.java)!! - service.replay(timeSource, workload, seed) - } + val service = provisioner.registry.resolve("compute.opendc.org", ComputeService::class.java)!! + service.replay(timeSource, workload, seed) + } - println( - "Scheduler " + - "Success=${monitor.attemptsSuccess} " + - "Failure=${monitor.attemptsFailure} " + - "Error=${monitor.attemptsError} " + - "Pending=${monitor.serversPending} " + - "Active=${monitor.serversActive}" - ) + println( + "Scheduler " + + "Success=${monitor.attemptsSuccess} " + + "Failure=${monitor.attemptsFailure} " + + "Error=${monitor.attemptsError} " + + "Pending=${monitor.serversPending} " + + "Active=${monitor.serversActive}", + ) - // Note that these values have been verified beforehand - assertAll( - { assertEquals(10996730092, monitor.idleTime) { "Idle time incorrect" } }, - { assertEquals(9741285381, monitor.activeTime) { "Active time incorrect" } }, - { assertEquals(152, monitor.stealTime) { "Steal time incorrect" } }, - { assertEquals(0, monitor.lostTime) { "Lost time incorrect" } }, - { assertEquals(7.0109E8, monitor.energyUsage, 1E4) { "Incorrect power draw" } } - ) - } + // Note that these values have been verified beforehand + assertAll( + { assertEquals(10996730092, monitor.idleTime) { "Idle time incorrect" } }, + { assertEquals(9741285381, monitor.activeTime) { "Active time incorrect" } }, + { assertEquals(152, monitor.stealTime) { "Steal time incorrect" } }, + { assertEquals(0, monitor.lostTime) { "Lost time incorrect" } }, + { assertEquals(7.0109E8, monitor.energyUsage, 1E4) { "Incorrect power draw" } }, + ) + } /** * Test a small simulation setup with interference. */ @Test - fun testInterference() = runSimulation { - val seed = 0L - val workload = createTestWorkload(1.0, seed) - val topology = createTopology("single") + fun testInterference() = + runSimulation { + val seed = 0L + val workload = createTestWorkload(1.0, seed) + val topology = createTopology("single") - Provisioner(dispatcher, seed).use { provisioner -> - provisioner.runSteps( - setupComputeService(serviceDomain = "compute.opendc.org", { computeScheduler }), - registerComputeMonitor(serviceDomain = "compute.opendc.org", monitor), - setupHosts(serviceDomain = "compute.opendc.org", topology) - ) + Provisioner(dispatcher, seed).use { provisioner -> + provisioner.runSteps( + setupComputeService(serviceDomain = "compute.opendc.org", { computeScheduler }), + registerComputeMonitor(serviceDomain = "compute.opendc.org", monitor), + setupHosts(serviceDomain = "compute.opendc.org", topology), + ) - val service = provisioner.registry.resolve("compute.opendc.org", ComputeService::class.java)!! - service.replay(timeSource, workload, seed, interference = true) - } + val service = provisioner.registry.resolve("compute.opendc.org", ComputeService::class.java)!! + service.replay(timeSource, workload, seed, interference = true) + } - println( - "Scheduler " + - "Success=${monitor.attemptsSuccess} " + - "Failure=${monitor.attemptsFailure} " + - "Error=${monitor.attemptsError} " + - "Pending=${monitor.serversPending} " + - "Active=${monitor.serversActive}" - ) + println( + "Scheduler " + + "Success=${monitor.attemptsSuccess} " + + "Failure=${monitor.attemptsFailure} " + + "Error=${monitor.attemptsError} " + + "Pending=${monitor.serversPending} " + + "Active=${monitor.serversActive}", + ) - // Note that these values have been verified beforehand - assertAll( - { assertEquals(42814948316, monitor.idleTime) { "Idle time incorrect" } }, - { assertEquals(40138266225, monitor.activeTime) { "Active time incorrect" } }, - { assertEquals(23489356981, monitor.stealTime) { "Steal time incorrect" } }, - { assertEquals(424267131, monitor.lostTime) { "Lost time incorrect" } } - ) - } + // Note that these values have been verified beforehand + assertAll( + { assertEquals(42814948316, monitor.idleTime) { "Idle time incorrect" } }, + { assertEquals(40138266225, monitor.activeTime) { "Active time incorrect" } }, + { assertEquals(23489356981, monitor.stealTime) { "Steal time incorrect" } }, + { assertEquals(424267131, monitor.lostTime) { "Lost time incorrect" } }, + ) + } /** * Test a small simulation setup with failures. */ @Test - fun testFailures() = runSimulation { - val seed = 0L - val topology = createTopology("single") - val workload = createTestWorkload(0.25, seed) - val monitor = monitor + fun testFailures() = + runSimulation { + val seed = 0L + val topology = createTopology("single") + val workload = createTestWorkload(0.25, seed) + val monitor = monitor - Provisioner(dispatcher, seed).use { provisioner -> - provisioner.runSteps( - setupComputeService(serviceDomain = "compute.opendc.org", { computeScheduler }), - registerComputeMonitor(serviceDomain = "compute.opendc.org", monitor), - setupHosts(serviceDomain = "compute.opendc.org", topology) - ) + Provisioner(dispatcher, seed).use { provisioner -> + provisioner.runSteps( + setupComputeService(serviceDomain = "compute.opendc.org", { computeScheduler }), + registerComputeMonitor(serviceDomain = "compute.opendc.org", monitor), + setupHosts(serviceDomain = "compute.opendc.org", topology), + ) - val service = provisioner.registry.resolve("compute.opendc.org", ComputeService::class.java)!! - service.replay(timeSource, workload, seed, failureModel = grid5000(Duration.ofDays(7))) - } + val service = provisioner.registry.resolve("compute.opendc.org", ComputeService::class.java)!! + service.replay(timeSource, workload, seed, failureModel = grid5000(Duration.ofDays(7))) + } - // Note that these values have been verified beforehand - assertAll( - { assertEquals(1404277711, monitor.idleTime) { "Idle time incorrect" } }, - { assertEquals(1478675712, monitor.activeTime) { "Active time incorrect" } }, - { assertEquals(152, monitor.stealTime) { "Steal time incorrect" } }, - { assertEquals(0, monitor.lostTime) { "Lost time incorrect" } }, - { assertEquals(360369187, monitor.uptime) { "Uptime incorrect" } } - ) - } + // Note that these values have been verified beforehand + assertAll( + { assertEquals(1404277711, monitor.idleTime) { "Idle time incorrect" } }, + { assertEquals(1478675712, monitor.activeTime) { "Active time incorrect" } }, + { assertEquals(152, monitor.stealTime) { "Steal time incorrect" } }, + { assertEquals(0, monitor.lostTime) { "Lost time incorrect" } }, + { assertEquals(360369187, monitor.uptime) { "Uptime incorrect" } }, + ) + } /** * Obtain the trace reader for the test. */ - private fun createTestWorkload(fraction: Double, seed: Long): List<VirtualMachine> { + private fun createTestWorkload( + fraction: Double, + seed: Long, + ): List<VirtualMachine> { val source = trace("bitbrains-small").sampleByLoad(fraction) return source.resolve(workloadLoader, Random(seed)) } diff --git a/opendc-experiments/opendc-experiments-greenifier/src/test/kotlin/org/opendc/experiments/greenifier/GreenifierRunnerTest.kt b/opendc-experiments/opendc-experiments-greenifier/src/test/kotlin/org/opendc/experiments/greenifier/GreenifierRunnerTest.kt index ad3113e1..b6d6a6e9 100644 --- a/opendc-experiments/opendc-experiments-greenifier/src/test/kotlin/org/opendc/experiments/greenifier/GreenifierRunnerTest.kt +++ b/opendc-experiments/opendc-experiments-greenifier/src/test/kotlin/org/opendc/experiments/greenifier/GreenifierRunnerTest.kt @@ -46,20 +46,20 @@ class GreenifierRunnerTest { private val tracePath = File("src/test/resources/trace") /** - * Smoke test with output. + * Smoke test with output. fixme: Fix failures and enable Test */ -// @Test // fixme: Fix failures and enable fun testSmoke() { val outputPath = Files.createTempDirectory("output").toFile() try { val runner = GreenifierRunner(envPath, tracePath, outputPath) - val scenario = Scenario( - Topology("topology"), - Workload("bitbrains-small", trace("bitbrains-small")), - OperationalPhenomena(failureFrequency = 24.0 * 7, hasInterference = true), - "active-servers" - ) + val scenario = + Scenario( + Topology("topology"), + Workload("bitbrains-small", trace("bitbrains-small")), + OperationalPhenomena(failureFrequency = 24.0 * 7, hasInterference = true), + "active-servers", + ) assertDoesNotThrow { runner.runScenario(scenario, seed = 0L) } } finally { @@ -68,17 +68,17 @@ class GreenifierRunnerTest { } /** - * Smoke test without output. + * Smoke test without output. fixme: Fix failures and enable Test */ -// @Test // fixme: Fix failures and enable fun testSmokeNoOutput() { val runner = GreenifierRunner(envPath, tracePath, null) - val scenario = Scenario( - Topology("topology"), - Workload("bitbrains-small", trace("bitbrains-small")), - OperationalPhenomena(failureFrequency = 24.0 * 7, hasInterference = true), - "active-servers" - ) + val scenario = + Scenario( + Topology("topology"), + Workload("bitbrains-small", trace("bitbrains-small")), + OperationalPhenomena(failureFrequency = 24.0 * 7, hasInterference = true), + "active-servers", + ) assertDoesNotThrow { runner.runScenario(scenario, seed = 0L) } } |
