Skip to content

Commit

Permalink
feat(can-i-deploy): experimental - add a warning message if there are…
Browse files Browse the repository at this point in the history
… interactions missing verification test results.
  • Loading branch information
bethesque committed May 28, 2020
1 parent 3c209a4 commit f7ab8cc
Show file tree
Hide file tree
Showing 11 changed files with 294 additions and 7 deletions.
17 changes: 17 additions & 0 deletions lib/pact_broker/api/decorators/reason_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ def to_s
"There are no missing dependencies"
when PactBroker::Matrix::Successful
"All required verification results are published and successful"
when PactBroker::Matrix::InteractionsMissingVerifications
descriptions = reason.interactions.collect do | interaction |
interaction_description(interaction)
end.join('; ')
"WARNING: Although the verification was reported as successful, the results for #{reason.consumer_selector.description} and #{reason.provider_selector.description} may be missing tests for the following interactions: #{descriptions}"
else
reason
end
Expand All @@ -44,6 +49,18 @@ def version_does_not_exist_description selector
""
end
end

# TODO move this somewhere else
def interaction_description(interaction)
if interaction['providerState'] && interaction['providerState'] != ''
"#{interaction['description']} given #{interaction['providerState']}"
elsif interaction['providerStates'] && interaction['providerStates'].is_a?(Array) && interaction['providerStates'].any?
provider_states = interaction['providerStates'].collect{ |ps| ps['name'] }.compact.join(', ')
"#{interaction['description']} given #{provider_states}"
else
interaction['description']
end
end
end
end
end
Expand Down
13 changes: 13 additions & 0 deletions lib/pact_broker/domain/verification.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
require 'sequel'
require 'pact_broker/repositories/helpers'
require 'pact_broker/tags/tag_with_latest_flag'
require 'pact_broker/pacts/content'


module PactBroker
Expand Down Expand Up @@ -83,6 +84,18 @@ def provider_version_tag_names
def latest_pact_publication
pact_version.latest_pact_publication
end

def interactions_missing_test_results
@interactions_missing_test_results ||= pact_content_with_test_results.interactions_missing_test_results
end

def all_interactions_missing_test_results?
pact_content_with_test_results.interactions.count == pact_content_with_test_results.interactions_missing_test_results.count
end

def pact_content_with_test_results
@pact_content_with_test_results = PactBroker::Pacts::Content.from_json(pact_version.content).with_test_results(test_results)
end
end

Verification.plugin :timestamps
Expand Down
24 changes: 23 additions & 1 deletion lib/pact_broker/matrix/deployment_status_summary.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def deployable?
end

def reasons
error_messages.any? ? error_messages : success_messages
error_messages.any? ? error_messages + warning_messages : success_messages + warning_messages
end

private
Expand All @@ -51,6 +51,10 @@ def error_messages
end
end

def warning_messages
warnings_for_missing_interactions
end

def specified_selectors_that_do_not_exist
resolved_selectors.select(&:specified_version_that_does_not_exist?)
end
Expand Down Expand Up @@ -182,6 +186,24 @@ def dummy_selectors_from_rows
[dummy_consumer_selector, dummy_provider_selector]
end.flatten
end

# experimental
def warnings_for_missing_interactions
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
log_error(e, "Error determining if there were missing interaction verifications")
nil
end
end.compact.tap { |it| report_missing_interaction_verifications(it) if it.any? }
end

def report_missing_interaction_verifications(messages)
logger.warn("Interactions missing verifications", messages)
end
end
end
end
9 changes: 9 additions & 0 deletions lib/pact_broker/matrix/reason.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,14 @@ class Successful < Reason
# provider verifications.
class NoDependenciesMissing < Reason
end

class InteractionsMissingVerifications < ErrorReasonWithTwoSelectors
attr_reader :interactions

def initialize(consumer_selector, provider_selector, interactions)
super(consumer_selector, provider_selector)
@interactions = interactions
end
end
end
end
28 changes: 26 additions & 2 deletions lib/pact_broker/pacts/content.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,25 @@ def sort
Content.from_hash(SortContent.call(pact_hash))
end

def interactions_missing_test_results
interactions.reject do | interaction |
interaction['tests']&.any?
end
end

def with_test_results(test_results)
tests = test_results && test_results['tests']
if tests.nil? || !tests.is_a?(Array) || tests.empty?
tests = []
end

new_pact_hash = pact_hash.dup
if interactions && interactions.is_a?(Array)
new_pact_hash['interactions'] = merge_verification_results(interactions, test_results)
new_pact_hash['interactions'] = merge_verification_results(interactions, tests)
end

if messages && messages.is_a?(Array)
new_pact_hash['messages'] = merge_verification_results(messages, test_results)
new_pact_hash['messages'] = merge_verification_results(messages, tests)
end
Content.from_hash(new_pact_hash)
end
Expand Down Expand Up @@ -107,6 +118,19 @@ def add_ids(interactions, overwrite_existing_id)
end
end
end

