Skip to content

Commit

Permalink
tests: test on Ubuntu 18.04.
Browse files Browse the repository at this point in the history
  • Loading branch information
MikeMcQuaid authored Nov 9, 2022
1 parent d385212 commit 59f4b52
Show file tree
Hide file tree
Showing 21 changed files with 162 additions and 94 deletions.
20 changes: 6 additions & 14 deletions .devcontainer/on-create-command.sh
Original file line number Diff line number Diff line change
@@ -1,23 +1,15 @@
#!/bin/bash
set -e

# dump information variables for debugging
echo "==> env"
env | grep -v TOKEN
echo
echo "==> /etc/os-release"
cat /etc/os-release || true
echo
echo "==> /etc/lsb-release"
cat /etc/lsb-release || true
echo
echo "==> /etc/issue"
cat /etc/issue || true
echo

# fix permissions so Homebrew and Bundler don't complain
sudo chmod -R g-w,o-w /home/linuxbrew

# everything below is too slow to do unless prebuilding so skip it
if [ -z "$CODESPACES_PREBUILD_TOKEN" ]
then
exit 0
fi

# install Homebrew's development gems
brew install-bundler-gems --groups=sorbet

Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ permissions:
env:
HOMEBREW_DEVELOPER: 1
HOMEBREW_NO_AUTO_UPDATE: 1
HOMEBREW_NO_ENV_HINTS: 1

concurrency:
group: "${{ github.ref }}"
Expand Down Expand Up @@ -235,10 +236,9 @@ jobs:
- name: tests (Ubuntu 22.04)
test-flags: --online --coverage
runs-on: ubuntu-22.04
# Enable later once this can be fixed.
# - name: tests (Ubuntu 18.04)
# test-flags: --online --coverage
# runs-on: ubuntu-18.04
- name: tests (Ubuntu 18.04)
test-flags: --online --coverage
runs-on: ubuntu-18.04
steps:
- name: Set up Homebrew
id: set-up-homebrew
Expand Down
105 changes: 56 additions & 49 deletions Library/Homebrew/dev-cmd/tests.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,55 +93,7 @@ def tests
require "byebug" if args.byebug?

HOMEBREW_LIBRARY_PATH.cd do
# 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 /tmp is mounted 755 which makes Ruby warn constantly.
if (ENV["HOMEBREW_CODESPACES"] == "true") && (HOMEBREW_TEMP.to_s == "/tmp")
homebrew_prefix_tmp = "#{HOMEBREW_PREFIX}/tmp"
ENV["HOMEBREW_TEMP"] = homebrew_prefix_tmp
FileUtils.mkdir_p homebrew_prefix_tmp
system "chmod", "-R", "g-w,o-w", "/tmp"
end

ENV["HOMEBREW_NO_ANALYTICS_THIS_RUN"] = "1"
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"

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
setup_environment!(args)

parallel = true

Expand Down Expand Up @@ -237,4 +189,59 @@ def tests
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_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"

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
9 changes: 7 additions & 2 deletions Library/Homebrew/development_tools.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,17 @@ def clear_version_cache
end

sig { returns(T::Boolean) }
def build_system_too_old?
def needs_build_formulae?
needs_libc_formula? || needs_compiler_formula?
end

sig { returns(T::Boolean) }
def needs_libc_formula?
false
end

sig { returns(T::Boolean) }
def system_gcc_too_old?
def needs_compiler_formula?
false
end

Expand Down
26 changes: 20 additions & 6 deletions Library/Homebrew/extend/os/linux/dependency_collector.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,22 @@ class DependencyCollector
sig { params(related_formula_names: T::Set[String]).returns(T.nilable(Dependency)) }
def gcc_dep_if_needed(related_formula_names)
# gcc is required for libgcc_s.so.1 if glibc or gcc are too old
return unless DevelopmentTools.build_system_too_old?
return unless DevelopmentTools.needs_build_formulae?
return if building_global_dep_tree?
return if related_formula_names.include?(GCC)
return if global_dep_tree[GCC]&.intersect?(related_formula_names)
return unless formula_for(GCC)

