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…...
无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...
RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
