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