def test_begin(self): """Call this when the test begins execution. Sets the begin_time of this record. """ self.begin_time = utils.get_current_epoch_time() self.signature = '%s-%s' % (self.test_name, self.begin_time)
def _test_end(self, result, e): """Marks the end of the test logic. Args: result: One of the TEST_RESULT enums in TestResultEnums. e: A test termination signal (usually an exception object). It can be any exception instance or of any subclass of mobly.signals.TestSignal. """ if self.begin_time is not None: self.end_time = utils.get_current_epoch_time() self.result = result if e: self.termination_signal = ExceptionRecord(e)
def set_status_code(self, status_code_line): """Sets the status code for the instrumentation test method, used in determining the test result. Args: status_code_line: string, the raw instrumentation output line that contains the status code of the instrumentation block. """ self._empty = False self.status_code = self._remove_structure_prefix( _InstrumentationStructurePrefixes.STATUS_CODE, status_code_line, ) if self.status_code == _InstrumentationStatusCodes.START: self.begin_time = utils.get_current_epoch_time()
def _test_end(self, result, e): """Class internal function to signal the end of a test case execution. Args: result: One of the TEST_RESULT enums in TestResultEnums. e: A test termination signal (usually an exception object). It can be any exception instance or of any subclass of mobly.signals.TestSignal. """ self.end_time = utils.get_current_epoch_time() self.result = result if self.extra_errors: self.result = TestResultEnums.TEST_RESULT_ERROR if isinstance(e, signals.TestSignal): self.details = e.details self.extras = e.extras elif e: self.details = str(e)
def record_data(self, content): """Record an entry in test summary file. Sometimes additional data need to be recorded in summary file for debugging or post-test analysis. Each call adds a new entry to the summary file, with no guarantee of its position among the summary file entries. The content should be a dict. If absent, timestamp field is added for ease of parsing later. Args: content: dict, the data to add to summary file. """ if 'timestamp' not in content: content['timestamp'] = utils.get_current_epoch_time() self.summary_writer.dump(content, records.TestSummaryEntryType.USER_DATA)
def _test_end(self, result, e): """Class internal function to signal the end of a test execution. Args: result: One of the TEST_RESULT enums in TestResultEnums. e: A test termination signal (usually an exception object). It can be any exception instance or of any subclass of mobly.signals.TestSignal. """ self.end_time = utils.get_current_epoch_time() self.result = result if self.extra_errors: self.result = TestResultEnums.TEST_RESULT_ERROR if isinstance(e, signals.TestSignal): self.details = e.details _, _, exc_traceback = sys.exc_info() if exc_traceback: self.stacktrace = ''.join(traceback.format_tb(exc_traceback)) self.extras = e.extras elif isinstance(e, Exception): self.details = str(e) _, _, exc_traceback = sys.exc_info() if exc_traceback: self.stacktrace = ''.join(traceback.format_tb(exc_traceback))
def test_begin(self): """Call this when the test begins execution. Sets the begin_time of this record. """ self.begin_time = utils.get_current_epoch_time()
def take_bug_report(self, test_name=None, begin_time=None, timeout=300, destination=None): """Takes a bug report on the device and stores it in a file. Args: test_name: Name of the test method that triggered this bug report. If not set, then this will default to android_device.DEFAULT_BUG_REPORT_NAME. begin_time: Timestamp of when the test started. If not set, then this will default to the current time. timeout: float, the number of seconds to wait for bugreport to complete, default is 5min. destination: string, path to the directory where the bugreport should be saved. Returns: A string containing the absolute path to the bug report on the host machine. """ if test_name is None: test_name = DEFAULT_BUG_REPORT_NAME if begin_time is None: epoch_time = utils.get_current_epoch_time() timestamp = mobly_logger.epoch_to_log_line_timestamp(epoch_time) begin_time = mobly_logger.normalize_log_line_timestamp(timestamp) new_br = True try: stdout = self.adb.shell('bugreportz -v').decode('utf-8') # This check is necessary for builds before N, where adb shell's ret # code and stderr are not propagated properly. if 'not found' in stdout: new_br = False except adb.AdbError: new_br = False if destination: br_path = utils.abs_path(destination) else: br_path = os.path.join(self.log_path, 'BugReports') utils.create_dir(br_path) base_name = ',%s,%s.txt' % (begin_time, self._normalized_serial) if new_br: base_name = base_name.replace('.txt', '.zip') test_name_len = utils.MAX_FILENAME_LEN - len(base_name) out_name = test_name[:test_name_len] + base_name full_out_path = os.path.join(br_path, out_name.replace(' ', r'\ ')) # in case device restarted, wait for adb interface to return self.wait_for_boot_completion() self.log.info('Taking bugreport for %s.', test_name) if new_br: out = self.adb.shell('bugreportz', timeout=timeout).decode('utf-8') if not out.startswith('OK'): raise DeviceError(self, 'Failed to take bugreport: %s' % out) br_out_path = out.split(':')[1].strip() self.adb.pull([br_out_path, full_out_path]) else: # shell=True as this command redirects the stdout to a local file # using shell redirection. self.adb.bugreport(' > "%s"' % full_out_path, shell=True, timeout=timeout) self.log.info('Bugreport for %s taken at %s.', test_name, full_out_path) return full_out_path