【问题标题】:How to Mock Linux System Calls in C如何在 C 中模拟 Linux 系统调用
【发布时间】:2017-07-09 21:51:49
【问题描述】:

在编写使用 linux 系统调用的 C 模块时,模拟这些调用以测试模块的最佳实践是什么?是否有任何库为 linux 系统调用提供模拟?

"my-module.h" - 接口说明

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

"my-module.c" - 要测试的模块。

#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" - 单元测试我期望它工作的方式(例如我使用谷歌单元测试)。

#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);

}

当我想模拟不是系统调用的东西时,我可以从头文件创建接口的替代实现并将模拟实现编译到测试中。但是我如何通过系统调用来做到这一点。我可以重新实现(覆盖)函数调用吗?我的模块是否应该为函数调用调用包装模块?

【问题讨论】:

  • @c650 - 为什么这里需要 MCVE?举个例子可以说明问题的哪一部分?
  • @OliverCharlesworth 这个问题对我来说似乎不完整,但我明白你的意思。

标签: c linux unit-testing mocking


【解决方案1】:

通常,您希望为要测试的每个系统调用创建一个包装器。 A good way to do this and make your code easy to follow, would be just to use the ld option: --wrap。这使您可以在构建时交换符号,而无需重新编写代码以使用包装函数代替真正的 libc 函数。

Additionally, you could use LD_PRELOAD to override libc system call wrapper functions,就像 rootkit/病毒编写者所做的那样,但涉及的工作不仅仅是使用 --wrap 功能。

最后,您可以在包装函数中使用utilize a unit test framework (i.e. CUnit),从而简化您的测试。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-21
    • 2021-09-05
    • 2015-07-02
    • 1970-01-01
    相关资源
    最近更新 更多