diff --git a/bin/cmdtest.rb b/bin/cmdtest.rb index ab06890..2d5c320 100755 --- a/bin/cmdtest.rb +++ b/bin/cmdtest.rb @@ -288,10 +288,14 @@ module Cmdtest if ! @opts.slave File.join(tmp_cmdtest_dir, "top") else - File.join(tmp_cmdtest_dir, @opts.slave) + tmp_dir_slave(@opts.slave) end end + def tmp_dir_slave(slave_name) + File.join(tmp_cmdtest_dir, slave_name) + end + def tmp_work_dir File.join(tmp_dir, "work") end @@ -319,16 +323,75 @@ module Cmdtest end end - clog.notify("testsuite") do - for adm_file in @adm_files - clog.notify("testfile", adm_file.path) do + if @opts.parallel > 1 + json_files = [] + nclasses = 0 + File.open("tmp.sh", "w") do |f| + for adm_file in @adm_files + if ! @opts.quiet + f.puts "echo '### " + "=" * 40 + " " + adm_file.path + "'" + end for adm_class in adm_file.adm_classes - clog.notify("testclass", adm_class.runtime_class.display_name) do - for adm_method in adm_class.adm_methods - adm_method.run(clog, self) - if $cmdtest_got_ctrl_c > 0 - puts "cmdtest: exiting after Ctrl-C ..." - exit(1) + nclasses += 1 + if ! @opts.quiet + f.puts "echo '### " + "-" * 40 + " " + adm_class.as_filename + "'" + end + for adm_method in adm_class.adm_methods + slave_name = adm_method.as_filename + f.puts "#{$0} %s --slave %s %s" % [ + (@opts.quiet ? "-q" : ""), + slave_name, + adm_file.path, + ] + json_files << File.join(tmp_dir_slave(slave_name), "result.json") + end + end + end + end + cmd = "parallel -k -j%d < tmp.sh" % [@opts.parallel] + ok = system(cmd) + summary = Hash.new(0) + for file in json_files + File.open(file) do |f| + data = JSON.load(f) + for k,v in data + summary[k] += v + end + end + end + summary["classes"] = nclasses + if ! @opts.quiet + Cmdtest.print_summary(summary) + end + + ok = summary["errors"] == 0 && summary["failures"] == 0 + error_exit = ! @opts.no_exit_code && ! ok + exit( error_exit ? 1 : 0 ) + + + elsif @opts.slave + for adm_file in @adm_files + for adm_class in adm_file.adm_classes + for adm_method in adm_class.adm_methods + if adm_method.as_filename == @opts.slave + adm_method.run(clog, self) + end + end + end + end + + else + clog.notify("testsuite") do + for adm_file in @adm_files + clog.notify("testfile", adm_file.path) do + for adm_class in adm_file.adm_classes + clog.notify("testclass", adm_class.runtime_class.display_name) do + for adm_method in adm_class.adm_methods + adm_method.run(clog, self) + if $cmdtest_got_ctrl_c > 0 + puts "cmdtest: exiting after Ctrl-C ..." + exit(1) + end end end end @@ -343,6 +406,21 @@ module Cmdtest #---------------------------------------------------------------------- + def self.print_summary(summary) + puts + puts "%s %d test classes, %d test methods, %d commands, %d errors, %d fatals." % [ + summary["failures"] == 0 && summary["errors"] == 0 ? "###" : "---", + summary["classes"], + summary["methods"], + summary["commands"], + summary["failures"], + summary["errors"], + ] + puts + end + + #---------------------------------------------------------------------- + class ProjectDir ORIG_CWD = Dir.pwd @@ -420,7 +498,6 @@ module Cmdtest class Main def initialize - _update_cmdtest_level end def _parse_options @@ -442,6 +519,8 @@ module Cmdtest def run opts = _parse_options + _update_cmdtest_level(opts.slave ? 0 : 1) + files = [] for arg in opts.args case @@ -495,28 +574,43 @@ module Cmdtest end @runner.run(clog) - if ! opts.quiet - puts - puts "%s %d test classes, %d test methods, %d commands, %d errors, %d fatals." % [ - error_logger.n_failures == 0 && error_logger.n_errors == 0 ? "###" : "---", - error_logger.n_classes, - error_logger.n_methods, - error_logger.n_commands, - error_logger.n_failures, - error_logger.n_errors - ] - puts - end + if opts.slave + result = { + "classes" => error_logger.n_classes, + "methods" => error_logger.n_methods, + "commands" => error_logger.n_commands, + "failures" => error_logger.n_failures, + "errors" => error_logger.n_errors, + } + result_file = File.join(@runner.tmp_dir, "result.json") + File.open(result_file, "w") do |f| + f.puts JSON.pretty_generate(result) + end + exit(0) + else + if ! opts.quiet + puts + puts "%s %d test classes, %d test methods, %d commands, %d errors, %d fatals." % [ + error_logger.n_failures == 0 && error_logger.n_errors == 0 ? "###" : "---", + error_logger.n_classes, + error_logger.n_methods, + error_logger.n_commands, + error_logger.n_failures, + error_logger.n_errors, + ] + puts + end - ok = error_logger.everything_ok? - error_exit = ! opts.no_exit_code && ! ok - exit( error_exit ? 1 : 0 ) + ok = error_logger.everything_ok? + error_exit = ! opts.no_exit_code && ! ok + exit( error_exit ? 1 : 0 ) + end end private - def _update_cmdtest_level - $cmdtest_level = (ENV["CMDTEST_LEVEL"] || "0").to_i + 1 + def _update_cmdtest_level(inc) + $cmdtest_level = (ENV["CMDTEST_LEVEL"] || "0").to_i + inc ENV["CMDTEST_LEVEL"] = $cmdtest_level.to_s end diff --git a/t/CMDTEST_summary.rb b/t/CMDTEST_summary.rb index 4ff49aa..e463583 100644 --- a/t/CMDTEST_summary.rb +++ b/t/CMDTEST_summary.rb @@ -28,7 +28,7 @@ class CMDTEST_summery < Cmdtest::Testcase ' exit_zero', ' end', ' cmd "true" do', - ' exit_nonzero', + ' exit_nonzero', # +1 errors ' end', ' end', '', @@ -36,25 +36,25 @@ class CMDTEST_summery < Cmdtest::Testcase ' cmd "true" do', ' exit_zero', ' end', - ' non_existing_method', + ' non_existing_method', # +1 fatals ' end', '', ' def test_foo3', ' cmd "true" do', ' exit_zero', ' end', - ' non_existing_method', + ' non_existing_method', # +1 fatals ' end', '', ' def test_foo4', ' cmd "true" do', - ' exit_nonzero', + ' exit_nonzero', # +1 errors ' end', ' end', '', ' def test_foo5', ' cmd "true" do', - ' exit_nonzero', + ' exit_nonzero', # +1 errors ' end', ' end', '', diff --git a/t/selftest_utils.rb b/t/selftest_utils.rb index 5e76c90..8b9a008 100644 --- a/t/selftest_utils.rb +++ b/t/selftest_utils.rb @@ -12,6 +12,7 @@ module SelftestUtils end def setup + ignore_file "**/tmp.sh" ignore_file "**/.cmdtest-filter" ignore_file "tmp-cmdtest-2/" ignore_file "tmp-cmdtest-2/TIMESTAMP"