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 <stdio.h>
6#if defined(OS_POSIX)
7#include <unistd.h>
8#elif defined(OS_WIN)
9#include <windows.h>
10#endif
11
12#define TELEMETRY 1
13
14#include "base/command_line.h"
15#include "base/environment.h"
16#include "base/path_service.h"
17#include "base/process/kill.h"
18#include "base/process/launch.h"
19#include "base/strings/string_number_conversions.h"
20#include "base/win/windows_version.h"
21#include "chrome/common/chrome_switches.h"
22#include "chrome/test/nacl/nacl_browsertest_util.h"
23#include "components/nacl/browser/nacl_browser.h"
24#include "components/nacl/common/nacl_switches.h"
25#include "content/public/common/content_switches.h"
26
27namespace {
28
29#if defined(OS_WIN)
30// crbug.com/98721
31#  define MAYBE_SysconfNprocessorsOnln DISABLED_SysconfNprocessorsOnln
32#else
33#  define MAYBE_SysconfNprocessorsOnln SysconfNprocessorsOnln
34#endif
35
36NACL_BROWSER_TEST_F(NaClBrowserTest, SimpleLoad, {
37  RunLoadTest(FILE_PATH_LITERAL("nacl_load_test.html"));
38})
39
40IN_PROC_BROWSER_TEST_F(NaClBrowserTestNonSfiMode, MAYBE_NONSFI(Messaging)) {
41  RunLoadTest(FILE_PATH_LITERAL("libc_free.html"));
42}
43
44IN_PROC_BROWSER_TEST_F(NaClBrowserTestNonSfiMode, MAYBE_NONSFI(Irt)) {
45  RunNaClIntegrationTest(FILE_PATH_LITERAL("irt_test.html"));
46}
47
48NACL_BROWSER_TEST_F(NaClBrowserTest, ExitStatus0, {
49  RunNaClIntegrationTest(FILE_PATH_LITERAL(
50      "pm_exit_status_test.html?trigger=exit0&expected_exit=0"));
51})
52
53NACL_BROWSER_TEST_F(NaClBrowserTest, ExitStatus254, {
54  RunNaClIntegrationTest(FILE_PATH_LITERAL(
55      "pm_exit_status_test.html?trigger=exit254&expected_exit=254"));
56})
57
58NACL_BROWSER_TEST_F(NaClBrowserTest, ExitStatusNeg2, {
59  RunNaClIntegrationTest(FILE_PATH_LITERAL(
60      "pm_exit_status_test.html?trigger=exitneg2&expected_exit=254"));
61})
62
63#if defined(ADDRESS_SANITIZER)
64#define Maybe_PPAPICore DISABLED_PPAPICore
65#else
66#define Maybe_PPAPICore PPAPICore
67#endif
68NACL_BROWSER_TEST_F(NaClBrowserTest, Maybe_PPAPICore, {
69  RunNaClIntegrationTest(FILE_PATH_LITERAL("ppapi_ppb_core.html"));
70})
71
72NACL_BROWSER_TEST_F(NaClBrowserTest, PPAPIPPBInstance, {
73  RunNaClIntegrationTest(FILE_PATH_LITERAL("ppapi_ppb_instance.html"));
74})
75
76NACL_BROWSER_TEST_F(NaClBrowserTest, PPAPIPPPInstance, {
77  RunNaClIntegrationTest(FILE_PATH_LITERAL("ppapi_ppp_instance.html"));
78})
79
80NACL_BROWSER_TEST_F(NaClBrowserTest, ProgressEvents, {
81  RunNaClIntegrationTest(FILE_PATH_LITERAL("ppapi_progress_events.html"));
82})
83
84// Note: currently not run on PNaCl because crash throttling causes the last few
85// tests to fail for the wrong reasons.  Enabling this test would also require
86// creating a new set of manifests because shared NaCl/PNaCl manifests are not
87// allowed.  Also not run on GLibc because it's a large test that is at risk of
88// causing timeouts.
89// crbug/338444
90#if defined(OS_WIN)
91#define MAYBE_Bad DISABLED_Bad
92#else
93#define MAYBE_Bad Bad
94#endif
95IN_PROC_BROWSER_TEST_F(NaClBrowserTestNewlib, MAYBE_Bad) {
96  RunNaClIntegrationTest(FILE_PATH_LITERAL("ppapi_bad.html"));
97}
98
99// partially_invalid.c does not have an ARM version of its asm.
100#if !defined(__arm__)
101IN_PROC_BROWSER_TEST_F(NaClBrowserTestNewlib, BadNative) {
102  RunNaClIntegrationTest(FILE_PATH_LITERAL("ppapi_bad_native.html"));
103}
104#endif
105
106#if defined(OS_WIN)
107// crbug.com/98721
108#  define MAYBE_Crash DISABLED_Crash
109#elif defined(OS_LINUX)
110// crbug.com/366334
111#  define MAYBE_Crash DISABLED_Crash
112#else
113#  define MAYBE_Crash Crash
114#endif
115NACL_BROWSER_TEST_F(NaClBrowserTest, MAYBE_Crash, {
116  RunNaClIntegrationTest(FILE_PATH_LITERAL("ppapi_crash.html"));
117})
118
119// PNaCl version does not work.
120IN_PROC_BROWSER_TEST_F(NaClBrowserTestNewlib, ManifestFile) {
121  RunNaClIntegrationTest(FILE_PATH_LITERAL("pm_manifest_file_test.html"));
122}
123IN_PROC_BROWSER_TEST_F(NaClBrowserTestGLibc, MAYBE_GLIBC(ManifestFile)) {
124  RunNaClIntegrationTest(FILE_PATH_LITERAL("pm_manifest_file_test.html"));
125}
126IN_PROC_BROWSER_TEST_F(NaClBrowserTestNewlib, PreInitManifestFile) {
127  RunNaClIntegrationTest(FILE_PATH_LITERAL(
128      "pm_pre_init_manifest_file_test.html"));
129}
130IN_PROC_BROWSER_TEST_F(NaClBrowserTestGLibc,
131                       MAYBE_GLIBC(PreInitManifestFile)) {
132  RunNaClIntegrationTest(FILE_PATH_LITERAL(
133      "pm_pre_init_manifest_file_test.html"));
134}
135IN_PROC_BROWSER_TEST_F(NaClBrowserTestNewlib, IrtManifestFile) {
136  RunNaClIntegrationTest(FILE_PATH_LITERAL("irt_manifest_file_test.html"));
137}
138IN_PROC_BROWSER_TEST_F(NaClBrowserTestPnaclNonSfi,
139                       MAYBE_PNACL_NONSFI(IrtManifestFile)) {
140  RunNaClIntegrationTest(FILE_PATH_LITERAL("irt_manifest_file_test.html"));
141}
142
143IN_PROC_BROWSER_TEST_F(NaClBrowserTestNewlib, IrtException) {
144  RunNaClIntegrationTest(FILE_PATH_LITERAL("irt_exception_test.html"));
145}
146IN_PROC_BROWSER_TEST_F(NaClBrowserTestPnaclNonSfi,
147                       MAYBE_PNACL_NONSFI(IrtException)) {
148  RunNaClIntegrationTest(FILE_PATH_LITERAL("irt_exception_test.html"));
149}
150
151NACL_BROWSER_TEST_F(NaClBrowserTest, Nameservice, {
152  RunNaClIntegrationTest(FILE_PATH_LITERAL("pm_nameservice_test.html"));
153})
154
155// Some versions of Visual Studio does not like preprocessor
156// conditionals inside the argument of a macro, so we put the
157// conditionals on a helper function.  We are already in an anonymous
158// namespace, so the name of the helper is not visible in external
159// scope.
160#if defined(OS_POSIX)
161base::FilePath::StringType NumberOfCoresAsFilePathString() {
162  char string_rep[23];
163  long nprocessors = sysconf(_SC_NPROCESSORS_ONLN);
164#if TELEMETRY
165  fprintf(stderr, "browser says nprocessors = %ld\n", nprocessors);
166  fflush(NULL);
167#endif
168  snprintf(string_rep, sizeof string_rep, "%ld", nprocessors);
169  return string_rep;
170}
171#elif defined(OS_WIN)
172base::FilePath::StringType NumberOfCoresAsFilePathString() {
173  wchar_t string_rep[23];
174  SYSTEM_INFO system_info;
175  GetSystemInfo(&system_info);
176#if TELEMETRY
177  fprintf(stderr, "browser says nprocessors = %d\n",
178          system_info.dwNumberOfProcessors);
179  fflush(NULL);
180#endif
181  _snwprintf_s(string_rep, sizeof string_rep / sizeof string_rep[0], _TRUNCATE,
182               L"%u", system_info.dwNumberOfProcessors);
183  return string_rep;
184}
185#endif
186
187#if TELEMETRY
188static void PathTelemetry(base::FilePath::StringType const &path) {
189# if defined(OS_WIN)
190    fwprintf(stderr, L"path = %s\n", path.c_str());
191# else
192    fprintf(stderr, "path = %s\n", path.c_str());
193# endif
194    fflush(NULL);
195}
196#else
197static void PathTelemetry(base::FilePath::StringType const &path) {
198  (void) path;
199}
200#endif
201
202NACL_BROWSER_TEST_F(NaClBrowserTest, MAYBE_SysconfNprocessorsOnln, {
203    base::FilePath::StringType path =
204      FILE_PATH_LITERAL("sysconf_nprocessors_onln_test.html?cpu_count=");
205    path = path + NumberOfCoresAsFilePathString();
206    PathTelemetry(path);
207    RunNaClIntegrationTest(path);
208})
209
210IN_PROC_BROWSER_TEST_F(NaClBrowserTestStatic, CrossOriginCORS) {
211  RunLoadTest(FILE_PATH_LITERAL("cross_origin/cors.html"));
212}
213
214IN_PROC_BROWSER_TEST_F(NaClBrowserTestStatic, CrossOriginFail) {
215  RunLoadTest(FILE_PATH_LITERAL("cross_origin/fail.html"));
216}
217
218IN_PROC_BROWSER_TEST_F(NaClBrowserTestStatic, SameOriginCookie) {
219  RunLoadTest(FILE_PATH_LITERAL("cross_origin/same_origin_cookie.html"));
220}
221
222IN_PROC_BROWSER_TEST_F(NaClBrowserTestStatic, CORSNoCookie) {
223  RunLoadTest(FILE_PATH_LITERAL("cross_origin/cors_no_cookie.html"));
224}
225
226IN_PROC_BROWSER_TEST_F(NaClBrowserTestStatic, RelativeManifest) {
227  RunLoadTest(FILE_PATH_LITERAL("manifest/relative_manifest.html"));
228}
229
230// Test with the NaCl debug flag turned on.
231class NaClBrowserTestPnaclDebug : public NaClBrowserTestPnacl {
232 public:
233  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
234    NaClBrowserTestPnacl::SetUpCommandLine(command_line);
235    // Turn on debugging to influence the PNaCl URL loaded
236    command_line->AppendSwitch(switches::kEnableNaClDebug);
237    // On windows, the debug stub requires --no-sandbox:
238    // crbug.com/265624
239#if defined(OS_WIN)
240    command_line->AppendSwitch(switches::kNoSandbox);
241#endif
242  }
243
244  // On some platforms this test does not work.
245  bool TestIsBroken() {
246    // TODO(jvoung): Make this test work on Windows 32-bit. When --no-sandbox
247    // is used, the required 1GB sandbox address space is not reserved.
248    // (see note in chrome/browser/nacl_host/test/nacl_gdb_browsertest.cc)
249#if defined(OS_WIN)
250    if (base::win::OSInfo::GetInstance()->wow64_status() ==
251        base::win::OSInfo::WOW64_DISABLED &&
252        base::win::OSInfo::GetInstance()->architecture() ==
253        base::win::OSInfo::X86_ARCHITECTURE) {
254      return true;
255    }
256#endif
257    return false;
258  }
259
260  void StartTestScript(base::ProcessHandle* test_process,
261                       int debug_stub_port) {
262    // We call a python script that speaks to the debug stub, and
263    // lets the app continue, so that the load progress event completes.
264    CommandLine cmd(base::FilePath(FILE_PATH_LITERAL("python")));
265    base::FilePath script;
266    PathService::Get(base::DIR_SOURCE_ROOT, &script);
267    script = script.AppendASCII(
268        "chrome/browser/nacl_host/test/debug_stub_browser_tests.py");
269    cmd.AppendArgPath(script);
270    cmd.AppendArg(base::IntToString(debug_stub_port));
271    cmd.AppendArg("continue");
272    LOG(INFO) << cmd.GetCommandLineString();
273    base::LaunchProcess(cmd, base::LaunchOptions(), test_process);
274  }
275
276  void RunWithTestDebugger(const base::FilePath::StringType& test_url) {
277    base::ProcessHandle test_script;
278    scoped_ptr<base::Environment> env(base::Environment::Create());
279    nacl::NaClBrowser::GetInstance()->SetGdbDebugStubPortListener(
280        base::Bind(&NaClBrowserTestPnaclDebug::StartTestScript,
281                   base::Unretained(this), &test_script));
282    // Turn on debug stub logging.
283    env->SetVar("NACLVERBOSITY", "1");
284    RunLoadTest(test_url);
285    env->UnSetVar("NACLVERBOSITY");
286    nacl::NaClBrowser::GetInstance()->ClearGdbDebugStubPortListener();
287    int exit_code;
288    LOG(INFO) << "Waiting for script to exit (which waits for embed to die).";
289    base::WaitForExitCode(test_script, &exit_code);
290    EXPECT_EQ(0, exit_code);
291  }
292};
293
294// Test with the NaCl debug flag turned on, but mask off every URL
295// so that nothing is actually debugged.
296class NaClBrowserTestPnaclDebugMasked : public NaClBrowserTestPnaclDebug {
297 public:
298  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
299    NaClBrowserTestPnaclDebug::SetUpCommandLine(command_line);
300    command_line->AppendSwitchASCII(switches::kNaClDebugMask,
301                                    "!<all_urls>");
302  }
303};
304
305// The tests which actually start a debug session must use the debug stub
306// to continue the app startup. However, NaCl on windows can't open the
307// debug stub socket in the browser process as needed by the test.
308// See http://crbug.com/157312.
309#if defined(OS_WIN)
310#define MAYBE_PnaclDebugURLFlagAndURL DISABLED_PnaclDebugURLFlagAndURL
311#define MAYBE_PnaclDebugURLFlagNoURL DISABLED_PnaclDebugURLFlagNoURL
312#else
313#define MAYBE_PnaclDebugURLFlagAndURL PnaclDebugURLFlagAndURL
314#define MAYBE_PnaclDebugURLFlagNoURL PnaclDebugURLFlagNoURL
315#endif
316IN_PROC_BROWSER_TEST_F(NaClBrowserTestPnaclDebug,
317                       MAYBE_PnaclDebugURLFlagAndURL) {
318  RunWithTestDebugger(FILE_PATH_LITERAL(
319      "pnacl_debug_url.html?nmf_file=pnacl_has_debug.nmf"));
320}
321
322IN_PROC_BROWSER_TEST_F(NaClBrowserTestPnaclDebug,
323                       MAYBE_PnaclDebugURLFlagNoURL) {
324  RunWithTestDebugger(FILE_PATH_LITERAL(
325      "pnacl_debug_url.html?nmf_file=pnacl_no_debug.nmf"));
326}
327
328IN_PROC_BROWSER_TEST_F(NaClBrowserTestPnacl,
329                       MAYBE_PNACL(PnaclDebugURLFlagOff)) {
330  RunLoadTest(FILE_PATH_LITERAL(
331      "pnacl_debug_url.html?nmf_file=pnacl_has_debug_flag_off.nmf"));
332}
333
334IN_PROC_BROWSER_TEST_F(NaClBrowserTestPnaclDebugMasked,
335                       MAYBE_PNACL(PnaclDebugURLFlagMaskedOff)) {
336  if (TestIsBroken()) {
337    return;
338  }
339  // If the mask excludes debugging, it's as if the flag was off.
340  RunLoadTest(FILE_PATH_LITERAL(
341      "pnacl_debug_url.html?nmf_file=pnacl_has_debug_flag_off.nmf"));
342}
343
344IN_PROC_BROWSER_TEST_F(NaClBrowserTestPnacl,
345                       MAYBE_PNACL(PnaclErrorHandling)) {
346  RunNaClIntegrationTest(FILE_PATH_LITERAL("pnacl_error_handling.html"));
347}
348
349IN_PROC_BROWSER_TEST_F(NaClBrowserTestPnacl,
350                       MAYBE_PNACL(PnaclNMFOptionsO0)) {
351  RunLoadTest(FILE_PATH_LITERAL("pnacl_options.html?use_nmf=o_0"));
352}
353
354IN_PROC_BROWSER_TEST_F(NaClBrowserTestPnacl,
355                       MAYBE_PNACL(PnaclNMFOptionsO2)) {
356  RunLoadTest(FILE_PATH_LITERAL("pnacl_options.html?use_nmf=o_2"));
357}
358
359IN_PROC_BROWSER_TEST_F(NaClBrowserTestPnacl,
360                       MAYBE_PNACL(PnaclNMFOptionsOlarge)) {
361  RunLoadTest(FILE_PATH_LITERAL("pnacl_options.html?use_nmf=o_large"));
362}
363
364IN_PROC_BROWSER_TEST_F(NaClBrowserTestPnacl,
365                       MAYBE_PNACL(PnaclDyncodeSyscallDisabled)) {
366  RunNaClIntegrationTest(FILE_PATH_LITERAL(
367      "pnacl_dyncode_syscall_disabled.html"));
368}
369
370IN_PROC_BROWSER_TEST_F(NaClBrowserTestPnacl,
371                       MAYBE_PNACL(PnaclExceptionHandlingDisabled)) {
372  RunNaClIntegrationTest(FILE_PATH_LITERAL(
373      "pnacl_exception_handling_disabled.html"));
374}
375
376IN_PROC_BROWSER_TEST_F(NaClBrowserTestPnacl, PnaclMimeType) {
377  RunLoadTest(FILE_PATH_LITERAL("pnacl_mime_type.html"));
378}
379
380IN_PROC_BROWSER_TEST_F(NaClBrowserTestPnaclDisabled, PnaclMimeType) {
381  RunLoadTest(FILE_PATH_LITERAL("pnacl_mime_type.html"));
382}
383
384class NaClBrowserTestNewlibStdoutPM : public NaClBrowserTestNewlib {
385 public:
386  virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
387    // Env needs to be set early because nacl_helper is spawned before the test
388    // body on Linux.
389    scoped_ptr<base::Environment> env(base::Environment::Create());
390    env->SetVar("NACL_EXE_STDOUT", "DEBUG_ONLY:dev://postmessage");
391    NaClBrowserTestNewlib::SetUpInProcessBrowserTestFixture();
392  }
393};
394
395IN_PROC_BROWSER_TEST_F(NaClBrowserTestNewlibStdoutPM, RedirectFg0) {
396  RunNaClIntegrationTest(FILE_PATH_LITERAL(
397      "pm_redir_test.html?stream=stdout&thread=fg&delay_us=0"));
398}
399
400IN_PROC_BROWSER_TEST_F(NaClBrowserTestNewlibStdoutPM, RedirectBg0) {
401  RunNaClIntegrationTest(FILE_PATH_LITERAL(
402      "pm_redir_test.html?stream=stdout&thread=bg&delay_us=0"));
403}
404
405IN_PROC_BROWSER_TEST_F(NaClBrowserTestNewlibStdoutPM, RedirectFg1) {
406  RunNaClIntegrationTest(FILE_PATH_LITERAL(
407      "pm_redir_test.html?stream=stdout&thread=fg&delay_us=1000000"));
408}
409
410IN_PROC_BROWSER_TEST_F(NaClBrowserTestNewlibStdoutPM, RedirectBg1) {
411  RunNaClIntegrationTest(FILE_PATH_LITERAL(
412      "pm_redir_test.html?stream=stdout&thread=bg&delay_us=1000000"));
413}
414
415class NaClBrowserTestNewlibStderrPM : public NaClBrowserTestNewlib {
416 public:
417  virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
418    // Env needs to be set early because nacl_helper is spawned before the test
419    // body on Linux.
420    scoped_ptr<base::Environment> env(base::Environment::Create());
421    env->SetVar("NACL_EXE_STDERR", "DEBUG_ONLY:dev://postmessage");
422    NaClBrowserTestNewlib::SetUpInProcessBrowserTestFixture();
423  }
424};
425
426IN_PROC_BROWSER_TEST_F(NaClBrowserTestNewlibStderrPM, RedirectFg0) {
427  RunNaClIntegrationTest(FILE_PATH_LITERAL(
428      "pm_redir_test.html?stream=stderr&thread=fg&delay_us=0"));
429}
430
431IN_PROC_BROWSER_TEST_F(NaClBrowserTestNewlibStderrPM, RedirectBg0) {
432  RunNaClIntegrationTest(FILE_PATH_LITERAL(
433      "pm_redir_test.html?stream=stderr&thread=bg&delay_us=0"));
434}
435
436IN_PROC_BROWSER_TEST_F(NaClBrowserTestNewlibStderrPM, RedirectFg1) {
437  RunNaClIntegrationTest(FILE_PATH_LITERAL(
438      "pm_redir_test.html?stream=stderr&thread=fg&delay_us=1000000"));
439}
440
441IN_PROC_BROWSER_TEST_F(NaClBrowserTestNewlibStderrPM, RedirectBg1) {
442  RunNaClIntegrationTest(FILE_PATH_LITERAL(
443      "pm_redir_test.html?stream=stderr&thread=bg&delay_us=1000000"));
444}
445
446// TODO(ncbray) support glibc and PNaCl
447#if defined(OS_MACOSX)
448// crbug.com/375894
449#define MAYBE_MimeHandler DISABLED_MimeHandler
450#else
451#define MAYBE_MimeHandler MimeHandler
452#endif
453IN_PROC_BROWSER_TEST_F(NaClBrowserTestNewlibExtension, MAYBE_MimeHandler) {
454  RunNaClIntegrationTest(FILE_PATH_LITERAL(
455      "ppapi_extension_mime_handler.html"));
456}
457
458}  // namespace
459