xref: /minix3/external/bsd/kyua-cli/dist/engine/test_case_atf_helpers.cpp (revision 11be35a165022172ed3cea20f2b5df0307540b0e)
1*11be35a1SLionel Sambuc // Copyright 2010 Google Inc.
2*11be35a1SLionel Sambuc // All rights reserved.
3*11be35a1SLionel Sambuc //
4*11be35a1SLionel Sambuc // Redistribution and use in source and binary forms, with or without
5*11be35a1SLionel Sambuc // modification, are permitted provided that the following conditions are
6*11be35a1SLionel Sambuc // met:
7*11be35a1SLionel Sambuc //
8*11be35a1SLionel Sambuc // * Redistributions of source code must retain the above copyright
9*11be35a1SLionel Sambuc //   notice, this list of conditions and the following disclaimer.
10*11be35a1SLionel Sambuc // * Redistributions in binary form must reproduce the above copyright
11*11be35a1SLionel Sambuc //   notice, this list of conditions and the following disclaimer in the
12*11be35a1SLionel Sambuc //   documentation and/or other materials provided with the distribution.
13*11be35a1SLionel Sambuc // * Neither the name of Google Inc. nor the names of its contributors
14*11be35a1SLionel Sambuc //   may be used to endorse or promote products derived from this software
15*11be35a1SLionel Sambuc //   without specific prior written permission.
16*11be35a1SLionel Sambuc //
17*11be35a1SLionel Sambuc // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18*11be35a1SLionel Sambuc // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*11be35a1SLionel Sambuc // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20*11be35a1SLionel Sambuc // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21*11be35a1SLionel Sambuc // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22*11be35a1SLionel Sambuc // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23*11be35a1SLionel Sambuc // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*11be35a1SLionel Sambuc // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*11be35a1SLionel Sambuc // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*11be35a1SLionel Sambuc // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27*11be35a1SLionel Sambuc // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*11be35a1SLionel Sambuc 
29*11be35a1SLionel Sambuc extern "C" {
30*11be35a1SLionel Sambuc #include <sys/stat.h>
31*11be35a1SLionel Sambuc 
32*11be35a1SLionel Sambuc #include <signal.h>
33*11be35a1SLionel Sambuc #include <unistd.h>
34*11be35a1SLionel Sambuc }
35*11be35a1SLionel Sambuc 
36*11be35a1SLionel Sambuc #include <cstdlib>
37*11be35a1SLionel Sambuc #include <fstream>
38*11be35a1SLionel Sambuc #include <iostream>
39*11be35a1SLionel Sambuc #include <sstream>
40*11be35a1SLionel Sambuc 
41*11be35a1SLionel Sambuc #include <atf-c++.hpp>
42*11be35a1SLionel Sambuc 
43*11be35a1SLionel Sambuc #include "utils/env.hpp"
44*11be35a1SLionel Sambuc #include "utils/fs/operations.hpp"
45*11be35a1SLionel Sambuc #include "utils/fs/path.hpp"
46*11be35a1SLionel Sambuc #include "utils/optional.ipp"
47*11be35a1SLionel Sambuc 
48*11be35a1SLionel Sambuc namespace fs = utils::fs;
49*11be35a1SLionel Sambuc 
50*11be35a1SLionel Sambuc 
51*11be35a1SLionel Sambuc namespace {
52*11be35a1SLionel Sambuc 
53*11be35a1SLionel Sambuc 
54*11be35a1SLionel Sambuc /// Creates an empty file in the given directory.
55*11be35a1SLionel Sambuc ///
56*11be35a1SLionel Sambuc /// \param test_case The test case currently running.
57*11be35a1SLionel Sambuc /// \param directory The name of the configuration variable that holds the path
58*11be35a1SLionel Sambuc ///     to the directory in which to create the cookie file.
59*11be35a1SLionel Sambuc /// \param name The name of the cookie file to create.
60*11be35a1SLionel Sambuc static void
create_cookie(const atf::tests::tc * test_case,const char * directory,const char * name)61*11be35a1SLionel Sambuc create_cookie(const atf::tests::tc* test_case, const char* directory,
62*11be35a1SLionel Sambuc               const char* name)
63*11be35a1SLionel Sambuc {
64*11be35a1SLionel Sambuc     if (!test_case->has_config_var(directory))
65*11be35a1SLionel Sambuc         test_case->fail(std::string(name) + " not provided");
66*11be35a1SLionel Sambuc 
67*11be35a1SLionel Sambuc     const fs::path control_dir(test_case->get_config_var(directory));
68*11be35a1SLionel Sambuc     std::ofstream file((control_dir / name).c_str());
69*11be35a1SLionel Sambuc     if (!file)
70*11be35a1SLionel Sambuc         test_case->fail("Failed to create the control cookie");
71*11be35a1SLionel Sambuc     file.close();
72*11be35a1SLionel Sambuc }
73*11be35a1SLionel Sambuc 
74*11be35a1SLionel Sambuc 
75*11be35a1SLionel Sambuc }  // anonymous namespace
76*11be35a1SLionel Sambuc 
77*11be35a1SLionel Sambuc 
78*11be35a1SLionel Sambuc ATF_TEST_CASE_WITH_CLEANUP(check_cleanup_workdir);
ATF_TEST_CASE_HEAD(check_cleanup_workdir)79*11be35a1SLionel Sambuc ATF_TEST_CASE_HEAD(check_cleanup_workdir)
80*11be35a1SLionel Sambuc {
81*11be35a1SLionel Sambuc     set_md_var("require.config", "control_dir");
82*11be35a1SLionel Sambuc }
ATF_TEST_CASE_BODY(check_cleanup_workdir)83*11be35a1SLionel Sambuc ATF_TEST_CASE_BODY(check_cleanup_workdir)
84*11be35a1SLionel Sambuc {
85*11be35a1SLionel Sambuc     std::ofstream cookie("workdir_cookie");
86*11be35a1SLionel Sambuc     cookie << "1234\n";
87*11be35a1SLionel Sambuc     cookie.close();
88*11be35a1SLionel Sambuc     skip("cookie created");
89*11be35a1SLionel Sambuc }
ATF_TEST_CASE_CLEANUP(check_cleanup_workdir)90*11be35a1SLionel Sambuc ATF_TEST_CASE_CLEANUP(check_cleanup_workdir)
91*11be35a1SLionel Sambuc {
92*11be35a1SLionel Sambuc     const fs::path control_dir(get_config_var("control_dir"));
93*11be35a1SLionel Sambuc 
94*11be35a1SLionel Sambuc     std::ifstream cookie("workdir_cookie");
95*11be35a1SLionel Sambuc     if (!cookie) {
96*11be35a1SLionel Sambuc         std::ofstream((control_dir / "missing_cookie").c_str()).close();
97*11be35a1SLionel Sambuc         std::exit(EXIT_FAILURE);
98*11be35a1SLionel Sambuc     }
99*11be35a1SLionel Sambuc 
100*11be35a1SLionel Sambuc     std::string value;
101*11be35a1SLionel Sambuc     cookie >> value;
102*11be35a1SLionel Sambuc     if (value != "1234") {
103*11be35a1SLionel Sambuc         std::ofstream((control_dir / "invalid_cookie").c_str()).close();
104*11be35a1SLionel Sambuc         std::exit(EXIT_FAILURE);
105*11be35a1SLionel Sambuc     }
106*11be35a1SLionel Sambuc 
107*11be35a1SLionel Sambuc     std::ofstream((control_dir / "cookie_ok").c_str()).close();
108*11be35a1SLionel Sambuc     std::exit(EXIT_SUCCESS);
109*11be35a1SLionel Sambuc }
110*11be35a1SLionel Sambuc 
111*11be35a1SLionel Sambuc 
112*11be35a1SLionel Sambuc ATF_TEST_CASE_WITHOUT_HEAD(check_unprivileged);
ATF_TEST_CASE_BODY(check_unprivileged)113*11be35a1SLionel Sambuc ATF_TEST_CASE_BODY(check_unprivileged)
114*11be35a1SLionel Sambuc {
115*11be35a1SLionel Sambuc     if (::getuid() == 0)
116*11be35a1SLionel Sambuc         fail("Running as root, but I shouldn't be");
117*11be35a1SLionel Sambuc 
118*11be35a1SLionel Sambuc     std::ofstream file("cookie");
119*11be35a1SLionel Sambuc     if (!file)
120*11be35a1SLionel Sambuc         fail("Failed to create the cookie; work directory probably owned by "
121*11be35a1SLionel Sambuc              "root");
122*11be35a1SLionel Sambuc     file.close();
123*11be35a1SLionel Sambuc }
124*11be35a1SLionel Sambuc 
125*11be35a1SLionel Sambuc 
126*11be35a1SLionel Sambuc ATF_TEST_CASE_WITHOUT_HEAD(crash);
ATF_TEST_CASE_BODY(crash)127*11be35a1SLionel Sambuc ATF_TEST_CASE_BODY(crash)
128*11be35a1SLionel Sambuc {
129*11be35a1SLionel Sambuc     std::abort();
130*11be35a1SLionel Sambuc }
131*11be35a1SLionel Sambuc 
132*11be35a1SLionel Sambuc 
133*11be35a1SLionel Sambuc ATF_TEST_CASE_WITH_CLEANUP(crash_cleanup);
ATF_TEST_CASE_HEAD(crash_cleanup)134*11be35a1SLionel Sambuc ATF_TEST_CASE_HEAD(crash_cleanup)
135*11be35a1SLionel Sambuc {
136*11be35a1SLionel Sambuc }
ATF_TEST_CASE_BODY(crash_cleanup)137*11be35a1SLionel Sambuc ATF_TEST_CASE_BODY(crash_cleanup)
138*11be35a1SLionel Sambuc {
139*11be35a1SLionel Sambuc }
ATF_TEST_CASE_CLEANUP(crash_cleanup)140*11be35a1SLionel Sambuc ATF_TEST_CASE_CLEANUP(crash_cleanup)
141*11be35a1SLionel Sambuc {
142*11be35a1SLionel Sambuc     std::abort();
143*11be35a1SLionel Sambuc }
144*11be35a1SLionel Sambuc 
145*11be35a1SLionel Sambuc 
146*11be35a1SLionel Sambuc ATF_TEST_CASE_WITHOUT_HEAD(create_cookie_in_control_dir);
ATF_TEST_CASE_BODY(create_cookie_in_control_dir)147*11be35a1SLionel Sambuc ATF_TEST_CASE_BODY(create_cookie_in_control_dir)
148*11be35a1SLionel Sambuc {
149*11be35a1SLionel Sambuc     create_cookie(this, "control_dir", "cookie");
150*11be35a1SLionel Sambuc }
151*11be35a1SLionel Sambuc 
152*11be35a1SLionel Sambuc 
153*11be35a1SLionel Sambuc ATF_TEST_CASE_WITHOUT_HEAD(create_cookie_in_workdir);
ATF_TEST_CASE_BODY(create_cookie_in_workdir)154*11be35a1SLionel Sambuc ATF_TEST_CASE_BODY(create_cookie_in_workdir)
155*11be35a1SLionel Sambuc {
156*11be35a1SLionel Sambuc     std::ofstream file("cookie");
157*11be35a1SLionel Sambuc     if (!file)
158*11be35a1SLionel Sambuc         fail("Failed to create the cookie");
159*11be35a1SLionel Sambuc     file.close();
160*11be35a1SLionel Sambuc }
161*11be35a1SLionel Sambuc 
162*11be35a1SLionel Sambuc 
163*11be35a1SLionel Sambuc ATF_TEST_CASE_WITH_CLEANUP(create_cookie_from_cleanup);
ATF_TEST_CASE_HEAD(create_cookie_from_cleanup)164*11be35a1SLionel Sambuc ATF_TEST_CASE_HEAD(create_cookie_from_cleanup)
165*11be35a1SLionel Sambuc {
166*11be35a1SLionel Sambuc }
ATF_TEST_CASE_BODY(create_cookie_from_cleanup)167*11be35a1SLionel Sambuc ATF_TEST_CASE_BODY(create_cookie_from_cleanup)
168*11be35a1SLionel Sambuc {
169*11be35a1SLionel Sambuc }
ATF_TEST_CASE_CLEANUP(create_cookie_from_cleanup)170*11be35a1SLionel Sambuc ATF_TEST_CASE_CLEANUP(create_cookie_from_cleanup)
171*11be35a1SLionel Sambuc {
172*11be35a1SLionel Sambuc     create_cookie(this, "control_dir", "cookie");
173*11be35a1SLionel Sambuc }
174*11be35a1SLionel Sambuc 
175*11be35a1SLionel Sambuc 
176*11be35a1SLionel Sambuc ATF_TEST_CASE_WITH_CLEANUP(output);
ATF_TEST_CASE_HEAD(output)177*11be35a1SLionel Sambuc ATF_TEST_CASE_HEAD(output)
178*11be35a1SLionel Sambuc {
179*11be35a1SLionel Sambuc }
ATF_TEST_CASE_BODY(output)180*11be35a1SLionel Sambuc ATF_TEST_CASE_BODY(output)
181*11be35a1SLionel Sambuc {
182*11be35a1SLionel Sambuc     std::cout << "Body message to stdout\n";
183*11be35a1SLionel Sambuc     std::cerr << "Body message to stderr\n";
184*11be35a1SLionel Sambuc }
ATF_TEST_CASE_CLEANUP(output)185*11be35a1SLionel Sambuc ATF_TEST_CASE_CLEANUP(output)
186*11be35a1SLionel Sambuc {
187*11be35a1SLionel Sambuc     std::cout << "Cleanup message to stdout\n";
188*11be35a1SLionel Sambuc     std::cerr << "Cleanup message to stderr\n";
189*11be35a1SLionel Sambuc }
190*11be35a1SLionel Sambuc 
191*11be35a1SLionel Sambuc 
192*11be35a1SLionel Sambuc ATF_TEST_CASE_WITHOUT_HEAD(pass);
ATF_TEST_CASE_BODY(pass)193*11be35a1SLionel Sambuc ATF_TEST_CASE_BODY(pass)
194*11be35a1SLionel Sambuc {
195*11be35a1SLionel Sambuc }
196*11be35a1SLionel Sambuc 
197*11be35a1SLionel Sambuc 
198*11be35a1SLionel Sambuc ATF_TEST_CASE(spawn_blocking_child);
ATF_TEST_CASE_HEAD(spawn_blocking_child)199*11be35a1SLionel Sambuc ATF_TEST_CASE_HEAD(spawn_blocking_child)
200*11be35a1SLionel Sambuc {
201*11be35a1SLionel Sambuc     set_md_var("require.config", "control_dir");
202*11be35a1SLionel Sambuc }
ATF_TEST_CASE_BODY(spawn_blocking_child)203*11be35a1SLionel Sambuc ATF_TEST_CASE_BODY(spawn_blocking_child)
204*11be35a1SLionel Sambuc {
205*11be35a1SLionel Sambuc     pid_t pid = ::fork();
206*11be35a1SLionel Sambuc     if (pid == -1)
207*11be35a1SLionel Sambuc         fail("Cannot fork subprocess");
208*11be35a1SLionel Sambuc     else if (pid == 0) {
209*11be35a1SLionel Sambuc         for (;;)
210*11be35a1SLionel Sambuc             ::pause();
211*11be35a1SLionel Sambuc     } else {
212*11be35a1SLionel Sambuc         const fs::path name = fs::path(get_config_var("control_dir")) / "pid";
213*11be35a1SLionel Sambuc         std::ofstream pidfile(name.c_str());
214*11be35a1SLionel Sambuc         ATF_REQUIRE(pidfile);
215*11be35a1SLionel Sambuc         pidfile << pid;
216*11be35a1SLionel Sambuc         pidfile.close();
217*11be35a1SLionel Sambuc     }
218*11be35a1SLionel Sambuc }
219*11be35a1SLionel Sambuc 
220*11be35a1SLionel Sambuc 
221*11be35a1SLionel Sambuc ATF_TEST_CASE(timeout_body);
ATF_TEST_CASE_HEAD(timeout_body)222*11be35a1SLionel Sambuc ATF_TEST_CASE_HEAD(timeout_body)
223*11be35a1SLionel Sambuc {
224*11be35a1SLionel Sambuc     if (has_config_var("timeout"))
225*11be35a1SLionel Sambuc         set_md_var("timeout", get_config_var("timeout"));
226*11be35a1SLionel Sambuc }
ATF_TEST_CASE_BODY(timeout_body)227*11be35a1SLionel Sambuc ATF_TEST_CASE_BODY(timeout_body)
228*11be35a1SLionel Sambuc {
229*11be35a1SLionel Sambuc     ::sleep(10);
230*11be35a1SLionel Sambuc     create_cookie(this, "control_dir", "cookie");
231*11be35a1SLionel Sambuc }
232*11be35a1SLionel Sambuc 
233*11be35a1SLionel Sambuc 
234*11be35a1SLionel Sambuc ATF_TEST_CASE_WITH_CLEANUP(timeout_cleanup);
ATF_TEST_CASE_HEAD(timeout_cleanup)235*11be35a1SLionel Sambuc ATF_TEST_CASE_HEAD(timeout_cleanup)
236*11be35a1SLionel Sambuc {
237*11be35a1SLionel Sambuc     if (has_config_var("timeout"))
238*11be35a1SLionel Sambuc         set_md_var("timeout", get_config_var("timeout"));
239*11be35a1SLionel Sambuc }
ATF_TEST_CASE_BODY(timeout_cleanup)240*11be35a1SLionel Sambuc ATF_TEST_CASE_BODY(timeout_cleanup)
241*11be35a1SLionel Sambuc {
242*11be35a1SLionel Sambuc }
ATF_TEST_CASE_CLEANUP(timeout_cleanup)243*11be35a1SLionel Sambuc ATF_TEST_CASE_CLEANUP(timeout_cleanup)
244*11be35a1SLionel Sambuc {
245*11be35a1SLionel Sambuc     ::sleep(10);
246*11be35a1SLionel Sambuc     create_cookie(this, "control_dir", "cookie");
247*11be35a1SLionel Sambuc }
248*11be35a1SLionel Sambuc 
249*11be35a1SLionel Sambuc 
250*11be35a1SLionel Sambuc ATF_TEST_CASE_WITHOUT_HEAD(validate_isolation);
ATF_TEST_CASE_BODY(validate_isolation)251*11be35a1SLionel Sambuc ATF_TEST_CASE_BODY(validate_isolation)
252*11be35a1SLionel Sambuc {
253*11be35a1SLionel Sambuc     ATF_REQUIRE(utils::getenv("HOME").get() != "fake-value");
254*11be35a1SLionel Sambuc     ATF_REQUIRE(!utils::getenv("LANG"));
255*11be35a1SLionel Sambuc }
256*11be35a1SLionel Sambuc 
257*11be35a1SLionel Sambuc 
ATF_INIT_TEST_CASES(tcs)258*11be35a1SLionel Sambuc ATF_INIT_TEST_CASES(tcs)
259*11be35a1SLionel Sambuc {
260*11be35a1SLionel Sambuc     ATF_ADD_TEST_CASE(tcs, check_cleanup_workdir);
261*11be35a1SLionel Sambuc     ATF_ADD_TEST_CASE(tcs, check_unprivileged);
262*11be35a1SLionel Sambuc     ATF_ADD_TEST_CASE(tcs, crash);
263*11be35a1SLionel Sambuc     ATF_ADD_TEST_CASE(tcs, crash_cleanup);
264*11be35a1SLionel Sambuc     ATF_ADD_TEST_CASE(tcs, create_cookie_in_control_dir);
265*11be35a1SLionel Sambuc     ATF_ADD_TEST_CASE(tcs, create_cookie_in_workdir);
266*11be35a1SLionel Sambuc     ATF_ADD_TEST_CASE(tcs, create_cookie_from_cleanup);
267*11be35a1SLionel Sambuc     ATF_ADD_TEST_CASE(tcs, output);
268*11be35a1SLionel Sambuc     ATF_ADD_TEST_CASE(tcs, pass);
269*11be35a1SLionel Sambuc     ATF_ADD_TEST_CASE(tcs, spawn_blocking_child);
270*11be35a1SLionel Sambuc     ATF_ADD_TEST_CASE(tcs, timeout_body);
271*11be35a1SLionel Sambuc     ATF_ADD_TEST_CASE(tcs, timeout_cleanup);
272*11be35a1SLionel Sambuc     ATF_ADD_TEST_CASE(tcs, validate_isolation);
273*11be35a1SLionel Sambuc }
274