bdcfdd44f6
step_mock_popen_success stored mock_proc (Popen's return value) as context.popen_mock, but call_args is recorded on the mock *replacing* subprocess.Popen (what patcher.start() returns). Reading call_args from mock_proc returns None, causing TypeError in the three command-construction scenarios — behave reports these as "errored" not "failed". Fix: assign patcher.start() to context.popen_mock so the assertion steps read call_args from the correct mock. Also remove the redundant patcher.stop() calls from the assertion Then steps (context.add_cleanup already handles teardown). Add the required @tdd_issue and @tdd_issue_691 tags to the Connect with .py file path scenario per the TDD bug fix workflow. ISSUES CLOSED: #691
125 lines
4.7 KiB
Gherkin
125 lines
4.7 KiB
Gherkin
Feature: A2A stdio transport for local-mode communication
|
|
As a developer using local-mode agent communication
|
|
I want the A2aStdioTransport to handle subprocess communication correctly
|
|
So that JSON-RPC messages are sent and received reliably
|
|
|
|
@coverage
|
|
Scenario: Transport initializes with no process
|
|
Given a new A2aStdioTransport instance
|
|
Then the stdio transport should not be connected
|
|
And the stdio transport process should be None
|
|
|
|
@coverage
|
|
Scenario: Send raises when not connected
|
|
Given a new A2aStdioTransport instance
|
|
When I try to send a request without connecting
|
|
Then a RuntimeError should be raised about not connected
|
|
|
|
@coverage
|
|
Scenario: Send raises for non-A2aRequest input
|
|
Given a connected A2aStdioTransport with a mock process
|
|
When I try to send a non-A2aRequest object
|
|
Then a TypeError should be raised about A2aRequest
|
|
|
|
@coverage
|
|
Scenario: Send succeeds with valid request and mock response
|
|
Given a connected A2aStdioTransport with a mock process
|
|
And the mock process returns a valid JSON-RPC response
|
|
When I send a valid A2aRequest
|
|
Then I should receive an A2aResponse
|
|
|
|
@coverage
|
|
Scenario: Send raises on invalid JSON response
|
|
Given a connected A2aStdioTransport with a mock process
|
|
And the mock process returns invalid JSON
|
|
When I try to send a valid A2aRequest
|
|
Then a RuntimeError should be raised about invalid JSON
|
|
|
|
@coverage
|
|
Scenario: Send raises when subprocess closes unexpectedly
|
|
Given a connected A2aStdioTransport with a mock process
|
|
And the mock process returns empty response
|
|
When I try to send a valid A2aRequest
|
|
Then a RuntimeError should be raised about closed unexpectedly
|
|
|
|
@coverage
|
|
Scenario: Send raises when stdin is unavailable
|
|
Given a connected A2aStdioTransport with a mock process
|
|
And the mock process has no stdin
|
|
When I try to send a valid A2aRequest
|
|
Then a RuntimeError should be raised about stdin
|
|
|
|
@coverage
|
|
Scenario: Send raises when stdout is unavailable
|
|
Given a connected A2aStdioTransport with a mock process
|
|
And the mock process has no stdout but valid stdin
|
|
When I try to send a valid A2aRequest
|
|
Then a RuntimeError should be raised about stdout
|
|
|
|
@coverage
|
|
Scenario: Connect raises for empty agent path
|
|
Given a new A2aStdioTransport instance
|
|
When I try to connect with empty agent path
|
|
Then a ValueError should be raised about agent_path
|
|
|
|
@coverage
|
|
Scenario: Connect raises when already connected
|
|
Given a connected A2aStdioTransport with a mock process
|
|
When I try to connect again with a valid path
|
|
Then a RuntimeError should be raised about already connected
|
|
|
|
@coverage
|
|
Scenario: Disconnect is a no-op when not connected
|
|
Given a new A2aStdioTransport instance
|
|
When I call disconnect
|
|
Then no stdio transport error should be raised
|
|
|
|
@coverage
|
|
Scenario: Disconnect closes stdin and waits for process
|
|
Given a connected A2aStdioTransport with a mock process
|
|
When I call disconnect
|
|
Then the stdio transport should not be connected
|
|
And mock stdin close should have been called
|
|
And mock process wait should have been called
|
|
|
|
@coverage
|
|
Scenario: Disconnect terminates when wait times out
|
|
Given a connected A2aStdioTransport with a mock process
|
|
And the mock process times out on first wait
|
|
When I call disconnect
|
|
Then the stdio transport should not be connected
|
|
And mock process terminate should have been called
|
|
|
|
@coverage
|
|
Scenario: Connect with Python module path
|
|
Given a new A2aStdioTransport instance
|
|
And subprocess Popen is mocked to succeed
|
|
When I connect with agent path "cleveragents.a2a.agent"
|
|
Then the stdio transport should be connected
|
|
And subprocess Popen should have been called with python -m module args
|
|
|
|
@coverage
|
|
Scenario: Connect with executable path
|
|
Given a new A2aStdioTransport instance
|
|
And subprocess Popen is mocked to succeed
|
|
When I connect with agent path "/usr/local/bin/agent"
|
|
Then the stdio transport should be connected
|
|
And subprocess Popen should have been called with direct executable args
|
|
|
|
@coverage
|
|
@tdd_issue
|
|
@tdd_issue_691
|
|
Scenario: Connect with .py file path
|
|
Given a new A2aStdioTransport instance
|
|
And subprocess Popen is mocked to succeed
|
|
When I connect with agent path "agent.py"
|
|
Then the stdio transport should be connected
|
|
And subprocess Popen should have been called with python script args
|
|
|
|
@coverage
|
|
Scenario: Connect raises for file not found
|
|
Given a new A2aStdioTransport instance
|
|
And subprocess Popen raises FileNotFoundError
|
|
When I try to connect with agent path "/nonexistent/agent"
|
|
Then a RuntimeError should be raised about agent not found
|