From: Eric Fiselier Date: Thu, 26 Jul 2018 03:28:48 +0000 (+0000) Subject: Workaround OS X 10.11 behavior where stat truncates st_mtimespec to seconds. X-Git-Tag: llvmorg-7.0.0-rc1~550 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=982bb884ff788f6d4524e1d9867d327de3ea19c0;p=platform%2Fupstream%2Fllvm.git Workaround OS X 10.11 behavior where stat truncates st_mtimespec to seconds. llvm-svn: 337998 --- diff --git a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp index 3443f98..59f7d81 100644 --- a/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp +++ b/libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp @@ -225,6 +225,24 @@ static const bool SupportsNanosecondRoundTrip = [] { } }(); + +static const bool WorkaroundStatTruncatesToSeconds = [] { + MicroSec micros(3); + static_assert(std::is_same::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, TimeSpec t2) { return false; auto diff = std::abs(t1.tv_nsec - t2.tv_nsec); - + if (WorkaroundStatTruncatesToSeconds) + return diff < duration_cast(Sec(1)).count(); return diff < duration_cast(MicroSec(1)).count(); } @@ -275,8 +294,9 @@ static bool CompareTime(file_time_type t1, file_time_type t2) { dur = t1 - t2; else dur = t2 - t1; - - return duration_cast(dur).count() < 1; + if (WorkaroundStatTruncatesToSeconds) + return duration_cast(dur).count() == 0; + return duration_cast(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_env_test) 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_env_test) 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()