blob: f4ecb7105285e290e256f00d869d77cc57aa1d5f [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
[email protected]7358d572011-02-15 18:44:4010#include "ppapi/c/pp_instance.h"
[email protected]de9bdd12010-11-04 00:36:2211#include "ppapi/c/pp_stdint.h"
[email protected]7310b162013-11-25 22:39:1512#include "ppapi/c/private/ppb_testing_private.h"
[email protected]de9bdd12010-11-04 00:36:2213#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]b1784f42013-06-13 06:48:3617namespace pp {
[email protected]ee517552013-06-22 20:07:5018class NetAddress;
[email protected]b1784f42013-06-13 06:48:3619}
20
[email protected]3c149c62011-11-11 23:22:5221// Timeout to wait for some action to complete.
22extern const int kActionTimeoutMs;
23
[email protected]7310b162013-11-25 22:39:1524const PPB_Testing_Private* GetTestingInterface();
[email protected]de9bdd12010-11-04 00:36:2225std::string ReportError(const char* method, int32_t error);
[email protected]3c149c62011-11-11 23:22:5226void PlatformSleep(int duration_ms);
[email protected]961e8972011-12-15 15:29:1927bool GetLocalHostPort(PP_Instance instance, std::string* host, uint16_t* port);
[email protected]de9bdd12010-11-04 00:36:2228
[email protected]2414d922013-06-10 09:19:2129uint16_t ConvertFromNetEndian16(uint16_t x);
30uint16_t ConvertToNetEndian16(uint16_t x);
[email protected]ee517552013-06-22 20:07:5031bool EqualNetAddress(const pp::NetAddress& addr1, const pp::NetAddress& addr2);
[email protected]b1784f42013-06-13 06:48:3632// Only returns the first address if there are more than one available.
33bool ResolveHost(PP_Instance instance,
34 const std::string& host,
35 uint16_t port,
[email protected]ee517552013-06-22 20:07:5036 pp::NetAddress* addr);
[email protected]92576792013-09-20 15:29:1337bool ReplacePort(PP_Instance instance,
38 const pp::NetAddress& input_addr,
39 uint16_t port,
40 pp::NetAddress* output_addr);
41uint16_t GetPort(const pp::NetAddress& addr);
[email protected]2414d922013-06-10 09:19:2142
[email protected]3ab61272012-04-07 00:09:0843// NestedEvent allows you to run a nested MessageLoop and wait for a particular
44// event to complete. For example, you can use it to wait for a callback on a
45// PPP interface, which will "Signal" the event and make the loop quit.
46// "Wait()" will return immediately if it has already been signalled. Otherwise,
47// it will run a nested message loop (using PPB_Testing.RunMessageLoop) and will
48// return only after it has been signalled.
49// Example:
50// std::string TestFullscreen::TestNormalToFullscreen() {
51// pp::Fullscreen screen_mode(instance);
52// screen_mode.SetFullscreen(true);
53// SimulateUserGesture();
54// // Let DidChangeView run in a nested message loop.
55// nested_event_.Wait();
56// Pass();
57// }
58//
59// void TestFullscreen::DidChangeView(const pp::View& view) {
60// nested_event_.Signal();
61// }
[email protected]808fbcf2013-04-11 04:10:3362//
63// All methods except Signal and PostSignal must be invoked on the main thread.
64// It's OK to signal from a background thread, so you can (for example) Signal()
65// from the Audio thread.
[email protected]3ab61272012-04-07 00:09:0866class NestedEvent {
67 public:
68 explicit NestedEvent(PP_Instance instance)
69 : instance_(instance), waiting_(false), signalled_(false) {
70 }
71 // Run a nested message loop and wait until Signal() is called. If Signal()
72 // has already been called, return immediately without running a nested loop.
73 void Wait();
74 // Signal the NestedEvent. If Wait() has been called, quit the message loop.
[email protected]808fbcf2013-04-11 04:10:3375 // This can be called from any thread.
[email protected]3ab61272012-04-07 00:09:0876 void Signal();
[email protected]808fbcf2013-04-11 04:10:3377 // Signal the NestedEvent in |wait_ms| milliseconds. This can be called from
78 // any thread.
79 void PostSignal(int32_t wait_ms);
80
[email protected]6de743a2012-08-30 20:03:2281 // Reset the NestedEvent so it can be used again.
82 void Reset();
[email protected]3ab61272012-04-07 00:09:0883 private:
[email protected]808fbcf2013-04-11 04:10:3384 void SignalOnMainThread();
85 static void SignalThunk(void* async_event, int32_t result);
86
[email protected]3ab61272012-04-07 00:09:0887 PP_Instance instance_;
88 bool waiting_;
89 bool signalled_;
90 // Disable copy and assign.
91 NestedEvent(const NestedEvent&);
92 NestedEvent& operator=(const NestedEvent&);
93};
94
95enum CallbackType { PP_REQUIRED, PP_OPTIONAL, PP_BLOCKING };
[email protected]de9bdd12010-11-04 00:36:2296class TestCompletionCallback {
97 public:
[email protected]cc2386c42012-06-29 04:41:4298 class Delegate {
99 public:
100 virtual ~Delegate() {}
101 virtual void OnCallback(void* user_data, int32_t result) = 0;
102 };
[email protected]3ab61272012-04-07 00:09:08103 explicit TestCompletionCallback(PP_Instance instance);
104 // TODO(dmichael): Remove this constructor.
[email protected]917e86a2011-06-30 21:42:37105 TestCompletionCallback(PP_Instance instance, bool force_async);
[email protected]de9bdd12010-11-04 00:36:22106
[email protected]3ab61272012-04-07 00:09:08107 TestCompletionCallback(PP_Instance instance, CallbackType callback_type);
108
[email protected]cc2386c42012-06-29 04:41:42109 // Sets a Delegate instance. OnCallback() of this instance will be invoked
110 // when the completion callback is invoked.
111 // The delegate will be reset when Reset() or GetCallback() is called.
112 void SetDelegate(Delegate* delegate) { delegate_ = delegate; }
113
[email protected]3ab61272012-04-07 00:09:08114 // Wait for a result, given the return from the call which took this callback
115 // as a parameter. If |result| is PP_OK_COMPLETIONPENDING, WaitForResult will
116 // block until its callback has been invoked (in some cases, this will already
117 // have happened, and WaitForCallback can return immediately).
118 // For any other values, WaitForResult will simply set its internal "result_"
119 // field. To retrieve the final result of the operation (i.e., the result
120 // the callback has run, if necessary), call result(). You can call result()
121 // as many times as necessary until a new pp::CompletionCallback is retrieved.
122 //
123 // In some cases, you may want to check that the callback was invoked in the
124 // expected way (i.e., if the callback was "Required", then it should be
125 // invoked asynchronously). Within the body of a test (where returning a non-
126 // empty string indicates test failure), you can use the
127 // CHECK_CALLBACK_BEHAVIOR(callback) macro. From within a helper function,
128 // you can use failed() and errors().
129 //
130 // Example usage within a test:
131 // callback.WaitForResult(foo.DoSomething(callback));
132 // CHECK_CALLBACK_BEHAVIOR(callback);
133 // ASSERT_EQ(PP_OK, callback.result());
134 //
135 // Example usage within a helper function:
136 // void HelperFunction(std::string* error_message) {
137 // callback.WaitForResult(foo.DoSomething(callback));
138 // if (callback.failed())
139 // error_message->assign(callback.errors());
140 // }
141 void WaitForResult(int32_t result);
[email protected]de9bdd12010-11-04 00:36:22142
[email protected]3ab61272012-04-07 00:09:08143 // Used when you expect to receive either synchronous completion with PP_OK
144 // or a PP_ERROR_ABORTED asynchronously.
145 // Example usage:
146 // int32_t result = 0;
147 // {
148 // pp::URLLoader temp(instance_);
149 // result = temp.Open(request, callback);
150 // }
151 // callback.WaitForAbortResult(result);
152 // CHECK_CALLBACK_BEHAVIOR(callback);
153 void WaitForAbortResult(int32_t result);
154
155 // Retrieve a pp::CompletionCallback for use in testing. This Reset()s the
156 // TestCompletionCallback.
157 pp::CompletionCallback GetCallback();
[email protected]3ab61272012-04-07 00:09:08158
[email protected]3ab61272012-04-07 00:09:08159 bool failed() { return !errors_.empty(); }
160 const std::string& errors() { return errors_; }
161
[email protected]db567f2b2011-04-12 23:28:59162 int32_t result() const { return result_; }
163
[email protected]3ab61272012-04-07 00:09:08164 // Reset so that this callback can be used again.
165 void Reset();
166
[email protected]500fc4982013-03-29 18:29:45167 CallbackType callback_type() { return callback_type_; }
168 void set_target_loop(const pp::MessageLoop& loop) { target_loop_ = loop; }
[email protected]de9bdd12010-11-04 00:36:22169 static void Handler(void* user_data, int32_t result);
[email protected]500fc4982013-03-29 18:29:45170
171 protected:
[email protected]77c34172012-11-08 18:55:16172 void RunMessageLoop();
173 void QuitMessageLoop();
[email protected]de9bdd12010-11-04 00:36:22174
[email protected]3ab61272012-04-07 00:09:08175 // Used to check that WaitForResult is only called once for each usage of the
176 // callback.
177 bool wait_for_result_called_;
178 // Indicates whether we have already been invoked.
[email protected]26d912d32011-05-02 17:28:10179 bool have_result_;
[email protected]3ab61272012-04-07 00:09:08180 // The last result received (or PP_OK_COMPLETIONCALLBACK if none).
[email protected]de9bdd12010-11-04 00:36:22181 int32_t result_;
[email protected]3ab61272012-04-07 00:09:08182 CallbackType callback_type_;
[email protected]de9bdd12010-11-04 00:36:22183 bool post_quit_task_;
[email protected]3ab61272012-04-07 00:09:08184 std::string errors_;
[email protected]7358d572011-02-15 18:44:40185 PP_Instance instance_;
[email protected]cc2386c42012-06-29 04:41:42186 Delegate* delegate_;
[email protected]d4ab94712012-11-15 21:01:23187 pp::MessageLoop target_loop_;
[email protected]de9bdd12010-11-04 00:36:22188};
189
[email protected]09bd7bc22014-04-30 21:54:43190template <typename OutputT>
191class TestCompletionCallbackWithOutput {
[email protected]bcc801f2012-11-16 07:41:09192 public:
[email protected]09bd7bc22014-04-30 21:54:43193 explicit TestCompletionCallbackWithOutput(PP_Instance instance)
[email protected]d06ae7f2013-07-11 01:10:08194 : callback_(instance),
195 output_storage_() {
[email protected]09bd7bc22014-04-30 21:54:43196 pp::internal::CallbackOutputTraits<OutputT>::Initialize(&output_storage_);
[email protected]bcc801f2012-11-16 07:41:09197 }
[email protected]78784362012-12-11 09:49:13198
[email protected]09bd7bc22014-04-30 21:54:43199 TestCompletionCallbackWithOutput(PP_Instance instance, bool force_async)
[email protected]d06ae7f2013-07-11 01:10:08200 : callback_(instance, force_async),
201 output_storage_() {
[email protected]09bd7bc22014-04-30 21:54:43202 pp::internal::CallbackOutputTraits<OutputT>::Initialize(&output_storage_);
[email protected]78784362012-12-11 09:49:13203 }
[email protected]bcc801f2012-11-16 07:41:09204
[email protected]09bd7bc22014-04-30 21:54:43205 TestCompletionCallbackWithOutput(PP_Instance instance,
206 CallbackType callback_type)
[email protected]d06ae7f2013-07-11 01:10:08207 : callback_(instance, callback_type),
208 output_storage_() {
[email protected]09bd7bc22014-04-30 21:54:43209 pp::internal::CallbackOutputTraits<OutputT>::Initialize(&output_storage_);
[email protected]bcc801f2012-11-16 07:41:09210 }
211
[email protected]09bd7bc22014-04-30 21:54:43212 pp::CompletionCallbackWithOutput<OutputT> GetCallback();
[email protected]2f93bcc2013-04-01 19:19:48213 OutputT output() {
[email protected]09bd7bc22014-04-30 21:54:43214 return pp::internal::CallbackOutputTraits<OutputT>::StorageToPluginArg(
[email protected]2f93bcc2013-04-01 19:19:48215 output_storage_);
216 }
[email protected]bcc801f2012-11-16 07:41:09217
[email protected]500fc4982013-03-29 18:29:45218 // Delegate functions to TestCompletionCallback
219 void SetDelegate(TestCompletionCallback::Delegate* delegate) {
220 callback_.SetDelegate(delegate);
221 }
[email protected]500fc4982013-03-29 18:29:45222 void WaitForResult(int32_t result) { callback_.WaitForResult(result); }
223 void WaitForAbortResult(int32_t result) {
224 callback_.WaitForAbortResult(result);
225 }
[email protected]500fc4982013-03-29 18:29:45226 bool failed() { return callback_.failed(); }
227 const std::string& errors() { return callback_.errors(); }
228 int32_t result() const { return callback_.result(); }
[email protected]d06ae7f2013-07-11 01:10:08229 void Reset() {
[email protected]09bd7bc22014-04-30 21:54:43230 pp::internal::CallbackOutputTraits<OutputT>::Initialize(&output_storage_);
[email protected]d06ae7f2013-07-11 01:10:08231 return callback_.Reset();
232 }
[email protected]500fc4982013-03-29 18:29:45233
234 private:
235 TestCompletionCallback callback_;
[email protected]09bd7bc22014-04-30 21:54:43236 typename pp::CompletionCallbackWithOutput<OutputT>::OutputStorageType
237 output_storage_;
[email protected]bcc801f2012-11-16 07:41:09238};
239
[email protected]09bd7bc22014-04-30 21:54:43240template <typename OutputT>
241pp::CompletionCallbackWithOutput<OutputT>
242TestCompletionCallbackWithOutput<OutputT>::GetCallback() {
[email protected]d06ae7f2013-07-11 01:10:08243 this->Reset();
[email protected]500fc4982013-03-29 18:29:45244 if (callback_.callback_type() == PP_BLOCKING) {
[email protected]09bd7bc22014-04-30 21:54:43245 pp::CompletionCallbackWithOutput<OutputT> cc(&output_storage_);
[email protected]78784362012-12-11 09:49:13246 return cc;
247 }
248
[email protected]500fc4982013-03-29 18:29:45249 callback_.set_target_loop(pp::MessageLoop::GetCurrent());
[email protected]09bd7bc22014-04-30 21:54:43250 pp::CompletionCallbackWithOutput<OutputT> cc(
251 &TestCompletionCallback::Handler,
252 this,
253 &output_storage_);
[email protected]500fc4982013-03-29 18:29:45254 if (callback_.callback_type() == PP_OPTIONAL)
[email protected]bcc801f2012-11-16 07:41:09255 cc.set_flags(PP_COMPLETIONCALLBACK_FLAG_OPTIONAL);
256 return cc;
257}
258
[email protected]3ab61272012-04-07 00:09:08259// Verifies that the callback didn't record any errors. If the callback is run
260// in an unexpected way (e.g., if it's invoked asynchronously when the call
261// should have blocked), this returns an appropriate error string.
262#define CHECK_CALLBACK_BEHAVIOR(callback) \
263do { \
264 if ((callback).failed()) \
[email protected]2f93bcc2013-04-01 19:19:48265 return MakeFailureMessage(__FILE__, __LINE__, \
266 (callback).errors().c_str()); \
[email protected]3ab61272012-04-07 00:09:08267} while (false)
268
[email protected]2059f3d2011-12-01 20:12:37269/*
270 * A set of macros to use for platform detection. These were largely copied
271 * from chromium's build_config.h.
272 */
273#if defined(__APPLE__)
274#define PPAPI_OS_MACOSX 1
275#elif defined(ANDROID)
276#define PPAPI_OS_ANDROID 1
277#elif defined(__native_client__)
278#define PPAPI_OS_NACL 1
279#elif defined(__linux__)
280#define PPAPI_OS_LINUX 1
281#elif defined(_WIN32)
282#define PPAPI_OS_WIN 1
283#elif defined(__FreeBSD__)
284#define PPAPI_OS_FREEBSD 1
285#elif defined(__OpenBSD__)
286#define PPAPI_OS_OPENBSD 1
287#elif defined(__sun)
288#define PPAPI_OS_SOLARIS 1
289#else
[email protected]3ab61272012-04-07 00:09:08290#error Please add support for your platform in ppapi/tests/test_utils.h
[email protected]2059f3d2011-12-01 20:12:37291#endif
292
293/* These are used to determine POSIX-like implementations vs Windows. */
294#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \
295 defined(__OpenBSD__) || defined(__sun) || defined(__native_client__)
296#define PPAPI_POSIX 1
297#endif
298
dmichael822ba8f2016-01-11 17:54:52299// By default, ArrayBuffers over a certain size are sent via shared memory. In
300// order to test for this without sending huge buffers, tests can use this
301// class to set the minimum array buffer size used for shared memory temporarily
302// lower.
303class ScopedArrayBufferSizeSetter {
304 public:
305 ScopedArrayBufferSizeSetter(const PPB_Testing_Private* interface,
306 PP_Instance instance,
307 uint32_t threshold)
308 : interface_(interface),
309 instance_(instance) {
310 interface_->SetMinimumArrayBufferSizeForShmem(instance_, threshold);
311 }
312 ~ScopedArrayBufferSizeSetter() {
313 interface_->SetMinimumArrayBufferSizeForShmem(instance_, 0);
314 }
315 private:
316 const PPB_Testing_Private* interface_;
317 PP_Instance instance_;
318};
319
[email protected]de9bdd12010-11-04 00:36:22320#endif // PPAPI_TESTS_TEST_UTILS_H_