diff options
| author | Fabian Mastenbroek <mail.fabianm@gmail.com> | 2021-05-04 20:31:48 +0200 |
|---|---|---|
| committer | Fabian Mastenbroek <mail.fabianm@gmail.com> | 2021-05-05 10:03:18 +0200 |
| commit | 6466d5e1b8da4582434f02dff2ab56e8f736ef85 (patch) | |
| tree | e8c8e6b96c7abdd80fa0a3198da5776488cd06fe /opendc-harness/opendc-harness-cli/src/main | |
| parent | 4a8b32d288ba3ee986ecef7933fa77554d34e762 (diff) | |
harness: Extend Harness CLI with classpath options
This change adds support for appending libraries to the classpath when
searching for experiments to run using the OpenDC Harness command line
interface.
Diffstat (limited to 'opendc-harness/opendc-harness-cli/src/main')
| -rw-r--r-- | opendc-harness/opendc-harness-cli/src/main/kotlin/org/opendc/harness/runner/cli/ConsoleRunner.kt | 56 |
1 files changed, 51 insertions, 5 deletions
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 + } } /** |
