Testing

测试并发系统比单线程应用程序更困难,因为测试本身和应用程序在不同的线程上运行。 此外,由于Riker的弹性自我修复方法,恐慌被隔离,处理和故障组件重新启动,检测测试失败证明是具有挑战性的。

为了帮助简化测试,riker-testkit引入了一个“探测器”,可以通过消息传递或作为 Actor道具的一部分发送给 Actor。 然后,探针可以将值发送回测试线程。

以下是测试actor重启的示例:

#[macro_use]
extern crate riker_testkit;

type TestProbe = ChannelProbe<(), ()>;

#[derive(Clone, Debug)]
enum TestMsg {
    Probe(TestProbe),
    Panic,
}

impl Into<ActorMsg<TestMsg>> for TestMsg {
    fn into(self) -> ActorMsg<TestMsg> {
        ActorMsg::User(self)
    }
}

struct MyActor;

impl MyActor {
    fn new() -> BoxActor<TestMsg> {
        Box::new(MyActor)
    }
}

impl Actor for MyActor {
    type Msg = TestMsg;

    fn receive(&mut self,
                _ctx: &Context<Self::Msg>,
                msg: Self::Msg,
                _sender: Option<ActorRef<Self::Msg>>)
    {
        match msg {
            TestMsg::Panic => {
                // panic the actor to simulate failure
                panic!("// TEST PANIC // TEST PANIC // TEST PANIC //");
            }
            TestMsg::Probe(probe) => {
                // received probe
                // let's emit () empty tuple back to listener
                probe.event(());
            }
        };
    }
}

#[test]
fn panic_actor() {
    let model: DefaultModel<TestMsg> = DefaultModel::new();
    let sys = ActorSystem::new(&model).unwrap();

    let props = Props::new(Box::new(MyActor::new));
    let actor = sys.actor_of(props, "my-actor").unwrap();

    // Make the test actor panic
    actor.tell(TestMsg::Panic, None);

    // Prepare a probe
    let (probe, listen) = probe::<()>();

    // Send the probe to the panicked actor
    // which would have been restarted
    actor.tell(TestMsg::Probe(probe), None);

    // Testkit provides a macro to assert the result
    // that gets emmitted from the probe to the listener.
    // Here we're expecting () empty tuple.
    p_assert_eq!(listen, ());
}

此测试显示我们的actor在失败后成功重启。 它能够继续接收消息,在这种情况下是探测。 宏p_assert_eq! 等待(块)侦听器,直到从探测器接收到值。

上次更新: 1/7/2019, 3:17:09 PM