From f80eb4029c9bcb6195c5a725b687d98b68f2b168 Mon Sep 17 00:00:00 2001 From: Fabio Lima Date: Sat, 9 Jul 2022 14:43:36 -0300 Subject: [PATCH] Add support for RandomGenerator in Java 17 #19 --- CHANGELOG.md | 7 +- README.md | 34 ++- .../com/github/f4b6a3/ulid/UlidFactory.java | 256 +++++++++++++++--- .../f4b6a3/ulid/UlidFactoryDefaultfTest.java | 195 ++++++++++++- .../f4b6a3/ulid/UlidFactoryMonotonicTest.java | 72 ++++- .../github/f4b6a3/ulid/UlidFactoryTest.java | 2 - .../java/com/github/f4b6a3/ulid/UlidTest.java | 2 - .../ulid/{ => uniq}/UniquenessTest.java | 6 +- 8 files changed, 508 insertions(+), 66 deletions(-) rename src/test/java/com/github/f4b6a3/ulid/{ => uniq}/UniquenessTest.java (95%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 984fad2..79ac9d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ All notable changes to this project will be documented in this file. Nothing unreleased. +## [5.0.0] - 2022-07-09 + +Add support for RandomGenerator in Java 17. #19 + ## [4.2.1] - 2022-04-21 Handle clock drift. #18 @@ -286,7 +290,8 @@ Project created as an alternative Java implementation of [ULID spec](https://git - Added `LICENSE` - Added test cases -[unreleased]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-4.2.1...HEAD +[unreleased]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-5.0.0...HEAD +[5.0.0]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-4.2.1...ulid-creator-5.0.0 [4.2.1]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-4.2.0...ulid-creator-4.2.1 [4.2.0]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-4.1.2...ulid-creator-4.2.0 [4.1.2]: https://github.com/f4b6a3/ulid-creator/compare/ulid-creator-4.1.1...ulid-creator-4.1.2 diff --git a/README.md b/README.md index 9a3e647..512903f 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ Add these lines to your `pom.xml`. com.github.f4b6a3 ulid-creator - 4.2.1 + 5.0.0 ``` See more options in [maven.org](https://search.maven.org/artifact/com.github.f4b6a3/ulid-creator). @@ -198,12 +198,38 @@ Ulid ulid = factory.create(); --- -A `UlidFactory` with `ThreadLocalRandom` inside of a `Supplier`: +A `UlidFactory` with `SplittableRandom`: + +```java +// use a random function that returns a long value +SplittableRandom random = new SplittableRandom(); +UlidFactory factory = UlidFactory.newInstance(() -> random.nextLong()); + +// use the factory +Ulid ulid = factory.create(); +``` + +--- + +A `UlidFactory` with `RandomGenerator` (JDK 17+): + +```java +// use a random function that returns a long value +RandomGenerator random = RandomGenerator.getDefault(); +UlidFactory factory = UlidFactory.newInstance(() -> random.nextLong()); + +// use the factory +Ulid ulid = factory.create(); +``` + +--- + +A `UlidFactory` with `ThreadLocalRandom`: ```java // use a random supplier that returns an array of 10 bytes -UlidFactory factory = UlidFactory.newInstance(() -> { - final byte[] bytes = new byte[Ulid.RANDOM_BYTES]; +UlidFactory factory = UlidFactory.newInstance((length) -> { + final byte[] bytes = new byte[length]; ThreadLocalRandom.current().nextBytes(bytes); return bytes; }); diff --git a/src/main/java/com/github/f4b6a3/ulid/UlidFactory.java b/src/main/java/com/github/f4b6a3/ulid/UlidFactory.java index 4aaef93..8aa53f6 100644 --- a/src/main/java/com/github/f4b6a3/ulid/UlidFactory.java +++ b/src/main/java/com/github/f4b6a3/ulid/UlidFactory.java @@ -27,8 +27,9 @@ package com.github.f4b6a3.ulid; import java.security.SecureRandom; import java.time.Clock; import java.util.Random; +import java.util.function.IntFunction; import java.util.function.LongFunction; -import java.util.function.Supplier; +import java.util.function.LongSupplier; /** * Factory that generates ULIDs. @@ -47,7 +48,7 @@ public final class UlidFactory { private final LongFunction ulidFunction; public UlidFactory() { - this(new UlidFunction(getRandomSupplier(null))); + this(new UlidFunction()); } private UlidFactory(LongFunction ulidFunction) { @@ -67,7 +68,7 @@ public final class UlidFactory { * @return {@link UlidFactory} */ public static UlidFactory newInstance() { - return newInstance(getRandomSupplier(null)); + return new UlidFactory(new UlidFunction()); } /** @@ -77,19 +78,31 @@ public final class UlidFactory { * @return {@link UlidFactory} */ public static UlidFactory newInstance(Random random) { - return newInstance(getRandomSupplier(random)); + return new UlidFactory(new UlidFunction(random)); } /** * Returns a new factory. * - * The given random supplier must return an array of 10 bytes. + * The given random function must return a long value. * - * @param randomSupplier a random supplier that returns 10 bytes + * @param randomFunction a random function that returns a long value * @return {@link UlidFactory} */ - public static UlidFactory newInstance(Supplier randomSupplier) { - return new UlidFactory(new UlidFunction(randomSupplier)); + public static UlidFactory newInstance(LongSupplier randomFunction) { + return new UlidFactory(new UlidFunction(randomFunction)); + } + + /** + * Returns a new factory. + * + * The given random function must return a byte array. + * + * @param randomFunction a random function that returns a byte array + * @return {@link UlidFactory} + */ + public static UlidFactory newInstance(IntFunction randomFunction) { + return new UlidFactory(new UlidFunction(randomFunction)); } /** @@ -98,7 +111,7 @@ public final class UlidFactory { * @return {@link UlidFactory} */ public static UlidFactory newMonotonicInstance() { - return newMonotonicInstance(getRandomSupplier(null)); + return new UlidFactory(new MonotonicFunction()); } /** @@ -108,32 +121,57 @@ public final class UlidFactory { * @return {@link UlidFactory} */ public static UlidFactory newMonotonicInstance(Random random) { - return newMonotonicInstance(getRandomSupplier(random)); + return new UlidFactory(new MonotonicFunction(random)); } /** * Returns a new monotonic factory. * - * The given random supplier must return an array of 10 bytes. + * The given random function must return a long value. * - * @param randomSupplier a random supplier that returns 10 bytes + * @param randomFunction a random function that returns a long value * @return {@link UlidFactory} */ - public static UlidFactory newMonotonicInstance(Supplier randomSupplier) { - return new UlidFactory(new MonotonicFunction(randomSupplier)); + public static UlidFactory newMonotonicInstance(LongSupplier randomFunction) { + return new UlidFactory(new MonotonicFunction(randomFunction)); } /** * Returns a new monotonic factory. * - * The given random supplier must return an array of 10 bytes. + * The given random function must return a byte array. * - * @param randomSupplier a random supplier that returns 10 bytes + * @param randomFunction a random function that returns a byte array + * @return {@link UlidFactory} + */ + public static UlidFactory newMonotonicInstance(IntFunction randomFunction) { + return new UlidFactory(new MonotonicFunction(randomFunction)); + } + + /** + * Returns a new monotonic factory. + * + * The given random function must return a long value. + * + * @param randomFunction a random function that returns a long value * @param clock a custom clock instance for tests * @return {@link UlidFactory} */ - protected static UlidFactory newMonotonicInstance(Supplier randomSupplier, Clock clock) { - return new UlidFactory(new MonotonicFunction(randomSupplier), clock); + protected static UlidFactory newMonotonicInstance(LongSupplier randomFunction, Clock clock) { + return new UlidFactory(new MonotonicFunction(randomFunction), clock); + } + + /** + * Returns a new monotonic factory. + * + * The given random function must return a byte array. + * + * @param randomFunction a random function that returns a byte array + * @param clock a custom clock instance for tests + * @return {@link UlidFactory} + */ + protected static UlidFactory newMonotonicInstance(IntFunction randomFunction, Clock clock) { + return new UlidFactory(new MonotonicFunction(randomFunction), clock); } /** @@ -141,8 +179,8 @@ public final class UlidFactory { * * @return a ULID */ - public Ulid create() { - return create(clock.millis()); + public synchronized Ulid create() { + return this.ulidFunction.apply(clock.millis()); } /** @@ -153,7 +191,7 @@ public final class UlidFactory { * @param time a given time * @return a ULID */ - public Ulid create(final long time) { + public synchronized Ulid create(final long time) { return this.ulidFunction.apply(time); } @@ -162,16 +200,33 @@ public final class UlidFactory { */ protected static final class UlidFunction implements LongFunction { - // it must return an array of 10 bytes - private Supplier randomSupplier; + private final IRandom random; - public UlidFunction(Supplier randomSupplier) { - this.randomSupplier = randomSupplier; + public UlidFunction() { + this.random = new ByteRandom(); + } + + public UlidFunction(Random random) { + this.random = IRandom.newInstance(random); + } + + public UlidFunction(IntFunction randomFunction) { + this.random = new ByteRandom(randomFunction); + } + + public UlidFunction(LongSupplier randomFunction) { + this.random = new LongRandom(randomFunction); } @Override public Ulid apply(final long time) { - return new Ulid(time, this.randomSupplier.get()); + if (this.random instanceof ByteRandom) { + return new Ulid(time, this.random.nextBytes(Ulid.RANDOM_BYTES)); + } else { + final long msb = (time << 16) | (this.random.nextLong() & 0xffffL); + final long lsb = this.random.nextLong(); + return new Ulid(msb, lsb); + } } } @@ -183,20 +238,35 @@ public final class UlidFactory { private long lastTime; private Ulid lastUlid; + private final IRandom random; + // Used to preserve monotonicity when the system clock is // adjusted by NTP after a small clock drift or when the // system clock jumps back by 1 second due to leap second. protected static final int CLOCK_DRIFT_TOLERANCE = 10_000; - // it must return an array of 10 bytes - private Supplier randomSupplier; + public MonotonicFunction() { + this(new ByteRandom()); + } - public MonotonicFunction(Supplier randomSupplier) { - this.randomSupplier = randomSupplier; + public MonotonicFunction(Random random) { + this(IRandom.newInstance(random)); + } + + public MonotonicFunction(IntFunction randomFunction) { + this(new ByteRandom(randomFunction)); + } + + public MonotonicFunction(LongSupplier randomFunction) { + this(new LongRandom(randomFunction)); + } + + private MonotonicFunction(IRandom random) { + this.random = random; // initialize internal state this.lastTime = Clock.systemUTC().millis(); - this.lastUlid = new Ulid(lastTime, randomSupplier.get()); + this.lastUlid = new Ulid(lastTime, random.nextBytes(Ulid.RANDOM_BYTES)); } @Override @@ -209,26 +279,122 @@ public final class UlidFactory { this.lastUlid = lastUlid.increment(); } else { this.lastTime = time; - this.lastUlid = new Ulid(time, this.randomSupplier.get()); + if (this.random instanceof ByteRandom) { + this.lastUlid = new Ulid(time, this.random.nextBytes(Ulid.RANDOM_BYTES)); + } else { + final long msb = (time << 16) | (this.random.nextLong() & 0xffffL); + final long lsb = this.random.nextLong(); + this.lastUlid = new Ulid(msb, lsb); + } } return new Ulid(this.lastUlid); } } - /** - * It instantiates a supplier that returns an array of 10 bytes. - * - * @param random a {@link Random} generator - * @return a random supplier that returns 10 bytes - */ - protected static Supplier getRandomSupplier(Random random) { - Random entropy = random != null ? random : new SecureRandom(); - return () -> { - byte[] payload = new byte[Ulid.RANDOM_BYTES]; - entropy.nextBytes(payload); - return payload; - }; + protected static interface IRandom { + + public long nextLong(); + + public byte[] nextBytes(int length); + + static IRandom newInstance(Random random) { + if (random == null) { + return new ByteRandom(); + } else { + if (random instanceof SecureRandom) { + return new ByteRandom(random); + } else { + return new LongRandom(random); + } + } + } } + protected static class LongRandom implements IRandom { + + private final LongSupplier randomFunction; + + public LongRandom() { + this(newRandomFunction(null)); + } + + public LongRandom(Random random) { + this(newRandomFunction(random)); + } + + public LongRandom(LongSupplier randomFunction) { + this.randomFunction = randomFunction != null ? randomFunction : newRandomFunction(null); + } + + @Override + public long nextLong() { + return randomFunction.getAsLong(); + } + + @Override + public byte[] nextBytes(int length) { + + int shift = 0; + long random = 0; + final byte[] bytes = new byte[length]; + + for (int i = 0; i < length; i++) { + if (shift < Byte.SIZE) { + shift = Long.SIZE; + random = randomFunction.getAsLong(); + } + shift -= Byte.SIZE; // 56, 48, 42... + bytes[i] = (byte) (random >>> shift); + } + + return bytes; + } + + protected static LongSupplier newRandomFunction(Random random) { + final Random entropy = random != null ? random : new SecureRandom(); + return entropy::nextLong; + } + } + + protected static class ByteRandom implements IRandom { + + private final IntFunction randomFunction; + + public ByteRandom() { + this(newRandomFunction(null)); + } + + public ByteRandom(Random random) { + this(newRandomFunction(random)); + } + + public ByteRandom(IntFunction randomFunction) { + this.randomFunction = randomFunction != null ? randomFunction : newRandomFunction(null); + } + + @Override + public long nextLong() { + long number = 0; + byte[] bytes = this.randomFunction.apply(Long.BYTES); + for (int i = 0; i < Long.BYTES; i++) { + number = (number << 8) | (bytes[i] & 0xff); + } + return number; + } + + @Override + public byte[] nextBytes(int length) { + return this.randomFunction.apply(length); + } + + protected static IntFunction newRandomFunction(Random random) { + final Random entropy = random != null ? random : new SecureRandom(); + return (final int length) -> { + final byte[] bytes = new byte[length]; + entropy.nextBytes(bytes); + return bytes; + }; + } + } } diff --git a/src/test/java/com/github/f4b6a3/ulid/UlidFactoryDefaultfTest.java b/src/test/java/com/github/f4b6a3/ulid/UlidFactoryDefaultfTest.java index eca2121..d946d44 100644 --- a/src/test/java/com/github/f4b6a3/ulid/UlidFactoryDefaultfTest.java +++ b/src/test/java/com/github/f4b6a3/ulid/UlidFactoryDefaultfTest.java @@ -2,13 +2,16 @@ package com.github.f4b6a3.ulid; import org.junit.Test; -import com.github.f4b6a3.ulid.Ulid; -import com.github.f4b6a3.ulid.UlidCreator; -import com.github.f4b6a3.ulid.UlidFactory; - import static org.junit.Assert.*; +import java.nio.ByteBuffer; +import java.security.SecureRandom; +import java.util.Arrays; import java.util.Random; +import java.util.SplittableRandom; +import java.util.concurrent.ThreadLocalRandom; +import java.util.function.IntFunction; +import java.util.function.LongSupplier; public class UlidFactoryDefaultfTest extends UlidFactoryTest { @@ -59,4 +62,188 @@ public class UlidFactoryDefaultfTest extends UlidFactoryTest { assertEquals(time, ulid.getTime()); } } + + @Test + public void testDefault() { + UlidFactory factory = new UlidFactory(); + assertNotNull(factory.create()); + } + + @Test + public void testWithRandom() { + { + Random random = new Random(); + UlidFactory factory = UlidFactory.newInstance(random); + assertNotNull(factory.create()); + } + { + SecureRandom random = new SecureRandom(); + UlidFactory factory = UlidFactory.newInstance(random); + assertNotNull(factory.create()); + } + } + + @Test + public void testWithRandomNull() { + UlidFactory factory = UlidFactory.newInstance((Random) null); + assertNotNull(factory.create()); + } + + @Test + public void testWithRandomFunction() { + { + SplittableRandom random = new SplittableRandom(); + LongSupplier function = () -> random.nextLong(); + UlidFactory factory = UlidFactory.newInstance(function); + assertNotNull(factory.create()); + } + { + IntFunction function = (length) -> { + byte[] bytes = new byte[length]; + ThreadLocalRandom.current().nextBytes(bytes); + return bytes; + }; + UlidFactory factory = UlidFactory.newInstance(function); + assertNotNull(factory.create()); + } + } + + @Test + public void testWithRandomFunctionNull() { + { + UlidFactory factory = UlidFactory.newInstance((LongSupplier) null); + assertNotNull(factory.create()); + } + { + UlidFactory factory = UlidFactory.newInstance((IntFunction) null); + assertNotNull(factory.create()); + } + } + + @Test + public void testByteRandomNextLong() { + + for (int i = 0; i < 10; i++) { + byte[] bytes = new byte[Long.BYTES]; + (new Random()).nextBytes(bytes); + long number = ByteBuffer.wrap(bytes).getLong(); + UlidFactory.IRandom random = new UlidFactory.ByteRandom((x) -> bytes); + assertEquals(number, random.nextLong()); + } + + for (int i = 0; i < 10; i++) { + + int longs = 10; + int size = Long.BYTES * longs; + + byte[] bytes = new byte[size]; + (new Random()).nextBytes(bytes); + ByteBuffer buffer1 = ByteBuffer.wrap(bytes); + ByteBuffer buffer2 = ByteBuffer.wrap(bytes); + + UlidFactory.IRandom random = new UlidFactory.ByteRandom((x) -> { + byte[] octects = new byte[x]; + buffer1.get(octects); + return octects; + }); + + for (int j = 0; j < longs; j++) { + assertEquals(buffer2.getLong(), random.nextLong()); + } + } + } + + @Test + public void testByteRandomNextBytes() { + + for (int i = 0; i < 10; i++) { + byte[] bytes = new byte[Long.BYTES]; + (new Random()).nextBytes(bytes); + UlidFactory.IRandom random = new UlidFactory.ByteRandom((x) -> bytes); + assertEquals(Arrays.toString(bytes), Arrays.toString(random.nextBytes(Long.BYTES))); + } + + for (int i = 0; i < 10; i++) { + + int ints = 10; + int size = Long.BYTES * ints; + + byte[] bytes = new byte[size]; + (new Random()).nextBytes(bytes); + ByteBuffer buffer1 = ByteBuffer.wrap(bytes); + ByteBuffer buffer2 = ByteBuffer.wrap(bytes); + + UlidFactory.IRandom random = new UlidFactory.ByteRandom((x) -> { + byte[] octects = new byte[x]; + buffer1.get(octects); + return octects; + }); + + for (int j = 0; j < ints; j++) { + byte[] octects = new byte[Long.BYTES]; + buffer2.get(octects); + assertEquals(Arrays.toString(octects), Arrays.toString(random.nextBytes(Long.BYTES))); + } + } + } + + @Test + public void testLogRandomNextLong() { + + for (int i = 0; i < 10; i++) { + byte[] bytes = new byte[Long.BYTES]; + (new Random()).nextBytes(bytes); + long number = ByteBuffer.wrap(bytes).getLong(); + UlidFactory.IRandom random = new UlidFactory.LongRandom(() -> number); + assertEquals(number, random.nextLong()); + } + + for (int i = 0; i < 10; i++) { + + int ints = 10; + int size = Long.BYTES * ints; + + byte[] bytes = new byte[size]; + (new Random()).nextBytes(bytes); + ByteBuffer buffer1 = ByteBuffer.wrap(bytes); + ByteBuffer buffer2 = ByteBuffer.wrap(bytes); + + UlidFactory.IRandom random = new UlidFactory.LongRandom(() -> buffer1.getLong()); + + for (int j = 0; j < ints; j++) { + assertEquals(buffer2.getLong(), random.nextLong()); + } + } + } + + @Test + public void testLogRandomNextBytes() { + + for (int i = 0; i < 10; i++) { + byte[] bytes = new byte[Long.BYTES]; + (new Random()).nextBytes(bytes); + long number = ByteBuffer.wrap(bytes).getLong(); + UlidFactory.IRandom random = new UlidFactory.LongRandom(() -> number); + assertEquals(Arrays.toString(bytes), Arrays.toString(random.nextBytes(Long.BYTES))); + } + + for (int i = 0; i < 10; i++) { + + int ints = 10; + int size = Long.BYTES * ints; + + byte[] bytes = new byte[size]; + (new Random()).nextBytes(bytes); + ByteBuffer buffer1 = ByteBuffer.wrap(bytes); + ByteBuffer buffer2 = ByteBuffer.wrap(bytes); + + UlidFactory.IRandom random = new UlidFactory.LongRandom(() -> buffer1.getLong()); + + for (int j = 0; j < ints; j++) { + byte[] octects = new byte[Long.BYTES]; + buffer2.get(octects); + assertEquals(Arrays.toString(octects), Arrays.toString(random.nextBytes(Long.BYTES))); + } + } + } } diff --git a/src/test/java/com/github/f4b6a3/ulid/UlidFactoryMonotonicTest.java b/src/test/java/com/github/f4b6a3/ulid/UlidFactoryMonotonicTest.java index 1f6f06c..495621f 100644 --- a/src/test/java/com/github/f4b6a3/ulid/UlidFactoryMonotonicTest.java +++ b/src/test/java/com/github/f4b6a3/ulid/UlidFactoryMonotonicTest.java @@ -2,10 +2,6 @@ package com.github.f4b6a3.ulid; import org.junit.Test; -import com.github.f4b6a3.ulid.Ulid; -import com.github.f4b6a3.ulid.UlidCreator; -import com.github.f4b6a3.ulid.UlidFactory; - import static org.junit.Assert.*; import java.time.Clock; @@ -13,7 +9,10 @@ import java.time.Instant; import java.time.ZoneId; import java.util.Arrays; import java.util.Random; -import java.util.function.Supplier; +import java.util.SplittableRandom; +import java.util.concurrent.ThreadLocalRandom; +import java.util.function.IntFunction; +import java.util.function.LongSupplier; public class UlidFactoryMonotonicTest extends UlidFactoryTest { @@ -66,7 +65,7 @@ public class UlidFactoryMonotonicTest extends UlidFactoryTest { } }; - Supplier randomSupplier = UlidFactory.getRandomSupplier(new Random()); + IntFunction randomSupplier = UlidFactory.ByteRandom.newRandomFunction(new Random()); UlidFactory factory = UlidFactory.newMonotonicInstance(randomSupplier, clock); long ms1 = factory.create().getTime(); // time @@ -115,7 +114,7 @@ public class UlidFactoryMonotonicTest extends UlidFactoryTest { } }; - Supplier randomSupplier = UlidFactory.getRandomSupplier(new Random()); + IntFunction randomSupplier = UlidFactory.ByteRandom.newRandomFunction(new Random()); UlidFactory factory = UlidFactory.newMonotonicInstance(randomSupplier, clock); long ms1 = factory.create().getTime(); // second @@ -163,4 +162,63 @@ public class UlidFactoryMonotonicTest extends UlidFactoryTest { assertEquals(time, ulid.getTime()); } } + + @Test + public void testWithRandom() { + Random random = new Random(); + UlidFactory factory = UlidFactory.newMonotonicInstance(random); + assertNotNull(factory.create()); + } + + @Test + public void testWithRandomNull() { + UlidFactory factory = UlidFactory.newMonotonicInstance((Random) null); + assertNotNull(factory.create()); + } + + @Test + public void testWithRandomFunction() { + { + SplittableRandom random = new SplittableRandom(); + LongSupplier function = () -> random.nextLong(); + UlidFactory factory = UlidFactory.newMonotonicInstance(function); + assertNotNull(factory.create()); + } + { + SplittableRandom random = new SplittableRandom(); + LongSupplier function = () -> random.nextLong(); + UlidFactory factory = UlidFactory.newMonotonicInstance(function, Clock.systemDefaultZone()); + assertNotNull(factory.create()); + } + { + IntFunction function = (length) -> { + byte[] bytes = new byte[length]; + ThreadLocalRandom.current().nextBytes(bytes); + return bytes; + }; + UlidFactory factory = UlidFactory.newMonotonicInstance(function); + assertNotNull(factory.create()); + } + { + IntFunction function = (length) -> { + byte[] bytes = new byte[length]; + ThreadLocalRandom.current().nextBytes(bytes); + return bytes; + }; + UlidFactory factory = UlidFactory.newMonotonicInstance(function, Clock.systemDefaultZone()); + assertNotNull(factory.create()); + } + } + + @Test + public void testWithRandomFunctionNull() { + { + UlidFactory factory = UlidFactory.newMonotonicInstance((LongSupplier) null); + assertNotNull(factory.create()); + } + { + UlidFactory factory = UlidFactory.newMonotonicInstance((IntFunction) null); + assertNotNull(factory.create()); + } + } } diff --git a/src/test/java/com/github/f4b6a3/ulid/UlidFactoryTest.java b/src/test/java/com/github/f4b6a3/ulid/UlidFactoryTest.java index e36863b..bf2296b 100644 --- a/src/test/java/com/github/f4b6a3/ulid/UlidFactoryTest.java +++ b/src/test/java/com/github/f4b6a3/ulid/UlidFactoryTest.java @@ -9,8 +9,6 @@ import java.util.Random; import java.util.Set; import java.util.UUID; -import com.github.f4b6a3.ulid.UlidFactory; - public abstract class UlidFactoryTest { protected static final int DEFAULT_LOOP_MAX = 10_000; diff --git a/src/test/java/com/github/f4b6a3/ulid/UlidTest.java b/src/test/java/com/github/f4b6a3/ulid/UlidTest.java index a45c784..97a3afa 100644 --- a/src/test/java/com/github/f4b6a3/ulid/UlidTest.java +++ b/src/test/java/com/github/f4b6a3/ulid/UlidTest.java @@ -15,8 +15,6 @@ import java.util.UUID; import org.junit.Test; -import com.github.f4b6a3.ulid.Ulid; - public class UlidTest { private static final int DEFAULT_LOOP_MAX = 1_000; diff --git a/src/test/java/com/github/f4b6a3/ulid/UniquenessTest.java b/src/test/java/com/github/f4b6a3/ulid/uniq/UniquenessTest.java similarity index 95% rename from src/test/java/com/github/f4b6a3/ulid/UniquenessTest.java rename to src/test/java/com/github/f4b6a3/ulid/uniq/UniquenessTest.java index 106ce1d..9333d1c 100644 --- a/src/test/java/com/github/f4b6a3/ulid/UniquenessTest.java +++ b/src/test/java/com/github/f4b6a3/ulid/uniq/UniquenessTest.java @@ -1,8 +1,12 @@ -package com.github.f4b6a3.ulid; +package com.github.f4b6a3.ulid.uniq; import java.util.HashSet; import java.util.Random; +import com.github.f4b6a3.ulid.TestSuite; +import com.github.f4b6a3.ulid.Ulid; +import com.github.f4b6a3.ulid.UlidFactory; + /** * * This test starts many threads that keep requesting thousands of ULIDs to a