1
0
mirror of https://github.com/mgcaret/of816.git synced 2024-06-02 02:41:33 +00:00
of816/platforms/GoSXB/run-tests.rb

204 lines
5.9 KiB
Ruby
Raw Normal View History

2019-12-29 22:53:44 +00:00
#!/usr/bin/ruby
require 'open3'
require 'yaml'
require 'stringio'
require 'timeout'
2020-01-06 01:42:58 +00:00
require 'optparse'
2019-12-29 22:53:44 +00:00
2020-01-06 01:42:58 +00:00
@opts = {
test_dir: '../../test',
suites: '*',
output_file: nil,
cov_file: nil,
verbose: $DEBUG,
list_only: false
}
@coverage = Hash.new(0)
OptionParser.new do |o|
o.banner = "Usage: #{$0} [options]"
o.on('-d', '--dir TEST_DIR', 'Specify test directory.') do |d|
@opts[:test_dir] = d
end
o.on('-s', '--suites PATTERN', 'Specify suites as shell glob.') do |p|
@opts[:suites] = p
end
o.on('-o', '--outfile FILENAME', 'Specify test output file (default none).') do |f|
@opts[:output_file] = f
end
o.on('-c', '--coverage FILENAME', 'Specify test coverage file (default none).') do |f|
@opts[:cov_file] = f
end
o.on('-l', '--list-suites', 'List available test suites.') do |d|
@opts[:list_only] = true
end
o.on("-v", "--[no-]verbose", "Run verbosely") do |v|
@opts[:verbose] = v
end
o.on_tail("-h", "--help", "Show this message") do
puts o
exit
end
end.parse!
2019-12-29 22:53:44 +00:00
@total_errors = 0
2020-01-06 01:42:58 +00:00
def verbose
@opts[:verbose]
end
def run_suite(suite, outfile = nil)
2019-12-29 22:53:44 +00:00
errors = 0
suite_text = []
outbuf = StringIO.new
errbuf = StringIO.new
suite['load'].each do |file|
2020-01-06 01:42:58 +00:00
suite_text += File.readlines("#{@opts[:test_dir]}/#{file}")
2019-12-29 22:53:44 +00:00
end
2020-01-06 01:42:58 +00:00
colons = {}
2019-12-29 22:53:44 +00:00
suite_text << "\nbye\n"
Open3.popen3('./gosxb-of816.sh') do |stdin, stdout, stderr, wait_thr|
until [stdout, stderr].find {|f| !f.eof}.nil?
readable, writable, errored = IO.select([stdout,stderr],[stdin],[],0)
if writable.include?(stdin)
if line = suite_text.shift
2020-01-06 01:42:58 +00:00
puts ">> #{line}" if verbose
2019-12-29 22:53:44 +00:00
stdin.write(line)
else
puts "Lines complete."
stdin.flush
begin
# Give test 30 seconds to complete
Timeout.timeout(30) do
2019-12-29 22:53:44 +00:00
outbuf.write(stdout.read)
end
rescue Timeout::Error
begin
outbuf.write(stdout.read_nonblock(1024))
rescue IO::EAGAINWaitReadable
# nothing
end
2020-01-06 01:42:58 +00:00
puts outbuf.string unless verbose
2019-12-29 22:53:44 +00:00
STDERR.puts "Emulator did not exit on its own."
errors += 1
end
stdin.close
2020-01-06 01:42:58 +00:00
puts outbuf.string if verbose
2019-12-29 22:53:44 +00:00
break
end
end
if readable.include?(stdout)
text = stdout.readline
2020-01-06 01:42:58 +00:00
puts "<< #{text}" if verbose
2019-12-29 22:53:44 +00:00
outbuf.write(text)
end
if readable.include?(stderr)
stdin.flush
errbuf.write(stderr.read)
puts "Unexpected output on stderr:"
puts outbuf.string
puts errbuf.string
stdout.close
stderr.close
exit 2
end
break unless wait_thr.alive?
end
2020-01-06 01:42:58 +00:00
outfile.write(outbuf.string) if outfile
2019-12-29 22:53:44 +00:00
prevline = ""
outbuf.string.lines.each do |line|
2020-01-06 20:30:09 +00:00
cs_line = line.gsub(/\\.+$/,'')
2019-12-29 22:53:44 +00:00
case line
when /Exception/, /Def not found/, /Stack u/
2019-12-29 22:53:44 +00:00
STDERR.puts prevline, line
errors += 1
when /WRONG/, /INCORRECT/
unless prevline =~ /\[OK\]/
STDERR.puts line
errors += 1
end
when /TESTING/i
2020-01-06 20:30:09 +00:00
puts line unless line.start_with?(':') || line.start_with?('\\')
2019-12-29 22:53:44 +00:00
end
2020-01-06 20:30:09 +00:00
if cs_line =~ /\s*:\s+(\S+)/
2020-01-06 01:42:58 +00:00
colons[$1.downcase] = true
end
2020-01-06 20:30:09 +00:00
if cs_line =~ /\s*[tT]\{\s+:\s+(\S+)/
2020-01-06 01:42:58 +00:00
colons[$1.downcase] = true
end
2020-01-07 03:51:19 +00:00
if cs_line =~ /^\s*T\{\s+(.+)\s+\-\>\s+/i
2020-01-06 20:30:09 +00:00
words = $1.split(/\s+/)
2020-01-06 01:42:58 +00:00
words.each do |word|
next if word == '->'
@coverage[word.downcase] += 1 unless colons[word.downcase]
end
end
if line =~ /\\.*\s+covers:\s*(\S+)\s*$/
@coverage[$1.downcase] += 1
end
if prevline =~ /expect:\s*\"(.+)\"\s*$/
unless line.chomp == $1
STDERR.puts prevline
STDERR.puts "Unexpected: #{line.chomp.inspect}"
errors += 1
end
elsif prevline =~ /expect:\s*\/(.+)\/\s*$/
rexp = Regexp.new($1)
unless line.chomp =~ rexp
STDERR.puts prevline
STDERR.puts "Unexpected: #{line.chomp.inspect}"
errors += 1
end
end
2019-12-29 22:53:44 +00:00
prevline = line
end
puts "Errors = #{errors}"
end
puts "Suite complete."
return errors
end
2020-01-06 01:42:58 +00:00
outfile = nil
begin
manifest = YAML.load(File.read("#{@opts[:test_dir]}/test-manifest.yaml"))
#puts manifest.inspect
2019-12-29 22:53:44 +00:00
2020-01-06 01:42:58 +00:00
unless @opts[:verbose]
outfile = File.open(@opts[:output_file], 'w') if @opts[:output_file]
end
2019-12-29 22:53:44 +00:00
2020-01-06 01:42:58 +00:00
manifest.each do |suite|
if File.fnmatch(@opts[:suites], suite['name'])
print "Executing suite: " unless @opts[:list_only]
puts suite['name']
@total_errors += run_suite(suite, outfile) unless @opts[:list_only]
end
end
rescue RuntimeError => e
STDERR.puts e.to_s
ensure
outfile.close if outfile
2019-12-29 22:53:44 +00:00
end
2020-01-06 01:42:58 +00:00
exit 0 if @opts[:list_only]
File.write(@opts[:cov_file], @coverage.to_yaml) if @opts[:cov_file]
2019-12-29 22:53:44 +00:00
if @total_errors > 0
STDERR.puts "Tests complete, total errors: #{@total_errors}"
exit 1
end
STDOUT.puts "Tests complete, no errors."
exit 0