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

Side by Side Diff: content/browser/plugin_loader_posix_unittest.cc

Issue 8318028: Gracefully handle child process death in out-of-process plugin loading. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase, use sync messages. Created 9 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 | Annotate | Revision Log
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 "content/browser/plugin_loader_posix.h"
6
7 #include "base/bind.h"
8 #include "base/file_path.h"
9 #include "base/message_loop.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/utf_string_conversions.h"
12 #include "content/browser/browser_thread.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "webkit/plugins/webplugininfo.h"
16
17 class MockPluginLoaderPosix : public PluginLoaderPosix {
18 public:
19 MOCK_METHOD0(LoadPluginsInternal, void(void));
20
21 size_t number_of_pending_callbacks() {
22 return callbacks_.size();
23 }
24
25 std::vector<FilePath>* canonical_list() {
26 return &canonical_list_;
27 }
28
29 size_t next_load_index() {
30 return next_load_index_;
31 }
32
33 const std::vector<webkit::WebPluginInfo>& loaded_plugins() {
34 return loaded_plugins_;
35 }
36
37 std::vector<webkit::WebPluginInfo>* internal_plugins() {
38 return &internal_plugins_;
39 }
40
41 void TestOnPluginLoaded(size_t index, const webkit::WebPluginInfo& plugin) {
42 OnPluginLoaded(index, plugin);
43 }
44
45 void TestOnPluginLoadFailed(size_t index, const FilePath& path) {
46 OnPluginLoadFailed(index, path);
47 }
48 };
49
50 void VerifyCallback(int* run_count, const std::vector<webkit::WebPluginInfo>&) {
51 ++(*run_count);
52 }
53
54 class PluginLoaderPosixTest : public testing::Test {
55 public:
56 PluginLoaderPosixTest()
57 : plugin1_(ASCIIToUTF16("plugin1"), FilePath("/tmp/one.plugin"),
58 ASCIIToUTF16("1.0"), string16()),
59 plugin2_(ASCIIToUTF16("plugin2"), FilePath("/tmp/two.plugin"),
60 ASCIIToUTF16("2.0"), string16()),
61 plugin3_(ASCIIToUTF16("plugin3"), FilePath("/tmp/three.plugin"),
62 ASCIIToUTF16("3.0"), string16()),
63 file_thread_(BrowserThread::FILE, &message_loop_),
64 io_thread_(BrowserThread::IO, &message_loop_),
65 plugin_loader_(new MockPluginLoaderPosix) {
66 }
67
68 MessageLoop* message_loop() { return &message_loop_; }
69 MockPluginLoaderPosix* plugin_loader() { return plugin_loader_.get(); }
70
71 void AddThreePlugins() {
72 plugin_loader_->canonical_list()->clear();
73 plugin_loader_->canonical_list()->push_back(plugin1_.path);
74 plugin_loader_->canonical_list()->push_back(plugin2_.path);
75 plugin_loader_->canonical_list()->push_back(plugin3_.path);
76 }
77
78 // Data used for testing.
79 webkit::WebPluginInfo plugin1_;
80 webkit::WebPluginInfo plugin2_;
81 webkit::WebPluginInfo plugin3_;
82
83 private:
84 MessageLoopForIO message_loop_;
85 BrowserThread file_thread_;
86 BrowserThread io_thread_;
87
88 scoped_refptr<MockPluginLoaderPosix> plugin_loader_;
89 };
90
91 TEST_F(PluginLoaderPosixTest, QueueRequests) {
92 int did_callback = 0;
93 PluginService::GetPluginsCallback callback =
94 base::Bind(&VerifyCallback, base::Unretained(&did_callback));
95
96 EXPECT_EQ(0u, plugin_loader()->number_of_pending_callbacks());
97 plugin_loader()->LoadPlugins(message_loop()->message_loop_proxy(), callback);
98 EXPECT_EQ(1u, plugin_loader()->number_of_pending_callbacks());
99
100 plugin_loader()->LoadPlugins(message_loop()->message_loop_proxy(), callback);
101 EXPECT_EQ(2u, plugin_loader()->number_of_pending_callbacks());
102
103 EXPECT_CALL(*plugin_loader(), LoadPluginsInternal()).Times(1);
104 message_loop()->RunAllPending();
105
106 plugin_loader()->canonical_list()->clear();
107 plugin_loader()->canonical_list()->push_back(plugin1_.path);
108
109 EXPECT_EQ(0, did_callback);
110
111 plugin_loader()->TestOnPluginLoaded(0, plugin1_);
112 message_loop()->RunAllPending();
113
114 EXPECT_EQ(2, did_callback);
115 EXPECT_EQ(0u, plugin_loader()->number_of_pending_callbacks());
116 }
117
118 TEST_F(PluginLoaderPosixTest, ThreeSuccessfulLoads) {
119 int did_callback = 0;
120 PluginService::GetPluginsCallback callback =
121 base::Bind(&VerifyCallback, base::Unretained(&did_callback));
122
123 plugin_loader()->LoadPlugins(message_loop()->message_loop_proxy(), callback);
124
125 EXPECT_CALL(*plugin_loader(), LoadPluginsInternal()).Times(1);
126 message_loop()->RunAllPending();
127
128 AddThreePlugins();
129
130 EXPECT_EQ(0u, plugin_loader()->next_load_index());
131
132 const std::vector<webkit::WebPluginInfo>& plugins(
133 plugin_loader()->loaded_plugins());
134
135 plugin_loader()->TestOnPluginLoaded(0, plugin1_);
136 EXPECT_EQ(1u, plugin_loader()->next_load_index());
137 EXPECT_EQ(1u, plugins.size());
138 EXPECT_EQ(plugin1_.name, plugins[0].name);
139
140 message_loop()->RunAllPending();
141 EXPECT_EQ(0, did_callback);
142
143 plugin_loader()->TestOnPluginLoaded(1, plugin2_);
144 EXPECT_EQ(2u, plugin_loader()->next_load_index());
145 EXPECT_EQ(2u, plugins.size());
146 EXPECT_EQ(plugin2_.name, plugins[1].name);
147
148 message_loop()->RunAllPending();
149 EXPECT_EQ(0, did_callback);
150
151 plugin_loader()->TestOnPluginLoaded(2, plugin3_);
152 EXPECT_EQ(3u, plugins.size());
153 EXPECT_EQ(plugin3_.name, plugins[2].name);
154
155 message_loop()->RunAllPending();
156 EXPECT_EQ(1, did_callback);
157 }
158
159 TEST_F(PluginLoaderPosixTest, TwoFailures) {
160 int did_callback = 0;
161 PluginService::GetPluginsCallback callback =
162 base::Bind(&VerifyCallback, base::Unretained(&did_callback));
163
164 plugin_loader()->LoadPlugins(message_loop()->message_loop_proxy(), callback);
165
166 EXPECT_CALL(*plugin_loader(), LoadPluginsInternal()).Times(1);
167 message_loop()->RunAllPending();
168
169 AddThreePlugins();
170
171 EXPECT_EQ(0u, plugin_loader()->next_load_index());
172
173 const std::vector<webkit::WebPluginInfo>& plugins(
174 plugin_loader()->loaded_plugins());
175
176 plugin_loader()->TestOnPluginLoadFailed(0, plugin1_.path);
177 EXPECT_EQ(1u, plugin_loader()->next_load_index());
178 EXPECT_EQ(0u, plugins.size());
179
180 message_loop()->RunAllPending();
181 EXPECT_EQ(0, did_callback);
182
183 plugin_loader()->TestOnPluginLoaded(1, plugin2_);
184 EXPECT_EQ(2u, plugin_loader()->next_load_index());
185 EXPECT_EQ(1u, plugins.size());
186 EXPECT_EQ(plugin2_.name, plugins[0].name);
187
188 message_loop()->RunAllPending();
189 EXPECT_EQ(0, did_callback);
190
191 plugin_loader()->TestOnPluginLoadFailed(2, plugin3_.path);
192 EXPECT_EQ(1u, plugins.size());
193
194 message_loop()->RunAllPending();
195 EXPECT_EQ(1, did_callback);
196 }
197
198 TEST_F(PluginLoaderPosixTest, CrashedProcess) {
199 int did_callback = 0;
200 PluginService::GetPluginsCallback callback =
201 base::Bind(&VerifyCallback, base::Unretained(&did_callback));
202
203 plugin_loader()->LoadPlugins(message_loop()->message_loop_proxy(), callback);
204
205 EXPECT_CALL(*plugin_loader(), LoadPluginsInternal()).Times(1);
206 message_loop()->RunAllPending();
207
208 AddThreePlugins();
209
210 EXPECT_EQ(0u, plugin_loader()->next_load_index());
211
212 const std::vector<webkit::WebPluginInfo>& plugins(
213 plugin_loader()->loaded_plugins());
214
215 plugin_loader()->TestOnPluginLoaded(0, plugin1_);
216 EXPECT_EQ(1u, plugin_loader()->next_load_index());
217 EXPECT_EQ(1u, plugins.size());
218 EXPECT_EQ(plugin1_.name, plugins[0].name);
219
220 message_loop()->RunAllPending();
221 EXPECT_EQ(0, did_callback);
222
223 EXPECT_CALL(*plugin_loader(), LoadPluginsInternal()).Times(1);
224 plugin_loader()->OnProcessCrashed(42);
225 EXPECT_EQ(1u, plugin_loader()->canonical_list()->size());
226 EXPECT_EQ(0u, plugin_loader()->next_load_index());
227 EXPECT_EQ(plugin3_.path.value(),
228 plugin_loader()->canonical_list()->at(0).value());
229 }
230
231 TEST_F(PluginLoaderPosixTest, InternalPlugin) {
232 int did_callback = 0;
233 PluginService::GetPluginsCallback callback =
234 base::Bind(&VerifyCallback, base::Unretained(&did_callback));
235
236 plugin_loader()->LoadPlugins(message_loop()->message_loop_proxy(), callback);
237
238 EXPECT_CALL(*plugin_loader(), LoadPluginsInternal()).Times(1);
239 message_loop()->RunAllPending();
240
241 plugin2_.path = FilePath("/internal/plugin.plugin");
242
243 AddThreePlugins();
244
245 plugin_loader()->internal_plugins()->clear();
246 plugin_loader()->internal_plugins()->push_back(plugin2_);
247
248 EXPECT_EQ(0u, plugin_loader()->next_load_index());
249
250 const std::vector<webkit::WebPluginInfo>& plugins(
251 plugin_loader()->loaded_plugins());
252
253 plugin_loader()->TestOnPluginLoaded(0, plugin1_);
254 EXPECT_EQ(1u, plugin_loader()->next_load_index());
255 EXPECT_EQ(1u, plugins.size());
256 EXPECT_EQ(plugin1_.name, plugins[0].name);
257
258 message_loop()->RunAllPending();
259 EXPECT_EQ(0, did_callback);
260
261 // Internal plugins can fail to load if they're built-in with manual
262 // entrypoint functions.
263 plugin_loader()->TestOnPluginLoadFailed(1, plugin2_.path);
264 EXPECT_EQ(2u, plugin_loader()->next_load_index());
265 EXPECT_EQ(2u, plugins.size());
266 EXPECT_EQ(plugin2_.name, plugins[1].name);
267 EXPECT_EQ(0u, plugin_loader()->internal_plugins()->size());
268
269 message_loop()->RunAllPending();
270 EXPECT_EQ(0, did_callback);
271
272 plugin_loader()->TestOnPluginLoaded(2, plugin3_);
273 EXPECT_EQ(3u, plugins.size());
274 EXPECT_EQ(plugin3_.name, plugins[2].name);
275
276 message_loop()->RunAllPending();
277 EXPECT_EQ(1, did_callback);
278 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698