Hi again! :wave: I am trying to implement consume...
# libpact_ffi-users
s
Hi again! 👋 I am trying to implement consumer version selectors. I am struggling to understand either why is it not working for me or how is it supposed to work 😅 For testing purposes, I did the following:
Copy code
char myJson[256];
    strcpy(myJson, "[{");
    strcat(myJson, "\"branch\": \"foo-bar\"");
    strcat(myJson, "}]");
    const char *mockSelectors[] = {myJson};

    printf("mockSelectors is %s\n", mockSelectors[0]);
    // prints out mockSelectors is [{"branch": "foo-bar"}]

    pactffi_verifier_broker_source_with_selectors(..., mockSelectors, 1, ...)
...
As I understand, this is supposed to verify against consumers with branch
foo-bar
? When I run the verifier, it instead uses the latest version.
Copy code
The pact at ... is being verified because the pact content belongs to the consumer version matching the following criterion:
    * latest version of <consumer> that has a pact with <provider> (<absolute-version of consumer>)
Any help would be greatly appreciated! 🙇
1
m
mind sharing any additional logs there? The selectors look OK
If you have the logs set to DEBUG you should see a
POST HOST/…/for-verification
in there somewhere. That will have the actual query sent to the broker. My guess is your settings haven’t taken effect.
Ah, you’ve set
len
to
1
, but this is presumably the length of the selectors string (it’s a C interface, so it needs to know how many characters to read over the FFI)
s
Logs set to debug for what? FFI?
oooooooohhhhh
I thought it is the amount of selectors
Let me try giving it a proper length
👍 1
m
Logs set to debug for what? FFI?
yep, there should be an FFI to set the log level and where you want the logs to go (stdout, file etc.)
👀 1
s
Btw should the length be number of characters in the selectors string? escaped or unescaped?
m
It’s the JSON string length. From the 0th character, how many characters needs to be read in until the final closing brace
}
📌 1
So if I read your code correctly, it produces this string:
[{"branch": "foo-bar"}]
which is 24 characters long
(^^ updated I included the escaping)
s
_int_ mockSelectors_len = strlen(mockSelectors[0]);
gives me 23 😄 But now I get a different error, trying to get to the bottom of this one. tysm for bearing with me here..
👍 1
m
I might have been off by one 🤷 😆
yes, it’s 23
I did
echo "[{\"branch\": \"foo-bar\"}]" | wc -c
instead of
echo -n "[{\"branch\": \"foo-bar\"}]" | wc -c
(I always forget to do that)
s
So currently... When I pass length as 0, or 1 - The tests pass, as they verify with latest pacts (the initial issue)) When I pass the
strlen(mockSelectors)
, and a proper length is used the tests fail, or do not run. Hard to tell, no logs from pact_erlang or FFI side... I am using elixir, where I do
Copy code
{:ok, verfier_ref} = :pact_verifier.start_verifier(service_name, provider_opts)
    output = :pact_verifier.verify(verfier_ref)

    assert 0 = output
and I simply get
Copy code
test contracts (.....)
     test/contract/testfile.exs:6
     match (=) failed
     code:  assert 0 = output
     left:  0
     right: 139
     stacktrace:
       test/contract/testfile.exs:43: (test)
