[libcxx-commits] [libcxx] dab5f56 - [libc++] Fix filesystem tests on platforms that don't have IO

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Thu Jul 13 10:58:44 PDT 2023


Author: Louis Dionne
Date: 2023-07-13T13:58:37-04:00
New Revision: dab5f56eaf99bd1bc96e0ef0d48f31bfff9f4316

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

LOG: [libc++] Fix filesystem tests on platforms that don't have IO

This patch moves a few tests that were still using std::fprintf to
using TEST_REQUIRE instead, which provides a single point to tweak
for platforms that don't implement fprintf. As a fly-by fix, it also
avoids including `time_utils.h` in filesystem_clock.cpp when it is
not required, since that header makes some pretty large assumptions
about the platform it is on.

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

Added: 
    

Modified: 
    libcxx/src/filesystem/filesystem_clock.cpp
    libcxx/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_normal.pass.cpp
    libcxx/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_relative_and_proximate.pass.cpp
    libcxx/test/std/input.output/filesystems/fs.enum/enum.directory_options.pass.cpp
    libcxx/test/std/input.output/filesystems/fs.enum/enum.perm_options.pass.cpp
    libcxx/test/std/input.output/filesystems/fs.enum/enum.perms.pass.cpp
    libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.proximate/proximate.pass.cpp
    libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.weakly_canonical/weakly_canonical.pass.cpp
    libcxx/test/support/concat_macros.h
    libcxx/test/support/test_macros.h

Removed: 
    


################################################################################
diff  --git a/libcxx/src/filesystem/filesystem_clock.cpp b/libcxx/src/filesystem/filesystem_clock.cpp
index 9ea070bf75c3ba..d00cdc6df3437c 100644
--- a/libcxx/src/filesystem/filesystem_clock.cpp
+++ b/libcxx/src/filesystem/filesystem_clock.cpp
@@ -11,7 +11,9 @@
 #include <filesystem>
 #include <time.h>
 
-#include "time_utils.h"
+#if defined(_LIBCPP_WIN32API)
+#  include "time_utils.h"
+#endif
 
 #if defined(_LIBCPP_WIN32API)
 # define WIN32_LEAN_AND_MEAN

diff  --git a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_normal.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_normal.pass.cpp
index bb25daf56ff73d..871a3a89255a1d 100644
--- a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_normal.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_normal.pass.cpp
@@ -16,13 +16,13 @@
 // path lexically_normal() const;
 
 #include "filesystem_include.h"
-#include <cstdio>
 #include <string>
 
 #include "../../path_helper.h"
 #include "count_new.h"
 #include "test_macros.h"
-
+#include "assert_macros.h"
+#include "concat_macros.h"
 
 int main(int, char**) {
   // clang-format off
@@ -127,22 +127,15 @@ int main(int, char**) {
       {"foo/..", "."}
   };
   // clang-format on
-  int ID = 0;
-  bool Failed = false;
   for (auto& TC : TestCases) {
-    ++ID;
     fs::path p(TC.input);
     const fs::path output = p.lexically_normal();
     fs::path expect(TC.expect);
     expect.make_preferred();
-    if (!PathEq(output, expect)) {
-      Failed = true;
-      std::fprintf(stderr, "TEST CASE #%d FAILED:\n"
-                  "  Input: '%s'\n"
-                  "  Expected: '%s'\n"
-                  "  Output: '%s'\n",
-        ID, TC.input.c_str(), expect.string().c_str(), output.string().c_str());
-    }
+
+    TEST_REQUIRE(
+        PathEq(output, expect),
+        TEST_WRITE_CONCATENATED("Input: ", TC.input, "\nExpected: ", expect.string(), "\nOutput: ", output.string()));
   }
-  return Failed;
+  return 0;
 }

diff  --git a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_relative_and_proximate.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_relative_and_proximate.pass.cpp
index 7dae87d8e90184..55901086079dac 100644
--- a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_relative_and_proximate.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_relative_and_proximate.pass.cpp
@@ -17,10 +17,11 @@
 // path lexically_proximate(const path& p) const;
 
 #include "filesystem_include.h"
-#include <cstdio>
 #include <string>
 
 #include "../../path_helper.h"
+#include "assert_macros.h"
+#include "concat_macros.h"
 #include "count_new.h"
 #include "test_macros.h"
 
