Skip to content
File

Blob: kv/memory/prefix_test.go

go157 lines
1package memory
2 
3import (
4 "bytes"
5 "context"
6 "crypto/rand"
7 "testing"
8 
9 "go.miragespace.co/specter/spec/chord"
10 
11 "github.com/stretchr/testify/assert"
12)
13 
14func TestPrefixAppend(t *testing.T) {
15 as := assert.New(t)
16 
17 kv := WithHashFn(chord.Hash)
18 
19 prefix := make([]byte, 8)
20 child := make([]byte, 16)
21 rand.Read(prefix)
22 rand.Read(child)
23 
24 as.NoError(kv.PrefixAppend(context.Background(), prefix, child))
25 as.Error(kv.PrefixAppend(context.Background(), prefix, child))
26}
27 
28func TestPrefixList(t *testing.T) {
29 as := assert.New(t)
30 
31 kv := WithHashFn(chord.Hash)
32 
33 numChildren := 32
34 prefix := make([]byte, 8)
35 children := make([][]byte, numChildren)
36 for i := range children {
37 children[i] = make([]byte, 16)
38 rand.Read(children[i])
39 kv.PrefixAppend(context.Background(), prefix, children[i])
40 }
41 
42 ret, err := kv.PrefixList(context.Background(), prefix)
43 as.NoError(err)
44 for _, child := range ret {
45 as.Greater(len(child), 0)
46 }
47 
48 found := 0
49 for _, needle := range children {
50 for _, haystack := range ret {
51 if bytes.Equal(haystack, needle) {
52 found++
53 }
54 }
55 }
56 
57 as.Equal(numChildren, found, "missing from prefix list")
58}
59 
60func TestPrefixContains(t *testing.T) {
61 as := assert.New(t)
62 
63 kv := WithHashFn(chord.Hash)
64 
65 prefix := make([]byte, 8)
66 child := make([]byte, 16)
67 rand.Read(prefix)
68 rand.Read(child)
69 
70 as.NoError(kv.PrefixAppend(context.Background(), prefix, child))
71 
72 b, err := kv.PrefixContains(context.Background(), prefix, child)
73 as.NoError(err)
74 as.True(b)
75 
76 b, err = kv.PrefixContains(context.Background(), prefix, child[1:])
77 as.NoError(err)
78 as.False(b)
79}
80 
81func TestPrefixDelete(t *testing.T) {
82 as := assert.New(t)
83 
84 kv := WithHashFn(chord.Hash)
85 
86 numChildren := 32
87 prefix := make([]byte, 8)
88 children := make([][]byte, numChildren)
89 for i := range children {
90 children[i] = make([]byte, 16)
91 rand.Read(children[i])
92 kv.PrefixAppend(context.Background(), prefix, children[i])
93 }
94 
95 ret, err := kv.PrefixList(context.Background(), prefix)
96 as.NoError(err)
97 
98 found := 0
99 for _, needle := range children {
100 for _, haystack := range ret {
101 if bytes.Equal(haystack, needle) {
102 found++
103 }
104 }
105 }
106 
107 as.Equal(numChildren, found, "missing child from prefix list")
108 
109 expectMissing := 0
110 for i := 0; i < numChildren; i += 2 {
111 kv.PrefixRemove(context.Background(), prefix, children[i])
112 expectMissing++
113 }
114 
115 ret, err = kv.PrefixList(context.Background(), prefix)
116 as.NoError(err)
117 
118 found = 0
119 for _, needle := range children {
120 for _, haystack := range ret {
121 if bytes.Equal(haystack, needle) {
122 found++
123 }
124 }
125 }
126 
127 as.Equal(numChildren-expectMissing, found, "found deleted child")
128}
129 
130func TestSharedKeyspace(t *testing.T) {
131 as := assert.New(t)
132 
133 kv := WithHashFn(chord.Hash)
134 
135 key := make([]byte, 8)
136 rand.Read(key)
137 
138 plainValue := make([]byte, 16)
139 rand.Read(plainValue)
140 child := make([]byte, 32)
141 rand.Read(child)
142 
143 as.NoError(kv.Put(context.Background(), key, plainValue))
144 as.NoError(kv.PrefixAppend(context.Background(), key, child))
145 
146 // deleting the key from plain keyspace should not affect the prefix keyspace
147 as.NoError(kv.Delete(context.Background(), key))
148 val, err := kv.Get(context.Background(), key)
149 as.NoError(err)
150 as.Nil(val)
151 
152 vals, err := kv.PrefixList(context.Background(), key)
153 as.NoError(err)
154 as.Len(vals, 1)
155 as.EqualValues(child, vals[0])
156}