fix(gateway): handle lifecycle edge cases
This commit is contained in:
@@ -103,6 +103,7 @@ def test_launchd_install_dry_run_renders_plist(tmp_path):
|
||||
"/Users/test/.nanobot/config.json",
|
||||
]
|
||||
assert payload["KeepAlive"] == {"SuccessfulExit": False}
|
||||
assert payload["RunAtLoad"] is True
|
||||
assert ("launchctl", "bootstrap", _expected_launchd_domain(), str(result.path)) in result.commands
|
||||
|
||||
|
||||
@@ -118,11 +119,34 @@ def test_launchd_no_enable_start_still_bootstraps(tmp_path):
|
||||
dry_run=True,
|
||||
)
|
||||
|
||||
assert result.content is not None
|
||||
payload = plistlib.loads(result.content.encode("utf-8"))
|
||||
assert payload["RunAtLoad"] is False
|
||||
assert result.commands[0][:2] == ("launchctl", "bootstrap")
|
||||
assert not any(command[1] == "enable" for command in result.commands)
|
||||
assert any(command[1] == "kickstart" for command in result.commands)
|
||||
|
||||
|
||||
def test_launchd_enable_without_start_sets_run_at_load_without_bootstrap(tmp_path):
|
||||
installer = GatewayServiceInstaller(platform_name="Darwin", home=tmp_path)
|
||||
|
||||
result = installer.install(
|
||||
GatewayServiceOptions(
|
||||
start=GatewayStartOptions(port=18790),
|
||||
enable=True,
|
||||
start_now=False,
|
||||
),
|
||||
dry_run=True,
|
||||
)
|
||||
|
||||
assert result.content is not None
|
||||
payload = plistlib.loads(result.content.encode("utf-8"))
|
||||
assert payload["RunAtLoad"] is True
|
||||
assert not any(command[1] == "bootstrap" for command in result.commands)
|
||||
assert any(command[1] == "enable" for command in result.commands)
|
||||
assert not any(command[1] == "kickstart" for command in result.commands)
|
||||
|
||||
|
||||
def test_launchd_no_enable_start_reinstall_boots_out_existing_label(tmp_path):
|
||||
commands: list[list[str]] = []
|
||||
installer = GatewayServiceInstaller(
|
||||
|
||||
@@ -139,10 +139,32 @@ def test_stop_terminates_recorded_process(tmp_path, monkeypatch):
|
||||
monkeypatch.setattr(runtime, "_is_pid_running", lambda _pid: True)
|
||||
monkeypatch.setattr(runtime, "_process_identity", lambda _pid: 12345)
|
||||
terminated: list[int] = []
|
||||
monkeypatch.setattr(runtime, "_terminate", lambda pid, timeout_s: terminated.append(pid))
|
||||
|
||||
def fake_terminate(pid, timeout_s):
|
||||
terminated.append(pid)
|
||||
return True
|
||||
|
||||
monkeypatch.setattr(runtime, "_terminate", fake_terminate)
|
||||
|
||||
result = runtime.stop()
|
||||
|
||||
assert result.ok is True
|
||||
assert terminated == [12345]
|
||||
assert not runtime.paths.state_path.exists()
|
||||
|
||||
|
||||
def test_stop_keeps_state_when_process_survives_timeout(tmp_path, monkeypatch):
|
||||
runtime = GatewayRuntime(paths=_paths(tmp_path), platform_name="Linux")
|
||||
runtime.paths.run_dir.mkdir(parents=True)
|
||||
runtime.paths.state_path.write_text('{"pid": 12345, "identity": 12345}', encoding="utf-8")
|
||||
monkeypatch.setattr(runtime, "_is_pid_running", lambda _pid: True)
|
||||
monkeypatch.setattr(runtime, "_process_identity", lambda _pid: 12345)
|
||||
monkeypatch.setattr(runtime, "_terminate", lambda _pid, timeout_s: False)
|
||||
|
||||
result = runtime.stop(timeout_s=0)
|
||||
|
||||
assert result.ok is False
|
||||
assert result.message == "gateway_stop_timeout"
|
||||
assert result.status.running is True
|
||||
assert result.status.reason == "stop_timeout"
|
||||
assert runtime.paths.state_path.exists()
|
||||
|
||||
Reference in New Issue
Block a user