Ignore non-active fullscreen windows for shelf state.
[chromium-blink-merge.git] / sandbox / linux / tests / unit_tests.cc
blobad30d840f43acf7c573442892692612b0cd0aabf
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.
5 #include <fcntl.h>
6 #include <poll.h>
7 #include <signal.h>
8 #include <stdio.h>
9 #include <sys/resource.h>
10 #include <sys/time.h>
11 #include <unistd.h>
13 #include "base/file_util.h"
14 #include "base/third_party/valgrind/valgrind.h"
15 #include "build/build_config.h"
16 #include "sandbox/linux/tests/unit_tests.h"
18 namespace {
19 std::string TestFailedMessage(const std::string& msg) {
20 return msg.empty() ? std::string() : "Actual test failure: " + msg;
23 int GetSubProcessTimeoutTimeInSeconds() {
24 // 10s ought to be enough for anybody.
25 return 10;
28 // Returns the number of threads of the current process or -1.
29 int CountThreads() {
30 struct stat task_stat;
31 int task_d = stat("/proc/self/task", &task_stat);
32 // task_stat.st_nlink should be the number of tasks + 2 (accounting for
33 // "." and "..".
34 if (task_d != 0 || task_stat.st_nlink < 3)
35 return -1;
36 const int num_threads = task_stat.st_nlink - 2;
37 return num_threads;
40 } // namespace
42 namespace sandbox {
44 bool IsAndroid() {
45 #if defined(OS_ANDROID)
46 return true;
47 #else
48 return false;
49 #endif
52 bool IsArchitectureArm() {
53 #if defined(ARCH_CPU_ARM_FAMILY)
54 return true;
55 #else
56 return false;
57 #endif
60 // TODO(jln): figure out why base/.../dynamic_annotations.h's
61 // RunningOnValgrind() cannot link.
62 bool IsRunningOnValgrind() { return RUNNING_ON_VALGRIND; }
64 static const int kExpectedValue = 42;
65 static const int kIgnoreThisTest = 43;
66 static const int kExitWithAssertionFailure = 1;
67 static const int kExitForTimeout = 2;
69 static void SigAlrmHandler(int) {
70 const char failure_message[] = "Timeout reached!\n";
71 // Make sure that we never block here.
72 if (!fcntl(2, F_SETFL, O_NONBLOCK)) {
73 ignore_result(write(2, failure_message, sizeof(failure_message) - 1));
75 _exit(kExitForTimeout);
78 // Set a timeout with a handler that will automatically fail the
79 // test.
80 static void SetProcessTimeout(int time_in_seconds) {
81 struct sigaction act = {};
82 act.sa_handler = SigAlrmHandler;
83 SANDBOX_ASSERT(sigemptyset(&act.sa_mask) == 0);
84 act.sa_flags = 0;
86 struct sigaction old_act;
87 SANDBOX_ASSERT(sigaction(SIGALRM, &act, &old_act) == 0);
89 // We don't implemenet signal chaining, so make sure that nothing else
90 // is expecting to handle SIGALRM.
91 SANDBOX_ASSERT((old_act.sa_flags & SA_SIGINFO) == 0);
92 SANDBOX_ASSERT(old_act.sa_handler == SIG_DFL);
93 sigset_t sigalrm_set;
94 SANDBOX_ASSERT(sigemptyset(&sigalrm_set) == 0);
95 SANDBOX_ASSERT(sigaddset(&sigalrm_set, SIGALRM) == 0);
96 SANDBOX_ASSERT(sigprocmask(SIG_UNBLOCK, &sigalrm_set, NULL) == 0);
97 SANDBOX_ASSERT(alarm(time_in_seconds) == 0); // There should be no previous
98 // alarm.
101 // Runs a test in a sub-process. This is necessary for most of the code
102 // in the BPF sandbox, as it potentially makes global state changes and as
103 // it also tends to raise fatal errors, if the code has been used in an
104 // insecure manner.
105 void UnitTests::RunTestInProcess(UnitTests::Test test,
106 void* arg,
107 DeathCheck death,
108 const void* death_aux) {
109 // We need to fork(), so we can't be multi-threaded, as threads could hold
110 // locks.
111 int num_threads = CountThreads();
112 #if defined(THREAD_SANITIZER)
113 // Under TSAN, there is a special helper thread. It should be completely
114 // invisible to our testing, so we ignore it. It should be ok to fork()
115 // with this thread. It's currently buggy, but it's the best we can do until
116 // there is a way to delay the start of the thread
117 // (https://code.google.com/p/thread-sanitizer/issues/detail?id=19).
118 num_threads--;
119 #endif
120 ASSERT_EQ(1, num_threads) << "Running sandbox tests with multiple threads "
121 << "is not supported and will make the tests "
122 << "flaky.\n";
123 int fds[2];
124 ASSERT_EQ(0, pipe(fds));
125 // Check that our pipe is not on one of the standard file descriptor.
126 SANDBOX_ASSERT(fds[0] > 2 && fds[1] > 2);
128 pid_t pid;
129 ASSERT_LE(0, (pid = fork()));
130 if (!pid) {
131 // In child process
132 // Redirect stderr to our pipe. This way, we can capture all error
133 // messages, if we decide we want to do so in our tests.
134 SANDBOX_ASSERT(dup2(fds[1], 2) == 2);
135 SANDBOX_ASSERT(!close(fds[0]));
136 SANDBOX_ASSERT(!close(fds[1]));
138 // Don't set a timeout if running on Valgrind, since it's generally much
139 // slower.
140 if (!IsRunningOnValgrind()) {
141 SetProcessTimeout(GetSubProcessTimeoutTimeInSeconds());
144 // Disable core files. They are not very useful for our individual test
145 // cases.
146 struct rlimit no_core = {0};
147 setrlimit(RLIMIT_CORE, &no_core);
149 test(arg);
150 _exit(kExpectedValue);
153 close(fds[1]);
154 std::vector<char> msg_buf;
155 ssize_t rc;
157 // Make sure read() will never block as we'll use poll() to
158 // block with a timeout instead.
159 const int fcntl_ret = fcntl(fds[0], F_SETFL, O_NONBLOCK);
160 ASSERT_EQ(fcntl_ret, 0);
161 struct pollfd poll_fd = {fds[0], POLLIN | POLLRDHUP, 0};
163 int poll_ret;
164 // We prefer the SIGALRM timeout to trigger in the child than this timeout
165 // so we double the common value here.
166 int poll_timeout = GetSubProcessTimeoutTimeInSeconds() * 2 * 1000;
167 while ((poll_ret = poll(&poll_fd, 1, poll_timeout) > 0)) {
168 const size_t kCapacity = 256;
169 const size_t len = msg_buf.size();
170 msg_buf.resize(len + kCapacity);
171 rc = HANDLE_EINTR(read(fds[0], &msg_buf[len], kCapacity));
172 msg_buf.resize(len + std::max(rc, static_cast<ssize_t>(0)));
173 if (rc <= 0)
174 break;
176 ASSERT_NE(poll_ret, -1) << "poll() failed";
177 ASSERT_NE(poll_ret, 0) << "Timeout while reading child state";
178 close(fds[0]);
179 std::string msg(msg_buf.begin(), msg_buf.end());
181 int status = 0;
182 int waitpid_returned = HANDLE_EINTR(waitpid(pid, &status, 0));
183 ASSERT_EQ(pid, waitpid_returned) << TestFailedMessage(msg);
185 // At run-time, we sometimes decide that a test shouldn't actually
186 // run (e.g. when testing sandbox features on a kernel that doesn't
187 // have sandboxing support). When that happens, don't attempt to
188 // call the "death" function, as it might be looking for a
189 // death-test condition that would never have triggered.
190 if (!WIFEXITED(status) || WEXITSTATUS(status) != kIgnoreThisTest ||
191 !msg.empty()) {
192 // We use gtest's ASSERT_XXX() macros instead of the DeathCheck
193 // functions. This means, on failure, "return" is called. This
194 // only works correctly, if the call of the "death" callback is
195 // the very last thing in our function.
196 death(status, msg, death_aux);
200 void UnitTests::DeathSuccess(int status, const std::string& msg, const void*) {
201 std::string details(TestFailedMessage(msg));
203 bool subprocess_terminated_normally = WIFEXITED(status);
204 ASSERT_TRUE(subprocess_terminated_normally) << details;
205 int subprocess_exit_status = WEXITSTATUS(status);
206 ASSERT_EQ(kExpectedValue, subprocess_exit_status) << details;
207 bool subprocess_exited_but_printed_messages = !msg.empty();
208 EXPECT_FALSE(subprocess_exited_but_printed_messages) << details;
211 void UnitTests::DeathMessage(int status,
212 const std::string& msg,
213 const void* aux) {
214 std::string details(TestFailedMessage(msg));
215 const char* expected_msg = static_cast<const char*>(aux);
217 bool subprocess_terminated_normally = WIFEXITED(status);
218 ASSERT_TRUE(subprocess_terminated_normally) << details;
219 int subprocess_exit_status = WEXITSTATUS(status);
220 ASSERT_EQ(kExitWithAssertionFailure, subprocess_exit_status) << details;
221 bool subprocess_exited_without_matching_message =
222 msg.find(expected_msg) == std::string::npos;
223 EXPECT_FALSE(subprocess_exited_without_matching_message) << details;
226 void UnitTests::DeathExitCode(int status,
227 const std::string& msg,
228 const void* aux) {
229 int expected_exit_code = static_cast<int>(reinterpret_cast<intptr_t>(aux));
230 std::string details(TestFailedMessage(msg));
232 bool subprocess_terminated_normally = WIFEXITED(status);
233 ASSERT_TRUE(subprocess_terminated_normally) << details;
234 int subprocess_exit_status = WEXITSTATUS(status);
235 ASSERT_EQ(subprocess_exit_status, expected_exit_code) << details;
238 void UnitTests::DeathBySignal(int status,
239 const std::string& msg,
240 const void* aux) {
241 int expected_signo = static_cast<int>(reinterpret_cast<intptr_t>(aux));
242 std::string details(TestFailedMessage(msg));
244 bool subprocess_terminated_by_signal = WIFSIGNALED(status);
245 ASSERT_TRUE(subprocess_terminated_by_signal) << details;
246 int subprocess_signal_number = WTERMSIG(status);
247 ASSERT_EQ(subprocess_signal_number, expected_signo) << details;
250 void UnitTests::AssertionFailure(const char* expr, const char* file, int line) {
251 fprintf(stderr, "%s:%d:%s", file, line, expr);
252 fflush(stderr);
253 _exit(kExitWithAssertionFailure);
256 void UnitTests::IgnoreThisTest() {
257 fflush(stderr);
258 _exit(kIgnoreThisTest);
261 } // namespace