Skip to content

Commit

Permalink
feat(cli): add --consumer-version-selector parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
bethesque committed Jan 10, 2020
1 parent 905ab8d commit 2526590
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 15 deletions.
15 changes: 8 additions & 7 deletions lib/pact/provider_verifier/aggregate_pact_configs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ module Pact
module ProviderVerifier
class AggregatePactConfigs

def self.call(pact_urls, provider_name, consumer_version_tags, provider_version_tags, pact_broker_base_url, http_client_options)
new(pact_urls, provider_name, consumer_version_tags, provider_version_tags, pact_broker_base_url, http_client_options).call
def self.call(pact_urls, provider_name, consumer_version_tags, consumer_version_selectors, provider_version_tags, pact_broker_base_url, http_client_options)
new(pact_urls, provider_name, consumer_version_tags, consumer_version_selectors, provider_version_tags, pact_broker_base_url, http_client_options).call
end

def initialize(pact_urls, provider_name, consumer_version_tags, provider_version_tags, pact_broker_base_url, http_client_options)
def initialize(pact_urls, provider_name, consumer_version_tags, consumer_version_selectors, provider_version_tags, pact_broker_base_url, http_client_options)
@pact_urls = pact_urls
@provider_name = provider_name
@consumer_version_tags = consumer_version_tags
@consumer_version_selectors = consumer_version_selectors
@provider_version_tags = provider_version_tags
@pact_broker_base_url = pact_broker_base_url
@http_client_options = http_client_options
Expand All @@ -25,7 +26,7 @@ def call

private

attr_reader :pact_urls, :provider_name, :consumer_version_tags, :provider_version_tags, :pact_broker_base_url, :http_client_options
attr_reader :pact_urls, :provider_name, :consumer_version_tags, :consumer_version_selectors, :provider_version_tags, :pact_broker_base_url, :http_client_options

def specified_pact_uris
pact_urls.collect{ | url | Pact::PactBroker.build_pact_uri(url, http_client_options) }
Expand All @@ -40,11 +41,11 @@ def pacts_urls_from_broker
end

def pacts_for_verification
@pacts_for_verification ||= Pact::PactBroker.fetch_pact_uris_for_verification(provider_name, consumer_version_selectors, provider_version_tags, pact_broker_base_url, http_client_options)
@pacts_for_verification ||= Pact::PactBroker.fetch_pact_uris_for_verification(provider_name, aggregated_consumer_version_selectors, provider_version_tags, pact_broker_base_url, http_client_options)
end

def consumer_version_selectors
consumer_version_tags.collect{ |tag| { tag: tag, latest: true } }
def aggregated_consumer_version_selectors
consumer_version_selectors + consumer_version_tags.collect{ |tag| { tag: tag, latest: true } }
end
end
end
Expand Down
9 changes: 7 additions & 2 deletions lib/pact/provider_verifier/app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@ class App
include Pact::WaitUntilServerAvailable

PROXY_PACT_HELPER = File.expand_path(File.join(File.dirname(__FILE__), "pact_helper.rb"))
attr_reader :pact_urls, :options, :consumer_version_tags, :provider_version_tags
attr_reader :pact_urls, :options, :consumer_version_tags, :provider_version_tags, :consumer_version_selectors

def initialize pact_urls, options = {}
@pact_urls = pact_urls
@options = options
@consumer_version_tags = options[:consumer_version_tag] || []
@provider_version_tags = options[:provider_version_tag] || []
@consumer_version_selectors = parse_consumer_version_selectors(options[:consumer_version_selector] || [])
end

def self.call pact_urls, options
Expand Down Expand Up @@ -174,7 +175,7 @@ def reset_pact_configuration

def all_pact_urls
http_client_options = { username: options.broker_username, password: options.broker_password, token: options.broker_token, verbose: options.verbose }
AggregatePactConfigs.call(pact_urls, options.provider, consumer_version_tags, provider_version_tags, options.pact_broker_base_url, http_client_options)
AggregatePactConfigs.call(pact_urls, options.provider, consumer_version_tags, consumer_version_selectors, provider_version_tags, options.pact_broker_base_url, http_client_options)
end

def require_pact_project_pact_helper
Expand All @@ -200,6 +201,10 @@ def parse_header
end
end

def parse_consumer_version_selectors consumer_version_selectors
consumer_version_selectors.collect{ | string | JSON.parse(string) }
end

def print_deprecation_note
if options.provider_states_url
$stderr.puts "WARN: The --provider-states-url option is deprecated and the URL endpoint can be removed from the application"
Expand Down
23 changes: 23 additions & 0 deletions lib/pact/provider_verifier/cli/verify.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
require 'pact/provider_verifier/app'
require 'pact/provider_verifier/cli/custom_thor'

# verify --consumer-version-selector '{ all: true, tag: "feat-x", fallback: "master" }' --consumer-version-tag master

#
# tags "master", { all: true, tag: "feat-x", fallback: "master" }
#

