Skip to content

Commit

Permalink
core: TSID.deterministic introduced for using in test data generation
Browse files Browse the repository at this point in the history
  • Loading branch information
angryziber committed Feb 16, 2025
1 parent d8c6582 commit fd7f08e
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 4 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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<T> to avoid TS wanting all the keys to be present
* outputs provided custom types as separate types and references them
Expand Down
9 changes: 6 additions & 3 deletions core/src/TSID.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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())
Expand Down
12 changes: 12 additions & 0 deletions core/test/TSIDTest.kt
Original file line number Diff line number Diff line change
@@ -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<Any>

Expand All @@ -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<Any>().toString()).toEqual("21ayes")
expect(TSID<Any>().toString()).toEqual("21ayet")
expect(TSID<Any>().toString()).toEqual("21ayeu")
TSID.deterministic = null
expect(TSID<Any>().toString().length).toBeGreaterThan(8)
}
}

0 comments on commit fd7f08e

Please sign in to comment.