bundle: add tests for exec --services
This commit is contained in:
parent
b4ae6f5513
commit
4254b75cb8
@ -191,13 +191,22 @@ module Homebrew
|
||||
[entry, formula]
|
||||
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
|
||||
names_to_query = entries_formulae.flat_map do |entry, formula|
|
||||
[
|
||||
formula.name,
|
||||
*formula.versioned_formulae_names,
|
||||
*formula.conflicts.map(&:name),
|
||||
*entry.options[:conflicts_with],
|
||||
*conflicts.fetch(entry),
|
||||
]
|
||||
end
|
||||
|
||||
@ -227,7 +236,7 @@ module Homebrew
|
||||
conflicting_services = services_info.select do |candidate|
|
||||
next unless candidate["running"]
|
||||
|
||||
formula.versioned_formulae_names.include?(candidate["name"])
|
||||
conflicts.fetch(entry).include?(candidate["name"])
|
||||
end
|
||||
|
||||
raise "Failed to get service info for #{entry.name}" if info.nil?
|
||||
|
@ -67,27 +67,49 @@ RSpec.describe Homebrew::Bundle::BrewServices do
|
||||
let(:foo) do
|
||||
instance_double(
|
||||
Formula,
|
||||
name: "fooformula",
|
||||
version: "1.0",
|
||||
rack: HOMEBREW_CELLAR/"fooformula",
|
||||
plist_name: "homebrew.mxcl.fooformula",
|
||||
name: "fooformula",
|
||||
version: "1.0",
|
||||
rack: HOMEBREW_CELLAR/"fooformula",
|
||||
plist_name: "homebrew.mxcl.fooformula",
|
||||
service_name: "fooformula",
|
||||
)
|
||||
end
|
||||
|
||||
it "returns the versioned service file" do
|
||||
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)
|
||||
shared_examples "returns the versioned service file" do
|
||||
it "returns the versioned service file" do
|
||||
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)
|
||||
|
||||
prefix = foo.rack/"1.0"
|
||||
allow(FileTest).to receive(:directory?).and_call_original
|
||||
expect(FileTest).to receive(:directory?).with(prefix.to_s).and_return(true)
|
||||
prefix = foo.rack/"1.0"
|
||||
allow(FileTest).to receive(:directory?).and_call_original
|
||||
expect(FileTest).to receive(:directory?).with(prefix.to_s).and_return(true)
|
||||
|
||||
service_file = prefix/"#{foo.plist_name}.plist"
|
||||
expect(Homebrew::Services::System).to receive(:launchctl?).and_return(true)
|
||||
allow(FileTest).to receive(:file?).and_call_original
|
||||
expect(FileTest).to receive(:file?).with(service_file.to_s).and_return(true)
|
||||
service_file = prefix/service_basename
|
||||
allow(FileTest).to receive(:file?).and_call_original
|
||||
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
|
||||
|
||||
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
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
require "bundle"
|
||||
require "bundle/commands/exec"
|
||||
require "bundle/brewfile"
|
||||
require "bundle/brew_services"
|
||||
|
||||
RSpec.describe Homebrew::Bundle::Commands::Exec 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")
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user