From 824c87aa86ccda2dc01432d388f8deabe3702ddd Mon Sep 17 00:00:00 2001 From: danielsanchezq Date: Thu, 19 Oct 2023 09:26:01 +0200 Subject: [PATCH] Add sequence test --- overwatch-rs/tests/sequence.rs | 164 +++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 overwatch-rs/tests/sequence.rs diff --git a/overwatch-rs/tests/sequence.rs b/overwatch-rs/tests/sequence.rs new file mode 100644 index 0000000..af61dd7 --- /dev/null +++ b/overwatch-rs/tests/sequence.rs @@ -0,0 +1,164 @@ +use overwatch_derive::Services; +use overwatch_rs::overwatch::OverwatchRunner; +use overwatch_rs::services::handle::{ServiceHandle, ServiceStateHandle}; +use overwatch_rs::services::relay::NoMessage; +use overwatch_rs::services::state::{NoOperator, NoState}; +use overwatch_rs::services::status::{ServiceStatus, StatusWatcher}; +use overwatch_rs::services::{ServiceCore, ServiceData, ServiceId}; +use overwatch_rs::DynError; +use std::time::Duration; + +pub struct AwaitService1 { + service_state: ServiceStateHandle, +} + +pub struct AwaitService2 { + service_state: ServiceStateHandle, +} + +pub struct AwaitService3 { + service_state: ServiceStateHandle, +} + +impl ServiceData for AwaitService1 { + const SERVICE_ID: ServiceId = "S1"; + type Settings = (); + type State = NoState; + type StateOperator = NoOperator; + type Message = NoMessage; +} + +impl ServiceData for AwaitService2 { + const SERVICE_ID: ServiceId = "S2"; + type Settings = (); + type State = NoState; + type StateOperator = NoOperator; + type Message = NoMessage; +} + +impl ServiceData for AwaitService3 { + const SERVICE_ID: ServiceId = "S3"; + type Settings = (); + type State = NoState; + type StateOperator = NoOperator; + type Message = NoMessage; +} + +#[async_trait::async_trait] +impl ServiceCore for AwaitService1 { + fn init(service_state: ServiceStateHandle) -> Result { + Ok(Self { service_state }) + } + + async fn run(self) -> Result<(), DynError> { + println!("Initialized 1"); + self.service_state + .status_handle + .updater() + .update(ServiceStatus::Running); + tokio::time::sleep(Duration::from_millis(100)).await; + self.service_state + .status_handle + .updater() + .update(ServiceStatus::Stopped); + Ok(()) + } +} + +#[async_trait::async_trait] +impl ServiceCore for AwaitService2 { + fn init(service_state: ServiceStateHandle) -> Result { + Ok(Self { service_state }) + } + + async fn run(self) -> Result<(), DynError> { + self.service_state + .status_handle + .updater() + .update(ServiceStatus::Running); + + let mut watcher: StatusWatcher = self + .service_state + .overwatch_handle + .status_watcher::() + .await; + + watcher + .wait_for(ServiceStatus::Running, Some(Duration::from_millis(50))) + .await + .unwrap(); + + println!("Initialized 2"); + tokio::time::sleep(Duration::from_millis(100)).await; + watcher + .wait_for(ServiceStatus::Stopped, Some(Duration::from_millis(50))) + .await + .unwrap(); + self.service_state + .status_handle + .updater() + .update(ServiceStatus::Stopped); + Ok(()) + } +} + +#[async_trait::async_trait] +impl ServiceCore for AwaitService3 { + fn init(service_state: ServiceStateHandle) -> Result { + Ok(Self { service_state }) + } + + async fn run(self) -> Result<(), DynError> { + self.service_state + .status_handle + .updater() + .update(ServiceStatus::Running); + + let mut watcher: StatusWatcher = self + .service_state + .overwatch_handle + .status_watcher::() + .await; + + watcher + .wait_for(ServiceStatus::Running, Some(Duration::from_millis(50))) + .await + .unwrap(); + + println!("Initialized 3"); + tokio::time::sleep(Duration::from_millis(100)).await; + watcher + .wait_for(ServiceStatus::Stopped, Some(Duration::from_millis(50))) + .await + .unwrap(); + self.service_state + .status_handle + .updater() + .update(ServiceStatus::Stopped); + Ok(()) + } +} + +#[derive(Services)] +struct SequenceServices { + c: ServiceHandle, + b: ServiceHandle, + a: ServiceHandle, +} + +#[test] +fn sequenced_services_startup() { + let settings = SequenceServicesServiceSettings { + a: (), + b: (), + c: (), + }; + let overwatch = OverwatchRunner::::run(settings, None).unwrap(); + let handle = overwatch.handle().clone(); + + overwatch.spawn(async move { + tokio::time::sleep(Duration::from_secs(1)).await; + handle.shutdown().await; + }); + overwatch.wait_finished(); +}