diff --git a/.gitignore b/.gitignore index a437443..5aa6198 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,8 @@ __pycache__/ include/ ## Distribution files -/dist \ No newline at end of file +/dist + +# Logs and temporary files +/tmp +log \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 0e99aa5..f2ba524 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2227,9 +2227,9 @@ dependencies = [ [[package]] name = "pact-broker-cli" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b7325f4ecd43d8c7d13dd7d5ce64f4e5ca61f0085ae23fbed5d287e62d5c68" +checksum = "f55c7cd07df42619a3922cdd5246fa134aaf90ebad538030c34641b7c92a6276" dependencies = [ "anyhow", "base64 0.22.1", @@ -2448,7 +2448,7 @@ dependencies = [ [[package]] name = "pact_mock_server" version = "2.1.4" -source = "git+https://github.com/YOU54F/pact-core-mock-server.git?branch=feat%2Fcli_as_lib#fc2925f6feec4116d397dd6ac95fb4fb6e3f6ee9" +source = "git+https://github.com/YOU54F/pact-core-mock-server.git?branch=feat%2Fadd-pact-specification-option-to-cli#3c49532d0502ea508696993b7fa88724ad2f8a14" dependencies = [ "anyhow", "bytes", @@ -2481,7 +2481,7 @@ dependencies = [ [[package]] name = "pact_mock_server_cli" version = "2.0.0-beta.1" -source = "git+https://github.com/YOU54F/pact-core-mock-server.git?branch=feat%2Fcli_as_lib#fc2925f6feec4116d397dd6ac95fb4fb6e3f6ee9" +source = "git+https://github.com/YOU54F/pact-core-mock-server.git?branch=feat%2Fadd-pact-specification-option-to-cli#3c49532d0502ea508696993b7fa88724ad2f8a14" dependencies = [ "anyhow", "bytes", @@ -2694,12 +2694,12 @@ dependencies = [ [[package]] name = "pem" -version = "3.0.5" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3" +checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" dependencies = [ "base64 0.22.1", - "serde", + "serde_core", ] [[package]] @@ -4728,9 +4728,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2" +checksum = "32b130c0d2d49f8b6889abc456e795e82525204f27c42cf767cf0d7734e089b8" dependencies = [ "rustls-pki-types", ] diff --git a/Cargo.toml b/Cargo.toml index b53ac88..d985338 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,12 +26,6 @@ clap = { version = "4.5.2", features = ["derive", "env", "cargo"] } clap_complete = { version = "4.5.1", features = [] } home = "0.5.5" -# tracing = "0.1.40" -# tracing-appender = "0.2.3" -# tracing-core = "0.1.32" -# tracing-log = "0.2.0" -# tracing-subscriber = "0.3.16" - # pact-stub-server = { version = "*", path = "/Users/saf/dev/pact-foundation/pact-stub-server"} # pact_mock_server_cli = { version = "2.0.0-beta.1", path = "/Users/saf/dev/pact-foundation/pact-core-mock-server/pact_mock_server_cli"} # pact-plugin-cli = { version = "*", path = "/Users/saf/dev/pact-foundation/pact-plugins/cli"} @@ -39,10 +33,10 @@ home = "0.5.5" # pact-broker-cli = { version = "*", path = "/Users/saf/dev/pact-foundation/pact-broker-cli"} # pact-broker-cli = { version = "*", git = "https://github.com/pact-foundation/pact-broker-cli", branch = "main"} pact-stub-server = { version = "*", git = "https://github.com/YOU54F/pact-stub-server.git", branch = "feat/cli_as_lib"} -pact_mock_server_cli = { version = "2.0.0-beta.1", git = "https://github.com/YOU54F/pact-core-mock-server.git", branch = "feat/cli_as_lib"} +pact_mock_server_cli = { version = "2.0.0-beta.1", git = "https://github.com/YOU54F/pact-core-mock-server.git", branch = "feat/add-pact-specification-option-to-cli"} pact-plugin-cli = { version = "*", git = "https://github.com/pact-foundation/pact-plugins", branch = "feat/cli_as_lib"} pact_verifier_cli = { version = "*", git = "https://github.com/YOU54F/pact-reference", branch = "feat/cli_as_lib"} -pact-broker-cli = { version = "0.2.0" } +pact-broker-cli = { version = "0.2.1" } [dev-dependencies] trycmd = "0.15.0" diff --git a/examples/Gemfile b/examples/Gemfile new file mode 100644 index 0000000..a7e0c79 --- /dev/null +++ b/examples/Gemfile @@ -0,0 +1,5 @@ +source 'https://rubygems.org' + +gem 'sinatra', '>= 4.1.0' +gem 'sinatra-contrib', '>= 4.1.0' +gem 'pact-provider-verifier', '>= 1.39.1' diff --git a/examples/Gemfile.lock b/examples/Gemfile.lock new file mode 100644 index 0000000..5665211 --- /dev/null +++ b/examples/Gemfile.lock @@ -0,0 +1,136 @@ +GEM + remote: https://rubygems.org/ + specs: + awesome_print (1.9.2) + base64 (0.3.0) + diff-lcs (1.6.2) + expgen (0.1.1) + parslet + faraday (2.14.0) + faraday-net_http (>= 2.0, < 3.5) + json + logger + faraday-net_http (3.4.1) + net-http (>= 0.5.0) + faraday-retry (2.3.2) + faraday (~> 2.0) + find_a_port (1.0.1) + json (2.15.1) + jsonpath (1.1.5) + multi_json + logger (1.7.0) + multi_json (1.17.0) + mustermann (3.0.4) + ruby2_keywords (~> 0.0.1) + net-http (0.6.0) + uri + ostruct (0.6.3) + pact (1.66.2) + jsonpath (~> 1.0) + pact-mock_service (~> 3.0, >= 3.3.1) + pact-support (~> 1.21, >= 1.21.0) + rack-test (>= 0.6.3, < 3.0.0) + rainbow (~> 3.1) + rspec (~> 3.0) + string_pattern (~> 2.0) + thor (>= 0.20, < 2.0) + pact-message (0.11.1) + pact-mock_service (~> 3.1) + pact-support (~> 1.8) + thor (>= 0.20, < 2.0) + pact-mock_service (3.12.3) + find_a_port (~> 1.0.1) + json + pact-support (~> 1.16, >= 1.16.4) + rack (>= 3.0, < 4.0) + rackup (~> 2.0) + rspec (>= 2.14) + thor (>= 0.19, < 2.0) + webrick (~> 1.8) + pact-provider-verifier (1.39.1) + faraday (~> 2.5) + faraday-retry (~> 2.2) + json (> 1.8) + ostruct + pact (~> 1.59) + pact-message (~> 0.5) + rack (>= 3.0, < 4.0) + rack-reverse-proxy-pact + rackup (~> 2.0) + rspec (~> 3.5) + rspec_junit_formatter (~> 0.3) + pact-support (1.21.2) + awesome_print (~> 1.9) + diff-lcs (~> 1.5) + expgen (~> 0.1) + jsonpath (~> 1.0) + rainbow (~> 3.1.1) + string_pattern (~> 2.0) + parslet (2.0.0) + rack (3.2.3) + rack-protection (4.2.1) + base64 (>= 0.1.0) + logger (>= 1.6.0) + rack (>= 3.0.0, < 4) + rack-proxy (0.7.7) + rack + rack-reverse-proxy-pact (1.0.2) + rack (>= 3.0, < 4.0) + rack-proxy (~> 0.6, >= 0.6.1) + rackup (~> 2.0) + rack-session (2.1.1) + base64 (>= 0.1.0) + rack (>= 3.0.0) + rack-test (2.2.0) + rack (>= 1.3) + rackup (2.2.1) + rack (>= 3) + rainbow (3.1.1) + regexp_parser (2.11.3) + rspec (3.13.1) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) + rspec-core (3.13.5) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.5) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.6) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-support (3.13.6) + rspec_junit_formatter (0.6.0) + rspec-core (>= 2, < 4, != 2.12.0) + ruby2_keywords (0.0.5) + sinatra (4.2.1) + logger (>= 1.6.0) + mustermann (~> 3.0) + rack (>= 3.0.0, < 4) + rack-protection (= 4.2.1) + rack-session (>= 2.0.0, < 3) + tilt (~> 2.0) + sinatra-contrib (4.2.1) + multi_json (>= 0.0.2) + mustermann (~> 3.0) + rack-protection (= 4.2.1) + sinatra (= 4.2.1) + tilt (~> 2.0) + string_pattern (2.3.0) + regexp_parser (~> 2.5, >= 2.5.0) + thor (1.4.0) + tilt (2.6.1) + uri (1.0.4) + webrick (1.9.1) + +PLATFORMS + arm64-darwin-24 + ruby + +DEPENDENCIES + pact-provider-verifier (>= 1.39.1) + sinatra (>= 4.1.0) + sinatra-contrib (>= 4.1.0) + +BUNDLED WITH + 2.7.0 diff --git a/examples/another-they.json b/examples/another-they.json new file mode 100644 index 0000000..01396fc --- /dev/null +++ b/examples/another-they.json @@ -0,0 +1,46 @@ +{ + "consumer": { + "name": "anotherclient" + }, + "provider": { + "name": "they" + }, + "interactions": [ + { + "description": "Greeting", + "request": { + "method": "GET", + "path": "/" + }, + "response": { + "status": 200, + "headers": { + }, + "body": { + "greeting": "Hello" + } + } + }, + { + "description": "Provider state success", + "providerState": "There is a greeting", + "request": { + "method": "GET", + "path": "/somestate" + }, + "response": { + "status": 200, + "headers": { + }, + "body": { + "greeting": "State data!" + } + } + } + ], + "metadata": { + "pactSpecification": { + "version": "2.0.0" + } + } +} diff --git a/examples/api.rb b/examples/api.rb new file mode 100644 index 0000000..199defb --- /dev/null +++ b/examples/api.rb @@ -0,0 +1,33 @@ +require 'sinatra' +require 'sinatra/base' +require 'sinatra/json' +require 'json' + +state_data = "" + +get '/' do + json :greeting => 'Hello' +end + +get '/fail' do + json :greeting => 'Oh noes!' +end + +get '/provider-states' do + content_type :json + { + :me => ["There is a greeting"], + :anotherclient => ["There is a greeting"] + }.to_json +end + +post '/provider-state' do + logger.info "Provider state request: #{params}" + state_data = "State data!" + json :greeting => "State set" + status 201 +end + +get '/somestate' do + json :greeting => state_data +end diff --git a/examples/consumer-interaction.json b/examples/consumer-interaction.json new file mode 100644 index 0000000..5cb287f --- /dev/null +++ b/examples/consumer-interaction.json @@ -0,0 +1,16 @@ +{ + "description": "foo", + "request": { + "path": "/foo", + "method": "GET" + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": { + "message": "Hello world" + } + } +} diff --git a/examples/fail.json b/examples/fail.json new file mode 100644 index 0000000..8dc1490 --- /dev/null +++ b/examples/fail.json @@ -0,0 +1,61 @@ +{ + "consumer": { + "name": "me" + }, + "provider": { + "name": "they" + }, + "interactions": [ + { + "description": "Greeting", + "request": { + "method": "GET", + "path": "/" + }, + "response": { + "status": 200, + "headers": { + }, + "body": { + "greeting": "Hello" + } + } + }, + { + "description": "Greeting fail", + "request": { + "method": "GET", + "path": "/fail" + }, + "response": { + "status": 201, + "headers": { + }, + "body": { + "greeting": "Oh yes!" + } + } + }, + { + "description": "Provider state success", + "providerStates": "There is a greeting", + "request": { + "method": "GET", + "path": "/somestate" + }, + "response": { + "status": 200, + "headers": { + }, + "body": { + "greeting": "State data!" + } + } + } + ], + "metadata": { + "pactSpecification": { + "version": "2.0.0" + } + } +} diff --git a/examples/foo-bar.json b/examples/foo-bar.json new file mode 100644 index 0000000..44e95fd --- /dev/null +++ b/examples/foo-bar.json @@ -0,0 +1,31 @@ +{ + "consumer": { + "name": "Foo" + }, + "provider": { + "name": "Bar" + }, + "interactions": [ + { + "description": "foo", + "request": { + "method": "GET", + "path": "/foo" + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": { + "message": "Hello world" + } + } + } + ], + "metadata": { + "pactSpecification": { + "version": "2.0.0" + } + } +} \ No newline at end of file diff --git a/examples/me-they.json b/examples/me-they.json new file mode 100644 index 0000000..9a62745 --- /dev/null +++ b/examples/me-they.json @@ -0,0 +1,46 @@ +{ + "consumer": { + "name": "me" + }, + "provider": { + "name": "they" + }, + "interactions": [ + { + "description": "Greeting", + "request": { + "method": "GET", + "path": "/" + }, + "response": { + "status": 200, + "headers": { + }, + "body": { + "greeting": "Hello" + } + } + }, + { + "description": "Provider state success", + "providerState": "There is a greeting", + "request": { + "method": "GET", + "path": "/somestate" + }, + "response": { + "status": 200, + "headers": { + }, + "body": { + "greeting": "State data!" + } + } + } + ], + "metadata": { + "pactSpecification": { + "version": "2.0.0" + } + } +} diff --git a/examples/mock_example-ruby.sh b/examples/mock_example-ruby.sh new file mode 100755 index 0000000..72f3325 --- /dev/null +++ b/examples/mock_example-ruby.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +# BEFORE SUITE start mock service +# invoked by the pact framework +BIN=${BIN:-pact-mock-service} +$BIN service \ + --port 1234 \ + --consumer Foo \ + --provider Bar \ + --pact-specification-version 2 \ + --pact-dir ./tmp/pacts \ + --log ./tmp/bar_mock_service.log \ + --log-level DEBUG & +pid=$! + +# BEFORE SUITE wait for mock service to start up +# invoked by the pact framework +while [ "200" -ne "$(curl -H "X-Pact-Mock-Service: true" -s -o /dev/null -w "%{http_code}" localhost:1234)" ]; do sleep 0.5; done + +# uncomment this line to see the curl commands interleaved with the responses +# set -x + +# BEFORE EACH TEST clear interactions from previous test +# invoked by the pact framework +curl -X DELETE -H "X-Pact-Mock-Service: true" localhost:1234/interactions + +# BEFORE A TEST set up interaction(s) just for that test +# The contents of this would be written by the developer in the provided pact DSL for +# your language eg. mockService.given(...).uponReceiving(...). ... +# This can be called mulitple times. Alternatively PUT could be used +# with a body of `{interactions: [...]}` which would negate the need to call DELETE. +curl -X POST -H "X-Pact-Mock-Service: true" -d@examples/consumer-interaction.json localhost:1234/interactions + +# IN A TEST execute interaction(s) +# this would be done by the consumer code under test +curl localhost:1234/foo +echo '' + +# AFTER EACH TEST verify interaction(s) took place +# This would be done explicitly by the developer or automatically by the framework, +# depending on the language +curl -H "X-Pact-Mock-Service: true" localhost:1234/interactions/verification + +# AFTER SUITE +# write pact +# this would be invoked explictly by the developer or automatically framework, +# depending on the language +curl -X POST -H "X-Pact-Mock-Service: true" -H "Content-Length: 0" localhost:1234/pact + +# AFTER SUITE stop mock service +# this would be invoked by the test framework +kill -2 $pid + +while [ kill -0 $pid 2> /dev/null ]; do sleep 0.5; done + +echo '' +echo 'FYI the mock service logs are:' +cat ./tmp/bar_mock_service.log \ No newline at end of file diff --git a/examples/mock_example-rust.sh b/examples/mock_example-rust.sh new file mode 100755 index 0000000..974af4d --- /dev/null +++ b/examples/mock_example-rust.sh @@ -0,0 +1,111 @@ +#!/usr/bin/env bash + +# BEFORE SUITE start mock service +# invoked by the pact framework +BIN=${BIN:-pact} +$BIN mock start \ + --port 1234 \ + --loglevel ${LOG_LEVEL:-debug} \ + --output ./tmp \ + --base-port 8081 & +pid=$! + +# # BEFORE SUITE wait for mock service to start up +# # invoked by the pact framework +while [ "200" -ne "$(curl -s -o /dev/null -w "%{http_code}" localhost:1234)" ]; do sleep 0.5; done + +# # uncomment this line to see the curl commands interleaved with the responses +# # set -x + +# # BEFORE EACH TEST create new mock server +# # invoked by the pact framework + +# # Use cli to create mock server from pact file +mock_output=$($BIN mock create --file examples/foo-bar.json --port 1234) +# mock_output=$(pact-cli mock create --file examples/foo-bar.json --port 1234 --specification v3) +mock_id=$(echo "$mock_output" | awk '/Mock server/ {print $3}') +mock_port=$(echo "$mock_output" | awk '/Mock server/ {print $7}') +# echo "Mock server ID: $mock_id" +# echo "Mock server port: $mock_port" + + +# # BEFORE A TEST set up interaction(s) just for that test +# # The contents of this would be written by the developer in the provided pact DSL for +# # your language eg. mockService.given(...).uponReceiving(...). ... +# # This can be called mulitple times. Alternatively PUT could be used +# # with a body of `{interactions: [...]}` which would negate the need to call DELETE. +# use rest api to create mock server from pact file +# response=$(curl -s -X POST -H "Content-Type: application/json" -d @examples/foo-bar.json localhost:1234) +# mock_id=$(echo "$response" | jq -r '.mockServer.id') +# mock_port=$(echo "$response" | jq -r '.mockServer.port') +# echo "Mock server ID: $mock_id" +# echo "Mock server port: $mock_port" + +# # BEFORE SUITE wait for mock server to start up +# # invoked by the pact framework +while [ "200" -ne "$(curl -s -o /dev/null -w "%{http_code}" localhost:1234/mockserver/$mock_id)" ]; do sleep 0.5; done + +# # get details of the newly created mock server via api +# curl -s -H "Content-Type: application/json" localhost:1234/mockserver/$mock_id | jq . + +# # get info about all mock servers via cli +# # no mechanism to list details about indiv mock server via cli +# $BIN mock list --port 1234 +# # get info about all mock servers via rest api +# curl -s -H "Content-Type: application/json" localhost:1234 | jq . + + +# check the status of the mock server via api is ok +mock_server_status=$(curl -s -H "Content-Type: application/json" localhost:1234/mockserver/$mock_id) +# Extract fields from mock_server_status using jq and store in variables +mock_address=$(echo "$mock_server_status" | jq -r '.address') +mock_requests=$(echo "$mock_server_status" | jq -r '.metrics.requests') +mock_provider_name=$(echo "$mock_server_status" | jq -r '.provider') +mock_scheme=$(echo "$mock_server_status" | jq -r '.scheme') +mock_status=$(echo "$mock_server_status" | jq -r '.status') +echo "Mock server address: $mock_address" +echo "Mock server requests: $mock_requests" +echo "Mock server provider name: $mock_provider_name" +echo "Mock server scheme: $mock_scheme" +echo "Mock server status: $mock_status" + +# # IN A TEST execute interaction(s) +# # this would be done by the consumer code under test +curl $mock_scheme://$mock_address/foo +echo '' + +# # AFTER EACH TEST verify interaction(s) took place +# # This would be done explicitly by the developer or automatically by the framework, +# # depending on the language +# verify interactions took place via rest api +curl -s -X POST -H "Content-Type: application/json" localhost:1234/mockserver/$mock_id/verify | jq . + +# check the status of the mock server via api is ok +mock_server_status=$(curl -s -H "Content-Type: application/json" localhost:1234/mockserver/$mock_id) +# Extract fields from mock_server_status using jq and store in variables +mock_address=$(echo "$mock_server_status" | jq -r '.address') +mock_requests=$(echo "$mock_server_status" | jq -r '.metrics.requests') +mock_provider_name=$(echo "$mock_server_status" | jq -r '.provider') +mock_scheme=$(echo "$mock_server_status" | jq -r '.scheme') +mock_status=$(echo "$mock_server_status" | jq -r '.status') +echo "Mock server address: $mock_address" +echo "Mock server requests: $mock_requests" +echo "Mock server provider name: $mock_provider_name" +echo "Mock server scheme: $mock_scheme" +echo "Mock server status: $mock_status" + +# # use rest api to shutdown mock server by id +# curl -s -X DELETE -H "Content-Type: application/json" localhost:1234/mockserver/$mock_id +# use cli to shutdown mock server by id or port +$BIN mock shutdown --mock-server-id $mock_id --port 1234 +# $BIN mock shutdown --mock-server-port $mock_port --port 1234 + +# # AFTER SUITE stop mock service +# # this would be invoked by the test framework +kill -9 $pid + +while [ kill -0 $pid 2> /dev/null ]; do sleep 0.5; done + +# echo '' +# echo 'FYI the mock service logs are:' +# cat ./tmp/bar_mock_service.log \ No newline at end of file diff --git a/examples/stub-health-check.json b/examples/stub-health-check.json new file mode 100644 index 0000000..0233ab6 --- /dev/null +++ b/examples/stub-health-check.json @@ -0,0 +1,34 @@ +{ + "consumer": { + "name": "healthcheck-consumer" + }, + "provider": { + "name": "stub-server" + }, + "interactions": [ + { + "description": "foo", + "request": { + "method": "GET", + "path": "/healthcheck", + "headers": { + "X-Pact-Stub-Server": "true" + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": { + "ok": true + } + } + } + ], + "metadata": { + "pactSpecification": { + "version": "2.0.0" + } + } +} \ No newline at end of file diff --git a/examples/stub_example-ruby.sh b/examples/stub_example-ruby.sh new file mode 100755 index 0000000..2cee8b6 --- /dev/null +++ b/examples/stub_example-ruby.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +# BEFORE SUITE start mock service +# invoked by the pact framework +BIN=${BIN:-pact-stub-service} +$BIN examples/foo-bar.json \ + --port 1234 \ + --log ./tmp/bar_stub_service.log & +pid=$! + +# BEFORE SUITE wait for mock service to start up +# invoked by the pact framework +while [ "200" -ne "$(curl -H "X-Pact-Mock-Service: true" -s -o /dev/null -w "%{http_code}" localhost:1234)" ]; do sleep 0.5; done + +# IN A TEST execute interaction(s) +# this would be done by the consumer code under test +curl localhost:1234/foo +echo '' + + +# AFTER SUITE stop mock service +# this would be invoked by the test framework +kill -2 $pid + +while [ kill -0 $pid 2> /dev/null ]; do sleep 0.5; done + +echo '' +echo 'FYI the stub service logs are:' +cat ./tmp/bar_stub_service.log \ No newline at end of file diff --git a/examples/stub_example-rust.sh b/examples/stub_example-rust.sh new file mode 100755 index 0000000..8e9b153 --- /dev/null +++ b/examples/stub_example-rust.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +# BEFORE SUITE start mock service +# invoked by the pact framework +BIN=${BIN:-pact} +$BIN stub --file examples/foo-bar.json --file examples/stub-health-check.json --port 1234 \ + --loglevel ${LOG_LEVEL:-debug} & +pid=$! + +# BEFORE SUITE wait for mock service to start up +# invoked by the pact framework +while [ "200" -ne "$(curl -H "X-Pact-Stub-Server: true" -s -o /dev/null -w "%{http_code}" localhost:1234/healthcheck)" ]; do sleep 0.5; done + +# IN A TEST execute interaction(s) +# this would be done by the consumer code under test +curl localhost:1234/foo +echo '' + + +# AFTER SUITE stop mock service +# this would be invoked by the test framework +kill -2 $pid + +while [ kill -0 $pid 2> /dev/null ]; do sleep 0.5; done \ No newline at end of file diff --git a/examples/verifier_example-ruby.sh b/examples/verifier_example-ruby.sh new file mode 100755 index 0000000..f2106ab --- /dev/null +++ b/examples/verifier_example-ruby.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env ruby + +BIN = ENV['BIN'] || 'pact-provider-verifier' + +puts "=> Starting API" +pipe = IO.popen("ruby examples/api.rb") +sleep 2 + +puts "=> Running Pact" +puts "=> Test FAILING Pact" +res = `#{BIN} --provider-base-url http://localhost:4567 --pact-urls ./examples/fail.json --provider_states_setup_url http://localhost:4567/provider-state --provider_states_url http://localhost:4567/provider-states` +puts res + +puts "=> Test SUCCESSFUL Pact" +res = `#{BIN} --provider-base-url http://localhost:4567 --pact-urls ./examples/me-they.json,./examples/another-they.json --provider_states_setup_url http://localhost:4567/provider-state --provider_states_url http://localhost:4567/provider-states` +puts res + +puts "=> Shutting down API" +if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/ + system("taskkill /im #{pipe.pid} /f /t >nul 2>&1") +else + Process.kill 'TERM', pipe.pid +end + +puts "Test exit status: #{res}" +puts diff --git a/examples/verifier_example-rust.sh b/examples/verifier_example-rust.sh new file mode 100755 index 0000000..11e427b --- /dev/null +++ b/examples/verifier_example-rust.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env ruby + +BIN = ENV['BIN'] || 'pact-provider-verifier' + +puts "=> Starting API" +pipe = IO.popen("ruby examples/api.rb") +sleep 2 + +puts "=> Running Pact" +puts "=> Test FAILING Pact" +res = `#{BIN} verifier --hostname localhost --port 4567 --file ./examples/fail.json --state-change-url http://localhost:4567/provider-state` +puts res + +puts "=> Test SUCCESSFUL Pact" +res = `#{BIN} verifier --hostname localhost --port 4567 --file ./examples/fail.json --file ./examples/another-they.json --state-change-url http://localhost:4567/provider-state` +puts res + +puts "=> Shutting down API" +if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/ + system("taskkill /im #{pipe.pid} /f /t >nul 2>&1") +else + Process.kill 'TERM', pipe.pid +end + +puts "Test exit status: #{res}" +puts diff --git a/run.sh b/run.sh index c3d7696..ea54a3c 100755 --- a/run.sh +++ b/run.sh @@ -38,6 +38,7 @@ ${BIN} mock shutdown-master --help ${BIN} broker ruby stop || true ${BIN} broker ruby start -d + ${BIN} broker ruby info ${BIN} broker list-latest-pact-versions ${BIN} broker create-environment --name name_foo1 @@ -76,6 +77,8 @@ ${BIN} broker delete-branch --branch bar --pacticipant foo ${BIN} broker describe-pacticipant --name foo ${BIN} broker generate-uuid +./examples/mock_example-rust.sh +./examples/stub_example-rust.sh +./examples/verifier_example-rust.sh -${BIN} broker ruby stop - +${BIN} broker ruby stop \ No newline at end of file