summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--opendc-experiments/opendc-experiments-energy21/build.gradle.kts6
-rw-r--r--opendc-experiments/opendc-experiments-energy21/src/main/kotlin/org/opendc/experiments/energy21/EnergyExperiment.kt3
-rw-r--r--opendc-harness/opendc-harness-cli/build.gradle.kts6
-rw-r--r--opendc-harness/opendc-harness-cli/src/main/kotlin/org/opendc/harness/runner/cli/ConsoleRunner.kt56
-rw-r--r--opendc-harness/opendc-harness-engine/src/main/kotlin/org/opendc/harness/engine/discovery/DiscoveryProvider.kt6
-rw-r--r--opendc-harness/opendc-harness-engine/src/main/kotlin/org/opendc/harness/engine/internal/CompositeDiscovery.kt4
-rw-r--r--opendc-harness/opendc-harness-engine/src/main/kotlin/org/opendc/harness/engine/internal/DslDiscovery.kt3
-rw-r--r--opendc-harness/opendc-harness-engine/src/main/kotlin/org/opendc/harness/engine/internal/DslDiscoveryProvider.kt2
-rw-r--r--opendc-harness/opendc-harness-engine/src/test/kotlin/org/opendc/harness/EngineTest.kt2
-rw-r--r--opendc-harness/opendc-harness-junit5/src/main/kotlin/org/opendc/harness/runner/junit5/OpenDCTestEngine.kt3
10 files changed, 68 insertions, 23 deletions
diff --git a/opendc-experiments/opendc-experiments-energy21/build.gradle.kts b/opendc-experiments/opendc-experiments-energy21/build.gradle.kts
index 618c525e..7d5fc98d 100644
--- a/opendc-experiments/opendc-experiments-energy21/build.gradle.kts
+++ b/opendc-experiments/opendc-experiments-energy21/build.gradle.kts
@@ -27,12 +27,6 @@ plugins {
`kotlin-library-conventions`
`experiment-conventions`
`testing-conventions`
- application
-}
-
-application {
- mainClass.set("org.opendc.harness.runner.cli.ConsoleRunnerKt")
- applicationDefaultJvmArgs = listOf("-Xms2500M")
}
dependencies {
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 bb6dcd3a..772c9bcc 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
@@ -26,7 +26,6 @@ import io.opentelemetry.api.metrics.MeterProvider
import io.opentelemetry.sdk.metrics.SdkMeterProvider
import io.opentelemetry.sdk.metrics.export.MetricProducer
import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.coroutineScope
import mu.KotlinLogging
@@ -85,9 +84,7 @@ public class EnergyExperiment : Experiment("Energy Modeling 2021") {
*/
private val powerModel by anyOf(PowerModelType.LINEAR, PowerModelType.CUBIC, PowerModelType.INTERPOLATION)
- @OptIn(ExperimentalCoroutinesApi::class)
override fun doRun(repeat: Int): Unit = runBlockingSimulation {
-
val chan = Channel<Unit>(Channel.CONFLATED)
val allocationPolicy = FilterScheduler(
filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()),
diff --git a/opendc-harness/opendc-harness-cli/build.gradle.kts b/opendc-harness/opendc-harness-cli/build.gradle.kts
index 26f02f55..3e169e2a 100644
--- a/opendc-harness/opendc-harness-cli/build.gradle.kts
+++ b/opendc-harness/opendc-harness-cli/build.gradle.kts
@@ -25,6 +25,12 @@ description = "Command line interface of OpenDC Harness"
/* Build configuration */
plugins {
`kotlin-library-conventions`
+ application
+}
+
+application {
+ applicationName = "opendc-harness"
+ mainClass.set("org.opendc.harness.runner.cli.ConsoleRunnerKt")
}
dependencies {
diff --git a/opendc-harness/opendc-harness-cli/src/main/kotlin/org/opendc/harness/runner/cli/ConsoleRunner.kt b/opendc-harness/opendc-harness-cli/src/main/kotlin/org/opendc/harness/runner/cli/ConsoleRunner.kt
index c59e623c..82adb2fd 100644
--- a/opendc-harness/opendc-harness-cli/src/main/kotlin/org/opendc/harness/runner/cli/ConsoleRunner.kt
+++ b/opendc-harness/opendc-harness-cli/src/main/kotlin/org/opendc/harness/runner/cli/ConsoleRunner.kt
@@ -23,16 +23,23 @@
package org.opendc.harness.runner.cli
import com.github.ajalt.clikt.core.CliktCommand
+import com.github.ajalt.clikt.parameters.arguments.argument
+import com.github.ajalt.clikt.parameters.arguments.multiple
+import com.github.ajalt.clikt.parameters.arguments.unique
import com.github.ajalt.clikt.parameters.options.default
import com.github.ajalt.clikt.parameters.options.multiple
import com.github.ajalt.clikt.parameters.options.option
+import com.github.ajalt.clikt.parameters.options.unique
+import com.github.ajalt.clikt.parameters.types.file
import com.github.ajalt.clikt.parameters.types.int
import mu.KotlinLogging
+import org.junit.platform.commons.util.ClassLoaderUtils
import org.opendc.harness.engine.ExperimentEngineLauncher
import org.opendc.harness.engine.discovery.DiscoveryProvider
import org.opendc.harness.engine.discovery.DiscoveryRequest
import org.opendc.harness.engine.discovery.DiscoverySelector
import org.opendc.harness.engine.scheduler.ThreadPoolExperimentScheduler
+import java.net.URLClassLoader
/**
* The logger for this experiment runner.
@@ -53,23 +60,38 @@ public class ConsoleRunner : CliktCommand(name = "opendc-harness") {
/**
* The selected experiments to run by name.
*/
- private val experiments by option("-e", "--experiments", help = "Names of experiments to explore")
- .multiple(emptyList())
+ private val experiments by argument(help = "Experiments to explore")
+ .multiple()
+ .unique()
/**
* The maximum number of worker threads to use.
*/
private val parallelism by option("-p", "--parallelism", help = "Maximum number of concurrent simulation runs")
.int()
- .default(Runtime.getRuntime().availableProcessors())
+ .default(Runtime.getRuntime().availableProcessors() - 1)
+
+ /**
+ * Additional classpath entries to load.
+ */
+ private val additionalClasspathEntries by option("--class-path", help = "Additional classpath entries to load")
+ .file(mustExist = true)
+ .multiple()
+ .unique()
override fun run() {
logger.info { "Starting OpenDC Console Experiment Runner" }
- val discovery = DiscoveryProvider.createComposite()
+ val classLoader = createClassLoader()
+ // TODO: Add way to specify class loader for scheduler
+ Thread.currentThread().contextClassLoader = classLoader
+
+ val discovery = DiscoveryProvider.createComposite(classLoader)
val experiments = discovery.discover(
DiscoveryRequest(
- selectors = experiments.map { DiscoverySelector.Name(it) }
+ selectors = experiments.flatMap {
+ listOf(DiscoverySelector.Name(it), DiscoverySelector.Meta("class.name", it))
+ }
)
)
@@ -91,6 +113,30 @@ public class ConsoleRunner : CliktCommand(name = "opendc-harness") {
logger.info { "Finished all experiments. Exiting." }
}
+
+ /**
+ * Create a [ClassLoader] that is used to load the
+ */
+ private fun createClassLoader(): ClassLoader {
+ val parent = ClassLoaderUtils.getDefaultClassLoader()
+
+ if (additionalClasspathEntries.isNotEmpty()) {
+ val urls = additionalClasspathEntries.flatMap { file ->
+ if (file.isDirectory) {
+ file.walk()
+ .filter { it.extension == "jar" }
+ .map { it.toURI().toURL() }
+ .toList()
+ } else {
+ listOf(file.toURI().toURL())
+ }
+ }
+
+ return URLClassLoader.newInstance(urls.toTypedArray(), parent)
+ }
+
+ return parent
+ }
}
/**
diff --git a/opendc-harness/opendc-harness-engine/src/main/kotlin/org/opendc/harness/engine/discovery/DiscoveryProvider.kt b/opendc-harness/opendc-harness-engine/src/main/kotlin/org/opendc/harness/engine/discovery/DiscoveryProvider.kt
index 204de3fc..c4b420c5 100644
--- a/opendc-harness/opendc-harness-engine/src/main/kotlin/org/opendc/harness/engine/discovery/DiscoveryProvider.kt
+++ b/opendc-harness/opendc-harness-engine/src/main/kotlin/org/opendc/harness/engine/discovery/DiscoveryProvider.kt
@@ -40,7 +40,7 @@ public interface DiscoveryProvider {
/**
* Factory method for creating a new [Discovery] instance.
*/
- public fun create(): Discovery
+ public fun create(classLoader: ClassLoader): Discovery
public companion object {
/**
@@ -58,8 +58,8 @@ public interface DiscoveryProvider {
/**
* Obtain a composite [Discovery] that combines the results of all available providers.
*/
- public fun createComposite(): Discovery {
- return CompositeDiscovery(providers)
+ public fun createComposite(classLoader: ClassLoader): Discovery {
+ return CompositeDiscovery(classLoader, providers)
}
}
}
diff --git a/opendc-harness/opendc-harness-engine/src/main/kotlin/org/opendc/harness/engine/internal/CompositeDiscovery.kt b/opendc-harness/opendc-harness-engine/src/main/kotlin/org/opendc/harness/engine/internal/CompositeDiscovery.kt
index 8ebc485a..726125a8 100644
--- a/opendc-harness/opendc-harness-engine/src/main/kotlin/org/opendc/harness/engine/internal/CompositeDiscovery.kt
+++ b/opendc-harness/opendc-harness-engine/src/main/kotlin/org/opendc/harness/engine/internal/CompositeDiscovery.kt
@@ -32,11 +32,11 @@ import org.opendc.harness.engine.discovery.DiscoveryRequest
/**
* A composite [Discovery] instance that combines the results of multiple delegate instances.
*/
-internal class CompositeDiscovery(providers: Iterable<DiscoveryProvider>) : Discovery {
+internal class CompositeDiscovery(classLoader: ClassLoader, providers: Iterable<DiscoveryProvider>) : Discovery {
/**
* The [Discovery] instances to delegate to.
*/
- private val delegates = providers.map { it.create() }
+ private val delegates = providers.map { it.create(classLoader) }
@OptIn(FlowPreview::class)
override fun discover(request: DiscoveryRequest): Flow<ExperimentDefinition> {
diff --git a/opendc-harness/opendc-harness-engine/src/main/kotlin/org/opendc/harness/engine/internal/DslDiscovery.kt b/opendc-harness/opendc-harness-engine/src/main/kotlin/org/opendc/harness/engine/internal/DslDiscovery.kt
index 20708230..3fa3fe35 100644
--- a/opendc-harness/opendc-harness-engine/src/main/kotlin/org/opendc/harness/engine/internal/DslDiscovery.kt
+++ b/opendc-harness/opendc-harness-engine/src/main/kotlin/org/opendc/harness/engine/internal/DslDiscovery.kt
@@ -36,7 +36,7 @@ import org.opendc.harness.engine.discovery.DiscoverySelector
/**
* A [Discovery] implementation that discovers [Experiment] instances on the classpath.
*/
-internal class DslDiscovery : Discovery {
+internal class DslDiscovery(private val classLoader: ClassLoader) : Discovery {
/*
* Lazily memoize the results of the classpath scan.
*/
@@ -84,6 +84,7 @@ internal class DslDiscovery : Discovery {
*/
private fun scan(): ScanResult {
return ClassGraph()
+ .addClassLoader(classLoader)
.enableClassInfo()
.enableExternalClasses()
.ignoreClassVisibility()
diff --git a/opendc-harness/opendc-harness-engine/src/main/kotlin/org/opendc/harness/engine/internal/DslDiscoveryProvider.kt b/opendc-harness/opendc-harness-engine/src/main/kotlin/org/opendc/harness/engine/internal/DslDiscoveryProvider.kt
index 987bc889..6a9bd599 100644
--- a/opendc-harness/opendc-harness-engine/src/main/kotlin/org/opendc/harness/engine/internal/DslDiscoveryProvider.kt
+++ b/opendc-harness/opendc-harness-engine/src/main/kotlin/org/opendc/harness/engine/internal/DslDiscoveryProvider.kt
@@ -32,5 +32,5 @@ import org.opendc.harness.engine.discovery.DiscoveryProvider
public class DslDiscoveryProvider : DiscoveryProvider {
override val id: String = "dsl"
- override fun create(): Discovery = DslDiscovery()
+ override fun create(classLoader: ClassLoader): Discovery = DslDiscovery(classLoader)
}
diff --git a/opendc-harness/opendc-harness-engine/src/test/kotlin/org/opendc/harness/EngineTest.kt b/opendc-harness/opendc-harness-engine/src/test/kotlin/org/opendc/harness/EngineTest.kt
index 6f2989db..6955f7c5 100644
--- a/opendc-harness/opendc-harness-engine/src/test/kotlin/org/opendc/harness/EngineTest.kt
+++ b/opendc-harness/opendc-harness-engine/src/test/kotlin/org/opendc/harness/EngineTest.kt
@@ -50,7 +50,7 @@ internal class EngineTest {
@Test
fun discovery() {
runBlocking {
- val discovery = DiscoveryProvider.findById("dsl")?.create()
+ val discovery = DiscoveryProvider.findById("dsl")?.create(Thread.currentThread().contextClassLoader)
assertNotNull(discovery)
val res = mutableListOf<ExperimentDefinition>()
discovery?.discover(DiscoveryRequest())?.toList(res)
diff --git a/opendc-harness/opendc-harness-junit5/src/main/kotlin/org/opendc/harness/runner/junit5/OpenDCTestEngine.kt b/opendc-harness/opendc-harness-junit5/src/main/kotlin/org/opendc/harness/runner/junit5/OpenDCTestEngine.kt
index ab7367b8..7fc97f6d 100644
--- a/opendc-harness/opendc-harness-junit5/src/main/kotlin/org/opendc/harness/runner/junit5/OpenDCTestEngine.kt
+++ b/opendc-harness/opendc-harness-junit5/src/main/kotlin/org/opendc/harness/runner/junit5/OpenDCTestEngine.kt
@@ -25,6 +25,7 @@ package org.opendc.harness.runner.junit5
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.emptyFlow
import mu.KotlinLogging
+import org.junit.platform.commons.util.ClassLoaderUtils
import org.junit.platform.engine.*
import org.junit.platform.engine.discovery.ClassNameFilter
import org.junit.platform.engine.discovery.ClassSelector
@@ -63,7 +64,7 @@ public class OpenDCTestEngine : TestEngine {
val classNames = request.getSelectorsByType(ClassSelector::class.java).map { DiscoverySelector.Meta("class.name", it.className) }
val classNameFilters = request.getFiltersByType(ClassNameFilter::class.java).map { DiscoveryFilter.Name(it.toPredicate()) }
- val discovery = DiscoveryProvider.createComposite()
+ val discovery = DiscoveryProvider.createComposite(ClassLoaderUtils.getDefaultClassLoader())
val definitions = discovery.discover(DiscoveryRequest(classNames, classNameFilters))
return ExperimentEngineDescriptor(uniqueId, definitions)