blob: 1dc451a4bd3eb5705a2ba6f03b332e7af8bb6007 [file] [log] [blame]
Fumitoshi Ukai119dc912015-03-30 16:52:41 +09001#!/usr/bin/env ruby
2
3require 'fileutils'
4
Shinichiro Hamaji9f4f5d32015-04-28 03:53:49 +09005if ARGV[0] == '-s'
6 test_serialization = true
7end
8
Fumitoshi Ukai119dc912015-03-30 16:52:41 +09009def get_output_filenames
10 files = Dir.glob('*')
11 files.delete('Makefile')
Shinichiro Hamajib674d582015-04-28 03:40:57 +090012 files.reject!{|f|f =~ /\.json$/}
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090013 files
14end
15
16def cleanup
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +090017 (get_output_filenames + Dir.glob('.*')).each do |fname|
18 next if fname == '.' || fname == '..'
Shinichiro Hamajic6713602015-04-01 01:03:34 +090019 FileUtils.rm_rf fname
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090020 end
21end
22
Shinichiro Hamaji74a66002015-04-27 16:42:30 +090023def move_circular_dep(l)
24 # We don't care when circular dependency detection happens.
25 circ = ''
26 while l.sub!(/Circular .* dropped\.\n/, '') do
27 circ += $&
28 end
29 circ + l
30end
31
Shinichiro Hamajic6713602015-04-01 01:03:34 +090032expected_failures = []
33unexpected_passes = []
34failures = []
35passes = []
36
Shinichiro Hamajiec42b4e2015-05-14 16:20:03 +090037if !ARGV.empty?
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +090038 test_files = ARGV.map do |test|
39 "testcase/#{File.basename(test)}"
Shinichiro Hamajiec42b4e2015-05-14 16:20:03 +090040 end
41else
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +090042 test_files = Dir.glob('testcase/*.mk').sort
43 test_files += Dir.glob('testcase/*.sh').sort
Shinichiro Hamajiec42b4e2015-05-14 16:20:03 +090044end
45
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +090046def run_in_testdir(test_filename)
47 c = File.read(test_filename)
48 name = File.basename(test_filename)
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090049 dir = "out/#{name}"
Shinichiro Hamaji52e42032015-03-31 23:20:13 +090050
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090051 FileUtils.mkdir_p(dir)
Shinichiro Hamaji52e42032015-03-31 23:20:13 +090052 Dir.glob("#{dir}/*").each do |fname|
53 FileUtils.rm_rf(fname)
54 end
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090055
56 Dir.chdir(dir) do
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +090057 yield name
58 end
59end
60
61def normalize_make_log(expected)
62 expected.gsub!(/^make(?:\[\d+\])?: (Entering|Leaving) directory.*\n/, '')
63 expected.gsub!(/^make(?:\[\d+\])?: /, '')
64 expected = move_circular_dep(expected)
65
66 # Normalizations for old/new GNU make.
67 expected.gsub!(/[`'"]/, '"')
68 expected.gsub!(/ (?:commands|recipe) for target /,
69 ' commands for target ')
70 expected.gsub!(/ (?:commands|recipe) commences /,
71 ' commands commence ')
72 expected.gsub!(' (did you mean TAB instead of 8 spaces?)', '')
73 expected.gsub!('Extraneous text after', 'extraneous text after')
74 # Not sure if this is useful.
75 expected.gsub!(/\s+Stop\.$/, '')
76 # GNU make 4.0 has this output.
77 expected.gsub!(/Makefile:\d+: commands for target ".*?" failed\n/, '')
78 # We treat some warnings as errors.
79 expected.gsub!(/Nothing to be done for "test"\.\n/, '')
80
81 expected
82end
83
84def normalize_kati_log(output)
85 output = move_circular_dep(output)
86 # kati specific log messages.
87 output.gsub!(/^\*kati\*.*\n/, '')
88 output.gsub!(/[`'"]/, '"')
89 output.gsub!(/(: )open (\S+): n(o such file or directory)\nNOTE:.*/,
90 "\\1\\2: N\\3\n*** No rule to make target \"\\2\".")
91 output
92end
93
94run_make_test = proc do |mk|
95 c = File.read(mk)
96 expected_failure = c =~ /\A# TODO/
97
98 run_in_testdir(mk) do |name|
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090099 File.open("Makefile", 'w') do |ofile|
100 ofile.print(c)
101 end
102
103 expected = ''
104 output = ''
105
Shinichiro Hamaji491e73f2015-04-07 12:41:59 +0900106 testcases = c.scan(/^test\d*/).sort.uniq
Shinichiro Hamaji497754d2015-03-31 02:02:11 +0900107 if testcases.empty?
108 testcases = ['']
109 end
Shinichiro Hamajie5be0142015-03-30 19:26:01 +0900110
111 cleanup
112 testcases.each do |tc|
Shinichiro Hamaji74a66002015-04-27 16:42:30 +0900113 res = `make #{tc} 2>&1`
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900114 res = normalize_make_log(res)
Shinichiro Hamaji74a66002015-04-27 16:42:30 +0900115 expected += "=== #{tc} ===\n" + res
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900116 expected_files = get_output_filenames
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900117 expected += "\n=== FILES ===\n#{expected_files * "\n"}\n"
Shinichiro Hamajie5be0142015-03-30 19:26:01 +0900118 end
119
120 cleanup
121 testcases.each do |tc|
Shinichiro Hamajic48d9ce2015-04-28 03:47:39 +0900122 json = "#{tc.empty? ? 'test' : tc}"
123 cmd = "../../kati -save_json=#{json}.json -kati_log #{tc} 2>&1"
Shinichiro Hamajib674d582015-04-28 03:40:57 +0900124 res = IO.popen(cmd, 'r:binary', &:read)
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900125 res = normalize_kati_log(res)
Shinichiro Hamaji42f42e12015-04-13 14:26:45 +0900126 output += "=== #{tc} ===\n" + res
Shinichiro Hamajie5be0142015-03-30 19:26:01 +0900127 output_files = get_output_filenames
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900128 output += "\n=== FILES ===\n#{output_files * "\n"}\n"
129 end
130
131 File.open('out.make', 'w'){|ofile|ofile.print(expected)}
132 File.open('out.kati', 'w'){|ofile|ofile.print(output)}
133
Shinichiro Hamaji74c832f2015-04-09 14:54:39 +0900134 if expected =~ /FAIL/
135 puts %Q(#{name} has a string "FAIL" in its expectation)
136 exit 1
137 end
138
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900139 if expected != output
Shinichiro Hamaji91b105c2015-03-30 18:39:05 +0900140 if expected_failure
141 puts "#{name}: FAIL (expected)"
Shinichiro Hamajic6713602015-04-01 01:03:34 +0900142 expected_failures << name
Shinichiro Hamaji91b105c2015-03-30 18:39:05 +0900143 else
144 puts "#{name}: FAIL"
145 puts `diff -u out.make out.kati`
Shinichiro Hamajic6713602015-04-01 01:03:34 +0900146 failures << name
Shinichiro Hamaji91b105c2015-03-30 18:39:05 +0900147 end
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900148 else
Shinichiro Hamaji91b105c2015-03-30 18:39:05 +0900149 if expected_failure
150 puts "#{name}: PASS (unexpected)"
Shinichiro Hamajic6713602015-04-01 01:03:34 +0900151 unexpected_passes << name
Shinichiro Hamaji91b105c2015-03-30 18:39:05 +0900152 else
153 puts "#{name}: PASS"
Shinichiro Hamajic6713602015-04-01 01:03:34 +0900154 passes << name
Shinichiro Hamaji91b105c2015-03-30 18:39:05 +0900155 end
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900156 end
Shinichiro Hamajic48d9ce2015-04-28 03:47:39 +0900157
Shinichiro Hamajie666ac82015-04-28 04:18:13 +0900158 if name !~ /^err_/ && test_serialization && !expected_failure
Shinichiro Hamajic48d9ce2015-04-28 03:47:39 +0900159 testcases.each do |tc|
160 json = "#{tc.empty? ? 'test' : tc}"
Shinichiro Hamaji9f4f5d32015-04-28 03:53:49 +0900161 cmd = "../../kati -save_json=#{json}_2.json -load_json=#{json}.json -n -kati_log #{tc} 2>&1"
Shinichiro Hamajic48d9ce2015-04-28 03:47:39 +0900162 res = IO.popen(cmd, 'r:binary', &:read)
163 if !File.exist?("#{json}.json") || !File.exist?("#{json}_2.json")
164 puts "#{name}##{json}: Serialize failure (not exist)"
Shinichiro Hamaji9f4f5d32015-04-28 03:53:49 +0900165 puts res
Shinichiro Hamajic48d9ce2015-04-28 03:47:39 +0900166 else
167 json1 = File.read("#{json}.json")
168 json2 = File.read("#{json}_2.json")
169 if json1 != json2
170 puts "#{name}##{json}: Serialize failure"
Shinichiro Hamaji9f4f5d32015-04-28 03:53:49 +0900171 puts res
Shinichiro Hamajic48d9ce2015-04-28 03:47:39 +0900172 end
173 end
174 end
175 end
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900176 end
177end
Shinichiro Hamajic6713602015-04-01 01:03:34 +0900178
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900179run_shell_test = proc do |sh|
180 run_in_testdir(sh) do |name|
181 cleanup
182 cmd = "sh ../../#{sh} make"
183 expected = IO.popen(cmd, 'r:binary', &:read)
184 cleanup
185 cmd = "sh ../../#{sh} ../../kati --use_cache --kati_log"
186 output = IO.popen(cmd, 'r:binary', &:read)
187
188 expected = normalize_make_log(expected)
189 output = normalize_kati_log(output)
190 File.open('out.make', 'w'){|ofile|ofile.print(expected)}
191 File.open('out.kati', 'w'){|ofile|ofile.print(output)}
192
193 if expected != output
194 puts "#{name}: FAIL"
Shinichiro Hamaji39e62402015-05-20 19:34:58 +0900195 puts `diff -u out.make out.kati`
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900196 failures << name
197 else
198 puts "#{name}: PASS"
199 passes << name
200 end
201 end
202end
203
204test_files.each do |test|
205 if /\.mk$/ =~ test
206 run_make_test.call(test)
207 elsif /\.sh$/ =~ test
208 run_shell_test.call(test)
209 else
210 raise "Unknown test type: #{test}"
211 end
212end
213
Shinichiro Hamajic6713602015-04-01 01:03:34 +0900214puts
215
216if !expected_failures.empty?
217 puts "=== Expected failures ==="
218 expected_failures.each do |n|
219 puts n
220 end
221end
222
223if !unexpected_passes.empty?
224 puts "=== Unexpected passes ==="
225 unexpected_passes.each do |n|
226 puts n
227 end
228end
229
230if !failures.empty?
231 puts "=== Failures ==="
232 failures.each do |n|
233 puts n
234 end
235end
236
237puts
238
239if !unexpected_passes.empty? || !failures.empty?
240 puts 'FAIL!'
241else
242 puts 'PASS!'
243end