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

Side by Side Diff: tools/isolate/isolate.py

Issue 9513003: Add target base_unittests_run and tools/isolate/isolate.py. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Working Created 8 years, 9 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 """Does one of the following depending on the --mode argument:
7 check verify all the inputs exist, touches the file specified with
8 --result and exits.
9 run recreates a tree with all the inputs files and run the executable
10 in it.
11 remap stores all the inputs files in a directory without running the
12 executable.
13 """
14
15 import logging
16 import optparse
17 import os
18 import re
19 import shutil
20 import subprocess
21 import sys
22 import tempfile
23 import time
24
25 import tree_creator
26
27
28 def touch(filename):
29 """Implements the equivalent of the 'touch' command."""
30 if not os.path.exists(filename):
31 open(filename, 'a').close()
32 os.utime(filename, None)
33
34
35 def rmtree(root):
36 if sys.platform == 'win32':
37 for i in range(3):
38 try:
39 shutil.rmtree(root)
40 break
41 except WindowsError: # pylint: disable=E0602
42 delay = (i+1)*2
43 print >> sys.stderr, (
44 'The test has subprocess outliving it. Sleep %d seconds.' % delay)
45 time.sleep(delay)
46 else:
47 shutil.rmtree(root)
48
49
50 def isolate(outdir, root, resultfile, mode, read_only, args):
51 cmd = []
52 if '--' in args:
53 # Strip off the command line from the inputs.
54 i = args.index('--')
55 cmd = args[i+1:]
56 args = args[:i]
57
58 # gyp provides paths relative to cwd. Convert them to be relative to
59 # root.
60 cwd = os.getcwd()
61
62 def make_relpath(i):
63 """Makes an input file a relative path but keeps any trailing slash."""
64 out = os.path.relpath(os.path.join(cwd, i), root)
65 if i.endswith('/'):
66 out += '/'
67 return out
68
69 infiles = [make_relpath(i) for i in args]
70
71 if not infiles:
72 raise ValueError('Need at least one input file to map')
73
74 # Other modes ignore the command.
75 if mode == 'run' and not cmd:
76 print >> sys.stderr, 'Using first input %s as executable' % infiles[0]
77 cmd = [infiles[0]]
78
79 tempdir = None
80 try:
81 if not outdir and mode != 'check':
82 tempdir = tempfile.mkdtemp(prefix='isolate')
83 outdir = tempdir
84 elif outdir:
85 outdir = os.path.abspath(outdir)
86
87 tree_creator.recreate_tree(
88 outdir,
89 os.path.abspath(root),
90 infiles,
91 tree_creator.DRY_RUN if mode == 'check' else tree_creator.HARDLINK,
92 lambda x: re.match(r'.*\.(svn|pyc)$', x))
93
94 if mode != 'check' and read_only:
95 tree_creator.make_writable(outdir, True)
96
97 if mode in ('check', 'remap'):
98 result = 0
99 else:
100 # TODO(maruel): Remove me. Layering violation. Used by
101 # base/base_paths_linux.cc
102 env = os.environ.copy()
103 env['CR_SOURCE_ROOT'] = outdir.encode()
104 # Rebase the command to the right path.
105 cmd[0] = os.path.join(outdir, cmd[0])
106 logging.info('Running %s' % cmd)
107 result = subprocess.call(cmd, cwd=outdir, env=env)
108
109 if not result and resultfile:
110 # Signal the build tool that the test succeeded.
111 touch(resultfile)
112 return result
113 finally:
114 if tempdir and mode == 'isolate':
115 if read_only:
116 tree_creator.make_writable(tempdir, False)
117 rmtree(tempdir)
118
119
120 def main():
121 parser = optparse.OptionParser(
122 usage='%prog [options] [inputs] -- [command line]',
123 description=sys.modules[__name__].__doc__)
124 parser.allow_interspersed_args = False
125 parser.format_description = lambda *_: parser.description
126 parser.add_option(
127 '-v', '--verbose', action='count', default=0, help='Use multiple times')
128 parser.add_option(
129 '--mode', choices=['remap', 'check', 'run'],
130 help='Determines the action to be taken')
131 parser.add_option(
132 '--result', metavar='X',
133 help='File to be touched when the command succeeds')
134 parser.add_option('--root', help='Base directory to fetch files, required')
135 parser.add_option(
136 '--outdir', metavar='X',
137 help='Directory used to recreate the tree. Defaults to a /tmp '
138 'subdirectory')
139 parser.add_option(
140 '--read-only', action='store_true',
141 help='Make the temporary tree read-only')
142
143 options, args = parser.parse_args()
144 level = [logging.ERROR, logging.INFO, logging.DEBUG][min(2, options.verbose)]
145 logging.basicConfig(
146 level=level,
147 format='%(levelname)5s %(module)15s(%(lineno)3d): %(message)s')
148
149 if not options.root:
150 parser.error('--root is required.')
151
152 try:
153 return isolate(
154 options.outdir,
155 options.root,
156 options.result,
157 options.mode,
158 options.read_only,
159 args)
160 except ValueError, e:
161 parser.error(str(e))
162
163
164 if __name__ == '__main__':
165 sys.exit(main())
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698