Commit cee8dd7c authored by Dominik Charousset's avatar Dominik Charousset

improved unit test for sync send

this patch adds tests for functor-only usage
parent c54bf185
...@@ -11,6 +11,14 @@ struct sync_mirror : sb_actor<sync_mirror> { ...@@ -11,6 +11,14 @@ struct sync_mirror : sb_actor<sync_mirror> {
); );
}; };
// replies to 'f' with 0.0f and to 'i' with 0
struct float_or_int : sb_actor<float_or_int> {
behavior init_state = (
on(atom("f")) >> [] { reply(0.0f); },
on(atom("i")) >> [] { reply(0); }
);
};
struct popular_actor : event_based_actor { // popular actors have a buddy struct popular_actor : event_based_actor { // popular actors have a buddy
actor_ptr m_buddy; actor_ptr m_buddy;
popular_actor(const actor_ptr& buddy) : m_buddy(buddy) { } popular_actor(const actor_ptr& buddy) : m_buddy(buddy) { }
...@@ -116,16 +124,95 @@ struct D : popular_actor { ...@@ -116,16 +124,95 @@ struct D : popular_actor {
} }
}; };
/******************************************************************************\
* test case 3: *
* *
* Client Server Worker *
* | | | *
* | | <---(idle)------ | *
* | ---(request)---> | | *
* | | ---(request)---> | *
* | | |---\ *
* | X | | *
* | |<--/ *
* | <------------(response)------------ | *
* X *
\******************************************************************************/
struct server : event_based_actor {
void init() {
auto die = [=] { quit(exit_reason::user_defined); };
become (
on(atom("idle")) >> [=] {
auto worker = last_sender();
become (
keep_behavior,
on(atom("request")) >> [=] {
forward_to(worker);
unbecome(); // await next idle message
},
on(atom("idle")) >> skip_message,
others() >> die
);
},
on(atom("request")) >> skip_message,
others() >> die
);
}
};
int main() { int main() {
CPPA_TEST(test__sync_send); CPPA_TEST(test__sync_send);
self->on_sync_failure([] {
CPPA_ERROR("received: " << to_string(self->last_dequeued()));
});
spawn_monitor([&] {
int invocations = 0;
auto foi = spawn_link<float_or_int>();
send(foi, atom("i"));
receive(on_arg_match >> [](int i) { CPPA_CHECK_EQUAL(i, 0); });
self->on_sync_failure([] {
CPPA_ERROR("received: " << to_string(self->last_dequeued()));
});
sync_send(foi, atom("i")).then(
[&](int i) { CPPA_CHECK_EQUAL(i, 0); ++invocations; },
[&](float) { CPPA_UNEXPECTED_MSG(); }
)
.continue_with([&] {
sync_send(foi, atom("f")).then(
[&](int) { CPPA_UNEXPECTED_MSG(); },
[&](float f) { CPPA_CHECK_EQUAL(f, 0); ++invocations; }
);
});
self->exec_behavior_stack();
CPPA_CHECK_EQUAL(invocations, 2);
// provoke invocation of self->handle_sync_failure()
bool sync_failure_called = false;
bool int_handler_called = false;
self->on_sync_failure([&] {
sync_failure_called = true;
});
sync_send(foi, atom("f")).await(
on<int>() >> [&] { int_handler_called = true; }
);
CPPA_CHECK_EQUAL(sync_failure_called, true);
CPPA_CHECK_EQUAL(int_handler_called, false);
self->quit(exit_reason::user_defined);
});
receive (
on(atom("DOWN"), exit_reason::user_defined) >> CPPA_CHECKPOINT_CB(),
others() >> CPPA_UNEXPECTED_MSG_CB()
);
auto mirror = spawn<sync_mirror>(); auto mirror = spawn<sync_mirror>();
bool continuation_called = false; bool continuation_called = false;
sync_send(mirror, 42).then( sync_send(mirror, 42)
[](int value) { CPPA_CHECK_EQUAL(value, 42); } .then([](int value) { CPPA_CHECK_EQUAL(value, 42); })
) .continue_with([&] { continuation_called = true; });
.continue_with(
[&] { continuation_called = true; }
);
self->exec_behavior_stack(); self->exec_behavior_stack();
CPPA_CHECK_EQUAL(continuation_called, true); CPPA_CHECK_EQUAL(continuation_called, true);
quit_actor(mirror, exit_reason::user_defined); quit_actor(mirror, exit_reason::user_defined);
...@@ -174,6 +261,7 @@ int main() { ...@@ -174,6 +261,7 @@ int main() {
// first test: sync error must occur, continuation must not be called // first test: sync error must occur, continuation must not be called
bool timeout_occured = false; bool timeout_occured = false;
self->on_sync_timeout([&] { timeout_occured = true; }); self->on_sync_timeout([&] { timeout_occured = true; });
self->on_sync_failure(CPPA_UNEXPECTED_MSG_CB());
timed_sync_send(c, std::chrono::milliseconds(500), atom("HiThere")) timed_sync_send(c, std::chrono::milliseconds(500), atom("HiThere"))
.then(CPPA_ERROR_CB("C replied to 'HiThere'!")) .then(CPPA_ERROR_CB("C replied to 'HiThere'!"))
.continue_with(CPPA_ERROR_CB("bad continuation")); .continue_with(CPPA_ERROR_CB("bad continuation"));
...@@ -186,6 +274,40 @@ int main() { ...@@ -186,6 +274,40 @@ int main() {
quit_actor(c, exit_reason::user_defined); quit_actor(c, exit_reason::user_defined);
await_all_others_done(); await_all_others_done();
CPPA_CHECKPOINT(); CPPA_CHECKPOINT();
// test use case 3
spawn_monitor([] { // client
auto s = spawn_link<server>(); // server
auto w = spawn_link([] { // worker
receive_loop(on(atom("request")) >> []{ reply(atom("response")); });
});
// first 'idle', then 'request'
send_as(w, s, atom("idle"));
sync_send(s, atom("request")).await(
on(atom("response")) >> [=] {
CPPA_CHECKPOINT();
CPPA_CHECK_EQUAL(self->last_sender(), w);
},
others() >> CPPA_UNEXPECTED_MSG_CB()
);
// first 'request', then 'idle'
auto handle = sync_send(s, atom("request"));
send_as(w, s, atom("idle"));
receive_response(handle) (
on(atom("response")) >> [=] {
CPPA_CHECKPOINT();
CPPA_CHECK_EQUAL(self->last_sender(), w);
},
others() >> CPPA_UNEXPECTED_MSG_CB()
);
send(s, "Ever danced with the devil in the pale moonlight?");
// response: {'EXIT', exit_reason::user_defined}
receive_loop(others() >> CPPA_UNEXPECTED_MSG_CB());
});
receive (
on(atom("DOWN"), exit_reason::user_defined) >> CPPA_CHECKPOINT_CB(),
others() >> CPPA_UNEXPECTED_MSG_CB()
);
await_all_others_done(); await_all_others_done();
CPPA_CHECKPOINT(); CPPA_CHECKPOINT();
shutdown(); shutdown();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment