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/odpor/Execution.hpp"
8 #include "src/mc/explo/odpor/WakeupTree.hpp"
9 #include "src/mc/explo/udpor/udpor_tests_private.hpp"
11 using namespace simgrid::mc;
12 using namespace simgrid::mc::odpor;
13 using namespace simgrid::mc::udpor;
15 TEST_CASE("simgrid::mc::odpor::WakeupTree: Testing Insertion")
17 // We imagine the following completed execution `E`
18 // consisting of executing actions a0-a3. Execution
19 // `E` cis the first such maximal execution explored
20 // by ODPOR, which implies that a) all sleep sets are
21 // empty and b) all wakeup trees (i.e. for each prefix) consist of the root
22 // node with a single leaf containing the action
23 // taken, save for the wakeup tree of the execution itself
26 // We first notice that there's a reversible race between
29 const auto a0 = std::make_shared<DependentAction>(Transition::Type::UNKNOWN, 3);
30 const auto a1 = std::make_shared<IndependentAction>(Transition::Type::UNKNOWN, 4);
31 const auto a2 = std::make_shared<ConditionallyDependentAction>(Transition::Type::UNKNOWN, 1);
32 const auto a3 = std::make_shared<ConditionallyDependentAction>(Transition::Type::UNKNOWN, 4);
35 execution.push_transition(a0);
36 execution.push_transition(a1);
37 execution.push_transition(a2);
38 execution.push_transition(a3);
40 REQUIRE(execution.get_racing_events_of(2) == std::unordered_set<Execution::EventHandle>{0});
41 REQUIRE(execution.get_racing_events_of(3) == std::unordered_set<Execution::EventHandle>{0});
43 // First, we initialize the tree to how it looked prior
44 // to the insertion of the race
46 tree.insert(Execution(), {a0});
48 // Then, after insertion, we ensure that the node was
49 // indeed added to the tree
51 tree.insert(Execution(), {a1, a3});
53 WakeupTreeIterator iter = tree.begin();
54 REQUIRE((*iter)->get_sequence() == PartialExecution{a0});
57 REQUIRE(iter != tree.end());
58 REQUIRE((*iter)->get_sequence() == PartialExecution{a1, a3});
61 REQUIRE(iter != tree.end());
62 REQUIRE((*iter)->get_sequence() == PartialExecution{});
65 REQUIRE(iter == tree.end());
67 SECTION("Attempting to re-insert the same sequence should have no effect")
69 tree.insert(Execution(), {a1, a3});
72 REQUIRE((*iter)->get_sequence() == PartialExecution{a0});
75 REQUIRE(iter != tree.end());
76 REQUIRE((*iter)->get_sequence() == PartialExecution{a1, a3});
79 REQUIRE(iter != tree.end());
80 REQUIRE((*iter)->get_sequence() == PartialExecution{});
83 REQUIRE(iter == tree.end());
86 SECTION("Inserting an extension")
88 tree.insert(Execution(), {a1, a2});
90 REQUIRE((*iter)->get_sequence() == PartialExecution{a0});
93 REQUIRE(iter != tree.end());
94 REQUIRE((*iter)->get_sequence() == PartialExecution{a1, a3});
97 REQUIRE(iter != tree.end());
98 REQUIRE((*iter)->get_sequence() == PartialExecution{a1, a2});
101 REQUIRE(iter != tree.end());
102 REQUIRE((*iter)->get_sequence() == PartialExecution{});
105 REQUIRE(iter == tree.end());