From 6ce118970ab576aaad05238e6f7545b4a29a9f0c Mon Sep 17 00:00:00 2001 From: Valerio Cosentino Date: Fri, 26 Nov 2021 14:21:11 +0100 Subject: [PATCH] until here --- .../pacts/hachebo-consumer-movies-api.json | 9 ++- pact-broker/ssl/nginx.conf | 28 ++++----- pacts/movies-api-duration-provider-pact.json | 63 +++++++++++++++++++ python/Makefile | 4 +- python/duration_provider/verify_pacts.py | 18 ++++++ python/movies_api/main.py | 6 +- python/movies_api/verify_pacts.py | 21 +++++++ 7 files changed, 127 insertions(+), 22 deletions(-) create mode 100644 pacts/movies-api-duration-provider-pact.json create mode 100644 python/duration_provider/verify_pacts.py create mode 100644 python/movies_api/verify_pacts.py diff --git a/javascript/packages/hachebo-consumer/pacts/hachebo-consumer-movies-api.json b/javascript/packages/hachebo-consumer/pacts/hachebo-consumer-movies-api.json index 998f50e..f336838 100644 --- a/javascript/packages/hachebo-consumer/pacts/hachebo-consumer-movies-api.json +++ b/javascript/packages/hachebo-consumer/pacts/hachebo-consumer-movies-api.json @@ -32,7 +32,8 @@ "name": "The Silence of the Lambs", "genre": "Jonathan Demme", "director": "Terror", - "year": 1991 + "year": 1991, + "duration": 192 }, "matchingRules": { "$.headers.Content-Type": { @@ -59,7 +60,8 @@ "name": "The Silence of the Lambs", "genre": "Jonathan Demme", "director": "Terror", - "year": 1991 + "year": 1991, + "duration": 192 }, "matchingRules": { "$.headers.Accept": { @@ -82,7 +84,8 @@ "name": "The Silence of the Lambs", "genre": "Jonathan Demme", "director": "Terror", - "year": 1991 + "year": 1991, + "duration": 192 }, "matchingRules": { "$.headers.Content-Type": { diff --git a/pact-broker/ssl/nginx.conf b/pact-broker/ssl/nginx.conf index e355a7f..fbd2494 100644 --- a/pact-broker/ssl/nginx.conf +++ b/pact-broker/ssl/nginx.conf @@ -10,17 +10,17 @@ server { } } -server { - listen 443 ssl; - server_name localhost; - ssl_certificate /etc/nginx/cert/pact_cert.pem; - ssl_certificate_key /etc/nginx/cert/pact_cert.key; - - location / { - proxy_pass http://app:80; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - } -} \ No newline at end of file +# server { +# listen 443 ssl; +# server_name localhost; +# ssl_certificate /etc/nginx/cert/pact_cert.pem; +# ssl_certificate_key /etc/nginx/cert/pact_cert.key; +# +# location / { +# proxy_pass http://app:80; +# proxy_set_header Host $host; +# proxy_set_header X-Real-IP $remote_addr; +# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +# proxy_set_header X-Forwarded-Proto $scheme; +# } +# } \ No newline at end of file diff --git a/pacts/movies-api-duration-provider-pact.json b/pacts/movies-api-duration-provider-pact.json new file mode 100644 index 0000000..16c208c --- /dev/null +++ b/pacts/movies-api-duration-provider-pact.json @@ -0,0 +1,63 @@ +{ + "consumer": { + "name": "movies-api" + }, + "provider": { + "name": "duration-provider" + }, + "interactions": [ + { + "providerState": "Given a movie exists", + "description": "a request for movies-api", + "request": { + "method": "GET", + "path": "/duration/42" + }, + "response": { + "status": 200, + "body": { + "id": 42, + "duration_min": 192 + }, + "matchingRules": { + "$.body": { + "match": "type" + } + } + } + }, + { + "providerState": "provider allows duration creation", + "description": "a request for create a duration", + "request": { + "method": "POST", + "path": "/duration", + "body": { + "duration_min": 192 + }, + "matchingRules": { + "$.body.duration_min": { + "match": "type" + } + } + }, + "response": { + "status": 201, + "body": { + "id": 42, + "duration_min": 192 + }, + "matchingRules": { + "$.body": { + "match": "type" + } + } + } + } + ], + "metadata": { + "pactSpecification": { + "version": "2.0.0" + } + } +} \ No newline at end of file diff --git a/python/Makefile b/python/Makefile index a076e6e..96a4967 100644 --- a/python/Makefile +++ b/python/Makefile @@ -15,9 +15,9 @@ movies-api-publish: $ curl -v --silent --output /dev/null --show-error --fail -XPUT \-H "Content-Type: application/json" -d@movies_api/pacts/movies-api-duration-provider-pact.json http://localhost/pacts/provider/duration-provider/consumer/movies-api/version/$(call args, $(MOVIES_API_VERSION)) movies-api-verify: - pactman-verifier -b http://localhost/ movies-api http://localhost:9001 http://localhost:9001/_pact/provider_states -a $(MOVIES_API_VERSION) -r + pytest --pact-publish-results --pact-broker-url http://localhost/ --pact-provider-name=movies-api --pact-provider-version=$(MOVIES_API_VERSION) movies_api/verify_pacts.py -v duration-provider-verify: - pactman-verifier -b http://localhost/ duration-provider http://localhost:9000 http://localhost:9000/_pact/provider_states -a $(DURATION_PROVIDER_VERSION) -r + pytest --pact-publish-results --pact-broker-url http://localhost/ --pact-provider-name=duration-provider --pact-provider-version=$(DURATION_PROVIDER_VERSION) duration_provider/verify_pacts.py -v .PHONY: movies-api-generate movies-api-publish movies-api-verify duration-provider-verify \ No newline at end of file diff --git a/python/duration_provider/verify_pacts.py b/python/duration_provider/verify_pacts.py new file mode 100644 index 0000000..ebb3290 --- /dev/null +++ b/python/duration_provider/verify_pacts.py @@ -0,0 +1,18 @@ +from pactman.verifier.verify import ProviderStateMissing +import requests + +PORT = 9000 + + +def provider_state(name, **params): + if name == "there is an existing tv show": + state = requests.post(f"http://localhost:{PORT}/_pact/setup_provider_state", json={"state": "provider allows duration creation" }) + state.raise_for_status() + else: + raise ProviderStateMissing(name) + + +def test_pacts(pact_verifier): + pact_verifier.verify(provider_setup=provider_state, provider_url=f"http://localhost:{PORT}") + + diff --git a/python/movies_api/main.py b/python/movies_api/main.py index 1550941..cb64a0b 100644 --- a/python/movies_api/main.py +++ b/python/movies_api/main.py @@ -23,7 +23,7 @@ class Movie(BaseModel): genre: str director: str year: Optional[int] = None - duration_min: Optional[int] = None + duration: Optional[int] = None # duration_min: int app = FastAPI() @@ -41,13 +41,13 @@ async def movie(movie_id: int): response = get_duration(movie_id) duration_min = response['duration_min'] - JSON_RESULT['duration_min'] = duration_min + JSON_RESULT['duration'] = duration_min return JSONResponse(content=JSON_RESULT, headers=HEADERS) @app.post("/movies") async def create_movie(movie: Movie): - post_duration(movie.duration_min) + post_duration(movie.duration) content = dict(movie) content['id'] = random.randint(1, 100) return JSONResponse(content=content, headers=HEADERS, status_code=201) diff --git a/python/movies_api/verify_pacts.py b/python/movies_api/verify_pacts.py new file mode 100644 index 0000000..aaba46e --- /dev/null +++ b/python/movies_api/verify_pacts.py @@ -0,0 +1,21 @@ +from pactman.verifier.verify import ProviderStateMissing +import requests + +PORT = 9001 + + +def provider_state(name, **params): + if name == "provider allows duration creation": + state = requests.post(f"http://localhost:{PORT}/_pact/setup_provider_state", json={ "state": "provider allows duration creation" }) + state.raise_for_status() + elif name == "Given a movie exists": + state = requests.post(f"http://localhost:{PORT}/_pact/setup_provider_state", json={ "state": "Given a movie exists" }) + state.raise_for_status() + else: + raise ProviderStateMissing(name) + + +def test_pacts(pact_verifier): + pact_verifier.verify(provider_setup=provider_state, provider_url=f"http://localhost:{PORT}") + +