-
Notifications
You must be signed in to change notification settings - Fork 30
/
Copy pathtest-transcript.py
executable file
·168 lines (131 loc) · 4.96 KB
/
test-transcript.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#!/usr/bin/env python
"""
Check whether make invoked the right commands for all test-cases in
the directory test/build-sequence/
The expected sequence of commands for each given test-case is written
in the first line of the respective .tex file.
"""
import os
import os.path
import subprocess
import sys
import string
import util.ensure_version
import re
# Colorize terminal output
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
def run_make(makefile, directory, target):
"""Runs make with the given target in the given directory
Note that we set WRITE_TRANSCRIPT to true, and we supress the output.
"""
subprocess.call(args = ("make",
"--makefile=" + makefile,
"WRITE_TRANSCRIPT=true",
target),
stderr = subprocess.STDOUT,
stdout = subprocess.PIPE,
cwd = directory)
def read_transcript(path):
"""Returns two lists containing the "transcript" and "justification"
"transcript" is a list of commands that were executed by make, and
"justification" is a list of reasons for why each command was executed
The "path" argument is a file .transcript.make that contains a list
of executed commands together with the reason given. Each line of
the file is assumed to have the following format:
Running command (reason)
"""
# Read the .transcript.make file
with open(path) as myfile:
lines = myfile.readlines()
transcript = []
justification = []
# Now extract the information we need
for line in lines:
matchObj = re.match("Running (.*) \((.*)\)", line)
transcript.append(matchObj.group(1))
justification.append(matchObj.group(2))
return transcript, justification
def read_expected_transcript(path):
"""Returns a list containing the "expected transcript"
"path" is expected to be a file whose first line contains the
expected transcript in the following format:
% Expected transcript: latex bibtex latex latex
"""
with open(path) as myfile:
expected_str = myfile.next()
# Strip the string to the right format and convert it to a list
expected_str = string.replace(expected_str, "% Expected transcript: ", "")
expected_str = string.strip(expected_str)
expected_transcript = expected_str.split()
return expected_transcript
def main():
current_directory = os.getcwd()
makefile = os.path.join(current_directory, "Makefile")
if not os.path.exists(makefile):
print FAIL + "Failed.",
print ENDC + " You need to ./build the Makefile before running this test!"
quit(1)
if len(sys.argv) == 2:
initial_dir = os.path.join("test", "transcript", sys.argv[1])
else:
initial_dir = os.path.join("test", "transcript")
total_tests = 0
passed_tests = 0
print WARNING + "Testing transcripts... \n"
for dirpath, dirnames, filenames in os.walk(initial_dir):
for fname in filenames:
name, ext = os.path.splitext(fname)
if ext != ".tex":
continue
total_tests += 1
print ENDC + os.path.join(dirpath, fname) + "...",
# make clean
run_make(makefile, dirpath, "clean")
# make testfile
run_make(makefile, dirpath, name)
transcript_filename = os.path.join(dirpath, name + ".transcript.make")
if(os.path.exists(transcript_filename)):
actual, justification = read_transcript(transcript_filename)
else:
actual, justification = [], []
expected = read_expected_transcript(os.path.join(dirpath, fname))
# Delete the transcript file and run make a second time
# to see whether fixed-point was reached
os.remove(transcript_filename)
run_make(makefile, dirpath, name)
second_success = 0
if not os.path.exists(transcript_filename):
second_success = 1
else:
actual2, justification2 = read_transcript(transcript_filename)
if actual == expected and second_success:
passed_tests += 1
print OKGREEN + " Passed."
else:
print FAIL + " Failed."
if actual == expected:
print ENDC + " First 'make' was ok, but the second 'make' rebuilt stuff"
print ENDC + " Transcript of 1st 'make': " + OKBLUE + str(expected)
print ENDC + " Transcript of 2nd 'make': " + OKBLUE + str(actual2)
for i, (act, just) in enumerate(zip(actual2, justification2)):
print "%s %d: Ran %s%s%s because: %s" \
% (ENDC, i+1, OKBLUE, act, ENDC, just)
else:
print "%s Expected transcript: %s%s" % (ENDC, OKBLUE, str(expected))
print "%s Observed transcript: %s%s" % (ENDC, OKBLUE, str(actual))
for i, (act, just) in enumerate(zip(actual, justification)):
print "%s %d: Ran %s%s%s because: %s" \
% (ENDC, i+1, OKBLUE, act, ENDC, just)
print ""
# make clean
run_make(makefile, dirpath, "clean")
print WARNING + "Result: ",
print OKGREEN + str(passed_tests) + " passed ",
print FAIL + str(total_tests-passed_tests) + " failed"
if __name__ == '__main__':
main()