@@ -9,6 +9,11 @@ class LongRunningSchmoozer < Schmooze::Base
99 # This method keeps the Node.js process running with a setTimeout
1010 # Even after stdin is closed, the process will wait for the timeout
1111 method :echo , 'function(x) { setTimeout(() => {}, 60000); return x; }'
12+
13+ # Expose the finalizer for testing
14+ def self . create_finalizer ( owner_pid , stdin , stdout , stderr , process_thread )
15+ finalize ( owner_pid , stdin , stdout , stderr , process_thread )
16+ end
1217 end
1318
1419 # Test that the finalizer does not hang when the process is still running.
@@ -21,19 +26,23 @@ class LongRunningSchmoozer < Schmooze::Base
2126 # The fix uses `Process.kill(:KILL, pid)` to actually terminate the process
2227 # before waiting for it.
2328 def test_finalizer_does_not_hang
24- finalizer = nil
25- pid = nil
29+ # Create a schmoozer and get its internal state
30+ schmoozer = LongRunningSchmoozer . new ( __dir__ )
31+ schmoozer . echo ( "test" )
32+ pid = schmoozer . pid
2633
27- # Capture the finalizer without letting it run automatically
28- ObjectSpace . stub :define_finalizer , proc { | _s , p | finalizer = p } do
29- schmoozer = LongRunningSchmoozer . new ( __dir__ )
30- schmoozer . echo ( "test" )
31- pid = schmoozer . pid
34+ # Get the internal process data
35+ stdin = schmoozer . instance_variable_get ( :@_schmooze_stdin )
36+ stdout = schmoozer . instance_variable_get ( :@_schmooze_stdout )
37+ stderr = schmoozer . instance_variable_get ( :@_schmooze_stderr )
38+ process_thread = schmoozer . instance_variable_get ( :@_schmooze_process_thread )
3239
33- # Verify the process is running
34- assert pid , "Process should be running"
35- Process . kill ( 0 , pid ) # Should not raise if process is running
36- end
40+ # Create a finalizer manually (simulating what ObjectSpace.define_finalizer does)
41+ finalizer = LongRunningSchmoozer . create_finalizer ( Process . pid , stdin , stdout , stderr , process_thread )
42+
43+ # Verify the process is running
44+ assert pid , "Process should be running"
45+ Process . kill ( 0 , pid ) # Should not raise if process is running
3746
3847 # Run the finalizer with a timeout to detect hanging
3948 assert_raises_nothing_within ( 5 ) do
@@ -50,17 +59,24 @@ def test_finalizer_does_not_hang
5059 # This tests the scenario where GC.stress is enabled and many instances
5160 # are created and garbage collected.
5261 def test_finalizer_handles_multiple_instances_under_gc_pressure
53- pids = [ ]
62+ instances = [ ]
5463 finalizers = [ ]
5564
56- ObjectSpace . stub :define_finalizer , proc { |_s , p | finalizers << p } do
57- 5 . times do
58- schmoozer = LongRunningSchmoozer . new ( __dir__ )
59- schmoozer . echo ( "test" )
60- pids << schmoozer . pid
61- end
65+ 5 . times do
66+ schmoozer = LongRunningSchmoozer . new ( __dir__ )
67+ schmoozer . echo ( "test" )
68+
69+ stdin = schmoozer . instance_variable_get ( :@_schmooze_stdin )
70+ stdout = schmoozer . instance_variable_get ( :@_schmooze_stdout )
71+ stderr = schmoozer . instance_variable_get ( :@_schmooze_stderr )
72+ process_thread = schmoozer . instance_variable_get ( :@_schmooze_process_thread )
73+
74+ instances << { schmoozer : schmoozer , pid : schmoozer . pid }
75+ finalizers << LongRunningSchmoozer . create_finalizer ( Process . pid , stdin , stdout , stderr , process_thread )
6276 end
6377
78+ pids = instances . map { |i | i [ :pid ] }
79+
6480 assert_equal 5 , pids . length
6581 assert_equal 5 , finalizers . length
6682
@@ -81,14 +97,17 @@ def test_finalizer_handles_multiple_instances_under_gc_pressure
8197 def test_finalizer_is_fork_safe
8298 skip "Fork not available on this platform" unless Process . respond_to? ( :fork )
8399
84- finalizer = nil
85- pid = nil
100+ schmoozer = LongRunningSchmoozer . new ( __dir__ )
101+ schmoozer . echo ( "test" )
102+ pid = schmoozer . pid
86103
87- ObjectSpace . stub :define_finalizer , proc { |_s , p | finalizer = p } do
88- schmoozer = LongRunningSchmoozer . new ( __dir__ )
89- schmoozer . echo ( "test" )
90- pid = schmoozer . pid
91- end
104+ stdin = schmoozer . instance_variable_get ( :@_schmooze_stdin )
105+ stdout = schmoozer . instance_variable_get ( :@_schmooze_stdout )
106+ stderr = schmoozer . instance_variable_get ( :@_schmooze_stderr )
107+ process_thread = schmoozer . instance_variable_get ( :@_schmooze_process_thread )
108+
109+ # Create finalizer with parent's PID
110+ finalizer = LongRunningSchmoozer . create_finalizer ( Process . pid , stdin , stdout , stderr , process_thread )
92111
93112 # Fork and try to run finalizer in child
94113 child_pid = fork do
0 commit comments