Skip to content

Commit a67d66c

Browse files
committed
chore(tests): use long-lived pact broker
The initial implementation of the compatibility suite spun up and down the Pact Broker for each scenario, which also resulting in flaky tests in CI. This refactor uses a session pytest fixture which will spin up the broker once, and keep re-using it. Functionality to 'reset' the broker between tests has also been added. Signed-off-by: JP-Ellis <josh@jpellis.me>
1 parent 63b30f9 commit a67d66c

File tree

2 files changed

+75
-10
lines changed

2 files changed

+75
-10
lines changed

tests/v3/compatibility_suite/test_v1_provider.py

+56-10
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@
99
import logging
1010
import pickle
1111
import re
12+
import shutil
1213
import signal
1314
import subprocess
1415
import sys
1516
import time
17+
from contextvars import ContextVar
1618
from pathlib import Path
1719
from threading import Thread
18-
from typing import Any, Generator, NoReturn
20+
from typing import Any, Generator, NoReturn, Union
1921

2022
import pytest
2123
import requests
@@ -34,13 +36,52 @@
3436

3537
logger = logging.getLogger(__name__)
3638

39+
reset_broker_var = ContextVar("reset_broker", default=True)
40+
"""
41+
This context variable is used to determine whether the Pact broker should be
42+
cleaned up. It is used to ensure that the broker is only cleaned up once, even
43+
if a step is run multiple times.
44+
45+
All scenarios which make use of the Pact broker should set this to `True` at the
46+
start of the scenario.
47+
"""
48+
3749

3850
@pytest.fixture()
3951
def verifier() -> Verifier:
4052
"""Return a new Verifier."""
4153
return Verifier()
4254

4355

56+
@pytest.fixture(scope="session")
57+
def broker_url(request: pytest.FixtureRequest) -> Generator[URL, Any, None]:
58+
"""
59+
Fixture to run the Pact broker.
60+
61+
This inspects whether the `--broker-url` option has been given. If it has,
62+
it is assumed that the broker is already running and simply returns the
63+
given URL.
64+
65+
Otherwise, the Pact broker is started in a container. The URL of the
66+
containerised broker is then returned.
67+
"""
68+
broker_url: Union[str, None] = request.config.getoption("--broker-url")
69+
70+
# If we have been given a broker URL, there's nothing more to do here and we
71+
# can return early.
72+
if broker_url:
73+
yield URL(broker_url)
74+
return
75+
76+
with DockerCompose(
77+
Path(__file__).parent / "util",
78+
compose_file_name="pact-broker.yml",
79+
pull=True,
80+
) as _:
81+
yield URL("http://pactbroker:pactbroker@localhost:9292")
82+
return
83+
84+
4485
################################################################################
4586
## Scenario
4687
################################################################################
@@ -76,6 +117,7 @@ def test_incorrect_request_is_made_to_provider() -> None:
76117
)
77118
def test_verifying_a_simple_http_request_via_a_pact_broker() -> None:
78119
"""Verifying a simple HTTP request via a Pact broker."""
120+
reset_broker_var.set(True) # noqa: FBT003
79121

80122

81123
@scenario(
@@ -84,6 +126,7 @@ def test_verifying_a_simple_http_request_via_a_pact_broker() -> None:
84126
)
85127
def test_verifying_a_simple_http_request_via_a_pact_broker_with_publishing() -> None:
86128
"""Verifying a simple HTTP request via a Pact broker with publishing."""
129+
reset_broker_var.set(True) # noqa: FBT003
87130

88131

89132
@scenario(
@@ -92,6 +135,7 @@ def test_verifying_a_simple_http_request_via_a_pact_broker_with_publishing() ->
92135
)
93136
def test_verifying_multiple_pact_files_via_a_pact_broker() -> None:
94137
"""Verifying multiple Pact files via a Pact broker."""
138+
reset_broker_var.set(True) # noqa: FBT003
95139

96140

97141
@scenario(
@@ -100,6 +144,7 @@ def test_verifying_multiple_pact_files_via_a_pact_broker() -> None:
100144
)
101145
def test_incorrect_request_is_made_to_provider_via_a_pact_broker() -> None:
102146
"""Incorrect request is made to provider via a Pact broker."""
147+
reset_broker_var.set(True) # noqa: FBT003
103148

104149

105150
@scenario(
@@ -475,6 +520,7 @@ def a_pact_file_for_interaction_is_to_be_verified(
475520
)
476521
def a_pact_file_for_interaction_is_to_be_verified_from_a_pact_broker(
477522
interaction_definitions: dict[int, InteractionDefinition],
523+
broker_url: URL,
478524
verifier: Verifier,
479525
interaction: int,
480526
temp_dir: Path,
@@ -491,18 +537,18 @@ def a_pact_file_for_interaction_is_to_be_verified_from_a_pact_broker(
491537
defn.add_to_pact(pact, f"interaction {interaction}")
492538

493539
pacts_dir = temp_dir / "pacts"
540+
if pacts_dir.exists():
541+
shutil.rmtree(pacts_dir)
494542
pacts_dir.mkdir(exist_ok=True, parents=True)
495543
pact.write_file(pacts_dir)
496544

497-
with DockerCompose(
498-
Path(__file__).parent / "util",
499-
compose_file_name="pact-broker.yml",
500-
pull=True,
501-
) as _:
502-
pact_broker = PactBroker(URL("http://pactbroker:pactbroker@localhost:9292"))
503-
pact_broker.publish(pacts_dir)
504-
verifier.broker_source(pact_broker.url)
505-
yield pact_broker
545+
pact_broker = PactBroker(broker_url)
546+
if reset_broker_var.get():
547+
pact_broker.reset()
548+
reset_broker_var.set(False) # noqa: FBT003
549+
pact_broker.publish(pacts_dir)
550+
verifier.broker_source(pact_broker.url)
551+
yield pact_broker
506552

507553

508554
@given("publishing of verification results is enabled")

tests/v3/compatibility_suite/util/provider.py

+19
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,25 @@ def _install(self) -> None:
299299
msg = "pact-broker not found"
300300
raise NotImplementedError(msg)
301301

302+
def reset(self) -> None:
303+
"""
304+
Reset the Pact Broker.
305+
306+
This function will reset the Pact Broker by deleting all pacts and
307+
verification results.
308+
"""
309+
requests.delete(
310+
str(
311+
self.url
312+
/ "integrations"
313+
/ "provider"
314+
/ self.provider
315+
/ "consumer"
316+
/ self.consumer
317+
),
318+
timeout=2,
319+
)
320+
302321
def publish(self, directory: Path | str, version: str | None = None) -> None:
303322
"""
304323
Publish the interactions to the Pact Broker.

0 commit comments

Comments
 (0)