Example #1
0
def adb_connect(device, timeout=None):
    _check_env()
    command = "adb connect " + device
    if ":" in device:
        port = device.split(':')[-1]
        logger.debug(command)

        output, _ = check_output(command, shell=True, timeout=timeout)
        logger.debug(output)
        #### due to a rare adb bug sometimes an extra :5555 is appended to the IP address
        if output.find('{}:{}'.format(port, port)) != -1:
            logger.debug('ADB BUG with extra port')
            command = "adb connect " + device.replace(':{}'.format(port), '')

    tries = 0
    output = None
    while not poll_for_file(device, "/proc/cpuinfo"):
        logger.debug("adb connect failed, retrying now...")
        tries += 1
        if tries > MAX_TRIES:
            raise DeviceError('Cannot connect to adb server on the device.')
        logger.debug(command)
        output, _ = check_output(command, shell=True, timeout=timeout)
        time.sleep(10)

    if tries and output.find('connected to') == -1:
        raise DeviceError('Could not connect to {}'.format(device))
 def execute(self,
             command,
             timeout=None,
             check_exit_code=True,
             as_root=False,
             strip_colors=True):
     try:
         with self.lock:
             if self.connection_lost:
                 logger.debug('Attempting to reconnect...')
                 self.reconnect()
                 self.connection_lost = False
             output = self._execute_and_wait_for_prompt(
                 command, timeout, as_root, strip_colors)
             if check_exit_code:
                 exit_code_text = self._execute_and_wait_for_prompt(
                     'echo $?', strip_colors=strip_colors, log=False)
                 try:
                     exit_code = int(exit_code_text.split()[0])
                     if exit_code:
                         message = 'Got exit code {}\nfrom: {}\nOUTPUT: {}'
                         raise DeviceError(
                             message.format(exit_code, command, output))
                 except (ValueError, IndexError):
                     logger.warning(
                         'Could not get exit code for "{}",\ngot: "{}"'.
                         format(command, exit_code_text))
             return output
     except EOF:
         self.connection_lost = True
         raise DeviceError('Connection dropped.')
Example #3
0
    def connect(self):  # NOQA pylint: disable=R0912
        iteration_number = 0
        max_iterations = self.ready_timeout / self.delay
        available = False
        self.logger.debug('Polling for device {}...'.format(self.adb_name))
        while iteration_number < max_iterations:
            devices = adb_list_devices()
            if self.adb_name:
                for device in devices:
                    if device.name == self.adb_name and device.status != 'offline':
                        available = True
            else:  # adb_name not set
                if len(devices) == 1:
                    available = True
                elif len(devices) > 1:
                    raise DeviceError(
                        'More than one device is connected and adb_name is not set.'
                    )

            if available:
                break
            else:
                time.sleep(self.delay)
                iteration_number += 1
        else:
            raise DeviceError('Could not boot {} ({}).'.format(
                self.name, self.adb_name))

        while iteration_number < max_iterations:
            available = (1 == int('0' +
                                  adb_shell(self.adb_name,
                                            'getprop sys.boot_completed',
                                            timeout=self.default_timeout)))
            if available:
                break
            else:
                time.sleep(self.delay)
                iteration_number += 1
        else:
            raise DeviceError('Could not boot {} ({}).'.format(
                self.name, self.adb_name))

        if self._just_rebooted:
            self.logger.debug('Waiting for boot to complete...')
            # On some devices, adb connection gets reset some time after booting.
            # This  causes errors during execution. To prevent this, open a shell
            # session and wait for it to be killed. Once its killed, give adb
            # enough time to restart, and then the device should be ready.
            # TODO: This is more of a work-around rather than an actual solution.
            #       Need to figure out what is going on the "proper" way of handling it.
            try:
                adb_shell(self.adb_name, '', timeout=20)
                time.sleep(5)  # give adb time to re-initialize
            except TimeoutError:
                pass  # timed out waiting for the session to be killed -- assume not going to be.

            self.logger.debug('Boot completed.')
            self._just_rebooted = False
        self._is_ready = True
