execute

Macro execute 

Source
macro_rules! execute {
    (
        actors: [
            $($actor_type:ty $(: $init_context:expr )? ),* $(,)?
        ],

        validation: async |$(mut $arg_pat:ident : $arg_ty:ty),* $(,)?| $validation_body:block $(,)?
    ) => { ... };
    (
        actors: [
            $($actor_type:ty $(: $init_context:expr )? ),* $(,)?
        ],

        validation: async || $validation_body:block $(,)?
    ) => { ... };
}
Expand description

Execute a test case with a set of actors.

This macro’s syntax mirrors that of veecle_os::runtime::execute! with an extra validation argument. The argument should be an async closure that runs any needed validations on the actors behaviors.

Any store lifetimes in the validation argument should use '_ as a placeholder.

use veecle_os::runtime::{Never, Reader, Writer, Storable};

#[derive(Clone, Copy, Debug, Eq, PartialEq, Storable)]
pub struct Data(u32);

#[derive(Debug, Storable)]
pub struct Trigger;

#[veecle_os::runtime::actor]
async fn incrementor(mut writer: Writer<'_, Data>, mut trigger: Reader<'_, Trigger>) -> Never {
    loop {
        trigger.wait_for_update().await;
        writer.modify(|data| {
            *data = Some(data.map_or(Data(0), |data| Data(data.0 + 1)));
        }).await;
    }
}

veecle_os_test::block_on_future(
    veecle_os_test::execute! {
        actors: [Incrementor],

        validation: async |mut reader: Reader<'_, Data>, mut trigger: Writer<'_, Trigger>| {
            trigger.write(Trigger).await;
            assert_eq!(reader.wait_for_update().await.read_cloned(), Some(Data(0)));
            trigger.write(Trigger).await;
            assert_eq!(reader.wait_for_update().await.read_cloned(), Some(Data(1)));
            trigger.write(Trigger).await;
            assert_eq!(reader.wait_for_update().await.read_cloned(), Some(Data(2)));
        },
    }
);