Skip to content

Commit

Permalink
[libc] Refactor statvfs tests (#114147)
Browse files Browse the repository at this point in the history
The previous statvfs tests had several issues, this patch updates them
to meet current standards.
  • Loading branch information
michaelrj-google authored Oct 30, 2024
1 parent 56dcfbe commit 5d35747
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 82 deletions.
6 changes: 4 additions & 2 deletions libc/test/src/sys/statvfs/linux/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ add_libc_unittest(
statvfs_test.cpp
DEPENDS
libc.src.errno.errno
libc.src.sys.statvfs.linux.statfs_utils
libc.src.sys.statvfs.statvfs
libc.src.sys.stat.mkdirat
libc.src.sys.stat.rmdir
libc.test.UnitTest.ErrnoSetterMatcher
)

Expand All @@ -21,8 +22,9 @@ add_libc_unittest(
fstatvfs_test.cpp
DEPENDS
libc.src.errno.errno
libc.src.sys.statvfs.linux.statfs_utils
libc.src.sys.statvfs.fstatvfs
libc.src.sys.stat.mkdirat
libc.src.sys.stat.rmdir
libc.src.fcntl.open
libc.src.unistd.close
libc.test.UnitTest.ErrnoSetterMatcher
Expand Down
81 changes: 44 additions & 37 deletions libc/test/src/sys/statvfs/linux/fstatvfs_test.cpp
Original file line number Diff line number Diff line change
@@ -1,49 +1,56 @@
//===-- Unittests for fstatvfs --------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "hdr/fcntl_macros.h"
#include "src/__support/macros/config.h"
#include "src/fcntl/open.h"
#include "src/sys/stat/mkdirat.h"
#include "src/sys/statvfs/fstatvfs.h"
#include "src/sys/statvfs/linux/statfs_utils.h"
#include "src/unistd/close.h"
#include "src/unistd/rmdir.h"
#include "test/UnitTest/ErrnoSetterMatcher.h"
#include "test/UnitTest/LibcTest.h"
#include <linux/magic.h>
#include "test/UnitTest/Test.h"

using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;

#ifdef SYS_statfs64
using StatFs = statfs64;
#else
using StatFs = statfs;
#endif

namespace LIBC_NAMESPACE_DECL {
static int fstatfs(int fd, StatFs *buf) {
using namespace statfs_utils;
if (cpp::optional<StatFs> result = linux_fstatfs(fd)) {
*buf = *result;
return 0;
}
return -1;
}
} // namespace LIBC_NAMESPACE_DECL

struct PathFD {
int fd;
explicit PathFD(const char *path)
: fd(LIBC_NAMESPACE::open(path, O_CLOEXEC | O_PATH)) {}
~PathFD() { LIBC_NAMESPACE::close(fd); }
operator int() const { return fd; }
};

TEST(LlvmLibcSysStatvfsTest, FstatfsBasic) {
StatFs buf;
ASSERT_THAT(LIBC_NAMESPACE::fstatfs(PathFD("/"), &buf), Succeeds());
ASSERT_THAT(LIBC_NAMESPACE::fstatfs(PathFD("/proc"), &buf), Succeeds());
ASSERT_EQ(buf.f_type, static_cast<decltype(buf.f_type)>(PROC_SUPER_MAGIC));
ASSERT_THAT(LIBC_NAMESPACE::fstatfs(PathFD("/sys"), &buf), Succeeds());
ASSERT_EQ(buf.f_type, static_cast<decltype(buf.f_type)>(SYSFS_MAGIC));
TEST(LlvmLibcSysFStatvfsTest, FStatvfsBasic) {
struct statvfs buf;

int fd = LIBC_NAMESPACE::open("/", O_PATH);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(fd, 0);

// The root of the file directory must always exist
ASSERT_THAT(LIBC_NAMESPACE::fstatvfs(fd, &buf), Succeeds());
ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
}

TEST(LlvmLibcSysStatvfsTest, FstatvfsInvalidFD) {
TEST(LlvmLibcSysFStatvfsTest, FStatvfsInvalidPath) {
struct statvfs buf;
ASSERT_THAT(LIBC_NAMESPACE::fstatvfs(-1, &buf), Fails(EBADF));

constexpr const char *FILENAME = "testdata/statvfs.testdir";
auto TEST_DIR = libc_make_test_file_path(FILENAME);

ASSERT_THAT(LIBC_NAMESPACE::mkdirat(AT_FDCWD, TEST_DIR, S_IRWXU),
Succeeds(0));

int fd = LIBC_NAMESPACE::open(TEST_DIR, O_PATH);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(fd, 0);

// create the file, assert it exists, then delete it and assert it doesn't
// exist anymore.

ASSERT_THAT(LIBC_NAMESPACE::fstatvfs(fd, &buf), Succeeds());

ASSERT_THAT(LIBC_NAMESPACE::rmdir(TEST_DIR), Succeeds(0));

ASSERT_THAT(LIBC_NAMESPACE::fstatvfs(fd, &buf), Fails(ENOENT));
ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
ASSERT_THAT(LIBC_NAMESPACE::fstatvfs(fd, &buf), Fails(ENOENT));
}
75 changes: 32 additions & 43 deletions libc/test/src/sys/statvfs/linux/statvfs_test.cpp
Original file line number Diff line number Diff line change
@@ -1,54 +1,43 @@
//===-- Unittests for statvfs ---------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "hdr/fcntl_macros.h"
#include "src/__support/macros/config.h"
#include "src/sys/statvfs/linux/statfs_utils.h"
#include "src/sys/stat/mkdirat.h"
#include "src/sys/statvfs/statvfs.h"
#include "src/unistd/rmdir.h"
#include "test/UnitTest/ErrnoSetterMatcher.h"
#include "test/UnitTest/LibcTest.h"
#include <linux/magic.h>
#include "test/UnitTest/Test.h"

using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;

#ifdef SYS_statfs64
using StatFs = statfs64;
#else
using StatFs = statfs;
#endif

namespace LIBC_NAMESPACE_DECL {
static int statfs(const char *path, StatFs *buf) {
using namespace statfs_utils;
if (cpp::optional<LinuxStatFs> result = linux_statfs(path)) {
*buf = *result;
return 0;
}
return -1;
}
} // namespace LIBC_NAMESPACE_DECL

TEST(LlvmLibcSysStatfsTest, StatfsBasic) {
StatFs buf;
ASSERT_THAT(LIBC_NAMESPACE::statfs("/", &buf), Succeeds());
ASSERT_THAT(LIBC_NAMESPACE::statfs("/proc", &buf), Succeeds());
ASSERT_EQ(buf.f_type, static_cast<decltype(buf.f_type)>(PROC_SUPER_MAGIC));
ASSERT_THAT(LIBC_NAMESPACE::statfs("/sys", &buf), Succeeds());
ASSERT_EQ(buf.f_type, static_cast<decltype(buf.f_type)>(SYSFS_MAGIC));
TEST(LlvmLibcSysStatvfsTest, StatvfsBasic) {
struct statvfs buf;
// The root of the file directory must always exist
ASSERT_THAT(LIBC_NAMESPACE::statvfs("/", &buf), Succeeds());
}

TEST(LlvmLibcSysStatfsTest, StatvfsInvalidPath) {
TEST(LlvmLibcSysStatvfsTest, StatvfsInvalidPath) {
struct statvfs buf;

ASSERT_THAT(LIBC_NAMESPACE::statvfs("", &buf), Fails(ENOENT));
ASSERT_THAT(LIBC_NAMESPACE::statvfs("/nonexistent", &buf), Fails(ENOENT));
ASSERT_THAT(LIBC_NAMESPACE::statvfs("/dev/null/whatever", &buf),
Fails(ENOTDIR));
ASSERT_THAT(LIBC_NAMESPACE::statvfs(nullptr, &buf), Fails(EFAULT));
}

TEST(LlvmLibcSysStatfsTest, StatvfsNameTooLong) {
struct statvfs buf;
ASSERT_THAT(LIBC_NAMESPACE::statvfs("/", &buf), Succeeds());
char *name = static_cast<char *>(__builtin_alloca(buf.f_namemax + 3));
name[0] = '/';
name[buf.f_namemax + 2] = '\0';
for (unsigned i = 1; i < buf.f_namemax + 2; ++i) {
name[i] = 'a';
}
ASSERT_THAT(LIBC_NAMESPACE::statvfs(name, &buf), Fails(ENAMETOOLONG));
// create the file, assert it exists, then delete it and assert it doesn't
// exist anymore.
constexpr const char *FILENAME = "testdata/statvfs.testdir";
auto TEST_DIR = libc_make_test_file_path(FILENAME);

ASSERT_THAT(LIBC_NAMESPACE::mkdirat(AT_FDCWD, TEST_DIR, S_IRWXU),
Succeeds(0));

ASSERT_THAT(LIBC_NAMESPACE::statvfs(TEST_DIR, &buf), Succeeds());

ASSERT_THAT(LIBC_NAMESPACE::rmdir(TEST_DIR), Succeeds(0));

ASSERT_THAT(LIBC_NAMESPACE::statvfs(TEST_DIR, &buf), Fails(ENOENT));
}

0 comments on commit 5d35747

Please sign in to comment.