Skip to content
Robin Nicholson edited this page Apr 18, 2018 · 43 revisions

ELFspy is a library for linux for writing tests using fakes and spies in C++. For very large call graphs, the testing of the higher nodes can be difficult due to the sum of dependencies of lower nodes e.g. databases, network connections etc. Adding fakes and spies to the callees of a function allows it to be tested in isolation without the inherited dependencies.

ELFspy works by allowing the program to change function addresses in the global offset tables of the running program, so that these are redirected to a different function created by ELFspy. This allows new functions to be interjected between the caller and the callee to spy on the arguments and return value. In addition the original function can be replaced with a simulation (fake) of the original. The code under test needs no changes and is unaware of the additional calls that are being made in between a caller and a callee.

Call graph before change

External code:

auto add_spy = SPY(&add)

Call graph after change(the code does not change, but the runtime execution does)

This technique relies on code being compiled as position independent code and uses the Executable and Linking Format(ELF) information found in the executable and its shared libraries to find the global offset table entries and modify them.

To see how ELFspy can be used start by reading this example

Mocks offer a way to unit test classes by inheriting from them and overriding their virtual functions. It is not possible to use a mocked version of a class in a test context where the instantiation is not done using a class factory, or the class instance is on the stack, or the method that is to be mocked isn't virtual. In addition, mocking by inheritance cannot be used for static member functions or ordinary functions. Fakes overcome all these limitations by replacing the existing implementation with another one. Additionally the original implementation can be invoked, if done so explicitly.

With fakes it is possible to simulate errors that happen from operating system calls, by replacing the system call with an alternative one. With spies the original functions are called, but a spy "knows about" when, how and with which arguments it was called.

17/09/2016: ELFspy is very recently finished with the first version. If you know anything of relevance to make ELFspy better aligned to ELF standard, glibc implementation, more portable or otherwise see something that should be better, your contribution is welcome.

17/03/2018: Happy Paddy's day. New update for libc 2.27.