unit_tests.h revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef SANDBOX_LINUX_TESTS_UNIT_TESTS_H__ 6#define SANDBOX_LINUX_TESTS_UNIT_TESTS_H__ 7 8#include "base/basictypes.h" 9#include "testing/gtest/include/gtest/gtest.h" 10 11namespace sandbox { 12 13// While it is perfectly OK for a complex test to provide its own DeathCheck 14// function. Most death tests have very simple requirements. These tests should 15// use one of the predefined DEATH_XXX macros as an argument to 16// SANDBOX_DEATH_TEST(). You can check for a (sub-)string in the output of the 17// test, for a particular exit code, or for a particular death signal. 18// NOTE: If you do decide to write your own DeathCheck, make sure to use 19// gtests's ASSERT_XXX() macros instead of SANDBOX_ASSERT(). See 20// unit_tests.cc for examples. 21#define DEATH_SUCCESS() sandbox::UnitTests::DeathSuccess, NULL 22#define DEATH_MESSAGE(msg) sandbox::UnitTests::DeathMessage, \ 23 static_cast<const void *>( \ 24 static_cast<const char *>(msg)) 25#define DEATH_EXIT_CODE(rc) sandbox::UnitTests::DeathExitCode, \ 26 reinterpret_cast<void *>(static_cast<intptr_t>(rc)) 27#define DEATH_BY_SIGNAL(s) sandbox::UnitTests::DeathExitCode, \ 28 reinterpret_cast<void *>(static_cast<intptr_t>(s)) 29 30// A SANDBOX_DEATH_TEST is just like a SANDBOX_TEST (see below), but it assumes 31// that the test actually dies. The death test only passes if the death occurs 32// in the expected fashion, as specified by "death" and "death_aux". These two 33// parameters are typically set to one of the DEATH_XXX() macros. 34#define SANDBOX_DEATH_TEST(test_case_name, test_name, death) \ 35 void TEST_##test_name(void *); \ 36 TEST(test_case_name, test_name) { \ 37 sandbox::UnitTests::RunTestInProcess(TEST_##test_name, NULL, death); \ 38 } \ 39 void TEST_##test_name(void *) 40 41// Define a new test case that runs inside of a GTest death test. This is 42// necessary, as most of our tests by definition make global and irreversible 43// changes to the system (i.e. they install a sandbox). GTest provides death 44// tests as a tool to isolate global changes from the rest of the tests. 45#define SANDBOX_TEST(test_case_name, test_name) \ 46 SANDBOX_DEATH_TEST(test_case_name, test_name, DEATH_SUCCESS()) 47 48// Simple assertion macro that is compatible with running inside of a death 49// test. We unfortunately cannot use any of the GTest macros. 50#define SANDBOX_STR(x) #x 51#define SANDBOX_ASSERT(expr) \ 52 ((expr) \ 53 ? static_cast<void>(0) \ 54 : sandbox::UnitTests::AssertionFailure(SANDBOX_STR(expr), \ 55 __FILE__, __LINE__)) 56 57class UnitTests { 58 public: 59 typedef void (*Test)(void *); 60 typedef void (*DeathCheck)(int status, const std::string& msg, 61 const void *aux); 62 63 // Runs a test inside a short-lived process. Do not call this function 64 // directly. It is automatically invoked by SANDBOX_TEST(). Most sandboxing 65 // functions make global irreversible changes to the execution environment 66 // and must therefore execute in their own isolated process. 67 static void RunTestInProcess(Test test, void *arg, DeathCheck death, 68 const void *death_aux); 69 70 // Report a useful error message and terminate the current SANDBOX_TEST(). 71 // Calling this function from outside a SANDBOX_TEST() is unlikely to do 72 // anything useful. 73 static void AssertionFailure(const char *expr, const char *file, int line); 74 75 // Sometimes we determine at run-time that a test should be disabled. 76 // Call this method if we want to return from a test and completely 77 // ignore its results. 78 // You should not call this method, if the test already ran any test-relevant 79 // code. Most notably, you should not call it, you already wrote any messages 80 // to stderr. 81 static void IgnoreThisTest(); 82 83 // A DeathCheck method that verifies that the test completed succcessfully. 84 // This is the default test mode for SANDBOX_TEST(). The "aux" parameter 85 // of this DeathCheck is unused (and thus unnamed) 86 static void DeathSuccess(int status, const std::string& msg, const void *); 87 88 // A DeathCheck method that verifies that the test completed with error 89 // code "1" and printed a message containing a particular substring. The 90 // "aux" pointer should point to a C-string containing the expected error 91 // message. This method is useful for checking assertion failures such as 92 // in SANDBOX_ASSERT() and/or SANDBOX_DIE(). 93 static void DeathMessage(int status, const std::string& msg, 94 const void *aux); 95 96 // A DeathCheck method that verifies that the test completed with a 97 // particular exit code. If the test output any messages to stderr, they are 98 // silently ignored. The expected exit code should be passed in by 99 // casting the its "int" value to a "void *", which is then used for "aux". 100 static void DeathExitCode(int status, const std::string& msg, 101 const void *aux); 102 103 // A DeathCheck method that verifies that the test was terminated by a 104 // particular signal. If the test output any messages to stderr, they are 105 // silently ignore. The expected signal number should be passed in by 106 // casting the its "int" value to a "void *", which is then used for "aux". 107 static void DeathBySignal(int status, const std::string& msg, 108 const void *aux); 109 110 private: 111 DISALLOW_IMPLICIT_CONSTRUCTORS(UnitTests); 112}; 113 114} // namespace 115 116#endif // SANDBOX_LINUX_TESTS_UNIT_TESTS_H__ 117