test_case.h revision 5821806d5e7f356e8fa4b058a389a808ea183019
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 PPAPI_TESTS_TEST_CASE_H_ 6#define PPAPI_TESTS_TEST_CASE_H_ 7 8#include <cmath> 9#include <limits> 10#include <set> 11#include <string> 12 13#include "ppapi/c/pp_resource.h" 14#include "ppapi/c/dev/ppb_testing_dev.h" 15#include "ppapi/cpp/dev/message_loop_dev.h" 16#include "ppapi/cpp/dev/scrollbar_dev.h" 17#include "ppapi/cpp/view.h" 18#include "ppapi/tests/test_utils.h" 19#include "ppapi/tests/testing_instance.h" 20 21#if (defined __native_client__) 22#include "ppapi/cpp/var.h" 23#else 24#include "ppapi/cpp/private/var_private.h" 25#endif 26 27class TestingInstance; 28 29namespace pp { 30namespace deprecated { 31class ScriptableObject; 32} 33} 34 35// Individual classes of tests derive from this generic test case. 36class TestCase { 37 public: 38 explicit TestCase(TestingInstance* instance); 39 virtual ~TestCase(); 40 41 // Optionally override to do testcase specific initialization. 42 // Default implementation just returns true. 43 virtual bool Init(); 44 45 // Override to implement the test case. It will be called after the plugin is 46 // first displayed, passing a string. If the string is empty, the 47 // should run all tests for this test case. Otherwise, it should run the test 48 // whose name matches test_filter exactly (if there is one). This should 49 // generally be implemented using the RUN_TEST* macros. 50 virtual void RunTests(const std::string& test_filter) = 0; 51 52 static std::string MakeFailureMessage(const char* file, int line, 53 const char* cmd); 54 55#if !(defined __native_client__) 56 // Returns the scriptable test object for the current test, if any. 57 // Internally, this uses CreateTestObject which each test overrides. 58 pp::VarPrivate GetTestObject(); 59#endif 60 61 // A function that is invoked whenever HandleMessage is called on the 62 // associated TestingInstance. Default implementation does nothing. TestCases 63 // that want to handle incoming postMessage events should override this 64 // method. 65 virtual void HandleMessage(const pp::Var& message_data); 66 67 // A function that is invoked whenever DidChangeView is called on the 68 // associated TestingInstance. Default implementation does nothing. TestCases 69 // that want to handle view changes should override this method. 70 virtual void DidChangeView(const pp::View& view); 71 72 // A function that is invoked whenever HandleInputEvent is called on the 73 // associated TestingInstance. Default implementation returns false. TestCases 74 // that want to handle view changes should override this method. 75 virtual bool HandleInputEvent(const pp::InputEvent& event); 76 77 void IgnoreLeakedVar(int64_t id); 78 79 TestingInstance* instance() { return instance_; } 80 81 const PPB_Testing_Dev* testing_interface() { return testing_interface_; } 82 83 static void QuitMainMessageLoop(PP_Instance instance); 84 85 protected: 86#if !(defined __native_client__) 87 // Overridden by each test to supply a ScriptableObject corresponding to the 88 // test. There can only be one object created for all tests in a given class, 89 // so be sure your object is designed to be re-used. 90 // 91 // This object should be created on the heap. Ownership will be passed to the 92 // caller. Return NULL if there is no supported test object (the default). 93 virtual pp::deprecated::ScriptableObject* CreateTestObject(); 94#endif 95 96 // Checks whether the testing interface is available. Returns true if it is, 97 // false otherwise. If it is not available, adds a descriptive error. This is 98 // for use by tests that require the testing interface. 99 bool CheckTestingInterface(); 100 101 // Makes sure the test is run over HTTP. 102 bool EnsureRunningOverHTTP(); 103 104 // Return true if the given test name matches the filter. This is true if 105 // (a) filter is empty or (b) test_name and filter match exactly. 106 bool MatchesFilter(const std::string& test_name, const std::string& filter); 107 108 // Check for leaked resources and vars at the end of the test. If any exist, 109 // return a string with some information about the error. Otherwise, return 110 // an empty string. 111 // 112 // You should pass the error string from the test so far; if it is non-empty, 113 // CheckResourcesAndVars will do nothing and return the same string. 114 std::string CheckResourcesAndVars(std::string errors); 115 116 // Run the given test method on a background thread and return the result. 117 template <class T> 118 std::string RunOnThread(std::string(T::*test_to_run)()) { 119#ifdef ENABLE_PEPPER_THREADING 120 if (!testing_interface_) { 121 return "Testing blocking callbacks requires the testing interface. In " 122 "Chrome, use the --enable-pepper-testing flag."; 123 } 124 // These tests are only valid if running out-of-process (threading is not 125 // supported in-process). For in-process, just consider it a pass. 126 if (!testing_interface_->IsOutOfProcess()) 127 return std::string(); 128 pp::MessageLoop_Dev background_loop(instance_); 129 ThreadedTestRunner<T> runner(instance_->pp_instance(), 130 static_cast<T*>(this), test_to_run, background_loop); 131 RunOnThreadInternal(&ThreadedTestRunner<T>::ThreadFunction, &runner, 132 testing_interface_); 133 return runner.result(); 134#else 135 // If threading's not enabled, just treat it as success. 136 return std::string(); 137#endif 138 } 139 140 // Pointer to the instance that owns us. 141 TestingInstance* instance_; 142 143 // NULL unless InitTestingInterface is called. 144 const PPB_Testing_Dev* testing_interface_; 145 146 // TODO(dmichael): Remove this, it's for temporary backwards compatibility so 147 // I don't have to change all the tests at once. 148 bool force_async_; 149 150 void set_callback_type(CallbackType callback_type) { 151 callback_type_ = callback_type; 152 // TODO(dmichael): Remove this; see comment on force_async_. 153 force_async_ = (callback_type_ == PP_REQUIRED); 154 } 155 CallbackType callback_type() const { 156 return callback_type_; 157 } 158 159 private: 160 template <class T> 161 class ThreadedTestRunner { 162 public: 163 typedef std::string(T::*TestMethodType)(); 164 ThreadedTestRunner(PP_Instance instance, 165 T* test_case, 166 TestMethodType test_to_run, 167 pp::MessageLoop_Dev loop) 168 : instance_(instance), 169 test_case_(test_case), 170 test_to_run_(test_to_run), 171 loop_(loop) { 172 } 173 const std::string& result() { return result_; } 174 static void ThreadFunction(void* runner) { 175 static_cast<ThreadedTestRunner<T>*>(runner)->Run(); 176 } 177 178 private: 179 void Run() { 180 PP_DCHECK(PP_OK == loop_.AttachToCurrentThread()); 181 result_ = (test_case_->*test_to_run_)(); 182 // Now give the loop a chance to clean up. 183 loop_.PostQuit(true /* should_destroy */); 184 loop_.Run(); 185 // Tell the main thread to quit its nested message loop, now that the test 186 // is complete. 187 TestCase::QuitMainMessageLoop(instance_); 188 } 189 190 std::string result_; 191 PP_Instance instance_; 192 T* test_case_; 193 TestMethodType test_to_run_; 194 pp::MessageLoop_Dev loop_; 195 }; 196 197 // The internals for RunOnThread. This allows us to avoid including 198 // pp_thread.h in this header file, since it includes system headers like 199 // windows.h. 200 // RunOnThreadInternal launches a new thread to run |thread_func|, waits 201 // for it to complete using RunMessageLoop(), then joins. 202 void RunOnThreadInternal(void (*thread_func)(void*), 203 void* thread_param, 204 const PPB_Testing_Dev* testing_interface); 205 206 static void DoQuitMainMessageLoop(void* pp_instance, int32_t result); 207 208 // Passed when creating completion callbacks in some tests. This determines 209 // what kind of callback we use for the test. 210 CallbackType callback_type_; 211 212 // Var ids that should be ignored when checking for leaks on shutdown. 213 std::set<int64_t> ignored_leaked_vars_; 214 215#if !(defined __native_client__) 216 // Holds the test object, if any was retrieved from CreateTestObject. 217 pp::VarPrivate test_object_; 218#endif 219}; 220 221// This class is an implementation detail. 222class TestCaseFactory { 223 public: 224 typedef TestCase* (*Method)(TestingInstance* instance); 225 226 TestCaseFactory(const char* name, Method method) 227 : next_(head_), 228 name_(name), 229 method_(method) { 230 head_ = this; 231 } 232 233 private: 234 friend class TestingInstance; 235 236 TestCaseFactory* next_; 237 const char* name_; 238 Method method_; 239 240 static TestCaseFactory* head_; 241}; 242 243// Use the REGISTER_TEST_CASE macro in your TestCase implementation file to 244// register your TestCase. If your test is named TestFoo, then add the 245// following to test_foo.cc: 246// 247// REGISTER_TEST_CASE(Foo); 248// 249// This will cause your test to be included in the set of known tests. 250// 251#define REGISTER_TEST_CASE(name) \ 252 static TestCase* Test##name##_FactoryMethod(TestingInstance* instance) { \ 253 return new Test##name(instance); \ 254 } \ 255 static TestCaseFactory g_Test##name_factory( \ 256 #name, &Test##name##_FactoryMethod \ 257 ) 258 259// Helper macro for calling functions implementing specific tests in the 260// RunTest function. This assumes the function name is TestFoo where Foo is the 261// test |name|. 262#define RUN_TEST(name, test_filter) \ 263 if (MatchesFilter(#name, test_filter)) { \ 264 set_callback_type(PP_OPTIONAL); \ 265 instance_->LogTest(#name, CheckResourcesAndVars(Test##name())); \ 266 } 267 268// Like RUN_TEST above but forces functions taking callbacks to complete 269// asynchronously on success or error. 270#define RUN_TEST_FORCEASYNC(name, test_filter) \ 271 if (MatchesFilter(#name, test_filter)) { \ 272 set_callback_type(PP_REQUIRED); \ 273 instance_->LogTest(#name"ForceAsync", \ 274 CheckResourcesAndVars(Test##name())); \ 275 } 276 277#define RUN_TEST_BLOCKING(test_case, name, test_filter) \ 278 if (MatchesFilter(#name, test_filter)) { \ 279 set_callback_type(PP_BLOCKING); \ 280 instance_->LogTest(#name"Blocking", \ 281 CheckResourcesAndVars(RunOnThread(&test_case::Test##name))); \ 282 } 283 284#define RUN_TEST_BACKGROUND(test_case, name, test_filter) \ 285 if (MatchesFilter(#name, test_filter)) { \ 286 instance_->LogTest(#name"Background", \ 287 CheckResourcesAndVars(RunOnThread(&test_case::Test##name))); \ 288 } 289 290#define RUN_TEST_FORCEASYNC_AND_NOT(name, test_filter) \ 291 do { \ 292 RUN_TEST_FORCEASYNC(name, test_filter); \ 293 RUN_TEST(name, test_filter); \ 294 } while (false) 295 296// Run a test with all possible callback types. 297#define RUN_CALLBACK_TEST(test_case, name, test_filter) \ 298 do { \ 299 RUN_TEST_FORCEASYNC(name, test_filter); \ 300 RUN_TEST(name, test_filter); \ 301 RUN_TEST_BLOCKING(test_case, name, test_filter); \ 302 RUN_TEST_BACKGROUND(test_case, name, test_filter); \ 303 } while (false) 304 305#define RUN_TEST_WITH_REFERENCE_CHECK(name, test_filter) \ 306 if (MatchesFilter(#name, test_filter)) { \ 307 set_callback_type(PP_OPTIONAL); \ 308 uint32_t objects = testing_interface_->GetLiveObjectsForInstance( \ 309 instance_->pp_instance()); \ 310 std::string error_message = Test##name(); \ 311 if (error_message.empty() && \ 312 testing_interface_->GetLiveObjectsForInstance( \ 313 instance_->pp_instance()) != objects) \ 314 error_message = MakeFailureMessage(__FILE__, __LINE__, \ 315 "reference leak check"); \ 316 instance_->LogTest(#name, error_message); \ 317 } 318 319// Helper macros for checking values in tests, and returning a location 320// description of the test fails. 321#define ASSERT_TRUE(cmd) \ 322 if (!(cmd)) { \ 323 return MakeFailureMessage(__FILE__, __LINE__, #cmd); \ 324 } 325#define ASSERT_FALSE(cmd) ASSERT_TRUE(!(cmd)) 326#define ASSERT_EQ(a, b) ASSERT_TRUE((a) == (b)) 327#define ASSERT_NE(a, b) ASSERT_TRUE((a) != (b)) 328 329#define ASSERT_DOUBLE_EQ(a, b) ASSERT_TRUE( \ 330 std::fabs((a)-(b)) <= std::numeric_limits<double>::epsilon()) 331 332// Runs |function| as a subtest and asserts that it has passed. 333#define ASSERT_SUBTEST_SUCCESS(function) \ 334 do { \ 335 std::string result = (function); \ 336 if (!result.empty()) \ 337 return result; \ 338 } while (false) 339 340#define PASS() return std::string() 341 342#endif // PPAPI_TESTS_TEST_CASE_H_ 343