From eb67511c795fddffea9f365ac9da3b4294e7941f Mon Sep 17 00:00:00 2001 From: Beth Skurrie Date: Wed, 23 May 2018 13:41:14 +1000 Subject: [PATCH] feat: create view for latest verifications for consumer version tags --- .../20180311_optimise_head_matrix.rb | 1 + ...verifications_for_consumer_version_tags.rb | 24 ++++++++++ lib/pact_broker/matrix/row.rb | 14 ++++++ ...t_verification_for_consumer_version_tag.rb | 9 ++++ spec/lib/pact_broker/matrix/row_spec.rb | 46 +++++++++++++++++-- 5 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 db/migrations/20180523_create_latest_verifications_for_consumer_version_tags.rb create mode 100644 lib/pact_broker/verifications/latest_verification_for_consumer_version_tag.rb diff --git a/db/migrations/20180311_optimise_head_matrix.rb b/db/migrations/20180311_optimise_head_matrix.rb index 529f347db..3ff853dfe 100644 --- a/db/migrations/20180311_optimise_head_matrix.rb +++ b/db/migrations/20180311_optimise_head_matrix.rb @@ -16,6 +16,7 @@ ) # Add provider_version_order to original definition + # The most recent verification for each pact version v = :verifications create_or_replace_view(:latest_verifications, from(v) diff --git a/db/migrations/20180523_create_latest_verifications_for_consumer_version_tags.rb b/db/migrations/20180523_create_latest_verifications_for_consumer_version_tags.rb new file mode 100644 index 000000000..ade9fcef1 --- /dev/null +++ b/db/migrations/20180523_create_latest_verifications_for_consumer_version_tags.rb @@ -0,0 +1,24 @@ +Sequel.migration do + up do + # The latest verification id for each consumer version tag + create_view(:latest_verifications_ids_for_consumer_version_tags, + "select t.name as consumer_version_tag_name, max(lv.id) as latest_verification_id + from verifications lv + join latest_pact_publications_by_consumer_versions lpp + on lv.pact_version_id = lpp.pact_version_id + join tags t on lpp.consumer_version_id = t.version_id + group by t.name") + + # The latest verification for each consumer version tag + create_view(:latest_verifications_for_consumer_version_tags, + "select v.*, lv.consumer_version_tag_name + from verifications v + join latest_verifications_ids_for_consumer_version_tags lv + on lv.latest_verification_id = v.id") + end + + down do + drop_view(:latest_verifications_for_consumer_version_tags) + drop_view(:latest_verifications_ids_for_consumer_version_tags) + end +end diff --git a/lib/pact_broker/matrix/row.rb b/lib/pact_broker/matrix/row.rb index 1d9063a80..a19f9e702 100644 --- a/lib/pact_broker/matrix/row.rb +++ b/lib/pact_broker/matrix/row.rb @@ -2,9 +2,11 @@ require 'pact_broker/webhooks/latest_triggered_webhook' require 'pact_broker/tags/tag_with_latest_flag' require 'pact_broker/logging' +require 'pact_broker/verifications/latest_verification_for_consumer_version_tag' module PactBroker module Matrix + class Row < Sequel::Model(:materialized_matrix) # Used when using table_print to output query results @@ -14,6 +16,18 @@ class Row < Sequel::Model(:materialized_matrix) associate(:one_to_many, :webhooks, :class => "PactBroker::Webhooks::Webhook", primary_key: [:consumer_id, :provider_id], key: [:consumer_id, :provider_id]) associate(:one_to_many, :consumer_version_tags, :class => "PactBroker::Tags::TagWithLatestFlag", primary_key: :consumer_version_id, key: :version_id) associate(:one_to_many, :provider_version_tags, :class => "PactBroker::Tags::TagWithLatestFlag", primary_key: :provider_version_id, key: :version_id) + associate(:many_to_one, :verification, :class => "PactBroker::Domain::Verification", primary_key: :id, key: :verification_id) + + one_to_one :latest_verification_for_consumer_version_tag, primary_keys: [], key: [], :eager_loader=>(proc do |eo_opts| + tag_to_row = eo_opts[:rows].each_with_object({}) { | row, map | row.consumer_version_tags.each{ | tag | map[tag.name] = row } } + eo_opts[:rows].each{|row| row.associations[:latest_verification_for_consumer_version_tag] = nil} + + PactBroker::Verifications::LatestVerificationForConsumerVersionTag.each do | verification | + if tag_to_row[verification.consumer_version_tag_name] + tag_to_row[verification.consumer_version_tag_name].associations[:latest_verification_for_consumer_version_tag] = verification + end + end + end) dataset_module do include PactBroker::Repositories::Helpers diff --git a/lib/pact_broker/verifications/latest_verification_for_consumer_version_tag.rb b/lib/pact_broker/verifications/latest_verification_for_consumer_version_tag.rb new file mode 100644 index 000000000..2c07b4541 --- /dev/null +++ b/lib/pact_broker/verifications/latest_verification_for_consumer_version_tag.rb @@ -0,0 +1,9 @@ +require 'pact_broker/domain/verification' + +module PactBroker + module Verifications + class LatestVerificationForConsumerVersionTag < PactBroker::Domain::Verification + set_dataset(:latest_verifications_for_consumer_version_tags) + end + end +end \ No newline at end of file diff --git a/spec/lib/pact_broker/matrix/row_spec.rb b/spec/lib/pact_broker/matrix/row_spec.rb index 75a364d26..d59d45ac8 100644 --- a/spec/lib/pact_broker/matrix/row_spec.rb +++ b/spec/lib/pact_broker/matrix/row_spec.rb @@ -3,14 +3,54 @@ module PactBroker module Matrix describe Row do - describe "refresh", migration: true do - before do - PactBroker::Database.migrate + let(:td) { TestDataBuilder.new } + + describe "latest_verification_for_consumer_version_tag" do + context "when the pact with a given tag has been verified" do + before do + td.create_pact_with_hierarchy("Foo", "1", "Bar") + .create_consumer_version_tag("prod") + .create_verification(provider_version: "10") + .create_consumer_version("2") + .create_consumer_version_tag("prod") + .create_pact + .create_verification(provider_version: "11", number: 1) + .create_verification(provider_version: "12", number: 2) + end + + subject { Row.eager(:consumer_version_tags).eager(:latest_verification_for_consumer_version_tag).order(:pact_publication_id, :verification_id).all } + + it "returns its most recent verification" do + expect(subject.last.provider_version_number).to eq "12" + expect(subject.last.latest_verification_for_consumer_version_tag.provider_version.number).to eq "12" + end + end + + context "when the most recent pact with a given tag has not been verified, but a previous version with the same tag has" do + before do + td.create_pact_with_hierarchy("Foo", "1", "Bar") + .create_consumer_version_tag("prod") + .create_verification(provider_version: "10") + .create_verification(provider_version: "11", number: 2, comment: "this is the latest verification for a pact with cv tag prod") + .create_consumer_version("2") + .create_consumer_version_tag("prod") + .create_pact + end + + subject { Row.eager(:consumer_version_tags).eager(:latest_verification_for_consumer_version_tag).order(:pact_publication_id).all } + + it "returns the most recent verification for the previous version with the same tag" do + expect(subject.last.verification_id).to be nil # this pact version has not been verified directly + expect(subject.last.latest_verification_for_consumer_version_tag.provider_version.number).to eq "11" + end end + end + describe "refresh", migration: true do let(:td) { TestDataBuilder.new(auto_refresh_matrix: false) } before do + PactBroker::Database.migrate td.create_pact_with_hierarchy("Foo", "1", "Bar") end