Module: Perfgate::Policy::Engine
- Defined in:
- lib/perfgate/policy/engine.rb
Overview
Turns a comparison-result document (or the absence of one) into the PASS/WARN/FAIL/INCOMPARABLE decision and CI exit code baseline exits with (spec section 17):
0 PASS, or WARN under a non-blocking policy
1 Performance FAIL
2 Configuration error (raised directly by the CLI, not here)
3 Execution error (raised directly by the CLI, not here)
4 Missing baseline under a strict policy
5 Incompatible baseline under a strict policy
config.policy controls how "soft" signals (an incompatible
fingerprint, a new/removed workload) escalate into a hard FAIL --
every one of those keys defaults to "warn" (never blocking) and
only escalates when explicitly set to "fail".
Constant Summary collapse
- EXIT_CODES =
{ "pass" => 0, "warn" => 0, "fail" => 1, "missing_baseline" => 4, "incomparable" => 5 }.freeze
- ESCALATING_WORKLOAD_DECISIONS =
{ "new_workload" => :new_workload, "removed_workload" => :removed_workload, "incomparable" => :incompatible }.freeze
Class Method Summary collapse
- .evaluate(comparison_result:, config: Perfgate.configuration) ⇒ Object
-
.evaluate_missing_baseline(config: Perfgate.configuration) ⇒ Object
A separate entry point for the CLI: there is no comparison result at all when no prior baseline run could be found to compare against (spec section 17's exit code 4).
- .incompatible_status(config) ⇒ Object
- .metric_status(comparison_result, config) ⇒ Object
- .status_for(comparison_result, config) ⇒ Object
- .workload_escalation(comparison_result, config) ⇒ Object
Class Method Details
.evaluate(comparison_result:, config: Perfgate.configuration) ⇒ Object
27 28 29 30 |
# File 'lib/perfgate/policy/engine.rb', line 27 def evaluate(comparison_result:, config: Perfgate.configuration) status = status_for(comparison_result, config) { "status" => status, "exit_code" => EXIT_CODES.fetch(status) } end |
.evaluate_missing_baseline(config: Perfgate.configuration) ⇒ Object
A separate entry point for the CLI: there is no comparison result at all when no prior baseline run could be found to compare against (spec section 17's exit code 4).
35 36 37 38 |
# File 'lib/perfgate/policy/engine.rb', line 35 def evaluate_missing_baseline(config: Perfgate.configuration) status = config.policy[:missing_baseline] == "fail" ? "missing_baseline" : "warn" { "status" => status, "exit_code" => EXIT_CODES.fetch(status) } end |
.incompatible_status(config) ⇒ Object
49 50 51 |
# File 'lib/perfgate/policy/engine.rb', line 49 def incompatible_status(config) config.policy[:incompatible] == "fail" ? "incomparable" : "warn" end |
.metric_status(comparison_result, config) ⇒ Object
64 65 66 67 68 69 70 |
# File 'lib/perfgate/policy/engine.rb', line 64 def metric_status(comparison_result, config) case comparison_result["decision"] when "fail" then "fail" when "warn" then config.policy[:fail_on] == "warn" ? "fail" : "warn" else "pass" end end |
.status_for(comparison_result, config) ⇒ Object
40 41 42 43 44 45 46 47 |
# File 'lib/perfgate/policy/engine.rb', line 40 def status_for(comparison_result, config) return incompatible_status(config) if comparison_result["decision"] == "incompatible" escalation = workload_escalation(comparison_result, config) return escalation if escalation metric_status(comparison_result, config) end |
.workload_escalation(comparison_result, config) ⇒ Object
53 54 55 56 57 58 59 60 61 62 |
# File 'lib/perfgate/policy/engine.rb', line 53 def workload_escalation(comparison_result, config) workloads = comparison_result.fetch("workloads", []) ESCALATING_WORKLOAD_DECISIONS.each do |decision, policy_key| next unless config.policy[policy_key] == "fail" next unless workloads.any? { |w| w["decision"] == decision } return "fail" end nil end |