mirror of
https://github.com/Homebrew/brew.git
synced 2025-07-14 16:09:03 +08:00
321 lines
12 KiB
Ruby
321 lines
12 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "services/cli"
|
|
require "services/system"
|
|
require "services/formula_wrapper"
|
|
|
|
RSpec.describe Homebrew::Services::Cli do
|
|
subject(:services_cli) { described_class }
|
|
|
|
let(:service_string) { "service" }
|
|
|
|
describe "#bin" do
|
|
it "outputs command name" do
|
|
expect(services_cli.bin).to eq("brew services")
|
|
end
|
|
end
|
|
|
|
describe "#running" do
|
|
it "macOS - returns the currently running services" do
|
|
allow(Homebrew::Services::System).to receive_messages(launchctl?: true, systemctl?: false)
|
|
allow(Utils).to receive(:popen_read).and_return <<~EOS
|
|
77513 50 homebrew.mxcl.php
|
|
495 0 homebrew.mxcl.node_exporter
|
|
1234 34 homebrew.mxcl.postgresql@14
|
|
EOS
|
|
expect(services_cli.running).to eq([
|
|
"homebrew.mxcl.php",
|
|
"homebrew.mxcl.node_exporter",
|
|
"homebrew.mxcl.postgresql@14",
|
|
])
|
|
end
|
|
|
|
it "systemD - returns the currently running services" do
|
|
allow(Homebrew::Services::System).to receive(:launchctl?).and_return(false)
|
|
allow(Homebrew::Services::System::Systemctl).to receive(:popen_read).and_return <<~EOS
|
|
homebrew.php.service loaded active running Homebrew PHP service
|
|
systemd-udevd.service loaded active running Rule-based Manager for Device Events and Files
|
|
udisks2.service loaded active running Disk Manager
|
|
user@1000.service loaded active running User Manager for UID 1000
|
|
EOS
|
|
expect(services_cli.running).to eq(["homebrew.php.service"])
|
|
end
|
|
end
|
|
|
|
describe "#check" do
|
|
it "checks the input does not exist" do
|
|
expect do
|
|
services_cli.check([])
|
|
end.to raise_error(UsageError, "Invalid usage: Formula(e) missing, please provide a formula name or use --all")
|
|
end
|
|
|
|
it "checks the input exists" do
|
|
expect do
|
|
services_cli.check("hello")
|
|
end.not_to raise_error(UsageError,
|
|
"Invalid usage: Formula(e) missing, please provide a formula name or use --all")
|
|
end
|
|
end
|
|
|
|
describe "#kill_orphaned_services" do
|
|
it "skips unmanaged services" do
|
|
allow(services_cli).to receive(:running).and_return(["example_service"])
|
|
expect do
|
|
services_cli.kill_orphaned_services
|
|
end.to output("Warning: Service example_service not managed by `brew services` => skipping\n").to_stderr
|
|
end
|
|
|
|
it "tries but is unable to kill a non existing service" do
|
|
service = instance_double(
|
|
service_string,
|
|
name: "example_service",
|
|
pid?: true,
|
|
dest: Pathname("this_path_does_not_exist"),
|
|
keep_alive?: false,
|
|
)
|
|
allow(service).to receive(:service_name)
|
|
allow(service).to receive(:reset_cache!)
|
|
allow(Homebrew::Services::FormulaWrapper).to receive(:from).and_return(service)
|
|
allow(services_cli).to receive(:running).and_return(["example_service"])
|
|
expect do
|
|
services_cli.kill_orphaned_services
|
|
end.to output("Killing `example_service`... (might take a while)\n").to_stdout
|
|
end
|
|
end
|
|
|
|
describe "#run" do
|
|
it "checks missing file causes error" do
|
|
expect(Homebrew::Services::System).not_to receive(:root?)
|
|
expect do
|
|
services_cli.start(["service_name"], "/non/existent/path")
|
|
end.to raise_error(UsageError, "Invalid usage: Provided service file does not exist")
|
|
end
|
|
|
|
it "checks empty targets cause no error" do
|
|
expect(Homebrew::Services::System).not_to receive(:root?)
|
|
services_cli.run([])
|
|
end
|
|
|
|
it "checks if target service is already running and suggests restart instead" do
|
|
expected_output = "Service `example_service` already running, " \
|
|
"use `brew services restart example_service` to restart.\n"
|
|
service = instance_double(service_string, name: "example_service", pid?: true)
|
|
expect do
|
|
services_cli.run([service])
|
|
end.to output(expected_output).to_stdout
|
|
end
|
|
end
|
|
|
|
describe "#start" do
|
|
it "checks missing file causes error" do
|
|
expect(Homebrew::Services::System).not_to receive(:root?)
|
|
expect do
|
|
services_cli.start(["service_name"], "/hfdkjshksdjhfkjsdhf/fdsjghsdkjhb")
|
|
end.to raise_error(UsageError, "Invalid usage: Provided service file does not exist")
|
|
end
|
|
|
|
it "checks empty targets cause no error" do
|
|
expect(Homebrew::Services::System).not_to receive(:root?)
|
|
services_cli.start([])
|
|
end
|
|
|
|
it "checks if target service has already been started and suggests restart instead" do
|
|
expected_output = "Service `example_service` already started, " \
|
|
"use `brew services restart example_service` to restart.\n"
|
|
service = instance_double(service_string, name: "example_service", pid?: true)
|
|
expect do
|
|
services_cli.start([service])
|
|
end.to output(expected_output).to_stdout
|
|
end
|
|
end
|
|
|
|
describe "#stop" do
|
|
it "checks empty targets cause no error" do
|
|
expect(Homebrew::Services::System).not_to receive(:root?)
|
|
services_cli.stop([])
|
|
end
|
|
end
|
|
|
|
describe "#kill" do
|
|
it "checks empty targets cause no error" do
|
|
expect(Homebrew::Services::System).not_to receive(:root?)
|
|
services_cli.kill([])
|
|
end
|
|
|
|
it "prints a message if service is not running" do
|
|
expected_output = "Service `example_service` is not started.\n"
|
|
service = instance_double(service_string, name: "example_service", pid?: false)
|
|
expect do
|
|
services_cli.kill([service])
|
|
end.to output(expected_output).to_stdout
|
|
end
|
|
|
|
it "prints a message if service is set to keep alive" do
|
|
expected_output = "Service `example_service` is set to automatically restart and can't be killed.\n"
|
|
service = instance_double(service_string, name: "example_service", pid?: true, keep_alive?: true)
|
|
expect do
|
|
services_cli.kill([service])
|
|
end.to output(expected_output).to_stdout
|
|
end
|
|
end
|
|
|
|
describe "#install_service_file" do
|
|
it "checks service is installed" do
|
|
service = instance_double(Homebrew::Services::FormulaWrapper, name: "name", installed?: false)
|
|
expect do
|
|
services_cli.install_service_file(service, nil)
|
|
end.to raise_error(UsageError, "Invalid usage: Formula `name` is not installed")
|
|
end
|
|
|
|
it "checks service file exists" do
|
|
service = instance_double(
|
|
Homebrew::Services::FormulaWrapper,
|
|
name: "name",
|
|
installed?: true,
|
|
service_file: instance_double(Pathname, exist?: false),
|
|
)
|
|
expect do
|
|
services_cli.install_service_file(service, nil)
|
|
end.to raise_error(
|
|
UsageError,
|
|
"Invalid usage: Formula `name` has not implemented #plist, #service or installed a locatable service file",
|
|
)
|
|
end
|
|
end
|
|
|
|
describe "#systemd_load", :needs_linux do
|
|
it "checks non-enabling run" do
|
|
expect(Homebrew::Services::System::Systemctl).to receive(:run).once.and_return(true)
|
|
services_cli.systemd_load(
|
|
instance_double(Homebrew::Services::FormulaWrapper, service_name: "name"),
|
|
enable: false,
|
|
)
|
|
end
|
|
|
|
it "checks enabling run" do
|
|
expect(Homebrew::Services::System::Systemctl).to receive(:run).twice.and_return(true)
|
|
services_cli.systemd_load(
|
|
instance_double(Homebrew::Services::FormulaWrapper, service_name: "name"),
|
|
enable: true,
|
|
)
|
|
end
|
|
end
|
|
|
|
describe "#launchctl_load", :needs_macos do
|
|
it "checks non-enabling run" do
|
|
allow(Homebrew::Services::System).to receive(:launchctl).and_return(Pathname.new("/bin/launchctl"))
|
|
expect(Homebrew::Services::System).to receive(:domain_target).once.and_return("target")
|
|
expect(described_class).to receive(:safe_system).once.and_return(true)
|
|
services_cli.launchctl_load(instance_double(Homebrew::Services::FormulaWrapper), file: "a", enable: false)
|
|
end
|
|
|
|
it "checks enabling run" do
|
|
allow(Homebrew::Services::System).to receive(:launchctl).and_return(Pathname.new("/bin/launchctl"))
|
|
expect(Homebrew::Services::System).to receive(:domain_target).twice.and_return("target")
|
|
expect(described_class).to receive(:safe_system).twice.and_return(true)
|
|
services_cli.launchctl_load(instance_double(Homebrew::Services::FormulaWrapper, service_name: "name"),
|
|
file: "a",
|
|
enable: true)
|
|
end
|
|
end
|
|
|
|
describe "#service_load" do
|
|
it "checks non-root for login" do
|
|
expect(Homebrew::Services::System).to receive(:launchctl?).once.and_return(false)
|
|
expect(Homebrew::Services::System).to receive(:systemctl?).once.and_return(false)
|
|
expect(Homebrew::Services::System).to receive(:root?).once.and_return(true)
|
|
|
|
expect do
|
|
services_cli.service_load(
|
|
instance_double(
|
|
Homebrew::Services::FormulaWrapper,
|
|
name: "name",
|
|
service_name: "service.name",
|
|
service_startup?: false,
|
|
),
|
|
nil,
|
|
enable: false,
|
|
)
|
|
end.to output("==> Successfully ran `name` (label: service.name)\n").to_stdout
|
|
end
|
|
|
|
it "checks root for startup" do
|
|
expect(Homebrew::Services::System).to receive(:launchctl?).once.and_return(false)
|
|
expect(Homebrew::Services::System).to receive(:systemctl?).once.and_return(false)
|
|
expect(Homebrew::Services::System).to receive(:root?).twice.and_return(false)
|
|
expect do
|
|
services_cli.service_load(
|
|
instance_double(
|
|
Homebrew::Services::FormulaWrapper,
|
|
name: "name",
|
|
service_name: "service.name",
|
|
service_startup?: true,
|
|
),
|
|
nil,
|
|
enable: false,
|
|
)
|
|
end.to output("==> Successfully ran `name` (label: service.name)\n").to_stdout
|
|
end
|
|
|
|
it "triggers launchctl" do
|
|
expect(Homebrew::Services::System).to receive(:launchctl?).once.and_return(true)
|
|
expect(Homebrew::Services::System).not_to receive(:systemctl?)
|
|
expect(Homebrew::Services::System).to receive(:root?).twice.and_return(false)
|
|
expect(described_class).to receive(:launchctl_load).once.and_return(true)
|
|
expect do
|
|
services_cli.service_load(
|
|
instance_double(
|
|
Homebrew::Services::FormulaWrapper,
|
|
name: "name",
|
|
service_name: "service.name",
|
|
service_startup?: false,
|
|
service_file: instance_double(Pathname, exist?: false),
|
|
),
|
|
nil,
|
|
enable: false,
|
|
)
|
|
end.to output("==> Successfully ran `name` (label: service.name)\n").to_stdout
|
|
end
|
|
|
|
it "triggers systemctl" do
|
|
expect(Homebrew::Services::System).to receive(:launchctl?).once.and_return(false)
|
|
expect(Homebrew::Services::System).to receive(:systemctl?).once.and_return(true)
|
|
expect(Homebrew::Services::System).to receive(:root?).twice.and_return(false)
|
|
expect(Homebrew::Services::System::Systemctl).to receive(:run).once.and_return(true)
|
|
expect do
|
|
services_cli.service_load(
|
|
instance_double(
|
|
Homebrew::Services::FormulaWrapper,
|
|
name: "name",
|
|
service_name: "service.name",
|
|
service_startup?: false,
|
|
dest: instance_double(Pathname, exist?: true),
|
|
),
|
|
nil,
|
|
enable: false,
|
|
)
|
|
end.to output("==> Successfully ran `name` (label: service.name)\n").to_stdout
|
|
end
|
|
|
|
it "represents correct action" do
|
|
expect(Homebrew::Services::System).to receive(:launchctl?).once.and_return(false)
|
|
expect(Homebrew::Services::System).to receive(:systemctl?).once.and_return(true)
|
|
expect(Homebrew::Services::System).to receive(:root?).twice.and_return(false)
|
|
expect(Homebrew::Services::System::Systemctl).to receive(:run).twice.and_return(true)
|
|
expect do
|
|
services_cli.service_load(
|
|
instance_double(
|
|
Homebrew::Services::FormulaWrapper,
|
|
name: "name",
|
|
service_name: "service.name",
|
|
service_startup?: false,
|
|
dest: instance_double(Pathname, exist?: true),
|
|
),
|
|
nil,
|
|
enable: true,
|
|
)
|
|
end.to output("==> Successfully started `name` (label: service.name)\n").to_stdout
|
|
end
|
|
end
|
|
end
|