Files
oraios--serena/test/serena/test_activation_command.py
wehub-resource-sync c6af9e284a
Tests / catch-all (windows-latest) (push) Has been cancelled
Tests / jvm (macos-latest) (push) Has been cancelled
Tests / jvm (ubuntu-latest) (push) Has been cancelled
Tests / jvm (windows-latest) (push) Has been cancelled
Tests / native (macos-latest) (push) Has been cancelled
Tests / native (ubuntu-latest) (push) Has been cancelled
Tests / native (windows-latest) (push) Has been cancelled
Tests / niche (ubuntu-latest) (push) Has been cancelled
Tests / other-langs (macos-latest) (push) Has been cancelled
Tests / other-langs (ubuntu-latest) (push) Has been cancelled
Tests / other-langs (windows-latest) (push) Has been cancelled
Tests / catch-all (macos-latest) (push) Has been cancelled
Tests / catch-all (ubuntu-latest) (push) Has been cancelled
Docs Build / build (push) Has been cancelled
Docs Build / deploy (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Codespell / Check for spelling errors (push) Has been cancelled
Build and Push Docker Images / build-and-push (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:39:38 +08:00

101 lines
4.1 KiB
Python

"""Tests for SerenaAgent._run_activation_command."""
import logging
import sys
from pathlib import Path
import pytest
from serena.config.serena_config import ProjectConfig, SerenaConfig
from serena.project import Project
from solidlsp.ls_config import Language
def _make_project(
project_root: Path,
activation_command: str | None = None,
activation_command_timeout: float = 180.0,
trusted: bool = True,
) -> Project:
"""Create a minimal Project pointing at project_root with the given activation settings."""
serena_config = SerenaConfig(
gui_log_window=False,
web_dashboard=False,
trusted_project_path_patterns=["**"] if trusted else [],
)
project_config = ProjectConfig(
project_name="test-activation",
languages=[Language.PYTHON],
activation_command=activation_command,
activation_command_timeout=activation_command_timeout,
)
return Project(
project_root=str(project_root),
project_config=project_config,
serena_config=serena_config,
)
class TestRunActivationCommand:
"""Unit tests for SerenaAgent._run_activation_command."""
def _make_agent(self, project: Project):
from serena.agent import SerenaAgent
agent = SerenaAgent.__new__(SerenaAgent)
# wire up only what _run_activation_command needs
agent.serena_config = project.serena_config
return agent
def test_no_command_does_nothing(self, tmp_path: Path, caplog):
project = _make_project(tmp_path, activation_command=None)
agent = self._make_agent(project)
with caplog.at_level(logging.INFO):
agent._run_project_activation_command(project)
assert "activation_command" not in caplog.text
def test_trusted_command_runs_in_project_root(self, tmp_path: Path):
sentinel = tmp_path / "sentinel.txt"
# write a sentinel file from within the command to confirm cwd is project_root
if sys.platform == "win32":
cmd = "type nul > sentinel.txt"
else:
cmd = "touch sentinel.txt"
project = _make_project(tmp_path, activation_command=cmd, trusted=True)
agent = self._make_agent(project)
agent._run_project_activation_command(project)
assert sentinel.exists(), "Command did not run in project root (sentinel file missing)"
def test_untrusted_project_skips_command(self, tmp_path: Path, caplog):
sentinel = tmp_path / "sentinel.txt"
cmd = "touch sentinel.txt" if sys.platform != "win32" else "type nul > sentinel.txt"
project = _make_project(tmp_path, activation_command=cmd, trusted=False)
agent = self._make_agent(project)
with caplog.at_level(logging.WARNING):
agent._run_project_activation_command(project)
assert not sentinel.exists(), "Command must not run for untrusted project"
assert "not trusted" in caplog.text
def test_failing_command_logs_error_and_continues(self, tmp_path: Path, caplog):
cmd = "exit 1" if sys.platform != "win32" else "cmd /c exit 1"
project = _make_project(tmp_path, activation_command=cmd, trusted=True)
agent = self._make_agent(project)
with caplog.at_level(logging.ERROR):
agent._run_project_activation_command(project) # must not raise
assert any("failed" in r.message.lower() for r in caplog.records if r.levelno == logging.ERROR)
@pytest.mark.slow
def test_timeout_kills_process_and_continues(self, tmp_path: Path, caplog):
"""A hanging command must be killed and activation must continue."""
cmd = 'python3 -c "import time; time.sleep(60)"'
project = _make_project(
tmp_path,
activation_command=cmd,
activation_command_timeout=1.0, # 1s — fast for the test
trusted=True,
)
agent = self._make_agent(project)
with caplog.at_level(logging.ERROR):
agent._run_project_activation_command(project) # must not hang or raise
assert any("timed out" in r.message.lower() for r in caplog.records if r.levelno == logging.ERROR)