| #!/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:])) |