[libcxx-commits] [PATCH] D98703: [libcxx] [test] Readd randomness to temporary directory names

Martin Storsjö via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Tue Mar 16 06:07:29 PDT 2021


mstorsjo created this revision.
mstorsjo requested review of this revision.
Herald added a project: libc++.
Herald added a reviewer: libc++.

Prior to e0d01294bc124211a8ffb55e69162eb34a242680 <https://reviews.llvm.org/rGe0d01294bc124211a8ffb55e69162eb34a242680>, all tests used a
random directory name, but now it is deterministic, based on the
test name. As some multiple test subdirectories contain tests with
the same file names (e.g. there are 3 tests under
std/input.output/filesystem named "copy_assign.pass.cpp"), there's
an actual race condition here, which does seem to manifest itself
as occasional random breakage in CI runners that run lots of tests
in parallel.

Bring back some code from before e0d01294bc124211a8ffb55e69162eb34a242680 <https://reviews.llvm.org/rGe0d01294bc124211a8ffb55e69162eb34a242680>,
and conditionally use it if randomness is available, to reduce the
risk of hitting the race condition.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D98703

Files:
  libcxx/test/support/filesystem_test_helper.h


Index: libcxx/test/support/filesystem_test_helper.h
===================================================================
--- libcxx/test/support/filesystem_test_helper.h
+++ libcxx/test/support/filesystem_test_helper.h
@@ -18,6 +18,7 @@
 #include <string>
 #include <chrono>
 #include <vector>
+#include <random>
 
 #include "make_string.h"
 #include "test_macros.h"
@@ -30,6 +31,27 @@
 # include <sys/un.h>
 #endif
 
+#if !defined(_LIBCPP_HAS_NO_RANDOM_DEVICE)
+namespace random_utils {
+inline char to_hex(int ch) {
+  return ch < 10 ? static_cast<char>('0' + ch)
+                 : static_cast<char>('a' + (ch - 10));
+}
+
+inline char random_hex_char() {
+  static std::mt19937 rd{std::random_device{}()};
+  static std::uniform_int_distribution<int> mrand{0, 15};
+  return to_hex(mrand(rd));
+}
+std::string random_string(int n) {
+  std::string ret;
+  for (int i = 0; i < n; i++)
+    ret.push_back(random_hex_char());
+  return ret;
+}
+} // end namespace random_utils
+#endif
+
 namespace utils {
 #ifdef _WIN32
     inline int mkdir(const char* path, int mode) { (void)mode; return ::_mkdir(path); }
@@ -292,14 +314,16 @@
 
 private:
     // This could potentially introduce a filesystem race if multiple
-    // scoped_test_envs were created concurrently in the same test (hence
-    // sharing the same cwd). However, it is fairly unlikely to happen as
-    // we generally don't use scoped_test_env from multiple threads, so
-    // this is deemed acceptable.
+    // scoped_test_envs were created concurrently in the same test or if
+    // multiple tests with the same file name run concurrently. If a random
+    // device is available, append a short random string.
     static inline fs::path available_cwd_path() {
         fs::path const cwd = utils::getcwd();
         fs::path const tmp = fs::temp_directory_path();
         std::string base = cwd.filename().string();
+#if !defined(_LIBCPP_HAS_NO_RANDOM_DEVICE)
+        base += "-" + random_utils::random_string(4);
+#endif
         int i = 0;
         fs::path p = tmp / (base + "-static_env." + std::to_string(i));
         while (utils::exists(p.string())) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D98703.330960.patch
Type: text/x-patch
Size: 2137 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20210316/482ebb6a/attachment.bin>


More information about the libcxx-commits mailing list