diff --git a/lib/rspecq/worker.rb b/lib/rspecq/worker.rb index a999698..540e6b9 100644 --- a/lib/rspecq/worker.rb +++ b/lib/rspecq/worker.rb @@ -162,39 +162,32 @@ def try_publish_queue!(queue) puts "Published queue (size=#{queue.publish(jobs)})" end + # Split a list of spec files into their individual examples. + # # NOTE: RSpec has to load the files before we can split them as individual # examples. In case a file to be splitted fails to be loaded # (e.g. contains a syntax error), we return the files unchanged, thereby # falling back to scheduling them as whole files. Their errors will be # reported in the normal flow when they're eventually picked up by a worker. def files_to_example_ids(files) - cmd = "DISABLE_SPRING=1 bundle exec rspec --dry-run --format json #{files.join(' ')} 2>&1" - out = `#{cmd}` - cmd_result = $? - - if !cmd_result.success? - rspec_output = begin - JSON.parse(out) - rescue JSON::ParserError - out - end - - log_event( - "Failed to split slow files, falling back to regular scheduling", - "error", - rspec_output: rspec_output, - cmd_result: cmd_result.inspect, - ) + out = StringIO.new - pp rspec_output + reset_rspec_state! - return files - end - - JSON.parse(out)["examples"].map { |e| e["id"] } + RSpec.configuration.add_formatter(RSpec::Core::Formatters::JsonFormatter.new(out)) + RSpec.configuration.files_or_directories_to_run = files_or_dirs_to_run + RSpec.configuration.dry_run = true + + opts = RSpec::Core::ConfigurationOptions.new(files) + result = RSpec::Core::Runner.new(opts).run($stderr, $stdout) + return files if result != 0 + JSON.parse(out.string)["examples"].map { |e| e["id"] } + ensure + RSpec.configuration.dry_run = false + # clear formatters + reset_rspec_state! end - private def reset_rspec_state! diff --git a/test/test_worker.rb b/test/test_worker.rb index 146fc82..b9884b8 100644 --- a/test/test_worker.rb +++ b/test/test_worker.rb @@ -18,7 +18,7 @@ def test_files_to_example_ids ] ) - assert_equal expected, actual + assert_equal expected.sort, actual.sort end def test_files_to_example_ids_failure_fallback @@ -36,6 +36,6 @@ def test_files_to_example_ids_failure_fallback ] ) - assert_equal expected, actual + assert_equal expected.sort, actual.sort end end