1// Copyright 2010 The Kyua Authors.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8// * Redistributions of source code must retain the above copyright
9//   notice, this list of conditions and the following disclaimer.
10// * Redistributions in binary form must reproduce the above copyright
11//   notice, this list of conditions and the following disclaimer in the
12//   documentation and/or other materials provided with the distribution.
13// * Neither the name of Google Inc. nor the names of its contributors
14//   may be used to endorse or promote products derived from this software
15//   without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29#include "utils/fs/auto_cleaners.hpp"
30
31extern "C" {
32#include <unistd.h>
33}
34
35#include <atf-c++.hpp>
36
37#include "utils/env.hpp"
38#include "utils/fs/operations.hpp"
39#include "utils/fs/path.hpp"
40
41namespace fs = utils::fs;
42
43
44ATF_TEST_CASE_WITHOUT_HEAD(auto_directory__automatic);
45ATF_TEST_CASE_BODY(auto_directory__automatic)
46{
47    const fs::path root("root");
48    fs::mkdir(root, 0755);
49
50    {
51        fs::auto_directory dir(root);
52        ATF_REQUIRE_EQ(root, dir.directory());
53
54        ATF_REQUIRE(::access("root", X_OK) == 0);
55
56        {
57            fs::auto_directory dir_copy(dir);
58        }
59        // Should still exist after a copy is destructed.
60        ATF_REQUIRE(::access("root", X_OK) == 0);
61    }
62    ATF_REQUIRE(::access("root", X_OK) == -1);
63}
64
65
66ATF_TEST_CASE_WITHOUT_HEAD(auto_directory__explicit);
67ATF_TEST_CASE_BODY(auto_directory__explicit)
68{
69    const fs::path root("root");
70    fs::mkdir(root, 0755);
71
72    fs::auto_directory dir(root);
73    ATF_REQUIRE_EQ(root, dir.directory());
74
75    ATF_REQUIRE(::access("root", X_OK) == 0);
76    dir.cleanup();
77    dir.cleanup();
78    ATF_REQUIRE(::access("root", X_OK) == -1);
79}
80
81
82ATF_TEST_CASE_WITHOUT_HEAD(auto_directory__mkdtemp_public);
83ATF_TEST_CASE_BODY(auto_directory__mkdtemp_public)
84{
85    utils::setenv("TMPDIR", (fs::current_path() / "tmp").str());
86    fs::mkdir(fs::path("tmp"), 0755);
87
88    const std::string path_template("test.XXXXXX");
89    {
90        fs::auto_directory auto_directory = fs::auto_directory::mkdtemp_public(
91            path_template);
92        ATF_REQUIRE(::access((fs::path("tmp") / path_template).c_str(),
93                             X_OK) == -1);
94        ATF_REQUIRE(::rmdir("tmp") == -1);
95
96        ATF_REQUIRE(::access(auto_directory.directory().c_str(), X_OK) == 0);
97    }
98    ATF_REQUIRE(::rmdir("tmp") != -1);
99}
100
101
102ATF_TEST_CASE_WITHOUT_HEAD(auto_file__automatic);
103ATF_TEST_CASE_BODY(auto_file__automatic)
104{
105    const fs::path file("foo");
106    atf::utils::create_file(file.str(), "");
107    {
108        fs::auto_file auto_file(file);
109        ATF_REQUIRE_EQ(file, auto_file.file());
110
111        ATF_REQUIRE(::access(file.c_str(), R_OK) == 0);
112
113        {
114            fs::auto_file auto_file_copy(auto_file);
115        }
116        // Should still exist after a copy is destructed.
117        ATF_REQUIRE(::access(file.c_str(), R_OK) == 0);
118    }
119    ATF_REQUIRE(::access(file.c_str(), R_OK) == -1);
120}
121
122
123ATF_TEST_CASE_WITHOUT_HEAD(auto_file__explicit);
124ATF_TEST_CASE_BODY(auto_file__explicit)
125{
126    const fs::path file("bar");
127    atf::utils::create_file(file.str(), "");
128
129    fs::auto_file auto_file(file);
130    ATF_REQUIRE_EQ(file, auto_file.file());
131
132    ATF_REQUIRE(::access(file.c_str(), R_OK) == 0);
133    auto_file.remove();
134    auto_file.remove();
135    ATF_REQUIRE(::access(file.c_str(), R_OK) == -1);
136}
137
138
139ATF_TEST_CASE_WITHOUT_HEAD(auto_file__mkstemp);
140ATF_TEST_CASE_BODY(auto_file__mkstemp)
141{
142    utils::setenv("TMPDIR", (fs::current_path() / "tmp").str());
143    fs::mkdir(fs::path("tmp"), 0755);
144
145    const std::string path_template("test.XXXXXX");
146    {
147        fs::auto_file auto_file = fs::auto_file::mkstemp(path_template);
148        ATF_REQUIRE(::access((fs::path("tmp") / path_template).c_str(),
149                             X_OK) == -1);
150        ATF_REQUIRE(::rmdir("tmp") == -1);
151
152        ATF_REQUIRE(::access(auto_file.file().c_str(), R_OK) == 0);
153    }
154    ATF_REQUIRE(::rmdir("tmp") != -1);
155}
156
157
158ATF_INIT_TEST_CASES(tcs)
159{
160    ATF_ADD_TEST_CASE(tcs, auto_directory__automatic);
161    ATF_ADD_TEST_CASE(tcs, auto_directory__explicit);
162    ATF_ADD_TEST_CASE(tcs, auto_directory__mkdtemp_public);
163
164    ATF_ADD_TEST_CASE(tcs, auto_file__automatic);
165    ATF_ADD_TEST_CASE(tcs, auto_file__explicit);
166    ATF_ADD_TEST_CASE(tcs, auto_file__mkstemp);
167}
168