forked from cowtowncoder/java-uuid-generator
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTimeBasedEpochGeneratorTest.java
More file actions
88 lines (75 loc) · 3.51 KB
/
Copy pathTimeBasedEpochGeneratorTest.java
File metadata and controls
88 lines (75 loc) · 3.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package com.fasterxml.uuid.impl;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.UUID;
import java.util.function.Consumer;
import com.fasterxml.uuid.UUIDClock;
import junit.framework.TestCase;
/**
* @since 5.3
*/
public class TimeBasedEpochGeneratorTest extends TestCase
{
public void testFormat() {
BigInteger minEntropy = BigInteger.ZERO;
long minTimestamp = 0;
TimeBasedEpochGenerator generatorEmpty = new TimeBasedEpochGenerator(staticEntropy(minEntropy), staticClock(minTimestamp));
UUID uuidEmpty = generatorEmpty.generate();
assertEquals(0x07, uuidEmpty.version());
assertEquals(0x02, uuidEmpty.variant());
assertEquals(minTimestamp, getTimestamp(uuidEmpty));
assertEquals(minEntropy, getEntropy(uuidEmpty));
Consumer<byte[]> entropyFull = bytes -> Arrays.fill(bytes, (byte) 0xFF);
long maxTimestamp = rightBitmask(48);
TimeBasedEpochGenerator generatorFull = new TimeBasedEpochGenerator(entropyFull, staticClock(maxTimestamp));
UUID uuidFull = generatorFull.generate();
assertEquals(0x07, uuidFull.version());
assertEquals(0x02, uuidFull.variant());
assertEquals(maxTimestamp, getTimestamp(uuidFull));
assertEquals(BigInteger.ONE.shiftLeft(73).subtract(BigInteger.ONE), getEntropy(uuidFull));
}
public void testIncrement() {
TimeBasedEpochGenerator generator = new TimeBasedEpochGenerator(staticEntropy(BigInteger.ZERO), staticClock(0));
assertEquals(BigInteger.valueOf(0), getEntropy(generator.generate()));
assertEquals(BigInteger.valueOf(1), getEntropy(generator.generate()));
assertEquals(BigInteger.valueOf(2), getEntropy(generator.generate()));
assertEquals(BigInteger.valueOf(3), getEntropy(generator.generate()));
}
public void testCarryOnce() {
TimeBasedEpochGenerator generator = new TimeBasedEpochGenerator(staticEntropy(BigInteger.valueOf(0xFF)), staticClock(0));
assertEquals(BigInteger.valueOf(0xFF), getEntropy(generator.generate()));
assertEquals(BigInteger.valueOf(0x100), getEntropy(generator.generate()));
}
public void testCarryAll() {
BigInteger largeEntropy = BigInteger.ONE.shiftLeft(73).subtract(BigInteger.ONE);
TimeBasedEpochGenerator generator = new TimeBasedEpochGenerator(staticEntropy(largeEntropy), staticClock(0));
assertEquals(largeEntropy, getEntropy(generator.generate()));
assertEquals(BigInteger.ONE.shiftLeft(73), getEntropy(generator.generate()));
}
private long getTimestamp(UUID uuid) {
return uuid.getMostSignificantBits() >>> 16;
}
private BigInteger getEntropy(UUID uuid) {
return BigInteger.valueOf(uuid.getMostSignificantBits() & rightBitmask(12)).shiftLeft(62).or(
BigInteger.valueOf(uuid.getLeastSignificantBits() & rightBitmask(62)));
}
private Consumer<byte[]> staticEntropy(BigInteger entropy) {
byte[] entropyBytes = entropy.toByteArray();
return bytes -> {
int offset = bytes.length - entropyBytes.length;
Arrays.fill(bytes, 0, offset, (byte) 0x00);
System.arraycopy(entropyBytes, 0, bytes, offset, entropyBytes.length);
};
}
private UUIDClock staticClock(long timestamp) {
return new UUIDClock() {
@Override
public long currentTimeMillis() {
return timestamp;
}
};
}
private long rightBitmask(int bits) {
return (1L << bits) - 1;
}
}