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 // <filesystem>
15
16 // path read_symlink(const path& p);
17 // path read_symlink(const path& p, error_code& ec);
18
19 #include <filesystem>
20
21 #include "test_macros.h"
22 #include "filesystem_test_helper.h"
23 namespace fs = std::filesystem;
24 using namespace fs;
25
test_signatures()26 static void test_signatures()
27 {
28 const path p; ((void)p);
29 std::error_code ec; ((void)ec);
30 ASSERT_SAME_TYPE(decltype(fs::read_symlink(p)), fs::path);
31 ASSERT_SAME_TYPE(decltype(fs::read_symlink(p, ec)), fs::path);
32
33 ASSERT_NOT_NOEXCEPT(fs::read_symlink(p));
34 // Not noexcept because of narrow contract
35 ASSERT_NOT_NOEXCEPT(fs::read_symlink(p, ec));
36 }
37
test_error_reporting()38 static void test_error_reporting()
39 {
40 auto checkThrow = [](path const& f, const std::error_code& ec)
41 {
42 #ifndef TEST_HAS_NO_EXCEPTIONS
43 try {
44 (void)fs::read_symlink(f);
45 return false;
46 } catch (filesystem_error const& err) {
47 return err.path1() == f
48 && err.path2() == ""
49 && err.code() == ec;
50 }
51 #else
52 ((void)f); ((void)ec);
53 return true;
54 #endif
55 };
56
57 scoped_test_env env;
58 const path cases[] = {
59 env.make_env_path("dne"),
60 env.create_file("file", 42),
61 env.create_dir("dir")
62 };
63 for (path const& p : cases) {
64 std::error_code ec;
65 const path ret = fs::read_symlink(p, ec);
66 assert(ec);
67 assert(ret == path{});
68 assert(checkThrow(p, ec));
69 }
70
71 }
72
basic_symlink_test()73 static void basic_symlink_test()
74 {
75 scoped_test_env env;
76 const path dne = env.make_env_path("dne");
77 const path file = env.create_file("file", 42);
78 const path dir = env.create_dir("dir");
79 const path link = env.create_symlink(dne, "link");
80 const path nested_link = env.make_env_path("nested_link");
81 create_symlink(link, nested_link);
82 struct TestCase {
83 path symlink;
84 path expected;
85 } testCases[] = {
86 {env.create_symlink(dne, "dne_link"), dne},
87 {env.create_symlink(file, "file_link"), file},
88 {env.create_directory_symlink(dir, "dir_link"), dir},
89 {nested_link, link}
90 };
91 for (auto& TC : testCases) {
92 std::error_code ec = std::make_error_code(std::errc::address_in_use);
93 const path ret = read_symlink(TC.symlink, ec);
94 assert(!ec);
95 assert(ret == TC.expected);
96 }
97 }
98
main(int,char **)99 int main(int, char**) {
100 test_signatures();
101 test_error_reporting();
102 basic_symlink_test();
103
104 return 0;
105 }
106