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

Support mocking of IO #18

Open
withoutboats opened this issue May 24, 2020 · 5 comments
Open

Support mocking of IO #18

withoutboats opened this issue May 24, 2020 · 5 comments

Comments

@withoutboats
Copy link
Collaborator

It occurred to me this monring that io-uring is exceptionally mockable as far as IO interfaces go, because it is mostly just a data structure. With changes to make it easier to create fake SQEs and CQEs, a mock driver for testing that does no actual IO would not be difficult to build.

@gardnervickers
Copy link

This sounds like it would be very interesting for deterministic simulation testing!

For creating fake SQEs/CQEs, would that be something which could be done within the iou crate or were you thinking of adding traits for SQEs/CQEs which implementers of Drive would provide concrete impls for?

@mxxo
Copy link
Contributor

mxxo commented Oct 9, 2020

Don't mean to barge in but I believe at least mock CQEs are supported by iou (https://docs.rs/iou/0.3.3/iou/cqe/struct.CQE.html#method.from_raw_parts)

@mxxo
Copy link
Contributor

mxxo commented Oct 14, 2020

I think SQEs would be the tricky one. The only way to get a valid sqe pointer from liburing is to call io_uring_get_sqe on a ring instance, which is the same for iou. Adding a SQE::from_raw method to iou seems like an unnecessary footgun that would only be useful for mocks. Trying to actually submit the fake SQE will be buggy.

Is the goal to avoid requiring a valid io_uring instance entirely? Maybe another way is to define mock driver internal structs FakeSQE, FakeSQEs identical to iou::SQE, iou::SQEs etc. and transmute between them. This would let the driver implement all the prepare methods without requiring changes elsewhere.

@gardnervickers
Copy link

@mxxo Good point! I’m not super familiar with the requirements of transmute so please correct me if I’m wrong but to transmute between FakeSQEs and SQEs, would the SQEs iterator have to have a stable layout like #repr(C) or something?

@mxxo
Copy link
Contributor

mxxo commented Oct 15, 2020

You're right for the general case but I think in this case we don't need any extra annotations because SQEs (SQE too) have a single field, so their layout is defined as that of the field. We can also avoid transmute entirely and use pointer casts (suggested by clippy):

// pub struct SQEs<'ring> {
//     sqes: slice::IterMut<'ring, uring_sys::io_uring_sqe>,
// }

use iou::SQEs;

struct MockSqes<'ring> {
    sqes: std::slice::IterMut<'ring, uring_sys::io_uring_sqe>,
}

impl<'ring> MockSqes<'ring> {
    fn as_sqes(&mut self) -> &mut SQEs {
        unsafe { &mut *(self as *mut MockSqes as *mut SQEs) }
    }
}

I don't know if this is a great implementation idea for a mock driver in general though.

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

3 participants