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 resolved_selectors.count(&:specified?) == 1 && no_to_tag_or_branch_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 102 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 221 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 213 def dummy_selector_for(pacticipant_name) dummy_selectors.find{ | s| s.pacticipant_name == pacticipant_name } end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 233 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 225 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 118 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 163 def log_required_integrations_without_a_row_occurred integrations logger.info("required_integrations_without_a_row returned non empty", integrations: integrations, considered_rows: considered_rows) end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 171 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 177 def missing_specified_version_reasons(selectors) selectors.collect(&:version_does_not_exist_description) end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 90 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 98 def no_to_tag_or_branch_or_environment_specified? !(query_results.options[:tag] || query_results.options[:environment_name] || query_results.options[:main_branch]) end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 114 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 185 def pact_not_ever_verified_by_provider(row) PactNotEverVerifiedByProvider.new(*selectors_for(row)) end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 181 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 257 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 155 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 167 def row_exists_for_integration(integration) all_rows.find { | row | integration.matches_pacticipant_ids?(row) } end
Find the resolved version selector that caused the matrix row with the specified pacticipant name and version number to be returned in the query.
@return [PactBroker::Matrix::ResolvedSelector]
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 193 def selector_for(pacticipant_name, pacticipant_version_number) found = resolved_selectors.select{ | s| s.pacticipant_name == pacticipant_name } if found.size == 1 found.first elsif pacticipant_version_number found.find{ |s| s.pacticipant_version_number == pacticipant_version_number } || dummy_selector_for(pacticipant_name) else dummy_selector_for(pacticipant_name) end 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 if resolved_selectors.select(&:specified?).reject(&:only_pacticipant_name_specified?).any? # There should be at least one selector with a version number specified resolved_selectors .select(&:specified?) .select(&:pacticipant_version_specified_in_original_selector?) .empty? else false end end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 205 def selectors_for(row_or_integration) if row_or_integration.respond_to?(:consumer_version_number) [selector_for(row_or_integration.consumer_name, row_or_integration.consumer_version_number), selector_for(row_or_integration.provider_name, row_or_integration.provider_version_number)] else [selector_for(row_or_integration.consumer_name, nil), selector_for(row_or_integration.provider_name, nil)] end end
# File lib/pact_broker/matrix/deployment_status_summary.rb, line 110 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 106 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 122 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 244 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, row.consumer_version_number), selector_for(row.provider_name, row.provider_version_number), 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