xref: /llvm-project/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.exists/exists.pass.cpp (revision 4c5bc7667728d5383c41eb8a20dd5e49257904d2)
1f7b43230SLouis Dionne //===----------------------------------------------------------------------===//
2f7b43230SLouis Dionne //
3f7b43230SLouis Dionne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4f7b43230SLouis Dionne // See https://llvm.org/LICENSE.txt for license information.
5f7b43230SLouis Dionne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f7b43230SLouis Dionne //
7f7b43230SLouis Dionne //===----------------------------------------------------------------------===//
8f7b43230SLouis Dionne 
9*4c5bc766SRodrigo Salazar // REQUIRES: can-create-symlinks
10ac8c9f1eSLouis Dionne // UNSUPPORTED: c++03, c++11, c++14
11c352fa74SLouis Dionne // UNSUPPORTED: no-filesystem
12c352fa74SLouis Dionne // UNSUPPORTED: availability-filesystem-missing
133d405081SLouis Dionne 
14f7b43230SLouis Dionne // <filesystem>
15f7b43230SLouis Dionne 
16f7b43230SLouis Dionne // bool exists(file_status s) noexcept
17f7b43230SLouis Dionne // bool exists(path const& p);
18f7b43230SLouis Dionne // bool exists(path const& p, std::error_code& ec) noexcept;
19f7b43230SLouis Dionne 
20ac8c9f1eSLouis Dionne #include <filesystem>
21f7b43230SLouis Dionne #include <type_traits>
22f7b43230SLouis Dionne #include <cassert>
23f7b43230SLouis Dionne 
242f2ed477SMark de Wever #include "assert_macros.h"
25f7b43230SLouis Dionne #include "test_macros.h"
26cc89063bSNico Weber #include "filesystem_test_helper.h"
27ac8c9f1eSLouis Dionne namespace fs = std::filesystem;
28f7b43230SLouis Dionne using namespace fs;
29f7b43230SLouis Dionne 
signature_test()302f2ed477SMark de Wever static void signature_test()
31f7b43230SLouis Dionne {
32f7b43230SLouis Dionne     file_status s; ((void)s);
33f7b43230SLouis Dionne     const path p; ((void)p);
34f7b43230SLouis Dionne     std::error_code ec; ((void)ec);
35f7b43230SLouis Dionne     ASSERT_NOEXCEPT(exists(s));
36f7b43230SLouis Dionne     ASSERT_NOEXCEPT(exists(p, ec));
37f7b43230SLouis Dionne     ASSERT_NOT_NOEXCEPT(exists(p));
38f7b43230SLouis Dionne }
39f7b43230SLouis Dionne 
exists_status_test()402f2ed477SMark de Wever static void exists_status_test()
41f7b43230SLouis Dionne {
42f7b43230SLouis Dionne     struct TestCase {
43f7b43230SLouis Dionne         file_type type;
44f7b43230SLouis Dionne         bool expect;
45f7b43230SLouis Dionne     };
46f7b43230SLouis Dionne     const TestCase testCases[] = {
47f7b43230SLouis Dionne         {file_type::none, false},
48f7b43230SLouis Dionne         {file_type::not_found, false},
49f7b43230SLouis Dionne         {file_type::regular, true},
50f7b43230SLouis Dionne         {file_type::directory, true},
51f7b43230SLouis Dionne         {file_type::symlink, true},
52f7b43230SLouis Dionne         {file_type::block, true},
53f7b43230SLouis Dionne         {file_type::character, true},
54f7b43230SLouis Dionne         {file_type::fifo, true},
55f7b43230SLouis Dionne         {file_type::socket, true},
56f7b43230SLouis Dionne         {file_type::unknown, true}
57f7b43230SLouis Dionne     };
58f7b43230SLouis Dionne     for (auto& TC : testCases) {
59f7b43230SLouis Dionne         file_status s(TC.type);
602f2ed477SMark de Wever         assert(exists(s) == TC.expect);
61f7b43230SLouis Dionne     }
62f7b43230SLouis Dionne }
63f7b43230SLouis Dionne 
test_exist_not_found()642f2ed477SMark de Wever static void test_exist_not_found()
65f7b43230SLouis Dionne {
66b62ce9e0SSergej Jaskiewicz     static_test_env static_env;
67b62ce9e0SSergej Jaskiewicz     const path p = static_env.DNE;
682f2ed477SMark de Wever     assert(exists(p) == false);
69f7b43230SLouis Dionne 
702f2ed477SMark de Wever     assert(exists(static_env.Dir) == true);
712f2ed477SMark de Wever     assert(exists(static_env.Dir / "dne") == false);
727a154c32SMartin Storsjö     // Whether <dir>/dne/.. is considered to exist or not is not necessarily
737a154c32SMartin Storsjö     // something we need to define, but the platform specific behaviour
747a154c32SMartin Storsjö     // does affect a few other tests, so clarify the root cause here.
757a154c32SMartin Storsjö #ifdef _WIN32
762f2ed477SMark de Wever     assert(exists(static_env.Dir / "dne" / "..") == true);
777a154c32SMartin Storsjö #else
782f2ed477SMark de Wever     assert(exists(static_env.Dir / "dne" / "..") == false);
797a154c32SMartin Storsjö #endif
807a154c32SMartin Storsjö 
81f7b43230SLouis Dionne     std::error_code ec = GetTestEC();
822f2ed477SMark de Wever     assert(exists(p, ec) == false);
832f2ed477SMark de Wever     assert(!ec);
84f7b43230SLouis Dionne }
85f7b43230SLouis Dionne 
test_exists_fails()862f2ed477SMark de Wever static void test_exists_fails()
87f7b43230SLouis Dionne {
88e69c65d5SMartin Storsjö #ifdef _WIN32
89e69c65d5SMartin Storsjö     // Windows doesn't support setting perms::none to trigger failures
90e69c65d5SMartin Storsjö     // reading directories; test using a special inaccessible directory
91e69c65d5SMartin Storsjö     // instead.
92e69c65d5SMartin Storsjö     const path p = GetWindowsInaccessibleDir();
93a9a7498bSMartin Storsjö     if (p.empty())
942f2ed477SMark de Wever         return;
95e69c65d5SMartin Storsjö #else
96f7b43230SLouis Dionne     scoped_test_env env;
97f7b43230SLouis Dionne     const path dir = env.create_dir("dir");
98e69c65d5SMartin Storsjö     const path p = env.create_file("dir/file", 42);
99f7b43230SLouis Dionne     permissions(dir, perms::none);
100e69c65d5SMartin Storsjö #endif
101f7b43230SLouis Dionne 
102f7b43230SLouis Dionne     std::error_code ec;
1032f2ed477SMark de Wever     assert(exists(p, ec) == false);
1042f2ed477SMark de Wever     assert(ec);
105f7b43230SLouis Dionne 
1062f2ed477SMark de Wever     TEST_THROWS_TYPE(filesystem_error, exists(p));
107f7b43230SLouis Dionne }
108f7b43230SLouis Dionne 
1098ba05e14SMartin Storsjö #ifndef _WIN32
1108ba05e14SMartin Storsjö // Checking for the existence of an invalid long path name doesn't
1118ba05e14SMartin Storsjö // trigger errors on windows.
test_name_too_long()1122f2ed477SMark de Wever static void test_name_too_long() {
113f7b43230SLouis Dionne     std::string long_name(2500, 'a');
114f7b43230SLouis Dionne     const path file(long_name);
115f7b43230SLouis Dionne 
116f7b43230SLouis Dionne     std::error_code ec;
1172f2ed477SMark de Wever     assert(exists(file, ec) == false);
1182f2ed477SMark de Wever     assert(ec);
119f7b43230SLouis Dionne }
1202f2ed477SMark de Wever #endif // _WIN32
1212f2ed477SMark de Wever 
main(int,char **)1222f2ed477SMark de Wever int main(int, char**) {
1232f2ed477SMark de Wever     signature_test();
1242f2ed477SMark de Wever     exists_status_test();
1252f2ed477SMark de Wever     test_exist_not_found();
1262f2ed477SMark de Wever     test_exists_fails();
1272f2ed477SMark de Wever #ifndef _WIN32
1282f2ed477SMark de Wever     test_name_too_long();
1298ba05e14SMartin Storsjö #endif
130f7b43230SLouis Dionne 
1312f2ed477SMark de Wever     return 0;
1322f2ed477SMark de Wever }
133