class PactBroker::Matrix::DeploymentStatusSummary
Attributes
Public Class Methods
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 14 def initialize(query_results) @query_results = query_results @all_rows = query_results.rows @dummy_selectors = create_dummy_selectors end
Public Instance Methods
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 20 def counts { success: considered_rows.count(&:success), failed: considered_rows.count { |row| row.success == false }, unknown: required_integrations_without_a_row.count + considered_rows.count { |row| row.success.nil? }, ignored: resolved_ignore_selectors.any? ? ignored_rows.count : nil }.compact end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 29 def deployable? return false if considered_specified_selectors_that_do_not_exist.any? return nil if considered_rows.any?{ |row| row.success.nil? } return nil if required_integrations_without_a_row.any? considered_rows.all?(&:success) # true if considered_rows is empty end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 36 def reasons error_messages.any? ? warning_messages + error_messages : warning_messages + success_messages end
Private Instance Methods
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 62 def bad_practice_warnings warnings = [] if no_to_tag_or_environment_specified? warnings << NoEnvironmentSpecified.new end if selector_without_pacticipant_version_number_specified? warnings << SelectorWithoutPacticipantVersionNumberSpecified.new end warnings end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 98 def considered_specified_selectors_that_do_not_exist resolved_selectors.select(&:consider?).select(&:specified_version_that_does_not_exist?) end
When the user has not specified a version of the provider (eg no 'latest' and/or 'tag', which means 'all versions') so the “add inferred selectors” code in the Matrix::Repository
has not run, we may end up with considered_rows for which we do not have a selector. To solve this, create dummy selectors from the row and integration data.
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 208 def create_dummy_selectors (dummy_selectors_from_considered_rows + dummy_selectors_from_integrations).uniq end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 220 def dummy_selectors_from_considered_rows considered_rows.collect do | row | dummy_consumer_selector = ResolvedSelector.for_pacticipant_and_version(row.consumer, row.consumer_version, {}, :inferred, false) dummy_provider_selector = row.provider_version ? ResolvedSelector.for_pacticipant_and_version(row.provider, row.provider_version, {}, :inferred, false) : ResolvedSelector.for_pacticipant(row.provider, {}, :inferred, false) [dummy_consumer_selector, dummy_provider_selector] end.flatten end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 212 def dummy_selectors_from_integrations integrations.collect do | row | dummy_consumer_selector = ResolvedSelector.for_pacticipant(row.consumer, {}, :inferred, false) dummy_provider_selector = ResolvedSelector.for_pacticipant(row.provider, {}, :inferred, false) [dummy_consumer_selector, dummy_provider_selector] end.flatten end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 44 def error_messages @error_messages ||= begin messages = [] messages.concat(specified_selectors_do_not_exist_messages) if messages.empty? messages.concat(missing_reasons) messages.concat(failure_messages) messages.concat(not_ever_verified_reasons) end messages.uniq end end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 114 def failure_messages considered_rows.select{ |row| row.success == false }.collect { | row | VerificationFailed.new(*selectors_for(row)) } end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 159 def log_required_integrations_without_a_row_occurred integrations logger.info("required_integrations_without_a_row returned non empty", payload: { integrations: integrations, considered_rows: considered_rows }) end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 167 def missing_reasons required_integrations_without_a_row.collect do | integration | pact_not_verified_by_required_provider_version(integration) end.flatten end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 183 def missing_specified_version_reasons(selectors) selectors.collect(&:version_does_not_exist_description) end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 86 def more_than_one_selector_specified? # If only the pacticipant name is specified, it can't be a can-i-deploy query, must be a matrix UI query resolved_selectors .select(&:specified?) .reject(&:only_pacticipant_name_specified?) .any? end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 94 def no_to_tag_or_environment_specified? !(query_results.options[:tag] || query_results.options[:environment_name]) end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 110 def not_ever_verified_reasons considered_rows.select{ | row | row.success.nil? }.collect{ |row | pact_not_ever_verified_by_provider(row) } end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 191 def pact_not_ever_verified_by_provider(row) PactNotEverVerifiedByProvider.new(*selectors_for(row)) end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 187 def pact_not_verified_by_required_provider_version(integration) PactNotVerifiedByRequiredProviderVersion.new(*selectors_for(integration)) end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 244 def report_missing_interaction_verifications(messages) logger.warn("Interactions missing verifications", messages) end
For deployment, the consumer requires the provider, but the provider does not require the consumer This method tells us which providers are missing. Technically, it tells us which integrations do not have a row because the pact that belongs to the consumer version has in fact been verified, but not by the provider version specified in the query (because left outer join)
Imagine query for deploying Foo v3 to prod with the following matrix: Foo v2 -> Bar v1 (latest prod) [this line not included because CV doesn't match] Foo v3 -> Bar v2 [this line not included because PV doesn't match]
No matrix considered_rows would be returned. This method identifies that we have no row for the Foo -> Bar integration, and therefore cannot deploy Foo. However, if we were to try and deploy the provider, Bar, that would be ok as Bar does not rely on Foo, so this method would not return that integration. UPDATE: The matrix query now returns a row with blank provider version/verification fields so the above comment is now redundant. I'm not sure if this piece of code can ever return a list with anything in it any more. Will log it for a while and see.
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 151 def required_integrations_without_a_row @required_integrations_without_a_row ||= begin integrations.select(&:required?).select do | integration | !row_exists_for_integration(integration) end end.tap { |it| log_required_integrations_without_a_row_occurred(it) if it.any? } end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 163 def row_exists_for_integration(integration) all_rows.find { | row | integration.matches_pacticipant_ids?(row) } end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 195 def selector_for(pacticipant_name) resolved_selectors.find{ | s| s.pacticipant_name == pacticipant_name } || dummy_selectors.find{ | s| s.pacticipant_name == pacticipant_name } end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 76 def selector_without_pacticipant_version_number_specified? # If only the pacticipant name is specified, it can't be a can-i-deploy query, must be a matrix UI query resolved_selectors .select(&:specified?) .reject(&:only_pacticipant_name_specified?) .reject(&:pacticipant_version_specified_in_original_selector?) .any? end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 200 def selectors_for(row) [selector_for(row.consumer_name), selector_for(row.provider_name)] end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 179 def selectors_with_non_existing_versions @selectors_with_non_existing_versions ||= resolved_selectors.select(&:latest_tagged_version_that_does_not_exist?) end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 173 def selectors_without_a_version_for(integration) selectors_with_non_existing_versions.select do | selector | integration.involves_pacticipant_with_name?(selector.pacticipant_name) end end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 106 def specified_selectors_do_not_exist_messages specified_selectors_that_do_not_exist.select(&:consider?).collect { | selector | SpecifiedVersionDoesNotExist.new(selector) } end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 102 def specified_selectors_that_do_not_exist resolved_selectors.select(&:specified_version_that_does_not_exist?) end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 118 def success_messages if considered_rows.all?(&:success) && required_integrations_without_a_row.empty? if considered_rows.any? [Successful.new] else [NoDependenciesMissing.new] end else [] end.flatten.uniq end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 57 def warning_messages resolved_ignore_selectors.select(&:pacticipant_or_version_does_not_exist?).collect { | s | IgnoreSelectorDoesNotExist.new(s) } + bad_practice_warnings end
experimental
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 231 def warnings_for_missing_interactions considered_rows.select(&:success).collect do | row | begin if row.verification.interactions_missing_test_results.any? && !row.verification.all_interactions_missing_test_results? InteractionsMissingVerifications.new(selector_for(row.consumer_name), selector_for(row.provider_name), row.verification.interactions_missing_test_results) end rescue StandardError => e logger.warn("Error determining if there were missing interaction verifications", e) nil end end.compact.tap { |it| report_missing_interaction_verifications(it) if it.any? } end