@@ -77,6 +77,16 @@ func New(ctx *stopper.Context, env *env.Env, blobStorage blob.Storage) (*Validat
7777 return nil , err
7878 }
7979
80+ // Check for pending jobs on the source table
81+ pendingJobs , err := sourceTable .PendingJobs (ctx , conn )
82+ if err != nil {
83+ return nil , errors .Wrap (err , "failed to check for pending jobs on source table" )
84+ }
85+ if len (pendingJobs ) > 0 {
86+ slog .Error ("pending jobs found on source table. Please review and cancel them." , slog .Any ("job_ids" , pendingJobs ))
87+ return nil , errors .New ("pending jobs found on source table" )
88+ }
89+
8090 restoredTable , err := createRestoredTable (ctx , conn )
8191 if err != nil {
8292 return nil , err
@@ -113,24 +123,34 @@ func preflight(ctx *stopper.Context, env *env.Env, blobStorage blob.Storage) err
113123
114124// Clean removes all resources created by the validator.
115125func (v * Validator ) Clean (ctx * stopper.Context ) error {
126+ slog .Debug ("Starting cleanup of validator resources" )
116127 conn , err := v .acquireConn (ctx )
117128 if err != nil {
118129 return err
119130 }
120131 defer conn .Release ()
121132
122133 var e1 , e2 error
134+ slog .Debug ("Dropping source database" , slog .String ("database" , v .sourceTable .Database .String ()))
123135 if err := v .sourceTable .Database .Drop (ctx , conn ); err != nil {
124- slog .Error ("drop source DB" , "err" , err )
125136 e1 = errors .Wrap (err , "failed to drop source database" )
126137 }
138+ slog .Debug ("Dropping restored database" , slog .String ("database" , v .restoredTable .Database .String ()))
127139 if err := v .restoredTable .Database .Drop (ctx , conn ); err != nil {
128- slog .Error ("drop restored DB" , "err" , err )
129140 e2 = errors .Wrap (err , "failed to drop restored database" )
130141 }
131142 return errors .Join (e1 , e2 )
132143}
133144
145+ // validationStepFn is a function that performs a validation step.
146+ type validationStepFn func (ctx * stopper.Context , extConn * db.ExternalConn ) error
147+
148+ // validationStep represents a step in the validation process.
149+ type validationStep struct {
150+ name string
151+ fn validationStepFn
152+ }
153+
134154// Validate performs a backup/restore against a storage provider
135155// to asses minimum compatibility at the functional level.
136156// This does not imply that a storage provider passing the test is supported.
@@ -148,31 +168,55 @@ func (v *Validator) Validate(ctx *stopper.Context) (*Report, error) {
148168 }
149169 defer extConn .Drop (ctx , conn )
150170
151- stats , err := captureInitialStats (ctx , extConn , conn )
152- if err != nil {
153- return nil , err
154- }
155-
156- if err := v .runWorkloadWithBackup (ctx , extConn ); err != nil {
157- return nil , err
158- }
159-
160- if err := v .runIncrementalBackup (ctx , conn , extConn ); err != nil {
161- return nil , err
162- }
163-
164- if err := v .checkBackups (ctx , extConn ); err != nil {
165- return nil , err
166- }
167-
168- if err := v .performRestore (ctx , conn , extConn ); err != nil {
169- return nil , err
170- }
171-
172- if err := v .verifyIntegrity (ctx , conn ); err != nil {
173- // If we fail to verify the integrity, just log the error, but
174- // still provide a complete report
175- slog .Error ("failed to verify integrity" , slog .Any ("error" , err ))
171+ var stats []* db.Stats
172+
173+ // Define validation steps
174+ steps := []validationStep {
175+ {
176+ name : "capture initial stats" ,
177+ fn : func (ctx * stopper.Context , extConn * db.ExternalConn ) error {
178+ var err error
179+ stats , err = v .captureInitialStats (ctx , extConn )
180+ return err
181+ },
182+ },
183+ {
184+ name : "workload with backup" ,
185+ fn : v .runWorkloadWithBackup ,
186+ },
187+ {
188+ name : "incremental backup" ,
189+ fn : v .runIncrementalBackup ,
190+ },
191+ {
192+ name : "check backups" ,
193+ fn : v .checkBackups ,
194+ },
195+ {
196+ name : "restore" ,
197+ fn : v .performRestore ,
198+ },
199+ {
200+ name : "verify integrity" ,
201+ fn : func (ctx * stopper.Context , extConn * db.ExternalConn ) error {
202+ if err := v .verifyIntegrity (ctx ); err != nil {
203+ // If we fail to verify the integrity, just log the error, but
204+ // still provide a complete report
205+ slog .Error ("failed to verify integrity" , slog .Any ("error" , err ))
206+ }
207+ return nil
208+ },
209+ },
210+ }
211+
212+ // Execute steps
213+ for _ , step := range steps {
214+ if ctx .IsStopping () {
215+ return nil , ctx .Err ()
216+ }
217+ if err := step .fn (ctx , extConn ); err != nil {
218+ return nil , errors .Wrapf (err , "failed during step: %s" , step .name )
219+ }
176220 }
177221
178222 return & Report {
0 commit comments