Dependency.new(GCC)
end

sig { params(related_formula_names: T::Set[String]).returns(T.nilable(Dependency)) }
def glibc_dep_if_needed(related_formula_names)
return unless OS::Linux::Glibc.below_ci_version?
return unless DevelopmentTools.needs_libc_formula?
return if building_global_dep_tree?
return if related_formula_names.include?(GLIBC)
return if global_dep_tree[GLIBC]&.intersect?(related_formula_names)
return unless formula_for(GLIBC)

Dependency.new(GLIBC)
end
Expand All @@ -38,7 +40,7 @@ def glibc_dep_if_needed(related_formula_names)

sig { void }
def init_global_dep_tree_if_needed!
return unless DevelopmentTools.build_system_too_old?
return unless DevelopmentTools.needs_build_formulae?
return if building_global_dep_tree?
return unless global_dep_tree.empty?

Expand All @@ -49,15 +51,27 @@ def init_global_dep_tree_if_needed!
built_global_dep_tree!
end

sig { params(name: String).returns(T.nilable(Formula)) }
def formula_for(name)
@formula_for ||= {}
@formula_for[name] ||= Formula[name]
rescue FormulaUnavailableError
nil
end

sig { params(name: String).returns(T::Array[String]) }
def global_deps_for(name)
@global_deps_for ||= {}
# Always strip out glibc and gcc from all parts of dependency tree when
# we're calculating their dependency trees. Other parts of Homebrew will
# catch any circular dependencies.
@global_deps_for[name] ||= Formula[name].deps.map(&:name).flat_map do |dep|
[dep, *global_deps_for(dep)].compact
end.uniq
@global_deps_for[name] ||= if (formula = formula_for(name))
formula.deps.map(&:name).flat_map do |dep|
[dep, *global_deps_for(dep)].compact
end.uniq
else
[]
end
end

# Use class variables to avoid this expensive logic needing to be done more
Expand Down
22 changes: 13 additions & 9 deletions Library/Homebrew/extend/os/linux/development_tools.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ class << self
sig { params(tool: String).returns(T.nilable(Pathname)) }
def locate(tool)
(@locate ||= {}).fetch(tool) do |key|
@locate[key] = if build_system_too_old? &&
@locate[key] = if needs_build_formulae? &&
(binutils_path = HOMEBREW_PREFIX/"opt/binutils/bin/#{tool}").executable?
binutils_path
elsif build_system_too_old? && (glibc_path = HOMEBREW_PREFIX/"opt/glibc/bin/#{tool}").executable?
elsif needs_build_formulae? && (glibc_path = HOMEBREW_PREFIX/"opt/glibc/bin/#{tool}").executable?
glibc_path
elsif (homebrew_path = HOMEBREW_PREFIX/"bin/#{tool}").executable?
homebrew_path
Expand All @@ -27,18 +27,22 @@ def default_compiler
end

sig { returns(T::Boolean) }
def build_system_too_old?
return @build_system_too_old if defined? @build_system_too_old
def needs_libc_formula?
return @needs_libc_formula if defined? @needs_libc_formula

@build_system_too_old = (system_gcc_too_old? || OS::Linux::Glibc.below_ci_version?)
@needs_libc_formula = OS::Linux::Glibc.below_ci_version?
end

sig { returns(T::Boolean) }
def system_gcc_too_old?
gcc = "/usr/bin/gcc"
return true unless File.exist?(gcc)
def needs_compiler_formula?
return @needs_compiler_formula if defined? @needs_compiler_formula

gcc_version(gcc) < OS::LINUX_GCC_CI_VERSION
gcc = "/usr/bin/gcc"
@needs_compiler_formula = if File.exist?(gcc)
gcc_version(gcc) < OS::LINUX_GCC_CI_VERSION
else
true
end
end

