57fcc880c3
ISSUES CLOSED: #176
146 lines
7.3 KiB
Gherkin
146 lines
7.3 KiB
Gherkin
Feature: Validation apply gate
|
|
As a plan executor
|
|
I want attached validations to run before apply
|
|
So that required validation failures block apply
|
|
|
|
Background:
|
|
Given a validation apply test environment
|
|
|
|
# -- Attachment model ----------------------------------------------------
|
|
|
|
Scenario: Create a required validation attachment
|
|
Given a validation attachment "lint-check" for resource "res-001" with mode "required"
|
|
Then the attachment mode should be "required"
|
|
And the attachment scope should be "direct"
|
|
|
|
Scenario: Create an informational validation attachment
|
|
Given a validation attachment "style-check" for resource "res-002" with mode "informational"
|
|
Then the attachment mode should be "informational"
|
|
|
|
Scenario: Create a project-scoped attachment
|
|
Given a project-scoped attachment "lint-check" for resource "res-001" targeting "my-project"
|
|
Then the attachment scope should be "project"
|
|
And the attachment scope target should be "my-project"
|
|
|
|
Scenario: Create a plan-scoped attachment
|
|
Given a plan-scoped attachment "lint-check" for resource "res-001" targeting "01PLAN0001"
|
|
Then the attachment scope should be "plan"
|
|
And the attachment scope target should be "01PLAN0001"
|
|
|
|
# -- DefaultValidationRunner ---------------------------------------------
|
|
|
|
Scenario: DefaultValidationRunner passes when context matches
|
|
Given a validation attachment "lint-check" for resource "res-001" with mode "required"
|
|
And a validation run context with key "lint-check" and value "passed"
|
|
When I execute the validation with DefaultValidationRunner
|
|
Then the validation result should be passed
|
|
|
|
Scenario: DefaultValidationRunner fails when context has no match
|
|
Given a validation attachment "lint-check" for resource "res-001" with mode "required"
|
|
And a validation run context with key "status" and value "no matches"
|
|
When I execute the validation with DefaultValidationRunner
|
|
Then the validation result should be failed
|
|
|
|
Scenario: DefaultValidationRunner matches via arguments
|
|
Given a validation attachment "coverage-check" for resource "res-001" with mode "required"
|
|
And the attachment has argument "threshold" with value "90"
|
|
And a validation run context with key "coverage" and value "90 percent"
|
|
When I execute the validation with DefaultValidationRunner
|
|
Then the validation result should be passed
|
|
|
|
# -- ApplyValidationSummary ----------------------------------------------
|
|
|
|
Scenario: Summary all required passed with no failures
|
|
Given an apply validation summary with 2 required passed and 0 required failed
|
|
Then the apply summary should report all required passed
|
|
And the apply summary total should be 2
|
|
|
|
Scenario: Summary blocked when required failure exists
|
|
Given an apply validation summary with 1 required passed and 1 required failed
|
|
Then the apply summary should not report all required passed
|
|
And the apply summary required failed count should be 1
|
|
|
|
Scenario: Summary with informational results does not block
|
|
Given an apply validation summary with 0 required passed and 0 required failed
|
|
And the summary has 1 informational passed and 1 informational failed
|
|
Then the apply summary should report all required passed
|
|
And the apply summary informational failed count should be 1
|
|
|
|
Scenario: Empty summary reports all required passed
|
|
Given an empty apply validation summary
|
|
Then the apply summary should be empty
|
|
And the apply summary should report all required passed
|
|
|
|
Scenario: Summary to_plan_metadata has expected fields
|
|
Given an apply validation summary with 1 required passed and 1 required failed
|
|
Then the plan metadata should have key "total"
|
|
And the plan metadata should have key "all_required_passed"
|
|
And the plan metadata should have key "results"
|
|
|
|
Scenario: Summary format_cli_output shows BLOCKED on failures
|
|
Given an apply validation summary with 0 required passed and 1 required failed
|
|
Then the validation gate CLI output should contain "BLOCKED"
|
|
|
|
Scenario: Summary format_cli_output shows no details when neither message nor error
|
|
Given an apply validation summary with a bare failure result
|
|
Then the validation gate CLI output should contain "no details"
|
|
|
|
Scenario: Summary format_cli_output shows error in failure detail
|
|
Given an apply validation summary with an error result
|
|
Then the validation gate CLI output should contain "execution timed out"
|
|
|
|
Scenario: Summary format_cli_output shows PASSED when all pass
|
|
Given an apply validation summary with 2 required passed and 0 required failed
|
|
Then the validation gate CLI output should contain "PASSED"
|
|
|
|
Scenario: DefaultValidationRunner populates duration_ms
|
|
Given a validation attachment "lint-check" for resource "res-001" with mode "required"
|
|
And a validation run context with key "lint-check" and value "passed"
|
|
When I execute the validation with DefaultValidationRunner
|
|
Then the validation result duration_ms should be >= 0
|
|
|
|
Scenario: DefaultValidationRunner handles exception during execution
|
|
Given a validation attachment "err-val" for resource "res-err" with mode "required"
|
|
And a validation run context that raises an error during iteration
|
|
When I execute the validation with DefaultValidationRunner
|
|
Then the validation result should be failed
|
|
And the validation result should have an error message
|
|
|
|
# -- ApplyValidationGate -------------------------------------------------
|
|
|
|
Scenario: Gate allows apply when all required pass
|
|
Given a validation attachment "lint-check" for resource "res-001" with mode "required"
|
|
And a validation run context with key "lint-check" and value "ok"
|
|
When I run the apply validation gate for plan "01PLAN0001"
|
|
Then the gate should allow apply
|
|
|
|
Scenario: Gate blocks apply when required validation fails
|
|
Given a validation attachment "lint-check" for resource "res-001" with mode "required"
|
|
And a validation run context with key "other" and value "irrelevant"
|
|
When I run the apply validation gate for plan "01PLAN0001"
|
|
Then the gate should block apply
|
|
And the gate failure reasons should mention "lint-check"
|
|
|
|
Scenario: Gate allows apply despite informational failures
|
|
Given a validation attachment "style-check" for resource "res-001" with mode "informational"
|
|
And a validation run context with key "other" and value "irrelevant"
|
|
When I run the apply validation gate for plan "01PLAN0001"
|
|
Then the gate should allow apply
|
|
|
|
Scenario: Gate with multiple attachments mixed results
|
|
Given a validation attachment "lint-check" for resource "res-001" with mode "required"
|
|
And a validation attachment "style-check" for resource "res-001" with mode "informational"
|
|
And a validation run context with key "lint-check" and value "passed"
|
|
When I run the apply validation gate for plan "01PLAN0001"
|
|
Then the gate should allow apply
|
|
And the apply summary total should be 2
|
|
|
|
Scenario: Gate failure reasons include error text when result has error
|
|
Given an apply validation summary with an error result
|
|
Then the gate failure reasons should mention "error:"
|
|
|
|
Scenario: Gate with no attachments allows apply
|
|
When I run the apply validation gate for plan "01PLAN0001" with no attachments
|
|
Then the gate should allow apply
|
|
And the apply summary should be empty
|