diff --git a/examples/failures.rb b/examples/failures.rb index 48d943a..7620f31 100644 --- a/examples/failures.rb +++ b/examples/failures.rb @@ -31,7 +31,7 @@ def test_another_test_yes end def test_inc_test - assert_includes %w[a b c], 'd' + assert_include %w[a b c], 'd' end def test_equal diff --git a/examples/parallel.rb b/examples/parallel.rb new file mode 100644 index 0000000..918eabd --- /dev/null +++ b/examples/parallel.rb @@ -0,0 +1,15 @@ +require File.expand_path('../../lib/para', __FILE__) + +class Foo < Para::Test + enable_parallel + + test "foo" do + assert true + sleep 1 + end + + test "foo again" do + assert true + sleep 1 + end +end diff --git a/lib/para/base.rb b/lib/para/base.rb index 4fc1686..667c247 100644 --- a/lib/para/base.rb +++ b/lib/para/base.rb @@ -6,14 +6,31 @@ def thread_count() (ENV['THREADS'] || 1).to_i; end def printer() @printer ||= Printer.new; end # Worker - def worker!(q, i) while q.any?; run_test i, *q.shift; end; end + def worker!(q, i) + if i == 0 + # For the first thread, just take the next test. + while q.any? + run_test i, *q.shift + end + else + # For other threads, only work on the ones that are enabled for parallel. + while true + test = q.detect { |(testcase, _)| testcase.parallel? } or break + q.delete test + run_test i, *test + end + end + end # Spawn multiple threads, each doing #work! def start! Signal.trap("INT") { printer.done; exit } queue = Test.all_tests - thread_count.times.map { |i| Thread.new { worker!(queue, i) } }.each { |t| t.join } + threads = (thread_count-1).times.map { |i| Thread.new { worker!(queue, i+1) } } + + worker!(queue, 0) + threads.join printer.done end @@ -46,6 +63,10 @@ def failures() @failures ||= Array.new; end def teardown(); end def setup(); end + def self.enable_parallel() @parallel = true; end + def self.disable_parallel() @parallel = false; end + def self.parallel?() !! @parallel; end + def assert(what, msg=nil) if what @runner.printer.success