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 // space_info space(const path& p);
17 // space_info space(const path& p, 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 
EqualDelta(std::uintmax_t x,std::uintmax_t y,std::uintmax_t delta)26 bool EqualDelta(std::uintmax_t x, std::uintmax_t y, std::uintmax_t delta) {
27     if (x >= y) {
28         return (x - y) <= delta;
29     } else {
30         return (y - x) <= delta;
31     }
32 }
33 
signature_test()34 static void signature_test()
35 {
36     const path p; ((void)p);
37     std::error_code ec; ((void)ec);
38     ASSERT_SAME_TYPE(decltype(space(p)), space_info);
39     ASSERT_SAME_TYPE(decltype(space(p, ec)), space_info);
40     ASSERT_NOT_NOEXCEPT(space(p));
41     ASSERT_NOEXCEPT(space(p, ec));
42 }
43 
test_error_reporting()44 static void test_error_reporting()
45 {
46     static_test_env static_env;
47     auto checkThrow = [](path const& f, const std::error_code& ec)
48     {
49 #ifndef TEST_HAS_NO_EXCEPTIONS
50         try {
51             (void)space(f);
52             return false;
53         } catch (filesystem_error const& err) {
54             return err.path1() == f
55                 && err.path2() == ""
56                 && err.code() == ec;
57         }
58 #else
59         ((void)f); ((void)ec);
60         return true;
61 #endif
62     };
63     const path cases[] = {
64         "",
65         static_env.DNE,
66         static_env.BadSymlink
67     };
68     for (auto& p : cases) {
69         const auto expect = static_cast<std::uintmax_t>(-1);
70         std::error_code ec;
71         space_info info = space(p, ec);
72         assert(ec);
73         assert(info.capacity == expect);
74         assert(info.free == expect);
75         assert(info.available == expect);
76         assert(checkThrow(p, ec));
77     }
78 }
79 
basic_space_test()80 static void basic_space_test()
81 {
82     static_test_env static_env;
83 
84     // All the test cases should reside on the same filesystem and therefore
85     // should have the same expected result. Compute this expected result
86     // one and check that it looks semi-sane.
87     const std::uintmax_t bad_value = static_cast<std::uintmax_t>(-1);
88     std::uintmax_t expect_capacity;
89     std::uintmax_t expect_free;
90     std::uintmax_t expect_avail;
91     assert(utils::space(static_env.Dir.string(), expect_capacity,
92                               expect_free, expect_avail));
93 
94     // Other processes running on the operating system may have changed
95     // the amount of space available. Check that these are within tolerances.
96     // Currently 5% of capacity
97     const std::uintmax_t delta = expect_capacity / 20;
98     const path cases[] = {
99         static_env.File,
100         static_env.Dir,
101         static_env.Dir2,
102         static_env.SymlinkToFile,
103         static_env.SymlinkToDir
104     };
105     for (auto& p : cases) {
106         std::error_code ec = GetTestEC();
107         space_info info = space(p, ec);
108         assert(!ec);
109         assert(info.capacity != bad_value);
110         assert(expect_capacity == info.capacity);
111         assert(info.free != bad_value);
112         assert(EqualDelta(expect_free, info.free, delta));
113         assert(info.available != bad_value);
114         assert(EqualDelta(expect_avail, info.available, delta));
115     }
116 }
117 
main(int,char **)118 int main(int, char**) {
119     signature_test();
120     test_error_reporting();
121     basic_space_test();
122 
123     return 0;
124 }
125