To be honest, this part is handled manually via a test value injector. There's a global map of names to "adjusters", which are either values or callbacks that are allowed to manipulate a value. If there's a particular request we want to fail after making, we do something like this:
// System under test code:
auto status = DoRequest();
TestManipulate("after_request", status);
if (IsError(status)) {
// Handle errors.
}
// Test code
SetTestValue("after_request", MyErrorStatus());
RunSystemUnderTest();
The module that handles test value manipulation is typically disabled by a global variable, and lives in the cold section under FDO and opt compilation, so it costs essentially nothing. It cannot be enabled in release builds due to the code that enables it being compiled out.
We find in many cases this isn't really necessary, as the error handling code in most cases just bubbles up the error, and so it is not particularly interesting to test. There are a few cases where we do this where the error handling is more complex than "return same error to user" or "retry after delay."
This type of thing can't always solve the problem, but it's often good enough to get things done.
We find in many cases this isn't really necessary, as the error handling code in most cases just bubbles up the error, and so it is not particularly interesting to test. There are a few cases where we do this where the error handling is more complex than "return same error to user" or "retry after delay."
This type of thing can't always solve the problem, but it's often good enough to get things done.