This looks like an older version of the swift libr...
# pact-swift
m
This looks like an older version of the swift library that uses the Ruby “core”. There should be some logs somewhere (or you should be able to enable them), could you please share those? Did the test ever work or are these new tests? What OS are you on?
☝️ 1
v
Hi Matt, Do you know how to enable the logs? I'm a beginner in Swift language, once I have them, for sure I could share them. The test is new, so there are no previous records. I'm using MacOs Sonoma 14.5
I've just found these logs, hope they might help
There is another log package, hope they'll help 😉
m
I think these are the swift logs
💯 1
When you start the mock service, it’s the
--log
flag - wherever that is set the logs should be
v
I checked your suggestion and there is no logs generated on
/tmp
folder nor pact interactions file too. I also verify the
SRCROOT
variable and it is proper. Finally, I got the standalone pact bin value from the value of
which pact-mock-service
i don't understand what is going wrong :s
For instance, here is the Pre-actions script
Copy code
PATH=/opt/homebrew/bin/pact-mock-service:$PATH
pact-mock-service start --pact-specification-version 2.0.0 --log "${SRCROOT}/tmp/pact.log" --pact-dir "${SRCROOT}/tmp/pacts" -p 1234
m
it’s not in the
/tmp
directory, it’s in a directory inside your project.
e.g.
/path/to/swift/project/tmp
I think
But if there is no log, perhaps it’s not starting the mock service
try and execute that command - does it work?
v
Yes, indeed. I meant
/path/to/swift/project/tmp
My bad
I executed the command and I got this:
Copy code
mock WARN: Please note: we are tracking events anonymously to gather important usage statistics like Pact-Ruby version and operating system. To disable tracking, set the 'PACT_DO_NOT_TRACK' environment variable to 'true'.
INFO  WEBrick 1.8.1
INFO  ruby 3.3.3 (2024-06-12) [arm64-darwin22]
INFO  WEBrick::HTTPServer#start: pid=5982 port=1234
I also got an empty
pact.log
file, and a
mock-service-1234.pid
file with
5982
content.
After that, I ran a test, and I got the following error:
Copy code
ERROR -- : Error ocurred in mock service: NoMethodError - undefined method `empty?' for an instance of Pact::ArrayLike
ERROR -- : /opt/homebrew/Cellar/pact-ruby-standalone/2.4.6/lib/vendor/ruby/3.3.0/gems/pact-support-1.20.0/lib/pact/consumer_contract/query_string.rb:42:in `empty?'
m
Probably need to see your test setup. Is this a new project or an old one? There is a newer library you may want to consider using instead
(see the channel desc)
v
It is a new one. Regarding to the new library, I was verifying that, but my backend its build in python, and it seems to not to be supported in PactSwift Library
m
what’s not supported about it? It should be, as long as PactSwift can serialise a V2 pact it should be fine
v
It is not supported (We assumed that for some issues with Pact JS v3 and PactPython v2) Because they have different specification version. Python doesn't have v3. Do you have an example of that serialization? We tried to install PactSwift as suggested, but we are having the following error:
Copy code
failed - Failed to verify Pact! Actual request does not match expected interactions...
Reason:
	Missing request
....
_NSURLErrorRelatedURLSessionTaskErrorKey=(
  "LocalDataTask <3DE3D57F-F4A8-4BC6-AC99-DC7B106F80D0>.<1>"
), NSLocalizedDescription=Could not connect to the server., NSErrorFailingURLStringKey=<http://127.0.0.1:4034/calculator?amount=5000.0&location=bogota&paymentMethod=&tip=0.15&vat=0.19>, NSErrorFailingURLKey=<http://127.0.0.1:4034/calculator?amount=5000.0&location=bogota&paymentMethod=&tip=0.15&vat=0.19>, _kCFStreamErrorDomainKey=1}
There are no logs generated :S
m
@Marko (IttyBittyApps / pact-swift) is there a way users can specify the pact spec version to serialise to?
m
No, not when using PactSwift v1.x. I have a huge refactor (pretty much the whole thing is pushed down into the
pact_ffi
layer) sitting on a branch where it can be defined when instantiating the service. But, have absolutely no time to clean it up and make it RC. But that doesn't seem to be the problem here. It's the Swift's API client implementation that's throwing the error because it's failing to make the request outside the consumer implementation for some reason. If it would have managed to hit
pact_ffi
and there was an error on the mocked provider, the error would definitely not be a
_NS
error.
pact-consumer-swift
relies on its own API client implementation that makes the request to
pact-ruby-standalone
. Apple made some changes to how Swift's networking works and we figured using
127.0.0.1
was a workaround. I'm quite sure I've never had to use anything else than
<https://localhost>
when using
PactSwift
. There's logs that can be enabled by setting
PACT_ENABLE_LOGGING=all
. I assume it's an Xcode project and not a library/executable in a Swift package?
👍 1
If you're stuck on a provider that can only support Pact spec v2, then your best bet right now is to use
pact-consumer-swift
(for now, until I magically come up with extra time in a day and energy to get through it). This: https://pact-foundation.slack.com/archives/C9VBGNT4K/p1721338177462059?thread_ts=1721083156.996839&amp;cid=C9VBGNT4K is a Ruby issue. Something in
pact-ruby-server
or
pact-ruby-standalone
isn't quite right.
v
I enabled logging as suggested. Here the results:
Copy code
PactSwift: Setting up pact test: {"provider": ...."consumer":{"name":"Example-app-for-testing"}}
...
PactSwift: Setting up pact mock server for consumer verification: {"interactions" .. "consumer":{"name":"Example-app-for-testing"},"metadata":{"pactSpecification":{"version":"3.0.0"},"pactSwift":{"version":"1.1.0"}}}
..
PactSwift: Starting up mock server for pact interaction test:
..
PactSwift: Mock server started on port 4842:
..
failed - Failed to verify Pact! Actual request does not match expected interactions...

