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

Unified Diff: ppapi/native_client/tools/browser_tester/browsertester/browserlauncher.py

Issue 10914053: Relocating files in the nacl repo that belong in chrome. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merge Created 8 years, 3 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 side-by-side diff with in-line comments
Download patch
Index: ppapi/native_client/tools/browser_tester/browsertester/browserlauncher.py
diff --git a/ppapi/native_client/tools/browser_tester/browsertester/browserlauncher.py b/ppapi/native_client/tools/browser_tester/browsertester/browserlauncher.py
new file mode 100755
index 0000000000000000000000000000000000000000..07780773a880f80e4ba359ad45c478269ccc744d
--- /dev/null
+++ b/ppapi/native_client/tools/browser_tester/browsertester/browserlauncher.py
@@ -0,0 +1,334 @@
+#!/usr/bin/python
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import os.path
+import re
+import shutil
+import sys
+import tempfile
+import time
+
+import browserprocess
+
+class LaunchFailure(Exception):
+ pass
+
+
+def GetPlatform():
+ if sys.platform == 'darwin':
+ platform = 'mac'
+ elif sys.platform.startswith('linux'):
+ platform = 'linux'
+ elif sys.platform in ('cygwin', 'win32'):
+ platform = 'windows'
+ else:
+ raise LaunchFailure('Unknown platform: %s' % sys.platform)
+ return platform
+
+
+PLATFORM = GetPlatform()
+
+
+def SelectRunCommand():
+ # The subprocess module added support for .kill in Python 2.6
+ assert (sys.version_info[0] >= 3 or (sys.version_info[0] == 2 and
+ sys.version_info[1] >= 6))
+ if PLATFORM == 'linux':
+ return browserprocess.RunCommandInProcessGroup
+ else:
+ return browserprocess.RunCommandWithSubprocess
+
+
+RunCommand = SelectRunCommand()
+
+def RemoveDirectory(path):
+ retry = 5
+ sleep_time = 0.25
+ while True:
+ try:
+ shutil.rmtree(path)
+ except Exception:
+ # Windows processes sometime hang onto files too long
+ if retry > 0:
+ retry -= 1
+ time.sleep(sleep_time)
+ sleep_time *= 2
+ else:
+ # No luck - don't mask the error
+ raise
+ else:
+ # succeeded
+ break
+
+
+
+# In Windows, subprocess seems to have an issue with file names that
+# contain spaces.
+def EscapeSpaces(path):
+ if PLATFORM == 'windows' and ' ' in path:
+ return '"%s"' % path
+ return path
+
+
+def MakeEnv(options):
+ env = dict(os.environ)
+ # Enable PPAPI Dev interfaces for testing.
+ env['NACL_ENABLE_PPAPI_DEV'] = str(options.enable_ppapi_dev)
+ if options.debug:
+ env['PPAPI_BROWSER_DEBUG'] = '1'
+ env['NACL_PLUGIN_DEBUG'] = '1'
+ env['NACL_PPAPI_PROXY_DEBUG'] = '1'
+ # env['NACL_SRPC_DEBUG'] = '1'
+ return env
+
+
+class BrowserLauncher(object):
+
+ WAIT_TIME = 20
+ WAIT_STEPS = 80
+ SLEEP_TIME = float(WAIT_TIME) / WAIT_STEPS
+
+ def __init__(self, options):
+ self.options = options
+ self.profile = None
+ self.binary = None
+ self.tool_log_dir = None
+
+ def KnownPath(self):
+ raise NotImplementedError
+
+ def BinaryName(self):
+ raise NotImplementedError
+
+ def CreateProfile(self):
+ raise NotImplementedError
+
+ def MakeCmd(self, url):
+ raise NotImplementedError
+
+ def CreateToolLogDir(self):
+ self.tool_log_dir = tempfile.mkdtemp(prefix='vglogs_')
+ return self.tool_log_dir
+
+ def FindBinary(self):
+ if self.options.browser_path:
+ return self.options.browser_path
+ else:
+ path = self.KnownPath()
+ if path is None or not os.path.exists(path):
+ raise LaunchFailure('Cannot find the browser directory')
+ binary = os.path.join(path, self.BinaryName())
+ if not os.path.exists(binary):
+ raise LaunchFailure('Cannot find the browser binary')
+ return binary
+
+ def WaitForProcessDeath(self):
+ self.browser_process.Wait(self.WAIT_STEPS, self.SLEEP_TIME)
+
+ def Cleanup(self):
+ self.browser_process.Kill()
+
+ RemoveDirectory(self.profile)
+ if self.tool_log_dir is not None:
+ RemoveDirectory(self.tool_log_dir)
+
+ def MakeProfileDirectory(self):
+ self.profile = tempfile.mkdtemp(prefix='browserprofile_')
+ return self.profile
+
+ def SetStandardStream(self, env, var_name, redirect_file, is_output):
+ if redirect_file is None:
+ return
+ file_prefix = 'file:'
+ dev_prefix = 'dev:'
+ debug_warning = 'DEBUG_ONLY:'
+ # logic must match src/trusted/service_runtime/nacl_resource.*
+ # resource specification notation. file: is the default
+ # interpretation, so we must have an exhaustive list of
+ # alternative schemes accepted. if we remove the file-is-default
+ # interpretation, replace with
+ # is_file = redirect_file.startswith(file_prefix)
+ # and remove the list of non-file schemes.
+ is_file = (not (redirect_file.startswith(dev_prefix) or
+ redirect_file.startswith(debug_warning + dev_prefix)))
+ if is_file:
+ if redirect_file.startswith(file_prefix):
+ bare_file = redirect_file[len(file_prefix)]
+ else:
+ bare_file = redirect_file
+ # why always abspath? does chrome chdir or might it in the
+ # future? this means we do not test/use the relative path case.
+ redirect_file = file_prefix + os.path.abspath(bare_file)
+ else:
+ bare_file = None # ensure error if used without checking is_file
+ env[var_name] = redirect_file
+ if is_output:
+ # sel_ldr appends program output to the file so we need to clear it
+ # in order to get the stable result.
+ if is_file:
+ if os.path.exists(bare_file):
+ os.remove(bare_file)
+ parent_dir = os.path.dirname(bare_file)
+ # parent directory may not exist.
+ if not os.path.exists(parent_dir):
+ os.makedirs(parent_dir)
+
+ def Launch(self, cmd, env):
+ browser_path = cmd[0]
+ if not os.path.exists(browser_path):
+ raise LaunchFailure('Browser does not exist %r'% browser_path)
+ if not os.access(browser_path, os.X_OK):
+ raise LaunchFailure('Browser cannot be executed %r (Is this binary on an '
+ 'NFS volume?)' % browser_path)
+ if self.options.sel_ldr:
+ env['NACL_SEL_LDR'] = self.options.sel_ldr
+ if self.options.sel_ldr_bootstrap:
+ env['NACL_SEL_LDR_BOOTSTRAP'] = self.options.sel_ldr_bootstrap
+ if self.options.irt_library:
+ env['NACL_IRT_LIBRARY'] = self.options.irt_library
+ if self.options.prefer_portable_in_manifest:
+ env['NACL_PREFER_PORTABLE_IN_MANIFEST'] = '1'
+ self.SetStandardStream(env, 'NACL_EXE_STDIN',
+ self.options.nacl_exe_stdin, False)
+ self.SetStandardStream(env, 'NACL_EXE_STDOUT',
+ self.options.nacl_exe_stdout, True)
+ self.SetStandardStream(env, 'NACL_EXE_STDERR',
+ self.options.nacl_exe_stderr, True)
+ print 'ENV:', ' '.join(['='.join(pair) for pair in env.iteritems()])
+ print 'LAUNCHING: %s' % ' '.join(cmd)
+ sys.stdout.flush()
+ self.browser_process = RunCommand(cmd, env=env)
+
+ def IsRunning(self):
+ return self.browser_process.IsRunning()
+
+ def GetReturnCode(self):
+ return self.browser_process.GetReturnCode()
+
+ def Run(self, url, port):
+ self.binary = EscapeSpaces(self.FindBinary())
+ self.profile = self.CreateProfile()
+ if self.options.tool is not None:
+ self.tool_log_dir = self.CreateToolLogDir()
+ cmd = self.MakeCmd(url, port)
+ self.Launch(cmd, MakeEnv(self.options))
+
+
+def EnsureDirectory(path):
+ if not os.path.exists(path):
+ os.makedirs(path)
+
+
+def EnsureDirectoryForFile(path):
+ EnsureDirectory(os.path.dirname(path))
+
+
+class ChromeLauncher(BrowserLauncher):
+
+ def KnownPath(self):
+ if PLATFORM == 'linux':
+ # TODO(ncbray): look in path?
+ return '/opt/google/chrome'
+ elif PLATFORM == 'mac':
+ return '/Applications/Google Chrome.app/Contents/MacOS'
+ else:
+ homedir = os.path.expanduser('~')
+ path = os.path.join(homedir, r'AppData\Local\Google\Chrome\Application')
+ return path
+
+ def BinaryName(self):
+ if PLATFORM == 'mac':
+ return 'Google Chrome'
+ elif PLATFORM == 'windows':
+ return 'chrome.exe'
+ else:
+ return 'chrome'
+
+ def MakeEmptyJSONFile(self, path):
+ EnsureDirectoryForFile(path)
+ f = open(path, 'w')
+ f.write('{}')
+ f.close()
+
+ def CreateProfile(self):
+ profile = self.MakeProfileDirectory()
+
+ # Squelch warnings by creating bogus files.
+ self.MakeEmptyJSONFile(os.path.join(profile, 'Default', 'Preferences'))
+ self.MakeEmptyJSONFile(os.path.join(profile, 'Local State'))
+
+ return profile
+
+ def NetLogName(self):
+ return os.path.join(self.profile, 'netlog.json')
+
+ def MakeCmd(self, url, port):
+ cmd = [self.binary,
+ '--disable-web-resources',
+ '--disable-preconnect',
+ '--no-first-run',
+ '--no-default-browser-check',
+ '--enable-logging',
+ '--log-level=1',
+ '--safebrowsing-disable-auto-update',
+ # Chrome explicitly blacklists some ports as "unsafe" because
+ # certain protocols use them. Chrome gives an error like this:
+ # Error 312 (net::ERR_UNSAFE_PORT): Unknown error
+ # Unfortunately, the browser tester can randomly choose a
+ # blacklisted port. To work around this, the tester whitelists
+ # whatever port it is using.
+ '--explicitly-allowed-ports=%d' % port,
+ '--user-data-dir=%s' % self.profile]
+ # Log network requests to assist debugging.
+ cmd.append('--log-net-log=%s' % self.NetLogName())
+ if self.options.ppapi_plugin is None:
+ cmd.append('--enable-nacl')
+ disable_sandbox = False
+ # Sandboxing Chrome on Linux requires a SUIDed helper binary. This
+ # binary may not be installed, so disable sandboxing to avoid the
+ # corner cases where it may fail. This is a little scarry, because it
+ # means we are not testing NaCl inside the outer sandbox on Linux.
+ disable_sandbox |= PLATFORM == 'linux'
+ # Chrome process can't access file within sandbox
+ disable_sandbox |= self.options.nacl_exe_stdin is not None
+ disable_sandbox |= self.options.nacl_exe_stdout is not None
+ disable_sandbox |= self.options.nacl_exe_stderr is not None
+ if disable_sandbox:
+ cmd.append('--no-sandbox')
+ else:
+ cmd.append('--register-pepper-plugins=%s;application/x-nacl'
+ % self.options.ppapi_plugin)
+ cmd.append('--no-sandbox')
+ if self.options.browser_extensions:
+ cmd.append('--load-extension=%s' %
+ ','.join(self.options.browser_extensions))
+ cmd.append('--enable-experimental-extension-apis')
+ if self.options.tool == 'memcheck':
+ cmd = ['src/third_party/valgrind/memcheck.sh',
+ '-v',
+ '--xml=yes',
+ '--leak-check=no',
+ '--gen-suppressions=all',
+ '--num-callers=30',
+ '--trace-children=yes',
+ '--nacl-file=%s' % (self.options.files[0],),
+ '--suppressions=' +
+ '../tools/valgrind/memcheck/suppressions.txt',
+ '--xml-file=%s/xml.%%p' % (self.tool_log_dir,),
+ '--log-file=%s/log.%%p' % (self.tool_log_dir,)] + cmd
+ elif self.options.tool == 'tsan':
+ cmd = ['src/third_party/valgrind/tsan.sh',
+ '-v',
+ '--num-callers=30',
+ '--trace-children=yes',
+ '--nacl-file=%s' % (self.options.files[0],),
+ '--ignore=../tools/valgrind/tsan/ignores.txt',
+ '--suppressions=../tools/valgrind/tsan/suppressions.txt',
+ '--log-file=%s/log.%%p' % (self.tool_log_dir,)] + cmd
+ elif self.options.tool != None:
+ raise LaunchFailure('Invalid tool name "%s"' % (self.options.tool,))
+ cmd.extend(self.options.browser_flags)
+ cmd.append(url)
+ return cmd

Powered by Google App Engine
This is Rietveld 408576698