Skip to content

Initial unit tests for Trustee interaction#53

Merged
alicefr merged 12 commits into
trusted-execution-clusters:mainfrom
Jakob-Naucke:initial-unittest
Oct 13, 2025
Merged

Initial unit tests for Trustee interaction#53
alicefr merged 12 commits into
trusted-execution-clusters:mainfrom
Jakob-Naucke:initial-unittest

Conversation

@Jakob-Naucke
Copy link
Copy Markdown
Contributor

@Jakob-Naucke Jakob-Naucke commented Oct 9, 2025

Respinning #34. Attempts to supersede #39 + #20.

e: contains some minimally-invasive refactorings for better testability in separate commits

@Jakob-Naucke Jakob-Naucke force-pushed the initial-unittest branch 3 times, most recently from d7042e0 to e93dc43 Compare October 9, 2025 15:48
Comment thread operator/src/mock_client.rs
Comment thread operator/src/trustee.rs Outdated
async fn test_generate_att_policy_success() {
let ns = "test".to_string();
let client = MockClient::new(StatusCode::OK, ConfigMap::default(), ns).into_client();
let clos = |_: &_| Ok(ConfigMap::default());
Copy link
Copy Markdown
Contributor

@alicefr alicefr Oct 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can you create a macro for the cases we don't use any input, it will be a bit easier to read the code:

macro_rules! return_config_map {
    (ok) => {
        |_: &_| Ok(ConfigMap::default())
    };
    (err, $err:expr) => {
        |_: &_| Err::<ConfigMap, _>($err)
    };
}

let clos_ok = return_config_map!(ok);
let clos_err = return_config_map!(err, StatusCode::CONFLICT);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

had one but dropped it again. checking URIs & methods now, and with that there would be one single use for the Ok case and zero for the Err case.

@alicefr
Copy link
Copy Markdown
Contributor

alicefr commented Oct 10, 2025

@Jakob-Naucke one question, you are implementing a closure which return a single object for all the type of requests. I'm wondering if we should distinguish the type of request. IOW, I might want to use the mocking client for Get, Create and Patch. Maybe for now we can leave it as it is since the patches are already quite complex.

Another functionalities we might require in the future is the ability to specify how many times you want to return that object. For example, in a retry loop we might just want to return it only once and then changing behavior. It can be useful for example to test the recovery from an error, you return first and error and then the correct object.

@alicefr
Copy link
Copy Markdown
Contributor

alicefr commented Oct 10, 2025

it already looks very promising, thanks! I will do a second pass later

@Jakob-Naucke
Copy link
Copy Markdown
Contributor Author

one question, you are implementing a closure which return a single object for all the type of requests. I'm wondering if we should distinguish the type of request. IOW, I might want to use the mocking client for Get, Create and Patch. Maybe for now we can leave it as it is since the patches are already quite complex.

hmm, already with this patch you could match on the method in the same way that e.g. test_update_rvs matches on the URI. is that not what you mean?

Another functionalities we might require in the future is the ability to specify how many times you want to return that object. For example, in a retry loop we might just want to return it only once and then changing behavior. It can be useful for example to test the recovery from an error, you return first and error and then the correct object.

ayy, state. I suppose the response_closure could also take an attempt_number: u8 (maybe in a future PR) or there's something more elegant here.

@alicefr
Copy link
Copy Markdown
Contributor

alicefr commented Oct 10, 2025

one question, you are implementing a closure which return a single object for all the type of requests. I'm wondering if we should distinguish the type of request. IOW, I might want to use the mocking client for Get, Create and Patch. Maybe for now we can leave it as it is since the patches are already quite complex.

hmm, already with this patch you could match on the method in the same way that e.g. test_update_rvs matches on the URI. is that not what you mean?

yes, but you aren't checking that. It could be any method called and you return that with the mock.
What I meant was more close as the go mock that they always have a mock call per methods in the interface.
What if for example I change the update_reference_values with a different set of client calls e.g create, get and patch (even if the example doesn't make sense)

Another functionalities we might require in the future is the ability to specify how many times you want to return that object. For example, in a retry loop we might just want to return it only once and then changing behavior. It can be useful for example to test the recovery from an error, you return first and error and then the correct object.

ayy, state. I suppose the response_closure could also take an attempt_number: u8 (maybe in a future PR) or there's something more elegant here.

Yes, the comment wasn't for now

@Jakob-Naucke
Copy link
Copy Markdown
Contributor Author

one question, you are implementing a closure which return a single object for all the type of requests. I'm wondering if we should distinguish the type of request. IOW, I might want to use the mocking client for Get, Create and Patch. Maybe for now we can leave it as it is since the patches are already quite complex.

hmm, already with this patch you could match on the method in the same way that e.g. test_update_rvs matches on the URI. is that not what you mean?

yes, but you aren't checking that. It could be any method called and you return that with the mock. What I meant was more close as the go mock that they always have a mock call per methods in the interface. What if for example I change the update_reference_values with a different set of client calls e.g create, get and patch (even if the example doesn't make sense)

Sorry, I still don't understand what you're going for. You could do e.g.

let clos = move |req: &Option<Request<_>>| match req {
    Some(r) if r.method() == Method::PATCH => Ok(some_config_map.clone()),

what is it instead that you want to be able to do?

@Jakob-Naucke Jakob-Naucke force-pushed the initial-unittest branch 2 times, most recently from a62f869 to ace593d Compare October 10, 2025 14:25
Jakob-Naucke and others added 12 commits October 10, 2025 16:26
Signed-off-by: Jakob Naucke <jnaucke@redhat.com>
instead as subroutine for better testability

Signed-off-by: Jakob Naucke <jnaucke@redhat.com>
Signed-off-by: Alice Frosi <afrosi@redhat.com>
Co-authored-by: Jakob Naucke <jnaucke@redhat.com>
- `test_generate_att_policy_success`: Verifies the function returns
  `Ok(())` on a successful API response (200 OK).
- `test_generate_att_policy_already_exists`: Verifies the function
  correctly handles a 409 Conflict and returns `Ok(())`, confirming
  idempotency.
- `test_generate_att_policy_error`: Verifies server errors are
  returned correctly.

Signed-off-by: Dehan Meng <demeng@redhat.com>
Co-authored-by: Alice Frosi <afrosi@redhat.com>
Co-authored-by: Jakob Naucke <jnaucke@redhat.com>
- `test_get_image_pcrs_success`: Verifies that a valid JSON string in
   a ConfigMap is correctly deserialized into the `ImagePcrs` struct.
- `test_get_image_pcrs_no_data`: Ensures an error is returned when the
   ConfigMap's `data` field is missing.
- `test_get_image_pcrs_no_file`: Ensures an error is returned when the
  ConfigMap's `data` field is empty.
- `test_get_image_pcrs_invalid_json`: Confirms that an error is
  propagated when the data contains an invalid JSON string.

Signed-off-by: Dehan Meng <demeng@redhat.com>
Co-authored-by: Jakob Naucke <jnaucke@redhat.com>
A sanity check to validate that `generate_luks_key` runs without errors and returns a key of the expected 32-byte length.

Signed-off-by: Dehan Meng <demeng@redhat.com>
Co-authored-by: Jakob Naucke <jnaucke@redhat.com>
Instrument MockClient to respond with a closure on a result of request
body and status code.

Signed-off-by: Jakob Naucke <jnaucke@redhat.com>
Success, missing PCR ConfigMap, missing Trustee ConfigMap, missing
Trustee data, missing RV file

Signed-off-by: Jakob Naucke <jnaucke@redhat.com>
Signed-off-by: Jakob Naucke <jnaucke@redhat.com>
for generate_{secret,trustee_data,kbs_{service,deployment}}

Signed-off-by: Jakob Naucke <jnaucke@redhat.com>
Signed-off-by: Jakob Naucke <jnaucke@redhat.com>
Signed-off-by: Jakob Naucke <jnaucke@redhat.com>
@alicefr
Copy link
Copy Markdown
Contributor

alicefr commented Oct 13, 2025

one question, you are implementing a closure which return a single object for all the type of requests. I'm wondering if we should distinguish the type of request. IOW, I might want to use the mocking client for Get, Create and Patch. Maybe for now we can leave it as it is since the patches are already quite complex.

hmm, already with this patch you could match on the method in the same way that e.g. test_update_rvs matches on the URI. is that not what you mean?

yes, but you aren't checking that. It could be any method called and you return that with the mock. What I meant was more close as the go mock that they always have a mock call per methods in the interface. What if for example I change the update_reference_values with a different set of client calls e.g create, get and patch (even if the example doesn't make sense)

Sorry, I still don't understand what you're going for. You could do e.g.

let clos = move |req: &Option<Request<_>>| match req {
    Some(r) if r.method() == Method::PATCH => Ok(some_config_map.clone()),

what is it instead that you want to be able to do?

As discussed offline, this is exactly what I want. The issue was that the test didn't include the specification of the method we were testing against

@alicefr
Copy link
Copy Markdown
Contributor

alicefr commented Oct 13, 2025

Very nice, thanks Jakob for the work! Looks great!
/lgtm

@alicefr alicefr merged commit 2efa076 into trusted-execution-clusters:main Oct 13, 2025
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants