[test] Disable reduce result on the main process

Since we're not winning anything by changing the result between
processors on the main process, reduce is noop there and result is
immutable.

Bug: v8:6917
Change-Id: Ieb282e7abd4ab31162aee6b52493a6e1b6a25109
Cq-Include-Trybots: luci.v8.try:v8_linux64_fyi_rel_ng
Reviewed-on: https://chromium-review.googlesource.com/878239
Commit-Queue: Michał Majewski <majeski@google.com>
Reviewed-by: Michael Achenbach <machenbach@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50784}
This commit is contained in:
Michal Majewski 2018-01-23 09:20:56 +01:00 committed by Commit Bot
parent a262b54474
commit 0998eda9a4
6 changed files with 54 additions and 50 deletions

View File

@ -27,9 +27,11 @@
import signal
import copy
from ..local import utils
class Output(object):
def __init__(self, exit_code, timed_out, stdout, stderr, pid, duration):
@ -40,6 +42,13 @@ class Output(object):
self.pid = pid
self.duration = duration
def without_text(self):
"""Returns copy of the output without stdout and stderr."""
other = copy.copy(self)
other.stdout = None
other.stderr = None
return other
def HasCrashed(self):
if utils.IsWindows():
return 0x80000000 & self.exit_code and not (0x3FFFFF00 & self.exit_code)

View File

@ -31,9 +31,6 @@ class OutProc(outproc_base.BaseOutProc):
super(OutProc, self).__init__()
self._outproc = _outproc
def process(self, output):
return Result(self.has_unexpected_output(output), output)
def has_unexpected_output(self, output):
return output.exit_code != 0

View File

@ -2,9 +2,10 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import collections
import itertools
from ..testproc.base import (
DROP_RESULT, DROP_OUTPUT, DROP_PASS_OUTPUT, DROP_PASS_STDOUT)
from ..local import statusfile
from ..testproc.result import Result
@ -14,12 +15,30 @@ OUTCOMES_FAIL = [statusfile.FAIL]
class BaseOutProc(object):
def process(self, output):
return Result(self.has_unexpected_output(output), output)
def process(self, output, reduction=None):
has_unexpected_output = self.has_unexpected_output(output)
return self._create_result(has_unexpected_output, output, reduction)
def has_unexpected_output(self, output):
return self.get_outcome(output) not in self.expected_outcomes
def _create_result(self, has_unexpected_output, output, reduction):
"""Creates Result instance. When reduction is passed it tries to drop some
parts of the result to save memory and time needed to send the result
across process boundary. None disables reduction and full result is created.
"""
if reduction == DROP_RESULT:
return None
if reduction == DROP_OUTPUT:
return Result(has_unexpected_output, None)
if not has_unexpected_output:
if reduction == DROP_PASS_OUTPUT:
return Result(has_unexpected_output, None)
if reduction == DROP_PASS_STDOUT:
return Result(has_unexpected_output, output.without_text())
return Result(has_unexpected_output, output)
def get_outcome(self, output):
if output.HasCrashed():
return statusfile.CRASH

View File

@ -37,31 +37,6 @@ DROP_OUTPUT = 1
DROP_PASS_OUTPUT = 2
DROP_PASS_STDOUT = 3
def get_reduce_result_function(requirement):
if requirement == DROP_RESULT:
return lambda _: None
if requirement == DROP_OUTPUT:
def f(result):
result.output = None
return result
return f
if requirement == DROP_PASS_OUTPUT:
def f(result):
if not result.has_unexpected_output:
result.output = None
return result
return f
if requirement == DROP_PASS_STDOUT:
def f(result):
if not result.has_unexpected_output:
result.output.stdout = None
result.output.stderr = None
return result
return f
class TestProc(object):
def __init__(self):
@ -90,8 +65,14 @@ class TestProc(object):
self._prev_requirement = requirement
if self._next_proc:
self._next_proc.setup(max(requirement, self._requirement))
if self._prev_requirement < self._requirement:
self._reduce_result = get_reduce_result_function(self._prev_requirement)
# Since we're not winning anything by droping part of the result we are
# dropping the whole result or pass it as it is. The real reduction happens
# during result creation (in the output processor), so the result is
# immutable.
if (self._prev_requirement < self._requirement and
self._prev_requirement == DROP_RESULT):
self._reduce_result = lambda _: None
def next_test(self, test):
"""

View File

@ -15,12 +15,12 @@ def run_job(job, process_context):
return job.run(process_context)
def create_process_context(requirement):
return ProcessContext(base.get_reduce_result_function(requirement))
def create_process_context(result_reduction):
return ProcessContext(result_reduction)
JobResult = collections.namedtuple('JobResult', ['id', 'result'])
ProcessContext = collections.namedtuple('ProcessContext', ['reduce_result_f'])
ProcessContext = collections.namedtuple('ProcessContext', ['result_reduction'])
class Job(object):
@ -32,9 +32,8 @@ class Job(object):
def run(self, process_ctx):
output = self.cmd.execute()
result = self.outproc.process(output)
if not self.keep_output:
result = process_ctx.reduce_result_f(result)
reduction = process_ctx.result_reduction if not self.keep_output else None
result = self.outproc.process(output, reduction)
return JobResult(self.test_id, result)

View File

@ -2,7 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import copy
import json
import os
import sys
@ -70,25 +69,25 @@ class SimpleProgressIndicator(ProgressIndicator):
def _on_result_for(self, test, result):
# TODO(majeski): Support for dummy/grouped results
if result.has_unexpected_output:
self._failed.append((test, result.cmd, copy.copy(result.output)))
self._failed.append((test, result))
def finished(self):
crashed = 0
print
for test, cmd, output in self._failed:
for test, result in self._failed:
print_failure_header(test)
if output.stderr:
if result.output.stderr:
print "--- stderr ---"
print output.stderr.strip()
if output.stdout:
print result.output.stderr.strip()
if result.output.stdout:
print "--- stdout ---"
print output.stdout.strip()
print "Command: %s" % cmd.to_string()
if output.HasCrashed():
print "exit code: %d" % output.exit_code
print result.output.stdout.strip()
print "Command: %s" % result.cmd.to_string()
if result.output.HasCrashed():
print "exit code: %d" % result.output.exit_code
print "--- CRASHED ---"
crashed += 1
if output.HasTimedOut():
if result.output.HasTimedOut():
print "--- TIMEOUT ---"
if len(self._failed) == 0:
print "==="