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

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

Issue 1862513003: Remove NPAPI from browser and utility (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 8 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
« no previous file with comments | « content/browser/plugin_loader_posix.cc ('k') | content/browser/plugin_process_host.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 <stddef.h>
8 #include <stdint.h>
9
10 #include "base/at_exit.h"
11 #include "base/bind.h"
12 #include "base/files/file_path.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/message_loop/message_loop.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "content/browser/browser_thread_impl.h"
17 #include "content/common/plugin_list.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 using base::ASCIIToUTF16;
22
23 namespace content {
24
25 class MockPluginLoaderPosix : public PluginLoaderPosix {
26 public:
27 MOCK_METHOD0(LoadPluginsInternal, void(void));
28
29 size_t number_of_pending_callbacks() {
30 return callbacks_.size();
31 }
32
33 std::vector<base::FilePath>* canonical_list() {
34 return &canonical_list_;
35 }
36
37 size_t next_load_index() {
38 return next_load_index_;
39 }
40
41 const std::vector<WebPluginInfo>& loaded_plugins() {
42 return loaded_plugins_;
43 }
44
45 std::vector<WebPluginInfo>* internal_plugins() {
46 return &internal_plugins_;
47 }
48
49 void RealLoadPluginsInternal() {
50 PluginLoaderPosix::LoadPluginsInternal();
51 }
52
53 bool LaunchUtilityProcess() override {
54 // This method always does nothing and returns false. The actual
55 // implementation of this method launches another process, which is not
56 // very unit_test friendly.
57 return false;
58 }
59
60 void TestOnPluginLoaded(uint32_t index, const WebPluginInfo& plugin) {
61 OnPluginLoaded(index, plugin);
62 }
63
64 void TestOnPluginLoadFailed(uint32_t index, const base::FilePath& path) {
65 OnPluginLoadFailed(index, path);
66 }
67
68 protected:
69 virtual ~MockPluginLoaderPosix() {}
70 };
71
72 void VerifyCallback(int* run_count, const std::vector<WebPluginInfo>&) {
73 ++(*run_count);
74 }
75
76 class PluginLoaderPosixTest : public testing::Test {
77 public:
78 PluginLoaderPosixTest()
79 : plugin1_(ASCIIToUTF16("plugin1"), base::FilePath("/tmp/one.plugin"),
80 ASCIIToUTF16("1.0"), base::string16()),
81 plugin2_(ASCIIToUTF16("plugin2"), base::FilePath("/tmp/two.plugin"),
82 ASCIIToUTF16("2.0"), base::string16()),
83 plugin3_(ASCIIToUTF16("plugin3"), base::FilePath("/tmp/three.plugin"),
84 ASCIIToUTF16("3.0"), base::string16()),
85 file_thread_(BrowserThread::FILE, &message_loop_),
86 io_thread_(BrowserThread::IO, &message_loop_),
87 plugin_loader_(new MockPluginLoaderPosix) {
88 }
89
90 void SetUp() override { PluginServiceImpl::GetInstance()->Init(); }
91
92 base::MessageLoop* message_loop() { return &message_loop_; }
93 MockPluginLoaderPosix* plugin_loader() { return plugin_loader_.get(); }
94
95 void AddThreePlugins() {
96 plugin_loader_->canonical_list()->clear();
97 plugin_loader_->canonical_list()->push_back(plugin1_.path);
98 plugin_loader_->canonical_list()->push_back(plugin2_.path);
99 plugin_loader_->canonical_list()->push_back(plugin3_.path);
100 }
101
102 // Data used for testing.
103 WebPluginInfo plugin1_;
104 WebPluginInfo plugin2_;
105 WebPluginInfo plugin3_;
106
107 private:
108 // Destroys PluginService and PluginList.
109 base::ShadowingAtExitManager at_exit_manager_;
110
111 base::MessageLoopForIO message_loop_;
112 BrowserThreadImpl file_thread_;
113 BrowserThreadImpl io_thread_;
114
115 scoped_refptr<MockPluginLoaderPosix> plugin_loader_;
116 };
117
118 TEST_F(PluginLoaderPosixTest, QueueRequests) {
119 int did_callback = 0;
120 PluginService::GetPluginsCallback callback =
121 base::Bind(&VerifyCallback, base::Unretained(&did_callback));
122
123 plugin_loader()->GetPlugins(callback);
124 plugin_loader()->GetPlugins(callback);
125
126 EXPECT_CALL(*plugin_loader(), LoadPluginsInternal()).Times(1);
127 message_loop()->RunUntilIdle();
128
129 EXPECT_EQ(0, did_callback);
130
131 plugin_loader()->canonical_list()->clear();
132 plugin_loader()->canonical_list()->push_back(plugin1_.path);
133 plugin_loader()->TestOnPluginLoaded(0, plugin1_);
134 message_loop()->RunUntilIdle();
135
136 EXPECT_EQ(2, did_callback);
137 }
138
139 TEST_F(PluginLoaderPosixTest, QueueRequestsAndInvalidate) {
140 int did_callback = 0;
141 PluginService::GetPluginsCallback callback =
142 base::Bind(&VerifyCallback, base::Unretained(&did_callback));
143
144 plugin_loader()->GetPlugins(callback);
145
146 EXPECT_CALL(*plugin_loader(), LoadPluginsInternal()).Times(1);
147 message_loop()->RunUntilIdle();
148
149 EXPECT_EQ(0, did_callback);
150 ::testing::Mock::VerifyAndClearExpectations(plugin_loader());
151
152 // Invalidate the plugin list, then queue up another request.
153 PluginList::Singleton()->RefreshPlugins();
154 plugin_loader()->GetPlugins(callback);
155
156 EXPECT_CALL(*plugin_loader(), LoadPluginsInternal()).Times(1);
157
158 plugin_loader()->canonical_list()->clear();
159 plugin_loader()->canonical_list()->push_back(plugin1_.path);
160 plugin_loader()->TestOnPluginLoaded(0, plugin1_);
161 message_loop()->RunUntilIdle();
162
163 // Only the first request should have been fulfilled.
164 EXPECT_EQ(1, did_callback);
165
166 plugin_loader()->canonical_list()->clear();
167 plugin_loader()->canonical_list()->push_back(plugin1_.path);
168 plugin_loader()->TestOnPluginLoaded(0, plugin1_);
169 message_loop()->RunUntilIdle();
170
171 EXPECT_EQ(2, did_callback);
172 }
173
174 TEST_F(PluginLoaderPosixTest, ThreeSuccessfulLoads) {
175 int did_callback = 0;
176 PluginService::GetPluginsCallback callback =
177 base::Bind(&VerifyCallback, base::Unretained(&did_callback));
178
179 plugin_loader()->GetPlugins(callback);
180
181 EXPECT_CALL(*plugin_loader(), LoadPluginsInternal()).Times(1);
182 message_loop()->RunUntilIdle();
183
184 AddThreePlugins();
185
186 EXPECT_EQ(0u, plugin_loader()->next_load_index());
187
188 const std::vector<WebPluginInfo>& plugins(plugin_loader()->loaded_plugins());
189
190 plugin_loader()->TestOnPluginLoaded(0, plugin1_);
191 EXPECT_EQ(1u, plugin_loader()->next_load_index());
192 EXPECT_EQ(1u, plugins.size());
193 EXPECT_EQ(plugin1_.name, plugins[0].name);
194
195 message_loop()->RunUntilIdle();
196 EXPECT_EQ(0, did_callback);
197
198 plugin_loader()->TestOnPluginLoaded(1, plugin2_);
199 EXPECT_EQ(2u, plugin_loader()->next_load_index());
200 EXPECT_EQ(2u, plugins.size());
201 EXPECT_EQ(plugin2_.name, plugins[1].name);
202
203 message_loop()->RunUntilIdle();
204 EXPECT_EQ(0, did_callback);
205
206 plugin_loader()->TestOnPluginLoaded(2, plugin3_);
207 EXPECT_EQ(3u, plugins.size());
208 EXPECT_EQ(plugin3_.name, plugins[2].name);
209
210 message_loop()->RunUntilIdle();
211 EXPECT_EQ(1, did_callback);
212 }
213
214 TEST_F(PluginLoaderPosixTest, ThreeSuccessfulLoadsThenCrash) {
215 int did_callback = 0;
216 PluginService::GetPluginsCallback callback =
217 base::Bind(&VerifyCallback, base::Unretained(&did_callback));
218
219 plugin_loader()->GetPlugins(callback);
220
221 EXPECT_CALL(*plugin_loader(), LoadPluginsInternal()).Times(2);
222 message_loop()->RunUntilIdle();
223
224 AddThreePlugins();
225
226 EXPECT_EQ(0u, plugin_loader()->next_load_index());
227
228 const std::vector<WebPluginInfo>& plugins(plugin_loader()->loaded_plugins());
229
230 plugin_loader()->TestOnPluginLoaded(0, plugin1_);
231 EXPECT_EQ(1u, plugin_loader()->next_load_index());
232 EXPECT_EQ(1u, plugins.size());
233 EXPECT_EQ(plugin1_.name, plugins[0].name);
234
235 message_loop()->RunUntilIdle();
236 EXPECT_EQ(0, did_callback);
237
238 plugin_loader()->TestOnPluginLoaded(1, plugin2_);
239 EXPECT_EQ(2u, plugin_loader()->next_load_index());
240 EXPECT_EQ(2u, plugins.size());
241 EXPECT_EQ(plugin2_.name, plugins[1].name);
242
243 message_loop()->RunUntilIdle();
244 EXPECT_EQ(0, did_callback);
245
246 plugin_loader()->TestOnPluginLoaded(2, plugin3_);
247 EXPECT_EQ(3u, plugins.size());
248 EXPECT_EQ(plugin3_.name, plugins[2].name);
249
250 message_loop()->RunUntilIdle();
251 EXPECT_EQ(1, did_callback);
252
253 plugin_loader()->OnProcessCrashed(42);
254 }
255
256 TEST_F(PluginLoaderPosixTest, TwoFailures) {
257 int did_callback = 0;
258 PluginService::GetPluginsCallback callback =
259 base::Bind(&VerifyCallback, base::Unretained(&did_callback));
260
261 plugin_loader()->GetPlugins(callback);
262
263 EXPECT_CALL(*plugin_loader(), LoadPluginsInternal()).Times(1);
264 message_loop()->RunUntilIdle();
265
266 AddThreePlugins();
267
268 EXPECT_EQ(0u, plugin_loader()->next_load_index());
269
270 const std::vector<WebPluginInfo>& plugins(plugin_loader()->loaded_plugins());
271
272 plugin_loader()->TestOnPluginLoadFailed(0, plugin1_.path);
273 EXPECT_EQ(1u, plugin_loader()->next_load_index());
274 EXPECT_EQ(0u, plugins.size());
275
276 message_loop()->RunUntilIdle();
277 EXPECT_EQ(0, did_callback);
278
279 plugin_loader()->TestOnPluginLoaded(1, plugin2_);
280 EXPECT_EQ(2u, plugin_loader()->next_load_index());
281 EXPECT_EQ(1u, plugins.size());
282 EXPECT_EQ(plugin2_.name, plugins[0].name);
283
284 message_loop()->RunUntilIdle();
285 EXPECT_EQ(0, did_callback);
286
287 plugin_loader()->TestOnPluginLoadFailed(2, plugin3_.path);
288 EXPECT_EQ(1u, plugins.size());
289
290 message_loop()->RunUntilIdle();
291 EXPECT_EQ(1, did_callback);
292 }
293
294 TEST_F(PluginLoaderPosixTest, CrashedProcess) {
295 int did_callback = 0;
296 PluginService::GetPluginsCallback callback =
297 base::Bind(&VerifyCallback, base::Unretained(&did_callback));
298
299 plugin_loader()->GetPlugins(callback);
300
301 EXPECT_CALL(*plugin_loader(), LoadPluginsInternal()).Times(1);
302 message_loop()->RunUntilIdle();
303
304 AddThreePlugins();
305
306 EXPECT_EQ(0u, plugin_loader()->next_load_index());
307
308 const std::vector<WebPluginInfo>& plugins(plugin_loader()->loaded_plugins());
309
310 plugin_loader()->TestOnPluginLoaded(0, plugin1_);
311 EXPECT_EQ(1u, plugin_loader()->next_load_index());
312 EXPECT_EQ(1u, plugins.size());
313 EXPECT_EQ(plugin1_.name, plugins[0].name);
314
315 message_loop()->RunUntilIdle();
316 EXPECT_EQ(0, did_callback);
317
318 EXPECT_CALL(*plugin_loader(), LoadPluginsInternal()).Times(1);
319 plugin_loader()->OnProcessCrashed(42);
320 EXPECT_EQ(1u, plugin_loader()->canonical_list()->size());
321 EXPECT_EQ(0u, plugin_loader()->next_load_index());
322 EXPECT_EQ(plugin3_.path.value(),
323 plugin_loader()->canonical_list()->at(0).value());
324 }
325
326 TEST_F(PluginLoaderPosixTest, InternalPlugin) {
327 int did_callback = 0;
328 PluginService::GetPluginsCallback callback =
329 base::Bind(&VerifyCallback, base::Unretained(&did_callback));
330
331 plugin_loader()->GetPlugins(callback);
332
333 EXPECT_CALL(*plugin_loader(), LoadPluginsInternal()).Times(1);
334 message_loop()->RunUntilIdle();
335
336 plugin2_.path = base::FilePath("/internal/plugin.plugin");
337
338 AddThreePlugins();
339
340 plugin_loader()->internal_plugins()->clear();
341 plugin_loader()->internal_plugins()->push_back(plugin2_);
342
343 EXPECT_EQ(0u, plugin_loader()->next_load_index());
344
345 const std::vector<WebPluginInfo>& plugins(plugin_loader()->loaded_plugins());
346
347 plugin_loader()->TestOnPluginLoaded(0, plugin1_);
348 EXPECT_EQ(1u, plugin_loader()->next_load_index());
349 EXPECT_EQ(1u, plugins.size());
350 EXPECT_EQ(plugin1_.name, plugins[0].name);
351
352 message_loop()->RunUntilIdle();
353 EXPECT_EQ(0, did_callback);
354
355 // Internal plugins can fail to load if they're built-in with manual
356 // entrypoint functions.
357 plugin_loader()->TestOnPluginLoadFailed(1, plugin2_.path);
358 EXPECT_EQ(2u, plugin_loader()->next_load_index());
359 EXPECT_EQ(2u, plugins.size());
360 EXPECT_EQ(plugin2_.name, plugins[1].name);
361 EXPECT_EQ(0u, plugin_loader()->internal_plugins()->size());
362
363 message_loop()->RunUntilIdle();
364 EXPECT_EQ(0, did_callback);
365
366 plugin_loader()->TestOnPluginLoaded(2, plugin3_);
367 EXPECT_EQ(3u, plugins.size());
368 EXPECT_EQ(plugin3_.name, plugins[2].name);
369
370 message_loop()->RunUntilIdle();
371 EXPECT_EQ(1, did_callback);
372 }
373
374 TEST_F(PluginLoaderPosixTest, AllCrashed) {
375 int did_callback = 0;
376 PluginService::GetPluginsCallback callback =
377 base::Bind(&VerifyCallback, base::Unretained(&did_callback));
378
379 plugin_loader()->GetPlugins(callback);
380
381 // Spin the loop so that the canonical list of plugins can be set.
382 EXPECT_CALL(*plugin_loader(), LoadPluginsInternal()).Times(1);
383 message_loop()->RunUntilIdle();
384 AddThreePlugins();
385
386 EXPECT_EQ(0u, plugin_loader()->next_load_index());
387
388 // Mock the first two calls like normal.
389 testing::Expectation first =
390 EXPECT_CALL(*plugin_loader(), LoadPluginsInternal()).Times(2);
391 // On the last call, go through the default impl.
392 EXPECT_CALL(*plugin_loader(), LoadPluginsInternal())
393 .After(first)
394 .WillOnce(
395 testing::Invoke(plugin_loader(),
396 &MockPluginLoaderPosix::RealLoadPluginsInternal));
397 plugin_loader()->OnProcessCrashed(42);
398 plugin_loader()->OnProcessCrashed(42);
399 plugin_loader()->OnProcessCrashed(42);
400
401 message_loop()->RunUntilIdle();
402 EXPECT_EQ(1, did_callback);
403
404 EXPECT_EQ(0u, plugin_loader()->loaded_plugins().size());
405 }
406
407 TEST_F(PluginLoaderPosixTest, PluginLaunchFailed) {
408 int did_callback = 0;
409 PluginService::GetPluginsCallback callback =
410 base::Bind(&VerifyCallback, base::Unretained(&did_callback));
411
412 EXPECT_CALL(*plugin_loader(), LoadPluginsInternal())
413 .WillOnce(testing::Invoke(
414 plugin_loader(), &MockPluginLoaderPosix::RealLoadPluginsInternal));
415
416 plugin_loader()->GetPlugins(callback);
417 message_loop()->RunUntilIdle();
418 EXPECT_EQ(1, did_callback);
419 EXPECT_EQ(0u, plugin_loader()->loaded_plugins().size());
420
421 // TODO(erikchen): This is a genuine leak that should be fixed.
422 // https://code.google.com/p/chromium/issues/detail?id=431906
423 testing::Mock::AllowLeak(plugin_loader());
424 }
425
426 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/plugin_loader_posix.cc ('k') | content/browser/plugin_process_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698