Example #4
0
    def execute(self,
                command,
                timeout=default_timeout,
                check_exit_code=True,
                background=False,
                as_root=False,
                busybox=False,
                **kwargs):
        """
        Execute the specified command on the device using adb.

        Parameters:

            :param command: The command to be executed. It should appear exactly
                            as if you were typing it into a shell.
            :param timeout: Time, in seconds, to wait for adb to return before aborting
                            and raising an error. Defaults to ``AndroidDevice.default_timeout``.
            :param check_exit_code: If ``True``, the return code of the command on the Device will
                                    be check and exception will be raised if it is not 0.
                                    Defaults to ``True``.
            :param background: If ``True``, will execute adb in a subprocess, and will return
                               immediately, not waiting for adb to return. Defaults to ``False``
            :param busybox: If ``True``, will use busybox to execute the command. Defaults to ``False``.

                            Added in version 2.1.3

                            .. note:: The device must be rooted to be able to use busybox.

            :param as_root: If ``True``, will attempt to execute command in privileged mode. The device
                            must be rooted, otherwise an error will be raised. Defaults to ``False``.

                            Added in version 2.1.3

        :returns: If ``background`` parameter is set to ``True``, the subprocess object will
                  be returned; otherwise, the contents of STDOUT from the device will be returned.

        :raises: DeviceError if adb timed out  or if the command returned non-zero exit
                 code on the device, or if attempting to execute a command in privileged mode on an
                 unrooted device.

        """
        self._check_ready()
        if as_root and not self.is_rooted:
            raise DeviceError(
                'Attempting to execute "{}" as root on unrooted device.'.
                format(command))
        if busybox:
            if not self.is_rooted:
                DeviceError('Attempting to execute "{}" with busybox. '.format(
                    command) +
                            'Busybox can only be deployed to rooted devices.')
            command = ' '.join([self.busybox, command])
        if background:
            return adb_background_shell(self.adb_name,
                                        command,
                                        as_root=as_root)
        else:
            return adb_shell(self.adb_name, command, timeout, check_exit_code,
                             as_root)
Example #5
0
    def execute(self,
                command,
                timeout=default_timeout,
                check_exit_code=True,
                background=False,
                as_root=False,
                strip_colors=True,
                **kwargs):
        """
        Execute the specified command on the device using adb.

        Parameters:

            :param command: The command to be executed. It should appear exactly
                            as if you were typing it into a shell.
            :param timeout: Time, in seconds, to wait for adb to return before aborting
                            and raising an error. Defaults to ``AndroidDevice.default_timeout``.
            :param check_exit_code: If ``True``, the return code of the command on the Device will
                                    be check and exception will be raised if it is not 0.
                                    Defaults to ``True``.
            :param background: If ``True``, will execute create a new ssh shell rather than using
                               the default session and will return it immediately. If this is ``True``,
                               ``timeout``, ``strip_colors`` and (obvisously) ``check_exit_code`` will
                               be ignored; also, with this, ``as_root=True``  is only valid if ``username``
                               for the device was set to ``root``.
            :param as_root: If ``True``, will attempt to execute command in privileged mode. The device
                            must be rooted, otherwise an error will be raised. Defaults to ``False``.

                            Added in version 2.1.3

        :returns: If ``background`` parameter is set to ``True``, the subprocess object will
                  be returned; otherwise, the contents of STDOUT from the device will be returned.

        """
        self._check_ready()
        try:
            if background:
                if as_root and self.username != 'root':
                    raise DeviceError(
                        'Cannot execute in background with as_root=True unless user is root.'
                    )
                return self.shell.background(command)
            else:
                # If we're already the root user, don't bother with sudo
                if self._is_root_user:
                    as_root = False
                return self.shell.execute(command, timeout, check_exit_code,
                                          as_root, strip_colors)
        except CalledProcessError as e:
            raise DeviceError(e)
