15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <fcntl.h> 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <poll.h> 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <signal.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/resource.h> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/time.h> 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <unistd.h> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/third_party/valgrind/valgrind.h" 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "build/build_config.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/linux/tests/unit_tests.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string TestFailedMessage(const std::string& msg) { 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return msg.empty() ? std::string() : "Actual test failure: " + msg; 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int GetSubProcessTimeoutTimeInSeconds() { 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 10s ought to be enough for anybody. 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 10; 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns the number of threads of the current process or -1. 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int CountThreads() { 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct stat task_stat; 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int task_d = stat("/proc/self/task", &task_stat); 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // task_stat.st_nlink should be the number of tasks + 2 (accounting for 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // "." and "..". 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (task_d != 0 || task_stat.st_nlink < 3) 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return -1; 36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const int num_threads = task_stat.st_nlink - 2; 37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return num_threads; 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace sandbox { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool IsAndroid() { 457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#if defined(OS_ANDROID) 467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return true; 477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#else 487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#endif 507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool IsArchitectureArm() { 537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#if defined(ARCH_CPU_ARM_FAMILY) 547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return true; 557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#else 567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#endif 587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// TODO(jln): figure out why base/.../dynamic_annotations.h's 617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// RunningOnValgrind() cannot link. 627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool IsRunningOnValgrind() { 637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return RUNNING_ON_VALGRIND; 647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kExpectedValue = 42; 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const int kIgnoreThisTest = 43; 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const int kExitWithAssertionFailure = 1; 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const int kExitForTimeout = 2; 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static void SigAlrmHandler(int) { 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char failure_message[] = "Timeout reached!\n"; 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make sure that we never block here. 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!fcntl(2, F_SETFL, O_NONBLOCK)) { 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (write(2, failure_message, sizeof(failure_message) - 1) < 0) { 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) _exit(kExitForTimeout); 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Set a timeout with a handler that will automatically fail the 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// test. 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static void SetProcessTimeout(int time_in_seconds) { 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct sigaction act = {}; 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) act.sa_handler = SigAlrmHandler; 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SANDBOX_ASSERT(sigemptyset(&act.sa_mask) == 0); 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) act.sa_flags = 0; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct sigaction old_act; 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SANDBOX_ASSERT(sigaction(SIGALRM, &act, &old_act) == 0); 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We don't implemenet signal chaining, so make sure that nothing else 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // is expecting to handle SIGALRM. 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SANDBOX_ASSERT((old_act.sa_flags & SA_SIGINFO) == 0); 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SANDBOX_ASSERT(old_act.sa_handler == SIG_DFL); 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sigset_t sigalrm_set; 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SANDBOX_ASSERT(sigemptyset(&sigalrm_set) == 0); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SANDBOX_ASSERT(sigaddset(&sigalrm_set, SIGALRM) == 0); 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SANDBOX_ASSERT(sigprocmask(SIG_UNBLOCK, &sigalrm_set, NULL) == 0); 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SANDBOX_ASSERT(alarm(time_in_seconds) == 0); // There should be no previous 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // alarm. 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Runs a test in a sub-process. This is necessary for most of the code 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// in the BPF sandbox, as it potentially makes global state changes and as 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// it also tends to raise fatal errors, if the code has been used in an 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// insecure manner. 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void UnitTests::RunTestInProcess(UnitTests::Test test, void *arg, 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeathCheck death, const void *death_aux) { 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // We need to fork(), so we can't be multi-threaded, as threads could hold 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // locks. 112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int num_threads = CountThreads(); 113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(THREAD_SANITIZER) 114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Under TSAN, there is a special helper thread. It should be completely 115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // invisible to our testing, so we ignore it. It should be ok to fork() 116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // with this thread. It's currently buggy, but it's the best we can do until 117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // there is a way to delay the start of the thread 118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // (https://code.google.com/p/thread-sanitizer/issues/detail?id=19). 119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch num_threads--; 120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(1, num_threads) << "Running sandbox tests with multiple threads " 122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << "is not supported and will make the tests " 123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << "flaky.\n"; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int fds[2]; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, pipe(fds)); 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check that our pipe is not on one of the standard file descriptor. 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SANDBOX_ASSERT(fds[0] > 2 && fds[1] > 2); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pid_t pid; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_LE(0, (pid = fork())); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pid) { 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In child process 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Redirect stderr to our pipe. This way, we can capture all error 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // messages, if we decide we want to do so in our tests. 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(dup2(fds[1], 2) == 2); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(!close(fds[0])); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(!close(fds[1])); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Don't set a timeout if running on Valgrind, since it's generally much 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // slower. 1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!IsRunningOnValgrind()) { 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetProcessTimeout(GetSubProcessTimeoutTimeInSeconds()); 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Disable core files. They are not very useful for our individual test 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cases. 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct rlimit no_core = { 0 }; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) setrlimit(RLIMIT_CORE, &no_core); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test(arg); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _exit(kExpectedValue); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (void)HANDLE_EINTR(close(fds[1])); 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<char> msg_buf; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssize_t rc; 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make sure read() will never block as we'll use poll() to 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // block with a timeout instead. 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int fcntl_ret = fcntl(fds[0], F_SETFL, O_NONBLOCK); 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(fcntl_ret, 0); 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct pollfd poll_fd = { fds[0], POLLIN | POLLRDHUP, 0 }; 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int poll_ret; 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We prefer the SIGALRM timeout to trigger in the child than this timeout 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // so we double the common value here. 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int poll_timeout = GetSubProcessTimeoutTimeInSeconds() * 2 * 1000; 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while ((poll_ret = poll(&poll_fd, 1, poll_timeout) > 0)) { 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const size_t kCapacity = 256; 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const size_t len = msg_buf.size(); 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) msg_buf.resize(len + kCapacity); 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rc = HANDLE_EINTR(read(fds[0], &msg_buf[len], kCapacity)); 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) msg_buf.resize(len + std::max(rc, static_cast<ssize_t>(0))); 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rc <= 0) 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_NE(poll_ret, -1) << "poll() failed"; 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_NE(poll_ret, 0) << "Timeout while reading child state"; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (void)HANDLE_EINTR(close(fds[0])); 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string msg(msg_buf.begin(), msg_buf.end()); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int status = 0; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int waitpid_returned = HANDLE_EINTR(waitpid(pid, &status, 0)); 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(pid, waitpid_returned) << TestFailedMessage(msg); 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // At run-time, we sometimes decide that a test shouldn't actually 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // run (e.g. when testing sandbox features on a kernel that doesn't 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // have sandboxing support). When that happens, don't attempt to 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // call the "death" function, as it might be looking for a 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // death-test condition that would never have triggered. 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!WIFEXITED(status) || WEXITSTATUS(status) != kIgnoreThisTest || 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !msg.empty()) { 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We use gtest's ASSERT_XXX() macros instead of the DeathCheck 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // functions. This means, on failure, "return" is called. This 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // only works correctly, if the call of the "death" callback is 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the very last thing in our function. 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) death(status, msg, death_aux); 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void UnitTests::DeathSuccess(int status, const std::string& msg, 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const void *) { 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string details(TestFailedMessage(msg)); 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool subprocess_terminated_normally = WIFEXITED(status); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(subprocess_terminated_normally) << details; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int subprocess_exit_status = WEXITSTATUS(status); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(kExpectedValue, subprocess_exit_status) << details; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool subprocess_exited_but_printed_messages = !msg.empty(); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(subprocess_exited_but_printed_messages) << details; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void UnitTests::DeathMessage(int status, const std::string& msg, 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const void *aux) { 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string details(TestFailedMessage(msg)); 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char *expected_msg = static_cast<const char *>(aux); 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool subprocess_terminated_normally = WIFEXITED(status); 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(subprocess_terminated_normally) << details; 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int subprocess_exit_status = WEXITSTATUS(status); 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(kExitWithAssertionFailure, subprocess_exit_status) << details; 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool subprocess_exited_without_matching_message = 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) msg.find(expected_msg) == std::string::npos; 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(subprocess_exited_without_matching_message) << details; 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void UnitTests::DeathExitCode(int status, const std::string& msg, 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const void *aux) { 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int expected_exit_code = static_cast<int>(reinterpret_cast<intptr_t>(aux)); 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string details(TestFailedMessage(msg)); 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool subprocess_terminated_normally = WIFEXITED(status); 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(subprocess_terminated_normally) << details; 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int subprocess_exit_status = WEXITSTATUS(status); 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(subprocess_exit_status, expected_exit_code) << details; 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void UnitTests::DeathBySignal(int status, const std::string& msg, 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const void *aux) { 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int expected_signo = static_cast<int>(reinterpret_cast<intptr_t>(aux)); 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string details(TestFailedMessage(msg)); 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool subprocess_terminated_by_signal = WIFSIGNALED(status); 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(subprocess_terminated_by_signal) << details; 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int subprocess_signal_number = WTERMSIG(status); 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(subprocess_signal_number, expected_signo) << details; 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UnitTests::AssertionFailure(const char *expr, const char *file, 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int line) { 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "%s:%d:%s", file, line, expr); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fflush(stderr); 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) _exit(kExitWithAssertionFailure); 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void UnitTests::IgnoreThisTest() { 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fflush(stderr); 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) _exit(kIgnoreThisTest); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 262