Skip to content

Commit 08e28c6

Browse files
committed
port tests
1 parent 04794ee commit 08e28c6

File tree

3 files changed

+949
-0
lines changed

3 files changed

+949
-0
lines changed

README.md

+44
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,50 @@ go test ./...
160160

161161
## Benchmarks
162162

163+
On an Apple M1 Max, MacOS 15.3 and Go 1.23.3
164+
165+
```
166+
goos: darwin
167+
goarch: arm64
168+
pkg: go.rtnl.ai/ulid
169+
cpu: Apple M1 Max
170+
BenchmarkNew/WithCrypoEntropy-10 9962818 109.0 ns/op 16 B/op 1 allocs/op
171+
BenchmarkNew/WithEntropy-10 39486076 33.55 ns/op 16 B/op 1 allocs/op
172+
BenchmarkNew/WithMonotonicEntropy_SameTimestamp_Inc0-10 39891241 29.24 ns/op 16 B/op 1 allocs/op
173+
BenchmarkNew/WithMonotonicEntropy_DifferentTimestamp_Inc0-10 32685003 36.05 ns/op 16 B/op 1 allocs/op
174+
BenchmarkNew/WithMonotonicEntropy_SameTimestamp_Inc1-10 45091450 25.16 ns/op 16 B/op 1 allocs/op
175+
BenchmarkNew/WithMonotonicEntropy_DifferentTimestamp_Inc1-10 34196192 35.31 ns/op 16 B/op 1 allocs/op
176+
BenchmarkNew/WithCryptoMonotonicEntropy_SameTimestamp_Inc1-10 47389621 25.40 ns/op 16 B/op 1 allocs/op
177+
BenchmarkNew/WithCryptoMonotonicEntropy_DifferentTimestamp_Inc1-10 39461244 30.50 ns/op 16 B/op 1 allocs/op
178+
BenchmarkNew/WithoutEntropy-10 72576985 16.62 ns/op 16 B/op 1 allocs/op
179+
BenchmarkMustNew/WithCrypoEntropy-10 11441258 107.4 ns/op 16 B/op 1 allocs/op
180+
BenchmarkMustNew/WithEntropy-10 37700085 31.30 ns/op 16 B/op 1 allocs/op
181+
BenchmarkMustNew/WithMonotonicEntropy_SameTimestamp_Inc0-10 41440399 29.14 ns/op 16 B/op 1 allocs/op
182+
BenchmarkMustNew/WithMonotonicEntropy_DifferentTimestamp_Inc0-10 32740442 36.39 ns/op 16 B/op 1 allocs/op
183+
BenchmarkMustNew/WithMonotonicEntropy_SameTimestamp_Inc1-10 46801796 26.14 ns/op 16 B/op 1 allocs/op
184+
BenchmarkMustNew/WithMonotonicEntropy_DifferentTimestamp_Inc1-10 32244736 37.13 ns/op 16 B/op 1 allocs/op
185+
BenchmarkMustNew/WithCryptoMonotonicEntropy_SameTimestamp_Inc1-10 45454687 26.91 ns/op 16 B/op 1 allocs/op
186+
BenchmarkMustNew/WithCryptoMonotonicEntropy_DifferentTimestamp_Inc1-10 36388584 33.81 ns/op 16 B/op 1 allocs/op
187+
BenchmarkMustNew/WithoutEntropy-10 70010307 18.37 ns/op 16 B/op 1 allocs/op
188+
BenchmarkParse-10 100000000 10.65 ns/op 2441.46 MB/s 0 B/op 0 allocs/op
189+
BenchmarkParseStrict-10 73864335 15.97 ns/op 1627.67 MB/s 0 B/op 0 allocs/op
190+
BenchmarkMustParse-10 95626101 12.61 ns/op 2061.36 MB/s 0 B/op 0 allocs/op
191+
BenchmarkString-10 86481555 13.67 ns/op 1170.76 MB/s 0 B/op 0 allocs/op
192+
BenchmarkMarshal/Text-10 94831988 12.63 ns/op 1266.42 MB/s 0 B/op 0 allocs/op
193+
BenchmarkMarshal/TextTo-10 100000000 10.98 ns/op 1456.62 MB/s 0 B/op 0 allocs/op
194+
BenchmarkMarshal/Binary-10 455631534 2.760 ns/op 5797.31 MB/s 0 B/op 0 allocs/op
195+
BenchmarkMarshal/BinaryTo-10 1000000000 1.111 ns/op 14402.78 MB/s 0 B/op 0 allocs/op
196+
BenchmarkUnmarshal/Text-10 100000000 10.43 ns/op 2492.96 MB/s 0 B/op 0 allocs/op
197+
BenchmarkUnmarshal/Binary-10 569854686 2.135 ns/op 7493.13 MB/s 0 B/op 0 allocs/op
198+
BenchmarkNow-10 31315614 38.77 ns/op 206.35 MB/s 0 B/op 0 allocs/op
199+
BenchmarkTimestamp-10 1000000000 0.7833 ns/op 10212.69 MB/s 0 B/op 0 allocs/op
200+
BenchmarkTime-10 1000000000 0.8018 ns/op 9977.95 MB/s 0 B/op 0 allocs/op
201+
BenchmarkSetTime-10 950735085 1.262 ns/op 6338.36 MB/s 0 B/op 0 allocs/op
202+
BenchmarkEntropy-10 574565655 2.042 ns/op 4896.79 MB/s 0 B/op 0 allocs/op
203+
BenchmarkSetEntropy-10 1000000000 0.9536 ns/op 10486.70 MB/s 0 B/op 0 allocs/op
204+
BenchmarkCompare-10 522322389 2.254 ns/op 14197.26 MB/s 0 B/op 0 allocs/op
205+
```
206+
163207
## References
164208

