mirror of
https://github.com/pgsty/minio.git
synced 2026-11-11 01:55:30 +03:00
fix(batch): fail an expiration run whose listing fails at once
A Walk that returned an error before any result cancelled the run like an ordinary cancellation: the job was saved as neither complete nor failed. The listing failure is now recorded first, and the run is saved as failed with its cursor where it was. Start still returns the error, so the job is left to a later run, which lists again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Feng Ruohang <rh@vonng.com>
This commit is contained in:
@@ -473,3 +473,45 @@ func TestBatchExpirePurgeBudgetIncludesAuthorization(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A listing that failed before any result fails the run without moving the
|
||||
// cursor or refusing the job; a later run completes it, in both modes.
|
||||
func TestBatchExpireWalkFailureResumes(t *testing.T) {
|
||||
for _, purgeAll := range []bool{false, true} {
|
||||
name := "retain-one"
|
||||
if purgeAll {
|
||||
name = "retain-zero"
|
||||
}
|
||||
t.Run(name, func(t *testing.T) {
|
||||
f := newBatchAuthzFixture(t)
|
||||
const key = "data/key"
|
||||
older := f.putVersions(t, key)
|
||||
definition := f.expireYAML("data/")
|
||||
if purgeAll {
|
||||
definition = f.purgeYAML("data/")
|
||||
}
|
||||
rec, job := f.submit(t, globalActiveCred, definition)
|
||||
if job == nil {
|
||||
t.Fatalf("submit: %d %s", rec.Code, rec.Body.String())
|
||||
}
|
||||
listErr := errors.New("review7: transient listing failure")
|
||||
err := job.Expire.Start(f.ctx, batchWalkError{ObjectLayer: f.obj, err: listErr}, *job)
|
||||
if !errors.Is(err, listErr) {
|
||||
t.Fatalf("listing error: %v", err)
|
||||
}
|
||||
ri := f.jobInfo(t, job)
|
||||
if !ri.Failed || ri.Complete || ri.FailureReason != "" || ri.Object != "" || !f.versionExists(t, key, older) {
|
||||
t.Fatalf("listing failure changed progress or became terminal: failed=%v complete=%v reason=%q cursor=%q", ri.Failed, ri.Complete, ri.FailureReason, ri.Object)
|
||||
}
|
||||
mustIAM(t, job.Expire.Start(f.ctx, f.obj, *job))
|
||||
ri = f.jobInfo(t, job)
|
||||
wantRemoved := int64(1)
|
||||
if purgeAll {
|
||||
wantRemoved = 2
|
||||
}
|
||||
if ri.Failed || !ri.Complete || ri.FailureReason != "" || ri.Objects != wantRemoved || f.versionExists(t, key, older) {
|
||||
t.Fatalf("resume did not complete: failed=%v complete=%v reason=%q removed=%d", ri.Failed, ri.Complete, ri.FailureReason, ri.Objects)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user