130 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// REQUIRES: can-create-symlinks10// UNSUPPORTED: c++03, c++11, c++1411// UNSUPPORTED: no-filesystem12 13// Starting in Android N (API 24), SELinux policy prevents the shell user from14// creating a hard link.15// XFAIL: LIBCXX-ANDROID-FIXME && !android-device-api={{21|22|23}}16 17// <filesystem>18 19// bool equivalent(path const& lhs, path const& rhs);20// bool equivalent(path const& lhs, path const& rhs, std::error_code& ec) noexcept;21 22#include <filesystem>23#include <type_traits>24#include <cassert>25 26#include "assert_macros.h"27#include "test_macros.h"28#include "filesystem_test_helper.h"29namespace fs = std::filesystem;30using namespace fs;31 32static void signature_test() {33 const path p;34 ((void)p);35 std::error_code ec;36 ((void)ec);37 ASSERT_NOEXCEPT(equivalent(p, p, ec));38 ASSERT_NOT_NOEXCEPT(equivalent(p, p));39}40 41static void equivalent_test() {42 static_test_env static_env;43 struct TestCase {44 path lhs;45 path rhs;46 bool expect;47 };48 const TestCase testCases[] = {49 {static_env.Dir, static_env.Dir, true},50 {static_env.File, static_env.Dir, false},51 {static_env.Dir, static_env.SymlinkToDir, true},52 {static_env.Dir, static_env.SymlinkToFile, false},53 {static_env.File, static_env.File, true},54 {static_env.File, static_env.SymlinkToFile, true},55 };56 for (auto& TC : testCases) {57 std::error_code ec;58 assert(equivalent(TC.lhs, TC.rhs, ec) == TC.expect);59 assert(!ec);60 }61}62 63static void equivalent_reports_error_if_input_dne() {64 static_test_env static_env;65 const path E = static_env.File;66 const path DNE = static_env.DNE;67 { // Test that an error is reported when either of the paths don't exist68 std::error_code ec = GetTestEC();69 assert(equivalent(E, DNE, ec) == false);70 assert(ec);71 assert(ec != GetTestEC());72 }73 {74 std::error_code ec = GetTestEC();75 assert(equivalent(DNE, E, ec) == false);76 assert(ec);77 assert(ec != GetTestEC());78 }79 {80 TEST_THROWS_TYPE(filesystem_error, equivalent(DNE, E));81 TEST_THROWS_TYPE(filesystem_error, equivalent(E, DNE));82 }83 { // Test that an exception is thrown if both paths do not exist.84 TEST_THROWS_TYPE(filesystem_error, equivalent(DNE, DNE));85 }86 {87 std::error_code ec = GetTestEC();88 assert(equivalent(DNE, DNE, ec) == false);89 assert(ec);90 assert(ec != GetTestEC());91 }92}93 94static void equivalent_hardlink_succeeds() {95 scoped_test_env env;96 path const file = env.create_file("file", 42);97 const path hl1 = env.create_hardlink(file, "hl1");98 const path hl2 = env.create_hardlink(file, "hl2");99 assert(equivalent(file, hl1));100 assert(equivalent(file, hl2));101 assert(equivalent(hl1, hl2));102}103 104#ifndef _WIN32105static void equivalent_is_other_succeeds() {106 scoped_test_env env;107 path const file = env.create_file("file", 42);108 const path fifo1 = env.create_fifo("fifo1");109 const path fifo2 = env.create_fifo("fifo2");110 // Required to test behavior for inputs where is_other(p) is true.111 assert(is_other(fifo1));112 assert(!equivalent(file, fifo1));113 assert(!equivalent(fifo2, file));114 assert(!equivalent(fifo1, fifo2));115 assert(equivalent(fifo1, fifo1));116}117#endif // _WIN32118 119int main(int, char**) {120 signature_test();121 equivalent_test();122 equivalent_reports_error_if_input_dne();123 equivalent_hardlink_succeeds();124#ifndef _WIN32125 equivalent_is_other_succeeds();126#endif127 128 return 0;129}130