From 9cac2d71689ec04d76501d86b607e909d5aa323d Mon Sep 17 00:00:00 2001 From: Elliott Murray Date: Tue, 23 Feb 2021 21:22:36 +0000 Subject: [PATCH 01/41] fix: introduced and renamed specification version --- pact/consumer.py | 9 +++++---- pact/pact.py | 12 ++++++------ tests/test_consumer.py | 6 +++--- tests/test_pact.py | 11 ++++++----- 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/pact/consumer.py b/pact/consumer.py index cc767066c..a2d60d3ca 100644 --- a/pact/consumer.py +++ b/pact/consumer.py @@ -49,7 +49,8 @@ def has_pact_with(self, provider, host_name='localhost', port=1234, cors=False, publish_to_broker=False, broker_base_url=None, broker_username=None, broker_password=None, broker_token=None, pact_dir=None, - version='2.0.0', file_write_mode='overwrite'): + specification_version='2.0.0', + file_write_mode='overwrite'): """ Create a contract between the `provider` and this consumer. @@ -108,8 +109,8 @@ def has_pact_with(self, provider, host_name='localhost', port=1234, :param pact_dir: Directory where the resulting pact files will be written. Defaults to the current directory. :type pact_dir: str - :param version: The Pact Specification version to use, defaults to - '2.0.0'. + :param specification_version: The Pact Specification version to use. + Defaults to '2.0.0'. :type version: str :param file_write_mode: How the mock service should apply multiple calls to .verify(). Pass 'overwrite' to overwrite the generated @@ -142,5 +143,5 @@ def has_pact_with(self, provider, host_name='localhost', port=1234, cors=cors, pact_dir=pact_dir, publish_to_broker=publish_to_broker, - version=version, + specification_version=specification_version, file_write_mode=file_write_mode) diff --git a/pact/pact.py b/pact/pact.py index 1587ed17a..b2403dfb2 100644 --- a/pact/pact.py +++ b/pact/pact.py @@ -58,7 +58,7 @@ def __init__( broker_password=None, broker_token=None, pact_dir=None, - version='2.0.0', + specification_version='2.0.0', file_write_mode='overwrite', ): """ @@ -112,9 +112,9 @@ def __init__( :param pact_dir: Directory where the resulting pact files will be written. Defaults to the current directory. :type pact_dir: str - :param version: The Pact Specification version to use, defaults to + :param specification_version: The Pact Specification version to use, defaults to '2.0.0'. - :type version: str + :type version: str of the consumer version. :param file_write_mode: `overwrite` or `merge`. Use `merge` when running multiple mock service instances in parallel for the same consumer/provider pair. Ensure the pact file is deleted before @@ -142,7 +142,7 @@ def __init__( self.ssl = ssl self.sslcert = sslcert self.sslkey = sslkey - self.version = version + self.specification_version = specification_version self._interactions = [] self._process = None @@ -196,7 +196,7 @@ def start_service(self): "--log", f"{self.log_dir}/pact-mock-service.log", "--pact-dir", self.pact_dir, "--pact-file-write-mode", self.file_write_mode, - f"--pact-specification-version={self.version}", + f"--pact-specification-version={self.specification_version}", "--consumer", self.consumer.name, "--provider", self.provider.name, ] @@ -235,7 +235,7 @@ def stop_service(self): if self.publish_to_broker: self.publish( self.consumer.name, - self.version, + self.consumer.version, tag_with_git_branch=self.consumer.tag_with_git_branch, consumer_tags=self.consumer.tags, ) diff --git a/tests/test_consumer.py b/tests/test_consumer.py index 7f0cdf903..d0fcfbe82 100644 --- a/tests/test_consumer.py +++ b/tests/test_consumer.py @@ -26,7 +26,7 @@ def test_has_pact_with(self): consumer=self.consumer, provider=self.provider, host_name='localhost', port=1234, log_dir=None, ssl=False, sslcert=None, sslkey=None, - cors=False, pact_dir=None, version='2.0.0', + cors=False, pact_dir=None, specification_version='2.0.0', broker_base_url=None, publish_to_broker=False, broker_username=None, broker_password=None, broker_token=None, file_write_mode='overwrite') @@ -35,7 +35,7 @@ def test_has_pact_with_customer_all_options(self): result = self.consumer.has_pact_with( self.provider, host_name='example.com', port=1111, log_dir='/logs', ssl=True, sslcert='/ssl.cert', sslkey='ssl.pem', - cors=True, pact_dir='/pacts', version='3.0.0', + cors=True, pact_dir='/pacts', specification_version='3.0.0', file_write_mode='merge') self.assertIs(result, self.mock_service.return_value) @@ -43,7 +43,7 @@ def test_has_pact_with_customer_all_options(self): consumer=self.consumer, provider=self.provider, host_name='example.com', port=1111, log_dir='/logs', ssl=True, sslcert='/ssl.cert', sslkey='ssl.pem', - cors=True, pact_dir='/pacts', version='3.0.0', + cors=True, pact_dir='/pacts', specification_version='3.0.0', broker_base_url=None, publish_to_broker=False, broker_username=None, broker_password=None, broker_token=None, file_write_mode='merge') diff --git a/tests/test_pact.py b/tests/test_pact.py index 2735f49ed..196a9bd47 100644 --- a/tests/test_pact.py +++ b/tests/test_pact.py @@ -35,14 +35,14 @@ def test_init_defaults(self): self.assertIsNone(target.sslcert) self.assertIsNone(target.sslkey) self.assertEqual(target.uri, 'http://localhost:1234') - self.assertEqual(target.version, '2.0.0') + self.assertEqual(target.specification_version, '2.0.0') self.assertEqual(len(target._interactions), 0) def test_init_custom_mock_service(self): target = Pact( self.consumer, self.provider, host_name='192.168.1.1', port=8000, log_dir='/logs', ssl=True, sslcert='/ssl.cert', sslkey='/ssl.pem', - cors=True, pact_dir='/pacts', version='3.0.0', + cors=True, pact_dir='/pacts', specification_version='3.0.0', file_write_mode='merge') self.assertIs(target.consumer, self.consumer) @@ -56,7 +56,7 @@ def test_init_custom_mock_service(self): self.assertEqual(target.sslcert, '/ssl.cert') self.assertEqual(target.sslkey, '/ssl.pem') self.assertEqual(target.uri, 'https://192.168.1.1:8000') - self.assertEqual(target.version, '3.0.0') + self.assertEqual(target.specification_version, '3.0.0') self.assertEqual(target.file_write_mode, 'merge') self.assertEqual(len(target._interactions), 0) @@ -371,7 +371,7 @@ def test_stop_windows(self): ruby_exe = Mock(spec=Process) self.mock_Process.return_value.children.return_value = [ruby_exe] self.mock_Pid_exists.return_value = False - pact = Pact(Consumer('consumer'), Provider('provider'), publish_to_broker=True) + pact = Pact(Consumer('consumer', version='abc'), Provider('provider'), publish_to_broker=True) pact._process = Mock(spec=Popen, pid=999) pact.stop_service() @@ -383,7 +383,8 @@ def test_stop_windows(self): ruby_exe.terminate.assert_called_once_with() self.mock_Process.return_value.wait.assert_called_once_with() self.mock_Pid_exists.assert_called_once_with(999) - self.mock_publish.assert_called_once() + self.mock_publish.assert_called_once_with( + pact, 'consumer', 'abc', consumer_tags=None, tag_with_git_branch=False) def test_stop_fails_posix(self): self.mock_platform.return_value = 'Linux' From 6aee3e2e492f172e6e4647cac26cc0fbaecf265a Mon Sep 17 00:00:00 2001 From: Elliott Murray Date: Sat, 27 Feb 2021 09:16:35 +0000 Subject: [PATCH 02/41] chore: Releasing version 1.3.1 --- CHANGELOG.md | 3 +++ pact/__version__.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 304f7ee1c..d48c89261 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +### 1.3.1 + * 4440022 - Merge pull request #203 from pact-foundation/fix/version_confusion (Elliott Murray, Sat Feb 27 09:15:08 2021 +0000) + * 9cac2d7 - fix: introduced and renamed specification version (Elliott Murray, Tue Feb 23 21:22:36 2021 +0000) ### 1.3.0 * eaa90e1 - Merge pull request #194 from williaminfante/feat/pact-message-2 (Elliott Murray, Mon Jan 25 08:48:00 2021 +0000) * 5ed73db - test: consider publish to broker with no pact_dir argument (William Infante, Mon Jan 25 17:19:08 2021 +1100) diff --git a/pact/__version__.py b/pact/__version__.py index 227654bee..59aabf89e 100644 --- a/pact/__version__.py +++ b/pact/__version__.py @@ -1,3 +1,3 @@ """Pact version info.""" -__version__ = '1.3.0' +__version__ = '1.3.1' From 66e79e2cbffbdc11ca285e45b2c46efd80471b52 Mon Sep 17 00:00:00 2001 From: Elliott Murray Date: Sat, 27 Feb 2021 09:34:37 +0000 Subject: [PATCH 03/41] chore: move from nose to pytests as we are now 3.6+ --- setup.cfg | 4 ++++ tests/conftest.py | 1 + 2 files changed, 5 insertions(+) create mode 100644 tests/conftest.py diff --git a/setup.cfg b/setup.cfg index d3e4a24fd..fce23ea96 100644 --- a/setup.cfg +++ b/setup.cfg @@ -17,3 +17,7 @@ xunit-file=nosetests.xml [pydocstyle] match-dir=[^(test|\.)].* + + +[tool:pytest] +norecursedirs=examples diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 000000000..20b94aaa6 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1 @@ +# conftest From 5a0934ca05a7b5b94114098ad13212d6383eeef8 Mon Sep 17 00:00:00 2001 From: Elliott Murray Date: Sat, 27 Feb 2021 09:57:31 +0000 Subject: [PATCH 04/41] chore: update ci stuff --- .github/workflows/build_and_test.yml | 2 +- requirements_dev.txt | 2 +- tox.ini | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index bd952f19e..436b4bc02 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -24,7 +24,7 @@ jobs: run: | flake8 pydocstyle pact - - name: Test with nosetests + - name: Test with pytest run: | tox -e test - name: Test examples diff --git a/requirements_dev.txt b/requirements_dev.txt index 192794210..79edd2c06 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -5,10 +5,10 @@ codecov==2.0.5 coverage==4.3.4 flake8==3.8.3 mock==3.0.5 -nose==1.3.7 psutil==5.7.0 pycodestyle==2.6.0 pydocstyle==4.0.1 tox==3.14.0 +pytest==5.4.1 tox-travis==0.8 wheel==0.24.0 diff --git a/tox.ini b/tox.ini index 6d45ae357..03c95edac 100644 --- a/tox.ini +++ b/tox.ini @@ -4,5 +4,5 @@ envlist=py{36,37,38,39}-{test,install} deps= test: -rrequirements_dev.txt commands= - test: nosetests + test: pytest install: python -c "import pact" From 261f24b20af5b8f4f959977abf59514b18d4293c Mon Sep 17 00:00:00 2001 From: Elliott Murray Date: Sat, 27 Feb 2021 10:10:23 +0000 Subject: [PATCH 05/41] chore: more clean up --- requirements_dev.txt | 4 ++-- tox.ini | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements_dev.txt b/requirements_dev.txt index 79edd2c06..6f700464a 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -1,8 +1,7 @@ Click>=2.0.0,<=6.7 +coverage==5.4 Flask==1.0 configparser==3.5.0 -codecov==2.0.5 -coverage==4.3.4 flake8==3.8.3 mock==3.0.5 psutil==5.7.0 @@ -10,5 +9,6 @@ pycodestyle==2.6.0 pydocstyle==4.0.1 tox==3.14.0 pytest==5.4.1 +pytest-cov==2.11.1 tox-travis==0.8 wheel==0.24.0 diff --git a/tox.ini b/tox.ini index 03c95edac..be16f7d07 100644 --- a/tox.ini +++ b/tox.ini @@ -4,5 +4,5 @@ envlist=py{36,37,38,39}-{test,install} deps= test: -rrequirements_dev.txt commands= - test: pytest + test: pytest --cov pact tests install: python -c "import pact" From 01e4ec4c5b46cef0735690ccac632329c21bedb6 Mon Sep 17 00:00:00 2001 From: Elliott Murray Date: Tue, 2 Mar 2021 21:30:48 +0000 Subject: [PATCH 06/41] chore: wip on using test containers on examples --- examples/e2e/run_pytest.sh | 3 +-- examples/e2e/tests/broker_container.py | 0 .../e2e/tests/consumer/test_user_consumer.py | 27 ++++++++++++++++--- examples/e2e/tests/provider/test_provider.py | 16 +++++++++++ 4 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 examples/e2e/tests/broker_container.py diff --git a/examples/e2e/run_pytest.sh b/examples/e2e/run_pytest.sh index 08b70cdea..0f8c32a88 100755 --- a/examples/e2e/run_pytest.sh +++ b/examples/e2e/run_pytest.sh @@ -19,5 +19,4 @@ sleep 3 pytest -teardown() - +teardown() \ No newline at end of file diff --git a/examples/e2e/tests/broker_container.py b/examples/e2e/tests/broker_container.py new file mode 100644 index 000000000..e69de29bb diff --git a/examples/e2e/tests/consumer/test_user_consumer.py b/examples/e2e/tests/consumer/test_user_consumer.py index 20df74b9e..9e96dd2cc 100644 --- a/examples/e2e/tests/consumer/test_user_consumer.py +++ b/examples/e2e/tests/consumer/test_user_consumer.py @@ -4,6 +4,8 @@ import os import atexit +from testcontainers.compose import DockerCompose + import pytest from pact import Consumer, Like, Provider, Term, Format @@ -30,6 +32,25 @@ def consumer(): .format(host=PACT_MOCK_HOST, port=PACT_MOCK_PORT) ) +@pytest.fixture(scope='session') +def broker(request): + version = request.config.getoption('--publish-pact') + publish = True if version else False + + if not publish: + return + + print('Starting broker') + with DockerCompose("../broker", + compose_file_name=["docker-compose.yml"], + pull=True) as compose: + + stdout, stderr = compose.get_logs() + if stderr: + print("Errors\\n:{}".format(stderr)) + print(stdout) + yield + @pytest.fixture(scope='session') def pact(request): @@ -43,13 +64,13 @@ def pact(request): print('start service') pact.start_service() - atexit.register(pact.stop_service) + # atexit.register(pact.stop_service) yield pact print('stop service') pact.stop_service() -def test_get_user_non_admin(pact, consumer): +def test_get_user_non_admin(broker, pact, consumer): expected = { 'name': 'UserA', 'id': Format().uuid, @@ -72,7 +93,7 @@ def test_get_user_non_admin(pact, consumer): assert user.name == 'UserA' -def test_get_non_existing_user(pact, consumer): +def test_get_non_existing_user(broker, pact, consumer): (pact .given('UserA does not exist') .upon_receiving('a request for UserA') diff --git a/examples/e2e/tests/provider/test_provider.py b/examples/e2e/tests/provider/test_provider.py index bb277b1c6..900ebab73 100644 --- a/examples/e2e/tests/provider/test_provider.py +++ b/examples/e2e/tests/provider/test_provider.py @@ -2,8 +2,10 @@ import logging import os +from testcontainers.compose import DockerCompose from pact import Verifier +import pytest log = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) @@ -33,3 +35,17 @@ def test_get_user_non_admin(): provider_states_setup_url="{}/_pact/provider_states".format(PACT_URL)) assert (output == 0) + + +# @pytest.fixture(scope='session') +# def broker(): +# print('Starting broker') +# with DockerCompose("../broker", +# compose_file_name=["docker-compose.yml"], +# pull=True) as compose: + +# stdout, stderr = compose.get_logs() +# if stderr: +# print("Errors\\n:{}".format(stderr)) +# print(stdout) +# yield From 1b4be80a0746a4f5eae4f67a14daccb00bcddd76 Mon Sep 17 00:00:00 2001 From: Elliott Murray Date: Sat, 13 Mar 2021 11:15:52 +0000 Subject: [PATCH 07/41] chore: spiking testcontainers --- Makefile | 1 - examples/e2e/requirements.txt | 3 +- examples/e2e/run_pytest.sh | 19 ++++------ examples/e2e/tests/broker_container.py | 0 examples/e2e/tests/conftest.py | 26 +++++++++++++ .../e2e/tests/consumer/test_user_consumer.py | 26 +------------ .../userserviceclient-userservice.json | 37 ------------------- examples/e2e/tests/provider/test_provider.py | 33 +++++++---------- 8 files changed, 51 insertions(+), 94 deletions(-) delete mode 100644 examples/e2e/tests/broker_container.py diff --git a/Makefile b/Makefile index 1c88a54d2..decc028c1 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,6 @@ define E2E pip install -r requirements.txt pip install -e ../../ ./run_pytest.sh - ./verify_pact.sh endef export E2E diff --git a/examples/e2e/requirements.txt b/examples/e2e/requirements.txt index 93186fa97..a11e78ea9 100644 --- a/examples/e2e/requirements.txt +++ b/examples/e2e/requirements.txt @@ -1,3 +1,4 @@ Flask==1.1.1 pytest==5.4.1 -requests==2.23.0 \ No newline at end of file +requests==2.23.0 +testcontainers==3.3.0 \ No newline at end of file diff --git a/examples/e2e/run_pytest.sh b/examples/e2e/run_pytest.sh index 0f8c32a88..ba541e6e4 100755 --- a/examples/e2e/run_pytest.sh +++ b/examples/e2e/run_pytest.sh @@ -1,22 +1,19 @@ #!/bin/bash set -o pipefail +FLASK_APP=pact_provider.py python -m flask run -p 5001 & &>/dev/null - -FLASK_APP=pact_provider.py python -m flask run -p 1235 & &>/dev/null - -# python pact_provider.py & &>/dev/null FLASK_PID=$! -function teardown { - echo "Tearing down Flask server ${FLASK_PID}" - - kill -9 $FLASK_PID -} +teardown() { + echo "Tearing down Flask server ${FLASK_PID}"; + kill -9 $FLASK_PID; +}; trap teardown EXIT sleep 3 -pytest +pytest --publish-pact 1 + +teardown -teardown() \ No newline at end of file diff --git a/examples/e2e/tests/broker_container.py b/examples/e2e/tests/broker_container.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/e2e/tests/conftest.py b/examples/e2e/tests/conftest.py index 1d23983d0..868af50e8 100644 --- a/examples/e2e/tests/conftest.py +++ b/examples/e2e/tests/conftest.py @@ -1,4 +1,8 @@ +from testcontainers.compose import DockerCompose + +import pytest + def pytest_addoption(parser): parser.addoption( "--publish-pact", type=str, action="store", @@ -9,3 +13,25 @@ def pytest_addoption(parser): "--provider-url", type=str, action="store", help="The url to our provider." ) + + +@pytest.fixture(scope='session', autouse=True) +def broker(request): + version = request.config.getoption('--publish-pact') + publish = True if version else False + + # yield + if not publish: + yield + return + + print('Starting broker') + with DockerCompose("../broker", + compose_file_name=["docker-compose.yml"], + pull=True) as compose: + + stdout, stderr = compose.get_logs() + if stderr: + print("Errors\\n:{}".format(stderr)) + print(stdout) + yield diff --git a/examples/e2e/tests/consumer/test_user_consumer.py b/examples/e2e/tests/consumer/test_user_consumer.py index 9e96dd2cc..abad18970 100644 --- a/examples/e2e/tests/consumer/test_user_consumer.py +++ b/examples/e2e/tests/consumer/test_user_consumer.py @@ -2,9 +2,6 @@ import logging import os -import atexit - -from testcontainers.compose import DockerCompose import pytest from pact import Consumer, Like, Provider, Term, Format @@ -32,27 +29,8 @@ def consumer(): .format(host=PACT_MOCK_HOST, port=PACT_MOCK_PORT) ) -@pytest.fixture(scope='session') -def broker(request): - version = request.config.getoption('--publish-pact') - publish = True if version else False - - if not publish: - return - - print('Starting broker') - with DockerCompose("../broker", - compose_file_name=["docker-compose.yml"], - pull=True) as compose: - - stdout, stderr = compose.get_logs() - if stderr: - print("Errors\\n:{}".format(stderr)) - print(stdout) - yield - -@pytest.fixture(scope='session') +@pytest.fixture(scope='class') def pact(request): version = request.config.getoption('--publish-pact') publish = True if version else False @@ -103,4 +81,4 @@ def test_get_non_existing_user(broker, pact, consumer): with pact: user = consumer.get_user('UserA') assert user is None - # pact.verify() + pact.verify() diff --git a/examples/e2e/tests/consumer/userserviceclient-userservice.json b/examples/e2e/tests/consumer/userserviceclient-userservice.json index 5453494e2..da96547a9 100644 --- a/examples/e2e/tests/consumer/userserviceclient-userservice.json +++ b/examples/e2e/tests/consumer/userserviceclient-userservice.json @@ -6,43 +6,6 @@ "name": "UserService" }, "interactions": [ - { - "description": "a request for UserA", - "providerState": "UserA exists and is not an administrator", - "request": { - "method": "get", - "path": "/users/UserA" - }, - "response": { - "status": 200, - "headers": { - }, - "body": { - "name": "UserA", - "id": "fc763eba-0905-41c5-a27f-3934ab26786c", - "created_on": "2016-12-15T20:16:01", - "ip_address": "127.0.0.1", - "admin": false - }, - "matchingRules": { - "$.body": { - "match": "type" - }, - "$.body.id": { - "match": "regex", - "regex": "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}" - }, - "$.body.created_on": { - "match": "regex", - "regex": "\\d+-\\d+-\\d+T\\d+:\\d+:\\d+" - }, - "$.body.ip_address": { - "match": "regex", - "regex": "(\\d{1,3}\\.)+\\d{1,3}" - } - } - } - }, { "description": "a request for UserA", "providerState": "UserA does not exist", diff --git a/examples/e2e/tests/provider/test_provider.py b/examples/e2e/tests/provider/test_provider.py index 900ebab73..0397bb1bc 100644 --- a/examples/e2e/tests/provider/test_provider.py +++ b/examples/e2e/tests/provider/test_provider.py @@ -2,7 +2,6 @@ import logging import os -from testcontainers.compose import DockerCompose from pact import Verifier import pytest @@ -21,31 +20,25 @@ PACT_BROKER_PASSWORD = "pactbroker" PACT_MOCK_HOST = 'localhost' -PACT_MOCK_PORT = 1235 +PACT_MOCK_PORT = 5001 PACT_URL = "http://{}:{}".format(PACT_MOCK_HOST, PACT_MOCK_PORT) PACT_DIR = os.path.dirname(os.path.realpath(__file__)) +@pytest.fixture +def default_opts(): + return { + 'broker_username': PACT_BROKER_USERNAME, + 'broker_password': PACT_BROKER_PASSWORD, + 'broker_url': PACT_BROKER_URL + } -def test_get_user_non_admin(): + +def test_get_user_non_admin(default_opts): verifier = Verifier(provider='UserService', provider_base_url=PACT_URL) - output, logs = verifier.verify_pacts('./userserviceclient-userservice.json', - verbose=False, - provider_states_setup_url="{}/_pact/provider_states".format(PACT_URL)) + output, logs = verifier.verify_with_broker(**default_opts, + verbose=True, + provider_states_setup_url="{}/_pact/provider_states".format(PACT_URL)) assert (output == 0) - - -# @pytest.fixture(scope='session') -# def broker(): -# print('Starting broker') -# with DockerCompose("../broker", -# compose_file_name=["docker-compose.yml"], -# pull=True) as compose: - -# stdout, stderr = compose.get_logs() -# if stderr: -# print("Errors\\n:{}".format(stderr)) -# print(stdout) -# yield From 565bc80cd2d069df6ac9004685165ad1e7ad9236 Mon Sep 17 00:00:00 2001 From: Elliott Murray Date: Sun, 14 Mar 2021 11:02:35 +0000 Subject: [PATCH 08/41] chore: added some docs about how to use the e2e example --- examples/e2e/README.md | 23 ++++++++++--------- examples/e2e/tests/conftest.py | 4 +++- .../e2e/tests/consumer/test_user_consumer.py | 1 - 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/examples/e2e/README.md b/examples/e2e/README.md index aef04a66f..0b6d50925 100644 --- a/examples/e2e/README.md +++ b/examples/e2e/README.md @@ -1,6 +1,8 @@ # Introduction -This is an e2e example to show the provider verification working for both cli and python api. +This is an e2e example to show the provider verification working for both cli and python api. + +Note in this example we are within conftest we are creating a Broker instance. This is purely to help demonstrate using Pact Broker in the code and you are strongly advised to set up a persistent Broker or use Pactflow ## Setup @@ -8,21 +10,22 @@ Create your own virtualenv for this. Run ```bash pip install -r requirements.txt -pip install ../../ -pytest +pip install -e ../../ +./run_pytest.sh ``` -This should provide you with a relative path to pact install relatively (2 dirs up) +This should provide you with a relative path to pact install relatively (2 dirs up) You can look at the Makefile in the root folder for more details. + -Create the local broker (for demo purposes only) Open a separate terminal in the examples/broker folder and run: +# Running +This example runs broker as part of it's tests. However, if you did wish to create the local broker open a separate terminal in the examples/broker folder and run: ```bash docker-compose up ``` -If you can open a browser to http://localhost and see the broker you have succeeded. +If you can open a browser to http://localhost and see the broker you have succeeded. You will have to remove the fixture in conftest.py to get this for the consumer to work, however. ## Consumer - From the root directory run: ```bash @@ -40,9 +43,7 @@ To get the consumer to publish a pact to broker you will need to run (2 is an ar pytest tests/consumer/test_user_consumer.py --publish-pact 2 ``` -And then you can run: +This example is using the python verifier code. There is an example script of how you could run the verifier cli which would be invoked like: ```bash ./verify_pact.sh 2 -``` - -To verify the pact +``` \ No newline at end of file diff --git a/examples/e2e/tests/conftest.py b/examples/e2e/tests/conftest.py index 868af50e8..76c83f55a 100644 --- a/examples/e2e/tests/conftest.py +++ b/examples/e2e/tests/conftest.py @@ -14,7 +14,9 @@ def pytest_addoption(parser): help="The url to our provider." ) - +# This fixture is to simulate a managed Pact Broker or Pactflow account +# Do not do this yourself but setup one of the above +# https://github.com/pact-foundation/pact_broker @pytest.fixture(scope='session', autouse=True) def broker(request): version = request.config.getoption('--publish-pact') diff --git a/examples/e2e/tests/consumer/test_user_consumer.py b/examples/e2e/tests/consumer/test_user_consumer.py index abad18970..5427dac60 100644 --- a/examples/e2e/tests/consumer/test_user_consumer.py +++ b/examples/e2e/tests/consumer/test_user_consumer.py @@ -42,7 +42,6 @@ def pact(request): print('start service') pact.start_service() - # atexit.register(pact.stop_service) yield pact print('stop service') From f82c0084ced5889a2306b940966840f62ed81a70 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 20 Mar 2021 04:53:58 +0000 Subject: [PATCH 09/41] chore(deps): bump jinja2 from 2.11.2 to 2.11.3 in /examples/e2e Bumps [jinja2](https://github.com/pallets/jinja) from 2.11.2 to 2.11.3. - [Release notes](https://github.com/pallets/jinja/releases) - [Changelog](https://github.com/pallets/jinja/blob/master/CHANGES.rst) - [Commits](https://github.com/pallets/jinja/compare/2.11.2...2.11.3) Signed-off-by: dependabot[bot] --- examples/e2e/Pipfile.lock | 115 ++++++++++++++++++++++++++------------ 1 file changed, 80 insertions(+), 35 deletions(-) diff --git a/examples/e2e/Pipfile.lock b/examples/e2e/Pipfile.lock index d3c8e0c12..c109e91ca 100644 --- a/examples/e2e/Pipfile.lock +++ b/examples/e2e/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "851a6e86276202576d0791677eb6d317d21d0bfac565835415870de3864c99b5" + "sha256": "3dc994a14f409cfa7ab130bdb194266f26b88a460cefd89eaaf8c04eff7561bb" }, "pipfile-spec": 6, "requires": { @@ -18,18 +18,17 @@ "default": { "attrs": { "hashes": [ - "sha256:26b54ddbbb9ee1d34d5d3668dd37d6cf74990ab23c828c2888dccdceee395594", - "sha256:fce7fc47dfc976152e82d53ff92fa0407700c21acd20886a13777a0d20e655dc" + "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6", + "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==20.2.0" + "version": "==20.3.0" }, "certifi": { "hashes": [ - "sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3", - "sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41" + "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c", + "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830" ], - "version": "==2020.6.20" + "version": "==2020.12.5" }, "chardet": { "hashes": [ @@ -43,7 +42,6 @@ "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==7.1.2" }, "flask": { @@ -59,7 +57,6 @@ "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6", "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.10" }, "itsdangerous": { @@ -67,16 +64,15 @@ "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19", "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.1.0" }, "jinja2": { "hashes": [ - "sha256:89aab215427ef59c34ad58735269eb58b1a5808103067f7bb9d5836c651b3bb0", - "sha256:f0a4641d3cf955324a89c04f3d94663aa4d638abe8f733ecd3582848e1c37035" + "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419", + "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==2.11.2" + "index": "pypi", + "version": "==2.11.3" }, "markupsafe": { "hashes": [ @@ -85,8 +81,12 @@ "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42", + "sha256:195d7d2c4fbb0ee8139a6cf67194f3973a6b3042d742ebe0a9ed36d8b6f0c07f", + "sha256:22c178a091fc6630d0d045bdb5992d2dfe14e3259760e713c490da5323866c39", "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", + "sha256:2beec1e0de6924ea551859edb9e7679da6e4870d32cb766240ce17e0a0ba2014", + "sha256:3b8a6499709d29c2e2399569d96719a1b21dcd94410a586a18526b143ec8470f", "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", @@ -95,66 +95,115 @@ "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15", "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", + "sha256:6f1e273a344928347c1290119b493a1f0303c52f5a5eae5f16d74f48c15d4a85", + "sha256:6fffc775d90dcc9aed1b89219549b329a9250d918fd0b8fa8d93d154918422e1", "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", + "sha256:7fed13866cf14bba33e7176717346713881f56d9d2bcebab207f7a036f41b850", + "sha256:84dee80c15f1b560d55bcfe6d47b27d070b4681c699c572af2e3c7cc90a3b8e0", "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", + "sha256:98bae9582248d6cf62321dcb52aaf5d9adf0bad3b40582925ef7c7f0ed85fceb", "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", + "sha256:a6a744282b7718a2a62d2ed9d993cad6f5f585605ad352c11de459f4108df0a1", + "sha256:acf08ac40292838b3cbbb06cfe9b2cb9ec78fce8baca31ddb87aaac2e2dc3bc2", "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", + "sha256:b1dba4527182c95a0db8b6060cc98ac49b9e2f5e64320e2b56e47cb2831978c7", "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", + "sha256:b7d644ddb4dbd407d31ffb699f1d140bc35478da613b441c582aeb7c43838dd8", "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", + "sha256:bf5aa3cbcfdf57fa2ee9cd1822c862ef23037f5c832ad09cfea57fa846dec193", "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", + "sha256:caabedc8323f1e93231b52fc32bdcde6db817623d33e100708d9a68e1f53b26b", "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2", + "sha256:d53bc011414228441014aa71dbec320c66468c1030aae3a6e29778a3382d96e5", + "sha256:d73a845f227b0bfe8a7455ee623525ee656a9e2e749e4742706d80a6065d5e2c", + "sha256:d9be0ba6c527163cbed5e0857c451fcd092ce83947944d6c14bc95441203f032", "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7", - "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be" + "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be", + "sha256:feb7b34d6325451ef96bc0e36e1a6c0c1c64bc1fbec4b854f4529e51887b1621" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.1.1" }, "more-itertools": { "hashes": [ - "sha256:8e1a2a43b2f2727425f2b5839587ae37093f19153dc26c0927d1048ff6557330", - "sha256:b3a9005928e5bed54076e6e549c792b306fddfe72b2d1d22dd63d42d5d3899cf" + "sha256:5652a9ac72209ed7df8d9c15daf4e1aa0e3d2ccd3c87f8265a0673cd9cbc9ced", + "sha256:c5d6da9ca3ff65220c3bfd2a8db06d698f05d4d2b9be57e1deb2be5a45019713" ], - "markers": "python_version >= '3.5'", - "version": "==8.6.0" + "version": "==8.7.0" }, "packaging": { "hashes": [ - "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8", - "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181" + "sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5", + "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a" + ], + "version": "==20.9" + }, + "pact-python": { + "hashes": [ + "sha256:0f014af33180ee4ed4d557acafaddc3f59bd6958fa49700e638197117e742bd0" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==20.4" + "index": "pypi", + "version": "==1.3.1" }, "pluggy": { "hashes": [ "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0", "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==0.13.1" }, + "psutil": { + "hashes": [ + "sha256:0066a82f7b1b37d334e68697faba68e5ad5e858279fd6351c8ca6024e8d6ba64", + "sha256:02b8292609b1f7fcb34173b25e48d0da8667bc85f81d7476584d889c6e0f2131", + "sha256:0ae6f386d8d297177fd288be6e8d1afc05966878704dad9847719650e44fc49c", + "sha256:0c9ccb99ab76025f2f0bbecf341d4656e9c1351db8cc8a03ccd62e318ab4b5c6", + "sha256:0dd4465a039d343925cdc29023bb6960ccf4e74a65ad53e768403746a9207023", + "sha256:12d844996d6c2b1d3881cfa6fa201fd635971869a9da945cf6756105af73d2df", + "sha256:1bff0d07e76114ec24ee32e7f7f8d0c4b0514b3fae93e3d2aaafd65d22502394", + "sha256:245b5509968ac0bd179287d91210cd3f37add77dad385ef238b275bad35fa1c4", + "sha256:28ff7c95293ae74bf1ca1a79e8805fcde005c18a122ca983abf676ea3466362b", + "sha256:36b3b6c9e2a34b7d7fbae330a85bf72c30b1c827a4366a07443fc4b6270449e2", + "sha256:52de075468cd394ac98c66f9ca33b2f54ae1d9bff1ef6b67a212ee8f639ec06d", + "sha256:5da29e394bdedd9144c7331192e20c1f79283fb03b06e6abd3a8ae45ffecee65", + "sha256:61f05864b42fedc0771d6d8e49c35f07efd209ade09a5afe6a5059e7bb7bf83d", + "sha256:6223d07a1ae93f86451d0198a0c361032c4c93ebd4bf6d25e2fb3edfad9571ef", + "sha256:6323d5d845c2785efb20aded4726636546b26d3b577aded22492908f7c1bdda7", + "sha256:6ffe81843131ee0ffa02c317186ed1e759a145267d54fdef1bc4ea5f5931ab60", + "sha256:74f2d0be88db96ada78756cb3a3e1b107ce8ab79f65aa885f76d7664e56928f6", + "sha256:74fb2557d1430fff18ff0d72613c5ca30c45cdbfcddd6a5773e9fc1fe9364be8", + "sha256:90d4091c2d30ddd0a03e0b97e6a33a48628469b99585e2ad6bf21f17423b112b", + "sha256:90f31c34d25b1b3ed6c40cdd34ff122b1887a825297c017e4cbd6796dd8b672d", + "sha256:99de3e8739258b3c3e8669cb9757c9a861b2a25ad0955f8e53ac662d66de61ac", + "sha256:c6a5fd10ce6b6344e616cf01cc5b849fa8103fbb5ba507b6b2dee4c11e84c935", + "sha256:ce8b867423291cb65cfc6d9c4955ee9bfc1e21fe03bb50e177f2b957f1c2469d", + "sha256:d225cd8319aa1d3c85bf195c4e07d17d3cd68636b8fc97e6cf198f782f99af28", + "sha256:ea313bb02e5e25224e518e4352af4bf5e062755160f77e4b1767dd5ccb65f876", + "sha256:ea372bcc129394485824ae3e3ddabe67dc0b118d262c568b4d2602a7070afdb0", + "sha256:f4634b033faf0d968bb9220dd1c793b897ab7f1189956e1aa9eae752527127d3", + "sha256:fcc01e900c1d7bee2a37e5d6e4f9194760a93597c97fee89c4ae51701de03563" + ], + "version": "==5.8.0" + }, "py": { "hashes": [ - "sha256:366389d1db726cd2fcfc79732e75410e5fe4d31db13692115529d34069a043c2", - "sha256:9ca6883ce56b4e8da7e79ac18787889fa5206c79dcc67fb065376cd2fe03f342" + "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3", + "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.9.0" + "version": "==1.10.0" }, "pyparsing": { "hashes": [ "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1", "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b" ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.4.7" }, "pytest": { @@ -168,7 +217,6 @@ "requests": { "hashes": [ "sha256:43999036bfa82904b6af1d99e4882b560e5e2c68e5c4b0aa03b655f3d7d73fee", - "sha256:5d2d0ffbb515f39417009a46c14256291061ac01ba8f875b90cad137de83beb4", "sha256:b3f43d496c6daba4493e7c431722aeb7dbc6288f52a6e04e7b6023b0247817e6" ], "index": "pypi", @@ -179,7 +227,6 @@ "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.15.0" }, "urllib3": { @@ -187,7 +234,6 @@ "sha256:8d7eaa5a82a1cac232164990f04874c594c9453ec55eef02eab885aa02fc17a2", "sha256:f5321fbe4bf3fefa0efd0bfe7fb14e90909eb62a48ccda331726b4319897dd5e" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", "version": "==1.25.11" }, "wcwidth": { @@ -202,7 +248,6 @@ "sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43", "sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==1.0.1" } }, From 579f3f88f6169aeced0b666dad751ce158ad4a42 Mon Sep 17 00:00:00 2001 From: Elliott Murray Date: Sun, 21 Mar 2021 13:18:01 +0000 Subject: [PATCH 10/41] fix: ensure path is passed to broker and allow running from root rather than test file --- examples/e2e/Pipfile | 15 -- examples/e2e/Pipfile.lock | 255 ------------------ examples/e2e/{tests => }/conftest.py | 0 examples/e2e/pythonclient-pythonservice.json | 81 ------ examples/e2e/run_pytest.sh | 2 +- .../e2e/userserviceclient-userservice.json | 65 ----- pact/broker.py | 1 + pact/pact.py | 1 + tests/test_broker.py | 38 ++- tests/test_pact.py | 9 +- 10 files changed, 36 insertions(+), 431 deletions(-) delete mode 100644 examples/e2e/Pipfile delete mode 100644 examples/e2e/Pipfile.lock rename examples/e2e/{tests => }/conftest.py (100%) delete mode 100644 examples/e2e/pythonclient-pythonservice.json delete mode 100644 examples/e2e/userserviceclient-userservice.json diff --git a/examples/e2e/Pipfile b/examples/e2e/Pipfile deleted file mode 100644 index 1683a3826..000000000 --- a/examples/e2e/Pipfile +++ /dev/null @@ -1,15 +0,0 @@ -[[source]] -name = "pypi" -url = "https://pypi.org/simple" -verify_ssl = true - -[dev-packages] - -[packages] -pytest = "==5.4.1" -requests = "==2.23.0" -Flask = "==1.1.1" -pact-python = "*" - -[requires] -python_version = "3.8" diff --git a/examples/e2e/Pipfile.lock b/examples/e2e/Pipfile.lock deleted file mode 100644 index c109e91ca..000000000 --- a/examples/e2e/Pipfile.lock +++ /dev/null @@ -1,255 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "3dc994a14f409cfa7ab130bdb194266f26b88a460cefd89eaaf8c04eff7561bb" - }, - "pipfile-spec": 6, - "requires": { - "python_version": "3.8" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.org/simple", - "verify_ssl": true - } - ] - }, - "default": { - "attrs": { - "hashes": [ - "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6", - "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700" - ], - "version": "==20.3.0" - }, - "certifi": { - "hashes": [ - "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c", - "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830" - ], - "version": "==2020.12.5" - }, - "chardet": { - "hashes": [ - "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", - "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" - ], - "version": "==3.0.4" - }, - "click": { - "hashes": [ - "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", - "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" - ], - "version": "==7.1.2" - }, - "flask": { - "hashes": [ - "sha256:13f9f196f330c7c2c5d7a5cf91af894110ca0215ac051b5844701f2bfd934d52", - "sha256:45eb5a6fd193d6cf7e0cf5d8a5b31f83d5faae0293695626f539a823e93b13f6" - ], - "index": "pypi", - "version": "==1.1.1" - }, - "idna": { - "hashes": [ - "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6", - "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0" - ], - "version": "==2.10" - }, - "itsdangerous": { - "hashes": [ - "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19", - "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749" - ], - "version": "==1.1.0" - }, - "jinja2": { - "hashes": [ - "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419", - "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6" - ], - "index": "pypi", - "version": "==2.11.3" - }, - "markupsafe": { - "hashes": [ - "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473", - "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", - "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", - "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", - "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42", - "sha256:195d7d2c4fbb0ee8139a6cf67194f3973a6b3042d742ebe0a9ed36d8b6f0c07f", - "sha256:22c178a091fc6630d0d045bdb5992d2dfe14e3259760e713c490da5323866c39", - "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", - "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", - "sha256:2beec1e0de6924ea551859edb9e7679da6e4870d32cb766240ce17e0a0ba2014", - "sha256:3b8a6499709d29c2e2399569d96719a1b21dcd94410a586a18526b143ec8470f", - "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", - "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", - "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", - "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", - "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b", - "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", - "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15", - "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", - "sha256:6f1e273a344928347c1290119b493a1f0303c52f5a5eae5f16d74f48c15d4a85", - "sha256:6fffc775d90dcc9aed1b89219549b329a9250d918fd0b8fa8d93d154918422e1", - "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", - "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", - "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", - "sha256:7fed13866cf14bba33e7176717346713881f56d9d2bcebab207f7a036f41b850", - "sha256:84dee80c15f1b560d55bcfe6d47b27d070b4681c699c572af2e3c7cc90a3b8e0", - "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", - "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", - "sha256:98bae9582248d6cf62321dcb52aaf5d9adf0bad3b40582925ef7c7f0ed85fceb", - "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", - "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", - "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", - "sha256:a6a744282b7718a2a62d2ed9d993cad6f5f585605ad352c11de459f4108df0a1", - "sha256:acf08ac40292838b3cbbb06cfe9b2cb9ec78fce8baca31ddb87aaac2e2dc3bc2", - "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", - "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", - "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", - "sha256:b1dba4527182c95a0db8b6060cc98ac49b9e2f5e64320e2b56e47cb2831978c7", - "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", - "sha256:b7d644ddb4dbd407d31ffb699f1d140bc35478da613b441c582aeb7c43838dd8", - "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", - "sha256:bf5aa3cbcfdf57fa2ee9cd1822c862ef23037f5c832ad09cfea57fa846dec193", - "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", - "sha256:caabedc8323f1e93231b52fc32bdcde6db817623d33e100708d9a68e1f53b26b", - "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", - "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2", - "sha256:d53bc011414228441014aa71dbec320c66468c1030aae3a6e29778a3382d96e5", - "sha256:d73a845f227b0bfe8a7455ee623525ee656a9e2e749e4742706d80a6065d5e2c", - "sha256:d9be0ba6c527163cbed5e0857c451fcd092ce83947944d6c14bc95441203f032", - "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7", - "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be", - "sha256:feb7b34d6325451ef96bc0e36e1a6c0c1c64bc1fbec4b854f4529e51887b1621" - ], - "version": "==1.1.1" - }, - "more-itertools": { - "hashes": [ - "sha256:5652a9ac72209ed7df8d9c15daf4e1aa0e3d2ccd3c87f8265a0673cd9cbc9ced", - "sha256:c5d6da9ca3ff65220c3bfd2a8db06d698f05d4d2b9be57e1deb2be5a45019713" - ], - "version": "==8.7.0" - }, - "packaging": { - "hashes": [ - "sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5", - "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a" - ], - "version": "==20.9" - }, - "pact-python": { - "hashes": [ - "sha256:0f014af33180ee4ed4d557acafaddc3f59bd6958fa49700e638197117e742bd0" - ], - "index": "pypi", - "version": "==1.3.1" - }, - "pluggy": { - "hashes": [ - "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0", - "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d" - ], - "version": "==0.13.1" - }, - "psutil": { - "hashes": [ - "sha256:0066a82f7b1b37d334e68697faba68e5ad5e858279fd6351c8ca6024e8d6ba64", - "sha256:02b8292609b1f7fcb34173b25e48d0da8667bc85f81d7476584d889c6e0f2131", - "sha256:0ae6f386d8d297177fd288be6e8d1afc05966878704dad9847719650e44fc49c", - "sha256:0c9ccb99ab76025f2f0bbecf341d4656e9c1351db8cc8a03ccd62e318ab4b5c6", - "sha256:0dd4465a039d343925cdc29023bb6960ccf4e74a65ad53e768403746a9207023", - "sha256:12d844996d6c2b1d3881cfa6fa201fd635971869a9da945cf6756105af73d2df", - "sha256:1bff0d07e76114ec24ee32e7f7f8d0c4b0514b3fae93e3d2aaafd65d22502394", - "sha256:245b5509968ac0bd179287d91210cd3f37add77dad385ef238b275bad35fa1c4", - "sha256:28ff7c95293ae74bf1ca1a79e8805fcde005c18a122ca983abf676ea3466362b", - "sha256:36b3b6c9e2a34b7d7fbae330a85bf72c30b1c827a4366a07443fc4b6270449e2", - "sha256:52de075468cd394ac98c66f9ca33b2f54ae1d9bff1ef6b67a212ee8f639ec06d", - "sha256:5da29e394bdedd9144c7331192e20c1f79283fb03b06e6abd3a8ae45ffecee65", - "sha256:61f05864b42fedc0771d6d8e49c35f07efd209ade09a5afe6a5059e7bb7bf83d", - "sha256:6223d07a1ae93f86451d0198a0c361032c4c93ebd4bf6d25e2fb3edfad9571ef", - "sha256:6323d5d845c2785efb20aded4726636546b26d3b577aded22492908f7c1bdda7", - "sha256:6ffe81843131ee0ffa02c317186ed1e759a145267d54fdef1bc4ea5f5931ab60", - "sha256:74f2d0be88db96ada78756cb3a3e1b107ce8ab79f65aa885f76d7664e56928f6", - "sha256:74fb2557d1430fff18ff0d72613c5ca30c45cdbfcddd6a5773e9fc1fe9364be8", - "sha256:90d4091c2d30ddd0a03e0b97e6a33a48628469b99585e2ad6bf21f17423b112b", - "sha256:90f31c34d25b1b3ed6c40cdd34ff122b1887a825297c017e4cbd6796dd8b672d", - "sha256:99de3e8739258b3c3e8669cb9757c9a861b2a25ad0955f8e53ac662d66de61ac", - "sha256:c6a5fd10ce6b6344e616cf01cc5b849fa8103fbb5ba507b6b2dee4c11e84c935", - "sha256:ce8b867423291cb65cfc6d9c4955ee9bfc1e21fe03bb50e177f2b957f1c2469d", - "sha256:d225cd8319aa1d3c85bf195c4e07d17d3cd68636b8fc97e6cf198f782f99af28", - "sha256:ea313bb02e5e25224e518e4352af4bf5e062755160f77e4b1767dd5ccb65f876", - "sha256:ea372bcc129394485824ae3e3ddabe67dc0b118d262c568b4d2602a7070afdb0", - "sha256:f4634b033faf0d968bb9220dd1c793b897ab7f1189956e1aa9eae752527127d3", - "sha256:fcc01e900c1d7bee2a37e5d6e4f9194760a93597c97fee89c4ae51701de03563" - ], - "version": "==5.8.0" - }, - "py": { - "hashes": [ - "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3", - "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a" - ], - "version": "==1.10.0" - }, - "pyparsing": { - "hashes": [ - "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1", - "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b" - ], - "version": "==2.4.7" - }, - "pytest": { - "hashes": [ - "sha256:0e5b30f5cb04e887b91b1ee519fa3d89049595f428c1db76e73bd7f17b09b172", - "sha256:84dde37075b8805f3d1f392cc47e38a0e59518fb46a431cfdaf7cf1ce805f970" - ], - "index": "pypi", - "version": "==5.4.1" - }, - "requests": { - "hashes": [ - "sha256:43999036bfa82904b6af1d99e4882b560e5e2c68e5c4b0aa03b655f3d7d73fee", - "sha256:b3f43d496c6daba4493e7c431722aeb7dbc6288f52a6e04e7b6023b0247817e6" - ], - "index": "pypi", - "version": "==2.23.0" - }, - "six": { - "hashes": [ - "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", - "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" - ], - "version": "==1.15.0" - }, - "urllib3": { - "hashes": [ - "sha256:8d7eaa5a82a1cac232164990f04874c594c9453ec55eef02eab885aa02fc17a2", - "sha256:f5321fbe4bf3fefa0efd0bfe7fb14e90909eb62a48ccda331726b4319897dd5e" - ], - "version": "==1.25.11" - }, - "wcwidth": { - "hashes": [ - "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784", - "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83" - ], - "version": "==0.2.5" - }, - "werkzeug": { - "hashes": [ - "sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43", - "sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c" - ], - "version": "==1.0.1" - } - }, - "develop": {} -} diff --git a/examples/e2e/tests/conftest.py b/examples/e2e/conftest.py similarity index 100% rename from examples/e2e/tests/conftest.py rename to examples/e2e/conftest.py diff --git a/examples/e2e/pythonclient-pythonservice.json b/examples/e2e/pythonclient-pythonservice.json deleted file mode 100644 index 25bf24f9e..000000000 --- a/examples/e2e/pythonclient-pythonservice.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "consumer": { - "name": "PythonClient" - }, - "provider": { - "name": "PythonService" - }, - "interactions": [ - { - "description": "a request for UserA", - "providerState": "UserA exists and is not an administrator", - "request": { - "method": "get", - "path": "/users/UserA" - }, - "response": { - "status": 200, - "headers": { - }, - "body": { - "json_class": "Pact::SomethingLike", - "contents": { - "name": "UserA", - "id": { - "json_class": "Pact::Term", - "data": { - "generate": "fc763eba-0905-41c5-a27f-3934ab26786c", - "matcher": { - "json_class": "Regexp", - "o": 0, - "s": "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}" - } - } - }, - "created_on": { - "json_class": "Pact::Term", - "data": { - "generate": "2016-12-15T20:16:01", - "matcher": { - "json_class": "Regexp", - "o": 0, - "s": "\\d+-\\d+-\\d+T\\d+:\\d+:\\d+" - } - } - }, - "ip_address": { - "json_class": "Pact::Term", - "data": { - "generate": "127.0.0.1", - "matcher": { - "json_class": "Regexp", - "o": 0, - "s": "(\\d{1,3}\\.)+\\d{1,3}" - } - } - }, - "admin": false - } - } - } - }, - { - "description": "a request for UserA", - "providerState": "UserA does not exist", - "request": { - "method": "get", - "path": "/users/UserA" - }, - "response": { - "status": 404, - "headers": { - } - } - } - ], - "metadata": { - "pactSpecification": { - "version": "1.0.0" - } - } -} \ No newline at end of file diff --git a/examples/e2e/run_pytest.sh b/examples/e2e/run_pytest.sh index ba541e6e4..212b1e4c8 100755 --- a/examples/e2e/run_pytest.sh +++ b/examples/e2e/run_pytest.sh @@ -13,7 +13,7 @@ trap teardown EXIT sleep 3 -pytest --publish-pact 1 +pytest contract_tests --publish-pact 1 teardown diff --git a/examples/e2e/userserviceclient-userservice.json b/examples/e2e/userserviceclient-userservice.json deleted file mode 100644 index 5453494e2..000000000 --- a/examples/e2e/userserviceclient-userservice.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "consumer": { - "name": "UserServiceClient" - }, - "provider": { - "name": "UserService" - }, - "interactions": [ - { - "description": "a request for UserA", - "providerState": "UserA exists and is not an administrator", - "request": { - "method": "get", - "path": "/users/UserA" - }, - "response": { - "status": 200, - "headers": { - }, - "body": { - "name": "UserA", - "id": "fc763eba-0905-41c5-a27f-3934ab26786c", - "created_on": "2016-12-15T20:16:01", - "ip_address": "127.0.0.1", - "admin": false - }, - "matchingRules": { - "$.body": { - "match": "type" - }, - "$.body.id": { - "match": "regex", - "regex": "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}" - }, - "$.body.created_on": { - "match": "regex", - "regex": "\\d+-\\d+-\\d+T\\d+:\\d+:\\d+" - }, - "$.body.ip_address": { - "match": "regex", - "regex": "(\\d{1,3}\\.)+\\d{1,3}" - } - } - } - }, - { - "description": "a request for UserA", - "providerState": "UserA does not exist", - "request": { - "method": "get", - "path": "/users/UserA" - }, - "response": { - "status": 404, - "headers": { - } - } - } - ], - "metadata": { - "pactSpecification": { - "version": "2.0.0" - } - } -} \ No newline at end of file diff --git a/pact/broker.py b/pact/broker.py index 814bc93ef..7f70ca3f3 100644 --- a/pact/broker.py +++ b/pact/broker.py @@ -61,6 +61,7 @@ def publish(self, consumer_name, version, pact_dir=None, os.listdir(pact_dir), self._normalize_consumer_name(consumer_name) + '*.json' ) + pact_files = list(map(lambda pact_file: f'{pact_dir}/{pact_file}', pact_files)) command = [ BROKER_CLIENT_PATH, 'publish', diff --git a/pact/pact.py b/pact/pact.py index b2403dfb2..a6ec2cdec 100644 --- a/pact/pact.py +++ b/pact/pact.py @@ -238,6 +238,7 @@ def stop_service(self): self.consumer.version, tag_with_git_branch=self.consumer.tag_with_git_branch, consumer_tags=self.consumer.tags, + pact_dir=self.pact_dir ) def upon_receiving(self, scenario): diff --git a/tests/test_broker.py b/tests/test_broker.py index 47ec26630..2659ab118 100644 --- a/tests/test_broker.py +++ b/tests/test_broker.py @@ -37,7 +37,9 @@ def test_publish_fails(self): broker_token="token") with self.assertRaises(RuntimeError): - broker.publish("TestConsumer", "2.0.1") + broker.publish("TestConsumer", + "2.0.1", + pact_dir='.') self.mock_Popen.assert_called_once_with([ BROKER_CLIENT_PATH, 'publish', @@ -46,7 +48,7 @@ def test_publish_fails(self): '--broker-username=username', '--broker-password=password', '--broker-token=token', - 'TestConsumer-TestProvider.json']) + './TestConsumer-TestProvider.json']) def test_publish_with_broker_url_environment_variable(self): BROKER_URL_ENV = 'http://broker.url' @@ -55,7 +57,9 @@ def test_publish_with_broker_url_environment_variable(self): broker = Broker(broker_username="username", broker_password="password") - broker.publish("TestConsumer", "2.0.1") + broker.publish("TestConsumer", + "2.0.1", + pact_dir='.') self.mock_Popen.assert_called_once_with([ BROKER_CLIENT_PATH, 'publish', @@ -63,7 +67,7 @@ def test_publish_with_broker_url_environment_variable(self): f"--broker-base-url={BROKER_URL_ENV}", '--broker-username=username', '--broker-password=password', - 'TestConsumer-TestProvider.json']) + './TestConsumer-TestProvider.json']) del os.environ["PACT_BROKER_BASE_URL"] @@ -72,7 +76,9 @@ def test_basic_authenticated_publish(self): broker_username="username", broker_password="password") - broker.publish("TestConsumer", "2.0.1") + broker.publish("TestConsumer", + "2.0.1", + pact_dir='.') self.mock_Popen.assert_called_once_with([ BROKER_CLIENT_PATH, 'publish', @@ -80,7 +86,7 @@ def test_basic_authenticated_publish(self): '--broker-base-url=http://localhost', '--broker-username=username', '--broker-password=password', - 'TestConsumer-TestProvider.json']) + './TestConsumer-TestProvider.json']) def test_token_authenticated_publish(self): broker = Broker(broker_base_url="http://localhost", @@ -88,7 +94,9 @@ def test_token_authenticated_publish(self): broker_password="password", broker_token="token") - broker.publish("TestConsumer", "2.0.1") + broker.publish("TestConsumer", + "2.0.1", + pact_dir='.') self.mock_Popen.assert_called_once_with([ BROKER_CLIENT_PATH, 'publish', @@ -97,29 +105,35 @@ def test_token_authenticated_publish(self): '--broker-username=username', '--broker-password=password', '--broker-token=token', - 'TestConsumer-TestProvider.json']) + './TestConsumer-TestProvider.json']) def test_git_tagged_publish(self): broker = Broker(broker_base_url="http://localhost") - broker.publish("TestConsumer", "2.0.1", tag_with_git_branch=True) + broker.publish("TestConsumer", + "2.0.1", + tag_with_git_branch=True, + pact_dir='.') self.mock_Popen.assert_called_once_with([ BROKER_CLIENT_PATH, 'publish', '--consumer-app-version=2.0.1', '--broker-base-url=http://localhost', - 'TestConsumer-TestProvider.json', + './TestConsumer-TestProvider.json', '--tag-with-git-branch']) def test_manual_tagged_publish(self): broker = Broker(broker_base_url="http://localhost") - broker.publish("TestConsumer", "2.0.1", consumer_tags=['tag1', 'tag2']) + broker.publish("TestConsumer", + "2.0.1", + consumer_tags=['tag1', 'tag2'], + pact_dir='.') self.mock_Popen.assert_called_once_with([ BROKER_CLIENT_PATH, 'publish', '--consumer-app-version=2.0.1', '--broker-base-url=http://localhost', - 'TestConsumer-TestProvider.json', + './TestConsumer-TestProvider.json', '-t', 'tag1', '-t', 'tag2']) diff --git a/tests/test_pact.py b/tests/test_pact.py index 196a9bd47..76e3dd346 100644 --- a/tests/test_pact.py +++ b/tests/test_pact.py @@ -371,7 +371,7 @@ def test_stop_windows(self): ruby_exe = Mock(spec=Process) self.mock_Process.return_value.children.return_value = [ruby_exe] self.mock_Pid_exists.return_value = False - pact = Pact(Consumer('consumer', version='abc'), Provider('provider'), publish_to_broker=True) + pact = Pact(Consumer('consumer', version='abc'), Provider('provider'), publish_to_broker=True, pact_dir='some_dir') pact._process = Mock(spec=Popen, pid=999) pact.stop_service() @@ -384,7 +384,12 @@ def test_stop_windows(self): self.mock_Process.return_value.wait.assert_called_once_with() self.mock_Pid_exists.assert_called_once_with(999) self.mock_publish.assert_called_once_with( - pact, 'consumer', 'abc', consumer_tags=None, tag_with_git_branch=False) + pact, + 'consumer', + 'abc', + consumer_tags=None, + tag_with_git_branch=False, + pact_dir='some_dir') def test_stop_fails_posix(self): self.mock_platform.return_value = 'Linux' From af3dadf8208a2ef38555651b3e23f672aaa8879c Mon Sep 17 00:00:00 2001 From: Elliott Murray Date: Sun, 21 Mar 2021 14:21:10 +0000 Subject: [PATCH 11/41] fix: remove pacts from examples --- .gitignore | 1 + .../userserviceclient-userservice.json | 28 ------------------- 2 files changed, 1 insertion(+), 28 deletions(-) delete mode 100644 examples/e2e/tests/consumer/userserviceclient-userservice.json diff --git a/.gitignore b/.gitignore index 14f33add1..43845f6fe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # pact-python specific ignores e2e/pacts +userserviceclient-userservice.json pact/bin # Byte-compiled / optimized / DLL files diff --git a/examples/e2e/tests/consumer/userserviceclient-userservice.json b/examples/e2e/tests/consumer/userserviceclient-userservice.json deleted file mode 100644 index da96547a9..000000000 --- a/examples/e2e/tests/consumer/userserviceclient-userservice.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "consumer": { - "name": "UserServiceClient" - }, - "provider": { - "name": "UserService" - }, - "interactions": [ - { - "description": "a request for UserA", - "providerState": "UserA does not exist", - "request": { - "method": "get", - "path": "/users/UserA" - }, - "response": { - "status": 404, - "headers": { - } - } - } - ], - "metadata": { - "pactSpecification": { - "version": "2.0.0" - } - } -} \ No newline at end of file From 23a512973198fc27cdba8ae5c91db2e774e7dc0b Mon Sep 17 00:00:00 2001 From: Elliott Murray Date: Sun, 21 Mar 2021 14:32:50 +0000 Subject: [PATCH 12/41] chore: Releasing version 1.3.2 --- CHANGELOG.md | 14 ++++++++++++++ pact/__version__.py | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d48c89261..00b4a882d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +### 1.3.2 + * 57c8ae8 - Merge pull request #209 from pact-foundation/bug/fix_test_dir (Elliott Murray, Sun Mar 21 14:29:40 2021 +0000) + * af3dadf - fix: remove pacts from examples (Elliott Murray, Sun Mar 21 14:21:10 2021 +0000) + * 579f3f8 - fix: ensure path is passed to broker and allow running from root rather than test file (Elliott Murray, Sun Mar 21 13:18:01 2021 +0000) + * 7e0feab - Merge pull request #208 from pact-foundation/dependabot/pip/examples/e2e/jinja2-2.11.3 (Elliott Murray, Sat Mar 20 12:46:32 2021 +0000) + * f82c008 - chore(deps): bump jinja2 from 2.11.2 to 2.11.3 in /examples/e2e (dependabot[bot], Sat Mar 20 04:53:58 2021 +0000) + * ea6f635 - Merge pull request #206 from pact-foundation/chore/use-testcontainers (Elliott Murray, Sun Mar 14 11:05:01 2021 +0000) + * 565bc80 - chore: added some docs about how to use the e2e example (Elliott Murray, Sun Mar 14 11:02:35 2021 +0000) + * 1b4be80 - chore: spiking testcontainers (Elliott Murray, Sat Mar 13 11:15:52 2021 +0000) + * 01e4ec4 - chore: wip on using test containers on examples (Elliott Murray, Tue Mar 2 21:30:48 2021 +0000) + * 882f4a2 - Merge pull request #204 from pact-foundation/chore/use_pytest (Elliott Murray, Sat Feb 27 10:58:19 2021 +0000) + * 261f24b - chore: more clean up (Elliott Murray, Sat Feb 27 10:10:23 2021 +0000) + * 5a0934c - chore: update ci stuff (Elliott Murray, Sat Feb 27 09:57:31 2021 +0000) + * 66e79e2 - chore: move from nose to pytests as we are now 3.6+ (Elliott Murray, Sat Feb 27 09:34:37 2021 +0000) ### 1.3.1 * 4440022 - Merge pull request #203 from pact-foundation/fix/version_confusion (Elliott Murray, Sat Feb 27 09:15:08 2021 +0000) * 9cac2d7 - fix: introduced and renamed specification version (Elliott Murray, Tue Feb 23 21:22:36 2021 +0000) diff --git a/pact/__version__.py b/pact/__version__.py index 59aabf89e..4d0fe8bfe 100644 --- a/pact/__version__.py +++ b/pact/__version__.py @@ -1,3 +1,3 @@ """Pact version info.""" -__version__ = '1.3.1' +__version__ = '1.3.2' From 987c4fc367a9205105cf7cdd6dcf50f27311ef40 Mon Sep 17 00:00:00 2001 From: Anne Schuth Date: Thu, 25 Mar 2021 10:06:54 +0100 Subject: [PATCH 13/41] fix: pass pact_dir to publish() --- examples/message/tests/consumer/test_message_consumer.py | 5 ++--- pact/message_pact.py | 1 + 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/message/tests/consumer/test_message_consumer.py b/examples/message/tests/consumer/test_message_consumer.py index b82a3ab25..0f06adae9 100644 --- a/examples/message/tests/consumer/test_message_consumer.py +++ b/examples/message/tests/consumer/test_message_consumer.py @@ -20,7 +20,7 @@ CONSUMER_NAME = 'DetectContentLambda' PROVIDER_NAME = 'ContentProvider' -PACT_FILE = (f"{CONSUMER_NAME.lower().replace(' ', '_')}_message-" +PACT_FILE = (f"{PACT_DIR}/{CONSUMER_NAME.lower().replace(' ', '_')}_message-" + f"{PROVIDER_NAME.lower().replace(' ', '_')}_message.json") @pytest.fixture(scope='session') @@ -31,9 +31,8 @@ def pact(request): pact = MessageConsumer(CONSUMER_NAME, version=version).has_pact_with( Provider(PROVIDER_NAME), publish_to_broker=publish, broker_base_url=PACT_BROKER_URL, - broker_username=PACT_BROKER_USERNAME, broker_password=PACT_BROKER_PASSWORD) + broker_username=PACT_BROKER_USERNAME, broker_password=PACT_BROKER_PASSWORD, pact_dir=PACT_DIR) - # current pact does not consider the PACT_DIR argument, assumes none yield pact diff --git a/pact/message_pact.py b/pact/message_pact.py index 13ad7381c..a53e7f242 100644 --- a/pact/message_pact.py +++ b/pact/message_pact.py @@ -203,6 +203,7 @@ def __exit__(self, exc_type, exc_val, exc_tb): self.publish( self.consumer.name, self.consumer.version, + pact_dir=self.pact_dir, tag_with_git_branch=self.consumer.tag_with_git_branch, consumer_tags=self.consumer.tags, ) From 2c8779b62726897c7252b3a87134cc5301e5224a Mon Sep 17 00:00:00 2001 From: Elliott Murray Date: Thu, 25 Mar 2021 21:23:29 +0000 Subject: [PATCH 14/41] chore: Releasing version 1.3.3 --- CHANGELOG.md | 3 +++ pact/__version__.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 00b4a882d..7c190dd53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +### 1.3.3 + * 5e282ff - Merge pull request #211 from anneschuth/fix/pass-pact-dir (Elliott Murray, Thu Mar 25 21:21:56 2021 +0000) + * 987c4fc - fix: pass pact_dir to publish() (Anne Schuth, Thu Mar 25 10:06:54 2021 +0100) ### 1.3.2 * 57c8ae8 - Merge pull request #209 from pact-foundation/bug/fix_test_dir (Elliott Murray, Sun Mar 21 14:29:40 2021 +0000) * af3dadf - fix: remove pacts from examples (Elliott Murray, Sun Mar 21 14:21:10 2021 +0000) diff --git a/pact/__version__.py b/pact/__version__.py index 4d0fe8bfe..c0a3c83ed 100644 --- a/pact/__version__.py +++ b/pact/__version__.py @@ -1,3 +1,3 @@ """Pact version info.""" -__version__ = '1.3.2' +__version__ = '1.3.3' From ea0b64ae380f7a13c16522a6b42e9e94f7c9a775 Mon Sep 17 00:00:00 2001 From: Elliott Murray Date: Sat, 27 Mar 2021 16:21:25 +0000 Subject: [PATCH 15/41] fix: verifier should now publish --- examples/e2e/conftest.py | 27 ++++++++++++++------ examples/e2e/run_pytest.sh | 2 +- examples/e2e/tests/provider/test_provider.py | 4 ++- pact/cli/verify.py | 4 +-- pact/verifier.py | 10 +++++--- tests/test_verifier.py | 26 +++++++++++++++++-- 6 files changed, 55 insertions(+), 18 deletions(-) diff --git a/examples/e2e/conftest.py b/examples/e2e/conftest.py index 76c83f55a..597921114 100644 --- a/examples/e2e/conftest.py +++ b/examples/e2e/conftest.py @@ -14,6 +14,11 @@ def pytest_addoption(parser): help="The url to our provider." ) + parser.addoption( + "--run-broker", type=bool, action="store", + help="Whether to run broker in this test or not." + ) + # This fixture is to simulate a managed Pact Broker or Pactflow account # Do not do this yourself but setup one of the above # https://github.com/pact-foundation/pact_broker @@ -27,13 +32,19 @@ def broker(request): yield return - print('Starting broker') - with DockerCompose("../broker", - compose_file_name=["docker-compose.yml"], - pull=True) as compose: + run_broker = request.config.getoption('--run-broker') - stdout, stderr = compose.get_logs() - if stderr: - print("Errors\\n:{}".format(stderr)) - print(stdout) + if not run_broker: yield + return + else: + print('Starting broker') + with DockerCompose("../broker", + compose_file_name=["docker-compose.yml"], + pull=True) as compose: + + stdout, stderr = compose.get_logs() + if stderr: + print("Errors\\n:{}".format(stderr)) + print(stdout) + yield diff --git a/examples/e2e/run_pytest.sh b/examples/e2e/run_pytest.sh index 212b1e4c8..f1a55023a 100755 --- a/examples/e2e/run_pytest.sh +++ b/examples/e2e/run_pytest.sh @@ -13,7 +13,7 @@ trap teardown EXIT sleep 3 -pytest contract_tests --publish-pact 1 +pytest tests --run-broker True --publish-pact 1 teardown diff --git a/examples/e2e/tests/provider/test_provider.py b/examples/e2e/tests/provider/test_provider.py index 0397bb1bc..1cd15206d 100644 --- a/examples/e2e/tests/provider/test_provider.py +++ b/examples/e2e/tests/provider/test_provider.py @@ -29,7 +29,9 @@ def default_opts(): return { 'broker_username': PACT_BROKER_USERNAME, 'broker_password': PACT_BROKER_PASSWORD, - 'broker_url': PACT_BROKER_URL + 'broker_url': PACT_BROKER_URL, + 'publish_version': '3', + 'publish_verification_results': True } diff --git a/pact/cli/verify.py b/pact/cli/verify.py index 996d6a6c3..e597e1e0c 100644 --- a/pact/cli/verify.py +++ b/pact/cli/verify.py @@ -164,7 +164,7 @@ def main(pacts, base_url, pact_url, pact_urls, states_url, states_setup_url, raise click.Abort() if publish_verification_results: - publish_results(error, provider_app_version) + validate_publish(error, provider_app_version) options = { 'broker_password': password, @@ -196,7 +196,7 @@ def main(pacts, base_url, pact_url, pact_urls, states_url, states_setup_url, sys.exit(success) -def publish_results(error, provider_app_version): +def validate_publish(error, provider_app_version): """Publish results to broker.""" if not provider_app_version: click.echo( diff --git a/pact/verifier.py b/pact/verifier.py index a9642aee8..13222483c 100644 --- a/pact/verifier.py +++ b/pact/verifier.py @@ -70,6 +70,7 @@ def verify_with_broker(self, enable_pending=False, include_wip_pacts_since=None, broker_url ([String]): url of broker enable_pending ([Boolean]) include_wip_pacts_since ([String]) + publish_version ([String]) """ broker_username = kwargs.get('broker_username', None) @@ -103,8 +104,8 @@ def extract_params(self, **kwargs): provider_tags = kwargs.get('provider_tags', []) states_setup_url = kwargs.get('provider_states_setup_url', None) verbose = kwargs.get('verbose', False) - publish_version = kwargs.get('publish_version', None) - + provider_app_version = kwargs.get('publish_version', None) + publish_verification_results = kwargs.get('publish_verification_results', None) raw_consumer_selectors = kwargs.get('consumer_version_selectors', []) consumer_selectors = self._build_consumer_selectors(raw_consumer_selectors) @@ -118,8 +119,9 @@ def extract_params(self, **kwargs): 'provider_tags': list(provider_tags), 'provider_states_setup_url': states_setup_url, 'verbose': verbose, - 'publish_version': publish_version, - 'consumer_selectors': consumer_selectors + 'provider_app_version': provider_app_version, + 'consumer_selectors': consumer_selectors, + 'publish_verification_results': publish_verification_results } return self.filter_empty_options(**options) diff --git a/tests/test_verifier.py b/tests/test_verifier.py index 0639ab3cd..3a28c3de6 100644 --- a/tests/test_verifier.py +++ b/tests/test_verifier.py @@ -89,7 +89,7 @@ def test_publish_on_success(self, mock_path_exists, mock_wrapper): provider_base_url='http://localhost:8888', log_level='INFO', verbose=False, - publish_version='1.0.0', + provider_app_version='1.0.0', enable_pending=False, include_wip_pacts_since=None) @@ -171,6 +171,28 @@ 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_and_pubish_with_broker(self, mock_wrapper): + + mock_wrapper.return_value = (True, 'some value') + + self.default_opts['publish_verification_results'] = True + output, _ = self.verifier.verify_with_broker(**self.default_opts) + + 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, + publish_verification_results=True) + @patch("pact.verify_wrapper.VerifyWrapper.call_verify") def test_verifier_with_broker_passes_consumer_selctors(self, mock_wrapper): @@ -216,7 +238,7 @@ def test_publish_on_success(self, mock_path_exists, mock_wrapper): broker_url=self.broker_url, log_level='INFO', verbose=False, - publish_version='1.0.0', + provider_app_version='1.0.0', enable_pending=False, include_wip_pacts_since=None) From e00f320bad5b5dd8949dad2069ebacf4821cbdcb Mon Sep 17 00:00:00 2001 From: Elliott Murray Date: Sat, 27 Mar 2021 21:26:29 +0000 Subject: [PATCH 16/41] chore: Releasing version 1.3.4 --- CHANGELOG.md | 3 +++ pact/__version__.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c190dd53..f34da2c3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +### 1.3.4 + * c778c71 - Merge pull request #212 from pact-foundation/fix/verify_in_provider (Elliott Murray, Sat Mar 27 18:59:25 2021 +0000) + * ea0b64a - fix: verifier should now publish (Elliott Murray, Sat Mar 27 16:21:25 2021 +0000) ### 1.3.3 * 5e282ff - Merge pull request #211 from anneschuth/fix/pass-pact-dir (Elliott Murray, Thu Mar 25 21:21:56 2021 +0000) * 987c4fc - fix: pass pact_dir to publish() (Anne Schuth, Thu Mar 25 10:06:54 2021 +0100) diff --git a/pact/__version__.py b/pact/__version__.py index c0a3c83ed..be860035b 100644 --- a/pact/__version__.py +++ b/pact/__version__.py @@ -1,3 +1,3 @@ """Pact version info.""" -__version__ = '1.3.3' +__version__ = '1.3.4' From 94e597a7b6cb8a4b1ea34e620046a80d6d37292d Mon Sep 17 00:00:00 2001 From: Elliott Murray Date: Sun, 28 Mar 2021 15:20:04 +0100 Subject: [PATCH 17/41] fix(publish): fixing the fix. Pact Python api uses only publish_version and ensures it follows that --- pact/verifier.py | 1 - tests/test_verifier.py | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pact/verifier.py b/pact/verifier.py index 13222483c..fcd13a0d5 100644 --- a/pact/verifier.py +++ b/pact/verifier.py @@ -97,7 +97,6 @@ def extract_params(self, **kwargs): """Extract params.""" log_dir = kwargs.get('log_dir', None) log_level = kwargs.get('log_level', 'INFO') - provider_app_version = kwargs.get('provider_app_version', None) headers = kwargs.get('headers', []) timeout = kwargs.get('timeout', None) consumer_tags = kwargs.get('consumer_tags', []) diff --git a/tests/test_verifier.py b/tests/test_verifier.py index 3a28c3de6..3822e4621 100644 --- a/tests/test_verifier.py +++ b/tests/test_verifier.py @@ -176,7 +176,7 @@ def test_verifier_and_pubish_with_broker(self, mock_wrapper): mock_wrapper.return_value = (True, 'some value') - self.default_opts['publish_verification_results'] = True + self.default_opts['publish_version'] = '1.0.0' output, _ = self.verifier.verify_with_broker(**self.default_opts) self.assertTrue(output) @@ -191,7 +191,8 @@ def test_verifier_and_pubish_with_broker(self, mock_wrapper): verbose=False, enable_pending=False, include_wip_pacts_since=None, - publish_verification_results=True) + provider_app_version='1.0.0', + ) @patch("pact.verify_wrapper.VerifyWrapper.call_verify") def test_verifier_with_broker_passes_consumer_selctors(self, mock_wrapper): From d6c5f4a5f9868f398a6b55d551df160c33609e23 Mon Sep 17 00:00:00 2001 From: Elliott Murray Date: Sun, 28 Mar 2021 15:32:45 +0100 Subject: [PATCH 18/41] chore: Releasing version 1.3.5 --- CHANGELOG.md | 3 +++ pact/__version__.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f34da2c3a..8f97dd432 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +### 1.3.5 + * 5864e47 - Merge pull request #213 from pact-foundation/fix/revert_some_publish (Elliott Murray, Sun Mar 28 15:27:50 2021 +0100) + * 94e597a - fix(publish): fixing the fix. Pact Python api uses only publish_version and ensures it follows that (Elliott Murray, Sun Mar 28 15:20:04 2021 +0100) ### 1.3.4 * c778c71 - Merge pull request #212 from pact-foundation/fix/verify_in_provider (Elliott Murray, Sat Mar 27 18:59:25 2021 +0000) * ea0b64a - fix: verifier should now publish (Elliott Murray, Sat Mar 27 16:21:25 2021 +0000) diff --git a/pact/__version__.py b/pact/__version__.py index be860035b..cb89baf0c 100644 --- a/pact/__version__.py +++ b/pact/__version__.py @@ -1,3 +1,3 @@ """Pact version info.""" -__version__ = '1.3.4' +__version__ = '1.3.5' From 5946872f58e362f779d152d0d61241f2654d743b Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Tue, 30 Mar 2021 21:41:35 +0000 Subject: [PATCH 19/41] fix: docker/py36.Dockerfile to reduce vulnerabilities The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-ALPINE311-KRB5-1043935 - https://snyk.io/vuln/SNYK-ALPINE311-OPENSSL-1051931 - https://snyk.io/vuln/SNYK-ALPINE311-OPENSSL-1075737 - https://snyk.io/vuln/SNYK-ALPINE311-OPENSSL-1075738 - https://snyk.io/vuln/SNYK-ALPINE311-OPENSSL-1075738 --- docker/py36.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/py36.Dockerfile b/docker/py36.Dockerfile index 21840497f..eb65578ad 100644 --- a/docker/py36.Dockerfile +++ b/docker/py36.Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.6.10-alpine3.11 +FROM python:3.8.6-alpine3.11 WORKDIR /home From e5722214862be1688e9d866e23fced4c7078c7a1 Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Fri, 2 Apr 2021 01:10:57 +0000 Subject: [PATCH 20/41] fix: docker/py38.Dockerfile to reduce vulnerabilities The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-ALPINE311-KRB5-1043935 - https://snyk.io/vuln/SNYK-ALPINE311-OPENSSL-1075737 - https://snyk.io/vuln/SNYK-ALPINE311-OPENSSL-1075738 - https://snyk.io/vuln/SNYK-ALPINE311-OPENSSL-1075738 - https://snyk.io/vuln/SNYK-ALPINE311-SQLITE-587424 --- docker/py38.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/py38.Dockerfile b/docker/py38.Dockerfile index 1b8f1ff89..455e51976 100644 --- a/docker/py38.Dockerfile +++ b/docker/py38.Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.8.2-alpine3.11 +FROM python:3.8-alpine3.11 WORKDIR /home From 47373ff232e51514e0f0ef7b5e6a28b72e0f8d69 Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Fri, 2 Apr 2021 03:13:49 +0000 Subject: [PATCH 21/41] fix: docker/py37.Dockerfile to reduce vulnerabilities The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-ALPINE311-KRB5-1043935 - https://snyk.io/vuln/SNYK-ALPINE311-OPENSSL-1051931 - https://snyk.io/vuln/SNYK-ALPINE311-OPENSSL-1075737 - https://snyk.io/vuln/SNYK-ALPINE311-OPENSSL-1075738 - https://snyk.io/vuln/SNYK-ALPINE311-OPENSSL-1075738 --- docker/py37.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/py37.Dockerfile b/docker/py37.Dockerfile index 4267e7feb..fcb940d80 100644 --- a/docker/py37.Dockerfile +++ b/docker/py37.Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.7.7-alpine3.11 +FROM python:3.7.9-alpine3.11 WORKDIR /home From 1a162cf1d0688b6b2d5d9419351a39354f31b0a3 Mon Sep 17 00:00:00 2001 From: Elliott Murray Date: Sat, 3 Apr 2021 11:00:37 +0100 Subject: [PATCH 22/41] ci: revert docker36 back --- docker/py36.Dockerfile | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 docker/py36.Dockerfile diff --git a/docker/py36.Dockerfile b/docker/py36.Dockerfile deleted file mode 100644 index eb65578ad..000000000 --- a/docker/py36.Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM python:3.8.6-alpine3.11 - -WORKDIR /home - -COPY requirements_dev.txt . - -RUN apk update -RUN apk upgrade - -RUN apk add gcc py-pip python-dev libffi-dev openssl-dev gcc libc-dev bash make - -RUN python -m pip install psutil -RUN pip install -r requirements_dev.txt - -CMD tox -e py36 From 34160a8c06c55b22c0bc1d77e60b5e1383b48a66 Mon Sep 17 00:00:00 2001 From: Elliott Murray Date: Tue, 20 Apr 2021 20:58:20 +0100 Subject: [PATCH 23/41] fix: publish verification results was wrong (#222) * fix: publish verification results was wrong * fix: PR comments --- examples/e2e/tests/provider/test_provider.py | 2 +- examples/e2e/verify_pact.sh | 2 +- pact/cli/verify.py | 1 + pact/verify_wrapper.py | 10 ++++------ tests/cli/test_verify.py | 9 +++++++-- tests/test_verify_wrapper.py | 10 +++------- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/examples/e2e/tests/provider/test_provider.py b/examples/e2e/tests/provider/test_provider.py index 1cd15206d..3c86d5996 100644 --- a/examples/e2e/tests/provider/test_provider.py +++ b/examples/e2e/tests/provider/test_provider.py @@ -31,7 +31,7 @@ def default_opts(): 'broker_password': PACT_BROKER_PASSWORD, 'broker_url': PACT_BROKER_URL, 'publish_version': '3', - 'publish_verification_results': True + 'publish_verification_results': False } diff --git a/examples/e2e/verify_pact.sh b/examples/e2e/verify_pact.sh index 48a6d64c5..539e08127 100755 --- a/examples/e2e/verify_pact.sh +++ b/examples/e2e/verify_pact.sh @@ -30,4 +30,4 @@ else --pact-broker-password pactbroker \ --publish-verification-results \ --provider-states-setup-url=http://localhost:5001/_pact/provider_states -fi \ No newline at end of file +fi diff --git a/pact/cli/verify.py b/pact/cli/verify.py index e597e1e0c..3474ddbe6 100644 --- a/pact/cli/verify.py +++ b/pact/cli/verify.py @@ -175,6 +175,7 @@ def main(pacts, base_url, pact_url, pact_urls, states_url, states_setup_url, 'log_level': log_level, 'provider_app_version': provider_app_version, 'custom_provider_headers': list(headers), + 'publish_verification_results': publish_verification_results, 'timeout': timeout, 'verbose': verbose, 'consumer_tags': list(consumer_version_tag), diff --git a/pact/verify_wrapper.py b/pact/verify_wrapper.py index a812c1ffc..bcd07f220 100644 --- a/pact/verify_wrapper.py +++ b/pact/verify_wrapper.py @@ -154,9 +154,6 @@ def call_verify( '--log-level': kwargs.get('log_level') } - if(kwargs.get('publish_verification_results', False) is not None): - options['--publish-verification-results'] = '' - command = [VERIFIER_PATH] all_pact_urls = expand_directories(list(pacts)) @@ -165,9 +162,10 @@ def call_verify( if(provider_app_version): command.extend(["--provider-app-version", - provider_app_version, - "--publish-verification-results"]) - # self.publish_results(provider_app_version, command) + provider_app_version]) + + if(kwargs.get('publish_verification_results', False) is True): + command.extend(['--publish-verification-results']) if(kwargs.get('verbose', False) is True): command.extend(['--verbose']) diff --git a/tests/cli/test_verify.py b/tests/cli/test_verify.py index 5c16eeb42..b95c92a36 100644 --- a/tests/cli/test_verify.py +++ b/tests/cli/test_verify.py @@ -112,6 +112,7 @@ def test_successful_verification(self, mock_isfile, mock_wrapper): timeout=30, verbose=True, enable_pending=False, + publish_verification_results=False, include_wip_pacts_since=None) @patch("pact.verify_wrapper.VerifyWrapper.call_verify") @@ -141,6 +142,7 @@ def test_pact_url_param_supported(self, mock_isfile, mock_wrapper): timeout=30, verbose=False, enable_pending=False, + publish_verification_results=False, include_wip_pacts_since=None) self.assertEqual(result.exit_code, 0) @@ -163,6 +165,7 @@ def test_pact_urls_param_supported(self, mock_isfile, mock_wrapper): timeout=30, verbose=False, enable_pending=False, + publish_verification_results=False, include_wip_pacts_since=None) self.assertEqual(result.exit_code, 0) @@ -189,6 +192,7 @@ def test_failed_verification(self, mock_isfile, mock_wrapper): timeout=30, verbose=False, enable_pending=False, + publish_verification_results=False, include_wip_pacts_since=None) @patch.dict(os.environ, {'PACT_BROKER_PASSWORD': 'pwd', @@ -212,6 +216,7 @@ def test_broker_creds_from_env_var(self, mock_isfile, mock_wrapper): timeout=30, verbose=False, enable_pending=False, + publish_verification_results=False, include_wip_pacts_since=None) @patch("pact.verify_wrapper.VerifyWrapper.call_verify") @@ -233,7 +238,6 @@ def test_all_url_options(self, mock_isfile, mock_wrapper): '--pact-broker-token=token', '--pact-broker-url=http://localhost/docker', '--provider=provider', - '--publish-verification-results', '--provider-app-version=1.2.3', '--log-dir=tmp/logs/pact.test.log', '--log-level=INFO', @@ -263,6 +267,7 @@ def test_all_url_options(self, mock_isfile, mock_wrapper): timeout=60, verbose=True, enable_pending=True, + publish_verification_results=False, include_wip_pacts_since=None) @patch("pact.verify_wrapper.VerifyWrapper.call_verify") @@ -305,7 +310,7 @@ def test_all_broker_options(self, mock_wrapper): '{"tag": "staging", "latest": true}'], provider_tags=['dev', 'qa'], provider_app_version='1.2.3', - # custom_provider_header=['Authorization: Basic cGFj', 'CustomHeader: somevalue'], + publish_verification_results=True, provider_states_setup_url='http://localhost/provider-states/set', timeout=60, verbose=True, diff --git a/tests/test_verify_wrapper.py b/tests/test_verify_wrapper.py index e175bd718..7d606f9ab 100644 --- a/tests/test_verify_wrapper.py +++ b/tests/test_verify_wrapper.py @@ -34,9 +34,6 @@ def setUp(self): self.mock_Popen.return_value.communicate.return_value = self.locale - # self.mock_isfile = patch.object( - # VerifyWrapper, 'isfile', autospec=True).start() - self.mock_rerun_command = patch.object( verify_wrapper, 'rerun_command', autospec=True).start() @@ -114,7 +111,6 @@ def test_all_url_options(self, mock_isfile): provider_base_url='http://localhost', provider_states_setup_url='http://localhost/provider-states/set', provider='provider', - publish_verification_results=True, provider_app_version='1.2.3', custom_provider_headers=['Authorization: Basic cGFj', 'CustomHeader: somevalue'], log_dir='tmp/logs/pact.test.log', @@ -135,7 +131,6 @@ def test_all_url_options(self, mock_isfile): '--provider-base-url=http://localhost', '--provider-states-setup-url=http://localhost/provider-states/set', '--provider=provider', - '--publish-verification-results', '--provider-app-version', '1.2.3', '--log-dir=tmp/logs/pact.test.log', '--log-level=INFO', @@ -199,8 +194,9 @@ def test_publishing_with_version(self, mock_sanitize_logs, mock_path_exists): './pacts/consumer-provider2.json', provider='test_provider', provider_base_url='http://localhost', - provider_app_version='1.2.3' - ) + provider_app_version='1.2.3', + publish_verification_results=True) + self.default_call.extend(['--provider-app-version', '1.2.3', '--publish-verification-results']) self.assertProcess(*self.default_call) From c4fe4220d1a4e26c939ed0dc4cd977e82183cdb3 Mon Sep 17 00:00:00 2001 From: Elliott Murray Date: Tue, 20 Apr 2021 20:58:50 +0100 Subject: [PATCH 24/41] chore: Releasing version 1.3.6 --- CHANGELOG.md | 83 +++++++++++++++++++++++++++++++++++++++++++++ pact/__version__.py | 2 +- 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f97dd432..aa921a0eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,86 @@ +### 1.3.6 + * 34160a8 - fix: publish verification results was wrong (#222) (Elliott Murray, Tue Apr 20 20:58:20 2021 +0100) + * 2c0252c - Merge pull request #219 from pact-foundation/ci/revert_snyk_36 (Elliott Murray, Sat Apr 3 11:13:49 2021 +0100) + * 1a162cf - ci: revert docker36 back (Elliott Murray, Sat Apr 3 11:00:37 2021 +0100) + * 4282de4 - Merge pull request #217 from pact-foundation/snyk-fix-8f994ea63cfa41070b04b182dbd11c74 (Elliott Murray, Sat Apr 3 10:54:58 2021 +0100) + * 4eb3fbb - Merge pull request #216 from pact-foundation/snyk-fix-fc54d9c7fe536fffe78fbd34fc5fd7ea (Elliott Murray, Sat Apr 3 10:54:10 2021 +0100) + * 47373ff - fix: docker/py37.Dockerfile to reduce vulnerabilities (snyk-bot, Fri Apr 2 03:13:49 2021 +0000) + * e572221 - fix: docker/py38.Dockerfile to reduce vulnerabilities (snyk-bot, Fri Apr 2 01:10:57 2021 +0000) + * f293dbb - Merge pull request #215 from pact-foundation/snyk-fix-ab489d8931bdf95d6ef0d217aa1b2eb6 (Elliott Murray, Wed Mar 31 09:27:02 2021 +0100) + * 5946872 - fix: docker/py36.Dockerfile to reduce vulnerabilities (snyk-bot, Tue Mar 30 21:41:35 2021 +0000) + * d6c5f4a - chore: Releasing version 1.3.5 (Elliott Murray, Sun Mar 28 15:32:45 2021 +0100) + * 5864e47 - Merge pull request #213 from pact-foundation/fix/revert_some_publish (Elliott Murray, Sun Mar 28 15:27:50 2021 +0100) + * 94e597a - fix(publish): fixing the fix. Pact Python api uses only publish_version and ensures it follows that (Elliott Murray, Sun Mar 28 15:20:04 2021 +0100) + * e00f320 - chore: Releasing version 1.3.4 (Elliott Murray, Sat Mar 27 21:26:29 2021 +0000) + * c778c71 - Merge pull request #212 from pact-foundation/fix/verify_in_provider (Elliott Murray, Sat Mar 27 18:59:25 2021 +0000) + * ea0b64a - fix: verifier should now publish (Elliott Murray, Sat Mar 27 16:21:25 2021 +0000) + * 2c8779b - chore: Releasing version 1.3.3 (Elliott Murray, Thu Mar 25 21:23:29 2021 +0000) + * 5e282ff - Merge pull request #211 from anneschuth/fix/pass-pact-dir (Elliott Murray, Thu Mar 25 21:21:56 2021 +0000) + * 987c4fc - fix: pass pact_dir to publish() (Anne Schuth, Thu Mar 25 10:06:54 2021 +0100) + * 23a5129 - chore: Releasing version 1.3.2 (Elliott Murray, Sun Mar 21 14:32:50 2021 +0000) + * 57c8ae8 - Merge pull request #209 from pact-foundation/bug/fix_test_dir (Elliott Murray, Sun Mar 21 14:29:40 2021 +0000) + * af3dadf - fix: remove pacts from examples (Elliott Murray, Sun Mar 21 14:21:10 2021 +0000) + * 579f3f8 - fix: ensure path is passed to broker and allow running from root rather than test file (Elliott Murray, Sun Mar 21 13:18:01 2021 +0000) + * 7e0feab - Merge pull request #208 from pact-foundation/dependabot/pip/examples/e2e/jinja2-2.11.3 (Elliott Murray, Sat Mar 20 12:46:32 2021 +0000) + * f82c008 - chore(deps): bump jinja2 from 2.11.2 to 2.11.3 in /examples/e2e (dependabot[bot], Sat Mar 20 04:53:58 2021 +0000) + * ea6f635 - Merge pull request #206 from pact-foundation/chore/use-testcontainers (Elliott Murray, Sun Mar 14 11:05:01 2021 +0000) + * 565bc80 - chore: added some docs about how to use the e2e example (Elliott Murray, Sun Mar 14 11:02:35 2021 +0000) + * 1b4be80 - chore: spiking testcontainers (Elliott Murray, Sat Mar 13 11:15:52 2021 +0000) + * 01e4ec4 - chore: wip on using test containers on examples (Elliott Murray, Tue Mar 2 21:30:48 2021 +0000) + * 882f4a2 - Merge pull request #204 from pact-foundation/chore/use_pytest (Elliott Murray, Sat Feb 27 10:58:19 2021 +0000) + * 261f24b - chore: more clean up (Elliott Murray, Sat Feb 27 10:10:23 2021 +0000) + * 5a0934c - chore: update ci stuff (Elliott Murray, Sat Feb 27 09:57:31 2021 +0000) + * 66e79e2 - chore: move from nose to pytests as we are now 3.6+ (Elliott Murray, Sat Feb 27 09:34:37 2021 +0000) + * 6aee3e2 - chore: Releasing version 1.3.1 (Elliott Murray, Sat Feb 27 09:16:35 2021 +0000) + * 4440022 - Merge pull request #203 from pact-foundation/fix/version_confusion (Elliott Murray, Sat Feb 27 09:15:08 2021 +0000) + * 9cac2d7 - fix: introduced and renamed specification version (Elliott Murray, Tue Feb 23 21:22:36 2021 +0000) + * 64d7bdc - chore: Releasing version 1.3.0 (Elliott Murray, Tue Jan 26 18:45:58 2021 +0000) + * eaa90e1 - Merge pull request #194 from williaminfante/feat/pact-message-2 (Elliott Murray, Mon Jan 25 08:48:00 2021 +0000) + * 5ed73db - test: consider publish to broker with no pact_dir argument (William Infante, Mon Jan 25 17:19:08 2021 +1100) + * e097153 - docs: update readme (William Infante, Mon Jan 25 17:18:35 2021 +1100) + * fc0d91c - feat: address PR comments (William Infante, Mon Jan 25 10:30:33 2021 +1100) + * 5448d8c - test: remove mock and check generated json file (William Infante, Wed Jan 20 21:07:39 2021 +1100) + * abd3574 - fix: few more tests to improve coverage (Tuan Pham, Wed Jan 20 09:23:13 2021 +1100) + * 0ef971f - fix: improve test coverage (Tuan Pham, Tue Jan 19 15:11:11 2021 +1100) + * e543f04 - chore: add missing import (William Infante, Tue Jan 19 13:58:17 2021 +1100) + * bc7ff78 - chore: pydocstyle (Tuan Pham, Tue Jan 19 10:40:12 2021 +1100) + * d4235f9 - chore: flake8, clean up deadcode (Tuan Pham, Tue Jan 19 00:53:03 2021 +1100) + * 19827d0 - chore: remove test param for provider (Tuan Pham, Mon Jan 18 16:06:42 2021 +1100) + * 912b477 - chore: flake8 revert (Tuan Pham, Mon Jan 18 16:04:00 2021 +1100) + * 4a730ae - fix: revert changes to quotes (Tuan Pham, Mon Jan 18 15:57:14 2021 +1100) + * cfe35cc - feat: update message hander to be independent of pact (William Infante, Mon Jan 18 13:12:17 2021 +1100) + * 12b4a50 - fix: flake8 warning (Tuan Pham, Mon Jan 18 12:50:50 2021 +1100) + * 7afe693 - test: update message handler condition based on content (William Infante, Mon Jan 18 12:37:50 2021 +1100) + * 79106bb - feat: move publish function to broker class (Tuan Pham, Mon Jan 18 11:30:35 2021 +1100) + * a04b954 - docs: add readme for message consumer (William Infante, Mon Jan 18 09:48:01 2021 +1100) + * 8672e2f - feat: update handler to handle error exceptions (William Infante, Fri Jan 15 16:24:38 2021 +1100) + * 47b7434 - feat: change dummy handler to a message handler (William Infante, Fri Jan 15 14:06:55 2021 +1100) + * a18ce3e - test: create external dummy handler in test (William Infante, Fri Jan 15 12:31:49 2021 +1100) + * 7358049 - chore: remove log_dir, refactor test (Tuan Pham, Fri Jan 15 09:11:55 2021 +1100) + * 6718b4c - feat: update message pact tests (William Infante, Thu Jan 14 16:12:44 2021 +1100) + * bf9864f - feat: add more test (William Infante, Thu Jan 14 16:09:52 2021 +1100) + * 84681b4 - fix: try different way to mock (Tuan Pham, Thu Jan 14 15:10:36 2021 +1100) + * 86cfe8e - chore: add generate_pact_test (Tuan Pham, Thu Jan 14 14:26:42 2021 +1100) + * a1c19b6 - fix: add missing conftest (Tuan Pham, Thu Jan 14 11:02:08 2021 +1100) + * a98850a - chore: add missing files in src (Tuan Pham, Thu Jan 14 10:53:35 2021 +1100) + * 63452aa - chore: fix bad merge (Tuan Pham, Thu Jan 14 10:47:43 2021 +1100) + * 85fc77f - feat: add pact-message integration test (Tuan Pham, Thu Jan 14 10:32:02 2021 +1100) + * 11793f5 - feat: add pact-message integration (Tuan Pham, Thu Jan 14 10:30:35 2021 +1100) + * 8546a26 - fix: linting (Tuan Pham, Thu Jan 14 10:38:52 2021 +1100) + * 65b69d7 - fix: remove publish fn for now (Tuan Pham, Thu Jan 14 10:38:10 2021 +1100) + * e31dd45 - feat: add constants test (William Infante, Wed Jan 13 17:28:45 2021 +1100) + * 955dbe1 - feat: update MessageConsumer and tests (William Infante, Wed Jan 13 16:38:30 2021 +1100) + * af5c9fb - feat: create basic tests for single pact message (William Infante, Wed Jan 13 15:52:07 2021 +1100) + * fea27c8 - feat: single message flow (William Infante, Wed Jan 13 15:03:41 2021 +1100) + * 9047855 - feat: add MessageConsumer (William Infante, Wed Jan 13 12:45:19 2021 +1100) + * 40edd39 - feat: initial interface (William Infante, Tue Jan 12 16:59:46 2021 +1100) + * 2946242 - Merge pull request #198 from pact-foundation/chore/deprecate_python35 (Elliott Murray, Sat Jan 23 15:26:01 2021 +0000) + * 0111698 - fix: add e2e example test into ci back in (Elliott Murray, Sat Jan 23 15:25:07 2021 +0000) + * 0cdc7e9 - chore: remove python35 and 34 and add 39 (Elliott Murray, Sat Jan 23 15:20:47 2021 +0000) + * 3885c60 - Merge pull request #197 from pact-foundation/fix/pull_request_trigger_workflow (Elliott Murray, Sat Jan 23 10:51:06 2021 +0000) + * 925b0ac - ci: pr not triggering workflow (Elliott Murray, Sat Jan 23 10:44:36 2021 +0000) + * 8f9a925 - Merge pull request #195 from cdambo/pass-pact-dir-to-cli (Elliott Murray, Sat Jan 23 10:39:53 2021 +0000) + * 545fc37 - fix: send to cli pact_files with the pact_dir in their path (Chanan Damboritz, Tue Jan 19 18:51:17 2021 +0200) ### 1.3.5 * 5864e47 - Merge pull request #213 from pact-foundation/fix/revert_some_publish (Elliott Murray, Sun Mar 28 15:27:50 2021 +0100) * 94e597a - fix(publish): fixing the fix. Pact Python api uses only publish_version and ensures it follows that (Elliott Murray, Sun Mar 28 15:20:04 2021 +0100) diff --git a/pact/__version__.py b/pact/__version__.py index cb89baf0c..ef7a2ce2b 100644 --- a/pact/__version__.py +++ b/pact/__version__.py @@ -1,3 +1,3 @@ """Pact version info.""" -__version__ = '1.3.5' +__version__ = '1.3.6' From 20f828fac3815d53e8b4256f3ccbc1de49840e06 Mon Sep 17 00:00:00 2001 From: Elliott Murray Date: Sat, 24 Apr 2021 13:47:22 +0100 Subject: [PATCH 25/41] fix(broker): token added to verify steps (#226) --- pact/verify_wrapper.py | 1 + tests/test_verify_wrapper.py | 2 ++ 2 files changed, 3 insertions(+) diff --git a/pact/verify_wrapper.py b/pact/verify_wrapper.py index bcd07f220..854e5b1ac 100644 --- a/pact/verify_wrapper.py +++ b/pact/verify_wrapper.py @@ -148,6 +148,7 @@ def call_verify( '--provider': provider, '--broker-username': kwargs.get('broker_username', None), '--broker-password': kwargs.get('broker_password', None), + '--broker-token': kwargs.get('broker_token', None), '--pact-broker-base-url': kwargs.get('broker_url', None), '--provider-states-setup-url': kwargs.get('provider_states_setup_url'), '--log-dir': kwargs.get('log_dir'), diff --git a/tests/test_verify_wrapper.py b/tests/test_verify_wrapper.py index 7d606f9ab..5dc247cf7 100644 --- a/tests/test_verify_wrapper.py +++ b/tests/test_verify_wrapper.py @@ -49,6 +49,7 @@ def setUp(self): '--pact-broker-base-url=http://broker', '--broker-username=username', '--broker-password=pwd', + '--broker-token=token', '--consumer-version-tag=prod', '--consumer-version-tag=dev', '--provider-version-tag=dev', @@ -147,6 +148,7 @@ def test_uses_broker_if_no_pacts_and_provider_required(self): provider_base_url='http://localhost', broker_username='username', broker_password='pwd', + broker_token='token', broker_url='http://broker', consumer_tags=['prod', 'dev'], provider_tags=['dev', 'qa']) From d348a9c9b1126fa6beb417293db0964f2284686c Mon Sep 17 00:00:00 2001 From: Elliott Murray Date: Sat, 24 Apr 2021 13:49:35 +0100 Subject: [PATCH 26/41] chore: Releasing version 1.3.7 --- CHANGELOG.md | 12 ++++++++++++ pact/__version__.py | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa921a0eb..51d7b4b6e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +### 1.3.7 + * 20f828f - fix(broker): token added to verify steps (#226) (Elliott Murray, Sat Apr 24 13:47:22 2021 +0100) + * c4fe422 - chore: Releasing version 1.3.6 (Elliott Murray, Tue Apr 20 20:58:50 2021 +0100) + * 34160a8 - fix: publish verification results was wrong (#222) (Elliott Murray, Tue Apr 20 20:58:20 2021 +0100) + * 2c0252c - Merge pull request #219 from pact-foundation/ci/revert_snyk_36 (Elliott Murray, Sat Apr 3 11:13:49 2021 +0100) + * 1a162cf - ci: revert docker36 back (Elliott Murray, Sat Apr 3 11:00:37 2021 +0100) + * 4282de4 - Merge pull request #217 from pact-foundation/snyk-fix-8f994ea63cfa41070b04b182dbd11c74 (Elliott Murray, Sat Apr 3 10:54:58 2021 +0100) + * 4eb3fbb - Merge pull request #216 from pact-foundation/snyk-fix-fc54d9c7fe536fffe78fbd34fc5fd7ea (Elliott Murray, Sat Apr 3 10:54:10 2021 +0100) + * 47373ff - fix: docker/py37.Dockerfile to reduce vulnerabilities (snyk-bot, Fri Apr 2 03:13:49 2021 +0000) + * e572221 - fix: docker/py38.Dockerfile to reduce vulnerabilities (snyk-bot, Fri Apr 2 01:10:57 2021 +0000) + * f293dbb - Merge pull request #215 from pact-foundation/snyk-fix-ab489d8931bdf95d6ef0d217aa1b2eb6 (Elliott Murray, Wed Mar 31 09:27:02 2021 +0100) + * 5946872 - fix: docker/py36.Dockerfile to reduce vulnerabilities (snyk-bot, Tue Mar 30 21:41:35 2021 +0000) ### 1.3.6 * 34160a8 - fix: publish verification results was wrong (#222) (Elliott Murray, Tue Apr 20 20:58:20 2021 +0100) * 2c0252c - Merge pull request #219 from pact-foundation/ci/revert_snyk_36 (Elliott Murray, Sat Apr 3 11:13:49 2021 +0100) diff --git a/pact/__version__.py b/pact/__version__.py index ef7a2ce2b..ac3f855fd 100644 --- a/pact/__version__.py +++ b/pact/__version__.py @@ -1,3 +1,3 @@ """Pact version info.""" -__version__ = '1.3.6' +__version__ = '1.3.7' From 63901445ebd5e95105d7af78af414b104a62a84a Mon Sep 17 00:00:00 2001 From: Syed Muhammad Dawoud Sheraz Ali <40599381+DawoudSheraz@users.noreply.github.com> Date: Thu, 29 Apr 2021 01:49:53 +0500 Subject: [PATCH 27/41] fix: fix datetime serialization issues in Format (#230) --- pact/matchers.py | 6 +++--- tests/test_matchers.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pact/matchers.py b/pact/matchers.py index 80ee06516..55424fdd2 100644 --- a/pact/matchers.py +++ b/pact/matchers.py @@ -331,7 +331,7 @@ def timestamp(self): return Term( self.Regexes.timestamp.value, datetime.datetime( 2000, 2, 1, 12, 30, 0, 0 - ) + ).isoformat() ) def date(self): @@ -344,7 +344,7 @@ def date(self): return Term( self.Regexes.date.value, datetime.datetime( 2000, 2, 1, 12, 30, 0, 0 - ).date() + ).date().isoformat() ) def time(self): @@ -357,7 +357,7 @@ def time(self): return Term( self.Regexes.time_regex.value, datetime.datetime( 2000, 2, 1, 12, 30, 0, 0 - ).time() + ).time().isoformat() ) class Regexes(Enum): diff --git a/tests/test_matchers.py b/tests/test_matchers.py index a64be292a..70fee2e18 100644 --- a/tests/test_matchers.py +++ b/tests/test_matchers.py @@ -362,7 +362,7 @@ def test_timestamp(self): "s": self.formatter.Regexes.timestamp.value, "o": 0, }, - "generate": datetime.datetime(2000, 2, 1, 12, 30, 0, 0), + "generate": datetime.datetime(2000, 2, 1, 12, 30, 0, 0).isoformat(), }, }, ) @@ -381,7 +381,7 @@ def test_date(self): "o": 0, }, "generate": datetime.datetime( - 2000, 2, 1, 12, 30, 0, 0).date(), + 2000, 2, 1, 12, 30, 0, 0).date().isoformat(), }, }, ) @@ -400,7 +400,7 @@ def test_time(self): "o": 0, }, "generate": datetime.datetime( - 2000, 2, 1, 12, 30, 0, 0).time(), + 2000, 2, 1, 12, 30, 0, 0).time().isoformat(), }, }, ) From 3c909f1392bb91ac3761e23b20461727d905d2cc Mon Sep 17 00:00:00 2001 From: Elliott Murray Date: Sat, 1 May 2021 11:51:28 +0100 Subject: [PATCH 28/41] docs: example uses date matcher (#231) --- examples/e2e/conftest.py | 2 ++ examples/e2e/src/consumer.py | 8 ++++++-- examples/e2e/tests/consumer/test_user_consumer.py | 10 +++++----- examples/e2e/tests/provider/test_provider.py | 1 + 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/examples/e2e/conftest.py b/examples/e2e/conftest.py index 597921114..1ee4c7dc2 100644 --- a/examples/e2e/conftest.py +++ b/examples/e2e/conftest.py @@ -3,6 +3,7 @@ import pytest + def pytest_addoption(parser): parser.addoption( "--publish-pact", type=str, action="store", @@ -19,6 +20,7 @@ def pytest_addoption(parser): help="Whether to run broker in this test or not." ) + # This fixture is to simulate a managed Pact Broker or Pactflow account # Do not do this yourself but setup one of the above # https://github.com/pact-foundation/pact_broker diff --git a/examples/e2e/src/consumer.py b/examples/e2e/src/consumer.py index 8bd15fccf..1381267f8 100644 --- a/examples/e2e/src/consumer.py +++ b/examples/e2e/src/consumer.py @@ -1,4 +1,5 @@ import requests +from datetime import datetime class UserConsumer(object): @@ -13,9 +14,12 @@ def get_user(self, user_name): return None name = response.json()['name'] - return User(name) + created_on = datetime.strptime(response.json()['created_on'], '%Y-%m-%dT%H:%M:%S') + + return User(name, created_on) class User(object): - def __init__(self, name): + def __init__(self, name, created_on): self.name = name + self.created_on = created_on diff --git a/examples/e2e/tests/consumer/test_user_consumer.py b/examples/e2e/tests/consumer/test_user_consumer.py index 5427dac60..942f745b9 100644 --- a/examples/e2e/tests/consumer/test_user_consumer.py +++ b/examples/e2e/tests/consumer/test_user_consumer.py @@ -2,9 +2,10 @@ import logging import os +from datetime import datetime import pytest -from pact import Consumer, Like, Provider, Term, Format +from pact import Consumer, Like, Provider, Format from src.consumer import UserConsumer @@ -47,14 +48,12 @@ def pact(request): print('stop service') pact.stop_service() + def test_get_user_non_admin(broker, pact, consumer): expected = { 'name': 'UserA', 'id': Format().uuid, - 'created_on': Term( - r'\d+-\d+-\d+T\d+:\d+:\d+', - '2016-12-15T20:16:01' - ), + 'created_on': Format().timestamp, 'ip_address': Format().ip_address, 'admin': False } @@ -68,6 +67,7 @@ def test_get_user_non_admin(broker, pact, consumer): with pact: user = consumer.get_user('UserA') assert user.name == 'UserA' + assert user.created_on == datetime.strptime('2000-2-1T12:30:00', '%Y-%m-%dT%H:%M:%S') def test_get_non_existing_user(broker, pact, consumer): diff --git a/examples/e2e/tests/provider/test_provider.py b/examples/e2e/tests/provider/test_provider.py index 3c86d5996..59e9a8666 100644 --- a/examples/e2e/tests/provider/test_provider.py +++ b/examples/e2e/tests/provider/test_provider.py @@ -24,6 +24,7 @@ PACT_URL = "http://{}:{}".format(PACT_MOCK_HOST, PACT_MOCK_PORT) PACT_DIR = os.path.dirname(os.path.realpath(__file__)) + @pytest.fixture def default_opts(): return { From 99fd9650609a0c4654f142f5ad51a680a11934dc Mon Sep 17 00:00:00 2001 From: Elliott Murray Date: Sat, 1 May 2021 12:26:47 +0100 Subject: [PATCH 29/41] chore: Releasing version 1.3.8 --- CHANGELOG.md | 3 +++ pact/__version__.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 51d7b4b6e..0f1d3d907 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +### 1.3.8 + * 3c909f1 - docs: example uses date matcher (#231) (Elliott Murray, Sat May 1 11:51:28 2021 +0100) + * 6390144 - fix: fix datetime serialization issues in Format (#230) (Syed Muhammad Dawoud Sheraz Ali, Thu Apr 29 01:49:53 2021 +0500) ### 1.3.7 * 20f828f - fix(broker): token added to verify steps (#226) (Elliott Murray, Sat Apr 24 13:47:22 2021 +0100) * c4fe422 - chore: Releasing version 1.3.6 (Elliott Murray, Tue Apr 20 20:58:50 2021 +0100) diff --git a/pact/__version__.py b/pact/__version__.py index ac3f855fd..17639190e 100644 --- a/pact/__version__.py +++ b/pact/__version__.py @@ -1,3 +1,3 @@ """Pact version info.""" -__version__ = '1.3.7' +__version__ = '1.3.8' From 657e770c917c7b963abb59205009c40c918735c1 Mon Sep 17 00:00:00 2001 From: Vasile Tofan Date: Thu, 13 May 2021 22:20:47 +0300 Subject: [PATCH 30/41] fix: change default from empty string to empty list (#235) Co-authored-by: Vasile Tofan --- pact/cli/verify.py | 8 ++++---- requirements_dev.txt | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pact/cli/verify.py b/pact/cli/verify.py index 3474ddbe6..b3fa87091 100644 --- a/pact/cli/verify.py +++ b/pact/cli/verify.py @@ -21,7 +21,7 @@ multiple=True) # Remove in major version 1.0.0 @click.option( 'pact_urls', '--pact-urls', - default='', + default=[], help='DEPRECATED: specify pacts as arguments instead.\n' 'The URI(s) of the pact to verify.' ' Can be an HTTP URI(s) or local file path(s).' @@ -47,19 +47,19 @@ ' via the environment variable PACT_BROKER_BASE_URL.') @click.option( 'consumer_version_tag', '--consumer-version-tag', - default='', + default=[], multiple=True, help='Retrieve the latest pacts with this consumer version tag. ' 'Used in conjunction with --provider. May be specified multiple times.') @click.option( 'consumer_version_selector', '--consumer-version-selector', - default='', + default=[], multiple=True, help='Retrieve the latest pacts with this consumer version selector. ' 'Used in conjunction with --provider. May be specified multiple times.') @click.option( 'provider_version_tag', '--provider-version-tag', - default='', + default=[], multiple=True, help='Tag to apply to the provider application version. ' 'May be specified multiple times.') diff --git a/requirements_dev.txt b/requirements_dev.txt index 6f700464a..0a2277631 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -1,4 +1,4 @@ -Click>=2.0.0,<=6.7 +Click>=2.0.0 coverage==5.4 Flask==1.0 configparser==3.5.0 From 98d9a4bf2069c41aa3b6d294f98706f9b6cf58bd Mon Sep 17 00:00:00 2001 From: Elliott Murray Date: Thu, 13 May 2021 20:21:10 +0100 Subject: [PATCH 31/41] chore(ruby): update ruby standalen (#233) --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 5451bf138..de556bfc8 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ IS_64 = sys.maxsize > 2 ** 32 -PACT_STANDALONE_VERSION = '1.88.3' +PACT_STANDALONE_VERSION = '1.88.51' here = os.path.abspath(os.path.dirname(__file__)) From 35e8b60c26a16272338f0d1760d2c47dd028edea Mon Sep 17 00:00:00 2001 From: Elliott Murray Date: Thu, 13 May 2021 21:51:15 +0100 Subject: [PATCH 32/41] chore: Releasing version 1.3.9 --- CHANGELOG.md | 6 ++++++ pact/__version__.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f1d3d907..5ca57ec4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +### 1.3.9 + * 98d9a4b - chore(ruby): update ruby standalen (#233) (Elliott Murray, Thu May 13 20:21:10 2021 +0100) + * 657e770 - fix: change default from empty string to empty list (#235) (Vasile Tofan, Thu May 13 22:20:47 2021 +0300) + * 99fd965 - chore: Releasing version 1.3.8 (Elliott Murray, Sat May 1 12:26:47 2021 +0100) + * 3c909f1 - docs: example uses date matcher (#231) (Elliott Murray, Sat May 1 11:51:28 2021 +0100) + * 6390144 - fix: fix datetime serialization issues in Format (#230) (Syed Muhammad Dawoud Sheraz Ali, Thu Apr 29 01:49:53 2021 +0500) ### 1.3.8 * 3c909f1 - docs: example uses date matcher (#231) (Elliott Murray, Sat May 1 11:51:28 2021 +0100) * 6390144 - fix: fix datetime serialization issues in Format (#230) (Syed Muhammad Dawoud Sheraz Ali, Thu Apr 29 01:49:53 2021 +0500) diff --git a/pact/__version__.py b/pact/__version__.py index 17639190e..b24a26504 100644 --- a/pact/__version__.py +++ b/pact/__version__.py @@ -1,3 +1,3 @@ """Pact version info.""" -__version__ = '1.3.8' +__version__ = '1.3.9' From 2c81029fec44595e311960361c7b43d6919b6c5e Mon Sep 17 00:00:00 2001 From: Elliott Murray Date: Fri, 11 Jun 2021 09:12:38 +0100 Subject: [PATCH 33/41] chore(snyk): update fastapi (#239) --- examples/fastapi_e2e/Pipfile | 15 -- examples/fastapi_e2e/Pipfile.lock | 210 -------------------------- examples/fastapi_e2e/requirements.txt | 2 +- 3 files changed, 1 insertion(+), 226 deletions(-) delete mode 100644 examples/fastapi_e2e/Pipfile delete mode 100644 examples/fastapi_e2e/Pipfile.lock diff --git a/examples/fastapi_e2e/Pipfile b/examples/fastapi_e2e/Pipfile deleted file mode 100644 index 1683a3826..000000000 --- a/examples/fastapi_e2e/Pipfile +++ /dev/null @@ -1,15 +0,0 @@ -[[source]] -name = "pypi" -url = "https://pypi.org/simple" -verify_ssl = true - -[dev-packages] - -[packages] -pytest = "==5.4.1" -requests = "==2.23.0" -Flask = "==1.1.1" -pact-python = "*" - -[requires] -python_version = "3.8" diff --git a/examples/fastapi_e2e/Pipfile.lock b/examples/fastapi_e2e/Pipfile.lock deleted file mode 100644 index d3c8e0c12..000000000 --- a/examples/fastapi_e2e/Pipfile.lock +++ /dev/null @@ -1,210 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "851a6e86276202576d0791677eb6d317d21d0bfac565835415870de3864c99b5" - }, - "pipfile-spec": 6, - "requires": { - "python_version": "3.8" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.org/simple", - "verify_ssl": true - } - ] - }, - "default": { - "attrs": { - "hashes": [ - "sha256:26b54ddbbb9ee1d34d5d3668dd37d6cf74990ab23c828c2888dccdceee395594", - "sha256:fce7fc47dfc976152e82d53ff92fa0407700c21acd20886a13777a0d20e655dc" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==20.2.0" - }, - "certifi": { - "hashes": [ - "sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3", - "sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41" - ], - "version": "==2020.6.20" - }, - "chardet": { - "hashes": [ - "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", - "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" - ], - "version": "==3.0.4" - }, - "click": { - "hashes": [ - "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", - "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==7.1.2" - }, - "flask": { - "hashes": [ - "sha256:13f9f196f330c7c2c5d7a5cf91af894110ca0215ac051b5844701f2bfd934d52", - "sha256:45eb5a6fd193d6cf7e0cf5d8a5b31f83d5faae0293695626f539a823e93b13f6" - ], - "index": "pypi", - "version": "==1.1.1" - }, - "idna": { - "hashes": [ - "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6", - "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.10" - }, - "itsdangerous": { - "hashes": [ - "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19", - "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.1.0" - }, - "jinja2": { - "hashes": [ - "sha256:89aab215427ef59c34ad58735269eb58b1a5808103067f7bb9d5836c651b3bb0", - "sha256:f0a4641d3cf955324a89c04f3d94663aa4d638abe8f733ecd3582848e1c37035" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==2.11.2" - }, - "markupsafe": { - "hashes": [ - "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473", - "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", - "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", - "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", - "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42", - "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", - "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", - "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", - "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", - "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", - "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", - "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b", - "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", - "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15", - "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", - "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", - "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", - "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", - "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", - "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", - "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", - "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", - "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", - "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", - "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", - "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", - "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", - "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", - "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", - "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", - "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2", - "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7", - "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.1.1" - }, - "more-itertools": { - "hashes": [ - "sha256:8e1a2a43b2f2727425f2b5839587ae37093f19153dc26c0927d1048ff6557330", - "sha256:b3a9005928e5bed54076e6e549c792b306fddfe72b2d1d22dd63d42d5d3899cf" - ], - "markers": "python_version >= '3.5'", - "version": "==8.6.0" - }, - "packaging": { - "hashes": [ - "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8", - "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==20.4" - }, - "pluggy": { - "hashes": [ - "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0", - "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.13.1" - }, - "py": { - "hashes": [ - "sha256:366389d1db726cd2fcfc79732e75410e5fe4d31db13692115529d34069a043c2", - "sha256:9ca6883ce56b4e8da7e79ac18787889fa5206c79dcc67fb065376cd2fe03f342" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.9.0" - }, - "pyparsing": { - "hashes": [ - "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1", - "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b" - ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.4.7" - }, - "pytest": { - "hashes": [ - "sha256:0e5b30f5cb04e887b91b1ee519fa3d89049595f428c1db76e73bd7f17b09b172", - "sha256:84dde37075b8805f3d1f392cc47e38a0e59518fb46a431cfdaf7cf1ce805f970" - ], - "index": "pypi", - "version": "==5.4.1" - }, - "requests": { - "hashes": [ - "sha256:43999036bfa82904b6af1d99e4882b560e5e2c68e5c4b0aa03b655f3d7d73fee", - "sha256:5d2d0ffbb515f39417009a46c14256291061ac01ba8f875b90cad137de83beb4", - "sha256:b3f43d496c6daba4493e7c431722aeb7dbc6288f52a6e04e7b6023b0247817e6" - ], - "index": "pypi", - "version": "==2.23.0" - }, - "six": { - "hashes": [ - "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", - "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.15.0" - }, - "urllib3": { - "hashes": [ - "sha256:8d7eaa5a82a1cac232164990f04874c594c9453ec55eef02eab885aa02fc17a2", - "sha256:f5321fbe4bf3fefa0efd0bfe7fb14e90909eb62a48ccda331726b4319897dd5e" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", - "version": "==1.25.11" - }, - "wcwidth": { - "hashes": [ - "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784", - "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83" - ], - "version": "==0.2.5" - }, - "werkzeug": { - "hashes": [ - "sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43", - "sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==1.0.1" - } - }, - "develop": {} -} diff --git a/examples/fastapi_e2e/requirements.txt b/examples/fastapi_e2e/requirements.txt index b1f97f165..a414b9e63 100644 --- a/examples/fastapi_e2e/requirements.txt +++ b/examples/fastapi_e2e/requirements.txt @@ -1,4 +1,4 @@ -fastapi==0.61.2 +fastapi==0.65.2 pytest==5.4.1 requests==2.23.0 uvicorn==0.12.3 From 3cf2891ef3e45ba1619b480ba11db2920c2e2da4 Mon Sep 17 00:00:00 2001 From: Fabio Pulvirenti Date: Thu, 22 Jul 2021 14:10:29 +0200 Subject: [PATCH 34/41] feat: started porting message provider to fastapi --- examples/message/src/message_handler.py | 3 +- pact/http_proxy.py | 96 +++++++------------------ pact/message_provider.py | 17 +++-- requirements_dev.txt | 1 - setup.py | 3 + tests/test_http_proxy.py | 72 ++++++++----------- tests/test_message_provider.py | 1 - 7 files changed, 66 insertions(+), 127 deletions(-) diff --git a/examples/message/src/message_handler.py b/examples/message/src/message_handler.py index 422d740a7..b3e208a1f 100644 --- a/examples/message/src/message_handler.py +++ b/examples/message/src/message_handler.py @@ -9,11 +9,12 @@ def __str__(self): if self.topic: return 'Custom Error:, {0}'.format(self.topic) + class MessageHandler(object): def __init__(self, event): self.pass_event(event) @staticmethod def pass_event(event): - if event.get('documentType') != 'application/pdf': + if event.get('documentType') != 'microsoft-word': raise CustomError("Not correct document type") diff --git a/pact/http_proxy.py b/pact/http_proxy.py index d20a67bb1..5579b1893 100644 --- a/pact/http_proxy.py +++ b/pact/http_proxy.py @@ -1,27 +1,22 @@ """Http Proxy to be used as provider url in verifier.""" -from werkzeug.local import LocalStack -from flask import Flask, jsonify, request -from werkzeug.exceptions import HTTPException -import json +#from werkzeug.local import LocalStack +from fastapi import FastAPI, status, Request, HTTPException +import uvicorn as uvicorn import logging log = logging.getLogger(__name__) logging.basicConfig(level=logging.DEBUG) -app = Flask(__name__) -localstack = LocalStack() +app = FastAPI() PROXY_PORT = 1234 +items = { + "states": None +} -def shutdown_server(): - """Shutdown Http Proxy server.""" - shutdown = request.environ.get('werkzeug.server.shutdown') - if shutdown is None: - raise RuntimeError('Not running with the Werkzeug Server') - shutdown() def _match_states(payload): """Match states in payload against stored message handlers.""" log.debug(f'Find handler from payload: {payload}') - handlers = localstack.top + handlers = items["states"] states = handlers['messageHandlers'] log.debug(f'Setup states: {handlers}') provider_states = payload['providerStates'] @@ -30,74 +25,33 @@ def _match_states(payload): matching_state = state['name'] if matching_state in states: return states[matching_state] - raise RuntimeError('No matched handler.') + raise HTTPException(status_code=500, detail='No matched handler.') -@app.route('/', methods=['POST']) -def home(): + +@app.post("/") +async def root(request: Request): """Match states with provided message handlers.""" - payload = request.json + payload = await request.json() message = _match_states(payload) - res = jsonify({ - 'contents': message - }) - res.status_code = 200 - return res + return {'contents': message} + -@app.route('/ping', methods=['GET']) +@app.get('/ping', status_code=status.HTTP_200_OK) def ping(): """Check whether the server is available before setting up states.""" - res = jsonify({ - 'ping': 'pong' - }) - res.status_code = 200 - return res + return {"ping": "pong"} -@app.route("/setup", methods=['POST']) -def setup(): + +@app.post("/setup", status_code=status.HTTP_201_CREATED) +async def setup(request: Request): """Endpoint to setup states. Use localstack to store payload. """ - payload = request.json - # Store payload in localstack - localstack.push(payload) - res = jsonify(payload) - res.status_code = 201 - return res - -@app.route('/shutdown', methods=['POST']) -def shutdown(): - """Shutdown Http Proxy server.""" - shutdown_server() - return 'Server shutting down...' - -@app.errorhandler(HTTPException) -def handle_exception(e): - """Return JSON instead of HTML for HTTP errors.""" - res = e.get_response() - res.data = json.dumps({ - "code": e.code, - "name": e.name, - "description": e.description, - }) - res.content_type = "application/json" - return res - -@app.errorhandler(RuntimeError) -def handle_runtime_error(e): - """Handle the RuntimeError. - - Handle HTML stacktrace when RuntimeError occurs due to no matched handler. - when the verifier fails. - """ - res = jsonify({ - "name": "RuntimeError", - "description": str(e), - }) - res.status_code = 500 - res.content_type = "application/json" - return res + payload = await request.json() + items["states"] = payload + return items["states"] -if __name__ == '__main__': - app.run(debug=True, port=PROXY_PORT) +def run_proxy(): + uvicorn.run("pact.http_proxy:app", port=PROXY_PORT) diff --git a/pact/message_provider.py b/pact/message_provider.py index 61632e175..5c4806b56 100644 --- a/pact/message_provider.py +++ b/pact/message_provider.py @@ -3,13 +3,15 @@ import requests from requests.adapters import HTTPAdapter from requests.packages.urllib3 import Retry -from subprocess import Popen, PIPE +from multiprocessing import Process from .verifier import Verifier +from .http_proxy import run_proxy import logging log = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) + class MessageProvider(object): """ A Pact message provider. @@ -81,21 +83,18 @@ def _wait_for_server_start(self): def _start_proxy(self): log.info('Start Http Proxy Server') - current_dir = os.path.dirname(os.path.realpath(__file__)) - cmd = f'python {current_dir}/http_proxy.py {self.proxy_port} >/dev/null &' - self._process = Popen(cmd.split(), stdout=PIPE) + self._process = Process(target=run_proxy, args=(), daemon=True) + self._process.start() self._wait_for_server_start() self._setup_states() def _stop_proxy(self): """Stop the Http Proxy. - - For some reason, I cannot stop the Flask process using with Popen process. - The workaround is to use the API endpoint. """ log.info('Stop Http Proxy Serve') - resp = requests.post(f'{self._proxy_url()}/shutdown', verify=False,) - assert resp.status_code == 200, resp.text + if isinstance(self._process, Process): + self._process.terminate() + assert not self._process.is_alive() def verify(self): """Verify pact files with executable verifier.""" diff --git a/requirements_dev.txt b/requirements_dev.txt index cc19ddd56..d8a27e228 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -1,6 +1,5 @@ Click>=2.0.0 coverage==5.4 -Flask==1.1.4 configparser==3.5.0 flake8==3.8.3 mock==3.0.5 diff --git a/setup.py b/setup.py index de556bfc8..7ff9edfa9 100644 --- a/setup.py +++ b/setup.py @@ -117,6 +117,9 @@ def read(filename): 'psutil>=2.0.0', 'requests>=2.5.0', 'six>=1.9.0', + 'fastapi==0.65.2', + 'persist-queue==0.6.0', + 'uvicorn==0.14.0' ] if __name__ == '__main__': diff --git a/tests/test_http_proxy.py b/tests/test_http_proxy.py index 5a56f1753..b99773498 100644 --- a/tests/test_http_proxy.py +++ b/tests/test_http_proxy.py @@ -2,59 +2,46 @@ from unittest import TestCase from mock import patch, Mock import json +from pact.http_proxy import app +from fastapi.testclient import TestClient +client = TestClient(app) + class HttpProxyTestCase(TestCase): - def test_ping(self): - res = http_proxy.app.test_client().get('/ping') - self.assertEqual(res.status_code, 200) - json_res = res.get_json() - self.assertEqual(json_res['ping'], 'pong') - @patch.object(http_proxy, 'request') - def test_shutdown(self, mock_request): - mock_shutdown = Mock() - mock_request.environ.get.return_value(mock_shutdown) - res = http_proxy.app.test_client().post('/shutdown') + def test_ping(self): + res = client.get('/ping') self.assertEqual(res.status_code, 200) + assert res.json() == {"ping": "pong"} - def test_shutdown_should_raise_500(self): - res = http_proxy.app.test_client().post('/shutdown') - self.assertEqual(res.status_code, 500) - self.assertEqual(res.get_json(), { - "description": "Not running with the Werkzeug Server", - "name": "RuntimeError" - }) + def test_handle_http_error(self): + res = client.get( + '/something_does_not_exist' + ) + self.assertEqual(res.status_code, 404) + json_res = res.json() + json_res['code'] = 404 + json_res['name'] = 'Not Found' def test_setup(self): payload = {'anyPayload': 'really'} - res = http_proxy.app.test_client().post( + res = client.post( '/setup', - data=json.dumps(payload), - content_type='application/json', + json=payload ) self.assertEqual(res.status_code, 201) - json_res = res.get_json() + json_res = res.json() assert json_res == payload def setup_state(self, payload): - setup_res = http_proxy.app.test_client().post( + setup_res = client.post( '/setup', - data=json.dumps(payload), - content_type='application/json', + json=payload ) self.assertEqual(setup_res.status_code, 201) - def test_handle_http_error(self): - res = http_proxy.app.test_client().get( - '/something_does_not_exist' - ) - self.assertEqual(res.status_code, 404) - json_res = res.get_json() - json_res['code'] = 404 - json_res['name'] = 'Not Found' - - def test_home_should_return_expected_resonse(self): + def test_home_should_return_expected_response(self): message = { 'event': 'ObjectCreated:Put', 'bucket': 'bucket_name', @@ -74,13 +61,12 @@ def test_home_should_return_expected_resonse(self): 'providerStates': [{'name': 'A document created successfully'}] } - res = http_proxy.app.test_client().post( + res = client.post( '/', - data=json.dumps(payload), - content_type='application/json', + json=payload ) - self.assertEqual(res.get_json(), {'contents': message}) + self.assertEqual(res.json(), {'contents': message}) def test_home_raise_runtime_error_if_no_matched(self): data = { @@ -94,14 +80,12 @@ def test_home_raise_runtime_error_if_no_matched(self): payload = { 'providerStates': [{'name': 'New state to raise RuntimeError'}] } - res = http_proxy.app.test_client().post( + res = client.post( '/', - data=json.dumps(payload), - content_type='application/json', + json=payload ) self.assertEqual(res.status_code, 500) - assert res.get_json() == { - 'description': 'No matched handler.', - 'name': 'RuntimeError' + assert res.json() == { + 'detail': 'No matched handler.' } diff --git a/tests/test_message_provider.py b/tests/test_message_provider.py index 3e87f6fee..b3fa7d3d7 100644 --- a/tests/test_message_provider.py +++ b/tests/test_message_provider.py @@ -104,7 +104,6 @@ def setUp(self): def test_shutdown_successfully(self, mock_requests): mock_requests.return_value = self._mock_response(content="success") self.provider._stop_proxy() - mock_requests.assert_called_once_with(f'{self.provider._proxy_url()}/shutdown', verify=False) class SetupStateTestCase(MessageProviderTestCase): def setUp(self): From 06897ba7dadaee11d917ba3cc9e2a520f8d3db31 Mon Sep 17 00:00:00 2001 From: Fabio Pulvirenti Date: Thu, 22 Jul 2021 14:30:35 +0200 Subject: [PATCH 35/41] feat: fixed test --- setup.py | 1 - tests/test_pact.py | 1 - 2 files changed, 2 deletions(-) diff --git a/setup.py b/setup.py index 7ff9edfa9..43ad6bda0 100644 --- a/setup.py +++ b/setup.py @@ -118,7 +118,6 @@ def read(filename): 'requests>=2.5.0', 'six>=1.9.0', 'fastapi==0.65.2', - 'persist-queue==0.6.0', 'uvicorn==0.14.0' ] diff --git a/tests/test_pact.py b/tests/test_pact.py index bdcc95e72..36b0b57e7 100644 --- a/tests/test_pact.py +++ b/tests/test_pact.py @@ -486,7 +486,6 @@ def setUp(self): .will_respond_with(200, body='success')) self.get_verification_call = call( 'get', 'http://localhost:1234/interactions/verification', - allow_redirects=True, headers={'X-Pact-Mock-Service': 'true'}, verify=False, params=None) From 3f3c41a4021aed2062aa8db754453878a204a73b Mon Sep 17 00:00:00 2001 From: Fabio Pulvirenti Date: Thu, 22 Jul 2021 14:33:39 +0200 Subject: [PATCH 36/41] security: update fastapi to latest version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 43ad6bda0..075150b3b 100644 --- a/setup.py +++ b/setup.py @@ -117,7 +117,7 @@ def read(filename): 'psutil>=2.0.0', 'requests>=2.5.0', 'six>=1.9.0', - 'fastapi==0.65.2', + 'fastapi==0.67.0', 'uvicorn==0.14.0' ] From e2a30601765f6e12de3dcef9a38d7a1b4b205ae4 Mon Sep 17 00:00:00 2001 From: Fabio Pulvirenti Date: Thu, 22 Jul 2021 14:47:09 +0200 Subject: [PATCH 37/41] feat: fixed flake8 errors --- pact/http_proxy.py | 1 - tests/test_http_proxy.py | 3 --- 2 files changed, 4 deletions(-) diff --git a/pact/http_proxy.py b/pact/http_proxy.py index 5579b1893..dcf07fb89 100644 --- a/pact/http_proxy.py +++ b/pact/http_proxy.py @@ -1,5 +1,4 @@ """Http Proxy to be used as provider url in verifier.""" -#from werkzeug.local import LocalStack from fastapi import FastAPI, status, Request, HTTPException import uvicorn as uvicorn import logging diff --git a/tests/test_http_proxy.py b/tests/test_http_proxy.py index b99773498..36bac25a8 100644 --- a/tests/test_http_proxy.py +++ b/tests/test_http_proxy.py @@ -1,7 +1,4 @@ -from pact import http_proxy as http_proxy from unittest import TestCase -from mock import patch, Mock -import json from pact.http_proxy import app from fastapi.testclient import TestClient client = TestClient(app) From e2f1e2a67b143231f53517b098ddd2e3bf881af1 Mon Sep 17 00:00:00 2001 From: Fabio Pulvirenti Date: Thu, 22 Jul 2021 14:52:07 +0200 Subject: [PATCH 38/41] fix: Fixed comments --- pact/http_proxy.py | 1 + pact/message_provider.py | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pact/http_proxy.py b/pact/http_proxy.py index dcf07fb89..3a3bfa8d3 100644 --- a/pact/http_proxy.py +++ b/pact/http_proxy.py @@ -53,4 +53,5 @@ async def setup(request: Request): def run_proxy(): + """Rub HTTP Proxy""" uvicorn.run("pact.http_proxy:app", port=PROXY_PORT) diff --git a/pact/message_provider.py b/pact/message_provider.py index 5c4806b56..e7220843a 100644 --- a/pact/message_provider.py +++ b/pact/message_provider.py @@ -89,8 +89,7 @@ def _start_proxy(self): self._setup_states() def _stop_proxy(self): - """Stop the Http Proxy. - """ + """Stop the Http Proxy.""" log.info('Stop Http Proxy Serve') if isinstance(self._process, Process): self._process.terminate() From 2616a18826b04e80de44079175ae314fbd84cfca Mon Sep 17 00:00:00 2001 From: Fabio Pulvirenti Date: Thu, 22 Jul 2021 14:54:02 +0200 Subject: [PATCH 39/41] fix: error on pydocstyle --- pact/http_proxy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pact/http_proxy.py b/pact/http_proxy.py index 3a3bfa8d3..ce2b4a7e0 100644 --- a/pact/http_proxy.py +++ b/pact/http_proxy.py @@ -53,5 +53,5 @@ async def setup(request: Request): def run_proxy(): - """Rub HTTP Proxy""" + """Rub HTTP Proxy.""" uvicorn.run("pact.http_proxy:app", port=PROXY_PORT) From 2549933595a1aecee6e31fc3eca9f35a86d5d532 Mon Sep 17 00:00:00 2001 From: Fabio Pulvirenti Date: Fri, 23 Jul 2021 15:16:33 +0200 Subject: [PATCH 40/41] fix: removed commented code useless after porting to fast api --- tests/test_message_pact.py | 1 + tests/test_message_provider.py | 21 ++++----------------- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/tests/test_message_pact.py b/tests/test_message_pact.py index ee0f0d0d6..9426458ac 100644 --- a/tests/test_message_pact.py +++ b/tests/test_message_pact.py @@ -9,6 +9,7 @@ from pact.constants import MESSAGE_PATH from pact import message_pact as message_pact + class MessagePactTestCase(TestCase): def setUp(self): self.consumer = MessageConsumer('TestConsumer') diff --git a/tests/test_message_provider.py b/tests/test_message_provider.py index b3fa7d3d7..5753014f7 100644 --- a/tests/test_message_provider.py +++ b/tests/test_message_provider.py @@ -6,6 +6,7 @@ from pact.message_provider import MessageProvider from pact import message_provider as message_provider + class MessageProviderTestCase(TestCase): def _mock_response( self, @@ -50,6 +51,7 @@ def test_verify(self, mock_verify_pacts): assert mock_verify_pacts.call_count == 1 mock_verify_pacts.assert_called_with(f'{self.provider.pact_dir}/{self.provider._pact_file()}', verbose=False) + class MessageProviderContextManagerTestCase(MessageProviderTestCase): def setUp(self): super(MessageProviderContextManagerTestCase, self).setUp() @@ -73,28 +75,11 @@ def test_stop_proxy_on_runtime_error(self, mock_stop_proxy, mock_start_proxy, mo mock_start_proxy.assert_called_once() mock_stop_proxy.assert_called_once() - # @pytest.mark.skip(reason="Caused BrokenPipeError in PactStartShutdownServerTestCase::test_stop_fails_posix. Need to investigate") - # @patch('pact.MessageProvider.verify', side_effect=RuntimeError('boom!')) - # @patch('pact.MessageProvider._stop_proxy') - # def test_exception_in_context_manager_body_will_cascade(self, mock_stop_proxy, mock_verify): - # with self.assertRaises(RuntimeError): - # with self.provider: - # self.provider.verify() - - # mock_stop_proxy.assert_called_once() class StartProxyTestCase(MessageProviderTestCase): def setUp(self): super(StartProxyTestCase, self).setUp() - # @pytest.mark.skip(reason="Caused BrokenPipeError in PactStartShutdownServerTestCase::test_stop_fails_posix. Need to investigate") - # @patch('pact.MessageProvider._setup_states') - # @patch('pact.MessageProvider._wait_for_server_start') - # def test_start_proxy_successfully(self, mock_wait_for_server_start, mock_setup_states): - # self.provider._start_proxy() - - # mock_wait_for_server_start.assert_called_once() - # mock_setup_states.assert_called_once() class StopProxyTestCase(MessageProviderTestCase): def setUp(self): @@ -105,6 +90,7 @@ def test_shutdown_successfully(self, mock_requests): mock_requests.return_value = self._mock_response(content="success") self.provider._stop_proxy() + class SetupStateTestCase(MessageProviderTestCase): def setUp(self): super(SetupStateTestCase, self).setUp() @@ -121,6 +107,7 @@ def test_shutdown_successfully(self, mock_requests): mock_requests.assert_called_once_with(f'{self.provider._proxy_url()}/setup', verify=False, json=expected_payload) + class WaitForServerStartTestCase(MessageProviderTestCase): def setUp(self): super(WaitForServerStartTestCase, self).setUp() From 226584bd97f630a67b22f0cc7d4aced5f5147350 Mon Sep 17 00:00:00 2001 From: Fabio Pulvirenti Date: Fri, 23 Jul 2021 15:26:33 +0200 Subject: [PATCH 41/41] fix: removed commented code --- tests/test_message_provider.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_message_provider.py b/tests/test_message_provider.py index 5753014f7..132af1c78 100644 --- a/tests/test_message_provider.py +++ b/tests/test_message_provider.py @@ -1,5 +1,4 @@ import os -# import pytest from mock import patch, Mock from unittest import TestCase