gtest单元测试:进程冻结与恢复管理模块的单元测试实现
文章目录
- 1. 概要
- 2. 进程管理接口详解
- 2.1 进程冻结与恢复的基本概念
- 2.2 进程查找与PID获取
- 2.3 进程冻结与恢复的实现
- 2.3.1 进程冻结
- 2.3.2 进程恢复
- 2.4 进程终止
- 2.5 进程状态监控与控制
- 3. dummy_process的设计与实现
- 3.1 创建dummy_process脚本
- 3.2 启动dummy_process
- 3.3 终止dummy_process
- 4. GTest单元测试代码详解
- 4.1 测试框架和测试结构
- 4.2 单元测试用例
- 4.2.1 测试冻结功能 `FreezeProcessByPidTest`
- 4.2.2 测试恢复功能 `TryToResumeProcessByPidTest`
- 4.2.3 测试终止功能 `TerminateProcessTest`
- 5. 运行和验证
1. 概要
在Linux系统中,进程的管理涉及到对进程状态的控制,特别是进程的冻结(暂停)和恢复(继续执行)功能对系统管理和调试非常重要。
本文将展示如何使用Google Test(gtest)编写针对进程冻结与恢复功能的单元测试。
- 完整代码见process_helper
- 提前阅读Linux C++编程-实现进程的冻结与恢复管理模块
2. 进程管理接口详解
2.1 进程冻结与恢复的基本概念
在Linux环境中,进程的管理涉及到对进程执行状态的控制,其中包括了进程的冻结(暂停)和恢复(继续执行)。这些操作通过发送特定的信号来实现,主要使用到 SIGSTOP 和 SIGCONT 信号。
2.2 进程查找与PID获取
为了准确控制目标进程,首先需要能够根据进程名称或者其他标识符获取到进程的PID。在Linux系统中,可以通过读取 /proc 文件系统来获取所有运行中进程的详细信息,包括进程的命令行参数和状态。
/*** @brief Function to find the PID of a process by its name* @param [in] processName process name* @param [out] pid process id* @return true - find pid by process name; false - not find pid by process name*/
bool FindPidByProcessName(const std::string& processName, pid_t &pid);
2.3 进程冻结与恢复的实现
2.3.1 进程冻结
进程冻结通过发送 SIGSTOP 信号来实现,暂停进程的执行。实现方法包括使用 kill(pid, SIGSTOP) 函数调用,并等待进程状态确认操作成功。
/*** @brief freeze process by pid** @param [in] pid - pid find by process name.* @return true - Freeze successfully; false - Freeze failed*/
bool FreezeProcessByPid(pid_t pid);
2.3.2 进程恢复
一旦进程被冻结,可以通过发送 SIGCONT 信号来恢复其执行。恢复过程中可能需要多次尝试,以确保进程成功从暂停状态恢复到执行状态。
/*** @brief try to resume a stopped process by pid** @param [in] attempts - if resume failed, try another attempts times.* @param [in] pid - pid find by process name.* @return true - Resume successfully; false - Resume failed*/
bool TryToResumeProcessByPid(pid_t pid, int attempts = 3);
2.4 进程终止
在某些情况下,需要强制终止一个进程以释放系统资源或确保安全性。可以使用 SIGKILL 信号立即终止进程的执行,但需要注意可能会造成数据丢失。
/*** @brief terminate a process** @param [in] processName - process name.* @param [in] attempts - if resume failed, try another attempts times.* @return 0 - successfully; -1 - not found process; -2 terminate failed* -3 - Handle waitpid error*/
int TerminateProcess(const std::string& processName, int attempts = 3);
2.5 进程状态监控与控制
在实现进程管理功能时,还需要监控进程的状态并根据需要进行控制。通过读取 /proc/[pid]/status 文件可以获取进程的详细状态信息,如是否处于停止状态。
/*** @brief Function to check if the process is not in stopped state** @param [in] pid - pid find by process name* @return true - stopped; false - not stopped*/
bool IsProcessStopped(pid_t pid);
确实,dummy_process是我们测试进程管理功能的一个重要组成部分。我们需要详细分析它的设计和实现,以便更好地理解整个测试框架。下面我们将详细介绍dummy_process的创建和管理过程,并分析其在单元测试中的作用。
3. dummy_process的设计与实现
为了测试进程管理功能,我们需要一个可以启动、冻结、恢复和终止的模拟进程。我们将创建一个名为dummy_process的shell脚本,该脚本将作为我们的模拟进程。通过这个脚本,我们可以在测试中验证进程管理功能的各个方面。
3.1 创建dummy_process脚本
dummy_process脚本是一个简单的无限循环脚本,它能够响应特定的信号(如SIGTERM)。我们使用C++程序来创建这个脚本,并确保它具有可执行权限。
void CreateDummyProcessScript(const std::string& scriptPath) {std::ofstream scriptFile(scriptPath);if (scriptFile.is_open()) {scriptFile << "#!/bin/bash\n";scriptFile << "\n";scriptFile << "# Function to handle signals\n";scriptFile << "function handle_signal() {\n";scriptFile << " echo \"[dummy_process] Received signal: $1\"\n";scriptFile << " exit 0\n"; // Exit gracefully on signalscriptFile << "}\n";scriptFile << "\n";scriptFile << "# Trap signals\n";scriptFile << "trap 'handle_signal SIGTERM' SIGTERM\n"; // Handle SIGTERM signalscriptFile << "\n";scriptFile << "# Main loop\n";scriptFile << "while true; do\n";scriptFile << " echo \"dummy_process is running...\"\n";scriptFile << " sleep 1\n";scriptFile << "done\n";scriptFile.close();// Add executable permission to the scriptif (chmod(scriptPath.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == -1) {std::cerr << "Failed to set execute permission on " << scriptPath << std::endl;exit(EXIT_FAILURE);}} else {std::cerr << "Failed to create " << scriptPath << std::endl;exit(EXIT_FAILURE);}
}
3.2 启动dummy_process
在每个测试用例运行之前,我们需要启动dummy_process。这里我们使用fork()和execlp()函数来创建一个子进程,并在子进程中运行dummy_process脚本。
pid_t StartDummyProcess() {pid_t pid = fork();if (pid == -1) {std::cerr << "Failed to fork() process." << std::endl;return -1;} else if (pid == 0) {// Child process: execute dummy_process scriptexeclp(dummyScriptPath.c_str(), dummyScriptPath.c_str(), nullptr);// execlp should not return if successfulstd::cerr << "Failed to exec " << dummyScriptPath << std::endl;exit(EXIT_FAILURE);} else {// Parent process: return child process PIDreturn pid;}
}
3.3 终止dummy_process
在每个测试用例运行之后,我们需要终止dummy_process以清理环境。这里我们使用kill()函数发送SIGKILL信号,并使用waitpid()等待子进程终止。
void TerminateDummyProcess(pid_t pid) {// Send SIGKILL to dummy_processkill(pid, SIGKILL);// Wait for child process to endint status;waitpid(pid, &status, 0);
}
4. GTest单元测试代码详解
4.1 测试框架和测试结构
测试夹具 ProcessHelperTest 管理测试过程中的环境准备和清理工作,包括创建、启动和终止dummy_process。
class ProcessHelperTest : public ::testing::Test {protected:pid_t dummyProcessPid;std::string dummyScriptPath = "./dummy_process"; // Path to dummy_process shell scriptvoid SetUp() override {// 创建 dummy_process shell 脚本并启动CreateDummyProcessScript(dummyScriptPath);dummyProcessPid = StartDummyProcess();ASSERT_NE(dummyProcessPid, -1); // 检查 dummy_process 启动成功}void TearDown() override {// 结束 dummy_processTerminateDummyProcess(dummyProcessPid);// 清理 dummy_process shell 脚本std::remove(dummyScriptPath.c_str());}
};
4.2 单元测试用例
4.2.1 测试冻结功能 FreezeProcessByPidTest
TEST_F(ProcessHelperTest, FreezeProcessByPidTest) {pid_t pid;bool find = FindPidByProcessName("dummy_process", pid);EXPECT_TRUE(find); // 预期找到进程的PIDbool result = FreezeProcessByPid(pid);EXPECT_TRUE(result); // 预期冻结操作成功ASSERT_TRUE(IsProcessRunning("dummy_process")); // 检查进程仍在运行ASSERT_TRUE(IsProcessStopped(dummyProcessPid)); // 检查进程是否被成功冻结
}
4.2.2 测试恢复功能 TryToResumeProcessByPidTest
TEST_F(ProcessHelperTest, TryToResumeProcessByPidTest) {pid_t pid;bool find = FindPidByProcessName("dummy_process", pid);EXPECT_TRUE(find); // 预期找到进程的PIDbool result = TryToResumeProcessByPid(pid, 3);EXPECT_TRUE(result); // 预期恢复操作成功ASSERT_TRUE(IsProcessRunning("dummy_process")); // 检查进程仍在运行ASSERT_FALSE(IsProcessStopped(dummyProcessPid)); // 检查进程是否已恢复执行
}
4.2.3 测试终止功能 TerminateProcessTest
TEST_F(ProcessHelperTest, TerminateProcessTest) {int result = TerminateProcess("dummy_process", 3);EXPECT_EQ(result, 0); // 预期终止操作成功ASSERT_FALSE(IsProcessRunning("dummy_process")); // 检查进程是否已终止
}
5. 运行和验证
测试程序的主函数调用了 RUN_ALL_TESTS() 来执行所有测试用例。在运行过程中,每个测试用例会被独立执行,并根据 EXPECT_ 和 ASSERT_ 宏的断言结果判断测试是否通过。
int main(int argc, char** argv) {testing::InitGoogleMock(&argc, argv);return RUN_ALL_TESTS();
}
单元测试结果:
$ ./process_helper_test
[==========] Running 6 tests from 2 test suites.
[----------] Global test environment set-up.
[----------] 5 tests from ProcessHelperTest
[ RUN ] ProcessHelperTest.FreezeProcessByNameTest
dummy_process is running...
Success to send SIGSTOP to process 12780
Process 12780 status is T is in stopped state.
Process 12780 freeze success.
processName dummy_process pid 12780 freeze success.
Process 12780 status is T is in stopped state.
[ OK ] ProcessHelperTest.FreezeProcessByNameTest (9 ms)
[ RUN ] ProcessHelperTest.TryToResumeProcessByNameTest
dummy_process is running...
Process 12782 status is S is not in stopped state.
Process 12782 resumed successfully.
Process 12782 status is S is not in stopped state.
[ OK ] ProcessHelperTest.TryToResumeProcessByNameTest (25 ms)
[ RUN ] ProcessHelperTest.FreezeProcessByPidTest
dummy_process is running...
Success to send SIGSTOP to process 12784
Process 12784 status is T is in stopped state.
Process 12784 freeze success.
Process 12784 status is T is in stopped state.
[ OK ] ProcessHelperTest.FreezeProcessByPidTest (14 ms)
[ RUN ] ProcessHelperTest.TryToResumeProcessByPidTest
dummy_process is running...
Process 12786 status is S is not in stopped state.
Process 12786 resumed successfully.
Process 12786 status is S is not in stopped state.
[ OK ] ProcessHelperTest.TryToResumeProcessByPidTest (16 ms)
[ RUN ] ProcessHelperTest.TerminateProcessTest
dummy_process is running...
Process with PID: 12788 has been terminated.
[ OK ] ProcessHelperTest.TerminateProcessTest (6 ms)
[----------] 5 tests from ProcessHelperTest (74 ms total)[----------] 1 test from IsProcessStoppedTest
[ RUN ] IsProcessStoppedTest.IsStoppedTest
[ OK ] IsProcessStoppedTest.IsStoppedTest (0 ms)
[----------] 1 test from IsProcessStoppedTest (1 ms total)[----------] Global test environment tear-down
[==========] 6 tests from 2 test suites ran. (77 ms total)
[ PASSED ] 6 tests.
相关文章:
gtest单元测试:进程冻结与恢复管理模块的单元测试实现
文章目录 1. 概要2. 进程管理接口详解2.1 进程冻结与恢复的基本概念2.2 进程查找与PID获取2.3 进程冻结与恢复的实现2.3.1 进程冻结2.3.2 进程恢复 2.4 进程终止2.5 进程状态监控与控制 3. dummy_process的设计与实现3.1 创建dummy_process脚本3.2 启动dummy_process3.3 终止du…...
Flutter动画详解第二篇之显式动画(Explicit Animations)
目录 前言 一、定义 1.AnimationController 1.常用属性 1. value 2. status 3. duration 2.常用方法 1.forward 2.reverse 3.repeat 4.stop 5. reset 6. animateTo(double target, {Duration? duration, Curve curve Curves.linear}) 7.animateBack(double ta…...
python常用模块(JSON与pickle、Os模块)
一、Open函数使用 在python中,open() 函数用于打开文件,并返回一个文件对象,同时支持读取和写入文件。 基本用法: file open(file_path, moder, encodingNone, newlineNone) 其中file_path表示的是文件的路径,可以…...
MMLab-dataset_analysis
数据分析工具 这里写目录标题 数据分析工具dataset_analysis.py数据可视化分析 benchmark.pybrowse_coco_json.pybrowse_dataset.pyOptimize_anchors mmyolo、mmsegmentation等提供了数据集分析工具 dataset_analysis.py 数据采用coco格式数据 根据配置文件分析全部数据类型或…...
艺术与技术的交响曲:CSS绘图的艺术与实践
在前端开发的世界里,CSS(层叠样式表)作为网页布局和样式的基石,其功能早已超越了简单的颜色和间距设置。近年来,随着CSS3的普及,开发者们开始探索CSS在图形绘制方面的潜力,用纯粹的代码创造出令…...
基于 JAVA 的旅游网站设计与实现
点击下载源码 塞北村镇旅游网站设计 摘要 城市旅游产业的日新月异影响着村镇旅游产业的发展变化。网络、电子科技的迅猛前进同样牵动着旅游产业的快速成长。随着人们消费理念的不断发展变化,越来越多的人开始注意精神文明的追求,而不仅仅只是在意物质消…...
【C++深度探索】二叉搜索树的全面解析与高效实现
🔥 个人主页:大耳朵土土垚 🔥 所属专栏:C从入门至进阶 这里将会不定期更新有关C/C的内容,欢迎大家点赞,收藏,评论🥳🥳🎉🎉🎉 文章目录…...
Java实习记录 1 ——初入职场
Java实习记录 1 ——初入职场 引言正文收获 引言 在几个月的春招过程中,在完成学校学业的同时,进行投简历、笔试和面试。得益于较为扎实的技术基础,在暑假来临之际,找到了第一份实习工作。目前已入职将近半个月。记录一下实习经历…...
opencv—常用函数学习_“干货“_3
目录 八、图像拼接 水平拼接图像 (hconcat) 垂直拼接图像 (vconcat) 全景图像拼接 (Stitcher) 九、颜色通道及数据格式 转换图像的颜色空间 (cvtColor) 转换图像的数据类型 (convertTo) 分离和合并颜色通道 (split 和 merge) 提取和插入颜色通道 (extractChannel 和 in…...
用Docker来开发
未完成。。。 现在好像用Docker是越来越多了。之前其实也看过docker的原理,大概就是cgroup那些,不过现在就不看原理了,不谈理论,只看实际中怎么用,解决眼前问题。 用docker来做开发,其实就是解决的编译环境…...
从0开始的STM32HAL库学习2
外部中断(HAL库GPIO讲解) 今天我们会详细地学习STM32CubeMX配置外部中断,并且讲解HAL库的GPIO的各种函数。 准备工作: 1、STM32开发板(我的是STM32F103C8T6) 2、STM32CubeMx软件、 IDE: Keil软件 3、STM32F1xx/ST…...
【MySQL篇】Percona XtraBackup工具备份指南:常用备份命令详解与实践(第二篇,总共五篇)
💫《博主介绍》:✨又是一天没白过,我是奈斯,DBA一名✨ 💫《擅长领域》:✌️擅长Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式数据仓库)、Linux,也在扩展大数据方向的知识面✌️…...
Spock单元测试框架使用介绍和实践
背景 单元测试是保证我们写的代码是我们想要的结果的最有效的办法。根据下面的数据图统计,单元测试从长期来看也有很大的收益。 单元测试收益: 它是最容易保证代码覆盖率达到100%的测试。可以⼤幅降低上线时的紧张指数。单元测试能更快地发现问题。单元测试的性…...
web安全之跨站脚本攻击xss
定义: 后果 比如黑客可以通过恶意代码,拿到用户的cookie就可以去登陆了 分类 存储型 攻击者把恶意脚本存储在目标网站的数据库中(没有过滤直接保存),当用户访问这个页面时,恶意脚本会从数据库中被读取并在用户浏览器中执行。比如在那些允许用户评论的…...
TCP与UDP的理解
文章目录 UDP协议UDP协议的特点UDP的应用以及杂项 TCP协议TCP协议段格式解释和TCP过程详解确认应答机制 -- 序号和确认序号以及6位标志位中的ACK超时重传机制连接管理机制 与标志位SYN,FIN,ACK滑动窗口与16位窗口大小流量控制拥塞控制延迟应答捎带应答和面向字节流粘包问题TCP异…...
有效应对服务器遭受CC攻击的策略与实践
分布式拒绝服务(DDoS)攻击,尤其是其中的HTTP洪水攻击或称为CC攻击(Challenge Collapsar),是当今互联网安全领域的一大挑战。这种攻击通过大量合法的请求占用大量网络资源,导致服务器无法正常响应…...
STM32判断休眠
STM32是否进入休眠模式(或称为睡眠模式)的判断主要基于其功耗状态、内部时钟的关闭情况以及唤醒后的行为。以下是根据参考文章提供的信息,判断STM32是否进入休眠模式的方法: 功耗状态: STM32在休眠模式下,功耗会显著降低。这是因为休眠模式仅关闭了内核时钟,但外设仍然保…...
TikTok内嵌跨境商城全开源_搭建教程/前端uniapp+后端源码
多语言跨境电商外贸商城 TikTok内嵌商城,商家入驻一键铺货一键提货 全开源完美运营,接在tiktok里面的商城内嵌,也可单独分开出来当独立站运营 二十一种语言,可以做很多国家的市场,支持商家入驻,多店铺等等…...
前端学习(二)
这篇文章是紧接着前一篇前端学习写的,主要要写的是js剩下的基础知识 事件的绑定 什么是事件? HTML 事件可以是浏览器行为,也可以是用户行为。 当这些一些行为发生时,可以自动触发对应的JS函数的运行,我们称之为事件发生.JS的事件驱动指的就是…...
链接追踪系列-10.mall-swarm微服务运行并整合elk-上一篇的番外
因为上一篇没对微服务代码很详细地说明,所以在此借花献佛,使用开源的微服务代码去说明如何去做链路追踪。 项目是开源项目,fork到github以及gitee中,然后拉取到本地 后端代码: https://gitee.com/jelex/mall-swarm.gi…...
【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
comfyui 工作流中 图生视频 如何增加视频的长度到5秒
comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗? 在ComfyUI中实现图生视频并延长到5秒,需要结合多个扩展和技巧。以下是完整解决方案: 核心工作流配置(24fps下5秒120帧) #mermaid-svg-yP…...
论文阅读:Matting by Generation
今天介绍一篇关于 matting 抠图的文章,抠图也算是计算机视觉里面非常经典的一个任务了。从早期的经典算法到如今的深度学习算法,已经有很多的工作和这个任务相关。这两年 diffusion 模型很火,大家又开始用 diffusion 模型做各种 CV 任务了&am…...
海云安高敏捷信创白盒SCAP入选《中国网络安全细分领域产品名录》
近日,嘶吼安全产业研究院发布《中国网络安全细分领域产品名录》,海云安高敏捷信创白盒(SCAP)成功入选软件供应链安全领域产品名录。 在数字化转型加速的今天,网络安全已成为企业生存与发展的核心基石,为了解…...
Xcode 16 集成 cocoapods 报错
基于 Xcode 16 新建工程项目,集成 cocoapods 执行 pod init 报错 ### Error RuntimeError - PBXGroup attempted to initialize an object with unknown ISA PBXFileSystemSynchronizedRootGroup from attributes: {"isa">"PBXFileSystemSynchro…...
EEG-fNIRS联合成像在跨频率耦合研究中的创新应用
摘要 神经影像技术对医学科学产生了深远的影响,推动了许多神经系统疾病研究的进展并改善了其诊断方法。在此背景下,基于神经血管耦合现象的多模态神经影像方法,通过融合各自优势来提供有关大脑皮层神经活动的互补信息。在这里,本研…...
vxe-table vue 表格复选框多选数据,实现快捷键 Shift 批量选择功能
vxe-table vue 表格复选框多选数据,实现快捷键 Shift 批量选择功能 查看官网:https://vxetable.cn 效果 代码 通过 checkbox-config.isShift 启用批量选中,启用后按住快捷键和鼠标批量选取 <template><div><vxe-grid v-bind"gri…...
