- Add pure Go SQLite driver (modernc.org/sqlite) to avoid CGO dependency - Implement database connection management with WAL mode - Add write mutex for serializing concurrent writes - Create schema for all tables matching DESIGN.md specifications - Implement repository pattern for all database entities: - Files, FileChunks, Chunks, Blobs, BlobChunks, ChunkFiles, Snapshots - Add transaction support with proper rollback handling - Add fatal error handling for database integrity issues - Add snapshot fields for tracking file sizes and compression ratios - Make index path configurable via VAULTIK_INDEX_PATH environment variable - Add comprehensive test coverage for all repositories - Add format check to Makefile to ensure code formatting
101 lines
2.2 KiB
Go
101 lines
2.2 KiB
Go
package database
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestBlobRepository(t *testing.T) {
|
|
db, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
ctx := context.Background()
|
|
repo := NewBlobRepository(db)
|
|
|
|
// Test Create
|
|
blob := &Blob{
|
|
BlobHash: "blobhash123",
|
|
CreatedTS: time.Now().Truncate(time.Second),
|
|
}
|
|
|
|
err := repo.Create(ctx, nil, blob)
|
|
if err != nil {
|
|
t.Fatalf("failed to create blob: %v", err)
|
|
}
|
|
|
|
// Test GetByHash
|
|
retrieved, err := repo.GetByHash(ctx, blob.BlobHash)
|
|
if err != nil {
|
|
t.Fatalf("failed to get blob: %v", err)
|
|
}
|
|
if retrieved == nil {
|
|
t.Fatal("expected blob, got nil")
|
|
}
|
|
if retrieved.BlobHash != blob.BlobHash {
|
|
t.Errorf("blob hash mismatch: got %s, want %s", retrieved.BlobHash, blob.BlobHash)
|
|
}
|
|
if !retrieved.CreatedTS.Equal(blob.CreatedTS) {
|
|
t.Errorf("created timestamp mismatch: got %v, want %v", retrieved.CreatedTS, blob.CreatedTS)
|
|
}
|
|
|
|
// Test List
|
|
blob2 := &Blob{
|
|
BlobHash: "blobhash456",
|
|
CreatedTS: time.Now().Truncate(time.Second),
|
|
}
|
|
err = repo.Create(ctx, nil, blob2)
|
|
if err != nil {
|
|
t.Fatalf("failed to create second blob: %v", err)
|
|
}
|
|
|
|
blobs, err := repo.List(ctx, 10, 0)
|
|
if err != nil {
|
|
t.Fatalf("failed to list blobs: %v", err)
|
|
}
|
|
if len(blobs) != 2 {
|
|
t.Errorf("expected 2 blobs, got %d", len(blobs))
|
|
}
|
|
|
|
// Test pagination
|
|
blobs, err = repo.List(ctx, 1, 0)
|
|
if err != nil {
|
|
t.Fatalf("failed to list blobs with limit: %v", err)
|
|
}
|
|
if len(blobs) != 1 {
|
|
t.Errorf("expected 1 blob with limit, got %d", len(blobs))
|
|
}
|
|
|
|
blobs, err = repo.List(ctx, 1, 1)
|
|
if err != nil {
|
|
t.Fatalf("failed to list blobs with offset: %v", err)
|
|
}
|
|
if len(blobs) != 1 {
|
|
t.Errorf("expected 1 blob with offset, got %d", len(blobs))
|
|
}
|
|
}
|
|
|
|
func TestBlobRepositoryDuplicate(t *testing.T) {
|
|
db, cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
ctx := context.Background()
|
|
repo := NewBlobRepository(db)
|
|
|
|
blob := &Blob{
|
|
BlobHash: "duplicate_blob",
|
|
CreatedTS: time.Now().Truncate(time.Second),
|
|
}
|
|
|
|
err := repo.Create(ctx, nil, blob)
|
|
if err != nil {
|
|
t.Fatalf("failed to create blob: %v", err)
|
|
}
|
|
|
|
// Try to create duplicate - should fail due to unique constraint
|
|
err = repo.Create(ctx, nil, blob)
|
|
if err == nil {
|
|
t.Error("expected error for duplicate blob")
|
|
}
|
|
}
|