Example #6
0
def adb_shell(device,
              command,
              timeout=None,
              check_exit_code=False,
              as_root=False):  # NOQA
    _check_env()
    if as_root:
        command = 'echo "{}" | su'.format(escape_double_quotes(command))
    device_string = '-s {}'.format(device) if device else ''
    full_command = 'adb {} shell "{}"'.format(device_string,
                                              escape_double_quotes(command))
    logger.debug(full_command)
    if check_exit_code:
        actual_command = "adb {} shell '({}); echo $?'".format(
            device_string, escape_single_quotes(command))
        raw_output, error = check_output(actual_command, timeout, shell=True)
        if raw_output:
            try:
                output, exit_code, _ = raw_output.rsplit('\n', 2)
            except ValueError:
                exit_code, _ = raw_output.rsplit('\n', 1)
                output = ''
        else:  # raw_output is empty
            exit_code = '969696'  # just because
            output = ''

        exit_code = exit_code.strip()
        if exit_code.isdigit():
            if int(exit_code):
                message = 'Got exit code {}\nfrom: {}\nSTDOUT: {}\nSTDERR: {}'.format(
                    exit_code, full_command, output, error)
                raise DeviceError(message)
            elif am_start_error.findall(output):
                message = 'Could not start activity; got the following:'
                message += '\n{}'.format(am_start_error.findall(output)[0])
                raise DeviceError(message)
        else:  # not all digits
            if am_start_error.findall(output):
                message = 'Could not start activity; got the following:'
                message += '\n{}'.format(am_start_error.findall(output)[0])
                raise DeviceError(message)
            else:
                raise DeviceError(
                    'adb has returned early; did not get an exit code. Was kill-server invoked?'
                )
    else:  # do not check exit code
        output, _ = check_output(full_command, timeout, shell=True)
    return output
Example #7
0
    def boot(self, hard=False, **kwargs):
        if hard:
            self.hard_reset()
        else:
            self.reset()
        self.logger.debug('Waiting for device...')
        # Wait a fixed delay before starting polling to give the device time to
        # shut down, otherwise, might create the connection while it's still shutting
        # down resulting in subsequenct connection failing.
        initial_delay = 20
        time.sleep(initial_delay)
        boot_timeout = max(self.boot_timeout - initial_delay, 10)

        start_time = time.time()
        while (time.time() - start_time) < boot_timeout:
            try:
                s = socket.create_connection((self.host, self.port), timeout=5)
                s.close()
                break
            except socket.timeout:
                pass
            except socket.error:
                time.sleep(5)
        else:
            raise DeviceError('Could not connect to {} after reboot'.format(
                self.host))
Example #8
0
def ssh_get_shell(host, username, password=None, keyfile=None, port=None, timeout=10, telnet=False, original_prompt=None):
    _check_env()
    start_time = time.time()
    extra_login_args = {}
    while True:
        if telnet:
            if keyfile:
                raise ValueError('keyfile may not be used with a telnet connection.')
            conn = TelnetConnection()
            if original_prompt:
                extra_login_args['original_prompt'] = original_prompt
            if port is None:
                port = 23
        else:  # ssh
            conn = pxssh.pxssh()

        try:
            if keyfile:
                conn.login(host, username, ssh_key=keyfile, port=port, login_timeout=timeout, **extra_login_args)
            else:
                conn.login(host, username, password, port=port, login_timeout=timeout, **extra_login_args)
            break
        except EOF:
            timeout -= time.time() - start_time
            if timeout <= 0:
                message = 'Could not connect to {}; is the host name correct?'
                raise DeviceError(message.format(host))
            time.sleep(5)

    conn.setwinsize(500,200)
    conn.sendline('')
    conn.prompt()
    conn.setecho(False)
    return conn
