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
29class TestingInstance;
30
31namespace pp {
32namespace deprecated {
33class ScriptableObject;
34}
35}
36
37// Individual classes of tests derive from this generic test case.
38class 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.
255class 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