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