Example #9
0
 def install_apk(self,
                 filepath,
                 timeout=default_timeout,
                 replace=False,
                 allow_downgrade=False):  # pylint: disable=W0221
     self._check_ready()
     ext = os.path.splitext(filepath)[1].lower()
     if ext == '.apk':
         flags = []
         if replace:
             flags.append('-r')  # Replace existing APK
         if allow_downgrade:
             flags.append(
                 '-d'
             )  # Install the APK even if a newer version is already installed
         if self.get_sdk_version() >= 23:
             flags.append('-g')  # Grant all runtime permissions
         self.logger.debug("Replace APK = {}, ADB flags = '{}'".format(
             replace, ' '.join(flags)))
         return adb_command(self.adb_name,
                            "install {} '{}'".format(
                                ' '.join(flags), filepath),
                            timeout=timeout)
     else:
         raise DeviceError(
             'Can\'t install {}: unsupported format.'.format(filepath))
    def connect(self):
        if not self._is_ready:
            if not self.adb_name:  # pylint: disable=E0203
                with open_serial_connection(timeout=self.timeout,
                                            port=self.port,
                                            baudrate=self.baudrate,
                                            init_dtr=0) as target:
                    target.sendline('')
                    self.logger.debug('Waiting for the Android prompt.')
                    target.expect(self.android_prompt)

                    self.logger.debug('Waiting for IP address...')
                    wait_start_time = time.time()
                    while True:
                        target.sendline('ip addr list eth0')
                        time.sleep(1)
                        try:
                            target.expect('inet ([1-9]\d*.\d+.\d+.\d+)',
                                          timeout=10)
                            self.adb_name = target.match.group(1) + ':5555'  # pylint: disable=W0201
                            break
                        except pexpect.TIMEOUT:
                            pass  # We have our own timeout -- see below.
                        if (time.time() -
                                wait_start_time) > self.ready_timeout:
                            raise DeviceError('Could not acquire IP address.')

            if self.adb_name in adb_list_devices():
                adb_disconnect(self.adb_name)
            adb_connect(self.adb_name, timeout=self.timeout)
            super(Juno, self).connect()  # wait for boot to complete etc.
            self._is_ready = True
def ssh_get_shell(host,
                  username,
                  password=None,
                  keyfile=None,
                  port=None,
                  timeout=10,
                  telnet=False):
    _check_env()
    if telnet:
        if keyfile:
            raise ConfigError(
                'keyfile may not be used with a telnet connection.')
        conn = TelnetConnection()
    else:  # ssh
        conn = pxssh.pxssh()  # pylint: disable=redefined-variable-type
    try:
        if keyfile:
            conn.login(host,
                       username,
                       ssh_key=keyfile,
                       port=port,
                       login_timeout=timeout)
        else:
            conn.login(host,
                       username,
                       password,
                       port=port,
                       login_timeout=timeout)
    except EOF:
        raise DeviceError(
            'Could not connect to {}; is the host name correct?'.format(host))
    return conn
Example #12
0
    def set_sysfile_value(self, sysfile, value, verify=True, binary=False):
        """
        Set the value of the specified sysfile. By default, the value will be checked afterwards.
        Can be overridden by setting ``verify`` parameter to ``False``. By default binary values
        will not be written correctly this can be changed by setting the ``binary`` parameter to
        ``True``.

        """
        value = str(value)
        if binary:
            # Value is already string encoded, so need to decode before encoding in base64
            try:
                value = str(value.decode('string_escape'))
            except ValueError as e:
                msg = 'Can not interpret value "{}" for "{}": {}'
                raise ValueError(msg.format(value, sysfile, e.message))

            encoded_value = base64.b64encode(value)
            cmd = 'echo {} | {} base64 -d > \'{}\''.format(encoded_value, self.busybox, sysfile)
        else:
            cmd = 'echo {} > \'{}\''.format(value, sysfile)
        self.execute(cmd, check_exit_code=False, as_root=True)

        if verify:
            output = self.get_sysfile_value(sysfile, binary=binary)
            if output.strip() != value:  # pylint: disable=E1103
                message = 'Could not set the value of {} to {}'.format(sysfile, value)
                raise DeviceError(message)
        self._written_sysfiles.append((sysfile, binary))
