libstdc++: Skip filesystem tests that depend on permissions [PR90787]

Tests that depend on filesystem permissions FAIL if run on Windows or as
root. Add a helper function to detect those cases, so the tests can skip
those checks gracefully.

Signed-off-by: Jonathan Wakely <jwakely@redhat.com>

libstdc++-v3/ChangeLog:

	PR libstdc++/90787
	* testsuite/27_io/filesystem/iterators/directory_iterator.cc:
	Use new __gnu_test::permissions_are_testable() function.
	* testsuite/27_io/filesystem/iterators/recursive_directory_iterator.cc:
	Likewise.
	* testsuite/27_io/filesystem/operations/exists.cc: Likewise.
	* testsuite/27_io/filesystem/operations/is_empty.cc: Likewise.
	* testsuite/27_io/filesystem/operations/remove.cc: Likewise.
	* testsuite/27_io/filesystem/operations/remove_all.cc: Likewise.
	* testsuite/27_io/filesystem/operations/status.cc: Likewise.
	* testsuite/27_io/filesystem/operations/symlink_status.cc:
	Likewise.
	* testsuite/27_io/filesystem/operations/temp_directory_path.cc:
	Likewise.
	* testsuite/experimental/filesystem/iterators/directory_iterator.cc:
	Likewise.
	* testsuite/experimental/filesystem/iterators/recursive_directory_iterator.cc:
	Likewise.
	* testsuite/experimental/filesystem/operations/exists.cc:
	Likewise.
	* testsuite/experimental/filesystem/operations/is_empty.cc:
	Likewise.
	* testsuite/experimental/filesystem/operations/remove.cc:
	Likewise.
	* testsuite/experimental/filesystem/operations/remove_all.cc:
	Likewise.
	* testsuite/experimental/filesystem/operations/temp_directory_path.cc:
	Likewise.
	* testsuite/util/testsuite_fs.h (__gnu_test::permissions_are_testable):
	New function to guess whether testing permissions will work.
This commit is contained in:
Jonathan Wakely 2021-08-20 14:51:06 +01:00
parent 1b507b1e3c
commit 29b2fd371f
17 changed files with 189 additions and 174 deletions

View file

@ -56,24 +56,26 @@ test01()
++iter;
VERIFY( iter == end(iter) );
#if !(defined(__MINGW32__) || defined(__MINGW64__))
// Test inaccessible directory.
ec = bad_ec;
permissions(p, fs::perms::none, ec);
VERIFY( !ec );
iter = fs::directory_iterator(p, ec);
VERIFY( ec );
VERIFY( iter == end(iter) );
if (__gnu_test::permissions_are_testable())
{
// Test inaccessible directory.
ec = bad_ec;
permissions(p, fs::perms::none, ec);
VERIFY( !ec );
iter = fs::directory_iterator(p, ec);
VERIFY( ec );
VERIFY( iter == end(iter) );
// Test inaccessible directory, skipping permission denied.
const auto opts = fs::directory_options::skip_permission_denied;
ec = bad_ec;
iter = fs::directory_iterator(p, opts, ec);
VERIFY( !ec );
VERIFY( iter == end(iter) );
#endif
// Test inaccessible directory, skipping permission denied.
const auto opts = fs::directory_options::skip_permission_denied;
ec = bad_ec;
iter = fs::directory_iterator(p, opts, ec);
VERIFY( !ec );
VERIFY( iter == end(iter) );
permissions(p, fs::perms::owner_all, ec);
}
permissions(p, fs::perms::owner_all, ec);
remove_all(p, ec);
}

View file

