1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // UNSUPPORTED: c++03
10 // ADDITIONAL_COMPILE_FLAGS: -I %S/../../../../../../src/filesystem
11 
12 // This test relies on calling functions from the libcxx internal header
13 // filesystem_common.h; the Windows implementation uses different
14 // internals and doesn't provide the same set_file_times function as for
15 // other platforms.
16 // UNSUPPORTED: windows
17 
18 // This test assumes that time is stored as a 64 bit value when on MVS it is stored as 32 bit
19 // UNSUPPORTED: target={{.+}}-zos{{.*}}
20 
21 // <filesystem>
22 
23 // class directory_entry
24 
25 #include "filesystem_include.h"
26 #include <type_traits>
27 #include <cassert>
28 
29 #include "test_macros.h"
30 #include "rapid-cxx-test.h"
31 #include "filesystem_test_helper.h"
32 
33 #include "filesystem_common.h"
34 
35 using namespace fs::detail;
36 
37 TEST_SUITE(directory_entry_mods_suite)
38 
TEST_CASE(last_write_time_not_representable_error)39 TEST_CASE(last_write_time_not_representable_error) {
40   using namespace fs;
41   using namespace std::chrono;
42   scoped_test_env env;
43   const path dir = env.create_dir("dir");
44   const path file = env.create_file("dir/file", 42);
45 
46   TimeSpec ToTime;
47   ToTime.tv_sec = std::numeric_limits<decltype(ToTime.tv_sec)>::max();
48   ToTime.tv_nsec = duration_cast<nanoseconds>(seconds(1)).count() - 1;
49 
50   std::array<TimeSpec, 2> TS = {ToTime, ToTime};
51 
52   file_time_type old_time = last_write_time(file);
53   directory_entry ent(file);
54 
55   file_time_type start_time = file_time_type::clock::now() - hours(1);
56   last_write_time(file, start_time);
57 
58   TEST_CHECK(ent.last_write_time() == old_time);
59 
60   bool IsRepresentable = true;
61   file_time_type rep_value;
62   {
63     std::error_code ec;
64     TEST_REQUIRE(!set_file_times(file, TS, ec));
65     ec.clear();
66     rep_value = last_write_time(file, ec);
67     IsRepresentable = !bool(ec);
68   }
69 
70   if (!IsRepresentable) {
71     std::error_code rec = GetTestEC();
72     ent.refresh(rec);
73     TEST_CHECK(!rec);
74 
75     const std::errc expected_err = std::errc::value_too_large;
76 
77     std::error_code ec = GetTestEC();
78     TEST_CHECK(ent.last_write_time(ec) == file_time_type::min());
79     TEST_CHECK(ErrorIs(ec, expected_err));
80 
81     ec = GetTestEC();
82     TEST_CHECK(last_write_time(file, ec) == file_time_type::min());
83     TEST_CHECK(ErrorIs(ec, expected_err));
84 
85     ExceptionChecker CheckExcept(file, expected_err,
86                                  "directory_entry::last_write_time");
87     TEST_CHECK_THROW_RESULT(filesystem_error, CheckExcept,
88                             ent.last_write_time());
89 
90   } else {
91     ent.refresh();
92 
93     std::error_code ec = GetTestEC();
94     TEST_CHECK(ent.last_write_time(ec) == rep_value);
95     TEST_CHECK(!ec);
96   }
97 }
98 
99 TEST_SUITE_END()
100