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 |