208 lines
6.7 KiB
Ruby
Raw Normal View History

2020-10-10 14:16:11 +02:00
# typed: false
# frozen_string_literal: true
2019-04-17 18:25:08 +09:00
require "cli/parser"
require "fileutils"
module Homebrew
2020-10-20 12:03:48 +02:00
extend T::Sig
2016-09-26 01:44:51 +02:00
module_function
2020-10-20 12:03:48 +02:00
sig { returns(CLI::Parser) }
def tests_args
Homebrew::CLI::Parser.new do
description <<~EOS
Run Homebrew's unit and integration tests.
2018-09-28 21:39:52 +05:30
EOS
switch "--coverage",
2019-04-30 08:44:35 +01:00
description: "Generate code coverage reports."
2018-09-28 21:39:52 +05:30
switch "--generic",
2019-04-30 08:44:35 +01:00
description: "Run only OS-agnostic tests."
2018-09-28 21:39:52 +05:30
switch "--no-compat",
2019-04-30 08:44:35 +01:00
description: "Do not load the compatibility layer when running tests."
2018-09-28 21:39:52 +05:30
switch "--online",
2019-04-30 08:44:35 +01:00
description: "Include tests that use the GitHub API and tests that use any of the taps for "\
"official external commands."
2020-05-18 16:28:43 +05:30
switch "--byebug",
description: "Enable debugging using byebug."
2018-09-28 21:39:52 +05:30
flag "--only=",
2019-04-30 08:44:35 +01:00
description: "Run only <test_script>`_spec.rb`. Appending `:`<line_number> will start at a "\
"specific line."
2018-09-28 21:39:52 +05:30
flag "--seed=",
description: "Randomise tests with the specified <value> instead of a random seed."
2020-07-30 18:40:10 +02:00
2021-01-10 14:26:40 -05:00
named_args :none
end
end
2018-09-08 22:21:04 +05:30
def use_buildpulse?
return @use_buildpulse if defined?(@use_buildpulse)
@use_buildpulse = ENV["HOMEBREW_BUILDPULSE_ACCESS_KEY_ID"].present? &&
ENV["HOMEBREW_BUILDPULSE_SECRET_ACCESS_KEY"].present? &&
ENV["HOMEBREW_BUILDPULSE_ACCOUNT_ID"].present? &&
ENV["HOMEBREW_BUILDPULSE_REPOSITORY_ID"].present?
end
def run_buildpulse
require "formula"
unless Formula["buildpulse-test-reporter"].any_version_installed?
ohai "Installing `buildpulse-test-reporter` for reporting test flakiness..."
with_env(HOMEBREW_NO_AUTO_UPDATE: "1", HOMEBREW_NO_BOOTSNAP: "1") do
safe_system HOMEBREW_BREW_FILE, "install", "buildpulse-test-reporter"
end
end
ENV["BUILDPULSE_ACCESS_KEY_ID"] = ENV["HOMEBREW_BUILDPULSE_ACCESS_KEY_ID"]
ENV["BUILDPULSE_SECRET_ACCESS_KEY"] = ENV["HOMEBREW_BUILDPULSE_SECRET_ACCESS_KEY"]
ohai "Sending test results to BuildPulse"
safe_system Formula["buildpulse-test-reporter"].opt_bin/"buildpulse-test-reporter",
"submit", "#{HOMEBREW_LIBRARY_PATH}/test/junit",
"--account-id", ENV["HOMEBREW_BUILDPULSE_ACCOUNT_ID"],
"--repository-id", ENV["HOMEBREW_BUILDPULSE_REPOSITORY_ID"]
end
def tests
2020-07-30 18:40:10 +02:00
args = tests_args.parse
2018-03-25 13:18:23 +05:30
Homebrew.install_bundler_gems!(groups: ["sorbet"])
2020-05-18 16:28:43 +05:30
require "byebug" if args.byebug?
2016-10-21 08:57:39 +02:00
HOMEBREW_LIBRARY_PATH.cd do
2021-01-28 09:57:08 +00:00
# Cleanup any unwanted user configuration.
allowed_test_env = %w[
HOMEBREW_GITHUB_API_TOKEN
HOMEBREW_CACHE
HOMEBREW_LOGS
HOMEBREW_TEMP
2021-01-28 09:57:08 +00:00
]
Homebrew::EnvConfig::ENVS.keys.map(&:to_s).each do |env|
next if allowed_test_env.include?(env)
ENV.delete(env)
end
ENV["HOMEBREW_NO_ANALYTICS_THIS_RUN"] = "1"
2018-03-25 13:18:23 +05:30
ENV["HOMEBREW_NO_COMPAT"] = "1" if args.no_compat?
ENV["HOMEBREW_TEST_GENERIC_OS"] = "1" if args.generic?
ENV["HOMEBREW_TEST_ONLINE"] = "1" if args.online?
ENV["HOMEBREW_SORBET_RUNTIME"] = "1"
2017-02-28 14:33:39 +01:00
ENV["USER"] ||= system_command!("id", args: ["-nu"]).stdout.chomp
2019-04-08 12:47:15 -04:00
# Avoid local configuration messing with tests, e.g. git being configured
# to use GPG to sign by default
ENV["HOME"] = "#{HOMEBREW_LIBRARY_PATH}/test"
# Print verbose output when requesting debug or verbose output.
ENV["HOMEBREW_VERBOSE_TESTS"] = "1" if args.debug? || args.verbose?
2018-03-25 13:18:23 +05:30
if args.coverage?
ENV["HOMEBREW_TESTS_COVERAGE"] = "1"
2016-09-19 23:00:58 +01:00
FileUtils.rm_f "test/coverage/.resultset.json"
end
# Override author/committer as global settings might be invalid and thus
# will cause silent failure during the setup of dummy Git repositories.
%w[AUTHOR COMMITTER].each do |role|
ENV["GIT_#{role}_NAME"] = "brew tests"
ENV["GIT_#{role}_EMAIL"] = "brew-tests@localhost"
ENV["GIT_#{role}_DATE"] = "Sun Jan 22 19:59:13 2017 +0000"
end
2017-02-28 14:33:39 +01:00
parallel = true
2018-03-25 13:18:23 +05:30
files = if args.only
test_name, line = args.only.split(":", 2)
2017-02-28 14:33:39 +01:00
if line.nil?
Dir.glob("test/{#{test_name},#{test_name}/**/*}_spec.rb")
else
parallel = false
["test/#{test_name}_spec.rb:#{line}"]
end
else
Dir.glob("test/**/*_spec.rb")
end
parallel_rspec_log_name = "parallel_runtime_rspec"
parallel_rspec_log_name = "#{parallel_rspec_log_name}.no_compat" if args.no_compat?
parallel_rspec_log_name = "#{parallel_rspec_log_name}.generic" if args.generic?
parallel_rspec_log_name = "#{parallel_rspec_log_name}.online" if args.online?
parallel_rspec_log_name = "#{parallel_rspec_log_name}.log"
2021-04-03 19:03:35 +09:00
parallel_rspec_log_path = if ENV["CI"]
"tests/#{parallel_rspec_log_name}"
2021-04-01 23:15:51 +09:00
else
"#{HOMEBREW_CACHE}/#{parallel_rspec_log_name}"
2021-04-01 23:15:51 +09:00
end
Enhance test suite to emit JUnit XML test reports In preparation for detecting flaky tests with BuildPulse, this commit sets up the rspec_junit_formatter gem to output JUnit XML reports of the test suite, which is the format used by BuildPulse and various other tooling that interprets test results. Because the test suite uses the parallel_tests gem, this commit incorporates some related changes to make all the parallel_tests gem and the rspec_junit_formatter gem to cooperate with each other. rspec_junit_formatter writes everything to a single XML file. That works fine when there's only one process writing to the file. By default, whatever process finishes last will write to the file and clobber the output of all the other processes that wrote to the file. 🙈 To prevent this issue, the parallel_tests wiki recommends adding a `.rspec_parallel` file to specify its RSpec options (https://github.com/grosser/parallel_tests/wiki#with-rspec_junit_formatter----by-jgarber), then the project can specify different files for each process to write to like so: --format RspecJunitFormatter --out tmp/rspec<%= ENV['TEST_ENV_NUMBER'] %>.xml However, prior to this commit, the Homebrew/brew test suite specified its RSpec options via the command line. Unfortunately though, there's no way (AFAICT) to set the equivalent of these options via the command line: --format RspecJunitFormatter --out tmp/rspec<%= ENV['TEST_ENV_NUMBER'] %>.xml So, we need to use a `.rspec_parallel` file to specify these options ☝️. However, it appears that RSpec allows you to specify formatters _either_ in an options file (like `.rspec_parallel`) _or_ via command-line args. But if you specify any formatters via command-line args, then all formatters in the options file are ignored. (I suspect that's somehow related to this bit of code in rspec-core: https://github.com/rspec/rspec-core/blob/v3.10.0/lib/rspec/core/configuration_options.rb#L64.) With that in mind, in order to have the RspecJunitFormatter configured in `.rspec_parallel`, we need to move the other formatters into `.rpsec_parallel` as well, instead of passing them as command-line args. Therefore, this commit moves all the formatters into a `.rspec_parallel` file.
2021-06-21 12:58:09 -04:00
ENV["PARALLEL_RSPEC_LOG_PATH"] = parallel_rspec_log_path
2021-04-01 23:15:51 +09:00
parallel_args = if ENV["CI"]
2021-04-01 23:15:51 +09:00
%W[
--combine-stderr
--serialize-stdout
2021-04-08 20:23:50 +09:00
--runtime-log #{parallel_rspec_log_path}
]
else
%w[
--nice
]
2017-02-28 14:33:39 +01:00
end
2017-02-10 21:21:57 +01:00
# Generate seed ourselves and output later to avoid multiple different
# seeds being output when running parallel tests.
2018-06-06 23:34:19 -04:00
seed = args.seed || rand(0xFFFF).to_i
bundle_args = ["-I", HOMEBREW_LIBRARY_PATH/"test"]
bundle_args += %W[
--seed #{seed}
--color
--require spec_helper
2017-02-10 21:21:57 +01:00
]
2017-02-28 14:33:39 +01:00
unless OS.mac?
2018-08-09 15:00:19 +02:00
bundle_args << "--tag" << "~needs_macos" << "--tag" << "~cask"
files = files.grep_v(%r{^test/(os/mac|cask)(/.*|_spec\.rb)$})
end
2017-02-28 14:33:39 +01:00
2017-03-05 20:45:48 -08:00
unless OS.linux?
bundle_args << "--tag" << "~needs_linux"
files = files.grep_v(%r{^test/os/linux(/.*|_spec\.rb)$})
2017-03-05 20:45:48 -08:00
end
puts "Randomized with seed #{seed}"
# Let tests find `bundle` in the actual location.
ENV["HOMEBREW_TESTS_GEM_USER_DIR"] = gem_user_dir
# Let `bundle` in PATH find its gem.
ENV["GEM_PATH"] = "#{ENV["GEM_PATH"]}:#{gem_user_dir}"
# Submit test flakiness information using BuildPulse
# BUILDPULSE used in spec_helper.rb
if use_buildpulse?
ENV["BUILDPULSE"] = "1"
ohai "Running tests with BuildPulse-friendly settings"
end
if parallel
system "bundle", "exec", "parallel_rspec", *parallel_args, "--", *bundle_args, "--", *files
else
system "bundle", "exec", "rspec", *bundle_args, "--", *files
2017-02-28 14:33:39 +01:00
end
run_buildpulse if use_buildpulse?
return if $CHILD_STATUS.success?
2018-09-17 02:45:00 +02:00
2017-02-28 14:33:39 +01:00
Homebrew.failed = true
end
end
end