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
11 // <filesystem>
12
13 // space_info space(const path& p);
14 // space_info space(const path& p, error_code& ec) noexcept;
15
16 #include "filesystem_include.h"
17
18 #include "test_macros.h"
19 #include "rapid-cxx-test.h"
20 #include "filesystem_test_helper.h"
21
22 using namespace fs;
23
EqualDelta(std::uintmax_t x,std::uintmax_t y,std::uintmax_t delta)24 bool EqualDelta(std::uintmax_t x, std::uintmax_t y, std::uintmax_t delta) {
25 if (x >= y) {
26 return (x - y) <= delta;
27 } else {
28 return (y - x) <= delta;
29 }
30 }
31
32 TEST_SUITE(filesystem_space_test_suite)
33
TEST_CASE(signature_test)34 TEST_CASE(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_CASE(test_error_reporting)44 TEST_CASE(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 TEST_CHECK(ec);
73 TEST_CHECK(info.capacity == expect);
74 TEST_CHECK(info.free == expect);
75 TEST_CHECK(info.available == expect);
76 TEST_CHECK(checkThrow(p, ec));
77 }
78 }
79
TEST_CASE(basic_space_test)80 TEST_CASE(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 TEST_REQUIRE(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 TEST_CHECK(!ec);
109 TEST_CHECK(info.capacity != bad_value);
110 TEST_CHECK(expect_capacity == info.capacity);
111 TEST_CHECK(info.free != bad_value);
112 TEST_CHECK(EqualDelta(expect_free, info.free, delta));
113 TEST_CHECK(info.available != bad_value);
114 TEST_CHECK(EqualDelta(expect_avail, info.available, delta));
115 }
116 }
117
118 TEST_SUITE_END()
119