diff --git a/core/src/main/kotlin/com/r3corda/core/utilities/TimeWindow.kt b/core/src/main/kotlin/com/r3corda/core/utilities/TimeWindow.kt new file mode 100644 index 0000000000..8827553054 --- /dev/null +++ b/core/src/main/kotlin/com/r3corda/core/utilities/TimeWindow.kt @@ -0,0 +1,12 @@ +package com.r3corda.core.utilities + +import java.time.Duration +import java.time.Instant + +/** + * A class representing a window in time from a particular instant, lasting a specified duration. + */ +data class TimeWindow(val start: Instant, val duration: Duration) { + val end: Instant + get() = start + duration +} \ No newline at end of file diff --git a/node/src/main/kotlin/com/r3corda/node/internal/testing/MockNode.kt b/node/src/main/kotlin/com/r3corda/node/internal/testing/MockNode.kt index 3ca7678788..ea7e7fb279 100644 --- a/node/src/main/kotlin/com/r3corda/node/internal/testing/MockNode.kt +++ b/node/src/main/kotlin/com/r3corda/node/internal/testing/MockNode.kt @@ -12,7 +12,6 @@ import com.r3corda.core.node.services.ServiceType import com.r3corda.core.node.services.testing.MockIdentityService import com.r3corda.core.utilities.loggerFor import com.r3corda.node.internal.AbstractNode -import com.r3corda.node.serialization.NodeClock import com.r3corda.node.services.config.NodeConfiguration import com.r3corda.node.services.network.InMemoryMessagingNetwork import com.r3corda.node.services.network.NetworkMapService @@ -67,7 +66,7 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false, } open class MockNode(dir: Path, config: NodeConfiguration, val mockNet: MockNetwork, networkMapAddr: NodeInfo?, - advertisedServices: Set, val id: Int, val keyPair: KeyPair?) : AbstractNode(dir, config, networkMapAddr, advertisedServices, NodeClock()) { + advertisedServices: Set, val id: Int, val keyPair: KeyPair?) : AbstractNode(dir, config, networkMapAddr, advertisedServices, TestClock()) { override val log: Logger = loggerFor() override val serverThread: AffinityExecutor = if (mockNet.threadPerNode) diff --git a/node/src/main/kotlin/com/r3corda/node/internal/testing/TestClock.kt b/node/src/main/kotlin/com/r3corda/node/internal/testing/TestClock.kt index 68fcdb04ff..009c4f0d3c 100644 --- a/node/src/main/kotlin/com/r3corda/node/internal/testing/TestClock.kt +++ b/node/src/main/kotlin/com/r3corda/node/internal/testing/TestClock.kt @@ -1,5 +1,8 @@ package com.r3corda.node.internal.testing +import com.r3corda.core.serialization.SerializeAsToken +import com.r3corda.core.serialization.SerializeAsTokenContext +import com.r3corda.core.serialization.SingletonSerializationToken import com.r3corda.node.utilities.MutableClock import java.time.Clock import java.time.Duration @@ -12,24 +15,34 @@ import javax.annotation.concurrent.ThreadSafe * A [Clock] that can have the time advanced for use in testing */ @ThreadSafe -class TestClock(private var delegateClock: Clock = Clock.systemUTC()) : MutableClock() { +class TestClock(private var delegateClock: Clock = Clock.systemUTC()) : MutableClock(), SerializeAsToken { - @Synchronized fun advanceBy(duration: Duration): Boolean { - if (!duration.isNegative) { - // It's ok to increment - delegateClock = offset(delegateClock, duration) - notifyMutationObservers() - return true - } - return false + private val token = SingletonSerializationToken(this) + + override fun toToken(context: SerializeAsTokenContext) = SingletonSerializationToken.registerWithContext(token, this, context) + + /** + * Advance this [Clock] by the specified [Duration] for testing purposes. + */ + @Synchronized fun advanceBy(duration: Duration) { + delegateClock = offset(delegateClock, duration) + notifyMutationObservers() } + /** + * Move this [Clock] to the specified [Instant] for testing purposes. + * + * This will only be approximate due to the time ticking away, but will be some time shortly after the requested [Instant]. + */ + @Synchronized fun setTo(newInstant: Instant) = advanceBy(Duration.between(instant(), newInstant)) + @Synchronized override fun instant(): Instant { return delegateClock.instant() } - @Synchronized override fun withZone(zone: ZoneId): Clock { - return TestClock(delegateClock.withZone(zone)) + @Deprecated("Do not use this. Instead seek to use ZonedDateTime methods.", level = DeprecationLevel.ERROR) + override fun withZone(zone: ZoneId): Clock { + throw UnsupportedOperationException("Tokenized clock does not support withZone()") } @Synchronized override fun getZone(): ZoneId {