• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "chrome/test/ppapi/ppapi_test.h"
6 
7 #include "base/command_line.h"
8 #include "base/file_util.h"
9 #include "base/path_service.h"
10 #include "base/strings/string_util.h"
11 #include "base/strings/stringprintf.h"
12 #include "chrome/browser/chrome_notification_types.h"
13 #include "chrome/browser/content_settings/host_content_settings_map.h"
14 #include "chrome/browser/infobars/infobar_service.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/ui/browser.h"
17 #include "chrome/browser/ui/tabs/tab_strip_model.h"
18 #include "chrome/common/chrome_paths.h"
19 #include "chrome/common/chrome_switches.h"
20 #include "chrome/test/base/test_switches.h"
21 #include "chrome/test/base/ui_test_utils.h"
22 #include "components/infobars/core/confirm_infobar_delegate.h"
23 #include "components/infobars/core/infobar.h"
24 #include "components/nacl/common/nacl_switches.h"
25 #include "content/public/browser/dom_operation_notification_details.h"
26 #include "content/public/browser/notification_service.h"
27 #include "content/public/browser/web_contents.h"
28 #include "content/public/common/content_switches.h"
29 #include "media/base/media_switches.h"
30 #include "net/base/filename_util.h"
31 #include "net/base/test_data_directory.h"
32 #include "ppapi/shared_impl/ppapi_switches.h"
33 #include "ppapi/shared_impl/test_harness_utils.h"
34 #include "ui/gl/gl_switches.h"
35 
36 using content::DomOperationNotificationDetails;
37 using content::RenderViewHost;
38 using content::TestMessageHandler;
39 
40 namespace {
41 
AddPrivateSwitches(base::CommandLine * command_line)42 void AddPrivateSwitches(base::CommandLine* command_line) {
43   // For TestRequestOSFileHandle.
44   command_line->AppendSwitch(switches::kUnlimitedStorage);
45   command_line->AppendSwitchASCII(switches::kAllowNaClFileHandleAPI,
46                                   "127.0.0.1");
47 }
48 
49 }  // namespace
50 
PPAPITestMessageHandler()51 PPAPITestMessageHandler::PPAPITestMessageHandler() {
52 }
53 
HandleMessage(const std::string & json)54 TestMessageHandler::MessageResponse PPAPITestMessageHandler::HandleMessage(
55     const std::string& json) {
56   std::string trimmed;
57   base::TrimString(json, "\"", &trimmed);
58   if (trimmed == "...")
59     return CONTINUE;
60   message_ = trimmed;
61   return DONE;
62 }
63 
Reset()64 void PPAPITestMessageHandler::Reset() {
65   TestMessageHandler::Reset();
66   message_.clear();
67 }
68 
InfoBarObserver(PPAPITestBase * test_base)69 PPAPITestBase::InfoBarObserver::InfoBarObserver(PPAPITestBase* test_base)
70     : test_base_(test_base),
71       expecting_infobar_(false),
72       should_accept_(false) {
73   registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED,
74                  content::NotificationService::AllSources());
75 }
76 
~InfoBarObserver()77 PPAPITestBase::InfoBarObserver::~InfoBarObserver() {
78   EXPECT_FALSE(expecting_infobar_) << "Missing an expected infobar";
79 }
80 
ExpectInfoBarAndAccept(bool should_accept)81 void PPAPITestBase::InfoBarObserver::ExpectInfoBarAndAccept(
82     bool should_accept) {
83   ASSERT_FALSE(expecting_infobar_);
84   expecting_infobar_ = true;
85   should_accept_ = should_accept;
86 }
87 
Observe(int type,const content::NotificationSource & source,const content::NotificationDetails & details)88 void PPAPITestBase::InfoBarObserver::Observe(
89     int type,
90     const content::NotificationSource& source,
91     const content::NotificationDetails& details) {
92   ASSERT_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED, type);
93   // It's not safe to remove the infobar here, since other observers (e.g. the
94   // InfoBarContainer) may still need to access it.  Instead, post a task to
95   // do all necessary infobar manipulation as soon as this call stack returns.
96   base::MessageLoop::current()->PostTask(
97       FROM_HERE, base::Bind(&InfoBarObserver::VerifyInfoBarState,
98                             base::Unretained(this)));
99 }
100 
VerifyInfoBarState()101 void PPAPITestBase::InfoBarObserver::VerifyInfoBarState() {
102   content::WebContents* web_contents =
103       test_base_->browser()->tab_strip_model()->GetActiveWebContents();
104   ASSERT_TRUE(web_contents != NULL);
105   InfoBarService* infobar_service =
106       InfoBarService::FromWebContents(web_contents);
107   ASSERT_TRUE(infobar_service != NULL);
108 
109   EXPECT_EQ(expecting_infobar_ ? 1U : 0U, infobar_service->infobar_count());
110   if (!expecting_infobar_)
111     return;
112   expecting_infobar_ = false;
113 
114   infobars::InfoBar* infobar = infobar_service->infobar_at(0);
115   ConfirmInfoBarDelegate* delegate =
116       infobar->delegate()->AsConfirmInfoBarDelegate();
117   ASSERT_TRUE(delegate != NULL);
118   if (should_accept_)
119     delegate->Accept();
120   else
121     delegate->Cancel();
122 
123   infobar_service->RemoveInfoBar(infobar);
124 }
125 
PPAPITestBase()126 PPAPITestBase::PPAPITestBase() {
127 }
128 
SetUp()129 void PPAPITestBase::SetUp() {
130   EnablePixelOutput();
131   InProcessBrowserTest::SetUp();
132 }
133 
SetUpCommandLine(base::CommandLine * command_line)134 void PPAPITestBase::SetUpCommandLine(base::CommandLine* command_line) {
135   // The test sends us the result via a cookie.
136   command_line->AppendSwitch(switches::kEnableFileCookies);
137 
138   // Some stuff is hung off of the testing interface which is not enabled
139   // by default.
140   command_line->AppendSwitch(switches::kEnablePepperTesting);
141 
142   // Smooth scrolling confuses the scrollbar test.
143   command_line->AppendSwitch(switches::kDisableSmoothScrolling);
144 }
145 
SetUpOnMainThread()146 void PPAPITestBase::SetUpOnMainThread() {
147   // Always allow access to the PPAPI broker.
148   browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting(
149       CONTENT_SETTINGS_TYPE_PPAPI_BROKER, CONTENT_SETTING_ALLOW);
150 }
151 
GetTestFileUrl(const std::string & test_case)152 GURL PPAPITestBase::GetTestFileUrl(const std::string& test_case) {
153   base::FilePath test_path;
154   EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &test_path));
155   test_path = test_path.Append(FILE_PATH_LITERAL("ppapi"));
156   test_path = test_path.Append(FILE_PATH_LITERAL("tests"));
157   test_path = test_path.Append(FILE_PATH_LITERAL("test_case.html"));
158 
159   // Sanity check the file name.
160   EXPECT_TRUE(base::PathExists(test_path));
161 
162   GURL test_url = net::FilePathToFileURL(test_path);
163 
164   GURL::Replacements replacements;
165   std::string query = BuildQuery(std::string(), test_case);
166   replacements.SetQuery(query.c_str(), url::Component(0, query.size()));
167   return test_url.ReplaceComponents(replacements);
168 }
169 
RunTest(const std::string & test_case)170 void PPAPITestBase::RunTest(const std::string& test_case) {
171   GURL url = GetTestFileUrl(test_case);
172   RunTestURL(url);
173 }
174 
RunTestViaHTTP(const std::string & test_case)175 void PPAPITestBase::RunTestViaHTTP(const std::string& test_case) {
176   base::FilePath document_root;
177   ASSERT_TRUE(ui_test_utils::GetRelativeBuildDirectory(&document_root));
178   base::FilePath http_document_root;
179   ASSERT_TRUE(ui_test_utils::GetRelativeBuildDirectory(&http_document_root));
180   net::SpawnedTestServer http_server(net::SpawnedTestServer::TYPE_HTTP,
181                                      net::SpawnedTestServer::kLocalhost,
182                                      document_root);
183   ASSERT_TRUE(http_server.Start());
184   RunTestURL(GetTestURL(http_server, test_case, std::string()));
185 }
186 
RunTestWithSSLServer(const std::string & test_case)187 void PPAPITestBase::RunTestWithSSLServer(const std::string& test_case) {
188   base::FilePath http_document_root;
189   ASSERT_TRUE(ui_test_utils::GetRelativeBuildDirectory(&http_document_root));
190   net::SpawnedTestServer http_server(net::SpawnedTestServer::TYPE_HTTP,
191                                      net::SpawnedTestServer::kLocalhost,
192                                      http_document_root);
193   net::SpawnedTestServer ssl_server(net::SpawnedTestServer::TYPE_HTTPS,
194                                     net::BaseTestServer::SSLOptions(),
195                                     http_document_root);
196   // Start the servers in parallel.
197   ASSERT_TRUE(http_server.StartInBackground());
198   ASSERT_TRUE(ssl_server.StartInBackground());
199   // Wait until they are both finished before continuing.
200   ASSERT_TRUE(http_server.BlockUntilStarted());
201   ASSERT_TRUE(ssl_server.BlockUntilStarted());
202 
203   uint16_t port = ssl_server.host_port_pair().port();
204   RunTestURL(GetTestURL(http_server,
205                         test_case,
206                         base::StringPrintf("ssl_server_port=%d", port)));
207 }
208 
RunTestWithWebSocketServer(const std::string & test_case)209 void PPAPITestBase::RunTestWithWebSocketServer(const std::string& test_case) {
210   base::FilePath http_document_root;
211   ASSERT_TRUE(ui_test_utils::GetRelativeBuildDirectory(&http_document_root));
212   net::SpawnedTestServer http_server(net::SpawnedTestServer::TYPE_HTTP,
213                                      net::SpawnedTestServer::kLocalhost,
214                                      http_document_root);
215   net::SpawnedTestServer ws_server(net::SpawnedTestServer::TYPE_WS,
216                                    net::SpawnedTestServer::kLocalhost,
217                                    net::GetWebSocketTestDataDirectory());
218   // Start the servers in parallel.
219   ASSERT_TRUE(http_server.StartInBackground());
220   ASSERT_TRUE(ws_server.StartInBackground());
221   // Wait until they are both finished before continuing.
222   ASSERT_TRUE(http_server.BlockUntilStarted());
223   ASSERT_TRUE(ws_server.BlockUntilStarted());
224 
225   std::string host = ws_server.host_port_pair().HostForURL();
226   uint16_t port = ws_server.host_port_pair().port();
227   RunTestURL(GetTestURL(http_server,
228                         test_case,
229                         base::StringPrintf(
230                             "websocket_host=%s&websocket_port=%d",
231                             host.c_str(),
232                             port)));
233 }
234 
RunTestIfAudioOutputAvailable(const std::string & test_case)235 void PPAPITestBase::RunTestIfAudioOutputAvailable(
236     const std::string& test_case) {
237   RunTest(test_case);
238 }
239 
RunTestViaHTTPIfAudioOutputAvailable(const std::string & test_case)240 void PPAPITestBase::RunTestViaHTTPIfAudioOutputAvailable(
241     const std::string& test_case) {
242   RunTestViaHTTP(test_case);
243 }
244 
RunTestURL(const GURL & test_url)245 void PPAPITestBase::RunTestURL(const GURL& test_url) {
246 #if defined(OS_WIN) && defined(USE_ASH)
247   // PPAPITests are broken in Ash browser tests (http://crbug.com/263548).
248   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
249           switches::kAshBrowserTests)) {
250     LOG(WARNING) << "PPAPITests are disabled for Ash browser tests.";
251     return;
252   }
253 #endif
254 
255   // See comment above TestingInstance in ppapi/test/testing_instance.h.
256   // Basically it sends messages using the DOM automation controller. The
257   // value of "..." means it's still working and we should continue to wait,
258   // any other value indicates completion (in this case it will start with
259   // "PASS" or "FAIL"). This keeps us from timing out on waits for long tests.
260   PPAPITestMessageHandler handler;
261   content::JavascriptTestObserver observer(
262       browser()->tab_strip_model()->GetActiveWebContents(),
263       &handler);
264 
265   ui_test_utils::NavigateToURL(browser(), test_url);
266 
267   ASSERT_TRUE(observer.Run()) << handler.error_message();
268   EXPECT_STREQ("PASS", handler.message().c_str());
269 }
270 
GetTestURL(const net::SpawnedTestServer & http_server,const std::string & test_case,const std::string & extra_params)271 GURL PPAPITestBase::GetTestURL(
272     const net::SpawnedTestServer& http_server,
273     const std::string& test_case,
274     const std::string& extra_params) {
275   std::string query = BuildQuery("files/test_case.html?", test_case);
276   if (!extra_params.empty())
277     query = base::StringPrintf("%s&%s", query.c_str(), extra_params.c_str());
278 
279   return http_server.GetURL(query);
280 }
281 
PPAPITest()282 PPAPITest::PPAPITest() : in_process_(true) {
283 }
284 
SetUpCommandLine(base::CommandLine * command_line)285 void PPAPITest::SetUpCommandLine(base::CommandLine* command_line) {
286   PPAPITestBase::SetUpCommandLine(command_line);
287 
288   // Append the switch to register the pepper plugin.
289   // library name = <out dir>/<test_name>.<library_extension>
290   // MIME type = application/x-ppapi-<test_name>
291   base::FilePath plugin_dir;
292   EXPECT_TRUE(PathService::Get(base::DIR_MODULE, &plugin_dir));
293 
294   base::FilePath plugin_lib = plugin_dir.Append(ppapi::GetTestLibraryName());
295   EXPECT_TRUE(base::PathExists(plugin_lib));
296   base::FilePath::StringType pepper_plugin = plugin_lib.value();
297   pepper_plugin.append(FILE_PATH_LITERAL(";application/x-ppapi-tests"));
298   command_line->AppendSwitchNative(switches::kRegisterPepperPlugins,
299                                    pepper_plugin);
300   command_line->AppendSwitchASCII(switches::kAllowNaClSocketAPI, "127.0.0.1");
301 
302   if (in_process_)
303     command_line->AppendSwitch(switches::kPpapiInProcess);
304 }
305 
BuildQuery(const std::string & base,const std::string & test_case)306 std::string PPAPITest::BuildQuery(const std::string& base,
307                                   const std::string& test_case){
308   return base::StringPrintf("%stestcase=%s", base.c_str(), test_case.c_str());
309 }
310 
SetUpCommandLine(base::CommandLine * command_line)311 void PPAPIPrivateTest::SetUpCommandLine(base::CommandLine* command_line) {
312   PPAPITest::SetUpCommandLine(command_line);
313   AddPrivateSwitches(command_line);
314 }
315 
OutOfProcessPPAPITest()316 OutOfProcessPPAPITest::OutOfProcessPPAPITest() {
317   in_process_ = false;
318 }
319 
SetUpCommandLine(base::CommandLine * command_line)320 void OutOfProcessPPAPITest::SetUpCommandLine(base::CommandLine* command_line) {
321   PPAPITest::SetUpCommandLine(command_line);
322   command_line->AppendSwitch(switches::kUseFakeDeviceForMediaStream);
323   command_line->AppendSwitch(switches::kUseFakeUIForMediaStream);
324 }
325 
SetUpCommandLine(base::CommandLine * command_line)326 void OutOfProcessPPAPIPrivateTest::SetUpCommandLine(
327     base::CommandLine* command_line) {
328   OutOfProcessPPAPITest::SetUpCommandLine(command_line);
329   AddPrivateSwitches(command_line);
330 }
331 
SetUpCommandLine(base::CommandLine * command_line)332 void PPAPINaClTest::SetUpCommandLine(base::CommandLine* command_line) {
333 #if !defined(DISABLE_NACL)
334   PPAPITestBase::SetUpCommandLine(command_line);
335 
336   // Enable running (non-portable) NaCl outside of the Chrome web store.
337   command_line->AppendSwitch(switches::kEnableNaCl);
338   command_line->AppendSwitchASCII(switches::kAllowNaClSocketAPI, "127.0.0.1");
339   command_line->AppendSwitch(switches::kUseFakeDeviceForMediaStream);
340   command_line->AppendSwitch(switches::kUseFakeUIForMediaStream);
341 #endif
342 }
343 
SetUpOnMainThread()344 void PPAPINaClTest::SetUpOnMainThread() {
345   base::FilePath plugin_lib;
346   EXPECT_TRUE(PathService::Get(chrome::FILE_NACL_PLUGIN, &plugin_lib));
347   EXPECT_TRUE(base::PathExists(plugin_lib));
348 }
349 
RunTest(const std::string & test_case)350 void PPAPINaClTest::RunTest(const std::string& test_case) {
351 #if !defined(DISABLE_NACL)
352   PPAPITestBase::RunTest(test_case);
353 #endif
354 }
355 
RunTestViaHTTP(const std::string & test_case)356 void PPAPINaClTest::RunTestViaHTTP(const std::string& test_case) {
357 #if !defined(DISABLE_NACL)
358   PPAPITestBase::RunTestViaHTTP(test_case);
359 #endif
360 }
361 
RunTestWithSSLServer(const std::string & test_case)362 void PPAPINaClTest::RunTestWithSSLServer(const std::string& test_case) {
363 #if !defined(DISABLE_NACL)
364   PPAPITestBase::RunTestWithSSLServer(test_case);
365 #endif
366 }
367 
RunTestWithWebSocketServer(const std::string & test_case)368 void PPAPINaClTest::RunTestWithWebSocketServer(const std::string& test_case) {
369 #if !defined(DISABLE_NACL)
370   PPAPITestBase::RunTestWithWebSocketServer(test_case);
371 #endif
372 }
373 
RunTestIfAudioOutputAvailable(const std::string & test_case)374 void PPAPINaClTest::RunTestIfAudioOutputAvailable(
375     const std::string& test_case) {
376 #if !defined(DISABLE_NACL)
377   PPAPITestBase::RunTestIfAudioOutputAvailable(test_case);
378 #endif
379 }
380 
RunTestViaHTTPIfAudioOutputAvailable(const std::string & test_case)381 void PPAPINaClTest::RunTestViaHTTPIfAudioOutputAvailable(
382     const std::string& test_case) {
383 #if !defined(DISABLE_NACL)
384   PPAPITestBase::RunTestViaHTTPIfAudioOutputAvailable(test_case);
385 #endif
386 }
387 
388 // Append the correct mode and testcase string
BuildQuery(const std::string & base,const std::string & test_case)389 std::string PPAPINaClNewlibTest::BuildQuery(const std::string& base,
390                                             const std::string& test_case) {
391   return base::StringPrintf("%smode=nacl_newlib&testcase=%s", base.c_str(),
392                             test_case.c_str());
393 }
394 
SetUpCommandLine(base::CommandLine * command_line)395 void PPAPIPrivateNaClNewlibTest::SetUpCommandLine(
396     base::CommandLine* command_line) {
397   PPAPINaClNewlibTest::SetUpCommandLine(command_line);
398   AddPrivateSwitches(command_line);
399 }
400 
401 // Append the correct mode and testcase string
BuildQuery(const std::string & base,const std::string & test_case)402 std::string PPAPINaClGLibcTest::BuildQuery(const std::string& base,
403                                            const std::string& test_case) {
404   return base::StringPrintf("%smode=nacl_glibc&testcase=%s", base.c_str(),
405                             test_case.c_str());
406 }
407 
SetUpCommandLine(base::CommandLine * command_line)408 void PPAPIPrivateNaClGLibcTest::SetUpCommandLine(
409     base::CommandLine* command_line) {
410   PPAPINaClGLibcTest::SetUpCommandLine(command_line);
411   AddPrivateSwitches(command_line);
412 }
413 
414 // Append the correct mode and testcase string
BuildQuery(const std::string & base,const std::string & test_case)415 std::string PPAPINaClPNaClTest::BuildQuery(const std::string& base,
416                                            const std::string& test_case) {
417   return base::StringPrintf("%smode=nacl_pnacl&testcase=%s", base.c_str(),
418                             test_case.c_str());
419 }
420 
SetUpCommandLine(base::CommandLine * command_line)421 void PPAPIPrivateNaClPNaClTest::SetUpCommandLine(
422     base::CommandLine* command_line) {
423   PPAPINaClPNaClTest::SetUpCommandLine(command_line);
424   AddPrivateSwitches(command_line);
425 }
426 
SetUpCommandLine(base::CommandLine * command_line)427 void PPAPINaClPNaClNonSfiTest::SetUpCommandLine(
428     base::CommandLine* command_line) {
429   PPAPINaClTest::SetUpCommandLine(command_line);
430   command_line->AppendSwitch(switches::kEnableNaClNonSfiMode);
431 }
432 
BuildQuery(const std::string & base,const std::string & test_case)433 std::string PPAPINaClPNaClNonSfiTest::BuildQuery(
434     const std::string& base,
435     const std::string& test_case) {
436   return base::StringPrintf("%smode=nacl_pnacl_nonsfi&testcase=%s",
437                             base.c_str(), test_case.c_str());
438 }
439 
SetUpCommandLine(base::CommandLine * command_line)440 void PPAPIPrivateNaClPNaClNonSfiTest::SetUpCommandLine(
441     base::CommandLine* command_line) {
442   PPAPINaClPNaClNonSfiTest::SetUpCommandLine(command_line);
443   AddPrivateSwitches(command_line);
444 }
445 
SetUpCommandLine(base::CommandLine * command_line)446 void PPAPINaClTestDisallowedSockets::SetUpCommandLine(
447     base::CommandLine* command_line) {
448   PPAPITestBase::SetUpCommandLine(command_line);
449 
450   // Enable running (non-portable) NaCl outside of the Chrome web store.
451   command_line->AppendSwitch(switches::kEnableNaCl);
452 }
453 
454 // Append the correct mode and testcase string
BuildQuery(const std::string & base,const std::string & test_case)455 std::string PPAPINaClTestDisallowedSockets::BuildQuery(
456     const std::string& base,
457     const std::string& test_case) {
458   return base::StringPrintf("%smode=nacl_newlib&testcase=%s", base.c_str(),
459                             test_case.c_str());
460 }
461 
SetUpOnMainThread()462 void PPAPIBrokerInfoBarTest::SetUpOnMainThread() {
463   // The default content setting for the PPAPI broker is ASK. We purposefully
464   // don't call PPAPITestBase::SetUpOnMainThread() to keep it that way.
465 
466   base::FilePath plugin_lib;
467   EXPECT_TRUE(PathService::Get(chrome::FILE_NACL_PLUGIN, &plugin_lib));
468   EXPECT_TRUE(base::PathExists(plugin_lib));
469 }
470