Files
Artemis-Eapil/tests/unit/runtime/test_daemon_client.py
T
somew1nd c2c90a6378 feat: add multi-device concurrency, server lifecycle CLI, and unified execution stream
- Implement DevicePool and DeviceExecutionLock concurrency modes (per-device FIFO vs global serialization)
- Extend ArtemisClient SDK and CLI with explicit device targeting and concurrency strategy configuration
- Add server lifecycle management (artemis restart, stop, status) with cross-platform PID discovery
- Update MCP server tools to support multi-device dispatch, trace tagging, and per-device execution
- Enhance Showcase UI with step-by-step visual replay, playback speed controls, and device serial badges
- Add comprehensive unit test coverage and edge-case verification scripts
2026-08-26 15:53:14 -07:00

104 lines
3.4 KiB
Python

# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from unittest.mock import MagicMock, patch
import pytest
from artemis.runtime.daemon_client import (
ensure_daemon_running,
is_daemon_running,
is_standalone_forced,
spawn_daemon,
submit_task_to_daemon,
)
def test_is_standalone_forced(monkeypatch):
monkeypatch.delenv("ARTEMIS_STANDALONE", raising=False)
assert is_standalone_forced() is False
monkeypatch.setenv("ARTEMIS_STANDALONE", "1")
assert is_standalone_forced() is True
monkeypatch.setenv("ARTEMIS_STANDALONE", "true")
assert is_standalone_forced() is True
monkeypatch.setenv("ARTEMIS_STANDALONE", "0")
assert is_standalone_forced() is False
def test_is_daemon_running_success():
mock_resp = MagicMock()
mock_resp.status = 200
mock_resp.__enter__.return_value = mock_resp
with patch("urllib.request.urlopen", return_value=mock_resp):
assert is_daemon_running() is True
def test_is_daemon_running_failure():
with patch("urllib.request.urlopen", side_effect=OSError("Connection refused")):
assert is_daemon_running() is False
def test_spawn_daemon():
mock_proc = MagicMock()
mock_proc.pid = 54321
with patch("subprocess.Popen", return_value=mock_proc) as mock_popen:
proc = spawn_daemon(host="127.0.0.1", port=8000)
assert proc is mock_proc
assert mock_popen.called
def test_ensure_daemon_running_when_already_active():
with patch("artemis.runtime.daemon_client.is_daemon_running", return_value=True):
ok, base_url = ensure_daemon_running(host="127.0.0.1", port=8000)
assert ok is True
assert base_url == "http://127.0.0.1:8000"
def test_ensure_daemon_running_standalone_override(monkeypatch):
monkeypatch.setenv("ARTEMIS_STANDALONE", "1")
ok, base_url = ensure_daemon_running()
assert ok is False
assert base_url is None
def test_ensure_daemon_running_auto_spawns():
with (
patch("artemis.runtime.daemon_client.is_daemon_running", side_effect=[False, True]),
patch("artemis.runtime.daemon_client.spawn_daemon") as mock_spawn,
):
ok, base_url = ensure_daemon_running(timeout=1.0, wait_ready=True)
assert ok is True
assert base_url == "http://127.0.0.1:8000"
mock_spawn.assert_called_once()
def test_submit_task_to_daemon():
mock_resp = MagicMock()
mock_resp.status = 200
mock_resp.read.return_value = b'{"status": "queued", "tasks": [{"session_id": "test-sess"}]}'
mock_resp.__enter__.return_value = mock_resp
with patch("urllib.request.urlopen", return_value=mock_resp):
res = submit_task_to_daemon(
"test goal",
profile="flash",
device_serial="pixel-8",
)
assert res is not None
assert res["status"] == "queued"
assert res["tasks"][0]["session_id"] == "test-sess"