Example #1
0
    def testStopAfterStartingDutKvmFails(self):
        """Calling .Stop after a failed .Start undoes partial .Start."""
        self.testSuccessfulCreateWithDutDir()

        # Allow .Start to run, without expectation checking (done in other tests)
        self._mock_try_create_bridge_device.return_value = (937,
                                                            self.bridge_name)
        self._mock_create_tap_device.side_effect = iter(
            [self.moblab_tap_dev, self.dut_tap_dev])
        self._mock_start_kvm.side_effect = iter(
            [self.moblab_kvm_pid_path, _TestException])
        vmsetup = moblab_vm.MoblabVm(self.workspace)
        with self.assertRaises(_TestException):
            vmsetup.Start()

        # Verify .Stop releases global resources.
        vmsetup = moblab_vm.MoblabVm(self.workspace)
        vmsetup.Stop()
        self.assertEqual(self._mock_stop_kvm.call_args_list,
                         [mock.call(self.moblab_kvm_pid_path)])
        self.assertEqual(
            self._mock_remove_tap_device.call_args_list,
            [mock.call(self.dut_tap_dev),
             mock.call(self.moblab_tap_dev)])
        self.assertEqual(self._mock_remove_network_bridge.call_args_list,
                         [mock.call(self.bridge_name)])

        # Verify that final state is persisted across instance discards.
        vmsetup = moblab_vm.MoblabVm(self.workspace)
        self.assertFalse(vmsetup.running)
        self.assertFalse(vmsetup.dut_running)
Example #2
0
    def testStopAfterStartUndoesEverythingInStackWithDut(self):
        """.Stop undoes what .Start did in reverse order."""
        self.testSuccessfulCreateWithDutDir()

        # Allow .Start to run, without expectation checking (done in other tests)
        self._mock_try_create_bridge_device.return_value = (937,
                                                            self.bridge_name)
        self._mock_create_tap_device.side_effect = iter(
            [self.moblab_tap_dev, self.dut_tap_dev])
        self._mock_start_kvm.side_effect = iter(
            [self.moblab_kvm_pid_path, self.dut_kvm_pid_path])
        vmsetup = moblab_vm.MoblabVm(self.workspace)
        vmsetup.Start()

        # Verify .Stop releases global resources.
        vmsetup = moblab_vm.MoblabVm(self.workspace)
        vmsetup.Stop()
        self.assertEqual(self._mock_stop_kvm.call_args_list, [
            mock.call(self.dut_kvm_pid_path),
            mock.call(self.moblab_kvm_pid_path)
        ])
        self.assertEqual(
            self._mock_remove_tap_device.call_args_list,
            [mock.call(self.dut_tap_dev),
             mock.call(self.moblab_tap_dev)])
        self.assertEqual(self._mock_remove_network_bridge.call_args_list,
                         [mock.call(self.bridge_name)])

        # Verify that final state is persisted across instance discards.
        vmsetup = moblab_vm.MoblabVm(self.workspace)
        self.assertFalse(vmsetup.running)
        self.assertFalse(vmsetup.dut_running)
Example #3
0
 def testMountMoblabDiskContextAfterStartRaises(self):
     """Cannot mount a disk if the workspace isn't even initialized."""
     self.testSuccessfulStartAfterCreateWithoutDut()
     vmsetup = moblab_vm.MoblabVm(self.workspace)
     with self.assertRaises(moblab_vm.MoblabVmError):
         with vmsetup.MountedMoblabDiskContext():
             pass
