Add comprehensive test coverage for core functionalities
This commit introduces test cases for the API, archive, store, and filesystem functionalities, as well as a functional test for a full workflow. It ensures robust testing for snapshot operations, archiving, and blob management, significantly improving reliability.
This commit is contained in:
409
manager_test.go
Normal file
409
manager_test.go
Normal file
@ -0,0 +1,409 @@
|
||||
package agate
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"gitea.unprism.ru/KRBL/Agate/store"
|
||||
"gitea.unprism.ru/KRBL/Agate/store/filesystem"
|
||||
"gitea.unprism.ru/KRBL/Agate/store/sqlite"
|
||||
)
|
||||
|
||||
// setupTestEnvironment creates a temporary directory and initializes the stores
|
||||
func setupTestEnvironment(t *testing.T) (string, store.MetadataStore, store.BlobStore, func()) {
|
||||
// Create a temporary directory for tests
|
||||
tempDir, err := os.MkdirTemp("", "agate-test-*")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create temp directory: %v", err)
|
||||
}
|
||||
|
||||
// Create directories for metadata and blobs
|
||||
metadataDir := filepath.Join(tempDir, "metadata")
|
||||
blobsDir := filepath.Join(tempDir, "blobs")
|
||||
if err := os.MkdirAll(metadataDir, 0755); err != nil {
|
||||
os.RemoveAll(tempDir)
|
||||
t.Fatalf("Failed to create metadata directory: %v", err)
|
||||
}
|
||||
if err := os.MkdirAll(blobsDir, 0755); err != nil {
|
||||
os.RemoveAll(tempDir)
|
||||
t.Fatalf("Failed to create blobs directory: %v", err)
|
||||
}
|
||||
|
||||
// Initialize the stores
|
||||
dbPath := filepath.Join(metadataDir, "snapshots.db")
|
||||
metadataStore, err := sqlite.NewSQLiteStore(dbPath)
|
||||
if err != nil {
|
||||
os.RemoveAll(tempDir)
|
||||
t.Fatalf("Failed to create metadata store: %v", err)
|
||||
}
|
||||
|
||||
blobStore, err := filesystem.NewFileSystemStore(blobsDir)
|
||||
if err != nil {
|
||||
metadataStore.Close()
|
||||
os.RemoveAll(tempDir)
|
||||
t.Fatalf("Failed to create blob store: %v", err)
|
||||
}
|
||||
|
||||
// Return a cleanup function
|
||||
cleanup := func() {
|
||||
metadataStore.Close()
|
||||
os.RemoveAll(tempDir)
|
||||
}
|
||||
|
||||
return tempDir, metadataStore, blobStore, cleanup
|
||||
}
|
||||
|
||||
// createTestFiles creates test files in the specified directory
|
||||
func createTestFiles(t *testing.T, dir string) {
|
||||
// Create a subdirectory
|
||||
subDir := filepath.Join(dir, "subdir")
|
||||
if err := os.MkdirAll(subDir, 0755); err != nil {
|
||||
t.Fatalf("Failed to create subdirectory: %v", err)
|
||||
}
|
||||
|
||||
// Create some test files
|
||||
testFiles := map[string]string{
|
||||
filepath.Join(dir, "file1.txt"): "This is file 1",
|
||||
filepath.Join(dir, "file2.txt"): "This is file 2",
|
||||
filepath.Join(subDir, "subfile1.txt"): "This is subfile 1",
|
||||
filepath.Join(subDir, "subfile2.txt"): "This is subfile 2",
|
||||
}
|
||||
|
||||
for path, content := range testFiles {
|
||||
if err := os.WriteFile(path, []byte(content), 0644); err != nil {
|
||||
t.Fatalf("Failed to create test file %s: %v", path, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateAndGetSnapshot(t *testing.T) {
|
||||
tempDir, metadataStore, blobStore, cleanup := setupTestEnvironment(t)
|
||||
defer cleanup()
|
||||
|
||||
// Create a source directory with test files
|
||||
sourceDir := filepath.Join(tempDir, "source")
|
||||
if err := os.MkdirAll(sourceDir, 0755); err != nil {
|
||||
t.Fatalf("Failed to create source directory: %v", err)
|
||||
}
|
||||
createTestFiles(t, sourceDir)
|
||||
|
||||
// Create a snapshot manager
|
||||
manager, err := CreateSnapshotManager(metadataStore, blobStore)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create snapshot manager: %v", err)
|
||||
}
|
||||
|
||||
// Create a snapshot
|
||||
ctx := context.Background()
|
||||
snapshot, err := manager.CreateSnapshot(ctx, sourceDir, "Test Snapshot", "")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create snapshot: %v", err)
|
||||
}
|
||||
|
||||
// Check that the snapshot was created with the correct name
|
||||
if snapshot.Name != "Test Snapshot" {
|
||||
t.Errorf("Snapshot has wrong name: got %s, want %s", snapshot.Name, "Test Snapshot")
|
||||
}
|
||||
|
||||
// Check that the snapshot has the correct number of files
|
||||
if len(snapshot.Files) != 5 { // 4 files + 1 directory
|
||||
t.Errorf("Snapshot has wrong number of files: got %d, want %d", len(snapshot.Files), 5)
|
||||
}
|
||||
|
||||
// Get the snapshot details
|
||||
retrievedSnapshot, err := manager.GetSnapshotDetails(ctx, snapshot.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get snapshot details: %v", err)
|
||||
}
|
||||
|
||||
// Check that the retrieved snapshot matches the original
|
||||
if retrievedSnapshot.ID != snapshot.ID {
|
||||
t.Errorf("Retrieved snapshot ID does not match: got %s, want %s", retrievedSnapshot.ID, snapshot.ID)
|
||||
}
|
||||
if retrievedSnapshot.Name != snapshot.Name {
|
||||
t.Errorf("Retrieved snapshot name does not match: got %s, want %s", retrievedSnapshot.Name, snapshot.Name)
|
||||
}
|
||||
if len(retrievedSnapshot.Files) != len(snapshot.Files) {
|
||||
t.Errorf("Retrieved snapshot has wrong number of files: got %d, want %d", len(retrievedSnapshot.Files), len(snapshot.Files))
|
||||
}
|
||||
}
|
||||
|
||||
func TestListSnapshots(t *testing.T) {
|
||||
tempDir, metadataStore, blobStore, cleanup := setupTestEnvironment(t)
|
||||
defer cleanup()
|
||||
|
||||
// Create a source directory with test files
|
||||
sourceDir := filepath.Join(tempDir, "source")
|
||||
if err := os.MkdirAll(sourceDir, 0755); err != nil {
|
||||
t.Fatalf("Failed to create source directory: %v", err)
|
||||
}
|
||||
createTestFiles(t, sourceDir)
|
||||
|
||||
// Create a snapshot manager
|
||||
manager, err := CreateSnapshotManager(metadataStore, blobStore)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create snapshot manager: %v", err)
|
||||
}
|
||||
|
||||
// Create multiple snapshots
|
||||
ctx := context.Background()
|
||||
snapshot1, err := manager.CreateSnapshot(ctx, sourceDir, "Snapshot 1", "")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create snapshot: %v", err)
|
||||
}
|
||||
|
||||
// Modify a file
|
||||
if err := os.WriteFile(filepath.Join(sourceDir, "file1.txt"), []byte("Modified file 1"), 0644); err != nil {
|
||||
t.Fatalf("Failed to modify test file: %v", err)
|
||||
}
|
||||
|
||||
snapshot2, err := manager.CreateSnapshot(ctx, sourceDir, "Snapshot 2", snapshot1.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create snapshot: %v", err)
|
||||
}
|
||||
|
||||
// List the snapshots
|
||||
snapshots, err := manager.ListSnapshots(ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to list snapshots: %v", err)
|
||||
}
|
||||
|
||||
// Check that both snapshots are listed
|
||||
if len(snapshots) != 2 {
|
||||
t.Errorf("Wrong number of snapshots listed: got %d, want %d", len(snapshots), 2)
|
||||
}
|
||||
|
||||
// Check that the snapshots have the correct information
|
||||
for _, snap := range snapshots {
|
||||
if snap.ID == snapshot1.ID {
|
||||
if snap.Name != "Snapshot 1" {
|
||||
t.Errorf("Snapshot 1 has wrong name: got %s, want %s", snap.Name, "Snapshot 1")
|
||||
}
|
||||
if snap.ParentID != "" {
|
||||
t.Errorf("Snapshot 1 has wrong parent ID: got %s, want %s", snap.ParentID, "")
|
||||
}
|
||||
} else if snap.ID == snapshot2.ID {
|
||||
if snap.Name != "Snapshot 2" {
|
||||
t.Errorf("Snapshot 2 has wrong name: got %s, want %s", snap.Name, "Snapshot 2")
|
||||
}
|
||||
if snap.ParentID != snapshot1.ID {
|
||||
t.Errorf("Snapshot 2 has wrong parent ID: got %s, want %s", snap.ParentID, snapshot1.ID)
|
||||
}
|
||||
} else {
|
||||
t.Errorf("Unexpected snapshot ID: %s", snap.ID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteSnapshot(t *testing.T) {
|
||||
tempDir, metadataStore, blobStore, cleanup := setupTestEnvironment(t)
|
||||
defer cleanup()
|
||||
|
||||
// Create a source directory with test files
|
||||
sourceDir := filepath.Join(tempDir, "source")
|
||||
if err := os.MkdirAll(sourceDir, 0755); err != nil {
|
||||
t.Fatalf("Failed to create source directory: %v", err)
|
||||
}
|
||||
createTestFiles(t, sourceDir)
|
||||
|
||||
// Create a snapshot manager
|
||||
manager, err := CreateSnapshotManager(metadataStore, blobStore)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create snapshot manager: %v", err)
|
||||
}
|
||||
|
||||
// Create a snapshot
|
||||
ctx := context.Background()
|
||||
snapshot, err := manager.CreateSnapshot(ctx, sourceDir, "Test Snapshot", "")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create snapshot: %v", err)
|
||||
}
|
||||
|
||||
// Delete the snapshot
|
||||
err = manager.DeleteSnapshot(ctx, snapshot.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to delete snapshot: %v", err)
|
||||
}
|
||||
|
||||
// Try to get the deleted snapshot
|
||||
_, err = manager.GetSnapshotDetails(ctx, snapshot.ID)
|
||||
if err == nil {
|
||||
t.Fatalf("Expected error when getting deleted snapshot, got nil")
|
||||
}
|
||||
|
||||
// List snapshots to confirm it's gone
|
||||
snapshots, err := manager.ListSnapshots(ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to list snapshots: %v", err)
|
||||
}
|
||||
if len(snapshots) != 0 {
|
||||
t.Errorf("Expected 0 snapshots after deletion, got %d", len(snapshots))
|
||||
}
|
||||
}
|
||||
|
||||
func TestOpenFile(t *testing.T) {
|
||||
_, metadataStore, blobStore, cleanup := setupTestEnvironment(t)
|
||||
defer cleanup()
|
||||
|
||||
// Create a source directory with test files
|
||||
sourceDir := filepath.Join(blobStore.GetActiveDir(), "source")
|
||||
if err := os.MkdirAll(sourceDir, 0755); err != nil {
|
||||
t.Fatalf("Failed to create source directory: %v", err)
|
||||
}
|
||||
createTestFiles(t, sourceDir)
|
||||
|
||||
// Create a snapshot manager
|
||||
manager, err := CreateSnapshotManager(metadataStore, blobStore)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create snapshot manager: %v", err)
|
||||
}
|
||||
|
||||
// Create a snapshot
|
||||
ctx := context.Background()
|
||||
snapshot, err := manager.CreateSnapshot(ctx, sourceDir, "Test Snapshot", "")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create snapshot: %v", err)
|
||||
}
|
||||
|
||||
// Open a file from the snapshot
|
||||
fileReader, err := manager.OpenFile(ctx, snapshot.ID, "file1.txt")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to open file from snapshot: %v", err)
|
||||
}
|
||||
defer fileReader.Close()
|
||||
|
||||
// Read the file content
|
||||
content, err := io.ReadAll(fileReader)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read file content: %v", err)
|
||||
}
|
||||
|
||||
// Check that the content matches the original
|
||||
if string(content) != "This is file 1" {
|
||||
t.Errorf("File content does not match: got %s, want %s", string(content), "This is file 1")
|
||||
}
|
||||
|
||||
// Try to open a non-existent file
|
||||
pipe, err := manager.OpenFile(ctx, snapshot.ID, "nonexistent.txt")
|
||||
if err == nil {
|
||||
tmp := make([]byte, 1)
|
||||
_, err = pipe.Read(tmp)
|
||||
|
||||
if err == nil {
|
||||
t.Fatalf("Expected error when opening non-existent file, got nil")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractSnapshot(t *testing.T) {
|
||||
tempDir, metadataStore, blobStore, cleanup := setupTestEnvironment(t)
|
||||
defer cleanup()
|
||||
|
||||
// Create a source directory with test files
|
||||
sourceDir := filepath.Join(tempDir, "source")
|
||||
if err := os.MkdirAll(sourceDir, 0755); err != nil {
|
||||
t.Fatalf("Failed to create source directory: %v", err)
|
||||
}
|
||||
createTestFiles(t, sourceDir)
|
||||
|
||||
// Create a snapshot manager
|
||||
manager, err := CreateSnapshotManager(metadataStore, blobStore)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create snapshot manager: %v", err)
|
||||
}
|
||||
|
||||
// Create a snapshot
|
||||
ctx := context.Background()
|
||||
snapshot, err := manager.CreateSnapshot(ctx, sourceDir, "Test Snapshot", "")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create snapshot: %v", err)
|
||||
}
|
||||
|
||||
// Create a target directory for extraction
|
||||
targetDir := filepath.Join(tempDir, "target")
|
||||
if err := os.MkdirAll(targetDir, 0755); err != nil {
|
||||
t.Fatalf("Failed to create target directory: %v", err)
|
||||
}
|
||||
|
||||
// Extract the snapshot
|
||||
err = manager.ExtractSnapshot(ctx, snapshot.ID, targetDir)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to extract snapshot: %v", err)
|
||||
}
|
||||
|
||||
// Check that the files were extracted correctly
|
||||
testFiles := map[string]string{
|
||||
filepath.Join(targetDir, "file1.txt"): "This is file 1",
|
||||
filepath.Join(targetDir, "file2.txt"): "This is file 2",
|
||||
filepath.Join(targetDir, "subdir/subfile1.txt"): "This is subfile 1",
|
||||
filepath.Join(targetDir, "subdir/subfile2.txt"): "This is subfile 2",
|
||||
}
|
||||
|
||||
for path, expectedContent := range testFiles {
|
||||
content, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read extracted file %s: %v", path, err)
|
||||
}
|
||||
if string(content) != expectedContent {
|
||||
t.Errorf("Extracted file %s has wrong content: got %s, want %s", path, string(content), expectedContent)
|
||||
}
|
||||
}
|
||||
|
||||
// Try to extract a non-existent snapshot
|
||||
err = manager.ExtractSnapshot(ctx, "nonexistent-id", targetDir)
|
||||
if err == nil {
|
||||
t.Fatalf("Expected error when extracting non-existent snapshot, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateSnapshotMetadata(t *testing.T) {
|
||||
tempDir, metadataStore, blobStore, cleanup := setupTestEnvironment(t)
|
||||
defer cleanup()
|
||||
|
||||
// Create a source directory with test files
|
||||
sourceDir := filepath.Join(tempDir, "source")
|
||||
if err := os.MkdirAll(sourceDir, 0755); err != nil {
|
||||
t.Fatalf("Failed to create source directory: %v", err)
|
||||
}
|
||||
createTestFiles(t, sourceDir)
|
||||
|
||||
// Create a snapshot manager
|
||||
manager, err := CreateSnapshotManager(metadataStore, blobStore)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create snapshot manager: %v", err)
|
||||
}
|
||||
|
||||
// Create a snapshot
|
||||
ctx := context.Background()
|
||||
snapshot, err := manager.CreateSnapshot(ctx, sourceDir, "Test Snapshot", "")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create snapshot: %v", err)
|
||||
}
|
||||
|
||||
// Update the snapshot metadata
|
||||
newName := "Updated Snapshot Name"
|
||||
err = manager.UpdateSnapshotMetadata(ctx, snapshot.ID, newName)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to update snapshot metadata: %v", err)
|
||||
}
|
||||
|
||||
// Get the updated snapshot
|
||||
updatedSnapshot, err := manager.GetSnapshotDetails(ctx, snapshot.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get updated snapshot: %v", err)
|
||||
}
|
||||
|
||||
// Check that the name was updated
|
||||
if updatedSnapshot.Name != newName {
|
||||
t.Errorf("Snapshot name was not updated: got %s, want %s", updatedSnapshot.Name, newName)
|
||||
}
|
||||
|
||||
// Try to update a non-existent snapshot
|
||||
err = manager.UpdateSnapshotMetadata(ctx, "nonexistent-id", "New Name")
|
||||
if err == nil {
|
||||
t.Fatalf("Expected error when updating non-existent snapshot, got nil")
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user