You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在功能测试中模拟inotify相关调用的失败场景?

终端用户视角的inotify应用故障场景功能测试套件

针对你的Linux inotify应用,我整理了一套可直接在终端执行的功能测试套件,重点覆盖你提到的各类inotify系统调用失败场景,全程从终端用户操作出发,不需要修改应用源码。


前置准备

  • 确保你的系统安装了gcc(用于编译hook动态库)
  • 创建一个临时测试目录:mkdir -p /tmp/inotify_test && cd /tmp/inotify_test
  • 备份你的应用配置(如果有),避免测试影响生产环境

1. inotify_init() 调用失败测试

这个场景模拟inotify初始化失败,比如系统文件描述符耗尽、内存不足等情况。

测试步骤:

  1. 创建一个hook动态库的源码文件inotify_init_fail.c:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <sys/inotify.h>
#include <errno.h>

// 重写inotify_init,强制返回失败并设置错误码
int inotify_init(void) {
    // 可选错误码:EMFILE(文件描述符过多)、ENOMEM(内存不足)
    errno = EMFILE;
    return -1;
}
  1. 编译动态库:
gcc -shared -fPIC inotify_init_fail.c -o libinotify_init_fail.so -ldl
  1. 运行你的应用并注入hook库:
LD_PRELOAD=./libinotify_init_fail.so ./your_inotify_application
  1. 预期结果:
    • 应用应检测到初始化失败,输出清晰的错误提示(比如Failed to initialize inotify: Too many open files)
    • 应用正常退出,无崩溃或无响应情况

2. inotify_add_watch() 调用失败测试

覆盖权限不足、watch数量超限、目标文件不存在等常见失败场景。

场景A:watch数量超限(ENOSPC)

  1. 临时降低系统inotify watch上限:
# 先备份原有值
sysctl -n fs.inotify.max_user_watches > /tmp/old_watch_limit
# 设置为1,即最多只能创建1个watch
sudo sysctl fs.inotify.max_user_watches=1
  1. 先手动创建一个watch占用配额:
# 执行后保持终端打开,不要关闭
inotifywait -m /tmp > /dev/null &
  1. 运行你的应用,让它尝试添加新的watch:
./your_inotify_application
  1. 预期结果:
    • 应用应检测到添加watch失败,输出类似Failed to add watch: No space left on device的错误
    • 应用能优雅处理(比如跳过该文件、提示用户或退出),不崩溃
  2. 恢复系统配置:
sudo sysctl fs.inotify.max_user_watches=$(cat /tmp/old_watch_limit)
kill %1 # 关闭之前的inotifywait进程

场景B:目标文件权限不足(EACCES)

  1. 创建一个无权限的测试文件:
sudo touch /tmp/protected_file && sudo chmod 000 /tmp/protected_file
  1. 配置你的应用监控这个文件,然后运行应用:
./your_inotify_application --watch /tmp/protected_file
  1. 预期结果:
    • 应用应提示权限不足的错误,不会崩溃
    • 可选择跳过该文件或终止监控流程

3. inotify_rm_watch() 调用失败测试

模拟移除无效watch描述符的场景。

测试步骤:

  1. 创建hook库inotify_rm_watch_fail.c:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <sys/inotify.h>
#include <errno.h>

// 重写inotify_rm_watch,强制返回失败
int inotify_rm_watch(int fd, int wd) {
    errno = EINVAL; // 无效的watch描述符错误
    return -1;
}
  1. 编译动态库:
gcc -shared -fPIC inotify_rm_watch_fail.c -o libinotify_rm_watch_fail.so -ldl
  1. 运行应用并注入hook:
LD_PRELOAD=./libinotify_rm_watch_fail.so ./your_inotify_application
  1. 预期结果:
    • 当应用尝试移除watch时,应检测到错误并输出提示(比如Failed to remove watch: Invalid argument)
    • 应用不会崩溃,可继续运行或优雅退出

4. read() 调用失败测试

模拟读取inotify事件时的I/O错误、信号中断等场景。

场景A:强制read()返回错误

  1. 创建hook库inotify_read_fail.c:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <unistd.h>
#include <errno.h>

// 重写read,针对inotify fd返回失败
ssize_t read(int fd, void *buf, size_t count) {
    // 先获取原始read函数
    static ssize_t (*original_read)(int, void*, size_t) = NULL;
    if (!original_read) {
        original_read = dlsym(RTLD_NEXT, "read");
    }

    // 强制返回EIO错误(模拟I/O故障)
    errno = EIO;
    return -1;
}
  1. 编译动态库:
gcc -shared -fPIC inotify_read_fail.c -o libinotify_read_fail.so -ldl
  1. 运行应用:
LD_PRELOAD=./libinotify_read_fail.so ./your_inotify_application
  1. 预期结果:
    • 应用应检测到读取事件失败,输出类似Failed to read inotify events: Input/output error的提示
    • 应用可选择重试读取或优雅退出

场景B:信号中断read()

  1. 运行你的应用:
./your_inotify_application &
APP_PID=$!
  1. 向应用发送SIGINT信号中断read调用:
kill -SIGINT $APP_PID
  1. 预期结果:
    • 应用应处理信号中断,不会崩溃
    • 可选择恢复监控或正常退出

测试清理

完成所有测试后,清理临时文件和配置:

cd /tmp/inotify_test
rm -f *.so *.c
rm -rf /tmp/inotify_test

内容的提问来源于stack exchange,提问作者Gill Bates

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:18:58