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