Layer Architecture¶
The layers below form the core design of the framework. They remain stable regardless of execution mode or deployment environment.
This framework is built on a clear, layered structure that keeps BDD intent clean, execution flexible, and behaviour consistent across environments.
The primary focus is separation of responsibilities.
1. BDD Step Layer¶
Purpose:
Translate human‑readable Gherkin (Given/When/Then) into high‑level actions.
Characteristics:
- Express what should happen, never how
- Use fixtures to access orchestrators/services
- Contain no environment or infrastructure logic
- Steps rely on fixtures, not execution logic, ensuring portability across environments.
2. Orchestrator Layer (Lifecycle)¶
Purpose:
Coordinate multi‑step workflows such as:
- Submit → Poll → Check result
- Trigger job → Monitor logs
- API call → Await completion
Responsibilities:
- Manage workflow lifecycle
- Implement polling behaviour
- Aggregate responses for tests
Not responsible for:
- Running commands
- Parsing raw output
- Choosing execution mode
3. Service Layer (Coordination)¶
Purpose:
Build commands, call executors, and return structured data.
Responsibilities:
- Construct
Commandobjects - Invoke the configured executor
- Wrap output in
CLIResponse - Convert raw output using lightweight parsing (built‑in or model‑driven); ParserFactory is optional and used only when needed.
- Convert responses into domain models
This keeps orchestrators simple and free of execution details.
4. Domain Models & Configuration Layer¶
Purpose:
Typed, validated objects that define:
- WorkflowRequest
- WorkflowResponse
- Command models
- Environment configuration
- Executor selection
Characteristics:
- Pydantic‑style typed modelling
- Strict validation of input and output
- Safe serialisation for logs/traceability
- Response models can be extended (e.g., JSON, text, log formats) without breaking API contracts.
Domain models shield the rest of the system from raw, untyped input.
5. Executor Layer (Execution Strategy)¶
Executors define how commands run:
- Local subprocess
- Remote SSH / SSM
- API‑driven job runner
- Container‑based executor
Executors return raw output only; they do not interpret results.
Key point:
Execution strategies are swappable at runtime through configuration.
6. Tooling & Infrastructure Support Layer¶
This layer includes integrations such as:
- Cloud SDK helpers
- Container/job submission adapters
- Secure‑environment helpers (Kerberos, tokens, etc.)
These are optional technical enablers — not part of the core BDD logic.
7. Local vs Remote (Context, Not a Layer)¶
Local/remote is simply about where commands run, not a dedicated layer.
- Local: Executor runs commands inside the target environment
- Remote: Executor relays commands from outside (e.g., dev laptop)
It is a configuration choice, not an architectural building block.
Layer Interaction Overview¶
graph TD
Step[BDD Step Layer] --> Orch[Orchestrator]
Orch --> Svc[Service Layer]
Svc --> Exec[Executor - selected by config]
Svc --> Models[Domain Models & Config]
Exec --> RunEnv[Execution Context - local or remote] Benefits of the Layered Model¶
- Predictable, understandable structure
- Clean separation of concerns
- Environment‑agnostic test behaviour
- Plug‑and‑play executors
- Typed, model‑driven interactions
- Extensible without breaking tests
- Execution context flexibility without architectural disruption
This is the full architecture — robust, generic, and ready for secure cloud environments.