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

Unified Diff: ppapi/tests/test_utils.h

Issue 9937001: PPAPI: Refactor ppapi test callbacks to ease testing blocking callbacks. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: sync Created 8 years, 9 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
« no previous file with comments | « ppapi/tests/test_url_request.cc ('k') | ppapi/tests/test_utils.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ppapi/tests/test_utils.h
diff --git a/ppapi/tests/test_utils.h b/ppapi/tests/test_utils.h
index 8cff24e15f172e2f2f84759fc9223341ed675005..1e2ec369316475accbd41d986e2a22f40d0d1bb0 100644
--- a/ppapi/tests/test_utils.h
+++ b/ppapi/tests/test_utils.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -11,6 +11,7 @@
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_stdint.h"
#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/utility/completion_callback_factory.h"
// Timeout to wait for some action to complete.
extern const int kActionTimeoutMs;
@@ -20,36 +21,149 @@ std::string ReportError(const char* method, int32_t error);
void PlatformSleep(int duration_ms);
bool GetLocalHostPort(PP_Instance instance, std::string* host, uint16_t* port);
+// NestedEvent allows you to run a nested MessageLoop and wait for a particular
+// event to complete. For example, you can use it to wait for a callback on a
+// PPP interface, which will "Signal" the event and make the loop quit.
+// "Wait()" will return immediately if it has already been signalled. Otherwise,
+// it will run a nested message loop (using PPB_Testing.RunMessageLoop) and will
+// return only after it has been signalled.
+// Example:
+// std::string TestFullscreen::TestNormalToFullscreen() {
+// pp::Fullscreen screen_mode(instance);
+// screen_mode.SetFullscreen(true);
+// SimulateUserGesture();
+// // Let DidChangeView run in a nested message loop.
+// nested_event_.Wait();
+// Pass();
+// }
+//
+// void TestFullscreen::DidChangeView(const pp::View& view) {
+// nested_event_.Signal();
+// }
+class NestedEvent {
+ public:
+ explicit NestedEvent(PP_Instance instance)
+ : instance_(instance), waiting_(false), signalled_(false) {
+ }
+ // Run a nested message loop and wait until Signal() is called. If Signal()
+ // has already been called, return immediately without running a nested loop.
+ void Wait();
+ // Signal the NestedEvent. If Wait() has been called, quit the message loop.
+ void Signal();
+ private:
+ PP_Instance instance_;
+ bool waiting_;
+ bool signalled_;
+ // Disable copy and assign.
+ NestedEvent(const NestedEvent&);
+ NestedEvent& operator=(const NestedEvent&);
+};
+
+enum CallbackType { PP_REQUIRED, PP_OPTIONAL, PP_BLOCKING };
class TestCompletionCallback {
public:
- TestCompletionCallback(PP_Instance instance);
+ explicit TestCompletionCallback(PP_Instance instance);
+ // TODO(dmichael): Remove this constructor.
TestCompletionCallback(PP_Instance instance, bool force_async);
+ TestCompletionCallback(PP_Instance instance, CallbackType callback_type);
+
// Waits for the callback to be called and returns the
// result. Returns immediately if the callback was previously called
// and the result wasn't returned (i.e. each result value received
// by the callback is returned by WaitForResult() once and only
- // once).
+ // once). DEPRECATED: Please use the one below.
+ // TODO(dmichael): Remove this one when all the tests are updated.
int32_t WaitForResult();
- operator pp::CompletionCallback() const;
+ // Wait for a result, given the return from the call which took this callback
+ // as a parameter. If |result| is PP_OK_COMPLETIONPENDING, WaitForResult will
+ // block until its callback has been invoked (in some cases, this will already
+ // have happened, and WaitForCallback can return immediately).
+ // For any other values, WaitForResult will simply set its internal "result_"
+ // field. To retrieve the final result of the operation (i.e., the result
+ // the callback has run, if necessary), call result(). You can call result()
+ // as many times as necessary until a new pp::CompletionCallback is retrieved.
+ //
+ // In some cases, you may want to check that the callback was invoked in the
+ // expected way (i.e., if the callback was "Required", then it should be
+ // invoked asynchronously). Within the body of a test (where returning a non-
+ // empty string indicates test failure), you can use the
+ // CHECK_CALLBACK_BEHAVIOR(callback) macro. From within a helper function,
+ // you can use failed() and errors().
+ //
+ // Example usage within a test:
+ // callback.WaitForResult(foo.DoSomething(callback));
+ // CHECK_CALLBACK_BEHAVIOR(callback);
+ // ASSERT_EQ(PP_OK, callback.result());
+ //
+ // Example usage within a helper function:
+ // void HelperFunction(std::string* error_message) {
+ // callback.WaitForResult(foo.DoSomething(callback));
+ // if (callback.failed())
+ // error_message->assign(callback.errors());
+ // }
+ void WaitForResult(int32_t result);
+ // Used when you expect to receive either synchronous completion with PP_OK
+ // or a PP_ERROR_ABORTED asynchronously.
+ // Example usage:
+ // int32_t result = 0;
+ // {
+ // pp::URLLoader temp(instance_);
+ // result = temp.Open(request, callback);
+ // }
+ // callback.WaitForAbortResult(result);
+ // CHECK_CALLBACK_BEHAVIOR(callback);
+ void WaitForAbortResult(int32_t result);
+
+ // Retrieve a pp::CompletionCallback for use in testing. This Reset()s the
+ // TestCompletionCallback.
+ pp::CompletionCallback GetCallback();
+ operator pp::CompletionCallback() {
+ return GetCallback();
+ }
+
+ // TODO(dmichael): Remove run_count when all tests are updated. Most cases
+ // that use this can simply use CHECK_CALLBACK_BEHAVIOR.
unsigned run_count() const { return run_count_; }
+ // TODO(dmichael): Remove this; tests should use Reset() instead.
void reset_run_count() { run_count_ = 0; }
+ bool failed() { return !errors_.empty(); }
+ const std::string& errors() { return errors_; }
+
int32_t result() const { return result_; }
+ // Reset so that this callback can be used again.
+ void Reset();
+
private:
static void Handler(void* user_data, int32_t result);
+ // Used to check that WaitForResult is only called once for each usage of the
+ // callback.
+ bool wait_for_result_called_;
+ // Indicates whether we have already been invoked.
bool have_result_;
+ // The last result received (or PP_OK_COMPLETIONCALLBACK if none).
int32_t result_;
- bool force_async_;
+ CallbackType callback_type_;
bool post_quit_task_;
+ std::string errors_;
unsigned run_count_;
PP_Instance instance_;
};
+// Verifies that the callback didn't record any errors. If the callback is run
+// in an unexpected way (e.g., if it's invoked asynchronously when the call
+// should have blocked), this returns an appropriate error string.
+#define CHECK_CALLBACK_BEHAVIOR(callback) \
+do { \
+ if ((callback).failed()) \
+ return (callback).errors(); \
+} while (false)
+
/*
* A set of macros to use for platform detection. These were largely copied
* from chromium's build_config.h.
@@ -71,7 +185,7 @@ class TestCompletionCallback {
#elif defined(__sun)
#define PPAPI_OS_SOLARIS 1
#else
-#error Please add support for your platform in ppapi/c/pp_macros.h.
+#error Please add support for your platform in ppapi/tests/test_utils.h
#endif
/* These are used to determine POSIX-like implementations vs Windows. */
« no previous file with comments | « ppapi/tests/test_url_request.cc ('k') | ppapi/tests/test_utils.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698