diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index aafe420135bd4ab9679233de041a6d71fc125157..e7fdbcaf69e289aefc77edd687a1e1696ddd210e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -157,7 +157,9 @@ add_executable (unit_tests test_WhileProcessor.cpp ) -set(checkpointing_TESTS) + set(checkpointing_TESTS + test_checkpointing_ResumingUtils.cpp + ) if(PUGS_HAS_HDF5) list(APPEND checkpointing_TESTS diff --git a/tests/test_checkpointing_ResumingUtils.cpp b/tests/test_checkpointing_ResumingUtils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..585d7d8a3f6017ee69fae6647c5cb5a00a4280ad --- /dev/null +++ b/tests/test_checkpointing_ResumingUtils.cpp @@ -0,0 +1,77 @@ +#include <catch2/catch_test_macros.hpp> +#include <catch2/matchers/catch_matchers_all.hpp> + +#include <utils/HighFivePugsUtils.hpp> +#include <utils/Messenger.hpp> +#include <utils/checkpointing/ResumingUtils.hpp> + +#include <filesystem> + +// clazy:excludeall=non-pod-global-static + +TEST_CASE("ResumingUtils", "[utils/checkpointing]") +{ +#ifdef PUGS_HAS_HDF5 + + std::string tmp_dirname; + { + { + if (parallel::rank() == 0) { + tmp_dirname = [&]() -> std::string { + std::string temp_filename = std::filesystem::temp_directory_path() / "pugs_checkpointing_XXXXXX"; + return std::string{mkdtemp(&temp_filename[0])}; + }(); + } + parallel::broadcast(tmp_dirname, 0); + } + std::filesystem::path path = tmp_dirname; + const std::string filename = path / "checkpoint.h5"; + + const std::string data_file0 = R"(Un tiens vaut mieux que deux tu l'auras, +Un tiens vaut mieux que deux tu l'auras,...)"; + const std::string data_file1 = R"(All work and no play makes Jack a dull boy, +All work and no play makes Jack a dull boy,...)"; + const std::string data_file2 = R"(solo trabajo y nada de juego hacen de Jack un chico aburrido, +solo trabajo y nada de juego hacen de Jack un chico aburrido,...)"; + + HighFive::FileAccessProps fapl; + fapl.add(HighFive::MPIOFileAccess{MPI_COMM_WORLD, MPI_INFO_NULL}); + fapl.add(HighFive::MPIOCollectiveMetadata{}); + HighFive::File file = HighFive::File(filename, HighFive::File::Truncate, fapl); + + file.createGroup("/checkpoint_0").createAttribute("data.pgs", data_file0); + file.createGroup("/checkpoint_1").createAttribute("data.pgs", data_file1); + file.createGroup("/checkpoint_2").createAttribute("data.pgs", data_file2); + file.createHardLink("last_checkpoint", file.getGroup("/checkpoint_2")); + + file.createHardLink("resuming_checkpoint", file.getGroup("/checkpoint_0")); + file.flush(); + parallel::barrier(); + REQUIRE(resumingDatafile(filename) == data_file0); + parallel::barrier(); + + file.unlink("resuming_checkpoint"); + file.createHardLink("resuming_checkpoint", file.getGroup("/checkpoint_1")); + file.flush(); + parallel::barrier(); + REQUIRE(resumingDatafile(filename) == data_file1); + parallel::barrier(); + + file.unlink("resuming_checkpoint"); + file.createHardLink("resuming_checkpoint", file.getGroup("/checkpoint_2")); + file.flush(); + parallel::barrier(); + REQUIRE(resumingDatafile(filename) == data_file2); + } + + parallel::barrier(); + if (parallel::rank() == 0) { + std::filesystem::remove_all(std::filesystem::path{tmp_dirname}); + } + +#else // PUGS_HAS_HDF5 + + REQUIRE_THROWS_WITH(resumingDatafile("foo.h5"), "error: Resuming requires HDF5"); + +#endif // PUGS_HAS_HDF5 +}