master
go 91 lines 2.39 KB
Raw
1 package node
2
3 import (
4 "context"
5 "math"
6 "testing"
7
8 "github.com/ipfs/go-datastore"
9 "github.com/stretchr/testify/assert"
10 "github.com/stretchr/testify/require"
11 )
12
13 // newTestDatastore returns a fresh in-memory datastore for unique-count
14 // persistence tests. Tests are single-goroutine so no sync wrapper is
15 // needed.
16 func newTestDatastore() datastore.Datastore {
17 return datastore.NewMapDatastore()
18 }
19
20 func TestReadLastUniqueCount_emptyReturnsZero(t *testing.T) {
21 ds := newTestDatastore()
22
23 // A fresh datastore has no persisted count. The reader treats this
24 // as "no previous cycle data available" and returns 0, which the
25 // caller falls back to DefaultBloomInitialCapacity for.
26 got := readLastUniqueCount(ds)
27 assert.Equal(t, uint64(0), got)
28 }
29
30 func TestPersistAndReadUniqueCount_roundTrip(t *testing.T) {
31 tests := []struct {
32 name string
33 count uint64
34 }{
35 {"zero", 0},
36 {"one", 1},
37 {"small", 1_000},
38 {"million", 1_000_000},
39 {"billion", 1_000_000_000},
40 {"max uint64", math.MaxUint64},
41 }
42
43 for _, tt := range tests {
44 t.Run(tt.name, func(t *testing.T) {
45 ds := newTestDatastore()
46 persistUniqueCount(ds, tt.count)
47 got := readLastUniqueCount(ds)
48 assert.Equal(t, tt.count, got)
49 })
50 }
51 }
52
53 func TestPersistUniqueCount_overwriteReplacesPreviousValue(t *testing.T) {
54 ds := newTestDatastore()
55
56 // Each reprovide cycle persists a new count, overwriting the
57 // previous one. The reader must return the most recent value.
58 persistUniqueCount(ds, 1_000)
59 persistUniqueCount(ds, 2_000_000)
60 persistUniqueCount(ds, 42)
61
62 got := readLastUniqueCount(ds)
63 assert.Equal(t, uint64(42), got)
64 }
65
66 func TestReadLastUniqueCount_corruptLengthReturnsZero(t *testing.T) {
67 tests := []struct {
68 name string
69 raw []byte
70 }{
71 {"empty bytes", []byte{}},
72 {"too short (4 bytes)", []byte{0x01, 0x02, 0x03, 0x04}},
73 {"too long (16 bytes)", make([]byte, 16)},
74 {"single byte", []byte{0xFF}},
75 }
76
77 for _, tt := range tests {
78 t.Run(tt.name, func(t *testing.T) {
79 ds := newTestDatastore()
80 // Write malformed bytes directly under the persistence key
81 // to simulate a corrupt or truncated entry.
82 err := ds.Put(context.Background(), datastore.NewKey(reprovideLastUniqueCountKey), tt.raw)
83 require.NoError(t, err)
84
85 // The reader rejects anything that is not exactly 8 bytes
86 // and falls back to 0 instead of panicking on a short read.
87 got := readLastUniqueCount(ds)
88 assert.Equal(t, uint64(0), got)
89 })
90 }
91 }