Skip to content
Advertisement

How to Mock Linux System Calls in C

When writing C modules that use linux system calls, what is the best practice to mock those calls in order to test the module? Are there maybe any libraries that offer mocks for linux system calls?

“my-module.h” – The interface description

#include "unistd.h"
int mm_foo(int);
int mm_bar(int);

“my-module.c” – The module to test.

#include "my-module.h"
int mm_foo(int arg) {

    ...
    int write_ret = write(...);
    ...

};
int mm_bar(int arg) {

    ...
    int read_ret = read(...);
    ...
};

“my-module.test.cpp” – The unit test the way I would expect this to work (I am using google unit test for example).

#include "my-module.h"

TEST(MyModule, FooTest) {

    reset(write_mock);

    ...

    // this is pure imagination
    write_mock.return_value = -1; // failure
    write_mock.expected_args.fd = somefd;

    int ret_val = mm_foo(somearg);

    ASSERT_EQ(exp_val, ret_val);
    verify(write_mock);

}

When I want to mock something that is no system call, I can just create an alternative implementation of the interface from the header file and compile a mocking implementation into the test. But how do I do this with system calls. Can I just reimplement (override) a function call? Should my module call a wrapper module for function calls?

Advertisement

Answer

In general, you want to create a wrapper for each system call you’re testing. A good way to do this and make your code easy to follow, would be just to use the ld option: --wrap. This lets you swap out symbols at build time without having to re-write your code to use your wrapper functions in place of the real libc functions.

Additionally, you could use LD_PRELOAD to override libc system call wrapper functions, like how rootkit/virus writers do, but there is more work involved than just using --wrap functionality.

Finally, you could utilize a unit test framework (i.e. CUnit) in your wrapper functions, simplifying your testing.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement