def _RunSuite(self, test_exprs, suite_chroot_results_dir, timeout):
    """Runs a collection of tests.

    Args:
      test_exprs: List of string expressions describing which tests to run; this
                  is passed directly to the 'tast run' command. See
                  https://goo.gl/UPNEgT for info about test expressions.
      suite_chroot_results_dir: String containing path of directory where the
                                tast command should store test results,
                                relative to chroot.
      timeout: Integer containing timeout in seconds to pass to Tast. This is
               used to let the Tast process reserve adequate time to collect
               system information after running tests so that it can exit
               cleanly instead of being killed.

    Raises:
      failures_lib.TestFailure if an internal error is encountered.
    """
    vm_path = os.path.join(self.GetImageDirSymlink(), constants.VM_IMAGE_BIN)
    results_dir = self._MakeChrootPathAbsolute(suite_chroot_results_dir)
    cmd = ['./cros_run_test', '--no-display', '--copy-on-write', '--debug',
           '--board=%s' % self._current_board, '--image-path=%s' % vm_path,
           '--results-dir=%s' % results_dir, '--test-timeout=%d' % timeout,
           '--tast'] + test_exprs

    result = cros_build_lib.run(
        cmd, error_code_ok=True, cwd=constants.CHROMITE_BIN_DIR,
        kill_timeout=TastVMTestStage.CLEANUP_TIMEOUT_SEC
    )
    if result.returncode:
      raise failures_lib.TestFailure(FAILURE_EXIT_CODE % result.returncode)
 def testTastVMTestStageFails(self):
   """Verify VMTestStage is still run when TastVMTestStage fails."""
   self.stage_exceptions = {
       tast_test_stages.TastVMTestStage: failures_lib.TestFailure(),
   }
   self.assertEquals([failures_lib.TestFailure], self._RunVMTests())
   self.assertEquals(self.all_vm_test_stages, self.called_stages)
Beispiel #3
0
def _RunTestSuiteUsingCtest(buildroot,
                            board,
                            image_path,
                            results_dir,
                            test_config,
                            allow_chrome_crashes,
                            ssh_private_key=None,
                            ssh_port=9228):
    """Runs the test harness suite using the ctest code path."""
    results_dir_in_chroot = os.path.join(buildroot, 'chroot',
                                         results_dir.lstrip('/'))
    osutils.RmDir(results_dir_in_chroot, ignore_missing=True)

    test_type = test_config.test_type
    cwd = os.path.join(buildroot, 'src', 'scripts')
    dut_type = 'gce' if test_type == constants.GCE_SUITE_TEST_TYPE else 'vm'

    crostestutils = os.path.join(buildroot, 'src', 'platform', 'crostestutils')
    cmd = [
        os.path.join(crostestutils, 'au_test_harness',
                     'cros_au_test_harness.py'),
        '--board=%s' % board,
        '--type=%s' % dut_type, '--no_graphics', '--verbose',
        '--target_image=%s' % image_path,
        '--test_results_root=%s' % results_dir_in_chroot
    ]

    if test_type not in constants.VALID_VM_TEST_TYPES:
        raise AssertionError('Unrecognized test type %r' % test_type)

    if test_type in [
            constants.VM_SUITE_TEST_TYPE, constants.GCE_SUITE_TEST_TYPE
    ]:
        cmd.append('--ssh_port=%s' % ssh_port)
        cmd.append('--verify_suite_name=%s' % test_config.test_suite)

    cmd.append('--test_prefix=SimpleTestVerify')

    if allow_chrome_crashes:
        cmd.append('--allow_chrome_crashes')

    if ssh_private_key is not None:
        cmd.append('--ssh_private_key=%s' % ssh_private_key)

    # Give tests 10 minutes to clean up before shutting down.
    result = cros_build_lib.run(cmd,
                                cwd=cwd,
                                check=False,
                                kill_timeout=10 * 60)
    if result.returncode:
        if os.path.exists(results_dir_in_chroot):
            error = '%s exited with code %d' % (' '.join(cmd),
                                                result.returncode)
            with open(results_dir_in_chroot + '/failed_test_command',
                      'w') as failed:
                failed.write(error)

        raise failures_lib.TestFailure('** VMTests failed with code %d **' %
                                       result.returncode)
    def _ProcessResultsFile(self, abs_results_dir, url_base, suite_names):
        """Parses the results file and prints links to failed tests.

    Args:
      abs_results_dir: Absolute path to directory containing test results.
      url_base: Relative path within the archive dir where results are stored.
      suite_names: List of string test suite names.

    Raises:
      failures_lib.TestFailure if one or more tests failed or results were
        missing or unreadable.
    """
        num_failed = 0

        for suite_name in sorted(suite_names):
            results_path = os.path.join(abs_results_dir, suite_name,
                                        RESULTS_FILENAME)

            # The results file contains an array with objects representing tests.
            # Each object should contain the test name in a 'name' attribute and a
            # list of errors in an 'error' attribute.
            try:
                with open(results_path, 'r') as f:
                    for test in json.load(f):
                        # Report the test as failed if it didn't finish or had errors.
                        if test[RESULTS_END_KEY] == ZERO_TIME or test[
                                RESULTS_ERRORS_KEY]:
                            name = test[RESULTS_NAME_KEY]
                            informational = (RESULTS_INFORMATIONAL_ATTR
                                             in test.get(RESULTS_ATTR_KEY, []))
                            test_url = os.path.join(url_base, suite_name,
                                                    RESULTS_TESTS_DIR, name)
                            desc = INFORMATIONAL_PREFIX + name if informational else name
                            self.PrintDownloadLink(test_url,
                                                   text_to_display=desc)

                            # Ignore the failure if the test was marked informational.
                            if not informational:
                                num_failed += 1
            except Exception as e:
                raise failures_lib.TestFailure(FAILURE_BAD_RESULTS %
                                               (results_path, str(e)))

        if num_failed > 0:
            logging.error('%d test(s) failed', num_failed)
            raise failures_lib.TestFailure(FAILURE_TESTS_FAILED % num_failed)
