128 lines
3.6 KiB
Ruby
Raw Normal View History

2021-09-11 01:00:23 +01:00
# typed: true
# frozen_string_literal: true
2014-06-19 17:57:36 -05:00
require "extend/ENV"
2015-04-13 18:05:41 +08:00
require "sandbox"
require "timeout"
2019-04-17 18:25:08 +09:00
require "cli/parser"
module Homebrew
2016-09-26 01:44:51 +02:00
module_function
2020-10-20 12:03:48 +02:00
sig { returns(CLI::Parser) }
def test_args
Homebrew::CLI::Parser.new do
description <<~EOS
Run the test method provided by an installed formula.
There is no standard output or return code, but generally it should notify the
user if something is wrong with the installed formula.
*Example:* `brew install jruby && brew test jruby`
EOS
2021-03-18 14:46:48 +00:00
switch "-f", "--force",
description: "Test formulae even if they are unlinked."
switch "--HEAD",
2019-04-30 08:44:35 +01:00
description: "Test the head version of a formula."
switch "--keep-tmp",
description: "Retain the temporary files created for the test."
switch "--retry",
description: "Retry if a testing fails."
2020-07-30 18:40:10 +02:00
2021-01-10 14:26:40 -05:00
named_args :installed_formula, min: 1
end
end
2011-03-10 21:28:49 -08:00
def test
2020-07-30 18:40:10 +02:00
args = test_args.parse
Homebrew.install_bundler_gems!(setup_path: false)
require "formula_assertions"
require "formula_free_port"
args.named.to_resolved_formulae.each do |f|
2011-03-10 21:28:49 -08:00
# Cannot test uninstalled formulae
unless f.latest_version_installed?
2015-05-27 21:14:35 +08:00
ofail "Testing requires the latest version of #{f.full_name}"
2011-03-10 21:28:49 -08:00
next
end
# Cannot test formulae without a test method
2013-01-07 17:34:56 -06:00
unless f.test_defined?
2015-05-27 21:14:35 +08:00
ofail "#{f.full_name} defines no test"
2011-03-10 21:28:49 -08:00
next
end
# Don't test unlinked formulae
if !args.force? && !f.keg_only? && !f.linked?
ofail "#{f.full_name} is not linked"
next
end
# Don't test formulae missing test dependencies
missing_test_deps = f.recursive_dependencies do |_, dependency|
Dependency.prune if dependency.installed?
next if dependency.test?
2018-09-17 02:45:00 +02:00
Dependency.prune if dependency.optional?
Dependency.prune if dependency.build?
end.map(&:to_s)
unless missing_test_deps.empty?
ofail "#{f.full_name} is missing test dependencies: #{missing_test_deps.join(" ")}"
next
end
oh1 "Testing #{f.full_name}"
env = ENV.to_hash
2011-03-10 21:28:49 -08:00
begin
exec_args = HOMEBREW_RUBY_EXEC_ARGS + %W[
2015-04-13 18:05:41 +08:00
--
#{HOMEBREW_LIBRARY_PATH}/test.rb
#{f.path}
].concat(args.options_only)
2015-04-13 18:05:41 +08:00
exec_args << "--HEAD" if f.head?
2015-04-13 18:05:41 +08:00
Utils.safe_fork do
if Sandbox.available?
2015-04-13 18:05:41 +08:00
sandbox = Sandbox.new
2015-04-26 21:59:47 -04:00
f.logs.mkpath
2016-05-27 01:53:08 -04:00
sandbox.record_log(f.logs/"test.sandbox.log")
2015-04-13 18:05:41 +08:00
sandbox.allow_write_temp_and_cache
sandbox.allow_write_log(f)
sandbox.allow_write_xcode
sandbox.allow_write_path(HOMEBREW_PREFIX/"var/cache")
sandbox.allow_write_path(HOMEBREW_PREFIX/"var/homebrew/locks")
sandbox.allow_write_path(HOMEBREW_PREFIX/"var/log")
sandbox.allow_write_path(HOMEBREW_PREFIX/"var/run")
sandbox.exec(*exec_args)
2015-04-13 18:05:41 +08:00
else
exec(*exec_args)
2015-04-13 18:05:41 +08:00
end
2013-06-04 20:34:34 +01:00
end
rescue Exception => e # rubocop:disable Lint/RescueException
2020-07-31 19:45:18 +02:00
retry if retry_test?(f, args: args)
ofail "#{f.full_name}: failed"
$stderr.puts e, e.backtrace
ensure
ENV.replace(env)
2011-03-10 21:28:49 -08:00
end
end
end
def retry_test?(formula, args:)
@test_failed ||= Set.new
if args.retry? && @test_failed.add?(formula)
oh1 "Testing #{formula.full_name} (again)"
formula.clear_cache
ENV["RUST_BACKTRACE"] = "full"
true
else
Homebrew.failed = true
false
end
end
2011-03-10 21:28:49 -08:00
end