From 013eb33d7cb73fb55d3d41f80a5613b7e18c0cf1 Mon Sep 17 00:00:00 2001 From: szymonsztuka Date: Fri, 18 May 2018 16:39:55 +0100 Subject: [PATCH] ENT-1574 Progress tracker distinguishes steps which were not processed (#3173) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Progress Tracker doesn't mark as "green tick" a step which hasn't been set in the flow. Steps behind the current step, which were not processed ('an optional step') are now marked distingishly as green crossed sign for shell and as minus sign for ssh.
 * Finality Flow sets the current step to NOTARISING only if the actual notarization is performed. --- .../net/corda/core/flows/FinalityFlow.kt | 2 +- .../kotlin/net/corda/core/internal/Emoji.kt | 3 ++ .../corda/core/utilities/ProgressTracker.kt | 9 ++++- .../core/utilities/ProgressTrackerTest.kt | 35 +++++++++++++++++++ .../shell/utlities/ANSIProgressRenderer.kt | 7 +++- 5 files changed, 53 insertions(+), 3 deletions(-) diff --git a/core/src/main/kotlin/net/corda/core/flows/FinalityFlow.kt b/core/src/main/kotlin/net/corda/core/flows/FinalityFlow.kt index a08654acb9..a958ef6a91 100644 --- a/core/src/main/kotlin/net/corda/core/flows/FinalityFlow.kt +++ b/core/src/main/kotlin/net/corda/core/flows/FinalityFlow.kt @@ -52,7 +52,6 @@ class FinalityFlow(val transaction: SignedTransaction, // Lookup the resolved transactions and use them to map each signed transaction to the list of participants. // Then send to the notary if needed, record locally and distribute. val parties = getPartiesToSend(verifyTx()) - progressTracker.currentStep = NOTARISING val notarised = notariseAndRecord() // Each transaction has its own set of recipients, but extra recipients get them all. @@ -70,6 +69,7 @@ class FinalityFlow(val transaction: SignedTransaction, @Suspendable private fun notariseAndRecord(): SignedTransaction { val notarised = if (needsNotarySignature(transaction)) { + progressTracker.currentStep = NOTARISING val notarySignatures = subFlow(NotaryFlow.Client(transaction)) transaction + notarySignatures } else { diff --git a/core/src/main/kotlin/net/corda/core/internal/Emoji.kt b/core/src/main/kotlin/net/corda/core/internal/Emoji.kt index 27b780ece0..4d7d8b9dcd 100644 --- a/core/src/main/kotlin/net/corda/core/internal/Emoji.kt +++ b/core/src/main/kotlin/net/corda/core/internal/Emoji.kt @@ -49,6 +49,8 @@ object Emoji { val CODE_DEVELOPER: String = codePointsString(0x1F469, 0x200D, 0x1F4BB) @JvmStatic val CODE_WARNING_SIGN: String = codePointsString(0x26A0, 0xFE0F) + @JvmStatic + val CROSS_MARK_BUTTON: String = codePointsString(0x274E) /** * When non-null, toString() methods are allowed to use emoji in the output as we're going to render them to a @@ -76,6 +78,7 @@ object Emoji { val rightArrow: String get() = if (emojiMode.get() != null) "$CODE_RIGHT_ARROW " else "▶︎" val skullAndCrossbones: String get() = if (emojiMode.get() != null) "$CODE_SKULL_AND_CROSSBONES " else "☂" val noEntry: String get() = if (emojiMode.get() != null) "$CODE_NO_ENTRY " else "✘" + val notRun: String get() = if (emojiMode.get() != null) "$CROSS_MARK_BUTTON " else "-" inline fun renderIfSupported(body: () -> T): T { if (hasEmojiTerminal) diff --git a/core/src/main/kotlin/net/corda/core/utilities/ProgressTracker.kt b/core/src/main/kotlin/net/corda/core/utilities/ProgressTracker.kt index 4fa4797a29..f646f0569a 100644 --- a/core/src/main/kotlin/net/corda/core/utilities/ProgressTracker.kt +++ b/core/src/main/kotlin/net/corda/core/utilities/ProgressTracker.kt @@ -148,8 +148,15 @@ class ProgressTracker(vararg steps: Step) { val currentStepRecursive: Step get() = getChildProgressTracker(currentStep)?.currentStepRecursive ?: currentStep + /** Returns the current step, descending into children to find the deepest started step we are up to. */ + private val currentStartedStepRecursive: Step + get() { + val step = getChildProgressTracker(currentStep)?.currentStartedStepRecursive ?: currentStep + return if (step == UNSTARTED) currentStep else step + } + private fun currentStepRecursiveWithoutUnstarted(): Step { - val stepRecursive = getChildProgressTracker(currentStep)?.currentStepRecursive + val stepRecursive = getChildProgressTracker(currentStep)?.currentStartedStepRecursive return if (stepRecursive == null || stepRecursive == UNSTARTED) currentStep else stepRecursive } diff --git a/core/src/test/kotlin/net/corda/core/utilities/ProgressTrackerTest.kt b/core/src/test/kotlin/net/corda/core/utilities/ProgressTrackerTest.kt index 4e15f122d9..7ee985e05b 100644 --- a/core/src/test/kotlin/net/corda/core/utilities/ProgressTrackerTest.kt +++ b/core/src/test/kotlin/net/corda/core/utilities/ProgressTrackerTest.kt @@ -131,6 +131,41 @@ class ProgressTrackerTest { assertThat(stepsTreeNotification).isEmpty() } + @Test + fun `steps tree index counts two levels of children steps`() { + pt.setChildProgressTracker(SimpleSteps.FOUR, pt2) + pt2.setChildProgressTracker(ChildSteps.SEA, pt3) + val allSteps = pt.allSteps + + // Capture notifications. + val stepsIndexNotifications = LinkedList() + pt.stepsTreeIndexChanges.subscribe { + stepsIndexNotifications += it + } + val stepsTreeNotification = LinkedList>>() + pt.stepsTreeChanges.subscribe { + stepsTreeNotification += it + } + + fun assertCurrentStepsTree(index: Int, step: ProgressTracker.Step) { + assertEquals(index, pt.stepsTreeIndex) + assertEquals(step, allSteps[pt.stepsTreeIndex].second) + } + + pt.currentStep = SimpleSteps.ONE + assertCurrentStepsTree(0, SimpleSteps.ONE) + + pt.currentStep = SimpleSteps.FOUR + assertCurrentStepsTree(3, SimpleSteps.FOUR) + + pt2.currentStep = ChildSteps.SEA + assertCurrentStepsTree(6, ChildSteps.SEA) + + // Assert no structure changes and proper steps propagation. + assertThat(stepsIndexNotifications).containsExactlyElementsOf(listOf(0, 3, 6)) + assertThat(stepsTreeNotification).isEmpty() + } + @Test fun `structure changes are pushed down when progress trackers are added`() { pt.setChildProgressTracker(SimpleSteps.TWO, pt2) diff --git a/tools/shell/src/main/kotlin/net/corda/tools/shell/utlities/ANSIProgressRenderer.kt b/tools/shell/src/main/kotlin/net/corda/tools/shell/utlities/ANSIProgressRenderer.kt index 4848ff5d47..aef5b4ca70 100644 --- a/tools/shell/src/main/kotlin/net/corda/tools/shell/utlities/ANSIProgressRenderer.kt +++ b/tools/shell/src/main/kotlin/net/corda/tools/shell/utlities/ANSIProgressRenderer.kt @@ -23,6 +23,7 @@ abstract class ANSIProgressRenderer { protected var checkEmoji = false protected var treeIndex: Int = 0 + protected var treeIndexProcessed: MutableSet = mutableSetOf() protected var tree: List> = listOf() private var installedYet = false @@ -55,6 +56,7 @@ abstract class ANSIProgressRenderer { subscriptionIndex?.unsubscribe() subscriptionTree?.unsubscribe() treeIndex = 0 + treeIndexProcessed.clear() tree = listOf() if (!installedYet) { @@ -70,8 +72,10 @@ abstract class ANSIProgressRenderer { flowProgressHandle?.apply { stepsTreeIndexFeed?.apply { treeIndex = snapshot + treeIndexProcessed.add(snapshot) subscriptionIndex = updates.subscribe({ treeIndex = it + treeIndexProcessed.add(it) draw(true) }, { done(it) }, { done(null) }) } @@ -144,7 +148,8 @@ abstract class ANSIProgressRenderer { for ((index, step) in tree.withIndex()) { val marker = when { - index < treeIndex -> "${Emoji.greenTick} " + treeIndexProcessed.contains(index) -> " ${Emoji.greenTick} " + index < treeIndex -> " ${Emoji.notRun} " treeIndex == tree.lastIndex -> "${Emoji.greenTick} " index == treeIndex -> "${Emoji.rightArrow} " error -> "${Emoji.noEntry} "