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