From b037330f65f23d8f62e3f89fc73a2936a05390ba Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Del=20Pino?= <stephane.delpino44@gmail.com>
Date: Mon, 9 Nov 2020 19:09:28 +0100
Subject: [PATCH] Fix OMP_PLACES default value and add a few tests for
 PugsUtils

---
 src/utils/PugsUtils.cpp  |   4 +-
 src/utils/PugsUtils.hpp  |   2 +
 tests/CMakeLists.txt     |   3 +-
 tests/test_PugsUtils.cpp | 110 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 117 insertions(+), 2 deletions(-)
 create mode 100644 tests/test_PugsUtils.cpp

diff --git a/src/utils/PugsUtils.cpp b/src/utils/PugsUtils.cpp
index 6186f6fdc..ad9e12e7e 100644
--- a/src/utils/PugsUtils.cpp
+++ b/src/utils/PugsUtils.cpp
@@ -30,11 +30,13 @@ pugsVersion()
   os << "HEAD: " << rang::style::bold << RevisionInfo::gitHead() << rang::style::reset << '\n';
   os << "hash: " << rang::style::bold << RevisionInfo::gitHash() << rang::style::reset << "  (";
 
+  // LCOV_EXCL_START Cannot cover both situations at same time
   if (RevisionInfo::gitIsClean()) {
     os << rang::fgB::green << "clean" << rang::fg::reset;
   } else {
     os << rang::fgB::red << "dirty" << rang::fg::reset;
   }
+  // LCOV_EXCL_STOP
   os << ")\n";
   os << "-------------------------------------------------------";
 
@@ -63,7 +65,7 @@ setDefaultOMPEnvironment()
 {
   if constexpr (std::string_view{PUGS_BUILD_KOKKOS_DEVICES} == std::string_view{"OpenMP"}) {
     setenv("OMP_PROC_BIND", "spread", 0);
-    setenv("OMP_PLACES", "treads", 0);
+    setenv("OMP_PLACES", "threads", 0);
   }
 }
 
diff --git a/src/utils/PugsUtils.hpp b/src/utils/PugsUtils.hpp
index 54bcc6d05..7429a75b3 100644
--- a/src/utils/PugsUtils.hpp
+++ b/src/utils/PugsUtils.hpp
@@ -21,6 +21,8 @@ parallel_reduce(size_t size, const ArrayType& array, ReturnType& value, const st
   Kokkos::parallel_reduce(label, size, array, value);
 }
 
