space.pass.cpp
3.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03
// <filesystem>
// space_info space(const path& p);
// space_info space(const path& p, error_code& ec) noexcept;
#include "filesystem_include.h"
#include <sys/statvfs.h>
#include "test_macros.h"
#include "rapid-cxx-test.h"
#include "filesystem_test_helper.h"
using namespace fs;
bool EqualDelta(std::uintmax_t x, std::uintmax_t y, std::uintmax_t delta) {
if (x >= y) {
return (x - y) <= delta;
} else {
return (y - x) <= delta;
}
}
TEST_SUITE(filesystem_space_test_suite)
TEST_CASE(signature_test)
{
const path p; ((void)p);
std::error_code ec; ((void)ec);
ASSERT_SAME_TYPE(decltype(space(p)), space_info);
ASSERT_SAME_TYPE(decltype(space(p, ec)), space_info);
ASSERT_NOT_NOEXCEPT(space(p));
ASSERT_NOEXCEPT(space(p, ec));
}
TEST_CASE(test_error_reporting)
{
static_test_env static_env;
auto checkThrow = [](path const& f, const std::error_code& ec)
{
#ifndef TEST_HAS_NO_EXCEPTIONS
try {
space(f);
return false;
} catch (filesystem_error const& err) {
return err.path1() == f
&& err.path2() == ""
&& err.code() == ec;
}
#else
((void)f); ((void)ec);
return true;
#endif
};
const path cases[] = {
"",
static_env.DNE,
static_env.BadSymlink
};
for (auto& p : cases) {
const auto expect = static_cast<std::uintmax_t>(-1);
std::error_code ec;
space_info info = space(p, ec);
TEST_CHECK(ec);
TEST_CHECK(info.capacity == expect);
TEST_CHECK(info.free == expect);
TEST_CHECK(info.available == expect);
TEST_CHECK(checkThrow(p, ec));
}
}
TEST_CASE(basic_space_test)
{
static_test_env static_env;
// All the test cases should reside on the same filesystem and therefore
// should have the same expected result. Compute this expected result
// one and check that it looks semi-sane.
struct statvfs expect;
TEST_REQUIRE(::statvfs(static_env.Dir.c_str(), &expect) != -1);
TEST_CHECK(expect.f_bavail > 0);
TEST_CHECK(expect.f_bfree > 0);
TEST_CHECK(expect.f_bsize > 0);
TEST_CHECK(expect.f_blocks > 0);
TEST_REQUIRE(expect.f_frsize > 0);
auto do_mult = [&](std::uintmax_t val) {
std::uintmax_t fsize = expect.f_frsize;
std::uintmax_t new_val = val * fsize;
TEST_CHECK(new_val / fsize == val); // Test for overflow
return new_val;
};
const std::uintmax_t bad_value = static_cast<std::uintmax_t>(-1);
const std::uintmax_t expect_capacity = do_mult(expect.f_blocks);
const std::uintmax_t expect_free = do_mult(expect.f_bfree);
const std::uintmax_t expect_avail = do_mult(expect.f_bavail);
// Other processes running on the operating system may have changed
// the amount of space available. Check that these are within tolerances.
// Currently 5% of capacity
const std::uintmax_t delta = expect_capacity / 20;
const path cases[] = {
static_env.File,
static_env.Dir,
static_env.Dir2,
static_env.SymlinkToFile,
static_env.SymlinkToDir
};
for (auto& p : cases) {
std::error_code ec = GetTestEC();
space_info info = space(p, ec);
TEST_CHECK(!ec);
TEST_CHECK(info.capacity != bad_value);
TEST_CHECK(expect_capacity == info.capacity);
TEST_CHECK(info.free != bad_value);
TEST_CHECK(EqualDelta(expect_free, info.free, delta));
TEST_CHECK(info.available != bad_value);
TEST_CHECK(EqualDelta(expect_avail, info.available, delta));
}
}
TEST_SUITE_END()