| #! /usr/bin/env python |
| |
| # Update expectations in an Autotest test suite. |
| |
| # Copyright (C) 2019-2022, 2025 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 <https://www.gnu.org/licenses/>. |
| # |
| # 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) |