Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Versions after 1.60.0 do not produce message pacts with providerStates populated #43

Closed
2 tasks done
cfmack opened this issue Jan 15, 2020 · 6 comments
Closed
2 tasks done

Comments

@cfmack
Copy link

cfmack commented Jan 15, 2020

Pre issue-raising checklist

I have already (please mark the applicable with an x):

  • Upgraded to the latest version of the relevant libraries
  • Checked to see if the issue has already been raised
  • [] Created an executable example that demonstrates the issue using either:

I hope I can make a better example in this ticket.

Software versions

  • pact library: pact-php latest
  • pact-ruby-standalone: 1.60
  • OS: Windows, Linux, and Mac. See PR, Linux, Windows

Expected behaviour

This was working with standalone version 1.54.4 and up to 1.60.0. It seems that 1.61.0 broke the functionality. In this case, when I run my consumer tests, 1.60.0 produces a Pact providerStates in the message object.

{
	      "description": "an alligator named Mary exists",
	      "providerStates": [
	        {
	          "name": "a hello message"
	        }
	      ],
	      "contents": {
	        "text": "Hello Mary"
	      },
	      "matchingRules": {
	        "body": {
	        }
	      },
	      "metaData": {
	        "queue": "wind cries",
	        "routing_key": "wind cries"
	      }
	    }

With this message pact, the provider correctly validates the state/pact.

Actual behaviour

In version 1.61.0 to 1.74.0, when running the message consumer produces the following pact w/o providerStates populated.

{	
	      "description": "an alligator named Mary exists",	
	      "providerStates": [	
		
		
		
	      ],	
	      "contents": {	
	        "text": "Hello Mary"	
	      },	
	      "matchingRules": {	
	        "body": {	
	        }	
	      },	
	      "metaData": {	
	        "queue": "wind cries",	
	        "routing_key": "wind cries"	
	      }	
	    }

So something appears to have happened between 1.60.0 and 1.61.0. I confirmed this is still broken in 1.74.0

Steps to reproduce

You are going to hate this. I hope @cwdt might be able to help.

  1. Install PHP :)
  2. git clone https://github.com/pact-foundation/pact-php.git
  3. composer update
  4. php ./vendor/phpunit/phpunit/phpunit --debug -c example/phpunit.message.consumer.xml
  5. php ./vendor/phpunit/phpunit/phpunit --debug -c example/phpunit.message.provider.xml (passing)
  6. cp example/output/test_consumer-test_provider.json example/output/test_consumer-test_provider-WORKING.json
  7. vi src/PhpPact/Standalone/Installer/Service/InstallerLinux.php
  8. Edit file to replace const VERSION = '1.54.4'; with const VERSION = '1.74.0';
  9. rm -Rf pact
  10. rm example/output/test_consumer-test_provider.json
  11. php ./vendor/phpunit/phpunit/phpunit --debug -c example/phpunit.message.consumer.xml
  12. php ./vendor/phpunit/phpunit/phpunit --debug -c example/phpunit.message.provider.xml (
    failing)
  13. diff example/output/test_consumer-test_provider.json example/output/test_consumer-test_provider-WORKING.json
@cfmack
Copy link
Author

cfmack commented Jan 15, 2020

Below is the logs that I could find but I want to highlight what I find as the relevant logs.