Beispiel #5
0
def ValidateMoblabVmTest(results_dir):
  """Determine if the VM test passed or not.

  Args:
    results_dir (str): Path to directory containing test_that results.

  Raises:
    failures_lib.TestFailure: If dummy_PassServer did not run or failed.
  """
  log_file = os.path.join(results_dir, 'debug', 'test_that.INFO')
  if not os.path.isfile(log_file):
    raise failures_lib.TestFailure('Found no test_that logs at %s' % log_file)

  log_file_contents = osutils.ReadFile(log_file)
  if not re.match(r'dummy_PassServer\s*\[\s*PASSED\s*]', log_file_contents):
    raise failures_lib.TestFailure('Moblab run_suite succeeded, but did '
                                   'not successfully run dummy_PassServer.')
 def testAllVMTestStagesFail(self):
   """Verify failures are reported when all VM test stages fail."""
   self.stage_exceptions = {
       vm_test_stages.VMTestStage: failures_lib.InfrastructureFailure(),
       tast_test_stages.TastVMTestStage: failures_lib.TestFailure(),
   }
   self.assertEquals(
       [failures_lib.InfrastructureFailure, failures_lib.TestFailure],
       self._RunVMTests())
   self.assertEquals(self.all_vm_test_stages, self.called_stages)
Beispiel #7
0
def ValidateMoblabTestSuccess(results_dir):
    """Verifies that moblab tests ran, and succeeded.

  Looks at the result logs dropped by the moblab tests and sanity checks that
  the expected tests ran, and were successful.
  """
    log_path = os.path.join(results_dir, 'debug', 'test_that.INFO')
    if not os.path.isfile(log_path):
        raise failures_lib.TestFailure('Could not find test_that logs at %s' %
                                       log_path)

    dummy_pass_server_success_re = re.compile(
        r'dummy_PassServer\s*\[\s*PASSED\s*]')
    with open(log_path) as log_file:
        for line in log_file:
            if dummy_pass_server_success_re.search(line):
                return

    raise failures_lib.TestFailure(
        'Moblab run_suite succeeded, but did not successfully run '
        'dummy_PassServer')
