From fd7f08e73ee87cf9e1a3d6acab93b11079522302 Mon Sep 17 00:00:00 2001 From: Anton Keks Date: Sun, 16 Feb 2025 21:46:19 +0200 Subject: [PATCH] core: TSID.deterministic introduced for using in test data generation --- CHANGELOG.md | 2 +- core/src/TSID.kt | 9 ++++++--- core/test/TSIDTest.kt | 12 ++++++++++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9cd09c94..fe75e380 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Unreleased * jdbc: add helpful details to Postgres exception "no hstore extension installed" -* core: TSID now can use a preconfigured random seed using TSID_SEED, good for test data +* core: TSID.deterministic introduced for using in test data generation * json: TSGenerator updates * wraps records with enum keys into Partial to avoid TS wanting all the keys to be present * outputs provided custom types as separate types and references them diff --git a/core/src/TSID.kt b/core/src/TSID.kt index dd1c65c9..e8716b24 100644 --- a/core/src/TSID.kt +++ b/core/src/TSID.kt @@ -4,6 +4,7 @@ import java.lang.System.currentTimeMillis import java.security.SecureRandom import java.time.Instant import java.util.concurrent.atomic.AtomicInteger +import java.util.concurrent.atomic.AtomicLong /** * Time-Sorted unique ID, a more compact and DB index-friendly alternative to UUID. @@ -14,11 +15,13 @@ import java.util.concurrent.atomic.AtomicInteger const val RANDOM_BITS = 22 const val RANDOM_MASK = 0x003fffff val EPOCH = Instant.parse(Config.optional("TSID_EPOCH", "2022-10-21T03:45:00.000Z")).toEpochMilli() - val random = Config.optional("TSID_SEED")?.toByteArray()?.let { SecureRandom(it) } ?: SecureRandom() - val counter = AtomicInteger() - @Volatile var lastTime = 0L + private var random = SecureRandom() + private val counter = AtomicInteger() + @Volatile private var lastTime = 0L + var deterministic: AtomicLong? = null fun generateValue(): Long { + deterministic?.let { return it.incrementAndGet() } val time = (currentTimeMillis() - EPOCH) shl RANDOM_BITS if (time != lastTime) { counter.set(random.nextInt()) diff --git a/core/test/TSIDTest.kt b/core/test/TSIDTest.kt index a7e66379..504876bb 100644 --- a/core/test/TSIDTest.kt +++ b/core/test/TSIDTest.kt @@ -1,10 +1,12 @@ package klite +import ch.tutteli.atrium.api.fluent.en_GB.toBeGreaterThan import ch.tutteli.atrium.api.fluent.en_GB.toBeLessThanOrEqualTo import ch.tutteli.atrium.api.fluent.en_GB.toEqual import ch.tutteli.atrium.api.verbs.expect import org.junit.jupiter.api.Test import java.lang.System.currentTimeMillis +import java.util.concurrent.atomic.AtomicLong typealias Id = TSID @@ -30,4 +32,14 @@ class TSIDTest { for (i in 1..1000000) ids.add(Id()) expect(ids.size).toEqual(1000000) } + + @Test + fun deterministic() { + TSID.deterministic = AtomicLong(123123123) + expect(TSID().toString()).toEqual("21ayes") + expect(TSID().toString()).toEqual("21ayet") + expect(TSID().toString()).toEqual("21ayeu") + TSID.deterministic = null + expect(TSID().toString().length).toBeGreaterThan(8) + } }