Running the test runner from an AI coding agent burns a large part of the agent's context on output it never reads: the status file variables alone are ~2.5KB of a ~1.9KB-plus-noise run, and the progress display redraws a status line the agent sees as a wall of control characters. Add --quiet, which suppresses the build/statusfile/processor headers and selects the 'none' progress indicator printing only failures and a one-line summary. It is enabled by default when one of depot_tools' AI agent environment variables is set, matching what siso does for ninja, and prints the same style of notification so a human reading the transcript knows why the usual output is missing. --no-quiet opts out. The unit test harness now hides those variables while running the runner, so expected output doesn't depend on who runs the tests. Change-Id: I5cb8dff5e6f5d9a18818ba24a4be433638431208 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/8175711 Commit-Queue: Michael Achenbach <machenbach@chromium.org> Auto-Submit: Jakob Linke <jgruber@chromium.org> Reviewed-by: Michael Achenbach <machenbach@chromium.org> Cr-Commit-Position: refs/heads/main@{#109038}
100 lines
3.1 KiB
Python
100 lines
3.1 KiB
Python
# Copyright 2018 the V8 project authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
|
|
from . import base
|
|
from testrunner.local import utils
|
|
from testrunner.testproc.indicators import (
|
|
JsonTestProgressIndicator, TestScheduleIndicator, PROGRESS_INDICATORS)
|
|
from testrunner.testproc.resultdb import rdb_sink, ResultDBIndicator
|
|
|
|
|
|
class ResultsTracker(base.TestProcObserver):
|
|
@staticmethod
|
|
def create(options):
|
|
return ResultsTracker(options.exit_after_n_failures, options.quiet)
|
|
|
|
"""Tracks number of results and stops to run tests if max_failures reached."""
|
|
|
|
def __init__(self, max_failures, quiet):
|
|
super(ResultsTracker, self).__init__()
|
|
self._requirement = base.DROP_OUTPUT
|
|
|
|
self.failed = 0
|
|
self.remaining = 0
|
|
self.total = 0
|
|
self.max_failures = max_failures
|
|
self.quiet = quiet
|
|
|
|
def _on_next_test(self, test):
|
|
self.total += 1
|
|
self.remaining += 1
|
|
|
|
def _on_result_for(self, test, result):
|
|
self.remaining -= 1
|
|
# Count failures - treat flakes as failures, too.
|
|
if result.has_unexpected_output or result.is_rerun:
|
|
self.failed += 1
|
|
if self.max_failures and self.failed >= self.max_failures:
|
|
print('>>> Too many failures, exiting...')
|
|
self.stop()
|
|
|
|
def standard_show(self, tests):
|
|
if not self.quiet:
|
|
if tests.test_count_estimate:
|
|
percentage = float(self.total) / tests.test_count_estimate * 100
|
|
else:
|
|
percentage = 0
|
|
print(('>>> %d base tests produced %d (%d%s)'
|
|
' non-filtered tests') %
|
|
(tests.test_count_estimate, self.total, percentage, '%'))
|
|
# Always report how many tests ran: without it, an over-eager filter that
|
|
# matched nothing is indistinguishable from a successful run.
|
|
print('>>> %d tests ran' % (self.total - self.remaining))
|
|
|
|
def exit_code(self):
|
|
exit_code = utils.EXIT_CODE_PASS
|
|
if self.failed:
|
|
exit_code = utils.EXIT_CODE_FAILURES
|
|
if not self.total:
|
|
exit_code = utils.EXIT_CODE_NO_TESTS
|
|
return exit_code
|
|
|
|
|
|
class ProgressProc(base.TestProcObserver):
|
|
|
|
def __init__(self, context, options, test_count):
|
|
super(ProgressProc, self).__init__()
|
|
self.procs = [
|
|
PROGRESS_INDICATORS[options.progress](context, options, test_count)
|
|
]
|
|
if options.log_test_schedule:
|
|
self.procs.insert(
|
|
0,
|
|
TestScheduleIndicator(context, options, test_count))
|
|
if options.json_test_results:
|
|
self.procs.insert(
|
|
0,
|
|
JsonTestProgressIndicator(context, options, test_count))
|
|
sink = rdb_sink()
|
|
if sink:
|
|
self.procs.append(ResultDBIndicator(context, options, test_count, sink))
|
|
self._requirement = max(proc._requirement for proc in self.procs)
|
|
|
|
def _on_result_for(self, test, result):
|
|
for proc in self.procs:
|
|
proc.on_test_result(test, result)
|
|
|
|
def finished(self):
|
|
for proc in self.procs:
|
|
proc.finished()
|
|
|
|
def _on_heartbeat(self):
|
|
for proc in self.procs:
|
|
proc.on_heartbeat()
|
|
|
|
def _on_event(self, event):
|
|
for proc in self.procs:
|
|
proc.on_event(event)
|