Beispiel #8
0
def _RunTestSuiteUsingChromite(board,
                               image_path,
                               results_dir,
                               test_config,
                               allow_chrome_crashes,
                               ssh_private_key=None,
                               ssh_port=9228):
    """Runs the test harness suite using the chromite code path."""
    image_dir = os.path.dirname(image_path)
    vm_image_path = os.path.join(image_dir, constants.VM_IMAGE_BIN)

    cmd = [
        'cros_run_test',
        '--debug',
        '--board=%s' % board,
        '--image-path=%s' % path_util.ToChrootPath(vm_image_path),
        '--ssh-port=%s' % ssh_port,
        '--autotest=suite:%s' % test_config.test_suite,
        '--results-dir=%s' % results_dir,
    ]

    if allow_chrome_crashes:
        cmd.append('--test_that-args=--allow-chrome-crashes')

    if ssh_private_key is not None:
        cmd.append('--private-key=%s' %
                   path_util.ToChrootPath(ssh_private_key))

    # Give tests 10 minutes to clean up before shutting down.
    result = cros_build_lib.run(cmd,
                                check=False,
                                kill_timeout=10 * 60,
                                enter_chroot=True)
    if result.returncode:
        results_dir_in_chroot = os.path.join(constants.SOURCE_ROOT,
                                             constants.DEFAULT_CHROOT_DIR,
                                             results_dir.lstrip('/'))
        if os.path.exists(results_dir_in_chroot):
            error = '%s exited with code %d' % (' '.join(cmd),
                                                result.returncode)
            with open(results_dir_in_chroot + '/failed_test_command',
                      'w') as failed:
                failed.write(error)

        raise failures_lib.TestFailure('** VMTests failed with code %d **' %
                                       result.returncode)
    def _ProcessAndArchiveResults(self, abs_results_dir, suite_names,
                                  already_have_error):
        """Processes and archives test results.

    Args:
      abs_results_dir: Absolute path to directory containing test results.
      suite_names: List of string test suite names.
      already_have_error: Boolean for whether testing has already failed.

    Raises:
      failures_lib.TestFailure if one or more tests failed or results were
        unavailable. Suppressed if already_have_error is True.
    """
        if not os.path.isdir(abs_results_dir) or not os.listdir(
                abs_results_dir):
            raise failures_lib.TestFailure(FAILURE_NO_RESULTS %
                                           abs_results_dir)

        archive_base = constants.TAST_VM_TEST_RESULTS % {
            'attempt': self._attempt
        }
        _CopyResultsDir(abs_results_dir,
                        os.path.join(self.archive_path, archive_base))

        # TODO(crbug.com/770562): Collect stack traces once the tast executable is
        # symbolizing and collecting them (see VMTestStage._ArchiveTestResults).

        # Now archive the results to Cloud Storage.
        logging.info('Uploading artifacts to Cloud Storage...')
        self.UploadArtifact(archive_base, archive=False, strict=False)
        self.PrintDownloadLink(archive_base, RESULTS_LINK_PREFIX)

        try:
            self._ProcessResultsFile(abs_results_dir, archive_base,
                                     suite_names)
        except Exception as e:
            # Don't raise a new exception if testing already failed.
            if already_have_error:
                logging.exception(
                    'Got error while archiving or processing results')
            else:
                raise e
        finally:
            osutils.RmDir(abs_results_dir, ignore_missing=True, sudo=True)
Beispiel #10
0
    def _RunSuite(self, test_exprs, suite_chroot_results_dir):
        """Runs a collection of tests.

    Args:
      test_exprs: List of string expressions describing which tests to run; this
                  is passed directly to the 'tast run' command. See
                  https://goo.gl/UPNEgT for info about test expressions.
      suite_chroot_results_dir: String containing path of directory where the
                                tast command should store test results,
                                relative to chroot.

    Raises:
      failures_lib.TestFailure if an internal error is encountered.
    """
        image = os.path.join(self.GetImageDirSymlink(),
                             constants.TEST_IMAGE_BIN)
        ssh_key = os.path.join(self.GetImageDirSymlink(),
                               constants.TEST_KEY_PRIVATE)
        cmd = [
            TastVMTestStage.SCRIPT_PATH,
            '--board=' + self._current_board,
            '--image_path=' + image,
            '--ssh_private_key=' + ssh_key,
            '--no_graphics',
            '--results_dir=' + suite_chroot_results_dir,
        ]
        cmd += test_exprs

        result = cros_build_lib.RunCommand(
            cmd,
            cwd=os.path.join(self._build_root, 'src/scripts'),
            error_code_ok=True,
            kill_timeout=TastVMTestStage.CLEANUP_TIMEOUT_SEC)
        if result.returncode:
            raise failures_lib.TestFailure(FAILURE_EXIT_CODE %
                                           result.returncode)
