Files
OpenJarvis/tests/cli/test_daemon_cmd.py
T
Jon Saad-FalconandClaude Opus 4.6 a4c4081ff4 Add desktop distribution pipeline: rolling releases, auto-updates, code signing
- Rewrite .github/workflows/desktop.yml: 2-job pipeline (validate + build-and-release)
  with rolling desktop-latest pre-release on push to main and stable desktop-v* releases
- Add UpdateChecker component: checks for updates on startup + every 30 min,
  background download with progress bar, one-click relaunch
- Configure Tauri updater: endpoints pointing to desktop-latest release, pubkey placeholder
- Add tauri-plugin-process for relaunch support (Cargo.toml, lib.rs, package.json)
- Add macOS Entitlements.plist for notarization (network + file access, no sandbox)
- Add scripts/bump-desktop-version.sh for atomic version bumps across 3 config files
- Add desktop/README.md with dev setup, auto-update architecture, signing docs
- Update .gitignore for desktop/node_modules, dist, target
- Configure macOS minimumSystemVersion, Windows timestampUrl
- Include all Phase 14-21 work: agent hardening, RBAC, taint tracking, workflows,
  skills, knowledge graph, sessions, A2A, MCP templates, WASM sandbox, TUI dashboard,
  production tools, CLI expansion, API expansion, learning productionization,
  Tauri desktop app, and 10 new channels

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 19:14:05 +00:00

92 lines
3.2 KiB
Python

"""Tests for ``jarvis start|stop|restart|status`` daemon management commands."""
from __future__ import annotations
from pathlib import Path
from unittest.mock import MagicMock, patch
from click.testing import CliRunner
from openjarvis.cli import cli
from openjarvis.cli.daemon_cmd import _read_pid, _write_pid
class TestDaemonCommands:
"""Core daemon CLI tests."""
def test_start_command_exists(self) -> None:
"""``jarvis start --help`` succeeds."""
result = CliRunner().invoke(cli, ["start", "--help"])
assert result.exit_code == 0
out = result.output.lower()
assert "daemon" in out or "start" in out or "background" in out
def test_stop_no_server(self) -> None:
"""``jarvis stop`` when no PID file shows 'not running'."""
with patch(
"openjarvis.cli.daemon_cmd._read_pid", return_value=None
):
result = CliRunner().invoke(cli, ["stop"])
assert result.exit_code != 0
assert "No running server" in result.output
def test_status_no_server(self) -> None:
"""``jarvis status`` when no PID file shows 'not running'."""
with patch(
"openjarvis.cli.daemon_cmd._read_pid", return_value=None
):
result = CliRunner().invoke(cli, ["status"])
assert result.exit_code == 0
assert "not running" in result.output
def test_read_pid_no_file(self, tmp_path: Path) -> None:
"""``_read_pid()`` returns None when no PID file exists."""
with patch(
"openjarvis.cli.daemon_cmd._PID_FILE",
tmp_path / "nonexistent.pid",
):
assert _read_pid() is None
def test_write_and_read_pid(self, tmp_path: Path) -> None:
"""Write a PID, then read it back (mock os.kill to succeed)."""
pid_file = tmp_path / "server.pid"
with (
patch("openjarvis.cli.daemon_cmd._PID_FILE", pid_file),
patch(
"openjarvis.cli.daemon_cmd.DEFAULT_CONFIG_DIR", tmp_path
),
patch("os.kill", return_value=None),
):
_write_pid(12345)
assert pid_file.exists()
assert _read_pid() == 12345
def test_status_shows_running(self) -> None:
"""``jarvis status`` shows running info when PID exists."""
mock_config = MagicMock()
mock_config.server.host = "127.0.0.1"
mock_config.server.port = 8000
with (
patch(
"openjarvis.cli.daemon_cmd._read_pid", return_value=9999
),
patch(
"openjarvis.cli.daemon_cmd.load_config",
return_value=mock_config,
),
):
result = CliRunner().invoke(cli, ["status"])
assert result.exit_code == 0
assert "running" in result.output
assert "9999" in result.output
def test_start_already_running(self) -> None:
"""``jarvis start`` exits with error when a server is already running."""
with patch(
"openjarvis.cli.daemon_cmd._read_pid", return_value=42
):
result = CliRunner().invoke(cli, ["start"])
assert result.exit_code != 0
assert "already running" in result.output