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.
287 lines
7.7 KiB
Go
287 lines
7.7 KiB
Go
package agate
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
// setupTestAPI creates a temporary directory and initializes an Agate instance
|
|
func setupTestAPI(t *testing.T) (*Agate, string, 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 a data directory
|
|
dataDir := filepath.Join(tempDir)
|
|
if err := os.MkdirAll(dataDir, 0755); err != nil {
|
|
os.RemoveAll(tempDir)
|
|
t.Fatalf("Failed to create data directory: %v", err)
|
|
}
|
|
|
|
// Create test files
|
|
createAPITestFiles(t, filepath.Join(dataDir, "blobs", "active"))
|
|
|
|
// Create Agate options
|
|
options := AgateOptions{
|
|
WorkDir: dataDir,
|
|
OpenFunc: func(dir string) error {
|
|
return nil
|
|
},
|
|
CloseFunc: func() error {
|
|
return nil
|
|
},
|
|
}
|
|
|
|
// Create Agate instance
|
|
ag, err := New(options)
|
|
if err != nil {
|
|
os.RemoveAll(tempDir)
|
|
t.Fatalf("Failed to create Agate instance: %v", err)
|
|
}
|
|
|
|
// Return a cleanup function
|
|
cleanup := func() {
|
|
ag.Close()
|
|
os.RemoveAll(tempDir)
|
|
}
|
|
|
|
return ag, tempDir, cleanup
|
|
}
|
|
|
|
// createAPITestFiles creates test files in the specified directory
|
|
func createAPITestFiles(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 TestNewAgate(t *testing.T) {
|
|
// Create a temporary directory for tests
|
|
tempDir, err := os.MkdirTemp("", "agate-test-*")
|
|
if err != nil {
|
|
t.Fatalf("Failed to create temp directory: %v", err)
|
|
}
|
|
defer os.RemoveAll(tempDir)
|
|
|
|
// Create a data directory
|
|
dataDir := filepath.Join(tempDir, "data")
|
|
if err := os.MkdirAll(dataDir, 0755); err != nil {
|
|
t.Fatalf("Failed to create data directory: %v", err)
|
|
}
|
|
|
|
// Create Agate options
|
|
options := AgateOptions{
|
|
WorkDir: dataDir,
|
|
OpenFunc: func(dir string) error {
|
|
return nil
|
|
},
|
|
CloseFunc: func() error {
|
|
return nil
|
|
},
|
|
}
|
|
|
|
// Create Agate instance
|
|
ag, err := New(options)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create Agate instance: %v", err)
|
|
}
|
|
defer ag.Close()
|
|
|
|
// Check that the Agate instance was created successfully
|
|
if ag == nil {
|
|
t.Fatalf("Agate instance is nil")
|
|
}
|
|
}
|
|
|
|
func TestSaveAndRestoreSnapshot(t *testing.T) {
|
|
ag, _, cleanup := setupTestAPI(t)
|
|
defer cleanup()
|
|
|
|
// Create a snapshot
|
|
ctx := context.Background()
|
|
snapshotID, err := ag.SaveSnapshot(ctx, "Test Snapshot", "")
|
|
if err != nil {
|
|
t.Fatalf("Failed to create snapshot: %v", err)
|
|
}
|
|
|
|
// Check that the snapshot was created with the correct name
|
|
snapshot, err := ag.GetSnapshotDetails(ctx, snapshotID)
|
|
if err != nil {
|
|
t.Fatalf("Failed to get snapshot details: %v", err)
|
|
}
|
|
if snapshot.Name != "Test Snapshot" {
|
|
t.Errorf("Snapshot has wrong name: got %s, want %s", snapshot.Name, "Test Snapshot")
|
|
}
|
|
|
|
// Modify a file
|
|
dataDir := ag.options.BlobStore.GetActiveDir()
|
|
if err := os.WriteFile(filepath.Join(dataDir, "file1.txt"), []byte("Modified file 1"), 0644); err != nil {
|
|
t.Fatalf("Failed to modify test file: %v", err)
|
|
}
|
|
|
|
// Restore the snapshot
|
|
err = ag.RestoreSnapshot(ctx, snapshotID)
|
|
if err != nil {
|
|
t.Fatalf("Failed to restore snapshot: %v", err)
|
|
}
|
|
|
|
// Check that the file was restored
|
|
content, err := os.ReadFile(filepath.Join(dataDir, "file1.txt"))
|
|
if err != nil {
|
|
t.Fatalf("Failed to read restored file: %v", err)
|
|
}
|
|
if string(content) != "This is file 1" {
|
|
t.Errorf("File content was not restored: got %s, want %s", string(content), "This is file 1")
|
|
}
|
|
}
|
|
|
|
func TestRestoreSnapshotToDir(t *testing.T) {
|
|
ag, tempDir, cleanup := setupTestAPI(t)
|
|
defer cleanup()
|
|
|
|
// Create a snapshot
|
|
ctx := context.Background()
|
|
snapshotID, err := ag.SaveSnapshot(ctx, "Test Snapshot", "")
|
|
if err != nil {
|
|
t.Fatalf("Failed to create snapshot: %v", err)
|
|
}
|
|
|
|
// Create a target directory
|
|
targetDir := filepath.Join(tempDir, "target")
|
|
if err := os.MkdirAll(targetDir, 0755); err != nil {
|
|
t.Fatalf("Failed to create target directory: %v", err)
|
|
}
|
|
|
|
// Restore the snapshot to the target directory
|
|
err = ag.RestoreSnapshotToDir(ctx, snapshotID, targetDir)
|
|
if err != nil {
|
|
t.Fatalf("Failed to restore snapshot to directory: %v", err)
|
|
}
|
|
|
|
// Check that the files were restored
|
|
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 restored file %s: %v", path, err)
|
|
}
|
|
if string(content) != expectedContent {
|
|
t.Errorf("Restored file %s has wrong content: got %s, want %s", path, string(content), expectedContent)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAPIListSnapshots(t *testing.T) {
|
|
ag, _, cleanup := setupTestAPI(t)
|
|
defer cleanup()
|
|
|
|
// Create multiple snapshots
|
|
ctx := context.Background()
|
|
snapshotID1, err := ag.SaveSnapshot(ctx, "Snapshot 1", "")
|
|
if err != nil {
|
|
t.Fatalf("Failed to create snapshot: %v", err)
|
|
}
|
|
|
|
// Modify a file
|
|
dataDir := ag.options.WorkDir
|
|
if err := os.WriteFile(filepath.Join(dataDir, "file1.txt"), []byte("Modified file 1"), 0644); err != nil {
|
|
t.Fatalf("Failed to modify test file: %v", err)
|
|
}
|
|
|
|
snapshotID2, err := ag.SaveSnapshot(ctx, "Snapshot 2", snapshotID1)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create snapshot: %v", err)
|
|
}
|
|
|
|
// List the snapshots
|
|
snapshots, err := ag.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 == snapshotID1 {
|
|
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 == snapshotID2 {
|
|
if snap.Name != "Snapshot 2" {
|
|
t.Errorf("Snapshot 2 has wrong name: got %s, want %s", snap.Name, "Snapshot 2")
|
|
}
|
|
if snap.ParentID != snapshotID1 {
|
|
t.Errorf("Snapshot 2 has wrong parent ID: got %s, want %s", snap.ParentID, snapshotID1)
|
|
}
|
|
} else {
|
|
t.Errorf("Unexpected snapshot ID: %s", snap.ID)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAPIDeleteSnapshot(t *testing.T) {
|
|
ag, _, cleanup := setupTestAPI(t)
|
|
defer cleanup()
|
|
|
|
// Create a snapshot
|
|
ctx := context.Background()
|
|
snapshotID, err := ag.SaveSnapshot(ctx, "Test Snapshot", "")
|
|
if err != nil {
|
|
t.Fatalf("Failed to create snapshot: %v", err)
|
|
}
|
|
|
|
// Delete the snapshot
|
|
err = ag.DeleteSnapshot(ctx, snapshotID)
|
|
if err != nil {
|
|
t.Fatalf("Failed to delete snapshot: %v", err)
|
|
}
|
|
|
|
// Try to get the deleted snapshot
|
|
_, err = ag.GetSnapshotDetails(ctx, snapshotID)
|
|
if err == nil {
|
|
t.Fatalf("Expected error when getting deleted snapshot, got nil")
|
|
}
|
|
|
|
// List snapshots to confirm it's gone
|
|
snapshots, err := ag.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))
|
|
}
|
|
}
|