Skip to content

Commit

Permalink
Canonicalize root paths in tests.
Browse files Browse the repository at this point in the history
Since the current and initial paths on Windows may have non-canonical
root paths (i.e. "c:\" instead of "C:\"), path comparisons may fail
because of the case differences between the canonicalized paths and
the expected paths. To avoid these spurious failures, canonicalize root
paths in all expected paths.
  • Loading branch information
Lastique committed Oct 11, 2024
1 parent cf92e38 commit 0848f53
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 17 deletions.
17 changes: 15 additions & 2 deletions test/issues/99_canonical_with_junction_point.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,25 @@ struct TmpDir
}
};

//! Converts root path of the argument to canonical form, i.e. "C:\" instead of "c:\".
inline fs::path canonicalize_root_path(fs::path const& p)
{
fs::path root_path = p.root_path();
if (root_path.empty())
return p;
root_path = fs::canonical(root_path);
fs::path rel_path = p.relative_path();
if (!rel_path.empty())
root_path.append(rel_path);
return root_path;
}

// Test fs::canonical for various path in a Windows directory junction point
// This failed before due to broken handling of absolute paths and ignored ReparseTag
int main()
{

const fs::path cwd = fs::current_path();
// Note: Use cacnonical form of the root path in all subsequent paths to make path comparisons more stable
const fs::path cwd = canonicalize_root_path(fs::current_path());
const TmpDir tmp(cwd);
const fs::path junction = tmp.path / "junction";
const fs::path real = tmp.path / "real";
Expand Down
50 changes: 35 additions & 15 deletions test/operations_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,19 @@ inline void unsetenv_(const char* name)

#endif

//! Converts root path of the argument to canonical form, i.e. "C:\" instead of "c:\" on Windows.
inline fs::path canonicalize_root_path(fs::path const& p)
{
fs::path root_path = p.root_path();
if (root_path.empty())
return p;
root_path = fs::canonical(root_path);
fs::path rel_path = p.relative_path();
if (!rel_path.empty())
root_path.append(rel_path);
return root_path;
}

#define CHECK_EXCEPTION(Functor, Expect) throws_fs_error(Functor, Expect, __LINE__)

namespace {
Expand Down Expand Up @@ -1780,17 +1793,20 @@ void canonical_basic_tests()
}
BOOST_TEST(ok);

// Note: Use cacnonical form of the root path in all paths to make path comparisons more stable
const fs::path cur_path = canonicalize_root_path(fs::current_path());

// non-symlink tests; also see canonical_symlink_tests()
BOOST_TEST_EQ(fs::canonical(""), fs::current_path());
BOOST_TEST_EQ(fs::canonical("", fs::current_path()), fs::current_path());
BOOST_TEST_EQ(fs::canonical("", ""), fs::current_path());
BOOST_TEST_EQ(fs::canonical(fs::current_path()), fs::current_path());
BOOST_TEST_EQ(fs::canonical(fs::current_path(), ""), fs::current_path());
BOOST_TEST_EQ(fs::canonical(fs::current_path(), "no-such-file"), fs::current_path());
BOOST_TEST_EQ(fs::canonical(""), cur_path);
BOOST_TEST_EQ(fs::canonical("", fs::current_path()), cur_path);
BOOST_TEST_EQ(fs::canonical("", ""), cur_path);
BOOST_TEST_EQ(fs::canonical(fs::current_path()), cur_path);
BOOST_TEST_EQ(fs::canonical(fs::current_path(), ""), cur_path);
BOOST_TEST_EQ(fs::canonical(fs::current_path(), "no-such-file"), cur_path);

BOOST_TEST_EQ(fs::canonical("."), fs::current_path());
BOOST_TEST_EQ(fs::canonical(".."), fs::current_path().parent_path());
BOOST_TEST_EQ(fs::canonical("/"), fs::current_path().root_path());
BOOST_TEST_EQ(fs::canonical("."), cur_path);
BOOST_TEST_EQ(fs::canonical(".."), cur_path.parent_path());
BOOST_TEST_EQ(fs::canonical("/"), cur_path.root_path());

fs::path relative_dir(dir.filename());
BOOST_TEST_EQ(fs::canonical(dir), dir);
Expand All @@ -1801,7 +1817,7 @@ void canonical_basic_tests()
BOOST_TEST_EQ(fs::canonical(relative_dir / "d1/../f0"), dir / "f0");

// treat parent of root as itself on both POSIX and Windows
fs::path init(fs::initial_path());
fs::path init(canonicalize_root_path(fs::initial_path()));
fs::path root(init.root_path());
fs::path::const_iterator it(init.begin());
fs::path first; // relative first non-root directory
Expand Down Expand Up @@ -2825,8 +2841,11 @@ void weakly_canonical_basic_tests()
cout << "weakly_canonical_basic_tests..." << endl;
cout << " dir is " << dir << endl;

BOOST_TEST_EQ(fs::weakly_canonical("no-such/foo/bar"), fs::current_path() / fs::path("no-such/foo/bar"));
BOOST_TEST_EQ(fs::weakly_canonical("no-such/foo/../bar"), fs::current_path() / fs::path("no-such/bar"));
// Note: Use cacnonical form of the root path in all paths to make path comparisons more stable
const fs::path cur_path = canonicalize_root_path(fs::current_path());

BOOST_TEST_EQ(fs::weakly_canonical("no-such/foo/bar"), cur_path / fs::path("no-such/foo/bar"));
BOOST_TEST_EQ(fs::weakly_canonical("no-such/foo/../bar"), cur_path / fs::path("no-such/bar"));
BOOST_TEST_EQ(fs::weakly_canonical(dir), dir);
BOOST_TEST_EQ(fs::weakly_canonical(dir / "no-such/foo/bar"), dir / "no-such/foo/bar");
BOOST_TEST_EQ(fs::weakly_canonical(dir / "no-such/foo/../bar"), dir / "no-such/bar");
Expand Down Expand Up @@ -2910,8 +2929,8 @@ int cpp_main(int argc, char* argv[])
#error neither BOOST_POSIX_API nor BOOST_WINDOWS_API is defined. See boost/system/api_config.hpp
#endif
cout << "API is " << platform << endl;
cout << "initial_path() is " << fs::initial_path() << endl;
fs::path ip = fs::initial_path();
const fs::path ip = fs::initial_path();
cout << "initial_path() is " << ip << endl;
do_the_right_thing_tests(); // compile-only tests, but call anyhow to suppress warnings

for (fs::path::const_iterator it = ip.begin(); it != ip.end(); ++it)
Expand All @@ -2922,7 +2941,8 @@ int cpp_main(int argc, char* argv[])
}
cout << endl;

dir = fs::initial_path() / temp_dir;
// Note: Use cacnonical form of the root path in all subsequent paths to make path comparisons more stable
dir = canonicalize_root_path(ip / temp_dir);

if (fs::exists(dir))
{
Expand Down

0 comments on commit 0848f53

Please sign in to comment.