#! /usr/bin/env python # Update expectations in an Autotest test suite. # Copyright (C) 2019-2022 Free Software Foundation, Inc. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # Written by Akim Demaille. # usage: # # update-test _build/8d/tests/testsuite.dir/*/testsuite.log # # from your source tree. import argparse import os import re def getargs(): p = argparse.ArgumentParser(description='Update test cases.') opt = p.add_argument opt('logs', metavar='log', nargs='+', type=str, default=None, help='log files to process') opt('-v', '--verbose', action='store_true', help='Be verbose') return p.parse_args() args = getargs() subst = dict() def trace(*args_): if args.verbose: print(*args_) def contents(file): '''The contents of a file.''' trace(file) f = open(file) return f.read() def diff_to_re(match): '''Convert a portion of patch into a regex substitution to perform. No longer used, we now use the expected/effective parts. ''' frm = [] to = [] is_diff = False for l in match.group(1).splitlines(): print(l) # t in [-+ ] t = l[0] l = l[1:] if t in ['-', ' ']: is_diff = True frm.append(l) if t in ['+', ' ']: is_diff = True to.append(l) if is_diff: # Do not run s//SOMETHING/g (with an emty pattern), that won't # work well... if frm == []: trace("no from for", match.group(1)) return frm = "\n".join(frm) to = "\n".join(to) subst[frm] = to def update(at_file, logfile): test = contents(at_file) if os.path.isfile(logfile): trace("LOG: ", logfile) l = contents(logfile) trace("LOG: ", l) global subst subst = {} re.sub(r'(?:^@@.*\n)((?:^[-+ ].*\n)+)', diff_to_re, l, flags = re.MULTILINE) print(subst) if subst: # Turn "subst{frm} -> to" into a large RE. frm = '|'.join([re.escape(x) for x in subst]) trace("FROM:", frm) test = re.sub("(" + frm + ")", lambda m: subst[m.group(1)], test, flags=re.MULTILINE) open(at_file, 'w').write(test) def process(logfile): log = contents(logfile) # Look for the file to update. m = re.search(r'^\d+\. ([\-\+\w]+\.at):\d+: ', log, re.MULTILINE) if not m: trace("no diff found:", logfile) return at_file = 'tests/' + m.group(1) print(at_file) update(at_file, logfile) for logfile in args.logs: trace("FILE:", logfile) if os.path.isdir(logfile): logfile = os.path.join(logfile, 'testsuite.log') process(logfile)