11#pragma once
22
3+ #include < algorithm>
34#include < atomic>
5+ #include < cctype>
46#include < cstdint>
57#include < cstdlib>
8+ #include < filesystem>
69#include < memory>
10+ #include < sstream>
711#include < string>
12+ #include < string_view>
13+ #include < system_error>
814#include < typeinfo>
915#ifdef __GNUG__
1016# include < cxxabi.h>
1723# pragma warning(disable : 4459)
1824#endif
1925
26+ #include < gtest/gtest.h>
27+
28+ #include < libenvpp/detail/environment.hpp>
2029#include < nlohmann/json.hpp>
2130
2231// / @brief JSON namespace used for settings and config parsing.
@@ -55,7 +64,7 @@ class DestructorFailureFlag {
5564
5665enum class GTestParamIndex : uint8_t { kTaskGetter , kNameTest , kTestParams };
5766
58- std::string GetAbsoluteTaskPath (const std::string & id_path, const std::string & relative_path);
67+ std::string GetAbsoluteTaskPath (const std::string& id_path, const std::string& relative_path);
5968int GetNumThreads ();
6069int GetNumProc ();
6170double GetTaskMaxTime ();
@@ -66,13 +75,13 @@ std::string GetNamespace() {
6675 std::string name = typeid (T).name ();
6776#ifdef __GNUC__
6877 int status = 0 ;
69- std::unique_ptr<char , void (*)(void *)> demangled{abi::__cxa_demangle (name.c_str (), nullptr , nullptr , &status),
70- std::free};
78+ std::unique_ptr<char , void (*)(void *)> demangled{abi::__cxa_demangle (name.c_str (), nullptr , nullptr , &status),
79+ std::free};
7180 name = (status == 0 ) ? demangled.get () : name;
7281#endif
7382#ifdef _MSC_VER
7483 const std::string prefixes[] = {" class " , " struct " , " enum " , " union " };
75- for (const auto & prefix : prefixes) {
84+ for (const auto & prefix : prefixes) {
7685 if (name.starts_with (prefix)) {
7786 name = name.substr (prefix.size ());
7887 break ;
@@ -90,4 +99,57 @@ inline std::shared_ptr<nlohmann::json> InitJSONPtr() {
9099
91100bool IsUnderMpirun ();
92101
102+ namespace test {
103+
104+ [[nodiscard]] inline std::string SanitizeToken (std::string_view token_sv) {
105+ std::string token{token_sv};
106+ auto is_allowed = [](char c) {
107+ return std::isalnum (static_cast <unsigned char >(c)) || c == ' _' || c == ' -' || c == ' .' ;
108+ };
109+ std::ranges::replace (token, ' ' , ' _' );
110+ for (char & ch : token) {
111+ if (!is_allowed (ch)) {
112+ ch = ' _' ;
113+ }
114+ }
115+ return token;
116+ }
117+
118+ class ScopedPerTestEnv {
119+ public:
120+ explicit ScopedPerTestEnv (const std::string& token)
121+ : set_uid_(" PPC_TEST_UID" , token), set_tmp_(" PPC_TEST_TMPDIR" , CreateTmpDir(token)) {}
122+
123+ private:
124+ static std::string CreateTmpDir (const std::string& token) {
125+ namespace fs = std::filesystem;
126+ const fs::path tmp = fs::temp_directory_path () / (std::string (" ppc_test_" ) + token);
127+ std::error_code ec;
128+ fs::create_directories (tmp, ec);
129+ (void )ec;
130+ return tmp.string ();
131+ }
132+
133+ env::detail::set_scoped_environment_variable set_uid_;
134+ env::detail::set_scoped_environment_variable set_tmp_;
135+ };
136+
137+ [[nodiscard]] inline std::string MakeCurrentGTestToken (std::string_view fallback_name) {
138+ const auto * unit = ::testing::UnitTest::GetInstance ();
139+ const auto * info = (unit != nullptr ) ? unit->current_test_info () : nullptr ;
140+ std::ostringstream os;
141+ if (info != nullptr ) {
142+ os << info->test_suite_name () << " ." << info->name ();
143+ } else {
144+ os << fallback_name;
145+ }
146+ return SanitizeToken (os.str ());
147+ }
148+
149+ inline ScopedPerTestEnv MakePerTestEnvForCurrentGTest (std::string_view fallback_name) {
150+ return ScopedPerTestEnv (MakeCurrentGTestToken (fallback_name));
151+ }
152+
153+ } // namespace test
154+
93155} // namespace ppc::util
0 commit comments