Commit e5ac6335 authored by dmichael's avatar dmichael Committed by Commit bot

PPAPI: Add more error testing for postMessageAndAwaitResponse

Add a test that tries using postMessageAndAwaitResponse in ways that should throw an exception, and makes sure it actually throws.

BUG=367896

Review URL: https://codereview.chromium.org/608843002

Cr-Commit-Position: refs/heads/master@{#297024}
parent f8831db3
...@@ -184,7 +184,8 @@ void FakeDestroy(PP_Instance instance, void* user_data) {} ...@@ -184,7 +184,8 @@ void FakeDestroy(PP_Instance instance, void* user_data) {}
TestMessageHandler::TestMessageHandler(TestingInstance* instance) TestMessageHandler::TestMessageHandler(TestingInstance* instance)
: TestCase(instance), : TestCase(instance),
ppb_messaging_if_(NULL), ppb_messaging_if_(NULL),
handler_thread_(instance) { handler_thread_(instance),
message_received_(instance->pp_instance()) {
} }
TestMessageHandler::~TestMessageHandler() { TestMessageHandler::~TestMessageHandler() {
...@@ -202,11 +203,22 @@ bool TestMessageHandler::Init() { ...@@ -202,11 +203,22 @@ bool TestMessageHandler::Init() {
void TestMessageHandler::RunTests(const std::string& filter) { void TestMessageHandler::RunTests(const std::string& filter) {
RUN_TEST(RegisterErrorConditions, filter); RUN_TEST(RegisterErrorConditions, filter);
RUN_TEST(PostMessageAndAwaitResponse, filter); RUN_TEST(PostMessageAndAwaitResponse, filter);
RUN_TEST(Exceptions, filter);
} }
void TestMessageHandler::HandleMessage(const pp::Var& message_data) { void TestMessageHandler::HandleMessage(const pp::Var& message_data) {
// All messages should go to the background thread message handler. if (instance()->current_test_name() == "Exceptions") {
assert(false); // For TestPostMessageAndAwaitResponse(), all messages should go to the
// background thread message handler.
assert(false);
} else {
if (message_data.is_string()) {
last_message_ = message_data.AsString();
} else {
last_message_ = "message_data was not a string!";
}
message_received_.Signal();
}
} }
std::string TestMessageHandler::TestRegisterErrorConditions() { std::string TestMessageHandler::TestRegisterErrorConditions() {
...@@ -244,6 +256,7 @@ std::string TestMessageHandler::TestRegisterErrorConditions() { ...@@ -244,6 +256,7 @@ std::string TestMessageHandler::TestRegisterErrorConditions() {
std::string TestMessageHandler::TestPostMessageAndAwaitResponse() { std::string TestMessageHandler::TestPostMessageAndAwaitResponse() {
EchoingMessageHandler handler(instance(), EchoingMessageHandler handler(instance(),
handler_thread_.message_loop()); handler_thread_.message_loop());
// Test doing a sync call before the handler is registered.
handler.Register(); handler.Register();
std::string js_code("var plugin = document.getElementById('plugin');\n"); std::string js_code("var plugin = document.getElementById('plugin');\n");
js_code += "var result = undefined;\n"; js_code += "var result = undefined;\n";
...@@ -275,3 +288,56 @@ std::string TestMessageHandler::TestPostMessageAndAwaitResponse() { ...@@ -275,3 +288,56 @@ std::string TestMessageHandler::TestPostMessageAndAwaitResponse() {
PASS(); PASS();
} }
std::string TestMessageHandler::TestExceptions() {
EchoingMessageHandler handler(instance(),
handler_thread_.message_loop());
{
// First, try sending a blocking message when there is no handler
// registered. It should throw an exception.
std::string js_code(
"var plugin = document.getElementById('plugin');\n"
"var caught_exception = false;\n"
"try {\n"
" plugin.postMessageAndAwaitResponse('Hello!');\n"
"} catch (err) {\n"
" caught_exception = true;\n"
"}\n"
"plugin.postMessage(caught_exception ? 'SUCCESS' : 'FAIL');\n");
instance_->EvalScript(js_code);
message_received_.Wait();
ASSERT_EQ("SUCCESS", last_message_);
}
handler.Register();
{
// Now that a handler is registered, try requesting and sending a
// FileSystem. It should throw an exception. The file system is opened
// asynchronously. What *should* happen is that it opens successfully, then
// we try to send it via postMessageAndAwaitResponse, which fails with an
// exception. The test could fail either because the filesystem doesn't
// open or because postMessageAndAwaitResponse doesn't throw an exception.
std::string js_code(
"var plugin = document.getElementById('plugin');\n"
"function gotFileSystem(fs) {\n"
" var caught_exception = false;\n"
" try {\n"
" plugin.postMessageAndAwaitResponse(fs);\n"
" } catch (err) {\n"
" caught_exception = true;\n"
" }\n"
" plugin.postMessage(caught_exception ? 'SUCCESS' : 'FAIL');\n"
"}\n"
"function fileSystemError() {\n"
" plugin.postMessage('Failed to open filesystem');\n"
"}\n"
"window.webkitRequestFileSystem(\n"
" window.Temporary, 1024, gotFileSystem, fileSystemError)\n");
instance_->EvalScript(js_code);
message_received_.Wait();
ASSERT_EQ("SUCCESS", last_message_);
}
handler.Unregister();
ASSERT_SUBTEST_SUCCESS(handler.WaitForDestroy());
PASS();
}
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "ppapi/c/ppb_messaging.h" #include "ppapi/c/ppb_messaging.h"
#include "ppapi/tests/test_case.h" #include "ppapi/tests/test_case.h"
#include "ppapi/tests/test_utils.h"
#include "ppapi/utility/threading/simple_thread.h" #include "ppapi/utility/threading/simple_thread.h"
class TestMessageHandler : public TestCase { class TestMessageHandler : public TestCase {
...@@ -25,9 +26,14 @@ class TestMessageHandler : public TestCase { ...@@ -25,9 +26,14 @@ class TestMessageHandler : public TestCase {
std::string TestRegisterErrorConditions(); std::string TestRegisterErrorConditions();
std::string TestPostMessageAndAwaitResponse(); std::string TestPostMessageAndAwaitResponse();
std::string TestExceptions();
const PPB_Messaging_1_2* ppb_messaging_if_; const PPB_Messaging_1_2* ppb_messaging_if_;
pp::SimpleThread handler_thread_; pp::SimpleThread handler_thread_;
// For TestExceptions():
NestedEvent message_received_;
std::string last_message_;
}; };
#endif // PPAPI_TESTS_TEST_MESSAGE_HANDLER_H_ #endif // PPAPI_TESTS_TEST_MESSAGE_HANDLER_H_
......
...@@ -124,6 +124,8 @@ void TestingInstance::SetCookie(const std::string& name, ...@@ -124,6 +124,8 @@ void TestingInstance::SetCookie(const std::string& name,
void TestingInstance::LogTest(const std::string& test_name, void TestingInstance::LogTest(const std::string& test_name,
const std::string& error_message, const std::string& error_message,
PP_TimeTicks start_time) { PP_TimeTicks start_time) {
current_test_name_ = test_name;
// Compute the time to run the test and save it in a string for logging: // Compute the time to run the test and save it in a string for logging:
PP_TimeTicks end_time(pp::Module::Get()->core()->GetTimeTicks()); PP_TimeTicks end_time(pp::Module::Get()->core()->GetTimeTicks());
std::ostringstream number_stream; std::ostringstream number_stream;
...@@ -164,6 +166,8 @@ void TestingInstance::LogTest(const std::string& test_name, ...@@ -164,6 +166,8 @@ void TestingInstance::LogTest(const std::string& test_name,
test_time.append(time_string); test_time.append(time_string);
test_time.append(" seconds."); test_time.append(" seconds.");
LogTestTime(test_time); LogTestTime(test_time);
current_test_name_.clear();
} }
void TestingInstance::AppendError(const std::string& message) { void TestingInstance::AppendError(const std::string& message) {
......
...@@ -87,6 +87,7 @@ pp::InstancePrivate { ...@@ -87,6 +87,7 @@ pp::InstancePrivate {
void LogTest(const std::string& test_name, void LogTest(const std::string& test_name,
const std::string& error_message, const std::string& error_message,
PP_TimeTicks start_time); PP_TimeTicks start_time);
const std::string& current_test_name() { return current_test_name_; }
// Appends an error message to the log. // Appends an error message to the log.
void AppendError(const std::string& message); void AppendError(const std::string& message);
...@@ -150,6 +151,8 @@ pp::InstancePrivate { ...@@ -150,6 +151,8 @@ pp::InstancePrivate {
// Owning pointer to the current test case. Valid after Init has been called. // Owning pointer to the current test case. Valid after Init has been called.
TestCase* current_case_; TestCase* current_case_;
std::string current_test_name_;
// A filter to use when running tests. This is passed to 'RunTests', which // A filter to use when running tests. This is passed to 'RunTests', which
// runs only tests whose name contains test_filter_ as a substring. // runs only tests whose name contains test_filter_ as a substring.
std::string test_filter_; std::string test_filter_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment