Refactor snapshot parent updates: replace full metadata reload with UpdateSnapshotParentID method, enhance functional test logging, and add CleanOnRestore option.
This commit is contained in:
@ -20,7 +20,8 @@ func TestFullWorkflow(t *testing.T) {
|
||||
|
||||
// Create Agate options
|
||||
options := AgateOptions{
|
||||
WorkDir: tempDir,
|
||||
WorkDir: tempDir,
|
||||
CleanOnRestore: true,
|
||||
}
|
||||
|
||||
// Create Agate instance
|
||||
@ -123,12 +124,20 @@ func TestFullWorkflow(t *testing.T) {
|
||||
}
|
||||
if string(content) != expectedContent {
|
||||
t.Errorf("Restored file %s has wrong content: got %s, want %s", path, string(content), expectedContent)
|
||||
} else {
|
||||
t.Logf("SUCCESS: Restored file %s has correct content after restoring first snapshot", path)
|
||||
}
|
||||
}
|
||||
|
||||
// Check that file4.txt doesn't exist
|
||||
if _, err := os.Stat(filepath.Join(dataDir, "file4.txt")); !os.IsNotExist(err) {
|
||||
file4Path := filepath.Join(dataDir, "file4.txt")
|
||||
_, err = os.Stat(file4Path)
|
||||
if err == nil {
|
||||
t.Errorf("File4.txt should not exist after restoring first snapshot")
|
||||
} else if !os.IsNotExist(err) {
|
||||
t.Errorf("Unexpected error checking if File4.txt exists: %v", err)
|
||||
} else {
|
||||
t.Logf("SUCCESS: File4.txt correctly does not exist after restoring first snapshot")
|
||||
}
|
||||
|
||||
// Step 9: Restore the third snapshot
|
||||
@ -152,12 +161,20 @@ func TestFullWorkflow(t *testing.T) {
|
||||
}
|
||||
if string(content) != expectedContent {
|
||||
t.Errorf("Restored file %s has wrong content: got %s, want %s", path, string(content), expectedContent)
|
||||
} else {
|
||||
t.Logf("SUCCESS: Restored file %s has correct content after restoring third snapshot", path)
|
||||
}
|
||||
}
|
||||
|
||||
// Check that file2.txt doesn't exist
|
||||
if _, err := os.Stat(filepath.Join(dataDir, "file2.txt")); !os.IsNotExist(err) {
|
||||
file2Path := filepath.Join(dataDir, "file2.txt")
|
||||
_, err = os.Stat(file2Path)
|
||||
if err == nil {
|
||||
t.Errorf("File2.txt should not exist after restoring third snapshot")
|
||||
} else if !os.IsNotExist(err) {
|
||||
t.Errorf("Unexpected error checking if File2.txt exists: %v", err)
|
||||
} else {
|
||||
t.Logf("SUCCESS: File2.txt correctly does not exist after restoring third snapshot")
|
||||
}
|
||||
|
||||
// Step 11: Delete a snapshot
|
||||
@ -190,17 +207,26 @@ func TestFullWorkflow(t *testing.T) {
|
||||
// Verify that snapshot 3's parent ID has been updated to point to snapshot 1
|
||||
if snapshot3 != nil && snapshot3.ParentID != snapshot1ID {
|
||||
t.Errorf("Snapshot 3's parent ID should be updated to point to Snapshot 1 after Snapshot 2 is deleted. Got ParentID=%s, want ParentID=%s", snapshot3.ParentID, snapshot1ID)
|
||||
} else {
|
||||
t.Logf("SUCCESS: Snapshot 3's parent ID has been correctly updated to point to Snapshot 1: %s", snapshot3.ParentID)
|
||||
}
|
||||
|
||||
if len(snapshots) != 2 {
|
||||
t.Errorf("Expected 2 snapshots after deletion, got %d", len(snapshots))
|
||||
} else {
|
||||
t.Logf("SUCCESS: Found correct number of snapshots after deletion: %d", len(snapshots))
|
||||
}
|
||||
|
||||
foundDeletedSnapshot := false
|
||||
for _, snap := range snapshots {
|
||||
if snap.ID == snapshot2ID {
|
||||
foundDeletedSnapshot = true
|
||||
t.Errorf("Snapshot 2 (ID=%s) should have been deleted", snapshot2ID)
|
||||
}
|
||||
}
|
||||
if !foundDeletedSnapshot {
|
||||
t.Logf("SUCCESS: Snapshot 2 (ID=%s) was correctly deleted", snapshot2ID)
|
||||
}
|
||||
}
|
||||
|
||||
// TestLargeFiles tests creating and restoring snapshots with large files
|
||||
@ -219,7 +245,8 @@ func TestLargeFiles(t *testing.T) {
|
||||
|
||||
// Create Agate options
|
||||
options := AgateOptions{
|
||||
WorkDir: tempDir,
|
||||
WorkDir: tempDir,
|
||||
CleanOnRestore: true,
|
||||
OpenFunc: func(dir string) error {
|
||||
return nil
|
||||
},
|
||||
|
14
manager.go
14
manager.go
@ -207,18 +207,8 @@ func (data *SnapshotManagerData) DeleteSnapshot(ctx context.Context, snapshotID
|
||||
// Update parent references for any snapshots that have this one as a parent
|
||||
for _, info := range allSnapshots {
|
||||
if info.ParentID == snapshotID {
|
||||
// Get the full snapshot details
|
||||
childSnapshot, err := data.metadataStore.GetSnapshotMetadata(ctx, info.ID)
|
||||
if err != nil {
|
||||
data.logger.Printf("WARNING: failed to get child snapshot %s details: %v", info.ID, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Update the parent ID to point to the deleted snapshot's parent
|
||||
childSnapshot.ParentID = parentID
|
||||
|
||||
// Save the updated snapshot
|
||||
if err := data.metadataStore.SaveSnapshotMetadata(ctx, *childSnapshot); err != nil {
|
||||
// Используем новый, более надежный метод для обновления только parent_id
|
||||
if err := data.metadataStore.UpdateSnapshotParentID(ctx, info.ID, parentID); err != nil {
|
||||
data.logger.Printf("WARNING: failed to update parent reference for snapshot %s: %v", info.ID, err)
|
||||
} else {
|
||||
data.logger.Printf("Updated parent reference for snapshot %s from %s to %s", info.ID, snapshotID, parentID)
|
||||
|
@ -265,3 +265,13 @@ func (s *sqliteStore) DeleteSnapshotMetadata(ctx context.Context, snapshotID str
|
||||
|
||||
return nil // Не возвращаем ошибку, если запись не найдена
|
||||
}
|
||||
|
||||
// UpdateSnapshotParentID обновляет ParentID для указанного снапшота.
|
||||
func (s *sqliteStore) UpdateSnapshotParentID(ctx context.Context, snapshotID, newParentID string) error {
|
||||
query := `UPDATE snapshots SET parent_id = ? WHERE id = ?;`
|
||||
_, err := s.db.ExecContext(ctx, query, newParentID, snapshotID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update parent ID for snapshot %s: %w", snapshotID, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -55,6 +55,9 @@ type MetadataStore interface {
|
||||
// Не должен возвращать ошибку, если снапшот не найден.
|
||||
DeleteSnapshotMetadata(ctx context.Context, snapshotID string) error
|
||||
|
||||
// UpdateSnapshotParentID обновляет ParentID для указанного снапшота.
|
||||
UpdateSnapshotParentID(ctx context.Context, snapshotID, newParentID string) error
|
||||
|
||||
// Close закрывает соединение с хранилищем метаданных.
|
||||
Close() error
|
||||
}
|
||||
|
Reference in New Issue
Block a user