blob: 09e0b94eaf47d1dcd7b56162d5f3a1a7f77fa8ad [file] [log] [blame]
[email protected]3ab61272012-04-07 00:09:081// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]de9bdd12010-11-04 00:36:222// 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_UTILS_H_
6#define PPAPI_TESTS_TEST_UTILS_H_
7
8#include <string>
9
10#include "ppapi/c/dev/ppb_testing_dev.h"
[email protected]7358d572011-02-15 18:44:4011#include "ppapi/c/pp_instance.h"
[email protected]de9bdd12010-11-04 00:36:2212#include "ppapi/c/pp_stdint.h"
13#include "ppapi/cpp/completion_callback.h"
[email protected]d4ab94712012-11-15 21:01:2314#include "ppapi/cpp/message_loop.h"
[email protected]3ab61272012-04-07 00:09:0815#include "ppapi/utility/completion_callback_factory.h"
[email protected]de9bdd12010-11-04 00:36:2216
[email protected]3c149c62011-11-11 23:22:5217// Timeout to wait for some action to complete.
18extern const int kActionTimeoutMs;
19
[email protected]de9bdd12010-11-04 00:36:2220const PPB_Testing_Dev* GetTestingInterface();
21std::string ReportError(const char* method, int32_t error);
[email protected]3c149c62011-11-11 23:22:5222void PlatformSleep(int duration_ms);
[email protected]961e8972011-12-15 15:29:1923bool GetLocalHostPort(PP_Instance instance, std::string* host, uint16_t* port);
[email protected]de9bdd12010-11-04 00:36:2224
[email protected]3ab61272012-04-07 00:09:0825// 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// }
40//
41// void TestFullscreen::DidChangeView(const pp::View& view) {
42// nested_event_.Signal();
43// }
44class NestedEvent {
45 public:
46 explicit NestedEvent(PP_Instance instance)
47 : instance_(instance), waiting_(false), signalled_(false) {
48 }
49 // Run a nested message loop and wait until Signal() is called. If Signal()
50 // has already been called, return immediately without running a nested loop.
51 void Wait();
52 // Signal the NestedEvent. If Wait() has been called, quit the message loop.
53 void Signal();
[email protected]6de743a2012-08-30 20:03:2254 // Reset the NestedEvent so it can be used again.
55 void Reset();
[email protected]3ab61272012-04-07 00:09:0856 private:
57 PP_Instance instance_;
58 bool waiting_;
59 bool signalled_;
60 // Disable copy and assign.
61 NestedEvent(const NestedEvent&);
62 NestedEvent& operator=(const NestedEvent&);
63};
64
65enum CallbackType { PP_REQUIRED, PP_OPTIONAL, PP_BLOCKING };
[email protected]de9bdd12010-11-04 00:36:2266class TestCompletionCallback {
67 public:
[email protected]cc2386c42012-06-29 04:41:4268 class Delegate {
69 public:
70 virtual ~Delegate() {}
71 virtual void OnCallback(void* user_data, int32_t result) = 0;
72 };
[email protected]3ab61272012-04-07 00:09:0873 explicit TestCompletionCallback(PP_Instance instance);
74 // TODO(dmichael): Remove this constructor.
[email protected]917e86a2011-06-30 21:42:3775 TestCompletionCallback(PP_Instance instance, bool force_async);
[email protected]de9bdd12010-11-04 00:36:2276
[email protected]3ab61272012-04-07 00:09:0877 TestCompletionCallback(PP_Instance instance, CallbackType callback_type);
78
[email protected]cc2386c42012-06-29 04:41:4279 // Sets a Delegate instance. OnCallback() of this instance will be invoked
80 // when the completion callback is invoked.
81 // The delegate will be reset when Reset() or GetCallback() is called.
82 void SetDelegate(Delegate* delegate) { delegate_ = delegate; }
83
[email protected]26d912d32011-05-02 17:28:1084 // Waits for the callback to be called and returns the
85 // result. Returns immediately if the callback was previously called
86 // and the result wasn't returned (i.e. each result value received
87 // by the callback is returned by WaitForResult() once and only
[email protected]3ab61272012-04-07 00:09:0888 // once). DEPRECATED: Please use the one below.
89 // TODO(dmichael): Remove this one when all the tests are updated.
[email protected]de9bdd12010-11-04 00:36:2290 int32_t WaitForResult();
91
[email protected]3ab61272012-04-07 00:09:0892 // Wait for a result, given the return from the call which took this callback
93 // as a parameter. If |result| is PP_OK_COMPLETIONPENDING, WaitForResult will
94 // block until its callback has been invoked (in some cases, this will already
95 // have happened, and WaitForCallback can return immediately).
96 // For any other values, WaitForResult will simply set its internal "result_"
97 // field. To retrieve the final result of the operation (i.e., the result
98 // the callback has run, if necessary), call result(). You can call result()
99 // as many times as necessary until a new pp::CompletionCallback is retrieved.
100 //
101 // In some cases, you may want to check that the callback was invoked in the
102 // expected way (i.e., if the callback was "Required", then it should be
103 // invoked asynchronously). Within the body of a test (where returning a non-
104 // empty string indicates test failure), you can use the
105 // CHECK_CALLBACK_BEHAVIOR(callback) macro. From within a helper function,
106 // you can use failed() and errors().
107 //
108 // Example usage within a test:
109 // callback.WaitForResult(foo.DoSomething(callback));
110 // CHECK_CALLBACK_BEHAVIOR(callback);
111 // ASSERT_EQ(PP_OK, callback.result());
112 //
113 // Example usage within a helper function:
114 // void HelperFunction(std::string* error_message) {
115 // callback.WaitForResult(foo.DoSomething(callback));
116 // if (callback.failed())
117 // error_message->assign(callback.errors());
118 // }
119 void WaitForResult(int32_t result);
[email protected]de9bdd12010-11-04 00:36:22120
[email protected]3ab61272012-04-07 00:09:08121 // Used when you expect to receive either synchronous completion with PP_OK
122 // or a PP_ERROR_ABORTED asynchronously.
123 // Example usage:
124 // int32_t result = 0;
125 // {
126 // pp::URLLoader temp(instance_);
127 // result = temp.Open(request, callback);
128 // }
129 // callback.WaitForAbortResult(result);
130 // CHECK_CALLBACK_BEHAVIOR(callback);
131 void WaitForAbortResult(int32_t result);
132
133 // Retrieve a pp::CompletionCallback for use in testing. This Reset()s the
134 // TestCompletionCallback.
135 pp::CompletionCallback GetCallback();
136 operator pp::CompletionCallback() {
137 return GetCallback();
138 }
139
140 // TODO(dmichael): Remove run_count when all tests are updated. Most cases
141 // that use this can simply use CHECK_CALLBACK_BEHAVIOR.
[email protected]64264ef2010-12-21 00:45:43142 unsigned run_count() const { return run_count_; }
[email protected]3ab61272012-04-07 00:09:08143 // TODO(dmichael): Remove this; tests should use Reset() instead.
[email protected]64264ef2010-12-21 00:45:43144 void reset_run_count() { run_count_ = 0; }
145
[email protected]3ab61272012-04-07 00:09:08146 bool failed() { return !errors_.empty(); }
147 const std::string& errors() { return errors_; }
148
[email protected]db567f2b2011-04-12 23:28:59149 int32_t result() const { return result_; }
150
[email protected]3ab61272012-04-07 00:09:08151 // Reset so that this callback can be used again.
152 void Reset();
153
[email protected]bcc801f2012-11-16 07:41:09154 protected:
[email protected]de9bdd12010-11-04 00:36:22155 static void Handler(void* user_data, int32_t result);
[email protected]77c34172012-11-08 18:55:16156 void RunMessageLoop();
157 void QuitMessageLoop();
[email protected]de9bdd12010-11-04 00:36:22158
[email protected]3ab61272012-04-07 00:09:08159 // Used to check that WaitForResult is only called once for each usage of the
160 // callback.
161 bool wait_for_result_called_;
162 // Indicates whether we have already been invoked.
[email protected]26d912d32011-05-02 17:28:10163 bool have_result_;
[email protected]3ab61272012-04-07 00:09:08164 // The last result received (or PP_OK_COMPLETIONCALLBACK if none).
[email protected]de9bdd12010-11-04 00:36:22165 int32_t result_;
[email protected]3ab61272012-04-07 00:09:08166 CallbackType callback_type_;
[email protected]de9bdd12010-11-04 00:36:22167 bool post_quit_task_;
[email protected]3ab61272012-04-07 00:09:08168 std::string errors_;
[email protected]64264ef2010-12-21 00:45:43169 unsigned run_count_;
[email protected]7358d572011-02-15 18:44:40170 PP_Instance instance_;
[email protected]cc2386c42012-06-29 04:41:42171 Delegate* delegate_;
[email protected]d4ab94712012-11-15 21:01:23172 pp::MessageLoop target_loop_;
[email protected]de9bdd12010-11-04 00:36:22173};
174
[email protected]bcc801f2012-11-16 07:41:09175template <typename OutputT>
176class TestCompletionCallbackWithOutput : public TestCompletionCallback {
177 public:
178 explicit TestCompletionCallbackWithOutput(PP_Instance instance) :
179 TestCompletionCallback(instance) {
180 }
[email protected]78784362012-12-11 09:49:13181
182 TestCompletionCallbackWithOutput(PP_Instance instance, bool force_async) :
183 TestCompletionCallback(instance, force_async) {
184 }
[email protected]bcc801f2012-11-16 07:41:09185
186 TestCompletionCallbackWithOutput(PP_Instance instance,
187 CallbackType callback_type) :
188 TestCompletionCallback(instance, callback_type) {
189 }
190
191 pp::CompletionCallbackWithOutput<OutputT> GetCallbackWithOutput();
192 operator pp::CompletionCallbackWithOutput<OutputT>() {
193 return GetCallbackWithOutput();
194 }
195
196 const OutputT& output() { return output_storage_.output(); }
197
198 typename pp::CompletionCallbackWithOutput<OutputT>::OutputStorageType
199 output_storage_;
200};
201
202template <typename OutputT>
203pp::CompletionCallbackWithOutput<OutputT>
204TestCompletionCallbackWithOutput<OutputT>::GetCallbackWithOutput() {
205 Reset();
[email protected]78784362012-12-11 09:49:13206 if (callback_type_ == PP_BLOCKING) {
207 pp::CompletionCallbackWithOutput<OutputT> cc(
208 &TestCompletionCallback::Handler,
209 this,
210 &output_storage_);
211 return cc;
212 }
213
[email protected]bcc801f2012-11-16 07:41:09214 target_loop_ = pp::MessageLoop::GetCurrent();
215 pp::CompletionCallbackWithOutput<OutputT> cc(
216 &TestCompletionCallback::Handler,
217 this,
218 &output_storage_);
219 if (callback_type_ == PP_OPTIONAL)
220 cc.set_flags(PP_COMPLETIONCALLBACK_FLAG_OPTIONAL);
221 return cc;
222}
223
224
[email protected]3ab61272012-04-07 00:09:08225// Verifies that the callback didn't record any errors. If the callback is run
226// in an unexpected way (e.g., if it's invoked asynchronously when the call
227// should have blocked), this returns an appropriate error string.
228#define CHECK_CALLBACK_BEHAVIOR(callback) \
229do { \
230 if ((callback).failed()) \
231 return (callback).errors(); \
232} while (false)
233
[email protected]2059f3d2011-12-01 20:12:37234/*
235 * A set of macros to use for platform detection. These were largely copied
236 * from chromium's build_config.h.
237 */
238#if defined(__APPLE__)
239#define PPAPI_OS_MACOSX 1
240#elif defined(ANDROID)
241#define PPAPI_OS_ANDROID 1
242#elif defined(__native_client__)
243#define PPAPI_OS_NACL 1
244#elif defined(__linux__)
245#define PPAPI_OS_LINUX 1
246#elif defined(_WIN32)
247#define PPAPI_OS_WIN 1
248#elif defined(__FreeBSD__)
249#define PPAPI_OS_FREEBSD 1
250#elif defined(__OpenBSD__)
251#define PPAPI_OS_OPENBSD 1
252#elif defined(__sun)
253#define PPAPI_OS_SOLARIS 1
254#else
[email protected]3ab61272012-04-07 00:09:08255#error Please add support for your platform in ppapi/tests/test_utils.h
[email protected]2059f3d2011-12-01 20:12:37256#endif
257
258/* These are used to determine POSIX-like implementations vs Windows. */
259#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \
260 defined(__OpenBSD__) || defined(__sun) || defined(__native_client__)
261#define PPAPI_POSIX 1
262#endif
263
[email protected]de9bdd12010-11-04 00:36:22264#endif // PPAPI_TESTS_TEST_UTILS_H_