Example #13
0
    def kick_off(self, command):
        """
        Like execute but closes adb session and returns immediately, leaving the command running on the
        device (this is different from execute(background=True) which keeps adb connection open and returns
        a subprocess object).

        .. note:: This relies on busybox's nohup applet and so won't work on unrooted devices.

        Added in version 2.1.4

        """
        if not self.is_rooted:
            raise DeviceError(
                'kick_off uses busybox\'s nohup applet and so can only be run a rooted device.'
            )
        try:
            command = 'cd {} && busybox nohup {}'.format(
                self.working_directory, command)
            output = self.execute(command, timeout=1, as_root=True)
        except TimeoutError:
            pass
        else:
            raise ValueError(
                'Background command exited before timeout; got "{}"'.format(
                    output))
Example #14
0
 def initialize(self, context):
     if self.device.platform != 'android':
         raise DeviceError(
             'nestats instrument only supports on Android devices.')
     apk = context.resolver.get(ApkFile(self))
     self.collector = NetstatsCollector(self.device, apk)  # pylint: disable=attribute-defined-outside-init
     self.collector.setup(force=self.force_reinstall)
Example #15
0
    def connect(self):
        if not self._is_ready:
            if self.config.adb_name:
                self.adb_name = self.config.adb_name  # pylint: disable=attribute-defined-outside-init
            else:
                with open_serial_connection(
                        timeout=self.config.serial_max_timeout,
                        port=self.config.serial_device,
                        baudrate=self.config.serial_baud) as target:
                    # Get IP address and push the Gator and PMU logger.
                    target.sendline(
                        'su'
                    )  # as of Android v5.0.2, Linux does not boot into root shell
                    target.sendline('netcfg')
                    ipaddr_re = re.compile('eth0 +UP +(.+)/.+', re.MULTILINE)
                    target.expect(ipaddr_re)
                    output = target.after
                    match = re.search('eth0 +UP +(.+)/.+', output)
                    if not match:
                        raise DeviceError('Could not get adb IP address.')
                    ipaddr = match.group(1)

                    # Connect to device using adb.
                    target.expect(self.android_prompt)  # pylint: disable=E1101
                    self.adb_name = ipaddr + ":5555"  # pylint: disable=W0201

            if self.adb_name in adb_list_devices():
                adb_disconnect(self.adb_name)
            adb_connect(self.adb_name)
            self._is_ready = True
            self.execute("input keyevent 82", timeout=ADB_SHELL_TIMEOUT)
            self.execute("svc power stayon true", timeout=ADB_SHELL_TIMEOUT)
Example #16
0
    def set_cpu_max_frequency(self, cpu, frequency):
        """
        Set's the minimum value for CPU frequency. Actual frequency will
        depend on the Governor used and may vary during execution. The value should be
        either an int or a string representing an integer. The Value must also be
        supported by the device. The available frequencies can be obtained by calling
        get_available_frequencies() or examining

        /sys/devices/system/cpu/cpuX/cpufreq/scaling_available_frequencies

        on the device.

        :raises: ConfigError if the frequency is not supported by the CPU.
        :raises: DeviceError if, for some reason, frequency could not be set.

        """
        if isinstance(cpu, int):
            cpu = 'cpu{}'.format(cpu)
        available_frequencies = self.list_available_cpu_frequencies(cpu)
        try:
            value = int(frequency)
            if available_frequencies and value not in available_frequencies:
                raise DeviceError('Can\'t set {} frequency to {}\nmust be in {}'.format(cpu,
                                                                                        value,
                                                                                        available_frequencies))
            sysfile = '/sys/devices/system/cpu/{}/cpufreq/scaling_max_freq'.format(cpu)
            self.device.set_sysfile_value(sysfile, value)
        except ValueError:
            raise ValueError('value must be an integer; got: "{}"'.format(value))
