mkvtoolnix/tests/run.rb

352 lines
9.0 KiB
Ruby
Executable File

#!/usr/bin/ruby
class SubtestError < RuntimeError
end
class Test
attr_reader :commands
attr_reader :debug_commands
def initialize
@tmp_num = 0
@commands = Array.new
@debug_commands = Array.new
end
def description
return "dummy test class"
end
def run
return error("Trying to run the base class")
end
def unlink_tmp_files
n = "mkvtoolnix-auto-test-" + $$.to_s + "-"
Dir.entries("/tmp").each do |e|
File.unlink("/tmp/#{e}") if (e =~ /^#{n}/)
end
end
def run_test
begin
return run
rescue RuntimeError => ex
unlink_tmp_files
puts(ex.to_s)
return nil
end
end
def error(reason)
puts(" Failed. Reason: #{reason}")
raise "test failed"
end
def sys(command, *arg)
@commands.push(command)
@debug_commands.push(command)
command += "&> /dev/null" unless (command =~ />/)
if (!system(command))
if ((arg.size == 0) || ((arg[0] << 8) != $?))
error("system command failed: #{command} (" + ($? >> 8).to_s + ")")
end
end
end
def tmp_name
@tmp_num ||= 0
@tmp_num += 1
return "/tmp/mkvtoolnix-auto-test-" + $$.to_s + "-" + @tmp_num.to_s
end
def tmp
@tmp ||= tmp_name
return @tmp
end
def hash_file(name)
@debug_commands.push("md5sum #{name}")
return `md5sum #{name}`.chomp.gsub(/\s+.*/, "")
end
def hash_tmp(erase = true)
output = hash_file(@tmp)
if (erase)
File.unlink(@tmp) if (File.exists?(@tmp))
@debug_commands.push("rm #{@tmp}")
@tmp = nil
end
return output
end
def merge(*args)
command = "../src/mkvmerge --engage no_variable_data "
string_args = Array.new
retcode = 0
args.each do |a|
if (a.class == String)
string_args.push(a)
else
retcode = a
end
end
if ((string_args.size == 0) or (string_args.size > 2))
raise "Wrong use of the 'merge' function."
elsif (string_args.size == 1)
command += "-o " + tmp + " " + string_args[0]
else
command += "-o " + string_args[0] + " " + string_args[1]
end
sys(command, retcode)
end
def xtr_tracks_s(*args)
command = "../src/mkvextract tracks data/mkv/complex.mkv " +
"--no-variable-data "
command += args.join(" ")
command += ":#{tmp}"
sys(command, 0)
return hash_tmp
end
def xtr_tracks(*args)
command = "../src/mkvextract tracks "
command += args[0]
command += " --no-variable-data "
command += args[1..args.size - 1].join(" ")
sys(command, 0)
end
end
class Results
def initialize
load
end
def load
@results = Hash.new
return unless (FileTest.exist?("results.txt"))
IO.readlines("results.txt").each do |line|
parts = line.chomp.split(/:/)
parts[3] =~
/([0-9]{4})([0-9]{2})([0-9]{2})-([0-9]{2})([0-9]{2})([0-9]{2})/
@results[parts[0]] = {"hash" => parts[1], "status" => parts[2],
"date_added" => Time.local($1, $2, $3, $4, $5, $6) }
end
end
def save
f = File.new("results.txt", "w")
@results.keys.sort.each do |key|
f.puts("#{key}:" + @results[key]['hash'] + ":" +
@results[key]['status'] + ":" +
@results[key]['date_added'].strftime("%Y%m%d-%H%M%S"))
end
f.close
end
def exist?(name)
return @results.has_key?(name)
end
def hash?(name)
raise "No such result" unless (exist?(name))
return @results[name]['hash']
end
def status?(name)
raise "No such result" unless (exist?(name))
return @results[name]['status']
end
def date_added?(name)
raise "No such result" unless (exist?(name))
return @results[name]['date_added']
end
def add(name, hash)
raise "Test does already exist" if (exist?(name))
@results[name] = {"hash" => hash, "status" => "new",
"date_added" => Time.now }
save
end
def set(name, status)
return unless (exist?(name))
@results[name]["status"] = status
save
end
def set_hash(name, hash)
raise "Test does not exist" unless (exist?(name))
@results[name]["hash"] = hash
save
end
end
def main
ENV['LC_ALL'] = "en_US.ISO-8859-1"
results = Results.new
test_failed = false
test_new = false
test_date_after = nil
test_date_before = nil
update_failed = false
tests = Array.new
dir_entries = Dir.entries(".")
ARGV.each do |arg|
if ((arg == "-f") or (arg == "--failed"))
test_failed = true
elsif ((arg == "-n") or (arg == "--new"))
test_new = true
elsif ((arg == "-u") or (arg == "--update-failed"))
update_failed = true
elsif (arg =~ /-d([0-9]{4})([0-9]{2})([0-9]{2})-([0-9]{2})([0-9]{2})/)
test_date_after = Time.local($1, $2, $3, $4, $5, $6)
elsif (arg =~ /-D([0-9]{4})([0-9]{2})([0-9]{2})-([0-9]{2})([0-9]{2})/)
test_date_before = Time.local($1, $2, $3, $4, $5, $6)
elsif (arg =~ /^[0-9]{3}$/)
dir_entries.each { |e| tests.push(e) if (e =~ /^test-#{arg}/) }
else
puts("Unknown argument '#{arg}'.")
exit(2)
end
end
test_all = (!test_failed && !test_new)
tests = dir_entries unless (tests.size > 0)
ENV['PATH'] = "../src:" + ENV['PATH']
if (ENV["DEBUG"] == "1")
$stderr.puts("#!/bin/bash\n\n")
$stderr.puts("export LD_LIBRARY_PATH=/usr/local/lib\n\n")
$stderr.puts("rm new_results.txt &> /dev/null")
$stderr.puts("touch new_results.txt\n\n")
end
num_tests = 0
num_failed = 0
start = Time.now
tests.sort.each do |entry|
next unless (FileTest.file?(entry) and (entry =~ /^test-.*\.rb$/))
class_name = "T_" + entry.gsub(/^test-/, "").gsub(/\.rb$/, "")
test_this = test_all
if (results.exist?(class_name))
if (test_failed and (results.status?(class_name) == "failed"))
test_this = true
elsif (test_new and (results.status?(class_name) == "new"))
test_this = true
end
elsif (test_new || test_failed)
test_this = true
end
if (results.exist?(class_name))
if (test_date_after and
(results.date_added?(class_name) < test_date_after))
test_this = false
elsif (test_date_before and
(results.date_added?(class_name) > test_date_before))
test_this = false
end
end
next unless (test_this)
num_tests += 1
if (!require("./" + entry))
puts(" Failed to load '#{entry}'.")
results.set(class_name, "failed")
num_failed += 1
next
end
begin
current_test = eval(class_name + ".new")
rescue
puts(" Failed to create an instance of class '#{class_name}'.")
results.set(class_name, "failed")
num_failed += 1
next
end
if (current_test.description == "INSERT DESCRIPTION")
puts("Skipping '#{class_name}': Not implemented yet")
next
end
puts("Running '#{class_name}': #{current_test.description}")
result = current_test.run_test
if (result)
if (!results.exist?(class_name))
puts(" NEW test. Storing result '#{result}'.")
results.add(class_name, result)
elsif (results.hash?(class_name) != result)
puts(" FAILED: checksum is different. Commands:")
puts(" " + current_test.commands.join("\n "))
if (update_failed)
puts(" UPDATING result")
results.set_hash(class_name, result)
results.set(class_name, "passed")
else
results.set(class_name, "failed")
num_failed += 1
end
else
results.set(class_name, "passed")
end
else
puts(" FAILED: no result from test")
results.set(class_name, "failed")
num_failed += 1
end
if (ENV["DEBUG"] == "1")
$stderr.puts("echo -n Running #{class_name}")
$stderr.puts("FAILED=0")
$stderr.puts("echo -n #{class_name}: >> new_results.txt")
first = true
current_test.debug_commands.each do |c|
c.gsub!(/\/tmp\//, "$HOME/tmp/")
if (c =~ /^md5sum/)
$stderr.puts("echo -n - >> new_results.txt") unless (first)
first = false
$stderr.puts("SUM=`" + c + " | gawk '{print $1}'`")
$stderr.puts("echo -n $SUM >> new_results.txt")
else
if (c =~ />/)
$stderr.puts(c)
else
$stderr.puts(c + " &> /dev/null")
end
$stderr.puts("if [ $? -ne 0 -a $? -ne 1 ]; then")
$stderr.puts(" FAILED=1")
$stderr.puts("fi")
end
end
da = results.date_added?(class_name).strftime("%Y%m%d-%H%M%S")
$stderr.puts("if [ $FAILED -eq 1 ]; then")
$stderr.puts(" echo :failed:#{da} >> new_results.txt")
$stderr.puts(" echo ' FAILED'")
$stderr.puts("else")
$stderr.puts(" echo :passed:#{da} >> new_results.txt")
$stderr.puts(" echo ' ok'")
$stderr.puts("fi")
$stderr.puts("rm ~/tmp/mkvtoolnix-auto-test-* &> /dev/null\n\n")
end
end
duration = Time.now - start
puts("#{num_failed}/#{num_tests} failed (" +
(num_tests > 0 ? (num_failed * 100 / num_tests).to_s : "0") + "%). " +
"Tests took #{duration}s.")
exit(num_failed > 0 ? 1 : 0)
end
main