From af821af7bd422199844d7c1832628e3ca017a0b2 Mon Sep 17 00:00:00 2001 From: Przemek Bruski Date: Tue, 28 Jan 2020 01:57:09 +0100 Subject: [PATCH 1/2] smarter action shuffler --- .../jirasoftwareactions/ActionShuffler.kt | 85 +++++++++++++++++++ .../api/JiraSoftwareScenario.kt | 13 +-- 2 files changed, 92 insertions(+), 6 deletions(-) create mode 100644 src/main/kotlin/com/atlassian/performance/tools/jirasoftwareactions/ActionShuffler.kt diff --git a/src/main/kotlin/com/atlassian/performance/tools/jirasoftwareactions/ActionShuffler.kt b/src/main/kotlin/com/atlassian/performance/tools/jirasoftwareactions/ActionShuffler.kt new file mode 100644 index 0000000..88a499a --- /dev/null +++ b/src/main/kotlin/com/atlassian/performance/tools/jirasoftwareactions/ActionShuffler.kt @@ -0,0 +1,85 @@ +package com.atlassian.performance.tools.jirasoftwareactions + +import com.atlassian.performance.tools.jiraactions.api.SeededRandom +import com.atlassian.performance.tools.jiraactions.api.WebJira +import com.atlassian.performance.tools.jiraactions.api.action.Action +import com.atlassian.performance.tools.jiraactions.api.action.BrowseProjectsAction +import com.atlassian.performance.tools.jiraactions.api.action.CreateIssueAction +import com.atlassian.performance.tools.jiraactions.api.action.SearchJqlAction +import com.atlassian.performance.tools.jiraactions.api.measure.ActionMeter +import com.atlassian.performance.tools.jiraactions.api.memories.IssueKeyMemory +import com.atlassian.performance.tools.jiraactions.api.memories.JqlMemory +import com.atlassian.performance.tools.jiraactions.api.page.IssuePage +import com.atlassian.performance.tools.jiraactions.api.scenario.addMultiple +import com.atlassian.performance.tools.jirasoftwareactions.api.actions.BrowseBoardsAction +import kotlin.reflect.KClass + +class ActionShuffler { + private class FixedJqlMemory(val jql: String) : JqlMemory { + override fun observe(issuePage: IssuePage) { + throw UnsupportedOperationException() + } + + override fun recall(): String? { + return jql + } + + override fun remember(memories: Collection) { + throw UnsupportedOperationException() + } + } + + companion object { + fun createRandomisedScenario(seededRandom: SeededRandom, actionProportions: Map, + issueKeyMemoriser: Action): List { + //createIssue needs a project - browserProject goes first + //viewIssue needs to have issues - createIssues goes second + //viewBoards needs to know about boards + return createRandomisedScenario(seededRandom, actionProportions, issueKeyMemoriser, + BrowseProjectsAction::class, CreateIssueAction::class, BrowseBoardsAction::class) + } + + fun findIssueKeysWithJql(jira: WebJira, meter: ActionMeter, issueKeyMemory: IssueKeyMemory): SearchJqlAction { + return SearchJqlAction( + jira = jira, + meter = meter, + jqlMemory = FixedJqlMemory("project is not EMPTY"), + issueKeyMemory = issueKeyMemory + ) + } + + private fun createRandomisedScenario(seededRandom: SeededRandom, actionProportions: Map, + issueKeyDiscoverer: Action, vararg actions: KClass): List { + val initialActions = findActions(actionProportions, *actions) + + val scenario: MutableList = mutableListOf() + + val actionProportionsToRandomise = deductActionCount(actionProportions, initialActions) + actionProportionsToRandomise.entries.forEach { scenario.addMultiple(element = it.key, repeats = it.value) } + scenario.shuffle(seededRandom.random) + + //viewIssue needs to remember isssues - issueKeyDiscoverer goes after all actions + scenario.addAll(0, initialActions.plus(issueKeyDiscoverer)) + return scenario + } + + private fun findActions(actionProportions: Map, vararg actions: KClass): List { + return actions + .mapNotNull { findAction(actionProportions, it) } + } + + private fun deductActionCount(actionProportions: Map, actions: List): MutableMap { + val modifiedActionProportions = actionProportions.toMutableMap() + + actions.forEach { + val originalCount = actionProportions.getValue(it) + modifiedActionProportions[it] = originalCount-1 + } + return modifiedActionProportions + } + + private fun findAction(actionProportions: Map, kClass: KClass): T? { + return actionProportions.keys.find { kClass.isInstance(it) } as T? + } + } +} diff --git a/src/main/kotlin/com/atlassian/performance/tools/jirasoftwareactions/api/JiraSoftwareScenario.kt b/src/main/kotlin/com/atlassian/performance/tools/jirasoftwareactions/api/JiraSoftwareScenario.kt index ac4b7cd..30ebc52 100644 --- a/src/main/kotlin/com/atlassian/performance/tools/jirasoftwareactions/api/JiraSoftwareScenario.kt +++ b/src/main/kotlin/com/atlassian/performance/tools/jirasoftwareactions/api/JiraSoftwareScenario.kt @@ -9,7 +9,7 @@ import com.atlassian.performance.tools.jiraactions.api.memories.adaptive.Adaptiv import com.atlassian.performance.tools.jiraactions.api.memories.adaptive.AdaptiveJqlMemory import com.atlassian.performance.tools.jiraactions.api.memories.adaptive.AdaptiveProjectMemory import com.atlassian.performance.tools.jiraactions.api.scenario.Scenario -import com.atlassian.performance.tools.jiraactions.api.scenario.addMultiple +import com.atlassian.performance.tools.jirasoftwareactions.ActionShuffler import com.atlassian.performance.tools.jirasoftwareactions.api.actions.BrowseBoardsAction import com.atlassian.performance.tools.jirasoftwareactions.api.actions.ViewBacklogAction import com.atlassian.performance.tools.jirasoftwareactions.api.actions.ViewBoardAction @@ -45,6 +45,8 @@ class JiraSoftwareScenario : Scenario { jqlMemory = jqlMemory, issueKeyMemory = issueKeyMemory ) + val findInitialIssues = ActionShuffler.findIssueKeysWithJql(jira, meter, issueKeyMemory) + val viewIssue = ViewIssueAction( jira = jira, meter = meter, @@ -97,7 +99,7 @@ class JiraSoftwareScenario : Scenario { ) { it.issuesInBacklog != 0 } val actionProportions = mapOf( createIssue to 5, - searchWithJql to 20, + searchWithJql to 19, viewIssue to 55, projectSummary to 5, viewDashboard to 10, @@ -108,8 +110,7 @@ class JiraSoftwareScenario : Scenario { viewBacklog to 10, browseBoards to 2 ) - actionProportions.entries.forEach { scenario.addMultiple(element = it.key, repeats = it.value) } - scenario.shuffle(seededRandom.random) - return scenario + + return ActionShuffler.createRandomisedScenario(seededRandom, actionProportions, findInitialIssues) } -} \ No newline at end of file +} From ac7eacfa2b599137b61a251767c7f16ff2d4fb0a Mon Sep 17 00:00:00 2001 From: Przemek Bruski Date: Wed, 4 Mar 2020 16:22:46 +0100 Subject: [PATCH 2/2] made action internal --- .../tools/jirasoftwareactions/ActionShuffler.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/com/atlassian/performance/tools/jirasoftwareactions/ActionShuffler.kt b/src/main/kotlin/com/atlassian/performance/tools/jirasoftwareactions/ActionShuffler.kt index 88a499a..27dda87 100644 --- a/src/main/kotlin/com/atlassian/performance/tools/jirasoftwareactions/ActionShuffler.kt +++ b/src/main/kotlin/com/atlassian/performance/tools/jirasoftwareactions/ActionShuffler.kt @@ -12,9 +12,10 @@ import com.atlassian.performance.tools.jiraactions.api.memories.JqlMemory import com.atlassian.performance.tools.jiraactions.api.page.IssuePage import com.atlassian.performance.tools.jiraactions.api.scenario.addMultiple import com.atlassian.performance.tools.jirasoftwareactions.api.actions.BrowseBoardsAction +import java.util.function.Predicate import kotlin.reflect.KClass -class ActionShuffler { +internal class ActionShuffler { private class FixedJqlMemory(val jql: String) : JqlMemory { override fun observe(issuePage: IssuePage) { throw UnsupportedOperationException() @@ -27,6 +28,10 @@ class ActionShuffler { override fun remember(memories: Collection) { throw UnsupportedOperationException() } + + override fun recallByTag(filter: Predicate): String? { + throw UnsupportedOperationException() + } } companion object {