From 9f10965b5f9f7cdcdad1884a27986b09b389ce35 Mon Sep 17 00:00:00 2001 From: Stephen Anderson Date: Thu, 3 Sep 2026 20:56:01 +1000 Subject: [PATCH 1/2] Generate temp spec file names independently of the global PRNG minitest 5.16 added `srand Minitest.seed` to Test.runnable_methods, which runs once per suite, so from that version on the global PRNG replays the same sequence at the start of every describe block. command_line_interface_spec's write_file built its file name from Digest::MD5.hexdigest(rand.to_s), so specs in different describe blocks were handed the same name. The second `require` of that path does nothing - it is already in $LOADED_FEATURES - so LOADED_FILES never gets an entry for it and the assertions on it fail. Which specs collide moves around with the seed, so the failures read as flakes rather than as a bug. Under minitest 5.25 every one of six seeds tried produced between one and three of them. SecureRandom is not affected by srand. --- spec/que/command_line_interface_spec.rb | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/spec/que/command_line_interface_spec.rb b/spec/que/command_line_interface_spec.rb index 7ee69c31..7e1350ed 100644 --- a/spec/que/command_line_interface_spec.rb +++ b/spec/que/command_line_interface_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -require 'digest/md5' +require 'securerandom' require 'que/command_line_interface' describe Que::CommandLineInterface do @@ -93,7 +93,13 @@ def write_file # same files will result in spec failures. So instead just generate a new # file name for each spec to write/delete. - name = "spec/temp/file_#{Digest::MD5.hexdigest(rand.to_s)}" + # This can't use Kernel#rand, because minitest 5.16 and up call + # `srand Minitest.seed` before shuffling each suite's methods, so the + # global PRNG replays the same sequence once per describe block. Two specs + # in different blocks would then be given the same file name, and the + # second `require` of it does nothing - the path is already in + # $LOADED_FEATURES - leaving LOADED_FILES without an entry for it. + name = "spec/temp/file_#{SecureRandom.hex(16)}" written_files << name File.open("#{name}.rb", 'w') { |f| f.puts %(LOADED_FILES["#{name}"] = true) } name From 5a71fa89ab6b4f54762e02d45ba17d57c0c608b8 Mon Sep 17 00:00:00 2001 From: Stephen Anderson Date: Thu, 3 Sep 2026 20:56:09 +1000 Subject: [PATCH 2/2] Support Ruby 3.4 Ruby 3.4 removed mutex_m from the standard library. minitest 5.10.1 requires it, so the suite could not even load. minitest 5.25 has no such dependency and still supports Ruby 2.7, so the one pin covers the whole matrix. Ruby 3.4 also changed Hash#inspect to render symbol keys as {key: 1} rather than {:key=>1}. listener_spec hardcoded the old rendering of a hash that Que::Listener inspects into an error message; deriving the expectation with #inspect instead makes it hold either way. Adds Ruby 3.3 and 3.4 to CI, against Rails 7.2 only - the older Rails gemfiles are already excluded from the newer Rubies they don't support. --- .github/workflows/tests.yml | 2 ++ Gemfile | 2 +- spec/gemfiles/Gemfile-rails-6.0 | 2 +- spec/gemfiles/Gemfile-rails-6.1 | 2 +- spec/gemfiles/Gemfile-rails-7.0 | 2 +- spec/gemfiles/Gemfile-rails-7.1 | 2 +- spec/gemfiles/Gemfile-rails-7.2 | 2 +- spec/que/listener_spec.rb | 7 +++++-- 8 files changed, 13 insertions(+), 8 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1842dce3..b0f474ac 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -18,6 +18,8 @@ jobs: - { ruby_version: '3.2', rails_gemfile: '7.2', postgres_version: '12' } - { ruby_version: '3.2', rails_gemfile: '7.2', postgres_version: '13' } - { ruby_version: '3.2', rails_gemfile: '7.2', postgres_version: '14' } + - { ruby_version: '3.3', rails_gemfile: '7.2', postgres_version: '14' } + - { ruby_version: '3.4', rails_gemfile: '7.2', postgres_version: '14' } exclude: # Rails 7.2 is not compatible with Ruby < 3.1 - ruby_version: '2.7' rails_gemfile: '7.2' diff --git a/Gemfile b/Gemfile index eeec1ae1..401e8274 100644 --- a/Gemfile +++ b/Gemfile @@ -17,7 +17,7 @@ group :development, :test do end group :test do - gem 'minitest', '~> 5.10.1' + gem 'minitest', '~> 5.25.0' gem 'minitest-profile', '0.0.2' gem 'minitest-hooks', '1.4.0' gem 'minitest-fail-fast', '0.1.0' diff --git a/spec/gemfiles/Gemfile-rails-6.0 b/spec/gemfiles/Gemfile-rails-6.0 index 9bcb0dbb..9aa92fac 100644 --- a/spec/gemfiles/Gemfile-rails-6.0 +++ b/spec/gemfiles/Gemfile-rails-6.0 @@ -15,7 +15,7 @@ group :development, :test do end group :test do - gem 'minitest', '~> 5.10.1' + gem 'minitest', '~> 5.25.0' gem 'minitest-profile', '0.0.2' gem 'minitest-hooks', '1.4.0' gem 'pry' diff --git a/spec/gemfiles/Gemfile-rails-6.1 b/spec/gemfiles/Gemfile-rails-6.1 index 7a3d2828..13908e56 100644 --- a/spec/gemfiles/Gemfile-rails-6.1 +++ b/spec/gemfiles/Gemfile-rails-6.1 @@ -15,7 +15,7 @@ group :development, :test do end group :test do - gem 'minitest', '~> 5.10.1' + gem 'minitest', '~> 5.25.0' gem 'minitest-profile', '0.0.2' gem 'minitest-hooks', '1.4.0' gem 'pry' diff --git a/spec/gemfiles/Gemfile-rails-7.0 b/spec/gemfiles/Gemfile-rails-7.0 index b40936de..c8aedb5f 100644 --- a/spec/gemfiles/Gemfile-rails-7.0 +++ b/spec/gemfiles/Gemfile-rails-7.0 @@ -15,7 +15,7 @@ group :development, :test do end group :test do - gem 'minitest', '~> 5.10.1' + gem 'minitest', '~> 5.25.0' gem 'minitest-profile', '0.0.2' gem 'minitest-hooks', '1.4.0' gem 'pry' diff --git a/spec/gemfiles/Gemfile-rails-7.1 b/spec/gemfiles/Gemfile-rails-7.1 index 2da7475c..d3999640 100644 --- a/spec/gemfiles/Gemfile-rails-7.1 +++ b/spec/gemfiles/Gemfile-rails-7.1 @@ -15,7 +15,7 @@ group :development, :test do end group :test do - gem 'minitest', '~> 5.10.1' + gem 'minitest', '~> 5.25.0' gem 'minitest-profile', '0.0.2' gem 'minitest-hooks', '1.4.0' gem 'pry' diff --git a/spec/gemfiles/Gemfile-rails-7.2 b/spec/gemfiles/Gemfile-rails-7.2 index 1caa4180..3550e0aa 100644 --- a/spec/gemfiles/Gemfile-rails-7.2 +++ b/spec/gemfiles/Gemfile-rails-7.2 @@ -15,7 +15,7 @@ group :development, :test do end group :test do - gem 'minitest', '~> 5.10.1' + gem 'minitest', '~> 5.25.0' gem 'minitest-profile', '0.0.2' gem 'minitest-hooks', '1.4.0' gem 'pry' diff --git a/spec/que/listener_spec.rb b/spec/que/listener_spec.rb index ddfe37b0..4adad4e3 100644 --- a/spec/que/listener_spec.rb +++ b/spec/que/listener_spec.rb @@ -273,10 +273,13 @@ def assert_message_ignored assert_instance_of Que::Error, error + # Inspected rather than written out, so that the expectation holds on + # Rubies that inspect hashes differently - 3.4 prints {priority: 90} + # where earlier versions print {:priority=>90}. expected_message = [ "Message of type 'job_available' doesn't match format!", - "Message: {:priority=>90, :queue=>\"queue_name\", :run_at=>\"2017-06-30T18:33:35.425307Z\"}", - "Format: {:id=>Integer, :priority=>Integer, :queue=>String, :run_at=>/\\A\\d{4}\\-\\d{2}\\-\\d{2}T\\d{2}:\\d{2}:\\d{2}.\\d{6}Z\\z/}", + "Message: #{{priority: 90, queue: "queue_name", run_at: "2017-06-30T18:33:35.425307Z"}.inspect}", + "Format: #{{id: Integer, priority: Integer, queue: String, run_at: /\A\d{4}\-\d{2}\-\d{2}T\d{2}:\d{2}:\d{2}.\d{6}Z\z/}.inspect}", ].join("\n") assert_equal expected_message, error.message