Home | History | Annotate | Download | only in common
      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 CONTENT_COMMON_SANDBOX_MAC_UNITTEST_HELPER_H_
      6 #define CONTENT_COMMON_SANDBOX_MAC_UNITTEST_HELPER_H_
      7 
      8 #include "base/test/multiprocess_test.h"
      9 #include "content/common/sandbox_mac.h"
     10 
     11 namespace content {
     12 
     13 // Helpers for writing unit tests that runs in the context of the Mac sandbox.
     14 //
     15 // How to write a sandboxed test:
     16 // 1. Create a class that inherits from MacSandboxTestCase and overrides
     17 // its functions to run code before or after the sandbox is initialised in a
     18 // subprocess.
     19 // 2. Register the class you just created with the REGISTER_SANDBOX_TEST_CASE()
     20 // macro.
     21 // 3. Write a test [using TEST_F()] that inherits from MacSandboxTest and call
     22 // one of its helper functions to launch the test.
     23 //
     24 // Example:
     25 //  class TestCaseThatRunsInSandboxedSubprocess : public MacSandboxTestCase {
     26 //   public:
     27 //    virtual bool SandboxedTest() {
     28 //      .. test code that runs in sandbox goes here ..
     29 //      return true; // always succeed.
     30 //    }
     31 //  };
     32 //
     33 //  // Register the test case you just created.
     34 //  REGISTER_SANDBOX_TEST_CASE(TestCaseThatRunsInSandboxedSubprocess);
     35 //
     36 //  TEST_F(MacSandboxTest, ATest) {
     37 //    EXPECT_TRUE(RunTestInAllSandboxTypes(
     38 //                    "TestCaseThatRunsInSandboxedSubprocess",
     39 //                    NULL));
     40 //  }
     41 
     42 // Base test type with helper functions to spawn a subprocess that exercises
     43 // a given test in the sandbox.
     44 class MacSandboxTest : public base::MultiProcessTest {
     45  public:
     46   // Runs a test specified by |test_name| in a sandbox of the type specified
     47   // by |sandbox_type|. |test_data| is a custom string that a test can pass
     48   // to the child process runing in the sandbox, or NULL if additional data is
     49   // required.
     50   // Returns true if the test passes, false if either of the functions in
     51   // the corresponding MacSandboxTestCase return false.
     52   bool RunTestInSandbox(content::SandboxType sandbox_type,
     53                         const char* test_name,
     54                         const char* test_data);
     55 
     56   // Runs the test specified by |test_name| in all the different sandbox types
     57   // known to content, one by one.
     58   // Returns true if the test passes, false if either of the functions in
     59   // the corresponding MacSandboxTestCase return false in any of the spawned
     60   // processes.
     61   //
     62   // DANGER DANGER DANGER:
     63   // Additional sandbox types defined by the embedder (e.g. the NaCl sandbox)
     64   // won't be covered by these tests.
     65   bool RunTestInAllSandboxTypes(const char* test_name,
     66                                 const char* test_data);
     67 };
     68 
     69 // Class to ease writing test cases that run inside the OS X sandbox.
     70 // This class is instantiated in a subprocess, and allows you to run test code
     71 // at various stages of execution.
     72 // Note that you must register the subclass you create with the
     73 // REGISTER_SANDBOX_TEST_CASE so it's visible to the test driver.
     74 class MacSandboxTestCase {
     75  public:
     76   virtual ~MacSandboxTestCase() {}
     77 
     78   // Code that runs in the sandboxed subprocess before the sandbox is
     79   // initialized.
     80   // Returning false from this function will cause the entire test case to fail.
     81   virtual bool BeforeSandboxInit();
     82 
     83   // Code that runs in the sandboxed subprocess when the sandbox has been
     84   // enabled.
     85   // Returning false from this function will cause the entire test case to fail.
     86   virtual bool SandboxedTest() = 0;
     87 
     88   // The data that's passed in the |user_data| parameter of
     89   // RunTest[s]InSandbox() is passed to this function.
     90   virtual void SetTestData(const char* test_data);
     91 
     92  protected:
     93   std::string test_data_;
     94 };
     95 
     96 // Plumbing to support the REGISTER_SANDBOX_TEST_CASE macro.
     97 namespace internal {
     98 
     99 // Register a test case with a given name.
    100 void AddSandboxTestCase(const char* test_name, MacSandboxTestCase* test_class);
    101 
    102 // Construction of this class causes a new entry to be placed in a global
    103 // map.
    104 template <class T> struct RegisterSandboxTest {
    105   RegisterSandboxTest(const char* test_name) {
    106     AddSandboxTestCase(test_name, new T);
    107   }
    108 };
    109 
    110 #define REGISTER_SANDBOX_TEST_CASE(class_name) \
    111   namespace { \
    112     content::internal::RegisterSandboxTest<class_name> \
    113       register_test##class_name(#class_name); \
    114   }  // namespace
    115 
    116 }  // namespace internal
    117 
    118 }  // namespace content
    119 
    120 #endif  // CONTENT_COMMON_SANDBOX_MAC_UNITTEST_HELPER_H_
    121