Quality improvements: Remove dead code, add unit tests, fix ignored errors

HIGH PRIORITY FIXES:
1. Remove unused progressCallback mechanism (dead code cleanup)
2. Add unit tests for restore package (formats, safety checks)
   - Test coverage for archive format detection
   - Test coverage for safety validation
   - Added NullLogger for testing
3. Fix ignored errors in backup pipeline
   - Handle StdoutPipe() errors properly
   - Log stderr pipe errors
   - Document CPU detection errors

IMPROVEMENTS:
- formats_test.go: 8 test functions, all passing
- safety_test.go: 6 test functions for validation
- logger/null.go: Test helper for unit tests
- Proper error handling in streaming compression
- Fixed indentation in stderr handling
This commit is contained in:
2025-11-07 11:47:07 +00:00
parent bf9a2b652a
commit 95ea807d18
8 changed files with 380 additions and 39 deletions

View File

@ -23,7 +23,6 @@ type Engine struct {
progress progress.Indicator
detailedReporter *progress.DetailedReporter
dryRun bool
progressCallback func(phase, status string, percent int) // Callback for TUI progress
}
// New creates a new restore engine
@ -53,19 +52,6 @@ func NewSilent(cfg *config.Config, log logger.Logger, db database.Database) *Eng
progress: progressIndicator,
detailedReporter: detailedReporter,
dryRun: false,
progressCallback: nil,
}
}
// SetProgressCallback sets a callback function for progress updates (used by TUI)
func (e *Engine) SetProgressCallback(callback func(phase, status string, percent int)) {
e.progressCallback = callback
}
// reportProgress calls the progress callback if set
func (e *Engine) reportProgress(phase, status string, percent int) {
if e.progressCallback != nil {
e.progressCallback(phase, status, percent)
}
}
@ -326,7 +312,6 @@ func (e *Engine) RestoreCluster(ctx context.Context, archivePath string) error {
}
e.progress.Start(fmt.Sprintf("Restoring cluster from %s", filepath.Base(archivePath)))
e.reportProgress("Extracting", "Extracting cluster archive...", 5)
// Create temporary extraction directory
tempDir := filepath.Join(e.cfg.BackupDir, fmt.Sprintf(".restore_%d", time.Now().Unix()))
@ -348,7 +333,6 @@ func (e *Engine) RestoreCluster(ctx context.Context, archivePath string) error {
if _, err := os.Stat(globalsFile); err == nil {
e.log.Info("Restoring global objects")
e.progress.Update("Restoring global objects (roles, tablespaces)...")
e.reportProgress("Globals", "Restoring global objects...", 15)
if err := e.restoreGlobals(ctx, globalsFile); err != nil {
e.log.Warn("Failed to restore global objects", "error", err)
// Continue anyway - global objects might already exist
@ -388,13 +372,12 @@ func (e *Engine) RestoreCluster(ctx context.Context, archivePath string) error {
dumpFile := filepath.Join(dumpsDir, entry.Name())
dbName := strings.TrimSuffix(entry.Name(), ".dump")
// Calculate progress: 15% for extraction/globals, 85% for databases
// Calculate progress percentage for logging
dbProgress := 15 + int(float64(i)/float64(totalDBs)*85.0)
statusMsg := fmt.Sprintf("⠋ [%d/%d] Restoring: %s", i+1, totalDBs, dbName)
e.progress.Update(statusMsg)
e.reportProgress("Restoring", statusMsg, dbProgress)
e.log.Info("Restoring database", "name", dbName, "file", dumpFile)
e.log.Info("Restoring database", "name", dbName, "file", dumpFile, "progress", dbProgress)
// Create database first if it doesn't exist
if err := e.ensureDatabaseExists(ctx, dbName); err != nil {