def _pull_diag_logs(self, test_name, begin_time):
     for (logger, session) in self.logger_sessions:
         self.log.info("Pulling diagnostic session {}".format(logger))
         logger.stop(session)
         diag_path = os.path.join(self.log_path, begin_time)
         utils.create_dir(diag_path)
         logger.pull(session, diag_path)
示例#2
0
def take_btsnoop_log(ad, testcase, testname):
    """Grabs the btsnoop_hci log on a device and stores it in the log directory
    of the test class.

    If you want grab the btsnoop_hci log, call this function with android_device
    objects in on_fail. Bug report takes a relative long time to take, so use
    this cautiously.

    Args:
        ad: The android_device instance to take bugreport on.
        testcase: Name of the test calss that triggered this snoop log.
        testname: Name of the test case that triggered this bug report.
    """
    testname = "".join(x for x in testname if x.isalnum())
    serial = ad.droid.getBuildSerial()
    device_model = ad.droid.getBuildModel()
    device_model = device_model.replace(" ", "")
    out_name = ','.join((testname, device_model, serial))
    snoop_path = ad.log_path + "/BluetoothSnoopLogs"
    utils.create_dir(snoop_path)
    cmd = ''.join(("adb -s ", serial, " pull /sdcard/btsnoop_hci.log ",
                   snoop_path + '/' + out_name, ".btsnoop_hci.log"))
    testcase.log.info(
        "Test failed, grabbing the bt_snoop logs on {} {}.".format(
            device_model, serial))
    exe_cmd(cmd)
示例#3
0
 def _take_bug_report(self, test_name, begin_time):
     test_log_path = os.path.join(self.log_path, test_name)
     utils.create_dir(test_log_path)
     # Extract test_run_info.txt, test_run_detail.txt
     for file_name in ("test_run_info.txt", "test_run_details.txt"):
         extract_test_log(
             self.log, os.path.join(self.log_path, file_name),
             os.path.join(test_log_path, "%s_%s" % (test_name, file_name)),
             "\[Test Case\] %s " % test_name)
     if self._skip_bug_report():
         return
     dev_num = getattr(self, "number_of_devices", None) or len(
         self.android_devices)
     tasks = [(self._ad_take_bugreport, (ad, test_name, begin_time))
              for ad in self.android_devices[:dev_num]]
     tasks.extend([(self._ad_take_extra_logs, (ad, test_name, begin_time))
                   for ad in self.android_devices[:dev_num]])
     run_multithread_func(self.log, tasks)
     for ad in self.android_devices[:dev_num]:
         if getattr(ad, "reboot_to_recover", False):
             reboot_device(ad)
             ad.reboot_to_recover = False
     # Zip log folder
     if not self.user_params.get("zip_log", False): return
     src_dir = os.path.join(self.log_path, test_name)
     file_name = "%s_%s" % (src_dir, begin_time)
     self.log.info("Zip folder %s to %s.zip", src_dir, file_name)
     shutil.make_archive(file_name, "zip", src_dir)
     shutil.rmtree(src_dir)
 def __init__(self, profile, password, log_path):
     devices = {}
     self.device_interface = False
     self.mainloop = 0
     self.property_changed = False
     self.bd_address = None
     self.list_daemon = ["dbus", "bluez"]
     self.log_path = os.path.join(log_path, "bluez")
     create_dir(self.log_path)
     self.sudo_command = "echo " + password + " | sudo -S "
     if profile.lower() == "hfp":
         self.list_daemon.append("ofonod")
     elif profile.lower() == "a2dp":
         self.list_daemon.append("pulseaudio")
     elif profile.lower() == "multiprofile":
         self.list_daemon.extend(["pulseaudio", "ofonod"])
     if not self.hci_config("up"):
         logging.error("Can't get device info: No such device")
     self.run_daemons()
     self.bus = dbus.SystemBus()
     self.bus.add_signal_receiver(
         self.properties_changed,
         dbus_interface=DBUS_INTERFACE,
         signal_name=PROPERTIES_CHANGED,
         arg0=DEVICE_INTERFACE,
         path_keyword="path")
     self.om = dbus.Interface(
         self.bus.get_object(SERVICE_NAME, "/"), OBJECT_MANGER)
     objects = self.om.GetManagedObjects()
     for path, interfaces in objects.items():
         if ADAPTER_INTERFACE in interfaces:
             devices[path] = interfaces[ADAPTER_INTERFACE]
             self.adapter = self.find_adapter(0)
