@@ -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,43 +202,59 @@ 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 |
202- # Load files in this batch
203- batch_tests = [ ]
205+ puts "Processing batch #{ batch_num } with #{ file_batch . size } files..."
206+ # Track which file loaded which runnables
207+ runnable_to_file = { }
208+
209+ # Load all files in this batch
204210 file_batch . each do |file_path |
205211 abs_path = ::File . expand_path ( file_path )
212+ puts "Loading file #{ abs_path } ..."
206213 require abs_path
214+ puts "Finished loading file #{ abs_path } ..."
207215 @source_files_loaded . add ( abs_path )
208216 end
209217
210- # Extract tests from newly loaded files
218+ # Extract tests from runnables (call runnables only once!)
219+ # The @index.key? check automatically skips already-processed tests
220+ batch_tests = [ ]
211221 if defined? ( Minitest )
222+ puts "Extracting tests from runnables..."
212223 Minitest ::Test . runnables . each do |runnable |
213224 runnable . runnable_methods . each do |method_name |
214225 test = Minitest ::Queue ::SingleExample . new ( runnable , method_name )
215226 unless @index . key? ( test . id )
216227 batch_tests << test
217228 @index [ test . id ] = test
229+ # Map this runnable to the batch file for metadata
230+ runnable_to_file [ runnable ] ||= file_batch . first
218231 end
219232 end
220233 end
221234 end
222235
236+ puts "Found #{ batch_tests . size } new tests in batch"
237+
223238 # Shuffle tests in this batch
224239 batch_tests = Queue . shuffle ( batch_tests , random )
225-
240+ puts "Shuffled tests: #{ batch_tests . size } "
226241 unless batch_tests . empty?
227242 # Extract metadata
228243 test_ids = [ ]
229244 metadata = { }
230245
231246 batch_tests . each do |test |
232247 test_ids << test . id
233- if test . respond_to? ( :source_location ) && ( location = test . source_location )
234- metadata [ test . id ] = location [ 0 ] # file path
248+ # Use the file that loaded the runnable, not source_location
249+ if runnable_to_file . key? ( test . runnable )
250+ metadata [ test . id ] = runnable_to_file [ test . runnable ]
251+ elsif test . respond_to? ( :source_location ) && ( location = test . source_location )
252+ metadata [ test . id ] = location [ 0 ] # fallback to source_location
235253 end
236254 end
237255
238256 # Upload batch to Redis
257+ puts "Uploading batch to Redis..."
239258 with_redis_timeout ( 5 ) do
240259 redis . without_reconnect do
241260 redis . pipelined do |pipeline |
@@ -256,6 +275,8 @@ def push_files_in_batches(file_paths, random)
256275 raise
257276 end
258277
278+ puts "Finished uploading batch to Redis..."
279+
259280 tests_uploaded += test_ids . size
260281
261282 # Progress reporting
@@ -280,6 +301,16 @@ def push_files_in_batches(file_paths, random)
280301
281302 puts
282303 puts "Finished pushing #{ @total } tests to the queue in #{ duration . round ( 2 ) } s."
304+ else
305+ # Non-master workers need to load at least one test file to ensure
306+ # the test_helper (and thus minitest/autorun) is loaded, which registers
307+ # the at_exit hook needed for test execution
308+ unless file_paths . empty?
309+ first_file = file_paths . first
310+ abs_path = ::File . expand_path ( first_file )
311+ require abs_path
312+ @source_files_loaded . add ( abs_path )
313+ end
283314 end
284315
285316 register
@@ -301,6 +332,7 @@ def build_index_entry(test_id)
301332 file_path = redis . hget ( key ( 'test-metadata' ) , test_id )
302333
303334 if file_path && !@source_files_loaded . include? ( file_path )
335+ puts "Loading test file #{ file_path } ..."
304336 # Lazy load the test file
305337 require_test_file ( file_path )
306338 @source_files_loaded . add ( file_path )
@@ -339,7 +371,7 @@ def find_test_object(test_id)
339371 end
340372
341373 # 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"
374+ puts "Warning: Test #{ test_id } not found after loading file. Ensure all dependencies are explicitly required in test_helper.rb"
343375 # Return nil and let index.fetch handle the KeyError
344376 nil
345377 end
0 commit comments