Skip to content
File

Blob: kv/memory/simple_test.go

go139 lines
1package memory
2 
3import (
4 "context"
5 "crypto/rand"
6 "hash/fnv"
7 "strconv"
8 "strings"
9 "testing"
10 
11 "go.miragespace.co/specter/spec/chord"
12 
13 "github.com/stretchr/testify/assert"
14)
15 
16const (
17 collisionRing = 8
18 keyPrefix = "k"
19 valPrefix = "val"
20)
21 
22func collisionHash(s []byte) uint64 {
23 h := fnv.New64a()
24 h.Write(s)
25 return h.Sum64() % collisionRing
26}
27 
28func ks(p string, i int) []byte {
29 var sb strings.Builder
30 sb.WriteString(p)
31 sb.WriteString("/")
32 sb.WriteString(strconv.FormatInt(int64(i), 10))
33 return []byte(sb.String())
34}
35 
36func TestCollisionPutGet(t *testing.T) {
37 as := assert.New(t)
38 
39 kv := WithHashFn(collisionHash)
40 
41 for i := 1; i < collisionRing*2; i++ {
42 as.Nil(kv.Put(context.Background(), ks(keyPrefix, i), ks(valPrefix, i)))
43 }
44 
45 as.LessOrEqual(collisionRing, kv.s.Len())
46 
47 for i := 1; i < collisionRing*2; i++ {
48 val, err := kv.Get(context.Background(), ks(keyPrefix, i))
49 as.Nil(err)
50 as.Equal(ks(valPrefix, i), val)
51 }
52}
53 
54func TestCollisionNil(t *testing.T) {
55 as := assert.New(t)
56 
57 kv := WithHashFn(collisionHash)
58 
59 for i := 1; i < collisionRing*2; i++ {
60 as.Nil(kv.Put(context.Background(), ks(keyPrefix, i), ks(valPrefix, i)))
61 }
62 
63 as.LessOrEqual(collisionRing, kv.s.Len())
64 
65 for i := collisionRing * 2; i < collisionRing*4; i++ {
66 val, err := kv.Get(context.Background(), ks(keyPrefix, i))
67 as.Nil(err)
68 as.Nil(val)
69 }
70}
71 
72func TestCollisionDelete(t *testing.T) {
73 as := assert.New(t)
74 
75 kv := WithHashFn(collisionHash)
76 
77 for i := 1; i < collisionRing*2; i++ {
78 as.Nil(kv.Put(context.Background(), ks(keyPrefix, i), ks(valPrefix, i)))
79 }
80 
81 as.LessOrEqual(collisionRing, kv.s.Len())
82 
83 for i := 1; i < collisionRing*2; i++ {
84 as.Nil(kv.Delete(context.Background(), ks(keyPrefix, i)))
85 }
86 
87 for i := 1; i < collisionRing*2; i++ {
88 val, err := kv.Get(context.Background(), ks(keyPrefix, i))
89 as.Nil(err)
90 as.Nil(val)
91 }
92}
93 
94func TestEmpty(t *testing.T) {
95 as := assert.New(t)
96 
97 kv := WithHashFn(chord.Hash)
98 
99 key := make([]byte, 6)
100 rand.Read(key)
101 
102 val, err := kv.Get(context.Background(), key)
103 as.NoError(err)
104 as.Nil(val)
105 
106 err = kv.Put(context.Background(), key, []byte("v"))
107 as.NoError(err)
108 
109 val, err = kv.Get(context.Background(), key)
110 as.NoError(err)
111 as.NotNil(val)
112 
113 err = kv.Delete(context.Background(), key)
114 as.NoError(err)
115 
116 val, err = kv.Get(context.Background(), key)
117 as.NoError(err)
118 as.Nil(val)
119 
120 keys, err := kv.RangeKeys(context.Background(), 0, 0)
121 as.NoError(err)
122 exp, err := kv.Export(context.Background(), keys)
123 as.NoError(err)
124 
125 kv2 := WithHashFn(chord.Hash)
126 as.NoError(kv2.Import(context.Background(), keys, exp))
127 
128 val, err = kv2.Get(context.Background(), key)
129 as.NoError(err)
130 as.Nil(val)
131 
132 err = kv2.Put(context.Background(), key, []byte{})
133 as.NoError(err)
134 
135 val, err = kv2.Get(context.Background(), key)
136 as.NoError(err)
137 as.NotNil(val)
138}