forked from pact-foundation/pact_broker
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: allow limit to be applied to clean task
- Loading branch information
Showing
13 changed files
with
287 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
require 'pact_broker/api/resources/base_resource' | ||
require 'pact_broker/db/clean' | ||
require 'pact_broker/matrix/unresolved_selector' | ||
|
||
module PactBroker | ||
module Api | ||
module Resources | ||
class Clean < BaseResource | ||
def content_types_accepted | ||
[["application/json"]] | ||
end | ||
|
||
def content_types_provided | ||
[["application/hal+json"]] | ||
end | ||
|
||
def allowed_methods | ||
["POST", "OPTIONS"] | ||
end | ||
|
||
def process_post | ||
keep_selectors = (params[:keep] || []).collect do | hash | | ||
PactBroker::Matrix::UnresolvedSelector.new(hash) | ||
end | ||
|
||
result = PactBroker::DB::Clean.call(Sequel::Model.db, { keep: keep_selectors }) | ||
response.body = result.to_json | ||
end | ||
|
||
def policy_name | ||
:'integrations::clean' | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
require 'pact_broker/logging' | ||
require 'pact_broker/matrix/unresolved_selector' | ||
|
||
module PactBroker | ||
module DB | ||
class CleanIncremental | ||
include PactBroker::Logging | ||
|
||
DEFAULT_KEEP_SELECTORS = [ | ||
PactBroker::Matrix::UnresolvedSelector.new(tag: true, latest: true), | ||
PactBroker::Matrix::UnresolvedSelector.new(latest: true), | ||
PactBroker::Matrix::UnresolvedSelector.new(max_age: 90) | ||
] | ||
TABLES = [:versions, :pact_publications, :pact_versions, :verifications, :triggered_webhooks, :webhook_executions] | ||
|
||
def self.call database_connection, options = {} | ||
new(database_connection, options).call | ||
end | ||
|
||
def initialize database_connection, options = {} | ||
@db = database_connection | ||
@options = options | ||
end | ||
|
||
def keep | ||
options[:keep] || DEFAULT_KEEP_SELECTORS | ||
end | ||
|
||
def limit | ||
options[:limit] || 1000 | ||
end | ||
|
||
def resolve_ids(query, column_name = :id) | ||
query.collect { |h| h[column_name] } | ||
end | ||
|
||
def version_ids_to_delete | ||
db[:versions].where(id: version_ids_to_keep).invert.limit(limit).order(Sequel.asc(:id)) | ||
end | ||
|
||
def version_ids_to_keep | ||
@version_ids_to_keep ||= keep.collect do | selector | | ||
PactBroker::Domain::Version.select(:id).for_selector(selector) | ||
end.reduce(&:union) | ||
end | ||
|
||
def call | ||
require 'pact_broker/domain/version' | ||
before_counts = current_counts | ||
|
||
result = PactBroker::Domain::Version.where(id: resolve_ids(version_ids_to_delete)).delete | ||
delete_orphan_pact_versions | ||
|
||
after_counts = current_counts | ||
|
||
TABLES.each_with_object({}) do | table_name, comparison_counts | | ||
comparison_counts[table_name.to_s] = { "deleted" => before_counts[table_name] - after_counts[table_name], "kept" => after_counts[table_name] } | ||
end | ||
end | ||
|
||
private | ||
|
||
attr_reader :db, :options | ||
|
||
def current_counts | ||
TABLES.each_with_object({}) do | table_name, counts | | ||
counts[table_name] = db[table_name].count | ||
end | ||
end | ||
|
||
def delete_orphan_pact_versions | ||
logger.info("Deleting orphan pact versions") | ||
referenced_pact_version_ids = db[:pact_publications].select(:pact_version_id).union(db[:verifications].select(:pact_version_id)) | ||
db[:pact_versions].where(id: referenced_pact_version_ids).invert.delete | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
require 'pact_broker/db/clean_incremental' | ||
require 'pact_broker/matrix/unresolved_selector' | ||
|
||
IS_MYSQL = !!DB.mysql? | ||
|
||
module PactBroker | ||
module DB | ||
# Inner queries don't work on MySQL. Seriously, MySQL??? | ||
describe CleanIncremental, pending: IS_MYSQL do | ||
|
||
def pact_publication_count_for(consumer_name, version_number) | ||
PactBroker::Pacts::PactPublication.where(consumer_version: PactBroker::Domain::Version.where_pacticipant_name(consumer_name).where(number: version_number)).count | ||
end | ||
|
||
let(:options) { {} } | ||
let(:db) { PactBroker::DB.connection } | ||
|
||
subject { CleanIncremental.call(PactBroker::DB.connection, options) } | ||
let(:latest_dev_selector) { PactBroker::Matrix::UnresolvedSelector.new(tag: "dev", latest: true) } | ||
let(:all_prod_selector) { PactBroker::Matrix::UnresolvedSelector.new(tag: "prod") } | ||
let(:limit) { 3 } | ||
|
||
describe ".call"do | ||
context "when there are specified versions to keep" do | ||
before do | ||
td.create_pact_with_hierarchy("Foo", "1", "Bar") | ||
.create_consumer_version_tag("prod").comment("keep as one of prod") | ||
.create_consumer_version_tag("dev") | ||
.add_day | ||
.create_consumer_version("2").comment("DELETE") | ||
.add_day | ||
.create_consumer_version("3", tag_names: %w{prod}).comment("keep as one of prod") | ||
.create_pact | ||
.add_day | ||
.create_consumer_version("4", tag_names: %w{dev}).comment("DELETE as not latest") | ||
.create_pact | ||
.add_day | ||
.create_consumer_version("5", tag_names: %w{dev}).comment("keep as latest dev") | ||
.create_pact | ||
.add_day | ||
.create_consumer_version("6", tag_names: %w{foo}).comment("DELETE as not specified") | ||
.create_pact | ||
.add_day | ||
.create_consumer_version("7").comment("keep as deletion limit is 3") | ||
.create_pact | ||
end | ||
|
||
let(:options) { { keep: [all_prod_selector, latest_dev_selector], limit: limit } } | ||
|
||
it "does not delete the consumer versions specified" do | ||
expect(PactBroker::Domain::Version.where(number: "1").count).to be 1 | ||
expect(PactBroker::Domain::Version.where(number: "2").count).to be 1 | ||
expect(PactBroker::Domain::Version.where(number: "3").count).to be 1 | ||
expect(PactBroker::Domain::Version.where(number: "4").count).to be 1 | ||
expect(PactBroker::Domain::Version.where(number: "5").count).to be 1 | ||
expect(PactBroker::Domain::Version.where(number: "6").count).to be 1 | ||
expect(PactBroker::Domain::Version.where(number: "7").count).to be 1 | ||
subject | ||
expect(PactBroker::Domain::Version.where(number: "1").count).to be 1 | ||
expect(PactBroker::Domain::Version.where(number: "2").count).to be 0 | ||
expect(PactBroker::Domain::Version.where(number: "3").count).to be 1 | ||
expect(PactBroker::Domain::Version.where(number: "4").count).to be 0 | ||
expect(PactBroker::Domain::Version.where(number: "5").count).to be 1 | ||
expect(PactBroker::Domain::Version.where(number: "6").count).to be 0 | ||
expect(PactBroker::Domain::Version.where(number: "7").count).to be 1 | ||
end | ||
end | ||
|
||
context "with orphan pact versions" do | ||
before do | ||
# Create a pact that will not be deleted | ||
td.create_pact_with_hierarchy("Foo", "0", "Bar", json_content_1) | ||
.create_consumer_version_tag("dev") | ||
# Create an orphan pact version | ||
pact_version_params = PactBroker::Pacts::PactVersion.first.to_hash | ||
pact_version_params.delete(:id) | ||
pact_version_params[:sha] = "1234" | ||
PactBroker::Pacts::PactVersion.create(pact_version_params) | ||
end | ||
|
||
let(:json_content_1) { { interactions: ['a', 'b']}.to_json } | ||
let(:json_content_2) { { interactions: ['a', 'c']}.to_json } | ||
|
||
let(:options) { { keep: [latest_dev_selector] } } | ||
|
||
it "deletes them" do | ||
expect { subject }.to change { PactBroker::Pacts::PactVersion.count }.by(-1) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
Oops, something went wrong.