[libcxx-commits] [libcxx] 645ad5b - [libc++] Generate symlinks in static_test_env on the fly

Sergej Jaskiewicz via libcxx-commits libcxx-commits at lists.llvm.org
Tue May 5 15:13:37 PDT 2020


Author: Sergej Jaskiewicz
Date: 2020-05-06T01:13:18+03:00
New Revision: 645ad5badbabdeca31de5c98ea8135c5a6e7d710

URL: https://github.com/llvm/llvm-project/commit/645ad5badbabdeca31de5c98ea8135c5a6e7d710
DIFF: https://github.com/llvm/llvm-project/commit/645ad5badbabdeca31de5c98ea8135c5a6e7d710.diff

LOG: [libc++] Generate symlinks in static_test_env on the fly

Instead of storing static_test_env (with all the symlinks) in the repo,
we create it on the fly to be cross-toolchain-friendly. The primary
use case for this are Windows-hosted cross-toolchains. Windows doesn't
really have a concept of symlinks. So, when the monorepo is cloned,
those symlinks turn to ordinary text files. Previously, if we
cross-compiled libc++ for some symlink-friendly system (e. g. Linux) and
ran tests on the target system, some tests would fail. This patch makes
them pass.

Differential Revision: https://reviews.llvm.org/D78200

Added: 
    

Modified: 
    libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp
    libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/file_size.pass.cpp
    libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/hard_link_count.pass.cpp
    libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/last_write_time.pass.cpp
    libcxx/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/ctor.pass.cpp
    libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp
    libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp
    libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.canonical/canonical.pass.cpp
    libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.equivalent/equivalent.pass.cpp
    libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.file_size/file_size.pass.cpp
    libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_directory/is_directory.pass.cpp
    libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_empty/is_empty.pass.cpp
    libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_symlink/is_symlink.pass.cpp
    libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp
    libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.relative/relative.pass.cpp
    libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.space/space.pass.cpp
    libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.status/status.pass.cpp
    libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.symlink_status/symlink_status.pass.cpp
    libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.weakly_canonical/weakly_canonical.pass.cpp
    libcxx/test/support/filesystem_test_helper.h

Removed: 
    libcxx/test/std/input.output/filesystems/Inputs/static_test_env/bad_symlink
    libcxx/test/std/input.output/filesystems/Inputs/static_test_env/dir1/dir2/symlink_to_dir3
    libcxx/test/std/input.output/filesystems/Inputs/static_test_env/symlink_to_dir
    libcxx/test/std/input.output/filesystems/Inputs/static_test_env/symlink_to_empty_file


################################################################################
diff  --git a/libcxx/test/std/input.output/filesystems/Inputs/static_test_env/bad_symlink b/libcxx/test/std/input.output/filesystems/Inputs/static_test_env/bad_symlink
deleted file mode 120000
index 76646beed5ed..000000000000
--- a/libcxx/test/std/input.output/filesystems/Inputs/static_test_env/bad_symlink
+++ /dev/null
@@ -1 +0,0 @@
-dne
\ No newline at end of file

diff  --git a/libcxx/test/std/input.output/filesystems/Inputs/static_test_env/dir1/dir2/symlink_to_dir3 b/libcxx/test/std/input.output/filesystems/Inputs/static_test_env/dir1/dir2/symlink_to_dir3
deleted file mode 120000
index 397913952621..000000000000
--- a/libcxx/test/std/input.output/filesystems/Inputs/static_test_env/dir1/dir2/symlink_to_dir3
+++ /dev/null
@@ -1 +0,0 @@
-dir3
\ No newline at end of file

diff  --git a/libcxx/test/std/input.output/filesystems/Inputs/static_test_env/symlink_to_dir b/libcxx/test/std/input.output/filesystems/Inputs/static_test_env/symlink_to_dir
deleted file mode 120000
index df490f837a85..000000000000
--- a/libcxx/test/std/input.output/filesystems/Inputs/static_test_env/symlink_to_dir
+++ /dev/null
@@ -1 +0,0 @@
-dir1
\ No newline at end of file

