Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
b083ded116a9724f01e858adca926e77d33aa45c
[simgrid.git] / teshsuite / s4u / activity-lifecycle / testing_test-wait.cpp
1 /* Copyright (c) 2010-2021. The SimGrid Team. All rights reserved.          */
2
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. */
5
6 #include "activity-lifecycle.hpp"
7
8 //========== Creators: create an async activity
9
10 template <typename Activity> using creator_type = Activity (*)(double);
11
12 // Create a new async execution with given duration
13 static simgrid::s4u::ActivityPtr create_exec(double duration)
14 {
15   double speed = simgrid::s4u::this_actor::get_host()->get_speed();
16   return simgrid::s4u::this_actor::exec_async(speed * duration);
17 }
18
19 // TODO: check other kinds of activities too (Io, Comm, ...)
20
21 //========== Testers: test the completion of an activity
22
23 template <typename Activity> using tester_type = bool (*)(const Activity&);
24
25 // Calls activity->test() and returns its result
26 template <typename Activity> bool tester_test(const Activity& activity)
27 {
28   return activity->test();
29 }
30
31 // Calls activity->wait_for(Duration / 128.0) and returns true when activity is terminated, just like test()
32 template <int Duration, typename Activity> bool tester_wait(const Activity& activity)
33 {
34   constexpr double duration = Duration / 128.0;
35   const double timeout      = simgrid::s4u::Engine::get_clock() + duration;
36   bool ret;
37   try {
38     XBT_DEBUG("calling wait_for(%f)", duration);
39     activity->wait_for(duration);
40     XBT_DEBUG("wait_for() returned normally");
41     ret = true;
42   } catch (const simgrid::TimeoutException& e) {
43     XBT_DEBUG("wait_for() timed out (%s)", e.what());
44     INFO("wait_for() timeout should expire at expected date: " << timeout);
45     REQUIRE(simgrid::s4u::Engine::get_clock() == Approx(timeout));
46     ret = false;
47   } catch (const simgrid::Exception& e) {
48     XBT_DEBUG("wait_for() threw an exception: %s", e.what());
49     ret = true;
50   }
51   INFO("wait_for() should return before timeout expiration at date: " << timeout);
52   REQUIRE(simgrid::s4u::Engine::get_clock() <= Approx(timeout));
53   return ret;
54 }
55
56 //========== Waiters: wait for the completion of an activity
57
58 template <typename Activity> using waiter_type = void (*)(const Activity&);
59
60 // Wait for 6s
61 template <typename Activity> void waiter_sleep6(const Activity&)
62 {
63   simgrid::s4u::this_actor::sleep_for(6.0);
64   XBT_DEBUG("wake up after 6s sleep");
65 }
66
67 // Wait for completion of activity
68 template <typename Activity> void waiter_wait(const Activity& activity)
69 {
70   activity->wait();
71   XBT_DEBUG("end of wait()");
72 }
73
74 //========== Finally, the test templates
75
76 template <typename Activity, creator_type<Activity> Create, tester_type<Activity> Test> void test_trivial()
77 {
78   XBT_INFO("Launch an activity for 5s, and let it proceed before test");
79
80   simgrid::s4u::ActorPtr actor = simgrid::s4u::Actor::create("actor", all_hosts[1], []() {
81     assert_exit(true, 6.);
82     Activity activity = Create(5.0);
83     simgrid::s4u::this_actor::sleep_for(6.0);
84     INFO("activity should be terminated now");
85     REQUIRE(Test(activity));
86   });
87   actor->join();
88 }
89
90 template <typename Activity, creator_type<Activity> Create, tester_type<Activity> Test> void test_basic()
91 {
92   XBT_INFO("Launch an activity for 5s, and test while it proceeds");
93
94   simgrid::s4u::ActorPtr actor = simgrid::s4u::Actor::create("actor", all_hosts[1], []() {
95     assert_exit(true, 6.);
96     Activity activity = Create(5.0);
97     for (int i = 0; i < 3; i++) {
98       const double timestep = simgrid::s4u::Engine::get_clock() + 2.0;
99       INFO("activity should be still running (i = " << i << ")");
100       REQUIRE(not Test(activity));
101       simgrid::s4u::this_actor::sleep_until(timestep);
102     }
103     INFO("activity should be terminated now");
104     REQUIRE(Test(activity));
105   });
106   actor->join();
107 }
108
109 template <typename Activity, creator_type<Activity> Create, tester_type<Activity> Test> void test_cancel()
110 {
111   XBT_INFO("Launch an activity for 5s, and cancel it after 2s");
112
113   simgrid::s4u::ActorPtr actor = simgrid::s4u::Actor::create("actor", all_hosts[1], []() {
114     assert_exit(true, 2.);
115     Activity activity = Create(5.0);
116     simgrid::s4u::this_actor::sleep_for(2.0);
117     activity->cancel();
118     INFO("activity should be terminated now");
119     REQUIRE(Test(activity));
120   });
121   actor->join();
122 }
123
124 template <typename Activity, creator_type<Activity> Create, tester_type<Activity> Test, waiter_type<Activity> Wait>
125 void test_failure_actor()
126 {
127   XBT_INFO("Launch an activity for 5s, and kill running actor after 2s");
128
129   Activity activity;
130   simgrid::s4u::ActorPtr actor = simgrid::s4u::Actor::create("actor", all_hosts[1], [&activity]() {
131     assert_exit(false, 2.);
132     activity = Create(5.0);
133     Wait(activity);
134     FAIL("should not be here!");
135   });
136   const double timestep = simgrid::s4u::Engine::get_clock() + 2.0;
137   simgrid::s4u::this_actor::sleep_for(1.0);
138   INFO("activity should be still running");
139   REQUIRE(not Test(activity));
140   simgrid::s4u::this_actor::sleep_until(timestep);
141   actor->kill();
142   INFO("activity should be terminated now");
143   REQUIRE(Test(activity));
144 }
145
146 template <typename Activity, creator_type<Activity> Create, tester_type<Activity> Test, waiter_type<Activity> Wait>
147 void test_failure_host()
148 {
149   XBT_INFO("Launch an activity for 5s, and shutdown host 2s");
150
151   Activity activity;
152   simgrid::s4u::ActorPtr actor = simgrid::s4u::Actor::create("actor", all_hosts[1], [&activity]() {
153     assert_exit(false, 2.);
154     activity = Create(5.0);
155     Wait(activity);
156     FAIL("should not be here!");
157   });
158   const double timestep = simgrid::s4u::Engine::get_clock() + 2.0;
159   simgrid::s4u::this_actor::sleep_for(1.0);
160   INFO("activity should be still running");
161   REQUIRE(not Test(activity));
162   simgrid::s4u::this_actor::sleep_until(timestep);
163   actor->get_host()->turn_off();
164   actor->get_host()->turn_on();
165   INFO("activity should be terminated now");
166   REQUIRE(Test(activity));
167 }
168
169 //==========
170
171 using simgrid::s4u::ActivityPtr;
172
173 TEST_CASE("Activity test/wait: using <tester_test>")
174 {
175   XBT_INFO("#####[ launch next test ]#####");
176
177   RUN_SECTION("exec: run and test once", test_trivial<ActivityPtr, create_exec, tester_test>);
178   RUN_SECTION("exec: run and test many", test_basic<ActivityPtr, create_exec, tester_test>);
179   RUN_SECTION("exec: cancel and test", test_cancel<ActivityPtr, create_exec, tester_test>);
180   RUN_SECTION("exec: actor failure and test / sleep",
181               test_failure_actor<ActivityPtr, create_exec, tester_test, waiter_sleep6>);
182   RUN_SECTION("exec: host failure and test / sleep",
183               test_failure_host<ActivityPtr, create_exec, tester_test, waiter_sleep6>);
184   RUN_SECTION("exec: actor failure and test / wait",
185               test_failure_actor<ActivityPtr, create_exec, tester_test, waiter_wait>);
186   RUN_SECTION("exec: host failure and test / wait",
187               test_failure_host<ActivityPtr, create_exec, tester_test, waiter_wait>);
188
189   simgrid::s4u::this_actor::sleep_for(10);
190   assert_cleanup();
191 }
192
193 TEST_CASE("Activity test/wait: using <tester_wait<0>>")
194 {
195   XBT_INFO("#####[ launch next test ]#####");
196
197   RUN_SECTION("exec: run and wait<0> once", test_trivial<ActivityPtr, create_exec, tester_wait<0>>);
198   // exec: run and wait<0> many
199   RUN_SECTION("exec: cancel and wait<0>", test_cancel<ActivityPtr, create_exec, tester_wait<0>>);
200   // exec: actor failure and wait<0> / sleep
201   // exec: host failure and wait<0> / sleep
202   // exec: actor failure and wait<0> / wait
203   // exec: host failure and wait<0> / wait
204
205   simgrid::s4u::this_actor::sleep_for(10);
206   assert_cleanup();
207 }
208
209 TEST_CASE("Activity test/wait: using <tester_wait<1>>")
210 {
211   XBT_INFO("#####[ launch next test ]#####");
212
213   RUN_SECTION("exec: run and wait<1> once", test_trivial<ActivityPtr, create_exec, tester_wait<1>>);
214   // exec: run and wait<1> many
215   RUN_SECTION("exec: cancel and wait<1>", test_cancel<ActivityPtr, create_exec, tester_wait<1>>);
216   // exec: actor failure and wait<1> / sleep
217   // exec: host failure and wait<1> / sleep
218   // exec: actor failure and wait<1> / wait
219   // exec: host failure and wait<1> / wait
220
221   simgrid::s4u::this_actor::sleep_for(10);
222   assert_cleanup();
223 }
224
225 // FIXME: The tests grouped here are currently failing. Once fixed, they should be put in the right section above.
226 //        The tests can be activated with run-time parameter '*' or, more specifically '[failing]'
227 TEST_CASE("Activity test/wait: tests currently failing", "[.][failing]")
228 {
229   XBT_INFO("#####[ launch next failing test ]#####");
230
231   // with tester_wait<0>
232   RUN_SECTION("exec: run and wait<0> many", test_basic<ActivityPtr, create_exec, tester_wait<0>>);
233   RUN_SECTION("exec: actor failure and wait<0> / sleep",
234               test_failure_actor<ActivityPtr, create_exec, tester_wait<0>, waiter_sleep6>);
235   RUN_SECTION("exec: host failure and wait<0> / sleep",
236               test_failure_host<ActivityPtr, create_exec, tester_wait<0>, waiter_sleep6>);
237   RUN_SECTION("exec: actor failure and wait<0> / wait",
238               test_failure_actor<ActivityPtr, create_exec, tester_wait<0>, waiter_wait>);
239   RUN_SECTION("exec: host failure and wait<0> / wait",
240               test_failure_host<ActivityPtr, create_exec, tester_wait<0>, waiter_wait>);
241
242   // with tester_wait<1>
243   RUN_SECTION("exec: run and wait<1> many", test_basic<ActivityPtr, create_exec, tester_wait<1>>);
244   RUN_SECTION("exec: actor failure and wait<1> / sleep",
245               test_failure_actor<ActivityPtr, create_exec, tester_wait<1>, waiter_sleep6>);
246   RUN_SECTION("exec: host failure and wait<1> / sleep",
247               test_failure_host<ActivityPtr, create_exec, tester_wait<1>, waiter_sleep6>);
248   RUN_SECTION("exec: actor failure and wait<1> / wait",
249               test_failure_actor<ActivityPtr, create_exec, tester_wait<1>, waiter_wait>);
250   RUN_SECTION("exec: host failure and wait<1> / wait",
251               test_failure_host<ActivityPtr, create_exec, tester_wait<1>, waiter_wait>);
252
253   simgrid::s4u::this_actor::sleep_for(10);
254   assert_cleanup();
255 }