示例#5
0
    def take_bug_report(self, test_name, begin_time):
        """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: Logline format timestamp taken when the test started.
        """
        new_br = True
        try:
            self.adb.shell("bugreportz -v")
        except adb.AdbError:
            new_br = False
        br_path = os.path.join(self.log_path, "BugReports")
        utils.create_dir(br_path)
        base_name = ",{},{}.txt".format(begin_time, self.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(' ', '\ '))
        # 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").decode("utf-8")
            if not out.startswith("OK"):
                raise AndroidDeviceError("Failed to take bugreport on %s" %
                                         self.serial)
            br_out_path = out.split(':')[1].strip()
            self.adb.pull("%s %s" % (br_out_path, full_out_path))
        else:
            self.adb.bugreport(" > {}".format(full_out_path))
        self.log.info("Bugreport for %s taken at %s.", test_name,
                      full_out_path)
示例#6
0
    def start(self, iperf_args, ad, ip):
        """Starts iperf client on specified port.

        Args:
            iperf_args: A string representing arguments to start iperf
            client. Eg: iperf_args = "-t 10 -p 5001 -w 512k/-u -b 200M -J".
            ad: Android device object.
            ip: Iperf server ip address.

        Returns:
            full_out_path: Iperf result path.
        """
        iperf_cmd = "iperf3 -c {} ".format(ip) + iperf_args
        port = iperf_cmd.split(' ')[6]
        log_path = os.path.join(ad.log_path, "iPerf{}".format(port))
        utils.create_dir(log_path)
        out_file_name = "IPerfClient,{},{}.log".format(port,
                                                       len(self.log_files))
        full_out_path = os.path.join(log_path, out_file_name)
        if self.client_type == "remote":
            try:
                job_result = self.ssh_session.run(iperf_cmd)
                self.iperf_process = job_result.stdout
                with open(full_out_path, 'w') as outfile:
                    outfile.write(self.iperf_process)
            except Exception:
                logging.info("Iperf run failed.")
        else:
            cmd = iperf_cmd.split()
            with open(full_out_path, "w") as f:
                subprocess.call(cmd, stdout=f)
        self.log_files.append(full_out_path)
        return full_out_path
 def setup_class(self):
     """
     This method finds bluetooth protobuf definitions from config file,
     compile the protobuf and create a log directory for metrics dumping
     :return: True on success, False on failure
     """
     super(BtMetricsBaseTest, self).setup_class()
     self.bluetooth_proto_path = self.user_params["bluetooth_proto_path"]
     if not os.path.isfile(self.bluetooth_proto_path):
         try:
             self.bluetooth_proto_path = "{}/bluetooth.proto".format(
                 os.path.dirname(os.path.realpath(__file__)))
         except Exception:
             self.log.error("File not found.")
         if not os.path.isfile(self.bluetooth_proto_path):
             self.log.error("Unable to find Bluetooth proto {}.".format(
                 self.bluetooth_proto_path))
             return False
     for ad in self.android_devices:
         ad.metrics_path = os.path.join(ad.log_path, "BluetoothMetrics")
         create_dir(ad.metrics_path)
         ad.bluetooth_proto_module = \
             compile_import_proto(ad.metrics_path, self.bluetooth_proto_path)
         if not ad.bluetooth_proto_module:
             self.log.error("Unable to compile bluetooth proto at " +
                            self.bluetooth_proto_path)
             return False
     return True
示例#8
0
 def __init__(self, config, log_path):
     self.server_type = "local"
     self.port = config
     self.log_path = os.path.join(log_path, "iPerf{}".format(self.port))
     utils.create_dir(self.log_path)
     self.iperf_str = "iperf3 -s -J -p {}".format(self.port)
     self.log_files = []
     self.started = False
示例#9
0
 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))
         utils.create_dir(diag_path)
         mylogger.pull(session, diag_path)
 def get_qxdm_logs(self):
     """Get qxdm logs."""
     ad.log.info("Pull QXDM Logs")
     qxdm_logs = self.get_file_names(
         "/data/vendor/radio/diag_logs/logs/*.qmdl")
     if qxdm_logs:
         qxdm_path = os.path.join(ad.log_path, "QXDM_Logs")
         utils.create_dir(qxdm_path)
         ad.pull_files(qxdm_logs, qxdm_path)
