Files
cleveragents-core/features/devcontainer_state.feature
T
HAL9000 be45020a5c 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 02:39:58 -04:00

199 lines
9.6 KiB
Gherkin

Feature: Devcontainer Lifecycle State Model
As a CleverAgents developer
I want the container lifecycle state model to enforce valid transitions
So that containers follow a predictable state machine
# Lifecycle state model
Scenario: ContainerLifecycleState has all required values
When I inspect ContainerLifecycleState enum values
Then the lifecycle enum should contain "discovered"
And the lifecycle enum should contain "building"
And the lifecycle enum should contain "running"
And the lifecycle enum should contain "stopping"
And the lifecycle enum should contain "stopped"
And the lifecycle enum should contain "failed"
Scenario: Valid transitions are accepted
Given a lifecycle tracker for resource "01TESTLIFECYCLE0000000001"
When I transition from "discovered" to "building"
Then the transition should succeed
And the tracker state should be "building"
Scenario: Active transition after starting
Given a lifecycle tracker in "building" state for resource "01TESTLIFECYCLE0000000002"
When I transition from "building" to "running"
Then the transition should succeed
And the tracker state should be "running"
Scenario: Invalid transition is rejected
Given a lifecycle tracker for resource "01TESTLIFECYCLE0000000003"
When I attempt to transition from "discovered" to "running"
Then the transition should raise ValueError
Scenario: Stopping to error transition is valid
Given a lifecycle tracker in "stopping" state for resource "01TESTLIFECYCLE0000000004"
When I transition from "stopping" to "failed"
Then the transition should succeed
And the tracker state should be "failed"
Scenario: Error to starting transition is valid for retry
Given a lifecycle tracker in "failed" state for resource "01TESTLIFECYCLE0000000005"
When I transition from "failed" to "building"
Then the transition should succeed
And the tracker state should be "building"
Scenario: Stopped to starting transition is valid for rebuild
Given a lifecycle tracker in "stopped" state for resource "01TESTLIFECYCLE0000000006"
When I transition from "stopped" to "building"
Then the transition should succeed
Scenario: Transition history is recorded
Given a lifecycle tracker for resource "01TESTLIFECYCLE0000000007"
When I transition from "discovered" to "building"
Then the tracker should have 1 transition in history
# ── Lifecycle registry ─────────────────────────────────────
Scenario: Lifecycle tracker persists state across calls
Given a lifecycle tracker for resource "01TESTLIFECYCLE0000000060"
When I transition from "discovered" to "building"
And I retrieve the tracker for "01TESTLIFECYCLE0000000060"
Then the retrieved tracker state should be "building"
Scenario: List active containers returns only active ones
Given a mock devcontainer CLI runner
And the runner configured for successful activation
And an active container "01TESTLIFECYCLE0000000070" with container ID "ctr-x"
And a lifecycle tracker for resource "01TESTLIFECYCLE0000000071"
When I list active containers
Then the active list should contain "01TESTLIFECYCLE0000000070"
And the active list should not contain "01TESTLIFECYCLE0000000071"
# ── JSON output parsing ────────────────────────────────────
Scenario: Parse valid devcontainer up JSON output
When I parse devcontainer up output with containerId "abcdef123456" and workspace "/ws"
Then the parsed container ID should be "abcdef123456"
And the parsed workspace path should be "/ws"
Scenario: Parse invalid devcontainer up JSON output gracefully
When I parse devcontainer up output with invalid JSON
Then the parsed container ID should be None
And the parsed workspace path should be None
# ── Argument validation ────────────────────────────────────
Scenario: validate_transition rejects wrong types
When I call validate_transition with non-enum arguments
Then it should raise TypeError
Scenario: validate_transition rejects wrong to_state type
When I call validate_transition with non-enum to_state
Then it should raise TypeError
Scenario: transition_state rejects wrong tracker type
When I call transition_state with non-tracker argument
Then it should raise TypeError
Scenario: transition_state rejects wrong to_state type
When I call transition_state with non-enum to_state argument
Then it should raise TypeError
# ── Registry edge cases ────────────────────────────────────
Scenario: get_lifecycle_tracker rejects empty resource_id
When I attempt to get tracker with empty resource_id
Then the get tracker should raise ValueError
Scenario: set_lifecycle_tracker rejects wrong type
When I attempt to set tracker with wrong type
Then the set tracker should raise TypeError
# ── R13: Additional invalid transition coverage ────────────
Scenario: Invalid transition running to building is rejected
Given a lifecycle tracker in "running" state for resource "01TESTLIFECYCLE0000000240"
When I attempt to transition from "running" to "building"
Then the transition should raise ValueError
Scenario: Invalid transition stopped to running is rejected
Given a lifecycle tracker in "stopped" state for resource "01TESTLIFECYCLE0000000241"
When I attempt to transition from "stopped" to "running"
Then the transition should raise ValueError
Scenario: Invalid transition building to stopped is rejected
Given a lifecycle tracker in "building" state for resource "01TESTLIFECYCLE0000000242"
When I attempt to transition from "building" to "stopped"
Then the transition should raise ValueError
Scenario: Invalid transition failed to running is rejected
Given a lifecycle tracker in "failed" state for resource "01TESTLIFECYCLE0000000243"
When I attempt to transition from "failed" to "running"
Then the transition should raise ValueError
Scenario: Invalid transition discovered to stopping is rejected
Given a lifecycle tracker for resource "01TESTLIFECYCLE0000000244"
When I attempt to transition from "discovered" to "stopping"
Then the transition should raise ValueError
Scenario: Invalid transition building to discovered is rejected
Given a lifecycle tracker in "building" state for resource "01TESTLIFECYCLE0000000245"
When I attempt to transition from "building" to "discovered"
Then the transition should raise ValueError
# ── R4: Multi-line JSON output parsing ─────────────────────
Scenario: Parse devcontainer up output with log lines before JSON
When I parse devcontainer up output with log lines before JSON
Then the parsed container ID should be "aabbccddee0099887766"
And the parsed workspace path should be "/workspaces/multi"
# ── T1: Transition history cap at 100 ──────────────────────
Scenario: Transition history is capped at 100 entries
Given a lifecycle tracker for resource "01TESTLIFECYCLE0000000300"
When I perform 105 transitions cycling through valid states
Then the tracker should have at most 100 transitions
# ── S1: Container ID format validation ─────────────────────
Scenario: Invalid container ID format is rejected during parsing
When I parse devcontainer up output with invalid container ID "not-a-hex-id!"
Then the parsed container ID should be empty
# ── F11: Invalid workspace path rejected during parsing ────
Scenario: Parse devcontainer up output with relative workspace path
When I parse devcontainer up output with relative workspace "relative/ws"
Then the parsed container ID should be "aabbccddee0011223344"
And the parsed workspace path should be None
# ── R7-F8: Terminal tracker eviction ────────────────────────
Scenario: Terminal tracker eviction removes oldest stopped trackers
Given 210 stopped container trackers in the registry
When I run terminal tracker eviction
Then the registry should have at most 200 terminal trackers
# ── TEST-3: Coverage gap scenarios ──────────────────────────
Scenario: evict_terminal_trackers returns 0 when below threshold
Given 50 stopped container trackers in the registry
When I run terminal tracker eviction
Then the eviction count should be 0
Scenario: get_lifecycle_tracker auto-creates tracker for new resource
When I get tracker for new resource "01TESTLIFECYCLE0000000730"
Then the auto-created tracker state should be "discovered"
And the auto-created tracker resource_id should be "01TESTLIFECYCLE0000000730"
Scenario: clear_lifecycle_registry stops health check threads
Given a mock devcontainer CLI runner
And the runner configured for successful health check
And an active container "01TESTLIFECYCLE0000000740" with container ID "ctr-clr"
And a running health check for "01TESTLIFECYCLE0000000740"
When I clear the lifecycle registry
Then the registry should be empty
And the health check for "01TESTLIFECYCLE0000000740" should be unregistered