use std::sync::Arc;
use std::sync::atomic::Ordering;
use super::KEY;
use super::fixtures::{WithholdingStore, keyed_params, task_of, withholding_handler};
use crate::error::ServerError;
use crate::store::TaskStore as _;
#[tokio::test]
async fn a_replayed_key_waits_for_a_task_the_winner_has_not_written_yet() {
let store = Arc::new(WithholdingStore::default());
let (handler, executions) = withholding_handler(&store);
let first = handler
.on_send_message(keyed_params("msg-1", Some(KEY)), false, None)
.await
.expect("the first keyed send must succeed");
let first_id = task_of(&first).id.clone();
store.withhold(&first_id, 2);
let replay = handler
.on_send_message(keyed_params("msg-1", Some(KEY)), false, None)
.await
.expect(
"the replay must wait for the task the winner is still writing, \
not report it missing",
);
assert_eq!(
task_of(&replay).id,
first_id,
"the replay must return the winner's task, not a new one"
);
assert_eq!(
executions.load(Ordering::SeqCst),
1,
"the whole point of the key is that the agent runs once"
);
}
#[tokio::test]
async fn a_key_whose_task_was_swept_still_reports_it_missing() {
let store = Arc::new(WithholdingStore::default());
let (handler, executions) = withholding_handler(&store);
let first = handler
.on_send_message(keyed_params("msg-1", Some(KEY)), false, None)
.await
.expect("the first keyed send must succeed");
let first_id = task_of(&first).id.clone();
store
.delete(&first_id)
.await
.expect("deleting the task must succeed");
let err = handler
.on_send_message(keyed_params("msg-1", Some(KEY)), false, None)
.await
.expect_err("a key whose task is really gone must not report success");
match err {
ServerError::TaskNotFound(id) => assert_eq!(
id, first_id,
"the error must name the task the key still points at"
),
other => panic!("expected TaskNotFound, got {other:?}"),
}
assert_eq!(
executions.load(Ordering::SeqCst),
1,
"the retry must not re-run the agent just because the task is gone"
);
}