predictable_wrapper.py 2.41 KB
Newer Older
1
#!/usr/bin/env python3
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
# Copyright 2017 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.

"""
Wrapper script for verify-predictable mode. D8 is expected to be compiled with
v8_enable_verify_predictable.

The actual test command is expected to be passed to this wraper as is. E.g.:
predictable_wrapper.py path/to/d8 --test --predictable --flag1 --flag2

The command is run up to three times and the printed allocation hash is
compared. Differences are reported as errors.
"""

17 18

# for py2/py3 compatibility
19
from __future__ import absolute_import
20 21
from __future__ import print_function

22 23 24
import sys

from testrunner.local import command
25
from testrunner.local import utils
26

27

28
MAX_TRIES = 3
29
TIMEOUT = 120
30

31
# Predictable mode works only when run on the host os.
32
command.setup(utils.GuessOS(), None)
33

34 35 36 37 38 39
def maybe_decode(message):
  if not isinstance(message, str):
    return message.decode()
  return message


40 41 42
def main(args):
  def allocation_str(stdout):
    for line in reversed((stdout or '').splitlines()):
43
      if maybe_decode(line).startswith('### Allocations = '):
44 45 46
        return line
    return None

47 48
  cmd = command.Command(
      args[0], args[1:], timeout=TIMEOUT, handle_sigterm=True)
49 50 51

  previous_allocations = None
  for run in range(1, MAX_TRIES + 1):
52
    print('### Predictable run #%d' % run)
53 54
    output = cmd.execute()
    if output.stdout:
55 56
      print('### Stdout:')
      print(output.stdout)
57
    if output.stderr:
58 59 60
      print('### Stderr:')
      print(output.stderr)
    print('### Return code: %s' % output.exit_code)
61 62 63
    if output.HasTimedOut():
      # If we get a timeout in any run, we are in an unpredictable state. Just
      # report it as a failure and don't rerun.
64
      print('### Test timed out')
65 66 67 68 69 70 71 72
      return 1
    allocations = allocation_str(output.stdout)
    if not allocations:
      print ('### Test had no allocation output. Ensure this is built '
             'with v8_enable_verify_predictable and that '
             '--verify-predictable is passed at the cmd line.')
      return 2
    if previous_allocations and previous_allocations != allocations:
73
      print('### Allocations differ')
74 75 76 77 78 79 80 81 82 83 84
      return 3
    if run >= MAX_TRIES:
      # No difference on the last run -> report a success.
      return 0
    previous_allocations = allocations
  # Unreachable.
  assert False


if __name__ == '__main__':
  sys.exit(main(sys.argv[1:]))