[libcxx] r337998 - Workaround OS X 10.11 behavior where stat truncates st_mtimespec to seconds.

Eric Fiselier via cfe-commits cfe-commits at lists.llvm.org
Wed Jul 25 20:28:49 PDT 2018


Author: ericwf
Date: Wed Jul 25 20:28:48 2018
New Revision: 337998

URL: http://llvm.org/viewvc/llvm-project?rev=337998&view=rev
Log:
Workaround OS X 10.11 behavior where stat truncates st_mtimespec to seconds.

Modified:
    libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp

Modified: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp?rev=337998&r1=337997&r2=337998&view=diff
==============================================================================
--- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp (original)
+++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp Wed Jul 25 20:28:48 2018
@@ -225,6 +225,24 @@ static const bool SupportsNanosecondRoun
   }
 }();
 
+
+static const bool WorkaroundStatTruncatesToSeconds = [] {
+  MicroSec micros(3);
+  static_assert(std::is_same<file_time_type::period, std::nano>::value, "");
+
+  // Test for the behavior of OS X 10.11 and older, which truncates the result
+  // of st_mtimespec to seconds.
+  file_time_type ft(micros);
+  {
+    scoped_test_env env;
+    const path p = env.create_file("file", 42);
+    if (LastWriteTime(p).tv_nsec != 0)
+      return false;
+    last_write_time(p, ft);
+    return last_write_time(p) != ft && LastWriteTime(p).tv_nsec == 0;
+  }
+}();
+
 static const bool SupportsMinRoundTrip = [] {
   TimeSpec ts = {};
   if (!ConvertToTimeSpec(ts, file_time_type::min()))
@@ -244,7 +262,8 @@ static bool CompareTime(TimeSpec t1, Tim
     return false;
 
   auto diff = std::abs(t1.tv_nsec - t2.tv_nsec);
-
+  if (WorkaroundStatTruncatesToSeconds)
+   return diff < duration_cast<NanoSec>(Sec(1)).count();
   return diff < duration_cast<NanoSec>(MicroSec(1)).count();
 }
 
@@ -275,8 +294,9 @@ static bool CompareTime(file_time_type t
     dur = t1 - t2;
   else
     dur = t2 - t1;
-
-  return duration_cast<MicroSec>(dur).count() < 1;
+  if (WorkaroundStatTruncatesToSeconds)
+    return duration_cast<Sec>(dur).count() == 0;
+  return duration_cast<MicroSec>(dur).count() == 0;
 }
 
 // Check if a time point is representable on a given filesystem. Check that:
@@ -399,7 +419,6 @@ TEST_CASE(get_last_write_time_dynamic_en
 TEST_CASE(set_last_write_time_dynamic_env_test)
 {
     using Clock = file_time_type::clock;
-    using SubSecT = file_time_type::duration;
     scoped_test_env env;
 
     const path file = env.create_file("file", 42);
@@ -453,12 +472,6 @@ TEST_CASE(set_last_write_time_dynamic_en
         if (TimeIsRepresentableByFilesystem(TC.new_time)) {
             TEST_CHECK(got_time != old_time);
             TEST_CHECK(CompareTime(got_time, TC.new_time));
-
-            // FIXME(EricWF): Remove these after getting information from
-            // some failing bots.
-            std::cerr << (long long)got_time.time_since_epoch().count() << std::endl;
-            std::cerr << (long long)TC.new_time.time_since_epoch().count() << std::endl;
-
             TEST_CHECK(CompareTime(LastAccessTime(TC.p), old_times.access));
         }
     }
@@ -484,7 +497,11 @@ TEST_CASE(last_write_time_symlink_test)
 
     file_time_type  got_time = last_write_time(sym);
     TEST_CHECK(!CompareTime(got_time, old_times.write));
-    TEST_CHECK(got_time == new_time);
+    if (!WorkaroundStatTruncatesToSeconds) {
+      TEST_CHECK(got_time == new_time);
+    } else {
+      TEST_CHECK(CompareTime(got_time, new_time));
+    }
 
     TEST_CHECK(CompareTime(LastWriteTime(file), new_time));
     TEST_CHECK(CompareTime(LastAccessTime(sym), old_times.access));
@@ -577,4 +594,14 @@ TEST_CASE(test_exists_fails)
     TEST_CHECK_THROW_RESULT(filesystem_error, Checker, last_write_time(file));
 }
 
+// Just for sanity ensure that WorkaroundStatTruncatesToSeconds is only
+// ever true on Apple platforms.
+TEST_CASE(apple_truncates_to_seconds_check) {
+#ifndef __APPLE__
+  TEST_CHECK(!WorkaroundStatTruncatesToSeconds);
+#else
+  TEST_CHECK(SupportsNanosecondRoundTrip != WorkaroundStatTruncatesToSeconds);
+#endif
+}
+
 TEST_SUITE_END()




More information about the cfe-commits mailing list