| #!/usr/bin/env python |
| # 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. |
| """ |
| |
| |
| # for py2/py3 compatibility |
| from __future__ import print_function |
| |
| import sys |
| |
| from testrunner.local import command |
| from testrunner.local import utils |
| |
| |
| MAX_TRIES = 3 |
| TIMEOUT = 120 |
| |
| # Predictable mode works only when run on the host os. |
| command.setup(utils.GuessOS(), None) |
| |
| def main(args): |
| def allocation_str(stdout): |
| for line in reversed((stdout or '').splitlines()): |
| if line.startswith('### Allocations = '): |
| return line |
| return None |
| |
| cmd = command.Command(args[0], args[1:], timeout=TIMEOUT) |
| |
| previous_allocations = None |
| for run in range(1, MAX_TRIES + 1): |
| print('### Predictable run #%d' % run) |
| output = cmd.execute() |
| if output.stdout: |
| print('### Stdout:') |
| print(output.stdout) |
| if output.stderr: |
| print('### Stderr:') |
| print(output.stderr) |
| print('### Return code: %s' % output.exit_code) |
| 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. |
| print('### Test timed out') |
| 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: |
| print('### Allocations differ') |
| 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:])) |