Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(200)

Unified Diff: ppapi/tests/test_case.h

Issue 10081020: PPAPI: Make blocking completion callbacks work. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Updated TestURLLoader to test blocking callbacks. Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ppapi/tests/test_case.h
diff --git a/ppapi/tests/test_case.h b/ppapi/tests/test_case.h
index 297308489f58441da361e1dd3081ee4fb3c624c6..2cce0c1225280befa6d5c6bf18b1a41b7285b64c 100644
--- a/ppapi/tests/test_case.h
+++ b/ppapi/tests/test_case.h
@@ -12,9 +12,12 @@
#include "ppapi/c/pp_resource.h"
#include "ppapi/c/dev/ppb_testing_dev.h"
+#include "ppapi/cpp/dev/message_loop_dev.h"
#include "ppapi/cpp/dev/scrollbar_dev.h"
#include "ppapi/cpp/view.h"
+#include "ppapi/tests/pp_thread.h"
#include "ppapi/tests/test_utils.h"
+#include "ppapi/tests/testing_instance.h"
#if (defined __native_client__)
#include "ppapi/cpp/var.h"
@@ -78,6 +81,8 @@ class TestCase {
const PPB_Testing_Dev* testing_interface() { return testing_interface_; }
+ static void QuitMainMessageLoop(PP_Instance instance);
+
protected:
#if !(defined __native_client__)
// Overridden by each test to supply a ScriptableObject corresponding to the
@@ -104,12 +109,41 @@ class TestCase {
// Check for leaked resources and vars at the end of the test. If any exist,
// return a string with some information about the error. Otherwise, return
// an empty string.
- std::string CheckResourcesAndVars();
+ //
+ // You should pass the error string from the test so far; if it is non-empty,
+ // CheckResourcesAndVars will do nothing and return the same string.
+ std::string CheckResourcesAndVars(std::string errors);
+
+ // Run the given test method on a background thread and return the result.
+ template <class T>
+ std::string RunOnThread(std::string(T::*test_to_run)()) {
+#ifdef ENABLE_PEPPER_THREADING
+ if (!testing_interface_) {
+ return "Testing blocking callbacks requires the testing interface. In "
+ "Chrome, use the --enable-pepper-testing flag.";
+ }
+ // These tests are only valid if running out-of-process (threading is not
+ // supported in-process). Just consider it a pass.
+ if (!testing_interface_->IsOutOfProcess())
+ return std::string();
+ ThreadedTestRunner<T> runner(instance_->pp_instance(),
+ static_cast<T*>(this), test_to_run);
+ PP_ThreadType thread;
+ PP_CreateThread(&thread, &ThreadedTestRunner<T>::ThreadFunction, &runner);
+ // Run a message loop so pepper calls can be dispatched. The background
+ // thread will make us Quit when it's done.
+ testing_interface_->RunMessageLoop(instance_->pp_instance());
+ PP_JoinThread(thread);
+ return runner.result();
+#else
+ // If threading's not enabled, just treat it as success.
+ return std::string();
+#endif
+ }
// Pointer to the instance that owns us.
TestingInstance* instance_;
- protected:
// NULL unless InitTestingInterface is called.
const PPB_Testing_Dev* testing_interface_;
@@ -127,6 +161,40 @@ class TestCase {
}
private:
+ template <class T>
+ class ThreadedTestRunner {
+ public:
+ typedef std::string(T::*TestMethodType)();
+ explicit ThreadedTestRunner(PP_Instance instance,
+ T* test_case,
+ TestMethodType test_to_run)
+ : instance_(instance),
+ test_case_(test_case),
+ test_to_run_(test_to_run) {
+ }
+ std::string result() { return result_; }
+ static void ThreadFunction(void* runner) {
+ static_cast<ThreadedTestRunner<T>*>(runner)->Run();
+ }
+
+ private:
+ void Run() {
+ // TODO(dmichael): Create and attach a pp::MessageLoop for this thread so
+ // nested loops work.
+ result_ = (test_case_->*test_to_run_)();
+ // Tell the main thread to quit its nested message loop, now that the test
+ // is complete.
+ TestCase::QuitMainMessageLoop(instance_);
+ }
+
+ std::string result_;
+ PP_Instance instance_;
+ T* test_case_;
+ TestMethodType test_to_run_;
+ };
+
+ static void DoQuitMainMessageLoop(void* pp_instance, int32_t result);
+
// Passed when creating completion callbacks in some tests. This determines
// what kind of callback we use for the test.
CallbackType callback_type_;
@@ -184,12 +252,39 @@ class TestCaseFactory {
#define RUN_TEST(name, test_filter) \
if (MatchesFilter(#name, test_filter)) { \
set_callback_type(PP_OPTIONAL); \
- std::string error_message = Test##name(); \
- if (error_message.empty()) \
- error_message = CheckResourcesAndVars(); \
- instance_->LogTest(#name, error_message); \
+ instance_->LogTest(#name, CheckResourcesAndVars(Test##name())); \
+ }
+
+// Like RUN_TEST above but forces functions taking callbacks to complete
+// asynchronously on success or error.
+#define RUN_TEST_FORCEASYNC(name, test_filter) \
+ if (MatchesFilter(#name, test_filter)) { \
+ set_callback_type(PP_REQUIRED); \
+ instance_->LogTest(#name"ForceAsync", \
+ CheckResourcesAndVars(Test##name())); \
}
+#define RUN_TEST_BLOCKING(test_case, name, test_filter) \
+ if (MatchesFilter(#name, test_filter)) { \
+ set_callback_type(PP_BLOCKING); \
+ instance_->LogTest(#name"Blocking", \
+ CheckResourcesAndVars(RunOnThread(&test_case::Test##name))); \
+ }
+
+#define RUN_TEST_FORCEASYNC_AND_NOT(name, test_filter) \
+ do { \
+ RUN_TEST_FORCEASYNC(name, test_filter); \
+ RUN_TEST(name, test_filter); \
+ } while (false)
+
+// Run a test with all possible callback types.
+#define RUN_CALLBACK_TEST(test_case, name, test_filter) \
+ do { \
+ RUN_TEST_FORCEASYNC(name, test_filter); \
+ RUN_TEST(name, test_filter); \
+ RUN_TEST_BLOCKING(test_case, name, test_filter); \
+ } while (false)
+
#define RUN_TEST_WITH_REFERENCE_CHECK(name, test_filter) \
if (MatchesFilter(#name, test_filter)) { \
set_callback_type(PP_OPTIONAL); \
@@ -204,21 +299,6 @@ class TestCaseFactory {
instance_->LogTest(#name, error_message); \
}
-// Like RUN_TEST above but forces functions taking callbacks to complete
-// asynchronously on success or error.
-#define RUN_TEST_FORCEASYNC(name, test_filter) \
- if (MatchesFilter(#name"ForceAsync", test_filter)) { \
dmichael (off chromium) 2012/04/19 20:02:00 Note the first parameter used to say '#name"ForceA
- set_callback_type(PP_REQUIRED); \
- instance_->LogTest(#name"ForceAsync", Test##name()); \
- }
-
-#define RUN_TEST_FORCEASYNC_AND_NOT(name, test_filter) \
- do { \
- RUN_TEST_FORCEASYNC(name, test_filter); \
- RUN_TEST(name, test_filter); \
- } while (false)
-
-
// Helper macros for checking values in tests, and returning a location
// description of the test fails.
#define ASSERT_TRUE(cmd) \

Powered by Google App Engine
This is Rietveld 408576698