Skip to content

Commit 9786cc0

Browse files
committed
wip
1 parent 33fc116 commit 9786cc0

6 files changed

Lines changed: 61 additions & 1068 deletions

File tree

ruby/Rakefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Rake::TestTask.new(:test) do |t|
88
t.libs << 'lib'
99
selected_files = ENV["TEST_FILES"].to_s.strip.split(/\s+/)
1010
selected_files = nil if selected_files.empty?
11-
t.test_files = selected_files || FileList['test/**/*_test.rb'] - FileList['test/fixtures/**/*_test.rb']
11+
t.test_files = selected_files || FileList['test/integration/minitest_redis_test.rb'] - FileList['test/fixtures/**/*_test.rb']
1212
end
1313

1414
task :default => :test

ruby/lib/ci/queue/redis/base.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,13 @@ def custom_middlewares
105105
end
106106

107107
def exhausted?
108-
queue_initialized? && size == 0
108+
# In batch upload mode, don't consider the queue exhausted while streaming
109+
# The master is still uploading tests, so workers should wait/retry
110+
if config.batch_upload && master_status == 'streaming'
111+
false
112+
else
113+
queue_initialized? && size == 0
114+
end
109115
end
110116

111117
def expired?

ruby/lib/ci/queue/redis/worker.rb

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ def master?
6565

6666
def poll
6767
wait_for_master
68+
# Non-master workers need to fetch total from Redis after master finishes
69+
@total ||= redis.get(key('total')).to_i unless master?
70+
puts "Starting poll loop, master: #{master?}"
6871
attempt = 0
6972
until shutdown_required? || config.circuit_breakers.any?(&:open?) || exhausted? || max_test_failed?
7073
if test_id = reserve
@@ -199,12 +202,28 @@ def push_files_in_batches(file_paths, random)
199202
attempts = 0
200203
duration = measure do
201204
file_paths.each_slice(files_per_batch).with_index do |file_batch, batch_num|
205+
puts "Processing batch #{batch_num} of #{file_batch.size} files..."
206+
# Track which file loaded which runnables
207+
runnable_to_file = {}
208+
202209
# Load files in this batch
203210
batch_tests = []
204211
file_batch.each do |file_path|
205212
abs_path = ::File.expand_path(file_path)
213+
214+
# Track runnables before loading
215+
runnables_before = defined?(Minitest) ? Minitest::Test.runnables.dup : []
216+
206217
require abs_path
207218
@source_files_loaded.add(abs_path)
219+
220+
# Track which new runnables came from this file
221+
if defined?(Minitest)
222+
new_runnables = Minitest::Test.runnables - runnables_before
223+
new_runnables.each do |runnable|
224+
runnable_to_file[runnable] = abs_path
225+
end
226+
end
208227
end
209228

210229
# Extract tests from newly loaded files
@@ -230,8 +249,11 @@ def push_files_in_batches(file_paths, random)
230249

231250
batch_tests.each do |test|
232251
test_ids << test.id
233-
if test.respond_to?(:source_location) && (location = test.source_location)
234-
metadata[test.id] = location[0] # file path
252+
# Use the file that loaded the runnable, not source_location
253+
if runnable_to_file.key?(test.runnable)
254+
metadata[test.id] = runnable_to_file[test.runnable]
255+
elsif test.respond_to?(:source_location) && (location = test.source_location)
256+
metadata[test.id] = location[0] # fallback to source_location
235257
end
236258
end
237259

@@ -280,6 +302,16 @@ def push_files_in_batches(file_paths, random)
280302

281303
puts
282304
puts "Finished pushing #{@total} tests to the queue in #{duration.round(2)}s."
305+
else
306+
# Non-master workers need to load at least one test file to ensure
307+
# the test_helper (and thus minitest/autorun) is loaded, which registers
308+
# the at_exit hook needed for test execution
309+
unless file_paths.empty?
310+
first_file = file_paths.first
311+
abs_path = ::File.expand_path(first_file)
312+
require abs_path
313+
@source_files_loaded.add(abs_path)
314+
end
283315
end
284316

285317
register
@@ -301,6 +333,7 @@ def build_index_entry(test_id)
301333
file_path = redis.hget(key('test-metadata'), test_id)
302334

303335
if file_path && !@source_files_loaded.include?(file_path)
336+
puts "Loading test file #{file_path}..."
304337
# Lazy load the test file
305338
require_test_file(file_path)
306339
@source_files_loaded.add(file_path)
@@ -339,7 +372,7 @@ def find_test_object(test_id)
339372
end
340373

341374
# Fallback: create a test object that will report an error
342-
warn "Warning: Test #{test_id} not found after loading file. Ensure all dependencies are explicitly required in test_helper.rb"
375+
puts "Warning: Test #{test_id} not found after loading file. Ensure all dependencies are explicitly required in test_helper.rb"
343376
# Return nil and let index.fetch handle the KeyError
344377
nil
345378
end

ruby/lib/minitest/queue.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ def loaded_tests
289289

290290
def __run(*args)
291291
if queue
292+
puts "------- Running tests #{queue.config.worker_id}"
292293
Queue.run(*args)
293294

294295
if queue.config.circuit_breakers.any?(&:open?)

ruby/test/fixtures/test/dummy_test.rb

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,10 @@
22
require 'test_helper'
33

44
class ATest < Minitest::Test
5-
def test_foo
6-
skip
7-
end
8-
9-
def test_bar
10-
assert false
11-
end
125

13-
def test_flaky
14-
if defined?(@@already_ran) && @@already_ran
6+
1000.times do |i|
7+
define_method("test_dummy_#{i}") do
158
assert true
16-
else
17-
@@already_ran = true
18-
assert false
199
end
2010
end
21-
22-
def test_flaky_fails_retry
23-
assert false
24-
end
25-
26-
def test_flaky_passes
27-
assert true
28-
end
29-
end
30-
31-
class BTest < Minitest::Test
32-
def test_foo
33-
assert true
34-
end
35-
36-
def test_bar
37-
1 + '1'
38-
end
3911
end

0 commit comments

Comments
 (0)