Fix build break
[chromium-blink-merge.git] / ppapi / tests / test_utils.h
blob43d531d06acf417b954c7482a6ed3d1bbb5cf7af
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.
5 #ifndef PPAPI_TESTS_TEST_UTILS_H_
6 #define PPAPI_TESTS_TEST_UTILS_H_
8 #include <string>
10 #include "ppapi/c/dev/ppb_testing_dev.h"
11 #include "ppapi/c/pp_instance.h"
12 #include "ppapi/c/pp_stdint.h"
13 #include "ppapi/cpp/completion_callback.h"
14 #include "ppapi/cpp/message_loop.h"
15 #include "ppapi/utility/completion_callback_factory.h"
17 // Timeout to wait for some action to complete.
18 extern const int kActionTimeoutMs;
20 const PPB_Testing_Dev* GetTestingInterface();
21 std::string ReportError(const char* method, int32_t error);
22 void PlatformSleep(int duration_ms);
23 bool GetLocalHostPort(PP_Instance instance, std::string* host, uint16_t* port);
25 // NestedEvent allows you to run a nested MessageLoop and wait for a particular
26 // event to complete. For example, you can use it to wait for a callback on a
27 // PPP interface, which will "Signal" the event and make the loop quit.
28 // "Wait()" will return immediately if it has already been signalled. Otherwise,
29 // it will run a nested message loop (using PPB_Testing.RunMessageLoop) and will
30 // return only after it has been signalled.
31 // Example:
32 // std::string TestFullscreen::TestNormalToFullscreen() {
33 // pp::Fullscreen screen_mode(instance);
34 // screen_mode.SetFullscreen(true);
35 // SimulateUserGesture();
36 // // Let DidChangeView run in a nested message loop.
37 // nested_event_.Wait();
38 // Pass();
39 // }
41 // void TestFullscreen::DidChangeView(const pp::View& view) {
42 // nested_event_.Signal();
43 // }
45 // All methods except Signal and PostSignal must be invoked on the main thread.
46 // It's OK to signal from a background thread, so you can (for example) Signal()
47 // from the Audio thread.
48 class NestedEvent {
49 public:
50 explicit NestedEvent(PP_Instance instance)
51 : instance_(instance), waiting_(false), signalled_(false) {
53 // Run a nested message loop and wait until Signal() is called. If Signal()
54 // has already been called, return immediately without running a nested loop.
55 void Wait();
56 // Signal the NestedEvent. If Wait() has been called, quit the message loop.
57 // This can be called from any thread.
58 void Signal();
59 // Signal the NestedEvent in |wait_ms| milliseconds. This can be called from
60 // any thread.
61 void PostSignal(int32_t wait_ms);
63 // Reset the NestedEvent so it can be used again.
64 void Reset();
65 private:
66 void SignalOnMainThread();
67 static void SignalThunk(void* async_event, int32_t result);
69 PP_Instance instance_;
70 bool waiting_;
71 bool signalled_;
72 // Disable copy and assign.
73 NestedEvent(const NestedEvent&);
74 NestedEvent& operator=(const NestedEvent&);
77 enum CallbackType { PP_REQUIRED, PP_OPTIONAL, PP_BLOCKING };
78 class TestCompletionCallback {
79 public:
80 class Delegate {
81 public:
82 virtual ~Delegate() {}
83 virtual void OnCallback(void* user_data, int32_t result) = 0;
85 explicit TestCompletionCallback(PP_Instance instance);
86 // TODO(dmichael): Remove this constructor.
87 TestCompletionCallback(PP_Instance instance, bool force_async);
89 TestCompletionCallback(PP_Instance instance, CallbackType callback_type);
91 // Sets a Delegate instance. OnCallback() of this instance will be invoked
92 // when the completion callback is invoked.
93 // The delegate will be reset when Reset() or GetCallback() is called.
94 void SetDelegate(Delegate* delegate) { delegate_ = delegate; }
96 // Wait for a result, given the return from the call which took this callback
97 // as a parameter. If |result| is PP_OK_COMPLETIONPENDING, WaitForResult will
98 // block until its callback has been invoked (in some cases, this will already
99 // have happened, and WaitForCallback can return immediately).
100 // For any other values, WaitForResult will simply set its internal "result_"
101 // field. To retrieve the final result of the operation (i.e., the result
102 // the callback has run, if necessary), call result(). You can call result()
103 // as many times as necessary until a new pp::CompletionCallback is retrieved.
105 // In some cases, you may want to check that the callback was invoked in the
106 // expected way (i.e., if the callback was "Required", then it should be
107 // invoked asynchronously). Within the body of a test (where returning a non-
108 // empty string indicates test failure), you can use the
109 // CHECK_CALLBACK_BEHAVIOR(callback) macro. From within a helper function,
110 // you can use failed() and errors().
112 // Example usage within a test:
113 // callback.WaitForResult(foo.DoSomething(callback));
114 // CHECK_CALLBACK_BEHAVIOR(callback);
115 // ASSERT_EQ(PP_OK, callback.result());
117 // Example usage within a helper function:
118 // void HelperFunction(std::string* error_message) {
119 // callback.WaitForResult(foo.DoSomething(callback));
120 // if (callback.failed())
121 // error_message->assign(callback.errors());
122 // }
123 void WaitForResult(int32_t result);
125 // Used when you expect to receive either synchronous completion with PP_OK
126 // or a PP_ERROR_ABORTED asynchronously.
127 // Example usage:
128 // int32_t result = 0;
129 // {
130 // pp::URLLoader temp(instance_);
131 // result = temp.Open(request, callback);
132 // }
133 // callback.WaitForAbortResult(result);
134 // CHECK_CALLBACK_BEHAVIOR(callback);
135 void WaitForAbortResult(int32_t result);
137 // Retrieve a pp::CompletionCallback for use in testing. This Reset()s the
138 // TestCompletionCallback.
139 pp::CompletionCallback GetCallback();
141 bool failed() { return !errors_.empty(); }
142 const std::string& errors() { return errors_; }
144 int32_t result() const { return result_; }
146 // Reset so that this callback can be used again.
147 void Reset();
149 CallbackType callback_type() { return callback_type_; }
150 void set_target_loop(const pp::MessageLoop& loop) { target_loop_ = loop; }
151 static void Handler(void* user_data, int32_t result);
153 protected:
154 void RunMessageLoop();
155 void QuitMessageLoop();
157 // Used to check that WaitForResult is only called once for each usage of the
158 // callback.
159 bool wait_for_result_called_;
160 // Indicates whether we have already been invoked.
161 bool have_result_;
162 // The last result received (or PP_OK_COMPLETIONCALLBACK if none).
163 int32_t result_;
164 CallbackType callback_type_;
165 bool post_quit_task_;
166 std::string errors_;
167 PP_Instance instance_;
168 Delegate* delegate_;
169 pp::MessageLoop target_loop_;
172 template <typename OutputT>
173 class TestCompletionCallbackWithOutput {
174 public:
175 explicit TestCompletionCallbackWithOutput(PP_Instance instance) :
176 callback_(instance) {
179 TestCompletionCallbackWithOutput(PP_Instance instance, bool force_async) :
180 callback_(instance, force_async) {
183 TestCompletionCallbackWithOutput(PP_Instance instance,
184 CallbackType callback_type) :
185 callback_(instance, callback_type) {
188 pp::CompletionCallbackWithOutput<OutputT> GetCallback();
189 OutputT output() {
190 return pp::internal::CallbackOutputTraits<OutputT>::StorageToPluginArg(
191 output_storage_);
194 // Delegate functions to TestCompletionCallback
195 void SetDelegate(TestCompletionCallback::Delegate* delegate) {
196 callback_.SetDelegate(delegate);
198 void WaitForResult(int32_t result) { callback_.WaitForResult(result); }
199 void WaitForAbortResult(int32_t result) {
200 callback_.WaitForAbortResult(result);
202 bool failed() { return callback_.failed(); }
203 const std::string& errors() { return callback_.errors(); }
204 int32_t result() const { return callback_.result(); }
205 void Reset() { return callback_.Reset(); }
207 private:
208 TestCompletionCallback callback_;
209 typename pp::CompletionCallbackWithOutput<OutputT>::OutputStorageType
210 output_storage_;
213 template <typename OutputT>
214 pp::CompletionCallbackWithOutput<OutputT>
215 TestCompletionCallbackWithOutput<OutputT>::GetCallback() {
216 callback_.Reset();
217 if (callback_.callback_type() == PP_BLOCKING) {
218 pp::CompletionCallbackWithOutput<OutputT> cc(&output_storage_);
219 return cc;
222 callback_.set_target_loop(pp::MessageLoop::GetCurrent());
223 pp::CompletionCallbackWithOutput<OutputT> cc(
224 &TestCompletionCallback::Handler,
225 this,
226 &output_storage_);
227 if (callback_.callback_type() == PP_OPTIONAL)
228 cc.set_flags(PP_COMPLETIONCALLBACK_FLAG_OPTIONAL);
229 return cc;
233 // Verifies that the callback didn't record any errors. If the callback is run
234 // in an unexpected way (e.g., if it's invoked asynchronously when the call
235 // should have blocked), this returns an appropriate error string.
236 #define CHECK_CALLBACK_BEHAVIOR(callback) \
237 do { \
238 if ((callback).failed()) \
239 return MakeFailureMessage(__FILE__, __LINE__, \
240 (callback).errors().c_str()); \
241 } while (false)
244 * A set of macros to use for platform detection. These were largely copied
245 * from chromium's build_config.h.
247 #if defined(__APPLE__)
248 #define PPAPI_OS_MACOSX 1
249 #elif defined(ANDROID)
250 #define PPAPI_OS_ANDROID 1
251 #elif defined(__native_client__)
252 #define PPAPI_OS_NACL 1
253 #elif defined(__linux__)
254 #define PPAPI_OS_LINUX 1
255 #elif defined(_WIN32)
256 #define PPAPI_OS_WIN 1
257 #elif defined(__FreeBSD__)
258 #define PPAPI_OS_FREEBSD 1
259 #elif defined(__OpenBSD__)
260 #define PPAPI_OS_OPENBSD 1
261 #elif defined(__sun)
262 #define PPAPI_OS_SOLARIS 1
263 #else
264 #error Please add support for your platform in ppapi/tests/test_utils.h
265 #endif
267 /* These are used to determine POSIX-like implementations vs Windows. */
268 #if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \
269 defined(__OpenBSD__) || defined(__sun) || defined(__native_client__)
270 #define PPAPI_POSIX 1
271 #endif
273 #endif // PPAPI_TESTS_TEST_UTILS_H_