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 turned off.
16 * However, this model would suppose that there would be 2 mailboxes for each pair of nodes, which is probably unacceptable.
22 #include <simgrid/kernel/ProfileBuilder.hpp>
23 #include <simgrid/s4u.hpp>
28 namespace sg4 = simgrid::s4u;
29 namespace pr = simgrid::kernel::profile;
31 XBT_LOG_NEW_DEFAULT_CATEGORY(comm_fault_scenarios, "Messages specific for this s4u example");
33 /*************************************************************************************************/
35 // Constants for platform configuration
36 constexpr double HostComputePower = 1e9; // FLOPs
37 constexpr double LinkBandwidth = 1e9; // Bytes/second
38 constexpr double LinkLatency = 1e-6; // Seconds
40 // Constants for application behaviour
41 constexpr uint64_t MsgSize = LinkBandwidth / 2;
43 /*************************************************************************************************/
54 //ONESIDE_INIT is equivalent to ONESIDE_ASYNC
57 enum class Action { SLEEP, PUT, GET, START, WAIT, DIE, END };
59 static const char* to_string(const Action x)
81 double rel_time; // Time relative to Scenario startTime
82 enum { STATE, ACTION } type;
83 enum { LNK, SND, RCV } entity;
94 std::vector<Step> steps;
98 static std::string to_string(const Scenario& s)
100 std::stringstream ss;
101 ss <<"#"<< s.index << "[" << s.start_time << "s," << s.start_time + s.duration << "s[: (";
103 case CommType::EAGER_SYNC:
106 case CommType::EAGER_ASYNC:
109 case CommType::EAGER_INIT:
112 case CommType::RDV_SYNC:
115 case CommType::RDV_ASYNC:
118 case CommType::RDV_INIT:
121 case CommType::ONESIDE_SYNC:
122 ss << "ONESIDE_SYNC";
124 case CommType::ONESIDE_ASYNC:
125 ss << "ONESIDE_ASYNC";
129 ss << ") Expected: S:" << to_string(s.snd_expected) << " R:" << to_string(s.rcv_expected) << " Steps: ";
130 for (const Step& step : s.steps) {
131 ss << "+" << step.rel_time << "s:";
132 switch (step.entity) {
144 if (step.type == Step::STATE) {
151 ss << "." << to_string(step.action_type);
155 return ss.str().c_str();
158 struct ScenarioContext {
162 std::stringstream sender_profile;
163 std::stringstream receiver_profile;
164 std::stringstream link_profile;
165 std::vector<int> active_indices;
166 std::vector<Scenario> scenarios;
169 sg4::Mailbox* mbox_eager = nullptr;
170 sg4::Mailbox* mbox_rdv = nullptr;
175 static size_t scenario_;
177 sg4::Host* other_host_;
178 const ScenarioContext& ctx_;
180 sg4::CommPtr do_put(CommType type, double& send_value)
183 case CommType::EAGER_SYNC:
184 mbox_eager->put(&send_value, MsgSize);
186 case CommType::EAGER_ASYNC:
187 return mbox_eager->put_async(&send_value, MsgSize);
188 case CommType::EAGER_INIT:
189 return mbox_eager->put_init(&send_value, MsgSize);
190 case CommType::RDV_SYNC:
191 mbox_rdv->put(&send_value, MsgSize);
193 case CommType::RDV_ASYNC:
194 return mbox_rdv->put_async(&send_value, MsgSize);
195 case CommType::RDV_INIT:
196 return mbox_rdv->put_init(&send_value, MsgSize);
197 case CommType::ONESIDE_SYNC:
198 sg4::Comm::sendto(sg4::this_actor::get_host(), other_host_, MsgSize);
200 case CommType::ONESIDE_ASYNC:
201 return sg4::Comm::sendto_async(sg4::this_actor::get_host(), other_host_, MsgSize);
206 void send_message(const Scenario& s)
208 std::string scenario_string = to_string(s);
209 XBT_DEBUG("Will try: %s", scenario_string.c_str());
211 sg4::CommPtr comm = nullptr;
212 Action expected = s.snd_expected;
213 double end_time = s.start_time + s.duration;
214 send_value = end_time;
215 size_t step_index = 0;
216 sg4::this_actor::sleep_until(s.start_time);
217 //Make sure we have a clean slate
218 xbt_assert(not mbox_eager->listen(),"Eager mailbox should be empty when starting a test");
219 xbt_assert(not mbox_rdv->listen(),"RDV mailbox should be empty when starting a test");
220 for (; step_index < s.steps.size(); step_index++) {
221 const Step& step = s.steps[step_index];
222 if (step.entity != Step::SND || step.type != Step::ACTION)
225 sg4::this_actor::sleep_until(s.start_time + step.rel_time);
226 } catch (std::exception& e) {
227 XBT_DEBUG("During Sleep, failed to send message because of a %s exception (%s)", typeid(e).name(), e.what());
230 // Check if the other host is still OK.
231 if (not other_host_->is_on())
233 // Perform the action
235 switch (step.action_type) {
237 comm=do_put(s.type, send_value);
246 xbt_die("Not a valid action for SND");
248 } catch (std::exception& e) {
249 XBT_DEBUG("During %s, failed to send message because of a %s exception (%s)", to_string(step.action_type),
250 typeid(e).name(), e.what());
255 sg4::this_actor::sleep_until(end_time);
256 } catch (std::exception& e) {
257 XBT_DEBUG("During Sleep, failed to send message because of a %s exception (%s)", typeid(e).name(), e.what());
259 Action outcome = Action::END;
260 if (step_index < s.steps.size()) {
261 const Step& step = s.steps[step_index];
262 assert(step.entity == Step::SND && step.type == Step::ACTION);
263 outcome = step.action_type;
265 if (outcome != expected) {
266 XBT_ERROR("Expected %s but got %s in %s", to_string(expected), to_string(outcome), scenario_string.c_str());
268 XBT_DEBUG("OK: %s", scenario_string.c_str());
270 sg4::this_actor::sleep_until(end_time);
271 xbt_assert(not mbox_eager->listen(), "Mailbox should not have ongoing communication!");
272 xbt_assert(not mbox_rdv->listen(), "Mailbox should not have ongoing communication!");
276 explicit SendAgent(int id, sg4::Host* other_host, const ScenarioContext& ctx) : id_(id), other_host_(other_host),ctx_(ctx) {}
281 XBT_DEBUG("Host %i starts run %i and scenario %lu.", id_, run_, scenario_);
282 while (scenario_ < ctx_.scenarios.size()) {
283 const Scenario& s = ctx_.scenarios[scenario_];
290 int SendAgent::run_ = 0;
291 size_t SendAgent::scenario_ = 0;
293 /*************************************************************************************************/
298 static size_t scenario_;
300 sg4::Host* other_host_;
301 const ScenarioContext& ctx_;
303 sg4::CommPtr do_get(CommType type, double*& receive_ptr)
306 case CommType::EAGER_SYNC:
307 receive_ptr = mbox_eager->get<double>();
309 case CommType::EAGER_ASYNC:
310 return mbox_eager->get_async(&receive_ptr);
311 case CommType::EAGER_INIT:
312 return mbox_eager->get_init()->set_dst_data((void**)(&receive_ptr));
313 case CommType::RDV_SYNC:
314 receive_ptr = mbox_rdv->get<double>();
316 case CommType::RDV_ASYNC:
317 return mbox_rdv->get_async(&receive_ptr);
318 case CommType::RDV_INIT:
319 return mbox_rdv->get_init()->set_dst_data((void**)(&receive_ptr));
320 case CommType::ONESIDE_SYNC:
321 case CommType::ONESIDE_ASYNC:
322 xbt_die("No get in One Sided comunications!");
327 void receive_message(const Scenario& s)
329 sg4::CommPtr comm = nullptr;
330 CommType type = s.type;
331 Action expected = s.rcv_expected;
332 double end_time = s.start_time + s.duration;
333 double* receive_ptr = nullptr;
334 size_t step_index = 0;
335 sg4::this_actor::sleep_until(s.start_time);
336 //Make sure we have a clean slate
337 xbt_assert(not mbox_eager->listen(),"Eager mailbox should be empty when starting a test");
338 xbt_assert(not mbox_rdv->listen(),"RDV mailbox should be empty when starting a test");
339 for (; step_index < s.steps.size(); step_index++) {
340 const Step& step = s.steps[step_index];
341 if (step.entity != Step::RCV || step.type != Step::ACTION)
344 sg4::this_actor::sleep_until(s.start_time + step.rel_time);
345 } catch (std::exception& e) {
346 XBT_DEBUG("During Sleep, failed to receive message because of a %s exception (%s)", typeid(e).name(), e.what());
349 // Check if the other host is still OK.
350 if (not other_host_->is_on())
352 // Perform the action
354 switch (step.action_type) {
356 comm = do_get(type, receive_ptr);
365 xbt_die("Not a valid action for RCV");
367 } catch (std::exception& e) {
368 XBT_DEBUG("During %s, failed to receive message because of a %s exception (%s)", to_string(step.action_type),
369 typeid(e).name(), e.what());
374 sg4::this_actor::sleep_until(end_time - .1);
375 } catch (std::exception& e) {
376 XBT_DEBUG("During Sleep, failed to send message because of a %s exception (%s)", typeid(e).name(), e.what());
378 Action outcome = Action::END;
379 std::string scenario_string = to_string(s);
380 if (step_index < s.steps.size()) {
381 const Step& step = s.steps[step_index];
382 assert(step.entity == Step::RCV && step.type == Step::ACTION);
383 outcome = step.action_type;
384 } else if (s.type!=CommType::ONESIDE_SYNC &&
385 s.type!=CommType::ONESIDE_ASYNC
387 //One sided / detached operations do not actually transfer anything
388 if(receive_ptr == nullptr ) {
389 XBT_ERROR("Received address is NULL in %s", scenario_string.c_str());
390 } else if (*receive_ptr != end_time) {
391 XBT_ERROR("Received value invalid: expected %f but got %f in %s", end_time, *receive_ptr,
392 scenario_string.c_str());
395 if (outcome != expected) {
396 XBT_ERROR("Expected %s but got %s in %s", to_string(expected), to_string(outcome), scenario_string.c_str());
398 XBT_DEBUG("OK: %s", scenario_string.c_str());
400 sg4::this_actor::sleep_until(end_time);
401 xbt_assert(not mbox_eager->listen(), "Mailbox should not have ongoing communication!");
402 xbt_assert(not mbox_rdv->listen(), "Mailbox should not have ongoing communication!");
406 explicit ReceiveAgent(int id, sg4::Host* other_host, const ScenarioContext& ctx) : id_(id), other_host_(other_host), ctx_(ctx) {}
410 XBT_DEBUG("Host %i starts run %i and scenario %lu.", id_, run_, scenario_);
411 mbox_eager->set_receiver(sg4::Actor::self());
412 while (scenario_ < ctx_.scenarios.size()) {
413 const Scenario& s = ctx_.scenarios[scenario_];
420 int ReceiveAgent::run_ = 0;
421 size_t ReceiveAgent::scenario_ = 0;
423 static void on_host_state_change(sg4::Host const& host)
425 XBT_DEBUG("Host %s is now %s", host.get_cname(), host.is_on() ? "ON " : "OFF");
426 if(not host.is_on()) {
432 static void on_link_state_change(sg4::Link const& link)
434 XBT_DEBUG("Link %s is now %s", link.get_cname(), link.is_on() ? "ON " : "OFF");
437 double build_scenarios(ScenarioContext& ctx);
439 int main(int argc, char* argv[])
441 sg4::Engine e(&argc, argv);
443 int previous_index=-1;
444 bool is_range_last=false;
445 for(int i=1; i<argc; i++) {
446 if(not strcmp(argv[i],"-"))
449 int index=atoi(argv[i]);
450 xbt_assert(index>previous_index);
452 for(int j=previous_index+1;j<=index;j++)
453 ctx.active_indices.push_back(j);
455 ctx.active_indices.push_back(index);
457 previous_index=index;
460 double end_time = build_scenarios(ctx);
461 XBT_INFO("Will run for %f seconds", end_time);
462 mbox_eager = e.mailbox_by_name_or_create("eager");
463 mbox_rdv = e.mailbox_by_name_or_create("rdv");
464 sg4::NetZone* zone = sg4::create_full_zone("Top");
465 pr::Profile* profile_sender = pr::ProfileBuilder::from_string("sender_profile", ctx.sender_profile.str(), 0);
466 sg4::Host* sender_host = zone->create_host("senderHost", HostComputePower)->set_state_profile(profile_sender)->seal();
467 pr::Profile* profile_receiver = pr::ProfileBuilder::from_string("receiver_profile", ctx.receiver_profile.str(), 0);
468 sg4::Host* receiver_host = zone->create_host("receiverHost", HostComputePower)->set_state_profile(profile_receiver)->seal();
469 sg4::ActorPtr sender = sg4::Actor::create("sender", sender_host, SendAgent(0, receiver_host,ctx));
470 sender->set_auto_restart(true);
471 sg4::ActorPtr receiver = sg4::Actor::create("receiver", receiver_host, ReceiveAgent(1, sender_host,ctx));
472 receiver->set_auto_restart(true);
473 pr::Profile* profile_link = pr::ProfileBuilder::from_string("link_profile",ctx.link_profile.str(), 0);
475 zone->create_link("link", LinkBandwidth)->set_latency(LinkLatency)->set_state_profile(profile_link)->seal();
476 zone->add_route(sender_host->get_netpoint(), receiver_host->get_netpoint(), nullptr, nullptr,
477 {sg4::LinkInRoute{link}}, false);
479 sg4::Host::on_state_change.connect(on_host_state_change);
480 sg4::Link::on_state_change_cb(on_link_state_change);
481 e.run_until(end_time);
483 //Make sure we have a clean slate
484 xbt_assert(not mbox_eager->listen(),"Eager mailbox should be empty in the end");
485 xbt_assert(not mbox_rdv->listen(),"RDV mailbox should be empty in the end");
490 static void addStateEvent(std::ostream& out, double date, bool isOn)
493 out << date << " 1\n";
495 out << date << " 0\n";
498 static void prepareScenario(ScenarioContext& ctx, CommType type, double duration,
499 Action sender_expected, Action receiver_expected,
500 std::vector<Step> steps)
502 if(std::find(ctx.active_indices.begin(),ctx.active_indices.end(),ctx.index)!=ctx.active_indices.end()) {
503 // Update fault profiles
504 for (Step& step : steps) {
505 assert(step.rel_time < duration);
506 if (step.type != Step::STATE)
508 int val = step.new_state ? 1 : 0;
509 switch (step.entity) {
511 ctx.sender_profile << ctx.start_time + step.rel_time << " " << val << std::endl;
514 ctx.receiver_profile << ctx.start_time + step.rel_time << " " << val << std::endl;
517 ctx.link_profile << ctx.start_time + step.rel_time << " " << val << std::endl;
521 ctx.scenarios.push_back( {type, ctx.start_time, duration, sender_expected, receiver_expected, steps, ctx.index} );
525 ctx.start_time += duration;
528 /*************************************************************************************************/
530 // A bunch of dirty macros to help readability (supposedly)
531 #define MAKE_SCENARIO(type, duration, snd_expected, rcv_expected, steps...) \
532 prepareScenario(ctx,CommType::type, duration, Action::snd_expected, Action::rcv_expected, {steps} )
535 static Step loff(double rel_time) { return { rel_time, Step::STATE, Step::LNK, Action::END, false }; }
536 static Step lon(double rel_time) { return {rel_time , Step::STATE, Step::LNK, Action::END, true }; }
538 static Step soff(double rel_time) { return {rel_time , Step::STATE, Step::SND, Action::END, false }; }
539 static Step son(double rel_time) { return {rel_time , Step::STATE, Step::SND, Action::END, true }; }
540 static Step sput(double rel_time) { return {rel_time , Step::ACTION, Step::SND, Action::PUT, false }; }
541 static Step swait(double rel_time) { return {rel_time , Step::ACTION, Step::SND, Action::WAIT, false }; }
543 static Step roff(double rel_time) { return {rel_time , Step::STATE, Step::RCV, Action::END, false}; }
544 static Step ron(double rel_time) { return {rel_time , Step::STATE, Step::RCV, Action::END, true }; }
545 static Step rget(double rel_time) { return {rel_time , Step::ACTION, Step::RCV, Action::GET, false}; }
546 static Step rwait(double rel_time) { return {rel_time , Step::ACTION, Step::RCV, Action::WAIT, false}; }
548 double build_scenarios(ScenarioContext& ctx )
554 // EAGER SYNC use cases
556 MAKE_SCENARIO(EAGER_SYNC, 1, END, END, sput(.2), rget(.4));
557 MAKE_SCENARIO(EAGER_SYNC, 1, END, END, rget(.2), sput(.4));
559 MAKE_SCENARIO(EAGER_SYNC, 2, PUT, DIE, roff(.1), sput(.2), ron(1));
560 MAKE_SCENARIO(EAGER_SYNC, 2, PUT, DIE, sput(.2), roff(.3), ron(1));
561 MAKE_SCENARIO(EAGER_SYNC, 2, PUT, DIE, sput(.2), rget(.4), roff(.5), ron(1));
562 MAKE_SCENARIO(EAGER_SYNC, 2, PUT, DIE, rget(.2), sput(.4), roff(.5), ron(1));
564 MAKE_SCENARIO(EAGER_SYNC, 2, DIE, GET, sput(.2), soff(.3), rget(.4), son(1));
565 MAKE_SCENARIO(EAGER_SYNC, 2, DIE, GET, sput(.2), rget(.4), soff(.5), son(1));
567 MAKE_SCENARIO(EAGER_SYNC, 2, PUT, GET, loff(.1), sput(.2), rget(.4), lon(1));
568 MAKE_SCENARIO(EAGER_SYNC, 2, PUT, GET, sput(.2), loff(.3), rget(.4), lon(1));
569 MAKE_SCENARIO(EAGER_SYNC, 2, PUT, GET, sput(.2), rget(.4), loff(.5), lon(1));
570 MAKE_SCENARIO(EAGER_SYNC, 2, PUT, GET, loff(.1), rget(.2), sput(.4), lon(1));
571 MAKE_SCENARIO(EAGER_SYNC, 2, PUT, GET, rget(.2), loff(.3), sput(.4), lon(1));
572 MAKE_SCENARIO(EAGER_SYNC, 2, PUT, GET, rget(.2), sput(.4), loff(.5), lon(1));
574 // EAGER ASYNC use cases
576 MAKE_SCENARIO(EAGER_ASYNC, 2, END, END, sput(.2), swait(.4), rget(.6), rwait(.8));
577 MAKE_SCENARIO(EAGER_ASYNC, 2, END, END, sput(.2), rget(.4), swait(.6), rwait(.8));
578 MAKE_SCENARIO(EAGER_ASYNC, 2, END, END, sput(.2), rget(.4), rwait(.6), swait(.8));
579 MAKE_SCENARIO(EAGER_ASYNC, 2, END, END, rget(.2), sput(.4), swait(.6), rwait(.8));
580 MAKE_SCENARIO(EAGER_ASYNC, 2, END, END, rget(.2), sput(.4), rwait(.6), swait(.8));
581 MAKE_SCENARIO(EAGER_ASYNC, 2, END, END, rget(.2), rwait(.4), sput(.6), swait(.8));
583 MAKE_SCENARIO(EAGER_ASYNC, 2, PUT, DIE, roff(.1), sput(.2), swait(.4), ron(1));
584 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, DIE, sput(.2), roff(.3), swait(.4), ron(1));
585 MAKE_SCENARIO(EAGER_ASYNC, 2, PUT, DIE, rget(.2), roff(.3), sput(.4), swait(.6), ron(1));
586 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, DIE, sput(.2), swait(.4), roff(.5), ron(1));
587 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, DIE, sput(.2), rget(.4), roff(.5), swait(.6), ron(1));
588 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, DIE, rget(.2), sput(.4), roff(.5), swait(.6), ron(1));
589 MAKE_SCENARIO(EAGER_ASYNC, 2, PUT , DIE, rget(.2), rwait(.4), roff(.5), sput(.6), swait(.8), ron(1));
590 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, DIE, sput(.2), swait(.4), rget(.6), roff(.7), ron(1));
591 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, DIE, sput(.2), rget(.4), swait(.6), roff(.7), ron(1));
592 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, DIE, sput(.2), rget(.4), rwait(.6), roff(.7), swait(.8), ron(1));
593 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, DIE, rget(.2), sput(.4), swait(.6), roff(.7), ron(1));
594 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, DIE, rget(.2), sput(.4), rwait(.6), roff(.7), swait(.8), ron(1));
595 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, DIE, rget(.2), rwait(.4), sput(.6), roff(.7), swait(.8), ron(1));
596 // Sender off (only cases where sender did put, because otherwise receiver cannot find out there was a fault)
597 MAKE_SCENARIO(EAGER_ASYNC, 2, DIE, GET, sput(.2), soff(.3), rget(.4), rwait(.6), son(1));
598 MAKE_SCENARIO(EAGER_ASYNC, 2, DIE, WAIT, rget(.2), sput(.4), soff(.5), rwait(.6), son(1));
599 MAKE_SCENARIO(EAGER_ASYNC, 2, DIE, WAIT, sput(.2), rget(.4), soff(.5), rwait(.6), son(1));
600 MAKE_SCENARIO(EAGER_ASYNC, 2, DIE, GET, sput(.2), swait(.4), soff(.5), rget(.6), rwait(.8), son(1));
601 MAKE_SCENARIO(EAGER_ASYNC, 2, DIE, WAIT, rget(.2), rwait(.4), sput(.6), soff(.7), son(1));
602 MAKE_SCENARIO(EAGER_ASYNC, 2, DIE, WAIT, rget(.2), sput(.4), rwait(.6), soff(.7), son(1));
603 MAKE_SCENARIO(EAGER_ASYNC, 2, DIE, WAIT, rget(.2), sput(.4), swait(.6), soff(.7), rwait(.8), son(1));
604 MAKE_SCENARIO(EAGER_ASYNC, 2, DIE, WAIT, sput(.2), rget(.4), rwait(.6), soff(.7), son(1));
605 MAKE_SCENARIO(EAGER_ASYNC, 2, DIE, WAIT, sput(.2), rget(.4), swait(.6), soff(.7), rwait(.8), son(1));
606 MAKE_SCENARIO(EAGER_ASYNC, 2, DIE, WAIT, sput(.2), swait(.4), rget(.6), soff(.7), rwait(.8), son(1));
608 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, loff(.1), sput(.2), swait(.4), rget(.6), rwait(.8), lon(1));
609 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, loff(.1), sput(.2), rget(.4), swait(.6), rwait(.8), lon(1));
610 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, loff(.1), sput(.2), rget(.4), rwait(.6), swait(.8), lon(1));
611 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, loff(.1), rget(.2), sput(.4), swait(.6), rwait(.8), lon(1));
612 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, loff(.1), rget(.2), sput(.4), rwait(.6), swait(.8), lon(1));
613 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, loff(.1), rget(.2), rwait(.4), sput(.6), swait(.8), lon(1));
614 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, sput(.2), loff(.3), swait(.4), rget(.6), rwait(.8), lon(1));
615 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, sput(.2), loff(.3), rget(.4), swait(.6), rwait(.8), lon(1));
616 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, sput(.2), loff(.3), rget(.4), rwait(.6), swait(.8), lon(1));
617 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, rget(.2), loff(.3), sput(.4), swait(.6), rwait(.8), lon(1));
618 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, rget(.2), loff(.3), sput(.4), rwait(.6), swait(.8), lon(1));
619 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, rget(.2), loff(.3), rwait(.4), sput(.6), swait(.8), lon(1));
620 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, sput(.2), swait(.4), loff(.5), rget(.6), rwait(.8), lon(1));
621 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, sput(.2), rget(.4), loff(.5), swait(.6), rwait(.8), lon(1));
622 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, sput(.2), rget(.4), loff(.5), rwait(.6), swait(.8), lon(1));
623 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, rget(.2), sput(.4), loff(.5), swait(.6), rwait(.8), lon(1));
624 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, rget(.2), sput(.4), loff(.5), rwait(.6), swait(.8), lon(1));
625 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, rget(.2), rwait(.4), loff(.5), sput(.6), swait(.8), lon(1));
626 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, sput(.2), swait(.4), rget(.6), loff(.7), rwait(.8), lon(1));
627 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, sput(.2), rget(.4), swait(.6), loff(.7), rwait(.8), lon(1));
628 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, sput(.2), rget(.4), rwait(.6), loff(.7), swait(.8), lon(1));
629 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, rget(.2), sput(.4), swait(.6), loff(.7), rwait(.8), lon(1));
630 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, rget(.2), sput(.4), rwait(.6), loff(.7), swait(.8), lon(1));
631 MAKE_SCENARIO(EAGER_ASYNC, 2, WAIT, WAIT, rget(.2), rwait(.4), sput(.6), loff(.7), swait(.8), lon(1));
633 // RDV SYNC use cases
635 MAKE_SCENARIO(RDV_SYNC, 1, END, END, sput(.2), rget(.4));
636 MAKE_SCENARIO(RDV_SYNC, 1, END, END, rget(.2), sput(.4));
638 MAKE_SCENARIO(RDV_SYNC, 2, PUT, DIE, roff(.1), sput(.2), ron(1));
639 MAKE_SCENARIO(RDV_SYNC, 2, PUT, DIE, sput(.2), roff(.3), ron(1)); //Fails because put comm cancellation does not trigger sender exception
640 MAKE_SCENARIO(RDV_SYNC, 2, PUT, DIE, sput(.2), rget(.4), roff(.5), ron(1));
641 MAKE_SCENARIO(RDV_SYNC, 2, PUT, DIE, rget(.2), sput(.4), roff(.5), ron(1));
643 MAKE_SCENARIO(RDV_SYNC, 2, DIE, GET, sput(.2), rget(.4), soff(.5), son(1));
645 MAKE_SCENARIO(RDV_SYNC, 2, PUT, GET, loff(.1), sput(.2), rget(.4), lon(1));
646 MAKE_SCENARIO(RDV_SYNC, 2, PUT, GET, sput(.2), loff(.3), rget(.4), lon(1));
647 MAKE_SCENARIO(RDV_SYNC, 2, PUT, GET, sput(.2), rget(.4), loff(.5), lon(1));
648 MAKE_SCENARIO(RDV_SYNC, 2, PUT, GET, loff(.1), rget(.2), sput(.4), lon(1));
649 MAKE_SCENARIO(RDV_SYNC, 2, PUT, GET, rget(.2), loff(.3), sput(.4), lon(1));
650 MAKE_SCENARIO(RDV_SYNC, 2, PUT, GET, rget(.2), sput(.4), loff(.5), lon(1));
652 // RDV ASYNC use cases
654 MAKE_SCENARIO(RDV_ASYNC, 2, END, END, sput(.2), swait(.4), rget(.6), rwait(.8));
655 MAKE_SCENARIO(RDV_ASYNC, 2, END, END, sput(.2), rget(.4), swait(.6), rwait(.8));
656 MAKE_SCENARIO(RDV_ASYNC, 2, END, END, sput(.2), rget(.4), rwait(.6), swait(.8));
657 MAKE_SCENARIO(RDV_ASYNC, 2, END, END, rget(.2), sput(.4), swait(.6), rwait(.8));
658 MAKE_SCENARIO(RDV_ASYNC, 2, END, END, rget(.2), sput(.4), rwait(.6), swait(.8));
659 MAKE_SCENARIO(RDV_ASYNC, 2, END, END, rget(.2), rwait(.4), sput(.6), swait(.8));
661 MAKE_SCENARIO(RDV_ASYNC, 2, PUT, DIE, roff(.1), sput(.2), swait(.4), ron(1));
662 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, DIE, sput(.2), roff(.3), swait(.4), ron(1));
663 MAKE_SCENARIO(RDV_ASYNC, 2, PUT, DIE, rget(.2), roff(.3), sput(.4), swait(.6), ron(1));
664 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, DIE, sput(.2), swait(.4), roff(.5), ron(1)); //Fails because put comm cancellation does not trigger sender exception
665 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, DIE, sput(.2), rget(.4), roff(.5), swait(.6), ron(1));
666 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, DIE, rget(.2), sput(.4), roff(.5), swait(.6), ron(1));
667 MAKE_SCENARIO(RDV_ASYNC, 2, PUT , DIE, rget(.2), rwait(.4), roff(.5), sput(.6), swait(.8), ron(1));
668 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, DIE, sput(.2), swait(.4), rget(.6), roff(.7), ron(1));
669 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, DIE, sput(.2), rget(.4), swait(.6), roff(.7), ron(1));
670 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, DIE, sput(.2), rget(.4), rwait(.6), roff(.7), swait(.8), ron(1));
671 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, DIE, rget(.2), sput(.4), swait(.6), roff(.7), ron(1));
672 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, DIE, rget(.2), sput(.4), rwait(.6), roff(.7), swait(.8), ron(1));
673 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, DIE, rget(.2), rwait(.4), sput(.6), roff(.7), swait(.8), ron(1));
674 // Sender off (only cases where sender did put, because otherwise receiver cannot find out there was a fault)
675 MAKE_SCENARIO(RDV_ASYNC, 2, DIE, GET, sput(.2), soff(.3), rget(.4), rwait(.6), son(1));
676 MAKE_SCENARIO(RDV_ASYNC, 2, DIE, WAIT, rget(.2), sput(.4), soff(.5), rwait(.6), son(1));
677 MAKE_SCENARIO(RDV_ASYNC, 2, DIE, WAIT, sput(.2), rget(.4), soff(.5), rwait(.6), son(1));
678 MAKE_SCENARIO(RDV_ASYNC, 2, DIE, GET, sput(.2), swait(.4), soff(.5), rget(.6), rwait(.8), son(1));
679 MAKE_SCENARIO(RDV_ASYNC, 2, DIE, WAIT, rget(.2), rwait(.4), sput(.6), soff(.7), son(1));
680 MAKE_SCENARIO(RDV_ASYNC, 2, DIE, WAIT, rget(.2), sput(.4), rwait(.6), soff(.7), son(1));
681 MAKE_SCENARIO(RDV_ASYNC, 2, DIE, WAIT, rget(.2), sput(.4), swait(.6), soff(.7), rwait(.8), son(1));
682 MAKE_SCENARIO(RDV_ASYNC, 2, DIE, WAIT, sput(.2), rget(.4), rwait(.6), soff(.7), son(1));
683 MAKE_SCENARIO(RDV_ASYNC, 2, DIE, WAIT, sput(.2), rget(.4), swait(.6), soff(.7), rwait(.8), son(1));
684 MAKE_SCENARIO(RDV_ASYNC, 2, DIE, WAIT, sput(.2), swait(.4), rget(.6), soff(.7), rwait(.8), son(1));
686 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, loff(.1), sput(.2), swait(.4), rget(.6), rwait(.8), lon(1));
687 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, loff(.1), sput(.2), rget(.4), swait(.6), rwait(.8), lon(1));
688 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, loff(.1), sput(.2), rget(.4), rwait(.6), swait(.8), lon(1));
689 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, loff(.1), rget(.2), sput(.4), swait(.6), rwait(.8), lon(1));
690 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, loff(.1), rget(.2), sput(.4), rwait(.6), swait(.8), lon(1));
691 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, loff(.1), rget(.2), rwait(.4), sput(.6), swait(.8), lon(1));
692 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, sput(.2), loff(.3), swait(.4), rget(.6), rwait(.8), lon(1));
693 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, sput(.2), loff(.3), rget(.4), swait(.6), rwait(.8), lon(1));
694 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, sput(.2), loff(.3), rget(.4), rwait(.6), swait(.8), lon(1));
695 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, rget(.2), loff(.3), sput(.4), swait(.6), rwait(.8), lon(1));
696 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, rget(.2), loff(.3), sput(.4), rwait(.6), swait(.8), lon(1));
697 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, rget(.2), loff(.3), rwait(.4), sput(.6), swait(.8), lon(1));
698 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, sput(.2), swait(.4), loff(.5), rget(.6), rwait(.8), lon(1));
699 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, sput(.2), rget(.4), loff(.5), swait(.6), rwait(.8), lon(1));
700 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, sput(.2), rget(.4), loff(.5), rwait(.6), swait(.8), lon(1));
701 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, rget(.2), sput(.4), loff(.5), swait(.6), rwait(.8), lon(1));
702 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, rget(.2), sput(.4), loff(.5), rwait(.6), swait(.8), lon(1));
703 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, rget(.2), rwait(.4), loff(.5), sput(.6), swait(.8), lon(1));
704 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, sput(.2), swait(.4), rget(.6), loff(.7), rwait(.8), lon(1));
705 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, sput(.2), rget(.4), swait(.6), loff(.7), rwait(.8), lon(1));
706 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, sput(.2), rget(.4), rwait(.6), loff(.7), swait(.8), lon(1));
707 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, rget(.2), sput(.4), swait(.6), loff(.7), rwait(.8), lon(1));
708 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, rget(.2), sput(.4), rwait(.6), loff(.7), swait(.8), lon(1));
709 MAKE_SCENARIO(RDV_ASYNC, 2, WAIT, WAIT, rget(.2), rwait(.4), sput(.6), loff(.7), swait(.8), lon(1));
711 // ONESIDE SYNC use cases
713 MAKE_SCENARIO(ONESIDE_SYNC, 1, END, END, sput(.2));
715 MAKE_SCENARIO(ONESIDE_SYNC, 2, PUT, DIE, roff(.1), sput(.2), ron(1));
716 MAKE_SCENARIO(ONESIDE_SYNC, 2, PUT, DIE, sput(.2), roff(.3), ron(1));
718 MAKE_SCENARIO(ONESIDE_SYNC, 2, DIE, END, sput(.2), soff(.3), son(1));
720 MAKE_SCENARIO(ONESIDE_SYNC, 2, PUT, END, loff(.1), sput(.2), lon(1));
721 MAKE_SCENARIO(ONESIDE_SYNC, 2, PUT, END, sput(.2), loff(.3), lon(1));
723 // ONESIDE ASYNC use cases
725 MAKE_SCENARIO(ONESIDE_ASYNC, 2, END, END, sput(.2), swait(.4));
727 MAKE_SCENARIO(ONESIDE_ASYNC, 2, PUT, DIE, roff(.1), sput(.2), swait(.4), ron(1));
728 MAKE_SCENARIO(ONESIDE_ASYNC, 2, WAIT, DIE, sput(.2), roff(.3), swait(.4), ron(1));
729 MAKE_SCENARIO(ONESIDE_ASYNC, 2, WAIT, DIE, sput(.2), swait(.4), roff(.5), ron(1));
731 MAKE_SCENARIO(ONESIDE_ASYNC, 2, DIE, END, sput(.2), soff(.3), son(1));
733 MAKE_SCENARIO(ONESIDE_ASYNC, 2, WAIT, END, loff(.1), sput(.2), swait(.4), lon(1));
734 MAKE_SCENARIO(ONESIDE_ASYNC, 2, WAIT, END, sput(.2), loff(.3), swait(.4), lon(1));
735 MAKE_SCENARIO(ONESIDE_ASYNC, 2, WAIT, END, sput(.2), swait(.4), loff(.5), lon(1));
737 XBT_INFO("Will execute %i active scenarios out of %i.",ctx.active,ctx.index);
738 return ctx.start_time + 1;