1 // Copyright (c) 2007 The NetBSD Foundation, Inc.
2 // All rights reserved.
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions
7 // 1. Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 // 2. Redistributions in binary form must reproduce the above copyright
10 // notice, this list of conditions and the following disclaimer in the
11 // documentation and/or other materials provided with the distribution.
13 // THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
14 // CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
15 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 // IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
18 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20 // GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24 // IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #include "atf-c++/check.hpp"
42 #include <atf-c++.hpp>
44 #include "atf-c++/detail/fs.hpp"
45 #include "atf-c++/detail/process.hpp"
46 #include "atf-c++/detail/test_helpers.hpp"
47 #include "atf-c++/detail/text.hpp"
48 #include "atf-c++/utils.hpp"
50 // ------------------------------------------------------------------------
51 // Auxiliary functions.
52 // ------------------------------------------------------------------------
55 std::auto_ptr< atf::check::check_result >
56 do_exec(const atf::tests::tc* tc, const char* helper_name)
58 std::vector< std::string > argv;
59 argv.push_back(get_process_helpers_path(*tc, false).str());
60 argv.push_back(helper_name);
61 std::cout << "Executing " << argv[0] << " " << argv[1] << "\n";
63 atf::process::argv_array argva(argv);
64 return atf::check::exec(argva);
68 std::auto_ptr< atf::check::check_result >
69 do_exec(const atf::tests::tc* tc, const char* helper_name, const char *carg2)
71 std::vector< std::string > argv;
72 argv.push_back(get_process_helpers_path(*tc, false).str());
73 argv.push_back(helper_name);
74 argv.push_back(carg2);
75 std::cout << "Executing " << argv[0] << " " << argv[1] << " "
78 atf::process::argv_array argva(argv);
79 return atf::check::exec(argva);
82 // ------------------------------------------------------------------------
83 // Helper test cases for the free functions.
84 // ------------------------------------------------------------------------
86 ATF_TEST_CASE(h_build_c_o_ok);
87 ATF_TEST_CASE_HEAD(h_build_c_o_ok)
89 set_md_var("descr", "Helper test case for build_c_o");
91 ATF_TEST_CASE_BODY(h_build_c_o_ok)
93 std::ofstream sfile("test.c");
94 sfile << "#include <stdio.h>\n";
97 ATF_REQUIRE(atf::check::build_c_o("test.c", "test.o",
98 atf::process::argv_array()));
101 ATF_TEST_CASE(h_build_c_o_fail);
102 ATF_TEST_CASE_HEAD(h_build_c_o_fail)
104 set_md_var("descr", "Helper test case for build_c_o");
106 ATF_TEST_CASE_BODY(h_build_c_o_fail)
108 std::ofstream sfile("test.c");
109 sfile << "void foo(void) { int a = UNDEFINED_SYMBOL; }\n";
112 ATF_REQUIRE(!atf::check::build_c_o("test.c", "test.o",
113 atf::process::argv_array()));
116 ATF_TEST_CASE(h_build_cpp_ok);
117 ATF_TEST_CASE_HEAD(h_build_cpp_ok)
119 set_md_var("descr", "Helper test case for build_cpp");
121 ATF_TEST_CASE_BODY(h_build_cpp_ok)
123 std::ofstream sfile("test.c");
124 sfile << "#define A foo\n";
125 sfile << "#define B bar\n";
129 ATF_REQUIRE(atf::check::build_cpp("test.c", "test.p",
130 atf::process::argv_array()));
133 ATF_TEST_CASE(h_build_cpp_fail);
134 ATF_TEST_CASE_HEAD(h_build_cpp_fail)
136 set_md_var("descr", "Helper test case for build_cpp");
138 ATF_TEST_CASE_BODY(h_build_cpp_fail)
140 std::ofstream sfile("test.c");
141 sfile << "#include \"./non-existent.h\"\n";
144 ATF_REQUIRE(!atf::check::build_cpp("test.c", "test.p",
145 atf::process::argv_array()));
148 ATF_TEST_CASE(h_build_cxx_o_ok);
149 ATF_TEST_CASE_HEAD(h_build_cxx_o_ok)
151 set_md_var("descr", "Helper test case for build_cxx_o");
153 ATF_TEST_CASE_BODY(h_build_cxx_o_ok)
155 std::ofstream sfile("test.cpp");
156 sfile << "#include <iostream>\n";
159 ATF_REQUIRE(atf::check::build_cxx_o("test.cpp", "test.o",
160 atf::process::argv_array()));
163 ATF_TEST_CASE(h_build_cxx_o_fail);
164 ATF_TEST_CASE_HEAD(h_build_cxx_o_fail)
166 set_md_var("descr", "Helper test case for build_cxx_o");
168 ATF_TEST_CASE_BODY(h_build_cxx_o_fail)
170 std::ofstream sfile("test.cpp");
171 sfile << "void foo(void) { int a = UNDEFINED_SYMBOL; }\n";
174 ATF_REQUIRE(!atf::check::build_cxx_o("test.cpp", "test.o",
175 atf::process::argv_array()));
178 // ------------------------------------------------------------------------
179 // Test cases for the free functions.
180 // ------------------------------------------------------------------------
182 ATF_TEST_CASE(build_c_o);
183 ATF_TEST_CASE_HEAD(build_c_o)
185 set_md_var("descr", "Tests the build_c_o function");
187 ATF_TEST_CASE_BODY(build_c_o)
189 ATF_TEST_CASE_USE(h_build_c_o_ok);
190 run_h_tc< ATF_TEST_CASE_NAME(h_build_c_o_ok) >();
191 ATF_REQUIRE(atf::utils::grep_file("-o test.o", "stdout"));
192 ATF_REQUIRE(atf::utils::grep_file("-c test.c", "stdout"));
194 ATF_TEST_CASE_USE(h_build_c_o_fail);
195 run_h_tc< ATF_TEST_CASE_NAME(h_build_c_o_fail) >();
196 ATF_REQUIRE(atf::utils::grep_file("-o test.o", "stdout"));
197 ATF_REQUIRE(atf::utils::grep_file("-c test.c", "stdout"));
198 ATF_REQUIRE(atf::utils::grep_file("test.c", "stderr"));
199 ATF_REQUIRE(atf::utils::grep_file("UNDEFINED_SYMBOL", "stderr"));
202 ATF_TEST_CASE(build_cpp);
203 ATF_TEST_CASE_HEAD(build_cpp)
205 set_md_var("descr", "Tests the build_cpp function");
207 ATF_TEST_CASE_BODY(build_cpp)
209 ATF_TEST_CASE_USE(h_build_cpp_ok);
210 run_h_tc< ATF_TEST_CASE_NAME(h_build_cpp_ok) >();
211 ATF_REQUIRE(atf::utils::grep_file("-o.*test.p", "stdout"));
212 ATF_REQUIRE(atf::utils::grep_file("test.c", "stdout"));
213 ATF_REQUIRE(atf::utils::grep_file("foo bar", "test.p"));
215 ATF_TEST_CASE_USE(h_build_cpp_fail);
216 run_h_tc< ATF_TEST_CASE_NAME(h_build_cpp_fail) >();
217 ATF_REQUIRE(atf::utils::grep_file("-o test.p", "stdout"));
218 ATF_REQUIRE(atf::utils::grep_file("test.c", "stdout"));
219 ATF_REQUIRE(atf::utils::grep_file("test.c", "stderr"));
220 ATF_REQUIRE(atf::utils::grep_file("non-existent.h", "stderr"));
223 ATF_TEST_CASE(build_cxx_o);
224 ATF_TEST_CASE_HEAD(build_cxx_o)
226 set_md_var("descr", "Tests the build_cxx_o function");
228 ATF_TEST_CASE_BODY(build_cxx_o)
230 ATF_TEST_CASE_USE(h_build_cxx_o_ok);
231 run_h_tc< ATF_TEST_CASE_NAME(h_build_cxx_o_ok) >();
232 ATF_REQUIRE(atf::utils::grep_file("-o test.o", "stdout"));
233 ATF_REQUIRE(atf::utils::grep_file("-c test.cpp", "stdout"));
235 ATF_TEST_CASE_USE(h_build_cxx_o_fail);
236 run_h_tc< ATF_TEST_CASE_NAME(h_build_cxx_o_fail) >();
237 ATF_REQUIRE(atf::utils::grep_file("-o test.o", "stdout"));
238 ATF_REQUIRE(atf::utils::grep_file("-c test.cpp", "stdout"));
239 ATF_REQUIRE(atf::utils::grep_file("test.cpp", "stderr"));
240 ATF_REQUIRE(atf::utils::grep_file("UNDEFINED_SYMBOL", "stderr"));
243 ATF_TEST_CASE(exec_cleanup);
244 ATF_TEST_CASE_HEAD(exec_cleanup)
246 set_md_var("descr", "Tests that exec properly cleans up the temporary "
249 ATF_TEST_CASE_BODY(exec_cleanup)
251 std::auto_ptr< atf::fs::path > out;
252 std::auto_ptr< atf::fs::path > err;
255 std::auto_ptr< atf::check::check_result > r =
256 do_exec(this, "exit-success");
257 out.reset(new atf::fs::path(r->stdout_path()));
258 err.reset(new atf::fs::path(r->stderr_path()));
259 ATF_REQUIRE(atf::fs::exists(*out.get()));
260 ATF_REQUIRE(atf::fs::exists(*err.get()));
262 ATF_REQUIRE(!atf::fs::exists(*out.get()));
263 ATF_REQUIRE(!atf::fs::exists(*err.get()));
266 ATF_TEST_CASE(exec_exitstatus);
267 ATF_TEST_CASE_HEAD(exec_exitstatus)
269 set_md_var("descr", "Tests that exec properly captures the exit "
270 "status of the executed command");
272 ATF_TEST_CASE_BODY(exec_exitstatus)
275 std::auto_ptr< atf::check::check_result > r =
276 do_exec(this, "exit-success");
277 ATF_REQUIRE(r->exited());
278 ATF_REQUIRE(!r->signaled());
279 ATF_REQUIRE_EQ(r->exitcode(), EXIT_SUCCESS);
283 std::auto_ptr< atf::check::check_result > r =
284 do_exec(this, "exit-failure");
285 ATF_REQUIRE(r->exited());
286 ATF_REQUIRE(!r->signaled());
287 ATF_REQUIRE_EQ(r->exitcode(), EXIT_FAILURE);
291 std::auto_ptr< atf::check::check_result > r =
292 do_exec(this, "exit-signal");
293 ATF_REQUIRE(!r->exited());
294 ATF_REQUIRE(r->signaled());
295 ATF_REQUIRE_EQ(r->termsig(), SIGKILL);
301 check_lines(const std::string& path, const char* outname,
304 std::ifstream f(path.c_str());
308 std::getline(f, line);
309 ATF_REQUIRE_EQ(line, std::string("Line 1 to ") + outname + " for " +
311 std::getline(f, line);
312 ATF_REQUIRE_EQ(line, std::string("Line 2 to ") + outname + " for " +
316 ATF_TEST_CASE(exec_stdout_stderr);
317 ATF_TEST_CASE_HEAD(exec_stdout_stderr)
319 set_md_var("descr", "Tests that exec properly captures the stdout "
320 "and stderr streams of the child process");
322 ATF_TEST_CASE_BODY(exec_stdout_stderr)
324 std::auto_ptr< atf::check::check_result > r1 =
325 do_exec(this, "stdout-stderr", "result1");
326 ATF_REQUIRE(r1->exited());
327 ATF_REQUIRE_EQ(r1->exitcode(), EXIT_SUCCESS);
329 std::auto_ptr< atf::check::check_result > r2 =
330 do_exec(this, "stdout-stderr", "result2");
331 ATF_REQUIRE(r2->exited());
332 ATF_REQUIRE_EQ(r2->exitcode(), EXIT_SUCCESS);
334 const std::string out1 = r1->stdout_path();
335 const std::string out2 = r2->stdout_path();
336 const std::string err1 = r1->stderr_path();
337 const std::string err2 = r2->stderr_path();
339 ATF_REQUIRE(out1.find("check.XXXXXX") == std::string::npos);
340 ATF_REQUIRE(out2.find("check.XXXXXX") == std::string::npos);
341 ATF_REQUIRE(err1.find("check.XXXXXX") == std::string::npos);
342 ATF_REQUIRE(err2.find("check.XXXXXX") == std::string::npos);
344 ATF_REQUIRE(out1.find("/check") != std::string::npos);
345 ATF_REQUIRE(out2.find("/check") != std::string::npos);
346 ATF_REQUIRE(err1.find("/check") != std::string::npos);
347 ATF_REQUIRE(err2.find("/check") != std::string::npos);
349 ATF_REQUIRE(out1.find("/stdout") != std::string::npos);
350 ATF_REQUIRE(out2.find("/stdout") != std::string::npos);
351 ATF_REQUIRE(err1.find("/stderr") != std::string::npos);
352 ATF_REQUIRE(err2.find("/stderr") != std::string::npos);
354 ATF_REQUIRE(out1 != out2);
355 ATF_REQUIRE(err1 != err2);
357 check_lines(out1, "stdout", "result1");
358 check_lines(out2, "stdout", "result2");
359 check_lines(err1, "stderr", "result1");
360 check_lines(err2, "stderr", "result2");
363 ATF_TEST_CASE(exec_unknown);
364 ATF_TEST_CASE_HEAD(exec_unknown)
366 set_md_var("descr", "Tests that running a non-existing binary "
367 "is handled correctly");
369 ATF_TEST_CASE_BODY(exec_unknown)
371 std::vector< std::string > argv;
372 argv.push_back("/foo/bar/non-existent");
374 atf::process::argv_array argva(argv);
375 std::auto_ptr< atf::check::check_result > r = atf::check::exec(argva);
376 ATF_REQUIRE(r->exited());
377 ATF_REQUIRE_EQ(r->exitcode(), 127);
380 // ------------------------------------------------------------------------
382 // ------------------------------------------------------------------------
384 ATF_INIT_TEST_CASES(tcs)
386 // Add the test cases for the free functions.
387 ATF_ADD_TEST_CASE(tcs, build_c_o);
388 ATF_ADD_TEST_CASE(tcs, build_cpp);
389 ATF_ADD_TEST_CASE(tcs, build_cxx_o);
390 ATF_ADD_TEST_CASE(tcs, exec_cleanup);
391 ATF_ADD_TEST_CASE(tcs, exec_exitstatus);
392 ATF_ADD_TEST_CASE(tcs, exec_stdout_stderr);
393 ATF_ADD_TEST_CASE(tcs, exec_unknown);