diff  --git a/libcxx/test/std/input.output/filesystems/Inputs/static_test_env/symlink_to_empty_file b/libcxx/test/std/input.output/filesystems/Inputs/static_test_env/symlink_to_empty_file
deleted file mode 120000
index b79b689fc85a..000000000000
--- a/libcxx/test/std/input.output/filesystems/Inputs/static_test_env/symlink_to_empty_file
+++ /dev/null
@@ -1 +0,0 @@
-empty_file
\ No newline at end of file

diff  --git a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp
index 850be12e839c..6731bd80eac7 100644
--- a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp
@@ -121,6 +121,8 @@ TEST_CASE(path_ctor_calls_refresh) {
 TEST_CASE(path_ctor_dne) {
   using namespace fs;
 
+  static_test_env static_env;
+
   {
     std::error_code ec = GetTestEC();
     directory_entry ent(StaticEnv::DNE, ec);

diff  --git a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/file_size.pass.cpp b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/file_size.pass.cpp
index 8ff1b46b3b99..080222d89828 100644
--- a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/file_size.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/file_size.pass.cpp
@@ -112,6 +112,7 @@ TEST_CASE(not_regular_file) {
 TEST_CASE(error_reporting) {
   using namespace fs;
 
+  static_test_env static_env;
   scoped_test_env env;
 
   const path dir = env.create_dir("dir");

diff  --git a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/hard_link_count.pass.cpp b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/hard_link_count.pass.cpp
index d9958a6c5f03..7f3dcbd62560 100644
--- a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/hard_link_count.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/hard_link_count.pass.cpp
@@ -110,6 +110,7 @@ TEST_CASE(not_regular_file) {
 TEST_CASE(error_reporting) {
   using namespace fs;
 
+  static_test_env static_env;
   scoped_test_env env;
 
   const path dir = env.create_dir("dir");

diff  --git a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/last_write_time.pass.cpp b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/last_write_time.pass.cpp
index de6c36c218f2..4452358b3185 100644
--- a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/last_write_time.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/last_write_time.pass.cpp
@@ -84,6 +84,7 @@ TEST_CASE(basic) {
 TEST_CASE(error_reporting) {
   using namespace fs;
 
+  static_test_env static_env;
   scoped_test_env env;
 
   const path dir = env.create_dir("dir");

diff  --git a/libcxx/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/ctor.pass.cpp b/libcxx/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/ctor.pass.cpp
index a06c4a64c7ff..287ea5cf20b8 100644
--- a/libcxx/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/ctor.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/ctor.pass.cpp
@@ -60,6 +60,7 @@ TEST_CASE(test_constructor_signatures)
 
 TEST_CASE(test_construction_from_bad_path)
 {
+    static_test_env static_env;
     std::error_code ec;
     directory_options opts = directory_options::none;
     const directory_iterator endIt;
@@ -169,6 +170,7 @@ TEST_CASE(test_open_on_empty_directory_equals_end)
 
 TEST_CASE(test_open_on_directory_succeeds)
 {
+    static_test_env static_env;
     const path testDir = StaticEnv::Dir;
     std::set<path> dir_contents(std::begin(StaticEnv::DirIterationList),
                                 std::end(  StaticEnv::DirIterationList));
@@ -190,6 +192,7 @@ TEST_CASE(test_open_on_directory_succeeds)
 
 TEST_CASE(test_open_on_file_fails)
 {
+    static_test_env static_env;
     const path testFile = StaticEnv::File;
     const directory_iterator endIt{};
     {
@@ -225,6 +228,7 @@ TEST_CASE(test_open_on_dot_dir)
 
 TEST_CASE(test_open_on_symlink)
 {
+    static_test_env static_env;
     const path symlinkToDir = StaticEnv::SymlinkToDir;
     std::set<path> dir_contents;
     for (path const& p : StaticEnv::DirIterationList) {

diff  --git a/libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp b/libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp
index 1c7650543396..dc3046cde10e 100644
--- a/libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp
@@ -43,6 +43,7 @@ TEST_CASE(test_increment_signatures)
 
 TEST_CASE(test_prefix_increment)
 {
+    static_test_env static_env;
     const path testDir = StaticEnv::Dir;
     const std::set<path> dir_contents(std::begin(StaticEnv::RecDirIterationList),
                                       std::end(  StaticEnv::RecDirIterationList));
@@ -66,6 +67,7 @@ TEST_CASE(test_prefix_increment)
 
 TEST_CASE(test_postfix_increment)
 {
+    static_test_env static_env;
     const path testDir = StaticEnv::Dir;
     const std::set<path> dir_contents(std::begin(StaticEnv::RecDirIterationList),
                                       std::end(  StaticEnv::RecDirIterationList));
@@ -89,6 +91,7 @@ TEST_CASE(test_postfix_increment)
 
 TEST_CASE(test_increment_method)
 {
+    static_test_env static_env;
     const path testDir = StaticEnv::Dir;
     const std::set<path> dir_contents(std::begin(StaticEnv::RecDirIterationList),
                                       std::end(  StaticEnv::RecDirIterationList));
@@ -113,6 +116,7 @@ TEST_CASE(test_increment_method)
 
 TEST_CASE(test_follow_symlinks)
 {
+    static_test_env static_env;
     const path testDir = StaticEnv::Dir;
     auto const& IterList = StaticEnv::RecDirFollowSymlinksIterationList;
 

diff  --git a/libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp b/libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp
index 24eaf84c2931..e08d7c0ae7a5 100644
--- a/libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.nonmembers/begin_end.pass.cpp
@@ -43,6 +43,7 @@ TEST_CASE(test_function_signatures)
 
 TEST_CASE(test_ranged_for_loop)
 {
+    static_test_env static_env;
     const path testDir = StaticEnv::Dir;
     std::set<path> dir_contents(std::begin(StaticEnv::RecDirIterationList),
                                 std::end(  StaticEnv::RecDirIterationList));

diff  --git a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.canonical/canonical.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.canonical/canonical.pass.cpp
index de2fa54aca48..7644d866cead 100644
--- a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.canonical/canonical.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.canonical/canonical.pass.cpp
@@ -47,6 +47,7 @@ TEST_CASE(signature_test)
 // Each scope tests one of the cases.
 TEST_CASE(test_canonical)
 {
+    static_test_env static_env;
     CWDGuard guard;
     // has_root_name() && has_root_directory()
     const path Root = StaticEnv::Root;

diff  --git a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.equivalent/equivalent.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.equivalent/equivalent.pass.cpp
index 71fce4726661..c2b53ca78657 100644
--- a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.equivalent/equivalent.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.equivalent/equivalent.pass.cpp
@@ -36,6 +36,7 @@ TEST_CASE(signature_test) {
 }
 
 TEST_CASE(equivalent_test) {
+  static_test_env static_env;
   struct TestCase {
     path lhs;
     path rhs;

diff  --git a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.file_size/file_size.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.file_size/file_size.pass.cpp
index 6f27a4cb5712..df9e6b12484b 100644
--- a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.file_size/file_size.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.file_size/file_size.pass.cpp
@@ -55,6 +55,7 @@ TEST_CASE(file_size_non_empty)
 
 TEST_CASE(symlink_test_case)
 {
+    static_test_env static_env;
     const path p = StaticEnv::File;
     const path p2 = StaticEnv::SymlinkToFile;
     TEST_CHECK(file_size(p) == file_size(p2));
@@ -62,6 +63,7 @@ TEST_CASE(symlink_test_case)
 
 TEST_CASE(file_size_error_cases)
 {
+  static_test_env static_env;
   struct {
     path p;
     std::errc expected_err;

diff  --git a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_directory/is_directory.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_directory/is_directory.pass.cpp
index 35dd5d40f7b0..05a313ae6c47 100644
--- a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_directory/is_directory.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_directory/is_directory.pass.cpp
@@ -69,6 +69,7 @@ TEST_CASE(test_exist_not_found)
 
 TEST_CASE(static_env_test)
 {
+    static_test_env static_env;
     TEST_CHECK(is_directory(StaticEnv::Dir));
     TEST_CHECK(is_directory(StaticEnv::SymlinkToDir));
     TEST_CHECK(!is_directory(StaticEnv::File));

diff  --git a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_empty/is_empty.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_empty/is_empty.pass.cpp
index e3393240aa40..c92c66cc0ec5 100644
--- a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_empty/is_empty.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_empty/is_empty.pass.cpp
@@ -45,6 +45,7 @@ TEST_CASE(test_exist_not_found)
 
 TEST_CASE(test_is_empty_directory)
 {
+    static_test_env static_env;
     TEST_CHECK(!is_empty(StaticEnv::Dir));
     TEST_CHECK(!is_empty(StaticEnv::SymlinkToDir));
 }

diff  --git a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_symlink/is_symlink.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_symlink/is_symlink.pass.cpp
index 75ab6059f4d8..603a1da7a68d 100644
--- a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_symlink/is_symlink.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_symlink/is_symlink.pass.cpp
@@ -63,6 +63,7 @@ TEST_CASE(is_symlink_status_test)
 
 TEST_CASE(static_env_test)
 {
+    static_test_env static_env;
     struct TestCase {
         path p;
         bool expect;

diff  --git a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp
index 3ef4c53303ad..4335c7a25e52 100644
--- a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp
@@ -350,6 +350,7 @@ TEST_CASE(signature_test)
 
 TEST_CASE(read_last_write_time_static_env_test)
 {
+    static_test_env static_env;
     using C = file_time_type::clock;
     file_time_type min = file_time_type::min();
     {

diff  --git a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.relative/relative.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.relative/relative.pass.cpp
index 2a8d8296c861..21529d3aab1d 100644
--- a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.relative/relative.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.relative/relative.pass.cpp
@@ -54,18 +54,21 @@ TEST_CASE(test_signature_3) {
 }
 
 TEST_CASE(test_signature_4) {
+  static_test_env static_env;
   fs::path p(StaticEnv::SymlinkToDir);
   const fs::path output = fs::weakly_canonical(p);
   TEST_CHECK(output == std::string(StaticEnv::Dir));
 }
 
 TEST_CASE(test_signature_5) {
+  static_test_env static_env;
   fs::path p(StaticEnv::SymlinkToDir / "dir2/.");
   const fs::path output = fs::weakly_canonical(p);
   TEST_CHECK(output == std::string(StaticEnv::Dir / "dir2"));
 }
 
 TEST_CASE(test_signature_6) {
+  static_test_env static_env;
   // FIXME? If the trailing separator occurs in a part of the path that exists,
   // it is omitted. Otherwise it is added to the end of the result.
   fs::path p(StaticEnv::SymlinkToDir / "dir2/./");
@@ -74,24 +77,28 @@ TEST_CASE(test_signature_6) {
 }
 
 TEST_CASE(test_signature_7) {
+  static_test_env static_env;
   fs::path p(StaticEnv::SymlinkToDir / "dir2/DNE/./");
   const fs::path output = fs::weakly_canonical(p);
   TEST_CHECK(output == std::string(StaticEnv::Dir / "dir2/DNE/"));
 }
 
 TEST_CASE(test_signature_8) {
+  static_test_env static_env;
   fs::path p(StaticEnv::SymlinkToDir / "dir2");
   const fs::path output = fs::weakly_canonical(p);
   TEST_CHECK(output == std::string(StaticEnv::Dir2));
 }
 
 TEST_CASE(test_signature_9) {
+  static_test_env static_env;
   fs::path p(StaticEnv::SymlinkToDir / "dir2/../dir2/DNE/..");
   const fs::path output = fs::weakly_canonical(p);
   TEST_CHECK(output == std::string(StaticEnv::Dir2 / ""));
 }
 
 TEST_CASE(test_signature_10) {
+  static_test_env static_env;
   fs::path p(StaticEnv::SymlinkToDir / "dir2/dir3/../DNE/DNE2");
   const fs::path output = fs::weakly_canonical(p);
   TEST_CHECK(output == std::string(StaticEnv::Dir2 / "DNE/DNE2"));

diff  --git a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.space/space.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.space/space.pass.cpp
index 4a0936b920db..51b02bb35ad0 100644
--- a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.space/space.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.space/space.pass.cpp
@@ -80,6 +80,8 @@ TEST_CASE(test_error_reporting)
 
 TEST_CASE(basic_space_test)
 {
+    static_test_env static_env;
+
     // All the test cases should reside on the same filesystem and therefore
     // should have the same expected result. Compute this expected result
     // one and check that it looks semi-sane.

diff  --git a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.status/status.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.status/status.pass.cpp
index 60c99ee923d5..dfbd6bd0a87d 100644
--- a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.status/status.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.status/status.pass.cpp
@@ -103,6 +103,7 @@ TEST_CASE(test_status_cannot_resolve)
 
 TEST_CASE(status_file_types_test)
 {
+    static_test_env static_env;
     scoped_test_env env;
     struct TestCase {
       path p;

diff  --git a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.symlink_status/symlink_status.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.symlink_status/symlink_status.pass.cpp
index 350076fcf370..77f870f59dac 100644
--- a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.symlink_status/symlink_status.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.symlink_status/symlink_status.pass.cpp
@@ -110,6 +110,7 @@ TEST_CASE(test_symlink_status_cannot_resolve)
 
 TEST_CASE(symlink_status_file_types_test)
 {
+    static_test_env static_env;
     scoped_test_env env;
     struct TestCase {
       path p;

diff  --git a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.weakly_canonical/weakly_canonical.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.weakly_canonical/weakly_canonical.pass.cpp
index 35d97b8703d5..d10283901417 100644
--- a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.weakly_canonical/weakly_canonical.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.weakly_canonical/weakly_canonical.pass.cpp
@@ -27,6 +27,9 @@
 
 
 int main(int, char**) {
+
+  static_test_env static_env;
+
   // clang-format off
   struct {
     std::string input;

diff  --git a/libcxx/test/support/filesystem_test_helper.h b/libcxx/test/support/filesystem_test_helper.h
index 8553317de76f..86bd4c359507 100644
--- a/libcxx/test/support/filesystem_test_helper.h
+++ b/libcxx/test/support/filesystem_test_helper.h
@@ -3,7 +3,7 @@
 
 #include "filesystem_include.h"
 
-#include <unistd.h> // for ftruncate
+#include <unistd.h> // for ftruncate, symlink, unlink
 
 #include <cassert>
 #include <cstdio> // for printf
@@ -105,6 +105,13 @@ static const fs::path RecDirFollowSymlinksIterationList[] = {
     makePath("dir1/dir2/symlink_to_dir3/file5"),
 };
 
+static const std::pair<fs::path, fs::path> SymlinkList[] = {
+    {"dne",        makePath("bad_symlink")},
+    {"dir1",       makePath("symlink_to_dir")},
+    {"empty_file", makePath("symlink_to_empty_file")},
+    {"dir3",       makePath("dir1/dir2/symlink_to_dir3")}
+};
+
 } // namespace StaticEnv
 
 namespace random_utils {
@@ -121,6 +128,39 @@ inline char random_hex_char() {
 
 } // namespace random_utils
 
+/// A RAII object that prepares the 'static_test_env' directory for usage in
+/// tests.
+///
+/// Namely, it creates some symlinks that tests expect to be present.
+/// We do it here instead of storing them in the repo to be
+/// cross-toolchain-friendly. The primary use case for this are Windows-hosted
+/// cross-toolchains.
+/// Windows doesn't really have a concept of symlinks. So, when the monorepo
+/// is cloned, those symlinks turn to ordinary text files.
+/// If we cross-compiled libc++ for some symlink-friendly system
+/// (e. g. Linux) and ran tests on the target system, some tests would fail.
+/// Instead, we create symlinks here, when a test is already being executed.
+class static_test_env {
+public:
+  static_test_env() {
+    for (const auto *link = std::begin(StaticEnv::SymlinkList);
+         link != std::end(StaticEnv::SymlinkList);
+         ++link) {
+      int ret = ::symlink(link->first.c_str(), link->second.c_str());
+      assert(ret == 0);
+    }
+  }
+
+  ~static_test_env() {
+    for (const auto *link = std::begin(StaticEnv::SymlinkList);
+         link != std::end(StaticEnv::SymlinkList);
+         ++link) {
+      int ret = ::unlink(link->second.c_str());
+      assert(ret == 0);
+    }
+  }
+};
+
 struct scoped_test_env
 {
     scoped_test_env() : test_root(random_path()) {


        


More information about the libcxx-commits mailing list