Beispiel #11
0
    def _RunHWTestSuite(self,
                        debug=False,
                        fails=False,
                        warns=False,
                        cmd_fail_mode=None):
        """Verify the stage behavior in various circumstances.

    Args:
      debug: Whether the HWTest suite should be run in debug mode.
      fails: Whether the stage should fail.
      warns: Whether the stage should warn.
      cmd_fail_mode: How commands.RunHWTestSuite() should fail.
        If None, don't fail.
    """
        # We choose to define these mocks in setUp() because they are
        # useful for tests that do not call this method. However, this
        # means we have to reset the mocks before each run.
        self.run_suite_mock.reset_mock()
        self.warning_mock.reset_mock()
        self.failure_mock.reset_mock()

        to_raise = None

        if cmd_fail_mode == None:
            to_raise = None
        elif cmd_fail_mode == 'timeout':
            to_raise = timeout_util.TimeoutError('Timed out')
        elif cmd_fail_mode == 'suite_timeout':
            to_raise = failures_lib.SuiteTimedOut('Suite timed out')
        elif cmd_fail_mode == 'board_not_available':
            to_raise = failures_lib.BoardNotAvailable('Board not available')
        elif cmd_fail_mode == 'lab_fail':
            to_raise = failures_lib.TestLabFailure('Test lab failure')
        elif cmd_fail_mode == 'test_warn':
            to_raise = failures_lib.TestWarning('Suite passed with warnings')
        elif cmd_fail_mode == 'test_fail':
            to_raise = failures_lib.TestFailure('HWTest failed.')
        else:
            raise ValueError('cmd_fail_mode %s not supported' % cmd_fail_mode)

        if cmd_fail_mode == 'timeout':
            self.run_suite_mock.side_effect = to_raise
        else:
            self.run_suite_mock.return_value = commands.HWTestSuiteResult(
                to_raise, None)

        if fails:
            self.assertRaises(failures_lib.StepFailure, self.RunStage)
        else:
            self.RunStage()

        self.run_suite_mock.assert_called_once()
        self.assertEqual(self.run_suite_mock.call_args[1].get('debug'), debug)

        # Make sure we print the buildbot failure/warning messages correctly.
        if fails:
            self.failure_mock.assert_called_once()
        else:
            self.assertFalse(self.failure_mock.called)

        if warns:
            self.warning_mock.assert_called_once()
        else:
            self.assertFalse(self.warning_mock.called)
Beispiel #12
0
def RunTestSuite(buildroot,
                 board,
                 image_path,
                 results_dir,
                 test_config,
                 whitelist_chrome_crashes,
                 archive_dir,
                 ssh_private_key=None,
                 ssh_port=9228):
    """Runs the test harness suite."""
    results_dir_in_chroot = os.path.join(buildroot, 'chroot',
                                         results_dir.lstrip('/'))
    osutils.RmDir(results_dir_in_chroot, ignore_missing=True)

    test_type = test_config.test_type
    cwd = os.path.join(buildroot, 'src', 'scripts')
    dut_type = 'gce' if test_type == constants.GCE_SUITE_TEST_TYPE else 'vm'

    cmd = [
        'bin/ctest',
        '--board=%s' % board,
        '--type=%s' % dut_type, '--no_graphics', '--verbose',
        '--target_image=%s' % image_path,
        '--test_results_root=%s' % results_dir_in_chroot
    ]

    if test_type not in constants.VALID_VM_TEST_TYPES:
        raise AssertionError('Unrecognized test type %r' % test_type)

    if test_type == constants.FULL_AU_TEST_TYPE:
        cmd.append('--archive_dir=%s' % archive_dir)
    elif test_type in [
            constants.VM_SUITE_TEST_TYPE, constants.GCE_SUITE_TEST_TYPE
    ]:
        cmd.append('--ssh_port=%s' % ssh_port)
        cmd.append('--only_verify')
        cmd.append('--suite=%s' % test_config.test_suite)
    else:
        cmd.append('--quick_update')

    if whitelist_chrome_crashes:
        cmd.append('--whitelist_chrome_crashes')

    if ssh_private_key is not None:
        cmd.append('--ssh_private_key=%s' % ssh_private_key)

    # Give tests 10 minutes to clean up before shutting down.
    result = cros_build_lib.RunCommand(cmd,
                                       cwd=cwd,
                                       error_code_ok=True,
                                       kill_timeout=10 * 60)
    if result.returncode:
        if os.path.exists(results_dir_in_chroot):
            error = '%s exited with code %d' % (' '.join(cmd),
                                                result.returncode)
            with open(results_dir_in_chroot + '/failed_test_command',
                      'w') as failed:
                failed.write(error)

        raise failures_lib.TestFailure('** VMTests failed with code %d **' %
                                       result.returncode)