Reputation: 1407
I have an existing C/C++ application that communicates with other applications/systems through several interfaces (TCP, DB, shared memory). I would like to run the application once with the real environment and "record" all function calls and their return values (or changes to the buffers passed as parameters). I would record only the calls related with external interfaces (TCP, DB) with a "spy". Then I could run the application again but using "fake" functions that should return the previous recorded values. This way I could "replay" an execution, and check if the results match the original execution.
One important feature is to mock the time functions as well (sleep, time, GetLocalTime), because (for example) the calls to the DB may have the current date or time in the selects. It would be even better to be able to "replay" all the calls faster than the original execution (one day of execution could be replayed in a few minutes). For example a call to sleep(1000) should return without waiting, but successive calls to GetLocalTime should return 1 second more. This should take into account that other threads should have consistent values for the time (for example the library should allow 1 call to sleep(1000) for one thread and 10 calls to sleep(100) in another thread).
Ideally it shouldn't require a lot of changes or refactoring to the application, just redefining the calls to time functions as well as the calls to the libraries of the external interfaces (DB, TCP).
I would like to know if there exists some library or framework that implements these features or what could be a good starting point.
I have implemented several times solutions for similar problems, but for very simple modules, for example mocking a TCP connection to test a protocol implementation, but I feel like reinventing the wheel each time, and these simple solutions wouldn't scale well with more threads or interactions with more interfaces.
Upvotes: 0
Views: 921
Reputation: 624
Since you mention that your application is C/C++, I will assume you have the ability to use C frameworks. I will talk about CMock and Unity in this answer. If object oriented principles are more prevalent in your task, then you can take a look at googlemock which is similar to CMock, but developed for C++ and accounts for classes.
--
CMock in combination with Unity may provide a framework for your testing needs.
CMock provides you the ability to easily mock public interfaces. For example, if you had the following trivial code to test:
void sendPacket(char * packet, int packetLen, int tcpSocket)
{
if (packet)
{
send(tcpSocket, packet, packetLen, 0);
}
}
You could use CMock to create a mock of the send call. This would allow you to verify the parameters passed to send, and thus verify content in buffers. You would also be able to verify the size returned by send. CMock's ExpectAndReturn variant of the mocked send function would allow you to perform these two verifications.
CMock also allows you to provide callbacks for mocked functions through the StubWithCallback variant. StubWithCallback will allow you to manually verify each call, in addition to doing special checks. You would be able to utilize StubWithCallback to record number of times a function is called, or almost anything else you can imagine. You would also be able to use the StubWithCallback for your needs with time, sleep, etc. You can mock individual calls with different stub callbacks-- some threads will start with a stub sleep callback that immediately returns, while threads you specify for testing can use a stub sleep callback that performs the full sleep.
You can find more information on CMock here: https://www.throwtheswitch.org/cmock
Upvotes: 2