Reason:
	Missing request

Expected:
	GET /calculator

...
PactSwift: Shutting down mock server on port 4842:
PactSwift: Shutting down mock server on port 4842:
...
nw_socket_handle_socket_event [C1:2] Socket SO_ERROR [61: Connection refused]
Task <5E1EEB49-A516-4A65-9FB1-15DCE4D9EC3A>.<1> HTTP load failed, 0/0 bytes (error code: -1004 [1:61])
Task <5E1EEB49-A516-4A65-9FB1-15DCE4D9EC3A>.<1> finished with error [-1004] Error Domain=NSURLErrorDomain Code=-1004 "Could not connect to the server."
...
_NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <5E1EEB49-A516-4A65-9FB1-15DCE4D9EC3A>.<1>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
  "LocalDataTask <5E1EEB49-A516-4A65-9FB1-15DCE4D9EC3A>.<1>"
), NSLocalizedDescription=Could not connect to the server., NSErrorFailingURLStringKey=<http://127.0.0.1:4842/calculator?amount=5000.0&location=bogota&paymentMethod=&tip=0.15&vat=0.19>, NSErrorFailingURLKey=<http://127.0.0.1:4842/calculator?amount=5000.0&location=bogota&paymentMethod=&tip=0.15&vat=0.19>, _kCFStreamErrorDomainKey=1}
m
Yep, your API client is not sending the
GET /calculator
request successfully to the right address. Your Swift code implementing your API client is faulty. What's the transport protocol you've set up for mock service? Are you sure you want to use http and not https? Change the domain back to
localhost
? What's the `URLSession`'s response when debugging?
m
But that doesn’t seem to be the problem here.
the problem is that Vladimir has to verify the contracts with a language that doesn’t supportn spec v3 or greater, so if they could set the spec version to 2 it would resolve that issue. As they can’t, then he needs to go back to the previous library and we need to look at the test setup as per https://pact-foundation.slack.com/archives/C9VBGNT4K/p1721340247509179?thread_ts=1721083156.996839&amp;cid=C9VBGNT4K to find out why it’s not working. I think something is being set on the query string that’s incorrect, but I can’t see without the code
☝️ 1
m
Yep,
Copy code
ERROR -- : Error ocurred in mock service: NoMethodError - undefined method `empty?' for an instance of Pact::ArrayLike
ERROR -- : /opt/homebrew/Cellar/pact-ruby-standalone/2.4.6/lib/vendor/ruby/3.3.0/gems/pact-support-1.20.0/lib/pact/consumer_contract/query_string.rb:42:in `empty?'
I've given up on keeping up to date with
pact-swift-standalone
when homebrew formula was transferred to
pact-foundation
🤷
who do we know that can decrypt ruby errors? thinking2
m
it should be easy to debug once we see what value is being put into the query string.
nod hmm yes 1
v
Hi guys, thanks for your help. Here is the request that I have using PactSwift
Copy code
.withRequest(
        method: .GET,
        path: "/calculator",
        query: [
          "amount": [Matcher.SomethingLike(5000.0)],
          "vat": [Matcher.SomethingLike(0.19)],
          "tip": [Matcher.SomethingLike(0.15)],
          "location": [Matcher.SomethingLike("bogota")],
          "paymentMethod": [Matcher.SomethingLike("")]
        ]
      )
It is important to say that amount, vat and tip are Double into our backend
👍 1
m
In PactSwift, there's heaps of specific matcher types you can use. What's the result if you remove
paymentMethod
as a required query value? And... and if I remember right,
.withRequest
doesn't really support matchers. Also, you are (should be) in complete control of the request so you should be able to set the
.withRequest
without matchers.
maybe matchers used in request suffer from the same issue as generators? https://github.com/surpher/PactSwift/issues/104
m
btw you can verify v3 or greater pacts with the new Python verifier: https://github.com/pact-foundation/pact-python/blob/master/src/pact/v3/verifier.py
🙌🏻 1
👍 1
v
Thank you Matt!
I delete matchers and the query param as suggested. The error still the same. Additionally, I have this pop up sometimes.
I always allow, btw 😉
m
That's just the firewall being annoying. Use the script above to exempt it.
🙌🏻 1
I see you're running an
ExampleAppForTesting
project. Any chance of sharing this project? Maybe through a private repo and allowing me access to it? First remove any sensitive info if present, obviously. It's a bit hard to debug through slack messages.
v
I understand. Please let me ask into my organization and perform the changes to share the project
Thanks Marko
m
If you checked any of the demo projects you can see there's really only the API client in the implementation (no ui or anything) and tests that use that API client to make the request. That should be enough.