@ -59,54 +59,55 @@ test01()
++iter;
VERIFY( iter == end(iter) );
#if ! (defined (__MINGW32__) || defined(__MINGW64__))
// Test inaccessible directory.
ec = bad_ec;
permissions(p, fs::perms::none, ec);
VERIFY( !ec );
iter = fs::recursive_directory_iterator(p, ec);
VERIFY( ec );
VERIFY( iter == end(iter) );
if (__gnu_test::permissions_are_testable())
{
// Test inaccessible directory.
ec = bad_ec;
permissions(p, fs::perms::none, ec);
VERIFY( !ec );
iter = fs::recursive_directory_iterator(p, ec);
VERIFY( ec );
VERIFY( iter == end(iter) );
// Test inaccessible directory, skipping permission denied.
const auto opts = fs::directory_options::skip_permission_denied;
iter = fs::recursive_directory_iterator(p, opts, ec);
VERIFY( !ec );
VERIFY( iter == end(iter) );
// Test inaccessible directory, skipping permission denied.
const auto opts = fs::directory_options::skip_permission_denied;
iter = fs::recursive_directory_iterator(p, opts, ec);
VERIFY( !ec );
VERIFY( iter == end(iter) );
// Test inaccessible sub-directory.
ec = bad_ec;
permissions(p, fs::perms::owner_all, ec);
VERIFY( !ec );
ec = bad_ec;
permissions(p/"d1/d2", fs::perms::none, ec);
VERIFY( !ec );
ec = bad_ec;
iter = fs::recursive_directory_iterator(p, ec);
VERIFY( !ec );
VERIFY( iter != end(iter) );
VERIFY( iter->path() == p/"d1" );
++iter; // should recurse into d1
VERIFY( iter != end(iter) );
VERIFY( iter->path() == p/"d1/d2" );
iter.increment(ec); // should fail to recurse into p/d1/d2
VERIFY( ec );
VERIFY( iter == end(iter) );
// Test inaccessible sub-directory.
ec = bad_ec;
permissions(p, fs::perms::owner_all, ec);
VERIFY( !ec );
ec = bad_ec;
permissions(p/"d1/d2", fs::perms::none, ec);
VERIFY( !ec );
ec = bad_ec;
iter = fs::recursive_directory_iterator(p, ec);
VERIFY( !ec );
VERIFY( iter != end(iter) );
VERIFY( iter->path() == p/"d1" );
++iter; // should recurse into d1
VERIFY( iter != end(iter) );
VERIFY( iter->path() == p/"d1/d2" );
iter.increment(ec); // should fail to recurse into p/d1/d2
VERIFY( ec );
VERIFY( iter == end(iter) );
// Test inaccessible sub-directory, skipping permission denied.
ec = bad_ec;
iter = fs::recursive_directory_iterator(p, opts, ec);
VERIFY( !ec );
VERIFY( iter != end(iter) );
VERIFY( iter->path() == p/"d1" );
++iter; // should recurse into d1
VERIFY( iter != end(iter) );
VERIFY( iter->path() == p/"d1/d2" );
ec = bad_ec;
iter.increment(ec); // should fail to recurse into p/d1/d2, so skip it
VERIFY( !ec );
VERIFY( iter == end(iter) );
#endif
// Test inaccessible sub-directory, skipping permission denied.
ec = bad_ec;
iter = fs::recursive_directory_iterator(p, opts, ec);
VERIFY( !ec );
VERIFY( iter != end(iter) );
VERIFY( iter->path() == p/"d1" );
++iter; // should recurse into d1
VERIFY( iter != end(iter) );
VERIFY( iter->path() == p/"d1/d2" );
ec = bad_ec;
iter.increment(ec); // should fail to recurse into p/d1/d2, so skip it
VERIFY( !ec );
VERIFY( iter == end(iter) );
}
permissions(p/"d1/d2", fs::perms::owner_all, ec);
remove_all(p, ec);

View file

