From 5f36282667c8c2034f7259db0053d5561788047a Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Fri, 12 Jul 2024 08:05:41 +0100 Subject: [PATCH] feat: recheck failed status Should a status check for a transient reason and is re-run, this will allow that to be detected without the need to restart the git-next server or force a spurious rebase. Closes kemitix/git-next#88 --- .../src/handlers/receive_ci_status.rs | 8 +++- crates/repo-actor/src/lib.rs | 19 ++++++++++ .../src/tests/handlers/receive_ci_status.rs | 37 +++++++++++++++---- 3 files changed, 55 insertions(+), 9 deletions(-) diff --git a/crates/repo-actor/src/handlers/receive_ci_status.rs b/crates/repo-actor/src/handlers/receive_ci_status.rs index 7e9bf88c..87418f8f 100644 --- a/crates/repo-actor/src/handlers/receive_ci_status.rs +++ b/crates/repo-actor/src/handlers/receive_ci_status.rs @@ -34,8 +34,12 @@ impl Handler for actor::RepoActor { git::forge::commit::Status::Fail => { tracing::warn!("Checks have failed"); // TODO: (#95) test: repo with next ahead of main and failing CI should notify user - // TODO: (#88) recheck after a longer than normal delay - actor::logger(&log, "send: nothing"); // replace with messages to send notification and revalidate later + actor::delay_send( + addr, + sleep_duration, + actor::messages::ValidateRepo::new(message_token), + &self.log, + ); } } } diff --git a/crates/repo-actor/src/lib.rs b/crates/repo-actor/src/lib.rs index a06082cd..24caf4f9 100644 --- a/crates/repo-actor/src/lib.rs +++ b/crates/repo-actor/src/lib.rs @@ -6,6 +6,8 @@ pub mod messages; #[cfg(test)] mod tests; +use std::time::Duration; + use actix::prelude::*; use derive_more::Deref; @@ -103,6 +105,23 @@ impl Actor for RepoActor { } } +pub fn delay_send( + addr: Addr, + delay: Duration, + msg: M, + log: &Option, +) where + M: actix::Message + Send + 'static + std::fmt::Debug, + RepoActor: actix::Handler, + ::Result: Send, +{ + let log_message = format!("send-after-delay: {:?}", msg); + tracing::debug!(log_message); + logger(log, log_message); + std::thread::sleep(delay); + do_send(addr, msg, log) +} + pub fn do_send(_addr: Addr, msg: M, log: &Option) where M: actix::Message + Send + 'static + std::fmt::Debug, diff --git a/crates/repo-actor/src/tests/handlers/receive_ci_status.rs b/crates/repo-actor/src/tests/handlers/receive_ci_status.rs index 88328554..d0a87f83 100644 --- a/crates/repo-actor/src/tests/handlers/receive_ci_status.rs +++ b/crates/repo-actor/src/tests/handlers/receive_ci_status.rs @@ -1,7 +1,7 @@ // use super::*; -#[actix::test] +#[test_log::test(actix::test)] async fn when_pass_should_advance_main_to_next() -> TestResult { //given let fs = given::a_filesystem(); @@ -31,7 +31,7 @@ async fn when_pass_should_advance_main_to_next() -> TestResult { Ok(()) } -#[actix::test] +#[test_log::test(actix::test)] async fn when_pending_should_recheck_ci_status() -> TestResult { //given let fs = given::a_filesystem(); @@ -61,7 +61,33 @@ async fn when_pending_should_recheck_ci_status() -> TestResult { Ok(()) } -#[actix::test] +#[test_log::test(actix::test)] +async fn when_fail_should_recheck_after_delay() -> TestResult { + //given + let fs = given::a_filesystem(); + let (open_repository, repo_details) = given::an_open_repository(&fs); + let next_commit = given::a_named_commit("next"); + + //when + let (addr, log) = when::start_actor_with_open_repository( + Box::new(open_repository), + repo_details, + given::a_forge(), + ); + addr.send(actor::messages::ReceiveCIStatus::new(( + next_commit.clone(), + git::forge::commit::Status::Fail, + ))) + .await?; + tokio::time::sleep(std::time::Duration::from_millis(2)).await; + System::current().stop(); + + //then + log.require_message_containing("send-after-delay: ValidateRepo")?; + Ok(()) +} + +#[test_log::test(actix::test)] #[ignore] //TODO: (#95) should notify user async fn when_fail_should_notify_user() -> TestResult { //given @@ -83,9 +109,6 @@ async fn when_fail_should_notify_user() -> TestResult { System::current().stop(); //then - tracing::debug!(?log, ""); - log.read() - .map_err(|e| e.to_string()) - .map(|l| assert!(l.iter().any(|message| message.contains("send: NotifyUser"))))?; + log.require_message_containing("send: NotifyUser")?; Ok(()) }