I tried now providing the correct branch name, thinking that maybe it worked but didn't find such branch
foo-bar
, but it did not succeed either.
My logs go into pact_erlang.log file. When I use length 23 (or whatever it is), there are no logs even. When I use length 1, I at least get some logs.
and about what you said earlier
If you have the logs set to DEBUG you should see a
POST HOST/…/for-verification
in there somewhere. That will have the actual query sent to the broker.
My guess is your settings haven’t taken effect.
I can see in the logs
_2024-07-10T11:41:41.123902Z_  INFO ThreadId(13) pact_verifier::pact_broker: Fetching path '/pacts/provider/<provider>/for-verification' from pact broker
And right after
_2024-07-10T11:41:42.089830Z_  INFO ThreadId(13) pact_verifier::pact_broker: Fetching path '/pacts/provider/<provider>/consumer/<consumer>/pact-version/a9ad1547da4dc3b534d84109157c124df17a7d75/metadata/c1tdW2xdPXRydWUmc1tdW2N2XT0zNg' from pact broker
After which it goes into state change url's already
m
Looks like logs are at INFO level, ideally they set to DEBUG to get the body sent
s
I'll try to do that
m
s
Changed this to debug, got the logs now..
nice 7771 1
Interesting... It does actually send it, sec
👍 1
m
So with c interfaces, if things just stop working randomly or crashes, that usually means the receiver of the function cannot read the arguments or gets something of the wrong shape and just dies
👍 1
s
Good to know 👍 Not a C developer directly, but more of a problem-solver, so I'm okay with working with any language 😄 Sorry for dumb questions from time to time. Now back to the logs.. Even though I give
[{"branch": "foo-bar"}]
to
pactffi_verifier_broker_source_with_selectors
function, the logs indicate that it uses the actual branch
Copy code
2024-07-10T11:51:03.944175Z DEBUG ThreadId(01) pact_verifier::pact_broker: templated URL = <https://gpoc.pactflow.io/pacts/provider/><provider>/for-verification
2024-07-10T11:51:03.944604Z DEBUG ThreadId(01) pact_verifier::pact_broker: final URL = <https://gpoc.pactflow.io/pacts/provider/><provider>/for-verification
2024-07-10T11:51:03.944633Z DEBUG ThreadId(01) pact_verifier::pact_broker: Sending JSON to <https://gpoc.pactflow.io/pacts/provider/><provider>/for-verification using POST: {"includePendingStatus":false,"consumerVersionSelectors":[],"providerVersionBranch":"<real-branch-name>"}
m
Can you please set the log-level to
trace
and then send me the entire log?
📌 1
s
Sent in DM. Can continue discussion here if something is found there.
m
These lines look suspicious:
Copy code
2024-07-10T11:55:53.086870Z DEBUG ThreadId(01) pact_ffi::verifier: pact_ffi::verifier::pactffi_verifier_broker_source_with_selectors FFI function invoked
2024-07-10T11:55:53.086873Z TRACE ThreadId(01) pact_ffi::verifier: @param handle = 0x148612d10
2024-07-10T11:55:53.086875Z TRACE ThreadId(01) pact_ffi::verifier: @param url = 0x150ef08c8
2024-07-10T11:55:53.086877Z TRACE ThreadId(01) pact_ffi::verifier: @param username = 0x0
2024-07-10T11:55:53.086879Z TRACE ThreadId(01) pact_ffi::verifier: @param password = 0x0
2024-07-10T11:55:53.086881Z TRACE ThreadId(01) pact_ffi::verifier: @param token = 0x150ef0948
2024-07-10T11:55:53.086883Z TRACE ThreadId(01) pact_ffi::verifier: @param enable_pending = 0
2024-07-10T11:55:53.086885Z TRACE ThreadId(01) pact_ffi::verifier: @param include_wip_pacts_since = 0x0
2024-07-10T11:55:53.086890Z TRACE ThreadId(01) pact_ffi::verifier: @param provider_tags = 0x0
2024-07-10T11:55:53.086892Z TRACE ThreadId(01) pact_ffi::verifier: @param provider_tags_len = 65535                    <-----------
2024-07-10T11:55:53.086894Z TRACE ThreadId(01) pact_ffi::verifier: @param provider_branch = 0x150ef0888
2024-07-10T11:55:53.086896Z TRACE ThreadId(01) pact_ffi::verifier: @param consumer_version_selectors = 0x16e366c58
2024-07-10T11:55:53.086898Z TRACE ThreadId(01) pact_ffi::verifier: @param consumer_version_selectors_len = 1           <------------
2024-07-10T11:55:53.086900Z TRACE ThreadId(01) pact_ffi::verifier: @param consumer_version_tags = 0x0
2024-07-10T11:55:53.086901Z TRACE ThreadId(01) pact_ffi::verifier: @param consumer_version_tags_len = 65535            <-------------
The
provider_tags_len
suggests the FFI function will read 65535 characters from
provider_tags
, so probably isn’t reading anything after that property
s
Oh… the provider tags len is set to -1 by pact_erlang.. wasn’t too suspicious of that at first, but I can change it to 0 to test
👍 1
that didn't change anything either.
🤔 1
Hold up, there were two values as -1. Trying with the following setup now
Copy code
pactffi_verifier_broker_source_with_selectors(verifierhandle, broker_url, NULL, NULL, broker_token, enable_pending, NULL, NULL, 0, branch, mockSelectors, 1, NULL, 0);
where...
Copy code
void pactffi_verifier_broker_source_with_selectors(struct VerifierHandle *handle,
                                                   const char *url,
                                                   const char *username,
                                                   const char *password,
                                                   const char *token,
                                                   unsigned char enable_pending,
                                                   const char *include_wip_pacts_since,
                                                   const char *const *provider_tags,
                                                   unsigned short provider_tags_len,
                                                   const char *provider_branch,
                                                   const char *const *consumer_version_selectors,
                                                   unsigned short consumer_version_selectors_len,
                                                   const char *const *consumer_version_tags,
                                                   unsigned short consumer_version_tags_len);
m
Mock selectors can't be 1, it needs to be the length of the char*
I got logs for that run, sec
Untitled
m
My apologies I just looked at my Go client and it IS the length of the array. Sorry, I'm tired 🤣
s
All good, you are a champion for bearing with me here so long 🙇
😆 1
So I think the problem is that you're passing a string (which is a JSON array) but it expects an array of strings (JSON objects) I think this is why the method is dying - it's receiving an array of chars not an array of array of chars
s
oooh
m
I should have looked at the definition at the start. This is why the
len
was confusing me. You're passing a string so its length was the obvious thing to send. But you should be passing an array (of length 1)
s
I was actually beginning to use json with
cJson
library earlier today, but I stopped for a second and though, "hmm, let me see if there are other examples here" and saw some other thing being passed as json string 😄 Just went from there.
m
So basically you need to give the FFI an array type on the arguments that also take a Len, and each value in the array is simply a JSON object as a string.
I need to head to bed, but will check back in tomorrow
🙌 1
s
Tyvm! Good night! I will report back the results.
🙌 1
In short, I got it working!
Copy code
// Works with no errors, tries to get pacts with branch foo-bar. Runs 0 tests
const char *jsonArray[] = {
  "{\"branch\": \"foo-bar\"}",
};

// Works with no errors, fetches pacts with real branch name. Runs tests
const char *jsonArray[] = {
  "{\"branch\": \"<real-branch>\"}",
};

pactffi_verifier_broker_source_with_selectors(..., jsonArray, 1, ..);
m
Woohoo!