skip ioctl-using tests when not supported

Summary:
[NB: this is a prerequisite for the /tmp-abuse-fixing patch]
This avoids spurious test failure on Linux systems
like Fedora for which /tmp is a tmpfs file system.

On a devtmpfs file
system, ioctl(fd, FS_IOC_GETVERSION, &version) returns -1 with
errno == ENOTTTY, indicating that that ioctl is not supported
on such a file system.  Do not let this cause test failures, e.g.,
where env_test would assert that file->GetUniqueId(...) > 0.

Before this change, ./env_test would fail these three tests
on a fedora rawhide system:

  [  FAILED  ] 3 tests, listed below:
  [  FAILED  ] EnvPosixTest.RandomAccessUniqueID
  [  FAILED  ] EnvPosixTest.RandomAccessUniqueIDConcurrent
  [  FAILED  ] EnvPosixTest.RandomAccessUniqueIDDeletes
   3 FAILED TESTS

The fix:
  When support for that ioctl is lacking, skip each affected test.
  Could be improved by noting which sub-tests are being skipped.

Test Plan:
run these on F21 and note that they now pass.

  TEST_TMPDIR=/dev/shm/rdb ./env_test
  ./env_test

Reviewers: ljin, rven, igor.sugak, yhchiang, sdong, igor

Reviewed By: igor

Subscribers: dhruba

Differential Revision: https://reviews.facebook.net/D37323
This commit is contained in:
Jim Meyering 2015-04-17 20:39:02 -07:00
parent 6059bdf86a
commit 79c21ec0c4
1 changed files with 34 additions and 0 deletions

View File

@ -8,12 +8,15 @@
// found in the LICENSE file. See the AUTHORS file for names of contributors. // found in the LICENSE file. See the AUTHORS file for names of contributors.
#include <sys/types.h> #include <sys/types.h>
#include <sys/ioctl.h>
#include <iostream> #include <iostream>
#include <unordered_set> #include <unordered_set>
#include <atomic> #include <atomic>
#ifdef OS_LINUX #ifdef OS_LINUX
#include <linux/fs.h>
#include <stdlib.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#endif #endif
@ -506,10 +509,35 @@ std::string GetOnDiskTestDir() {
return base; return base;
} }
// Determine whether we can use the FS_IOC_GETVERSION ioctl
// on a file in GetOnDiskTestDir(). Create a temporary file,
// try to apply the ioctl (save that result), cleanup and
// return the result. Return true if it is supported, and
// false if anything fails.
bool ioctl_support__FS_IOC_GETVERSION(void) {
std::string file_ro = GetOnDiskTestDir() + "/XXXXXX";
auto *file = new char[file_ro.size() + 1];
memcpy(file, file_ro.data(), file_ro.size() + 1);
int fd = mkstemp(file);
long int version;
bool ok = (fd >= 0 && ioctl(fd, FS_IOC_GETVERSION, &version) >= 0);
close(fd);
unlink(file);
delete[] file;
return ok;
}
} // namespace } // namespace
// Only works in linux platforms // Only works in linux platforms
TEST_F(EnvPosixTest, RandomAccessUniqueID) { TEST_F(EnvPosixTest, RandomAccessUniqueID) {
if (!ioctl_support__FS_IOC_GETVERSION()) {
return;
}
// Create file. // Create file.
const EnvOptions soptions; const EnvOptions soptions;
std::string fname = GetOnDiskTestDir() + "/" + "testfile"; std::string fname = GetOnDiskTestDir() + "/" + "testfile";
@ -630,6 +658,9 @@ bool HasPrefix(const std::unordered_set<std::string>& ss) {
// Only works in linux platforms // Only works in linux platforms
TEST_F(EnvPosixTest, RandomAccessUniqueIDConcurrent) { TEST_F(EnvPosixTest, RandomAccessUniqueIDConcurrent) {
if (!ioctl_support__FS_IOC_GETVERSION()) {
return;
}
// Check whether a bunch of concurrently existing files have unique IDs. // Check whether a bunch of concurrently existing files have unique IDs.
const EnvOptions soptions; const EnvOptions soptions;
@ -669,6 +700,9 @@ TEST_F(EnvPosixTest, RandomAccessUniqueIDConcurrent) {
// Only works in linux platforms // Only works in linux platforms
TEST_F(EnvPosixTest, RandomAccessUniqueIDDeletes) { TEST_F(EnvPosixTest, RandomAccessUniqueIDDeletes) {
if (!ioctl_support__FS_IOC_GETVERSION()) {
return;
}
const EnvOptions soptions; const EnvOptions soptions;
std::string fname = GetOnDiskTestDir() + "/" + "testfile"; std::string fname = GetOnDiskTestDir() + "/" + "testfile";