Improve the process for GNU tools
[minix3.git] / external / bsd / kyua-cli / dist / utils / sanity_test.cpp
blob4b281bdfa90b4e947562c5d04f87022389730577
1 // Copyright 2010 Google Inc.
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.
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"
31 extern "C" {
32 #include <signal.h>
33 #include <unistd.h>
36 #include <cstdlib>
37 #include <iostream>
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");
57 #if NDEBUG
58 static bool NDebug = true;
59 #else
60 static bool NDebug = false;
61 #endif
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: ");
72 return status;
76 static void
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()));
86 static void
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);
93 } else {
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") %
100 type % exp_message,
101 Stderr_File.str()));
102 else
103 ATF_REQUIRE(atf::utils::grep_file(F(FILE_REGEXP "%s") % type,
104 Stderr_File.str()));
109 template< bool Expression, bool WithMessage >
110 static void
111 do_inv_test(void)
113 std::cout << "Before test\n";
114 if (WithMessage)
115 INV_MSG(Expression, "Custom message");
116 else
117 INV(Expression);
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 >
148 static void
149 do_pre_test(void)
151 std::cout << "Before test\n";
152 if (WithMessage)
153 PRE_MSG(Expression, "Custom message");
154 else
155 PRE(Expression);
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 >
186 static void
187 do_post_test(void)
189 std::cout << "Before test\n";
190 if (WithMessage)
191 POST_MSG(Expression, "Custom message");
192 else
193 POST(Expression);
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 >
224 static void
225 do_unreachable_test(void)
227 std::cout << "Before test\n";
228 if (WithMessage)
229 UNREACHABLE_MSG("Custom message");
230 else
231 UNREACHABLE;
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 >
254 static void
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 >
265 static void
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,
272 Stderr_File.str()));
273 ATF_REQUIRE(atf::utils::grep_file("Log file is test-log.txt",
274 Stderr_File.str()));
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);