Initial Dever 0.0.1

This commit is contained in:
Codex committed 2026-11-03 03:32:07 +00:00
commit 81233d098c
1479 files changed
+163782

No files matched your search

+131
View File
@@ -0,0 +1,131 @@
// 独立 SQL 校验持久队列和业务结果,不能只用函数返回值或随机 ID 长度认定正确。
async fn clear(scope: &Scope<'_>, registry: &Arc<Registry>) {
let mut database = DbContext::new(registry.clone());
let executor = database.on(JOB_BINDING, scope).await.unwrap();
executor
.execute(scope, "DELETE FROM _dever_job", vec![])
.await
.unwrap();
executor
.execute(scope, "DELETE FROM bench_queue_model", vec![])
.await
.unwrap();
}
async fn check_rows(scope: &Scope<'_>, registry: &Arc<Registry>, inputs: &[JobInput], handled: bool) {
let mut database = DbContext::new(registry.clone());
let executor = database.on(JOB_BINDING, scope).await.unwrap();
let rows = executor.query(scope,
"SELECT id,target,payload,schema,execution,task_key,state,attempt,retries,timeout_ms,token,lease_until,available_at,created_at FROM _dever_job ORDER BY task_key",
vec![], inputs.len() + 1, |row| Ok((
row.get::<_, String>(0)?, row.get::<_, String>(1)?, row.get::<_, String>(2)?,
row.get::<_, String>(3)?, row.get::<_, String>(4)?, row.get::<_, String>(5)?,
row.get::<_, String>(6)?, row.get::<_, i64>(7)?, row.get::<_, i64>(8)?, row.get::<_, i64>(9)?,
row.get::<_, Option<String>>(10)?, row.get::<_, Option<i64>>(11)?, row.get::<_, i64>(12)?, row.get::<_, i64>(13)?,
))).await.unwrap();
assert_eq!(rows.len(), inputs.len());
let mut unique = std::collections::BTreeSet::new();
for (row, input) in rows.iter().zip(inputs) {
assert!(unique.insert(&row.0));
assert_eq!(row.0.len(), 32);
assert_eq!(row.1, TARGET);
let payload: RustPayload = dever_runtime::wire::decode(&row.2).unwrap();
assert_eq!(payload.name, input.name);
assert_eq!(payload.amount, input.amount);
assert_eq!(row.3, SCHEMA);
assert!(matches!(
dever_runtime::wire::decode::<Execution>(&row.4).unwrap(),
Execution::System { tenant: None }
));
assert_eq!(row.5, input.key);
assert_eq!(row.6, if handled { "completed" } else { "pending" });
assert_eq!((row.7, row.8, row.9), (i64::from(handled), 2, 1000));
assert!(row.10.is_none() && row.11.is_none());
assert!(row.12 >= row.13 && row.13 > 0);
}
let results = executor
.query(
scope,
"SELECT name,amount FROM bench_queue_model ORDER BY name",
vec![],
inputs.len() + 1,
|row| Ok((row.get::<_, String>(0)?, row.get::<_, i64>(1)?)),
)
.await
.unwrap();
let expected = if handled {
inputs
.iter()
.map(|input| (input.name.clone(), input.amount * 3 + 7))
.collect::<Vec<_>>()
} else {
vec![]
};
assert_eq!(results, expected);
}
fn check_jobs(runtime: &Runtime, registry: &Arc<Registry>) {
runtime
.run(async |scope| {
for generated in [true, false] {
clear(scope, registry).await;
let inputs = inputs(2);
for input in &inputs {
let id = submit(generated, input, scope, registry).await;
assert_eq!(submit(generated, input, scope, registry).await, id);
}
check_rows(scope, registry, &inputs, false).await;
for claim in claims(scope, registry, 2).await {
execute(generated, claim, scope, registry).await.unwrap();
}
check_rows(scope, registry, &inputs, true).await;
clear(scope, registry).await;
let input = JobInput {
name: "rollback".into(),
amount: -4,
key: "rollback".into(),
};
submit(generated, &input, scope, registry).await;
let claim = claims(scope, registry, 1).await.pop().unwrap();
assert!(matches!(
execute(generated, claim, scope, registry).await,
Err(JobFailure::Handler)
));
let mut database = DbContext::new(registry.clone());
let executor = database.on(JOB_BINDING, scope).await.unwrap();
assert_eq!(
executor
.query(
scope,
"SELECT COUNT(*) FROM bench_queue_model",
vec![],
1,
|row| Ok(row.get::<_, i64>(0)?)
)
.await
.unwrap(),
[0]
);
assert_eq!(
executor
.query(scope, "SELECT state FROM _dever_job", vec![], 1, |row| Ok(
row.get::<_, String>(0)?
))
.await
.unwrap(),
["running"]
);
drop(database);
clear(scope, registry).await;
submit(generated, &inputs[0], scope, registry).await;
let claim = claims(scope, registry, 1).await.pop().unwrap();
let mut claim = Arc::try_unwrap(claim).unwrap();
claim.payload = r#"["array-is-not-a-record",1]"#.into();
assert!(matches!(
execute(generated, Arc::new(claim), scope, registry).await,
Err(JobFailure::Blocked)
));
}
})
.unwrap();
}