Files
cleveragents-core/features/steps/skill_inline_coverage_steps.py
T

216 lines
7.8 KiB
Python

"""Step definitions for inline tool executor coverage boost tests."""
from __future__ import annotations
from behave import given, then, when
from behave.runner import Context
from cleveragents.skills.inline_executor import InlineToolExecutor
# ---------------------------------------------------------------------------
# Givens — Constructor validation
# ---------------------------------------------------------------------------
@given("I create an inline executor with invalid max runtime")
def create_executor_invalid_runtime(context: Context) -> None:
"""Attempt to create executor with non-positive runtime."""
context.executor_error = None
try:
InlineToolExecutor(max_runtime_seconds=-1.0)
except ValueError as exc:
context.executor_error = exc
@given("I create an inline executor with invalid max output")
def create_executor_invalid_output(context: Context) -> None:
"""Attempt to create executor with non-positive max output."""
context.executor_error = None
try:
InlineToolExecutor(max_output_bytes=0)
except ValueError as exc:
context.executor_error = exc
# ---------------------------------------------------------------------------
# Then — Constructor validation assertions
# ---------------------------------------------------------------------------
@then("creating the executor should raise a ValueError about runtime")
def assert_runtime_value_error(context: Context) -> None:
"""Assert ValueError was raised about runtime."""
assert context.executor_error is not None, "Expected ValueError"
assert "runtime" in str(context.executor_error).lower(), (
f"Expected 'runtime' in error: {context.executor_error}"
)
@then("creating the executor should raise a ValueError about output")
def assert_output_value_error(context: Context) -> None:
"""Assert ValueError was raised about output."""
assert context.executor_error is not None, "Expected ValueError"
assert "output" in str(context.executor_error).lower(), (
f"Expected 'output' in error: {context.executor_error}"
)
# ---------------------------------------------------------------------------
# Then — Property accessors
# ---------------------------------------------------------------------------
@then("the executor max_runtime_seconds should be {expected:g}")
def assert_max_runtime(context: Context, expected: float) -> None:
"""Assert max_runtime_seconds property value."""
actual = context.inline_executor.max_runtime_seconds
assert actual == expected, f"Expected {expected}, got {actual}"
@then("the executor max_output_bytes should be {expected:d}")
def assert_max_output(context: Context, expected: int) -> None:
"""Assert max_output_bytes property value."""
actual = context.inline_executor.max_output_bytes
assert actual == expected, f"Expected {expected}, got {actual}"
# ---------------------------------------------------------------------------
# When — Null argument guards
# ---------------------------------------------------------------------------
@when("I execute with None tool")
def execute_with_none_tool(context: Context) -> None:
"""Execute with None tool argument."""
context.exec_error = None
try:
context.inline_executor.execute(
tool=None, # type: ignore[arg-type]
context=context.inline_context,
input_data={},
)
except ValueError as exc:
context.exec_error = exc
@when("I execute with None context")
def execute_with_none_context(context: Context) -> None:
"""Execute with None context argument."""
context.exec_error = None
try:
context.inline_executor.execute(
tool=context.inline_tool,
context=None, # type: ignore[arg-type]
input_data={},
)
except ValueError as exc:
context.exec_error = exc
@when("I execute with None input_data")
def execute_with_none_input(context: Context) -> None:
"""Execute with None input_data argument."""
context.exec_error = None
try:
context.inline_executor.execute(
tool=context.inline_tool,
context=context.inline_context,
input_data=None, # type: ignore[arg-type]
)
except ValueError as exc:
context.exec_error = exc
@when("I validate with None tool")
def validate_with_none_tool(context: Context) -> None:
"""Validate with None tool argument."""
context.exec_error = None
try:
context.inline_executor.validate_tool(None) # type: ignore[arg-type]
except ValueError as exc:
context.exec_error = exc
# ---------------------------------------------------------------------------
# Then — Null argument guard assertions
# ---------------------------------------------------------------------------
@then("executing should raise a ValueError about tool")
def assert_tool_value_error(context: Context) -> None:
"""Assert ValueError was raised about tool."""
assert context.exec_error is not None, "Expected ValueError"
assert "tool" in str(context.exec_error).lower(), (
f"Expected 'tool' in error: {context.exec_error}"
)
@then("executing should raise a ValueError about context")
def assert_context_value_error(context: Context) -> None:
"""Assert ValueError was raised about context."""
assert context.exec_error is not None, "Expected ValueError"
assert "context" in str(context.exec_error).lower(), (
f"Expected 'context' in error: {context.exec_error}"
)
@then("executing should raise a ValueError about input_data")
def assert_input_value_error(context: Context) -> None:
"""Assert ValueError was raised about input_data."""
assert context.exec_error is not None, "Expected ValueError"
assert "input_data" in str(context.exec_error).lower(), (
f"Expected 'input_data' in error: {context.exec_error}"
)
@then("validating should raise a ValueError about tool")
def assert_validate_tool_error(context: Context) -> None:
"""Assert ValueError was raised about tool during validation."""
assert context.exec_error is not None, "Expected ValueError"
assert "tool" in str(context.exec_error).lower(), (
f"Expected 'tool' in error: {context.exec_error}"
)
@then("the inline result duration should be zero")
def assert_zero_duration(context: Context) -> None:
"""Assert the result duration is zero (validation failure path)."""
assert context.inline_result.duration_ms == 0.0, (
f"Expected 0.0 duration, got {context.inline_result.duration_ms}"
)
# ---------------------------------------------------------------------------
# When — Path validation
# ---------------------------------------------------------------------------
@when("I execute the inline tool with path input escaping sandbox")
def execute_with_escaping_path(context: Context) -> None:
"""Execute with a path that escapes the sandbox."""
context.inline_result = context.inline_executor.execute(
tool=context.inline_tool,
context=context.inline_context,
input_data={"file_path": "/etc/passwd"},
)
@when("I execute the inline tool with path input inside sandbox")
def execute_with_valid_path(context: Context) -> None:
"""Execute with a path inside the sandbox."""
context.inline_result = context.inline_executor.execute(
tool=context.inline_tool,
context=context.inline_context,
input_data={"file_path": "/tmp/inline-sandbox/data.txt"},
)
@when("I execute the inline tool with an invalid path value")
def execute_with_invalid_path(context: Context) -> None:
"""Execute with a path value containing null bytes."""
context.inline_result = context.inline_executor.execute(
tool=context.inline_tool,
context=context.inline_context,
input_data={"file_path": "\x00invalid"},
)