Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/python | 1 #!/usr/bin/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 import os | 6 import os |
| 7 import subprocess | 7 import subprocess |
| 8 import sys | 8 import sys |
| 9 import tempfile | 9 import tempfile |
| 10 import time | 10 import time |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 51 # crash_service.exe is not supposed to do this and such | 51 # crash_service.exe is not supposed to do this and such |
| 52 # behaviour should make the test fail. | 52 # behaviour should make the test fail. |
| 53 proc.terminate() | 53 proc.terminate() |
| 54 status = proc.wait() | 54 status = proc.wait() |
| 55 sys.stdout.write('crash_dump_tester: %s exited with status %s\n' | 55 sys.stdout.write('crash_dump_tester: %s exited with status %s\n' |
| 56 % (crash_service_exe, status)) | 56 % (crash_service_exe, status)) |
| 57 | 57 |
| 58 cleanup_funcs.append(Cleanup) | 58 cleanup_funcs.append(Cleanup) |
| 59 | 59 |
| 60 | 60 |
| 61 def GetDumpFiles(dumps_dir): | 61 def ListPathsInDir(dir_path): |
| 62 all_files = [os.path.join(dumps_dir, dump_file) | 62 if os.path.exists(dir_path): |
| 63 for dump_file in os.listdir(dumps_dir)] | 63 return [os.path.join(dir_path, name) |
| 64 for name in os.listdir(dir_path)] | |
| 65 else: | |
| 66 return [] | |
| 67 | |
| 68 | |
| 69 def GetDumpFiles(dumps_dirs): | |
| 70 all_files = [filename | |
| 71 for dumps_dir in dumps_dirs | |
| 72 for filename in ListPathsInDir(dumps_dir)] | |
| 64 sys.stdout.write('crash_dump_tester: Found %i files\n' % len(all_files)) | 73 sys.stdout.write('crash_dump_tester: Found %i files\n' % len(all_files)) |
| 65 for dump_file in all_files: | 74 for dump_file in all_files: |
| 66 sys.stdout.write(' %s\n' % dump_file) | 75 sys.stdout.write(' %s\n' % dump_file) |
| 67 return [dump_file for dump_file in all_files | 76 return [dump_file for dump_file in all_files |
| 68 if dump_file.endswith('.dmp')] | 77 if dump_file.endswith('.dmp')] |
| 69 | 78 |
| 70 | 79 |
| 71 def Main(cleanup_funcs): | 80 def Main(cleanup_funcs): |
| 72 parser = browser_tester.BuildArgParser() | 81 parser = browser_tester.BuildArgParser() |
| 73 parser.add_option('--expected_crash_dumps', dest='expected_crash_dumps', | 82 parser.add_option('--expected_crash_dumps', dest='expected_crash_dumps', |
| 74 type=int, default=0, | 83 type=int, default=0, |
| 75 help='The number of crash dumps that we should expect') | 84 help='The number of crash dumps that we should expect') |
| 76 parser.add_option('--expected_process_type_for_crash', | 85 parser.add_option('--expected_process_type_for_crash', |
| 77 dest='expected_process_type_for_crash', | 86 dest='expected_process_type_for_crash', |
| 78 type=str, default='nacl-loader', | 87 type=str, default='nacl-loader', |
| 79 help='The type of Chromium process that we expect the ' | 88 help='The type of Chromium process that we expect the ' |
| 80 'crash dump to be for') | 89 'crash dump to be for') |
| 81 # Ideally we would just query the OS here to find out whether we are | 90 # Ideally we would just query the OS here to find out whether we are |
| 82 # running x86-32 or x86-64 Windows, but Python's win32api module | 91 # running x86-32 or x86-64 Windows, but Python's win32api module |
| 83 # does not contain a wrapper for GetNativeSystemInfo(), which is | 92 # does not contain a wrapper for GetNativeSystemInfo(), which is |
| 84 # what NaCl uses to check this, or for IsWow64Process(), which is | 93 # what NaCl uses to check this, or for IsWow64Process(), which is |
| 85 # what Chromium uses. Instead, we just rely on the build system to | 94 # what Chromium uses. Instead, we just rely on the build system to |
| 86 # tell us. | 95 # tell us. |
| 87 parser.add_option('--win64', dest='win64', action='store_true', | 96 parser.add_option('--win64', dest='win64', action='store_true', |
| 88 help='Pass this if we are running tests for x86-64 Windows') | 97 help='Pass this if we are running tests for x86-64 Windows') |
| 89 options, args = parser.parse_args() | 98 options, args = parser.parse_args() |
| 90 | 99 |
| 91 dumps_dir = tempfile.mkdtemp(prefix='nacl_crash_dump_tester_') | 100 temp_dir = tempfile.mkdtemp(prefix='nacl_crash_dump_tester_') |
| 92 def CleanUpDumpsDir(): | 101 def CleanUpTempDir(): |
| 93 browsertester.browserlauncher.RemoveDirectory(dumps_dir) | 102 browsertester.browserlauncher.RemoveDirectory(temp_dir) |
| 94 cleanup_funcs.append(CleanUpDumpsDir) | 103 cleanup_funcs.append(CleanUpTempDir) |
| 95 | 104 |
| 96 # To get a guaranteed unique pipe name, use the base name of the | 105 # To get a guaranteed unique pipe name, use the base name of the |
| 97 # directory we just created. | 106 # directory we just created. |
| 98 windows_pipe_name = r'\\.\pipe\%s_crash_service' % os.path.basename(dumps_dir) | 107 windows_pipe_name = r'\\.\pipe\%s_crash_service' % os.path.basename(temp_dir) |
| 99 | 108 |
| 100 # This environment variable enables Breakpad crash dumping in | 109 # This environment variable enables Breakpad crash dumping in |
| 101 # non-official builds of Chromium. | 110 # non-official builds of Chromium. |
| 102 os.environ['CHROME_HEADLESS'] = '1' | 111 os.environ['CHROME_HEADLESS'] = '1' |
| 103 if sys.platform == 'win32': | 112 if sys.platform == 'win32': |
| 113 dumps_dir = temp_dir | |
| 104 # Override the default (global) Windows pipe name that Chromium will | 114 # Override the default (global) Windows pipe name that Chromium will |
| 105 # use for out-of-process crash reporting. | 115 # use for out-of-process crash reporting. |
| 106 os.environ['CHROME_BREAKPAD_PIPE_NAME'] = windows_pipe_name | 116 os.environ['CHROME_BREAKPAD_PIPE_NAME'] = windows_pipe_name |
| 107 # Launch the x86-32 crash service so that we can handle crashes in | 117 # Launch the x86-32 crash service so that we can handle crashes in |
| 108 # the browser process. | 118 # the browser process. |
| 109 StartCrashService(options.browser_path, dumps_dir, windows_pipe_name, | 119 StartCrashService(options.browser_path, dumps_dir, windows_pipe_name, |
| 110 cleanup_funcs, 'crash_service.exe') | 120 cleanup_funcs, 'crash_service.exe') |
| 111 if options.win64: | 121 if options.win64: |
| 112 # Launch the x86-64 crash service so that we can handle crashes | 122 # Launch the x86-64 crash service so that we can handle crashes |
| 113 # in the NaCl loader process (nacl64.exe). | 123 # in the NaCl loader process (nacl64.exe). |
| 114 StartCrashService(options.browser_path, dumps_dir, windows_pipe_name, | 124 StartCrashService(options.browser_path, dumps_dir, windows_pipe_name, |
| 115 cleanup_funcs, 'crash_service64.exe') | 125 cleanup_funcs, 'crash_service64.exe') |
| 116 # We add a delay because there is probably a race condition: | 126 # We add a delay because there is probably a race condition: |
| 117 # crash_service.exe might not have finished doing | 127 # crash_service.exe might not have finished doing |
| 118 # CreateNamedPipe() before NaCl does a crash dump and tries to | 128 # CreateNamedPipe() before NaCl does a crash dump and tries to |
| 119 # connect to that pipe. | 129 # connect to that pipe. |
| 120 # TODO(mseaborn): We could change crash_service.exe to report when | 130 # TODO(mseaborn): We could change crash_service.exe to report when |
| 121 # it has successfully created the named pipe. | 131 # it has successfully created the named pipe. |
| 122 time.sleep(1) | 132 time.sleep(1) |
| 123 elif sys.platform == 'darwin': | 133 elif sys.platform == 'darwin': |
| 134 dumps_dir = temp_dir | |
| 124 os.environ['BREAKPAD_DUMP_LOCATION'] = dumps_dir | 135 os.environ['BREAKPAD_DUMP_LOCATION'] = dumps_dir |
| 136 elif sys.platform == 'linux2': | |
|
Nick Bray (chromium)
2013/01/09 23:09:56
sys.platform.startwith('linux')? x2
Mark Seaborn
2013/01/10 00:48:28
OK, done.
| |
| 137 # The "--user-data-dir" option is not effective for the Breakpad | |
| 138 # setup in Linux Chromium, because Breakpad is initialized before | |
| 139 # "--user-data-dir" is read. So we set HOME to redirect the crash | |
| 140 # dumps to a temporary directory. | |
| 141 home_dir = temp_dir | |
| 142 os.environ['HOME'] = home_dir | |
| 143 # On Linux, we also need to set CHROME_ENABLE_BREAKPAD. | |
| 144 os.environ['CHROME_ENABLE_BREAKPAD'] = '1' | |
| 125 | 145 |
| 126 result = browser_tester.Run(options.url, options) | 146 result = browser_tester.Run(options.url, options) |
| 127 | 147 |
| 128 dmp_files = GetDumpFiles(dumps_dir) | 148 # Find crash dump results. |
| 149 if sys.platform == 'linux2': | |
| 150 # Look in "~/.config/*/Crash Reports". This will find crash | |
| 151 # reports under ~/.config/chromium or ~/.config/google-chrome, or | |
| 152 # under other subdirectories in case the branding is changed. | |
| 153 dumps_dirs = [os.path.join(path, 'Crash Reports') | |
| 154 for path in ListPathsInDir(os.path.join(home_dir, '.config'))] | |
| 155 else: | |
| 156 dumps_dirs = [dumps_dir] | |
| 157 dmp_files = GetDumpFiles(dumps_dirs) | |
| 158 | |
| 129 failed = False | 159 failed = False |
| 130 msg = ('crash_dump_tester: ERROR: Got %i crash dumps but expected %i\n' % | 160 msg = ('crash_dump_tester: ERROR: Got %i crash dumps but expected %i\n' % |
| 131 (len(dmp_files), options.expected_crash_dumps)) | 161 (len(dmp_files), options.expected_crash_dumps)) |
| 132 if len(dmp_files) != options.expected_crash_dumps: | 162 if len(dmp_files) != options.expected_crash_dumps: |
| 133 sys.stdout.write(msg) | 163 sys.stdout.write(msg) |
| 134 failed = True | 164 failed = True |
| 135 # On Windows, the crash dumps should come in pairs of a .dmp and | 165 # On Windows, the crash dumps should come in pairs of a .dmp and |
| 136 # .txt file. | 166 # .txt file. |
| 137 if sys.platform == 'win32': | 167 if sys.platform == 'win32': |
| 138 for dump_file in dmp_files: | 168 for dump_file in dmp_files: |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 171 cleanup_funcs = [] | 201 cleanup_funcs = [] |
| 172 try: | 202 try: |
| 173 return Main(cleanup_funcs) | 203 return Main(cleanup_funcs) |
| 174 finally: | 204 finally: |
| 175 for func in cleanup_funcs: | 205 for func in cleanup_funcs: |
| 176 func() | 206 func() |
| 177 | 207 |
| 178 | 208 |
| 179 if __name__ == '__main__': | 209 if __name__ == '__main__': |
| 180 sys.exit(MainWrapper()) | 210 sys.exit(MainWrapper()) |
| OLD | NEW |