1 // Copyright 2010 Google 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 are
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.
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.
29 #include "utils/sanity.hpp"
39 #include <atf-c++.hpp>
41 #include "utils/format/macros.hpp"
42 #include "utils/fs/path.hpp"
43 #include "utils/process/child.ipp"
44 #include "utils/process/status.hpp"
46 namespace fs
= utils::fs
;
47 namespace process
= utils::process
;
50 #define FILE_REGEXP __FILE__ ":[0-9]+: "
53 static const fs::path
Stdout_File("stdout.txt");
54 static const fs::path
Stderr_File("stderr.txt");
58 static bool NDebug
= true;
60 static bool NDebug
= false;
64 template< typename Function
>
65 static process::status
66 run_test(Function function
)
68 const process::status status
= process::child::fork_files(
69 function
, Stdout_File
, Stderr_File
)->wait();
70 atf::utils::cat_file(Stdout_File
.str(), "Helper stdout: ");
71 atf::utils::cat_file(Stderr_File
.str(), "Helper stderr: ");
77 verify_success(const process::status
& status
)
79 ATF_REQUIRE(status
.exited());
80 ATF_REQUIRE_EQ(EXIT_SUCCESS
, status
.exitstatus());
81 ATF_REQUIRE(atf::utils::grep_file("Before test", Stdout_File
.str()));
82 ATF_REQUIRE(atf::utils::grep_file("After test", Stdout_File
.str()));
87 verify_failed(const process::status
& status
, const char* type
,
88 const char* exp_message
, const bool check_ndebug
)
90 if (check_ndebug
&& NDebug
) {
91 std::cout
<< "Built with NDEBUG; skipping verification\n";
92 verify_success(status
);
94 ATF_REQUIRE(status
.signaled());
95 ATF_REQUIRE_EQ(SIGABRT
, status
.termsig());
96 ATF_REQUIRE(atf::utils::grep_file("Before test", Stdout_File
.str()));
97 ATF_REQUIRE(!atf::utils::grep_file("After test", Stdout_File
.str()));
98 if (exp_message
!= NULL
)
99 ATF_REQUIRE(atf::utils::grep_file(F(FILE_REGEXP
"%s: %s") %
103 ATF_REQUIRE(atf::utils::grep_file(F(FILE_REGEXP
"%s") % type
,
109 template< bool Expression
, bool WithMessage
>
113 std::cout
<< "Before test\n";
115 INV_MSG(Expression
, "Custom message");
118 std::cout
<< "After test\n";
119 std::exit(EXIT_SUCCESS
);
123 ATF_TEST_CASE_WITHOUT_HEAD(inv__holds
);
124 ATF_TEST_CASE_BODY(inv__holds
)
126 const process::status status
= run_test(do_inv_test
< true, false >);
127 verify_success(status
);
131 ATF_TEST_CASE_WITHOUT_HEAD(inv__triggers_default_message
);
132 ATF_TEST_CASE_BODY(inv__triggers_default_message
)
134 const process::status status
= run_test(do_inv_test
< false, false >);
135 verify_failed(status
, "Invariant check failed", "Expression", true);
139 ATF_TEST_CASE_WITHOUT_HEAD(inv__triggers_custom_message
);
140 ATF_TEST_CASE_BODY(inv__triggers_custom_message
)
142 const process::status status
= run_test(do_inv_test
< false, true >);
143 verify_failed(status
, "Invariant check failed", "Custom", true);
147 template< bool Expression
, bool WithMessage
>
151 std::cout
<< "Before test\n";
153 PRE_MSG(Expression
, "Custom message");
156 std::cout
<< "After test\n";
157 std::exit(EXIT_SUCCESS
);
161 ATF_TEST_CASE_WITHOUT_HEAD(pre__holds
);
162 ATF_TEST_CASE_BODY(pre__holds
)
164 const process::status status
= run_test(do_pre_test
< true, false >);
165 verify_success(status
);
169 ATF_TEST_CASE_WITHOUT_HEAD(pre__triggers_default_message
);
170 ATF_TEST_CASE_BODY(pre__triggers_default_message
)
172 const process::status status
= run_test(do_pre_test
< false, false >);
173 verify_failed(status
, "Precondition check failed", "Expression", true);
177 ATF_TEST_CASE_WITHOUT_HEAD(pre__triggers_custom_message
);
178 ATF_TEST_CASE_BODY(pre__triggers_custom_message
)
180 const process::status status
= run_test(do_pre_test
< false, true >);
181 verify_failed(status
, "Precondition check failed", "Custom", true);
185 template< bool Expression
, bool WithMessage
>
189 std::cout
<< "Before test\n";
191 POST_MSG(Expression
, "Custom message");
194 std::cout
<< "After test\n";
195 std::exit(EXIT_SUCCESS
);
199 ATF_TEST_CASE_WITHOUT_HEAD(post__holds
);
200 ATF_TEST_CASE_BODY(post__holds
)
202 const process::status status
= run_test(do_post_test
< true, false >);
203 verify_success(status
);
207 ATF_TEST_CASE_WITHOUT_HEAD(post__triggers_default_message
);
208 ATF_TEST_CASE_BODY(post__triggers_default_message
)
210 const process::status status
= run_test(do_post_test
< false, false >);
211 verify_failed(status
, "Postcondition check failed", "Expression", true);
215 ATF_TEST_CASE_WITHOUT_HEAD(post__triggers_custom_message
);
216 ATF_TEST_CASE_BODY(post__triggers_custom_message
)
218 const process::status status
= run_test(do_post_test
< false, true >);
219 verify_failed(status
, "Postcondition check failed", "Custom", true);
223 template< bool WithMessage
>
225 do_unreachable_test(void)
227 std::cout
<< "Before test\n";
229 UNREACHABLE_MSG("Custom message");
232 std::cout
<< "After test\n";
233 std::exit(EXIT_SUCCESS
);
237 ATF_TEST_CASE_WITHOUT_HEAD(unreachable__default_message
);
238 ATF_TEST_CASE_BODY(unreachable__default_message
)
240 const process::status status
= run_test(do_unreachable_test
< false >);
241 verify_failed(status
, "Unreachable point reached", NULL
, false);
245 ATF_TEST_CASE_WITHOUT_HEAD(unreachable__custom_message
);
246 ATF_TEST_CASE_BODY(unreachable__custom_message
)
248 const process::status status
= run_test(do_unreachable_test
< true >);
249 verify_failed(status
, "Unreachable point reached", "Custom", false);
253 template< int Signo
>
255 do_crash_handler_test(void)
257 utils::install_crash_handlers("test-log.txt");
258 ::kill(::getpid(), Signo
);
259 std::cout
<< "After signal\n";
260 std::exit(EXIT_FAILURE
);
264 template< int Signo
>
266 crash_handler_test(void)
268 const process::status status
= run_test(do_crash_handler_test
< Signo
>);
269 ATF_REQUIRE(status
.signaled());
270 ATF_REQUIRE_EQ(Signo
, status
.termsig());
271 ATF_REQUIRE(atf::utils::grep_file(F("Fatal signal %s") % Signo
,
273 ATF_REQUIRE(atf::utils::grep_file("Log file is test-log.txt",
275 ATF_REQUIRE(!atf::utils::grep_file("After signal", Stdout_File
.str()));
279 ATF_TEST_CASE_WITHOUT_HEAD(install_crash_handlers__sigabrt
);
280 ATF_TEST_CASE_BODY(install_crash_handlers__sigabrt
)
282 crash_handler_test
< SIGABRT
>();
286 ATF_TEST_CASE_WITHOUT_HEAD(install_crash_handlers__sigbus
);
287 ATF_TEST_CASE_BODY(install_crash_handlers__sigbus
)
289 crash_handler_test
< SIGBUS
>();
293 ATF_TEST_CASE_WITHOUT_HEAD(install_crash_handlers__sigsegv
);
294 ATF_TEST_CASE_BODY(install_crash_handlers__sigsegv
)
296 crash_handler_test
< SIGSEGV
>();
300 ATF_INIT_TEST_CASES(tcs
)
302 ATF_ADD_TEST_CASE(tcs
, inv__holds
);
303 ATF_ADD_TEST_CASE(tcs
, inv__triggers_default_message
);
304 ATF_ADD_TEST_CASE(tcs
, inv__triggers_custom_message
);
305 ATF_ADD_TEST_CASE(tcs
, pre__holds
);
306 ATF_ADD_TEST_CASE(tcs
, pre__triggers_default_message
);
307 ATF_ADD_TEST_CASE(tcs
, pre__triggers_custom_message
);
308 ATF_ADD_TEST_CASE(tcs
, post__holds
);
309 ATF_ADD_TEST_CASE(tcs
, post__triggers_default_message
);
310 ATF_ADD_TEST_CASE(tcs
, post__triggers_custom_message
);
311 ATF_ADD_TEST_CASE(tcs
, unreachable__default_message
);
312 ATF_ADD_TEST_CASE(tcs
, unreachable__custom_message
);
314 ATF_ADD_TEST_CASE(tcs
, install_crash_handlers__sigabrt
);
315 ATF_ADD_TEST_CASE(tcs
, install_crash_handlers__sigbus
);
316 ATF_ADD_TEST_CASE(tcs
, install_crash_handlers__sigsegv
);