blob: 60a7e84f5e910aeab05a1ffaeb0dd5a8b653bbf4 [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 Ukai2c6eff62015-08-11 17:50:56 +0900140 output.gsub!(/^\/bin\/sh: line 0: /, '')
Fumitoshi Ukaib0ede7d2015-07-29 10:19:05 +0900141 output.gsub!(/ (\.\/+)+kati\.\S+/, '') # kati log files in find_command.mk
142 output.gsub!(/ (\.\/+)+test\S+.json/, '') # json files in find_command.mk
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900143 output
144end
145
146run_make_test = proc do |mk|
147 c = File.read(mk)
Shinichiro Hamaji6a492922015-07-27 19:37:20 +0900148 expected_failure = false
Fumitoshi Ukaibfabe632015-07-28 15:26:56 +0900149 if c =~ /\A# TODO(?:\(([-a-z|]+)\))?/
Shinichiro Hamaji6a492922015-07-27 19:37:20 +0900150 if $1
151 todos = $1.split('|')
152 if todos.include?('go') && !ckati
153 expected_failure = true
154 end
155 if todos.include?('c') && ckati
156 expected_failure = true
157 end
Fumitoshi Ukaibfabe632015-07-28 15:26:56 +0900158 if todos.include?('go-ninja') && !ckati && via_ninja
159 expected_failure = true
160 end
161 if todos.include?('c-ninja') && ckati && via_ninja
162 expected_failure = true
163 end
Shinichiro Hamaji6a492922015-07-27 19:37:20 +0900164 if todos.include?('ninja') && via_ninja
165 expected_failure = true
166 end
167 else
168 expected_failure = true
Shinichiro Hamajie919d002015-06-26 01:15:55 +0900169 end
170 end
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900171
172 run_in_testdir(mk) do |name|
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900173 # TODO: Fix
174 if name =~ /eval_assign/ && ckati
175 next
176 end
177
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900178 File.open("Makefile", 'w') do |ofile|
179 ofile.print(c)
180 end
181
182 expected = ''
183 output = ''
184
Shinichiro Hamaji491e73f2015-04-07 12:41:59 +0900185 testcases = c.scan(/^test\d*/).sort.uniq
Shinichiro Hamaji497754d2015-03-31 02:02:11 +0900186 if testcases.empty?
187 testcases = ['']
188 end
Shinichiro Hamajie5be0142015-03-30 19:26:01 +0900189
190 cleanup
191 testcases.each do |tc|
Shinichiro Hamaji8ac81712015-07-16 09:15:54 +0900192 cmd = 'make'
193 if via_ninja
194 cmd += ' -s'
195 end
196 cmd += " #{tc} 2>&1"
197 res = `#{cmd}`
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900198 res = normalize_make_log(res)
Shinichiro Hamaji74a66002015-04-27 16:42:30 +0900199 expected += "=== #{tc} ===\n" + res
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900200 expected_files = get_output_filenames
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900201 expected += "\n=== FILES ===\n#{expected_files * "\n"}\n"
Shinichiro Hamajie5be0142015-03-30 19:26:01 +0900202 end
203
204 cleanup
205 testcases.each do |tc|
Shinichiro Hamajic48d9ce2015-04-28 03:47:39 +0900206 json = "#{tc.empty? ? 'test' : tc}"
Fumitoshi Ukai0547db62015-07-29 16:20:59 +0900207 cmd = "../../kati -save_json=#{json}.json -log_dir=. --use_find_emulator"
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900208 if ckati
Shinichiro Hamaji8ac81712015-07-16 09:15:54 +0900209 cmd = "../../ckati --use_find_emulator"
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900210 end
Shinichiro Hamaji8ac81712015-07-16 09:15:54 +0900211 if via_ninja
212 cmd += ' --ninja'
213 end
214 cmd += " #{tc} 2>&1"
Shinichiro Hamajib674d582015-04-28 03:40:57 +0900215 res = IO.popen(cmd, 'r:binary', &:read)
Fumitoshi Ukai39837dd2015-07-28 12:25:56 +0900216 if via_ninja && File.exist?('build.ninja') && File.exists?('ninja.sh')
Shinichiro Hamaji6a492922015-07-27 19:37:20 +0900217 log = IO.popen('./ninja.sh -j1 -v 2>&1', 'r:binary', &:read)
Shinichiro Hamaji86e11332015-07-28 15:24:17 +0900218 res += normalize_ninja_log(log, mk)
Shinichiro Hamaji8ac81712015-07-16 09:15:54 +0900219 end
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900220 res = normalize_kati_log(res)
Shinichiro Hamaji42f42e12015-04-13 14:26:45 +0900221 output += "=== #{tc} ===\n" + res
Shinichiro Hamajie5be0142015-03-30 19:26:01 +0900222 output_files = get_output_filenames
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900223 output += "\n=== FILES ===\n#{output_files * "\n"}\n"
224 end
225
226 File.open('out.make', 'w'){|ofile|ofile.print(expected)}
227 File.open('out.kati', 'w'){|ofile|ofile.print(output)}
228
Shinichiro Hamaji74c832f2015-04-09 14:54:39 +0900229 if expected =~ /FAIL/
230 puts %Q(#{name} has a string "FAIL" in its expectation)
231 exit 1
232 end
233
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900234 if expected != output
Shinichiro Hamaji91b105c2015-03-30 18:39:05 +0900235 if expected_failure
236 puts "#{name}: FAIL (expected)"
Shinichiro Hamajic6713602015-04-01 01:03:34 +0900237 expected_failures << name
Shinichiro Hamaji91b105c2015-03-30 18:39:05 +0900238 else
239 puts "#{name}: FAIL"
240 puts `diff -u out.make out.kati`
Shinichiro Hamajic6713602015-04-01 01:03:34 +0900241 failures << name
Shinichiro Hamaji91b105c2015-03-30 18:39:05 +0900242 end
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900243 else
Shinichiro Hamaji91b105c2015-03-30 18:39:05 +0900244 if expected_failure
245 puts "#{name}: PASS (unexpected)"
Shinichiro Hamajic6713602015-04-01 01:03:34 +0900246 unexpected_passes << name
Shinichiro Hamaji91b105c2015-03-30 18:39:05 +0900247 else
248 puts "#{name}: PASS"
Shinichiro Hamajic6713602015-04-01 01:03:34 +0900249 passes << name
Shinichiro Hamaji91b105c2015-03-30 18:39:05 +0900250 end
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900251 end
Shinichiro Hamajic48d9ce2015-04-28 03:47:39 +0900252
Shinichiro Hamajie666ac82015-04-28 04:18:13 +0900253 if name !~ /^err_/ && test_serialization && !expected_failure
Shinichiro Hamajic48d9ce2015-04-28 03:47:39 +0900254 testcases.each do |tc|
255 json = "#{tc.empty? ? 'test' : tc}"
Fumitoshi Ukai6450d0f2015-07-10 16:34:06 +0900256 cmd = "../../kati -save_json=#{json}_2.json -load_json=#{json}.json -n -log_dir=. #{tc} 2>&1"
Shinichiro Hamajic48d9ce2015-04-28 03:47:39 +0900257 res = IO.popen(cmd, 'r:binary', &:read)
258 if !File.exist?("#{json}.json") || !File.exist?("#{json}_2.json")
259 puts "#{name}##{json}: Serialize failure (not exist)"
Shinichiro Hamaji9f4f5d32015-04-28 03:53:49 +0900260 puts res
Shinichiro Hamajic48d9ce2015-04-28 03:47:39 +0900261 else
262 json1 = File.read("#{json}.json")
263 json2 = File.read("#{json}_2.json")
264 if json1 != json2
265 puts "#{name}##{json}: Serialize failure"
Shinichiro Hamaji9f4f5d32015-04-28 03:53:49 +0900266 puts res
Shinichiro Hamajic48d9ce2015-04-28 03:47:39 +0900267 end
268 end
269 end
270 end
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900271 end
272end
Shinichiro Hamajic6713602015-04-01 01:03:34 +0900273
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900274run_shell_test = proc do |sh|
Shinichiro Hamaji09796ef2015-07-30 17:08:29 +0900275 is_ninja_test = sh =~ /\/ninja_/
276 if is_ninja_test && (!ckati || !via_ninja)
277 next
278 end
279
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900280 run_in_testdir(sh) do |name|
281 cleanup
282 cmd = "sh ../../#{sh} make"
Shinichiro Hamaji09796ef2015-07-30 17:08:29 +0900283 if is_ninja_test
284 cmd += ' -s'
285 end
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900286 expected = IO.popen(cmd, 'r:binary', &:read)
287 cleanup
Shinichiro Hamaji09796ef2015-07-30 17:08:29 +0900288
289 if is_ninja_test
290 if ckati
Shinichiro Hamajia88c1c22015-07-31 12:29:48 +0900291 cmd = "sh ../../#{sh} ../../ckati --ninja --regen"
Shinichiro Hamaji09796ef2015-07-30 17:08:29 +0900292 else
293 next
294 end
295 else
296 if ckati
297 cmd = "sh ../../#{sh} ../../ckati"
298 else
299 cmd = "sh ../../#{sh} ../../kati --use_cache -log_dir=."
300 end
301 end
302
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900303 output = IO.popen(cmd, 'r:binary', &:read)
304
305 expected = normalize_make_log(expected)
306 output = normalize_kati_log(output)
Shinichiro Hamaji09796ef2015-07-30 17:08:29 +0900307 if is_ninja_test
308 output = normalize_ninja_log(output, sh)
Shinichiro Hamaji59956602015-08-11 15:35:55 +0900309 output.gsub!(/No need to regenerate ninja file\n/, '')
Shinichiro Hamaji09796ef2015-07-30 17:08:29 +0900310 end
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900311 File.open('out.make', 'w'){|ofile|ofile.print(expected)}
312 File.open('out.kati', 'w'){|ofile|ofile.print(output)}
313
314 if expected != output
315 puts "#{name}: FAIL"
Shinichiro Hamaji39e62402015-05-20 19:34:58 +0900316 puts `diff -u out.make out.kati`
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900317 failures << name
318 else
319 puts "#{name}: PASS"
320 passes << name
321 end
322 end
323end
324
325test_files.each do |test|
326 if /\.mk$/ =~ test
327 run_make_test.call(test)
328 elsif /\.sh$/ =~ test
329 run_shell_test.call(test)
330 else
331 raise "Unknown test type: #{test}"
332 end
333end
334
Shinichiro Hamajic6713602015-04-01 01:03:34 +0900335puts
336
337if !expected_failures.empty?
338 puts "=== Expected failures ==="
339 expected_failures.each do |n|
340 puts n
341 end
342end
343
344if !unexpected_passes.empty?
345 puts "=== Unexpected passes ==="
346 unexpected_passes.each do |n|
347 puts n
348 end
349end
350
351if !failures.empty?
352 puts "=== Failures ==="
353 failures.each do |n|
354 puts n
355 end
356end
357
358puts
359
360if !unexpected_passes.empty? || !failures.empty?
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900361 puts "FAIL! (#{failures.size + unexpected_passes.size} fails #{passes.size} passes)"
Shinichiro Hamajic6713602015-04-01 01:03:34 +0900362else
363 puts 'PASS!'
364end