Home | History | Annotate | Download | only in services
      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/basictypes.h"
     14 #include "base/logging.h"
     15 #include "base/memory/scoped_ptr.h"
     16 #include "base/posix/eintr_wrapper.h"
     17 #include "base/process/process_metrics.h"
     18 #include "base/threading/platform_thread.h"
     19 #include "base/threading/thread.h"
     20 #include "build/build_config.h"
     21 #include "sandbox/linux/tests/unit_tests.h"
     22 #include "testing/gtest/include/gtest/gtest.h"
     23 
     24 using base::PlatformThread;
     25 
     26 namespace sandbox {
     27 
     28 namespace {
     29 
     30 int GetRaceTestIterations() {
     31   if (IsRunningOnValgrind()) {
     32     return 2;
     33   } else {
     34     return 1000;
     35   }
     36 }
     37 
     38 class ScopedProcSelfTask {
     39  public:
     40   ScopedProcSelfTask() : fd_(-1) {
     41     fd_ = open("/proc/self/task/", O_RDONLY | O_DIRECTORY);
     42     CHECK_LE(0, fd_);
     43   }
     44 
     45   ~ScopedProcSelfTask() { PCHECK(0 == IGNORE_EINTR(close(fd_))); }
     46 
     47   int fd() { return fd_; }
     48 
     49  private:
     50   int fd_;
     51   DISALLOW_COPY_AND_ASSIGN(ScopedProcSelfTask);
     52 };
     53 
     54 #if defined(THREAD_SANITIZER)
     55 // These tests fail under ThreadSanitizer, see http://crbug.com/342305
     56 #define MAYBE_IsSingleThreadedBasic DISABLED_IsSingleThreadedBasic
     57 #define MAYBE_IsSingleThreadedIterated DISABLED_IsSingleThreadedIterated
     58 #define MAYBE_IsSingleThreadedStartAndStop DISABLED_IsSingleThreadedStartAndStop
     59 #else
     60 #define MAYBE_IsSingleThreadedBasic IsSingleThreadedBasic
     61 #define MAYBE_IsSingleThreadedIterated IsSingleThreadedIterated
     62 #define MAYBE_IsSingleThreadedStartAndStop IsSingleThreadedStartAndStop
     63 #endif
     64 
     65 TEST(ThreadHelpers, MAYBE_IsSingleThreadedBasic) {
     66   ScopedProcSelfTask task;
     67   ASSERT_TRUE(ThreadHelpers::IsSingleThreaded(task.fd()));
     68   ASSERT_TRUE(ThreadHelpers::IsSingleThreaded(-1));
     69 
     70   base::Thread thread("sandbox_tests");
     71   ASSERT_TRUE(thread.Start());
     72   ASSERT_FALSE(ThreadHelpers::IsSingleThreaded(task.fd()));
     73   ASSERT_FALSE(ThreadHelpers::IsSingleThreaded(-1));
     74   // Explicitly stop the thread here to not pollute the next test.
     75   ASSERT_TRUE(ThreadHelpers::StopThreadAndWatchProcFS(task.fd(), &thread));
     76 }
     77 
     78 TEST(ThreadHelpers, MAYBE_IsSingleThreadedIterated) {
     79   ScopedProcSelfTask task;
     80   ASSERT_TRUE(ThreadHelpers::IsSingleThreaded(task.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(thread.Start());
     86     ASSERT_FALSE(ThreadHelpers::IsSingleThreaded(task.fd()));
     87     // Explicitly stop the thread here to not pollute the next test.
     88     ASSERT_TRUE(ThreadHelpers::StopThreadAndWatchProcFS(task.fd(), &thread));
     89   }
     90 }
     91 
     92 TEST(ThreadHelpers, MAYBE_IsSingleThreadedStartAndStop) {
     93   ScopedProcSelfTask task;
     94   ASSERT_TRUE(ThreadHelpers::IsSingleThreaded(task.fd()));
     95 
     96   base::Thread thread("sandbox_tests");
     97   // This is testing for a race condition, so iterate.
     98   // Manually, this has been tested with more that 1M iterations.
     99   for (int i = 0; i < GetRaceTestIterations(); ++i) {
    100     ASSERT_TRUE(thread.Start());
    101     ASSERT_FALSE(ThreadHelpers::IsSingleThreaded(task.fd()));
    102 
    103     ASSERT_TRUE(ThreadHelpers::StopThreadAndWatchProcFS(task.fd(), &thread));
    104     ASSERT_TRUE(ThreadHelpers::IsSingleThreaded(task.fd()));
    105     ASSERT_EQ(1, base::GetNumberOfThreads(base::GetCurrentProcessHandle()));
    106   }
    107 }
    108 
    109 }  // namespace
    110 
    111 }  // namespace sandbox
    112