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