Hi!
I'm working on a storage engine for a little embedded database. The storage engine saves data to a file, and needs to do that atomically. (Every write succeeds or doesn't succeed). If the program crashes, the user should never lose data.
I'm using a scheme that I think should work. The file is made up of fixed size pages. Every page has a checksum. Writes use a "double buffering" type system where data is alternately written to a secondary page when necessary to make sure there's always a backup copy of all data when updates happen.
Anyway, the details don't matter. Its quite complex, and I think it'll be correct.
But experience has taught me that thinking my code is correct is very different from actually having correct code.
So, I want something to test all the edge cases. To do that, I want to write a little fuzzer which issues random write calls to my API. Along the way, the system should randomly inject "crashes" / filesystem write failures, in accordance with the guarantees provided by the operating system. (So, if fsync()
succeeds, then all writes issued before the fsync can't be lost. But any writes since then may or may not have completed). After a simulated crash, I should be able to read back the file. All committed data should be there, and the file should never end up in a corrupt state.
Any ideas or libraries to help do this in rust?
I'm imagining a trait which wraps std::fs
. For testing, I want to provide my library code with a mocked implementation of the filesystem which randomly generates write failures. But I can't find anything like that on cargo.
I can imagine other approaches which could work out-of-process like:
- Running my testing process in a wrapper which provides a different
glibc
. Then randomly segfault the child process (my test) and reload it to make sure everything looks good. - Using FUSE to mount an intentionally buggy testing filesystem, and send all the file IO into that.
But both of those approaches feel much more complicated to setup and run. And they'd probably run much slower.
Thoughts?