Report comparison cleanup recovery state

This commit is contained in:
2026-08-13 03:18:55 +00:00
parent 302f5aba2d
commit 79cba800ee
11 changed files with 228 additions and 51 deletions

View File

@@ -87,27 +87,42 @@ func TestCompareDetailedPublishesPartialBundleAndReturnsAggregateError(t *testin
}
func TestCompareDetailedRetainsCommittedPathsWhenBackupCleanupFails(t *testing.T) {
bundle := generationBundle(t)
backupPath := filepath.Join(t.TempDir(), ".comparison-daily.backup-retained")
cleanupCause := errors.New("backup cleanup failed")
publish := func(context.Context, comparison.DestinationPlan, comparison.LogicalBundle) (comparison.PublicationResult, error) {
return comparison.PublicationResult{Committed: true, RetainedBackupPath: backupPath}, &comparison.PublicationCleanupError{RetainedBackupPath: backupPath, Err: cleanupCause}
}
for _, test := range []struct {
name string
state comparison.BackupRecoveryState
path bool
}{
{name: "complete recovery bundle", state: comparison.BackupRecoveryComplete, path: true},
{name: "partial remnants", state: comparison.BackupRecoveryPartial, path: true},
{name: "absent backup", state: comparison.BackupRecoveryAbsent},
} {
t.Run(test.name, func(t *testing.T) {
bundle := generationBundle(t)
recoveryPath := ""
if test.path {
recoveryPath = filepath.Join(t.TempDir(), ".comparison-daily.backup-recovery")
}
cleanupCause := errors.New("backup cleanup failed")
publish := func(context.Context, comparison.DestinationPlan, comparison.LogicalBundle) (comparison.PublicationResult, error) {
return comparison.PublicationResult{Committed: true, RecoveryState: test.state, RecoveryPath: recoveryPath}, &comparison.PublicationCleanupError{RecoveryState: test.state, RecoveryPath: recoveryPath, Err: cleanupCause}
}
result, err := compareDetailed(context.Background(), ComparisonRequest{
Config: comparisonConfig(), Report: ReportDaily, ProfileIDs: []string{"weather-light", "weather-deep"},
WorkingDir: t.TempDir(), Date: generationTime("2026-05-29T12:00:00-05:00"),
Clock: timeutil.FixedClock{Time: generationTime("2026-05-29T08:30:00-05:00")},
Collector: &generationCollector{bundle: &bundle}, Executor: &generationExecutor{},
}, publish)
var cleanupErr *comparison.PublicationCleanupError
if result == nil || !errors.As(err, &cleanupErr) || !errors.Is(err, cleanupCause) || cleanupErr.RetainedBackupPath != backupPath || !filepath.IsAbs(result.ManifestPath) || !filepath.IsAbs(result.DataPackagePath) {
t.Fatalf("CompareDetailed() result/error = %#v/%v", result, err)
}
for _, profile := range result.Results {
if profile.Status == comparison.StatusSucceeded && !filepath.IsAbs(profile.ReportPath) {
t.Fatalf("published profile result = %#v", profile)
}
result, err := compareDetailed(context.Background(), ComparisonRequest{
Config: comparisonConfig(), Report: ReportDaily, ProfileIDs: []string{"weather-light", "weather-deep"},
WorkingDir: t.TempDir(), Date: generationTime("2026-05-29T12:00:00-05:00"),
Clock: timeutil.FixedClock{Time: generationTime("2026-05-29T08:30:00-05:00")},
Collector: &generationCollector{bundle: &bundle}, Executor: &generationExecutor{},
}, publish)
var cleanupErr *comparison.PublicationCleanupError
if result == nil || !errors.As(err, &cleanupErr) || !errors.Is(err, cleanupCause) || cleanupErr.RecoveryState != test.state || cleanupErr.RecoveryPath != recoveryPath || !filepath.IsAbs(result.ManifestPath) || !filepath.IsAbs(result.DataPackagePath) {
t.Fatalf("CompareDetailed() result/error = %#v/%v", result, err)
}
for _, profile := range result.Results {
if profile.Status == comparison.StatusSucceeded && !filepath.IsAbs(profile.ReportPath) {
t.Fatalf("published profile result = %#v", profile)
}
}
})
}
}