Ejemplo n.º 1
0
  def testSshConnectError(self):
    """Tests an SSH error other than a host key mismatch.

    User should not be prompted, SSH should only be attempted once, and
    no host keys should be removed.
    """
    self.SetupCommandMock([self.DEVICE_IP])
    self.mock_base_run_command.side_effect = remote_access.SSHConnectionError()

    self.assertRaises(remote_access.SSHConnectionError, self.cmd_mock.inst.Run)

    self.assertFalse(self.mock_prompt.called)
    self.assertEqual(self.mock_base_run_command.call_count, 1)
    self.assertFalse(self.mock_remove_known_host.called)
Ejemplo n.º 2
0
  def _QuickProvision(self, device):
    """Performs a quick provision of device.

    Returns:
      A dictionary of extracted key-value pairs returned from the script
      execution.

    Raises:
      cros_build_lib.RunCommandError: error executing command or script
      remote_access.SSHConnectionError: SSH connection error
    """
    pid = os.getpid()
    pgid = os.getpgid(pid)
    if self.progress_tracker is None:
      self.progress_tracker = cros_update_progress.AUProgress(self.host_name,
                                                              pgid)

    dut_script = '/tmp/quick-provision'
    status_url = self._MakeStatusUrl(self.devserver_url, self.host_name, pgid)
    cmd = ('curl -o %s %s && bash '
           '%s --status_url %s %s %s') % (
               dut_script, os.path.join(self.static_url, 'quick-provision'),
               dut_script, cros_build_lib.ShellQuote(status_url),
               self.build_name, self.static_url,
           )
    # Quick provision script issues a reboot and might result in the SSH
    # connection being terminated so set ssh_error_ok so that output can
    # still be captured.
    results = device.RunCommand(cmd, log_output=True, capture_output=True,
                                ssh_error_ok=True, shell=True, encoding='utf-8')
    key_re = re.compile(r'^KEYVAL: ([^\d\W]\w*)=(.*)$')
    matches = [key_re.match(l) for l in results.output.splitlines()]
    keyvals = {m.group(1): m.group(2) for m in matches if m}
    logging.info('DUT returned keyvals: %s', keyvals)

    # If there was an SSH error, check the keyvals to see if it actually
    # completed and suppress the error if so.
    if results.returncode == remote_access.SSH_ERROR_CODE:
      if 'COMPLETED' in keyvals:
        logging.warning('Quick provision completed with ssh error, ignoring...')
      else:
        logging.error('Incomplete quick provision failed with ssh error')
        raise remote_access.SSHConnectionError(results.error)

    return keyvals
Ejemplo n.º 3
0
class DeviceTester(cros_test_lib.RunCommandTestCase):
    """Test device.Device."""
    def setUp(self):
        """Common set up method for all tests."""
        opts = device.Device.GetParser().parse_args(
            ['--device', '190.0.2.130'])
        self._device = device.Device(opts)

    def CreateDevice(self, device_name, is_vm):
        """Creates a device.

    Args:
      device_name: Name of the device.
      is_vm: If True, then created device should be a VM.
    """
        self._device.device = device_name
        created_device = device.Device.Create(vm.VM.GetParser().parse_args(
            ['--device', device_name]))
        self.assertEqual(isinstance(created_device, vm.VM), is_vm)
        self.assertEqual(self._device.is_vm, is_vm)

    def testWaitForBoot(self):
        self._device.WaitForBoot()
        # Verify that ssh command is called with all of the right configurations.
        self.assertCommandContains(
            ['ssh', '-p', '22', '[email protected]', '--', 'true'])

    @mock.patch('chromite.lib.cros_build_lib.run',
                side_effect=remote_access.SSHConnectionError())
    def testWaitForBootTimeOut(self, boot_mock):
        """Verify an exception is raised when the device takes to long to boot."""
        self.assertRaises(device.DeviceError,
                          self._device.WaitForBoot,
                          sleep=0)
        boot_mock.assert_called()

    @mock.patch('chromite.lib.device.Device.RemoteCommand',
                return_value=cros_build_lib.CommandResult(returncode=1))
    def testWaitForBootReturnCode(self, boot_mock):
        """Verify an exception is raised when the returncode is not 0."""
        self.assertRaises(device.DeviceError, self._device.WaitForBoot)
        boot_mock.assert_called()

    def testRunCmd(self):
        """Verify that a command is run via RunCommand."""
        self._device.RunCommand(['/usr/local/autotest/bin/vm_sanity'])
        self.assertCommandContains(['sudo'], expected=False)
        self.assertCommandCalled(['/usr/local/autotest/bin/vm_sanity'])

    def testRunCmdDryRun(self):
        """Verify that a command is run while dry running for debugging."""
        self._device.dry_run = True
        # Look for dry run command in output.
        with cros_test_lib.LoggingCapturer() as logs:
            self._device.RunCommand(['echo', 'Hello'])
        self.assertTrue(logs.LogsContain('[DRY RUN] echo Hello'))

    def testRunCmdSudo(self):
        """Verify that a command is run via sudo."""
        self._device.use_sudo = True
        self._device.RunCommand(['mount', '-o', 'remount,rw', '/'])
        self.assertCommandCalled(
            ['sudo', '--', 'mount', '-o', 'remount,rw', '/'])

    def testRemoteCmd(self):
        """Verify remote command runs correctly with default arguments."""
        self._device.RemoteCommand(['/usr/local/autotest/bin/vm_sanity'])
        self.assertCommandContains(['/usr/local/autotest/bin/vm_sanity'])
        self.assertCommandContains(capture_output=True,
                                   combine_stdout_stderr=True,
                                   log_output=True)

    def testRemoteCmdStream(self):
        """Verify remote command for streaming output."""
        self._device.RemoteCommand('/usr/local/autotest/bin/vm_sanity',
                                   stream_output=True)
        self.assertCommandContains(capture_output=False)
        self.assertCommandContains(combine_stdout_stderr=True,
                                   log_output=True,
                                   expected=False)

    def testCreate(self):
        """Verify Device/VM creation."""
        # Verify a VM is created by default.
        self.CreateDevice(None, True)
        # Verify a VM is created when IP is localhost.
        self.CreateDevice('localhost', True)
        # Verify a Device is created when an IP is specified.
        self.CreateDevice('190.0.2.130', False)

    def testDryRunError(self):
        """Verify _DryRunCommand can only be called when dry_run is True."""
        self._device.dry_run = False
        self.assertRaises(AssertionError,
                          self._device._DryRunCommand,
                          cmd=['echo', 'Hello'])
