def crash_check_test(self): failure = 0 while time.time() < self.finishing_time: self.dut.log.info(dict(self.result_info)) try: begin_time = epoch_to_log_line_timestamp( get_current_epoch_time()) time.sleep(self.crash_check_interval) crash_report = self.dut.check_crash_report("checking_crash", begin_time, True) if crash_report: self.dut.log.error("Find new crash reports %s", crash_report) failure += 1 self.result_info["Crashes"] += 1 except IGNORE_EXCEPTIONS as e: self.log.error("Exception error %s", str(e)) self.result_info["Exception Errors"] += 1 if self.result_info["Exception Errors"] > EXCEPTION_TOLERANCE: self.finishing_time = time.time() raise except Exception as e: self.finishing_time = time.time() raise self.dut.log.info("Crashes found: %s", failure) if failure: return "%s crashes" % failure else: return ""
def start_tcpdump(ad, test_name): """Start tcpdump on all interfaces Args: ad: android device object. test_name: tcpdump file name will have this """ ad.log.info("Starting tcpdump on all interfaces") try: ad.adb.shell("killall -9 tcpdump") except AdbError: ad.log.warn("Killing existing tcpdump processes failed") out = ad.adb.shell("ls -l %s" % TCPDUMP_PATH) if "No such file" in out or not out: ad.adb.shell("mkdir %s" % TCPDUMP_PATH) else: ad.adb.shell("rm -rf %s/*" % TCPDUMP_PATH, ignore_status=True) begin_time = epoch_to_log_line_timestamp(get_current_epoch_time()) begin_time = normalize_log_line_timestamp(begin_time) file_name = "%s/tcpdump_%s_%s.pcap" % (TCPDUMP_PATH, ad.serial, test_name) ad.log.info("tcpdump file is %s", file_name) cmd = "adb -s {} shell tcpdump -i any -s0 -w {}".format( ad.serial, file_name) try: return start_standing_subprocess(cmd, 5) except Exception: ad.log.exception('Could not start standing process %s' % repr(cmd)) return None
def _pull_diag_logs(self, test_name, begin_time): for (mylogger, session) in self.logger_sessions: self.log.info("Pulling diagnostic session %s", mylogger) mylogger.stop(session) diag_path = os.path.join( self.log_path, logger.epoch_to_log_line_timestamp(begin_time)) os.makedirs(diag_path, exist_ok=True) mylogger.pull(session, diag_path)
def test_begin(self): """Call this when the test case it records begins execution. Sets the begin_time of this record. """ super().test_begin() self.log_begin_time = logger.epoch_to_log_line_timestamp( self.begin_time)
def _on_exception(self, record): """Proxy function to guarantee the base implementation of on_exception is called. Args: record: The records.TestResultRecord object for the failed test case. """ test_name = record.test_name self.log.exception(record.details) begin_time = logger.epoch_to_log_line_timestamp(record.begin_time) self.on_exception(test_name, begin_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 acts.signals.TestSignal. """ super()._test_end(result, e) if self.end_time: self.log_end_time = logger.epoch_to_log_line_timestamp( self.end_time)
def _on_skip(self, record): """Proxy function to guarantee the base implementation of on_skip is called. Args: record: The records.TestResultRecord object for the skipped test case. """ test_name = record.test_name begin_time = logger.epoch_to_log_line_timestamp(record.begin_time) self.log.info(RESULT_LINE_TEMPLATE, test_name, record.result) self.log.info("Reason to skip: %s", record.details) self.on_skip(test_name, begin_time)
def _on_fail(self, record): """Proxy function to guarantee the base implementation of on_fail is called. Args: record: The records.TestResultRecord object for the failed test case. """ test_name = record.test_name if record.details: self.log.error(record.details) begin_time = logger.epoch_to_log_line_timestamp(record.begin_time) self.log.info(RESULT_LINE_TEMPLATE, test_name, record.result) self.on_fail(test_name, begin_time)
def _on_pass(self, record): """Proxy function to guarantee the base implementation of on_pass is called. Args: record: The records.TestResultRecord object for the passed test case. """ test_name = record.test_name begin_time = logger.epoch_to_log_line_timestamp(record.begin_time) msg = record.details if msg: self.log.info(msg) self.log.info(RESULT_LINE_TEMPLATE, test_name, record.result) self.on_pass(test_name, begin_time)
def take_bug_report(self, test_name, begin_time, additional_log_objects=None): """Takes a bug report on the device and stores it in a file. Args: test_name: Name of the test case that triggered this bug report. begin_time: Epoch time when the test started. additional_log_objects: A list of additional objects in Fuchsia to query in the bug report. Must be in the following format: /hub/c/scenic.cmx/[0-9]*/out/objects """ if not additional_log_objects: additional_log_objects = [] log_items = [] matching_log_items = FUCHSIA_DEFAULT_LOG_ITEMS for additional_log_object in additional_log_objects: if additional_log_object not in matching_log_items: matching_log_items.append(additional_log_object) br_path = context.get_current_context().get_full_output_path() os.makedirs(br_path, exist_ok=True) time_stamp = acts_logger.normalize_log_line_timestamp( acts_logger.epoch_to_log_line_timestamp(begin_time)) out_name = "FuchsiaDevice%s_%s" % ( self.serial, time_stamp.replace(" ", "_").replace(":", "-")) out_name = "%s.txt" % out_name full_out_path = os.path.join(br_path, out_name) self.log.info("Taking bugreport for %s on FuchsiaDevice%s." % (test_name, self.serial)) system_objects = self.send_command_ssh('iquery --find /hub').stdout system_objects = system_objects.split() for matching_log_item in matching_log_items: for system_object in system_objects: if re.match(matching_log_item, system_object): log_items.append(system_object) log_command = '%s %s' % (FUCHSIA_DEFAULT_LOG_CMD, ' '.join(log_items)) bug_report_data = self.send_command_ssh(log_command).stdout bug_report_file = open(full_out_path, 'w') bug_report_file.write(bug_report_data) bug_report_file.close()
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 acts.signals.TestSignal. """ self.end_time = utils.get_current_epoch_time() self.log_end_time = logger.epoch_to_log_line_timestamp(self.end_time) self.result = result if self.extra_errors: self.result = TestResultEnums.TEST_RESULT_UNKNOWN if isinstance(e, signals.TestSignal): self.details = e.details self.extras = e.extras elif e: self.details = str(e)
def take_bt_snoop_log(self, custom_name=None): """Takes a the bt-snoop log from the device and stores it in a file in a pcap format. """ bt_snoop_path = context.get_current_context().get_full_output_path() time_stamp = acts_logger.normalize_log_line_timestamp( acts_logger.epoch_to_log_line_timestamp(time.time())) out_name = "FuchsiaDevice%s_%s" % ( self.serial, time_stamp.replace(" ", "_").replace(":", "-")) out_name = "%s.pcap" % out_name if custom_name: out_name = "%s.pcap" % custom_name else: out_name = "%s.pcap" % out_name full_out_path = os.path.join(bt_snoop_path, out_name) bt_snoop_data = self.send_command_ssh('bt-snoop-cli -d -f pcap').stdout bt_snoop_file = open(full_out_path, 'w') bt_snoop_file.write(bt_snoop_data) bt_snoop_file.close()
def dumpsys_last_call_info(ad): """ Get call information by dumpsys telecom. """ num = dumpsys_last_call_number(ad) output = ad.adb.shell("dumpsys telecom") result = re.search(r"Call TC@%s: {(.*?)}" % num, output, re.DOTALL) call_info = {"TC": num} if result: result = result.group(1) for attr in ("startTime", "endTime", "direction", "isInterrupted", "callTechnologies", "callTerminationsReason", "isVideoCall", "callProperties"): match = re.search(r"%s: (.*)" % attr, result) if match: if attr in ("startTime", "endTime"): call_info[attr] = epoch_to_log_line_timestamp( int(match.group(1))) else: call_info[attr] = match.group(1) ad.log.debug("call_info = %s", call_info) return call_info
import os import shutil import tempfile import unittest from acts import logger from acts.controllers import android_device from acts.controllers.android_lib import errors # Mock log path for a test run. MOCK_LOG_PATH = "/tmp/logs/MockTest/xx-xx-xx_xx-xx-xx/" # Mock start and end time of the adb cat. MOCK_ADB_EPOCH_BEGIN_TIME = 191000123 MOCK_ADB_LOGCAT_BEGIN_TIME = logger.normalize_log_line_timestamp( logger.epoch_to_log_line_timestamp(MOCK_ADB_EPOCH_BEGIN_TIME)) MOCK_ADB_LOGCAT_END_TIME = "1970-01-02 21:22:02.000" MOCK_SERIAL = 1 MOCK_RELEASE_BUILD_ID = "ABC1.123456.007" MOCK_DEV_BUILD_ID = "ABC-MR1" MOCK_NYC_BUILD_ID = "N4F27P" def get_mock_ads(num): """Generates a list of mock AndroidDevice objects. The serial number of each device will be integer 0 through num - 1. Args: num: An integer that is the number of mock AndroidDevice objects to
def test_epoch_to_log_line_timestamp(self): os.environ['TZ'] = 'US/Pacific' time.tzset() actual_stamp = logger.epoch_to_log_line_timestamp(1469134262116) self.assertEqual("2016-07-21 13:51:02.116", actual_stamp)
def test_epoch_to_log_line_timestamp(self): actual_stamp = logger.epoch_to_log_line_timestamp(1469134262116) self.assertEqual("07-21 13:51:02.116", actual_stamp)