From fb167a2776b8df2f8742c3472b40fba3006cd4ed Mon Sep 17 00:00:00 2001 From: Chester Twomey Date: Thu, 30 Apr 2026 13:12:17 -0500 Subject: [PATCH] add compatibility for minitest 6 --- .github/workflows/tests.yml | 8 ++++++ ruby/Gemfile.lock | 5 +++- ruby/ci-queue.gemspec | 3 ++- ruby/lib/minitest/queue.rb | 45 ++++++++++++++++++++++--------- ruby/lib/minitest/queue/runner.rb | 1 + ruby/test/test_helper.rb | 8 ++++++ 6 files changed, 56 insertions(+), 14 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 263e6e3d..f0534345 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -22,6 +22,13 @@ jobs: - '3.4' - '4.0' - 'truffleruby' + minitest: + - '~> 5.11' + - '~> 6.0' + exclude: + # minitest 6 requires Ruby >= 3.2 + - ruby: '3.1' + minitest: '~> 6.0' steps: - uses: actions/checkout@v2 - name: Install deps @@ -38,6 +45,7 @@ jobs: env: SUITE: ruby REDIS_HOST: localhost + MINITEST_VERSION: ${{ matrix.minitest }} python-tests: runs-on: ubuntu-latest diff --git a/ruby/Gemfile.lock b/ruby/Gemfile.lock index 1f8e7f04..914d4c6e 100644 --- a/ruby/Gemfile.lock +++ b/ruby/Gemfile.lock @@ -38,6 +38,7 @@ GEM lint_roller (1.1.0) logger (1.7.0) minitest (5.27.0) + minitest-mock (5.27.0) minitest-reporters (1.7.1) ansi builder @@ -106,6 +107,7 @@ GEM PLATFORMS arm64-darwin-23 + arm64-darwin-24 ruby DEPENDENCIES @@ -113,7 +115,8 @@ DEPENDENCIES benchmark bundler ci-queue! - minitest (~> 5.11) + minitest (>= 5.11) + minitest-mock minitest-reporters (~> 1.1) mocha msgpack diff --git a/ruby/ci-queue.gemspec b/ruby/ci-queue.gemspec index ae55143f..eac9a1b0 100644 --- a/ruby/ci-queue.gemspec +++ b/ruby/ci-queue.gemspec @@ -35,11 +35,12 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'bundler' spec.add_development_dependency 'rake' - spec.add_development_dependency 'minitest', ENV.fetch('MINITEST_VERSION', '~> 5.11') + spec.add_development_dependency 'minitest', ENV.fetch('MINITEST_VERSION', '>= 5.11') spec.add_development_dependency 'rspec', '~> 3.10' spec.add_development_dependency 'redis' spec.add_development_dependency 'simplecov', '~> 0.12' spec.add_development_dependency 'minitest-reporters', '~> 1.1' + spec.add_development_dependency 'minitest-mock' spec.add_development_dependency 'mocha' spec.add_development_dependency 'rexml' diff --git a/ruby/lib/minitest/queue.rb b/ruby/lib/minitest/queue.rb index 5bb3755b..d7f62564 100644 --- a/ruby/lib/minitest/queue.rb +++ b/ruby/lib/minitest/queue.rb @@ -359,7 +359,7 @@ def with_timestamps def run with_timestamps do - Minitest.run_one_method(@runnable, @method_name) + @runnable.new(@method_name).run end end @@ -450,7 +450,7 @@ def run elsif skip_stale_tests? && !(runnable.method_defined?(@method_name) || runnable.private_method_defined?(@method_name)) build_stale_skip_result else - Minitest.run_one_method(runnable, @method_name) + runnable.new(@method_name).run end rescue StandardError, ScriptError => error build_error_result(error) @@ -552,6 +552,12 @@ def queue_reporters=(reporters) Reporters.use!(((Reporters.reporters || []) - @queue_reporters) + reporters) Minitest.backtrace_filter.add_filter(%r{exe/minitest-queue|lib/ci/queue/}) @queue_reporters = reporters + + # minitest 6 made plugin loading opt-in (no longer called from + # Minitest.run). Ensure minitest-reporters' plugin is loaded so + # that its DelegateReporter wires our reporters into the + # CompositeReporter that Minitest.run creates. + Minitest.load_plugins if Minitest.respond_to?(:load_plugins) end def loaded_tests @@ -562,19 +568,34 @@ def loaded_tests end end - def __run(*args) - if queue - Queue.run(*args) + # minitest 5 calls __run; minitest 6 renamed it to run_all_suites. + # Define both so the prepend intercepts whichever version is active. + %i[__run run_all_suites].each do |name| + define_method(name) do |*args| + if queue + Queue.run(*args) - if queue.config.circuit_breakers.any?(&:open?) - STDERR.puts queue.config.circuit_breakers.map(&:message).join(' ').strip - end + if queue.config.circuit_breakers.any?(&:open?) + STDERR.puts queue.config.circuit_breakers.map(&:message).join(' ').strip + end + + if queue.max_test_failed? + STDERR.puts 'This worker is exiting early because too many failed tests were encountered.' + end - if queue.max_test_failed? - STDERR.puts 'This worker is exiting early because too many failed tests were encountered.' + # minitest 6 starts a Parallel::Executor thread pool before + # calling run_all_suites, then joins those threads in shutdown + # afterward. ci-queue bypasses the executor entirely (it has + # its own Redis poll loop), so the worker threads sit idle and + # shutdown hangs forever. Drain them here so the later + # shutdown in Minitest.run is a no-op. + if Minitest.respond_to?(:parallel_executor) + executor = Minitest.parallel_executor + executor.shutdown if executor.respond_to?(:shutdown) + end + else + super(*args) end - else - super end end end diff --git a/ruby/lib/minitest/queue/runner.rb b/ruby/lib/minitest/queue/runner.rb index 2a405ff1..66e49d60 100644 --- a/ruby/lib/minitest/queue/runner.rb +++ b/ruby/lib/minitest/queue/runner.rb @@ -393,6 +393,7 @@ def run_tests_in_fork(queue) child_pid = fork do Minitest.queue = queue Minitest::Reporters.use!([Minitest::Reporters::BisectReporter.new]) + Minitest.load_plugins if Minitest.respond_to?(:load_plugins) exit # let minitest excute its at_exit end diff --git a/ruby/test/test_helper.rb b/ruby/test/test_helper.rb index b0a8ed8a..75085544 100644 --- a/ruby/test/test_helper.rb +++ b/ruby/test/test_helper.rb @@ -9,6 +9,14 @@ require 'ci/queue/redis' require 'minitest/queue' require 'minitest/autorun' + +# minitest 6 extracted mock into a separate gem +begin + require 'minitest/mock' +rescue LoadError + require 'minitest-mock' +end + require 'mocha/minitest' Minitest::Reporters.use!([Minitest::Reporters::SpecReporter.new])