Skip to content

Commit 475703c

Browse files
Resolves #58: Update to pact-ruby-standalone 1.9.0
- Pinned to pact-ruby-standalone 1.9.0 - Removed the payload to `/pact` of the pact-mock-service as its no longer required - Added the option to specify pact URIs as arguments to be consistent with the Ruby verifier - Added deprecation notices to `--pact-url` and `--pact-urls` - Added `file_write_mode` to the Pact class to control how the mock service writes files when tests are run in parallel
1 parent 730ead7 commit 475703c

File tree

7 files changed

+51
-36
lines changed

7 files changed

+51
-36
lines changed

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ define E2E
4444
done
4545
pact-verifier \
4646
--provider-base-url=http://localhost:5000 \
47-
--pact-urls=./pacts/consumer-provider.json \
4847
--provider-states-url=http://localhost:5000/_pact/provider-states \
49-
--provider-states-setup-url=http://localhost:5000/_pact/provider-states/active
48+
--provider-states-setup-url=http://localhost:5000/_pact/provider-states/active \
49+
./pacts/consumer-provider.json
5050
endef
5151

5252

e2e/contracts/test_e2e.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ def test_sparse(self):
9393
(pact
9494
.given('the user `bob` exists')
9595
.upon_receiving('a request for the user object of `bob`')
96-
.with_request('get', '/users/bob')
96+
.with_request('get', Term('/users/[a-z]+', '/users/bob'))
9797
.will_respond_with(200, body={
9898
'username': SomethingLike('bob'),
9999
'id': Term('\d+', '123')}))

pact/pact.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ class Pact(object):
4040

4141
def __init__(self, consumer, provider, host_name='localhost', port=1234,
4242
log_dir=None, ssl=False, sslcert=None, sslkey=None,
43-
cors=False, pact_dir=None, version='2.0.0'):
43+
cors=False, pact_dir=None, version='2.0.0',
44+
file_write_mode='overwrite'):
4445
"""
4546
Constructor for Pact.
4647
@@ -74,13 +75,21 @@ def __init__(self, consumer, provider, host_name='localhost', port=1234,
7475
:param version: The Pact Specification version to use, defaults to
7576
'2.0.0'.
7677
:type version: str
78+
:param file_write_mode: `overwrite` or `merge`. Use `merge` when
79+
running multiple mock service instances in parallel for the same
80+
consumer/provider pair. Ensure the pact file is deleted before
81+
running tests when using this option so that interactions deleted
82+
from the code are not maintained in the file. Defaults to
83+
`overwrite`.
84+
:type file_write_mode: str
7785
"""
7886
scheme = 'https' if ssl else 'http'
7987
self.uri = '{scheme}://{host_name}:{port}'.format(
8088
host_name=host_name, port=port, scheme=scheme)
8189

8290
self.consumer = consumer
8391
self.cors = cors
92+
self.file_write_mode = file_write_mode
8493
self.host_name = host_name
8594
self.log_dir = log_dir or os.getcwd()
8695
self.pact_dir = pact_dir or os.getcwd()
@@ -137,6 +146,7 @@ def start_service(self):
137146
'--port={}'.format(self.port),
138147
'--log', '{}/pact-mock-service.log'.format(self.log_dir),
139148
'--pact-dir', self.pact_dir,
149+
'--pact-file-write-mode', self.file_write_mode,
140150
'--pact-specification-version={}'.format(self.version),
141151
'--consumer', self.consumer.name,
142152
'--provider', self.provider.name]
@@ -192,13 +202,8 @@ def verify(self):
192202
self.uri + '/interactions/verification',
193203
headers=self.HEADERS)
194204
assert resp.status_code == 200, resp.text
195-
payload = {
196-
'consumer': {'name': self.consumer.name},
197-
'provider': {'name': self.provider.name},
198-
'pact_dir': self.pact_dir
199-
}
200205
resp = requests.post(
201-
self.uri + '/pact', headers=self.HEADERS, json=payload)
206+
self.uri + '/pact', headers=self.HEADERS)
202207
assert resp.status_code == 200, resp.text
203208

204209
def with_request(self, method, path, body=None, headers=None, query=None):

pact/test/test_pact.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ def test_init_custom_mock_service(self):
3535
target = Pact(
3636
self.consumer, self.provider, host_name='192.168.1.1', port=8000,
3737
log_dir='/logs', ssl=True, sslcert='/ssl.cert', sslkey='/ssl.pem',
38-
cors=True, pact_dir='/pacts', version='3.0.0')
38+
cors=True, pact_dir='/pacts', version='3.0.0',
39+
file_write_mode='merge')
3940

