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