--- 1.60.0
D, [2020-01-14T21:58:16.621852 #6957] DEBUG -- : body :{"description":"an alligator named Mary exists","providerStates":[{"name":"a hello message","params":{}}]}

-- 1.74.0
D, [2020-01-14T22:00:17.281668 #7045] DEBUG -- : body :{"description":"an alligator named Mary exists","providerStates":[{"name":null,"params":{}}]}

Complete Log

-- 1.60.0
I, [2020-01-14T21:58:16.620673 #6957]  INFO -- : Running example 'Verifying a pact between test_consumer and test_provider Given a hello message an alligator named Mary exists has matching content'
I, [2020-01-14T21:58:16.621597 #6957]  INFO -- : Sending POST request to path: "/" with headers: {"CONTENT_TYPE"=>"application/json", "HTTP_X_PACT_ORIGINAL_HEADER_NAMES"=>"Content-Type", "X_PACT_PROVIDER_STATES"=>[{"name"=>"a hello message"}]}, see debug logs for body
D, [2020-01-14T21:58:16.621852 #6957] DEBUG -- : body :{"description":"an alligator named Mary exists","providerStates":[{"name":"a hello message","params":{}}]}
I, [2020-01-14T21:58:16.678660 #6957]  INFO -- : Received response with status: 200, headers: {"Content-Length"=>"63", "Content-Type"=>"application/json;", "Connection"=>"keep-alive", "Keep-Alive"=>"timeout=15", "Date"=>"Wed, 15 Jan 2020 03:58:16 GMT"}, see debug logs for body
D, [2020-01-14T21:58:16.678858 #6957] DEBUG -- : body: {"metadata":{"queue":"myKey"},"contents":{"text":"Hello Mary"}}
I, [2020-01-14T21:58:16.681570 #6957]  INFO -- : Running example 'Verifying a pact between test_consumer and test_provider Given You can hear happiness staggering on down the street footprints dressed in red has matching content'
I, [2020-01-14T21:58:16.682323 #6957]  INFO -- : Sending POST request to path: "/" with headers: {"CONTENT_TYPE"=>"application/json", "HTTP_X_PACT_ORIGINAL_HEADER_NAMES"=>"Content-Type", "X_PACT_PROVIDER_STATES"=>[{"name"=>"You can hear happiness staggering on down the street"}]}, see debug logs for body
D, [2020-01-14T21:58:16.682558 #6957] DEBUG -- : body :{"description":"footprints dressed in red","providerStates":[{"name":"You can hear happiness staggering on down the street","params":{}}]}
I, [2020-01-14T21:58:16.687819 #6957]  INFO -- : Received response with status: 200, headers: {"Content-Length"=>"79", "Content-Type"=>"application/json;", "Connection"=>"keep-alive", "Keep-Alive"=>"timeout=15", "Date"=>"Wed, 15 Jan 2020 03:58:16 GMT"}, see debug logs for body
D, [2020-01-14T21:58:16.687997 #6957] DEBUG -- : body: {"metadata":{"queue":"myKey"},"contents":{"song":"And the wind whispers Mary"}}

-- 1.74.0
I, [2020-01-14T22:00:17.280584 #7045]  INFO -- : Running example 'Verifying a pact between test_consumer and test_provider An alligator named mary exists has matching content'
I, [2020-01-14T22:00:17.281417 #7045]  INFO -- : Sending POST request to path: "/" with headers: {"CONTENT_TYPE"=>"application/json", "HTTP_X_PACT_ORIGINAL_HEADER_NAMES"=>"Content-Type"}, see debug logs for body
D, [2020-01-14T22:00:17.281668 #7045] DEBUG -- : body :{"description":"an alligator named Mary exists","providerStates":[{"name":null,"params":{}}]}
I, [2020-01-14T22:00:17.384426 #7045]  INFO -- : Received response with status: 500, headers: {"Content-Length"=>"2478", "Content-Type"=>"text/html; charset=utf-8", "Connection"=>"keep-alive", "Keep-Alive"=>"timeout=15", "Date"=>"Wed, 15 Jan 2020 04:00:16 GMT"}, see debug logs for body
D, [2020-01-14T22:00:17.384678 #7045] DEBUG -- : body: <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Error 500</title>
    <style>
        body, html {
            margin: 0;
            padding: 0;
            background: #eee;
            font-family: monospace;
            display: flex;
            align-items: center;
            justify-content: center;
            height: 100vh;
        }

        .box {
            margin: 30px;
            background: #fff;
            border-radius: 3px;
            padding: 20px 30px;
            max-width: 600px;
            flex-grow: 1;
            font-size: 14px;
            color: #333;
            margin: 0 auto; /* if there's no flex */
            box-shadow: 0 2px 6px rgba(0,0,0,.1);
        }

        h1 {
            color: #111;
            font-size: 20px;
            /* border-bottom: 2px solid #08e; */
            padding: 0 0 0 0;
            margin: 10px 0 8px 0;
        }

        ul {
            padding: 0 0 0 10px;
        }

        li {
            list-style-type: none;
        }

        li::before {
            content: '- ';
        }

        button {
            box-sizing: content-box;
            width: 100%;
            display: block;
            background: #48e;
            color: #fff;
            border-radius: 0 0 2px 2px;
            border: 0;
            padding: 15px 30px;
            margin: 20px -30px -20px -30px;
            font-weight: bold;
            font-family: monospace;
            box-shadow: 0 2px 4px rgba(0,0,0,.2) inset;
        }

        button:hover {
            background: #37d;
        }

        button:focus {
            outline: 0;
        }

        button:focus:not(:hover) {
            outline: 0;
            border: 2px solid #25d;
            padding: 13px 28px;
        }

        button:active {
            outline: 0;
            box-shadow: 0 0 6px rgba(0,0,0,.3) inset;
            border: 0;
            padding: 15px 30px;
        }
    </style>
</head>
<body>
    <div class="box">
        <header>
            <h1>Error 500</h1>
        </header>
        <main>
            <p>Internal Server Error</p>
            <ul>
                <li>Try again later.</li>
                <li>Check if you visited the correct URL.</li>
                <li>Report this issue if you think this is a mistake.</li>
            </ul>
            <button type="button" onclick="window.location.reload()">Retry</button>
        </main>
    </div>
</body>
</html>

I, [2020-01-14T22:00:17.391845 #7045]  INFO -- : Running example 'Verifying a pact between test_consumer and test_provider Footprints dressed in red has matching content'
I, [2020-01-14T22:00:17.392629 #7045]  INFO -- : Sending POST request to path: "/" with headers: {"CONTENT_TYPE"=>"application/json", "HTTP_X_PACT_ORIGINAL_HEADER_NAMES"=>"Content-Type"}, see debug logs for body
D, [2020-01-14T22:00:17.396870 #7045] DEBUG -- : body :{"description":"footprints dressed in red","providerStates":[{"name":null,"params":{}}]}
I, [2020-01-14T22:00:17.421544 #7045]  INFO -- : Received response with status: 500, headers: {"Content-Length"=>"2478", "Content-Type"=>"text/html; charset=utf-8", "Connection"=>"keep-alive", "Keep-Alive"=>"timeout=15", "Date"=>"Wed, 15 Jan 2020 04:00:16 GMT"}, see debug logs for body
D, [2020-01-14T22:00:17.421770 #7045] DEBUG -- : body: <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Error 500</title>
    <style>
        body, html {
            margin: 0;
            padding: 0;
            background: #eee;
            font-family: monospace;
            display: flex;
            align-items: center;
            justify-content: center;
            height: 100vh;
        }

        .box {
            margin: 30px;
            background: #fff;
            border-radius: 3px;
            padding: 20px 30px;
            max-width: 600px;
            flex-grow: 1;
            font-size: 14px;
            color: #333;
            margin: 0 auto; /* if there's no flex */
            box-shadow: 0 2px 6px rgba(0,0,0,.1);
        }

        h1 {
            color: #111;
            font-size: 20px;
            /* border-bottom: 2px solid #08e; */
            padding: 0 0 0 0;
            margin: 10px 0 8px 0;
        }

        ul {
            padding: 0 0 0 10px;
        }

        li {
            list-style-type: none;
        }

        li::before {
            content: '- ';
        }

        button {
            box-sizing: content-box;
            width: 100%;
            display: block;
            background: #48e;
            color: #fff;
            border-radius: 0 0 2px 2px;
            border: 0;
            padding: 15px 30px;
            margin: 20px -30px -20px -30px;
            font-weight: bold;
            font-family: monospace;
            box-shadow: 0 2px 4px rgba(0,0,0,.2) inset;
        }

        button:hover {
            background: #37d;
        }

        button:focus {
            outline: 0;
        }

        button:focus:not(:hover) {
            outline: 0;
            border: 2px solid #25d;
            padding: 13px 28px;
        }

        button:active {
            outline: 0;
            box-shadow: 0 0 6px rgba(0,0,0,.3) inset;
            border: 0;
            padding: 15px 30px;
        }
    </style>
</head>
<body>
    <div class="box">
        <header>
            <h1>Error 500</h1>
        </header>
        <main>
            <p>Internal Server Error</p>
            <ul>
                <li>Try again later.</li>
                <li>Check if you visited the correct URL.</li>
                <li>Report this issue if you think this is a mistake.</li>
            </ul>
            <button type="button" onclick="window.location.reload()">Retry</button>
        </main>
    </div>
</body>
</html>

@cwdt
Copy link

cwdt commented Jan 15, 2020

I created a fork of the pact-ruby-standalone-e2e-example repository and created two branches that show the difference between the last working version (1.60.0) and the latest version (1.74.0).

Reproduction scenario:

  • Clone https://github.com/cwdt/pact-ruby-standalone-e2e-example
  • Checkout branch message-1.60.0
  • Run ./script/install.sh
  • Run ./script/consumer-update-message-pact.sh
  • Inspect output/test_consumer-test_provider.json, this is including the provider state
  • Checkout branch message-1.74.0
  • Run ./script/install.sh
  • Run ./script/consumer-update-message-pact.sh
  • Inspect output/test_consumer-test_provider.json, this is missing the provider state

You could also inspect the difference in the output looking at this diff: https://github.com/cwdt/pact-ruby-standalone-e2e-example/compare/message-1.60.0...cwdt:message-1.74.0?expand=1

@bethesque
Copy link
Member

This is a bug report of such beauty it makes me weep a little tear. Thank you!

@bethesque
Copy link
Member

bethesque commented Jan 16, 2020

Ok, so technically v2 does not support message pact, and providerState is a v2 key. The code was in kind of weird state when I first wrote the message stuff, because the Ruby impl still doesn't fully support v3 (time!) and so I was working with what I had. The key to use in v3 is providerStates, and it's an array of hashes, where each hash has a String name and a Hash of params.

"providerStates": [
        {
          "name": "an alligator named Mary exists",
          "params" : { "foo": "bar" }
        }
      ],

If you update the php code to use this format, you should be hunky dory. I'm sorry that the code changed under your feet - I usually make sure everything is backwards compatible, even if it's not "to spec".

@cfmack
Copy link
Author

cfmack commented Jan 16, 2020

Thanks! I'll take a stab at that. I am secretly pretty pleased on of the PHP tests caught the change!

@bethesque
Copy link
Member

Closing as we've worked out the cause.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants