Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Update copyright lines for 2022.
[simgrid.git] / teshsuite / s4u / activity-lifecycle / testing_comm.cpp
1 /* Copyright (c) 2010-2022. 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 #include <array>
8
9 static void test_link_off_helper(double delay)
10 {
11   const double start = simgrid::s4u::Engine::get_clock();
12
13   simgrid::s4u::ActorPtr receiver = simgrid::s4u::Actor::create("receiver", all_hosts[1], [&start]() {
14     assert_exit(true, 9);
15     std::array<double, 5> milestone{{0.5, 3.5, 4.5, 7.5, 9.0}};
16     for (double& m : milestone)
17       m += start;
18     for (int i = 0; i < 4; i++) {
19       simgrid::s4u::this_actor::sleep_until(milestone[i]);
20       REQUIRE_NETWORK_FAILURE({
21         INFO("get(" << ('A' + i) << ")");
22         simgrid::s4u::Mailbox::by_name("mb")->get<int>();
23       });
24     }
25     simgrid::s4u::this_actor::sleep_until(milestone[4]);
26   });
27
28   simgrid::s4u::ActorPtr sender = simgrid::s4u::Actor::create("sender", all_hosts[2], [&start]() {
29     assert_exit(true, 9);
30     int data            = 42;
31     std::array<double, 5> milestone{{1.5, 2.5, 5.5, 6.5, 9.0}};
32     for (double& m : milestone)
33       m += start;
34     for (int i = 0; i < 2; i++) {
35       simgrid::s4u::this_actor::sleep_until(milestone[i]);
36       XBT_VERB("dsend(%c)", 'A' + i);
37       simgrid::s4u::Mailbox::by_name("mb")->put_init(&data, 100000)->detach();
38     }
39     for (int i = 2; i < 4; i++) {
40       simgrid::s4u::this_actor::sleep_until(milestone[i]);
41       REQUIRE_NETWORK_FAILURE({
42         INFO("put(" << ('A' + i) << ")");
43         simgrid::s4u::Mailbox::by_name("mb")->put(&data, 100000);
44       });
45     }
46     simgrid::s4u::this_actor::sleep_until(milestone[4]);
47   });
48
49   for (int i = 0; i < 4; i++) {
50     XBT_VERB("##### %d / 4 #####", i + 1);
51     simgrid::s4u::this_actor::sleep_for(delay);
52     XBT_VERB("link off");
53     simgrid::s4u::Link::by_name("link1")->turn_off();
54     simgrid::s4u::this_actor::sleep_for(2.0 - delay);
55     XBT_VERB("link on");
56     simgrid::s4u::Link::by_name("link1")->turn_on();
57   }
58   simgrid::s4u::this_actor::sleep_for(1.5);
59 };
60
61 TEST_CASE("Activity lifecycle: comm activities")
62 {
63   XBT_INFO("#####[ launch next \"comm\" test ]#####");
64
65   BEGIN_SECTION("comm")
66   {
67     XBT_INFO("Launch a communication");
68     bool send_done = false;
69     bool recv_done = false;
70
71     simgrid::s4u::Actor::create("sender", all_hosts[1], [&send_done]() {
72       assert_exit(true, 5);
73       char* payload = xbt_strdup("toto");
74       simgrid::s4u::Mailbox::by_name("mb")->put(payload, 5000);
75       send_done = true;
76     });
77
78     simgrid::s4u::Actor::create("receiver", all_hosts[2], [&recv_done]() {
79       assert_exit(true, 5);
80       char* payload = simgrid::s4u::Mailbox::by_name("mb")->get<char>();
81       xbt_free(payload);
82       recv_done = true;
83     });
84
85     simgrid::s4u::this_actor::sleep_for(9);
86     INFO("Sender or receiver killed somehow. It shouldn't");
87     REQUIRE(send_done);
88     REQUIRE(recv_done);
89
90     END_SECTION;
91   }
92
93   BEGIN_SECTION("comm dsend and quit (put before get)")
94   {
95     XBT_INFO("Launch a detached communication and end right after");
96     bool dsend_done = false;
97     bool recv_done  = false;
98
99     simgrid::s4u::ActorPtr sender = simgrid::s4u::Actor::create("sender", all_hosts[1], [&dsend_done]() {
100       assert_exit(true, 0);
101       char* payload = xbt_strdup("toto");
102       simgrid::s4u::Mailbox::by_name("mb")->put_init(payload, 1000)->detach();
103       dsend_done = true;
104     });
105
106     simgrid::s4u::Actor::create("receiver", all_hosts[2], [&recv_done]() {
107       assert_exit(true, 3);
108       simgrid::s4u::this_actor::sleep_for(2);
109       char* payload = simgrid::s4u::Mailbox::by_name("mb")->get<char>();
110       xbt_free(payload);
111       recv_done = true;
112     });
113
114     // Sleep long enough to let the test ends by itself. 3 + surf_precision should be enough.
115     simgrid::s4u::this_actor::sleep_for(4);
116     INFO("Sender or receiver killed somehow. It shouldn't");
117     REQUIRE(dsend_done);
118     REQUIRE(recv_done);
119
120     END_SECTION;
121   }
122
123   BEGIN_SECTION("comm dsend and quit (get before put)")
124   {
125     XBT_INFO("Launch a detached communication and end right after");
126     bool dsend_done = false;
127     bool recv_done  = false;
128
129     simgrid::s4u::ActorPtr sender = simgrid::s4u::Actor::create("sender", all_hosts[1], [&dsend_done]() {
130       assert_exit(true, 2);
131       char* payload = xbt_strdup("toto");
132       simgrid::s4u::this_actor::sleep_for(2);
133       simgrid::s4u::Mailbox::by_name("mb")->put_init(payload, 1000)->detach();
134       dsend_done = true;
135     });
136
137     simgrid::s4u::Actor::create("receiver", all_hosts[2], [&recv_done]() {
138       assert_exit(true, 3);
139       char* payload = simgrid::s4u::Mailbox::by_name("mb")->get<char>();
140       xbt_free(payload);
141       recv_done = true;
142     });
143
144     // Sleep long enough to let the test ends by itself. 3 + surf_precision should be enough.
145     simgrid::s4u::this_actor::sleep_for(4);
146     INFO("Sender or receiver killed somehow. It shouldn't");
147     REQUIRE(dsend_done);
148     REQUIRE(recv_done);
149
150     END_SECTION;
151   }
152
153   BEGIN_SECTION("comm kill sender")
154   {
155     XBT_INFO("Launch a communication and kill the sender");
156     bool send_done = false;
157     bool recv_done = false;
158
159     simgrid::s4u::ActorPtr sender = simgrid::s4u::Actor::create("sender", all_hosts[1], [&send_done]() {
160       assert_exit(false, 2);
161       // Encapsulate the payload in a std::unique_ptr so that it is correctly free'd when the sender is killed during
162       // its communication (thanks to RAII).  The pointer is then released when the communication is over.
163       std::unique_ptr<char, decltype(&xbt_free_f)> payload(xbt_strdup("toto"), &xbt_free_f);
164       simgrid::s4u::Mailbox::by_name("mb")->put(payload.get(), 5000);
165       payload.release();
166       send_done = true;
167     });
168
169     simgrid::s4u::Actor::create("receiver", all_hosts[2], [&recv_done]() {
170       assert_exit(true, 2);
171       REQUIRE_NETWORK_FAILURE({
172         char* payload = simgrid::s4u::Mailbox::by_name("mb")->get<char>();
173         xbt_free(payload);
174       });
175       recv_done = true;
176     });
177
178     simgrid::s4u::this_actor::sleep_for(2);
179     sender->kill();
180     // let the test ends by itself. waiting for surf_precision should be enough.
181     simgrid::s4u::this_actor::sleep_for(0.00001);
182
183     INFO("Sender was not killed properly or receiver killed somehow. It shouldn't");
184     REQUIRE(not send_done);
185     REQUIRE(recv_done);
186
187     END_SECTION;
188   }
189
190   BEGIN_SECTION("comm recv and kill")
191   {
192     XBT_INFO("Launch an actor that waits on a recv, kill its host");
193     bool in_on_exit              = false;
194     bool returned_from_main      = false;
195     bool in_catch_before_on_exit = false;
196     bool in_catch_after_on_exit  = false;
197     bool send_done               = false;
198
199     simgrid::s4u::ActorPtr receiver =
200         simgrid::s4u::Actor::create("receiver", all_hosts[1], [&in_on_exit, &returned_from_main,
201                                                                &in_catch_before_on_exit, &in_catch_after_on_exit]() {
202           assert_exit(false, 1);
203           try {
204             simgrid::s4u::Mailbox::by_name("mb")->get<int>();
205           } catch (simgrid::NetworkFailureException const&) {
206             // Shouldn't get in here after the on_exit function
207             in_catch_before_on_exit = not in_on_exit;
208             in_catch_after_on_exit  = in_on_exit;
209           }
210           returned_from_main = true;
211         });
212
213     receiver->on_exit([&in_on_exit](bool) { in_on_exit = true; });
214
215     simgrid::s4u::ActorPtr sender = simgrid::s4u::Actor::create("sender", all_hosts[2], [&send_done]() {
216       assert_exit(true, 1);
217       int data = 42;
218       REQUIRE_NETWORK_FAILURE(simgrid::s4u::Mailbox::by_name("mb")->put(&data, 100000));
219       send_done = true;
220     });
221
222     simgrid::s4u::this_actor::sleep_for(1);
223     receiver->get_host()->turn_off();
224
225     // Note: If we don't sleep here, we don't "see" the bug
226     simgrid::s4u::this_actor::sleep_for(1);
227
228     INFO("Receiver's on_exit function was never called");
229     REQUIRE(in_on_exit);
230     INFO("or receiver mistakenly went to catch clause (before the on_exit function was called)");
231     REQUIRE(not in_catch_before_on_exit);
232     INFO("or receiver mistakenly went to catch clause (after the on_exit function was called)");
233     REQUIRE(not in_catch_after_on_exit);
234     INFO("or receiver returned from main normally even though its host was killed");
235     REQUIRE(not returned_from_main);
236     INFO("or sender killed somehow, and it shouldn't");
237     REQUIRE(send_done);
238     receiver->get_host()->turn_on();
239
240     END_SECTION;
241   }
242
243   BEGIN_SECTION("comm turn link off before send/recv")
244   {
245     XBT_INFO("try to communicate with communicating link turned off before start");
246     test_link_off_helper(0.0);
247
248     END_SECTION;
249   }
250
251   BEGIN_SECTION("comm turn link off between send/recv")
252   {
253     XBT_INFO("try to communicate with communicating link turned off between send and receive");
254     test_link_off_helper(1.0);
255
256     END_SECTION;
257   }
258
259   BEGIN_SECTION("comm turn link off during transfer")
260   {
261     XBT_INFO("try to communicate with communicating link turned off during transfer");
262     test_link_off_helper(2.0);
263
264     END_SECTION;
265   }
266
267   BEGIN_SECTION("comm turn link off during wait_any")
268   {
269     XBT_INFO("try to communicate with communicating link turned off during wait_any");
270     simgrid::s4u::ActorPtr receiver = simgrid::s4u::Actor::create("receiver", all_hosts[1], []() {
271       assert_exit(true, 2);
272       int* data;
273       simgrid::s4u::CommPtr comm                       = simgrid::s4u::Mailbox::by_name("mb")->get_async<int>(&data);
274       std::vector<simgrid::s4u::CommPtr> pending_comms = {comm};
275       REQUIRE_NETWORK_FAILURE(simgrid::s4u::Comm::wait_any(pending_comms));
276     });
277
278     simgrid::s4u::ActorPtr sender = simgrid::s4u::Actor::create("sender", all_hosts[2], []() {
279       assert_exit(true, 2);
280       int data = 42;
281       REQUIRE_NETWORK_FAILURE(simgrid::s4u::Mailbox::by_name("mb")->put(&data, 100000));
282     });
283
284     simgrid::s4u::this_actor::sleep_for(2.0);
285     XBT_VERB("link off");
286     simgrid::s4u::Link::by_name("link1")->turn_off();
287     simgrid::s4u::this_actor::sleep_for(2.0);
288     XBT_VERB("link on");
289     simgrid::s4u::Link::by_name("link1")->turn_on();
290
291     END_SECTION;
292   }
293
294   simgrid::s4u::this_actor::sleep_for(10);
295   assert_cleanup();
296 }