Reputation:
We have a file IO library that basically writes data to a file in a fancy format and then later reads the file back. We must ensure that the file is readable even if the library (or computer) crashes amidst the middle of writing.
We know how to write a program that crashes itself. We can use kill(getpid())
to simulate a crash. Or we can use 1/0
and so on. So we'll write a program that opens the library, writes some data, and then kills itself right in the middle. Then we'd have a file in its half-baked state that we can open in the reader to see if the reader can handle the file.
The question: how to make this automated?
For example, we'd like our unit test suite (which tests many aspects of the library automatically and gives a pass/fail) to create a new program/process that begins writing a file and then commits suicide. Then control can be handled back to the unit test which can then open the file that the process created before seppuku. Then the unit test can do some validation on the file to see if we've satisfied our requirment "leave a valid file upon crash".
I was looking into the exec
function which seems to do what we need. However, I was not able to ascertain whether exec
returns back to the caller program/process if the exec
'd program crashes.
Upvotes: 0
Views: 542
Reputation: 754500
This is some thinking outside the box — a suggested alternative way to do your testing.
If your testing is supposed to determine how your main program works on a file that is truncated by a crash, then a more deterministic test method would be to take a copy of a valid file, truncate it with truncate()
or ftruncate()
and then run your main program on that. You could even run tests on file sizes from 0 through full size.
If you're concerned that you might have the first 20 KiB being the first part of some new file content but the other 30 KiB (for sake of argument) are the remainder of the prior version, then you need to work a little harder, but you could still generate such files deterministically and then run your main program on the deliberately generated corrupt files.
Upvotes: 1
Reputation: 129454
I have a "testrunner.cpp" for my compiler project, which is perfectly able to cope with both the compiler and the generated test-code crashing (unfortunately, during development, you do find that both of these things can happen when you've done something wrong either in the compiler or got the code for the test-code itself wrong - or both!). It's quite simple, it uses the standard library function system
to create a new process.
You can of course also use fork
followed by exec
, and then use waitpid
or another wait
type function to get the results. system
is essentially that, but it starts a shell too, so you can easily use redirection (which my "testrunner.cpp" does).
system
(or wait
) will return a result-code of the executed program. In my case, any "non-zero" result is deemed a failure (I don't really care WHY it failed - everything should pass!), but you may need to check "did it crash or finish normally" in your code.
My "testrunner.cpp" can be found here (it is the complete code for running the tests, aside from the compiler and "diff" - and of course to use it, you also need the test sources in the same directory): https://github.com/Leporacanthicus/lacsap/blob/master/test/testrunner.cpp
In particular the runcmd
is where the call to system
happens.
Upvotes: 1