示例#1
0
    def run_tests(self, expectations, test_inputs, tests_to_skip, num_workers,
                  retry_attempt):
        batch_size = self._options.derived_batch_size

        # If we're retrying a test, then it's because we think it might be flaky
        # and rerunning it might provide a different result. We must restart
        # content shell to get a valid result, as otherwise state can leak
        # from previous tests. To do so, we set a batch size of 1, as that
        # prevents content shell reuse.
        if not self._options.must_use_derived_batch_size and retry_attempt >= 1:
            batch_size = 1
        self._expectations = expectations
        self._test_inputs = test_inputs

        test_run_results = TestRunResults(
            self._expectations,
            len(test_inputs) + len(tests_to_skip),
            self._test_result_sink,
        )
        self._current_run_results = test_run_results
        self._printer.num_tests = len(test_inputs)
        self._printer.num_completed = 0

        for test_name in set(tests_to_skip):
            result = test_results.TestResult(test_name)
            result.type = ResultType.Skip
            test_run_results.add(
                result,
                expected=True,
                test_is_slow=self._test_is_slow(test_name))

        self._printer.write_update('Sharding tests ...')
        locked_shards, unlocked_shards = self._sharder.shard_tests(
            test_inputs, int(self._options.child_processes),
            self._options.fully_parallel, self._options.virtual_parallel,
            batch_size == 1)

        self._reorder_tests_by_args(locked_shards)
        self._reorder_tests_by_args(unlocked_shards)

        # We don't have a good way to coordinate the workers so that they don't
        # try to run the shards that need a lock. The easiest solution is to
        # run all of the locked shards first.
        all_shards = locked_shards + unlocked_shards
        num_workers = min(num_workers, len(all_shards))

        if retry_attempt < 1:
            self._printer.print_workers_and_shards(self._port, num_workers,
                                                   len(all_shards),
                                                   len(locked_shards))

        if self._options.dry_run:
            return test_run_results

        self._printer.write_update(
            'Starting %s ...' % grammar.pluralize('worker', num_workers))

        start_time = time.time()
        try:
            with message_pool.get(self, self._worker_factory, num_workers,
                                  self._port.host) as pool:
                pool.run(('test_list', shard.name, shard.test_inputs,
                          batch_size) for shard in all_shards)

            if self._shards_to_redo:
                num_workers -= len(self._shards_to_redo)
                if num_workers > 0:
                    with message_pool.get(self, self._worker_factory,
                                          num_workers,
                                          self._port.host) as pool:
                        pool.run(('test_list', shard.name, shard.test_inputs,
                                  batch_size)
                                 for shard in self._shards_to_redo)
                else:
                    self._mark_interrupted_tests_as_skipped(
                        self._current_run_results)
                    raise TestRunInterruptedException(
                        'All workers have device failures. Exiting.')
        except TestRunInterruptedException as error:
            _log.warning(error.reason)
            test_run_results.interrupted = True
        except KeyboardInterrupt:
            self._printer.flush()
            self._printer.writeln('Interrupted, exiting ...')
            test_run_results.keyboard_interrupted = True
        except Exception as error:
            _log.debug('%s("%s") raised, exiting', error.__class__.__name__,
                       error)
            raise
        finally:
            test_run_results.run_time = time.time() - start_time

        return test_run_results
示例#2
0
    def run_tests(self, expectations, test_inputs, tests_to_skip, num_workers,
                  retry_attempt):
        self._expectations = expectations
        self._test_inputs = test_inputs
        self._retry_attempt = retry_attempt

        test_run_results = TestRunResults(
            self._expectations,
            len(test_inputs) + len(tests_to_skip))
        self._current_run_results = test_run_results
        self._printer.num_tests = len(test_inputs)
        self._printer.num_completed = 0

        if retry_attempt < 1:
            self._printer.print_expected(
                test_run_results,
                self._expectations.get_tests_with_result_type)

        for test_name in set(tests_to_skip):
            result = test_results.TestResult(test_name)
            result.type = test_expectations.SKIP
            test_run_results.add(result,
                                 expected=True,
                                 test_is_slow=self._test_is_slow(test_name))

        self._printer.write_update('Sharding tests ...')
        locked_shards, unlocked_shards = self._sharder.shard_tests(
            test_inputs, int(self._options.child_processes),
            self._options.fully_parallel, self._options.batch_size == 1)

        self._reorder_tests_by_args(locked_shards)
        self._reorder_tests_by_args(unlocked_shards)

        # We don't have a good way to coordinate the workers so that they don't
        # try to run the shards that need a lock. The easiest solution is to
        # run all of the locked shards first.
        all_shards = locked_shards + unlocked_shards
        num_workers = min(num_workers, len(all_shards))

        if retry_attempt < 1:
            self._printer.print_workers_and_shards(num_workers,
                                                   len(all_shards),
                                                   len(locked_shards))

        if self._options.dry_run:
            return test_run_results

        self._printer.write_update('Starting %s ...' %
                                   grammar.pluralize('worker', num_workers))

        start_time = time.time()
        try:
            with message_pool.get(self, self._worker_factory, num_workers,
                                  self._port.host) as pool:
                pool.run(('test_list', shard.name, shard.test_inputs)
                         for shard in all_shards)

            if self._shards_to_redo:
                num_workers -= len(self._shards_to_redo)
                if num_workers > 0:
                    with message_pool.get(self, self._worker_factory,
                                          num_workers,
                                          self._port.host) as pool:
                        pool.run(('test_list', shard.name, shard.test_inputs)
                                 for shard in self._shards_to_redo)
        except TestRunInterruptedException as error:
            _log.warning(error.reason)
            test_run_results.interrupted = True
        except KeyboardInterrupt:
            self._printer.flush()
            self._printer.writeln('Interrupted, exiting ...')
            test_run_results.keyboard_interrupted = True
        except Exception as error:
            _log.debug('%s("%s") raised, exiting', error.__class__.__name__,
                       error)
            raise
        finally:
            test_run_results.run_time = time.time() - start_time

        return test_run_results