示例#11
0
 def __init__(self, controllers):
     BtFunhausBaseTest.__init__(self, controllers)
     self.chameleon = self.chameleon_devices[0]
     self.dut = self.android_devices[0]
     self.raw_audio_dest = "{}/{}".format(self.android_devices[0].log_path,
                                          "Chameleon_audio")
     utils.create_dir(self.raw_audio_dest)
     self.chameleon.audio_board_connect(1, headphone_bus_endpoint)
     self.chameleon.audio_board_connect(1, fpga_linein_bus_endpoint)
     time.sleep(delay_after_binding_seconds)
示例#12
0
 def _collect_bluetooth_manager_dumpsys_logs(self, ads):
     for ad in ads:
         serial = ad.serial
         out_name = "{}_{}".format(serial, "bluetooth_dumpsys.txt")
         dumpsys_path = ''.join((ad.log_path, "/BluetoothDumpsys"))
         create_dir(dumpsys_path)
         cmd = ''.join(
             ("adb -s ", serial, " shell dumpsys bluetooth_manager > ",
              dumpsys_path, "/", out_name))
         exe_cmd(cmd)
示例#13
0
 def __init__(self, config, log_path):
     self.server_type = "remote"
     self.ssh_settings = settings.from_config(config["ssh_config"])
     self.ssh_session = connection.SshConnection(self.ssh_settings)
     self.port = config["port"]
     self.log_path = os.path.join(log_path, "iPerf{}".format(self.port))
     utils.create_dir(self.log_path)
     self.iperf_str = "iperf3 -s -J -p {}".format(self.port)
     self.log_files = []
     self.started = False
 def _ad_take_reports(self, ad, test_name, begin_time):
     try:
         ad.take_bug_report(test_name, begin_time)
         bugreport_path = os.path.join(ad.log_path, test_name)
         utils.create_dir(bugreport_path)
         ad.check_crash_report(test_name, begin_time, True)
         if getattr(ad, "qxdm_always_on", False):
             ad.get_qxdm_logs()
     except Exception as e:
         ad.log.error("Failed to take a bug report for %s with error %s",
                      test_name, e)
示例#15
0
    def __init__(self, config, log_path):

        # Note: skip_sl4a must be set to True in iperf server config since
        # ACTS may have already initialized and started services on device
        self.server_type = "adb"
        self.adb_device = android_device.create(config["AndroidDevice"])
        self.adb_device = self.adb_device[0]
        self.adb_log_path = "~/data"
        self.port = config["port"]
        self.log_path = os.path.join(log_path, "iPerf{}".format(self.port))
        utils.create_dir(self.log_path)
        self.iperf_str = "iperf3 -s -J -p {}".format(self.port)
        self.log_files = []
        self.started = False
示例#16
0
def setup_test_logger(log_path, prefix=None, filename=None):
    """Customizes the root logger for a test run.

    Args:
        log_path: Location of the report file.
        prefix: A prefix for each log line in terminal.
        filename: Name of the files. The default is the time the objects
            are requested.
    """
    if filename is None:
        filename = get_log_file_timestamp()
    create_dir(log_path)
    logger = _setup_test_logger(log_path, prefix, filename)
    create_latest_log_alias(log_path)
示例#17
0
 def _collect_bluetooth_manager_dumpsys_logs(self, ads):
     """
     Collect "adb shell dumpsys bluetooth_manager" logs
     :param ads: list of active Android devices
     :return: None
     """
     for ad in ads:
         serial = ad.serial
         out_name = "{}_{}".format(serial, "bluetooth_dumpsys.txt")
         dumpsys_path = ''.join((ad.log_path, "/BluetoothDumpsys"))
         create_dir(dumpsys_path)
         cmd = ''.join(
             ("adb -s ", serial, " shell dumpsys bluetooth_manager > ",
              dumpsys_path, "/", out_name))
         exe_cmd(cmd)
