Module: Minitest::Queue

Extended by:
CI::Queue::OutputHelpers
Defined in:
lib/minitest/queue.rb,
lib/minitest/queue/runner.rb,
lib/minitest/queue/statsd.rb,
lib/minitest/queue/test_data.rb,
lib/minitest/queue/error_report.rb,
lib/minitest/queue/grind_recorder.rb,
lib/minitest/queue/grind_reporter.rb,
lib/minitest/queue/junit_reporter.rb,
lib/minitest/queue/failure_formatter.rb,
lib/minitest/queue/test_data_reporter.rb,
lib/minitest/queue/test_time_recorder.rb,
lib/minitest/queue/test_time_reporter.rb,
lib/minitest/queue/lazy_entry_resolver.rb,
lib/minitest/queue/lazy_test_discovery.rb,
lib/minitest/queue/build_status_recorder.rb,
lib/minitest/queue/build_status_reporter.rb,
lib/minitest/queue/local_requeue_reporter.rb,
lib/minitest/queue/worker_profile_reporter.rb,
lib/minitest/queue/queue_population_strategy.rb

Defined Under Namespace

Classes: BuildStatusRecorder, BuildStatusReporter, ErrorReport, FailureFormatter, GrindRecorder, GrindReporter, JUnitReporter, LazyEntryResolver, LazySingleExample, LazyTestDiscovery, LocalRequeueReporter, OrderReporter, QueuePopulationStrategy, Runner, SingleExample, Statsd, TestData, TestDataReporter, TestTimeRecorder, TestTimeReporter, WorkerProfileReporter

Constant Summary collapse

DEFAULT_RUN_COMMAND_FORMATTER =
lambda do |runnable|
  filename = Minitest::Queue.relative_path(runnable.source_location[0])
  identifier = "#{runnable.klass}##{runnable.name}"
  ['bundle', 'exec', 'ruby', '-Ilib:test', filename, '-n', identifier]
end
RAILS_RUN_COMMAND_FORMATTER =
lambda do |runnable|
  filename = Minitest::Queue.relative_path(runnable.source_location[0])
  lineno = runnable.source_location[1]
  ['bin/rails', 'test', "#{filename}:#{lineno}"]
end

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#project_root=(value) ⇒ Object (writeonly)

Sets the attribute project_root

Parameters:

  • the value to set the attribute project_root to.



116
117
118
# File 'lib/minitest/queue.rb', line 116

def project_root=(value)
  @project_root = value
end

#queueObject

Returns the value of attribute queue.



539
540
541
# File 'lib/minitest/queue.rb', line 539

def queue
  @queue
end

#run_command_formatterObject



118
119
120
121
122
123
124
# File 'lib/minitest/queue.rb', line 118

def run_command_formatter
  @run_command_formatter ||= if defined?(Rails) && defined?(Rails::TestUnitRailtie)
    RAILS_RUN_COMMAND_FORMATTER
  else
    DEFAULT_RUN_COMMAND_FORMATTER
  end
end

Class Method Details

.handle_test_result(reporter, example, result) ⇒ Object



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/minitest/queue.rb', line 181

def handle_test_result(reporter, example, result)
  if result.respond_to?(:queue_id=)
    result.queue_id = example.id
    result.queue_entry = example.queue_entry if result.respond_to?(:queue_entry=)
  end

  failed = !(result.passed? || result.skipped?)

  if example.flaky?
    result.mark_as_flaked!
    failed = false
  end

  if failed && queue.config.failing_test && queue.config.failing_test != example.id
    # When we do a bisect, we don't care about the result other than the test we're running the bisect on
    result.mark_as_flaked!
    failed = false
  end

  if failed && CI::Queue.requeueable?(result) && queue.requeue(example.queue_entry)
    result.requeue!
    if CI::Queue.debug?
      $stderr.puts "[ci-queue][requeue] test_id=#{example.id} error_class=#{result.failures.first&.class} error=#{result.failures.first&.message&.lines&.first&.chomp}"
    end
  elsif failed
    queue.report_failure!
  else
    queue.report_success!
  end
  reporter.record(result)
end

.project_rootObject



147
148
149
# File 'lib/minitest/queue.rb', line 147

def self.project_root
  @project_root ||= Dir.pwd
end

.queueObject



158
159
160
# File 'lib/minitest/queue.rb', line 158

def queue
  Minitest.queue
end

.relative_path(path, root: project_root) ⇒ Object



151
152
153
154
155
# File 'lib/minitest/queue.rb', line 151

def self.relative_path(path, root: project_root)
  Pathname(path).relative_path_from(Pathname(root)).to_s
rescue ArgumentError, TypeError
  path
end

.run(reporter) ⇒ Object



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/minitest/queue.rb', line 162

def run(reporter, *)
  rescue_run_errors do
    begin
      queue.poll do |example|
        result = queue.with_heartbeat(example.queue_entry) do
          example.run
        end

        handle_test_result(reporter, example, result)
      end

      report_load_stats(queue)
    ensure
      store_worker_profile(queue)
      queue.stop_heartbeat!
    end
  end
end

Instance Method Details

#__run(*args) ⇒ Object



556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
# File 'lib/minitest/queue.rb', line 556

def __run(*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.max_test_failed?
      STDERR.puts 'This worker is exiting early because too many failed tests were encountered.'
    end
  else
    super
  end
end

#loaded_testsObject



548
549
550
551
552
553
554
# File 'lib/minitest/queue.rb', line 548

def loaded_tests
  Minitest::Test.runnables.flat_map do |runnable|
    runnable.runnable_methods.map do |method_name|
      SingleExample.new(runnable, method_name)
    end
  end
end

#queue_reporters=(reporters) ⇒ Object



541
542
543
544
545
546
# File 'lib/minitest/queue.rb', line 541

def queue_reporters=(reporters)
  @queue_reporters ||= []
  Reporters.use!(((Reporters.reporters || []) - @queue_reporters) + reporters)
  Minitest.backtrace_filter.add_filter(%r{exe/minitest-queue|lib/ci/queue/})
  @queue_reporters = reporters
end

#run_command_for_runnable(runnable) ⇒ Object



138
139
140
141
142
143
144
145
# File 'lib/minitest/queue.rb', line 138

def run_command_for_runnable(runnable)
  command = run_command_formatter.call(runnable)
  if command.is_a?(Array)
    Shellwords.join(command)
  else
    command
  end
end