From 1fc1cd99f7f9f56c732dcaf07d8c9afed2560e85 Mon Sep 17 00:00:00 2001 From: Maxwell Pirtle Date: Mon, 20 Feb 2023 13:38:02 +0100 Subject: [PATCH] Add first batch of tests for UDPOR This commit adds tests for the UDPOR constructs that will be used when UDPOR is finally implemented. UDPOR will rely heavily on the correctness of the methods herein and hereafter (in subsequent commits) tested, so it is important that each function be tested to the maximum extent possible --- src/mc/explo/udpor/EventSet.hpp | 7 +- src/mc/explo/udpor/EventSet_test.cpp | 192 +++++++++++++++++++++ src/mc/explo/udpor/UnfoldingEvent.hpp | 3 +- src/mc/explo/udpor/UnfoldingEvent_test.cpp | 9 + src/mc/explo/udpor/Unfolding_test.cpp | 16 ++ tools/cmake/Tests.cmake | 6 +- 6 files changed, 230 insertions(+), 3 deletions(-) create mode 100644 src/mc/explo/udpor/EventSet_test.cpp create mode 100644 src/mc/explo/udpor/UnfoldingEvent_test.cpp create mode 100644 src/mc/explo/udpor/Unfolding_test.cpp diff --git a/src/mc/explo/udpor/EventSet.hpp b/src/mc/explo/udpor/EventSet.hpp index 9e5cab9e25..1808eae199 100644 --- a/src/mc/explo/udpor/EventSet.hpp +++ b/src/mc/explo/udpor/EventSet.hpp @@ -9,6 +9,7 @@ #include "src/mc/explo/udpor/udpor_forward.hpp" #include +#include #include namespace simgrid::mc::udpor { @@ -16,7 +17,6 @@ namespace simgrid::mc::udpor { class EventSet { private: std::unordered_set events_; - explicit EventSet(std::unordered_set&& raw_events) : events_(raw_events) {} public: EventSet() = default; @@ -24,6 +24,8 @@ public: EventSet& operator=(const EventSet&) = default; EventSet& operator=(EventSet&&) = default; EventSet(EventSet&&) = default; + explicit EventSet(std::unordered_set&& raw_events) : events_(raw_events) {} + explicit EventSet(std::initializer_list event_list) : events_(std::move(event_list)) {} inline auto begin() const { return this->events_.begin(); } inline auto end() const { return this->events_.end(); } @@ -46,6 +48,9 @@ public: bool empty() const; bool contains(UnfoldingEvent*) const; bool is_subset_of(const EventSet&) const; + + bool operator==(const EventSet& other) { return this->events_ == other.events_; } + bool operator!=(const EventSet& other) { return this->events_ != other.events_; } }; } // namespace simgrid::mc::udpor diff --git a/src/mc/explo/udpor/EventSet_test.cpp b/src/mc/explo/udpor/EventSet_test.cpp new file mode 100644 index 0000000000..f5e363daf4 --- /dev/null +++ b/src/mc/explo/udpor/EventSet_test.cpp @@ -0,0 +1,192 @@ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/3rd-party/catch.hpp" +#include "src/mc/explo/udpor/EventSet.hpp" +#include "src/mc/explo/udpor/UnfoldingEvent.hpp" + +using namespace simgrid::mc::udpor; + +TEST_CASE("simgrid::mc::udpor::EventSet: Initial conditions when creating sets") +{ + SECTION("Initialization with no elements") + { + SECTION("Default initializer") + { + EventSet event_set; + REQUIRE(event_set.size() == 0); + REQUIRE(event_set.empty()); + } + + SECTION("Set initializer") + { + EventSet event_set({}); + REQUIRE(event_set.size() == 0); + REQUIRE(event_set.empty()); + } + + SECTION("List initialization") + { + EventSet event_set{}; + REQUIRE(event_set.size() == 0); + REQUIRE(event_set.empty()); + } + } + + SECTION("Initialization with one or more elements") + { + UnfoldingEvent e1, e2, e3; + + SECTION("Set initializer") + { + EventSet event_set({&e1, &e2, &e3}); + REQUIRE(event_set.size() == 3); + REQUIRE(event_set.contains(&e1)); + REQUIRE(event_set.contains(&e2)); + REQUIRE(event_set.contains(&e3)); + REQUIRE_FALSE(event_set.empty()); + } + + SECTION("List initialization") + { + UnfoldingEvent e1, e2, e3; + EventSet event_set{&e1, &e2, &e3}; + REQUIRE(event_set.size() == 3); + REQUIRE(event_set.contains(&e1)); + REQUIRE(event_set.contains(&e2)); + REQUIRE(event_set.contains(&e3)); + REQUIRE_FALSE(event_set.empty()); + } + } +} + +TEST_CASE("simgrid::mc::udpor::EventSet: Insertions") +{ + EventSet event_set; + UnfoldingEvent e1, e2, e3; + + SECTION("Inserting unique elements") + { + event_set.insert(&e1); + REQUIRE(event_set.size() == 1); + REQUIRE(event_set.contains(&e1)); + REQUIRE_FALSE(event_set.empty()); + + event_set.insert(&e2); + REQUIRE(event_set.size() == 2); + REQUIRE(event_set.contains(&e2)); + REQUIRE_FALSE(event_set.empty()); + + SECTION("Check contains inserted elements") + { + REQUIRE(event_set.contains(&e1)); + REQUIRE(event_set.contains(&e2)); + REQUIRE_FALSE(event_set.contains(&e3)); + } + } + + SECTION("Inserting duplicate elements") + { + event_set.insert(&e1); + REQUIRE(event_set.size() == 1); + REQUIRE(event_set.contains(&e1)); + REQUIRE_FALSE(event_set.empty()); + + event_set.insert(&e1); + REQUIRE(event_set.size() == 1); + REQUIRE(event_set.contains(&e1)); + REQUIRE_FALSE(event_set.empty()); + + SECTION("Check contains inserted elements") + { + REQUIRE(event_set.contains(&e1)); + REQUIRE_FALSE(event_set.contains(&e2)); + REQUIRE_FALSE(event_set.contains(&e3)); + } + } +} + +TEST_CASE("simgrid::mc::udpor::EventSet: Deletions") +{ + UnfoldingEvent e1, e2, e3, e4; + EventSet event_set({&e1, &e2, &e3}); + + SECTION("Remove an element already present") + { + REQUIRE(event_set.contains(&e1)); + + // event_set = {e2, e3} + event_set.remove(&e1); + + // Check that + // 1. the size decreases by exactly 1 + // 2. the set remains unempty + // 3. the other elements are still contained in the set + REQUIRE(event_set.size() == 2); + REQUIRE_FALSE(event_set.contains(&e1)); + REQUIRE(event_set.contains(&e2)); + REQUIRE(event_set.contains(&e3)); + REQUIRE_FALSE(event_set.empty()); + + SECTION("Remove a single element more than once") + { + // event_set = {e2, e3} + event_set.remove(&e1); + REQUIRE(event_set.size() == 2); + REQUIRE_FALSE(event_set.contains(&e1)); + REQUIRE(event_set.contains(&e2)); + REQUIRE(event_set.contains(&e3)); + REQUIRE_FALSE(event_set.empty()); + } + + SECTION("Remove more than one element") + { + // event_set = {e3} + event_set.remove(&e2); + + REQUIRE(event_set.size() == 1); + REQUIRE_FALSE(event_set.contains(&e1)); + REQUIRE_FALSE(event_set.contains(&e2)); + REQUIRE(event_set.contains(&e3)); + REQUIRE_FALSE(event_set.empty()); + + // event_set = {} + event_set.remove(&e3); + + REQUIRE(event_set.size() == 0); + REQUIRE_FALSE(event_set.contains(&e1)); + REQUIRE_FALSE(event_set.contains(&e2)); + REQUIRE_FALSE(event_set.contains(&e3)); + REQUIRE(event_set.empty()); + } + } + + SECTION("Remove an element absent from the set") + { + REQUIRE_FALSE(event_set.contains(&e4)); + + // event_set = {e1, e2, e3} + event_set.remove(&e4); + REQUIRE(event_set.size() == 3); + REQUIRE(event_set.contains(&e1)); + REQUIRE(event_set.contains(&e2)); + REQUIRE(event_set.contains(&e3)); + + // Ensure e4 isn't somehow added + REQUIRE_FALSE(event_set.contains(&e4)); + REQUIRE_FALSE(event_set.empty()); + } +} + +TEST_CASE("simgrid::mc::udpor::EventSet: Set Equality") {} + +TEST_CASE("simgrid::mc::udpor::EventSet: Unions and Set Difference") +{ + UnfoldingEvent e1, e2, e3, e4; + + EventSet A{&e1, &e2, &e3}, B{&e2, &e3, &e4}, C{&e2, &e3, &e4}; + + SECTION("Self-union (A union A)") {} +} \ No newline at end of file diff --git a/src/mc/explo/udpor/UnfoldingEvent.hpp b/src/mc/explo/udpor/UnfoldingEvent.hpp index 812f02004c..d7a03e17a5 100644 --- a/src/mc/explo/udpor/UnfoldingEvent.hpp +++ b/src/mc/explo/udpor/UnfoldingEvent.hpp @@ -17,7 +17,8 @@ namespace simgrid::mc::udpor { class UnfoldingEvent { public: - UnfoldingEvent(std::shared_ptr transition, EventSet immediate_causes, unsigned long event_id = 0); + UnfoldingEvent(std::shared_ptr transition = std::make_unique(), + EventSet immediate_causes = EventSet(), unsigned long event_id = 0); UnfoldingEvent(const UnfoldingEvent&) = default; UnfoldingEvent& operator=(UnfoldingEvent const&) = default; diff --git a/src/mc/explo/udpor/UnfoldingEvent_test.cpp b/src/mc/explo/udpor/UnfoldingEvent_test.cpp new file mode 100644 index 0000000000..1623fd3eab --- /dev/null +++ b/src/mc/explo/udpor/UnfoldingEvent_test.cpp @@ -0,0 +1,9 @@ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/3rd-party/catch.hpp" +#include "src/mc/explo/udpor/UnfoldingEvent.hpp" + +using namespace simgrid::mc::udpor; diff --git a/src/mc/explo/udpor/Unfolding_test.cpp b/src/mc/explo/udpor/Unfolding_test.cpp new file mode 100644 index 0000000000..3f004e4500 --- /dev/null +++ b/src/mc/explo/udpor/Unfolding_test.cpp @@ -0,0 +1,16 @@ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/3rd-party/catch.hpp" +#include "src/mc/explo/udpor/Unfolding.hpp" + +TEST_CASE("simgrid::mc::udpor::Unfolding: Creating an unfolding") +{ + using namespace simgrid::mc::udpor; + + Unfolding unfolding; + CHECK(unfolding.empty()); + REQUIRE(unfolding.size() == 0); +} \ No newline at end of file diff --git a/tools/cmake/Tests.cmake b/tools/cmake/Tests.cmake index a7182fec9d..e6d38d8cfd 100644 --- a/tools/cmake/Tests.cmake +++ b/tools/cmake/Tests.cmake @@ -128,7 +128,11 @@ set(UNIT_TESTS src/xbt/unit-tests_main.cpp src/xbt/xbt_str_test.cpp src/kernel/lmm/maxmin_test.cpp) if (SIMGRID_HAVE_MC) - set(UNIT_TESTS ${UNIT_TESTS} src/mc/sosp/Snapshot_test.cpp src/mc/sosp/PageStore_test.cpp) + set(UNIT_TESTS ${UNIT_TESTS} src/mc/sosp/Snapshot_test.cpp + src/mc/sosp/PageStore_test.cpp + src/mc/explo/udpor/EventSet_test.cpp + src/mc/explo/udpor/Unfolding_test.cpp + src/mc/explo/udpor/UnfoldingEvent_test.cpp) else() set(EXTRA_DIST ${EXTRA_DIST} src/mc/sosp/Snapshot_test.cpp src/mc/sosp/PageStore_test.cpp) endif() -- 2.20.1