@@ -58,35 +59,40 @@ int main(int, char**) {
       {"a/b", "c/d", "../../a/b"}
   };
   // clang-format on
-  int ID = 0;
-  bool Failed = false;
   for (auto& TC : TestCases) {
-    ++ID;
     const fs::path p(TC.input);
     const fs::path output = p.lexically_relative(TC.base);
     fs::path expect(TC.expect);
     expect.make_preferred();
-    auto ReportErr = [&](const char* Testing, fs::path const& Output,
-                                              fs::path const& Expected) {
-      Failed = true;
-      std::fprintf(stderr, "TEST CASE #%d FAILED:\n"
-                  "  Testing: %s\n"
-                  "  Input: '%s'\n"
-                  "  Base: '%s'\n"
-                  "  Expected: '%s'\n"
-                  "  Output: '%s'\n",
-        ID, Testing, TC.input.c_str(), TC.base.c_str(),
-        Expected.string().c_str(), Output.string().c_str());
-    };
-    if (!PathEq(output, expect))
-      ReportErr("path::lexically_relative", output, expect);
+
+    // clang-format off
+    TEST_REQUIRE(
+        PathEq(output, expect),
+        TEST_WRITE_CONCATENATED(
+            "path::lexically_relative test case failed",
+            "\nInput: ", TC.input,
+            "\nBase: ", TC.base,
+            "\nExpected: ", expect,
+            "\nOutput: ", output));
+    // clang-format on
+
     const fs::path proximate_output = p.lexically_proximate(TC.base);
     // [path.gen] lexically_proximate
     // Returns: If the value of lexically_relative(base) is not an empty path,
     // return it. Otherwise return *this.
     const fs::path proximate_expect = expect.empty() ? p : expect;
-    if (!PathEq(proximate_output, proximate_expect))
-      ReportErr("path::lexically_proximate", proximate_output, proximate_expect);
+
+    // clang-format off
+    TEST_REQUIRE(
+        PathEq(proximate_output, proximate_expect),
+        TEST_WRITE_CONCATENATED(
+            "path::lexically_proximate test case failed",
+            "\nInput: ", TC.input,
+            "\nBase: ", TC.base,
+            "\nExpected: ", proximate_expect,
+            "\nOutput: ", proximate_output));
+    // clang-format on
   }
-  return Failed;
+
+  return 0;
 }

diff  --git a/libcxx/test/std/input.output/filesystems/fs.enum/enum.directory_options.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.enum/enum.directory_options.pass.cpp
index a9eee7980ace9f..d856d8105cfb3c 100644
--- a/libcxx/test/std/input.output/filesystems/fs.enum/enum.directory_options.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/fs.enum/enum.directory_options.pass.cpp
@@ -15,7 +15,6 @@
 #include "filesystem_include.h"
 #include <type_traits>
 #include <cassert>
-#include <sys/stat.h>
 
 #include "test_macros.h"
 #include "check_bitmask_types.h"

diff  --git a/libcxx/test/std/input.output/filesystems/fs.enum/enum.perm_options.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.enum/enum.perm_options.pass.cpp
index 99d695040bda55..eba4b79571998c 100644
--- a/libcxx/test/std/input.output/filesystems/fs.enum/enum.perm_options.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/fs.enum/enum.perm_options.pass.cpp
@@ -15,7 +15,6 @@
 #include "filesystem_include.h"
 #include <type_traits>
 #include <cassert>
-#include <sys/stat.h>
 
 #include "test_macros.h"
 #include "check_bitmask_types.h"

diff  --git a/libcxx/test/std/input.output/filesystems/fs.enum/enum.perms.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.enum/enum.perms.pass.cpp
index ca990cb2d3bb20..e876fc501d7de2 100644
--- a/libcxx/test/std/input.output/filesystems/fs.enum/enum.perms.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/fs.enum/enum.perms.pass.cpp
@@ -15,7 +15,6 @@
 #include "filesystem_include.h"
 #include <type_traits>
 #include <cassert>
-#include <sys/stat.h>
 
 #include "test_macros.h"
 #include "check_bitmask_types.h"

