1 /* Copyright (c) 2017-2023. 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 "src/3rd-party/catch.hpp"
7 #include "src/mc/explo/udpor/UnfoldingEvent.hpp"
8 #include "src/mc/explo/udpor/udpor_tests_private.hpp"
10 using namespace simgrid::mc::udpor;
12 TEST_CASE("simgrid::mc::udpor::UnfoldingEvent: Dependency/Conflict Tests")
14 SECTION("Properties of the relations")
16 // The following tests concern the given event structure:
25 // e5 and e6 are in conflict, e5 and e7 are in conflict, e2 and e6, and e2 ands e7 are in conflict
26 UnfoldingEvent e1(EventSet(), std::make_shared<ConditionallyDependentAction>());
27 UnfoldingEvent e2(EventSet({&e1}), std::make_shared<DependentAction>());
28 UnfoldingEvent e3(EventSet({&e2}), std::make_shared<IndependentAction>());
29 UnfoldingEvent e4(EventSet({&e3}), std::make_shared<ConditionallyDependentAction>());
30 UnfoldingEvent e5(EventSet({&e3}), std::make_shared<DependentAction>());
31 UnfoldingEvent e6(EventSet({&e1}), std::make_shared<ConditionallyDependentAction>());
32 UnfoldingEvent e7(EventSet({&e6, &e2}), std::make_shared<ConditionallyDependentAction>());
34 SECTION("Dependency relation properties")
36 SECTION("Dependency is reflexive")
38 REQUIRE(e2.is_dependent_with(&e2));
39 REQUIRE(e5.is_dependent_with(&e5));
42 SECTION("Dependency is symmetric")
44 REQUIRE(e2.is_dependent_with(&e6));
45 REQUIRE(e6.is_dependent_with(&e2));
48 SECTION("Dependency is NOT necessarily transitive")
50 REQUIRE(e1.is_dependent_with(&e5));
51 REQUIRE(e5.is_dependent_with(&e7));
52 REQUIRE_FALSE(e1.is_dependent_with(&e7));
56 SECTION("Conflict relation properties")
58 SECTION("Conflict relation is irreflexive")
60 REQUIRE_FALSE(e1.conflicts_with(&e1));
61 REQUIRE_FALSE(e2.conflicts_with(&e2));
62 REQUIRE_FALSE(e3.conflicts_with(&e3));
63 REQUIRE_FALSE(e4.conflicts_with(&e4));
64 REQUIRE_FALSE(e5.conflicts_with(&e5));
65 REQUIRE_FALSE(e6.conflicts_with(&e6));
66 REQUIRE_FALSE(e7.conflicts_with(&e7));
68 REQUIRE_FALSE(e1.immediately_conflicts_with(&e1));
69 REQUIRE_FALSE(e2.immediately_conflicts_with(&e2));
70 REQUIRE_FALSE(e3.immediately_conflicts_with(&e3));
71 REQUIRE_FALSE(e4.immediately_conflicts_with(&e4));
72 REQUIRE_FALSE(e5.immediately_conflicts_with(&e5));
73 REQUIRE_FALSE(e6.immediately_conflicts_with(&e6));
74 REQUIRE_FALSE(e7.immediately_conflicts_with(&e7));
77 SECTION("Conflict relation is symmetric")
79 REQUIRE(e5.conflicts_with(&e6));
80 REQUIRE(e6.conflicts_with(&e5));
81 REQUIRE(e5.immediately_conflicts_with(&e4));
82 REQUIRE(e4.immediately_conflicts_with(&e5));
87 SECTION("No conflicts whatsoever")
89 // The following tests concern the given event structure:
97 UnfoldingEvent e1(EventSet(), std::make_shared<IndependentAction>());
98 UnfoldingEvent e2(EventSet({&e1}), std::make_shared<IndependentAction>());
99 UnfoldingEvent e3(EventSet({&e2}), std::make_shared<IndependentAction>());
100 UnfoldingEvent e4(EventSet({&e3}), std::make_shared<IndependentAction>());
101 UnfoldingEvent e5(EventSet({&e3}), std::make_shared<IndependentAction>());
102 UnfoldingEvent e6(EventSet({&e1}), std::make_shared<IndependentAction>());
103 UnfoldingEvent e7(EventSet({&e6, &e2}), std::make_shared<IndependentAction>());
105 // Since everyone's actions are independent of one another, we expect
106 // that there are no conflicts between each pair of events
107 SECTION("Mutual dependencies")
109 CHECK_FALSE(e1.is_dependent_with(&e1));
110 CHECK_FALSE(e1.is_dependent_with(&e2));
111 CHECK_FALSE(e1.is_dependent_with(&e3));
112 CHECK_FALSE(e1.is_dependent_with(&e4));
113 CHECK_FALSE(e1.is_dependent_with(&e5));
114 CHECK_FALSE(e1.is_dependent_with(&e6));
115 CHECK_FALSE(e1.is_dependent_with(&e7));
117 CHECK_FALSE(e2.is_dependent_with(&e2));
118 CHECK_FALSE(e2.is_dependent_with(&e3));
119 CHECK_FALSE(e2.is_dependent_with(&e4));
120 CHECK_FALSE(e2.is_dependent_with(&e5));
121 CHECK_FALSE(e2.is_dependent_with(&e6));
122 CHECK_FALSE(e2.is_dependent_with(&e7));
124 CHECK_FALSE(e3.is_dependent_with(&e3));
125 CHECK_FALSE(e3.is_dependent_with(&e4));
126 CHECK_FALSE(e3.is_dependent_with(&e5));
127 CHECK_FALSE(e3.is_dependent_with(&e6));
128 CHECK_FALSE(e3.is_dependent_with(&e7));
130 CHECK_FALSE(e4.is_dependent_with(&e4));
131 CHECK_FALSE(e4.is_dependent_with(&e5));
132 CHECK_FALSE(e4.is_dependent_with(&e6));
133 CHECK_FALSE(e4.is_dependent_with(&e7));
135 CHECK_FALSE(e5.is_dependent_with(&e5));
136 CHECK_FALSE(e5.is_dependent_with(&e6));
137 CHECK_FALSE(e5.is_dependent_with(&e7));
139 CHECK_FALSE(e6.is_dependent_with(&e6));
140 CHECK_FALSE(e6.is_dependent_with(&e7));
142 CHECK_FALSE(e7.is_dependent_with(&e7));
145 SECTION("Mutual conflicts")
147 CHECK_FALSE(e1.conflicts_with(&e1));
148 CHECK_FALSE(e1.conflicts_with(&e2));
149 CHECK_FALSE(e1.conflicts_with(&e3));
150 CHECK_FALSE(e1.conflicts_with(&e4));
151 CHECK_FALSE(e1.conflicts_with(&e5));
152 CHECK_FALSE(e1.conflicts_with(&e6));
153 CHECK_FALSE(e1.conflicts_with(&e7));
155 CHECK_FALSE(e2.conflicts_with(&e1));
156 CHECK_FALSE(e2.conflicts_with(&e2));
157 CHECK_FALSE(e2.conflicts_with(&e3));
158 CHECK_FALSE(e2.conflicts_with(&e4));
159 CHECK_FALSE(e2.conflicts_with(&e5));
160 CHECK_FALSE(e2.conflicts_with(&e6));
161 CHECK_FALSE(e2.conflicts_with(&e7));
163 CHECK_FALSE(e3.conflicts_with(&e1));
164 CHECK_FALSE(e3.conflicts_with(&e2));
165 CHECK_FALSE(e3.conflicts_with(&e3));
166 CHECK_FALSE(e3.conflicts_with(&e4));
167 CHECK_FALSE(e3.conflicts_with(&e5));
168 CHECK_FALSE(e3.conflicts_with(&e6));
169 CHECK_FALSE(e3.conflicts_with(&e7));
171 CHECK_FALSE(e4.conflicts_with(&e1));
172 CHECK_FALSE(e4.conflicts_with(&e2));
173 CHECK_FALSE(e4.conflicts_with(&e3));
174 CHECK_FALSE(e4.conflicts_with(&e4));
175 CHECK_FALSE(e4.conflicts_with(&e5));
176 CHECK_FALSE(e4.conflicts_with(&e6));
177 CHECK_FALSE(e4.conflicts_with(&e7));
179 CHECK_FALSE(e5.conflicts_with(&e1));
180 CHECK_FALSE(e5.conflicts_with(&e2));
181 CHECK_FALSE(e5.conflicts_with(&e3));
182 CHECK_FALSE(e5.conflicts_with(&e4));
183 CHECK_FALSE(e5.conflicts_with(&e5));
184 CHECK_FALSE(e5.conflicts_with(&e6));
185 CHECK_FALSE(e5.conflicts_with(&e7));
187 CHECK_FALSE(e6.conflicts_with(&e1));
188 CHECK_FALSE(e6.conflicts_with(&e2));
189 CHECK_FALSE(e6.conflicts_with(&e3));
190 CHECK_FALSE(e6.conflicts_with(&e4));
191 CHECK_FALSE(e6.conflicts_with(&e5));
192 CHECK_FALSE(e6.conflicts_with(&e6));
193 CHECK_FALSE(e6.conflicts_with(&e7));
195 CHECK_FALSE(e7.conflicts_with(&e1));
196 CHECK_FALSE(e7.conflicts_with(&e2));
197 CHECK_FALSE(e7.conflicts_with(&e3));
198 CHECK_FALSE(e7.conflicts_with(&e4));
199 CHECK_FALSE(e7.conflicts_with(&e5));
200 CHECK_FALSE(e7.conflicts_with(&e6));
201 CHECK_FALSE(e7.conflicts_with(&e7));
205 SECTION("General conflicts")
207 // The following tests concern the given event structure:
215 UnfoldingEvent e1(EventSet(), std::make_shared<DependentAction>());
216 UnfoldingEvent e2(EventSet({&e1}), std::make_shared<DependentAction>());
217 UnfoldingEvent e3(EventSet({&e2}), std::make_shared<IndependentAction>());
218 UnfoldingEvent e4(EventSet({&e3}), std::make_shared<IndependentAction>());
219 UnfoldingEvent e5(EventSet({&e3}), std::make_shared<IndependentAction>());
220 UnfoldingEvent e6(EventSet({&e1}), std::make_shared<IndependentAction>());
221 UnfoldingEvent e7(EventSet({&e6, &e2}), std::make_shared<ConditionallyDependentAction>());
223 // Since everyone's actions are independent of one another, we expect
224 // that there are no conflicts between each pair of events
225 SECTION("Mutual dependencies")
227 CHECK(e1.is_dependent_with(&e1));
228 CHECK(e1.is_dependent_with(&e2));
229 CHECK_FALSE(e1.is_dependent_with(&e3));
230 CHECK_FALSE(e1.is_dependent_with(&e4));
231 CHECK_FALSE(e1.is_dependent_with(&e5));
232 CHECK_FALSE(e1.is_dependent_with(&e6));
233 CHECK(e1.is_dependent_with(&e7));
235 CHECK(e2.is_dependent_with(&e2));
236 CHECK_FALSE(e2.is_dependent_with(&e3));
237 CHECK_FALSE(e2.is_dependent_with(&e4));
238 CHECK_FALSE(e2.is_dependent_with(&e5));
239 CHECK_FALSE(e2.is_dependent_with(&e6));
240 CHECK(e2.is_dependent_with(&e7));
242 CHECK_FALSE(e3.is_dependent_with(&e3));
243 CHECK_FALSE(e3.is_dependent_with(&e4));
244 CHECK_FALSE(e3.is_dependent_with(&e5));
245 CHECK_FALSE(e3.is_dependent_with(&e6));
246 CHECK_FALSE(e3.is_dependent_with(&e7));
248 CHECK_FALSE(e4.is_dependent_with(&e4));
249 CHECK_FALSE(e4.is_dependent_with(&e5));
250 CHECK_FALSE(e4.is_dependent_with(&e6));
251 CHECK_FALSE(e4.is_dependent_with(&e7));
253 CHECK_FALSE(e5.is_dependent_with(&e5));
254 CHECK_FALSE(e5.is_dependent_with(&e6));
255 CHECK_FALSE(e5.is_dependent_with(&e7));
257 CHECK_FALSE(e6.is_dependent_with(&e6));
258 CHECK_FALSE(e6.is_dependent_with(&e7));
260 CHECK_FALSE(e7.is_dependent_with(&e7));
263 SECTION("Mutual conflicts")
265 // Although e1 is dependent with e1, e2, and e7,
266 // since they are related to one another, they are not
267 // considered to be in conflict
268 CHECK_FALSE(e1.conflicts_with(&e1));
269 CHECK_FALSE(e1.conflicts_with(&e2));
270 CHECK_FALSE(e1.conflicts_with(&e3));
271 CHECK_FALSE(e1.conflicts_with(&e4));
272 CHECK_FALSE(e1.conflicts_with(&e5));
273 CHECK_FALSE(e1.conflicts_with(&e6));
274 CHECK_FALSE(e1.conflicts_with(&e7));
276 // Same goes for e2 with e2 and e7
277 CHECK_FALSE(e2.conflicts_with(&e1));
278 CHECK_FALSE(e2.conflicts_with(&e2));
279 CHECK_FALSE(e2.conflicts_with(&e3));
280 CHECK_FALSE(e2.conflicts_with(&e4));
281 CHECK_FALSE(e2.conflicts_with(&e5));
282 CHECK_FALSE(e2.conflicts_with(&e6));
283 CHECK_FALSE(e2.conflicts_with(&e7));
285 CHECK_FALSE(e3.conflicts_with(&e1));
286 CHECK_FALSE(e3.conflicts_with(&e2));
287 CHECK_FALSE(e3.conflicts_with(&e3));
288 CHECK_FALSE(e3.conflicts_with(&e4));
289 CHECK_FALSE(e3.conflicts_with(&e5));
290 CHECK_FALSE(e3.conflicts_with(&e6));
291 CHECK_FALSE(e3.conflicts_with(&e7));
293 CHECK_FALSE(e4.conflicts_with(&e1));
294 CHECK_FALSE(e4.conflicts_with(&e2));
295 CHECK_FALSE(e4.conflicts_with(&e3));
296 CHECK_FALSE(e4.conflicts_with(&e4));
297 CHECK_FALSE(e4.conflicts_with(&e5));
298 CHECK_FALSE(e4.conflicts_with(&e6));
299 CHECK_FALSE(e4.conflicts_with(&e7));
301 CHECK_FALSE(e5.conflicts_with(&e1));
302 CHECK_FALSE(e5.conflicts_with(&e2));
303 CHECK_FALSE(e5.conflicts_with(&e3));
304 CHECK_FALSE(e5.conflicts_with(&e4));
305 CHECK_FALSE(e5.conflicts_with(&e5));
306 CHECK_FALSE(e5.conflicts_with(&e6));
307 CHECK_FALSE(e5.conflicts_with(&e7));
309 CHECK_FALSE(e6.conflicts_with(&e1));
310 CHECK_FALSE(e6.conflicts_with(&e2));
311 CHECK_FALSE(e6.conflicts_with(&e3));
312 CHECK_FALSE(e6.conflicts_with(&e4));
313 CHECK_FALSE(e6.conflicts_with(&e5));
314 CHECK_FALSE(e6.conflicts_with(&e6));
315 CHECK_FALSE(e6.conflicts_with(&e7));
317 CHECK_FALSE(e7.conflicts_with(&e1));
318 CHECK_FALSE(e7.conflicts_with(&e2));
319 CHECK_FALSE(e7.conflicts_with(&e3));
320 CHECK_FALSE(e7.conflicts_with(&e4));
321 CHECK_FALSE(e7.conflicts_with(&e5));
322 CHECK_FALSE(e7.conflicts_with(&e6));
323 CHECK_FALSE(e7.conflicts_with(&e7));
327 SECTION("More complicated conflicts")
329 // The following tests concern the given event structure:
337 UnfoldingEvent e1(EventSet(), std::make_shared<IndependentAction>());
338 UnfoldingEvent e2(EventSet({&e1}), std::make_shared<ConditionallyDependentAction>());
339 UnfoldingEvent e3(EventSet({&e2}), std::make_shared<IndependentAction>());
340 UnfoldingEvent e4(EventSet({&e3}), std::make_shared<IndependentAction>());
341 UnfoldingEvent e5(EventSet({&e3}), std::make_shared<IndependentAction>());
342 UnfoldingEvent e6(EventSet({&e1}), std::make_shared<DependentAction>());
343 UnfoldingEvent e7(EventSet({&e6}), std::make_shared<IndependentAction>());
345 CHECK_FALSE(e1.conflicts_with(&e1));
346 CHECK_FALSE(e1.conflicts_with(&e2));
347 CHECK_FALSE(e1.conflicts_with(&e3));
348 CHECK_FALSE(e1.conflicts_with(&e4));
349 CHECK_FALSE(e1.conflicts_with(&e5));
350 CHECK_FALSE(e1.conflicts_with(&e6));
351 CHECK_FALSE(e1.conflicts_with(&e7));
353 // e2 conflicts with e6. Since e6 < e7,
354 // e2 also conflicts with e7
355 CHECK_FALSE(e2.conflicts_with(&e1));
356 CHECK_FALSE(e2.conflicts_with(&e2));
357 CHECK_FALSE(e2.conflicts_with(&e3));
358 CHECK_FALSE(e2.conflicts_with(&e4));
359 CHECK_FALSE(e2.conflicts_with(&e5));
360 CHECK(e2.conflicts_with(&e6));
361 REQUIRE(e2.conflicts_with(&e7));
363 // e3 and e6 are dependent and unrelated, so they conflict
364 CHECK_FALSE(e3.conflicts_with(&e1));
365 CHECK_FALSE(e3.conflicts_with(&e2));
366 CHECK_FALSE(e3.conflicts_with(&e3));
367 CHECK_FALSE(e3.conflicts_with(&e4));
368 CHECK_FALSE(e3.conflicts_with(&e5));
369 CHECK(e3.conflicts_with(&e6));
370 CHECK_FALSE(e3.conflicts_with(&e7));
372 // Since e3 and e6 conflict and e3 < e4, e4 and e6 conflict
373 CHECK_FALSE(e4.conflicts_with(&e1));
374 CHECK_FALSE(e4.conflicts_with(&e2));
375 CHECK_FALSE(e4.conflicts_with(&e3));
376 CHECK_FALSE(e4.conflicts_with(&e4));
377 CHECK_FALSE(e4.conflicts_with(&e5));
378 CHECK(e4.conflicts_with(&e6));
379 CHECK_FALSE(e4.conflicts_with(&e7));
382 CHECK_FALSE(e5.conflicts_with(&e1));
383 CHECK_FALSE(e5.conflicts_with(&e2));
384 CHECK_FALSE(e5.conflicts_with(&e3));
385 CHECK_FALSE(e5.conflicts_with(&e4));
386 CHECK_FALSE(e5.conflicts_with(&e5));
387 CHECK(e5.conflicts_with(&e6));
388 CHECK_FALSE(e5.conflicts_with(&e7));
390 // Conflicts are symmetric
391 CHECK_FALSE(e6.conflicts_with(&e1));
392 CHECK(e6.conflicts_with(&e2));
393 CHECK(e6.conflicts_with(&e3));
394 CHECK(e6.conflicts_with(&e4));
395 CHECK(e6.conflicts_with(&e5));
396 CHECK_FALSE(e6.conflicts_with(&e6));
397 CHECK_FALSE(e6.conflicts_with(&e7));
399 CHECK_FALSE(e7.conflicts_with(&e1));
400 CHECK(e7.conflicts_with(&e2));
401 CHECK_FALSE(e7.conflicts_with(&e3));
402 CHECK_FALSE(e7.conflicts_with(&e4));
403 CHECK_FALSE(e7.conflicts_with(&e5));
404 CHECK_FALSE(e7.conflicts_with(&e6));
405 CHECK_FALSE(e7.conflicts_with(&e7));
409 TEST_CASE("simgrid::mc::udpor::UnfoldingEvent: Immediate Conflicts + Conflicts Stress Test")
411 // The following tests concern the given event structure:
424 // Immediate conflicts:
429 // NOTE: e7 + e8 ARE NOT in immediate conflict! The reason is that
430 // the set of events {e8, e6, e5, e3, e4, e1} is not a valid configuration,
431 // (nor is {e7, e6, e5, e3, e4, e1})
433 // NOTE: e2/e3 + e10 are NOT in immediate conflict! EVEN THOUGH {e1, e4, e10}
434 // is a valid configuration, {e1, e2/e3, e4} is not (since e2/e3 and e4 conflict)
435 UnfoldingEvent e1(EventSet(), std::make_shared<IndependentAction>());
436 UnfoldingEvent e2(EventSet({&e1}), std::make_shared<DependentAction>());
437 UnfoldingEvent e3(EventSet({&e1}), std::make_shared<DependentAction>());
438 UnfoldingEvent e4(EventSet({&e1}), std::make_shared<DependentAction>());
439 UnfoldingEvent e5(EventSet({&e3, &e4}), std::make_shared<IndependentAction>());
440 UnfoldingEvent e6(EventSet({&e5}), std::make_shared<IndependentAction>());
441 UnfoldingEvent e7(EventSet({&e6}), std::make_shared<DependentAction>());
442 UnfoldingEvent e8(EventSet({&e6}), std::make_shared<DependentAction>());
443 UnfoldingEvent e9(EventSet({&e8}), std::make_shared<IndependentAction>());
444 UnfoldingEvent e10(EventSet({&e4}), std::make_shared<DependentAction>());
446 REQUIRE(e2.immediately_conflicts_with(&e3));
447 REQUIRE(e3.immediately_conflicts_with(&e4));
448 REQUIRE(e2.immediately_conflicts_with(&e4));
450 REQUIRE(e2.conflicts_with(&e10));
451 REQUIRE(e3.conflicts_with(&e10));
452 REQUIRE(e7.conflicts_with(&e8));
453 REQUIRE_FALSE(e2.immediately_conflicts_with(&e10));
454 REQUIRE_FALSE(e3.immediately_conflicts_with(&e10));
455 REQUIRE_FALSE(e7.immediately_conflicts_with(&e8));