Example #17
0
    def install_apk(self, filepath, timeout=3 * 3600):  # pylint: disable=W0221
        """
        Install an APK on the gem5 device

        The APK is pushed to the device. Then the file and folder permissions
        are changed to ensure that the APK can be correctly installed. The APK
        is then installed on the device using 'pm'.
        """
        self._check_ready()
        self.logger.info("Installing {}".format(filepath))
        ext = os.path.splitext(filepath)[1].lower()
        if ext == '.apk':
            filename = os.path.basename(filepath)
            on_device_path = os.path.join('/data/local/tmp', filename)
            self.push_file(filepath, on_device_path)
            # We need to make sure that the folder permissions are set
            # correctly, else the APK does not install correctly.
            self.gem5_shell('chmod 775 /data/local/tmp')
            self.gem5_shell('chmod 774 {}'.format(on_device_path))
            self.logger.debug(
                "Actually installing the APK: {}".format(on_device_path))
            return self.gem5_shell("pm install {}".format(on_device_path))
        else:
            raise DeviceError(
                'Can\'t install {}: unsupported format.'.format(filepath))
Example #18
0
 def is_screen_on(self):
     """Returns ``True`` if the device screen is currently on, ``False`` otherwise."""
     output = self.execute('dumpsys power')
     match = SCREEN_STATE_REGEX.search(output)
     if match:
         return boolean(match.group(1))
     else:
         raise DeviceError('Could not establish screen state.')
Example #19
0
 def discover_idle_states(self):
     online_cpu = self.device.get_online_cpus(self.big_core)[0]
     self.big_idle_states = self.device.get_cpuidle_states(online_cpu)
     online_cpu = self.device.get_online_cpus(self.little_core)[0]
     self.little_idle_states = self.device.get_cpuidle_states(online_cpu)
     if not (len(self.big_idle_states) >= 2 and len(self.little_idle_states) >= 2):
         raise DeviceError('There do not appeart to be at least two idle states '
                           'on at least one of the clusters.')
def adb_disconnect(device):
    _check_env()
    if ":5555" in device:
        command = "adb disconnect " + device
        logger.debug(command)
        retval = subprocess.call(command, stdout=open(os.devnull, 'wb'), shell=True)
        if retval:
            raise DeviceError('"{}" returned {}'.format(command, retval))
Example #21
0
 def uninstall(self, executable_name):
     on_device_executable = self.get_binary_path(
         executable_name, search_system_binaries=False)
     if not on_device_executable:
         raise DeviceError(
             "Could not uninstall {}, binary not found".format(
                 on_device_executable))
     self.delete_file(on_device_executable, as_root=self.is_rooted)
Example #22
0
    def _boot_using_uefi(self, target):
        self.logger.debug('Booting using UEFI.')
        self._wait_for_vemsd_mount(target)
        self._setup_before_reboot()
        self._perform_uefi_reboot(target)

        # Get to the UEFI menu.
        self.logger.debug('Waiting for UEFI default selection.')
        target.sendline('reboot')
        target.expect('The default boot selection will start in'.rstrip())
        time.sleep(1)
        target.sendline(''.rstrip())

        # If delete every time is specified, try to delete entry.
        if self.config.always_delete_uefi_entry:
            self._delete_uefi_entry(target, entry='workload_automation_MP')
            self.config.always_delete_uefi_entry = False

        # Specify argument to be passed specifying that psci is (or is not) enabled
        if self.config.psci_enable:
            psci_enable = ' psci=enable'
        else:
            psci_enable = ''

        # Identify the workload automation entry.
        selection_pattern = r'\[([0-9]*)\] '

        try:
            target.expect(re.compile(selection_pattern + 'workload_automation_MP'), timeout=5)
            wl_menu_item = target.match.group(1)
        except pexpect.TIMEOUT:
            self._create_uefi_entry(target, psci_enable, entry_name='workload_automation_MP')
            # At this point the board should be rebooted so we need to retry to boot
            self._boot_using_uefi(target)
        else:  # Did not time out.
            try:
                #Identify the boot manager menu item
                target.expect(re.compile(selection_pattern + 'Boot Manager'))
                boot_manager_menu_item = target.match.group(1)

                #Update FDT
                target.sendline(boot_manager_menu_item)
                target.expect(re.compile(selection_pattern + 'Update FDT path'), timeout=15)
                update_fdt_menu_item = target.match.group(1)
                target.sendline(update_fdt_menu_item)
                target.expect(re.compile(selection_pattern + 'NOR Flash .*'), timeout=15)
                bootmonfs_menu_item = target.match.group(1)
                target.sendline(bootmonfs_menu_item)
                target.expect('File path of the FDT blob:')
                target.sendline(self.config.dtb)

                #Return to main manu and boot from wl automation
                target.expect(re.compile(selection_pattern + 'Return to main menu'), timeout=15)
                return_to_main_menu_item = target.match.group(1)
                target.sendline(return_to_main_menu_item)
                target.sendline(wl_menu_item)
            except pexpect.TIMEOUT:
                raise DeviceError('Timed out')
