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

Support message pacts #68

Open
richard-reece opened this issue Aug 13, 2019 · 9 comments
Open

Support message pacts #68

richard-reece opened this issue Aug 13, 2019 · 9 comments

Comments

@richard-reece
Copy link
Contributor

richard-reece commented Aug 13, 2019

Message pacts contain just the request part of a usual pact, though with renamed keys, as per the spec (note that "metaData" should be spelled "metadata".

An issue with message pacts is that there's no common transport like HTTP, so we need to provide a mechanism that can be more flexible to handle a variety of message system APIs. To that end, two components are proposed

First, a method to verify message pacts, extending the existing pytest pact_verifier fixture:
pact_verifier.verify_message(handler=handle, provider_state=provider_state)
The handler is responsible for accepting the pact structure (the JSON as a Python dict) and invoking the appropriate provider message handler function with the contents and metadata values.

This would be used like so (example shows both a stomp and AWS sqs implementation):

    sub = Mock()
    handler = NoteMessageHandler(sub)
    def handle(pact):
        handler.on_message(pact['metadata'], pact['contents'])
    pact_verifier.verify_message(handler=handle, provider_state=provider_state)
    sub.ack.assert_called_once()


def test_pact(pact_verifier, monkeypatch, patch):
    delete = monkeypatch(something_sqs, 'delete', Mock())
    def handle(pact):
        sqs_handle_messages([dict(MessageAttributes=pact['metadata'], Body=pact['contents'])])
    pact_verifier.verify_message(handler=handle, provider_state=provider_state)
    delete.assert_called_once()

The second addition is for mocking the consumer's generation of messages to capture and verify against a pact:

send_function_mock.register(
        description="Published credit data",
        providerState="or maybe 'scenario'? not sure about this",
        contents={"foo": Like("bar")},
        metadata={"contentType": "application/json"},
        transform=transform
)

This would be used like so (stomp example shown):

def MockConnection(mocker):
    mock = mocker.patch("stomp.Connection", autospec=True)
    def transform(**kwargs):
        return dict(contents=kwargs['body'], metadata=kwargs['headers'])
    mock.send = pactman.MessageMock()
    yield mock

The MockConnection fixture is then used in tests, like this:

def MockConnection(mocker):
    mock = mocker.patch("stomp.Connection", autospec=True)
    def transform(**kwargs):
        return dict(contents=kwargs['body'], metadata=kwargs['headers'])
    mock.send = pactman.MessageMock()
    yield mock

def test_sending(MockConnection):
    MockConnection.send.register(
        description="Published credit data",
        providerState="or maybe 'scenario'? not sure about this",
        contents={"foo": Like("bar")},
        metadata={"contentType": "application/json"},
        transform=transform
    )
    invoke_code_that_sends_a_message()
@richard-reece
Copy link
Contributor Author

To be clear, all the above code would appear in the pactman user's test suite. pactman only exposes those things namespaced as pactman. to use in that test suite.

@siwater
Copy link

siwater commented Sep 17, 2019

Looks interesting. Any timescale for an implementation?

@aorumbayev
Copy link

Any updates on this ?

@r1chardj0n3s
Copy link
Collaborator

I have no plans to implement this feature at this time.

@gordol
Copy link

gordol commented May 12, 2020

so, this library doesn't support v3 of the pact spec, then.

@r1chardj0n3s
Copy link
Collaborator

It doesn't support the message queue component of version 3, correct, but it does implement the rest of v3. The issue with message queue pacts is that it's never been more than a theoretical use-case for me, so it's been very difficult to approach in a concrete manner. I spit-balled some ideas at the start of this thread, but I honestly have no idea whether they'd be useful or appropriate.

I welcome contributions from people with active interest in message pacts.

@campellcl
Copy link

campellcl commented Oct 21, 2020

The issue with message queue pacts is that it's never been more than a theoretical use-case for me, so it's been very difficult to approach in a concrete manner. I spit-balled some ideas at the start of this thread, but I honestly have no idea whether they'd be useful or appropriate.

@r1chardj0n3s I believe they would be useful. Particularly in the Severless context as shown here in the pact-foundation repo. This is definitely no longer purely theoretical, as Serverless and IaaS is on the rise.

I need to get a better grasp of the core lib before I could personally contribute anything of worth. But this feature would definitely be welcome, as we have other devs using pact-foundation's pact-js implementation which does support Message Pacts. I was looking at using Pactman over pact-foundation/pact-python. This would mean I would need to handle the interoperability between the two pact types by modifying the pact file itself in order to use Pactman's standard Pacts in conjunction with pact-foundation/pact-js's Message Pacts.

To be fair, pact-foundation/pact-python doesn't yet support Message Pacts either. But if you beat them to it, it would be just another reason (in a steadily growing list) to prefer Pactman to pact-foundation/pact-python!

@campellcl
Copy link

campellcl commented Oct 21, 2020

so, this library doesn't support v3 of the pact spec, then.

@r1chardj0n3s Maybe update the README to clarify that what the pact-foundation devs refer to as "Message Pacts" is not yet supported in the Pactman version 3 implementation of the pact-specification?

Although @gordol to be fair, the pact-foundation devs do not yet support v3 in pact-foundation/pact-python either.

But @r1chardj0n3s the pact-foundation/pact-python devs only claim to support version 2 of the pact specification, and do not claim to support version 3 yet. I agree with @gordol that it is a bit of a misnomer to claim support for version 3 without "Message Pacts" given that the version 3 pact specification clearly implies support for message queues (e.g. "Message Pacts").

@r1chardj0n3s
Copy link
Collaborator

@campellcl I look forward to seeing a contribution from you! I have no current need for pact at present, and having someone with a direct need working on the code would be great :)

rDarge added a commit to rDarge/docs.pact.io that referenced this issue Dec 13, 2023
One of the main changes in pact v3 was the addition of the message queue format; users should be informed as soon as possible that Pactman is not a viable solution for validating message queue pacts, rather than wading through github issues like I had to do. 

reecetech/pactman#68
rDarge added a commit to rDarge/docs.pact.io that referenced this issue Dec 13, 2023
One of the main changes in pact v3 was the addition of the message queue format; users should be informed as soon as possible that Pactman is not a viable solution for validating message queue pacts, rather than wading through github issues like I had to do. 

reecetech/pactman#68
bethesque pushed a commit to pact-foundation/docs.pact.io that referenced this issue Dec 20, 2023
One of the main changes in pact v3 was the addition of the message queue format; users should be informed as soon as possible that Pactman is not a viable solution for validating message queue pacts, rather than wading through github issues like I had to do. 

reecetech/pactman#68
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

6 participants