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"
30namespace fs = std::filesystem;
31using namespace fs;
32
33static void signature_test() {
34 const path p;
35 ((void)p);
36 std::error_code ec;
37 ((void)ec);
38 ASSERT_NOEXCEPT(equivalent(p1: p, p2: p, ec&: ec));
39 ASSERT_NOT_NOEXCEPT(equivalent(p1: p, p2: p));
40}
41
42static 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
64static 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
95static 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
106static 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
120int 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

source code of libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.equivalent/equivalent.pass.cpp