11cb0ef41Sopenharmony_ci#!/usr/bin/env python3 21cb0ef41Sopenharmony_ci# Copyright 2017 the V8 project authors. All rights reserved. 31cb0ef41Sopenharmony_ci# Use of this source code is governed by a BSD-style license that can be 41cb0ef41Sopenharmony_ci# found in the LICENSE file. 51cb0ef41Sopenharmony_ci 61cb0ef41Sopenharmony_ci""" 71cb0ef41Sopenharmony_ciWrapper script for verify-predictable mode. D8 is expected to be compiled with 81cb0ef41Sopenharmony_civ8_enable_verify_predictable. 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ciThe actual test command is expected to be passed to this wraper as is. E.g.: 111cb0ef41Sopenharmony_cipredictable_wrapper.py path/to/d8 --test --predictable --flag1 --flag2 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_ciThe command is run up to three times and the printed allocation hash is 141cb0ef41Sopenharmony_cicompared. Differences are reported as errors. 151cb0ef41Sopenharmony_ci""" 161cb0ef41Sopenharmony_ci 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_ci# for py2/py3 compatibility 191cb0ef41Sopenharmony_cifrom __future__ import absolute_import 201cb0ef41Sopenharmony_cifrom __future__ import print_function 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_ciimport sys 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_cifrom testrunner.local import command 251cb0ef41Sopenharmony_cifrom testrunner.local import utils 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ciMAX_TRIES = 3 291cb0ef41Sopenharmony_ciTIMEOUT = 120 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_ci# Predictable mode works only when run on the host os. 321cb0ef41Sopenharmony_cicommand.setup(utils.GuessOS(), None) 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_cidef maybe_decode(message): 351cb0ef41Sopenharmony_ci if not isinstance(message, str): 361cb0ef41Sopenharmony_ci return message.decode() 371cb0ef41Sopenharmony_ci return message 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ci 401cb0ef41Sopenharmony_cidef main(args): 411cb0ef41Sopenharmony_ci def allocation_str(stdout): 421cb0ef41Sopenharmony_ci for line in reversed((stdout or '').splitlines()): 431cb0ef41Sopenharmony_ci if maybe_decode(line).startswith('### Allocations = '): 441cb0ef41Sopenharmony_ci return line 451cb0ef41Sopenharmony_ci return None 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ci cmd = command.Command( 481cb0ef41Sopenharmony_ci args[0], args[1:], timeout=TIMEOUT, handle_sigterm=True) 491cb0ef41Sopenharmony_ci 501cb0ef41Sopenharmony_ci previous_allocations = None 511cb0ef41Sopenharmony_ci for run in range(1, MAX_TRIES + 1): 521cb0ef41Sopenharmony_ci print('### Predictable run #%d' % run) 531cb0ef41Sopenharmony_ci output = cmd.execute() 541cb0ef41Sopenharmony_ci if output.stdout: 551cb0ef41Sopenharmony_ci print('### Stdout:') 561cb0ef41Sopenharmony_ci print(output.stdout) 571cb0ef41Sopenharmony_ci if output.stderr: 581cb0ef41Sopenharmony_ci print('### Stderr:') 591cb0ef41Sopenharmony_ci print(output.stderr) 601cb0ef41Sopenharmony_ci print('### Return code: %s' % output.exit_code) 611cb0ef41Sopenharmony_ci if output.HasTimedOut(): 621cb0ef41Sopenharmony_ci # If we get a timeout in any run, we are in an unpredictable state. Just 631cb0ef41Sopenharmony_ci # report it as a failure and don't rerun. 641cb0ef41Sopenharmony_ci print('### Test timed out') 651cb0ef41Sopenharmony_ci return 1 661cb0ef41Sopenharmony_ci allocations = allocation_str(output.stdout) 671cb0ef41Sopenharmony_ci if not allocations: 681cb0ef41Sopenharmony_ci print ('### Test had no allocation output. Ensure this is built ' 691cb0ef41Sopenharmony_ci 'with v8_enable_verify_predictable and that ' 701cb0ef41Sopenharmony_ci '--verify-predictable is passed at the cmd line.') 711cb0ef41Sopenharmony_ci return 2 721cb0ef41Sopenharmony_ci if previous_allocations and previous_allocations != allocations: 731cb0ef41Sopenharmony_ci print('### Allocations differ') 741cb0ef41Sopenharmony_ci return 3 751cb0ef41Sopenharmony_ci if run >= MAX_TRIES: 761cb0ef41Sopenharmony_ci # No difference on the last run -> report a success. 771cb0ef41Sopenharmony_ci return 0 781cb0ef41Sopenharmony_ci previous_allocations = allocations 791cb0ef41Sopenharmony_ci # Unreachable. 801cb0ef41Sopenharmony_ci assert False 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ciif __name__ == '__main__': 841cb0ef41Sopenharmony_ci sys.exit(main(sys.argv[1:])) 85