Home | History | Annotate | Download | only in tests
      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/pp_resource.h"
     15 #include "ppapi/c/pp_time.h"
     16 #include "ppapi/c/private/ppb_testing_private.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_Private* 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_Private* 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_Private* 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