forked from Homebrew/brew
-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
tests.rb
258 lines (209 loc) 路 8.33 KB
/
tests.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
# typed: true
# frozen_string_literal: true
require "cli/parser"
require "fileutils"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def tests_args
Homebrew::CLI::Parser.new do
description <<~EOS
Run Homebrew's unit and integration tests.
EOS
switch "--coverage",
description: "Generate code coverage reports."
switch "--generic",
description: "Run only OS-agnostic tests."
switch "--online",
description: "Include tests that use the GitHub API and tests that use any of the taps for " \
"official external commands."
switch "--byebug",
description: "Enable debugging using byebug."
switch "--changed",
description: "Only runs tests on files that were changed from the master branch."
flag "--only=",
description: "Run only <test_script>`_spec.rb`. Appending `:`<line_number> will start at a " \
"specific line."
flag "--seed=",
description: "Randomise tests with the specified <value> instead of a random seed."
conflicts "--changed", "--only"
named_args :none
end
end
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"
with_env(HOMEBREW_NO_AUTO_UPDATE: "1", HOMEBREW_NO_BOOTSNAP: "1") do
ensure_formula_installed!("buildpulse-test-reporter",
reason: "reporting test flakiness")
end
ENV["BUILDPULSE_ACCESS_KEY_ID"] = ENV.fetch("HOMEBREW_BUILDPULSE_ACCESS_KEY_ID")
ENV["BUILDPULSE_SECRET_ACCESS_KEY"] = ENV.fetch("HOMEBREW_BUILDPULSE_SECRET_ACCESS_KEY")
ohai "Sending test results to BuildPulse"
system_command Formula["buildpulse-test-reporter"].opt_bin/"buildpulse-test-reporter",
args: [
"submit", "#{HOMEBREW_LIBRARY_PATH}/test/junit",
"--account-id", ENV.fetch("HOMEBREW_BUILDPULSE_ACCOUNT_ID"),
"--repository-id", ENV.fetch("HOMEBREW_BUILDPULSE_REPOSITORY_ID")
]
end
def changed_test_files
changed_files = Utils.popen_read("git", "diff", "--name-only", "master")
raise UsageError, "No files have been changed from the master branch!" if changed_files.blank?
filestub_regex = %r{Library/Homebrew/([\w/-]+).rb}
changed_files.scan(filestub_regex).map(&:last).map do |filestub|
if filestub.start_with?("test/")
# Only run tests on *_spec.rb files in test/ folder
filestub.end_with?("_spec") ? Pathname("#{filestub}.rb") : nil
else
# For all other changed .rb files guess the associated test file name
Pathname("test/#{filestub}_spec.rb")
end
end.compact.select(&:exist?)
end
def tests
args = tests_args.parse
Homebrew.install_bundler_gems!(groups: ["prof"])
require "byebug" if args.byebug?
HOMEBREW_LIBRARY_PATH.cd do
setup_environment!(args)
parallel = true
files = if args.only
test_name, line = args.only.split(":", 2)
if line.nil?
Dir.glob("test/{#{test_name},#{test_name}/**/*}_spec.rb")
else
parallel = false
["test/#{test_name}_spec.rb:#{line}"]
end
elsif args.changed?
changed_test_files
else
Dir.glob("test/**/*_spec.rb")
end
if files.blank?
raise UsageError, "The `--only` argument requires a valid file or folder name!" if args.only
if args.changed?
opoo "No tests are directly associated with the changed files!"
return
end
end
parallel_rspec_log_name = "parallel_runtime_rspec"
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"
parallel_rspec_log_path = if ENV["CI"]
"tests/#{parallel_rspec_log_name}"
else
"#{HOMEBREW_CACHE}/#{parallel_rspec_log_name}"
end
ENV["PARALLEL_RSPEC_LOG_PATH"] = parallel_rspec_log_path
parallel_args = if ENV["CI"]
%W[
--combine-stderr
--serialize-stdout
--runtime-log #{parallel_rspec_log_path}
]
else
%w[
--nice
]
end
# Generate seed ourselves and output later to avoid multiple different
# seeds being output when running parallel tests.
seed = args.seed || rand(0xFFFF).to_i
bundle_args = ["-I", HOMEBREW_LIBRARY_PATH/"test"]
bundle_args += %W[
--seed #{seed}
--color
--require spec_helper
]
# TODO: Refactor and move to extend/os
# rubocop:disable Homebrew/MoveToExtendOS
unless OS.mac?
bundle_args << "--tag" << "~needs_macos" << "--tag" << "~cask"
files = files.grep_v(%r{^test/(os/mac|cask)(/.*|_spec\.rb)$})
end
unless OS.linux?
bundle_args << "--tag" << "~needs_linux"
files = files.grep_v(%r{^test/os/linux(/.*|_spec\.rb)$})
end
# rubocop:enable Homebrew/MoveToExtendOS
bundle_args << "--tag" << "~needs_network" unless args.online?
unless ENV["CI"]
bundle_args << "--tag" << "~needs_ci" \
<< "--tag" << "~needs_svn"
end
puts "Randomized with seed #{seed}"
# 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
end
success = $CHILD_STATUS.success?
run_buildpulse if use_buildpulse?
return if success
Homebrew.failed = true
end
end
def setup_environment!(args)
# Cleanup any unwanted user configuration.
allowed_test_env = %w[
HOMEBREW_GITHUB_API_TOKEN
HOMEBREW_CACHE
HOMEBREW_LOGS
HOMEBREW_TEMP
HOMEBREW_USE_RUBY_FROM_PATH
]
Homebrew::EnvConfig::ENVS.keys.map(&:to_s).each do |env|
next if allowed_test_env.include?(env)
ENV.delete(env)
end
# Codespaces HOMEBREW_PREFIX and /tmp are mounted 755 which makes Ruby warn constantly.
if (ENV["HOMEBREW_CODESPACES"] == "true") && (HOMEBREW_TEMP.to_s == "/tmp")
# Need to keep this fairly short to avoid socket paths being too long in tests.
homebrew_prefix_tmp = "/home/linuxbrew/tmp"
ENV["HOMEBREW_TEMP"] = homebrew_prefix_tmp
FileUtils.mkdir_p homebrew_prefix_tmp
system "chmod", "-R", "g-w,o-w", HOMEBREW_PREFIX, homebrew_prefix_tmp
end
ENV["HOMEBREW_TESTS"] = "1"
ENV["HOMEBREW_NO_AUTO_UPDATE"] = "1"
ENV["HOMEBREW_NO_ANALYTICS_THIS_RUN"] = "1"
ENV["HOMEBREW_TEST_GENERIC_OS"] = "1" if args.generic?
ENV["HOMEBREW_TEST_ONLINE"] = "1" if args.online?
ENV["HOMEBREW_SORBET_RUNTIME"] = "1"
# TODO: remove this and fix tests when possible.
ENV["HOMEBREW_NO_INSTALL_FROM_API"] = "1"
ENV["USER"] ||= system_command!("id", args: ["-nu"]).stdout.chomp
# 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?
if args.coverage?
ENV["HOMEBREW_TESTS_COVERAGE"] = "1"
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
end
end