示例#18
0
 def setup_class(self):
     self.dut = self.android_devices[0]
     req_params = ["rssi_test_params", "testbed_params", "main_network"]
     opt_params = ["RetailAccessPoints"]
     self.unpack_userparams(req_params, opt_params)
     self.test_params = self.rssi_test_params
     self.num_atten = self.attenuators[0].instrument.num_atten
     self.iperf_server = self.iperf_servers[0]
     self.access_points = retail_ap.create(self.RetailAccessPoints)
     self.access_point = self.access_points[0]
     self.log_path = os.path.join(logging.log_path, "results")
     utils.create_dir(self.log_path)
     self.log.info("Access Point Configuration: {}".format(
         self.access_point.ap_settings))
     self.testclass_results = []
 def test_check_crash(self):
     msg = ""
     for ad in self.android_devices:
         post_crash = ad.check_crash_report(self.test_id, None, False)
         pre_crash = getattr(ad, "crash_report_preflight", [])
         crash_diff = list(set(post_crash).difference(set(pre_crash)))
         if crash_diff:
             msg += "%s find new crash reports %s" % (ad.serial, crash_diff)
             ad.log.error("Find new crash reports %s", crash_diff)
             crash_path = os.path.join(ad.log_path, self.test_id, "Crashes")
             utils.create_dir(crash_path)
             ad.pull_files(crash_diff, crash_path)
     if msg:
         fail(msg)
     return True
    def cat_adb_log(self, tag, begin_time):
        """Takes an excerpt of the adb logcat log from a certain time point to
        current time.

        Args:
            tag: An identifier of the time period, usualy the name of a test.
            begin_time: Logline format timestamp of the beginning of the time
                period.
        """
        if not self.adb_logcat_file_path:
            raise AndroidDeviceError(
                ("Attempting to cat adb log when none has"
                 " been collected on Android device %s.") % self.serial)
        end_time = acts_logger.get_log_line_timestamp()
        self.log.debug("Extracting adb log from logcat.")
        adb_excerpt_path = os.path.join(self.log_path, "AdbLogExcerpts")
        utils.create_dir(adb_excerpt_path)
        f_name = os.path.basename(self.adb_logcat_file_path)
        out_name = f_name.replace("adblog,", "").replace(".txt", "")
        out_name = ",{},{}.txt".format(begin_time, out_name)
        tag_len = utils.MAX_FILENAME_LEN - len(out_name)
        tag = tag[:tag_len]
        out_name = tag + out_name
        full_adblog_path = os.path.join(adb_excerpt_path, out_name)
        with open(full_adblog_path, 'w', encoding='utf-8') as out:
            in_file = self.adb_logcat_file_path
            with open(in_file, 'r', encoding='utf-8', errors='replace') as f:
                in_range = False
                while True:
                    line = None
                    try:
                        line = f.readline()
                        if not line:
                            break
                    except:
                        continue
                    line_time = line[:acts_logger.log_line_timestamp_len]
                    if not acts_logger.is_valid_logline_timestamp(line_time):
                        continue
                    if self._is_timestamp_in_range(line_time, begin_time,
                                                   end_time):
                        in_range = True
                        if not line.endswith('\n'):
                            line += '\n'
                        out.write(line)
                    else:
                        if in_range:
                            break
示例#21
0
def _setup_test_logger(log_path, prefix=None, filename=None):
    """Customizes the root logger for a test run.

    The logger object has a stream handler and a file handler. The stream
    handler logs INFO level to the terminal, the file handler logs DEBUG
    level to files.

    Args:
        log_path: Location of the log file.
        prefix: A prefix for each log line in terminal.
        filename: Name of the log file. The default is the time the logger
                  is requested.
    """
    log = logging.getLogger()
    kill_test_logger(log)
    log.propagate = False
    log.setLevel(logging.DEBUG)
    # Log info to stream
    terminal_format = log_line_format
    if prefix:
        terminal_format = "[{}] {}".format(prefix, log_line_format)
    c_formatter = logging.Formatter(terminal_format, log_line_time_format)
    ch = logging.StreamHandler(sys.stdout)
    ch.setFormatter(c_formatter)
    ch.setLevel(logging.INFO)
    # Log everything to file
    f_formatter = logging.Formatter(log_line_format, log_line_time_format)
    # All the logs of this test class go into one directory
    if filename is None:
        filename = get_log_file_timestamp()
        create_dir(log_path)
    fh = logging.FileHandler(os.path.join(log_path, 'test_run_details.txt'))
    fh.setFormatter(f_formatter)
    fh.setLevel(logging.DEBUG)
    fh_info = logging.FileHandler(os.path.join(log_path, 'test_run_info.txt'))
    fh_info.setFormatter(f_formatter)
    fh_info.setLevel(logging.INFO)
    fh_error = logging.FileHandler(os.path.join(log_path,
                                                'test_run_error.txt'))
    fh_error.setFormatter(f_formatter)
    fh_error.setLevel(logging.WARNING)
    log.addHandler(ch)
    log.addHandler(fh)
    log.addHandler(fh_info)
    log.addHandler(fh_error)
    log.log_path = log_path
    logging.log_path = log_path
