From 17aa15bbb6344ae7dec24225c03faf8ed8a6d0d5 Mon Sep 17 00:00:00 2001 From: simkev2 Date: Sat, 24 Jun 2017 12:57:51 -0500 Subject: [PATCH 1/2] Issue: Cannot supply multiple files to pact-verifier - Updated '--pact-urls' to be a single comma separated string argument - Added '--pact-url' which can be specified multiple times --- .gitignore | 3 +++ README.md | 16 +++++++++++++--- pact/__version__.py | 2 +- pact/test/test_verify.py | 21 +++++++++++++++------ pact/verify.py | 27 ++++++++++++++++++++------- 5 files changed, 52 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index 9c62da2ca..4ab079cd1 100644 --- a/.gitignore +++ b/.gitignore @@ -61,6 +61,9 @@ local_settings.py instance/ .webassets-cache +# Intellij stuff +.idea/ + # Scrapy stuff: .scrapy diff --git a/README.md b/README.md index ed96efe25..5fe1c8072 100644 --- a/README.md +++ b/README.md @@ -222,7 +222,7 @@ The simplest example is verifying a server with locally stored Pact files and no states: ```bash -pact-verifier --provider-base-url=http://localhost:8080 --pact-urls=./pacts/consumer-provider.json +pact-verifier --provider-base-url=http://localhost:8080 --pact-url=./pacts/consumer-provider.json ``` Which will immediately invoke the Pact verifier, making HTTP requests to the server located @@ -235,10 +235,20 @@ There are several options for configuring how the Pacts are verified: Required. Defines the URL of the server to make requests to when verifying the Pacts. +###### --pact-url + +Required if --pact-urls not specified. The location of a Pact file you want +to verify. This can be a URL to a [Pact Broker] or a local path, to provide +multiple files, specify multiple arguments. + +``` +pact-verifier --provider-base-url=http://localhost:8080 --pact-url=./pacts/one.json --pact-url=./pacts/two.json +``` + ###### --pact-urls -Required. The location of the Pact files you want to verify. This can be a URL to a [Pact Broker] -or one or more local paths, separated by a comma. +Required if --pact-url not specified. The location of the Pact files you want +to verify. This can be a URL to a [Pact Broker] or one or more local paths, separated by a comma. ###### --provider-states-url diff --git a/pact/__version__.py b/pact/__version__.py index a475928c2..fb84f5c82 100644 --- a/pact/__version__.py +++ b/pact/__version__.py @@ -1,3 +1,3 @@ """Pact version info.""" -__version__ = '0.6.2' +__version__ = '0.7.0' diff --git a/pact/test/test_verify.py b/pact/test/test_verify.py index e540f150c..8d750950e 100644 --- a/pact/test/test_verify.py +++ b/pact/test/test_verify.py @@ -37,11 +37,14 @@ def setUp(self): self.runner = CliRunner() self.default_call = [ '--provider-base-url=http://localhost', - '--pact-urls=./pacts/consumer-provider.json'] + '--pact-urls=./pacts/consumer-provider.json,' + './pacts/consumer-provider2.json,./pacts/consumer-provider3.json'] self.default_opts = [ '--provider-base-url=http://localhost', - '--pact-urls=./pacts/consumer-provider.json'] + '--pact-url=./pacts/consumer-provider.json', + '--pact-urls=./pacts/consumer-provider2.json,' + './pacts/consumer-provider3.json'] def assertProcess(self, *expected): self.assertEqual(self.mock_Popen.call_count, 1) @@ -59,8 +62,9 @@ def test_provider_base_url_is_required(self): def test_pact_urls_are_required(self): result = self.runner.invoke( verify.main, ['--provider-base-url=http://localhost']) - self.assertEqual(result.exit_code, 2) - self.assertIn(b'--pact-urls', result.output_bytes) + print(result) + self.assertEqual(result.exit_code, 1) + self.assertIn(b'--pact-url or --pact-urls', result.output_bytes) self.assertFalse(self.mock_Popen.called) def test_local_pact_urls_must_exist(self): @@ -121,7 +125,10 @@ def test_all_options(self): self.mock_Popen.return_value.returncode = 0 result = self.runner.invoke(verify.main, [ '--provider-base-url=http://localhost', - '--pact-urls=./pacts/consumer-provider.json', + '--pact-urls=./pacts/consumer-provider.json,' + './pacts/consumer-provider2.json', + '--pact-url=./pacts/consumer-provider3.json', + '--pact-url=./pacts/consumer-provider4.json', '--provider-states-url=http=//localhost/provider-states', '--provider-states-setup-url=http://localhost/provider-states/set', '--pact-broker-username=user', @@ -132,7 +139,9 @@ def test_all_options(self): self.assertEqual(self.mock_Popen.call_count, 1) self.assertProcess( '--provider-base-url=http://localhost', - '--pact-urls=./pacts/consumer-provider.json', + '--pact-urls=./pacts/consumer-provider3.json,' + './pacts/consumer-provider4.json,' + './pacts/consumer-provider.json,./pacts/consumer-provider2.json', '--provider-states-url=http=//localhost/provider-states', '--provider-states-setup-url=http://localhost/provider-states/set', '--broker-username=user', diff --git a/pact/verify.py b/pact/verify.py index 5add1fbb9..3fc42ed49 100644 --- a/pact/verify.py +++ b/pact/verify.py @@ -18,12 +18,17 @@ help='Base URL of the provider to verify against.', required=True) @click.option( - 'pact_urls', '--pact-urls', + 'pact_url', '--pact-url', help='The URI of the pact to verify.' ' Can be an HTTP URI or a local file path.' ' It can be specified multiple times to verify several pacts.', - multiple=True, - required=True) + multiple=True) +@click.option( + 'pact_urls', '--pact-urls', + default='', + help='The URI(s) of the pact to verify.' + ' Can be an HTTP URI(s) or local file path(s).' + ' Provide multiple URI separated by a comma.') @click.option( 'states_url', '--provider-states-url', help='URL to fetch the provider states for the given provider API.') @@ -44,14 +49,14 @@ help='The duration in seconds we should wait to confirm verification' ' process was successful. Defaults to 30.', type=int) -def main(base_url, pact_urls, states_url, states_setup_url, username, +def main(base_url, pact_url, pact_urls, states_url, states_setup_url, username, password, timeout): """ Verify one or more contracts against a provider service. Minimal example: - pact-verifier --provider-base-url=http://localhost:8080 --pact-urls=./pacts + pact-verifier --provider-base-url=http://localhost:8080 --pact-url=./pact """ # NOQA error = click.style('Error:', fg='red') if bool(states_url) != bool(states_setup_url): @@ -61,7 +66,15 @@ def main(base_url, pact_urls, states_url, states_setup_url, username, ' --provider-states-url and --provider-states-setup-url.') raise click.Abort() - missing_files = [path for path in pact_urls if not path_exists(path)] + all_pact_urls = list(pact_url) + all_pact_urls.extend(p for p in pact_urls.split(',') if p) + if not all_pact_urls: + click.echo( + error + + ' At least one of --pact-url or --pact-urls is required.') + raise click.Abort() + + missing_files = [path for path in all_pact_urls if not path_exists(path)] if missing_files: click.echo( error @@ -71,7 +84,7 @@ def main(base_url, pact_urls, states_url, states_setup_url, username, options = { '--provider-base-url': base_url, - '--pact-urls': ','.join(pact_urls), + '--pact-urls': ','.join(all_pact_urls), '--provider-states-url': states_url, '--provider-states-setup-url': states_setup_url, '--broker-username': username, From b6e1a8b03572186ac5b3a0189026432e20036355 Mon Sep 17 00:00:00 2001 From: simkev2 Date: Sat, 24 Jun 2017 20:05:05 -0500 Subject: [PATCH 2/2] Issue: Cannot supply multiple files to pact-verifier - PR: Added deprecation warning instead of making api-breaking change --- pact/test/test_verify.py | 19 +++++++++++++++++++ pact/verify.py | 15 +++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/pact/test/test_verify.py b/pact/test/test_verify.py index 8d750950e..8f2934544 100644 --- a/pact/test/test_verify.py +++ b/pact/test/test_verify.py @@ -149,6 +149,25 @@ def test_all_options(self): self.mock_Popen.return_value.communicate.assert_called_once_with( timeout=60) + def test_deprecated_pact_urls(self): + self.mock_Popen.return_value.returncode = 0 + result = self.runner.invoke(verify.main, [ + '--provider-base-url=http://localhost', + '--pact-urls=./pacts/consumer-provider.json', + '--pact-urls=./pacts/consumer-provider2.json' + ]) + self.assertEqual(result.exit_code, 0) + self.assertIn( + b'Multiple --pact-urls arguments are deprecated.', + result.output_bytes) + self.assertEqual(self.mock_Popen.call_count, 1) + self.assertProcess( + '--provider-base-url=http://localhost', + '--pact-urls=./pacts/consumer-provider.json,' + './pacts/consumer-provider2.json') + self.mock_Popen.return_value.communicate.assert_called_once_with( + timeout=30) + class path_existsTestCase(TestCase): def setUp(self): diff --git a/pact/verify.py b/pact/verify.py index 3fc42ed49..b9fd4cdfa 100644 --- a/pact/verify.py +++ b/pact/verify.py @@ -28,7 +28,8 @@ default='', help='The URI(s) of the pact to verify.' ' Can be an HTTP URI(s) or local file path(s).' - ' Provide multiple URI separated by a comma.') + ' Provide multiple URI separated by a comma.', + multiple=True) # Remove in major version 1.0.0 @click.option( 'states_url', '--provider-states-url', help='URL to fetch the provider states for the given provider API.') @@ -59,6 +60,7 @@ def main(base_url, pact_url, pact_urls, states_url, states_setup_url, username, pact-verifier --provider-base-url=http://localhost:8080 --pact-url=./pact """ # NOQA error = click.style('Error:', fg='red') + warning = click.style('Warning:', fg='yellow') if bool(states_url) != bool(states_setup_url): click.echo( error @@ -67,7 +69,16 @@ def main(base_url, pact_url, pact_urls, states_url, states_setup_url, username, raise click.Abort() all_pact_urls = list(pact_url) - all_pact_urls.extend(p for p in pact_urls.split(',') if p) + for urls in pact_urls: # Remove in major version 1.0.0 + all_pact_urls.extend(p for p in urls.split(',') if p) + + if len(pact_urls) > 1: + click.echo( + warning + + ' Multiple --pact-urls arguments are deprecated. ' + 'Please provide a comma separated list of pacts to --pact-urls, ' + 'or multiple --pact-url arguments.') + if not all_pact_urls: click.echo( error