Merge pull request #19684 from Homebrew/bundle-exec-tests
bundle: add tests for `exec --services`
This commit is contained in:
commit
e42c792fe3
@ -191,13 +191,22 @@ module Homebrew
|
|||||||
[entry, formula]
|
[entry, formula]
|
||||||
end.to_h
|
end.to_h
|
||||||
|
|
||||||
|
conflicts = entries_formulae.to_h do |entry, formula|
|
||||||
|
[
|
||||||
|
entry,
|
||||||
|
(
|
||||||
|
formula.versioned_formulae_names +
|
||||||
|
formula.conflicts.map(&:name) +
|
||||||
|
Array(entry.options[:conflicts_with])
|
||||||
|
).uniq,
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
# The formula + everything that could possible conflict with the service
|
# The formula + everything that could possible conflict with the service
|
||||||
names_to_query = entries_formulae.flat_map do |entry, formula|
|
names_to_query = entries_formulae.flat_map do |entry, formula|
|
||||||
[
|
[
|
||||||
formula.name,
|
formula.name,
|
||||||
*formula.versioned_formulae_names,
|
*conflicts.fetch(entry),
|
||||||
*formula.conflicts.map(&:name),
|
|
||||||
*entry.options[:conflicts_with],
|
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -227,7 +236,7 @@ module Homebrew
|
|||||||
conflicting_services = services_info.select do |candidate|
|
conflicting_services = services_info.select do |candidate|
|
||||||
next unless candidate["running"]
|
next unless candidate["running"]
|
||||||
|
|
||||||
formula.versioned_formulae_names.include?(candidate["name"])
|
conflicts.fetch(entry).include?(candidate["name"])
|
||||||
end
|
end
|
||||||
|
|
||||||
raise "Failed to get service info for #{entry.name}" if info.nil?
|
raise "Failed to get service info for #{entry.name}" if info.nil?
|
||||||
|
@ -71,9 +71,11 @@ RSpec.describe Homebrew::Bundle::BrewServices do
|
|||||||
version: "1.0",
|
version: "1.0",
|
||||||
rack: HOMEBREW_CELLAR/"fooformula",
|
rack: HOMEBREW_CELLAR/"fooformula",
|
||||||
plist_name: "homebrew.mxcl.fooformula",
|
plist_name: "homebrew.mxcl.fooformula",
|
||||||
|
service_name: "fooformula",
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
shared_examples "returns the versioned service file" do
|
||||||
it "returns the versioned service file" do
|
it "returns the versioned service file" do
|
||||||
expect(Formula).to receive(:[]).with(foo.name).and_return(foo)
|
expect(Formula).to receive(:[]).with(foo.name).and_return(foo)
|
||||||
expect(Homebrew::Bundle).to receive(:formula_versions_from_env).and_return(foo.name => foo.version)
|
expect(Homebrew::Bundle).to receive(:formula_versions_from_env).and_return(foo.name => foo.version)
|
||||||
@ -82,12 +84,32 @@ RSpec.describe Homebrew::Bundle::BrewServices do
|
|||||||
allow(FileTest).to receive(:directory?).and_call_original
|
allow(FileTest).to receive(:directory?).and_call_original
|
||||||
expect(FileTest).to receive(:directory?).with(prefix.to_s).and_return(true)
|
expect(FileTest).to receive(:directory?).with(prefix.to_s).and_return(true)
|
||||||
|
|
||||||
service_file = prefix/"#{foo.plist_name}.plist"
|
service_file = prefix/service_basename
|
||||||
expect(Homebrew::Services::System).to receive(:launchctl?).and_return(true)
|
|
||||||
allow(FileTest).to receive(:file?).and_call_original
|
allow(FileTest).to receive(:file?).and_call_original
|
||||||
expect(FileTest).to receive(:file?).with(service_file.to_s).and_return(true)
|
expect(FileTest).to receive(:file?).with(service_file.to_s).and_return(true)
|
||||||
|
|
||||||
expect(described_class.versioned_service_file(foo.name)).to eq(service_file)
|
expect(described_class.versioned_service_file(foo.name)).to eq(service_file)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "with launchctl" do
|
||||||
|
before do
|
||||||
|
allow(Homebrew::Services::System).to receive(:launchctl?).and_return(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:service_basename) { "#{foo.plist_name}.plist" }
|
||||||
|
|
||||||
|
include_examples "returns the versioned service file"
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with systemd" do
|
||||||
|
before do
|
||||||
|
allow(Homebrew::Services::System).to receive(:launchctl?).and_return(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:service_basename) { "#{foo.service_name}.service" }
|
||||||
|
|
||||||
|
include_examples "returns the versioned service file"
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
require "bundle"
|
require "bundle"
|
||||||
require "bundle/commands/exec"
|
require "bundle/commands/exec"
|
||||||
|
require "bundle/brewfile"
|
||||||
|
require "bundle/brew_services"
|
||||||
|
|
||||||
RSpec.describe Homebrew::Bundle::Commands::Exec do
|
RSpec.describe Homebrew::Bundle::Commands::Exec do
|
||||||
context "when a Brewfile is not found" do
|
context "when a Brewfile is not found" do
|
||||||
@ -124,5 +126,142 @@ RSpec.describe Homebrew::Bundle::Commands::Exec do
|
|||||||
described_class.run("/usr/bin/true")
|
described_class.run("/usr/bin/true")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "--services" do
|
||||||
|
let(:brewfile_contents) { "brew 'nginx'\nbrew 'redis'" }
|
||||||
|
|
||||||
|
let(:nginx_formula) do
|
||||||
|
instance_double(
|
||||||
|
Formula,
|
||||||
|
name: "nginx",
|
||||||
|
any_version_installed?: true,
|
||||||
|
any_installed_prefix: HOMEBREW_PREFIX/"opt/nginx",
|
||||||
|
plist_name: "homebrew.mxcl.nginx",
|
||||||
|
service_name: "nginx",
|
||||||
|
versioned_formulae_names: [],
|
||||||
|
conflicts: [instance_double(FormulaConflict, name: "httpd")],
|
||||||
|
keg_only?: false,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:redis_formula) do
|
||||||
|
instance_double(
|
||||||
|
Formula,
|
||||||
|
name: "redis",
|
||||||
|
any_version_installed?: true,
|
||||||
|
any_installed_prefix: HOMEBREW_PREFIX/"opt/redis",
|
||||||
|
plist_name: "homebrew.mxcl.redis",
|
||||||
|
service_name: "redis",
|
||||||
|
versioned_formulae_names: ["redis@6.2"],
|
||||||
|
conflicts: [],
|
||||||
|
keg_only?: false,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:services_info_pre) do
|
||||||
|
[
|
||||||
|
{ "name" => "nginx", "running" => true, "loaded" => true },
|
||||||
|
{ "name" => "httpd", "running" => true, "loaded" => true },
|
||||||
|
{ "name" => "redis", "running" => false, "loaded" => false },
|
||||||
|
{ "name" => "redis@6.2", "running" => true, "loaded" => true, "registered" => true },
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:services_info_post) do
|
||||||
|
[
|
||||||
|
{ "name" => "nginx", "running" => true, "loaded" => true },
|
||||||
|
{ "name" => "httpd", "running" => false, "loaded" => false },
|
||||||
|
{ "name" => "redis", "running" => true, "loaded" => true },
|
||||||
|
{ "name" => "redis@6.2", "running" => false, "loaded" => false, "registered" => true },
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
stub_formula_loader(nginx_formula, "nginx")
|
||||||
|
stub_formula_loader(redis_formula, "redis")
|
||||||
|
|
||||||
|
pkgconf = formula("pkgconf") { url "pkgconf-1.0" }
|
||||||
|
stub_formula_loader(pkgconf)
|
||||||
|
allow(pkgconf).to receive(:any_version_installed?).and_return(false)
|
||||||
|
|
||||||
|
allow_any_instance_of(Pathname).to receive(:file?).and_return(true)
|
||||||
|
|
||||||
|
allow(described_class).to receive(:exit!).and_return(nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
shared_examples "handles service lifecycle correctly" do
|
||||||
|
it "handles service lifecycle correctly" do
|
||||||
|
# The order of operations is important. This unweildly looking test is so it tests that.
|
||||||
|
|
||||||
|
# Return original service state
|
||||||
|
expect(Utils).to receive(:safe_popen_read)
|
||||||
|
.with(HOMEBREW_BREW_FILE, "services", "info", "--json", "nginx", "httpd", "redis", "redis@6.2")
|
||||||
|
.and_return(services_info_pre.to_json)
|
||||||
|
|
||||||
|
# Stop original nginx
|
||||||
|
expect(Homebrew::Bundle::BrewServices).to receive(:stop)
|
||||||
|
.with("nginx", keep: true).and_return(true).ordered
|
||||||
|
|
||||||
|
# Stop nginx conflicts
|
||||||
|
expect(Homebrew::Bundle::BrewServices).to receive(:stop)
|
||||||
|
.with("httpd", keep: true).and_return(true).ordered
|
||||||
|
|
||||||
|
# Start new nginx
|
||||||
|
expect(Homebrew::Bundle::BrewServices).to receive(:run)
|
||||||
|
.with("nginx", file: nginx_service_file).and_return(true).ordered
|
||||||
|
|
||||||
|
# No need to stop original redis (not started)
|
||||||
|
|
||||||
|
# Stop redis conflicts
|
||||||
|
expect(Homebrew::Bundle::BrewServices).to receive(:stop)
|
||||||
|
.with("redis@6.2", keep: true).and_return(true).ordered
|
||||||
|
|
||||||
|
# Start new redis
|
||||||
|
expect(Homebrew::Bundle::BrewServices).to receive(:run)
|
||||||
|
.with("redis", file: redis_service_file).and_return(true).ordered
|
||||||
|
|
||||||
|
# Run exec commands
|
||||||
|
expect(Kernel).to receive(:system).with("/usr/bin/true").and_return(true).ordered
|
||||||
|
|
||||||
|
# Return new service state
|
||||||
|
expect(Utils).to receive(:safe_popen_read)
|
||||||
|
.with(HOMEBREW_BREW_FILE, "services", "info", "--json", "nginx", "httpd", "redis", "redis@6.2")
|
||||||
|
.and_return(services_info_post.to_json)
|
||||||
|
|
||||||
|
# Stop new services
|
||||||
|
expect(Homebrew::Bundle::BrewServices).to receive(:stop)
|
||||||
|
.with("nginx", keep: true).and_return(true).ordered
|
||||||
|
expect(Homebrew::Bundle::BrewServices).to receive(:stop)
|
||||||
|
.with("redis", keep: true).and_return(true).ordered
|
||||||
|
|
||||||
|
# Restart registered services we stopped due to conflicts (skip httpd as not registered)
|
||||||
|
expect(Homebrew::Bundle::BrewServices).to receive(:run).with("redis@6.2").and_return(true).ordered
|
||||||
|
|
||||||
|
described_class.run("/usr/bin/true", services: true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with launchctl" do
|
||||||
|
before do
|
||||||
|
allow(Homebrew::Services::System).to receive(:launchctl?).and_return(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:nginx_service_file) { nginx_formula.any_installed_prefix/"#{nginx_formula.plist_name}.plist" }
|
||||||
|
let(:redis_service_file) { redis_formula.any_installed_prefix/"#{redis_formula.plist_name}.plist" }
|
||||||
|
|
||||||
|
include_examples "handles service lifecycle correctly"
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with systemd" do
|
||||||
|
before do
|
||||||
|
allow(Homebrew::Services::System).to receive(:launchctl?).and_return(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:nginx_service_file) { nginx_formula.any_installed_prefix/"#{nginx_formula.service_name}.service" }
|
||||||
|
let(:redis_service_file) { redis_formula.any_installed_prefix/"#{redis_formula.service_name}.service" }
|
||||||
|
|
||||||
|
include_examples "handles service lifecycle correctly"
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user