diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-01 18:13:54 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-01 18:13:54 +0000 |
commit | 7d6fd8a472c86db1fd55be5bad2e4e08273c0a02 (patch) | |
tree | 558616f768289c9713c2c23fc8846579f219b0ac | |
parent | b411b2d6df0467d947f29c65bed83cbeb2a17384 (diff) | |
download | chromium_src-7d6fd8a472c86db1fd55be5bad2e4e08273c0a02.zip chromium_src-7d6fd8a472c86db1fd55be5bad2e4e08273c0a02.tar.gz chromium_src-7d6fd8a472c86db1fd55be5bad2e4e08273c0a02.tar.bz2 |
Add additional unit tests for the plugin side of SerializedVar object proxying.
TEST=is this
BUG=none
Review URL: http://codereview.chromium.org/7537015
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@94936 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ppapi/proxy/serialized_var.cc | 14 | ||||
-rw-r--r-- | ppapi/proxy/serialized_var.h | 8 | ||||
-rw-r--r-- | ppapi/proxy/serialized_var_unittest.cc | 119 |
3 files changed, 136 insertions, 5 deletions
diff --git a/ppapi/proxy/serialized_var.cc b/ppapi/proxy/serialized_var.cc index 786cc9e..ffae1b8 100644 --- a/ppapi/proxy/serialized_var.cc +++ b/ppapi/proxy/serialized_var.cc @@ -96,6 +96,14 @@ std::string* SerializedVar::Inner::GetStringPtr() { return &string_value_; } +void SerializedVar::Inner::ForceSetVarValueForTest(PP_Var value) { + var_ = value; +} + +void SerializedVar::Inner::ForceSetStringValueForTest(const std::string& str) { + string_value_ = str; +} + void SerializedVar::Inner::WriteToMessage(IPC::Message* m) const { // When writing to the IPC messages, a serization rules handler should // always have been set. @@ -515,7 +523,7 @@ PP_Var** SerializedVarVectorOutParam::ArrayOutParam(Dispatcher* dispatcher) { SerializedVarTestConstructor::SerializedVarTestConstructor( const PP_Var& pod_var) { DCHECK(pod_var.type != PP_VARTYPE_STRING); - inner_->SetVar(pod_var); + inner_->ForceSetVarValueForTest(pod_var); } SerializedVarTestConstructor::SerializedVarTestConstructor( @@ -523,8 +531,8 @@ SerializedVarTestConstructor::SerializedVarTestConstructor( PP_Var string_var = {}; string_var.type = PP_VARTYPE_STRING; string_var.value.as_id = 0; - inner_->SetVar(string_var); - *inner_->GetStringPtr() = str; + inner_->ForceSetVarValueForTest(string_var); + inner_->ForceSetStringValueForTest(str); } SerializedVarTestReader::SerializedVarTestReader(const SerializedVar& var) diff --git a/ppapi/proxy/serialized_var.h b/ppapi/proxy/serialized_var.h index 3f74a28..84168d7 100644 --- a/ppapi/proxy/serialized_var.h +++ b/ppapi/proxy/serialized_var.h @@ -103,6 +103,11 @@ class SerializedVar { const std::string& GetString() const; std::string* GetStringPtr(); + // For the SerializedVarTestConstructor, this writes the Var value as if + // it was just received off the wire, without any serialization rules. + void ForceSetVarValueForTest(PP_Var value); + void ForceSetStringValueForTest(const std::string& str); + void WriteToMessage(IPC::Message* m) const; bool ReadFromMessage(const IPC::Message* m, void** iter); @@ -425,7 +430,8 @@ class SerializedVarVectorOutParam { }; // For tests that just want to construct a SerializedVar for giving it to one -// of the other classes. +// of the other classes. This emulates a SerializedVar just received over the +// wire from another process. class SerializedVarTestConstructor : public SerializedVar { public: // For POD-types and objects. diff --git a/ppapi/proxy/serialized_var_unittest.cc b/ppapi/proxy/serialized_var_unittest.cc index 3cc4e61..e67617b 100644 --- a/ppapi/proxy/serialized_var_unittest.cc +++ b/ppapi/proxy/serialized_var_unittest.cc @@ -32,7 +32,8 @@ class SerializedVarTest : public PluginProxyTest { } // namespace -// Tests output arguments. +// Tests output arguments in the plugin. This is when the host calls into the +// plugin and the plugin returns something via an out param, like an exception. TEST_F(SerializedVarTest, PluginSerializedVarOutParam) { PP_Var host_object = MakeObjectVar(0x31337); @@ -70,5 +71,121 @@ TEST_F(SerializedVarTest, PluginSerializedVarOutParam) { // PluginVarTracker test has cases that cover that this message is correct. } +// Tests the case that the plugin receives the same var twice as an input +// parameter (not passing ownership). +TEST_F(SerializedVarTest, PluginReceiveInput) { + PP_Var host_object = MakeObjectVar(0x31337); + + PP_Var plugin_object; + { + // Receive the first param, we should be tracking it with no refcount, and + // no messages sent. + SerializedVarTestConstructor input1(host_object); + SerializedVarReceiveInput receive_input(input1); + plugin_object = receive_input.Get(plugin_dispatcher()); + EXPECT_EQ(0, var_tracker().GetRefCountForObject(plugin_object)); + EXPECT_EQ(0u, sink().message_count()); + + // Receive the second param, it should be resolved to the same plugin + // object and there should still be no refcount. + SerializedVarTestConstructor input2(host_object); + SerializedVarReceiveInput receive_input2(input2); + PP_Var plugin_object2 = receive_input2.Get(plugin_dispatcher()); + EXPECT_EQ(plugin_object.value.as_id, plugin_object2.value.as_id); + EXPECT_EQ(0, var_tracker().GetRefCountForObject(plugin_object)); + EXPECT_EQ(0u, sink().message_count()); + + // Take a reference to the object, as if the plugin was using it, and then + // release it, we should still be tracking the object since the + // ReceiveInputs keep the "track_with_no_reference_count" alive until + // they're destroyed. + var_tracker().AddRef(plugin_object); + EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object)); + var_tracker().Release(plugin_object); + EXPECT_EQ(0, var_tracker().GetRefCountForObject(plugin_object)); + EXPECT_EQ(2u, sink().message_count()); + } + + // Since we didn't keep any refs to the objects, it should have freed the + // object. + EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_object)); +} + +// Tests the plugin receiving a var as a return value from the browser +// two different times (passing ownership). +TEST_F(SerializedVarTest, PluginReceiveReturn) { + PP_Var host_object = MakeObjectVar(0x31337); + + PP_Var plugin_object; + { + // Receive the first param, we should be tracking it with a refcount of 1. + SerializedVarTestConstructor input1(host_object); + ReceiveSerializedVarReturnValue receive_input(input1); + plugin_object = receive_input.Return(plugin_dispatcher()); + EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object)); + EXPECT_EQ(0u, sink().message_count()); + + // Receive the second param, it should be resolved to the same plugin + // object and there should be a plugin refcount of 2. There should have + // been an IPC message sent that released the duplicated ref in the browser + // (so both of our refs are represented by one in the browser). + SerializedVarTestConstructor input2(host_object); + ReceiveSerializedVarReturnValue receive_input2(input2); + PP_Var plugin_object2 = receive_input2.Return(plugin_dispatcher()); + EXPECT_EQ(plugin_object.value.as_id, plugin_object2.value.as_id); + EXPECT_EQ(2, var_tracker().GetRefCountForObject(plugin_object)); + EXPECT_EQ(1u, sink().message_count()); + } + + // The ReceiveSerializedVarReturnValue destructor shouldn't have affected + // the refcount or sent any messages. + EXPECT_EQ(2, var_tracker().GetRefCountForObject(plugin_object)); + EXPECT_EQ(1u, sink().message_count()); + + // Manually release one refcount, it shouldn't have sent any more messages. + var_tracker().Release(plugin_object); + EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object)); + EXPECT_EQ(1u, sink().message_count()); + + // Manually release the last refcount, it should have freed it and sent a + // release message to the browser. + var_tracker().Release(plugin_object); + EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_object)); + EXPECT_EQ(2u, sink().message_count()); +} + +// Returns a value from the browser to the plugin, then return that one ref +// back to the browser. +TEST_F(SerializedVarTest, PluginReturnValue) { + PP_Var host_object = MakeObjectVar(0x31337); + + PP_Var plugin_object; + { + // Receive the param in the plugin. + SerializedVarTestConstructor input1(host_object); + ReceiveSerializedVarReturnValue receive_input(input1); + plugin_object = receive_input.Return(plugin_dispatcher()); + EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object)); + EXPECT_EQ(0u, sink().message_count()); + } + + { + // Now return to the browser. + SerializedVar output; + SerializedVarReturnValue return_output(&output); + return_output.Return(plugin_dispatcher(), plugin_object); + + // The ref in the plugin should be alive until the ReturnValue goes out of + // scope, since the release needs to be after the browser processes the + // message. + EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object)); + } + + // When the ReturnValue object goes out of scope, it should have sent a + // release message to the browser. + EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_object)); + EXPECT_EQ(1u, sink().message_count()); +} + } // namespace proxy } // namespace pp |