Files
2026-04-21 11:47:56 +02:00

163 lines
3.5 KiB
Go

package store
import (
"os"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.etcd.io/bbolt"
bbolterrors "go.etcd.io/bbolt/errors"
)
func TestBoltStore(t *testing.T) {
dbPath := "test.db"
defer os.Remove(dbPath)
s, err := NewBoltStore(dbPath, nil)
require.NoError(t, err)
defer s.Close()
t.Run("Open Existing Store", func(t *testing.T) {
dbPath := "existing_store.db"
defer os.Remove(dbPath)
s1, err := NewBoltStore(dbPath, nil)
require.NoError(t, err)
err = s1.Close()
require.NoError(t, err)
s2, err := NewBoltStore(dbPath, nil)
require.NoError(t, err)
defer s2.Close()
assert.NotNil(t, s2)
})
t.Run("Set and Get", func(t *testing.T) {
id := "id1"
hash := "hash1"
content := "content1"
err := s.Set(id, hash, content, nil)
assert.NoError(t, err)
p, exists, err := s.Get(id)
assert.NoError(t, err)
assert.True(t, exists)
assert.Equal(t, content, p.Content)
})
t.Run("GetIDByHash", func(t *testing.T) {
id := "id2"
hash := "hash2"
content := "content2"
s.Set(id, hash, content, nil)
storedID, exists, err := s.GetIDByHash(hash)
assert.NoError(t, err)
assert.True(t, exists)
assert.Equal(t, id, storedID)
})
t.Run("Del", func(t *testing.T) {
id := "id3"
s.Set(id, "h3", "c3", nil)
err := s.Del(id)
assert.NoError(t, err)
_, exists, _ := s.Get(id)
assert.False(t, exists)
_, hashExists, _ := s.GetIDByHash("h3")
assert.False(t, hashExists)
})
t.Run("Cleanup", func(t *testing.T) {
s.Set("old", "oldhash", "oldcontent", nil)
s.Cleanup(-time.Hour)
_, exists, _ := s.Get("old")
assert.False(t, exists)
_, hashExists, _ := s.GetIDByHash("oldhash")
assert.False(t, hashExists)
})
t.Run("Cleanup Bad Data", func(t *testing.T) {
s.db.Update(func(tx *bbolt.Tx) error {
return tx.Bucket(pastesBucket).Put([]byte("bad"), []byte("invalid json"))
})
s.Cleanup(-time.Hour)
// Should skip without panic
})
t.Run("Set Marshal Error", func(t *testing.T) {
dbPath := "marshal_error.db"
db, _ := bbolt.Open(dbPath, 0666, nil)
store := &BoltStore{db: db}
defer db.Close()
defer os.Remove(dbPath)
err := store.Set("id", "h", "c", map[string]interface{}{
"foo": func() {},
})
assert.Error(t, err)
})
t.Run("Set Put Error", func(t *testing.T) {
dbPath := "put_error.db"
s, err := NewBoltStore(dbPath, nil)
require.NoError(t, err)
defer s.Close()
defer os.Remove(dbPath)
err = s.Set("", "hash", "content", nil)
assert.ErrorIs(t, err, bbolterrors.ErrKeyRequired)
})
t.Run("Del Error", func(t *testing.T) {
dbPath := "error_del.db"
db, _ := bbolt.Open(dbPath, 0666, nil)
store := &BoltStore{db: db}
db.Close()
err := store.Del("id")
assert.Error(t, err)
os.Remove(dbPath)
})
t.Run("Get Error", func(t *testing.T) {
dbPath := "error_get.db"
db, _ := bbolt.Open(dbPath, 0666, nil)
store := &BoltStore{db: db}
db.Close()
_, _, err := store.Get("id")
assert.Error(t, err)
os.Remove(dbPath)
})
}
func TestNewBoltStoreError(t *testing.T) {
err := os.Mkdir("testdir", 0755)
require.NoError(t, err)
defer os.RemoveAll("testdir")
s, err := NewBoltStore("testdir", nil)
assert.Error(t, err)
assert.Nil(t, s)
t.Run("Bucket Creation Error", func(t *testing.T) {
dbPath := "bucket_error.db"
defer os.Remove(dbPath)
originalPastesBucket := pastesBucket
pastesBucket = []byte("")
defer func() { pastesBucket = originalPastesBucket }()
s, err := NewBoltStore(dbPath, nil)
assert.ErrorIs(t, err, bbolterrors.ErrBucketNameRequired)
assert.Nil(t, s)
})
}