OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ppapi/tests/test_post_message.h" | 5 #include "ppapi/tests/test_post_message.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "ppapi/c/dev/ppb_testing_dev.h" | 9 #include "ppapi/c/dev/ppb_testing_dev.h" |
10 #include "ppapi/c/pp_var.h" | 10 #include "ppapi/c/pp_var.h" |
11 #include "ppapi/cpp/dev/scriptable_object_deprecated.h" | 11 #include "ppapi/cpp/dev/scriptable_object_deprecated.h" |
12 #include "ppapi/cpp/instance.h" | 12 #include "ppapi/cpp/instance.h" |
13 #include "ppapi/cpp/var.h" | 13 #include "ppapi/cpp/var.h" |
14 #include "ppapi/tests/pp_thread.h" | |
14 #include "ppapi/tests/test_utils.h" | 15 #include "ppapi/tests/test_utils.h" |
15 #include "ppapi/tests/testing_instance.h" | 16 #include "ppapi/tests/testing_instance.h" |
16 | 17 |
17 // Windows defines 'PostMessage', so we have to undef it. | 18 // Windows defines 'PostMessage', so we have to undef it. |
18 #ifdef PostMessage | 19 #ifdef PostMessage |
19 #undef PostMessage | 20 #undef PostMessage |
20 #endif | 21 #endif |
21 | 22 |
22 REGISTER_TEST_CASE(PostMessage); | 23 REGISTER_TEST_CASE(PostMessage); |
23 | 24 |
24 namespace { | 25 namespace { |
25 | 26 |
26 const char kTestString[] = "Hello world!"; | 27 const char kTestString[] = "Hello world!"; |
27 const bool kTestBool = true; | 28 const bool kTestBool = true; |
28 const int32_t kTestInt = 42; | 29 const int32_t kTestInt = 42; |
29 const double kTestDouble = 42.0; | 30 const double kTestDouble = 42.0; |
30 const int32_t kThreadsToRun = 10; | 31 const int32_t kThreadsToRun = 10; |
32 const int32_t kMessagesToSendPerThread = 50; | |
33 | |
34 // The struct that invoke_post_message_thread_func expects for its argument. | |
35 // It includes the instance on which to invoke PostMessage, and the value to | |
36 // pass to PostMessage. | |
37 struct InvokePostMessageThreadArg { | |
38 InvokePostMessageThreadArg(pp::Instance* i, const pp::Var& v) | |
39 : instance(i), value_to_send(v) {} | |
40 pp::Instance* instance; | |
41 pp::Var value_to_send; | |
42 }; | |
43 | |
44 void InvokePostMessageThreadFunc(void* user_data) { | |
45 InvokePostMessageThreadArg* arg = | |
46 static_cast<InvokePostMessageThreadArg*>(user_data); | |
47 for (int32_t i = 0; i < kMessagesToSendPerThread; ++i) | |
48 arg->instance->PostMessage(arg->value_to_send); | |
49 delete arg; | |
50 } | |
31 | 51 |
32 } // namespace | 52 } // namespace |
33 | 53 |
34 bool TestPostMessage::Init() { | 54 bool TestPostMessage::Init() { |
35 return InitTestingInterface(); | 55 return InitTestingInterface(); |
36 } | 56 } |
37 | 57 |
38 void TestPostMessage::RunTest() { | 58 void TestPostMessage::RunTest() { |
39 RUN_TEST(SendingData); | 59 RUN_TEST(SendingData); |
40 RUN_TEST(MessageEvent); | 60 RUN_TEST(MessageEvent); |
41 RUN_TEST(NoHandler); | 61 RUN_TEST(NoHandler); |
42 RUN_TEST(ExtraParam); | 62 RUN_TEST(ExtraParam); |
63 if (testing_interface_->IsOutOfProcess()) | |
64 RUN_TEST(NonMainThread); | |
43 } | 65 } |
44 | 66 |
45 void TestPostMessage::HandleMessage(const pp::Var& message_data) { | 67 void TestPostMessage::HandleMessage(const pp::Var& message_data) { |
46 message_data_.push_back(message_data); | 68 message_data_.push_back(message_data); |
47 testing_interface_->QuitMessageLoop(instance_->pp_instance()); | 69 testing_interface_->QuitMessageLoop(instance_->pp_instance()); |
48 } | 70 } |
49 | 71 |
50 bool TestPostMessage::AddEchoingListener(const std::string& expression) { | 72 bool TestPostMessage::AddEchoingListener(const std::string& expression) { |
51 std::string js_code; | 73 std::string js_code; |
52 // Note the following code is dependent on some features of test_case.html. | 74 // Note the following code is dependent on some features of test_case.html. |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
247 // Therefore, we will do CallOnMainThread to yield control. That event should | 269 // Therefore, we will do CallOnMainThread to yield control. That event should |
248 // fire, but we should see no messages when we return. | 270 // fire, but we should see no messages when we return. |
249 TestCompletionCallback callback(instance_->pp_instance()); | 271 TestCompletionCallback callback(instance_->pp_instance()); |
250 pp::Module::Get()->core()->CallOnMainThread(0, callback); | 272 pp::Module::Get()->core()->CallOnMainThread(0, callback); |
251 callback.WaitForResult(); | 273 callback.WaitForResult(); |
252 ASSERT_TRUE(message_data_.empty()); | 274 ASSERT_TRUE(message_data_.empty()); |
253 | 275 |
254 PASS(); | 276 PASS(); |
255 } | 277 } |
256 | 278 |
279 std::string TestPostMessage::TestNonMainThread() { | |
280 ASSERT_TRUE(ClearListeners()); | |
281 ASSERT_TRUE(AddEchoingListener("message_event.data")); | |
282 message_data_.clear(); | |
283 | |
284 // Set up a thread for each integer from 0 to (kThreadsToRun - 1). Make each | |
285 // thread send the number that matches its index kMessagesToSendPerThread | |
286 // times. For good measure, call postMessage from the main thread | |
287 // kMessagesToSendPerThread times. At the end, we make sure we got all the | |
288 // values we expected. | |
289 PP_ThreadType threads[kThreadsToRun]; | |
290 for (int32_t i = 0; i < kThreadsToRun; ++i) { | |
291 // Set up a thread to send a value of i. | |
292 void* arg = new InvokePostMessageThreadArg(instance_, pp::Var(i)); | |
293 PP_CreateThread(&threads[i], &InvokePostMessageThreadFunc, arg); | |
294 } | |
295 // Invoke PostMessage right now to send a value of (kThreadsToRun). | |
296 for (int32_t j = 0; j < kMessagesToSendPerThread; ++j) | |
polina
2011/08/17 17:58:15
this can be i, no?
dmichael (off chromium)
2011/08/17 21:15:15
Done.
| |
297 instance_->PostMessage(pp::Var(kThreadsToRun)); | |
298 | |
299 // Now join all threads. | |
300 for (int32_t i = 0; i < kThreadsToRun; ++i) { | |
polina
2011/08/17 17:58:15
don't need {}
dmichael (off chromium)
2011/08/17 21:15:15
Done.
| |
301 PP_JoinThread(threads[i]); | |
302 } | |
303 | |
304 // PostMessage is asynchronous, so we should not receive a response yet. | |
305 ASSERT_EQ(message_data_.size(), 0); | |
306 | |
307 // Make sure we got all values that we expected. Note that because it's legal | |
308 // for the JavaScript engine to treat our integers as floating points, we | |
309 // can't just use std::find or equality comparison. So we first put the | |
polina
2011/08/17 17:58:15
you should be able to use the equality comparison
dmichael (off chromium)
2011/08/17 21:15:15
Yes, but that doesn't save me anything, since it m
| |
310 // integer version of all the received Vars in to received_ints, and build up | |
311 // expected_ints. After the loop, we can sort received_int (they may have | |
312 // arrived out of order) and compare to the expected_ints. | |
313 int32_t expected_num = (kThreadsToRun + 1) * kMessagesToSendPerThread; | |
314 // Count how many we receive per-index. | |
315 std::vector<int32_t> expected_counts(kThreadsToRun + 1, | |
316 kMessagesToSendPerThread); | |
polina
2011/08/17 17:58:15
wrong indentation
dmichael (off chromium)
2011/08/17 21:15:15
Done.
| |
317 std::vector<int32_t> received_counts(kThreadsToRun + 1, 0); | |
318 for (int32_t i = 0; i < expected_num; ++i) { | |
319 // Run the message loop to get the next expected message. | |
320 testing_interface_->RunMessageLoop(instance_->pp_instance()); | |
321 // Make sure we got another message in. | |
322 ASSERT_EQ(message_data_.size(), 1); | |
323 pp::Var latest_var(message_data_.back()); | |
324 message_data_.clear(); | |
325 | |
326 ASSERT_TRUE(latest_var.is_int() || (latest_var.is_double())); | |
327 int32_t received_value = -1; | |
328 if (latest_var.is_int()) { | |
329 received_value = latest_var.AsInt(); | |
330 } else if (latest_var.is_double()) { | |
331 received_value = static_cast<int32_t>(latest_var.AsDouble() + 0.5); | |
332 } | |
333 ASSERT_TRUE(received_value >= 0); | |
334 ASSERT_TRUE(received_value <= kThreadsToRun); | |
335 ++received_counts[received_value]; | |
336 } | |
337 ASSERT_EQ(received_counts, expected_counts); | |
338 | |
339 PASS(); | |
340 } | |
341 | |
OLD | NEW |