blob: 4d391fc7737dda9795801552e8a35a6a1ea1f54d [file] [log] [blame]
Fumitoshi Ukai119dc912015-03-30 16:52:41 +09001#!/usr/bin/env ruby
Shinichiro Hamajib69bf8a2015-06-10 14:52:06 +09002#
3# Copyright 2015 Google Inc. All rights reserved
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090016
17require 'fileutils'
18
Shinichiro Hamaji8ac81712015-07-16 09:15:54 +090019while true
20 if ARGV[0] == '-s'
21 test_serialization = true
22 ARGV.shift
23 elsif ARGV[0] == '-c'
24 ckati = true
25 ARGV.shift
26 ENV['KATI_VARIANT'] = 'c'
27 elsif ARGV[0] == '-n'
28 via_ninja = true
29 ARGV.shift
30 else
31 break
32 end
Shinichiro Hamaji9f4f5d32015-04-28 03:53:49 +090033end
34
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090035def get_output_filenames
36 files = Dir.glob('*')
37 files.delete('Makefile')
Shinichiro Hamaji8ac81712015-07-16 09:15:54 +090038 files.delete('build.ninja')
39 files.delete('ninja.sh')
Shinichiro Hamaji65489db2015-06-29 20:44:26 +090040 files.delete('gmon.out')
Shinichiro Hamajib674d582015-04-28 03:40:57 +090041 files.reject!{|f|f =~ /\.json$/}
Fumitoshi Ukai6450d0f2015-07-10 16:34:06 +090042 files.reject!{|f|f =~ /^kati\.*/}
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090043 files
44end
45
46def cleanup
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +090047 (get_output_filenames + Dir.glob('.*')).each do |fname|
48 next if fname == '.' || fname == '..'
Shinichiro Hamajic6713602015-04-01 01:03:34 +090049 FileUtils.rm_rf fname
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090050 end
51end
52
Shinichiro Hamaji74a66002015-04-27 16:42:30 +090053def move_circular_dep(l)
54 # We don't care when circular dependency detection happens.
55 circ = ''
56 while l.sub!(/Circular .* dropped\.\n/, '') do
57 circ += $&
58 end
59 circ + l
60end
61
Shinichiro Hamajic6713602015-04-01 01:03:34 +090062expected_failures = []
63unexpected_passes = []
64failures = []
65passes = []
66
Shinichiro Hamajiec42b4e2015-05-14 16:20:03 +090067if !ARGV.empty?
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +090068 test_files = ARGV.map do |test|
69 "testcase/#{File.basename(test)}"
Shinichiro Hamajiec42b4e2015-05-14 16:20:03 +090070 end
71else
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +090072 test_files = Dir.glob('testcase/*.mk').sort
73 test_files += Dir.glob('testcase/*.sh').sort
Shinichiro Hamajiec42b4e2015-05-14 16:20:03 +090074end
75
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +090076def run_in_testdir(test_filename)
77 c = File.read(test_filename)
78 name = File.basename(test_filename)
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090079 dir = "out/#{name}"
Shinichiro Hamaji52e42032015-03-31 23:20:13 +090080
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090081 FileUtils.mkdir_p(dir)
Shinichiro Hamaji52e42032015-03-31 23:20:13 +090082 Dir.glob("#{dir}/*").each do |fname|
83 FileUtils.rm_rf(fname)
84 end
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090085
86 Dir.chdir(dir) do
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +090087 yield name
88 end
89end
90
Shinichiro Hamaji86e11332015-07-28 15:24:17 +090091def normalize_ninja_log(log, mk)
Shinichiro Hamaji8ac81712015-07-16 09:15:54 +090092 log.gsub!(/^\[\d+\/\d+\] .*\n/, '')
Shinichiro Hamajicecc3582015-07-28 15:56:59 +090093 log.gsub!(/^ninja: no work to do\.\n/, '')
Fumitoshi Ukai786846d2015-07-28 18:08:47 +090094 log.gsub!(/^ninja: error: (.*, needed by .*),.*/,
95 '*** No rule to make target \\1.')
Shinichiro Hamaji86e11332015-07-28 15:24:17 +090096 if mk =~ /err_error_in_recipe.mk/
97 # This test expects ninja fails. Strip ninja specific error logs.
98 log.gsub!(/^FAILED: .*\n/, '')
99 log.gsub!(/^ninja: .*\n/, '')
100 end
Shinichiro Hamaji8ac81712015-07-16 09:15:54 +0900101 log
102end
103
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900104def normalize_make_log(expected)
105 expected.gsub!(/^make(?:\[\d+\])?: (Entering|Leaving) directory.*\n/, '')
106 expected.gsub!(/^make(?:\[\d+\])?: /, '')
107 expected = move_circular_dep(expected)
108
109 # Normalizations for old/new GNU make.
110 expected.gsub!(/[`'"]/, '"')
111 expected.gsub!(/ (?:commands|recipe) for target /,
112 ' commands for target ')
113 expected.gsub!(/ (?:commands|recipe) commences /,
114 ' commands commence ')
115 expected.gsub!(' (did you mean TAB instead of 8 spaces?)', '')
116 expected.gsub!('Extraneous text after', 'extraneous text after')
117 # Not sure if this is useful.
118 expected.gsub!(/\s+Stop\.$/, '')
119 # GNU make 4.0 has this output.
120 expected.gsub!(/Makefile:\d+: commands for target ".*?" failed\n/, '')
121 # We treat some warnings as errors.
122 expected.gsub!(/Nothing to be done for "test"\.\n/, '')
Shinichiro Hamaji3498f342015-08-11 14:23:12 +0900123 expected.gsub!(/^\/bin\/sh: line 0: /, '')
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900124
125 expected
126end
127
128def normalize_kati_log(output)
129 output = move_circular_dep(output)
130 # kati specific log messages.
131 output.gsub!(/^\*kati\*.*\n/, '')
Fumitoshi Ukaia43b96f2015-07-17 19:54:21 +0900132 output.gsub!(/^c?kati: /, '')
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900133 output.gsub!(/[`'"]/, '"')
Shinichiro Hamaji861bd642015-06-19 16:59:13 +0900134 output.gsub!(/(: )(?:open )?(\S+): [Nn](o such file or directory)\nNOTE:.*/,
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900135 "\\1\\2: N\\3\n*** No rule to make target \"\\2\".")
Fumitoshi Ukai08c1e942015-07-15 16:38:07 +0900136 output.gsub!(/\/bin\/sh: ([^:]*): command not found/,
137 "\\1: Command not found")
Shinichiro Hamajia06bee92015-08-05 17:13:05 +0900138 output.gsub!(/.*: warning for parse error in an unevaluated line: .*\n/, '')
Shinichiro Hamaji3498f342015-08-11 14:23:12 +0900139 output.gsub!(/^FindEmulator: /, '')
Fumitoshi Ukaib0ede7d2015-07-29 10:19:05 +0900140 output.gsub!(/ (\.\/+)+kati\.\S+/, '') # kati log files in find_command.mk
141 output.gsub!(/ (\.\/+)+test\S+.json/, '') # json files in find_command.mk
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900142 output
143end
144
145run_make_test = proc do |mk|
146 c = File.read(mk)
Shinichiro Hamaji6a492922015-07-27 19:37:20 +0900147 expected_failure = false
Fumitoshi Ukaibfabe632015-07-28 15:26:56 +0900148 if c =~ /\A# TODO(?:\(([-a-z|]+)\))?/
Shinichiro Hamaji6a492922015-07-27 19:37:20 +0900149 if $1
150 todos = $1.split('|')
151 if todos.include?('go') && !ckati
152 expected_failure = true
153 end
154 if todos.include?('c') && ckati
155 expected_failure = true
156 end
Fumitoshi Ukaibfabe632015-07-28 15:26:56 +0900157 if todos.include?('go-ninja') && !ckati && via_ninja
158 expected_failure = true
159 end
160 if todos.include?('c-ninja') && ckati && via_ninja
161 expected_failure = true
162 end
Shinichiro Hamaji6a492922015-07-27 19:37:20 +0900163 if todos.include?('ninja') && via_ninja
164 expected_failure = true
165 end
166 else
167 expected_failure = true
Shinichiro Hamajie919d002015-06-26 01:15:55 +0900168 end
169 end
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900170
171 run_in_testdir(mk) do |name|
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900172 # TODO: Fix
173 if name =~ /eval_assign/ && ckati
174 next
175 end
176
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900177 File.open("Makefile", 'w') do |ofile|
178 ofile.print(c)
179 end
180
181 expected = ''
182 output = ''
183
Shinichiro Hamaji491e73f2015-04-07 12:41:59 +0900184 testcases = c.scan(/^test\d*/).sort.uniq
Shinichiro Hamaji497754d2015-03-31 02:02:11 +0900185 if testcases.empty?
186 testcases = ['']
187 end
Shinichiro Hamajie5be0142015-03-30 19:26:01 +0900188
189 cleanup
190 testcases.each do |tc|
Shinichiro Hamaji8ac81712015-07-16 09:15:54 +0900191 cmd = 'make'
192 if via_ninja
193 cmd += ' -s'
194 end
195 cmd += " #{tc} 2>&1"
196 res = `#{cmd}`
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900197 res = normalize_make_log(res)
Shinichiro Hamaji74a66002015-04-27 16:42:30 +0900198 expected += "=== #{tc} ===\n" + res
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900199 expected_files = get_output_filenames
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900200 expected += "\n=== FILES ===\n#{expected_files * "\n"}\n"
Shinichiro Hamajie5be0142015-03-30 19:26:01 +0900201 end
202
203 cleanup
204 testcases.each do |tc|
Shinichiro Hamajic48d9ce2015-04-28 03:47:39 +0900205 json = "#{tc.empty? ? 'test' : tc}"
Fumitoshi Ukai0547db62015-07-29 16:20:59 +0900206 cmd = "../../kati -save_json=#{json}.json -log_dir=. --use_find_emulator"
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900207 if ckati
Shinichiro Hamaji8ac81712015-07-16 09:15:54 +0900208 cmd = "../../ckati --use_find_emulator"
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900209 end
Shinichiro Hamaji8ac81712015-07-16 09:15:54 +0900210 if via_ninja
211 cmd += ' --ninja'
212 end
213 cmd += " #{tc} 2>&1"
Shinichiro Hamajib674d582015-04-28 03:40:57 +0900214 res = IO.popen(cmd, 'r:binary', &:read)
Fumitoshi Ukai39837dd2015-07-28 12:25:56 +0900215 if via_ninja && File.exist?('build.ninja') && File.exists?('ninja.sh')
Shinichiro Hamaji6a492922015-07-27 19:37:20 +0900216 log = IO.popen('./ninja.sh -j1 -v 2>&1', 'r:binary', &:read)
Shinichiro Hamaji86e11332015-07-28 15:24:17 +0900217 res += normalize_ninja_log(log, mk)
Shinichiro Hamaji8ac81712015-07-16 09:15:54 +0900218 end
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900219 res = normalize_kati_log(res)
Shinichiro Hamaji42f42e12015-04-13 14:26:45 +0900220 output += "=== #{tc} ===\n" + res
Shinichiro Hamajie5be0142015-03-30 19:26:01 +0900221 output_files = get_output_filenames
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900222 output += "\n=== FILES ===\n#{output_files * "\n"}\n"
223 end
224
225 File.open('out.make', 'w'){|ofile|ofile.print(expected)}
226 File.open('out.kati', 'w'){|ofile|ofile.print(output)}
227
Shinichiro Hamaji74c832f2015-04-09 14:54:39 +0900228 if expected =~ /FAIL/
229 puts %Q(#{name} has a string "FAIL" in its expectation)
230 exit 1
231 end
232
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900233 if expected != output
Shinichiro Hamaji91b105c2015-03-30 18:39:05 +0900234 if expected_failure
235 puts "#{name}: FAIL (expected)"
Shinichiro Hamajic6713602015-04-01 01:03:34 +0900236 expected_failures << name
Shinichiro Hamaji91b105c2015-03-30 18:39:05 +0900237 else
238 puts "#{name}: FAIL"
239 puts `diff -u out.make out.kati`
Shinichiro Hamajic6713602015-04-01 01:03:34 +0900240 failures << name
Shinichiro Hamaji91b105c2015-03-30 18:39:05 +0900241 end
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900242 else
Shinichiro Hamaji91b105c2015-03-30 18:39:05 +0900243 if expected_failure
244 puts "#{name}: PASS (unexpected)"
Shinichiro Hamajic6713602015-04-01 01:03:34 +0900245 unexpected_passes << name
Shinichiro Hamaji91b105c2015-03-30 18:39:05 +0900246 else
247 puts "#{name}: PASS"
Shinichiro Hamajic6713602015-04-01 01:03:34 +0900248 passes << name
Shinichiro Hamaji91b105c2015-03-30 18:39:05 +0900249 end
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900250 end
Shinichiro Hamajic48d9ce2015-04-28 03:47:39 +0900251
Shinichiro Hamajie666ac82015-04-28 04:18:13 +0900252 if name !~ /^err_/ && test_serialization && !expected_failure
Shinichiro Hamajic48d9ce2015-04-28 03:47:39 +0900253 testcases.each do |tc|
254 json = "#{tc.empty? ? 'test' : tc}"
Fumitoshi Ukai6450d0f2015-07-10 16:34:06 +0900255 cmd = "../../kati -save_json=#{json}_2.json -load_json=#{json}.json -n -log_dir=. #{tc} 2>&1"
Shinichiro Hamajic48d9ce2015-04-28 03:47:39 +0900256 res = IO.popen(cmd, 'r:binary', &:read)
257 if !File.exist?("#{json}.json") || !File.exist?("#{json}_2.json")
258 puts "#{name}##{json}: Serialize failure (not exist)"
Shinichiro Hamaji9f4f5d32015-04-28 03:53:49 +0900259 puts res
Shinichiro Hamajic48d9ce2015-04-28 03:47:39 +0900260 else
261 json1 = File.read("#{json}.json")
262 json2 = File.read("#{json}_2.json")
263 if json1 != json2
264 puts "#{name}##{json}: Serialize failure"
Shinichiro Hamaji9f4f5d32015-04-28 03:53:49 +0900265 puts res
Shinichiro Hamajic48d9ce2015-04-28 03:47:39 +0900266 end
267 end
268 end
269 end
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900270 end
271end
Shinichiro Hamajic6713602015-04-01 01:03:34 +0900272
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900273run_shell_test = proc do |sh|
Shinichiro Hamaji09796ef2015-07-30 17:08:29 +0900274 is_ninja_test = sh =~ /\/ninja_/
275 if is_ninja_test && (!ckati || !via_ninja)
276 next
277 end
278
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900279 run_in_testdir(sh) do |name|
280 cleanup
281 cmd = "sh ../../#{sh} make"
Shinichiro Hamaji09796ef2015-07-30 17:08:29 +0900282 if is_ninja_test
283 cmd += ' -s'
284 end
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900285 expected = IO.popen(cmd, 'r:binary', &:read)
286 cleanup
Shinichiro Hamaji09796ef2015-07-30 17:08:29 +0900287
288 if is_ninja_test
289 if ckati
Shinichiro Hamajia88c1c22015-07-31 12:29:48 +0900290 cmd = "sh ../../#{sh} ../../ckati --ninja --regen"
Shinichiro Hamaji09796ef2015-07-30 17:08:29 +0900291 else
292 next
293 end
294 else
295 if ckati
296 cmd = "sh ../../#{sh} ../../ckati"
297 else
298 cmd = "sh ../../#{sh} ../../kati --use_cache -log_dir=."
299 end
300 end
301
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900302 output = IO.popen(cmd, 'r:binary', &:read)
303
304 expected = normalize_make_log(expected)
305 output = normalize_kati_log(output)
Shinichiro Hamaji09796ef2015-07-30 17:08:29 +0900306 if is_ninja_test
307 output = normalize_ninja_log(output, sh)
Shinichiro Hamaji59956602015-08-11 15:35:55 +0900308 output.gsub!(/No need to regenerate ninja file\n/, '')
Shinichiro Hamaji09796ef2015-07-30 17:08:29 +0900309 end
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900310 File.open('out.make', 'w'){|ofile|ofile.print(expected)}
311 File.open('out.kati', 'w'){|ofile|ofile.print(output)}
312
313 if expected != output
314 puts "#{name}: FAIL"
Shinichiro Hamaji39e62402015-05-20 19:34:58 +0900315 puts `diff -u out.make out.kati`
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900316 failures << name
317 else
318 puts "#{name}: PASS"
319 passes << name
320 end
321 end
322end
323
324test_files.each do |test|
325 if /\.mk$/ =~ test
326 run_make_test.call(test)
327 elsif /\.sh$/ =~ test
328 run_shell_test.call(test)
329 else
330 raise "Unknown test type: #{test}"
331 end
332end
333
Shinichiro Hamajic6713602015-04-01 01:03:34 +0900334puts
335
336if !expected_failures.empty?
337 puts "=== Expected failures ==="
338 expected_failures.each do |n|
339 puts n
340 end
341end
342
343if !unexpected_passes.empty?
344 puts "=== Unexpected passes ==="
345 unexpected_passes.each do |n|
346 puts n
347 end
348end
349
350if !failures.empty?
351 puts "=== Failures ==="
352 failures.each do |n|
353 puts n
354 end
355end
356
357puts
358
359if !unexpected_passes.empty? || !failures.empty?
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900360 puts "FAIL! (#{failures.size + unexpected_passes.size} fails #{passes.size} passes)"
Shinichiro Hamajic6713602015-04-01 01:03:34 +0900361else
362 puts 'PASS!'
363end