| 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" | |
| 15 #include "ppapi/tests/test_utils.h" | 14 #include "ppapi/tests/test_utils.h" |
| 16 #include "ppapi/tests/testing_instance.h" | 15 #include "ppapi/tests/testing_instance.h" |
| 17 | 16 |
| 18 // Windows defines 'PostMessage', so we have to undef it. | 17 // Windows defines 'PostMessage', so we have to undef it. |
| 19 #ifdef PostMessage | 18 #ifdef PostMessage |
| 20 #undef PostMessage | 19 #undef PostMessage |
| 21 #endif | 20 #endif |
| 22 | 21 |
| 23 REGISTER_TEST_CASE(PostMessage); | 22 REGISTER_TEST_CASE(PostMessage); |
| 24 | 23 |
| 25 namespace { | 24 namespace { |
| 26 | 25 |
| 27 const char kTestString[] = "Hello world!"; | 26 const char kTestString[] = "Hello world!"; |
| 28 const bool kTestBool = true; | 27 const bool kTestBool = true; |
| 29 const int32_t kTestInt = 42; | 28 const int32_t kTestInt = 42; |
| 30 const double kTestDouble = 42.0; | 29 const double kTestDouble = 42.0; |
| 31 const int32_t kThreadsToRun = 10; | 30 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 } | |
| 51 | 31 |
| 52 } // namespace | 32 } // namespace |
| 53 | 33 |
| 54 bool TestPostMessage::Init() { | 34 bool TestPostMessage::Init() { |
| 55 return InitTestingInterface(); | 35 return InitTestingInterface(); |
| 56 } | 36 } |
| 57 | 37 |
| 58 void TestPostMessage::RunTest() { | 38 void TestPostMessage::RunTest() { |
| 59 RUN_TEST(SendingData); | 39 RUN_TEST(SendingData); |
| 60 RUN_TEST(MessageEvent); | 40 RUN_TEST(MessageEvent); |
| 61 RUN_TEST(NoHandler); | 41 RUN_TEST(NoHandler); |
| 62 RUN_TEST(ExtraParam); | 42 RUN_TEST(ExtraParam); |
| 63 if (testing_interface_->IsOutOfProcess()) | |
| 64 RUN_TEST(NonMainThread); | |
| 65 } | 43 } |
| 66 | 44 |
| 67 void TestPostMessage::HandleMessage(const pp::Var& message_data) { | 45 void TestPostMessage::HandleMessage(const pp::Var& message_data) { |
| 68 message_data_.push_back(message_data); | 46 message_data_.push_back(message_data); |
| 69 testing_interface_->QuitMessageLoop(instance_->pp_instance()); | 47 testing_interface_->QuitMessageLoop(instance_->pp_instance()); |
| 70 } | 48 } |
| 71 | 49 |
| 72 bool TestPostMessage::AddEchoingListener(const std::string& expression) { | 50 bool TestPostMessage::AddEchoingListener(const std::string& expression) { |
| 73 std::string js_code; | 51 std::string js_code; |
| 74 // Note the following code is dependent on some features of test_case.html. | 52 // 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... |
| 269 // Therefore, we will do CallOnMainThread to yield control. That event should | 247 // Therefore, we will do CallOnMainThread to yield control. That event should |
| 270 // fire, but we should see no messages when we return. | 248 // fire, but we should see no messages when we return. |
| 271 TestCompletionCallback callback(instance_->pp_instance()); | 249 TestCompletionCallback callback(instance_->pp_instance()); |
| 272 pp::Module::Get()->core()->CallOnMainThread(0, callback); | 250 pp::Module::Get()->core()->CallOnMainThread(0, callback); |
| 273 callback.WaitForResult(); | 251 callback.WaitForResult(); |
| 274 ASSERT_TRUE(message_data_.empty()); | 252 ASSERT_TRUE(message_data_.empty()); |
| 275 | 253 |
| 276 PASS(); | 254 PASS(); |
| 277 } | 255 } |
| 278 | 256 |
| 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 i = 0; i < kMessagesToSendPerThread; ++i) | |
| 297 instance_->PostMessage(pp::Var(kThreadsToRun)); | |
| 298 | |
| 299 // Now join all threads. | |
| 300 for (int32_t i = 0; i < kThreadsToRun; ++i) | |
| 301 PP_JoinThread(threads[i]); | |
| 302 | |
| 303 // PostMessage is asynchronous, so we should not receive a response yet. | |
| 304 ASSERT_EQ(message_data_.size(), 0); | |
| 305 | |
| 306 // Make sure we got all values that we expected. Note that because it's legal | |
| 307 // for the JavaScript engine to treat our integers as floating points, we | |
| 308 // can't just use std::find or equality comparison. So we instead, we convert | |
| 309 // each incoming value to an integer, and count them in received_counts. | |
| 310 int32_t expected_num = (kThreadsToRun + 1) * kMessagesToSendPerThread; | |
| 311 // Count how many we receive per-index. | |
| 312 std::vector<int32_t> expected_counts(kThreadsToRun + 1, | |
| 313 kMessagesToSendPerThread); | |
| 314 std::vector<int32_t> received_counts(kThreadsToRun + 1, 0); | |
| 315 for (int32_t i = 0; i < expected_num; ++i) { | |
| 316 // Run the message loop to get the next expected message. | |
| 317 testing_interface_->RunMessageLoop(instance_->pp_instance()); | |
| 318 // Make sure we got another message in. | |
| 319 ASSERT_EQ(message_data_.size(), 1); | |
| 320 pp::Var latest_var(message_data_.back()); | |
| 321 message_data_.clear(); | |
| 322 | |
| 323 ASSERT_TRUE(latest_var.is_int() || latest_var.is_double()); | |
| 324 int32_t received_value = -1; | |
| 325 if (latest_var.is_int()) { | |
| 326 received_value = latest_var.AsInt(); | |
| 327 } else if (latest_var.is_double()) { | |
| 328 received_value = static_cast<int32_t>(latest_var.AsDouble() + 0.5); | |
| 329 } | |
| 330 ASSERT_TRUE(received_value >= 0); | |
| 331 ASSERT_TRUE(received_value <= kThreadsToRun); | |
| 332 ++received_counts[received_value]; | |
| 333 } | |
| 334 ASSERT_EQ(received_counts, expected_counts); | |
| 335 | |
| 336 PASS(); | |
| 337 } | |
| 338 | |
| OLD | NEW |