module Pact
module ProviderVerifier
module CLI
Expand All @@ -21,6 +27,7 @@ class InvalidArgumentsError < ::Thor::Error; end
method_option :broker_token, aliases: "-k", desc: "Pact Broker bearer token", :required => false
method_option :provider, required: false
method_option :consumer_version_tag, type: :array, banner: "TAG", desc: "Retrieve the latest pacts with this consumer version tag. Used in conjunction with --provider. May be specified multiple times.", :required => false
method_option :consumer_version_selector, type: :array, banner: "SELECTOR", desc: "JSON string specifying a selector that identifies which pacts to verify. May be specified multiple times.", :required => false
method_option :provider_version_tag, type: :array, banner: "TAG", desc: "Tag to apply to the provider application version. May be specified multiple times.", :required => false
method_option :provider_app_version, aliases: "-a", desc: "Provider application version, required when publishing verification results", :required => false
method_option :publish_verification_results, aliases: "-r", desc: "Publish verification results to the broker", required: false, type: :boolean, default: false
Expand Down Expand Up @@ -66,6 +73,22 @@ def validate_verify
if options.pact_broker_base_url && (options.provider.nil? || options.provider == "")
raise InvalidArgumentsError, "No value provided for required option '--provider'"
end
validate_consumer_version_selectors
end

def validate_consumer_version_selectors
error_messages = (options.consumer_version_selector || []).collect do | string |
begin
JSON.parse(string)
nil
rescue
"Invalid JSON string provided for --consumer-version-selector: #{string}"
end
end.compact

if error_messages.any?
raise InvalidArgumentsError, error_messages.join("\n")
end
end

def exit_with_non_zero_status
Expand Down
5 changes: 3 additions & 2 deletions script/dev/broker.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@ bundle exec rackup -p 4567 script/dev/bar_provider_config.ru 2> /dev/null &
pid=$!
sleep 3

export PACT_BROKER_PACTS_FOR_VERIFICATION_ENABLED=true

bundle exec bin/pact-provider-verifier \
--broker-username dXfltyFMgNOFZAxr8io9wJ37iUpY42M \
--broker-password O5AIZWxelWbLvqMd8PkAVycBJh2Psyg1 \
--provider Bar \
--provider-version-tag pdev \
--consumer-version-selector '{"tag": "dev", "latest": true}' \
--pact-broker-base-url https://test.pact.dius.com.au \
-a 1.0.100 \
--provider-base-url http://localhost:4567 \
--provider-states-setup-url http://localhost:4567/provider-state \
--publish-verification-results
--publish-verification-results \
--verbose

kill -2 $pid
wait $pid
10 changes: 6 additions & 4 deletions spec/lib/pact/provider_verifier/aggregate_pact_configs_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ module ProviderVerifier
let(:pact_urls) { ["http://pact-1"] }
let(:provider_name) { "Foo" }
let(:consumer_version_tags) { ["master", "prod"] }
let(:selector) { double('selector') }
let(:consumer_version_selectors) { [selector] }
let(:provider_version_tags) { ["dev"] }
let(:pact_broker_base_url) { "http://broker" }
let(:http_client_options) { { "foo" => "bar"} }
Expand All @@ -24,7 +26,7 @@ module ProviderVerifier
allow(pact_broker_api).to receive(:build_pact_uri) { | url | OpenStruct.new(uri: url) }
end

subject { AggregatePactConfigs.call(pact_urls, provider_name, consumer_version_tags, provider_version_tags, pact_broker_base_url, http_client_options) }
subject { AggregatePactConfigs.call(pact_urls, provider_name, consumer_version_tags, consumer_version_selectors, provider_version_tags, pact_broker_base_url, http_client_options) }

context "with no broker config" do
let(:pact_broker_base_url) { nil }
Expand Down Expand Up @@ -54,12 +56,12 @@ module ProviderVerifier
let(:metadata) { { some: 'metadata'} }
let(:pact_uris) { [double('PactURI', uri: "http://pact-1", metadata: metadata)] }

let(:consumer_version_selectors) do
[{ tag: "master", latest: true }, { tag: "prod", latest: true }]
let(:aggregated_consumer_version_selectors) do
[selector, { tag: "master", latest: true }, { tag: "prod", latest: true }]
end

it "fetches the pacts for verification" do
expect(pact_broker_api).to receive(:fetch_pact_uris_for_verification).with(provider_name, consumer_version_selectors, provider_version_tags, pact_broker_base_url, http_client_options)
expect(pact_broker_api).to receive(:fetch_pact_uris_for_verification).with(provider_name, aggregated_consumer_version_selectors, provider_version_tags, pact_broker_base_url, http_client_options)
subject
end

Expand Down
38 changes: 38 additions & 0 deletions spec/lib/pact/provider_verifier/cli/verify_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,44 @@ module CLI
invoke_verify
end
end

context "with multiple --consumer-version-selector" do
let(:options) do
minimum_valid_options.merge(
pact_broker_base_url: "http://broker",
provider: "Foo",
consumer_version_selector: [ { tag: "master" }.to_json, { tag: "prod" }.to_json ]
)
end

before do
subject.options = OpenStruct.new(options)
end

it "parses the JSON strings to hashes" do
expect(Pact::ProviderVerifier::App).to receive(:call).with(
pact_urls, OpenStruct.new(options))
invoke_verify
end
end

context "with --consumer-version-selector that is invalid JSON" do
let(:options) do
minimum_valid_options.merge(
pact_broker_base_url: "http://broker",
provider: "Foo",
consumer_version_selector: [ "a" ]
)
end

before do
subject.options = OpenStruct.new(options)
end

it "raises an InvalidArgumentsError" do
expect { subject.verify }.to raise_error Verify::InvalidArgumentsError, /Invalid JSON string/
end
end
end
end
end
Expand Down

0 comments on commit 2526590

Please sign in to comment.