Hi !! I am trying to run a provider verification ...
# libpact_ffi-users
p
Hi !! I am trying to run a provider verification using ffi lib, but it seems its unable to send the request to (http://localhost:8080/test_weather/generate_weather) verify the message pact : Code snippet:
Copy code
struct VerifierHandle *verifierhandle;
    verifierhandle = pactffi_verifier_new_for_application(name, version);
    pactffi_verifier_set_provider_info(verifierhandle, name, scheme, host, port, path);
    pactffi_verifier_add_provider_transport(verifierhandle, protocol, port, path, scheme);
    pactffi_verifier_set_publish_options(verifierhandle, version, NULL, NULL, -1, branch);
    pactffi_verifier_add_directory_source(verifierhandle, file_path);
    int output = pactffi_verifier_execute(verifierhandle);
    pactffi_verifier_shutdown(verifierhandle);
Here are the debug lvl logs attached
Copy code
2024-03-17T20:22:21.013948Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: Path = $    
2024-03-17T20:22:21.014020Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: Configuring a normal object    
2024-03-17T20:22:21.014407Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: Path = $.timestamp    
2024-03-17T20:22:21.014430Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: detected pact:matcher:type, will configure a matcher    
2024-03-17T20:22:21.014513Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: Path = $.weather    
2024-03-17T20:22:21.014527Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: Configuring a normal object    
2024-03-17T20:22:21.014541Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: Path = $.weather.humidity    
2024-03-17T20:22:21.014553Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: detected pact:matcher:type, will configure a matcher    
2024-03-17T20:22:21.014575Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: Path = $.weather.temperature    
2024-03-17T20:22:21.014588Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: detected pact:matcher:type, will configure a matcher    
2024-03-17T20:22:21.014614Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: Path = $.weather.wind_speed_kmh    
2024-03-17T20:22:21.014626Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: detected pact:matcher:type, will configure a matcher    
2024-03-17T20:22:21.020918Z DEBUG ThreadId(01) pact_ffi::mock_server::handles: pact_ffi::mock_server::handles::pactffi_pact_handle_write_file FFI function invoked
2024-03-17T20:22:21.021017Z DEBUG ThreadId(01) pact_models::pact: Writing new pact file to "./pacts/animal_service-weather_service.json"
%%% message_pact_SUITE ==> consumer.animal_consume_message: OK
2024-03-17T20:22:21.149207Z DEBUG ThreadId(01) pact_ffi::verifier: pact_ffi::verifier::pactffi_verifier_new_for_application FFI function invoked
2024-03-17T20:22:21.149308Z DEBUG ThreadId(01) pact_ffi::verifier: pact_ffi::verifier::pactffi_verifier_set_provider_info FFI function invoked
2024-03-17T20:22:21.149344Z DEBUG ThreadId(01) pact_ffi::verifier: pact_ffi::verifier::pactffi_verifier_add_provider_transport FFI function invoked
2024-03-17T20:22:21.149391Z DEBUG ThreadId(01) pact_ffi::verifier: pact_ffi::verifier::pactffi_verifier_set_publish_options FFI function invoked
2024-03-17T20:22:21.149421Z DEBUG ThreadId(01) pact_ffi::verifier: pact_ffi::verifier::pactffi_verifier_add_directory_source FFI function invoked
2024-03-17T20:22:21.149453Z DEBUG ThreadId(01) pact_ffi::verifier: pact_ffi::verifier::pactffi_verifier_execute FFI function invoked
2024-03-17T20:22:21.149474Z DEBUG ThreadId(01) pact_ffi::verifier::handle: Pact source to verify = Dir(./pacts)
2024-03-17T20:22:21.153359Z DEBUG ThreadId(01) pact_plugin_driver::catalogue_manager: Updated catalogue entries:
core/content-generator/binary
core/content-generator/json
core/content-matcher/json
core/content-matcher/multipart-form-data
core/content-matcher/text
core/content-matcher/xml
2024-03-17T20:22:21.153423Z DEBUG ThreadId(01) pact_plugin_driver::catalogue_manager: Updated catalogue entries:
core/matcher/v1-equality
core/matcher/v2-max-type
core/matcher/v2-min-type
core/matcher/v2-minmax-type
core/matcher/v2-regex
core/matcher/v2-type
core/matcher/v3-content-type
core/matcher/v3-date
core/matcher/v3-datetime
core/matcher/v3-decimal-type
core/matcher/v3-includes
core/matcher/v3-integer-type
core/matcher/v3-null
core/matcher/v3-number-type
core/matcher/v3-time
core/matcher/v4-array-contains
core/matcher/v4-equals-ignore-order
core/matcher/v4-max-equals-ignore-order
core/matcher/v4-min-equals-ignore-order
core/matcher/v4-minmax-equals-ignore-order
core/matcher/v4-not-empty
core/matcher/v4-semver
2024-03-17T20:22:21.153533Z DEBUG ThreadId(01) pact_verifier: Scanning "./pacts"
2024-03-17T20:22:21.154630Z DEBUG ThreadId(01) verify_interaction{interaction="a weather data message"}: pact_verifier: Executing provider states
2024-03-17T20:22:21.154649Z  INFO ThreadId(01) verify_interaction{interaction="a weather data message"}: pact_verifier: Running setup provider state change handler 'weather data for animals' for 'a weather data message'
2024-03-17T20:22:21.154662Z  WARN ThreadId(01) verify_interaction{interaction="a weather data message"}: pact_verifier::callback_executors: State Change ignored as there is no state change URL provided for interaction 
2024-03-17T20:22:21.154675Z DEBUG ThreadId(01) verify_interaction{interaction="a weather data message"}: pact_verifier: State Change: "ProviderState { name: "weather data for animals", params: {} }" -> Ok({})
2024-03-17T20:22:21.154689Z  INFO ThreadId(01) verify_interaction{interaction="a weather data message"}: pact_verifier: Running provider verification for 'a weather data message'
2024-03-17T20:22:21.154696Z DEBUG ThreadId(01) verify_interaction{interaction="a weather data message"}: pact_verifier: Verifying an asynchronous message (single shot)
2024-03-17T20:22:21.154729Z  INFO ThreadId(01) verify_interaction{interaction="a weather data message"}: pact_verifier::provider_client: Sending request to provider at <http://localhost:8080/test_weather/generate_weather>
2024-03-17T20:22:21.154737Z DEBUG ThreadId(01) verify_interaction{interaction="a weather data message"}: pact_verifier::provider_client: Provider details = ProviderInfo { name: "weather_service", protocol: "http", host: "localhost", port: Some(8080), path: "/test_weather/generate_weather", transports: [ProviderTransport { transport: "http", port: Some(8080), path: Some("/test_weather/generate_weather"), scheme: None }, ProviderTransport { transport: "message", port: Some(8080), path: Some("/test_weather/generate_weather"), scheme: Some("http") }] }
2024-03-17T20:22:21.154766Z  INFO ThreadId(01) verify_interaction{interaction="a weather data message"}: pact_verifier::provider_client: Sending request HTTP Request ( method: POST, path: /, query: None, headers: Some({"Content-Type": ["application/json"]}), body: Present(95 bytes, application/json) )
2024-03-17T20:22:21.154781Z DEBUG ThreadId(01) verify_interaction{interaction="a weather data message"}: pact_verifier::provider_client: body:
{"description":"a weather data message","providerStates":[{"name":"weather data for animals"}]}
2024-03-17T20:22:21.154895Z DEBUG ThreadId(01) verify_interaction{interaction="a weather data message"}: reqwest::connect: starting new connection: <http://localhost:8080/>    
2024-03-17T20:22:21.155114Z DEBUG tokio-runtime-worker hyper::client::connect::dns: resolving host="localhost"
2024-03-17T20:22:21.155328Z DEBUG ThreadId(01) verify_interaction{interaction="a weather data message"}: hyper::client::connect::http: connecting to 127.0.0.1:8080
2024-03-17T20:22:21.155535Z DEBUG ThreadId(01) verify_interaction{interaction="a weather data message"}: hyper::client::connect::http: connected to 127.0.0.1:8080
2024-03-17T20:22:21.155860Z DEBUG tokio-runtime-worker hyper::proto::h1::io: flushed 262 bytes
2024-03-17T20:22:26.156256Z  INFO ThreadId(01) pact_verifier: Not publishing results as publishing for pact source Dir("./pacts") is not possible or not yet implemented
2024-03-17T20:22:26.156350Z DEBUG ThreadId(01) pact_matching::metrics: 'PACT_DO_NOT_TRACK' environment variable is set, will not send metrics

Verifying a pact between animal_service and weather_service

  a weather data message (0s loading, 5s 2ms verification)
     Given weather data for animals
      Request Failed - error sending request for url (<http://localhost:8080/test_weather/generate_weather>): operation timed out


Failures:

1) Verifying a pact between animal_service and weather_service Given weather data for animals - a weather data message - error sending request for url (<http://localhost:8080/test_weather/generate_weather>): operation timed out


There were 1 pact failures
Also i am able to connect to this particular url via postman, but not via pact ffi. Any clues what could be wrong here?
r
operation timed out
- that's a networking issue
Are you running it in docker?
m
Just a thought - should we consider printing out the detected os/arch (and any other relevant details) at the top of a DEBUG log, so when people raise these types of things we have it immediately at our disposal? 🤔
p
@rholshausen no, I haven’t used docker here for running my server.
m
Are you able to demonstrate that the server is indeed running on
127.0.0.1:8080
?
e.g.
lsof -i:8080
or
netstat -an | grep LISTEN | grep 8080
p
yes
Copy code
ranjan@ranjan-MS-7D43:~/work/pact_erlang$ netstat -an | grep LISTEN | grep 8080
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN     
ranjan@ranjan-MS-7D43:~/work/pact_erlang$ lsof -i:8080
COMMAND   PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
beam.smp 6205 ranjan   26u  IPv4  54688      0t0  TCP *:http-alt (LISTEN)
m
Yeah, it’s bound to
0.0.0.0
and not
127.0.0.1
(see third column of your
netstat
output)
Copy code
grep localhost /etc/hosts
# localhost is used to configure the loopback interface
127.0.0.1	localhost
::1             localhost
That means if I bind to
localhost
I can connect to it on
127.0.0.1
and
::1
TL;DR - set your verifier target to
0.0.0.0
(or bind your API to a specific IP)
p
still didn’t work after i changed to
0.0.0.0
m
OK new thought - the thread is in a deadlock situation. I recall needing to execute this asynchronously in NodeJS otherwise the process is blocked.
👍 1
p
still didn't work after spawning a separate process in erlang that executes the c code snippet i shared erlang:
Copy code
Pid = spawn(?MODULE, assert_verification, [Name, Scheme, Host, Port, Path, Version, Branch, FilePath, Protocol]),
    Pid ! {self(), get_result},
    receive
        {Pid, Result} ->
            Result
    end,
    ?assertEqual(0, Result).

assert_verification(Name, Scheme, Host, Port, Path, Version, Branch, FilePath, Protocol) ->
    receive
        {From, get_result} ->
            Output = pactffi_nif:verify_via_file(Name, Scheme, Host, Port, Path, Version, Branch, FilePath, Protocol),
            From ! {self(), Output}
    end.
C:
Copy code
struct VerifierHandle *verifierhandle;
    verifierhandle = pactffi_verifier_new_for_application(name, version);
    pactffi_verifier_set_provider_info(verifierhandle, name, scheme, host, port, path);
    pactffi_verifier_add_provider_transport(verifierhandle, protocol, port, path, scheme);
    pactffi_verifier_set_publish_options(verifierhandle, version, NULL, NULL, -1, branch);
    pactffi_verifier_add_directory_source(verifierhandle, file_path);
    int output = pactffi_verifier_execute(verifierhandle);
    pactffi_verifier_shutdown(verifierhandle);
@Srijan Choudhary
my bad, Its definitely the thread deadlock issue as when i ran the server in a separate thread it worked. Thanks a lot @Matt (pactflow.io / pact-js / pact-go) @rholshausen
👍 2
m
Nice!