Skip to content

Commit 6f394ff

Browse files
authored
Merge pull request rails#50197 from Shopify/testing-isolation-crash
ActiveSupport::Testing::Isolation: gracefully handle the subprocess dying
2 parents 139c567 + b07362c commit 6f394ff

File tree

1 file changed

+17
-7
lines changed

1 file changed

+17
-7
lines changed

activesupport/lib/active_support/testing/isolation.rb

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ module Testing
55
module Isolation
66
require "thread"
77

8+
SubprocessCrashed = Class.new(StandardError)
9+
810
def self.included(klass) # :nodoc:
911
klass.class_eval do
1012
parallelize_me!
@@ -16,10 +18,17 @@ def self.forking_env?
1618
end
1719

1820
def run
19-
serialized = run_in_isolation do
21+
status, serialized = run_in_isolation do
2022
super
2123
end
2224

25+
unless status&.success?
26+
error = SubprocessCrashed.new("Subprocess exited with an error: #{status.inspect}\noutput: #{serialized.inspect}")
27+
error.set_backtrace(caller)
28+
self.failures << Minitest::UnexpectedError.new(error)
29+
return defined?(Minitest::Result) ? Minitest::Result.from(self) : dup
30+
end
31+
2332
Marshal.load(serialized)
2433
end
2534

@@ -50,13 +59,13 @@ def run_in_isolation(&blk)
5059
end
5160

5261
write.puts [result].pack("m")
53-
exit!
62+
exit!(0)
5463
end
5564

5665
write.close
5766
result = read.read
58-
Process.wait2(pid)
59-
result.unpack1("m")
67+
_, status = Process.wait2(pid)
68+
return status, result.unpack1("m")
6069
end
6170
end
6271
end
@@ -75,7 +84,7 @@ def run_in_isolation(&blk)
7584
File.open(ENV["ISOLATION_OUTPUT"], "w") do |file|
7685
file.puts [Marshal.dump(test_result)].pack("m")
7786
end
78-
exit!
87+
exit!(0)
7988
else
8089
Tempfile.open("isolation") do |tmpfile|
8190
env = {
@@ -93,13 +102,14 @@ def run_in_isolation(&blk)
93102

94103
child = IO.popen([env, Gem.ruby, *load_path_args, $0, *ORIG_ARGV, test_opts])
95104

105+
status = nil
96106
begin
97-
Process.wait(child.pid)
107+
_, status = Process.wait2(child.pid)
98108
rescue Errno::ECHILD # The child process may exit before we wait
99109
nil
100110
end
101111

102-
return tmpfile.read.unpack1("m")
112+
return status, tmpfile.read.unpack1("m")
103113
end
104114
end
105115
end

0 commit comments

Comments
 (0)