4041
self.assertIs(target.consumer, self.consumer)
4142
self.assertIs(target.cors, True)
@@ -49,6 +50,7 @@ def test_init_custom_mock_service(self):
4950
self.assertEqual(target.sslkey, '/ssl.pem')
5051
self.assertEqual(target.uri, 'https://192.168.1.1:8000')
5152
self.assertEqual(target.version, '3.0.0')
53+
self.assertEqual(target.file_write_mode, 'merge')
5254
self.assertEqual(len(target._interactions), 0)
5355

5456
def test_definition_sparse(self):
@@ -232,6 +234,7 @@ def test_start_fails(self):
232234
'--port=1234',
233235
'--log', '/logs/pact-mock-service.log',
234236
'--pact-dir', '/pacts',
237+
'--pact-file-write-mode', 'overwrite',
235238
'--pact-specification-version=2.0.0',
236239
'--consumer', 'consumer',
237240
'--provider', 'provider'])
@@ -247,6 +250,7 @@ def test_start_no_ssl(self):
247250
'--port=1234',
248251
'--log', '/logs/pact-mock-service.log',
249252
'--pact-dir', '/pacts',
253+
'--pact-file-write-mode', 'overwrite',
250254
'--pact-specification-version=2.0.0',
251255
'--consumer', 'consumer',
252256
'--provider', 'provider'])
@@ -263,6 +267,7 @@ def test_start_with_ssl(self):
263267
'--port=1234',
264268
'--log', '/logs/pact-mock-service.log',
265269
'--pact-dir', '/pacts',
270+
'--pact-file-write-mode', 'overwrite',
266271
'--pact-specification-version=2.0.0',
267272
'--consumer', 'consumer',
268273
'--provider', 'provider',
@@ -373,9 +378,7 @@ def setUp(self):
373378
'post', 'http://localhost:1234/pact',
374379
data=None,
375380
headers={'X-Pact-Mock-Service': 'true'},
376-
json={'pact_dir': os.getcwd(),
377-
'consumer': {'name': 'TestConsumer'},
378-
'provider': {'name': 'TestProvider'}})
381+
json=None)
379382

380383
def test_success(self):
381384
self.mock_requests.side_effect = iter([Mock(status_code=200)] * 2)

pact/test/test_verify.py

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,10 @@ def setUp(self):
4242

4343
self.runner = CliRunner()
4444
self.default_call = [
45-
'--provider-base-url=http://localhost',
46-
'--pact-urls=./pacts/consumer-provider.json,'
47-
'./pacts/consumer-provider2.json,./pacts/consumer-provider3.json']
45+
'./pacts/consumer-provider.json',
46+
'./pacts/consumer-provider2.json',
47+
'./pacts/consumer-provider3.json',
48+
'--provider-base-url=http://localhost']
4849

4950
self.default_opts = [
5051
'--provider-base-url=http://localhost',
@@ -74,7 +75,7 @@ def test_pact_urls_are_required(self):
7475
verify.main, ['--provider-base-url=http://localhost'])
7576

7677
self.assertEqual(result.exit_code, 1)
77-
self.assertIn(b'--pact-url or --pact-urls', result.output_bytes)
78+
self.assertIn(b'at least one', result.output_bytes)
7879
self.assertFalse(self.mock_Popen.called)
7980

8081
def test_local_pact_urls_must_exist(self):
@@ -123,6 +124,7 @@ def test_password_from_env_var(self):
123124
def test_all_options(self):
124125
self.mock_Popen.return_value.returncode = 0
125126
result = self.runner.invoke(verify.main, [
127+
'./pacts/consumer-provider5.json',
126128
'--provider-base-url=http://localhost',
127129
'--pact-urls=./pacts/consumer-provider.json,'
128130
'./pacts/consumer-provider2.json',
@@ -135,13 +137,15 @@ def test_all_options(self):
135137
'--provider-app-version=1.2.3',
136138
'--timeout=60'
137139
])
138-
self.assertEqual(result.exit_code, 0)
140+
self.assertEqual(result.exit_code, 0, result.output)
139141
self.assertEqual(self.mock_Popen.call_count, 1)
140142
self.assertProcess(
143+
'./pacts/consumer-provider5.json',
144+
'./pacts/consumer-provider3.json',
145+
'./pacts/consumer-provider4.json',
146+
'./pacts/consumer-provider.json',
147+
'./pacts/consumer-provider2.json',
141148
'--provider-base-url=http://localhost',
142-
'--pact-urls=./pacts/consumer-provider3.json,'
143-
'./pacts/consumer-provider4.json,'
144-
'./pacts/consumer-provider.json,./pacts/consumer-provider2.json',
145149
'--provider-states-setup-url=http://localhost/provider-states/set',
146150
'--broker-username=user',
147151
'--broker-password=pass',
@@ -163,9 +167,9 @@ def test_deprecated_pact_urls(self):
163167
result.output_bytes)
164168
self.assertEqual(self.mock_Popen.call_count, 1)
165169
self.assertProcess(
166-
'--provider-base-url=http://localhost',
167-
'--pact-urls=./pacts/consumer-provider.json,'
168-
'./pacts/consumer-provider2.json')
170+
'./pacts/consumer-provider.json',
171+
'./pacts/consumer-provider2.json',
172+
'--provider-base-url=http://localhost')
169173
self.mock_Popen.return_value.communicate.assert_called_once_with(
170174
timeout=30)
171175

