Skip to content

Commit 51eb338

Browse files
Command line application for verifying pacts
- Added `pact-verifier` which is a command line application that calls the Ruby verifier - It supports the same options as the JS version of Pact, including provider state and broker options - Removed all Docker related requirements
1 parent 3130f9a commit 51eb338

File tree

12 files changed

+394
-93
lines changed

12 files changed

+394
-93
lines changed

Makefile

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,33 @@ deps:
3434
pip install -r requirements_dev.txt
3535

3636

37+
define E2E
38+
set -e
39+
cd e2e
40+
nosetests ./contracts
41+
python app.py &
42+
APP_PID=$$!
43+
function teardown {
44+
echo 'Tearing down Flask server'
45+
kill $$APP_PID
46+
}
47+
trap teardown EXIT
48+
while ! nc -z localhost 5000; do
49+
sleep 0.1
50+
done
51+
pact-verifier \
52+
--provider-base-url=http://localhost:5000 \
53+
--pact-urls=./pacts/consumer-provider.json \
54+
--provider-states-url=http://localhost:5000/_pact/provider-states \
55+
--provider-states-setup-url=http://localhost:5000/_pact/provider-states/active
56+
endef
57+
58+
59+
export E2E
3760
.PHONY: e2e
3861
e2e:
39-
sh -c '\
40-
cd e2e; \
41-
docker-compose pull > /dev/null; \
42-
nosetests ./contracts; \
43-
docker-compose down; \
44-
docker-compose up -d app pactverifier; \
45-
docker-compose logs --follow >> ./pact/verifier-logs.txt & \
46-
docker-compose exec pactverifier bundle exec rake verify_pacts; \
47-
docker-compose down'
62+
sh -c "$$E2E"
63+
4864

4965
.PHONY: package
5066
package: pact/bin
@@ -61,11 +77,8 @@ test: deps pact/bin
6177
@echo "Checking version consistency..."
6278
python -c "$$VERSION_CHECK"
6379

64-
@echo "flake8..."
6580
flake8
66-
67-
@echo "pydocstyle..."
6881
pydocstyle pact
69-
70-
@echo "testing..."
82+
coverage erase
7183
tox
84+
coverage report --fail-under=100

README.md

Lines changed: 43 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -225,59 +225,56 @@ services:
225225
> the command line to be `8080`, your tests would need to contact `localhost:8080`.
226226

227227
## Verifying Pacts Against a Service
228-
> pact-python does not yet have any involvement in the process of verifying a contract against
229-
> a provider. This section is included to provide insight into the full cycle of a
230-
> contract for those getting started.
231228

232-
Like the mock service, the provider verifier can be run in two ways:
229+
In addition to writing Pacts for Python consumers, you can also verify those Pacts
230+
against a provider of any language. After installing pact-python a `pact-verifier`
231+
application should be available. To get details about its use you can call it with the
232+
help argument:
233233

234-
1. [Install and use it as a Ruby application][pact-provider-verifier]
235-
2. Run it as a Docker container
236-
237-
> Both choices have very similar configuration options. We will illustrate the Docker
238-
> method below, but the Ruby method supports the same features.
234+
```bash
235+
pact-verifier --help
236+
```
239237

240-
When verifying your contracts, you may find it easier to run the provider application
241-
and the verifier in separate Docker containers. This gives you a nice isolated
242-
network, where you can set the DNS records of the services to anything you desire
243-
and not have to worry about port conflicts with other services on your computer.
244-
Launching the provider verifier in a `docker-compose.yml` might look like this:
238+
The simplest example is verifying a server with locally stored Pact files and no provider
239+
states:
245240

246-
```yaml
247-
version: '2'
248-
services:
249-
app:
250-
image: the-provider-application-to-test
251-
252-
pactverifier:
253-
command: ['tail', '-f', '/dev/null']
254-
image: dius/pact-provider-verifier-docker
255-
depends_on:
256-
- app
257-
volumes:
258-
- ./contracts:/tmp/pacts
259-
environment:
260-
- pact_urls=/tmp/pacts/consumer-provider.json
261-
- provider_base_url=http://app
262-
- provider_states_url=http://app/_pact/provider-states
263-
- provider_states_active_url=http://app/_pact/provider-states/active
241+
```bash
242+
pact-verifier --provider-base-url=http://localhost:8080 --pact-urls=./pacts/consumer-provider.json
264243
```
265244

266-
In this example, our `app` container may take a few moments to start, so we don't
267-
immediately start running the verification, and instead `tail -f /dev/null` which will keep
268-
the container running forever. We can then use `docker-compose` to run the tests like so:
245+
Which will immediately invoke the Pact verifier, making HTTP requests to the server located
246+
at `http://localhost:8080` based on the Pacts in `./pacts/consumer-provider.json` and
247+
reporting the results.
269248