Example #4
0
    def Run(self):
        """The main handler of this CLI."""
        self.options.Freeze()
        cmd = self.options.moblabvm_command
        if cmd == 'create':
            # Allow the workspace to not exist. This makes the CLI uniform across the
            # 'cros moblabvm' commands, without burdening the user with a mkdir before
            # 'create'
            osutils.SafeMakedirsNonRoot(self.options.workspace)

        if not os.path.isdir(self.options.workspace):
            cros_build_lib.Die('Workspace directory %s does not exist!',
                               self.options.workspace)

        vm = moblab_vm.MoblabVm(self.options.workspace)
        if cmd == 'create':
            if self.options.clean:
                vm.Destroy()
            vm.Create(self.options.moblab_image_dir,
                      self.options.dut_image_dir,
                      create_vm_images=not self.options.source_vm_images)
        elif cmd == 'start':
            if self.options.restart:
                vm.Stop()
            vm.Start()
            _Describe(vm)
        elif cmd == 'stop':
            vm.Stop()
        elif cmd == 'destroy':
            vm.Destroy()
        elif cmd == 'describe':
            _Describe(vm)
        else:
            assert False, 'Unrecognized command %s!' % cmd
Example #5
0
 def setUp(self):
     self.builder = 'moblab-generic-vm/R12-3.4.5-67-890'
     self.image_dir = self.MockDirectory('files/image')
     self.payload_dir = self.MockDirectory('files/payload')
     self.results_dir = self.MockDirectory('results')
     self.vms = moblab_vm.MoblabVm(self.tempdir)
     self.chroot = chroot_lib.Chroot(path=self.tempdir)
 def testRunVmsContextNoFailure(self):
   """Calls .Start and .Stop in a basic use case."""
   vmsetup = moblab_vm.MoblabVm(self.workspace)
   start = self.PatchObject(moblab_vm.MoblabVm, 'Start')
   destroy = self.PatchObject(moblab_vm.MoblabVm, 'Destroy')
   with vmsetup.RunVmsContext():
     pass
   self.assertEqual(start.call_count, 1)
   self.assertEqual(destroy.call_count, 1)
 def testRunVmsContextWithFailure(self):
   """Calls .Start and .Stop when exception is raised within context."""
   vmsetup = moblab_vm.MoblabVm(self.workspace)
   start = self.PatchObject(moblab_vm.MoblabVm, 'Start')
   destroy = self.PatchObject(moblab_vm.MoblabVm, 'Destroy')
   try:
     with vmsetup.RunVmsContext():
       raise ValueError('uh oh!')
   except ValueError:
     self.assertEqual(start.call_count, 1)
     self.assertEqual(destroy.call_count, 1)
  def _testSuccessfulStartAfterCreate(self, with_dut):
    """A successful call to .Start, with or without a dut attached.

    This helper methods lets us 'parameterize' a longish test. Only change
    expectations based on the arguments. DO NOT change the interactions with
    MolabVm.
    """
    self._mock_try_create_bridge_device.return_value = (self._PORT,
                                                        self.bridge_name)
    self._mock_create_tap_device.side_effect = iter([self.moblab_tap_dev,
                                                     self.dut_tap_dev])

    # Create a new moblabvm instance. MoblabVm persists everything to disk an
    # must work seamlessly across instance discards.
    vmsetup = moblab_vm.MoblabVm(self.workspace, chroot_dir=self.chroot)
    vmsetup.Start()
    self.assertTrue(vmsetup.initialized)
    self.assertTrue(vmsetup.running)
    self.assertEqual(vmsetup.dut_running, with_dut)

    self.assertEqual(self._mock_try_create_bridge_device.call_count, 1)
    self.assertEqual(self._mock_create_tap_device.call_count, 2)
    # Different suffixes are used for tap devices.
    self.assertNotEqual(
        self._mock_create_tap_device.call_args_list[0][0][0],
        self._mock_create_tap_device.call_args_list[1][0][0],
    )
    self.assertEqual(
        self._mock_connect_device_to_bridge.call_args_list,
        [
            mock.call('moblabtap', self.bridge_name),
            mock.call('duttap', self.bridge_name),
        ])

    vm_calls = [mock.call(
        self.moblab_image_path, self._PORT + 2, self._PORT + 6,
        self.moblab_tap_dev, mock.ANY, is_moblab=True,
        disk_path=self.moblab_disk_path, chroot_path=self.chroot)]
    if with_dut:
      vm_calls.append(mock.call(
          self.dut_image_path, self._PORT + 6, self._PORT + 7,
          self.dut_tap_dev, mock.ANY, is_moblab=False, chroot_path=self.chroot))
    self.assertEqual(self._mock_start_vm.call_args_list, vm_calls)
    if with_dut:
      # Different SSH ports are used for the two VMs
      self.assertNotEqual(
          self._mock_start_vm.call_args_list[0][0][1],
          self._mock_start_vm.call_args_list[1][0][1],
      )
      # Different MAC addresses are used for secondary networks of two VMs.
      self.assertNotEqual(
          self._mock_start_vm.call_args_list[0][0][3],
          self._mock_start_vm.call_args_list[1][0][3],
      )
