- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / test / ppapi / ppapi_test.cc
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/logging.h"
10 #include "base/path_service.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/test/test_timeouts.h"
14 #include "build/build_config.h"
15 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/browser/content_settings/host_content_settings_map.h"
17 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
18 #include "chrome/browser/infobars/infobar.h"
19 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/browser/ui/browser.h"
21 #include "chrome/browser/ui/browser_tabstrip.h"
22 #include "chrome/browser/ui/tabs/tab_strip_model.h"
23 #include "chrome/common/chrome_paths.h"
24 #include "chrome/common/chrome_switches.h"
25 #include "chrome/test/base/test_switches.h"
26 #include "chrome/test/base/ui_test_utils.h"
27 #include "content/public/browser/dom_operation_notification_details.h"
28 #include "content/public/browser/notification_service.h"
29 #include "content/public/browser/notification_types.h"
30 #include "content/public/browser/web_contents.h"
31 #include "content/public/common/content_paths.h"
32 #include "content/public/common/content_switches.h"
33 #include "content/public/test/browser_test_utils.h"
34 #include "content/public/test/test_renderer_host.h"
35 #include "net/base/net_util.h"
36 #include "net/base/test_data_directory.h"
37 #include "ppapi/shared_impl/ppapi_switches.h"
38 #include "ui/gl/gl_switches.h"
39
40 using content::DomOperationNotificationDetails;
41 using content::RenderViewHost;
42
43 namespace {
44
45 // Platform-specific filename relative to the chrome executable.
46 #if defined(OS_WIN)
47 const wchar_t library_name[] = L"ppapi_tests.dll";
48 #elif defined(OS_MACOSX)
49 const char library_name[] = "ppapi_tests.plugin";
50 #elif defined(OS_POSIX)
51 const char library_name[] = "libppapi_tests.so";
52 #endif
53
54 }  // namespace
55
56 PPAPITestMessageHandler::PPAPITestMessageHandler() {
57 }
58
59 TestMessageHandler::MessageResponse PPAPITestMessageHandler::HandleMessage(
60     const std::string& json) {
61  std::string trimmed;
62  TrimString(json, "\"", &trimmed);
63  if (trimmed == "...") {
64    return CONTINUE;
65  } else {
66    message_ = trimmed;
67    return DONE;
68  }
69 }
70
71 void PPAPITestMessageHandler::Reset() {
72   TestMessageHandler::Reset();
73   message_.clear();
74 }
75
76 PPAPITestBase::InfoBarObserver::InfoBarObserver() {
77   registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED,
78                  content::NotificationService::AllSources());
79 }
80
81 PPAPITestBase::InfoBarObserver::~InfoBarObserver() {
82   EXPECT_EQ(0u, expected_infobars_.size()) << "Missing an expected infobar";
83 }
84
85 void PPAPITestBase::InfoBarObserver::Observe(
86     int type,
87     const content::NotificationSource& source,
88     const content::NotificationDetails& details) {
89   ASSERT_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED, type);
90   InfoBarDelegate* infobar =
91       content::Details<InfoBarAddedDetails>(details).ptr();
92   ConfirmInfoBarDelegate* confirm_infobar_delegate =
93       infobar->AsConfirmInfoBarDelegate();
94   ASSERT_TRUE(confirm_infobar_delegate);
95
96   ASSERT_FALSE(expected_infobars_.empty()) << "Unexpected infobar";
97   if (expected_infobars_.front())
98     confirm_infobar_delegate->Accept();
99   else
100     confirm_infobar_delegate->Cancel();
101   expected_infobars_.pop_front();
102
103   // TODO(bauerb): We should close the infobar.
104 }
105
106 void PPAPITestBase::InfoBarObserver::ExpectInfoBarAndAccept(
107     bool should_accept) {
108   expected_infobars_.push_back(should_accept);
109 }
110
111 PPAPITestBase::PPAPITestBase() {
112 }
113
114 void PPAPITestBase::SetUpCommandLine(CommandLine* command_line) {
115   // The test sends us the result via a cookie.
116   command_line->AppendSwitch(switches::kEnableFileCookies);
117
118   // Some stuff is hung off of the testing interface which is not enabled
119   // by default.
120   command_line->AppendSwitch(switches::kEnablePepperTesting);
121
122   // Smooth scrolling confuses the scrollbar test.
123   command_line->AppendSwitch(switches::kDisableSmoothScrolling);
124
125   // For TestRequestOSFileHandle.
126   command_line->AppendSwitch(switches::kUnlimitedStorage);
127   command_line->AppendSwitchASCII(switches::kAllowNaClFileHandleAPI,
128                                   "127.0.0.1");
129 }
130
131 void PPAPITestBase::SetUpOnMainThread() {
132   // Always allow access to the PPAPI broker.
133   browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting(
134       CONTENT_SETTINGS_TYPE_PPAPI_BROKER, CONTENT_SETTING_ALLOW);
135 }
136
137 GURL PPAPITestBase::GetTestFileUrl(const std::string& test_case) {
138   base::FilePath test_path;
139   EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &test_path));
140   test_path = test_path.Append(FILE_PATH_LITERAL("ppapi"));
141   test_path = test_path.Append(FILE_PATH_LITERAL("tests"));
142   test_path = test_path.Append(FILE_PATH_LITERAL("test_case.html"));
143
144   // Sanity check the file name.
145   EXPECT_TRUE(base::PathExists(test_path));
146
147   GURL test_url = net::FilePathToFileURL(test_path);
148
149   GURL::Replacements replacements;
150   std::string query = BuildQuery(std::string(), test_case);
151   replacements.SetQuery(query.c_str(), url_parse::Component(0, query.size()));
152   return test_url.ReplaceComponents(replacements);
153 }
154
155 void PPAPITestBase::RunTest(const std::string& test_case) {
156   GURL url = GetTestFileUrl(test_case);
157   RunTestURL(url);
158 }
159
160 void PPAPITestBase::RunTestAndReload(const std::string& test_case) {
161   GURL url = GetTestFileUrl(test_case);
162   RunTestURL(url);
163   // If that passed, we simply run the test again, which navigates again.
164   RunTestURL(url);
165 }
166
167 void PPAPITestBase::RunTestViaHTTP(const std::string& test_case) {
168   base::FilePath document_root;
169   ASSERT_TRUE(ui_test_utils::GetRelativeBuildDirectory(&document_root));
170   base::FilePath http_document_root;
171   ASSERT_TRUE(ui_test_utils::GetRelativeBuildDirectory(&http_document_root));
172   net::SpawnedTestServer http_server(net::SpawnedTestServer::TYPE_HTTP,
173                                      net::SpawnedTestServer::kLocalhost,
174                                      document_root);
175   ASSERT_TRUE(http_server.Start());
176   RunTestURL(GetTestURL(http_server, test_case, std::string()));
177 }
178
179 void PPAPITestBase::RunTestWithSSLServer(const std::string& test_case) {
180   base::FilePath http_document_root;
181   ASSERT_TRUE(ui_test_utils::GetRelativeBuildDirectory(&http_document_root));
182   net::SpawnedTestServer http_server(net::SpawnedTestServer::TYPE_HTTP,
183                                      net::SpawnedTestServer::kLocalhost,
184                                      http_document_root);
185   net::SpawnedTestServer ssl_server(net::SpawnedTestServer::TYPE_HTTPS,
186                                     net::BaseTestServer::SSLOptions(),
187                                     http_document_root);
188   // Start the servers in parallel.
189   ASSERT_TRUE(http_server.StartInBackground());
190   ASSERT_TRUE(ssl_server.StartInBackground());
191   // Wait until they are both finished before continuing.
192   ASSERT_TRUE(http_server.BlockUntilStarted());
193   ASSERT_TRUE(ssl_server.BlockUntilStarted());
194
195   uint16_t port = ssl_server.host_port_pair().port();
196   RunTestURL(GetTestURL(http_server,
197                         test_case,
198                         base::StringPrintf("ssl_server_port=%d", port)));
199 }
200
201 void PPAPITestBase::RunTestWithWebSocketServer(const std::string& test_case) {
202   base::FilePath http_document_root;
203   ASSERT_TRUE(ui_test_utils::GetRelativeBuildDirectory(&http_document_root));
204   net::SpawnedTestServer http_server(net::SpawnedTestServer::TYPE_HTTP,
205                                      net::SpawnedTestServer::kLocalhost,
206                                      http_document_root);
207   net::SpawnedTestServer ws_server(net::SpawnedTestServer::TYPE_WS,
208                                    net::SpawnedTestServer::kLocalhost,
209                                    net::GetWebSocketTestDataDirectory());
210   // Start the servers in parallel.
211   ASSERT_TRUE(http_server.StartInBackground());
212   ASSERT_TRUE(ws_server.StartInBackground());
213   // Wait until they are both finished before continuing.
214   ASSERT_TRUE(http_server.BlockUntilStarted());
215   ASSERT_TRUE(ws_server.BlockUntilStarted());
216
217   std::string host = ws_server.host_port_pair().HostForURL();
218   uint16_t port = ws_server.host_port_pair().port();
219   RunTestURL(GetTestURL(http_server,
220                         test_case,
221                         base::StringPrintf(
222                             "websocket_host=%s&websocket_port=%d",
223                             host.c_str(),
224                             port)));
225 }
226
227 void PPAPITestBase::RunTestIfAudioOutputAvailable(
228     const std::string& test_case) {
229   RunTest(test_case);
230 }
231
232 void PPAPITestBase::RunTestViaHTTPIfAudioOutputAvailable(
233     const std::string& test_case) {
234   RunTestViaHTTP(test_case);
235 }
236
237 std::string PPAPITestBase::StripPrefixes(const std::string& test_name) {
238   const char* const prefixes[] = {
239       "FAILS_", "FLAKY_", "DISABLED_", "SLOW_" };
240   for (size_t i = 0; i < sizeof(prefixes)/sizeof(prefixes[0]); ++i)
241     if (test_name.find(prefixes[i]) == 0)
242       return test_name.substr(strlen(prefixes[i]));
243   return test_name;
244 }
245
246 void PPAPITestBase::RunTestURL(const GURL& test_url) {
247 #if defined(OS_WIN) && defined(USE_ASH)
248   // PPAPITests are broken in Ash browser tests (http://crbug.com/263548).
249   if (CommandLine::ForCurrentProcess()->HasSwitch(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   JavascriptTestObserver observer(
262       browser()->tab_strip_model()->GetActiveWebContents()->GetRenderViewHost(),
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
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
282 PPAPITest::PPAPITest() : in_process_(true) {
283 }
284
285 void PPAPITest::SetUpCommandLine(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(library_name);
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
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
311 OutOfProcessPPAPITest::OutOfProcessPPAPITest() {
312   in_process_ = false;
313 }
314
315 void OutOfProcessPPAPITest::SetUpCommandLine(CommandLine* command_line) {
316   PPAPITest::SetUpCommandLine(command_line);
317   command_line->AppendSwitch(switches::kUseFakeDeviceForMediaStream);
318   command_line->AppendSwitch(switches::kUseFakeUIForMediaStream);
319 }
320
321 void PPAPINaClTest::SetUpCommandLine(CommandLine* command_line) {
322   PPAPITestBase::SetUpCommandLine(command_line);
323
324   base::FilePath plugin_lib;
325   EXPECT_TRUE(PathService::Get(chrome::FILE_NACL_PLUGIN, &plugin_lib));
326   EXPECT_TRUE(base::PathExists(plugin_lib));
327
328   // Enable running (non-portable) NaCl outside of the Chrome web store.
329   command_line->AppendSwitch(switches::kEnableNaCl);
330   command_line->AppendSwitchASCII(switches::kAllowNaClSocketAPI, "127.0.0.1");
331   command_line->AppendSwitch(switches::kUseFakeDeviceForMediaStream);
332   command_line->AppendSwitch(switches::kUseFakeUIForMediaStream);
333 }
334
335 // Append the correct mode and testcase string
336 std::string PPAPINaClNewlibTest::BuildQuery(const std::string& base,
337                                             const std::string& test_case) {
338   return base::StringPrintf("%smode=nacl_newlib&testcase=%s", base.c_str(),
339                             test_case.c_str());
340 }
341
342 // Append the correct mode and testcase string
343 std::string PPAPINaClGLibcTest::BuildQuery(const std::string& base,
344                                            const std::string& test_case) {
345   return base::StringPrintf("%smode=nacl_glibc&testcase=%s", base.c_str(),
346                             test_case.c_str());
347 }
348
349 // Append the correct mode and testcase string
350 std::string PPAPINaClPNaClTest::BuildQuery(const std::string& base,
351                                            const std::string& test_case) {
352   return base::StringPrintf("%smode=nacl_pnacl&testcase=%s", base.c_str(),
353                             test_case.c_str());
354 }
355
356 void PPAPINaClTestDisallowedSockets::SetUpCommandLine(
357     CommandLine* command_line) {
358   PPAPITestBase::SetUpCommandLine(command_line);
359
360   base::FilePath plugin_lib;
361   EXPECT_TRUE(PathService::Get(chrome::FILE_NACL_PLUGIN, &plugin_lib));
362   EXPECT_TRUE(base::PathExists(plugin_lib));
363
364   // Enable running (non-portable) NaCl outside of the Chrome web store.
365   command_line->AppendSwitch(switches::kEnableNaCl);
366 }
367
368 // Append the correct mode and testcase string
369 std::string PPAPINaClTestDisallowedSockets::BuildQuery(
370     const std::string& base,
371     const std::string& test_case) {
372   return base::StringPrintf("%smode=nacl_newlib&testcase=%s", base.c_str(),
373                             test_case.c_str());
374 }
375
376 void PPAPIBrokerInfoBarTest::SetUpOnMainThread() {
377   // The default content setting for the PPAPI broker is ASK. We purposefully
378   // don't call PPAPITestBase::SetUpOnMainThread() to keep it that way.
379 }