Commit | Line | Data |
---|---|---|
7eeb782e AT |
1 | #! /usr/bin/env python |
2 | ||
3 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # | |
4 | # This program is distributed with GNU Go, a Go program. # | |
5 | # # | |
6 | # Write gnugo@gnu.org or see http://www.gnu.org/software/gnugo/ # | |
7 | # for more information. # | |
8 | # # | |
9 | # Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005 and 2006 # | |
10 | # by the Free Software Foundation. # | |
11 | # # | |
12 | # This program is free software; you can redistribute it and/or # | |
13 | # modify it under the terms of the GNU General Public License # | |
14 | # as published by the Free Software Foundation - version 3 # | |
15 | # or (at your option) any later version. # | |
16 | # # | |
17 | # This program is distributed in the hope that it will be # | |
18 | # useful, but WITHOUT ANY WARRANTY; without even the implied # | |
19 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR # | |
20 | # PURPOSE. See the GNU General Public License in file COPYING # | |
21 | # for more details. # | |
22 | # # | |
23 | # You should have received a copy of the GNU General Public # | |
24 | # License along with this program; if not, write to the Free # | |
25 | # Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # | |
26 | # Boston, MA 02111, USA. # | |
27 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # | |
28 | ||
29 | import string | |
30 | import sys, getopt | |
31 | import re | |
32 | ||
33 | help_string = """ | |
34 | Usage: | |
35 | breakage2tst.py [--pike] <BREAKAGE_FILE | |
36 | This creates a command line invoking regress.pike to run all tes | |
37 | cases that appear as unexpected PASS or FAIL in BREAKAGE_FILE. | |
38 | breakage2tst.py [--pike] --update <BREAKAGE_FILE | |
39 | This changes all .tst files so that the expected results match | |
40 | the behaviour of the version that produced BREAKAGE_FILE. | |
41 | In both cases, it needs to be run from the regression test directory. | |
42 | """ | |
43 | ||
44 | # This prints out the list of tests from testfile in the format | |
45 | # <tstfile>:number | |
46 | def write_tests(tstfilename, tests): | |
47 | for number, expected in tests: | |
48 | print "%s:%d" % (tstfilename, number), | |
49 | ||
50 | ||
51 | def toggled_result(resultline, expected): | |
52 | if (re.search(r"\]$", resultline)): | |
53 | if (not expected == 0): | |
54 | print "Result line doesn't match 'unexpected FAIL':", | |
55 | print resultline | |
56 | sys.exit(2) | |
57 | return (re.sub(r"\]$", "]*", resultline)) | |
58 | elif (re.search(r"\]\*$", resultline)): | |
59 | if (not expected == 1): | |
60 | print "Result line doesn't match 'unexpected PASS':", | |
61 | print resultline | |
62 | sys.exit(2) | |
63 | return (re.sub(r"\]\*$", "]", resultline)) | |
64 | else: | |
65 | print "Couldn't parse alleged result line:", resultline | |
66 | sys.exit(2) | |
67 | ||
68 | ||
69 | # This toggles the expected result in the .tst-file "tstfilename" for | |
70 | # all tests whose id is listed in "tests" | |
71 | def update_tstfile(tstfilename, tests): | |
72 | if len(tests) == 0: | |
73 | print tstfilename, "unchanged." | |
74 | return | |
75 | print "Updating", tstfilename | |
76 | tstfile = open(tstfilename, 'r') | |
77 | tstlines = tstfile.readlines() | |
78 | tstfile.close | |
79 | new_tstfile = '' | |
80 | ||
81 | for number, expected in tests: | |
82 | current_line = tstlines.pop(0) | |
83 | command_pattern = re.compile("^%d " % number) | |
84 | ||
85 | # Look for the line containing the command with matching id, | |
86 | # while keeping recent commands and comments | |
87 | while (not command_pattern.match(current_line)): | |
88 | new_tstfile = new_tstfile + current_line | |
89 | current_line = tstlines.pop(0) | |
90 | ||
91 | # Found match. Now look for the result line: | |
92 | while (not re.match(r"^#\?", current_line)): | |
93 | new_tstfile = new_tstfile + current_line | |
94 | current_line = tstlines.pop(0) | |
95 | ||
96 | new_tstfile = new_tstfile + toggled_result(current_line, | |
97 | expected) | |
98 | ||
99 | # Now copy the rest of the file without change. | |
100 | new_tstfile = new_tstfile + string.join(tstlines, '') | |
101 | ||
102 | tstfile = open(tstfilename, 'w') | |
103 | tstfile.write(new_tstfile) | |
104 | tstfile.close | |
105 | ||
106 | def parse_input(do_work): | |
107 | tests = [] | |
108 | filename = '' | |
109 | while 1: | |
110 | try: | |
111 | inputline = raw_input() | |
112 | except EOFError: | |
113 | do_work(filename, tests) | |
114 | break | |
115 | else: | |
116 | s = string.split(inputline) | |
117 | if len(s) == 0: | |
118 | continue | |
119 | if (re.search(r"regress\.sh", s[0]) | |
120 | or re.search(r"eval\.sh", s[0])): | |
121 | if (filename != ''): | |
122 | do_work(filename, tests) | |
123 | filename = re.search(r"[^\s]+\.tst", inputline).group() | |
124 | tests = [] | |
125 | elif (re.search("PASS", string.join(s[1:3]))): | |
126 | tests.append([int(s[0]), 1]) | |
127 | elif (re.search("FAIL", string.join(s[1:3]))): | |
128 | tests.append([int(s[0]), 0]) | |
129 | ||
130 | def parse_pike_input(do_work): | |
131 | tests = [] | |
132 | filename = '' | |
133 | while 1: | |
134 | try: | |
135 | inputline = raw_input() | |
136 | except EOFError: | |
137 | if (filename != ''): | |
138 | do_work(filename, tests) | |
139 | break | |
140 | else: | |
141 | s = string.split(inputline) | |
142 | if (not re.search(r"\:", s[0])): | |
143 | continue | |
144 | new_filename = re.search(r"[^:]+", s[0]).group() \ | |
145 | + ".tst" | |
146 | if (filename != new_filename): | |
147 | if (filename != ''): | |
148 | do_work(filename, tests) | |
149 | filename = new_filename | |
150 | tests = [] | |
151 | number = int(re.search(r"[\d]+$", s[0]).group()) | |
152 | if (s[1] == "PASS"): | |
153 | tests.append([number, 1]) | |
154 | elif (s[1] == "FAIL"): | |
155 | tests.append([number, 0]) | |
156 | else: | |
157 | print "Inconsistent input line:", inputline | |
158 | sys.exit(2) | |
159 | ||
160 | ||
161 | def main(): | |
162 | mode = 0 | |
163 | pike = 0 | |
164 | try: | |
165 | opts, args = getopt.getopt(sys.argv[1:], "", | |
166 | ["update", "help", "pike"]) | |
167 | except getopt.GetoptError: | |
168 | print "breakage2tst: Unrecognized option." | |
169 | print help_string | |
170 | sys.exit(2) | |
171 | if (args != []): | |
172 | print "I know nothing about arguments", args | |
173 | print help_string | |
174 | sys.exit(2) | |
175 | ||
176 | for o, a in opts: | |
177 | if (o == "--help"): | |
178 | print help_string | |
179 | sys.exit() | |
180 | if (o == "--update"): | |
181 | mode = 1 | |
182 | if (o == "--pike"): | |
183 | pike = 1 | |
184 | ||
185 | if (mode == 0): | |
186 | print "./regress.pike ", | |
187 | do_work = write_tests | |
188 | else: | |
189 | do_work = update_tstfile | |
190 | ||
191 | ||
192 | if (pike): | |
193 | parse_pike_input(do_work) | |
194 | else: | |
195 | parse_input(do_work) | |
196 | ||
197 | if (mode == 0): | |
198 | ||
199 | else: | |
200 | print "Done." | |
201 | ||
202 | ||
203 | main() |