mirror of
https://github.com/agentscope-ai/ReMe.git
synced 2026-11-05 07:39:47 +00:00
Some checks failed
CI / Python packages / Build and verify distributions (push) Waiting to run
CI / Python quality / GitHub Actions (push) Waiting to run
CI / Python quality / Pre-commit (push) Waiting to run
CI / Python tests / Unit Tests - py3.11 (push) Waiting to run
CI / Python tests / Unit Tests - py3.12 (push) Waiting to run
CI / Python tests / Unit Tests - py3.13 (push) Waiting to run
CI / Python tests / Unit Tests - py3.14 (push) Waiting to run
CI / Windows / CLI smoke - py3.11 (push) Waiting to run
Deploy / Documentation / Build documentation (push) Waiting to run
Deploy / Documentation / deploy (push) Blocked by required conditions
CI and Release / Docker / Build and test / amd64 (push) Waiting to run
CI and Release / Docker / Build and test / arm64 (push) Waiting to run
CI and Release / Docker / Publish multi-platform tags (push) Blocked by required conditions
Security / CodeQL / Analyze javascript-typescript (push) Waiting to run
Security / CodeQL / Analyze python (push) Waiting to run
CI / ReMe Studio / Studio checks (push) Has been cancelled
86 lines
2.7 KiB
Python
86 lines
2.7 KiB
Python
"""Tests for asynchronous shell command execution."""
|
|
|
|
import time
|
|
|
|
import pytest
|
|
|
|
from reme.components.application_context import ApplicationContext
|
|
from reme.enumeration import ComponentEnum
|
|
from reme.steps.common.shell import DEFAULT_TIMEOUT, ShellStep
|
|
from reme.components import R
|
|
|
|
|
|
def test_shell_step_is_registered():
|
|
"""Importing common steps makes shell_step discoverable."""
|
|
assert R.get(ComponentEnum.STEP, "shell_step") is ShellStep
|
|
|
|
|
|
def test_shell_step_default_timeout_is_one_day():
|
|
"""Shell commands may run for one day when no timeout is supplied."""
|
|
assert DEFAULT_TIMEOUT == 86400
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_shell_step_returns_stdout_from_workspace(tmp_path):
|
|
"""Successful commands return stdout and run in the configured workspace."""
|
|
|
|
step = ShellStep(app_context=ApplicationContext(workspace_dir=str(tmp_path)))
|
|
response = await step(cmd="pwd")
|
|
|
|
assert response.success is True
|
|
assert response.answer.strip() == str(tmp_path)
|
|
assert response.metadata["returncode"] == 0
|
|
assert response.metadata["stderr"] == ""
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_shell_step_reports_stderr_on_failure():
|
|
"""Failed commands expose stderr and their non-zero exit status."""
|
|
|
|
step = ShellStep()
|
|
response = await step(cmd="echo boom >&2; exit 7")
|
|
|
|
assert response.success is False
|
|
assert response.answer == "boom\n"
|
|
assert response.metadata["returncode"] == 7
|
|
assert response.metadata["stderr"] == "boom\n"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_shell_step_times_out():
|
|
"""Timeout terminates child processes as well as their parent shell."""
|
|
|
|
step = ShellStep()
|
|
started = time.monotonic()
|
|
response = await step(cmd="sleep 3 & wait", shell_timeout=0.01)
|
|
|
|
assert response.success is False
|
|
assert response.answer == "Shell command timed out after 0.01s"
|
|
assert response.metadata["shell_timeout"] == 0.01
|
|
assert time.monotonic() - started < 1
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_shell_step_requires_a_command():
|
|
"""Blank commands are rejected without creating a subprocess."""
|
|
|
|
response = await ShellStep()(cmd=" ")
|
|
|
|
assert response.success is False
|
|
assert response.answer == "cmd is required"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_shell_step_does_not_accept_legacy_parameter_names():
|
|
"""Only cmd and shell_timeout configure shell execution."""
|
|
|
|
response = await ShellStep()(command="printf legacy", timeout=1)
|
|
|
|
assert response.success is False
|
|
assert response.answer == "cmd is required"
|
|
|
|
response = await ShellStep()(cmd="printf current", timeout=1)
|
|
|
|
assert response.success is True
|
|
assert response.answer == "current"
|
|
assert response.metadata["shell_timeout"] == DEFAULT_TIMEOUT
|