class DeviceTester(cros_test_lib.RunCommandTestCase):
    """Test device.Device."""
    def setUp(self):
        """Common set up method for all tests."""
        opts = device.Device.GetParser().parse_args(
            ['--device', '190.0.2.130'])
        self._device = device.Device(opts)

    def CreateDevice(self, device_name, should_start_vm):
        """Creates a device.

    Args:
      device_name: Name of the device.
      should_start_vm: If True, then created device should be a VM.
    """
        created_device = device.Device.Create(vm.VM.GetParser().parse_args(
            ['--device', device_name] if device_name else []))
        self.assertEqual(isinstance(created_device, vm.VM), should_start_vm)

    def testWaitForBoot(self):
        self._device.WaitForBoot()
        # Verify that ssh command is called with all of the right configurations.
        self.assertCommandContains(['ssh', '[email protected]', '--', 'true'])

    @mock.patch('chromite.lib.cros_build_lib.run',
                side_effect=remote_access.SSHConnectionError())
    def testWaitForBootTimeOut(self, boot_mock):
        """Verify an exception is raised when the device takes to long to boot."""
        self.assertRaises(device.DeviceError,
                          self._device.WaitForBoot,
                          sleep=0)
        boot_mock.assert_called()

    @mock.patch('chromite.lib.device.Device.remote_run',
                return_value=cros_build_lib.CommandResult(returncode=1))
    def testWaitForBootReturnCode(self, boot_mock):
        """Verify an exception is raised when the returncode is not 0."""
        self.assertRaises(device.DeviceError, self._device.WaitForBoot)
        boot_mock.assert_called()

    def testRemoteCmd(self):
        """Verify remote command runs correctly with default arguments."""
        self._device.remote_run(['/usr/local/autotest/bin/vm_sanity'])
        self.assertCommandContains(['/usr/local/autotest/bin/vm_sanity'])
        self.assertCommandContains(capture_output=True,
                                   stderr=subprocess.STDOUT,
                                   log_output=True)

    def testRemoteCmdStream(self):
        """Verify remote command for streaming output."""
        self._device.remote_run('/usr/local/autotest/bin/vm_sanity',
                                stream_output=True)
        self.assertCommandContains(capture_output=False)
        self.assertCommandContains(stderr=subprocess.STDOUT,
                                   log_output=True,
                                   expected=False)

    def testCreate(self):
        """Verify Device/VM creation."""
        # Verify a VM is created when no IP is specified.
        self.CreateDevice(None, True)
        # Verify a VM isn't created, even if IP address is localhost. This can
        # happen when SSH tunneling to a remote DUT.
        self.CreateDevice('localhost:12345', False)
        # Verify a Device is created when an IP is specified.
        self.CreateDevice('190.0.2.130', False)