OLD | NEW |
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """Collect debug info for a test.""" | 5 """Collect debug info for a test.""" |
6 | 6 |
7 import datetime | 7 import datetime |
8 import logging | 8 import logging |
9 import os | 9 import os |
10 import re | 10 import re |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 logging.info('Finish log dump.') | 127 logging.info('Finish log dump.') |
128 | 128 |
129 def TakeScreenshot(self, identifier_mark): | 129 def TakeScreenshot(self, identifier_mark): |
130 """Takes a screen shot from current specified device. | 130 """Takes a screen shot from current specified device. |
131 | 131 |
132 Args: | 132 Args: |
133 identifier_mark: A string to identify the screen shot DebugInfo will take. | 133 identifier_mark: A string to identify the screen shot DebugInfo will take. |
134 It will be part of filename of the screen shot. Empty | 134 It will be part of filename of the screen shot. Empty |
135 string is acceptable. | 135 string is acceptable. |
136 Returns: | 136 Returns: |
137 Returns True if successfully taking screen shot from device, otherwise | 137 Returns the file name on the host of the screenshot if successful, |
138 returns False. | 138 None otherwise. |
139 """ | 139 """ |
140 self.InitStorage() | 140 self.InitStorage() |
141 assert isinstance(identifier_mark, str) | 141 assert isinstance(identifier_mark, str) |
142 shot_path = os.path.join(self.log_dir, ''.join([self._GeneratePrefixName(), | 142 shot_path = os.path.join(self.log_dir, ''.join([self._GeneratePrefixName(), |
143 identifier_mark, | 143 identifier_mark, |
144 '_screenshot.png'])) | 144 '_screenshot.png'])) |
145 screenshot_path = os.path.join(os.getenv('ANDROID_HOST_OUT'), 'bin', | 145 screenshot_path = os.path.join(os.getenv('ANDROID_HOST_OUT'), 'bin', |
146 'screenshot2') | 146 'screenshot2') |
147 re_success = re.compile(re.escape('Success.'), re.MULTILINE) | 147 re_success = re.compile(re.escape('Success.'), re.MULTILINE) |
148 if re_success.findall(cmd_helper.GetCmdOutput([screenshot_path, '-s', | 148 if re_success.findall(cmd_helper.GetCmdOutput([screenshot_path, '-s', |
149 self.device, shot_path])): | 149 self.device, shot_path])): |
150 logging.info("Successfully took a screen shot to %s" % shot_path) | 150 logging.info("Successfully took a screen shot to %s" % shot_path) |
151 return True | 151 return shot_path |
152 logging.error('Failed to take screen shot from device %s' % self.device) | 152 logging.error('Failed to take screen shot from device %s' % self.device) |
153 return False | 153 return None |
154 | 154 |
155 def ListCrashFiles(self): | 155 def ListCrashFiles(self): |
156 """Collects crash files from current specified device. | 156 """Collects crash files from current specified device. |
157 | 157 |
158 Returns: | 158 Returns: |
159 A dict of crash files in format {"name": (size, lastmod), ...}. | 159 A dict of crash files in format {"name": (size, lastmod), ...}. |
160 """ | 160 """ |
161 if not self.collect_new_crashes: | 161 if not self.collect_new_crashes: |
162 return {} | 162 return {} |
163 return self.adb.ListPathContents(TOMBSTONE_DIR) | 163 return self.adb.ListPathContents(TOMBSTONE_DIR) |
164 | 164 |
165 def ArchiveNewCrashFiles(self): | 165 def ArchiveNewCrashFiles(self): |
166 """Archives the crash files newly generated until calling this method.""" | 166 """Archives the crash files newly generated until calling this method.""" |
167 if not self.collect_new_crashes: | 167 if not self.collect_new_crashes: |
168 return | 168 return |
169 current_crash_files = self.ListCrashFiles() | 169 current_crash_files = self.ListCrashFiles() |
170 files = [f for f in current_crash_files if f not in self.old_crash_files] | 170 files = [] |
171 logging.info('New crash file(s):%s' % ' '.join(files)) | 171 for f in current_crash_files: |
172 for f in files: | 172 if f not in self.old_crash_files: |
173 self.adb.Adb().Pull(TOMBSTONE_DIR + f, | 173 files += [f] |
174 os.path.join(self.GetStoragePath(), f)) | 174 elif current_crash_files[f] != self.old_crash_files[f]: |
| 175 # Tomestones dir can only have maximum 10 files, so we need to compare |
| 176 # size and timestamp information of file if the file exists. |
| 177 files += [f] |
| 178 if files: |
| 179 logging.info('New crash file(s):%s' % ' '.join(files)) |
| 180 for f in files: |
| 181 self.adb.Adb().Pull(TOMBSTONE_DIR + f, |
| 182 os.path.join(self.GetStoragePath(), f)) |
175 | 183 |
176 @staticmethod | 184 @staticmethod |
177 def ZipAndCleanResults(dest_dir, dump_file_name, debug_info_list): | 185 def ZipAndCleanResults(dest_dir, dump_file_name, debug_info_list): |
178 """A helper method to zip all debug information results into a dump file. | 186 """A helper method to zip all debug information results into a dump file. |
179 | 187 |
180 Args: | 188 Args: |
181 dest-dir: Dir path in where we put the dump file. | 189 dest-dir: Dir path in where we put the dump file. |
182 dump_file_name: Desired name of the dump file. This method makes sure | 190 dump_file_name: Desired name of the dump file. This method makes sure |
183 '.zip' will be added as ext name. | 191 '.zip' will be added as ext name. |
184 debug_info_list: List of all debug info objects. | 192 debug_info_list: List of all debug info objects. |
185 """ | 193 """ |
186 if not dest_dir or not dump_file_name or not debug_info_list: | 194 if not dest_dir or not dump_file_name or not debug_info_list: |
187 return | 195 return |
188 cmd_helper.RunCmd(['mkdir', '-p', dest_dir]) | 196 cmd_helper.RunCmd(['mkdir', '-p', dest_dir]) |
189 log_basename = os.path.basename(dump_file_name) | 197 log_basename = os.path.basename(dump_file_name) |
190 log_file = os.path.join(dest_dir, | 198 log_file = os.path.join(dest_dir, |
191 os.path.splitext(log_basename)[0] + '.zip') | 199 os.path.splitext(log_basename)[0] + '.zip') |
192 logging.info('Zipping debug dumps into %s ...' % log_file) | 200 logging.info('Zipping debug dumps into %s ...' % log_file) |
193 for d in debug_info_list: | 201 for d in debug_info_list: |
194 d.ArchiveNewCrashFiles() | 202 d.ArchiveNewCrashFiles() |
195 # Add new dumps into the zip file. The zip may exist already if previous | 203 # Add new dumps into the zip file. The zip may exist already if previous |
196 # gtest also dumps the debug information. It's OK since we clean up the old | 204 # gtest also dumps the debug information. It's OK since we clean up the old |
197 # dumps in each build step. | 205 # dumps in each build step. |
198 cmd_helper.RunCmd(['zip', '-q', '-r', log_file, | 206 cmd_helper.RunCmd(['zip', '-q', '-r', log_file, |
199 ' '.join([d.GetStoragePath() for d in debug_info_list])]) | 207 ' '.join([d.GetStoragePath() for d in debug_info_list])]) |
200 assert os.path.exists(log_file) | 208 assert os.path.exists(log_file) |
201 for debug_info in debug_info_list: | 209 for debug_info in debug_info_list: |
202 debug_info.CleanupStorage() | 210 debug_info.CleanupStorage() |
OLD | NEW |