//! Regression cover for the re-enqueue path.
//!
//! `upsert_pending` always conflicts onto the existing (upload_id, kind) row
//! when a job is retried, so the ActiveModel's `attempts: Set(0)` never
//! applies -- only the columns named in DO UPDATE SET do. Omitting Attempts
//! there stranded any job that had reached WORKER_MAX_ATTEMPTS: retry flipped
//! status to pending, but the worker's pre-flight attempts check still saw
//! the exhausted count and bounced it straight to the DLQ.
use dms::jobs::upsert_pending;
use dms::queue::JobKind;
use sea_orm::{DatabaseBackend, MockDatabase, Value};
use std::collections::BTreeMap;
use uuid::Uuid;
async fn upsert_sql(kind: JobKind) -> String {
// On Postgres, sea-orm 2 runs the insert as a query and reads the key
// back from its RETURNING row, so the mock answers with that row.
let db = MockDatabase::new(DatabaseBackend::Postgres)
.append_query_results([[BTreeMap::from([("id", Value::from(Uuid::now_v7()))])]])
.into_connection();
upsert_pending(&db, Uuid::now_v7(), kind).await.expect("upsert_pending");
let log = db.into_transaction_log();
assert_eq!(log.len(), 1, "expected exactly one statement");
format!("{:?}", log[0])
}
/// The whole point of the fix: a retry must clear the attempts budget.
#[tokio::test]
async fn upsert_pending_resets_attempts_on_conflict() {
let sql = upsert_sql(JobKind::Describe).await;
let update = sql
.split_once("DO UPDATE SET")
.expect("statement should be an upsert with a DO UPDATE branch")
.1;
assert!(
update.contains("attempts"),
"attempts must be reset in the conflict branch, or an exhausted job \
can never be retried out of the DLQ; got: {sql}"
);
}
/// Guard the columns the retry path also depends on, so a future edit to the
/// update list can't quietly drop one.
#[tokio::test]
async fn upsert_pending_resets_the_rest_of_the_retry_state() {
let sql = upsert_sql(JobKind::Ocr).await;
let update = sql.split_once("DO UPDATE SET").unwrap().1;
for col in ["status", "error", "started_at", "completed_at", "updated_at"] {
assert!(update.contains(col), "{col} missing from DO UPDATE SET; got: {sql}");
}
}
⭐
Log in to mark this repository.
2.2 KiB · text
History
8aa8e40