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 // REQUIRES: can-create-symlinks
10 // UNSUPPORTED: c++03, c++11, c++14
11 // UNSUPPORTED: no-filesystem
12 // UNSUPPORTED: availability-filesystem-missing
13 
14 // <filesystem>
15 
16 // void resize_file(const path& p, uintmax_t new_size);
17 // void resize_file(const path& p, uintmax_t new_size, error_code& ec) noexcept;
18 
19 #include <filesystem>
20 
21 #include "test_macros.h"
22 #include "filesystem_test_helper.h"
23 namespace fs = std::filesystem;
24 using namespace fs;
25 
test_signatures()26 static void test_signatures()
27 {
28     const path p; ((void)p);
29     std::uintmax_t i; ((void)i);
30     std::error_code ec; ((void)ec);
31 
32     ASSERT_SAME_TYPE(decltype(fs::resize_file(p, i)), void);
33     ASSERT_SAME_TYPE(decltype(fs::resize_file(p, i, ec)), void);
34 
35     ASSERT_NOT_NOEXCEPT(fs::resize_file(p, i));
36     ASSERT_NOEXCEPT(fs::resize_file(p, i, ec));
37 }
38 
test_error_reporting()39 static void test_error_reporting()
40 {
41     auto checkThrow = [](path const& f, std::uintmax_t s, const std::error_code& ec)
42     {
43 #ifndef TEST_HAS_NO_EXCEPTIONS
44         try {
45             fs::resize_file(f, s);
46             return false;
47         } catch (filesystem_error const& err) {
48             return err.path1() == f
49                 && err.path2() == ""
50                 && err.code() == ec;
51         }
52 #else
53         ((void)f); ((void)s); ((void)ec);
54         return true;
55 #endif
56     };
57     scoped_test_env env;
58     const path dne = env.make_env_path("dne");
59     const path bad_sym = env.create_symlink(dne, "sym");
60     const path dir = env.create_dir("dir1");
61     const path cases[] = {
62         dne, bad_sym, dir
63     };
64     for (auto& p : cases) {
65         std::error_code ec;
66         resize_file(p, 42, ec);
67         assert(ec);
68         assert(checkThrow(p, 42, ec));
69     }
70 }
71 
basic_resize_file_test()72 static void basic_resize_file_test()
73 {
74     scoped_test_env env;
75     const path file1 = env.create_file("file1", 42);
76     const auto set_ec = std::make_error_code(std::errc::address_in_use);
77     { // grow file
78         const std::uintmax_t new_s = 100;
79         std::error_code ec = set_ec;
80         resize_file(file1, new_s, ec);
81         assert(!ec);
82         assert(file_size(file1) == new_s);
83     }
84     { // shrink file
85         const std::uintmax_t new_s = 1;
86         std::error_code ec = set_ec;
87         resize_file(file1, new_s, ec);
88         assert(!ec);
89         assert(file_size(file1) == new_s);
90     }
91     { // shrink file to zero
92         const std::uintmax_t new_s = 0;
93         std::error_code ec = set_ec;
94         resize_file(file1, new_s, ec);
95         assert(!ec);
96         assert(file_size(file1) == new_s);
97     }
98     const path sym = env.create_symlink(file1, "sym");
99     { // grow file via symlink
100         const std::uintmax_t new_s = 1024;
101         std::error_code ec = set_ec;
102         resize_file(sym, new_s, ec);
103         assert(!ec);
104         assert(file_size(file1) == new_s);
105     }
106 }
107 
main(int,char **)108 int main(int, char**) {
109     test_signatures();
110     test_error_reporting();
111     basic_resize_file_test();
112     return 0;
113 }
114