diff  --git a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.proximate/proximate.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.proximate/proximate.pass.cpp
index 8be177187fe266..f32c2855c31e7f 100644
--- a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.proximate/proximate.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.proximate/proximate.pass.cpp
@@ -18,8 +18,9 @@
 
 #include "filesystem_include.h"
 #include <cassert>
-#include <cstdio>
 
+#include "assert_macros.h"
+#include "concat_macros.h"
 #include "test_macros.h"
 #include "count_new.h"
 #include "filesystem_test_helper.h"
@@ -34,27 +35,27 @@ static int count_path_elems(const fs::path& p) {
   return count;
 }
 
-
-static void signature_test()
-{
-    using fs::path;
-    const path p; ((void)p);
-    std::error_code ec; ((void)ec);
-    ASSERT_NOT_NOEXCEPT(proximate(p));
-    ASSERT_NOT_NOEXCEPT(proximate(p, p));
-    ASSERT_NOT_NOEXCEPT(proximate(p, ec));
-    ASSERT_NOT_NOEXCEPT(proximate(p, p, ec));
+static void signature_test() {
+  using fs::path;
+  const path p;
+  ((void)p);
+  std::error_code ec;
+  ((void)ec);
+  ASSERT_NOT_NOEXCEPT(proximate(p));
+  ASSERT_NOT_NOEXCEPT(proximate(p, p));
+  ASSERT_NOT_NOEXCEPT(proximate(p, ec));
+  ASSERT_NOT_NOEXCEPT(proximate(p, p, ec));
 }
 
 static void basic_test() {
   using fs::path;
-  const path cwd = fs::current_path();
+  const path cwd        = fs::current_path();
   const path parent_cwd = cwd.parent_path();
-  const path curdir = cwd.filename();
+  const path curdir     = cwd.filename();
   assert(!cwd.native().empty());
   int cwd_depth = count_path_elems(cwd);
   path dot_dot_to_root;
-  for (int i=0; i < cwd_depth; ++i)
+  for (int i = 0; i < cwd_depth; ++i)
     dot_dot_to_root /= "..";
   path relative_cwd = cwd.native().substr(cwd.root_path().native().size());
   // clang-format off
@@ -131,41 +132,36 @@ static void basic_test() {
       {"a/b", "c/d", "../../a/b"}
   };
   // clang-format on
-  int ID = 0;
   for (auto& TC : TestCases) {
-    ++ID;
-    std::error_code ec = GetTestEC();
-    fs::path p = TC.input;
+    std::error_code ec    = GetTestEC();
+    fs::path p            = TC.input;
     const fs::path output = fs::proximate(p, TC.base, ec);
-    fs::path expect = TC.expect;
+    fs::path expect       = TC.expect;
     expect.make_preferred();
-    if (ec) {
-      assert(!ec);
-      std::fprintf(stderr, "TEST CASE #%d FAILED:\n"
-                  "  Input: '%s'\n"
-                  "  Base: '%s'\n"
-                  "  Expected: '%s'\n",
-        ID, TC.input.string().c_str(), TC.base.string().c_str(),
-        expect.string().c_str());
-    } else if (!PathEq(output, expect)) {
-      assert(PathEq(output, expect));
+    TEST_REQUIRE(!ec,
+                 TEST_WRITE_CONCATENATED(
+                     "Input: ", TC.input.string(), "\nBase: ", TC.base.string(), "\nExpected: ", expect.string()));
 
-      const path canon_input = fs::weakly_canonical(TC.input);
-      const path canon_base = fs::weakly_canonical(TC.base);
-      const path lexically_p = canon_input.lexically_proximate(canon_base);
-      std::fprintf(stderr, "TEST CASE #%d FAILED:\n"
-                  "  Input: '%s'\n"
-                  "  Base: '%s'\n"
-                  "  Expected: '%s'\n"
-                  "  Output: '%s'\n"
-                  "  Lex Prox: '%s'\n"
-                  "  Canon Input: '%s'\n"
-                  "  Canon Base: '%s'\n",
-        ID, TC.input.string().c_str(), TC.base.string().c_str(),
-        expect.string().c_str(), output.string().c_str(),
-        lexically_p.string().c_str(), canon_input.string().c_str(),
-        canon_base.string().c_str());
-    }
+    const path canon_input = fs::weakly_canonical(TC.input);
+    const path canon_base  = fs::weakly_canonical(TC.base);
+    const path lexically_p = canon_input.lexically_proximate(canon_base);
+    TEST_REQUIRE(
+        PathEq(output, expect),
+        TEST_WRITE_CONCATENATED(
+            "Input: ",
+            TC.input.string(),
+            "\nBase: ",
+            TC.base.string(),
+            "\nExpected: ",
+            expect.string(),
+            "\nOutput: ",
+            output.string(),
+            "\nLex Prox: ",
+            lexically_p.string(),
+            "\nCanon Input: ",
+            canon_input.string(),
+            "\nCanon Base: ",
+            canon_base.string()));
   }
 }
 

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 d63da5cd5ed129..b7ceec67d655bc 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
@@ -16,9 +16,10 @@
 // path weakly_canonical(const path& p, error_code& ec);
 
 #include "filesystem_include.h"
-#include <cstdio>
 #include <string>
 
+#include "assert_macros.h"
+#include "concat_macros.h"
 #include "test_macros.h"
 #include "test_iterators.h"
 #include "count_new.h"
@@ -26,7 +27,6 @@
 #include "../../class.path/path_helper.h"
 
 int main(int, char**) {
-
   static_test_env static_env;
 
   fs::path root = fs::current_path().root_path();
@@ -68,23 +68,15 @@ int main(int, char**) {
       {static_env.Dir / "DNE/../foo", static_env.Dir / "foo"}
   };
   // clang-format on
-  int ID = 0;
-  bool Failed = false;
   for (auto& TC : TestCases) {
-    ++ID;
-    fs::path p = TC.input;
+    fs::path p      = TC.input;
     fs::path expect = TC.expect;
     expect.make_preferred();
     const fs::path output = fs::weakly_canonical(p);
-    if (!PathEq(output, expect)) {
-      Failed = true;
-      std::fprintf(stderr, "TEST CASE #%d FAILED:\n"
-                  "  Input: '%s'\n"
-                  "  Expected: '%s'\n"
-                  "  Output: '%s'\n",
-        ID, TC.input.string().c_str(), expect.string().c_str(),
-        output.string().c_str());
-    }
+
+    TEST_REQUIRE(PathEq(output, expect),
+                 TEST_WRITE_CONCATENATED(
+                     "Input: ", TC.input.string(), "\nExpected: ", expect.string(), "\nOutput: ", output.string()));
   }
-  return Failed;
+  return 0;
 }

diff  --git a/libcxx/test/support/concat_macros.h b/libcxx/test/support/concat_macros.h
index d6396a76dde737..ea89c62df9a659 100644
--- a/libcxx/test/support/concat_macros.h
+++ b/libcxx/test/support/concat_macros.h
@@ -49,6 +49,11 @@ std::string test_concat_message([[maybe_unused]] Args&&... args) {
 // Writes its arguments to stderr, using the test_concat_message helper.
 #  define TEST_WRITE_CONCATENATED(...) [&] { ::test_eprintf("%s", ::test_concat_message(__VA_ARGS__).c_str()); }
 
+#else
+
+// Fallback definition before C++20 that allows using the macro but doesn't provide a very good message.
+#  define TEST_WRITE_CONCATENATED(...) [&] { ::test_eprintf("%s", TEST_STRINGIZE(__VA_ARGS__)); }
+
 #endif // TEST_STD_VER > 17
 
 #endif //  TEST_SUPPORT_CONCAT_MACROS_H

diff  --git a/libcxx/test/support/test_macros.h b/libcxx/test/support/test_macros.h
index 55234fa1cbe0ea..62bd85eb3af27a 100644
--- a/libcxx/test/support/test_macros.h
+++ b/libcxx/test/support/test_macros.h
@@ -23,8 +23,8 @@
 #include <ciso646>
 #endif
 
-#define TEST_STRINGIZE_IMPL(x) #x
-#define TEST_STRINGIZE(x) TEST_STRINGIZE_IMPL(x)
+#define TEST_STRINGIZE_IMPL(...) #__VA_ARGS__
+#define TEST_STRINGIZE(...) TEST_STRINGIZE_IMPL(__VA_ARGS__)
 
 #define TEST_CONCAT1(X, Y) X##Y
 #define TEST_CONCAT(X, Y) TEST_CONCAT1(X, Y)


        


More information about the libcxx-commits mailing list