示例#22
0
 def test_check_dialer_crash(self):
     msg = ""
     for ad in self.android_devices:
         tombstones = ad.get_file_names("/data/tombstones/")
         if not tombstones: continue
         for tombstone in tombstones:
             if ad.adb.shell("cat %s | grep pid | grep dialer" % tombstone):
                 message = "%s dialer crash: %s " % (ad.serial, tombstone)
                 ad.log.error(message)
                 msg += message
                 crash_path = os.path.join(ad.log_path, self.test_name,
                                           "Crashes")
                 utils.create_dir(crash_path)
                 ad.pull_files([tombstone], crash_path)
     if msg:
         fail(msg)
     return True
示例#23
0
    def save_to_text_file(monsoon_data, file_path):
        """Save multiple MonsoonData objects to a text file.

        Args:
            monsoon_data: A list of MonsoonData objects to write to a text
                file.
            file_path: The full path of the file to save to, including the file
                name.
        """
        if not monsoon_data:
            raise MonsoonError("Attempting to write empty Monsoon data to "
                               "file, abort")
        utils.create_dir(os.path.dirname(file_path))
        with open(file_path, 'w') as f:
            for md in monsoon_data:
                f.write(str(md))
                f.write(MonsoonData.delimiter)
示例#24
0
    def _take_bug_report(self, test_name, begin_time):
        if "no_bug_report_on_fail" in self.user_params:
            return

        # magical sleep to ensure the runtime restart or reboot begins
        time.sleep(1)
        for ad in self.android_devices:
            try:
                ad.adb.wait_for_device()
                ad.take_bug_report(test_name, begin_time)
                tombstone_path = os.path.join(ad.log_path, "BugReports",
                        "{},{}".format(begin_time, ad.serial).replace(' ','_'))
                utils.create_dir(tombstone_path)
                ad.adb.pull('/data/tombstones/', tombstone_path)
            except:
                self.log.error("Failed to take a bug report for {}, {}"
                             .format(ad.serial, test_name))
示例#25
0
def _get_test_logger(log_path, TAG, prefix=None, filename=None):
    """Returns a logger object used for tests.

    The logger object has a stream handler and a file handler. The stream
    handler logs INFO level to the terminal, the file handler logs DEBUG
    level to files.

    Args:
        log_path: Location of the log file.
        TAG: Name of the logger's owner.
        prefix: A prefix for each log line in terminal.
        filename: Name of the log file. The default is the time the logger
            is requested.

    Returns:
        A logger configured with one stream handler and one file handler
    """
    log = logging.getLogger(TAG)
    if log.handlers:
        # This logger has been requested before.
        return log
    log.propagate = False
    log.setLevel(logging.DEBUG)
    # Log info to stream
    terminal_format = log_line_format
    if prefix:
        terminal_format = "[{}] {}".format(prefix, log_line_format)
    c_formatter = logging.Formatter(terminal_format, log_line_time_format)
    ch = logging.StreamHandler(sys.stdout)
    ch.setFormatter(c_formatter)
    ch.setLevel(logging.INFO)
    # Log everything to file
    f_formatter = logging.Formatter(log_line_format, log_line_time_format)
    # All the logs of this test class go into one directory
    if filename is None:
        filename = get_log_file_timestamp()
        create_dir(log_path)
    fh = logging.FileHandler(os.path.join(log_path, 'test_run_details.txt'))
    fh.setFormatter(f_formatter)
    fh.setLevel(logging.DEBUG)
    log.addHandler(ch)
    log.addHandler(fh)
    log.log_path = log_path
    return log
