Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Tests were wrong, fix them.
[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 // Create a new async execution with given duration
11 static simgrid::s4u::ActivityPtr create_exec(double duration)
12 {
13   double speed = simgrid::s4u::this_actor::get_host()->get_speed();
14   return simgrid::s4u::this_actor::exec_async(speed * duration);
15 }
16
17 // TODO: check other kinds of activities too (Io, Comm, ...)
18
19 using creator_type = decltype(create_exec);
20
21 //========== Testers: test the completion of an activity
22
23 // Calls activity->test() and returns its result
24 static bool tester_test(const simgrid::s4u::ActivityPtr& activity)
25 {
26   return activity->test();
27 }
28
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)
31 {
32   constexpr double duration = Duration / 128.0;
33   const double timeout      = simgrid::s4u::Engine::get_clock() + duration;
34   bool ret;
35   try {
36     XBT_DEBUG("calling wait_for(%f)", duration);
37     activity->wait_for(duration);
38     XBT_DEBUG("wait_for() returned normally");
39     ret = true;
40   } catch (const simgrid::TimeoutException& e) {
41     XBT_DEBUG("wait_for() timed out (%s)", e.what());
42     INFO("wait_for() timeout should expire at expected date: " << timeout);
43     REQUIRE(simgrid::s4u::Engine::get_clock() == Approx(timeout));
44     ret = false;
45   } catch (const simgrid::Exception& e) {
46     XBT_DEBUG("wait_for() threw an exception: %s", e.what());
47     ret = true;
48   }
49   INFO("wait_for() should return before timeout expiration at date: " << timeout);
50   REQUIRE(simgrid::s4u::Engine::get_clock() <= Approx(timeout));
51   return ret;
52 }
53
54 using tester_type = decltype(tester_test);
55
56 //========== Waiters: wait for the completion of an activity
57
58 // Wait for 6s
59 static void waiter_sleep6(const simgrid::s4u::ActivityPtr&)
60 {
61   simgrid::s4u::this_actor::sleep_for(6.0);
62   XBT_DEBUG("wake up after 6s sleep");
63 }
64
65 // Wait for completion of activity
66 static void waiter_wait(const simgrid::s4u::ActivityPtr& activity)
67 {
68   activity->wait();
69   XBT_DEBUG("end of wait()");
70 }
71
72 using waiter_type = decltype(waiter_wait);
73
74 //========== Finally, the test templates
75
76 template <creator_type Create, tester_type 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     simgrid::s4u::ActivityPtr 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 <creator_type Create, tester_type 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     simgrid::s4u::ActivityPtr 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 <creator_type Create, tester_type 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     simgrid::s4u::ActivityPtr 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 <creator_type Create, tester_type Test, waiter_type Wait> void test_failure_actor()
125 {
126   XBT_INFO("Launch an activity for 5s, and kill running actor after 2s");
127
128   simgrid::s4u::ActivityPtr activity;
129   simgrid::s4u::ActorPtr actor = simgrid::s4u::Actor::create("actor", all_hosts[1], [&activity]() {
130     assert_exit(false, 2.);
131     activity = Create(5.0);
132     Wait(activity);
133     FAIL("should not be here!");
134   });
135   const double timestep = simgrid::s4u::Engine::get_clock() + 2.0;
136   simgrid::s4u::this_actor::sleep_for(1.0);
137   INFO("activity should be still running");
138   REQUIRE(not Test(activity));
139   simgrid::s4u::this_actor::sleep_until(timestep);
140   actor->kill();
141   INFO("activity should be terminated now");
142   REQUIRE(Test(activity));
143 }
144
145 template <creator_type Create, tester_type Test, waiter_type Wait> void test_failure_host()
146 {
147   XBT_INFO("Launch an activity for 5s, and shutdown host 2s");
148
149   simgrid::s4u::ActivityPtr activity;
150   simgrid::s4u::ActorPtr actor = simgrid::s4u::Actor::create("actor", all_hosts[1], [&activity]() {
151     assert_exit(false, 2.);
152     activity = Create(5.0);
153     Wait(activity);
154     FAIL("should not be here!");
155   });
156   const double timestep = simgrid::s4u::Engine::get_clock() + 2.0;
157   simgrid::s4u::this_actor::sleep_for(1.0);
158   INFO("activity should be still running");
159   REQUIRE(not Test(activity));
160   simgrid::s4u::this_actor::sleep_until(timestep);
161   actor->get_host()->turn_off();
162   actor->get_host()->turn_on();
163   INFO("activity should be terminated now");
164   REQUIRE(Test(activity));
165 }
166
167 //==========
168
169 TEST_CASE("Activity test/wait: using <tester_test>")
170 {
171   XBT_INFO("#####[ launch next test ]#####");
172
173   RUN_SECTION("exec: run and test once", test_trivial<create_exec, tester_test>);
174   RUN_SECTION("exec: run and test many", test_basic<create_exec, tester_test>);
175   RUN_SECTION("exec: cancel and test", test_cancel<create_exec, tester_test>);
176   RUN_SECTION("exec: actor failure and test / sleep", test_failure_actor<create_exec, tester_test, waiter_sleep6>);
177   RUN_SECTION("exec: host failure and test / sleep", test_failure_host<create_exec, tester_test, waiter_sleep6>);
178   RUN_SECTION("exec: actor failure and test / wait", test_failure_actor<create_exec, tester_test, waiter_wait>);
179   RUN_SECTION("exec: host failure and test / wait", test_failure_host<create_exec, tester_test, waiter_wait>);
180
181   simgrid::s4u::this_actor::sleep_for(10);
182   assert_cleanup();
183 }
184
185 TEST_CASE("Activity test/wait: using <tester_wait<0>>")
186 {
187   XBT_INFO("#####[ launch next test ]#####");
188
189   RUN_SECTION("exec: run and wait<0> once", test_trivial<create_exec, tester_wait<0>>);
190   // exec: run and wait<0> many
191   RUN_SECTION("exec: cancel and wait<0>", test_cancel<create_exec, tester_wait<0>>);
192   // exec: actor failure and wait<0> / sleep
193   // exec: host failure and wait<0> / sleep
194   // exec: actor failure and wait<0> / wait
195   // exec: host failure and wait<0> / wait
196
197   simgrid::s4u::this_actor::sleep_for(10);
198   assert_cleanup();
199 }
200
201 TEST_CASE("Activity test/wait: using <tester_wait<1>>")
202 {
203   XBT_INFO("#####[ launch next test ]#####");
204
205   RUN_SECTION("exec: run and wait<1> once", test_trivial<create_exec, tester_wait<1>>);
206   // exec: run and wait<1> many
207   RUN_SECTION("exec: cancel and wait<1>", test_cancel<create_exec, tester_wait<1>>);
208   // exec: actor failure and wait<1> / sleep
209   // exec: host failure and wait<1> / sleep
210   // exec: actor failure and wait<1> / wait
211   // exec: host failure and wait<1> / wait
212
213   simgrid::s4u::this_actor::sleep_for(10);
214   assert_cleanup();
215 }
216
217 // FIXME: The tests grouped here are currently failing. Once fixed, they should be put in the right section above.
218 //        The tests can be activated with run-time parameter '*' or, more specifically '[failing]'
219 TEST_CASE("Activity test/wait: tests currently failing", "[.][failing]")
220 {
221   XBT_INFO("#####[ launch next failing test ]#####");
222
223   // with tester_wait<0>
224   RUN_SECTION("exec: run and wait<0> many", test_basic<create_exec, tester_wait<0>>);
225   RUN_SECTION("exec: actor failure and wait<0> / sleep", test_failure_actor<create_exec, tester_wait<0>, waiter_sleep6>);
226   RUN_SECTION("exec: host failure and wait<0> / sleep", test_failure_host<create_exec, tester_wait<0>, waiter_sleep6>);
227   RUN_SECTION("exec: actor failure and wait<0> / wait", test_failure_actor<create_exec, tester_wait<0>, waiter_wait>);
228   RUN_SECTION("exec: host failure and wait<0> / wait", test_failure_host<create_exec, tester_wait<0>, waiter_wait>);
229
230   // with tester_test<1>
231   RUN_SECTION("exec: run and wait<1> many", test_basic<create_exec, tester_wait<1>>);
232   RUN_SECTION("exec: actor failure and wait<1> / sleep", test_failure_actor<create_exec, tester_wait<1>, waiter_sleep6>);
233   RUN_SECTION("exec: host failure and wait<1> / sleep", test_failure_host<create_exec, tester_wait<1>, waiter_sleep6>);
234   RUN_SECTION("exec: actor failure and wait<1> / wait", test_failure_actor<create_exec, tester_wait<1>, waiter_wait>);
235   RUN_SECTION("exec: host failure and wait<1> / wait", test_failure_host<create_exec, tester_wait<1>, waiter_wait>);
236
237   simgrid::s4u::this_actor::sleep_for(10);
238   assert_cleanup();
239 }