diff --git a/CHANGELOG.md b/CHANGELOG.md index 56e94986..f3487a8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,11 @@ Dropping a requirement of a major version of a dependency is a new contract. ## [Unreleased] [Unreleased]: https://github.com/atlassian/virtual-users/compare/release-3.13.2...master +### Added +- Allow specifying Scenario class without having it in classpath. Resolve [JPERF-999]. + +[JPERF-999]: https://ecosystem.atlassian.net/browse/JPERF-999 + ## [3.13.2] - 2022-04-08 [3.13.2]: https://github.com/atlassian/virtual-users/compare/release-3.13.1...release-3.13.2 diff --git a/src/main/kotlin/com/atlassian/performance/tools/virtualusers/LoadTest.kt b/src/main/kotlin/com/atlassian/performance/tools/virtualusers/LoadTest.kt index edca2a34..c30498be 100644 --- a/src/main/kotlin/com/atlassian/performance/tools/virtualusers/LoadTest.kt +++ b/src/main/kotlin/com/atlassian/performance/tools/virtualusers/LoadTest.kt @@ -54,7 +54,7 @@ internal class LoadTest( private val random = SeededRandom(behavior.seed) private val diagnosisPatience = DiagnosisPatience(Duration.ofSeconds(5)) private val diagnosisLimit = DiagnosisLimit(behavior.diagnosticsLimit) - private val scenario = behavior.scenario.getConstructor().newInstance() as Scenario + private val scenario = Class.forName(behavior.scenarioClass).getConstructor().newInstance() as Scenario private val browser = behavior.browser.getConstructor().newInstance() as Browser private val userGenerator = options.behavior.userGenerator.getConstructor().newInstance() as UserGenerator diff --git a/src/main/kotlin/com/atlassian/performance/tools/virtualusers/api/VirtualUserOptions.kt b/src/main/kotlin/com/atlassian/performance/tools/virtualusers/api/VirtualUserOptions.kt index cf8eb210..6d0c2a5c 100644 --- a/src/main/kotlin/com/atlassian/performance/tools/virtualusers/api/VirtualUserOptions.kt +++ b/src/main/kotlin/com/atlassian/performance/tools/virtualusers/api/VirtualUserOptions.kt @@ -50,9 +50,10 @@ class VirtualUserOptions( val virtualUserLoad: VirtualUserLoad get() = behavior.load + @Suppress("UNCHECKED_CAST") @Deprecated(deprecatedGetterMessage) val scenario: Class - get() = behavior.scenario + get() = Class.forName(behavior.scenarioClass) as Class @Deprecated(deprecatedGetterMessage) val seed: Long @@ -341,7 +342,7 @@ class VirtualUserOptions( rampParameter to behavior.load.ramp, flatParameter to behavior.load.flat, maxOverallLoadParameter to behavior.load.maxOverallLoad.let { "${it.change}/${it.time}" }, - scenarioParameter to behavior.scenario.canonicalName, + scenarioParameter to behavior.scenarioClass, diagnosticsLimitParameter to behavior.diagnosticsLimit, seedParameter to behavior.seed, browserParameter to behavior.browser.name, @@ -398,6 +399,7 @@ class VirtualUserOptions( .getOptionValue(maxOverallLoadParameter) ?.let { it.split('/') } ?.let { (actions, time) -> TemporalRate(actions.toDouble(), Duration.parse(time)) } + val scenario = commandLine.getOptionValue(scenarioParameter) val diagnosticsLimit = commandLine.getOptionValue(diagnosticsLimitParameter).toInt() val seed = commandLine.getOptionValue(seedParameter).toLong() val skipSetup = commandLine.hasOption(skipSetupParameter) @@ -409,7 +411,7 @@ class VirtualUserOptions( userName = adminLogin, password = adminPassword ), - behavior = VirtualUserBehavior.Builder(getScenario(commandLine)) + behavior = VirtualUserBehavior.Builder(scenario) .let { if (results != null) it.results(results) else it } .diagnosticsLimit(diagnosticsLimit) .seed(seed) @@ -430,13 +432,6 @@ class VirtualUserOptions( ) } - private fun getScenario(commandLine: CommandLine): Class { - val scenario = commandLine.getOptionValue(scenarioParameter) - val scenarioClass = Class.forName(scenario) - val scenarioConstructor = scenarioClass.getConstructor() - return (scenarioConstructor.newInstance() as Scenario)::class.java - } - private fun getBrowser(commandLine: CommandLine): Class { return if (commandLine.hasOption(browserParameter)) { val browser = commandLine.getOptionValue(browserParameter) diff --git a/src/main/kotlin/com/atlassian/performance/tools/virtualusers/api/config/VirtualUserBehavior.kt b/src/main/kotlin/com/atlassian/performance/tools/virtualusers/api/config/VirtualUserBehavior.kt index 21ff064c..0ebb4c0d 100644 --- a/src/main/kotlin/com/atlassian/performance/tools/virtualusers/api/config/VirtualUserBehavior.kt +++ b/src/main/kotlin/com/atlassian/performance/tools/virtualusers/api/config/VirtualUserBehavior.kt @@ -23,7 +23,7 @@ class VirtualUserBehavior private constructor( ) internal val help: Boolean, internal val results: Path, - internal val scenario: Class, + internal val scenarioClass: String, val load: VirtualUserLoad, val maxOverhead: Duration, internal val seed: Long, @@ -48,7 +48,7 @@ class VirtualUserBehavior private constructor( ) : this( help = help, results = Paths.get("."), - scenario = scenario, + scenarioClass = scenario.canonicalName, load = load, maxOverhead = Duration.ofMinutes(5), seed = seed, @@ -111,7 +111,7 @@ class VirtualUserBehavior private constructor( ): VirtualUserBehavior = Builder(this).load(load).build() class Builder( - private var scenario: Class + private var scenarioClass: String ) { private var results: Path = Paths.get(".") private var load: VirtualUserLoad = VirtualUserLoad.Builder().build() @@ -129,7 +129,7 @@ class VirtualUserBehavior private constructor( */ fun results(results: Path) = apply { this.results = results } - fun scenario(scenario: Class) = apply { this.scenario = scenario } + fun scenario(scenario: Class) = apply { this.scenarioClass = scenario.canonicalName } fun load(load: VirtualUserLoad) = apply { this.load = load } fun maxOverhead(maxOverhead: Duration) = apply { this.maxOverhead = maxOverhead } fun seed(seed: Long) = apply { this.seed = seed } @@ -149,14 +149,20 @@ class VirtualUserBehavior private constructor( fun userGenerator(userGenerator: Class) = apply { this.userGenerator = userGenerator } + constructor( + scenario: Class + ) : this( + scenarioClass = scenario.canonicalName + ) + constructor( behavior: VirtualUserBehavior ) : this( - scenario = behavior.scenario + scenarioClass = behavior.scenarioClass ) { load = behavior.load maxOverhead = behavior.maxOverhead - scenario = behavior.scenario + scenarioClass = behavior.scenarioClass diagnosticsLimit = behavior.diagnosticsLimit browser = behavior.browser logging = behavior.logging @@ -168,7 +174,7 @@ class VirtualUserBehavior private constructor( fun build(): VirtualUserBehavior = VirtualUserBehavior( help = false, results = results, - scenario = scenario, + scenarioClass = scenarioClass, load = load, maxOverhead = maxOverhead, seed = seed,