270-
```
271-
docker-compose up -d
272-
# Insert code to check that `app` has finished starting and is ready for requests
273-
docker-compose exec pactverifier bundle exec rake verify_pacts
274-
```
249+
There are several options for configuring how the Pacts are verified:
250+
251+
###### --provider-base-url
252+
253+
Required. Defines the URL of the server to make requests to when verifying the Pacts.
254+
255+
###### --pact-urls
256+
257+
Required. The location of the Pact files you want to verify. This can be a URL to a [Pact Broker]
258+
or one or more local paths, separated by a comma.
259+
260+
###### --provider-states-url
261+
262+
The URL where your provider application will produce the list of available provider states.
263+
The verifier calls this URL to ensure the Pacts specify valid states before making the HTTP
264+
requests.
265+
266+
###### --provider-states-setup-url
267+
268+
The URL which should be called to setup a specific provider state before a Pact is verified.
269+
270+
###### --pact-broker-username
271+
272+
The username to use when contacting the Pact Broker.
273+
274+
###### --pact-broker-password
275275

276-
You configure the verifier in Docker using 4 environment variables:
277-
- `pact_urls` - a comma delimited list of pact file urls
278-
- `provider_base_url` - the base url of the pact provider
279-
- `provider_states_url` - the full url of the endpoint which returns provider states by consumer
280-
- `provider_states_active_url` - the full url of the endpoint which sets the active pact consumer and provider state
276+
The password to use when contacting the Pact Broker. You can also specify this value
277+
as the environment variable `PACT_BROKER_PASSWORD`.
281278

282279
### Provider States
283280
In many cases, your contracts will need very specific data to exist on the provider
@@ -310,6 +307,7 @@ End to end: `make e2e`
310307

311308
[context manager]: https://en.wikibooks.org/wiki/Python_Programming/Context_Managers
312309
[Pact]: https://www.gitbook.com/book/pact-foundation/pact/details
310+
[Pact Broker]: https://docs.pact.io/documentation/sharings_pacts.html
313311
[Pact documentation]: https://docs.pact.io/
314312
[Pact Mock Service]: https://github.com/bethesque/pact-mock_service
315313
[Provider States]: https://docs.pact.io/documentation/provider_states.html

e2e/app.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,4 @@ def catch_all(path):
5151

5252

5353
if __name__ == '__main__':
54-
app.run(host='0.0.0.0', port='80')
54+
app.run(port='5000')

e2e/docker-compose.yml

Lines changed: 0 additions & 28 deletions
This file was deleted.

pact/constants.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,16 @@ def mock_service_exe():
1111
return 'pact-mock-service'
1212

1313

14+
def provider_verifier_exe():
15+
"""Get the appropriate provider executable name for this platform."""
16+
if os.name == 'nt':
17+
return 'pact-provider-verifier.bat'
18+
else:
19+
return 'pact-provider-verifier'
20+
21+
1422
MOCK_SERVICE_PATH = normpath(join(
1523
dirname(__file__), 'bin', 'mock-service', 'bin', mock_service_exe()))
24+
25+
VERIFIER_PATH = normpath(join(
26+
dirname(__file__), 'bin', 'verifier', 'bin', provider_verifier_exe()))

pact/test/test_constants.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,20 @@ def test_other(self):
1818
def test_windows(self):
1919
self.mock_os.name = 'nt'
2020
self.assertEqual(constants.mock_service_exe(), 'pact-mock-service.bat')
21+
22+
23+
class provider_verifier_exeTestCase(TestCase):
24+
def setUp(self):
25+
super(provider_verifier_exeTestCase, self).setUp()
26+
self.addCleanup(patch.stopall)
27+
self.mock_os = patch.object(constants, 'os', autospec=True).start()
28+
29+
def test_other(self):
30+
self.mock_os.name = 'posix'
31+
self.assertEqual(
32+
constants.provider_verifier_exe(), 'pact-provider-verifier')
33+
34+
def test_windows(self):
35+
self.mock_os.name = 'nt'
36+
self.assertEqual(
37+
constants.provider_verifier_exe(), 'pact-provider-verifier.bat')

0 commit comments

Comments
 (0)