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

Unified Diff: build/android/pylib/debug_info.py

Issue 11649008: Reorganize Android's test scripts into packages. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « build/android/pylib/apk_info.py ('k') | build/android/pylib/gtest/__init__.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: build/android/pylib/debug_info.py
diff --git a/build/android/pylib/debug_info.py b/build/android/pylib/debug_info.py
deleted file mode 100644
index 6f0f55a33f2eafa74dd38d4b5f9625aaf5ce2cc3..0000000000000000000000000000000000000000
--- a/build/android/pylib/debug_info.py
+++ /dev/null
@@ -1,196 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Collect debug info for a test."""
-
-import datetime
-import logging
-import os
-import re
-import shutil
-import string
-import subprocess
-import tempfile
-
-import cmd_helper
-
-
-TOMBSTONE_DIR = '/data/tombstones/'
-
-
-class GTestDebugInfo(object):
- """A helper class to collect related debug information for a gtest.
-
- Debug info is collected in two steps:
- - first, object(s) of this class (one per device), accumulate logs
- and screenshots in tempdir.
- - once the test has finished, call ZipAndCleanResults to create
- a zip containing the logs from all devices, and clean them up.
-
- Args:
- adb: ADB interface the tests are using.
- device: Serial# of the Android device in which the specified gtest runs.
- testsuite_name: Name of the specified gtest.
- gtest_filter: Test filter used by the specified gtest.
- """
-
- def __init__(self, adb, device, testsuite_name, gtest_filter):
- """Initializes the DebugInfo class for a specified gtest."""
- self.adb = adb
- self.device = device
- self.testsuite_name = testsuite_name
- self.gtest_filter = gtest_filter
- self.logcat_process = None
- self.has_storage = False
- self.log_dir = os.path.join(tempfile.gettempdir(),
- 'gtest_debug_info',
- self.testsuite_name,
- self.device)
- if not os.path.exists(self.log_dir):
- os.makedirs(self.log_dir)
- self.log_file_name = os.path.join(self.log_dir,
- self._GeneratePrefixName() + '_log.txt')
- self.old_crash_files = self._ListCrashFiles()
-
- def _GetSignatureFromGTestFilter(self):
- """Gets a signature from gtest_filter.
-
- Signature is used to identify the tests from which we collect debug
- information.
-
- Returns:
- A signature string. Returns 'all' if there is no gtest filter.
- """
- if not self.gtest_filter:
- return 'all'
- filename_chars = "-_()%s%s" % (string.ascii_letters, string.digits)
- signature = ''.join(c for c in self.gtest_filter if c in filename_chars)
- if len(signature) > 64:
- # The signature can't be too long, as it'll be part of a file name.
- signature = signature[:64]
- return signature
-
- def _GeneratePrefixName(self):
- """Generates a prefix name for debug information of the test.
-
- The prefix name consists of the following:
- (1) root name of test_suite_base.
- (2) device serial number.
- (3) prefix of filter signature generate from gtest_filter.
- (4) date & time when calling this method.
-
- Returns:
- Name of the log file.
- """
- return (os.path.splitext(self.testsuite_name)[0] + '_' + self.device + '_' +
- self._GetSignatureFromGTestFilter() + '_' +
- datetime.datetime.utcnow().strftime('%Y-%m-%d-%H-%M-%S-%f'))
-
- def StartRecordingLog(self, clear=True, filters=['*:v']):
- """Starts recording logcat output to a file.
-
- This call should come before running test, with calling StopRecordingLog
- following the tests.
-
- Args:
- clear: True if existing log output should be cleared.
- filters: A list of logcat filters to be used.
- """
- self.StopRecordingLog()
- if clear:
- cmd_helper.RunCmd(['adb', '-s', self.device, 'logcat', '-c'])
- logging.info('Start dumping log to %s ...', self.log_file_name)
- command = 'adb -s %s logcat -v threadtime %s > %s' % (self.device,
- ' '.join(filters),
- self.log_file_name)
- self.logcat_process = subprocess.Popen(command, shell=True)
-
- def StopRecordingLog(self):
- """Stops an existing logcat recording subprocess."""
- if not self.logcat_process:
- return
- # Cannot evaluate directly as 0 is a possible value.
- if self.logcat_process.poll() is None:
- self.logcat_process.kill()
- self.logcat_process = None
- logging.info('Finish log dump.')
-
- def TakeScreenshot(self, identifier_mark):
- """Takes a screen shot from current specified device.
-
- Args:
- identifier_mark: A string to identify the screen shot DebugInfo will take.
- It will be part of filename of the screen shot. Empty
- string is acceptable.
- Returns:
- Returns the file name on the host of the screenshot if successful,
- None otherwise.
- """
- assert isinstance(identifier_mark, str)
- screenshot_path = os.path.join(os.getenv('ANDROID_HOST_OUT', ''),
- 'bin',
- 'screenshot2')
- if not os.path.exists(screenshot_path):
- logging.error('Failed to take screen shot from device %s', self.device)
- return None
- shot_path = os.path.join(self.log_dir, ''.join([self._GeneratePrefixName(),
- identifier_mark,
- '_screenshot.png']))
- re_success = re.compile(re.escape('Success.'), re.MULTILINE)
- if re_success.findall(cmd_helper.GetCmdOutput([screenshot_path, '-s',
- self.device, shot_path])):
- logging.info('Successfully took a screen shot to %s', shot_path)
- return shot_path
- logging.error('Failed to take screen shot from device %s', self.device)
- return None
-
- def _ListCrashFiles(self):
- """Collects crash files from current specified device.
-
- Returns:
- A dict of crash files in format {"name": (size, lastmod), ...}.
- """
- return self.adb.ListPathContents(TOMBSTONE_DIR)
-
- def ArchiveNewCrashFiles(self):
- """Archives the crash files newly generated until calling this method."""
- current_crash_files = self._ListCrashFiles()
- files = []
- for f in current_crash_files:
- if f not in self.old_crash_files:
- files += [f]
- elif current_crash_files[f] != self.old_crash_files[f]:
- # Tombstones dir can only have maximum 10 files, so we need to compare
- # size and timestamp information of file if the file exists.
- files += [f]
- if files:
- logging.info('New crash file(s):%s' % ' '.join(files))
- for f in files:
- self.adb.Adb().Pull(TOMBSTONE_DIR + f,
- os.path.join(self.log_dir, f))
-
- @staticmethod
- def ZipAndCleanResults(dest_dir, dump_file_name):
- """A helper method to zip all debug information results into a dump file.
-
- Args:
- dest_dir: Dir path in where we put the dump file.
- dump_file_name: Desired name of the dump file. This method makes sure
- '.zip' will be added as ext name.
- """
- if not dest_dir or not dump_file_name:
- return
- cmd_helper.RunCmd(['mkdir', '-p', dest_dir])
- log_basename = os.path.basename(dump_file_name)
- log_zip_file = os.path.join(dest_dir,
- os.path.splitext(log_basename)[0] + '.zip')
- logging.info('Zipping debug dumps into %s ...', log_zip_file)
- # Add new dumps into the zip file. The zip may exist already if previous
- # gtest also dumps the debug information. It's OK since we clean up the old
- # dumps in each build step.
- log_src_dir = os.path.join(tempfile.gettempdir(), 'gtest_debug_info')
- cmd_helper.RunCmd(['zip', '-q', '-r', log_zip_file, log_src_dir])
- assert os.path.exists(log_zip_file)
- assert os.path.exists(log_src_dir)
- shutil.rmtree(log_src_dir)
« no previous file with comments | « build/android/pylib/apk_info.py ('k') | build/android/pylib/gtest/__init__.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698