forked from cleveragents/cleveragents-core
127 lines
6.9 KiB
Gherkin
127 lines
6.9 KiB
Gherkin
Feature: Devcontainer Health Checking
|
|
As a CleverAgents developer
|
|
I want running devcontainers to be health-checked periodically
|
|
So that unhealthy containers are detected and transitioned to failed state
|
|
|
|
# ── Health check ───────────────────────────────────────────
|
|
|
|
Scenario: Health check failure transitions to error
|
|
Given a mock devcontainer CLI runner
|
|
And the runner configured for failed health check
|
|
And an active container "01TESTLIFECYCLE0000000050" with container ID "ctr-hc"
|
|
When I run a single health check probe for "01TESTLIFECYCLE0000000050"
|
|
Then the container state for "01TESTLIFECYCLE0000000050" should be "failed"
|
|
|
|
# ── start_health_check and health_check_loop coverage ──────
|
|
|
|
Scenario: Health check loop success path runs and returns
|
|
Given a mock devcontainer CLI runner
|
|
And the runner configured for successful health check
|
|
And an active container "01TESTLIFECYCLE0000000100" with container ID "ctr-hcbg"
|
|
When I run one iteration of the health check loop for "01TESTLIFECYCLE0000000100"
|
|
Then the health check should have probed "01TESTLIFECYCLE0000000100"
|
|
And the container state for "01TESTLIFECYCLE0000000100" should be "running"
|
|
|
|
Scenario: Health check loop transitions to error on probe failure
|
|
Given a mock devcontainer CLI runner
|
|
And the runner configured for failed health check
|
|
And an active container "01TESTLIFECYCLE0000000101" with container ID "ctr-hcf"
|
|
When I run one iteration of the health check loop for "01TESTLIFECYCLE0000000101"
|
|
Then the container state for "01TESTLIFECYCLE0000000101" should be "failed"
|
|
|
|
Scenario: Health check loop transitions to error on exception
|
|
Given a mock devcontainer CLI runner
|
|
And the runner configured to raise exception on exec
|
|
And an active container "01TESTLIFECYCLE0000000102" with container ID "ctr-hce"
|
|
When I run one iteration of the health check loop for "01TESTLIFECYCLE0000000102"
|
|
Then the container state for "01TESTLIFECYCLE0000000102" should be "failed"
|
|
|
|
Scenario: start_health_check registers thread and stop event
|
|
Given a mock devcontainer CLI runner
|
|
And the runner configured for successful health check
|
|
And an active container "01TESTLIFECYCLE0000000103" with container ID "ctr-reg"
|
|
When I call start_health_check for "01TESTLIFECYCLE0000000103"
|
|
Then a health check thread should be registered for "01TESTLIFECYCLE0000000103"
|
|
|
|
Scenario: Stopping active container stops running health check
|
|
Given a mock devcontainer CLI runner
|
|
And the runner configured for successful health check
|
|
And an active container "01TESTLIFECYCLE0000000104" with container ID "ctr-hcstop"
|
|
And a registered health check for "01TESTLIFECYCLE0000000104"
|
|
When I stop container "01TESTLIFECYCLE0000000104"
|
|
Then the container state for "01TESTLIFECYCLE0000000104" should be "stopped"
|
|
And the health check for "01TESTLIFECYCLE0000000104" should be unregistered
|
|
|
|
Scenario: Health check exits when container is no longer active
|
|
Given a mock devcontainer CLI runner
|
|
And the runner configured for successful health check
|
|
And a stopped container "01TESTLIFECYCLE0000000105"
|
|
When I run one iteration of the health check loop for "01TESTLIFECYCLE0000000105"
|
|
Then the container state for "01TESTLIFECYCLE0000000105" should be "stopped"
|
|
|
|
Scenario: start_health_check rejects empty resource_id
|
|
When I attempt to start health check with empty resource_id
|
|
Then the health check should raise ValueError
|
|
|
|
# ── T2: Concurrent activation rejects second caller ────────
|
|
|
|
Scenario: Concurrent activation of the same container is rejected
|
|
Given a mock devcontainer CLI runner
|
|
And the runner configured for successful activation
|
|
And a lifecycle tracker for resource "01TESTLIFECYCLE0000000310"
|
|
When I activate the container concurrently from two threads
|
|
Then exactly one activation should succeed
|
|
And exactly one activation should fail with ValueError
|
|
|
|
# ── T3: _single_probe uses /workspace fallback ─────────────
|
|
|
|
Scenario: Single probe falls back to /workspace when workspace_path is None
|
|
Given a mock devcontainer CLI runner
|
|
And an active container "01TESTLIFECYCLE0000000320" with container ID "ctr-t3"
|
|
When I run a single probe with no workspace_path set
|
|
Then the probe command should use "/workspace" as workspace folder
|
|
|
|
# ── T4: Health check thread join timeout ───────────────────
|
|
|
|
Scenario: Stopping health check joins thread with timeout
|
|
Given a mock devcontainer CLI runner
|
|
And an active container "01TESTLIFECYCLE0000000330" with container ID "ctr-t4"
|
|
And a running health check for "01TESTLIFECYCLE0000000330"
|
|
When I stop the health check for "01TESTLIFECYCLE0000000330"
|
|
Then the health check thread should have been joined
|
|
|
|
# ── F7: Concurrent stop_container ──────────────────────────
|
|
|
|
Scenario: Concurrent stop of the same container is handled safely
|
|
Given a mock devcontainer CLI runner
|
|
And an active container "01TESTLIFECYCLE0000000390" with container ID "ctr-cs"
|
|
When I stop the container concurrently from two threads
|
|
Then both stops should succeed
|
|
And the container state for "01TESTLIFECYCLE0000000390" should be "stopped"
|
|
And exactly 1 docker stop call should have been made
|
|
|
|
# ── R7-F3: Auto health check on activation ─────────────────
|
|
|
|
Scenario: Activation automatically starts health check
|
|
Given a mock devcontainer CLI runner
|
|
And the runner configured for successful activation
|
|
When I activate container "01TESTLIFECYCLE0000000620" at "/workspace/project"
|
|
Then the container state should be "running"
|
|
And a health check thread should be registered for "01TESTLIFECYCLE0000000620"
|
|
|
|
# ── F16: resolve() triggers lazy activation ─────────────────
|
|
|
|
Scenario: DevcontainerHandler.resolve triggers lazy activation for detected resource
|
|
Given a mock devcontainer CLI runner
|
|
And the runner configured for successful activation
|
|
And a lifecycle tracker for resource "01TESTLIFECYCLE0000000820"
|
|
When I resolve a devcontainer-instance "01TESTLIFECYCLE0000000820" at "/workspace/project"
|
|
Then the container state for "01TESTLIFECYCLE0000000820" should be "running"
|
|
|
|
Scenario: DevcontainerHandler.resolve skips activation for running resource
|
|
Given a mock devcontainer CLI runner
|
|
And an active container "01TESTLIFECYCLE0000000821" with container ID "ctr-resolve"
|
|
When I resolve a devcontainer-instance "01TESTLIFECYCLE0000000821" at "/workspace/project"
|
|
Then the container state for "01TESTLIFECYCLE0000000821" should be "running"
|
|
And the runner should not have received a devcontainer up call
|