Skip to content
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

Delay mock response #160

Closed
sr-gi opened this issue Feb 22, 2023 · 9 comments
Closed

Delay mock response #160

sr-gi opened this issue Feb 22, 2023 · 9 comments

Comments

@sr-gi
Copy link

sr-gi commented Feb 22, 2023

I've been using .with_body_from_fn to add delays to some of my mock responses as suggested in #64 (comment). e.g:

let api_mock = server
    .mock("POST", endpoint))
    .with_status(400)
    .with_header("content-type", "application/json")
    .with_body_from_fn(|w| {
        thread::sleep(Duration::from_secs_f64(API_DELAY));
        w.write_all(
            json!(ApiError {
                error: "error_msg".to_owned(),
                error_code: 1,
            })
            .to_string()
            .as_bytes(),
        )
    })
    .create_async()
    .await;

However, I've noticed that when tests are run in parallel as part of a bigger suite, the elapsed time for the delays is bigger than expected. This does not happen if the test is run standalone or if tests are run using -test-threads=1.

So that poses two questions:

  • Is this the right way of adding delays?
  • Why is spinning multiple servers in parallel affect the delays?
@lipanski
Copy link
Owner

lipanski commented Feb 22, 2023

since you're using async code there, try tokio::time::sleep instead - though you'd have to wrap the contents of the closure in async. or you could move the sleep to a tokio::task::spawn_blocking block, not sure.

@sr-gi
Copy link
Author

sr-gi commented Feb 22, 2023

I've tried to use tokio::time::sleep, but it doesn't look like async can be used in the with_body_from_fn closure (or I'm not creating this correctly). Would you mind providing a working example of an async sleep inside a with_body_from_fn block?

@lipanski
Copy link
Owner

I couldn't figure out the reason for the delay. I'll have a closer look when implemeting with_body_from_request.

@lipanski
Copy link
Owner

what works right now is using the sync API:

        let mut s = mockito::Server::new();
        let _m = s.mock("GET", "/").with_body_from_fn(|writer| {
            std::thread::sleep(std::time::Duration::from_secs(5));
            writer.write_all(b"test")
        }).create();

...but you'd have to change those tests using the sync API to be fully sync.

@sr-gi
Copy link
Author

sr-gi commented Feb 23, 2023

I don't think I can actually. This is a pretty simple example, but the tests are using some async components that are actually the ones sending the request to the mock.

I have a workaround in place for now, so I guess I'll wait until the async equivalent is in place.

Thanks for the help :)

@lipanski
Copy link
Owner

lipanski commented Mar 2, 2023

@sr-gi this should work with the Mock::with_body_from_request callback introduced in 0.32.4. I tried it out with the std::thread::sleep function and it seemed to respect the provided durations.

@lipanski lipanski closed this as completed Mar 2, 2023
@sr-gi
Copy link
Author

sr-gi commented Mar 2, 2023

@sr-gi this should work with the Mock::with_body_from_request callback introduced in 0.32.4. I tried it out with the std::thread::sleep function and it seemed to respect the provided durations.

I'm getting the same exact issue as before:

  • Running the test standalone --> Expected: ~0.45. Elapsed: 0.513677505
  • Running the whole suite (with --test-threads=1) --> Expected: ~0.45. Elapsed: 0.513677505
  • Running the whole suite (multithreaded) --> Expected: ~0.45. Elapsed: 1.5144681709999999 (this one actually goes up and down, but never close to the expected)

@lipanski
Copy link
Owner

lipanski commented Mar 2, 2023

@sr-gi the difference seems quite small (except for the multithreaded scenario), which is probably why I didn't spot it. if that's a problem then I'd recommend again the sync scenario. otherwise you can have a look under the hood yourself, I'd accept a pull request if you can figure out the issue 😸

@sr-gi
Copy link
Author

sr-gi commented Mar 3, 2023

@sr-gi the difference seems quite small (except for the multithreaded scenario), which is probably why I didn't spot it. if that's a problem then I'd recommend again the sync scenario. otherwise you can have a look under the hood yourself, I'd accept a pull request if you can figure out the issue 😸

Yeah, the two first scenarios are actually correct, the small difference may come from how I'm actually accounting for the delays. It is the multithreaded case that breaks my tests.

I'll try to see if there is a way of implementing a variant of with_body_from_request or with_body_from_fn that accepts async closures.

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

No branches or pull requests

2 participants