summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-01 18:13:54 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-01 18:13:54 +0000
commit7d6fd8a472c86db1fd55be5bad2e4e08273c0a02 (patch)
tree558616f768289c9713c2c23fc8846579f219b0ac
parentb411b2d6df0467d947f29c65bed83cbeb2a17384 (diff)
downloadchromium_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.cc14
-rw-r--r--ppapi/proxy/serialized_var.h8
-rw-r--r--ppapi/proxy/serialized_var_unittest.cc119
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