Skip to content

Commit 7c40734

Browse files
committed
fix unit test in store and templates
1 parent 89a1de6 commit 7c40734

3 files changed

Lines changed: 345 additions & 493 deletions

File tree

pkg/store/disk/disk_test.go

Lines changed: 344 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,344 @@
1+
package disk
2+
3+
import (
4+
"os"
5+
"path/filepath"
6+
"testing"
7+
8+
bolt "go.etcd.io/bbolt"
9+
10+
"github.com/stretchr/testify/assert"
11+
"github.com/stretchr/testify/require"
12+
)
13+
14+
// TestUser is a sample struct for testing
15+
type TestUser struct {
16+
ID string `json:"id"`
17+
Name string `json:"name"`
18+
}
19+
20+
// setupTestStore creates a temporary store for testing
21+
func setupTestStore(t *testing.T) (*Store[TestUser], string) {
22+
t.Helper()
23+
24+
// Create temporary directory for test database
25+
tmpDir := t.TempDir()
26+
27+
config := &Config{
28+
FileName: "test.db",
29+
BucketName: "test_bucket",
30+
}
31+
32+
store, err := newStorageStoreWithPath[TestUser](config, tmpDir)
33+
require.NoError(t, err)
34+
require.NotNil(t, store)
35+
36+
t.Cleanup(func() {
37+
err = store.Close()
38+
require.Nil(t, err)
39+
})
40+
41+
return store, tmpDir
42+
}
43+
44+
// newStorageStoreWithPath creates a new disk-based storage instance with a custom base path (for testing)
45+
func newStorageStoreWithPath[T any](config *Config, basePath string) (*Store[T], error) {
46+
vtHomeDir := filepath.Join(basePath, ".vt")
47+
if err := os.MkdirAll(vtHomeDir, 0750); err != nil {
48+
return nil, err
49+
}
50+
51+
dbPath := filepath.Join(vtHomeDir, config.FileName)
52+
db, err := bolt.Open(dbPath, 0600, nil)
53+
if err != nil {
54+
return nil, err
55+
}
56+
57+
return &Store[T]{
58+
db: db,
59+
Config: config,
60+
}, nil
61+
}
62+
63+
func TestNewStorageStore(t *testing.T) {
64+
tmpDir := t.TempDir()
65+
66+
config := &Config{
67+
FileName: "test.db",
68+
BucketName: "users",
69+
}
70+
71+
store, err := newStorageStoreWithPath[TestUser](config, tmpDir)
72+
require.NoError(t, err)
73+
require.NotNil(t, store)
74+
defer func() {
75+
err = store.Close()
76+
require.Nil(t, err)
77+
}()
78+
79+
// Verify the database file was created
80+
dbPath := filepath.Join(tmpDir, ".vt", "test.db")
81+
_, err = os.Stat(dbPath)
82+
assert.NoError(t, err, "database file should exist")
83+
84+
// Verify config is set
85+
assert.Equal(t, config, store.Config)
86+
}
87+
88+
func TestStore_Set(t *testing.T) {
89+
store, _ := setupTestStore(t)
90+
91+
user := TestUser{
92+
ID: "1",
93+
Name: "John Doe",
94+
}
95+
96+
err := store.Set("user1", user)
97+
assert.NoError(t, err)
98+
}
99+
100+
func TestStore_Get(t *testing.T) {
101+
store, _ := setupTestStore(t)
102+
103+
expectedUser := TestUser{
104+
ID: "1",
105+
Name: "John Doe",
106+
}
107+
108+
// First, set the user
109+
err := store.Set("user1", expectedUser)
110+
require.NoError(t, err)
111+
112+
// Now retrieve it
113+
actualUser, err := store.Get("user1")
114+
assert.NoError(t, err)
115+
assert.Equal(t, expectedUser, actualUser)
116+
}
117+
118+
func TestStore_GetAll(t *testing.T) {
119+
store, _ := setupTestStore(t)
120+
121+
users := []TestUser{
122+
{ID: "1", Name: "John Doe"},
123+
{ID: "2", Name: "Jane Smith"},
124+
{ID: "3", Name: "Bob Johnson"},
125+
}
126+
127+
// Store multiple users
128+
for i, user := range users {
129+
err := store.Set(user.ID, user)
130+
require.NoError(t, err, "failed to set user %d", i)
131+
}
132+
133+
// Retrieve all users
134+
results, err := store.GetAll()
135+
assert.NoError(t, err)
136+
assert.Len(t, results, len(users))
137+
138+
// Verify all users are present (order might differ)
139+
resultMap := make(map[string]TestUser)
140+
for _, user := range results {
141+
resultMap[user.ID] = user
142+
}
143+
144+
for _, expectedUser := range users {
145+
actualUser, exists := resultMap[expectedUser.ID]
146+
assert.True(t, exists, "user %s should exist", expectedUser.ID)
147+
assert.Equal(t, expectedUser, actualUser)
148+
}
149+
}
150+
151+
func TestStore_GetAll_EmptyBucket(t *testing.T) {
152+
store, _ := setupTestStore(t)
153+
154+
// GetAll on empty bucket should return empty slice
155+
results, err := store.GetAll()
156+
assert.NoError(t, err)
157+
assert.Empty(t, results)
158+
}
159+
160+
func TestStore_Delete(t *testing.T) {
161+
store, _ := setupTestStore(t)
162+
163+
user := TestUser{
164+
ID: "1",
165+
Name: "John Doe",
166+
}
167+
168+
// Set a user
169+
err := store.Set("user1", user)
170+
require.NoError(t, err)
171+
172+
// Verify it exists
173+
_, err = store.Get("user1")
174+
require.NoError(t, err)
175+
176+
// Delete the user
177+
err = store.Delete("user1")
178+
assert.NoError(t, err)
179+
180+
// Verify it's gone
181+
_, err = store.Get("user1")
182+
assert.Error(t, err, "should return error for deleted key")
183+
}
184+
185+
func TestStore_SetAndGetMultiple(t *testing.T) {
186+
store, _ := setupTestStore(t)
187+
188+
users := map[string]TestUser{
189+
"user1": {ID: "1", Name: "Alice"},
190+
"user2": {ID: "2", Name: "Bob"},
191+
"user3": {ID: "3", Name: "Charlie"},
192+
}
193+
194+
// Set multiple users
195+
for key, user := range users {
196+
err := store.Set(key, user)
197+
require.NoError(t, err)
198+
}
199+
200+
// Get each user and verify
201+
for key, expectedUser := range users {
202+
actualUser, err := store.Get(key)
203+
assert.NoError(t, err)
204+
assert.Equal(t, expectedUser, actualUser)
205+
}
206+
}
207+
208+
func TestStore_UpdateExistingValue(t *testing.T) {
209+
store, _ := setupTestStore(t)
210+
211+
originalUser := TestUser{
212+
ID: "1",
213+
Name: "John Doe",
214+
}
215+
216+
updatedUser := TestUser{
217+
ID: "1",
218+
Name: "John Doe Jr.",
219+
}
220+
221+
// Set original value
222+
err := store.Set("user1", originalUser)
223+
require.NoError(t, err)
224+
225+
// Update the value
226+
err = store.Set("user1", updatedUser)
227+
assert.NoError(t, err)
228+
229+
// Verify the update
230+
actualUser, err := store.Get("user1")
231+
assert.NoError(t, err)
232+
assert.Equal(t, updatedUser, actualUser)
233+
assert.NotEqual(t, originalUser, actualUser)
234+
}
235+
236+
func TestStore_Close(t *testing.T) {
237+
tmpDir := t.TempDir()
238+
239+
config := &Config{
240+
FileName: "test.db",
241+
BucketName: "test",
242+
}
243+
244+
store, err := newStorageStoreWithPath[TestUser](config, tmpDir)
245+
require.NoError(t, err)
246+
247+
// Close should not return an error
248+
err = store.Close()
249+
assert.NoError(t, err)
250+
}
251+
252+
func TestStore_WithDifferentTypes(t *testing.T) {
253+
tmpDir := t.TempDir()
254+
255+
t.Run("string values", func(t *testing.T) {
256+
config := &Config{
257+
FileName: "string_test.db",
258+
BucketName: "strings",
259+
}
260+
261+
store, err := newStorageStoreWithPath[string](config, tmpDir)
262+
require.NoError(t, err)
263+
defer func() {
264+
err = store.Close()
265+
require.Nil(t, err)
266+
}()
267+
268+
err = store.Set("key1", "hello world")
269+
require.NoError(t, err)
270+
271+
value, err := store.Get("key1")
272+
assert.NoError(t, err)
273+
assert.Equal(t, "hello world", value)
274+
})
275+
276+
t.Run("int values", func(t *testing.T) {
277+
config := &Config{
278+
FileName: "int_test.db",
279+
BucketName: "integers",
280+
}
281+
282+
store, err := newStorageStoreWithPath[int](config, tmpDir)
283+
require.NoError(t, err)
284+
defer func() {
285+
err = store.Close()
286+
require.Nil(t, err)
287+
}()
288+
289+
err = store.Set("key1", 42)
290+
require.NoError(t, err)
291+
292+
value, err := store.Get("key1")
293+
assert.NoError(t, err)
294+
assert.Equal(t, 42, value)
295+
})
296+
297+
t.Run("map values", func(t *testing.T) {
298+
config := &Config{
299+
FileName: "map_test.db",
300+
BucketName: "maps",
301+
}
302+
303+
store, err := newStorageStoreWithPath[map[string]string](config, tmpDir)
304+
require.NoError(t, err)
305+
defer func() {
306+
err = store.Close()
307+
require.Nil(t, err)
308+
}()
309+
310+
testMap := map[string]string{
311+
"foo": "bar",
312+
"baz": "qux",
313+
}
314+
315+
err = store.Set("key1", testMap)
316+
require.NoError(t, err)
317+
318+
value, err := store.Get("key1")
319+
assert.NoError(t, err)
320+
assert.Equal(t, testMap, value)
321+
})
322+
}
323+
324+
func TestStore_ConcurrentOperations(t *testing.T) {
325+
store, _ := setupTestStore(t)
326+
327+
// BoltDB handles concurrent reads well
328+
users := []TestUser{
329+
{ID: "1", Name: "User1"},
330+
{ID: "2", Name: "User2"},
331+
{ID: "3", Name: "User3"},
332+
}
333+
334+
// Set users sequentially
335+
for _, user := range users {
336+
err := store.Set(user.ID, user)
337+
require.NoError(t, err)
338+
}
339+
340+
// Get all users
341+
results, err := store.GetAll()
342+
assert.NoError(t, err)
343+
assert.Len(t, results, len(users))
344+
}

0 commit comments

Comments
 (0)