sig { returns(T::Hash[String, T.nilable(String)]) }
Expand Down
2 changes: 1 addition & 1 deletion Library/Homebrew/extend/os/linux/formula.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def deuniversalize_machos(*targets); end

sig { params(spec: SoftwareSpec).void }
def add_global_deps_to_spec(spec)
return unless DevelopmentTools.build_system_too_old?
return unless DevelopmentTools.needs_build_formulae?

@global_deps ||= begin
dependency_collector = spec.dependency_collector
Expand Down
2 changes: 1 addition & 1 deletion Library/Homebrew/formula_installer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ def check_install_sanity
if Homebrew.default_prefix? &&
!build_from_source? && !build_bottle? && !formula.head? && formula.tap&.core_tap? &&
# Integration tests override homebrew-core locations
ENV["HOMEBREW_TEST_TMPDIR"].nil? &&
ENV["HOMEBREW_INTEGRATION_TEST"].nil? &&
!pour_bottle?
message = if !formula.pour_bottle? && formula.pour_bottle_check_unsatisfied_reason
formula_message = formula.pour_bottle_check_unsatisfied_reason
Expand Down
3 changes: 3 additions & 0 deletions Library/Homebrew/tap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -797,6 +797,9 @@ def self.ensure_installed!
return if instance.installed?
return if Homebrew::EnvConfig.install_from_api?

# Tests override homebrew-core locations and we don't want to auto-tap in them.
return if ENV["HOMEBREW_TESTS"]

safe_system HOMEBREW_BREW_FILE, "tap", instance.name
end

Expand Down
9 changes: 9 additions & 0 deletions Library/Homebrew/test/caveats_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ def plist
end

context "when f.service is not nil" do
before do
allow_any_instance_of(Object).to receive(:which).with("launchctl").and_return(true)
allow_any_instance_of(Object).to receive(:which).with("systemctl").and_return(true)
end

it "prints warning when no service deamon is found" do
f = formula do
url "foo-1.0"
Expand Down Expand Up @@ -259,6 +264,10 @@ def plist
let(:path) { f.prefix.resolved_path }

before do
# don't try to load/fetch gcc/glibc
allow(DevelopmentTools).to receive(:needs_libc_formula?).and_return(false)
allow(DevelopmentTools).to receive(:needs_compiler_formula?).and_return(false)

allow_any_instance_of(Pathname).to receive(:children).and_return([Pathname.new("child")])
allow_any_instance_of(Object).to receive(:which).with(any_args).and_return(Pathname.new("shell"))
allow(Utils::Shell).to receive(:preferred).and_return(nil)
Expand Down
2 changes: 1 addition & 1 deletion Library/Homebrew/test/cmd/tap-info_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
describe "brew tap-info" do
it_behaves_like "parseable arguments"

it "gets information for a given Tap", :integration_test do
it "gets information for a given Tap", :integration_test, :needs_network do
setup_test_tap

expect { brew "tap-info", "--json=v1", "--installed" }
Expand Down
3 changes: 3 additions & 0 deletions Library/Homebrew/test/dev-cmd/audit_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1202,6 +1202,9 @@ class FooAT11 < Formula
end

specify "it warns when another formula does not have a symmetric conflict" do
stub_formula_loader formula("gcc") { url "gcc-1.0" }
stub_formula_loader formula("glibc") { url "glibc-1.0" }

foo = formula("foo") do
url "https://brew.sh/foo-1.0.tgz"
end
Expand Down
4 changes: 2 additions & 2 deletions Library/Homebrew/test/formula_installer_bottle_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ def temporarily_install_bottle(formula)
expect(formula).to be_bottled
expect(formula).to pour_bottle

stub_formula_loader formula
stub_formula_loader formula("gcc") { url "gcc-1.0" }
stub_formula_loader formula("gcc@11") { url "gcc-11.0" }
stub_formula_loader formula("glibc") { url "glibc-1.0" }
stub_formula_loader formula

fi = FormulaInstaller.new(formula)
fi.fetch
Expand Down
Loading

0 comments on commit 59f4b52

Please sign in to comment.