1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
|
#--
#
# Author:: Tsutomu Katsube.
# Copyright:: Copyright (c) 2024-2025 Tsutomu Katsube. All rights reserved.
# License:: Ruby license.
require_relative "sub-test-result"
require_relative "test-suite-runner"
require_relative "test-thread-run-context"
module Test
module Unit
class TestSuiteThreadRunner < TestSuiteRunner
class << self
def run_all_tests(result, options)
n_workers = TestSuiteRunner.n_workers
test_suite = options[:test_suite]
queue = Thread::Queue.new
run_context = TestThreadRunContext.new(self, queue)
yield(run_context)
run_context.progress_block.call(TestSuite::STARTED, test_suite.name)
run_context.progress_block.call(TestSuite::STARTED_OBJECT, test_suite)
run_context.parallel_unsafe_tests.each(&:call)
n_workers.times do
queue << nil
end
workers = []
sub_exceptions = []
n_workers.times do |i|
workers << Thread.new(i + 1) do |worker_id|
begin
loop do
task = queue.pop
break if task.nil?
catch do |stop_tag|
task.call(stop_tag, worker_id)
end
end
rescue Exception => exception
sub_exceptions << exception
end
end
end
workers.each(&:join)
run_context.progress_block.call(TestSuite::FINISHED, test_suite.name)
run_context.progress_block.call(TestSuite::FINISHED_OBJECT, test_suite)
sub_exceptions.each do |exception|
raise exception
end
end
end
def run(worker_context, &progress_block)
worker_context.run_context.progress_block = progress_block
run_tests_recursive(@test_suite, worker_context, &progress_block)
end
private
def run_tests_recursive(test_suite, worker_context, &progress_block)
run_context = worker_context.run_context
if test_suite.have_fixture?
task = lambda do |stop_tag, worker_id|
sub_result = SubTestResult.new(worker_context.result)
sub_result.stop_tag = stop_tag
sub_runner = TestSuiteRunner.new(test_suite)
sub_worker_context = WorkerContext.new(worker_id, run_context, sub_result)
sub_runner.run(sub_worker_context, &progress_block)
end
run_context.queue << task
else
test_suite.tests.each do |test|
if test.is_a?(TestSuite)
run_tests_recursive(test, worker_context, &progress_block)
elsif test_suite.parallel_safe?
task = lambda do |stop_tag, worker_id|
sub_result = SubTestResult.new(worker_context.result)
sub_result.stop_tag = stop_tag
sub_worker_context = WorkerContext.new(worker_id, run_context, sub_result)
run_test(test, sub_worker_context, &progress_block)
end
run_context.queue << task
else
run_context.parallel_unsafe_tests << lambda do
run_test(test, worker_context, &progress_block)
end
end
end
end
end
end
end
end
|