Example #9
0
    def testSuccessfulCreateNoCreateVm(self):
        """A successful call to .Create w/o create_vm_images."""
        self._mock_create_moblab_disk.return_value = self.moblab_disk_path
        osutils.SafeMakedirsNonRoot(self.moblab_from_path)
        osutils.WriteFile(
            os.path.join(self.moblab_from_path, 'chromiumos_qemu_image.bin'),
            'fake_image')

        vmsetup = moblab_vm.MoblabVm(self.workspace)
        vmsetup.Create(self.moblab_from_path, create_vm_images=False)
        self.assertEqual(self._mock_create_vm_image.call_count, 0)
        self._mock_create_moblab_disk.assert_called_once_with(
            self.moblab_workdir_path)
        self.assertTrue(vmsetup.initialized)
        self.assertFalse(vmsetup.running)
        self.assertFalse(vmsetup.dut_running)
Example #10
0
def CreateMoblabVm(workspace_dir, chroot_dir, image_dir):
  """Create the moblab VMs.

  Assumes that image_dir is in exactly the state it was after building
  a test image and then converting it to a VM image.

  Args:
    workspace_dir (str): Workspace for the moblab VM.
    chroot_dir (str): Directory containing the chroot for the moblab VM.
    image_dir (str): Directory containing the VM image.

  Returns:
    MoblabVm: The resulting VM.
  """
  vms = moblab_vm.MoblabVm(workspace_dir, chroot_dir=chroot_dir)
  vms.Create(image_dir, dut_image_dir=image_dir, create_vm_images=False)
  return vms
Example #11
0
    def testSuccessfulCreateNoDutDir(self):
        """A successful call to .Create not using a DUT image."""
        self._mock_create_vm_image.return_value = os.path.join(
            self.moblab_workdir_path, 'chromiumos_qemu_image.bin')
        self._mock_create_moblab_disk.return_value = self.moblab_disk_path

        vmsetup = moblab_vm.MoblabVm(self.workspace)
        vmsetup.Create(self.moblab_from_path)
        self._mock_create_vm_image.assert_called_once_with(
            self.moblab_from_path, self.moblab_workdir_path)
        self._mock_create_moblab_disk.assert_called_once_with(
            self.moblab_workdir_path)
        self.assertExists(self.moblab_workdir_path)
        self.assertNotExists(self.dut_workdir_path)
        self.assertTrue(vmsetup.initialized)
        self.assertFalse(vmsetup.running)
        self.assertFalse(vmsetup.dut_running)
