Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(461)

Side by Side Diff: ppapi/tests/test_post_message.cc

Issue 26564009: [PPAPI] It is now possible to pass filesystems from JavaScript to NaCl modules. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: GetConnectionForInstance DCHECKs if in-process. Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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 <string.h>
7 #include <algorithm> 8 #include <algorithm>
8 #include <map> 9 #include <map>
9 #include <sstream> 10 #include <sstream>
10 11
11 #include "ppapi/c/dev/ppb_testing_dev.h" 12 #include "ppapi/c/dev/ppb_testing_dev.h"
12 #include "ppapi/c/pp_var.h" 13 #include "ppapi/c/pp_var.h"
14 #include "ppapi/c/ppb_file_io.h"
15 #include "ppapi/cpp/file_io.h"
16 #include "ppapi/cpp/file_ref.h"
17 #include "ppapi/cpp/file_system.h"
13 #include "ppapi/cpp/instance.h" 18 #include "ppapi/cpp/instance.h"
14 #include "ppapi/cpp/var.h" 19 #include "ppapi/cpp/var.h"
15 #include "ppapi/cpp/var_array.h" 20 #include "ppapi/cpp/var_array.h"
16 #include "ppapi/cpp/var_array_buffer.h" 21 #include "ppapi/cpp/var_array_buffer.h"
17 #include "ppapi/cpp/var_dictionary.h" 22 #include "ppapi/cpp/var_dictionary.h"
18 #include "ppapi/tests/pp_thread.h" 23 #include "ppapi/tests/pp_thread.h"
19 #include "ppapi/tests/test_utils.h" 24 #include "ppapi/tests/test_utils.h"
20 #include "ppapi/tests/testing_instance.h" 25 #include "ppapi/tests/testing_instance.h"
21 26
22 // Windows defines 'PostMessage', so we have to undef it. 27 // Windows defines 'PostMessage', so we have to undef it.
23 #ifdef PostMessage 28 #ifdef PostMessage
24 #undef PostMessage 29 #undef PostMessage
25 #endif 30 #endif
26 31
27 REGISTER_TEST_CASE(PostMessage); 32 REGISTER_TEST_CASE(PostMessage);
28 33
29 namespace { 34 namespace {
30 35
36 const char kTestFilename[] = "testfile.txt";
31 const char kTestString[] = "Hello world!"; 37 const char kTestString[] = "Hello world!";
32 const bool kTestBool = true; 38 const bool kTestBool = true;
33 const int32_t kTestInt = 42; 39 const int32_t kTestInt = 42;
34 const double kTestDouble = 42.0; 40 const double kTestDouble = 42.0;
35 41
36 // On Windows XP bots, the NonMainThread test can run very slowly. So we dial 42 // On Windows XP bots, the NonMainThread test can run very slowly. So we dial
37 // back the number of threads & messages when running on Windows. 43 // back the number of threads & messages when running on Windows.
38 #ifdef PPAPI_OS_WIN 44 #ifdef PPAPI_OS_WIN
39 const int32_t kThreadsToRun = 2; 45 const int32_t kThreadsToRun = 2;
40 const int32_t kMessagesToSendPerThread = 5; 46 const int32_t kMessagesToSendPerThread = 5;
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 js_code += "var plugin = document.getElementById('plugin');" 160 js_code += "var plugin = document.getElementById('plugin');"
155 "plugin.removeEventListener('message'," 161 "plugin.removeEventListener('message',"
156 " plugin.wait_for_messages_handler);" 162 " plugin.wait_for_messages_handler);"
157 "delete plugin.wait_for_messages_handler;"; 163 "delete plugin.wait_for_messages_handler;";
158 instance_->EvalScript(js_code); 164 instance_->EvalScript(js_code);
159 } 165 }
160 166
161 bool TestPostMessage::Init() { 167 bool TestPostMessage::Init() {
162 bool success = CheckTestingInterface(); 168 bool success = CheckTestingInterface();
163 169
170 core_interface_ = static_cast<const PPB_Core*>(
171 pp::Module::Get()->GetBrowserInterface(PPB_CORE_INTERFACE));
172 file_system_interface_ = static_cast<const PPB_FileSystem*>(
173 pp::Module::Get()->GetBrowserInterface(PPB_FILESYSTEM_INTERFACE));
174 var_interface_ = static_cast<const PPB_Var*>(
175 pp::Module::Get()->GetBrowserInterface(PPB_VAR_INTERFACE));
176 var_resource_interface_ = static_cast<const PPB_VarResource_Dev*>(
177 pp::Module::Get()->GetBrowserInterface(PPB_VAR_RESOURCE_DEV_INTERFACE));
178 if (!core_interface_ || !file_system_interface_ || !var_interface_ ||
179 !var_resource_interface_)
180 return false;
181
164 // Set up a special listener that only responds to a FINISHED_WAITING string. 182 // Set up a special listener that only responds to a FINISHED_WAITING string.
165 // This is for use by WaitForMessages. 183 // This is for use by WaitForMessages.
166 std::string js_code; 184 std::string js_code;
167 // Note the following code is dependent on some features of test_case.html. 185 // Note the following code is dependent on some features of test_case.html.
168 // E.g., it is assumed that the DOM element where the plugin is embedded has 186 // E.g., it is assumed that the DOM element where the plugin is embedded has
169 // an id of 'plugin', and there is a function 'IsTestingMessage' that allows 187 // an id of 'plugin', and there is a function 'IsTestingMessage' that allows
170 // us to ignore the messages that are intended for use by the testing 188 // us to ignore the messages that are intended for use by the testing
171 // framework itself. 189 // framework itself.
172 js_code += "var plugin = document.getElementById('plugin');" 190 js_code += "var plugin = document.getElementById('plugin');"
173 "var wait_for_messages_handler = function(message_event) {" 191 "var wait_for_messages_handler = function(message_event) {"
(...skipping 20 matching lines...) Expand all
194 } 212 }
195 213
196 void TestPostMessage::RunTests(const std::string& filter) { 214 void TestPostMessage::RunTests(const std::string& filter) {
197 // Note: SendInInit must be first, because it expects to receive a message 215 // Note: SendInInit must be first, because it expects to receive a message
198 // that was sent in Init above. 216 // that was sent in Init above.
199 RUN_TEST(SendInInit, filter); 217 RUN_TEST(SendInInit, filter);
200 RUN_TEST(SendingData, filter); 218 RUN_TEST(SendingData, filter);
201 RUN_TEST(SendingArrayBuffer, filter); 219 RUN_TEST(SendingArrayBuffer, filter);
202 RUN_TEST(SendingArray, filter); 220 RUN_TEST(SendingArray, filter);
203 RUN_TEST(SendingDictionary, filter); 221 RUN_TEST(SendingDictionary, filter);
222 RUN_TEST(SendingResource, filter);
204 RUN_TEST(SendingComplexVar, filter); 223 RUN_TEST(SendingComplexVar, filter);
205 RUN_TEST(MessageEvent, filter); 224 RUN_TEST(MessageEvent, filter);
206 RUN_TEST(NoHandler, filter); 225 RUN_TEST(NoHandler, filter);
207 RUN_TEST(ExtraParam, filter); 226 RUN_TEST(ExtraParam, filter);
208 if (testing_interface_->IsOutOfProcess()) 227 if (testing_interface_->IsOutOfProcess())
209 RUN_TEST(NonMainThread, filter); 228 RUN_TEST(NonMainThread, filter);
210 } 229 }
211 230
212 void TestPostMessage::HandleMessage(const pp::Var& message_data) { 231 void TestPostMessage::HandleMessage(const pp::Var& message_data) {
213 if (message_data.is_string() && 232 if (message_data.is_string() &&
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 bool TestPostMessage::PostMessageFromJavaScript(const std::string& func) { 265 bool TestPostMessage::PostMessageFromJavaScript(const std::string& func) {
247 std::string js_code; 266 std::string js_code;
248 js_code += "var plugin = document.getElementById('plugin');" 267 js_code += "var plugin = document.getElementById('plugin');"
249 "plugin.postMessage("; 268 "plugin.postMessage(";
250 js_code += func + "()"; 269 js_code += func + "()";
251 js_code += " );"; 270 js_code += " );";
252 instance_->EvalScript(js_code); 271 instance_->EvalScript(js_code);
253 return true; 272 return true;
254 } 273 }
255 274
275 bool TestPostMessage::PostMessageFromJavaScriptAsync(const std::string& func) {
276 // After the |func| calls callback, post both the given |message|, as well as
277 // the special message FINISHED_WAITING_MESSAGE. This ensures that
278 // WaitForMessagesAsync correctly waits until the callback is called.
279 std::string js_code;
280 js_code += "var plugin = document.getElementById('plugin');"
281 "var callback = function(message) {"
282 " plugin.postMessage(message);"
283 " plugin.postMessage('" FINISHED_WAITING_MESSAGE "');"
284 "};";
285 js_code += "(" + func + ")(callback);";
286 instance_->EvalScript(js_code);
287 return true;
288 }
289
256 bool TestPostMessage::ClearListeners() { 290 bool TestPostMessage::ClearListeners() {
257 std::string js_code; 291 std::string js_code;
258 js_code += "var plugin = document.getElementById('plugin');" 292 js_code += "var plugin = document.getElementById('plugin');"
259 "while (plugin.eventListeners.length) {" 293 "while (plugin.eventListeners.length) {"
260 " plugin.removeEventListener('message'," 294 " plugin.removeEventListener('message',"
261 " plugin.eventListeners.pop());" 295 " plugin.eventListeners.pop());"
262 "}"; 296 "}";
263 instance_->EvalScript(js_code); 297 instance_->EvalScript(js_code);
264 return true; 298 return true;
265 } 299 }
266 300
267 int TestPostMessage::WaitForMessages() { 301 int TestPostMessage::WaitForMessages() {
268 size_t message_size_before = message_data_.size(); 302 size_t message_size_before = message_data_.size();
269 // We first post a FINISHED_WAITING_MESSAGE. This should be guaranteed to 303 // We first post a FINISHED_WAITING_MESSAGE. This should be guaranteed to
270 // come back _after_ any other incoming messages that were already pending. 304 // come back _after_ any other incoming messages that were already pending.
271 instance_->PostMessage(pp::Var(FINISHED_WAITING_MESSAGE)); 305 instance_->PostMessage(pp::Var(FINISHED_WAITING_MESSAGE));
272 testing_interface_->RunMessageLoop(instance_->pp_instance()); 306 testing_interface_->RunMessageLoop(instance_->pp_instance());
273 // Now that the FINISHED_WAITING_MESSAGE has been echoed back to us, we know 307 // Now that the FINISHED_WAITING_MESSAGE has been echoed back to us, we know
274 // that all pending messages have been slurped up. Return the number we 308 // that all pending messages have been slurped up. Return the number we
275 // received (which may be zero). 309 // received (which may be zero).
276 return message_data_.size() - message_size_before; 310 return message_data_.size() - message_size_before;
277 } 311 }
278 312
313 int TestPostMessage::WaitForMessagesAsync() {
dmichael (off chromium) 2013/10/23 17:36:02 This function only works right if you've called Po
Matt Giuca 2013/10/24 01:00:11 Done.
314 size_t message_size_before = message_data_.size();
315 // Unlike WaitForMessages, we do not post FINISHED_WAITING_MESSAGE. This is
316 // because PostMessageFromJavaScriptAsync will post it for us, when the
317 // asynchronous operation completes.
318 testing_interface_->RunMessageLoop(instance_->pp_instance());
319 // Now that the FINISHED_WAITING_MESSAGE has been echoed back to us, we know
320 // that all pending messages have been slurped up. Return the number we
321 // received (which may be zero).
322 return message_data_.size() - message_size_before;
323 }
324
279 std::string TestPostMessage::CheckMessageProperties( 325 std::string TestPostMessage::CheckMessageProperties(
280 const pp::Var& test_data, 326 const pp::Var& test_data,
281 const std::vector<std::string>& properties_to_check) { 327 const std::vector<std::string>& properties_to_check) {
282 typedef std::vector<std::string>::const_iterator Iterator; 328 typedef std::vector<std::string>::const_iterator Iterator;
283 for (Iterator iter = properties_to_check.begin(); 329 for (Iterator iter = properties_to_check.begin();
284 iter != properties_to_check.end(); 330 iter != properties_to_check.end();
285 ++iter) { 331 ++iter) {
286 ASSERT_TRUE(AddEchoingListener(*iter)); 332 ASSERT_TRUE(AddEchoingListener(*iter));
287 message_data_.clear(); 333 message_data_.clear();
288 instance_->PostMessage(test_data); 334 instance_->PostMessage(test_data);
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 ASSERT_EQ(WaitForMessages(), 1); 572 ASSERT_EQ(WaitForMessages(), 1);
527 ASSERT_TRUE(message_data_.back().is_dictionary()); 573 ASSERT_TRUE(message_data_.back().is_dictionary());
528 ASSERT_TRUE(VarsEqual(dictionary, message_data_.back())); 574 ASSERT_TRUE(VarsEqual(dictionary, message_data_.back()));
529 575
530 message_data_.clear(); 576 message_data_.clear();
531 ASSERT_TRUE(ClearListeners()); 577 ASSERT_TRUE(ClearListeners());
532 578
533 PASS(); 579 PASS();
534 } 580 }
535 581
582 std::string TestPostMessage::TestSendingResource() {
583 // Clean up after previous tests. This also swallows the message sent by Init
584 // if we didn't run the 'SendInInit' test. All tests other than 'SendInInit'
585 // should start with these.
586 WaitForMessages();
587 message_data_.clear();
588 ASSERT_TRUE(ClearListeners());
589
590 // Test sending a DOMFileSystem from JavaScript to the plugin.
591 // This opens a real (temporary) file using the HTML5 FileSystem API and
592 // writes to it.
593 ASSERT_TRUE(AddEchoingListener("message_event.data"));
594 std::string js_code =
595 "function(callback) {"
596 " window.webkitRequestFileSystem(window.TEMPORARY, 1024,"
597 " function(fileSystem) {"
598 " fileSystem.root.getFile('";
599 js_code += kTestFilename;
600 js_code += "', {create: true}, function(tempFile) {"
601 " tempFile.createWriter(function(writer) {"
602 " writer.onerror = function() { callback(null); };"
603 " writer.onwriteend = function() { callback(fileSystem); };"
604 " var blob = new Blob(['";
605 js_code += kTestString;
606 js_code += "'], {'type': 'text/plain'});"
607 " writer.write(blob);"
608 " });"
609 " }, function() { callback(null); });"
610 " }, function() { callback(null); });"
611 "}";
612 PostMessageFromJavaScriptAsync(js_code);
613 ASSERT_EQ(message_data_.size(), 0);
614 ASSERT_EQ(WaitForMessagesAsync(), 1);
615 // TODO(mgiuca): Use the C++ API instead of the C API, when it is available.
616 PP_Var var = message_data_.back().Detach();
617 PP_Resource result = var_resource_interface_->VarToResource(var);
618 ASSERT_TRUE(file_system_interface_->IsFileSystem(result));
619 {
620 pp::FileSystem file_system(pp::PASS_REF, result);
621 std::string file_path = "/";
622 file_path += kTestFilename;
623 pp::FileRef file_ref(file_system, file_path.c_str());
624 ASSERT_NE(0, file_ref.pp_resource());
625 ASSERT_EQ(kTestFilename, file_ref.GetName().AsString());
626 pp::FileIO file_io(instance_);
627 ASSERT_NE(0, file_io.pp_resource());
628
629 TestCompletionCallback callback_1(instance_->pp_instance(),
630 callback_type());
631 callback_1.WaitForResult(
632 file_io.Open(file_ref, PP_FILEOPENFLAG_READ, callback_1.GetCallback()));
633 CHECK_CALLBACK_BEHAVIOR(callback_1);
634 ASSERT_EQ(PP_OK, callback_1.result());
635
636 TestCompletionCallback callback_2(instance_->pp_instance(),
637 callback_type());
dmichael (off chromium) 2013/10/23 17:33:21 We usually just reuse the first TestCompletionCall
Matt Giuca 2013/10/24 01:00:11 Done. (I copied the callback_1 style from test_fil
dmichael (off chromium) 2013/10/25 20:13:16 That's necessary when you have 2 operations in par
638 int length = strlen(kTestString);
639 char buffer[length]; // Note: Not null-terminated!
640 callback_2.WaitForResult(
641 file_io.Read(0, buffer, length, callback_2.GetCallback()));
642 CHECK_CALLBACK_BEHAVIOR(callback_2);
643 ASSERT_EQ(length, callback_2.result());
644 ASSERT_EQ(0, memcmp(buffer, kTestString, length));
645 }
646 var_interface_->Release(var);
647
648 WaitForMessages();
649 message_data_.clear();
650 ASSERT_TRUE(ClearListeners());
651
652 // TODO(mgiuca): Test roundtrip from plugin to JS and back, when the plugin to
653 // JS support is available.
654
655 PASS();
656 }
657
536 std::string TestPostMessage::TestSendingComplexVar() { 658 std::string TestPostMessage::TestSendingComplexVar() {
537 // Clean up after previous tests. This also swallows the message sent by Init 659 // Clean up after previous tests. This also swallows the message sent by Init
538 // if we didn't run the 'SendInInit' test. All tests other than 'SendInInit' 660 // if we didn't run the 'SendInInit' test. All tests other than 'SendInInit'
539 // should start with these. 661 // should start with these.
540 WaitForMessages(); 662 WaitForMessages();
541 message_data_.clear(); 663 message_data_.clear();
542 ASSERT_TRUE(ClearListeners()); 664 ASSERT_TRUE(ClearListeners());
543 665
544 pp::Var string(kTestString); 666 pp::Var string(kTestString);
545 pp::VarDictionary dictionary; 667 pp::VarDictionary dictionary;
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
756 ASSERT_TRUE(received_value <= kThreadsToRun); 878 ASSERT_TRUE(received_value <= kThreadsToRun);
757 ++received_counts[received_value]; 879 ++received_counts[received_value];
758 } 880 }
759 ASSERT_EQ(received_counts, expected_counts); 881 ASSERT_EQ(received_counts, expected_counts);
760 882
761 message_data_.clear(); 883 message_data_.clear();
762 ASSERT_TRUE(ClearListeners()); 884 ASSERT_TRUE(ClearListeners());
763 885
764 PASS(); 886 PASS();
765 } 887 }
OLDNEW
« content/renderer/pepper/resource_converter.cc ('K') | « ppapi/tests/test_post_message.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698