From d9c7e66255c0f2c0ac4dd692c6bb4c1c2b1509a5 Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Tue, 15 Oct 2024 00:10:51 +0200
Subject: [PATCH] Add tests for ResumingUtils checkpointing

---
 tests/CMakeLists.txt                       |  4 +-
 tests/test_checkpointing_ResumingUtils.cpp | 77 ++++++++++++++++++++++
 2 files changed, 80 insertions(+), 1 deletion(-)
 create mode 100644 tests/test_checkpointing_ResumingUtils.cpp

diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index aafe42013..e7fdbcaf6 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 000000000..585d7d8a3
--- /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
+}
-- 
GitLab