Example #12
0
    def _PerformStage(self, workdir, results_dir):
        """Actually performs this stage.

    Args:
      workdir: The workspace directory to use for all temporary files.
      results_dir: The directory to use to drop test results into.
    """
        dut_target_image = self._SubDutTargetImage()
        osutils.SafeMakedirsNonRoot(self._Workspace(workdir))
        vms = moblab_vm.MoblabVm(self._Workspace(workdir))
        try:
            r = ' reached %s test run timeout.' % self
            with timeout_util.Timeout(self._PERFORM_TIMEOUT_S,
                                      reason_message=r):
                start_time = datetime.datetime.now()
                vms.Create(self.GetImageDirSymlink(),
                           self.GetImageDirSymlink())
                payload_dir = self._GenerateTestArtifactsInMoblabDisk(vms)
                vms.Start()

                elapsed = (datetime.datetime.now() -
                           start_time).total_seconds()
                RunMoblabTests(
                    moblab_board=self._current_board,
                    moblab_ip=vms.moblab_ssh_port,
                    dut_target_image=dut_target_image,
                    results_dir=results_dir,
                    local_image_cache=payload_dir,
                    timeout_m=(self._PERFORM_TIMEOUT_S - elapsed) // 60,
                )

            vms.Stop()
            ValidateMoblabTestSuccess(results_dir)
        except:
            # Ignore errors while arhiving images, but re-raise the original error.
            try:
                vms.Stop()
                self._ArchiveMoblabVMWorkspace(self._Workspace(workdir))
            except Exception as e:
                logging.error(
                    'Failed to archive VM images after test failure: %s', e)
            raise
        finally:
            vms.Destroy()
Example #13
0
    def testSuccessfulCreateWithDutDir(self):
        """A successful call to .Create using a DUT image."""
        self._mock_create_vm_image.side_effect = iter(
            [self.moblab_image_path, self.dut_image_path])
        self._mock_create_moblab_disk.return_value = os.path.join(
            self.moblab_workdir_path, 'disk')

        vmsetup = moblab_vm.MoblabVm(self.workspace)
        vmsetup.Create(self.moblab_from_path, self.dut_from_path)
        self.assertEqual(
            self._mock_create_vm_image.call_args_list,
            [
                mock.call(self.moblab_from_path, self.moblab_workdir_path),
                mock.call(self.dut_from_path, self.dut_workdir_path),
            ],
        )
        self.assertExists(self.moblab_workdir_path)
        self.assertExists(self.dut_workdir_path)
        self._mock_create_moblab_disk.assert_called_once_with(
            self.moblab_workdir_path)
        self.assertTrue(vmsetup.initialized)
        self.assertFalse(vmsetup.running)
        self.assertFalse(vmsetup.dut_running)
Example #14
0
 def testMountMoblabDiskContextInUninitilizedWorkspaceRaises(self):
     """Cannot mount a disk if the workspace isn't even initialized."""
     vmsetup = moblab_vm.MoblabVm(self.workspace)
     with self.assertRaises(moblab_vm.MoblabVmError):
         with vmsetup.MountedMoblabDiskContext():
             pass
Example #15
0
 def testStartWithoutCreateRaises(self):
     """Calling .Start before .Create is an error."""
     vmsetup = moblab_vm.MoblabVm(self.workspace)
     with self.assertRaises(moblab_vm.StartError):
         vmsetup.Start()
Example #16
0
 def testSuccessfulMountMoblabDiskContextAfter(self):
     """MountMoblabDiskContext works OK for initialized, non-running VM."""
     self.testSuccessfulCreateNoDutDir()
     vmsetup = moblab_vm.MoblabVm(self.workspace)
     with vmsetup.MountedMoblabDiskContext() as mounted_path:
         self.assertStartsWith(mounted_path, self.tempdir)
Example #17
0
 def testInstanceInitialization(self):
     """Sanity check attributes before using the instance for anything."""
     vmsetup = moblab_vm.MoblabVm(self.workspace)
     self.assertFalse(vmsetup.initialized)
     self.assertFalse(vmsetup.running)
     self.assertFalse(vmsetup.dut_running)
Example #18
0
 def testCreateNoCreateVmRaisesWhenSourceImageMissing(self):
     """A call to .Create w/o create_vm_images expects source image to exist."""
     vmsetup = moblab_vm.MoblabVm(self.workspace)
     with self.assertRaises(moblab_vm.SetupError):
         vmsetup.Create(self.moblab_from_path, create_vm_images=False)