Apply _RELATIVE relocations ahead of others.
[chromium-blink-merge.git] / content / browser / plugin_browsertest.cc
bloba5ca6da74eae64a34cc7357821296a487641a9f7
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.
5 #include "base/command_line.h"
6 #include "base/files/file_util.h"
7 #include "base/path_service.h"
8 #include "base/strings/string_util.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "content/browser/loader/resource_dispatcher_host_impl.h"
11 #include "content/public/browser/browser_thread.h"
12 #include "content/public/browser/resource_dispatcher_host_delegate.h"
13 #include "content/public/common/content_switches.h"
14 #include "content/public/test/browser_test_utils.h"
15 #include "content/public/test/content_browser_test.h"
16 #include "content/public/test/content_browser_test_utils.h"
17 #include "content/public/test/test_utils.h"
18 #include "content/shell/browser/shell.h"
19 #include "content/shell/common/shell_switches.h"
20 #include "net/test/embedded_test_server/embedded_test_server.h"
21 #include "net/test/url_request/url_request_mock_http_job.h"
22 #include "net/url_request/url_request.h"
23 #include "ui/gfx/rect.h"
25 #if defined(OS_WIN)
26 #include "base/win/registry.h"
27 #endif
29 // TODO(jschuh): Finish plugins on Win64. crbug.com/180861
30 #if defined(OS_WIN) && defined(ARCH_CPU_X86_64)
31 #define MAYBE(x) DISABLED_##x
32 #else
33 #define MAYBE(x) x
34 #endif
36 using base::ASCIIToUTF16;
38 namespace content {
39 namespace {
41 void SetUrlRequestMock(const base::FilePath& path) {
42 net::URLRequestMockHTTPJob::AddUrlHandler(
43 path, content::BrowserThread::GetBlockingPool());
48 class PluginTest : public ContentBrowserTest {
49 protected:
50 PluginTest() {}
52 void SetUpCommandLine(CommandLine* command_line) override {
53 // Some NPAPI tests schedule garbage collection to force object tear-down.
54 command_line->AppendSwitchASCII(switches::kJavaScriptFlags, "--expose_gc");
56 #if defined(OS_WIN)
57 const testing::TestInfo* const test_info =
58 testing::UnitTest::GetInstance()->current_test_info();
59 if (strcmp(test_info->name(), "MediaPlayerNew") == 0) {
60 // The installer adds our process names to the registry key below. Since
61 // the installer might not have run on this machine, add it manually.
62 base::win::RegKey regkey;
63 if (regkey.Open(HKEY_LOCAL_MACHINE,
64 L"Software\\Microsoft\\MediaPlayer\\ShimInclusionList",
65 KEY_WRITE) == ERROR_SUCCESS) {
66 regkey.CreateKey(L"BROWSER_TESTS.EXE", KEY_READ);
69 #elif defined(OS_MACOSX)
70 base::FilePath plugin_dir;
71 PathService::Get(base::DIR_MODULE, &plugin_dir);
72 plugin_dir = plugin_dir.AppendASCII("plugins");
73 // The plugins directory isn't read by default on the Mac, so it needs to be
74 // explicitly registered.
75 command_line->AppendSwitchPath(switches::kExtraPluginDir, plugin_dir);
76 #endif
79 void SetUpOnMainThread() override {
80 base::FilePath path = GetTestFilePath("", "");
81 BrowserThread::PostTask(
82 BrowserThread::IO, FROM_HERE, base::Bind(&SetUrlRequestMock, path));
85 static void LoadAndWaitInWindow(Shell* window, const GURL& url) {
86 base::string16 expected_title(ASCIIToUTF16("OK"));
87 TitleWatcher title_watcher(window->web_contents(), expected_title);
88 title_watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
89 title_watcher.AlsoWaitForTitle(ASCIIToUTF16("plugin_not_found"));
90 NavigateToURL(window, url);
91 base::string16 title = title_watcher.WaitAndGetTitle();
92 if (title == ASCIIToUTF16("plugin_not_found")) {
93 const testing::TestInfo* const test_info =
94 testing::UnitTest::GetInstance()->current_test_info();
95 VLOG(0) << "PluginTest." << test_info->name()
96 << " not running because plugin not installed.";
97 } else {
98 EXPECT_EQ(expected_title, title);
102 void LoadAndWait(const GURL& url) {
103 LoadAndWaitInWindow(shell(), url);
106 GURL GetURL(const char* filename) {
107 return GetTestUrl("npapi", filename);
110 void NavigateAway() {
111 GURL url = GetTestUrl("", "simple_page.html");
112 LoadAndWait(url);
115 void TestPlugin(const char* filename) {
116 base::FilePath path = GetTestFilePath("plugin", filename);
117 if (!base::PathExists(path)) {
118 const testing::TestInfo* const test_info =
119 testing::UnitTest::GetInstance()->current_test_info();
120 VLOG(0) << "PluginTest." << test_info->name()
121 << " not running because test data wasn't found.";
122 return;
125 GURL url = GetTestUrl("plugin", filename);
126 LoadAndWait(url);
130 // Make sure that navigating away from a plugin referenced by JS doesn't
131 // crash.
132 IN_PROC_BROWSER_TEST_F(PluginTest, UnloadNoCrash) {
133 LoadAndWait(GetURL("layout_test_plugin.html"));
134 NavigateAway();
137 // Tests if a plugin executing a self deleting script using NPN_GetURL
138 // works without crashing or hanging
139 // Flaky: http://crbug.com/59327
140 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(SelfDeletePluginGetUrl)) {
141 LoadAndWait(GetURL("self_delete_plugin_geturl.html"));
144 // Tests if a plugin executing a self deleting script using Invoke
145 // works without crashing or hanging
146 // Flaky. See http://crbug.com/30702
147 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(SelfDeletePluginInvoke)) {
148 LoadAndWait(GetURL("self_delete_plugin_invoke.html"));
151 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(NPObjectReleasedOnDestruction)) {
152 NavigateToURL(shell(), GetURL("npobject_released_on_destruction.html"));
153 NavigateAway();
156 // Test that a dialog is properly created when a plugin throws an
157 // exception. Should be run for in and out of process plugins, but
158 // the more interesting case is out of process, where we must route
159 // the exception to the correct renderer.
160 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(NPObjectSetException)) {
161 LoadAndWait(GetURL("npobject_set_exception.html"));
164 #if defined(OS_WIN)
165 // Tests if a plugin executing a self deleting script in the context of
166 // a synchronous mouseup works correctly.
167 // This was never ported to Mac. The only thing remaining is to make
168 // SimulateMouseClick get to Mac plugins, currently it doesn't work.
169 IN_PROC_BROWSER_TEST_F(PluginTest,
170 MAYBE(SelfDeletePluginInvokeInSynchronousMouseUp)) {
171 NavigateToURL(shell(), GetURL("execute_script_delete_in_mouse_up.html"));
173 base::string16 expected_title(ASCIIToUTF16("OK"));
174 TitleWatcher title_watcher(shell()->web_contents(), expected_title);
175 title_watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
176 SimulateMouseClick(shell()->web_contents(), 0,
177 blink::WebMouseEvent::ButtonLeft);
178 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
180 #endif
182 // Flaky, http://crbug.com/302274.
183 #if defined(OS_MACOSX)
184 #define MAYBE_GetURLRequest404Response DISABLED_GetURLRequest404Response
185 #else
186 #define MAYBE_GetURLRequest404Response MAYBE(GetURLRequest404Response)
187 #endif
189 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE_GetURLRequest404Response) {
190 GURL url(net::URLRequestMockHTTPJob::GetMockUrl(
191 base::FilePath().AppendASCII("npapi").AppendASCII(
192 "plugin_url_request_404.html")));
193 LoadAndWait(url);
196 // Tests if a plugin executing a self deleting script using Invoke with
197 // a modal dialog showing works without crashing or hanging
198 // Disabled, flakily exceeds timeout, http://crbug.com/46257.
199 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(SelfDeletePluginInvokeAlert)) {
200 // Navigate asynchronously because if we waitd until it completes, there's a
201 // race condition where the alert can come up before we start watching for it.
202 shell()->LoadURL(GetURL("self_delete_plugin_invoke_alert.html"));
204 base::string16 expected_title(ASCIIToUTF16("OK"));
205 TitleWatcher title_watcher(shell()->web_contents(), expected_title);
206 title_watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
208 WaitForAppModalDialog(shell());
210 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
213 // Test passing arguments to a plugin.
214 // crbug.com/306318
215 #if !defined(OS_LINUX)
216 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(Arguments)) {
217 LoadAndWait(GetURL("arguments.html"));
219 #endif
221 // Test invoking many plugins within a single page.
222 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(ManyPlugins)) {
223 LoadAndWait(GetURL("many_plugins.html"));
226 #if !defined(OS_MACOSX) // http://crbug.com/402164
227 // Test various calls to GetURL from a plugin.
228 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(GetURL)) {
229 LoadAndWait(GetURL("geturl.html"));
231 #endif
233 // Test various calls to GetURL for javascript URLs with
234 // non NULL targets from a plugin.
235 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(GetJavaScriptURL)) {
236 LoadAndWait(GetURL("get_javascript_url.html"));
239 // Test that calling GetURL with a javascript URL and target=_self
240 // works properly when the plugin is embedded in a subframe.
241 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(GetJavaScriptURL2)) {
242 LoadAndWait(GetURL("get_javascript_url2.html"));
245 // Test is flaky on linux/cros/win builders. http://crbug.com/71904
246 IN_PROC_BROWSER_TEST_F(PluginTest, GetURLRedirectNotification) {
247 LoadAndWait(GetURL("geturl_redirect_notify.html"));
250 // Tests that identity is preserved for NPObjects passed from a plugin
251 // into JavaScript.
252 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(NPObjectIdentity)) {
253 LoadAndWait(GetURL("npobject_identity.html"));
256 // Tests that if an NPObject is proxies back to its original process, the
257 // original pointer is returned and not a proxy. If this fails the plugin
258 // will crash.
259 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(NPObjectProxy)) {
260 LoadAndWait(GetURL("npobject_proxy.html"));
263 #if defined(OS_WIN) || defined(OS_MACOSX)
264 // Tests if a plugin executing a self deleting script in the context of
265 // a synchronous paint event works correctly
266 // http://crbug.com/44960
267 IN_PROC_BROWSER_TEST_F(PluginTest,
268 MAYBE(SelfDeletePluginInvokeInSynchronousPaint)) {
269 LoadAndWait(GetURL("execute_script_delete_in_paint.html"));
271 #endif
273 // Tests that if a plugin executes a self resizing script in the context of a
274 // synchronous paint, the plugin doesn't use deallocated memory.
275 // http://crbug.com/139462
276 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(ResizeDuringPaint)) {
277 LoadAndWait(GetURL("resize_during_paint.html"));
280 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(SelfDeletePluginInNewStream)) {
281 LoadAndWait(GetURL("self_delete_plugin_stream.html"));
284 // On Mac this test asserts in plugin_host: http://crbug.com/95558
285 // On all platforms it flakes in ~URLRequestContext: http://crbug.com/310336
286 #if !defined(NDEBUG)
287 IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_DeletePluginInDeallocate) {
288 LoadAndWait(GetURL("plugin_delete_in_deallocate.html"));
290 #endif
292 #if defined(OS_WIN)
294 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(VerifyPluginWindowRect)) {
295 LoadAndWait(GetURL("verify_plugin_window_rect.html"));
298 // Tests that creating a new instance of a plugin while another one is handling
299 // a paint message doesn't cause deadlock.
300 // http://crbug.com/406184
301 IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_CreateInstanceInPaint) {
302 LoadAndWait(GetURL("create_instance_in_paint.html"));
305 // Tests that putting up an alert in response to a paint doesn't deadlock.
306 IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_AlertInWindowMessage) {
307 NavigateToURL(shell(), GetURL("alert_in_window_message.html"));
309 WaitForAppModalDialog(shell());
310 WaitForAppModalDialog(shell());
313 // http://crbug.com/406184
314 IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_VerifyNPObjectLifetimeTest) {
315 LoadAndWait(GetURL("npobject_lifetime_test.html"));
318 // Tests that we don't crash or assert if NPP_New fails
319 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(NewFails)) {
320 LoadAndWait(GetURL("new_fails.html"));
323 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(SelfDeletePluginInNPNEvaluate)) {
324 LoadAndWait(GetURL("execute_script_delete_in_npn_evaluate.html"));
327 IN_PROC_BROWSER_TEST_F(PluginTest,
328 MAYBE(SelfDeleteCreatePluginInNPNEvaluate)) {
329 LoadAndWait(GetURL("npn_plugin_delete_create_in_evaluate.html"));
332 #endif // OS_WIN
334 // If this flakes, reopen http://crbug.com/17645
335 // As of 6 July 2011, this test is flaky on Windows (perhaps due to timing out).
336 #if !defined(OS_MACOSX) && !defined(OS_LINUX)
337 // Disabled on Mac because the plugin side isn't implemented yet, see
338 // "TODO(port)" in plugin_javascript_open_popup.cc.
339 // Disabled on Linux because we don't support NPAPI any more.
340 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(OpenPopupWindowWithPlugin)) {
341 LoadAndWait(GetURL("get_javascript_open_popup_with_plugin.html"));
343 #endif
345 // Test checking the privacy mode is off.
346 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(PrivateDisabled)) {
347 LoadAndWait(GetURL("private.html"));
350 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(ScheduleTimer)) {
351 LoadAndWait(GetURL("schedule_timer.html"));
354 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(PluginThreadAsyncCall)) {
355 LoadAndWait(GetURL("plugin_thread_async_call.html"));
358 IN_PROC_BROWSER_TEST_F(PluginTest, PluginSingleRangeRequest) {
359 LoadAndWait(GetURL("plugin_single_range_request.html"));
362 #if !defined(OS_WIN) // http://crbug.com/396373
363 // Test checking the privacy mode is on.
364 // If this flakes on Linux, use http://crbug.com/104380
365 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(PrivateEnabled)) {
366 GURL url = GetURL("private.html");
367 url = GURL(url.spec() + "?private");
368 LoadAndWaitInWindow(CreateOffTheRecordBrowser(), url);
370 #endif
372 // These used to run on Windows: http://crbug.com/396373
373 #if defined(OS_MACOSX)
374 // Test a browser hang due to special case of multiple
375 // plugin instances indulged in sync calls across renderer.
376 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(MultipleInstancesSyncCalls)) {
377 LoadAndWait(GetURL("multiple_instances_sync_calls.html"));
380 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(GetURLRequestFailWrite)) {
381 GURL url(net::URLRequestMockHTTPJob::GetMockUrl(
382 base::FilePath().AppendASCII("npapi").AppendASCII(
383 "plugin_url_request_fail_write.html")));
384 LoadAndWait(url);
386 #endif
388 #if defined(OS_WIN)
389 // Flaky on Windows x86. http://crbug.com/388245
390 IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_EnsureScriptingWorksInDestroy) {
391 LoadAndWait(GetURL("ensure_scripting_works_in_destroy.html"));
394 // This test uses a Windows Event to signal to the plugin that it should crash
395 // on NP_Initialize.
396 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(NoHangIfInitCrashes)) {
397 HANDLE crash_event = CreateEvent(NULL, TRUE, FALSE, L"TestPluginCrashOnInit");
398 SetEvent(crash_event);
399 LoadAndWait(GetURL("no_hang_if_init_crashes.html"));
400 CloseHandle(crash_event);
402 #endif
404 // If this flakes on Mac, use http://crbug.com/111508
405 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(PluginReferrerTest)) {
406 GURL url(net::URLRequestMockHTTPJob::GetMockUrl(
407 base::FilePath().AppendASCII("npapi").AppendASCII(
408 "plugin_url_request_referrer_test.html")));
409 LoadAndWait(url);
412 #if defined(OS_MACOSX)
413 // Test is flaky, see http://crbug.com/134515.
414 IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_PluginConvertPointTest) {
415 gfx::Rect bounds(50, 50, 400, 400);
416 SetWindowBounds(shell()->window(), bounds);
418 NavigateToURL(shell(), GetURL("convert_point.html"));
420 base::string16 expected_title(ASCIIToUTF16("OK"));
421 TitleWatcher title_watcher(shell()->web_contents(), expected_title);
422 title_watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
423 // TODO(stuartmorgan): When the automation system supports sending clicks,
424 // change the test to trigger on mouse-down rather than window focus.
426 // TODO: is this code still needed? It was here when it used to run in
427 // browser_tests.
428 //static_cast<WebContentsDelegate*>(shell())->
429 // ActivateContents(shell()->web_contents());
430 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
432 #endif
434 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(Flash)) {
435 TestPlugin("flash.html");
438 #if defined(OS_WIN)
439 // Windows only test
440 IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_FlashSecurity) {
441 TestPlugin("flash.html");
443 #endif // defined(OS_WIN)
445 #if defined(OS_WIN)
446 // TODO(port) Port the following tests to platforms that have the required
447 // plugins.
448 // Flaky: http://crbug.com/55915
449 IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_Quicktime) {
450 TestPlugin("quicktime.html");
453 // Disabled - http://crbug.com/44662
454 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(MediaPlayerNew)) {
455 TestPlugin("wmp_new.html");
458 // Disabled - http://crbug.com/44673
459 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(Real)) {
460 TestPlugin("real.html");
463 // http://crbug.com/320041
464 #if (defined(OS_WIN) && defined(ARCH_CPU_X86_64)) || \
465 (defined(GOOGLE_CHROME_BUILD) && defined(OS_WIN))
466 #define MAYBE_FlashOctetStream DISABLED_FlashOctetStream
467 #else
468 #define MAYBE_FlashOctetStream FlashOctetStream
469 #endif
470 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE_FlashOctetStream) {
471 TestPlugin("flash-octet-stream.html");
474 #if defined(OS_WIN)
475 // http://crbug.com/53926
476 IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_FlashLayoutWhilePainting) {
477 #else
478 IN_PROC_BROWSER_TEST_F(PluginTest, FlashLayoutWhilePainting) {
479 #endif
480 TestPlugin("flash-layout-while-painting.html");
483 // http://crbug.com/8690
484 IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_Java) {
485 TestPlugin("Java.html");
488 // Flaky: http://crbug.com/55915
489 IN_PROC_BROWSER_TEST_F(PluginTest, DISABLED_Silverlight) {
490 TestPlugin("silverlight.html");
492 #endif // defined(OS_WIN)
494 class TestResourceDispatcherHostDelegate
495 : public ResourceDispatcherHostDelegate {
496 public:
497 TestResourceDispatcherHostDelegate() : found_cookie_(false) {}
499 bool found_cookie() { return found_cookie_; }
501 void WaitForPluginRequest() {
502 if (found_cookie_)
503 return;
505 runner_ = new MessageLoopRunner;
506 runner_->Run();
509 private:
510 // ResourceDispatcherHostDelegate implementation:
511 void OnResponseStarted(net::URLRequest* request,
512 ResourceContext* resource_context,
513 ResourceResponse* response,
514 IPC::Sender* sender) override {
515 // The URL below comes from plugin_geturl_test.cc.
516 if (!EndsWith(request->url().spec(),
517 "npapi/plugin_ref_target_page.html",
518 true)) {
519 return;
521 net::HttpRequestHeaders headers;
522 bool found_cookie = false;
523 if (request->GetFullRequestHeaders(&headers) &&
524 headers.ToString().find("Cookie: blah") != std::string::npos) {
525 found_cookie = true;
527 BrowserThread::PostTask(
528 BrowserThread::UI,
529 FROM_HERE,
530 base::Bind(&TestResourceDispatcherHostDelegate::GotCookie,
531 base::Unretained(this), found_cookie));
534 void GotCookie(bool found_cookie) {
535 found_cookie_ = found_cookie;
536 if (runner_.get())
537 runner_->QuitClosure().Run();
540 scoped_refptr<MessageLoopRunner> runner_;
541 bool found_cookie_;
543 DISALLOW_COPY_AND_ASSIGN(TestResourceDispatcherHostDelegate);
546 // Ensure that cookies get sent with plugin requests.
547 IN_PROC_BROWSER_TEST_F(PluginTest, MAYBE(Cookies)) {
548 // Create a new browser just to ensure that the plugin process' child_id is
549 // not equal to its type (PROCESS_TYPE_PLUGIN), as that was the error which
550 // caused this bug.
551 NavigateToURL(CreateBrowser(), GURL("about:blank"));
553 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
554 GURL url(embedded_test_server()->GetURL("/npapi/cookies.html"));
556 TestResourceDispatcherHostDelegate test_delegate;
557 ResourceDispatcherHostDelegate* old_delegate =
558 ResourceDispatcherHostImpl::Get()->delegate();
559 ResourceDispatcherHostImpl::Get()->SetDelegate(&test_delegate);
560 LoadAndWait(url);
561 test_delegate.WaitForPluginRequest();
562 ASSERT_TRUE(test_delegate.found_cookie());
563 ResourceDispatcherHostImpl::Get()->SetDelegate(old_delegate);
566 } // namespace content