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 // UNSUPPORTED: c++03
10
11 // <filesystem>
12
13 // path temp_directory_path();
14 // path temp_directory_path(error_code& ec);
15
16 #include "filesystem_include.h"
17 #include <memory>
18 #include <cstdlib>
19 #include <cstring>
20 #include <cassert>
21
22 #include "test_macros.h"
23 #include "rapid-cxx-test.h"
24 #include "filesystem_test_helper.h"
25
26 using namespace fs;
27
PutEnv(std::string var,std::string value)28 void PutEnv(std::string var, std::string value) {
29 assert(::setenv(var.c_str(), value.c_str(), /* overwrite */ 1) == 0);
30 }
31
UnsetEnv(std::string var)32 void UnsetEnv(std::string var) {
33 assert(::unsetenv(var.c_str()) == 0);
34 }
35
36 TEST_SUITE(filesystem_temp_directory_path_test_suite)
37
TEST_CASE(signature_test)38 TEST_CASE(signature_test)
39 {
40 std::error_code ec; ((void)ec);
41 ASSERT_NOT_NOEXCEPT(temp_directory_path());
42 ASSERT_NOT_NOEXCEPT(temp_directory_path(ec));
43 }
44
TEST_CASE(basic_tests)45 TEST_CASE(basic_tests)
46 {
47 scoped_test_env env;
48 const path dne = env.make_env_path("dne");
49 const path file = env.create_file("file", 42);
50 const path dir_perms = env.create_dir("bad_perms_dir");
51 const path nested_dir = env.create_dir("bad_perms_dir/nested");
52 permissions(dir_perms, perms::none);
53 const std::error_code expect_ec = std::make_error_code(std::errc::not_a_directory);
54 struct TestCase {
55 std::string name;
56 path p;
57 } cases[] = {
58 {"TMPDIR", env.create_dir("dir1")},
59 {"TMP", env.create_dir("dir2")},
60 {"TEMP", env.create_dir("dir3")},
61 {"TEMPDIR", env.create_dir("dir4")}
62 };
63 for (auto& TC : cases) {
64 PutEnv(TC.name, TC.p);
65 }
66 for (auto& TC : cases) {
67 std::error_code ec = GetTestEC();
68 path ret = temp_directory_path(ec);
69 TEST_CHECK(!ec);
70 TEST_CHECK(ret == TC.p);
71 TEST_CHECK(is_directory(ret));
72
73 // Set the env variable to a path that does not exist and check
74 // that it fails.
75 PutEnv(TC.name, dne);
76 ec = GetTestEC();
77 ret = temp_directory_path(ec);
78 LIBCPP_ONLY(TEST_CHECK(ec == expect_ec));
79 TEST_CHECK(ec != GetTestEC());
80 TEST_CHECK(ec);
81 TEST_CHECK(ret == "");
82
83 // Set the env variable to point to a file and check that it fails.
84 PutEnv(TC.name, file);
85 ec = GetTestEC();
86 ret = temp_directory_path(ec);
87 LIBCPP_ONLY(TEST_CHECK(ec == expect_ec));
88 TEST_CHECK(ec != GetTestEC());
89 TEST_CHECK(ec);
90 TEST_CHECK(ret == "");
91
92 // Set the env variable to point to a dir we can't access
93 PutEnv(TC.name, nested_dir);
94 ec = GetTestEC();
95 ret = temp_directory_path(ec);
96 TEST_CHECK(ec == std::make_error_code(std::errc::permission_denied));
97 TEST_CHECK(ret == "");
98
99 // Set the env variable to point to a non-existent dir
100 PutEnv(TC.name, TC.p / "does_not_exist");
101 ec = GetTestEC();
102 ret = temp_directory_path(ec);
103 TEST_CHECK(ec != GetTestEC());
104 TEST_CHECK(ec);
105 TEST_CHECK(ret == "");
106
107 // Finally erase this env variable
108 UnsetEnv(TC.name);
109 }
110 // No env variables are defined
111 {
112 std::error_code ec = GetTestEC();
113 path ret = temp_directory_path(ec);
114 TEST_CHECK(!ec);
115 TEST_CHECK(ret == "/tmp");
116 TEST_CHECK(is_directory(ret));
117 }
118 }
119
120 TEST_SUITE_END()
121