Example #23
0
    def _check_ready(self):
        """
        Check if the device is ready.

        As this is gem5, we just assume that the device is ready once we have
        connected to the gem5 simulation, and updated the prompt.
        """
        if not self._is_ready:
            raise DeviceError('Device not ready.')
    def _run_job(self):   # pylint: disable=too-many-branches
        spec = self.current_job.spec
        if not spec.enabled:
            self.logger.info('Skipping workload %s (iteration %s)', spec, self.context.current_iteration)
            self.current_job.result.status = IterationResult.SKIPPED
            return

        self.logger.info('Running workload %s (iteration %s)', spec, self.context.current_iteration)
        if spec.flash:
            if not self.context.reboot_policy.can_reboot:
                raise ConfigError('Cannot flash as reboot_policy does not permit rebooting.')
            if not self.device.can('flash'):
                raise DeviceError('Device does not support flashing.')
            self._flash_device(spec.flash)
        elif not self.completed_jobs:
            # Never reboot on the very fist job of a run, as we would have done
            # the initial reboot if a reboot was needed.
            pass
        elif self.context.reboot_policy.reboot_on_each_spec and self.spec_changed:
            self.logger.debug('Rebooting on spec change.')
            self._reboot_device()
        elif self.context.reboot_policy.reboot_on_each_iteration:
            self.logger.debug('Rebooting on iteration.')
            self._reboot_device()

        instrumentation.disable_all()
        instrumentation.enable(spec.instrumentation)
        self.device.start()

        if self.spec_changed:
            self._send(signal.WORKLOAD_SPEC_START)
        self._send(signal.ITERATION_START)

        try:
            setup_ok = False
            with self._handle_errors('Setting up device parameters'):
                self.device.set_runtime_parameters(spec.runtime_parameters)
                setup_ok = True

            if setup_ok:
                with self._handle_errors('running {}'.format(spec.workload.name)):
                    self.current_job.result.status = IterationResult.RUNNING
                    self._run_workload_iteration(spec.workload)
            else:
                self.logger.info('\tSkipping the rest of the iterations for this spec.')
                spec.enabled = False
        except KeyboardInterrupt:
            self._send(signal.ITERATION_END)
            self._send(signal.WORKLOAD_SPEC_END)
            raise
        else:
            self._send(signal.ITERATION_END)
            if self.spec_will_change or not spec.enabled:
                self._send(signal.WORKLOAD_SPEC_END)
        finally:
            self.device.stop()
Example #25
0
 def install_apk(self, filepath, timeout=default_timeout):  # pylint: disable=W0221
     self._check_ready()
     ext = os.path.splitext(filepath)[1].lower()
     if ext == '.apk':
         return adb_command(self.adb_name,
                            "install {}".format(filepath),
                            timeout=timeout)
     else:
         raise DeviceError(
             'Can\'t install {}: unsupported format.'.format(filepath))
