137 lines
5.7 KiB
Markdown
137 lines
5.7 KiB
Markdown
# host-agent-dependency-supervisor Specification
|
|
|
|
## Purpose
|
|
|
|
Define optional Appium supervision by the Host Agent, including opt-in
|
|
activation, adoption of healthy instances, bounded restart behavior, and
|
|
cleanup tied to the Host Agent lifecycle.
|
|
|
|
## Requirements
|
|
|
|
### Requirement: Supervisor is opt-in and disabled by default
|
|
|
|
The Host Agent SHALL NOT start, adopt-check, or supervise Appium unless
|
|
`HOST_AGENT_DEPENDENCY_SUPERVISOR_ENABLED` is explicitly set to true. Appium
|
|
supervision SHALL additionally require `HOST_AGENT_APPIUM_SUPERVISED=true`
|
|
and SHALL default to false.
|
|
|
|
#### Scenario: Default configuration behaves exactly as before
|
|
|
|
- **WHEN** a Host Agent starts with no
|
|
`HOST_AGENT_DEPENDENCY_SUPERVISOR_ENABLED` or related Appium environment
|
|
variable set
|
|
- **THEN** the Host Agent does not attempt to connect to, probe, or spawn
|
|
Appium, and its heartbeat/claim behavior is unchanged
|
|
|
|
#### Scenario: Top-level flag on and Appium flag off
|
|
|
|
- **WHEN** `HOST_AGENT_DEPENDENCY_SUPERVISOR_ENABLED=true` and
|
|
`HOST_AGENT_APPIUM_SUPERVISED=false`
|
|
- **THEN** the Host Agent does not probe, adopt, or spawn Appium
|
|
|
|
### Requirement: Adopt an already-running, healthy Appium instance instead of spawning a duplicate
|
|
|
|
Before spawning supervised Appium, the Host Agent SHALL attempt a TCP
|
|
connection to its configured host and port and, if something is listening,
|
|
perform the Appium status health check. If the health check succeeds, the Host
|
|
Agent SHALL treat the existing process as adopted, SHALL NOT spawn a subprocess
|
|
for it, and SHALL NOT restart or terminate it at any point in its lifecycle.
|
|
|
|
#### Scenario: Appium already running and healthy
|
|
|
|
- **WHEN** Appium supervision is enabled and a healthy Appium server is already
|
|
listening on the configured host and port
|
|
- **THEN** the Host Agent logs that it adopted the existing instance and does
|
|
not spawn a new Appium process
|
|
|
|
#### Scenario: Port occupied by something unhealthy or unrelated
|
|
|
|
- **WHEN** the configured Appium port has a listener that does not pass the
|
|
health check
|
|
- **THEN** the Host Agent logs an error identifying the port conflict, does
|
|
not spawn a subprocess, and does not treat Appium as available
|
|
|
|
### Requirement: Spawn supervised Appium when it is not already running
|
|
|
|
The Host Agent SHALL spawn Appium as a child process when Appium supervision is
|
|
enabled and no healthy Appium instance is adopted, via
|
|
`appium --address <host> --port <port>`, and SHALL forward the child
|
|
process's stdout/stderr into the Host Agent's own logging, tagged by dependency
|
|
name.
|
|
|
|
#### Scenario: Appium is not running at Host Agent startup
|
|
|
|
- **WHEN** Appium supervision is enabled and no healthy Appium instance is
|
|
already listening
|
|
- **THEN** the Host Agent spawns Appium before proceeding to its first
|
|
device-connect attempt, and its output is visible in Host Agent logs
|
|
|
|
#### Scenario: Spawn fails because the executable is missing
|
|
|
|
- **WHEN** the Host Agent attempts to spawn Appium but `appium` is not found
|
|
on `PATH`
|
|
- **THEN** the Host Agent logs a dependency-supervisor-specific startup error
|
|
naming the missing dependency, distinct from a runtime crash of an
|
|
already-started process
|
|
|
|
### Requirement: Restart only Appium processes the supervisor itself spawned, with bounded backoff
|
|
|
|
The Host Agent SHALL restart supervised Appium automatically only if its own
|
|
child process handle exits unexpectedly. Restart attempts SHALL use capped
|
|
exponential backoff and SHALL stop permanently for the remaining Host Agent
|
|
process lifetime once `HOST_AGENT_DEPENDENCY_RESTART_MAX_ATTEMPTS` is
|
|
reached. The Host Agent SHALL NOT restart or terminate an Appium instance it
|
|
adopted rather than spawned.
|
|
|
|
#### Scenario: Spawned Appium process crashes
|
|
|
|
- **WHEN** a Host Agent-spawned Appium child process exits unexpectedly and
|
|
the restart attempt count is below the configured maximum
|
|
- **THEN** the Host Agent waits the current backoff interval and attempts to
|
|
spawn Appium again
|
|
|
|
#### Scenario: Restart attempts exhausted
|
|
|
|
- **WHEN** a supervised Appium process has crashed and been restarted until
|
|
reaching `HOST_AGENT_DEPENDENCY_RESTART_MAX_ATTEMPTS`
|
|
- **THEN** the Host Agent logs that it has given up restarting Appium and does
|
|
not attempt to spawn it again for the rest of the current process lifetime
|
|
|
|
#### Scenario: Adopted Appium exits
|
|
|
|
- **WHEN** an Appium instance the Host Agent adopted stops running
|
|
- **THEN** the Host Agent does not attempt to restart it, since it never held
|
|
a child process handle
|
|
|
|
### Requirement: Supervisor lifecycle is tied to Host Agent process lifecycle
|
|
|
|
The Host Agent SHALL start enabled, not-yet-healthy supervised Appium before
|
|
beginning its normal device-connect, heartbeat, and claim sequence, and SHALL
|
|
stop Appium processes it spawned, but not ones it adopted, during graceful
|
|
shutdown.
|
|
|
|
#### Scenario: Host Agent shuts down gracefully
|
|
|
|
- **WHEN** the Host Agent receives a shutdown signal while it holds a child
|
|
process handle for a spawned Appium instance
|
|
- **THEN** the Host Agent terminates that Appium child process as part of its
|
|
shutdown sequence
|
|
|
|
#### Scenario: Host Agent shuts down while adopted Appium is running
|
|
|
|
- **WHEN** the Host Agent shuts down and Appium was adopted rather than spawned
|
|
- **THEN** the adopted Appium process is left running, untouched, after the
|
|
Host Agent exits
|
|
|
|
### Requirement: Runtime supervision settings are retired
|
|
|
|
The Host Agent SHALL reject `HOST_AGENT_RUNTIME_SUPERVISED`,
|
|
`HOST_AGENT_RUNTIME_HOST`, and `HOST_AGENT_RUNTIME_PORT` because the
|
|
standalone Runtime service no longer exists.
|
|
|
|
#### Scenario: A legacy Runtime supervision variable is set
|
|
|
|
- **WHEN** startup configuration includes any removed Runtime supervision
|
|
variable
|
|
- **THEN** configuration fails with an actionable migration error
|