+void setDefaultOMPEnvironment();
+
 std::string pugsBuildInfo();
 
 std::string pugsVersion();
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 746f5d7b1..0502c414a 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -80,8 +80,9 @@ add_executable (unit_tests
   test_NameProcessor.cpp
   test_OStreamProcessor.cpp
   test_ParseError.cpp
-  test_PugsFunctionAdapter.cpp
   test_PugsAssert.cpp
+  test_PugsFunctionAdapter.cpp
+  test_PugsUtils.cpp
   test_RevisionInfo.cpp
   test_SparseMatrixDescriptor.cpp
   test_SymbolTable.cpp
diff --git a/tests/test_PugsUtils.cpp b/tests/test_PugsUtils.cpp
new file mode 100644
index 000000000..b966ae8f0
--- /dev/null
+++ b/tests/test_PugsUtils.cpp
@@ -0,0 +1,110 @@
+#include <catch2/catch.hpp>
+
+#include <utils/BuildInfo.hpp>
+#include <utils/PugsUtils.hpp>
+#include <utils/RevisionInfo.hpp>
+#include <utils/pugs_build_info.hpp>
+
+#include <rang.hpp>
+
+#include <string>
+
+// clazy:excludeall=non-pod-global-static
+
+TEST_CASE("PugsUtils", "[utils]")
+{
+  SECTION("checking infos")
+  {
+    const std::string pugs_version = [] {
+      std::stringstream os;
+
+      os << "pugs version: " << rang::style::bold << RevisionInfo::version() << rang::style::reset << '\n';
+
+      os << "-------------------- " << rang::fg::green << "git info" << rang::fg::reset << " -------------------------"
+         << '\n';
+      os << "tag:  " << rang::style::bold << RevisionInfo::gitTag() << rang::style::reset << '\n';
+      os << "HEAD: " << rang::style::bold << RevisionInfo::gitHead() << rang::style::reset << '\n';
+      os << "hash: " << rang::style::bold << RevisionInfo::gitHash() << rang::style::reset << "  (";
+
+      if (RevisionInfo::gitIsClean()) {
+        os << rang::fgB::green << "clean" << rang::fg::reset;
+      } else {
+        os << rang::fgB::red << "dirty" << rang::fg::reset;
+      }
+      os << ")\n";
+      os << "-------------------------------------------------------";
+
+      return os.str();
+    }();
+
+    REQUIRE(pugsVersion() == pugs_version);
+
+    const std::string build_info = [] {
+      std::ostringstream os;
+
+      os << "-------------------- " << rang::fg::green << "build info" << rang::fg::reset << " -----------------------"
+         << '\n';
+      os << "type:     " << rang::style::bold << BuildInfo::type() << rang::style::reset << '\n';
+      os << "compiler: " << rang::style::bold << BuildInfo::compiler() << rang::style::reset << '\n';
+      os << "kokkos:   " << rang::style::bold << BuildInfo::kokkosDevices() << rang::style::reset << '\n';
+      os << "MPI:      " << rang::style::bold << BuildInfo::mpiLibrary() << rang::style::reset << '\n';
+      os << "PETSc:    " << rang::style::bold << BuildInfo::petscLibrary() << rang::style::reset << '\n';
+      os << "-------------------------------------------------------";
+
+      return os.str();
+    }();
+
+    REQUIRE(pugsBuildInfo() == build_info);
+  }
+
+  SECTION("checking OMP environment setting")
+  {
+    if constexpr (std::string_view{PUGS_BUILD_KOKKOS_DEVICES} == std::string_view{"OpenMP"}) {
+      const std::string saved_omp_proc_bind = []() {
+        char* value = getenv("OMP_PROC_BIND");
+        if (value != nullptr) {
+          return std::string{value};
+        } else {
+          return std::string{};
+        }
+      }();
+
+      const std::string saved_omp_places = []() {
+        char* value = getenv("OMP_PLACES");
+        if (value != nullptr) {
+          return std::string{value};
+        } else {
+          return std::string{};
+        }
+      }();
+
+      unsetenv("OMP_PROC_BIND");
+      unsetenv("OMP_PLACES");
+
+      setDefaultOMPEnvironment();
+      REQUIRE(std::string{getenv("OMP_PROC_BIND")} == std::string{"spread"});
+      REQUIRE(std::string{getenv("OMP_PLACES")} == std::string{"threads"});
+
+      unsetenv("OMP_PROC_BIND");
+      unsetenv("OMP_PLACES");
+
+      setenv("OMP_PROC_BIND", "foo", 1);
+      setenv("OMP_PLACES", "bar", 1);
+
+      setDefaultOMPEnvironment();
+      REQUIRE(std::string{getenv("OMP_PROC_BIND")} == std::string{"foo"});
+      REQUIRE(std::string{getenv("OMP_PLACES")} == std::string{"bar"});
+
+      unsetenv("OMP_PROC_BIND");
+      unsetenv("OMP_PLACES");
+
+      if (saved_omp_proc_bind.size() != 0) {
+        setenv("OMP_PROC_BIND", saved_omp_proc_bind.c_str(), 1);
+      }
+
+      if (saved_omp_places.size() != 0) {
+        setenv("OMP_PLACES", saved_omp_places.c_str(), 1);
+      }
+    }
+  }
+}
-- 
GitLab