400 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			400 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package sqlite
 | 
						|
 | 
						|
import (
 | 
						|
	"context"
 | 
						|
	"os"
 | 
						|
	"path/filepath"
 | 
						|
	"testing"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"gitea.unprism.ru/KRBL/Agate/store"
 | 
						|
)
 | 
						|
 | 
						|
func TestNewSQLiteStore(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) // Clean up after test
 | 
						|
 | 
						|
	// Create a new store
 | 
						|
	dbPath := filepath.Join(tempDir, "test.db")
 | 
						|
	s, err := NewSQLiteStore(dbPath)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatalf("Failed to create SQLite store: %v", err)
 | 
						|
	}
 | 
						|
	defer s.Close()
 | 
						|
 | 
						|
	// Check that the database file was created
 | 
						|
	if _, err := os.Stat(dbPath); os.IsNotExist(err) {
 | 
						|
		t.Fatalf("Database file was not created")
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestSaveAndGetSnapshotMetadata(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) // Clean up after test
 | 
						|
 | 
						|
	// Create a new store
 | 
						|
	dbPath := filepath.Join(tempDir, "test.db")
 | 
						|
	s, err := NewSQLiteStore(dbPath)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatalf("Failed to create SQLite store: %v", err)
 | 
						|
	}
 | 
						|
	defer s.Close()
 | 
						|
 | 
						|
	// Create a test snapshot
 | 
						|
	now := time.Now().UTC().Truncate(time.Second) // SQLite doesn't store nanoseconds
 | 
						|
	testSnapshot := store.Snapshot{
 | 
						|
		ID:           "test-snapshot-id",
 | 
						|
		Name:         "Test Snapshot",
 | 
						|
		ParentID:     "parent-snapshot-id",
 | 
						|
		CreationTime: now,
 | 
						|
		Files: []store.FileInfo{
 | 
						|
			{
 | 
						|
				Path:   "/test/file1.txt",
 | 
						|
				Size:   100,
 | 
						|
				IsDir:  false,
 | 
						|
				SHA256: "hash1",
 | 
						|
			},
 | 
						|
			{
 | 
						|
				Path:   "/test/dir1",
 | 
						|
				Size:   0,
 | 
						|
				IsDir:  true,
 | 
						|
				SHA256: "",
 | 
						|
			},
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	// Save the snapshot
 | 
						|
	ctx := context.Background()
 | 
						|
	err = s.SaveSnapshotMetadata(ctx, testSnapshot)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatalf("Failed to save snapshot metadata: %v", err)
 | 
						|
	}
 | 
						|
 | 
						|
	// Retrieve the snapshot
 | 
						|
	retrievedSnapshot, err := s.GetSnapshotMetadata(ctx, testSnapshot.ID)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatalf("Failed to retrieve snapshot metadata: %v", err)
 | 
						|
	}
 | 
						|
 | 
						|
	// Check that the retrieved snapshot matches the original
 | 
						|
	if retrievedSnapshot.ID != testSnapshot.ID {
 | 
						|
		t.Errorf("Retrieved snapshot ID does not match: got %s, want %s", retrievedSnapshot.ID, testSnapshot.ID)
 | 
						|
	}
 | 
						|
	if retrievedSnapshot.Name != testSnapshot.Name {
 | 
						|
		t.Errorf("Retrieved snapshot name does not match: got %s, want %s", retrievedSnapshot.Name, testSnapshot.Name)
 | 
						|
	}
 | 
						|
	if retrievedSnapshot.ParentID != testSnapshot.ParentID {
 | 
						|
		t.Errorf("Retrieved snapshot parent ID does not match: got %s, want %s", retrievedSnapshot.ParentID, testSnapshot.ParentID)
 | 
						|
	}
 | 
						|
	if !retrievedSnapshot.CreationTime.Equal(testSnapshot.CreationTime) {
 | 
						|
		t.Errorf("Retrieved snapshot creation time does not match: got %v, want %v", retrievedSnapshot.CreationTime, testSnapshot.CreationTime)
 | 
						|
	}
 | 
						|
	if len(retrievedSnapshot.Files) != len(testSnapshot.Files) {
 | 
						|
		t.Errorf("Retrieved snapshot has wrong number of files: got %d, want %d", len(retrievedSnapshot.Files), len(testSnapshot.Files))
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestListSnapshotsMetadata(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) // Clean up after test
 | 
						|
 | 
						|
	// Create a new store
 | 
						|
	dbPath := filepath.Join(tempDir, "test.db")
 | 
						|
	s, err := NewSQLiteStore(dbPath)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatalf("Failed to create SQLite store: %v", err)
 | 
						|
	}
 | 
						|
	defer s.Close()
 | 
						|
 | 
						|
	// Create test snapshots
 | 
						|
	ctx := context.Background()
 | 
						|
	now := time.Now().UTC().Truncate(time.Second)
 | 
						|
 | 
						|
	testSnapshots := []store.Snapshot{
 | 
						|
		{
 | 
						|
			ID:           "snapshot-1",
 | 
						|
			Name:         "Snapshot 1",
 | 
						|
			ParentID:     "",
 | 
						|
			CreationTime: now.Add(-2 * time.Hour),
 | 
						|
			Files:        []store.FileInfo{},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			ID:           "snapshot-2",
 | 
						|
			Name:         "Snapshot 2",
 | 
						|
			ParentID:     "snapshot-1",
 | 
						|
			CreationTime: now.Add(-1 * time.Hour),
 | 
						|
			Files:        []store.FileInfo{},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			ID:           "snapshot-3",
 | 
						|
			Name:         "Snapshot 3",
 | 
						|
			ParentID:     "snapshot-2",
 | 
						|
			CreationTime: now,
 | 
						|
			Files:        []store.FileInfo{},
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	// Save the snapshots
 | 
						|
	for _, snap := range testSnapshots {
 | 
						|
		err = s.SaveSnapshotMetadata(ctx, snap)
 | 
						|
		if err != nil {
 | 
						|
			t.Fatalf("Failed to save snapshot metadata: %v", err)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// List the snapshots with empty options
 | 
						|
	snapshots, err := s.ListSnapshotsMetadata(ctx, store.ListOptions{})
 | 
						|
	if err != nil {
 | 
						|
		t.Fatalf("Failed to list snapshots: %v", err)
 | 
						|
	}
 | 
						|
 | 
						|
	// Check that all snapshots are listed
 | 
						|
	if len(snapshots) != len(testSnapshots) {
 | 
						|
		t.Errorf("Wrong number of snapshots listed: got %d, want %d", len(snapshots), len(testSnapshots))
 | 
						|
	}
 | 
						|
 | 
						|
	// Check that the snapshots have the correct information
 | 
						|
	for i, snap := range testSnapshots {
 | 
						|
		found := false
 | 
						|
		for _, listedSnap := range snapshots {
 | 
						|
			if listedSnap.ID == snap.ID {
 | 
						|
				found = true
 | 
						|
				if listedSnap.Name != snap.Name {
 | 
						|
					t.Errorf("Snapshot %d has wrong name: got %s, want %s", i, listedSnap.Name, snap.Name)
 | 
						|
				}
 | 
						|
				if listedSnap.ParentID != snap.ParentID {
 | 
						|
					t.Errorf("Snapshot %d has wrong parent ID: got %s, want %s", i, listedSnap.ParentID, snap.ParentID)
 | 
						|
				}
 | 
						|
				if !listedSnap.CreationTime.Equal(snap.CreationTime) {
 | 
						|
					t.Errorf("Snapshot %d has wrong creation time: got %v, want %v", i, listedSnap.CreationTime, snap.CreationTime)
 | 
						|
				}
 | 
						|
				break
 | 
						|
			}
 | 
						|
		}
 | 
						|
		if !found {
 | 
						|
			t.Errorf("Snapshot %d (%s) not found in listed snapshots", i, snap.ID)
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestListSnapshotsMetadata_WithOptions(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) // Clean up after test
 | 
						|
 | 
						|
	// Create a new store
 | 
						|
	dbPath := filepath.Join(tempDir, "test.db")
 | 
						|
	s, err := NewSQLiteStore(dbPath)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatalf("Failed to create SQLite store: %v", err)
 | 
						|
	}
 | 
						|
	defer s.Close()
 | 
						|
 | 
						|
	// Create test snapshots with different names
 | 
						|
	ctx := context.Background()
 | 
						|
	now := time.Now().UTC().Truncate(time.Second)
 | 
						|
 | 
						|
	testSnapshots := []store.Snapshot{
 | 
						|
		{
 | 
						|
			ID:           "alpha-1",
 | 
						|
			Name:         "alpha-1",
 | 
						|
			ParentID:     "",
 | 
						|
			CreationTime: now.Add(-3 * time.Hour),
 | 
						|
			Files:        []store.FileInfo{},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			ID:           "alpha-2",
 | 
						|
			Name:         "alpha-2",
 | 
						|
			ParentID:     "alpha-1",
 | 
						|
			CreationTime: now.Add(-2 * time.Hour),
 | 
						|
			Files:        []store.FileInfo{},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			ID:           "beta-1",
 | 
						|
			Name:         "beta-1",
 | 
						|
			ParentID:     "",
 | 
						|
			CreationTime: now.Add(-1 * time.Hour),
 | 
						|
			Files:        []store.FileInfo{},
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	// Save the snapshots
 | 
						|
	for _, snap := range testSnapshots {
 | 
						|
		err = s.SaveSnapshotMetadata(ctx, snap)
 | 
						|
		if err != nil {
 | 
						|
			t.Fatalf("Failed to save snapshot metadata: %v", err)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// Test different ListOptions scenarios
 | 
						|
	t.Run("FilterByName", func(t *testing.T) {
 | 
						|
		// Filter snapshots by name "alpha"
 | 
						|
		opts := store.ListOptions{
 | 
						|
			FilterByName: "alpha",
 | 
						|
		}
 | 
						|
		snapshots, err := s.ListSnapshotsMetadata(ctx, opts)
 | 
						|
		if err != nil {
 | 
						|
			t.Fatalf("Failed to list snapshots with filter: %v", err)
 | 
						|
		}
 | 
						|
 | 
						|
		// Should return 2 snapshots (alpha-1 and alpha-2)
 | 
						|
		if len(snapshots) != 2 {
 | 
						|
			t.Errorf("Wrong number of snapshots returned: got %d, want %d", len(snapshots), 2)
 | 
						|
		}
 | 
						|
 | 
						|
		// Check that only alpha snapshots are returned
 | 
						|
		for _, snap := range snapshots {
 | 
						|
			if snap.ID != "alpha-1" && snap.ID != "alpha-2" {
 | 
						|
				t.Errorf("Unexpected snapshot ID in filtered results: %s", snap.ID)
 | 
						|
			}
 | 
						|
		}
 | 
						|
	})
 | 
						|
 | 
						|
	t.Run("Limit", func(t *testing.T) {
 | 
						|
		// Limit to 1 snapshot (should return the newest one)
 | 
						|
		opts := store.ListOptions{
 | 
						|
			Limit: 1,
 | 
						|
		}
 | 
						|
		snapshots, err := s.ListSnapshotsMetadata(ctx, opts)
 | 
						|
		if err != nil {
 | 
						|
			t.Fatalf("Failed to list snapshots with limit: %v", err)
 | 
						|
		}
 | 
						|
 | 
						|
		// Should return 1 snapshot
 | 
						|
		if len(snapshots) != 1 {
 | 
						|
			t.Errorf("Wrong number of snapshots returned: got %d, want %d", len(snapshots), 1)
 | 
						|
		}
 | 
						|
 | 
						|
		// The newest snapshot should be beta-1
 | 
						|
		if snapshots[0].ID != "beta-1" {
 | 
						|
			t.Errorf("Wrong snapshot returned with limit: got %s, want %s", snapshots[0].ID, "beta-1")
 | 
						|
		}
 | 
						|
	})
 | 
						|
 | 
						|
	t.Run("Offset", func(t *testing.T) {
 | 
						|
		// Limit to 1 snapshot with offset 1 (should return the second newest)
 | 
						|
		opts := store.ListOptions{
 | 
						|
			Limit:  1,
 | 
						|
			Offset: 1,
 | 
						|
		}
 | 
						|
		snapshots, err := s.ListSnapshotsMetadata(ctx, opts)
 | 
						|
		if err != nil {
 | 
						|
			t.Fatalf("Failed to list snapshots with offset: %v", err)
 | 
						|
		}
 | 
						|
 | 
						|
		// Should return 1 snapshot
 | 
						|
		if len(snapshots) != 1 {
 | 
						|
			t.Errorf("Wrong number of snapshots returned: got %d, want %d", len(snapshots), 1)
 | 
						|
		}
 | 
						|
 | 
						|
		// The second newest snapshot should be alpha-2
 | 
						|
		if snapshots[0].ID != "alpha-2" {
 | 
						|
			t.Errorf("Wrong snapshot returned with offset: got %s, want %s", snapshots[0].ID, "alpha-2")
 | 
						|
		}
 | 
						|
	})
 | 
						|
 | 
						|
	t.Run("FilterAndPagination", func(t *testing.T) {
 | 
						|
		// Filter by "alpha" with limit 1
 | 
						|
		opts := store.ListOptions{
 | 
						|
			FilterByName: "alpha",
 | 
						|
			Limit:        1,
 | 
						|
		}
 | 
						|
		snapshots, err := s.ListSnapshotsMetadata(ctx, opts)
 | 
						|
		if err != nil {
 | 
						|
			t.Fatalf("Failed to list snapshots with filter and pagination: %v", err)
 | 
						|
		}
 | 
						|
 | 
						|
		// Should return 1 snapshot
 | 
						|
		if len(snapshots) != 1 {
 | 
						|
			t.Errorf("Wrong number of snapshots returned: got %d, want %d", len(snapshots), 1)
 | 
						|
		}
 | 
						|
 | 
						|
		// The newest alpha snapshot should be alpha-2
 | 
						|
		if snapshots[0].ID != "alpha-2" {
 | 
						|
			t.Errorf("Wrong snapshot returned with filter and limit: got %s, want %s", snapshots[0].ID, "alpha-2")
 | 
						|
		}
 | 
						|
	})
 | 
						|
 | 
						|
	t.Run("NoResults", func(t *testing.T) {
 | 
						|
		// Filter by a name that doesn't exist
 | 
						|
		opts := store.ListOptions{
 | 
						|
			FilterByName: "gamma",
 | 
						|
		}
 | 
						|
		snapshots, err := s.ListSnapshotsMetadata(ctx, opts)
 | 
						|
		if err != nil {
 | 
						|
			t.Fatalf("Failed to list snapshots with non-matching filter: %v", err)
 | 
						|
		}
 | 
						|
 | 
						|
		// Should return 0 snapshots
 | 
						|
		if len(snapshots) != 0 {
 | 
						|
			t.Errorf("Expected 0 snapshots, got %d", len(snapshots))
 | 
						|
		}
 | 
						|
	})
 | 
						|
}
 | 
						|
 | 
						|
func TestDeleteSnapshotMetadata(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) // Clean up after test
 | 
						|
 | 
						|
	// Create a new store
 | 
						|
	dbPath := filepath.Join(tempDir, "test.db")
 | 
						|
	s, err := NewSQLiteStore(dbPath)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatalf("Failed to create SQLite store: %v", err)
 | 
						|
	}
 | 
						|
	defer s.Close()
 | 
						|
 | 
						|
	// Create a test snapshot
 | 
						|
	ctx := context.Background()
 | 
						|
	testSnapshot := store.Snapshot{
 | 
						|
		ID:           "test-snapshot-id",
 | 
						|
		Name:         "Test Snapshot",
 | 
						|
		ParentID:     "",
 | 
						|
		CreationTime: time.Now().UTC().Truncate(time.Second),
 | 
						|
		Files:        []store.FileInfo{},
 | 
						|
	}
 | 
						|
 | 
						|
	// Save the snapshot
 | 
						|
	err = s.SaveSnapshotMetadata(ctx, testSnapshot)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatalf("Failed to save snapshot metadata: %v", err)
 | 
						|
	}
 | 
						|
 | 
						|
	// Delete the snapshot
 | 
						|
	err = s.DeleteSnapshotMetadata(ctx, testSnapshot.ID)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatalf("Failed to delete snapshot metadata: %v", err)
 | 
						|
	}
 | 
						|
 | 
						|
	// Try to retrieve the deleted snapshot
 | 
						|
	_, err = s.GetSnapshotMetadata(ctx, testSnapshot.ID)
 | 
						|
	if err == nil {
 | 
						|
		t.Fatalf("Expected error when retrieving deleted snapshot, got nil")
 | 
						|
	}
 | 
						|
 | 
						|
	// Deleting a non-existent snapshot should not return an error
 | 
						|
	err = s.DeleteSnapshotMetadata(ctx, "non-existent-id")
 | 
						|
	if err != nil {
 | 
						|
		t.Fatalf("DeleteSnapshotMetadata returned an error for non-existent snapshot: %v", err)
 | 
						|
	}
 | 
						|
}
 |