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