def merge_verification_results(interactions, tests)
interactions.collect(&:dup).collect do | interaction |
interaction['tests'] = tests.select do | test |
test_is_for_interaction(interaction, test)
end
interaction
end
end

def test_is_for_interaction(interaction, test)
test.is_a?(Hash) && interaction.is_a?(Hash) && test['interactionDescription'] == interaction['description'] && test['interactionProviderState'] == interaction['providerState']
end
end
end
end
4 changes: 3 additions & 1 deletion script/foo-bar-verification.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
"success": true,
"providerApplicationVersion": "1.0.0",
"testResults": {
"examples": [
"tests": [
{
"interactionDescription": "a request for something",
"interactionProviderState": null,
"description": "has status code 200",
"file_path": "/redacted/.gem/ruby/2.4.1/gems/pact-1.17.0/lib/pact/provider/rspec.rb",
"full_description": "Verifying a pact between me and they Greeting with GET / returns a response which has status code 200",
Expand Down
11 changes: 11 additions & 0 deletions script/foo-bar.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,17 @@
"status": 200,
"body" : "something"
}
},{
"description" : "a request for something else",
"providerState": null,
"request": {
"method": "get",
"path" : "/something"
},
"response": {
"status": 200,
"body" : "something"
}
}
]
}
19 changes: 18 additions & 1 deletion spec/lib/pact_broker/api/decorators/reason_decorator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ module Decorators

describe "the number of Reason classes" do
it "is 9 - add another spec here if a new Reason is added" do
expect(REASON_CLASSES.size).to eq 9
expect(REASON_CLASSES.size).to eq 10
end
end

Expand Down Expand Up @@ -52,6 +52,23 @@ module Decorators

its(:to_s) { is_expected.to eq "All required verification results are published and successful" }
end

context "when the reason is PactBroker::Matrix::InteractionsMissingVerifications" do
let(:reason) { PactBroker::Matrix::InteractionsMissingVerifications.new(consumer_selector, provider_selector, interactions) }
let(:interactions) do
[
{
"description" => "desc1",
"providerState" => "p2"
},{
"description" => "desc1",
"providerStates" => [ { "name" => "desc3"}, { "name" => "desc4"} ]
}
]
end

its(:to_s) { is_expected.to eq "WARNING: Although the verification was reported as successful, the results for version 2 of Foo and version 6 of Bar may be missing tests for the following interactions: desc1 given p2; desc1 given desc3, desc4" }
end
end
end
end
Expand Down
8 changes: 6 additions & 2 deletions spec/lib/pact_broker/matrix/deployment_status_summary_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ module Matrix
provider_name: bar.name,
provider_id: bar.id,
success: row_1_success,
pacticipant_names: [foo.name, bar.name]
pacticipant_names: [foo.name, bar.name],
verification: verification_1
)
end

Expand All @@ -46,7 +47,8 @@ module Matrix
provider_name: baz.name,
provider_id: baz.id,
success: true,
pacticipant_names: [foo.name, baz.name]
pacticipant_names: [foo.name, baz.name],
verification: verification_2
)
end

Expand All @@ -65,6 +67,8 @@ module Matrix
let(:foo_version) { double('foo version', number: "ddec8101dabf4edf9125a69f9a161f0f294af43c", id: 10)}
let(:bar_version) { double('bar version', number: "14131c5da3abf323ccf410b1b619edac76231243", id: 11)}
let(:baz_version) { double('baz version', number: "4ee06460f10e8207ad904fa9fa6c4842e462ab59", id: 12)}
let(:verification_1) { double('verification 1', interactions_missing_test_results: []) }
let(:verification_2) { double('verification 2', interactions_missing_test_results: []) }

let(:resolved_selectors) do
[
Expand Down
43 changes: 43 additions & 0 deletions spec/lib/pact_broker/matrix/integration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,49 @@ module Matrix
expect(subject.deployment_status_summary).to be_deployable
end
end

describe "when verification results are published missing tests for some interactions" do
let(:pact_content) do
{
"interactions" => [
{
"description" => "desc1"
},{
"description" => "desc2"
}
]
}
end

let(:verification_tests) do
[
{
"interactionDescription" => "desc1"
}
]
end

before do
td.create_consumer("Foo")
.create_provider("Bar")
.create_consumer_version
.create_pact(json_content: pact_content.to_json)
.create_verification(provider_version: "1", test_results: { tests: verification_tests })
end

let(:selectors) do
[
UnresolvedSelector.new(pacticipant_name: "Foo", latest: true),
UnresolvedSelector.new(pacticipant_name: "Bar", latest: true)
]
end

let(:options) { { latestby: "cvpv"} }

it "should include a warning" do
expect(subject.deployment_status_summary.reasons.last).to be_a(PactBroker::Matrix::InteractionsMissingVerifications)
end
end
end
end
end
Expand Down
Loading

0 comments on commit f7ab8cc

Please sign in to comment.