1# Copyright 2018 the V8 project authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import itertools 6import os 7import re 8 9from . import base 10 11 12class OutProc(base.OutProc): 13 def __init__(self, expected_outcomes, basepath, expected_fail): 14 super(OutProc, self).__init__(expected_outcomes) 15 self._basepath = basepath 16 self._expected_fail = expected_fail 17 18 def _is_failure_output(self, output): 19 fail = output.exit_code != 0 20 if fail != self._expected_fail: 21 return True 22 23 expected_lines = [] 24 # Can't use utils.ReadLinesFrom() here because it strips whitespace. 25 with open(self._basepath + '.out') as f: 26 for line in f: 27 if line.startswith("#") or not line.strip(): 28 continue 29 expected_lines.append(line) 30 raw_lines = output.stdout.splitlines() 31 actual_lines = [ s for s in raw_lines if not self._ignore_line(s) ] 32 if len(expected_lines) != len(actual_lines): 33 return True 34 35 env = { 36 'basename': os.path.basename(self._basepath + '.js'), 37 } 38 for (expected, actual) in itertools.izip_longest( 39 expected_lines, actual_lines, fillvalue=''): 40 pattern = re.escape(expected.rstrip() % env) 41 pattern = pattern.replace('\\*', '.*') 42 pattern = pattern.replace('\\{NUMBER\\}', '\d+(?:\.\d*)?') 43 pattern = '^%s$' % pattern 44 if not re.match(pattern, actual): 45 return True 46 return False 47 48 def _ignore_line(self, string): 49 """Ignore empty lines, valgrind output, Android output.""" 50 return ( 51 not string or 52 not string.strip() or 53 string.startswith("==") or 54 string.startswith("**") or 55 string.startswith("ANDROID") 56 ) 57