165209
- [github.com/oklog/ulid](https://github.com/oklog/ulid)

entropy_test.go

+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package ulid_test
2+
3+
import (
4+
"bytes"
5+
crand "crypto/rand"
6+
"fmt"
7+
"io"
8+
"math"
9+
"math/rand"
10+
"testing"
11+
"time"
12+
13+
"go.rtnl.ai/ulid"
14+
)
15+
16+
func TestMonotonic(t *testing.T) {
17+
now := ulid.Now()
18+
for _, e := range []struct {
19+
name string
20+
mk func() io.Reader
21+
}{
22+
{"cryptorand", func() io.Reader { return crand.Reader }},
23+
{"mathrand", func() io.Reader { return rand.New(rand.NewSource(int64(now))) }},
24+
} {
25+
for _, inc := range []uint64{
26+
0,
27+
1,
28+
2,
29+
math.MaxUint8 + 1,
30+
math.MaxUint16 + 1,
31+
math.MaxUint32 + 1,
32+
} {
33+
inc := inc
34+
entropy := ulid.Monotonic(e.mk(), uint64(inc))
35+
36+
t.Run(fmt.Sprintf("entropy=%s/inc=%d", e.name, inc), func(t *testing.T) {
37+
t.Parallel()
38+
39+
var prev ulid.ULID
40+
for i := 0; i < 10000; i++ {
41+
next, err := ulid.New(123, entropy)
42+
if err != nil {
43+
t.Fatal(err)
44+
}
45+
46+
if prev.Compare(next) >= 0 {
47+
t.Fatalf("prev: %v %v > next: %v %v",
48+
prev.Time(), prev.Entropy(), next.Time(), next.Entropy())
49+
}
50+
51+
prev = next
52+
}
53+
})
54+
}
55+
}
56+
}
57+
58+
func TestMonotonicOverflow(t *testing.T) {
59+
t.Parallel()
60+
61+
entropy := ulid.Monotonic(
62+
io.MultiReader(
63+
bytes.NewReader(bytes.Repeat([]byte{0xFF}, 10)), // Entropy for first ULID
64+
crand.Reader, // Following random entropy
65+
),
66+
0,
67+
)
68+
69+
prev, err := ulid.New(0, entropy)
70+
if err != nil {
71+
t.Fatal(err)
72+
}
73+
74+
next, err := ulid.New(prev.Time(), entropy)
75+
if have, want := err, ulid.ErrMonotonicOverflow; have != want {
76+
t.Errorf("have ulid: %v %v err: %v, want err: %v",
77+
next.Time(), next.Entropy(), have, want)
78+
}
79+
}
80+
81+
func TestMonotonicSafe(t *testing.T) {
82+
t.Parallel()
83+
84+
var (
85+
rng = rand.New(rand.NewSource(time.Now().UnixNano()))
86+
safe = &ulid.LockedMonotonicReader{MonotonicReader: ulid.Monotonic(rng, 0)}
87+
t0 = ulid.Timestamp(time.Now())
88+
)
89+
90+
errs := make(chan error, 100)
91+
for i := 0; i < cap(errs); i++ {
92+
go func() {
93+
u0 := ulid.MustNew(t0, safe)
94+
u1 := u0
95+
for j := 0; j < 1024; j++ {
96+
u0, u1 = u1, ulid.MustNew(t0, safe)
97+
if u0.String() >= u1.String() {
98+
errs <- fmt.Errorf(
99+
"%s (%d %x) >= %s (%d %x)",
100+
u0.String(), u0.Time(), u0.Entropy(),
101+
u1.String(), u1.Time(), u1.Entropy(),
102+
)
103+
return
104+
}
105+
}
106+
errs <- nil
107+
}()
108+
}
109+
110+
for i := 0; i < cap(errs); i++ {
111+
if err := <-errs; err != nil {
112+
t.Fatal(err)
113+
}
114+
}
115+
}

0 commit comments

Comments
 (0)