From ee2eda0199b865aedd13b315edd9513b16be37c1 Mon Sep 17 00:00:00 2001 From: Simon Nizov Date: Mon, 19 Oct 2020 11:01:18 +0300 Subject: [PATCH 1/4] feat(verifier): Allow setting consumer_version_selectors on Verifier --- pact/verifier.py | 13 ++++++++++ tests/test_verifier.py | 56 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/pact/verifier.py b/pact/verifier.py index c7936c174..d1545dc5f 100644 --- a/pact/verifier.py +++ b/pact/verifier.py @@ -1,4 +1,6 @@ """Classes and methods to verify Contracts.""" +import json + from pact.verify_wrapper import VerifyWrapper, path_exists, expand_directories class Verifier(object): @@ -103,6 +105,9 @@ def extract_params(self, **kwargs): verbose = kwargs.get('verbose', False) publish_version = kwargs.get('publish_version', None) + raw_consumer_selectors = kwargs.get('consumer_version_selectors', []) + consumer_selectors = self._build_consumer_selectors(raw_consumer_selectors) + options = { 'log_dir': log_dir, 'log_level': log_level, @@ -114,9 +119,17 @@ def extract_params(self, **kwargs): 'provider_states_setup_url': states_setup_url, 'verbose': verbose, 'publish_version': publish_version, + 'consumer_selectors': consumer_selectors } return self.filter_empty_options(**options) + def _build_consumer_selectors(self, consumer_selectors): + """ + Turns each dict in the consumer_selectors list into a string with a + json object, as expected by VerifyWrapper. + """ + return [json.dumps(selector) for selector in consumer_selectors] + def filter_empty_options(self, **kwargs): """Filter out empty options.""" kwargs = dict(filter(lambda item: item[1] is not None, kwargs.items())) diff --git a/tests/test_verifier.py b/tests/test_verifier.py index 2781de601..fa48e54eb 100644 --- a/tests/test_verifier.py +++ b/tests/test_verifier.py @@ -42,6 +42,34 @@ def test_verifier_with_provider_and_files(self, mock_path_exists, mock_wrapper): enable_pending=False, include_wip_pacts_since=None) + @patch("pact.verify_wrapper.VerifyWrapper.call_verify") + @patch('pact.verifier.path_exists', return_value=True) + def test_verifier_with_provider_and_files_passes_consumer_selctors(self, mock_path_exists, mock_wrapper): + mock_wrapper.return_value = (True, 'some logs') + + output, _ = self.verifier.verify_pacts( + 'path/to/pact1', + 'path/to/pact2', + headers=['header1', 'header2'], + consumer_version_selectors=[ + {"tag": "main", "latest": True}, + {"tag": "test", "latest": False}, + ] + ) + + assertVerifyCalled(mock_wrapper, + 'path/to/pact1', + 'path/to/pact2', + provider='test_provider', + custom_provider_headers=['header1', 'header2'], + provider_base_url='http://localhost:8888', + log_level='INFO', + verbose=False, + enable_pending=False, + include_wip_pacts_since=None, + consumer_selectors=['{"tag": "main", "latest": true}', + '{"tag": "test", "latest": false}']) + def test_validate_on_publish_results(self): self.assertRaises(Exception, self.verifier.verify_pacts, 'path/to/pact1', publish=True) @@ -140,6 +168,34 @@ def test_verifier_with_broker(self, mock_wrapper): enable_pending=False, include_wip_pacts_since=None) + @patch("pact.verify_wrapper.VerifyWrapper.call_verify") + def test_verifier_with_broker_passes_consumer_selctors(self, mock_wrapper): + + mock_wrapper.return_value = (True, 'some value') + + output, _ = self.verifier.verify_with_broker( + **self.default_opts, + consumer_version_selectors=[ + {"tag": "main", "latest": True}, + {"tag": "test", "latest": False}, + ] + ) + + self.assertTrue(output) + assertVerifyCalled(mock_wrapper, + provider='test_provider', + provider_base_url='http://localhost:8888', + broker_password=self.broker_password, + broker_username=self.broker_username, + broker_token='token', + broker_url=self.broker_url, + log_level='INFO', + verbose=False, + enable_pending=False, + include_wip_pacts_since=None, + consumer_selectors=['{"tag": "main", "latest": true}', + '{"tag": "test", "latest": false}']) + @patch("pact.verify_wrapper.VerifyWrapper.call_verify") @patch('pact.verifier.path_exists', return_value=True) def test_publish_on_success(self, mock_path_exists, mock_wrapper): From e7c87ced4d7d02ddcc61cae266656a8a46b07d5f Mon Sep 17 00:00:00 2001 From: Simon Nizov Date: Mon, 19 Oct 2020 11:16:59 +0300 Subject: [PATCH 2/4] style: Fix linting issues --- pact/verifier.py | 4 +++- tests/test_verifier.py | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/pact/verifier.py b/pact/verifier.py index d1545dc5f..a9642aee8 100644 --- a/pact/verifier.py +++ b/pact/verifier.py @@ -125,7 +125,9 @@ def extract_params(self, **kwargs): def _build_consumer_selectors(self, consumer_selectors): """ - Turns each dict in the consumer_selectors list into a string with a + Build the consumer_selectors list. + + Turn each dict in the consumer_selectors list into a string with a json object, as expected by VerifyWrapper. """ return [json.dumps(selector) for selector in consumer_selectors] diff --git a/tests/test_verifier.py b/tests/test_verifier.py index fa48e54eb..10b24369b 100644 --- a/tests/test_verifier.py +++ b/tests/test_verifier.py @@ -174,11 +174,11 @@ def test_verifier_with_broker_passes_consumer_selctors(self, mock_wrapper): mock_wrapper.return_value = (True, 'some value') output, _ = self.verifier.verify_with_broker( - **self.default_opts, consumer_version_selectors=[ {"tag": "main", "latest": True}, {"tag": "test", "latest": False}, - ] + ], + **self.default_opts, ) self.assertTrue(output) From 33be267fafa00ba0045c3990fe2d0eea0cf54fab Mon Sep 17 00:00:00 2001 From: Simon Nizov Date: Mon, 19 Oct 2020 11:22:05 +0300 Subject: [PATCH 3/4] style: Fix one more linting issue --- tests/test_verifier.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_verifier.py b/tests/test_verifier.py index 10b24369b..cb9ec965e 100644 --- a/tests/test_verifier.py +++ b/tests/test_verifier.py @@ -178,7 +178,7 @@ def test_verifier_with_broker_passes_consumer_selctors(self, mock_wrapper): {"tag": "main", "latest": True}, {"tag": "test", "latest": False}, ], - **self.default_opts, + **self.default_opts ) self.assertTrue(output) From 683a9319c053c160f288b88aaf58c0786477a0a2 Mon Sep 17 00:00:00 2001 From: Simon Nizov Date: Mon, 19 Oct 2020 17:21:21 +0300 Subject: [PATCH 4/4] fix: Fix flaky tests using OrderedDict --- tests/test_verifier.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/test_verifier.py b/tests/test_verifier.py index cb9ec965e..0639ab3cd 100644 --- a/tests/test_verifier.py +++ b/tests/test_verifier.py @@ -1,3 +1,5 @@ +from collections import OrderedDict + from unittest import TestCase import unittest from mock import patch @@ -52,8 +54,9 @@ def test_verifier_with_provider_and_files_passes_consumer_selctors(self, mock_pa 'path/to/pact2', headers=['header1', 'header2'], consumer_version_selectors=[ - {"tag": "main", "latest": True}, - {"tag": "test", "latest": False}, + # Using OrderedDict for the sake of testing + OrderedDict([("tag", "main"), ("latest", True)]), + OrderedDict([("tag", "test"), ("latest", False)]), ] ) @@ -175,8 +178,9 @@ def test_verifier_with_broker_passes_consumer_selctors(self, mock_wrapper): output, _ = self.verifier.verify_with_broker( consumer_version_selectors=[ - {"tag": "main", "latest": True}, - {"tag": "test", "latest": False}, + # Using OrderedDict for the sake of testing + OrderedDict([("tag", "main"), ("latest", True)]), + OrderedDict([("tag", "test"), ("latest", False)]), ], **self.default_opts )