@ -79,10 +79,8 @@ test03()
void
test04()
{
#if defined(__MINGW32__) || defined(__MINGW64__)
// filesystem permissions not supported
return;
#endif
if (!__gnu_test::permissions_are_testable())
return;
using std::filesystem::perms;
using std::filesystem::perm_options;

View file

@ -27,10 +27,8 @@ namespace fs = std::filesystem;
void
test01()
{
#if defined(__MINGW32__) || defined(__MINGW64__)
// filesystem permissions not supported
return;
#endif
if (!__gnu_test::permissions_are_testable())
return;
auto p = __gnu_test::nonexistent_path();
create_directory(p);

View file

@ -76,19 +76,18 @@ test01()
VERIFY( !n );
VERIFY( exists(dir/"a/b") );
#if defined(__MINGW32__) || defined(__MINGW64__)
// No permissions support
#else
permissions(dir, fs::perms::none, ec);
if (!ec)
if (__gnu_test::permissions_are_testable())
{
ec.clear();
n = remove(dir/"a/b", ec);
VERIFY( ec );
VERIFY( !n );
permissions(dir, fs::perms::owner_all, ec);
permissions(dir, fs::perms::none, ec);
if (!ec)
{
ec.clear();
n = remove(dir/"a/b", ec);
VERIFY( ec );
VERIFY( !n );
permissions(dir, fs::perms::owner_all, ec);
}
}
#endif
ec = bad_ec;
n = remove(dir/"a/b", ec);

View file

@ -142,9 +142,9 @@ test03()
void
test04()
{
#if defined(__MINGW32__) || defined(__MINGW64__)
// no permissions
#else
if (!__gnu_test::permissions_are_testable())
return;
// PR libstdc++/93201
std::error_code ec;
std::uintmax_t n;
@ -172,7 +172,6 @@ test04()
fs::permissions(dir, fs::perms::owner_write, fs::perm_options::add);
fs::remove_all(dir, ec);
f.path.clear();
#endif
}
int

View file

@ -55,10 +55,8 @@ test02()
void
test03()
{
#if defined(__MINGW32__) || defined(__MINGW64__)
// No permissions support
return;
#endif
if (!__gnu_test::permissions_are_testable())
return;
fs::path dir = __gnu_test::nonexistent_path();
fs::create_directory(dir);

View file

@ -68,6 +68,9 @@ test02()
void
test03()
{
if (!__gnu_test::permissions_are_testable())
return;
fs::path dir = __gnu_test::nonexistent_path();
fs::create_directory(dir);
__gnu_test::scoped_file d(dir, __gnu_test::scoped_file::adopt_file);

View file

@ -101,10 +101,8 @@ test02()
void
test03()
{
#if defined(__MINGW32__) || defined(__MINGW64__)
// No permissions support
return;
#endif
if (!__gnu_test::permissions_are_testable())
return;
clean_env();

View file

@ -53,22 +53,24 @@ test01()
++iter;
VERIFY( iter == end(iter) );
#if !(defined(__MINGW32__) || defined(__MINGW64__))
// Test inaccessible directory.
permissions(p, fs::perms::none, ec);
VERIFY( !ec );
iter = fs::directory_iterator(p, ec);
VERIFY( ec );
VERIFY( iter == end(iter) );
if (__gnu_test::permissions_are_testable())
{
// Test inaccessible directory.
permissions(p, fs::perms::none, ec);
VERIFY( !ec );
iter = fs::directory_iterator(p, ec);
VERIFY( ec );
VERIFY( iter == end(iter) );
// Test inaccessible directory, skipping permission denied.
const auto opts = fs::directory_options::skip_permission_denied;
iter = fs::directory_iterator(p, opts, ec);
VERIFY( !ec );
VERIFY( iter == end(iter) );
#endif
// Test inaccessible directory, skipping permission denied.
const auto opts = fs::directory_options::skip_permission_denied;
iter = fs::directory_iterator(p, opts, ec);
VERIFY( !ec );
VERIFY( iter == end(iter) );
permissions(p, fs::perms::owner_all, ec);
}
permissions(p, fs::perms::owner_all, ec);
remove_all(p, ec);
}

View file

@ -61,54 +61,58 @@ test01()
++iter;
VERIFY( iter == end(iter) );
// Test inaccessible directory.
ec = bad_ec;
permissions(p, fs::perms::none, ec);
VERIFY( !ec );
iter = fs::recursive_directory_iterator(p, ec);
VERIFY( ec );
VERIFY( iter == end(iter) );
if (__gnu_test::permissions_are_testable())
{
// Test inaccessible directory.
ec = bad_ec;
permissions(p, fs::perms::none, ec);
VERIFY( !ec );
iter = fs::recursive_directory_iterator(p, ec);
VERIFY( ec );
VERIFY( iter == end(iter) );
// Test inaccessible directory, skipping permission denied.
const auto opts = fs::directory_options::skip_permission_denied;
ec = bad_ec;
iter = fs::recursive_directory_iterator(p, opts, ec);
VERIFY( !ec );
VERIFY( iter == end(iter) );
// Test inaccessible directory, skipping permission denied.
const auto opts = fs::directory_options::skip_permission_denied;
ec = bad_ec;
iter = fs::recursive_directory_iterator(p, opts, ec);
VERIFY( !ec );
VERIFY( iter == end(iter) );
// Test inaccessible sub-directory.
ec = bad_ec;
permissions(p, fs::perms::owner_all, ec);
VERIFY( !ec );
ec = bad_ec;
permissions(p/"d1/d2", fs::perms::none, ec);
VERIFY( !ec );
ec = bad_ec;
iter = fs::recursive_directory_iterator(p, ec);
VERIFY( !ec );
VERIFY( iter != end(iter) );
VERIFY( iter->path() == p/"d1" );
++iter; // should recurse into d1
VERIFY( iter != end(iter) );
VERIFY( iter->path() == p/"d1/d2" );
iter.increment(ec); // should fail to recurse into p/d1/d2
VERIFY( ec );
VERIFY( iter == end(iter) );
// Test inaccessible sub-directory.
ec = bad_ec;
permissions(p, fs::perms::owner_all, ec);
VERIFY( !ec );
ec = bad_ec;
permissions(p/"d1/d2", fs::perms::none, ec);
VERIFY( !ec );
ec = bad_ec;
iter = fs::recursive_directory_iterator(p, ec);
VERIFY( !ec );
VERIFY( iter != end(iter) );
VERIFY( iter->path() == p/"d1" );
++iter; // should recurse into d1
VERIFY( iter != end(iter) );
VERIFY( iter->path() == p/"d1/d2" );
iter.increment(ec); // should fail to recurse into p/d1/d2
VERIFY( ec );
VERIFY( iter == end(iter) );
// Test inaccessible sub-directory, skipping permission denied.
ec = bad_ec;
iter = fs::recursive_directory_iterator(p, opts, ec);
VERIFY( !ec );
VERIFY( iter != end(iter) );
VERIFY( iter->path() == p/"d1" );
++iter; // should recurse into d1
VERIFY( iter->path() == p/"d1/d2" );
ec = bad_ec;
iter.increment(ec); // should fail to recurse into p/d1/d2, so skip it
VERIFY( !ec );
VERIFY( iter == end(iter) );
// Test inaccessible sub-directory, skipping permission denied.
ec = bad_ec;
iter = fs::recursive_directory_iterator(p, opts, ec);
VERIFY( !ec );
VERIFY( iter != end(iter) );
VERIFY( iter->path() == p/"d1" );
++iter; // should recurse into d1
VERIFY( iter->path() == p/"d1/d2" );
ec = bad_ec;
iter.increment(ec); // should fail to recurse into p/d1/d2, so skip it
VERIFY( !ec );
VERIFY( iter == end(iter) );
permissions(p/"d1/d2", fs::perms::owner_all, ec);
}
permissions(p/"d1/d2", fs::perms::owner_all, ec);
remove_all(p, ec);
}

View file

@ -74,10 +74,8 @@ test03()
void
test04()
{
#if defined(__MINGW32__) || defined(__MINGW64__)
// filesystem permissions not supported
return;
#endif
if (!__gnu_test::permissions_are_testable())
return;
using perms = std::experimental::filesystem::perms;
path p = __gnu_test::nonexistent_path();

View file

@ -28,10 +28,8 @@ namespace fs = std::experimental::filesystem;
void
test01()
{
#if defined(__MINGW32__) || defined(__MINGW64__)
// filesystem permissions not supported
return;
#endif
if (!__gnu_test::permissions_are_testable())
return;
auto p = __gnu_test::nonexistent_path();
create_directory(p);

View file

@ -78,19 +78,18 @@ test01()
VERIFY( !n );
VERIFY( exists(dir/"a/b") );
#if defined(__MINGW32__) || defined(__MINGW64__)
// No permissions support
#else
permissions(dir, fs::perms::none, ec);
if (!ec)
if (__gnu_test::permissions_are_testable())
{
ec.clear();
n = remove(dir/"a/b", ec);
VERIFY( ec );
VERIFY( !n );
permissions(dir, fs::perms::owner_all, ec);
permissions(dir, fs::perms::none, ec);
if (!ec)
{
ec.clear();
n = remove(dir/"a/b", ec);
VERIFY( ec );
VERIFY( !n );
permissions(dir, fs::perms::owner_all, ec);
}
}
#endif
ec = bad_ec;
n = remove(dir/"a/b", ec);

View file

@ -111,9 +111,9 @@ test02()
void
test04()
{
#if defined(__MINGW32__) || defined(__MINGW64__)
// no permissions
#else
if (!__gnu_test::permissions_are_testable())
return;
// PR libstdc++/93201
std::error_code ec;
std::uintmax_t n;
@ -139,7 +139,6 @@ test04()
fs::permissions(dir, fs::perms::owner_write|fs::perms::add_perms);
fs::remove_all(dir, ec);
f.path.clear();
#endif
}
int

View file

@ -102,6 +102,9 @@ test02()
void
test03()
{
if (!__gnu_test::permissions_are_testable())
return;
auto p = __gnu_test::nonexistent_path();
create_directories(p/"tmp");
permissions(p, fs::perms::none);

View file

@ -34,7 +34,7 @@ namespace test_fs = std::experimental::filesystem;
#include <fstream>
#include <string>
#include <cstdio>
#include <unistd.h> // unlink, close, getpid
#include <unistd.h> // unlink, close, getpid, geteuid
#if defined(_GNU_SOURCE) || _XOPEN_SOURCE >= 500 || _POSIX_C_SOURCE >= 200112L
#include <stdlib.h> // mkstemp
@ -160,5 +160,21 @@ namespace __gnu_test
path_type path;
};
bool
permissions_are_testable(bool print_msg = true)
{
bool testable = false;
#if !(defined __MINGW32__ || defined __MINGW64__)
if (geteuid() != 0)
testable = true;
// XXX on Linux the CAP_DAC_OVERRIDE and CAP_DAC_READ_SEARCH capabilities
// can give normal users extra permissions for files and directories.
// We ignore that possibility here.
#endif
if (print_msg && !testable)
std::puts("Skipping tests that depend on filesystem permissions");
return testable;
}
} // namespace __gnu_test
#endif