Module: Perfgate::Comparison::Engine
- Defined in:
- lib/perfgate/comparison/engine.rb
Overview
Builds the schema_version 1 comparison-result document (spec section 14.2) from a baseline run-result and a candidate run-result. This is the seam between the fingerprinting/statistics primitives and the CLI: it never touches storage or exit codes (that's Policy::Engine's job), only produces the structured decision document.
Compatibility is checked first (spec section 15): when the runs are incompatible, no per-workload metric decisions are computed at all -- Baseline never silently compares runs it can't vouch for.
Constant Summary collapse
- SCHEMA_VERSION =
1
Class Method Summary collapse
- .build_document(baseline_run, candidate_run, compatibility, workloads) ⇒ Object
- .compare(baseline_run:, candidate_run:, config: Perfgate.configuration) ⇒ Object
- .diagnostics(baseline_run, candidate_run, compatibility) ⇒ Object
- .evaluate_compatibility(baseline_run, candidate_run, config) ⇒ Object
- .overall_decision(compatibility, workloads) ⇒ Object
- .workloads_for(compatibility, baseline_run, candidate_run, config) ⇒ Object
Class Method Details
.build_document(baseline_run, candidate_run, compatibility, workloads) ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/perfgate/comparison/engine.rb', line 31 def build_document(baseline_run, candidate_run, compatibility, workloads) { "schema_version" => SCHEMA_VERSION, "baseline_run_id" => baseline_run["run_id"], "candidate_run_id" => candidate_run["run_id"], "compatibility" => compatibility, "decision" => overall_decision(compatibility, workloads), "workloads" => workloads, "diagnostics" => diagnostics(baseline_run, candidate_run, compatibility) } end |
.compare(baseline_run:, candidate_run:, config: Perfgate.configuration) ⇒ Object
24 25 26 27 28 29 |
# File 'lib/perfgate/comparison/engine.rb', line 24 def compare(baseline_run:, candidate_run:, config: Perfgate.configuration) compatibility = evaluate_compatibility(baseline_run, candidate_run, config) workloads = workloads_for(compatibility, baseline_run, candidate_run, config) build_document(baseline_run, candidate_run, compatibility, workloads) end |
.diagnostics(baseline_run, candidate_run, compatibility) ⇒ Object
66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/perfgate/comparison/engine.rb', line 66 def diagnostics(baseline_run, candidate_run, compatibility) diagnostics = [] diagnostics << { "code" => "empty_baseline", "message" => "baseline run has no workloads" } if baseline_run.fetch("workloads", []).empty? diagnostics << { "code" => "empty_candidate", "message" => "candidate run has no workloads" } if candidate_run.fetch("workloads", []).empty? Diagnostics.environment_changed_rules(compatibility).each do || diagnostics << { "code" => "environment_changed", "message" => } end diagnostics end |
.evaluate_compatibility(baseline_run, candidate_run, config) ⇒ Object
49 50 51 52 53 54 |
# File 'lib/perfgate/comparison/engine.rb', line 49 def evaluate_compatibility(baseline_run, candidate_run, config) Fingerprints::Compatibility.evaluate( baseline_components: baseline_run.fetch("fingerprint", {}), candidate_components: candidate_run.fetch("fingerprint", {}), config: config ) end |
.overall_decision(compatibility, workloads) ⇒ Object
56 57 58 59 60 61 62 63 64 |
# File 'lib/perfgate/comparison/engine.rb', line 56 def overall_decision(compatibility, workloads) return "incompatible" if compatibility["status"] == "incompatible" decisions = workloads.map { |w| w["decision"] } return "fail" if decisions.include?("fail") return "warn" if decisions.intersect?(%w[warn incomparable removed_workload new_workload]) "pass" end |
.workloads_for(compatibility, baseline_run, candidate_run, config) ⇒ Object
43 44 45 46 47 |
# File 'lib/perfgate/comparison/engine.rb', line 43 def workloads_for(compatibility, baseline_run, candidate_run, config) return [] if compatibility["status"] == "incompatible" WorkloadComparison.compare_all(baseline_run, candidate_run, config) end |