blob: 260305bdca23b9fc505fee25fc7c926f83e5af60 [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 Hamaji9f4f5d32015-04-28 03:53:49 +090019if ARGV[0] == '-s'
20 test_serialization = true
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090021elsif ARGV[0] == '-c'
22 ckati = true
23 ARGV.shift
Shinichiro Hamaji9f4f5d32015-04-28 03:53:49 +090024end
25
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090026def get_output_filenames
27 files = Dir.glob('*')
28 files.delete('Makefile')
Shinichiro Hamaji65489db2015-06-29 20:44:26 +090029 files.delete('gmon.out')
Shinichiro Hamajib674d582015-04-28 03:40:57 +090030 files.reject!{|f|f =~ /\.json$/}
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090031 files
32end
33
34def cleanup
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +090035 (get_output_filenames + Dir.glob('.*')).each do |fname|
36 next if fname == '.' || fname == '..'
Shinichiro Hamajic6713602015-04-01 01:03:34 +090037 FileUtils.rm_rf fname
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090038 end
39end
40
Shinichiro Hamaji74a66002015-04-27 16:42:30 +090041def move_circular_dep(l)
42 # We don't care when circular dependency detection happens.
43 circ = ''
44 while l.sub!(/Circular .* dropped\.\n/, '') do
45 circ += $&
46 end
47 circ + l
48end
49
Shinichiro Hamajic6713602015-04-01 01:03:34 +090050expected_failures = []
51unexpected_passes = []
52failures = []
53passes = []
54
Shinichiro Hamajiec42b4e2015-05-14 16:20:03 +090055if !ARGV.empty?
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +090056 test_files = ARGV.map do |test|
57 "testcase/#{File.basename(test)}"
Shinichiro Hamajiec42b4e2015-05-14 16:20:03 +090058 end
59else
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +090060 test_files = Dir.glob('testcase/*.mk').sort
61 test_files += Dir.glob('testcase/*.sh').sort
Shinichiro Hamajiec42b4e2015-05-14 16:20:03 +090062end
63
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +090064def run_in_testdir(test_filename)
65 c = File.read(test_filename)
66 name = File.basename(test_filename)
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090067 dir = "out/#{name}"
Shinichiro Hamaji52e42032015-03-31 23:20:13 +090068
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090069 FileUtils.mkdir_p(dir)
Shinichiro Hamaji52e42032015-03-31 23:20:13 +090070 Dir.glob("#{dir}/*").each do |fname|
71 FileUtils.rm_rf(fname)
72 end
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090073
74 Dir.chdir(dir) do
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +090075 yield name
76 end
77end
78
79def normalize_make_log(expected)
80 expected.gsub!(/^make(?:\[\d+\])?: (Entering|Leaving) directory.*\n/, '')
81 expected.gsub!(/^make(?:\[\d+\])?: /, '')
82 expected = move_circular_dep(expected)
83
84 # Normalizations for old/new GNU make.
85 expected.gsub!(/[`'"]/, '"')
86 expected.gsub!(/ (?:commands|recipe) for target /,
87 ' commands for target ')
88 expected.gsub!(/ (?:commands|recipe) commences /,
89 ' commands commence ')
90 expected.gsub!(' (did you mean TAB instead of 8 spaces?)', '')
91 expected.gsub!('Extraneous text after', 'extraneous text after')
92 # Not sure if this is useful.
93 expected.gsub!(/\s+Stop\.$/, '')
94 # GNU make 4.0 has this output.
95 expected.gsub!(/Makefile:\d+: commands for target ".*?" failed\n/, '')
96 # We treat some warnings as errors.
97 expected.gsub!(/Nothing to be done for "test"\.\n/, '')
98
99 expected
100end
101
102def normalize_kati_log(output)
103 output = move_circular_dep(output)
104 # kati specific log messages.
105 output.gsub!(/^\*kati\*.*\n/, '')
106 output.gsub!(/[`'"]/, '"')
Shinichiro Hamaji861bd642015-06-19 16:59:13 +0900107 output.gsub!(/(: )(?:open )?(\S+): [Nn](o such file or directory)\nNOTE:.*/,
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900108 "\\1\\2: N\\3\n*** No rule to make target \"\\2\".")
109 output
110end
111
112run_make_test = proc do |mk|
113 c = File.read(mk)
Shinichiro Hamajie919d002015-06-26 01:15:55 +0900114 expected_failure = c =~ /\A# TODO(?:\((go|c)\))?/
115 if $1
116 if $1 == 'go' && ckati
117 expected_failure = false
118 elsif $1 == 'c' && !ckati
119 expected_failure = false
120 end
121 end
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900122
123 run_in_testdir(mk) do |name|
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900124 # TODO: Fix
125 if name =~ /eval_assign/ && ckati
126 next
127 end
128
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900129 File.open("Makefile", 'w') do |ofile|
130 ofile.print(c)
131 end
132
133 expected = ''
134 output = ''
135
Shinichiro Hamaji491e73f2015-04-07 12:41:59 +0900136 testcases = c.scan(/^test\d*/).sort.uniq
Shinichiro Hamaji497754d2015-03-31 02:02:11 +0900137 if testcases.empty?
138 testcases = ['']
139 end
Shinichiro Hamajie5be0142015-03-30 19:26:01 +0900140
141 cleanup
142 testcases.each do |tc|
Shinichiro Hamaji74a66002015-04-27 16:42:30 +0900143 res = `make #{tc} 2>&1`
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900144 res = normalize_make_log(res)
Shinichiro Hamaji74a66002015-04-27 16:42:30 +0900145 expected += "=== #{tc} ===\n" + res
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900146 expected_files = get_output_filenames
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900147 expected += "\n=== FILES ===\n#{expected_files * "\n"}\n"
Shinichiro Hamajie5be0142015-03-30 19:26:01 +0900148 end
149
150 cleanup
151 testcases.each do |tc|
Shinichiro Hamajic48d9ce2015-04-28 03:47:39 +0900152 json = "#{tc.empty? ? 'test' : tc}"
153 cmd = "../../kati -save_json=#{json}.json -kati_log #{tc} 2>&1"
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900154 if ckati
155 cmd = "../../ckati #{tc} 2>&1"
156 end
Shinichiro Hamajib674d582015-04-28 03:40:57 +0900157 res = IO.popen(cmd, 'r:binary', &:read)
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900158 res = normalize_kati_log(res)
Shinichiro Hamaji42f42e12015-04-13 14:26:45 +0900159 output += "=== #{tc} ===\n" + res
Shinichiro Hamajie5be0142015-03-30 19:26:01 +0900160 output_files = get_output_filenames
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900161 output += "\n=== FILES ===\n#{output_files * "\n"}\n"
162 end
163
164 File.open('out.make', 'w'){|ofile|ofile.print(expected)}
165 File.open('out.kati', 'w'){|ofile|ofile.print(output)}
166
Shinichiro Hamaji74c832f2015-04-09 14:54:39 +0900167 if expected =~ /FAIL/
168 puts %Q(#{name} has a string "FAIL" in its expectation)
169 exit 1
170 end
171
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900172 if expected != output
Shinichiro Hamaji91b105c2015-03-30 18:39:05 +0900173 if expected_failure
174 puts "#{name}: FAIL (expected)"
Shinichiro Hamajic6713602015-04-01 01:03:34 +0900175 expected_failures << name
Shinichiro Hamaji91b105c2015-03-30 18:39:05 +0900176 else
177 puts "#{name}: FAIL"
178 puts `diff -u out.make out.kati`
Shinichiro Hamajic6713602015-04-01 01:03:34 +0900179 failures << name
Shinichiro Hamaji91b105c2015-03-30 18:39:05 +0900180 end
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900181 else
Shinichiro Hamaji91b105c2015-03-30 18:39:05 +0900182 if expected_failure
183 puts "#{name}: PASS (unexpected)"
Shinichiro Hamajic6713602015-04-01 01:03:34 +0900184 unexpected_passes << name
Shinichiro Hamaji91b105c2015-03-30 18:39:05 +0900185 else
186 puts "#{name}: PASS"
Shinichiro Hamajic6713602015-04-01 01:03:34 +0900187 passes << name
Shinichiro Hamaji91b105c2015-03-30 18:39:05 +0900188 end
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900189 end
Shinichiro Hamajic48d9ce2015-04-28 03:47:39 +0900190
Shinichiro Hamajie666ac82015-04-28 04:18:13 +0900191 if name !~ /^err_/ && test_serialization && !expected_failure
Shinichiro Hamajic48d9ce2015-04-28 03:47:39 +0900192 testcases.each do |tc|
193 json = "#{tc.empty? ? 'test' : tc}"
Shinichiro Hamaji9f4f5d32015-04-28 03:53:49 +0900194 cmd = "../../kati -save_json=#{json}_2.json -load_json=#{json}.json -n -kati_log #{tc} 2>&1"
Shinichiro Hamajic48d9ce2015-04-28 03:47:39 +0900195 res = IO.popen(cmd, 'r:binary', &:read)
196 if !File.exist?("#{json}.json") || !File.exist?("#{json}_2.json")
197 puts "#{name}##{json}: Serialize failure (not exist)"
Shinichiro Hamaji9f4f5d32015-04-28 03:53:49 +0900198 puts res
Shinichiro Hamajic48d9ce2015-04-28 03:47:39 +0900199 else
200 json1 = File.read("#{json}.json")
201 json2 = File.read("#{json}_2.json")
202 if json1 != json2
203 puts "#{name}##{json}: Serialize failure"
Shinichiro Hamaji9f4f5d32015-04-28 03:53:49 +0900204 puts res
Shinichiro Hamajic48d9ce2015-04-28 03:47:39 +0900205 end
206 end
207 end
208 end
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900209 end
210end
Shinichiro Hamajic6713602015-04-01 01:03:34 +0900211
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900212run_shell_test = proc do |sh|
213 run_in_testdir(sh) do |name|
214 cleanup
215 cmd = "sh ../../#{sh} make"
216 expected = IO.popen(cmd, 'r:binary', &:read)
217 cleanup
218 cmd = "sh ../../#{sh} ../../kati --use_cache --kati_log"
219 output = IO.popen(cmd, 'r:binary', &:read)
220
221 expected = normalize_make_log(expected)
222 output = normalize_kati_log(output)
223 File.open('out.make', 'w'){|ofile|ofile.print(expected)}
224 File.open('out.kati', 'w'){|ofile|ofile.print(output)}
225
226 if expected != output
227 puts "#{name}: FAIL"
Shinichiro Hamaji39e62402015-05-20 19:34:58 +0900228 puts `diff -u out.make out.kati`
Shinichiro Hamajia9bda7a2015-05-20 17:50:42 +0900229 failures << name
230 else
231 puts "#{name}: PASS"
232 passes << name
233 end
234 end
235end
236
237test_files.each do |test|
238 if /\.mk$/ =~ test
239 run_make_test.call(test)
240 elsif /\.sh$/ =~ test
241 run_shell_test.call(test)
242 else
243 raise "Unknown test type: #{test}"
244 end
245end
246
Shinichiro Hamajic6713602015-04-01 01:03:34 +0900247puts
248
249if !expected_failures.empty?
250 puts "=== Expected failures ==="
251 expected_failures.each do |n|
252 puts n
253 end
254end
255
256if !unexpected_passes.empty?
257 puts "=== Unexpected passes ==="
258 unexpected_passes.each do |n|
259 puts n
260 end
261end
262
263if !failures.empty?
264 puts "=== Failures ==="
265 failures.each do |n|
266 puts n
267 end
268end
269
270puts
271
272if !unexpected_passes.empty? || !failures.empty?
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900273 puts "FAIL! (#{failures.size + unexpected_passes.size} fails #{passes.size} passes)"
Shinichiro Hamajic6713602015-04-01 01:03:34 +0900274else
275 puts 'PASS!'
276end