1 /* Copyright (c) 2010-2021. The SimGrid Team. All rights reserved. */
3 /* This program is free software; you can redistribute it and/or modify it
4 * under the terms of the license (GNU LGPL) which comes with this package. */
6 /* This example validates the behaviour in presence of node and link fault.
7 * Each test scenario consists in one host/actor (named sender) sending one message to another host/actor.
8 * The space to cover is quite large, since we consider:
9 * * communication types (eager, rendez-vous, one-sided=detached)
10 * * use type (synchronous, asynchronous, init)
11 * * fault type (sender node, link, receiver node)
12 * * any legal permutation of the scenario steps
14 * This program also presents a way to simulate applications that are resilient to links and node faults.
15 * Essentially, it catches exceptions related to communications and it clears the mailboxes when one of the nodes gets
16 * turned off. However, this model would suppose that there would be 2 mailboxes for each pair of nodes, which is
17 * probably unacceptable.
23 #include <simgrid/kernel/ProfileBuilder.hpp>
24 #include <simgrid/s4u.hpp>
29 namespace sg4 = simgrid::s4u;
30 namespace pr = simgrid::kernel::profile;
32 XBT_LOG_NEW_DEFAULT_CATEGORY(comm_fault_scenarios, "Messages specific for this s4u example");
34 /*************************************************************************************************/
36 // Constants for platform configuration
37 constexpr double HostComputePower = 1e9; // FLOPs
38 constexpr double LinkBandwidth = 1e9; // Bytes/second
39 constexpr double LinkLatency = 1e-6; // Seconds
41 // Constants for application behaviour
42 constexpr uint64_t MsgSize = LinkBandwidth / 2;
44 /*************************************************************************************************/
46 XBT_DECLARE_ENUM_CLASS(CommType, EAGER_SYNC, EAGER_ASYNC, EAGER_INIT, RDV_SYNC, RDV_ASYNC, RDV_INIT, ONESIDE_SYNC,
48 // ONESIDE_INIT is equivalent to ONESIDE_ASYNC
51 XBT_DECLARE_ENUM_CLASS(Action, SLEEP, PUT, GET, START, WAIT, DIE, END);
54 double rel_time; // Time relative to Scenario startTime
55 XBT_DECLARE_ENUM_CLASS(Type, STATE, ACTION) type;
56 XBT_DECLARE_ENUM_CLASS(Entity, LNK, SND, RCV) entity;
67 std::vector<Step> steps;
71 static std::string to_string(const Scenario& s)
74 ss << "#" << s.index << "[" << s.start_time << "s," << s.start_time + s.duration << "s[: (" << to_c_str(s.type);
75 ss << ") Expected: S:" << to_c_str(s.snd_expected) << " R:" << to_c_str(s.rcv_expected) << " Steps: ";
76 for (const Step& step : s.steps) {
77 ss << "+" << step.rel_time << "s:" << Step::to_c_str(step.entity);
79 if (step.type == Step::Type::STATE) {
86 ss << "." << to_c_str(step.action_type);
90 return ss.str().c_str();
93 struct ScenarioContext {
97 std::stringstream sender_profile;
98 std::stringstream receiver_profile;
99 std::stringstream link_profile;
100 std::vector<int> active_indices;
101 std::vector<Scenario> scenarios;
104 sg4::Mailbox* mbox_eager = nullptr;
105 sg4::Mailbox* mbox_rdv = nullptr;
110 static size_t scenario_;
112 sg4::Host* other_host_;
113 const ScenarioContext& ctx_;
115 sg4::CommPtr do_put(CommType type, double& send_value)
118 case CommType::EAGER_SYNC:
119 mbox_eager->put(&send_value, MsgSize);
121 case CommType::EAGER_ASYNC:
122 return mbox_eager->put_async(&send_value, MsgSize);
123 case CommType::EAGER_INIT:
124 return mbox_eager->put_init(&send_value, MsgSize);
125 case CommType::RDV_SYNC:
126 mbox_rdv->put(&send_value, MsgSize);
128 case CommType::RDV_ASYNC:
129 return mbox_rdv->put_async(&send_value, MsgSize);
130 case CommType::RDV_INIT:
131 return mbox_rdv->put_init(&send_value, MsgSize);
132 case CommType::ONESIDE_SYNC:
133 sg4::Comm::sendto(sg4::this_actor::get_host(), other_host_, MsgSize);
135 case CommType::ONESIDE_ASYNC:
136 return sg4::Comm::sendto_async(sg4::this_actor::get_host(), other_host_, MsgSize);
141 void send_message(const Scenario& s)
143 std::string scenario_string = to_string(s);
144 XBT_DEBUG("Will try: %s", scenario_string.c_str());
146 sg4::CommPtr comm = nullptr;
147 Action expected = s.snd_expected;
148 double end_time = s.start_time + s.duration;
149 send_value = end_time;
150 size_t step_index = 0;
151 sg4::this_actor::sleep_until(s.start_time);
152 // Make sure we have a clean slate
153 xbt_assert(not mbox_eager->listen(), "Eager mailbox should be empty when starting a test");
154 xbt_assert(not mbox_rdv->listen(), "RDV mailbox should be empty when starting a test");
155 for (; step_index < s.steps.size(); step_index++) {
156 const Step& step = s.steps[step_index];
157 if (step.entity != Step::Entity::SND || step.type != Step::Type::ACTION)
160 sg4::this_actor::sleep_until(s.start_time + step.rel_time);
161 } catch (std::exception& e) {
162 XBT_DEBUG("During Sleep, failed to send message because of a %s exception (%s)", typeid(e).name(), e.what());
165 // Check if the other host is still OK.
166 if (not other_host_->is_on())
168 // Perform the action
170 switch (step.action_type) {
172 comm = do_put(s.type, send_value);
181 xbt_die("Not a valid action for SND");
183 } catch (std::exception& e) {
184 XBT_DEBUG("During %s, failed to send message because of a %s exception (%s)", to_c_str(step.action_type),
185 typeid(e).name(), e.what());
190 sg4::this_actor::sleep_until(end_time);
191 } catch (std::exception& e) {
192 XBT_DEBUG("During Sleep, failed to send message because of a %s exception (%s)", typeid(e).name(), e.what());
194 Action outcome = Action::END;
195 if (step_index < s.steps.size()) {
196 const Step& step = s.steps[step_index];
197 assert(step.entity == Step::Entity::SND && step.type == Step::Type::ACTION);
198 outcome = step.action_type;
200 if (outcome != expected) {
201 XBT_ERROR("Expected %s but got %s in %s", to_c_str(expected), to_c_str(outcome), scenario_string.c_str());
203 XBT_DEBUG("OK: %s", scenario_string.c_str());
205 sg4::this_actor::sleep_until(end_time);
206 xbt_assert(not mbox_eager->listen(), "Mailbox should not have ongoing communication!");
207 xbt_assert(not mbox_rdv->listen(), "Mailbox should not have ongoing communication!");
211 explicit SendAgent(int id, sg4::Host* other_host, const ScenarioContext& ctx)
212 : id_(id), other_host_(other_host), ctx_(ctx)
219 XBT_DEBUG("Host %i starts run %i and scenario %lu.", id_, run_, scenario_);
220 while (scenario_ < ctx_.scenarios.size()) {
221 const Scenario& s = ctx_.scenarios[scenario_];
228 int SendAgent::run_ = 0;
229 size_t SendAgent::scenario_ = 0;
231 /*************************************************************************************************/
236 static size_t scenario_;
238 sg4::Host* other_host_;
239 const ScenarioContext& ctx_;
241 sg4::CommPtr do_get(CommType type, double*& receive_ptr)
244 case CommType::EAGER_SYNC:
245 receive_ptr = mbox_eager->get<double>();
247 case CommType::EAGER_ASYNC:
248 return mbox_eager->get_async(&receive_ptr);
249 case CommType::EAGER_INIT:
250 return mbox_eager->get_init()->set_dst_data((void**)(&receive_ptr));
251 case CommType::RDV_SYNC:
252 receive_ptr = mbox_rdv->get<double>();
254 case CommType::RDV_ASYNC:
255 return mbox_rdv->get_async(&receive_ptr);
256 case CommType::RDV_INIT:
257 return mbox_rdv->get_init()->set_dst_data((void**)(&receive_ptr));
258 case CommType::ONESIDE_SYNC:
259 case CommType::ONESIDE_ASYNC:
260 xbt_die("No get in One Sided comunications!");
265 void receive_message(const Scenario& s)
267 sg4::CommPtr comm = nullptr;
268 CommType type = s.type;
269 Action expected = s.rcv_expected;
270 double end_time = s.start_time + s.duration;
271 double* receive_ptr = nullptr;
272 size_t step_index = 0;
273 sg4::this_actor::sleep_until(s.start_time);
274 // Make sure we have a clean slate
275 xbt_assert(not mbox_eager->listen(), "Eager mailbox should be empty when starting a test");
276 xbt_assert(not mbox_rdv->listen(), "RDV mailbox should be empty when starting a test");
277 for (; step_index < s.steps.size(); step_index++) {
278 const Step& step = s.steps[step_index];
279 if (step.entity != Step::Entity::RCV || step.type != Step::Type::ACTION)
282 sg4::this_actor::sleep_until(s.start_time + step.rel_time);
283 } catch (std::exception& e) {
284 XBT_DEBUG("During Sleep, failed to receive message because of a %s exception (%s)", typeid(e).name(), e.what());
287 // Check if the other host is still OK.
288 if (not other_host_->is_on())
290 // Perform the action
292 switch (step.action_type) {
294 comm = do_get(type, receive_ptr);
303 xbt_die("Not a valid action for RCV");
305 } catch (std::exception& e) {
306 XBT_DEBUG("During %s, failed to receive message because of a %s exception (%s)", to_c_str(step.action_type),
307 typeid(e).name(), e.what());
312 sg4::this_actor::sleep_until(end_time - .1);
313 } catch (std::exception& e) {
314 XBT_DEBUG("During Sleep, failed to send message because of a %s exception (%s)", typeid(e).name(), e.what());
316 Action outcome = Action::END;
317 std::string scenario_string = to_string(s);
318 if (step_index < s.steps.size()) {
319 const Step& step = s.steps[step_index];
320 assert(step.entity == Step::Entity::RCV && step.type == Step::Type::ACTION);
321 outcome = step.action_type;
322 } else if (s.type != CommType::ONESIDE_SYNC && s.type != CommType::ONESIDE_ASYNC) {
323 // One sided / detached operations do not actually transfer anything
324 if (receive_ptr == nullptr) {
325 XBT_ERROR("Received address is NULL in %s", scenario_string.c_str());
326 } else if (*receive_ptr != end_time) {
327 XBT_ERROR("Received value invalid: expected %f but got %f in %s", end_time, *receive_ptr,
328 scenario_string.c_str());
331 if (outcome != expected) {
332 XBT_ERROR("Expected %s but got %s in %s", to_c_str(expected), to_c_str(outcome), scenario_string.c_str());
334 XBT_DEBUG("OK: %s", scenario_string.c_str());
336 sg4::this_actor::sleep_until(end_time);
337 xbt_assert(not mbox_eager->listen(), "Mailbox should not have ongoing communication!");
338 xbt_assert(not mbox_rdv->listen(), "Mailbox should not have ongoing communication!");
342 explicit ReceiveAgent(int id, sg4::Host* other_host, const ScenarioContext& ctx)
343 : id_(id), other_host_(other_host), ctx_(ctx)
349 XBT_DEBUG("Host %i starts run %i and scenario %lu.", id_, run_, scenario_);
350 mbox_eager->set_receiver(sg4::Actor::self());
351 while (scenario_ < ctx_.scenarios.size()) {
352 const Scenario& s = ctx_.scenarios[scenario_];
359 int ReceiveAgent::run_ = 0;
360 size_t ReceiveAgent::scenario_ = 0;
362 static void on_host_state_change(sg4::Host const& host)
364 XBT_DEBUG("Host %s is now %s", host.get_cname(), host.is_on() ? "ON " : "OFF");
365 if (not host.is_on()) {
371 static void on_link_state_change(sg4::Link const& link)
373 XBT_DEBUG("Link %s is now %s", link.get_cname(), link.is_on() ? "ON " : "OFF");
376 double build_scenarios(ScenarioContext& ctx);
378 int main(int argc, char* argv[])
380 sg4::Engine e(&argc, argv);
382 int previous_index = -1;
383 bool is_range_last = false;
384 for (int i = 1; i < argc; i++) {
385 if (not strcmp(argv[i], "-"))
386 is_range_last = true;
388 int index = atoi(argv[i]);
389 xbt_assert(index > previous_index);
391 for (int j = previous_index + 1; j <= index; j++)
392 ctx.active_indices.push_back(j);
394 ctx.active_indices.push_back(index);
395 is_range_last = false;
396 previous_index = index;
399 double end_time = build_scenarios(ctx);
400 XBT_INFO("Will run for %f seconds", end_time);
401 mbox_eager = e.mailbox_by_name_or_create("eager");
402 mbox_rdv = e.mailbox_by_name_or_create("rdv");
403 sg4::NetZone* zone = sg4::create_full_zone("Top");
404 pr::Profile* profile_sender = pr::ProfileBuilder::from_string("sender_profile", ctx.sender_profile.str(), 0);
405 sg4::Host* sender_host = zone->create_host("senderHost", HostComputePower)->set_state_profile(profile_sender)->seal();
406 pr::Profile* profile_receiver = pr::ProfileBuilder::from_string("receiver_profile", ctx.receiver_profile.str(), 0);
407 sg4::Host* receiver_host =
408 zone->create_host("receiverHost", HostComputePower)->set_state_profile(profile_receiver)->seal();
409 sg4::ActorPtr sender = sg4::Actor::create("sender", sender_host, SendAgent(0, receiver_host, ctx));
410 sender->set_auto_restart(true);
411 sg4::ActorPtr receiver = sg4::Actor::create("receiver", receiver_host, ReceiveAgent(1, sender_host, ctx));
412 receiver->set_auto_restart(true);
413 pr::Profile* profile_link = pr::ProfileBuilder::from_string("link_profile", ctx.link_profile.str(), 0);
415 zone->create_link("link", LinkBandwidth)->set_latency(LinkLatency)->set_state_profile(profile_link)->seal();
416 zone->add_route(sender_host->get_netpoint(), receiver_host->get_netpoint(), nullptr, nullptr,
417 {sg4::LinkInRoute{link}}, false);
419 sg4::Host::on_state_change.connect(on_host_state_change);
420 sg4::Link::on_state_change_cb(on_link_state_change);
421 e.run_until(end_time);
423 // Make sure we have a clean slate
424 xbt_assert(not mbox_eager->listen(), "Eager mailbox should be empty in the end");
425 xbt_assert(not mbox_rdv->listen(), "RDV mailbox should be empty in the end");
430 static void addStateEvent(std::ostream& out, double date, bool isOn)
433 out << date << " 1\n";
435 out << date << " 0\n";
438 static void prepareScenario(ScenarioContext& ctx, CommType type, double duration, Action sender_expected,
439 Action receiver_expected, std::vector<Step> steps)
441 if (std::find(ctx.active_indices.begin(), ctx.active_indices.end(), ctx.index) != ctx.active_indices.end()) {
442 // Update fault profiles
443 for (Step& step : steps) {
444 assert(step.rel_time < duration);
445 if (step.type != Step::Type::STATE)
447 int val = step.new_state ? 1 : 0;
448 switch (step.entity) {
449 case Step::Entity::SND:
450 ctx.sender_profile << ctx.start_time + step.rel_time << " " << val << std::endl;
452 case Step::Entity::RCV:
453 ctx.receiver_profile << ctx.start_time + step.rel_time << " " << val << std::endl;
455 case Step::Entity::LNK:
456 ctx.link_profile << ctx.start_time + step.rel_time << " " << val << std::endl;
460 ctx.scenarios.push_back({type, ctx.start_time, duration, sender_expected, receiver_expected, steps, ctx.index});
464 ctx.start_time += duration;
467 /*************************************************************************************************/
469 // A bunch of dirty macros to help readability (supposedly)
470 #define MAKE_SCENARIO(type, duration, snd_expected, rcv_expected, steps...) \
471 prepareScenario(ctx, CommType::type, duration, Action::snd_expected, Action::rcv_expected, {steps})
474 static Step loff(double rel_time)
476 return {rel_time, Step::Type::STATE, Step::Entity::LNK, Action::END, false};
478 static Step lon(double rel_time)
480 return {rel_time, Step::Type::STATE, Step::Entity::LNK, Action::END, true};
483 static Step soff(double rel_time)
485 return {rel_time, Step::Type::STATE, Step::Entity::SND, Action::END, false};
487 static Step son(double rel_time)
489 return {rel_time, Step::Type::STATE, Step::Entity::SND, Action::END, true};
491 static Step sput(double rel_time)
493 return {rel_time, Step::Type::ACTION, Step::Entity::SND, Action::PUT, false};
495 static Step swait(double rel_time)
497 return {rel_time, Step::Type::ACTION, Step::Entity::SND, Action::WAIT, false};
500 static Step roff(double rel_time)
502 return {rel_time, Step::Type::STATE, Step::Entity::RCV, Action::END, false};
504 static Step ron(double rel_time)
506 return {rel_time, Step::Type::STATE, Step::Entity::RCV, Action::END, true};
508 static Step rget(double rel_time)
510 return {rel_time, Step::Type::ACTION, Step::Entity::RCV, Action::GET, false};
512 static Step rwait(double rel_time)
514 return {rel_time, Step::Type::ACTION, Step::Entity::RCV, Action::WAIT, false};
517 double build_scenarios(ScenarioContext& ctx)
523 // EAGER SYNC use cases
525 MAKE_SCENARIO(EAGER_SYNC, 1, END, END, sput(.2), rget(.4));
526 MAKE_SCENARIO(EAGER_SYNC, 1, END, END, rget(.2), sput(.4));
528 MAKE_SCENARIO(EAGER_SYNC, 2, PUT, DIE, roff(.1), sput(.2), ron(1));
529 MAKE_SCENARIO(EAGER_SYNC, 2, PUT, DIE, sput(.2), roff(.3), ron(1));
530 MAKE_SCENARIO(EAGER_SYNC, 2, PUT, DIE, sput(.2), rget(.4), roff(.5), ron(1));
531 MAKE_SCENARIO(EAGER_SYNC, 2, PUT, DIE, rget(.2), sput(.4), roff(.5), ron(1));
533 MAKE_SCENARIO(EAGER_SYNC, 2, DIE, GET, sput(.2), soff(.3), rget(.4), son(1));
534 MAKE_SCENARIO(EAGER_SYNC, 2, DIE, GET, sput(.2), rget(.4), soff(.5), son(1));
536 MAKE_SCENARIO(EAGER_SYNC, 2, PUT, GET, loff(.1), sput(.2), rget(.4), lon(1));
537 MAKE_SCENARIO(EAGER_SYNC, 2, PUT, GET, sput(.2), loff(.3), rget(.4), lon(1));
538 MAKE_SCENARIO(EAGER_SYNC, 2, PUT, GET, sput(.2), rget(.4), loff(.5), lon(1));
539 MAKE_SCENARIO(EAGER_SYNC, 2, PUT, GET, loff(.1), rget(.2), sput(.4), lon(1));
540 MAKE_SCENARIO(EAGER_SYNC, 2, PUT, GET, rget(.2), loff(.3), sput(.4), lon(1));
541 MAKE_SCENARIO(EAGER_SYNC, 2, PUT, GET, rget(.2), sput(.4), loff(.5), lon(1));
543 // EAGER ASYNC use cases
545 MAKE_SCENARIO(EAGER_ASYNC, 2, END, END, sput(.2), swait(.4), rget(.6), rwait(.8));
546 MAKE_SCENARIO(EAGER_ASYNC, 2, END, END, sput(.2), rget(.4), swait(.6), rwait(.8));
547 MAKE_SCENARIO(EAGER_ASYNC, 2, END, END, sput(.2), rget(.4), rwait(.6), swait(.8));
548 MAKE_SCENARIO(EAGER_ASYNC, 2, END, END, rget(.2), sput(.4), swait(.6), rwait(.8));
549 MAKE_SCENARIO(EAGER_ASYNC, 2, END, END, rget(.2), sput(.4), rwait(.6), swait(.8));
550 MAKE_SCENARIO(EAGER_ASYNC, 2, END, END, rget(.2), rwait(.4), sput(.6), swait(.8));
552 MAKE_SCENARIO(EAGER_ASYNC, 2, PUT, DIE, roff(.1), sput(.2), swait(.4), ron(1));
553 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, DIE, sput(.2), roff(.3), swait(.4), ron(1));
554 MAKE_SCENARIO(EAGER_ASYNC, 2, PUT, DIE, rget(.2), roff(.3), sput(.4), swait(.6), ron(1));
555 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, DIE, sput(.2), swait(.4), roff(.5), ron(1));
556 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, DIE, sput(.2), rget(.4), roff(.5), swait(.6), ron(1));
557 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, DIE, rget(.2), sput(.4), roff(.5), swait(.6), ron(1));
558 MAKE_SCENARIO(EAGER_ASYNC, 2, PUT, DIE, rget(.2), rwait(.4), roff(.5), sput(.6), swait(.8), ron(1));
559 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, DIE, sput(.2), swait(.4), rget(.6), roff(.7), ron(1));
560 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, DIE, sput(.2), rget(.4), swait(.6), roff(.7), ron(1));
561 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, DIE, sput(.2), rget(.4), rwait(.6), roff(.7), swait(.8), ron(1));
562 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, DIE, rget(.2), sput(.4), swait(.6), roff(.7), ron(1));
563 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, DIE, rget(.2), sput(.4), rwait(.6), roff(.7), swait(.8), ron(1));
564 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, DIE, rget(.2), rwait(.4), sput(.6), roff(.7), swait(.8), ron(1));
565 // Sender off (only cases where sender did put, because otherwise receiver cannot find out there was a fault)
566 MAKE_SCENARIO(EAGER_ASYNC, 2, DIE, GET, sput(.2), soff(.3), rget(.4), rwait(.6), son(1));
567 MAKE_SCENARIO(EAGER_ASYNC, 2, DIE, WAIT, rget(.2), sput(.4), soff(.5), rwait(.6), son(1));
568 MAKE_SCENARIO(EAGER_ASYNC, 2, DIE, WAIT, sput(.2), rget(.4), soff(.5), rwait(.6), son(1));
569 MAKE_SCENARIO(EAGER_ASYNC, 2, DIE, GET, sput(.2), swait(.4), soff(.5), rget(.6), rwait(.8), son(1));
570 MAKE_SCENARIO(EAGER_ASYNC, 2, DIE, WAIT, rget(.2), rwait(.4), sput(.6), soff(.7), son(1));
571 MAKE_SCENARIO(EAGER_ASYNC, 2, DIE, WAIT, rget(.2), sput(.4), rwait(.6), soff(.7), son(1));
572 MAKE_SCENARIO(EAGER_ASYNC, 2, DIE, WAIT, rget(.2), sput(.4), swait(.6), soff(.7), rwait(.8), son(1));
573 MAKE_SCENARIO(EAGER_ASYNC, 2, DIE, WAIT, sput(.2), rget(.4), rwait(.6), soff(.7), son(1));
574 MAKE_SCENARIO(EAGER_ASYNC, 2, DIE, WAIT, sput(.2), rget(.4), swait(.6), soff(.7), rwait(.8), son(1));
575 MAKE_SCENARIO(EAGER_ASYNC, 2, DIE, WAIT, sput(.2), swait(.4), rget(.6), soff(.7), rwait(.8), son(1));
577 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, loff(.1), sput(.2), swait(.4), rget(.6), rwait(.8), lon(1));
578 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, loff(.1), sput(.2), rget(.4), swait(.6), rwait(.8), lon(1));
579 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, loff(.1), sput(.2), rget(.4), rwait(.6), swait(.8), lon(1));
580 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, loff(.1), rget(.2), sput(.4), swait(.6), rwait(.8), lon(1));
581 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, loff(.1), rget(.2), sput(.4), rwait(.6), swait(.8), lon(1));
582 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, loff(.1), rget(.2), rwait(.4), sput(.6), swait(.8), lon(1));
583 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, sput(.2), loff(.3), swait(.4), rget(.6), rwait(.8), lon(1));
584 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, sput(.2), loff(.3), rget(.4), swait(.6), rwait(.8), lon(1));
585 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, sput(.2), loff(.3), rget(.4), rwait(.6), swait(.8), lon(1));
586 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, rget(.2), loff(.3), sput(.4), swait(.6), rwait(.8), lon(1));
587 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, rget(.2), loff(.3), sput(.4), rwait(.6), swait(.8), lon(1));
588 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, rget(.2), loff(.3), rwait(.4), sput(.6), swait(.8), lon(1));
589 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, sput(.2), swait(.4), loff(.5), rget(.6), rwait(.8), lon(1));
590 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, sput(.2), rget(.4), loff(.5), swait(.6), rwait(.8), lon(1));
591 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, sput(.2), rget(.4), loff(.5), rwait(.6), swait(.8), lon(1));
592 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, rget(.2), sput(.4), loff(.5), swait(.6), rwait(.8), lon(1));
593 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, rget(.2), sput(.4), loff(.5), rwait(.6), swait(.8), lon(1));
594 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, rget(.2), rwait(.4), loff(.5), sput(.6), swait(.8), lon(1));
595 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, sput(.2), swait(.4), rget(.6), loff(.7), rwait(.8), lon(1));
596 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, sput(.2), rget(.4), swait(.6), loff(.7), rwait(.8), lon(1));
597 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, sput(.2), rget(.4), rwait(.6), loff(.7), swait(.8), lon(1));
598 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, rget(.2), sput(.4), swait(.6), loff(.7), rwait(.8), lon(1));
599 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, rget(.2), sput(.4), rwait(.6), loff(.7), swait(.8), lon(1));
600 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, rget(.2), rwait(.4), sput(.6), loff(.7), swait(.8), lon(1));
602 // RDV SYNC use cases
604 MAKE_SCENARIO(RDV_SYNC, 1, END, END, sput(.2), rget(.4));
605 MAKE_SCENARIO(RDV_SYNC, 1, END, END, rget(.2), sput(.4));
607 MAKE_SCENARIO(RDV_SYNC, 2, PUT, DIE, roff(.1), sput(.2), ron(1));
608 MAKE_SCENARIO(RDV_SYNC, 2, PUT, DIE, sput(.2), roff(.3),
609 ron(1)); // Fails because put comm cancellation does not trigger sender exception
610 MAKE_SCENARIO(RDV_SYNC, 2, PUT, DIE, sput(.2), rget(.4), roff(.5), ron(1));
611 MAKE_SCENARIO(RDV_SYNC, 2, PUT, DIE, rget(.2), sput(.4), roff(.5), ron(1));
613 MAKE_SCENARIO(RDV_SYNC, 2, DIE, GET, sput(.2), rget(.4), soff(.5), son(1));
615 MAKE_SCENARIO(RDV_SYNC, 2, PUT, GET, loff(.1), sput(.2), rget(.4), lon(1));
616 MAKE_SCENARIO(RDV_SYNC, 2, PUT, GET, sput(.2), loff(.3), rget(.4), lon(1));
617 MAKE_SCENARIO(RDV_SYNC, 2, PUT, GET, sput(.2), rget(.4), loff(.5), lon(1));
618 MAKE_SCENARIO(RDV_SYNC, 2, PUT, GET, loff(.1), rget(.2), sput(.4), lon(1));
619 MAKE_SCENARIO(RDV_SYNC, 2, PUT, GET, rget(.2), loff(.3), sput(.4), lon(1));
620 MAKE_SCENARIO(RDV_SYNC, 2, PUT, GET, rget(.2), sput(.4), loff(.5), lon(1));
622 // RDV ASYNC use cases
624 MAKE_SCENARIO(RDV_ASYNC, 2, END, END, sput(.2), swait(.4), rget(.6), rwait(.8));
625 MAKE_SCENARIO(RDV_ASYNC, 2, END, END, sput(.2), rget(.4), swait(.6), rwait(.8));
626 MAKE_SCENARIO(RDV_ASYNC, 2, END, END, sput(.2), rget(.4), rwait(.6), swait(.8));
627 MAKE_SCENARIO(RDV_ASYNC, 2, END, END, rget(.2), sput(.4), swait(.6), rwait(.8));
628 MAKE_SCENARIO(RDV_ASYNC, 2, END, END, rget(.2), sput(.4), rwait(.6), swait(.8));
629 MAKE_SCENARIO(RDV_ASYNC, 2, END, END, rget(.2), rwait(.4), sput(.6), swait(.8));
631 MAKE_SCENARIO(RDV_ASYNC, 2, PUT, DIE, roff(.1), sput(.2), swait(.4), ron(1));
632 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, DIE, sput(.2), roff(.3), swait(.4), ron(1));
633 MAKE_SCENARIO(RDV_ASYNC, 2, PUT, DIE, rget(.2), roff(.3), sput(.4), swait(.6), ron(1));
634 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, DIE, sput(.2), swait(.4), roff(.5),
635 ron(1)); // Fails because put comm cancellation does not trigger sender exception
636 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, DIE, sput(.2), rget(.4), roff(.5), swait(.6), ron(1));
637 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, DIE, rget(.2), sput(.4), roff(.5), swait(.6), ron(1));
638 MAKE_SCENARIO(RDV_ASYNC, 2, PUT, DIE, rget(.2), rwait(.4), roff(.5), sput(.6), swait(.8), ron(1));
639 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, DIE, sput(.2), swait(.4), rget(.6), roff(.7), ron(1));
640 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, DIE, sput(.2), rget(.4), swait(.6), roff(.7), ron(1));
641 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, DIE, sput(.2), rget(.4), rwait(.6), roff(.7), swait(.8), ron(1));
642 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, DIE, rget(.2), sput(.4), swait(.6), roff(.7), ron(1));
643 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, DIE, rget(.2), sput(.4), rwait(.6), roff(.7), swait(.8), ron(1));
644 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, DIE, rget(.2), rwait(.4), sput(.6), roff(.7), swait(.8), ron(1));
645 // Sender off (only cases where sender did put, because otherwise receiver cannot find out there was a fault)
646 MAKE_SCENARIO(RDV_ASYNC, 2, DIE, GET, sput(.2), soff(.3), rget(.4), rwait(.6), son(1));
647 MAKE_SCENARIO(RDV_ASYNC, 2, DIE, WAIT, rget(.2), sput(.4), soff(.5), rwait(.6), son(1));
648 MAKE_SCENARIO(RDV_ASYNC, 2, DIE, WAIT, sput(.2), rget(.4), soff(.5), rwait(.6), son(1));
649 MAKE_SCENARIO(RDV_ASYNC, 2, DIE, GET, sput(.2), swait(.4), soff(.5), rget(.6), rwait(.8), son(1));
650 MAKE_SCENARIO(RDV_ASYNC, 2, DIE, WAIT, rget(.2), rwait(.4), sput(.6), soff(.7), son(1));
651 MAKE_SCENARIO(RDV_ASYNC, 2, DIE, WAIT, rget(.2), sput(.4), rwait(.6), soff(.7), son(1));
652 MAKE_SCENARIO(RDV_ASYNC, 2, DIE, WAIT, rget(.2), sput(.4), swait(.6), soff(.7), rwait(.8), son(1));
653 MAKE_SCENARIO(RDV_ASYNC, 2, DIE, WAIT, sput(.2), rget(.4), rwait(.6), soff(.7), son(1));
654 MAKE_SCENARIO(RDV_ASYNC, 2, DIE, WAIT, sput(.2), rget(.4), swait(.6), soff(.7), rwait(.8), son(1));
655 MAKE_SCENARIO(RDV_ASYNC, 2, DIE, WAIT, sput(.2), swait(.4), rget(.6), soff(.7), rwait(.8), son(1));
657 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, loff(.1), sput(.2), swait(.4), rget(.6), rwait(.8), lon(1));
658 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, loff(.1), sput(.2), rget(.4), swait(.6), rwait(.8), lon(1));
659 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, loff(.1), sput(.2), rget(.4), rwait(.6), swait(.8), lon(1));
660 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, loff(.1), rget(.2), sput(.4), swait(.6), rwait(.8), lon(1));
661 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, loff(.1), rget(.2), sput(.4), rwait(.6), swait(.8), lon(1));
662 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, loff(.1), rget(.2), rwait(.4), sput(.6), swait(.8), lon(1));
663 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, sput(.2), loff(.3), swait(.4), rget(.6), rwait(.8), lon(1));
664 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, sput(.2), loff(.3), rget(.4), swait(.6), rwait(.8), lon(1));
665 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, sput(.2), loff(.3), rget(.4), rwait(.6), swait(.8), lon(1));
666 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, rget(.2), loff(.3), sput(.4), swait(.6), rwait(.8), lon(1));
667 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, rget(.2), loff(.3), sput(.4), rwait(.6), swait(.8), lon(1));
668 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, rget(.2), loff(.3), rwait(.4), sput(.6), swait(.8), lon(1));
669 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, sput(.2), swait(.4), loff(.5), rget(.6), rwait(.8), lon(1));
670 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, sput(.2), rget(.4), loff(.5), swait(.6), rwait(.8), lon(1));
671 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, sput(.2), rget(.4), loff(.5), rwait(.6), swait(.8), lon(1));
672 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, rget(.2), sput(.4), loff(.5), swait(.6), rwait(.8), lon(1));
673 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, rget(.2), sput(.4), loff(.5), rwait(.6), swait(.8), lon(1));
674 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, rget(.2), rwait(.4), loff(.5), sput(.6), swait(.8), lon(1));
675 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, sput(.2), swait(.4), rget(.6), loff(.7), rwait(.8), lon(1));
676 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, sput(.2), rget(.4), swait(.6), loff(.7), rwait(.8), lon(1));
677 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, sput(.2), rget(.4), rwait(.6), loff(.7), swait(.8), lon(1));
678 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, rget(.2), sput(.4), swait(.6), loff(.7), rwait(.8), lon(1));
679 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, rget(.2), sput(.4), rwait(.6), loff(.7), swait(.8), lon(1));
680 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, rget(.2), rwait(.4), sput(.6), loff(.7), swait(.8), lon(1));
682 // ONESIDE SYNC use cases
684 MAKE_SCENARIO(ONESIDE_SYNC, 1, END, END, sput(.2));
686 MAKE_SCENARIO(ONESIDE_SYNC, 2, PUT, DIE, roff(.1), sput(.2), ron(1));
687 MAKE_SCENARIO(ONESIDE_SYNC, 2, PUT, DIE, sput(.2), roff(.3), ron(1));
689 MAKE_SCENARIO(ONESIDE_SYNC, 2, DIE, END, sput(.2), soff(.3), son(1));
691 MAKE_SCENARIO(ONESIDE_SYNC, 2, PUT, END, loff(.1), sput(.2), lon(1));
692 MAKE_SCENARIO(ONESIDE_SYNC, 2, PUT, END, sput(.2), loff(.3), lon(1));
694 // ONESIDE ASYNC use cases
696 MAKE_SCENARIO(ONESIDE_ASYNC, 2, END, END, sput(.2), swait(.4));
698 MAKE_SCENARIO(ONESIDE_ASYNC, 2, PUT, DIE, roff(.1), sput(.2), swait(.4), ron(1));
699 MAKE_SCENARIO(ONESIDE_ASYNC, 2, WAIT, DIE, sput(.2), roff(.3), swait(.4), ron(1));
700 MAKE_SCENARIO(ONESIDE_ASYNC, 2, WAIT, DIE, sput(.2), swait(.4), roff(.5), ron(1));
702 MAKE_SCENARIO(ONESIDE_ASYNC, 2, DIE, END, sput(.2), soff(.3), son(1));
704 MAKE_SCENARIO(ONESIDE_ASYNC, 2, WAIT, END, loff(.1), sput(.2), swait(.4), lon(1));
705 MAKE_SCENARIO(ONESIDE_ASYNC, 2, WAIT, END, sput(.2), loff(.3), swait(.4), lon(1));
706 MAKE_SCENARIO(ONESIDE_ASYNC, 2, WAIT, END, sput(.2), swait(.4), loff(.5), lon(1));
708 XBT_INFO("Will execute %i active scenarios out of %i.", ctx.active, ctx.index);
709 return ctx.start_time + 1;