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 #include "activity-lifecycle.hpp"
8 //========== Creators: create an async activity
10 // Create a new async execution with given duration
11 static simgrid::s4u::ActivityPtr create_exec(double duration)
13 double speed = simgrid::s4u::this_actor::get_host()->get_speed();
14 return simgrid::s4u::this_actor::exec_async(speed * duration);
17 // TODO: check other kinds of activities too (Io, Comm, ...)
19 using creator_type = decltype(create_exec);
21 //========== Testers: test the completion of an activity
23 // Calls activity->test() and returns its result
24 static bool tester_test(const simgrid::s4u::ActivityPtr& activity)
26 return activity->test();
29 // Calls activity->wait_for(Duration / 128.0) and returns true when activity is terminated, just like test()
30 template <int Duration> bool tester_wait(const simgrid::s4u::ActivityPtr& activity)
34 activity->wait_for(Duration / 128.0);
35 XBT_DEBUG("wait_for() returned normally");
37 } catch (const simgrid::TimeoutException& e) {
38 XBT_DEBUG("wait_for() timed out (%s)", e.what());
40 } catch (const simgrid::Exception& e) {
41 XBT_DEBUG("wait_for() threw an exception: %s", e.what());
47 using tester_type = decltype(tester_test);
49 //========== Waiters: wait for the completion of an activity
52 static void waiter_sleep6(const simgrid::s4u::ActivityPtr&)
54 simgrid::s4u::this_actor::sleep_for(6.0);
55 XBT_DEBUG("wake up after 6s sleep");
58 // Wait for completion of activity
59 static void waiter_wait(const simgrid::s4u::ActivityPtr& activity)
62 XBT_DEBUG("end of wait()");
65 using waiter_type = decltype(waiter_wait);
67 //========== Finally, the test templates
69 template <creator_type Create, tester_type Test> void test_trivial()
71 XBT_INFO("Launch an activity for 5s, and let it proceed before test");
73 simgrid::s4u::ActorPtr actor = simgrid::s4u::Actor::create("actor", all_hosts[1], []() {
74 assert_exit(true, 6.);
75 simgrid::s4u::ActivityPtr activity = Create(5.0);
76 simgrid::s4u::this_actor::sleep_for(6.0);
77 INFO("activity should be terminated now");
78 REQUIRE(Test(activity));
83 template <creator_type Create, tester_type Test> void test_basic()
85 XBT_INFO("Launch an activity for 5s, and test while it proceeds");
87 simgrid::s4u::ActorPtr actor = simgrid::s4u::Actor::create("actor", all_hosts[1], []() {
88 assert_exit(true, 6.);
89 simgrid::s4u::ActivityPtr activity = Create(5.0);
90 for (int i = 0; i < 3; i++) {
91 INFO("activity should be still running (i = " << i << ")");
92 REQUIRE(not Test(activity));
93 simgrid::s4u::this_actor::sleep_for(2.0);
95 INFO("activity should be terminated now");
96 REQUIRE(Test(activity));
101 template <creator_type Create, tester_type Test> void test_cancel()
103 XBT_INFO("Launch an activity for 5s, and cancel it after 2s");
105 simgrid::s4u::ActorPtr actor = simgrid::s4u::Actor::create("actor", all_hosts[1], []() {
106 assert_exit(true, 2.);
107 simgrid::s4u::ActivityPtr activity = Create(5.0);
108 simgrid::s4u::this_actor::sleep_for(2.0);
110 INFO("activity should be terminated now");
111 REQUIRE(Test(activity));
116 template <creator_type Create, tester_type Test, waiter_type Wait> void test_failure_actor()
118 XBT_INFO("Launch an activity for 5s, and kill running actor after 2s");
120 simgrid::s4u::ActivityPtr activity;
121 simgrid::s4u::ActorPtr actor = simgrid::s4u::Actor::create("actor", all_hosts[1], [&activity]() {
122 assert_exit(false, 2.);
123 activity = Create(5.0);
125 FAIL("should not be here!");
127 simgrid::s4u::this_actor::sleep_for(2.0);
128 INFO("activity should be still running");
129 REQUIRE(not Test(activity));
131 INFO("activity should be terminated now");
132 REQUIRE(Test(activity));
135 template <creator_type Create, tester_type Test, waiter_type Wait> void test_failure_host()
137 XBT_INFO("Launch an activity for 5s, and shutdown host 2s");
139 simgrid::s4u::ActivityPtr activity;
140 simgrid::s4u::ActorPtr actor = simgrid::s4u::Actor::create("actor", all_hosts[1], [&activity]() {
141 assert_exit(false, 2.);
142 activity = Create(5.0);
144 FAIL("should not be here!");
146 simgrid::s4u::this_actor::sleep_for(2.0);
147 INFO("activity should be still running");
148 REQUIRE(not Test(activity));
149 actor->get_host()->turn_off();
150 actor->get_host()->turn_on();
151 INFO("activity should be terminated now");
152 REQUIRE(Test(activity));
157 TEST_CASE("Activity test/wait: using <tester_test>")
159 XBT_INFO("#####[ launch next test ]#####");
161 RUN_SECTION("exec: run and test once", test_trivial<create_exec, tester_test>);
162 RUN_SECTION("exec: run and test many", test_basic<create_exec, tester_test>);
163 RUN_SECTION("exec: cancel and test", test_cancel<create_exec, tester_test>);
164 RUN_SECTION("exec: actor failure and test / sleep", test_failure_actor<create_exec, tester_test, waiter_sleep6>);
165 RUN_SECTION("exec: host failure and test / sleep", test_failure_host<create_exec, tester_test, waiter_sleep6>);
166 RUN_SECTION("exec: actor failure and test / wait", test_failure_actor<create_exec, tester_test, waiter_wait>);
167 RUN_SECTION("exec: host failure and test / wait", test_failure_host<create_exec, tester_test, waiter_wait>);
169 simgrid::s4u::this_actor::sleep_for(10);
173 TEST_CASE("Activity test/wait: using <tester_wait<0>>")
175 XBT_INFO("#####[ launch next test ]#####");
177 RUN_SECTION("exec: run and wait<0> once", test_trivial<create_exec, tester_wait<0>>);
178 // exec: run and wait<0> many
179 RUN_SECTION("exec: cancel and wait<0>", test_cancel<create_exec, tester_wait<0>>);
180 // exec: actor failure and wait<0> / sleep
181 // exec: host failure and wait<0> / sleep
182 // exec: actor failure and wait<0> / wait
183 // exec: host failure and wait<0> / wait
185 simgrid::s4u::this_actor::sleep_for(10);
189 TEST_CASE("Activity test/wait: using <tester_wait<1>>")
191 XBT_INFO("#####[ launch next test ]#####");
193 RUN_SECTION("exec: run and wait<1> once", test_trivial<create_exec, tester_wait<1>>);
194 // exec: run and wait<1> many
195 RUN_SECTION("exec: cancel and wait<1>", test_cancel<create_exec, tester_wait<1>>);
196 // exec: actor failure and wait<1> / sleep
197 // exec: host failure and wait<1> / sleep
198 // exec: actor failure and wait<1> / wait
199 // exec: host failure and wait<1> / wait
201 simgrid::s4u::this_actor::sleep_for(10);
205 // FIXME: The tests grouped here are currently failing. Once fixed, they should be put in the right section above.
206 // The tests can be activated with run-time parameter '*' or, more specifically '[failing]'
207 TEST_CASE("Activity test/wait: tests currently failing", "[.][failing]")
209 XBT_INFO("#####[ launch next failing test ]#####");
211 // with tester_wait<0>
212 RUN_SECTION("exec: run and wait<0> many", test_basic<create_exec, tester_wait<0>>);
213 RUN_SECTION("exec: actor failure and wait<0> / sleep", test_failure_actor<create_exec, tester_wait<0>, waiter_sleep6>);
214 RUN_SECTION("exec: host failure and wait<0> / sleep", test_failure_host<create_exec, tester_wait<0>, waiter_sleep6>);
215 RUN_SECTION("exec: actor failure and wait<0> / wait", test_failure_actor<create_exec, tester_wait<0>, waiter_wait>);
216 RUN_SECTION("exec: host failure and wait<0> / wait", test_failure_host<create_exec, tester_wait<0>, waiter_wait>);
218 // with tester_test<1>
219 RUN_SECTION("exec: run and wait<1> many", test_basic<create_exec, tester_wait<1>>);
220 RUN_SECTION("exec: actor failure and wait<1> / sleep", test_failure_actor<create_exec, tester_wait<1>, waiter_sleep6>);
221 RUN_SECTION("exec: host failure and wait<1> / sleep", test_failure_host<create_exec, tester_wait<1>, waiter_sleep6>);
222 RUN_SECTION("exec: actor failure and wait<1> / wait", test_failure_actor<create_exec, tester_wait<1>, waiter_wait>);
223 RUN_SECTION("exec: host failure and wait<1> / wait", test_failure_host<create_exec, tester_wait<1>, waiter_wait>);
225 simgrid::s4u::this_actor::sleep_for(10);