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

Side by Side Diff: testing/test_env.py

Issue 865853009: Symbolize JSON output snippets in swarming ASan runs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Sets environment variables needed to run a chromium unit test.""" 6 """Sets environment variables needed to run a chromium unit test."""
7 7
8 import os 8 import os
9 import stat 9 import stat
10 import subprocess 10 import subprocess
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 if sys.platform == 'darwin': 98 if sys.platform == 'darwin':
99 isolate_output_dir = os.path.abspath(os.path.dirname(cmd[0])) 99 isolate_output_dir = os.path.abspath(os.path.dirname(cmd[0]))
100 # This is needed because the test binary has @executable_path embedded in it 100 # This is needed because the test binary has @executable_path embedded in it
101 # it that the OS tries to resolve to the cache directory and not the mapped 101 # it that the OS tries to resolve to the cache directory and not the mapped
102 # directory. 102 # directory.
103 extra_env['DYLD_LIBRARY_PATH'] = str(isolate_output_dir) 103 extra_env['DYLD_LIBRARY_PATH'] = str(isolate_output_dir)
104 104
105 return extra_env 105 return extra_env
106 106
107 107
108 def get_sanitizer_symbolize_command(json_path=None):
109 """Construct the command to invoke offline symbolization script."""
110 script_path = '../tools/valgrind/asan/asan_symbolize.py'
111 cmd = [sys.executable, script_path]
112 if json_path is not None:
113 cmd.append('--test-summary-json-file=%s' % json_path)
114 return cmd
115
116
117 def get_json_path(cmd):
118 """Extract the JSON test summary path from a command line."""
119 json_path_flag = '--test-launcher-summary-output='
120 for arg in cmd:
121 if arg.startswith(json_path_flag):
122 return arg.split(json_path_flag).pop()
123 return None
124
125
126 def symbolize_snippets_in_json(cmd, env):
127 """Symbolize output snippets inside the JSON test summary."""
128 json_path = get_json_path(cmd)
129 if json_path is None:
130 return
131
132 try:
133 symbolize_command = get_sanitizer_symbolize_command(json_path=json_path)
134 p = subprocess.Popen(symbolize_command, stderr=subprocess.PIPE, env=env)
135 (_, stderr) = p.communicate()
136 except OSError as e:
137 print 'Exception while symbolizing snippets: %s' % e
138
139 if p.returncode != 0:
140 print "Error: failed to symbolize snippets in JSON:\n"
141 print stderr
142
143
108 def run_executable(cmd, env): 144 def run_executable(cmd, env):
109 """Runs an executable with: 145 """Runs an executable with:
110 - environment variable CR_SOURCE_ROOT set to the root directory. 146 - environment variable CR_SOURCE_ROOT set to the root directory.
111 - environment variable LANGUAGE to en_US.UTF-8. 147 - environment variable LANGUAGE to en_US.UTF-8.
112 - environment variable CHROME_DEVEL_SANDBOX set 148 - environment variable CHROME_DEVEL_SANDBOX set
113 - Reuses sys.executable automatically. 149 - Reuses sys.executable automatically.
114 """ 150 """
115 extra_env = {} 151 extra_env = {}
116 # Many tests assume a English interface... 152 # Many tests assume a English interface...
117 extra_env['LANG'] = 'en_US.UTF-8' 153 extra_env['LANG'] = 'en_US.UTF-8'
118 # Used by base/base_paths_linux.cc as an override. Just make sure the default 154 # Used by base/base_paths_linux.cc as an override. Just make sure the default
119 # logic is used. 155 # logic is used.
120 env.pop('CR_SOURCE_ROOT', None) 156 env.pop('CR_SOURCE_ROOT', None)
121 extra_env.update(get_sandbox_env(env)) 157 extra_env.update(get_sandbox_env(env))
122 158
123 # Copy logic from tools/build/scripts/slave/runtest.py. 159 # Copy logic from tools/build/scripts/slave/runtest.py.
124 asan = '--asan=1' in cmd 160 asan = '--asan=1' in cmd
125 lsan = '--lsan=1' in cmd 161 lsan = '--lsan=1' in cmd
162 use_symbolization_script = asan and not lsan
126 163
127 if asan: 164 if asan:
128 extra_env.update(get_asan_env(cmd, lsan)) 165 extra_env.update(get_asan_env(cmd, lsan))
129 # ASan is not yet sandbox-friendly on Windows (http://crbug.com/382867). 166 # ASan is not yet sandbox-friendly on Windows (http://crbug.com/382867).
130 if sys.platform == 'win32': 167 if sys.platform == 'win32':
131 cmd.append('--no-sandbox') 168 cmd.append('--no-sandbox')
132 if lsan: 169 if lsan:
133 cmd.append('--no-sandbox') 170 cmd.append('--no-sandbox')
134 171
135 cmd = trim_cmd(cmd) 172 cmd = trim_cmd(cmd)
136 173
137 # Ensure paths are correctly separated on windows. 174 # Ensure paths are correctly separated on windows.
138 cmd[0] = cmd[0].replace('/', os.path.sep) 175 cmd[0] = cmd[0].replace('/', os.path.sep)
139 cmd = fix_python_path(cmd) 176 cmd = fix_python_path(cmd)
140 177
141 print('Additional test environment:\n%s\n' 178 print('Additional test environment:\n%s\n'
142 'Command: %s\n' % ( 179 'Command: %s\n' % (
143 '\n'.join(' %s=%s' % 180 '\n'.join(' %s=%s' %
144 (k, v) for k, v in sorted(extra_env.iteritems())), 181 (k, v) for k, v in sorted(extra_env.iteritems())),
145 ' '.join(cmd))) 182 ' '.join(cmd)))
146 env.update(extra_env or {}) 183 env.update(extra_env or {})
147 try: 184 try:
148 # See above comment regarding offline symbolization. 185 # See above comment regarding offline symbolization.
149 if asan and not lsan: 186 if use_symbolization_script:
150 # Need to pipe to the symbolizer script. 187 # Need to pipe to the symbolizer script.
151 p1 = subprocess.Popen(cmd, env=env, stdout=subprocess.PIPE, 188 p1 = subprocess.Popen(cmd, env=env, stdout=subprocess.PIPE,
152 stderr=sys.stdout) 189 stderr=sys.stdout)
153 p2 = subprocess.Popen([sys.executable, 190 p2 = subprocess.Popen(get_sanitizer_symbolize_command(),
154 "../tools/valgrind/asan/asan_symbolize.py"],
155 env=env, stdin=p1.stdout) 191 env=env, stdin=p1.stdout)
156 p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits. 192 p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits.
157 p1.wait() 193 p1.wait()
158 p2.wait() 194 p2.wait()
195 # Also feed the out-of-band JSON output to the symbolizer script.
196 symbolize_snippets_in_json(cmd, env)
159 return p1.returncode 197 return p1.returncode
160 else: 198 else:
161 return subprocess.call(cmd, env=env) 199 return subprocess.call(cmd, env=env)
162 except OSError: 200 except OSError:
163 print >> sys.stderr, 'Failed to start %s' % cmd 201 print >> sys.stderr, 'Failed to start %s' % cmd
164 raise 202 raise
165 203
166 204
167 def main(): 205 def main():
168 return run_executable(sys.argv[1:], os.environ.copy()) 206 return run_executable(sys.argv[1:], os.environ.copy())
169 207
170 208
171 if __name__ == '__main__': 209 if __name__ == '__main__':
172 sys.exit(main()) 210 sys.exit(main())
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698