pact/verify.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,23 @@
1616

1717

1818
@click.command()
19+
@click.argument('pacts', nargs=-1)
1920
@click.option(
2021
'base_url', '--provider-base-url',
2122
help='Base URL of the provider to verify against.',
2223
required=True)
2324
@click.option(
2425
'pact_url', '--pact-url',
25-
help='The URI of the pact to verify.'
26+
help='DEPRECATED: specify pacts as arguments instead.\n'
27+
'The URI of the pact to verify.'
2628
' Can be an HTTP URI, a local file or directory path. '
2729
' It can be specified multiple times to verify several pacts.',
28-
multiple=True)
30+
multiple=True) # Remove in major version 1.0.0
2931
@click.option(
3032
'pact_urls', '--pact-urls',
3133
default='',
32-
help='The URI(s) of the pact to verify.'
34+
help='DEPRECATED: specify pacts as arguments instead.\n'
35+
'The URI(s) of the pact to verify.'
3336
' Can be an HTTP URI(s) or local file path(s).'
3437
' Provide multiple URI separated by a comma.',
3538
multiple=True) # Remove in major version 1.0.0
@@ -64,19 +67,19 @@
6467
default=False,
6568
help='Publish verification results to the broker',
6669
is_flag=True)
67-
def main(base_url, pact_url, pact_urls, states_url,
70+
def main(pacts, base_url, pact_url, pact_urls, states_url,
6871
states_setup_url, username, password, timeout, provider_app_version,
6972
publish_verification_results):
7073
"""
7174
Verify one or more contracts against a provider service.
7275
7376
Minimal example:
7477
75-
pact-verifier --provider-base-url=http://localhost:8080 --pact-url=./pact
78+
pact-verifier --provider-base-url=http://localhost:8080 ./pacts
7679
""" # NOQA
7780
error = click.style('Error:', fg='red')
7881
warning = click.style('Warning:', fg='yellow')
79-
all_pact_urls = list(pact_url)
82+
all_pact_urls = list(pacts) + list(pact_url)
8083
for urls in pact_urls: # Remove in major version 1.0.0
8184
all_pact_urls.extend(p for p in urls.split(',') if p)
8285

@@ -90,7 +93,7 @@ def main(base_url, pact_url, pact_urls, states_url,
9093
if not all_pact_urls:
9194
click.echo(
9295
error
93-
+ ' At least one of --pact-url or --pact-urls is required.')
96+
+ ' You must supply at least one pact file or directory to verify')
9497
raise click.Abort()
9598

9699
all_pact_urls = expand_directories(all_pact_urls)
@@ -104,13 +107,13 @@ def main(base_url, pact_url, pact_urls, states_url,
104107

105108
options = {
106109
'--provider-base-url': base_url,
107-
'--pact-urls': ','.join(all_pact_urls),
108110
'--provider-states-setup-url': states_setup_url,
109111
'--broker-username': username,
110112
'--broker-password': password
111113
}
112-
command = [VERIFIER_PATH] + [
113-
'{}={}'.format(k, v) for k, v in options.items() if v]
114+
command = [VERIFIER_PATH]
115+
command.extend(all_pact_urls)
116+
command.extend(['{}={}'.format(k, v) for k, v in options.items() if v])
114117

115118
if publish_verification_results:
116119
if not provider_app_version:

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414

1515
IS_64 = sys.maxsize > 2 ** 32
16-
PACT_STANDALONE_VERSION = '1.8.0'
16+
PACT_STANDALONE_VERSION = '1.9.0'
1717

1818

1919
here = os.path.abspath(os.path.dirname(__file__))

0 commit comments

Comments
 (0)