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 os 6import re 7 8from itertools import zip_longest 9 10from . import base 11 12 13class OutProc(base.ExpectedOutProc): 14 def __init__(self, expected_outcomes, basepath, expected_fail, 15 expected_filename, regenerate_expected_files): 16 super(OutProc, self).__init__(expected_outcomes, expected_filename, 17 regenerate_expected_files) 18 self._basepath = basepath 19 self._expected_fail = expected_fail 20 21 def _is_failure_output(self, output): 22 fail = output.exit_code != 0 23 if fail != self._expected_fail: 24 return True 25 26 expected_lines = [] 27 # Can't use utils.ReadLinesFrom() here because it strips whitespace. 28 with open(self._basepath + '.out') as f: 29 for line in f: 30 if line.startswith("#") or not line.strip(): 31 continue 32 expected_lines.append(line) 33 raw_lines = output.stdout.splitlines() 34 actual_lines = [ s for s in raw_lines if not self._ignore_line(s) ] 35 if len(expected_lines) != len(actual_lines): 36 return True 37 38 # Try .js first, and fall back to .mjs. 39 # TODO(v8:9406): clean this up by never separating the path from 40 # the extension in the first place. 41 base_path = self._basepath + '.js' 42 if not os.path.exists(base_path): 43 base_path = self._basepath + '.mjs' 44 45 env = { 46 'basename': os.path.basename(base_path), 47 } 48 for (expected, actual) in zip_longest( 49 expected_lines, actual_lines, fillvalue=''): 50 pattern = re.escape(expected.rstrip() % env) 51 pattern = pattern.replace('\\*', '.*') 52 pattern = pattern.replace('\\{NUMBER\\}', '\d+(?:\.\d*)?') 53 pattern = '^%s$' % pattern 54 if not re.match(pattern, actual): 55 return True 56 return False 57 58 def _ignore_line(self, string): 59 """Ignore empty lines, valgrind output, Android output.""" 60 return ( 61 not string or 62 not string.strip() or 63 string.startswith("==") or 64 string.startswith("**") or 65 string.startswith("ANDROID") or 66 # Android linker warning. 67 string.startswith('WARNING: linker:') 68 ) 69