Add additional tests in an attempt to diagnose ARM test failures.
Currently 4 tests are failing on the ARM buildbot. To try and diagnose each of the failures this patch does the following: 1) path.itr/iterator.pass.cpp * Temporarily print iteration sequence to see where its failing. 2) path.native.obs/string_alloc.pass.cpp * Remove test that ::new is not called when constructing a short string that requires a conversion. Since during the conversion global locale objects might be constructed. 3) fs.op.funcs/space.pass.cpp * Explicitly use uintmax_t in the implementation of space, hopefully preventing possible overflows. * Add additional tests that check for overflow is the calculation of the space_info values. * Add additional tests for the values returned from statfvs. 4) fs.op.funcs/last_write_time.pass.cpp * No changes made yet. llvm-svn: 273075
This commit is contained in:
parent
1040b4479c
commit
ccc9826f56
|
@ -669,7 +669,7 @@ void __resize_file(const path& p, std::uintmax_t size, std::error_code *ec) {
|
||||||
|
|
||||||
space_info __space(const path& p, std::error_code *ec) {
|
space_info __space(const path& p, std::error_code *ec) {
|
||||||
space_info si;
|
space_info si;
|
||||||
struct statvfs m_svfs;
|
struct statvfs m_svfs = {};
|
||||||
if (::statvfs(p.c_str(), &m_svfs) == -1) {
|
if (::statvfs(p.c_str(), &m_svfs) == -1) {
|
||||||
set_or_throw(ec, "space", p);
|
set_or_throw(ec, "space", p);
|
||||||
si.capacity = si.free = si.available =
|
si.capacity = si.free = si.available =
|
||||||
|
@ -678,7 +678,7 @@ space_info __space(const path& p, std::error_code *ec) {
|
||||||
}
|
}
|
||||||
if (ec) ec->clear();
|
if (ec) ec->clear();
|
||||||
// Multiply with overflow checking.
|
// Multiply with overflow checking.
|
||||||
auto do_mult = [&](std::uintmax_t& out, fsblkcnt_t other) {
|
auto do_mult = [&](std::uintmax_t& out, std::uintmax_t other) {
|
||||||
out = other * m_svfs.f_frsize;
|
out = other * m_svfs.f_frsize;
|
||||||
if (out / other != m_svfs.f_frsize || other == 0)
|
if (out / other != m_svfs.f_frsize || other == 0)
|
||||||
out = static_cast<std::uintmax_t>(-1);
|
out = static_cast<std::uintmax_t>(-1);
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "test_macros.h"
|
#include "test_macros.h"
|
||||||
#include "filesystem_test_helper.hpp"
|
#include "filesystem_test_helper.hpp"
|
||||||
|
|
||||||
|
@ -36,6 +38,29 @@ std::reverse_iterator<It> mkRev(It it) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class Iter1, class Iter2>
|
||||||
|
bool checkCollectionsEqualVerbose(
|
||||||
|
Iter1 start1, Iter1 const end1
|
||||||
|
, Iter2 start2, Iter2 const end2
|
||||||
|
)
|
||||||
|
{
|
||||||
|
while (start1 != end1 && start2 != end2) {
|
||||||
|
std::cout << "Got start1 = " << *start1 << "\n"
|
||||||
|
<< "Got start2 = " << *start2 << "\n";
|
||||||
|
if (*start1 != *start2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
++start1; ++start2;
|
||||||
|
}
|
||||||
|
if (start1 != end1) {
|
||||||
|
std::cout << "Got start1 = " << *start1 << " but expected end1\n";
|
||||||
|
}
|
||||||
|
if (start2 != end2) {
|
||||||
|
std::cout << "Got start2 = " << *start2 << " but expected end2\n";
|
||||||
|
}
|
||||||
|
return (start1 == end1 && start2 == end2);
|
||||||
|
}
|
||||||
|
|
||||||
void checkIteratorConcepts() {
|
void checkIteratorConcepts() {
|
||||||
using namespace fs;
|
using namespace fs;
|
||||||
using It = path::iterator;
|
using It = path::iterator;
|
||||||
|
@ -87,14 +112,18 @@ void checkBeginEndBasic() {
|
||||||
path p("//root_name//first_dir////second_dir");
|
path p("//root_name//first_dir////second_dir");
|
||||||
const path expect[] = {"//root_name", "/", "first_dir", "second_dir"};
|
const path expect[] = {"//root_name", "/", "first_dir", "second_dir"};
|
||||||
assert(checkCollectionsEqual(p.begin(), p.end(), std::begin(expect), std::end(expect)));
|
assert(checkCollectionsEqual(p.begin(), p.end(), std::begin(expect), std::end(expect)));
|
||||||
assert(checkCollectionsEqual(mkRev(p.end()), mkRev(p.begin()), mkRev(std::end(expect)), mkRev(std::begin(expect))));
|
assert(checkCollectionsEqualVerbose(mkRev(p.end()), mkRev(p.begin()),
|
||||||
|
mkRev(std::end(expect)),
|
||||||
|
mkRev(std::begin(expect))));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
path p("////foo/bar/baz///");
|
path p("////foo/bar/baz///");
|
||||||
const path expect[] = {"/", "foo", "bar", "baz", "."};
|
const path expect[] = {"/", "foo", "bar", "baz", "."};
|
||||||
assert(checkCollectionsEqual(p.begin(), p.end(), std::begin(expect), std::end(expect)));
|
assert(checkCollectionsEqual(p.begin(), p.end(), std::begin(expect), std::end(expect)));
|
||||||
assert(checkCollectionsEqual(mkRev(p.end()), mkRev(p.begin()), mkRev(std::end(expect)), mkRev(std::begin(expect))));
|
assert(checkCollectionsEqual(mkRev(p.end()), mkRev(p.begin()),
|
||||||
|
mkRev(std::end(expect)), mkRev(std::begin(expect))));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
#include "count_new.hpp"
|
#include "count_new.hpp"
|
||||||
#include "min_allocator.h"
|
#include "min_allocator.h"
|
||||||
#include "filesystem_test_helper.hpp"
|
#include "filesystem_test_helper.hpp"
|
||||||
#include "assert_checkpoint.h"
|
|
||||||
|
|
||||||
namespace fs = std::experimental::filesystem;
|
namespace fs = std::experimental::filesystem;
|
||||||
|
|
||||||
|
@ -43,14 +42,37 @@ void doShortStringTest(MultiStringType const& MS) {
|
||||||
Ptr value = MS;
|
Ptr value = MS;
|
||||||
const path p((const char*)MS);
|
const path p((const char*)MS);
|
||||||
{
|
{
|
||||||
DisableAllocationGuard g; // should not allocate
|
DisableAllocationGuard g;
|
||||||
CHECKPOINT("short string default constructed allocator");
|
if (!std::is_same<CharT, char>::value)
|
||||||
|
g.release();
|
||||||
Str s = p.string<CharT>();
|
Str s = p.string<CharT>();
|
||||||
assert(s == value);
|
assert(s == value);
|
||||||
CHECKPOINT("short string provided allocator");
|
|
||||||
Str s2 = p.string<CharT>(Alloc{});
|
Str s2 = p.string<CharT>(Alloc{});
|
||||||
assert(s2 == value);
|
assert(s2 == value);
|
||||||
}
|
}
|
||||||
|
using MAlloc = malloc_allocator<CharT>;
|
||||||
|
MAlloc::reset();
|
||||||
|
{
|
||||||
|
using Traits = std::char_traits<CharT>;
|
||||||
|
using AStr = std::basic_string<CharT, Traits, MAlloc>;
|
||||||
|
AStr s = p.string<CharT, Traits, MAlloc>();
|
||||||
|
assert(s == value);
|
||||||
|
assert(MAlloc::alloc_count == 0);
|
||||||
|
assert(MAlloc::outstanding_alloc() == 0);
|
||||||
|
}
|
||||||
|
MAlloc::reset();
|
||||||
|
{ // Other allocator - provided copy
|
||||||
|
using Traits = std::char_traits<CharT>;
|
||||||
|
using AStr = std::basic_string<CharT, Traits, MAlloc>;
|
||||||
|
MAlloc a;
|
||||||
|
// don't allow another allocator to be default constructed.
|
||||||
|
MAlloc::disable_default_constructor = true;
|
||||||
|
AStr s = p.string<CharT, Traits, MAlloc>(a);
|
||||||
|
assert(s == value);
|
||||||
|
assert(MAlloc::alloc_count == 0);
|
||||||
|
assert(MAlloc::outstanding_alloc() == 0);
|
||||||
|
}
|
||||||
|
MAlloc::reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class CharT>
|
template <class CharT>
|
||||||
|
@ -62,7 +84,6 @@ void doLongStringTest(MultiStringType const& MS) {
|
||||||
const path p((const char*)MS);
|
const path p((const char*)MS);
|
||||||
{ // Default allocator
|
{ // Default allocator
|
||||||
using Alloc = std::allocator<CharT>;
|
using Alloc = std::allocator<CharT>;
|
||||||
RequireAllocationGuard g;
|
|
||||||
Str s = p.string<CharT>();
|
Str s = p.string<CharT>();
|
||||||
assert(s == value);
|
assert(s == value);
|
||||||
Str s2 = p.string<CharT>(Alloc{});
|
Str s2 = p.string<CharT>(Alloc{});
|
||||||
|
@ -70,22 +91,18 @@ void doLongStringTest(MultiStringType const& MS) {
|
||||||
}
|
}
|
||||||
using MAlloc = malloc_allocator<CharT>;
|
using MAlloc = malloc_allocator<CharT>;
|
||||||
MAlloc::reset();
|
MAlloc::reset();
|
||||||
CHECKPOINT("Malloc allocator test - default construct");
|
|
||||||
{ // Other allocator - default construct
|
{ // Other allocator - default construct
|
||||||
using Traits = std::char_traits<CharT>;
|
using Traits = std::char_traits<CharT>;
|
||||||
using AStr = std::basic_string<CharT, Traits, MAlloc>;
|
using AStr = std::basic_string<CharT, Traits, MAlloc>;
|
||||||
DisableAllocationGuard g;
|
|
||||||
AStr s = p.string<CharT, Traits, MAlloc>();
|
AStr s = p.string<CharT, Traits, MAlloc>();
|
||||||
assert(s == value);
|
assert(s == value);
|
||||||
assert(MAlloc::alloc_count > 0);
|
assert(MAlloc::alloc_count > 0);
|
||||||
assert(MAlloc::outstanding_alloc() == 1);
|
assert(MAlloc::outstanding_alloc() == 1);
|
||||||
}
|
}
|
||||||
MAlloc::reset();
|
MAlloc::reset();
|
||||||
CHECKPOINT("Malloc allocator test - provided copy");
|
|
||||||
{ // Other allocator - provided copy
|
{ // Other allocator - provided copy
|
||||||
using Traits = std::char_traits<CharT>;
|
using Traits = std::char_traits<CharT>;
|
||||||
using AStr = std::basic_string<CharT, Traits, MAlloc>;
|
using AStr = std::basic_string<CharT, Traits, MAlloc>;
|
||||||
DisableAllocationGuard g;
|
|
||||||
MAlloc a;
|
MAlloc a;
|
||||||
// don't allow another allocator to be default constructed.
|
// don't allow another allocator to be default constructed.
|
||||||
MAlloc::disable_default_constructor = true;
|
MAlloc::disable_default_constructor = true;
|
||||||
|
|
|
@ -88,6 +88,8 @@ TEST_CASE(basic_space_test)
|
||||||
TEST_CHECK(expect.f_bfree > 0);
|
TEST_CHECK(expect.f_bfree > 0);
|
||||||
TEST_CHECK(expect.f_bsize > 0);
|
TEST_CHECK(expect.f_bsize > 0);
|
||||||
TEST_CHECK(expect.f_blocks > 0);
|
TEST_CHECK(expect.f_blocks > 0);
|
||||||
|
TEST_CHECK(expect.f_frsize > 0);
|
||||||
|
const std::uintmax_t bad_value = static_cast<std::uintmax_t>(-1);
|
||||||
const std::uintmax_t expect_cap = expect.f_blocks * expect.f_frsize;
|
const std::uintmax_t expect_cap = expect.f_blocks * expect.f_frsize;
|
||||||
// Other processes running on the operating system may have changed
|
// Other processes running on the operating system may have changed
|
||||||
// the amount of space available. Check that these are within tolerances.
|
// the amount of space available. Check that these are within tolerances.
|
||||||
|
@ -101,11 +103,14 @@ TEST_CASE(basic_space_test)
|
||||||
StaticEnv::SymlinkToDir
|
StaticEnv::SymlinkToDir
|
||||||
};
|
};
|
||||||
for (auto& p : cases) {
|
for (auto& p : cases) {
|
||||||
std::error_code ec = std::make_error_code(std::errc::address_in_use);
|
std::error_code ec = GetTestEC();
|
||||||
space_info info = space(p, ec);
|
space_info info = space(p, ec);
|
||||||
TEST_CHECK(!ec);
|
TEST_CHECK(!ec);
|
||||||
|
TEST_CHECK(info.capacity != bad_value);
|
||||||
TEST_CHECK((expect.f_blocks * expect.f_frsize) == info.capacity);
|
TEST_CHECK((expect.f_blocks * expect.f_frsize) == info.capacity);
|
||||||
|
TEST_CHECK(info.free != bad_value);
|
||||||
TEST_CHECK(EqualDelta((expect.f_bfree * expect.f_frsize), info.free, delta));
|
TEST_CHECK(EqualDelta((expect.f_bfree * expect.f_frsize), info.free, delta));
|
||||||
|
TEST_CHECK(info.available != bad_value);
|
||||||
TEST_CHECK(EqualDelta((expect.f_bavail * expect.f_frsize), info.available, delta));
|
TEST_CHECK(EqualDelta((expect.f_bavail * expect.f_frsize), info.available, delta));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue