Chromium Code Reviews| Index: ppapi/tests/test_utils.h |
| diff --git a/ppapi/tests/test_utils.h b/ppapi/tests/test_utils.h |
| index 8cff24e15f172e2f2f84759fc9223341ed675005..c296e2c06af6c89b8a988ae2a7d4f795a27ed01a 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,147 @@ 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); |
| +// Used for waiting for a nested event, such as a callback on a PPP interface. |
|
bbudge
2012/04/04 19:03:00
This comment makes me wonder about the name of the
dmichael (off chromium)
2012/04/04 19:50:47
Agreed... I don't love the name but can't think o
|
| +// "Wait()" will return immediately if it has already been signalled. Otherwise, |
| +// it will run a nested message loop (using PPB_Testing.RunMessageLoop) until |
| +// 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 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 +183,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. */ |