-
-
Notifications
You must be signed in to change notification settings - Fork 45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mocking retries? #96
Comments
Hi @jamesperez2005 , thanks for reaching out! Do you think delete will help you here? #[test]
fn delete_mock_test() {
let server = MockServer::start();
let mut m1 = server.mock(|when, then| {
when.method(GET).path("/test");
then.status(500);
});
let mut m2 = server.mock(|when, then| {
when.method(GET).path("/test");
then.status(200);
});
let response = get(&format!(
"http://{}:{}/test",
server.host(),
server.port()
))
.unwrap();
assert_eq!(response.status(), 500);
// As long as both m1 and m2 exist, m1 will take precedence over m2.
// Let's delete m1 so we can respond with a successful response.
m1.delete();
let response = get(&format!("http://{}/test", server.address())).unwrap();
assert_eq!(response.status(), 200);
} |
Not quite. I want to test a utility function that does the retries by itself, so I don't get a chance to intervene after the first N retries... It would be great to have a "match_at_most(N)" helper on the |
Interesting idea ... OK, let's keep this issue open and I'll try to get a PR for it after the next release (it's a big change, so it makes sense to wait a bit). |
If a `disk import` request is interrupted then the disk is likely to be left in a `ImportReady` or `ImportingFromBulkWrites` state, which prevents the user from deleting it. The commonly occurs when users interrupt the request using ^C, and is a frustrating experience. Add a new `GracefulShutdown` struct to listen for SIGINTs. This will cancel the executing `Future` on interrupt and run a cleanup task which will return an error, even if cleanup succeeds. A second SIGINT causes the process to exit immediately. Hook calls make in the critical section of the import into the new system to ensure we delete the partially imported disk. This introduces a race where the user may cancel the import operation while the disk creation saga is still executing and the disk is in `Creating` state. Attempting to finalize or delete the disk in this state will fail, so we are forced to wait until it has transitioned to `ImportReady` before proceeding. To avoid spamming the API too heavily, we poll the disk state every 500ms for no more than ten tries. The new polling creates a problem for our testing, though. We need the initial disk API query to return a 404, but subsequent ones to find the disk. `httpmock` does not provide a way to remove a mock after N hits, and we have no graceful way of replacing the mock while running the `oxide` binary. There is an open issue[0] to add an option like this to `httpmock`, but for right now we have no option but to delete the tests that check for failure. Closes #651 [0] alexliesenfeld/httpmock#96
In situations where a component is expected to automatically retry an endpoint manually calling `delete` on a `Mock` may not be an option. To support this scenario, add a new `delete_after_n` method to `When` that will remove the `Mock` from the server after it has matched the specified number of calls. Related to alexliesenfeld#76 Related to alexliesenfeld#96
If a `disk import` request is interrupted then the disk is likely to be left in a `ImportReady` or `ImportingFromBulkWrites` state, which prevents the user from deleting it. The commonly occurs when users interrupt the request using ^C, and is a frustrating experience. Add a new `GracefulShutdown` struct to listen for SIGINTs. This will cancel the executing `Future` on interrupt and run a cleanup task which will return an error, even if cleanup succeeds. A second SIGINT causes the process to exit immediately. Hook calls make in the critical section of the import into the new system to ensure we delete the partially imported disk. This introduces a race where the user may cancel the import operation while the disk creation saga is still executing and the disk is in `Creating` state. Attempting to finalize or delete the disk in this state will fail, so we are forced to wait until it has transitioned to `ImportReady` before proceeding. To avoid spamming the API too heavily, we poll the disk state every 500ms for no more than ten tries. The new polling creates a problem for our testing, though. We need the initial disk API query to return a 404, but subsequent ones to find the disk. `httpmock` does not provide a way to remove a mock after N hits, and we have no graceful way of replacing the mock while running the `oxide` binary. There is an open issue[0] to add an option like this to `httpmock`, but for right now we have no option but to delete the tests that check for failure. Closes #651 [0] alexliesenfeld/httpmock#96
Until #108 lands here is a (ugly) work around to mock failing the first request: static mut REQ_COUNT: u32 = 0;
...
let server = MockServer::start();
let get_mock = server.mock(|when, then| {
when.method(GET).path("/test").matches(|_req: &HttpMockRequest| {
let req = unsafe {
let req = REQ_COUNT;
REQ_COUNT += 1;
req
};
req >= 1
});
then.status(200).body("TEST");
}); Its not pretty but is a reasonable workaround. |
I'm trying to mock a service that is supposed to be called multiple times and fail, and then succeed at the Nth time. Since these are retries the requests should be the same, so there's no way to distinguish them by parameters or by path/body.
Is that something that can be done with
httpmock
?The text was updated successfully, but these errors were encountered: