diff options
author | maruel@chromium.org <maruel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-09 00:34:45 +0000 |
---|---|---|
committer | maruel@chromium.org <maruel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-09 00:34:45 +0000 |
commit | 0a88a6558d889d6352b9d547428bcfc963f6e67e (patch) | |
tree | f3f08f5494269642ac078b42cfecddd19a6491cb | |
parent | 94a0d258287787cf09854492ce889eb14273c059 (diff) | |
download | chromium_src-0a88a6558d889d6352b9d547428bcfc963f6e67e.zip chromium_src-0a88a6558d889d6352b9d547428bcfc963f6e67e.tar.gz chromium_src-0a88a6558d889d6352b9d547428bcfc963f6e67e.tar.bz2 |
Separate xvfb.py logic into its own script
Add --flags flag to isolate.py.
Fix issue with directory dependency.
R=rogerta@chromium.org,mark@chromium.org
BUG=117176
TEST="GYP_DEFINES=tests_run=run build/gyp_chromium; cd out/Debug; ninja base_unittests_run" work
Review URL: http://codereview.chromium.org/9621014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@125737 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | base/base.gyp | 30 | ||||
-rwxr-xr-x | testing/test_env.py | 36 | ||||
-rwxr-xr-x | testing/xvfb.py | 108 | ||||
-rwxr-xr-x | tools/isolate/isolate.py | 19 | ||||
-rw-r--r-- | tools/isolate/tree_creator.py | 2 |
5 files changed, 184 insertions, 11 deletions
diff --git a/base/base.gyp b/base/base.gyp index 2e98bf8..be9fda2 100644 --- a/base/base.gyp +++ b/base/base.gyp @@ -449,12 +449,14 @@ ], 'actions': [ { - 'action_name': 'isolate', + 'action_name': 'response_file', 'inputs': [ '<(PRODUCT_DIR)/base_unittests<(EXECUTABLE_SUFFIX)', + '<(DEPTH)/testing/test_env.py', + '<(DEPTH)/testing/xvfb.py', ], 'conditions': [ - ['OS != "mac" and OS != "win"', { + ['OS=="linux"', { 'inputs': [ '<(PRODUCT_DIR)/xdisplaycheck<(EXECUTABLE_SUFFIX)', ], @@ -467,6 +469,23 @@ }], ], 'outputs': [ + '<(PRODUCT_DIR)/base_unittests.inputs', + ], + 'action': [ + 'python', + '-c', + 'import sys; ' + 'open(sys.argv[1], \'w\').write(\'\\n\'.join(sys.argv[2:]))', + '<@(_outputs)', + '<@(_inputs)', + ], + }, + { + 'action_name': 'isolate', + 'inputs': [ + '<(PRODUCT_DIR)/base_unittests.inputs', + ], + 'outputs': [ '<(PRODUCT_DIR)/base_unittests.results', ], 'action': [ @@ -475,13 +494,18 @@ '--mode=<(tests_run)', '--root', '<(DEPTH)', '--result', '<@(_outputs)', - '<@(_inputs)', + '--files', '<@(_inputs)', # Directories can't be tracked by build tools (make, msbuild, xcode, # etc) so we just put it on the command line without specifying it # as an input. # TODO(maruel): Revisit the support for this at all and list each # individual test files instead. 'data/file_util_unittest/', + '--', + # Wraps base_unittests under xvfb. + '<(DEPTH)/testing/xvfb.py', + '<(PRODUCT_DIR)', + '<(PRODUCT_DIR)/base_unittests<(EXECUTABLE_SUFFIX)', ], }, ], diff --git a/testing/test_env.py b/testing/test_env.py new file mode 100755 index 0000000..f2a4f28 --- /dev/null +++ b/testing/test_env.py @@ -0,0 +1,36 @@ +#!/usr/bin/env 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. + +"""Sets environment variables needed to run a chromium unit test.""" + +import os +import subprocess +import sys + +# This is hardcoded to be src/ relative to this script. +ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + + +def run_executable(cmd, env): + """Runs an executable with: + - environment variable CR_SOURCE_ROOT set to the root directory. + - environment variable LANGUAGE to en_US.UTF-8. + - Reuses sys.executable automatically. + """ + # Many tests assume a English interface... + env['LANGUAGE'] = 'en_US.UTF-8' + # Used by base/base_paths_linux.cc + env['CR_SOURCE_ROOT'] = os.path.abspath(ROOT_DIR).encode('utf-8') + if cmd[0].endswith('.py'): + cmd.insert(0, sys.executable) + return subprocess.call(cmd, env=env) + + +def main(): + return run_executable(sys.argv[1:], os.environ.copy()) + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/testing/xvfb.py b/testing/xvfb.py new file mode 100755 index 0000000..a5cb7aa --- /dev/null +++ b/testing/xvfb.py @@ -0,0 +1,108 @@ +#!/usr/bin/env 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. + +"""Runs the test with xvfb on linux. Runs the test normally on other platforms. + +For simplicity in gyp targets, this script just runs the test normal on +non-linux platforms. +""" + +import os +import platform +import signal +import subprocess +import sys + +import test_env + + +def kill(pid): + """Kills a process and traps exception if the process doesn't exist anymore. + """ + # If the process doesn't exist, it raises an exception that we can ignore. + try: + os.kill(pid, signal.SIGKILL) + except OSError: + pass + + +def get_xvfb_path(server_dir): + """Figures out which X server to use.""" + xvfb_path = os.path.join(server_dir, 'Xvfb.' + platform.architecture()[0]) + if not os.path.exists(xvfb_path): + xvfb_path = os.path.join(server_dir, 'Xvfb') + if not os.path.exists(xvfb_path): + print >> sys.stderr, ( + 'No Xvfb found in designated server path: %s' % server_dir) + raise Exception('No virtual server') + return xvfb_path + + +def start_xvfb(xvfb_path, display): + """Starts a virtual X server that we run the tests in. + + This makes it so we can run the tests even if we didn't start the tests from + an X session. + + Args: + xvfb_path: Path to Xvfb. + """ + proc = subprocess.Popen( + [xvfb_path, display, '-screen', '0', '1024x768x24', '-ac'], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + return proc.pid + + +def wait_for_xvfb(xdisplaycheck, env): + """Waits for xvfb to be fully initialized by using xdisplaycheck.""" + try: + subprocess.check_call( + [xdisplaycheck], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + env=env) + except subprocess.CalledProcessError: + print >> sys.stderr, 'Xvfb failed to load properly.' + return False + return True + + +def run_executable(cmd, build_dir, env): + """Runs an executable within a xvfb buffer on linux or normally on other + platforms. + + Requires that both xvfb and icewm are installed on linux. + """ + pid = None + xvfb = 'Xvfb' + try: + if sys.platform == 'linux2': + # Defaults to X display 9. + display = ':9' + pid = start_xvfb(xvfb, display) + env['DISPLAY'] = display + if not wait_for_xvfb(os.path.join(build_dir, 'xdisplaycheck'), env): + return 3 + # Some ChromeOS tests need a window manager. Technically, it could be + # another script but that would be overkill. + subprocess.Popen( + 'icewm', stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=env) + return test_env.run_executable(cmd, env) + finally: + if pid: + kill(pid) + + +def main(): + if len(sys.argv) < 3: + print >> sys.stderr, ( + 'Usage: xvfb.py [path to build_dir] [command args...]') + return 2 + return run_executable(sys.argv[2:], sys.argv[1], os.environ.copy()) + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tools/isolate/isolate.py b/tools/isolate/isolate.py index d70296a..3e93b35 100755 --- a/tools/isolate/isolate.py +++ b/tools/isolate/isolate.py @@ -121,14 +121,10 @@ def run(outdir, resultfile, indir, infiles, read_only, cmd): if read_only: tree_creator.make_writable(outdir, True) - # TODO(maruel): Remove me. Layering violation. Used by - # base/base_paths_linux.cc - env = os.environ.copy() - env['CR_SOURCE_ROOT'] = outdir.encode() # Rebase the command to the right path. - cmd[0] = os.path.join(outdir, cmd[0]) - logging.info('Running %s' % cmd) - result = subprocess.call(cmd, cwd=outdir, env=env) + cwd = os.path.join(outdir, os.path.relpath(os.getcwd(), indir)) + logging.info('Running %s, cwd=%s' % (cmd, cwd)) + result = subprocess.call(cmd, cwd=cwd) if not result and resultfile: # Signal the build tool that the test succeeded. touch(resultfile) @@ -181,6 +177,9 @@ def main(): parser.add_option( '--read-only', action='store_true', help='Make the temporary tree read-only') + parser.add_option( + '--files', metavar='FILE', + help='File to be read containing input files') options, args = parser.parse_args() level = [logging.ERROR, logging.INFO, logging.DEBUG][min(2, options.verbose)] @@ -191,6 +190,12 @@ def main(): if not options.root: parser.error('--root is required.') + if options.files: + args = [ + i.decode('utf-8') + for i in open(options.files, 'rb').read().splitlines() if i + ] + args + infiles, cmd = separate_inputs_command(args, options.root) if not infiles: parser.error('Need at least one input file to map') diff --git a/tools/isolate/tree_creator.py b/tools/isolate/tree_creator.py index 9a7af1d..3c7e0c2 100644 --- a/tools/isolate/tree_creator.py +++ b/tools/isolate/tree_creator.py @@ -58,7 +58,7 @@ def preprocess_inputs(indir, infiles, blacklist): 'Input directory %s must have a trailing slash' % infile) for dirpath, dirnames, filenames in os.walk(infile): # Convert the absolute path to subdir + relative subdirectory. - relpath = dirpath[len(infile)+1:] + relpath = dirpath[len(indir)+1:] outfiles.extend(os.path.join(relpath, f) for f in filenames) for index, dirname in enumerate(dirnames): # Do not process blacklisted directories. |