I have a NIF function that executes a FFI function (pactffi from Release Pact FFI Library 0.4.19 · pact-foundation/pact-reference · GitHub).
static ERL_NIF_TERM verify_via_broker(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
// if (!enif_is_binary(env, argv[0]))
// {
// return enif_make_badarg(env);
// }
// char *name = convert_erl_binary_to_c_string(env, argv[0]);
// if (!enif_is_binary(env, argv[1]))
// {
// return enif_make_badarg(env);
// }
// char *scheme = convert_erl_binary_to_c_string(env, argv[1]);
// if (!enif_is_binary(env, argv[2]))
// {
// return enif_make_badarg(env);
// }
// char *host = convert_erl_binary_to_c_string(env, argv[2]);
// if (!enif_is_number(env, argv[3]))
// {
// return enif_make_badarg(env);
// }
// int port = convert_erl_int_to_c_int(env, argv[3]);
// if (!enif_is_binary(env, argv[4]))
// {
// return enif_make_badarg(env);
// }
// char *path = convert_erl_binary_to_c_string(env, argv[4]);
// if (!enif_is_binary(env, argv[5]))
// {
// return enif_make_badarg(env);
// }
// char *version = convert_erl_binary_to_c_string(env, argv[5]);
// if (!enif_is_binary(env, argv[6]))
// {
// return enif_make_badarg(env);
// }
// char *branch = convert_erl_binary_to_c_string(env, argv[6]);
// if (!enif_is_binary(env, argv[7]))
// {
// return enif_make_badarg(env);
// }
// char *broker_url = convert_erl_binary_to_c_string(env, argv[7]);
// if (!enif_is_binary(env, argv[8]))
// {
// return enif_make_badarg(env);
// }
// char *broker_username = convert_erl_binary_to_c_string(env, argv[8]);
// if (!enif_is_binary(env, argv[9]))
// {
// return enif_make_badarg(env);
// }
// char *broker_password = convert_erl_binary_to_c_string(env, argv[9]);
// if (!enif_is_number(env, argv[10]))
// {
// return enif_make_badarg(env);
// }
// int enable_pending = convert_erl_int_to_c_int(env, argv[10]);
// if (!enif_is_binary(env, argv[11]))
// {
// return enif_make_badarg(env);
// }
// char *consumer_version_selectors = convert_erl_binary_to_c_string(env, argv[11]);
// if (!enif_is_number(env, argv[12]))
// {
// return enif_make_badarg(env);
// }
// int consumer_version_selectors_len = convert_erl_int_to_c_int(env, argv[12]);
// if (!enif_is_binary(env, argv[13]))
// {
// return enif_make_badarg(env);
// }
// char *protocol = convert_erl_binary_to_c_string(env, argv[13]);
// ErlNifPid pid;
// enif_get_local_pid(env, argv[14], &pid);
// if (!enif_is_binary(env, argv[15]))
// {
// return enif_make_badarg(env);
// }
// char *state_path = convert_erl_binary_to_c_string(env, argv[15]);
char *name = "animal_service";
char *scheme = "http";
char *host = "localhost";
int port = 8080;
char *path = "/";
char *version = "default";
char *branch = "develop";
char *broker_url = "http://localhost:9292/";
// OSS pact broker docker image: pactfoundation/pact-broker
char *broker_username = "pact_workshop";
char *broker_password = "pact_workshop";
int enable_pending = 1;
char *consumer_version_selectors = "{}";
int consumer_version_selectors_len = 0;
char *protocol = "http";
char *state_path = "http://localhost:8080/pactStateChange";
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);
if (state_path[0] != '\0')
{
pactffi_verifier_set_provider_state(verifierhandle, state_path, 0, 1);
}
pactffi_verifier_set_verification_options(verifierhandle, 0, 5000),
pactffi_verifier_set_publish_options(verifierhandle, version, NULL, NULL, -1, branch);
pactffi_verifier_broker_source_with_selectors(verifierhandle, broker_url, broker_username, broker_password, NULL, enable_pending, NULL, NULL, -1, branch, consumer_version_selectors, consumer_version_selectors_len, NULL, -1);
setenv("PACT_DO_NOT_TRACK", "true", 1);
// ErlDrvTid tid;
// ErlDrvThreadOpts *opts = erl_drv_thread_opts_create("example_thread");
// // Create a new thread
// if (erl_drv_thread_create("example_thread", &tid, ranjan_function, &verifierhandle, opts) != 0) {
// // fprintf(stderr, "Failed to create thread\n");
// return 1;
// }
// int *result;
// if (erl_drv_thread_join(tid, (void **)&result) != 0) {
// // fprintf(stderr, "Failed to join thread\n");
// return 1;
// }
// printf("Result returned by the thread: %d\n", *result);
// // Detach the thread (optional)
// if (erl_drv_thread_detach(tid) != 0) {
// fprintf(stderr, "Failed to detach thread\n");
// return 1;
// }
int output = pactffi_verifier_execute(verifierhandle);
pactffi_verifier_shutdown(verifierhandle);
// ERL_NIF_TERM message = enif_make_int(env, output);
// enif_send(env, &pid, NULL, message);
return enif_make_int(env, output);
}
What this code does is when it sends requests to a localhost:8080/pactStateChange
in the int output = pactffi_verifier_execute(verifierhandle);
Now when I try to execute the above FFI via NIF erlang function, I can only execute this if I execute it from another erlang shell but not from the same shell where the http server is started which listens on localhost:8080/pactStateChange
.
What could be the reason for this?
PFA logs of the pactffi:
2024-04-17T10:57:48.373523Z DEBUG ThreadId(01) verify_interaction{interaction="a request to GET a non-existing animal: Miles"}: pact_verifier::provider_client: State change request failed with error error sending request for url (http://localhost:8080/pactStateChange): operation timed out
2024-04-17T10:57:48.373940Z DEBUG ThreadId(01) verify_interaction{interaction="a request to GET a non-existing animal: Miles"}: pact_verifier: State Change: "ProviderState { name: "", params: {} }" -> Err(Provider state failed: (interaction_id: 89d5c01cb84b83b5eaf9b413ff1add3c019f90af) Invalid response: error sending request for url (http://localhost:8080/pactStateChange): operation timed out)
2024-04-17T10:57:48.373986Z ERROR ThreadId(01) verify_interaction{interaction="a request to GET a non-existing animal: Miles"}: pact_verifier: Provider setup state change for has failed - MismatchResult::Error("Invalid response: error sending request for url (http://localhost:8080/pactStateChange): operation timed out", Some("89d5c01cb84b83b5eaf9b413ff1add3c019f90af"))
2024-04-17T10:57:48.528450Z DEBUG ThreadId(01) verify_interaction{interaction="a request to create an animal: Max"}: pact_verifier: Executing provider states