OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "testing/gtest/include/gtest/gtest.h" | 5 #include <stdio.h> |
6 int main(int argc, char *argv[]) { | 6 #include <sys/resource.h> |
7 testing::InitGoogleTest(&argc, argv); | 7 #include <sys/time.h> |
8 // Always go through re-execution for death tests. | 8 |
9 // This makes gtest only marginally slower for us and has the | 9 #include "base/file_util.h" |
10 // additional side effect of getting rid of gtest warnings about fork() | 10 #include "sandbox/linux/tests/unit_tests.h" |
11 // safety. | 11 |
12 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; | 12 namespace sandbox { |
13 return RUN_ALL_TESTS(); | 13 |
| 14 static const int kExpectedValue = 42; |
| 15 |
| 16 void UnitTests::RunTestInProcess(UnitTests::Test test, void *arg) { |
| 17 // Runs a test in a sub-process. This is necessary for most of the code |
| 18 // in the BPF sandbox, as it potentially makes global state changes and as |
| 19 // it also tends to raise fatal errors, if the code has been used in an |
| 20 // insecure manner. |
| 21 int fds[2]; |
| 22 ASSERT_EQ(0, pipe(fds)); |
| 23 |
| 24 pid_t pid; |
| 25 ASSERT_LE(0, (pid = fork())); |
| 26 if (!pid) { |
| 27 // In child process |
| 28 // Redirect stderr to our pipe. This way, we can capture all error |
| 29 // messages, if we decide we want to do so in our tests. |
| 30 SANDBOX_ASSERT(dup2(fds[1], 2) == 2); |
| 31 SANDBOX_ASSERT(!close(fds[0])); |
| 32 SANDBOX_ASSERT(!close(fds[1])); |
| 33 |
| 34 // Disable core files. They are not very useful for our individual test |
| 35 // cases. |
| 36 struct rlimit no_core = { 0 }; |
| 37 setrlimit(RLIMIT_CORE, &no_core); |
| 38 |
| 39 test(arg); |
| 40 _exit(kExpectedValue); |
| 41 } |
| 42 |
| 43 (void)HANDLE_EINTR(close(fds[1])); |
| 44 std::vector<char> msg; |
| 45 ssize_t rc; |
| 46 do { |
| 47 const unsigned int kCapacity = 256; |
| 48 size_t len = msg.size(); |
| 49 msg.resize(len + kCapacity); |
| 50 rc = HANDLE_EINTR(read(fds[0], &msg[len], kCapacity)); |
| 51 msg.resize(len + std::max(rc, static_cast<ssize_t>(0))); |
| 52 } while (rc > 0); |
| 53 std::string details; |
| 54 if (!msg.empty()) { |
| 55 details = "Actual test failure: " + std::string(msg.begin(), msg.end()); |
| 56 } |
| 57 (void)HANDLE_EINTR(close(fds[0])); |
| 58 |
| 59 int status = 0; |
| 60 int waitpid_returned = HANDLE_EINTR(waitpid(pid, &status, 0)); |
| 61 ASSERT_EQ(pid, waitpid_returned) << details; |
| 62 bool subprocess_terminated_normally = WIFEXITED(status); |
| 63 ASSERT_TRUE(subprocess_terminated_normally) << details; |
| 64 int subprocess_exit_status = WEXITSTATUS(status); |
| 65 ASSERT_EQ(kExpectedValue, subprocess_exit_status) << details; |
| 66 bool subprocess_exited_but_printed_messages = !msg.empty(); |
| 67 EXPECT_FALSE(subprocess_exited_but_printed_messages) << details; |
14 } | 68 } |
| 69 |
| 70 void UnitTests::AssertionFailure(const char *expr, const char *file, |
| 71 int line) { |
| 72 fprintf(stderr, "%s:%d:%s", file, line, expr); |
| 73 fflush(stderr); |
| 74 _exit(1); |
| 75 } |
| 76 |
| 77 } // namespace |
OLD | NEW |