pact-foundation / pact-python

Python version of Pact. Enables consumer driven contract testing, providing a mock service and DSL for the consumer project, and interaction playback and verification for the service provider project.
http://pact.io
MIT License
578 stars 137 forks source link

iso_8601_datetime matcher does not work on Windows #850

Open azosramonsaraiva opened 3 weeks ago

azosramonsaraiva commented 3 weeks ago

Have you read the Contributing Guidelines on issues?

Prerequisites

Description

When using MessageConsumer and attempting to set an iso_8601_datetime matcher, the pact file generation fails on Windows. This issue does not occur on Linux, where it works as expected.

Reproducible demo

No response

Steps to reproduce

Run this script on windows:

# consumer.py
from pact import MessageConsumer, Provider, matchers

# Função principal do consumer
def run_consumer():
    # Define o contrato do consumer
    contract = MessageConsumer(
        "my_contract Consumer"
    ).has_pact_with(
        Provider("my_contract Provider"),
        pact_dir="pacts",
    )

    # Define os dados do evento
    event_data = {
        "invoice_id": "12345",
        "amount": 100.00,
        "currency": "USD",
        "created": matchers.Format().iso_8601_datetime(),
    }

    # Cria uma mensagem que representa o evento
    contract.given("Create contract").expects_to_receive(
        "An event of contract").with_content(event_data)

    with contract:
        pass

if __name__ == "__main__":
    run_consumer()

Please note that the file will not be generated.

If you set a breakpoint on message_pact.py, line 193, you can observe that the issue occurs during: json.dumps(self._messages[0]), image

It seems to be something related with regex and json dumps Remember: it only happens on windows

Expected behavior

The file must be generated on windows

Actual behavior

If matchers.Format().iso_8601_datetime() is used, the local pact file is not being generated on windows

Your environment

Windows 11

Self-service

JP-Ellis commented 3 weeks ago

Thanks for the bug report and for including an example!

Could you please let me know which version of Python you are using? And just to (re)confirm, you are using the latest version of Pact Python?

azosramonsaraiva commented 2 weeks ago

Thanks for the bug report and for including an example!

Could you please let me know which version of Python you are using? And just to (re)confirm, you are using the latest version of Pact Python?

yes. Python 3.11 using venv and pact-python 2.2.2

The same problem happens using python 3.10 with conda as env

I have tested with diff venv because I was thinkg that could be something related to virtual env. But does not seems to be

JP-Ellis commented 2 weeks ago

Given this is a Windows-specific issue, can you please help me out and double check the output of the following:

from datetime import datetime, timezone

print(datetime.now(tz=timezone.utc).isoformat())

or as a console one-liner:

python -c "from datetime import datetime, timezone; print(datetime.now(tz=timezone.utc).isoformat())"
azosramonsaraiva commented 2 weeks ago

output: 2024-11-07T11:53:44.748496+00:00

JP-Ellis commented 2 weeks ago

I am able to replicate your issue, but can't fix it at this stage (though I will keep trying for a bit).

Is there any chance you can use the Pact Python v3 interface (form the pact.v3 module)? It should have much better support for message pacts.


So my investigation ultimately uncovered the issue to be due to the use of spaces in both the consumer and providers. It is unclear to me why this works on Linux/macOS and not Windows. Most likely, this is actually an issue with the underlying pact-message Ruby executable.

As such, I suspect this won't be fixed in V2; however, I have added warnings into Pact to catch this.

Can you please confirm that the space in the name is the issue? Once confirmed, I'll merge #858 and close this issue.

azosramonsaraiva commented 2 weeks ago

Hey @JP-Ellis , ok. I will use v3.

I have tried remove the space at MessageConsumer name, but the issue still happens. So I am not able to confirm it for you

JP-Ellis commented 2 weeks ago

So I updated the test in #858 to specifically incorporate the behaviour you are seeing:

https://github.com/pact-foundation/pact-python/blob/da3c9d4e633b9a58f1ef0397e4b99dafa2e243ab/tests/test_issue.py#L13-L44

And the CI tests succeeded on all platforms, indicating that the Pact JSON file was created on the Linux and macOS runners, and failed to be created on the Windows runner.

Can you make sure that both consumer and provider names have no spaces?

As far as I can tell, the issue is unrelated to the ISO 8601 datetime matchers.

azosramonsaraiva commented 2 weeks ago

Hey @JP-Ellis, unfortunately, at least in my env, removing the space from provider and consumer name did not solved the issue

as you can see my contract image

and the debug: image

JP-Ellis commented 2 weeks ago

The screenshot shows that you are interrupting the Python process during the invocation of the underlying pact-message executable, and I can't quite tell whether the file should have been written or not. I also don't see any error messages that would indicate what's going.

Your original question was specifically about he ISO 8601 matcher; can you confirm that this is the culprit? I do see that your URL decoded window shows a datetime which is not ISO 8601 compliant; however I do not know where this window comes from. Pycharm may be using its own formatting to display variables during a debug session.

Are you able to provide any debug logs? Or better yet, are you able to adapt the example I made in #858 to replicate your issue?

So in summary, to try and pinpoint what's going on:

  1. Can you confirm that remove the ISO 8601 matcher works for you (as implied by the original question)?
  2. Can you adapt the test in #858 to replicate the issue you are having?
  3. Can you provide some debug logs?
JP-Ellis commented 5 days ago

@azosramonsaraiva Where you able to test out any of the pointers I suggested in my previous post? Without being able to replicate your exact issue, it is difficult for me to help out.

azosramonsaraiva commented 1 day ago

@JP-Ellis About question 1 - As implied by the original question. I am sending a video attch.

  1. For now I will try to adapt the test in https://github.com/pact-foundation/pact-python/pull/858 for this issue

https://github.com/user-attachments/assets/bd40f192-b156-4c9f-96d5-0969ded3f684

JP-Ellis commented 1 day ago

Wow awesome thanks for the video! That is such strange behaviour!

The network path not found error looks like an underlying OS issue, which makes it very confusing as to why the ISO 8601 matcher would cause an issue. I'll spin up a virtual Windows machine to see if I can replicate it.

Just to double check one other thing, what happens if you run the script from the terminal (as opposed to your IDE's 'run' button)? E.g.:

python consumer.py

Do you will have the same issue with the ISO 8601 matcher? And does it go away when the ISO 8601 matcher is removed? My small hypothesis being tested here is whether PyCharm is injecting anything at runtime (e.g., for debugging).