LTP 第一章 LTP介绍及内部机制
来源:互联网 发布:大数据新闻标题 编辑:程序博客网 时间:2024/06/07 22:24
LTP系列链接:
本文同步发布于我的个人网站:LTP教程
第一章 LTP介绍及内部机制
第二章 开发Shell测试集
第三章 开发系统调用测试集
第四章 开发_exit()测试集
第五章 开发IO操作测试集
第六章 开发IO阻塞测试集
1 LTP介绍及内部机制
1.1 LTP介绍
LTP(Linux Test Project),是基于GPL协议的开源社区合作项目。2000年由SGI发起,IBM、OSDL和Bull等公司共同参与,2001年后由SUSE、富士通、Red Hat、Oracle共同开发和维护。
通过功能测试
、压力测试
和回归测试
来验证Linux系统的可靠性、稳定性和健壮性。整个项目约4000个测试用例,绝大部分用例采用C或Shell。
LTP不仅测试内核,还测试整体系统环境,对功能执行失败时的返回和处理也进行测试。
1.1.1 功能测试
主要对man pages
中1、8命令和2系统调用所描述的功能进行验证。
1.1.2 回归测试
修改了旧代码后,重新进行测试已确认修改没有引入新的错误或导致其他代码产生错误。
1.1.3 压力测试
测试系统功能特性再大负荷压力下的稳定性和可靠性。
1.2 LTP环境部署
1.2.1 下载LTP
LTP项目目前位于GitHub,项目地址:https://github.com/linux-test-project/ltp
获取最新版可以执行以下命令:git clone https://github.com/linux-test-project/ltp.git
1.2.2 部署LTP
首先执行下面命令安装相关软件包(已安装可跳过):
#CentOSsudo yum install autoconf automake autotools-dev m4#Ubuntusudo apt-get install autoconf automake autotools-dev m4
在上节中我将ltp项目下载到了wxs用户的家目录(/home/wxs)下,如图所示:
[wxs@bogon ~]$ cd ltp/[wxs@bogon ltp]$ lsaclocal.m4 configure.ac INSTALL pan testcasesautom4te.cache confLkNw6U install-sh README.kernel_config testscriptsconfc20wzw COPYING lib README.md TODOconfig.guess doc ltpmenu runltp toolsconfig.log execltp m4 runltplite.sh utilsconfig.status execltp.in Makefile runtest ver_linuxconfig.sub IDcheck.sh Makefile.release scenario_groups Versionconfigure include missing scripts VERSION
进入ltp目录:cd ltp
生成自动工具:make autotools
系统环境配置:./configure
编译:make -j$(getconf_NPROCESSORS_ONLN)
安装:sudo make install
依次执行以上命令后,LTP已经被正确安装到你的Linux系统中,默认安装位于/opt/ltp/
。
[wxs@bogon ltp]$ cd /opt/ltp/[wxs@bogon ltp]$ lsbin runltp runtest share testscripts VersionIDcheck.sh runltplite.sh scenario_groups testcases ver_linux
需要注意的是,我们通过git clone
命令下载的位于home目录下的ltp文件夹为ltp源码文件夹,我将在后文简称为源码包
。
通过执行一系列命令安装到/opt
目录下的ltp文件夹为ltp安装文件夹,我将在后文简称为安装包
。
1.3 目录结构
1.3.1 源码包
LTP源码包目录结构描述如下:
LTP测试套件包含以下内容:
[wxs@bogon ~]$ cd ltp/testcases/[wxs@bogon testcases]$ lscommands demoA kernel Makefile network realtimecve kdump lib misc open_posix_testsuite
目录结构描述如下:
1.3.2 安装包
LTP安装包目录结构描述如下:
1.4 测试框架
1.4.1 整体测试流程
ltp安装包根目录下的runltp
脚本是LTP自动测试系统的入口,其提供了一系列参数选项,允许用户设定测试环境制定测试集、控制测试结果输出方式和路径等,运行runltp会生成指定的测试列表并调用测试驱动PAN
来开始测试,待执行完毕后根据PAN
返回的结果来生成报告。
PAN
是LTP的一组测试驱动程序,负责实际测试的执行,根据runltp传递的参数和测试列表来依次执行测试,输出执行过程中的详细信息,对每个测试用例的执行结果进行统计,并将整体测试结果返回给runltp。
1.4.2 测试用例执行流程
测试结果的输出类型如下:
1.4.3 测试库
LTP目前测试库存在新旧测试库交替的情况,本文均采用新测试库的框架,具体的更新说明可以参考更新文档An update on the Linux Test Project。
这里以umount02为例,比较新旧框架的区别:
旧框架代码:
//Example using the old LTP library//https://lwn.net/Articles/708250/#include <errno.h>#include <sys/mount.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/fcntl.h>#include <pwd.h>#include "test.h"#include "safe_macros.h"static void setup(void);static void cleanup(void);char *TCID = "umount02";#define DIR_MODE S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH#define FILE_MODE S_IRWXU | S_IRWXG | S_IRWXO#define MNTPOINT "mntpoint"static char long_path[PATH_MAX + 2];static int mount_flag;static int fd;static const char *device;static struct test_case_t { char *err_desc; char *mntpoint; int exp_errno; char *exp_retval;} testcases[] = { {"Already mounted/busy", MNTPOINT, EBUSY, "EBUSY"}, {"Invalid address space", NULL, EFAULT, "EFAULT"}, {"Directory not found", "nonexistent", ENOENT, "ENOENT"}, {"Invalid device", "./", EINVAL, "EINVAL"}, {"Pathname too long", long_path, ENAMETOOLONG, "ENAMETOOLONG"}};int TST_TOTAL = ARRAY_SIZE(testcases);int main(int ac, char **av){ int lc, i; tst_parse_opts(ac, av, NULL, NULL); setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; for (i = 0; i < TST_TOTAL; ++i) { TEST(umount(testcases[i].mntpoint)); if ((TEST_RETURN == -1) && (TEST_ERRNO == testcases[i].exp_errno)) { tst_resm(TPASS, "umount(2) expected failure; " "Got errno - %s : %s", testcases[i].exp_retval, testcases[i].err_desc); } else { tst_resm(TFAIL, "umount(2) failed to produce " "expected error; %d, errno:%s got %d", testcases[i].exp_errno, testcases[i].exp_retval, TEST_ERRNO); } } } cleanup(); tst_exit();}static void setup(void){ const char *fs_type; tst_sig(FORK, DEF_HANDLER, cleanup); tst_require_root(); tst_tmpdir(); fs_type = tst_dev_fs_type(); device = tst_acquire_device(cleanup); if (!device) tst_brkm(TCONF, cleanup, "Failed to obtain block device"); tst_mkfs(cleanup, device, fs_type, NULL, NULL); memset(long_path, 'a', PATH_MAX + 1); SAFE_MKDIR(cleanup, MNTPOINT, DIR_MODE); if (mount(device, MNTPOINT, fs_type, 0, NULL)) tst_brkm(TBROK | TERRNO, cleanup, "mount() failed"); mount_flag = 1; fd = SAFE_OPEN(cleanup, MNTPOINT "/file", O_CREAT | O_RDWR); TEST_PAUSE;}static void cleanup(void){ if (fd > 0 && close(fd)) tst_resm(TWARN | TERRNO, "Failed to close file"); if (mount_flag && tst_umount(MNTPOINT)) tst_resm(TWARN | TERRNO, "umount() failed"); if (device) tst_release_device(device); tst_rmdir();}
新框架代码:
//Example using the new LTP library//https://lwn.net/Articles/708251/#include <errno.h>#include <string.h>#include <sys/mount.h>#include "tst_test.h"#define MNTPOINT "mntpoint"static char long_path[PATH_MAX + 2];static int mount_flag;static int fd;static struct tcase { const char *err_desc; const char *mntpoint; int exp_errno;} tcases[] = { {"Already mounted/busy", MNTPOINT, EBUSY}, {"Invalid address", NULL, EFAULT}, {"Directory not found", "nonexistent", ENOENT}, {"Invalid device", "./", EINVAL}, {"Pathname too long", long_path, ENAMETOOLONG}};static void verify_umount(unsigned int n){ struct tcase *tc = &tcases[n]; TEST(umount(tc->mntpoint)); if (TEST_RETURN != -1) { tst_res(TFAIL, "umount() succeeds unexpectedly"); return; } if (tc->exp_errno != TEST_ERRNO) { tst_res(TFAIL | TTERRNO, "umount() should fail with %s", tst_strerrno(tc->exp_errno)); return; } tst_res(TPASS | TTERRNO, "umount() fails as expected: %s", tc->err_desc);}static void setup(void){ memset(long_path, 'a', PATH_MAX + 1); SAFE_MKFS(tst_device->dev, tst_device->fs_type, NULL, NULL); SAFE_MKDIR(MNTPOINT, 0775); SAFE_MOUNT(tst_device->dev, MNTPOINT, tst_device->fs_type, 0, NULL); mount_flag = 1; fd = SAFE_CREAT(MNTPOINT "/file", 0777);}static void cleanup(void){ if (fd > 0 && close(fd)) tst_res(TWARN | TERRNO, "Failed to close file"); if (mount_flag) tst_umount(MNTPOINT);}static struct tst_test test = { .tid = "umount02", .tcnt = ARRAY_SIZE(tcases), .needs_root = 1, .needs_tmpdir = 1, .needs_device = 1, .setup = setup, .cleanup = cleanup, .test = verify_umount,};
1.5 测试执行
1.5.1 整体测试
我们可以测试所有的测试集,直接运行runltp
命令将测试ltp/scenario_groups/default
中的所有测试集,一次测试约2~3小时。
[wxs@bogon ltp]$ cd /opt/ltp[wxs@bogon ltp]$ sudo ./runltp
当然我们可以只测试某个测试集,测试集可以在ltp/runtest/
下查看。
[wxs@bogon ltp]$ ls runtest/admin_tools ipc net_stress.ipsec_udpcan kernel_misc net_stress.multicastcap_bounds ltp-aiodio.part1 net_stress.routecommands ltp-aiodio.part2 net.tcp_cmdsconnectors ltp-aiodio.part3 net.tirpc_testscontainers ltp-aiodio.part4 network_commandscontrollers ltp-aio-stress.part1 nptlcpuhotplug ltp-aio-stress.part2 numacrashme ltplite pipescve lvm.part1 power_management_testsdio lvm.part2 power_management_tests_exclusivedma_thread_diotest math ptyfcntl-locktests mm quickhitfilecaps modules schedfs net.features scsi_debug.part1fs_bind net.ipv6 securebitsfs_ext4 net.ipv6_lib smackfs_perms_simple net.multicast stress.part1fs_readonly net.nfs stress.part2fsx net.rpc stress.part3hugetlb net.rpc_tests syscallshyperthreading net.sctp syscalls-ipcima net_stress.appl timersinput net_stress.broken_ip tpm_toolsio net_stress.interface tracingio_cd net_stress.ipsec_icmpio_floppy net_stress.ipsec_tcp[wxs@bogon ltp]$ sudo ./runltp -f modules
需要注意的是,如果我们测试某个测试集,runltp需要指定-f
参数。
1.5.2 单独测试
如果我们不想测试某个测试集,只想测试某个单独的测试,可以采用安装包测试或者源码包测试。下面以access01为例,讲解单独测试。
1.5.2.1 安装包测试
进入安装包,执行以下命令即可。
[wxs@bogon ltp]$ cd /opt/ltp/[wxs@bogon ltp]$ sudo ./runltp -s access01
需要注意的是,如果我们测试某个测试,runltp需要指定-s
参数。
1.5.2.2 源码包测试
进入源码包,找到access01的位置,直接执行./access01
即可。
[wxs@bogon access]$ cd ~/ltp/testcases/kernel/syscalls/access/[wxs@bogon access]$ sudo ./access01
我们看到access01位于testcases目录下,实际上testcases目录下每个文件都是一个完整的可执行程序,可以在编译后的源码路径直接执行。
1.6 牛刀小试
本节中牵扯到的项目均位于源码包testcases下自建的demoA文件夹中。测试方法均采用测试集
测试(C实现的测试用例可以采用源码测试和测试集测试,Shell实现的测试用例只可以采用测试集测试)。
[wxs@bogon ~]$ cd ~/ltp/testcases/[wxs@bogon testcases]$ mkdir demoA[wxs@bogon testcases]$ cd demoA/[wxs@bogon demoA]$ pwd/home/wxs/ltp/testcases/demoA
1.6.1 验证sqrt() 函数
参考1.3.3节中给出的示例代码,编写测试用例sqrt.c
:
#include <errno.h>#include <string.h>#include <sys/mount.h>#include "tst_test.h"static struct tcase { const int input; const int output;} tcases[] = { {-1,1}, {9,3}};static void testSqrt(unsigned int n){ struct tcase *tc = &tcases[n]; TEST(sqrt(tc->input)); if (TEST_RETURN != tc->output) { tst_res(TFAIL, "sqrt() failed"); return; } tst_res(TPASS, "sqrt() succeeds");}static struct tst_test test = { .tid = "testSqrt", .tcnt = ARRAY_SIZE(tcases), .test = testSqrt,};
参考testcases目录下的其他Makefile文件,编写Makefile
:
top_srcdir ?= ../..include $(top_srcdir)/include/mk/testcases.mkinclude $(top_srcdir)/include/mk/generic_leaf_target.mksqrt: LDLIBS += -lm
需要注意的是,这里的top_srcdir
指的是ltp目录,因为demoA目录位于ltp目录的内两层,所以使用了../..
。
还需要注意的是,要想成功使用sqrt命令必须附加-lm
参数,在Makefile中已经体现这一点。
执行make命令,生成可执行文件sqrt
:
[wxs@bogon demoA]$ makemake -C "/home/wxs/ltp/lib" -f "/home/wxs/ltp/lib/Makefile" allmake[1]: 进入目录“/home/wxs/ltp/lib”make[2]: 进入目录“/home/wxs/ltp/lib/newlib_tests”make[2]: 对“all”无需做任何事。make[2]: 离开目录“/home/wxs/ltp/lib/newlib_tests”make[2]: 进入目录“/home/wxs/ltp/lib/tests”make[2]: 对“all”无需做任何事。make[2]: 离开目录“/home/wxs/ltp/lib/tests”make[1]: 离开目录“/home/wxs/ltp/lib”gcc -g -O2 -g -O2 -fno-strict-aliasing -pipe -Wall -W -Wold-style-definition -D_FORTIFY_SOURCE=2 -I../../include -I../../include -I../../include/old/ -L../../lib sqrt.c -lltp -lm -o sqrtsqrt.c: 在函数‘testSqrt’中:sqrt.c:17:2: 警告:隐式声明函数‘sqrt’ [-Wimplicit-function-declaration] TEST(sqrt(tc->input)); ^In file included from sqrt.c:4:0:sqrt.c:17:7: 警告:隐式声明与内建函数‘sqrt’不兼容 [默认启用] TEST(sqrt(tc->input)); ^../../include/tst_test.h:176:17: 附注:in definition of macro ‘TEST’ TEST_RETURN = SCALL; \ ^
这里可以直接执行命令./sqrt
来运行这个测试用例,但是对于下节的shell测试用例就不能这样做了,本节我都将它写在自定义测试集中。
首先复制可执行文件sqrt
到安装包
的testcases/bin/
目录下:
[wxs@bogon demoA]$ sudo cp sqrt /opt/ltp/testcases/bin/
然后进入安装包
的runtest
目录下,编写自定义测试用例集demoA:
[wxs@bogon runtest]$ cat demoA sqrt sqrt
测试用例集中每个测试用例包括两部分:前部分为昵称,后部分为testcases/bin/
目录下的文件名,中间用空格
分隔。
进入上层目录,执行整体测试命令:
[wxs@bogon runtest]$ cd ..[wxs@bogon ltp]$ sudo ./runltp -f demoA
执行后程序会输出一大段,我们只需关心最重要的部分。我定义从<<<test_start>>>
到<<<test_end>>>
中间的内容为test体
,后文均以此称呼:
···<<<test_start>>>tag=sqrt stime=1506106767cmdline="sqrt"contacts=""analysis=exit<<<test_output>>>tst_test.c:915: INFO: Timeout per run is 0h 05m 00sincrementing stopsqrt.c:20: FAIL: sqrt() failedsqrt.c:23: PASS: sqrt() succeedsSummary:passed 1failed 1skipped 0warnings 0<<<execution_status>>>initiation_status="ok"duration=0 termination_type=exited termination_id=1 corefile=nocutime=0 cstime=0<<<test_end>>>···
可以看到,两个测试点一个FAIL,一个PASS。对照sqrt.c文件中给出的测试数据,发现测试没有问题。至此,一个简单的LTP测试用例就完成了。
1.6.2 验证echo命令
重新回到demoA文件夹中,编写echo.sh
文件,代码可以参考源码包中testcases/commands
中其他的测试用例:
#测试函数执行次数TST_CNT=1#测试用例启动函数TST_TESTFUNC=do_test. tst_test.shecho_test(){ local std_in=$1 local echo_cmd=$(echo $std_in > a.out) local echo_res=$std_in local cat_res=$(cat a.out) if [ $echo_res = $cat_res ] then tst_res TPASS "$echo_cmd sucessed" else tst_res TFAIL "$echo_cmd failed" fi}do_test(){ echo_test "hello\tworld"}tst_run
为echo.sh添加可执行权限,并复制到安装包中的testcases/bin/
目录中。
这里一定要注意,不可以在当前路径直接./echo.sh
执行测试用例!!
[wxs@bogon demoA]$ pwd/home/wxs/ltp/testcases/demoA[wxs@bogon demoA]$ sudo chmod +x echo.sh [wxs@bogon demoA]$ sudo cp echo.sh /opt/ltp/testcases/bin/
修改上一节中编写的demoA测试用例集,将echo.sh测试用例添加进去:
[wxs@bogon demoA]$ cd /opt/ltp/runtest/[wxs@bogon runtest]$ cat demoA sqrt sqrtecho echo.sh
注意了,此时测试用例集中包含了两个测试用例,那么后面运行该测试用例集将会执行这两个测试用例。
进入上层目录,执行整体测试命令:
[wxs@bogon runtest]$ cd ..[wxs@bogon ltp]$ sudo ./runltp -f demoA
结果输出依然很多,我们依然只看最关键的部分:
···<<<test_output>>>tst_test.c:915: INFO: Timeout per run is 0h 05m 00ssqrt.c:20: FAIL: sqrt() failedsqrt.c:23: PASS: sqrt() succeedsSummary:passed 1failed 1skipped 0warnings 0<<<execution_status>>>initiation_status="ok"duration=1 termination_type=exited termination_id=1 corefile=nocutime=0 cstime=0<<<test_end>>><<<test_start>>>tag=echo stime=1506107663cmdline="echo.sh"contacts=""analysis=exit<<<test_output>>>incrementing stop 1 TPASS: sucessedSummary:passed 1failed 0skipped 0warnings 0<<<execution_status>>>initiation_status="ok"duration=0 termination_type=exited termination_id=0 corefile=nocutime=2 cstime=5<<<test_end>>>···
本次测试输出包含两个test体,第一个test体我们在上一节已经说过了,我们直接看第二个test体。该体中共计有1个测试点,状态为TPASS。
对照echo.sh中的测试点,发现没有问题。
至此你已经学会了最基本的创建C和Shell的测试用例以及整体测试的方法,本章内容你已经完成了。
- LTP 第一章 LTP介绍及内部机制
- LTP介绍
- LTP介绍
- LTP介绍
- LTP
- LTP(Linux Test Project)介绍
- LTP(Linux Test Project)介绍
- LTP测试流程及分析
- ltp测试流程及分析
- ltp测试流程及分析
- ltp-2
- LTP算子
- LTP语法分析
- LTP资料
- LTP 简介
- ltp 测试流程及测试脚本分析
- ltp 测试流程及测试脚本分析
- ltp 测试流程及测试脚本分析
- php-fpm设置扩展无效 _解决_ phpinfo中Loaded Configuration File 为 none
- WingIDE 5的安装与破解方法
- 深圳牌具店
- 深圳牌具店
- 最近不知道怎么去赚钱了
- LTP 第一章 LTP介绍及内部机制
- Codeforces862E(函数处理,stl?)
- 最新wingide6破解方法(支持Linux),亲测有效,支持python3.0
- [java]Tetranacci
- [cv][dsp] filter
- 欢迎使用CSDN-markdown编辑器
- centos7 无法启动网络(service network restart)错误解决办法
- Linux_CentOS7配置主机名
- AngularJS开发WebApp高亮跳转按钮效果,ui-sref和ui-sref-active的使用