Chromium Code Reviews

Side by Side Diff: ppapi/proxy/plugin_var_tracker_unittest.cc

Issue 6250024: Add a target for the proxy unittests. Write tests for the var tracker.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "ipc/ipc_test_sink.h"
6 #include "ppapi/proxy/plugin_var_tracker.h"
7 #include "ppapi/proxy/ppapi_messages.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9
10 namespace pp {
11 namespace proxy {
12
13 namespace {
14
15 PP_Var MakeObject(PluginVarTracker::VarID object_id) {
16 PP_Var ret;
17 ret.type = PP_VARTYPE_OBJECT;
18 ret.value.as_id = object_id;
19 return ret;
20 }
21
22 } // namespace
23
24 class PluginVarTrackerTest : public testing::Test {
25 public:
26 PluginVarTrackerTest() {}
27
28 protected:
29 // Asserts that there is a unique "release object" IPC message in the test
30 // sink. This will return the var ID from the message or -1 if none found.
31 PluginVarTracker::VarID GetObjectIDForUniqueReleaseObject() {
32 const IPC::Message* release_msg = sink_.GetUniqueMessageMatching(
33 PpapiHostMsg_PPBVar_ReleaseObject::ID);
34 if (!release_msg)
35 return -1;
36
37 Tuple1<int64> id;
38 PpapiHostMsg_PPBVar_ReleaseObject::Read(release_msg, &id);
39 return id.a;
40 }
41
42 PluginVarTracker tracker_;
43
44 IPC::TestSink sink_;
45 };
46
47 // Creates a PP_Var from the given string ID.
48 PP_Var MakeString(PluginVarTracker::VarID string_id) {
piman 2011/01/21 17:11:56 Move this to anonymous namespace ?
49 PP_Var ret;
50 ret.type = PP_VARTYPE_STRING;
51 ret.value.as_id = string_id;
52 return ret;
53 }
54
55 TEST_F(PluginVarTrackerTest, Strings) {
56 std::string str("Hello");
57 PluginVarTracker::VarID str_id1 = tracker_.MakeString(str);
58 EXPECT_NE(0, str_id1);
59
60 PluginVarTracker::VarID str_id2 = tracker_.MakeString(
61 str.c_str(), static_cast<uint32_t>(str.size()));
62 EXPECT_NE(0, str_id2);
63
64 // Make sure the strings come out the other end.
65 std::string result = tracker_.GetString(MakeString(str_id1));
66 EXPECT_EQ(str, result);
67 result = tracker_.GetString(MakeString(str_id2));
68 EXPECT_EQ(str, result);
69 }
70
71 TEST_F(PluginVarTrackerTest, GetHostObject) {
72 PP_Var host_object = MakeObject(12345);
73
74 // Round-trip through the tracker to make sure the host object comes out the
75 // other end.
76 PP_Var plugin_object = tracker_.ReceiveObjectPassRef(host_object, &sink_);
77 PP_Var host_object2 = tracker_.GetHostObject(plugin_object);
78 EXPECT_EQ(PP_VARTYPE_OBJECT, host_object2.type);
79 EXPECT_EQ(host_object.value.as_id, host_object2.value.as_id);
80
81 tracker_.Release(plugin_object);
82 }
83
84 TEST_F(PluginVarTrackerTest, ReceiveObjectPassRef) {
85 PP_Var host_object = MakeObject(12345);
86
87 // Receive the object, we should have one ref and no messages.
88 PP_Var plugin_object = tracker_.ReceiveObjectPassRef(host_object, &sink_);
89 EXPECT_EQ(0u, sink_.message_count());
90 EXPECT_EQ(1, tracker_.GetRefCountForObject(plugin_object));
91 EXPECT_EQ(0,
92 tracker_.GetTrackedWithNoReferenceCountForObject(plugin_object));
93
94 // Receive the same object again, we should get the same plugin ID out.
95 PP_Var plugin_object2 = tracker_.ReceiveObjectPassRef(host_object, &sink_);
96 EXPECT_EQ(plugin_object.value.as_id, plugin_object2.value.as_id);
97 EXPECT_EQ(2, tracker_.GetRefCountForObject(plugin_object));
98 EXPECT_EQ(0,
99 tracker_.GetTrackedWithNoReferenceCountForObject(plugin_object));
100
101 // It should have sent one message to decerment the refcount in the host.
102 // This is because it only maintains one host refcount for all references
103 // in the plugin, but the host just sent the second one.
104 EXPECT_EQ(host_object.value.as_id, GetObjectIDForUniqueReleaseObject());
105 sink_.ClearMessages();
106
107 // Release the object, one ref at a time. The second release should free
108 // the tracking data and send a release message to the browser.
109 tracker_.Release(plugin_object);
110 EXPECT_EQ(1, tracker_.GetRefCountForObject(plugin_object));
111 tracker_.Release(plugin_object);
112 EXPECT_EQ(-1, tracker_.GetRefCountForObject(plugin_object));
113 EXPECT_EQ(host_object.value.as_id, GetObjectIDForUniqueReleaseObject());
114 }
115
116 // Tests freeing objects that have both refcounts and "tracked with no ref".
117 TEST_F(PluginVarTrackerTest, FreeTrackedAndReferencedObject) {
118 PP_Var host_object = MakeObject(12345);
119
120 // Phase one: First receive via a "pass ref", then a tracked with no ref.
121 PP_Var plugin_var = tracker_.ReceiveObjectPassRef(host_object, &sink_);
122 PP_Var plugin_var2 = tracker_.TrackObjectWithNoReference(host_object, &sink_);
123 EXPECT_EQ(plugin_var.value.as_id, plugin_var2.value.as_id);
124 EXPECT_EQ(1, tracker_.GetRefCountForObject(plugin_var));
125 EXPECT_EQ(1, tracker_.GetTrackedWithNoReferenceCountForObject(plugin_var));
126
127 // Free via the refcount, this should release the object to the browser but
128 // maintain the tracked object.
129 tracker_.Release(plugin_var);
130 EXPECT_EQ(0, tracker_.GetRefCountForObject(plugin_var));
131 EXPECT_EQ(1u, sink_.message_count());
132 EXPECT_EQ(host_object.value.as_id, GetObjectIDForUniqueReleaseObject());
133
134 // Now free via the tracked object, this should free it.
135 tracker_.StopTrackingObjectWithNoReference(plugin_var);
136 EXPECT_EQ(-1, tracker_.GetRefCountForObject(plugin_var));
137
138 // Phase two: Receive via a tracked, then get an addref.
139 sink_.ClearMessages();
140 plugin_var = tracker_.TrackObjectWithNoReference(host_object, &sink_);
141 plugin_var2 = tracker_.ReceiveObjectPassRef(host_object, &sink_);
142 EXPECT_EQ(plugin_var.value.as_id, plugin_var2.value.as_id);
143 EXPECT_EQ(1, tracker_.GetRefCountForObject(plugin_var));
144 EXPECT_EQ(1, tracker_.GetTrackedWithNoReferenceCountForObject(plugin_var));
145
146 // Free via the tracked object, this should have no effect.
147 tracker_.StopTrackingObjectWithNoReference(plugin_var);
148 EXPECT_EQ(0, tracker_.GetTrackedWithNoReferenceCountForObject(plugin_var));
149 EXPECT_EQ(0u, sink_.message_count());
150
151 // Now free via the refcount, this should delete it.
152 tracker_.Release(plugin_var);
153 EXPECT_EQ(-1, tracker_.GetRefCountForObject(plugin_var));
154 EXPECT_EQ(host_object.value.as_id, GetObjectIDForUniqueReleaseObject());
155 }
156
157 TEST_F(PluginVarTrackerTest, RecursiveTrackWithNoRef) {
158 PP_Var host_object = MakeObject(12345);
159
160 // Receive a tracked object twice.
161 PP_Var plugin_var = tracker_.TrackObjectWithNoReference(host_object, &sink_);
162 EXPECT_EQ(1, tracker_.GetTrackedWithNoReferenceCountForObject(plugin_var));
163 PP_Var plugin_var2 = tracker_.TrackObjectWithNoReference(host_object, &sink_);
164 EXPECT_EQ(plugin_var.value.as_id, plugin_var2.value.as_id);
165 EXPECT_EQ(0, tracker_.GetRefCountForObject(plugin_var));
166 EXPECT_EQ(2, tracker_.GetTrackedWithNoReferenceCountForObject(plugin_var));
167
168 // Now release those tracked items, the reference should be freed.
169 tracker_.StopTrackingObjectWithNoReference(plugin_var);
170 EXPECT_EQ(1, tracker_.GetTrackedWithNoReferenceCountForObject(plugin_var));
171 tracker_.StopTrackingObjectWithNoReference(plugin_var);
172 EXPECT_EQ(-1, tracker_.GetTrackedWithNoReferenceCountForObject(plugin_var));
173 }
174
175 } // namespace proxy
176 } // namespace pp
OLDNEW

Powered by Google App Engine