Files
cleveragents-core/features/devcontainer_handler_protocol_methods.feature
T
HAL9000 619e8eff36 feat(resource): add --clone-into to container-instance and fix devcontainer-instance sandbox strategy
- Adds a --clone-into option to the container-instance command to clone repository contents into a specified path during container setup.
- Fixes the devcontainer-instance sandbox strategy to ensure proper isolation, correct mount permissions, and deterministic behavior across environments.
- Updates related validation and error handling to reflect the new option and sandbox changes.

ISSUES CLOSED: #7555
2026-06-02 20:37:35 -04:00

151 lines
8.2 KiB
Gherkin

Feature: DevcontainerHandler missing protocol methods
As a developer using DevcontainerHandler
I want delete(), list_children(), diff(), and create_sandbox() to be implemented
So that the handler satisfies the full ResourceHandler protocol (issue #1242)
# delete() method
Scenario: dcproto delete file successfully from devcontainer
Given dcproto a devcontainer handler
And dcproto a devcontainer-instance resource with location "/ws/project"
And dcproto subprocess returns successful rm output
When dcproto I delete path "src/old_file.py" from the resource
Then dcproto the delete should succeed
And dcproto the delete message should contain "src/old_file.py"
And dcproto the subprocess should have been called with "rm" and "src/old_file.py"
Scenario: dcproto delete with empty path targets workspace root
Given dcproto a devcontainer handler
And dcproto a devcontainer-instance resource with location "/ws/project"
And dcproto subprocess returns successful rm output
When dcproto I delete with empty path from the resource
Then dcproto the delete should succeed
And dcproto the subprocess should have been called with "rm" and "."
Scenario: dcproto delete fails when container is stopped
Given dcproto a devcontainer handler
And dcproto a devcontainer-instance resource with location "/ws/project"
And dcproto subprocess returns failed rm output with stderr "container not running"
When dcproto I delete path "file.txt" from the resource
Then dcproto the delete should fail
And dcproto the delete failure message should contain "container not running"
Scenario: dcproto delete from resource with no location raises ValueError
Given dcproto a devcontainer handler
And dcproto a devcontainer-instance resource with no location
When dcproto I delete path "any/file.txt" from the resource
Then dcproto the delete should raise ValueError containing "no location"
# ── list_children() method ───────────────────────────────────
Scenario: dcproto list_children returns sorted names from devcontainer
Given dcproto a devcontainer handler
And dcproto a devcontainer-instance resource with location "/ws/project"
And dcproto subprocess returns successful ls listing "src\ntests\nREADME.md"
When dcproto I list children of the resource
Then dcproto the children list should have 3 entries
And dcproto the children list should be "README.md,src,tests"
Scenario: dcproto list_children returns empty list when container is stopped
Given dcproto a devcontainer handler
And dcproto a devcontainer-instance resource with location "/ws/project"
And dcproto subprocess returns failed ls output
When dcproto I list children of the resource
Then dcproto the children list should have 0 entries
Scenario: dcproto list_children filters blank lines from ls output
Given dcproto a devcontainer handler
And dcproto a devcontainer-instance resource with location "/ws/project"
And dcproto subprocess returns successful ls listing "alpha\n\n\nbeta\n"
When dcproto I list children of the resource
Then dcproto the children list should have 2 entries
And dcproto the children list should be "alpha,beta"
Scenario: dcproto list_children from resource with no location raises ValueError
Given dcproto a devcontainer handler
And dcproto a devcontainer-instance resource with no location
When dcproto I list children of the resource
Then dcproto the list children should raise ValueError containing "no location"
Scenario: dcproto list_children uses devcontainer exec ls command
Given dcproto a devcontainer handler
And dcproto a devcontainer-instance resource with location "/ws/project"
And dcproto subprocess returns successful ls listing "main.py"
When dcproto I list children of the resource
Then dcproto the subprocess should have been called with "ls" and "--workspace-folder"
# ── diff() method ────────────────────────────────────────────
Scenario: dcproto diff detects changes when hashes differ
Given dcproto a devcontainer handler
And dcproto a devcontainer-instance resource with location "/ws/project"
And dcproto the container content hash is "aabbccdd"
And dcproto a temporary directory with a different file
When dcproto I diff the resource against the temporary directory
Then dcproto the diff should report has_changes true
And dcproto the diff files_changed should be 1
Scenario: dcproto diff reports no changes when hashes match
Given dcproto a devcontainer handler
And dcproto a devcontainer-instance resource with location "/ws/project"
And dcproto the container content hash matches the other location
When dcproto I diff the resource against the same location
Then dcproto the diff should report has_changes false
And dcproto the diff files_changed should be 0
Scenario: dcproto diff reports no changes when both sides are absent
Given dcproto a devcontainer handler
And dcproto a devcontainer-instance resource with location "/nonexistent/path"
When dcproto I diff the resource against "/another/nonexistent/path"
Then dcproto the diff should report has_changes false
Scenario: dcproto diff from resource with no location raises ValueError
Given dcproto a devcontainer handler
And dcproto a devcontainer-instance resource with no location
When dcproto I diff the resource against "/some/path"
Then dcproto the diff should raise ValueError containing "no location"
Scenario: dcproto diff unified_diff is always empty string
Given dcproto a devcontainer handler
And dcproto a devcontainer-instance resource with location "/ws/project"
And dcproto the container content hash is "aabbccdd"
And dcproto a temporary directory with a different file
When dcproto I diff the resource against the temporary directory
Then dcproto the diff unified_diff should be empty
# ── create_sandbox() method ──────────────────────────────────
Scenario: dcproto create_sandbox delegates to base class for running container
Given dcproto a devcontainer handler
And dcproto a devcontainer-instance resource with location "/ws/project"
And dcproto the container is in RUNNING state
And dcproto a mock sandbox manager that returns a valid sandbox
When dcproto I create a sandbox for the resource with plan "plan-001"
Then dcproto the sandbox result should have strategy "snapshot"
And dcproto the sandbox result should have a sandbox path
Scenario: dcproto create_sandbox activates container when in DETECTED state
Given dcproto a devcontainer handler
And dcproto a devcontainer-instance resource with location "/ws/project"
And dcproto the container is in DETECTED state
And dcproto a mock sandbox manager that returns a valid sandbox
And dcproto activate_container is mocked to succeed
When dcproto I create a sandbox for the resource with plan "plan-002"
Then dcproto activate_container should have been called
Scenario: dcproto create_sandbox activates container when in STOPPED state
Given dcproto a devcontainer handler
And dcproto a devcontainer-instance resource with location "/ws/project"
And dcproto the container is in STOPPED state
And dcproto a mock sandbox manager that returns a valid sandbox
And dcproto activate_container is mocked to succeed
When dcproto I create a sandbox for the resource with plan "plan-003"
Then dcproto activate_container should have been called
Scenario: dcproto create_sandbox raises ValueError for resource with no location
Given dcproto a devcontainer handler
And dcproto a devcontainer-instance resource with no location
And dcproto a mock sandbox manager that returns a valid sandbox
When dcproto I create a sandbox for the resource with plan "plan-004"
Then dcproto the create_sandbox should raise ValueError containing "no location"