diff --git a/tool/lib/test/unit.rb b/tool/lib/test/unit.rb index 7d43e825e1..4614a0f321 100644 --- a/tool/lib/test/unit.rb +++ b/tool/lib/test/unit.rb @@ -789,11 +789,11 @@ module Test unless rep.empty? rep.each do |r| if r[:error] - puke(*r[:error], Timeout::Error.new) + puke(*r[:error], Timeout::Error.new, r[:file]) next end r[:report]&.each do |f| - puke(*f) if f + puke(*f, r[:file]) if f end end if @options[:retry] @@ -1396,7 +1396,36 @@ module Test end module LaunchableOption - module Nothing + module Runner + def puke(klass, meth, e, file=nil) + if writer = options[:launchable_test_reports] + # # Since `record` method is not called when a timeout occurs while waiting for the worker's response, we need to capture it here. + if file && e.is_a?(Timeout::Error) + status = 'TEST_FAILED' + e = "Timeout:\n#{klass}##{meth}\n" + full_path = File.expand_path(file) + repo_path = File.expand_path("#{__dir__}/../../../") + relative_path = full_path.delete_prefix("#{repo_path}/") + # The test path is a URL-encoded representation. + # https://github.com/launchableinc/cli/blob/v1.81.0/launchable/testpath.py#L18 + test_path = {file: relative_path, class: klass, testcase: meth}.map{|key, val| + "#{encode_test_path_component(key)}=#{encode_test_path_component(val)}" + }.join('#') + writer.write_object( + { + testPath: test_path, + status: status, + duration: options[:worker_timeout], + createdAt: Time.now.to_s, + stderr: e, + stdout: nil + } + ) + end + end + super + end + private def setup_options(opts, options) super @@ -1422,9 +1451,6 @@ module Test when Test::Unit::AssertionFailedError status = 'TEST_FAILED' "Failure:\n#{suite.name}##{method} [#{location error}]:\n#{error.message}\n" - when Timeout::Error - status = 'TEST_FAILED' - "Timeout:\n#{suite.name}##{method}\n" else status = 'TEST_FAILED' bt = Test::filter_backtrace(error.backtrace).join "\n " @@ -1802,7 +1828,7 @@ module Test prepend Test::Unit::ExcludesOption prepend Test::Unit::TimeoutOption prepend Test::Unit::RunCount - prepend Test::Unit::LaunchableOption::Nothing + prepend Test::Unit::LaunchableOption::Runner ## # Begins the full test run. Delegates to +runner+'s #_run method. @@ -1828,7 +1854,7 @@ module Test alias orig_run_suite _run_suite # Overriding of Test::Unit::Runner#puke - def puke klass, meth, e + def puke klass, meth, e, file=nil n = report.size e = case e when Test::Unit::PendedError then diff --git a/tool/lib/test/unit/parallel.rb b/tool/lib/test/unit/parallel.rb index 188a0d1a19..4accf930c1 100644 --- a/tool/lib/test/unit/parallel.rb +++ b/tool/lib/test/unit/parallel.rb @@ -167,7 +167,7 @@ module Test abort("#{e.inspect} in _report(#{res.inspect}, #{args.inspect})\n#{e.backtrace.join("\n")}") end - def puke(klass, meth, e) # :nodoc: + def puke(klass, meth, e, file=nil) # :nodoc: if e.is_a?(Test::Unit::PendedError) new_e = Test::Unit::PendedError.new(e.message) new_e.set_backtrace(e.backtrace)