Example #26
0
 def set_mode(self, mode):
     if self._has_booted:
         raise DeviceError('Attempting to set boot mode when already booted.')
     valid_modes = MODES.keys()
     if mode is None:
         mode = self.config.default_mode
     if mode not in valid_modes:
         message = 'Invalid mode: {}; must be in {}'.format(mode, valid_modes)
         raise ConfigError(message)
     self.config.mode = mode
Example #27
0
 def hard_reset(self):
     try:
         conn = KshellConnection(host=self.host, port=self.port)
         conn.login(self.username, self.password)
         conn.disable_port(self.psu)
         time.sleep(2)
         conn.enable_port(self.psu)
         conn.close()
     except Exception as e:
         raise DeviceError('Could not reset power: {}'.format(e))
Example #28
0
 def deploy_images(self, device, image_bundle=None, images=None):
     try:
         if image_bundle:
             self.deploy_image_bundle(device, image_bundle)
         if images:
             self.overlay_images(device, images)
         os.system('sync')
     except (IOError, OSError), e:
         msg = 'Could not deploy images to {}; got: {}'
         raise DeviceError(msg.format(device.microsd_mount_point, e))
 def _reboot_device(self):
     with self._signal_wrap('BOOT'):
         for reboot_attempts in xrange(MAX_REBOOT_ATTEMPTS):
             if reboot_attempts:
                 self.logger.info('\tRetrying...')
             with self._handle_errors('Rebooting device'):
                 self.device.boot(**self.current_job.spec.boot_parameters)
                 break
         else:
             raise DeviceError('Could not reboot device; max reboot attempts exceeded.')
         self.device.connect()
Example #30
0
    def boot(self, **kwargs):  # NOQA
        mode = kwargs.get('os_mode', None)
        self._is_ready = False
        self._has_booted = False

        self.mode = mode
        self.logger.debug('Booting in {} mode'.format(self.mode))

        with open_serial_connection(timeout=self.config.serial_max_timeout,
                                    port=self.config.serial_device,
                                    baudrate=self.config.serial_baud) as target:
            if self.config.boot_firmware == 'bootmon':
                self._boot_using_bootmon(target)
            elif self.config.boot_firmware == 'uefi':
                self._boot_using_uefi(target)
            else:
                message = 'Unexpected boot firmware: {}'.format(self.config.boot_firmware)
                raise ConfigError(message)

            try:
                target.sendline('')
                self.logger.debug('Waiting for the Android prompt.')
                target.expect(self.android_prompt, timeout=40)  # pylint: disable=E1101
            except pexpect.TIMEOUT:
                # Try a second time before giving up.
                self.logger.debug('Did not get Android prompt, retrying...')
                target.sendline('')
                target.expect(self.android_prompt, timeout=10)  # pylint: disable=E1101

            self.logger.debug('Waiting for OS to initialize...')
            started_waiting_time = time.time()
            time.sleep(20)  # we know it's not going to to take less time than this.
            boot_completed, got_ip_address = False, False
            while True:
                try:
                    if not boot_completed:
                        target.sendline('getprop sys.boot_completed')
                        boot_completed = target.expect(['0.*', '1.*'], timeout=10)
                    if not got_ip_address:
                        target.sendline('getprop dhcp.eth0.ipaddress')
                        # regexes  are processed in order, so ip regex has to
                        # come first (as we only want to match new line if we
                        # don't match the IP). We do a "not" make the logic
                        # consistent with boot_completed.
                        got_ip_address = not target.expect(['[1-9]\d*.\d+.\d+.\d+', '\n'], timeout=10)
                except pexpect.TIMEOUT:
                    pass  # We have our own timeout -- see below.
                if boot_completed and got_ip_address:
                    break
                time.sleep(5)
                if (time.time() - started_waiting_time) > self.config.init_timeout:
                    raise DeviceError('Timed out waiting for the device to initialize.')

        self._has_booted = True