1// Copyright 2014 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#include "sandbox/linux/services/thread_helpers.h" 6 7#include <errno.h> 8#include <fcntl.h> 9#include <sys/stat.h> 10#include <sys/types.h> 11#include <unistd.h> 12 13#include "base/logging.h" 14#include "base/macros.h" 15#include "base/posix/eintr_wrapper.h" 16#include "base/process/process_metrics.h" 17#include "base/threading/platform_thread.h" 18#include "base/threading/thread.h" 19#include "build/build_config.h" 20#include "sandbox/linux/tests/unit_tests.h" 21#include "testing/gtest/include/gtest/gtest.h" 22 23using base::PlatformThread; 24 25namespace sandbox { 26 27namespace { 28 29// These tests fail under ThreadSanitizer, see http://crbug.com/342305 30#if !defined(THREAD_SANITIZER) 31 32int GetRaceTestIterations() { 33 if (IsRunningOnValgrind()) { 34 return 2; 35 } else { 36 return 1000; 37 } 38} 39 40class ScopedProc { 41 public: 42 ScopedProc() : fd_(-1) { 43 fd_ = open("/proc/", O_RDONLY | O_DIRECTORY); 44 CHECK_LE(0, fd_); 45 } 46 47 ~ScopedProc() { PCHECK(0 == IGNORE_EINTR(close(fd_))); } 48 49 int fd() { return fd_; } 50 51 private: 52 int fd_; 53 DISALLOW_COPY_AND_ASSIGN(ScopedProc); 54}; 55 56TEST(ThreadHelpers, IsSingleThreadedBasic) { 57 ScopedProc proc_fd; 58 ASSERT_TRUE(ThreadHelpers::IsSingleThreaded(proc_fd.fd())); 59 ASSERT_TRUE(ThreadHelpers::IsSingleThreaded()); 60 61 base::Thread thread("sandbox_tests"); 62 ASSERT_TRUE(ThreadHelpers::StartThreadAndWatchProcFS(proc_fd.fd(), &thread)); 63 ASSERT_FALSE(ThreadHelpers::IsSingleThreaded(proc_fd.fd())); 64 ASSERT_FALSE(ThreadHelpers::IsSingleThreaded()); 65 // Explicitly stop the thread here to not pollute the next test. 66 ASSERT_TRUE(ThreadHelpers::StopThreadAndWatchProcFS(proc_fd.fd(), &thread)); 67} 68 69SANDBOX_TEST(ThreadHelpers, AssertSingleThreaded) { 70 ScopedProc proc_fd; 71 SANDBOX_ASSERT(ThreadHelpers::IsSingleThreaded(proc_fd.fd())); 72 SANDBOX_ASSERT(ThreadHelpers::IsSingleThreaded()); 73 74 ThreadHelpers::AssertSingleThreaded(proc_fd.fd()); 75 ThreadHelpers::AssertSingleThreaded(); 76} 77 78TEST(ThreadHelpers, IsSingleThreadedIterated) { 79 ScopedProc proc_fd; 80 ASSERT_TRUE(ThreadHelpers::IsSingleThreaded(proc_fd.fd())); 81 82 // Iterate to check for race conditions. 83 for (int i = 0; i < GetRaceTestIterations(); ++i) { 84 base::Thread thread("sandbox_tests"); 85 ASSERT_TRUE( 86 ThreadHelpers::StartThreadAndWatchProcFS(proc_fd.fd(), &thread)); 87 ASSERT_FALSE(ThreadHelpers::IsSingleThreaded(proc_fd.fd())); 88 // Explicitly stop the thread here to not pollute the next test. 89 ASSERT_TRUE(ThreadHelpers::StopThreadAndWatchProcFS(proc_fd.fd(), &thread)); 90 } 91} 92 93TEST(ThreadHelpers, IsSingleThreadedStartAndStop) { 94 ScopedProc proc_fd; 95 ASSERT_TRUE(ThreadHelpers::IsSingleThreaded(proc_fd.fd())); 96 97 base::Thread thread("sandbox_tests"); 98 // This is testing for a race condition, so iterate. 99 // Manually, this has been tested with more that 1M iterations. 100 for (int i = 0; i < GetRaceTestIterations(); ++i) { 101 ASSERT_TRUE( 102 ThreadHelpers::StartThreadAndWatchProcFS(proc_fd.fd(), &thread)); 103 ASSERT_FALSE(ThreadHelpers::IsSingleThreaded(proc_fd.fd())); 104 105 ASSERT_TRUE(ThreadHelpers::StopThreadAndWatchProcFS(proc_fd.fd(), &thread)); 106 ASSERT_TRUE(ThreadHelpers::IsSingleThreaded(proc_fd.fd())); 107 ASSERT_EQ(1, base::GetNumberOfThreads(base::GetCurrentProcessHandle())); 108 } 109} 110 111SANDBOX_TEST(ThreadHelpers, AssertSingleThreadedAfterThreadStopped) { 112 ScopedProc proc_fd; 113 SANDBOX_ASSERT(ThreadHelpers::IsSingleThreaded()); 114 115 base::Thread thread1("sandbox_tests"); 116 base::Thread thread2("sandbox_tests"); 117 118 for (int i = 0; i < GetRaceTestIterations(); ++i) { 119 SANDBOX_ASSERT( 120 ThreadHelpers::StartThreadAndWatchProcFS(proc_fd.fd(), &thread1)); 121 SANDBOX_ASSERT( 122 ThreadHelpers::StartThreadAndWatchProcFS(proc_fd.fd(), &thread2)); 123 SANDBOX_ASSERT(!ThreadHelpers::IsSingleThreaded()); 124 125 thread1.Stop(); 126 thread2.Stop(); 127 // This will wait on /proc/ to reflect the state of threads in the 128 // process. 129 ThreadHelpers::AssertSingleThreaded(); 130 SANDBOX_ASSERT(ThreadHelpers::IsSingleThreaded()); 131 } 132} 133 134// Only run this test in Debug mode, where AssertSingleThreaded() will return 135// in less than 64ms. 136#if !defined(NDEBUG) 137SANDBOX_DEATH_TEST( 138 ThreadHelpers, 139 AssertSingleThreadedDies, 140 DEATH_MESSAGE( 141 ThreadHelpers::GetAssertSingleThreadedErrorMessageForTests())) { 142 base::Thread thread1("sandbox_tests"); 143 SANDBOX_ASSERT(thread1.Start()); 144 ThreadHelpers::AssertSingleThreaded(); 145} 146#endif // !defined(NDEBUG) 147 148#endif // !defined(THREAD_SANITIZER) 149 150} // namespace 151 152} // namespace sandbox 153