示例#26
0
    def setup_class(self):
        # Not to call Base class setup_class()
        # since it removes the bonded devices
        for ad in self.android_devices:
            sync_device_time(ad)
        self.ad = self.android_devices[0]
        self.mon = self.monsoons[0]
        self.mon.set_voltage(self.MONSOON_OUTPUT_VOLTAGE)
        self.mon.set_max_current(self.MONSOON_MAX_CURRENT)
        # Monsoon phone
        self.mon.attach_device(self.ad)
        self.monsoon_log_path = os.path.join(self.log_path, "MonsoonLog")
        create_dir(self.monsoon_log_path)

        asserts.assert_true(self.mon.usb("auto"),
                            "Failed to turn USB mode to auto on monsoon.")

        asserts.assert_true(
            force_airplane_mode(self.ad, True),
            "Can not turn on airplane mode on: %s" % self.ad.serial)
        asserts.assert_true(bluetooth_enabled_check(self.ad),
                            "Failed to set Bluetooth state to enabled")
        set_location_service(self.ad, False)
        set_adaptive_brightness(self.ad, False)
        set_ambient_display(self.ad, False)
        self.ad.adb.shell("settings put system screen_brightness 0")
        set_auto_rotate(self.ad, False)
        set_phone_screen_on(self.log, self.ad, self.SCREEN_TIME_OFF)

        wutils.wifi_toggle_state(self.ad, False)

        # Start PMC app.
        self.log.info("Start PMC app...")
        self.ad.adb.shell(self.START_PMC_CMD)
        self.ad.adb.shell(self.PMC_VERBOSE_CMD)

        self.log.info("Check to see if PMC app started")
        for _ in range(self.WAIT_TIME):
            time.sleep(1)
            try:
                self.ad.adb.shell('ps -A | grep "S com.android.pmc"')
                break
            except adb.AdbError as e:
                self.log.info("PMC app is NOT started yet")
示例#27
0
def get_test_logger(log_path, TAG, prefix=None, filename=None):
    """Returns a logger customized for a test run.

    Args:
        log_path: Location of the report file.
        TAG: Name of the logger's owner.
        prefix: A prefix for each log line in terminal.
        filename: Name of the files. The default is the time the objects
            are requested.

    Returns:
        A logger object.
    """
    if filename is None:
        filename = get_log_file_timestamp()
    create_dir(log_path)
    logger = _get_test_logger(log_path, TAG, prefix, filename)
    create_latest_log_alias(log_path)
    return logger
示例#28
0
    def start_iperf_server_on_shell(self, server_port):
        """Starts iperf server on android device with specified.

        Args:
            server_port: Port in which server should be started.
        """
        log_path = os.path.join(self.pri_ad.log_path,
                                "iPerf{}".format(server_port))
        iperf_server = "iperf3 -s -p {} -J".format(server_port)
        create_dir(log_path)
        out_file_name = "IPerfServer,{},{},{}.log".format(
            server_port, self.tag, len(self.log_files))
        self.tag = self.tag + 1
        self.iperf_server_path = os.path.join(log_path, out_file_name)
        cmd = "adb -s {} shell {} > {}".format(self.pri_ad.serial,
                                               iperf_server,
                                               self.iperf_server_path)
        self.iperf_process.append(start_standing_subprocess(cmd))
        self.log_files.append(self.iperf_server_path)
        time.sleep(IPERF_SERVER_WAIT_TIME)
示例#29
0
    def start(self, extra_args="", tag=""):
        """Starts iperf server on specified port.

        Args:
            extra_args: A string representing extra arguments to start iperf
                server with.
            tag: Appended to log file name to identify logs from different
                iperf runs.
        """
        if self.started:
            return
        create_dir(self.log_path)
        self.exec_count += 1
        if tag:
            tag = tag + ','
        out_file_name = "IPerfServer,{},{}{}.log".format(
            self.port, tag, self.exec_count)
        full_out_path = os.path.join(self.log_path, out_file_name)
        cmd = "{} {} > {}".format(self.iperf_str, extra_args, full_out_path)
        self.iperf_process = start_standing_subprocess(cmd)
        self.started = True
 def start_adb_logcat(self):
     """Starts a standing adb logcat collection in separate subprocesses and
     save the logcat in a file.
     """
     if self.is_adb_logcat_on:
         raise AndroidDeviceError(("Android device {} already has an adb "
                                   "logcat thread going on. Cannot start "
                                   "another one.").format(self.serial))
     # Disable adb log spam filter.
     self.adb.shell("logpersist.start --clear")
     f_name = "adblog,{},{}.txt".format(self.model, self.serial)
     utils.create_dir(self.log_path)
     logcat_file_path = os.path.join(self.log_path, f_name)
     try:
         extra_params = self.adb_logcat_param
     except AttributeError:
         extra_params = "-b all"
     cmd = "adb -s {} logcat -v threadtime {} >> {}".format(
         self.serial, extra_params, logcat_file_path)
     self.adb_logcat_process = utils.start_standing_subprocess(cmd)
     self.adb_logcat_file_path = logcat_file_path