2 // Automated Testing Framework (atf)
4 // Copyright (c) 2007 The NetBSD Foundation, Inc.
5 // All rights reserved.
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
10 // 1. Redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer.
12 // 2. Redistributions in binary form must reproduce the above copyright
13 // notice, this list of conditions and the following disclaimer in the
14 // documentation and/or other materials provided with the distribution.
16 // THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17 // CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 // IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23 // GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 // IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44 #include <atf-c++.hpp>
50 #include "detail/fs.hpp"
51 #include "detail/process.hpp"
52 #include "detail/test_helpers.hpp"
53 #include "detail/text.hpp"
55 // ------------------------------------------------------------------------
56 // Auxiliary functions.
57 // ------------------------------------------------------------------------
60 std::auto_ptr
< atf::check::check_result
>
61 do_exec(const atf::tests::tc
* tc
, const char* helper_name
)
63 std::vector
< std::string
> argv
;
64 argv
.push_back(get_process_helpers_path(*tc
, false).str());
65 argv
.push_back(helper_name
);
66 std::cout
<< "Executing " << argv
[0] << " " << argv
[1] << "\n";
68 atf::process::argv_array
argva(argv
);
69 return atf::check::exec(argva
);
73 std::auto_ptr
< atf::check::check_result
>
74 do_exec(const atf::tests::tc
* tc
, const char* helper_name
, const char *carg2
)
76 std::vector
< std::string
> argv
;
77 argv
.push_back(get_process_helpers_path(*tc
, false).str());
78 argv
.push_back(helper_name
);
79 argv
.push_back(carg2
);
80 std::cout
<< "Executing " << argv
[0] << " " << argv
[1] << " "
83 atf::process::argv_array
argva(argv
);
84 return atf::check::exec(argva
);
87 // ------------------------------------------------------------------------
88 // Helper test cases for the free functions.
89 // ------------------------------------------------------------------------
91 ATF_TEST_CASE(h_build_c_o_ok
);
92 ATF_TEST_CASE_HEAD(h_build_c_o_ok
)
94 set_md_var("descr", "Helper test case for build_c_o");
96 ATF_TEST_CASE_BODY(h_build_c_o_ok
)
98 std::ofstream
sfile("test.c");
99 sfile
<< "#include <stdio.h>\n";
102 ATF_REQUIRE(atf::check::build_c_o("test.c", "test.o",
103 atf::process::argv_array()));
106 ATF_TEST_CASE(h_build_c_o_fail
);
107 ATF_TEST_CASE_HEAD(h_build_c_o_fail
)
109 set_md_var("descr", "Helper test case for build_c_o");
111 ATF_TEST_CASE_BODY(h_build_c_o_fail
)
113 std::ofstream
sfile("test.c");
114 sfile
<< "void foo(void) { int a = UNDEFINED_SYMBOL; }\n";
117 ATF_REQUIRE(!atf::check::build_c_o("test.c", "test.o",
118 atf::process::argv_array()));
121 ATF_TEST_CASE(h_build_cpp_ok
);
122 ATF_TEST_CASE_HEAD(h_build_cpp_ok
)
124 set_md_var("descr", "Helper test case for build_cpp");
126 ATF_TEST_CASE_BODY(h_build_cpp_ok
)
128 std::ofstream
sfile("test.c");
129 sfile
<< "#define A foo\n";
130 sfile
<< "#define B bar\n";
134 ATF_REQUIRE(atf::check::build_cpp("test.c", "test.p",
135 atf::process::argv_array()));
138 ATF_TEST_CASE(h_build_cpp_fail
);
139 ATF_TEST_CASE_HEAD(h_build_cpp_fail
)
141 set_md_var("descr", "Helper test case for build_cpp");
143 ATF_TEST_CASE_BODY(h_build_cpp_fail
)
145 std::ofstream
sfile("test.c");
146 sfile
<< "#include \"./non-existent.h\"\n";
149 ATF_REQUIRE(!atf::check::build_cpp("test.c", "test.p",
150 atf::process::argv_array()));
153 ATF_TEST_CASE(h_build_cxx_o_ok
);
154 ATF_TEST_CASE_HEAD(h_build_cxx_o_ok
)
156 set_md_var("descr", "Helper test case for build_cxx_o");
158 ATF_TEST_CASE_BODY(h_build_cxx_o_ok
)
160 std::ofstream
sfile("test.cpp");
161 sfile
<< "#include <iostream>\n";
164 ATF_REQUIRE(atf::check::build_cxx_o("test.cpp", "test.o",
165 atf::process::argv_array()));
168 ATF_TEST_CASE(h_build_cxx_o_fail
);
169 ATF_TEST_CASE_HEAD(h_build_cxx_o_fail
)
171 set_md_var("descr", "Helper test case for build_cxx_o");
173 ATF_TEST_CASE_BODY(h_build_cxx_o_fail
)
175 std::ofstream
sfile("test.cpp");
176 sfile
<< "void foo(void) { int a = UNDEFINED_SYMBOL; }\n";
179 ATF_REQUIRE(!atf::check::build_cxx_o("test.cpp", "test.o",
180 atf::process::argv_array()));
183 // ------------------------------------------------------------------------
184 // Test cases for the free functions.
185 // ------------------------------------------------------------------------
187 ATF_TEST_CASE(build_c_o
);
188 ATF_TEST_CASE_HEAD(build_c_o
)
190 set_md_var("descr", "Tests the build_c_o function");
192 ATF_TEST_CASE_BODY(build_c_o
)
194 ATF_TEST_CASE_USE(h_build_c_o_ok
);
195 run_h_tc
< ATF_TEST_CASE_NAME(h_build_c_o_ok
) >();
196 ATF_REQUIRE(atf::utils::grep_file("-o test.o", "stdout"));
197 ATF_REQUIRE(atf::utils::grep_file("-c test.c", "stdout"));
199 ATF_TEST_CASE_USE(h_build_c_o_fail
);
200 run_h_tc
< ATF_TEST_CASE_NAME(h_build_c_o_fail
) >();
201 ATF_REQUIRE(atf::utils::grep_file("-o test.o", "stdout"));
202 ATF_REQUIRE(atf::utils::grep_file("-c test.c", "stdout"));
203 ATF_REQUIRE(atf::utils::grep_file("test.c", "stderr"));
204 ATF_REQUIRE(atf::utils::grep_file("UNDEFINED_SYMBOL", "stderr"));
207 ATF_TEST_CASE(build_cpp
);
208 ATF_TEST_CASE_HEAD(build_cpp
)
210 set_md_var("descr", "Tests the build_cpp function");
212 ATF_TEST_CASE_BODY(build_cpp
)
214 ATF_TEST_CASE_USE(h_build_cpp_ok
);
215 run_h_tc
< ATF_TEST_CASE_NAME(h_build_cpp_ok
) >();
216 ATF_REQUIRE(atf::utils::grep_file("-o.*test.p", "stdout"));
217 ATF_REQUIRE(atf::utils::grep_file("test.c", "stdout"));
218 ATF_REQUIRE(atf::utils::grep_file("foo bar", "test.p"));
220 ATF_TEST_CASE_USE(h_build_cpp_fail
);
221 run_h_tc
< ATF_TEST_CASE_NAME(h_build_cpp_fail
) >();
222 ATF_REQUIRE(atf::utils::grep_file("-o test.p", "stdout"));
223 ATF_REQUIRE(atf::utils::grep_file("test.c", "stdout"));
224 ATF_REQUIRE(atf::utils::grep_file("test.c", "stderr"));
225 ATF_REQUIRE(atf::utils::grep_file("non-existent.h", "stderr"));
228 ATF_TEST_CASE(build_cxx_o
);
229 ATF_TEST_CASE_HEAD(build_cxx_o
)
231 set_md_var("descr", "Tests the build_cxx_o function");
233 ATF_TEST_CASE_BODY(build_cxx_o
)
235 ATF_TEST_CASE_USE(h_build_cxx_o_ok
);
236 run_h_tc
< ATF_TEST_CASE_NAME(h_build_cxx_o_ok
) >();
237 ATF_REQUIRE(atf::utils::grep_file("-o test.o", "stdout"));
238 ATF_REQUIRE(atf::utils::grep_file("-c test.cpp", "stdout"));
240 ATF_TEST_CASE_USE(h_build_cxx_o_fail
);
241 run_h_tc
< ATF_TEST_CASE_NAME(h_build_cxx_o_fail
) >();
242 ATF_REQUIRE(atf::utils::grep_file("-o test.o", "stdout"));
243 ATF_REQUIRE(atf::utils::grep_file("-c test.cpp", "stdout"));
244 ATF_REQUIRE(atf::utils::grep_file("test.cpp", "stderr"));
245 ATF_REQUIRE(atf::utils::grep_file("UNDEFINED_SYMBOL", "stderr"));
248 ATF_TEST_CASE(exec_cleanup
);
249 ATF_TEST_CASE_HEAD(exec_cleanup
)
251 set_md_var("descr", "Tests that exec properly cleans up the temporary "
254 ATF_TEST_CASE_BODY(exec_cleanup
)
256 std::auto_ptr
< atf::fs::path
> out
;
257 std::auto_ptr
< atf::fs::path
> err
;
260 std::auto_ptr
< atf::check::check_result
> r
=
261 do_exec(this, "exit-success");
262 out
.reset(new atf::fs::path(r
->stdout_path()));
263 err
.reset(new atf::fs::path(r
->stderr_path()));
264 ATF_REQUIRE(atf::fs::exists(*out
.get()));
265 ATF_REQUIRE(atf::fs::exists(*err
.get()));
267 ATF_REQUIRE(!atf::fs::exists(*out
.get()));
268 ATF_REQUIRE(!atf::fs::exists(*err
.get()));
271 ATF_TEST_CASE(exec_exitstatus
);
272 ATF_TEST_CASE_HEAD(exec_exitstatus
)
274 set_md_var("descr", "Tests that exec properly captures the exit "
275 "status of the executed command");
277 ATF_TEST_CASE_BODY(exec_exitstatus
)
280 std::auto_ptr
< atf::check::check_result
> r
=
281 do_exec(this, "exit-success");
282 ATF_REQUIRE(r
->exited());
283 ATF_REQUIRE(!r
->signaled());
284 ATF_REQUIRE_EQ(r
->exitcode(), EXIT_SUCCESS
);
288 std::auto_ptr
< atf::check::check_result
> r
=
289 do_exec(this, "exit-failure");
290 ATF_REQUIRE(r
->exited());
291 ATF_REQUIRE(!r
->signaled());
292 ATF_REQUIRE_EQ(r
->exitcode(), EXIT_FAILURE
);
296 std::auto_ptr
< atf::check::check_result
> r
=
297 do_exec(this, "exit-signal");
298 ATF_REQUIRE(!r
->exited());
299 ATF_REQUIRE(r
->signaled());
300 ATF_REQUIRE_EQ(r
->termsig(), SIGKILL
);
306 check_lines(const std::string
& path
, const char* outname
,
309 std::ifstream
f(path
.c_str());
313 std::getline(f
, line
);
314 ATF_REQUIRE_EQ(line
, std::string("Line 1 to ") + outname
+ " for " +
316 std::getline(f
, line
);
317 ATF_REQUIRE_EQ(line
, std::string("Line 2 to ") + outname
+ " for " +
321 ATF_TEST_CASE(exec_stdout_stderr
);
322 ATF_TEST_CASE_HEAD(exec_stdout_stderr
)
324 set_md_var("descr", "Tests that exec properly captures the stdout "
325 "and stderr streams of the child process");
327 ATF_TEST_CASE_BODY(exec_stdout_stderr
)
329 std::auto_ptr
< atf::check::check_result
> r1
=
330 do_exec(this, "stdout-stderr", "result1");
331 ATF_REQUIRE(r1
->exited());
332 ATF_REQUIRE_EQ(r1
->exitcode(), EXIT_SUCCESS
);
334 std::auto_ptr
< atf::check::check_result
> r2
=
335 do_exec(this, "stdout-stderr", "result2");
336 ATF_REQUIRE(r2
->exited());
337 ATF_REQUIRE_EQ(r2
->exitcode(), EXIT_SUCCESS
);
339 const std::string out1
= r1
->stdout_path();
340 const std::string out2
= r2
->stdout_path();
341 const std::string err1
= r1
->stderr_path();
342 const std::string err2
= r2
->stderr_path();
344 ATF_REQUIRE(out1
.find("check.XXXXXX") == std::string::npos
);
345 ATF_REQUIRE(out2
.find("check.XXXXXX") == std::string::npos
);
346 ATF_REQUIRE(err1
.find("check.XXXXXX") == std::string::npos
);
347 ATF_REQUIRE(err2
.find("check.XXXXXX") == std::string::npos
);
349 ATF_REQUIRE(out1
.find("/check") != std::string::npos
);
350 ATF_REQUIRE(out2
.find("/check") != std::string::npos
);
351 ATF_REQUIRE(err1
.find("/check") != std::string::npos
);
352 ATF_REQUIRE(err2
.find("/check") != std::string::npos
);
354 ATF_REQUIRE(out1
.find("/stdout") != std::string::npos
);
355 ATF_REQUIRE(out2
.find("/stdout") != std::string::npos
);
356 ATF_REQUIRE(err1
.find("/stderr") != std::string::npos
);
357 ATF_REQUIRE(err2
.find("/stderr") != std::string::npos
);
359 ATF_REQUIRE(out1
!= out2
);
360 ATF_REQUIRE(err1
!= err2
);
362 check_lines(out1
, "stdout", "result1");
363 check_lines(out2
, "stdout", "result2");
364 check_lines(err1
, "stderr", "result1");
365 check_lines(err2
, "stderr", "result2");
368 ATF_TEST_CASE(exec_unknown
);
369 ATF_TEST_CASE_HEAD(exec_unknown
)
371 set_md_var("descr", "Tests that running a non-existing binary "
372 "is handled correctly");
374 ATF_TEST_CASE_BODY(exec_unknown
)
376 std::vector
< std::string
> argv
;
377 argv
.push_back(atf::config::get("atf_workdir") + "/non-existent");
379 atf::process::argv_array
argva(argv
);
380 std::auto_ptr
< atf::check::check_result
> r
= atf::check::exec(argva
);
381 ATF_REQUIRE(r
->exited());
382 ATF_REQUIRE_EQ(r
->exitcode(), 127);
385 // ------------------------------------------------------------------------
386 // Tests cases for the header file.
387 // ------------------------------------------------------------------------
389 HEADER_TC(include
, "atf-c++/check.hpp");
391 // ------------------------------------------------------------------------
393 // ------------------------------------------------------------------------
395 ATF_INIT_TEST_CASES(tcs
)
397 // Add the test cases for the free functions.
398 ATF_ADD_TEST_CASE(tcs
, build_c_o
);
399 ATF_ADD_TEST_CASE(tcs
, build_cpp
);
400 ATF_ADD_TEST_CASE(tcs
, build_cxx_o
);
401 ATF_ADD_TEST_CASE(tcs
, exec_cleanup
);
402 ATF_ADD_TEST_CASE(tcs
, exec_exitstatus
);
403 ATF_ADD_TEST_CASE(tcs
, exec_stdout_stderr
);
404 ATF_ADD_TEST_CASE(tcs
, exec_unknown
);
406 // Add the test cases for the header file.
407 ATF_ADD_TEST_CASE(tcs
, include
);