diff --git a/.gitee/ISSUE_TEMPLATE/config.yaml b/.gitee/ISSUE_TEMPLATE/config.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2f363146febe2481e59e0692d17238c7295d48f3 --- /dev/null +++ b/.gitee/ISSUE_TEMPLATE/config.yaml @@ -0,0 +1,30 @@ +name: Bug 反馈 +description: 当你在代码中发现了一个 Bug,导致应用崩溃或抛出异常,或者有一个组件存在问题,或者某些地方看起来不对劲。 +title: "[Bug]: " +labels: ["bug"] +body: + - type: textarea + attributes: + label: 如何复现 + description: 请详细告诉我们如何复现你遇到的问题,如涉及代码,可提供一个最小代码示例,并使用反引号```附上它 + placeholder: | + 问题描述 + 内核版本: + OS 版本: + 平台架构: + 相关日志: + + 复现方法 + + 实际效果 + + 期望效果 + + validations: + required: true + - type: textarea + attributes: + label: 截图或视频 + description: 如果可以的话,上传任何关于 bug 的截图。 + value: | + [在这里上传图片] diff --git a/docs/apps/duktape/tc_duktape_fun_001.yaml b/docs/apps/duktape/tc_duktape_fun_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..9cb9e4a4e6d7db717ffedcc22a14e85af034e22e --- /dev/null +++ b/docs/apps/duktape/tc_duktape_fun_001.yaml @@ -0,0 +1,43 @@ +作者: zhixin +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 使用Duktape API来执行JavaScript代码段 +修改人: zhixin + +前置条件: +- 安装duktape、duktape-devel软件包 +- 创建javascript_sim.c文件 +#include "duktape.h" +#include + +int main(void) { + duk_context *ctx = duk_create_heap_default(); + if (!ctx) { + printf("Failed to create a Duktape heap.\\n"); + return 1; + } + + duk_eval_string(ctx, "123 + 456"); + if (duk_is_number(ctx, -1)) { + printf("123 + 456 = %.6f\\n", duk_get_number(ctx, -1)); + } else { + printf("The evaluation did not return a number!\\n"); + } + + duk_destroy_heap(ctx); + return 0; +} + +测试步骤: +- 编译javascript_sim.c文件 +gcc -o javascript_sim javascript_sim.c -lduktape +- 执行命令`ldd ./javascript_sim`,查看依赖的动态链接库 +- 运行./javascript_sim + +期望结果: +- 编译成功 +- 命令执行成功,返回结果中包含'libduktape.so' +- 命令执行成功,返回结果包含 "123 + 456 = 579.000000" diff --git a/docs/apps/inih/tc_inih_fun_001.yaml b/docs/apps/inih/tc_inih_fun_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..879379d7e4b580576b7e95368af17976905d2c04 --- /dev/null +++ b/docs/apps/inih/tc_inih_fun_001.yaml @@ -0,0 +1,52 @@ +作者: zhixin +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 验证解析INI文件的基本功能 +修改人: zhixin + +前置条件: +- 安装inih、inih-devel软件包 +- 创建print_ini.c文件 +#include +#include + +// 定义解析INI文件时的回调函数 +static int handler(void* user, const char* section, const char* name, const char* value) +{ + printf("Section [%s] Key %s = %s\\n", section, name, value); + return 1; // 返回1表示成功解析 +} + +int main(int argc, char* argv[]) +{ + if (argc < 2) { + fputs("Usage: print_ini \\n", stderr); + return 1; + } + + if (ini_parse(argv[1], handler, NULL) < 0) { + printf("Can't load '%s' file\\n", argv[1]); + return 1; + } + return 0; +} +- 创建file.ini文件 +[database] +server=127.0.0.1 +port=3306 +user=root +password=s3cr3t + +测试步骤: +- 编译print_ini.c文件 +gcc print_ini.c -o print_ini -linih +- 执行命令`ldd ./print_ini`,查看依赖的动态链接库 +- 执行命令`./print_ini file.ini`,解析file.ini文件 + +期望结果: +- 编译成功 +- 命令执行成功,返回结果中包含'libinih.so.0' +- 解析文件成功,返回"Section [database] Key server = 127.0.0.1\nSection [database] Key port = 3306\nSection [database] Key user = root\nSection [database] Key password = s3cr3t" diff --git a/docs/apps/inih/tc_inih_fun_002.yaml b/docs/apps/inih/tc_inih_fun_002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..bef4fe9bbc24d833e018887a324d29927be43322 --- /dev/null +++ b/docs/apps/inih/tc_inih_fun_002.yaml @@ -0,0 +1,48 @@ +作者: zhixin +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 编写c++文件验证解析INI文件的基本功能 +修改人: zhixin + +前置条件: +- 创建myapp.cpp文件 +#include +#include + +int main() { + INIReader reader("example.ini"); + + if (reader.ParseError() < 0) { + std::cout << "Can't load 'example.ini'\\n"; + return 1; + } + + std::string name = reader.Get("owner", "name", "UNKNOWN"); + std::string organization = reader.Get("owner", "organization", "UNKNOWN"); + + std::cout << "Owner name: " << name << "\\n" + << "Organization: " << organization << std::endl; + + return 0; +} + +- 创建example.ini文件 +[owner] +name=John Doe +organization=Acme Widgets Inc. + +测试步骤: +- 编译myapp.cpp文件 +g++ myapp.cpp -o myapp -lINIReader +- 执行命令`ldd ./myapp`,查看依赖的动态链接库 +- 执行命令`./myapp`,解析example.ini文件 +- 删除example.ini,执行命令`./myapp > result.log 2>&1`,查看result.log文件 + +期望结果: +- 编译成功 +- 命令执行成功,返回结果中包含'libINIReader.so.0'和'libinih.so.0' +- 文件解析成功,返回 "Owner name: John Doe\nOrganization: Acme Widgets Inc." +- result.log内容展示"Can't load 'example.ini'" diff --git a/docs/apps/inih/tc_inih_fun_003.yaml b/docs/apps/inih/tc_inih_fun_003.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d45c485a1ec27d386b58fa2e671a488b6cda9a0e --- /dev/null +++ b/docs/apps/inih/tc_inih_fun_003.yaml @@ -0,0 +1,57 @@ +作者: zhixin +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 验证INI文件中包含特殊字符、多节点、注释、节点下有重复的键值时可以正常解析 +修改人: zhixin + +前置条件: +- 创建print_ini.c文件 +#include +#include + +// 定义解析INI文件时的回调函数 +static int handler(void* user, const char* section, const char* name, const char* value) +{ + printf("Section [%s] Key %s = %s\\n", section, name, value); + return 1; // 返回1表示成功解析 +} + +int main(int argc, char* argv[]) +{ + if (argc < 2) { + fputs("Usage: print_ini \\n", stderr); + return 1; + } + + if (ini_parse(argv[1], handler, NULL) < 0) { + printf("Can't load '%s' file\\n", argv[1]); + return 1; + } + return 0; +} + +- 创建file.ini文件 +[database] +server=127.0.0.1 +port=3306 +user=root +user=root +#name=John +password=s3cr3t +[owner] +name=John Doe +organization=Acme Widgets Inc. + +测试步骤: +- 编译print_ini.c文件 +gcc print_ini.c -o print_ini -linih +- 执行命令`./print_ini file.ini > result.log`,解析文件 +- 查看result.log + +期望结果: +- 编译成功 +- 文件解析成功 +- result.log内容包括"Section [owner] Key name = John Doe"以及2个相同键值"Key user = root",不包括"Section [database] Key name = John" diff --git a/docs/apps/inih/tc_inih_fun_004.yaml b/docs/apps/inih/tc_inih_fun_004.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e607bca3730a7aa350441cb7052d3031645285a3 --- /dev/null +++ b/docs/apps/inih/tc_inih_fun_004.yaml @@ -0,0 +1,56 @@ +作者: zhixin +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 验证输入异常时解析功能 +修改人: zhixin + +前置条件: +- 创建print_ini.c文件 +#include +#include + +// 定义解析INI文件时的回调函数 +static int handler(void* user, const char* section, const char* name, const char* value) +{ + printf("Section [%s] Key %s = %s\\n", section, name, value); + return 1; // 返回1表示成功解析 +} + +int main(int argc, char* argv[]) +{ + if (argc < 2) { + fputs("Usage: print_ini \\n", stderr); + return 1; + } + + if (ini_parse(argv[1], handler, NULL) < 0) { + printf("Can't load '%s' file\\n", argv[1]); + return 1; + } + return 0; +} + +- 创建file_end_txt.txt文件 +[owner] +name=John Doe +organization=Acme Widgets Inc. + +- 创建file_no_header.ini文件 +name=John Doe +organization=Acme Widgets Inc. + +测试步骤: +- 编译print_ini.c文件 +gcc print_ini.c -o print_ini -linih +- 执行命令`./print_ini aaa.ini > result.log 2>&1`解析文件,其中aaa.ini不存在 +- 执行命令`./print_ini file_end_txt.txt`解析文件,INI文件以.txt为后缀 +- 执行命令`./print_ini file_no_header.ini`解析文件,其中INI文件无节点 + +期望结果: +- 编译成功 +- 命令执行失败,结果返回"Can't load 'aaa.ini' file" +- 命令执行成功,结果返回"Section [owner] Key name = John Doe\nSection [owner] Key organization = Acme Widgets Inc." +- 命令执行成功,结果返回"Section [] Key name = John Doe\nSection [] Key organization = Acme Widgets Inc." diff --git a/docs/apps/polkit-pkla-compat/tc_polkit_pkla_compat_func001.yaml b/docs/apps/polkit-pkla-compat/tc_polkit_pkla_compat_func001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d13738a97c69aad74063d8552fa4f2badf2548ac --- /dev/null +++ b/docs/apps/polkit-pkla-compat/tc_polkit_pkla_compat_func001.yaml @@ -0,0 +1,27 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: polkit-pkla-compat测试非root用户执行cloud-init status +修改人: gaohongmei + +前置条件: +- 创建/etc/polkit-1/localauthority/50-local.d/allow_ghm_cloud-init.pkla规则文件 +[Allow ghm to run cloud-init status] +Identity=unix-user:ghm +Action=org.freedesktop.cloud-init.status +ResultActive=yes + +测试步骤: +- 执行`useradd ghm`,创建ghm用户 +- 执行`chmod +755 /etc/polkit-1/localauthority/50-local.d/allow_ghm_cloud-init.pkla`,添加执行权限 +- 执行`systemctl restart polkit.service` +- 执行`sudo -u ghm cloud-init status`,ghm用户执行cloud-init status命令 + +期望结果: +- 命令执行成功,创建成功 +- 命令执行成功,添加成功 +- 命令执行成功,重启成功 +- 命令执行成功,执行成功返回status: done \ No newline at end of file diff --git a/docs/apps/polkit-pkla-compat/tc_polkit_pkla_compat_func002.yaml b/docs/apps/polkit-pkla-compat/tc_polkit_pkla_compat_func002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..76fdb8130685d667d86ae2634c101b19b9041b2d --- /dev/null +++ b/docs/apps/polkit-pkla-compat/tc_polkit_pkla_compat_func002.yaml @@ -0,0 +1,27 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: polkit-pkla-compat测试非root用户执行timedatectl命令 +修改人: gaohongmei + +前置条件: +- 创建/etc/polkit-1/localauthority/50-local.d/allow_testuser_timedatectl.pkla规则文件 +[Allow testuser to query system time] +Identity=unix-user:testuser +Action=org.freedesktop.timedate.time +ResultActive=yes + +测试步骤: +- 执行`useradd testuser`,创建testuser用户 +- 执行`chmod +755 /etc/polkit-1/localauthority/50-local.d/allow_testuser_timedatectl.pkla`,添加执行权限 +- 执行`systemctl restart polkit.service` +- 执行`sudo -u testuser timedatectl status`,testuser用户执行timedatectl status命令 + +期望结果: +- 命令执行成功,创建成功 +- 命令执行成功,添加成功 +- 命令执行成功,重启成功 +- 命令执行成功,执行成功返回当前时间 \ No newline at end of file diff --git a/docs/apps/polkit-pkla-compat/tc_polkit_pkla_compat_func003.yaml b/docs/apps/polkit-pkla-compat/tc_polkit_pkla_compat_func003.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d1010aaeb947d3bc05642cb770ea4dbca4540230 --- /dev/null +++ b/docs/apps/polkit-pkla-compat/tc_polkit_pkla_compat_func003.yaml @@ -0,0 +1,29 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: polkit-pkla-compat测试非root用户执行journalctl命令 +修改人: gaohongmei + +前置条件: +- 创建/etc/polkit-1/localauthority/50-local.d/allow_syslog_viewer_journalctl.pkla规则文件 +[Allow syslog_viewer to read system journal] +Identity=unix-user:syslog_viewer +Action=org.freedesktop.systemd1.manage-journal +ResultAny=no +ResultInactive=no +ResultActive=yes + +测试步骤: +- 执行`useradd syslog_viewer`,创建syslog_viewer用户 +- 执行`chmod +755 /etc/polkit-1/localauthority/50-local.d/allow_syslog_viewer_journalctl.pkla`,添加执行权限 +- 执行`systemctl restart polkit.service` +- 执行`sudo -u syslog_viewer journalctl -n 10 --no-pager`,syslog_viewer用户执行journalctl命令 + +期望结果: +- 命令执行成功,创建成功 +- 命令执行成功,添加成功 +- 命令执行成功,重启成功 +- 命令执行成功,执行成功返回日志 \ No newline at end of file diff --git a/docs/apps/tpm2-tss/tc_tpm2_tss_func001.yaml b/docs/apps/tpm2-tss/tc_tpm2_tss_func001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f4fc6849ea29f362aea7ea86fc178df0bbd6d4d4 --- /dev/null +++ b/docs/apps/tpm2-tss/tc_tpm2_tss_func001.yaml @@ -0,0 +1,69 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: tpm2-tss库异常初始化 +修改人: gaohongmei + +前置条件: +- 创建/tmp/ghm/test_tpm2_tss.c文件,TCTI插件未找到初始化失败 +#include +#include +#include +#include +#include +#include +#include + +int main() { + TSS2_RC rc; + TSS2_TCTI_CONTEXT *tctiContext = NULL; + TSS2_SYS_CONTEXT *sysContext = NULL; + size_t size; + + printf("TPM2-TSS Example Running\\n"); + + //初始化TCTI + rc = Tss2_TctiLdr_Initialize("tabrmd", &tctiContext); + if (rc != TSS2_RC_SUCCESS) { + fprintf(stderr, "Failed to initialize TCTI: 0x%x\\n", rc); + return 1; + } + + // 计算SYS上下文所需大小并分配 + size = Tss2_Sys_GetContextSize(0); + sysContext = (TSS2_SYS_CONTEXT*)malloc(size); + if (!sysContext) { + fprintf(stderr, "Memory allocation failed\\n"); + Tss2_TctiLdr_Finalize(&tctiContext); + return 1; + } + + // 初始化SYS上下文 + rc = Tss2_Sys_Initialize(sysContext, size, tctiContext, NULL); + if (rc != TSS2_RC_SUCCESS) { + fprintf(stderr, "Failed to initialize Sys Context: 0x%x\\n", rc); + free(sysContext); + Tss2_TctiLdr_Finalize(&tctiContext); + return 1; + } + + printf("TPM2-TSS Context Initialized Successfully\\n"); + + // 清理资源 + Tss2_Sys_Finalize(sysContext); + free(sysContext); + Tss2_TctiLdr_Finalize(&tctiContext); + + return 0; +} + +测试步骤: +- 执行`gcc -o /tmp/ghm/test_tpm2_tss /tmp/ghm/test_tpm2_tss.c -ltss2-esys -ltss2-tcti-mssim -ltss2-tcti-device -ltss2-tctildr -ltss2-sys` +- 执行`/tmp/ghm/test_tpm2_tss` + +期望结果: +- 命令执行成功,生成/tmp/ghm/test_tpm2_tss文件。 +- 命令执行成功,返回TPM2-TSS Example Running\n ERROR:tcti:src/tss2-tcti/tctildr.c:430:Tss2_TctiLdr_Initialize_Ex() Failed to instantiate TCTI\n Failed to initialize TCTI: 0xa0015 \ No newline at end of file diff --git a/docs/apps/tpm2-tss/tc_tpm2_tss_func002.yaml b/docs/apps/tpm2-tss/tc_tpm2_tss_func002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..95fe5f619c9feb4d2a04c1a5417953ab32b447b3 --- /dev/null +++ b/docs/apps/tpm2-tss/tc_tpm2_tss_func002.yaml @@ -0,0 +1,34 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: tpm2-tss库ABI版本信息 +修改人: gaohongmei + +前置条件: +- 创建/tmp/ghm/test_tpm2_tss.c文件,包括Creator、Family、Level和Version号 +#include +#include + +int main() { + // 直接访问TSS2_ABI_VERSION_CURRENT宏来获取当前版本信息 + TSS2_ABI_VERSION currentVersion = TSS2_ABI_VERSION_CURRENT; + + printf("TPM2-TSS Library ABI Version:\\n"); + printf("Creator: %u\\n", currentVersion.tssCreator); + printf("Family: %u\\n", currentVersion.tssFamily); + printf("Level: %u\\n", currentVersion.tssLevel); + printf("Version: %u\\n", currentVersion.tssVersion); + + return 0; +} + +测试步骤: +- 执行`gcc -o /tmp/ghm/test_tpm2_tss /tmp/ghm/test_tpm2_tss.c` +- 执行`/tmp/ghm/test_tpm2_tss` + +期望结果: +- 命令执行成功,生成/tmp/ghm/test_tpm2_tss文件。 +- 命令执行成功,返回TPM2-TSS Library ABI Version:\n Creator: 1\n Family: 2\n Level: 1\n Version: 108 \ No newline at end of file diff --git a/docs/apps_libraries/c-ares/tc_c-ares_fun_001.yaml b/docs/apps_libraries/c-ares/tc_c-ares_fun_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..477a28aa131815a0699115e1cd59030c550bfae4 --- /dev/null +++ b/docs/apps_libraries/c-ares/tc_c-ares_fun_001.yaml @@ -0,0 +1,89 @@ +作者: zhixin +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 验证异步地请求一个域名的IP地址 +修改人: zhixin + +前置条件: +- 安装c-ares、c-ares-devel软件包 +- 创建dnsquery.c文件 +#include +#include +#include +#include + +void callback(void *arg, int status, int timeouts, struct hostent *host) { + if(!host || status != ARES_SUCCESS) { + printf("Failed to lookup: %s\\n", ares_strerror(status)); + return; + } + + printf("Found address name %s\\n", host->h_name); + for (int i = 0; host->h_addr_list[i]; ++i) { + struct in_addr addr; + addr.s_addr = *(in_addr_t *) host->h_addr_list[i]; + printf("Found address: %s\\n", inet_ntoa(addr)); + } +} + +int main(int argc, char **argv) { + ares_channel channel; + int status; + + // 初始化 c-ares + status = ares_library_init(ARES_LIB_INIT_ALL); + if (status != ARES_SUCCESS) { + printf("ares_library_init: %s\\n", ares_strerror(status)); + return 1; + } + + // 创建 c-ares 通道 + status = ares_init(&channel); + if(status != ARES_SUCCESS) { + printf("ares_init: %s\\n", ares_strerror(status)); + return 1; + } + + // 开始解析 + ares_gethostbyname(channel, "www.example.com", AF_INET, callback, NULL); + + // 等待所有解析完成 + for(;;) { + struct timeval *tvp, tv; + fd_set read_fds, write_fds; + int nfds; + + FD_ZERO(&read_fds); + FD_ZERO(&write_fds); + nfds = ares_fds(channel, &read_fds, &write_fds); + + if(nfds == 0) { + break; + } + + tvp = ares_timeout(channel, NULL, &tv); + select(nfds, &read_fds, &write_fds, NULL, tvp); + + // 处理事件 + ares_process(channel, &read_fds, &write_fds); + } + + // 清理 + ares_destroy(channel); + ares_library_cleanup(); + return 0; +} + +测试步骤: +- 编译dnsquery.c文件 +gcc -o dnsquery dnsquery.c -lcares +- 执行命令`ldd ./dnsquery`,查看依赖的动态链接库 +- 运行./dnsquery + +期望结果: +- 编译成功 +- 命令执行成功,返回结果中包含'libcares.so.2' +- 命令执行成功,返回结果包含 "Found address name www.example.com" 和 "Found address: +ip地址" diff --git a/docs/apps_libraries/c-ares/tc_c-ares_fun_002.yaml b/docs/apps_libraries/c-ares/tc_c-ares_fun_002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..655bd25ea8001b8ed8707fe9394c0aa4797e0c10 --- /dev/null +++ b/docs/apps_libraries/c-ares/tc_c-ares_fun_002.yaml @@ -0,0 +1,82 @@ +作者: zhixin +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 验证异步请求域名的IP时,对非法域名结果校验 +修改人: zhixin + +前置条件: +- 安装c-ares、c-ares-devel软件包 +- 创建nonvalid.c文件 +#include +#include +#include + +void query_callback(void *arg, int status, int timeouts, unsigned char *abuf, int alen) { + char* domain = (char*)arg; + if (status != ARES_SUCCESS) { + fprintf(stderr, "Domain %s: %s\\n", domain, ares_strerror(status)); + } else { + fprintf(stderr, "Domain %s: Unexpected successful response\\n", domain); + } +} + +int main(void) { + ares_channel channel; + int status; + + status = ares_library_init(ARES_LIB_INIT_ALL); + if (status != ARES_SUCCESS) { + fprintf(stderr, "ares_library_init failed: %s\\n", ares_strerror(status)); + return 1; + } + + status = ares_init(&channel); + if (status != ARES_SUCCESS) { + fprintf(stderr, "ares_init failed: %s\\n", ares_strerror(status)); + return 1; + } + + // 准备一组无效域名进行测试 + const char* invalid_domains[] = { + "invalid_domain", // 格式错误 + "unlikely-exist-123457.com", // 很可能不存在 + "no-this-site-abcdefg.net" // 很可能不存在 + }; + + for (int i = 0; i < sizeof(invalid_domains)/sizeof(invalid_domains[0]); ++i) { + ares_query(channel, invalid_domains[i], ns_c_in, ns_t_a, query_callback, + (void*)invalid_domains[i]); + } + + // 事件循环处理DNS响应 + for (;;) { + struct timeval *tvp, tv; + fd_set read_fds, write_fds; + + FD_ZERO(&read_fds); + FD_ZERO(&write_fds); + int nfds = ares_fds(channel, &read_fds, &write_fds); + if (nfds == 0) + break; + + tvp = ares_timeout(channel, NULL, &tv); + select(nfds, &read_fds, &write_fds, NULL, tvp); + ares_process(channel, &read_fds, &write_fds); + } + + ares_destroy(channel); + ares_library_cleanup(); + return 0; +} + +测试步骤: +- 编译nonvalid.c文件 +gcc -o nonvalid nonvalid.c -lcares +- 执行命令`./nonvalid > result.log 2>&1`,并查看result.log内容 + +期望结果: +- 编译成功 +- 返回结果包含 "Domain no-this-site-abcdefg.net: Domain name not found"、"Domain unlikely-exist-123457.com: Domain name not found" 和 "Domain invalid_domain: Could not contact DNS servers" diff --git a/docs/apps_libraries/c-ares/tc_c-ares_fun_003.yaml b/docs/apps_libraries/c-ares/tc_c-ares_fun_003.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0f79b32ec9cbeee7a44028e1f0e1461934a4150d --- /dev/null +++ b/docs/apps_libraries/c-ares/tc_c-ares_fun_003.yaml @@ -0,0 +1,122 @@ +作者: zhixin +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 验证c-ares库支持查询不同类型的DNS记录的能力 +修改人: zhixin + +前置条件: +- 安装c-ares、c-ares-devel软件包 +- 创建query_dns.c文件 +#include +#include +#include +#include +#include +#include +#include +#include + +// A记录的回调 +void a_record_callback(void* arg, int status, int timeouts, unsigned char* abuf, int alen) { + struct hostent* host = NULL; + char* query = (char*) arg; + + if(status == ARES_SUCCESS) { + status = ares_parse_a_reply(abuf, alen, &host, NULL, NULL); + if(status == ARES_SUCCESS) { + printf("A record for %s: %s\\n", query, inet_ntoa(*(struct in_addr*)host->h_addr)); + free(host); + } + } + if(status != ARES_SUCCESS) { + fprintf(stderr, "Failed to find A record for %s with status: %s\\n", query, ares_strerror(status)); + } +} + +// AAAA记录的回调 +void aaaa_record_callback(void* arg, int status, int timeouts, unsigned char* abuf, int alen) { + struct hostent* host = NULL; + char ip[INET6_ADDRSTRLEN]; + char* query = (char*) arg; + + if(status == ARES_SUCCESS) { + status = ares_parse_aaaa_reply(abuf, alen, &host, NULL, NULL); + if(status == ARES_SUCCESS) { + inet_ntop(AF_INET6, host->h_addr, ip, INET6_ADDRSTRLEN); + printf("AAAA record for %s: %s\\n", query, ip); + free(host); + } + } + if(status != ARES_SUCCESS) { + fprintf(stderr, "Failed to find AAAA record for %s with status: %s\\n", query, ares_strerror(status)); + } +} + +// MX记录的回调 +void mx_record_callback(void* arg, int status, int timeouts, unsigned char* abuf, int alen) { + struct ares_mx_reply* mx_reply = NULL; + char* query = (char*) arg; + + if(status == ARES_SUCCESS) { + status = ares_parse_mx_reply(abuf, alen, &mx_reply); + if(status == ARES_SUCCESS) { + printf("MX record for %s: %s with priority %u\\n", query, mx_reply->host, mx_reply->priority); + ares_free_data(mx_reply); + } + } + if(status != ARES_SUCCESS) { + fprintf(stderr, "Failed to find MX record for %s with status: %s\\n", query, ares_strerror(status)); + } +} + +int main(int argc, char* argv[]) { + if(argc != 2) { + printf("Usage: %s \\n", argv[0]); + exit(1); + } + + ares_channel channel; + int status = ares_library_init(ARES_LIB_INIT_ALL); + if(status != ARES_SUCCESS) return 1; + + status = ares_init(&channel); + if(status != ARES_SUCCESS) return 1; + + // 查询指定的DNS记录类型 + ares_query(channel, argv[1], ns_c_in, ns_t_a, a_record_callback, strdup(argv[1])); + ares_query(channel, argv[1], ns_c_in, ns_t_aaaa, aaaa_record_callback, strdup(argv[1])); + ares_query(channel, argv[1], ns_c_in, ns_t_mx, mx_record_callback, strdup(argv[1])); + + // 处理响应 + for(;;) { + struct timeval* tvp, tv; + fd_set read_fds, write_fds; + FD_ZERO(&read_fds); + FD_ZERO(&write_fds); + int nfds = ares_fds(channel, &read_fds, &write_fds); + if(nfds == 0) + break; + tvp = ares_timeout(channel, NULL, &tv); + select(nfds, &read_fds, &write_fds, NULL, tvp); + ares_process(channel, &read_fds, &write_fds); + } + + // 清理 + ares_destroy(channel); + ares_library_cleanup(); + return 0; +} + +测试步骤: +- 编译query_dns.c文件 +gcc -o query_dns query_dns.c -lcares +- 执行命令`./query_dns www.example.com > result.log 2>&1`,其中域名为有效域名,并查看result.log内容 +- 执行命令`./query_dns invalid_domain > result.log 2>&1`,其中域名为无效域名,并查看result.log内容 + +期望结果: +- 编译成功 +- 返回结果包含 "AAAA record for www.example.com: +ipv6地址"、"A record for www.example.com: +ip地址" 和 "Failed to find MX record for www.example.com with status: DNS server returned answer with no data" +- 返回结果包含 "Failed to find AAAA record for invalid_domain with status: Domain name not found" 、"Failed to find MX record for invalid_domain with status: Domain name not found" 和 "Failed to find A record for invalid_domain with status: Could not contact DNS servers" diff --git a/docs/apps_libraries/c-ares/tc_c-ares_fun_004.yaml b/docs/apps_libraries/c-ares/tc_c-ares_fun_004.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a9636b5e0cff01691f7dffee8266855998ddaaf3 --- /dev/null +++ b/docs/apps_libraries/c-ares/tc_c-ares_fun_004.yaml @@ -0,0 +1,95 @@ +作者: zhixin +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 验证c-ares库支持异步DNS查询不同地址家族 +修改人: zhixin + +前置条件: +- 安装c-ares、c-ares-devel软件包 +- 创建query.c文件 +#include +#include +#include +#include +#include +#include +#include + +void callback(void *arg, int status, int timeouts, struct hostent *host) { + if(!host || status != ARES_SUCCESS) { + printf("Failed to lookup %s\\n", ares_strerror(status)); + return; + } + + printf("Found address name %s\\n", host->h_name); + for (int i = 0; host->h_addr_list[i]; ++i) { + char ip[INET6_ADDRSTRLEN]; + inet_ntop(host->h_addrtype, host->h_addr_list[i], ip, sizeof(ip)); + printf("%s\\n", ip); + } +} + +int main(int argc, char **argv) +{ + if(argc != 2) { + printf("Usage: %s \\n", argv[0]); + exit(1); + } + + ares_channel channel; + int status, nfds, count; + fd_set read_fds, write_fds; + struct timeval *tvp, tv; + + /* 初始化 c-ares 库 */ + status = ares_library_init(ARES_LIB_INIT_ALL); + if (status != ARES_SUCCESS) { + fprintf(stderr, "ares_library_init: %s\\n", ares_strerror(status)); + return 1; + } + + /* 创建 channel */ + status = ares_init(&channel); + if (status != ARES_SUCCESS) { + fprintf(stderr, "ares_init: %s\\n", ares_strerror(status)); + return 1; + } + + /* 设置不同的地址类型 */ + ares_gethostbyname(channel, argv[1], AF_INET, callback, NULL); + ares_gethostbyname(channel, argv[1], AF_INET6, callback, NULL); + + /* 主循环处理 */ + while (1) { + FD_ZERO(&read_fds); + FD_ZERO(&write_fds); + nfds = ares_fds(channel, &read_fds, &write_fds); + if (nfds == 0) { + break; + } + tvp = ares_timeout(channel, NULL, &tv); + count = select(nfds, &read_fds, &write_fds, NULL, tvp); + if (count <= 0) { + continue; + } + ares_process(channel, &read_fds, &write_fds); + } + + ares_destroy(channel); + ares_library_cleanup(); + return 0; +} + +测试步骤: +- 编译query.c文件 +gcc -o query query.c -lcares +- 执行命令`./query www.example.com > result.log 2>&1`,其中域名为有效域名,并查看result.log内容 +- 执行命令`./query invalid_domain > result.log 2>&1`,其中域名为无效域名,并查看result.log内容 + +期望结果: +- 编译成功 +- 返回结果包含 "Found address name www.example.com\n+ip地址" 和 "Found address name www.example.com\n+ipv6地址" +- 返回结果包含 "Failed to lookup Misformatted domain name" diff --git a/docs/apps_libraries/cyrus-sasl/tc_cyrus_sasl_func_001.yaml b/docs/apps_libraries/cyrus-sasl/tc_cyrus_sasl_func_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1c6536b3f4f07a4fee140d9282996e718a92c87c --- /dev/null +++ b/docs/apps_libraries/cyrus-sasl/tc_cyrus_sasl_func_001.yaml @@ -0,0 +1,16 @@ +作者: liuhaiyang +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 查看或管理插件信息. +修改人: liuhaiyang + +前置条件: + +测试步骤: +- 执行pluginviewer命令,期望命令执行成功 + +期望结果: +- 期望命令执行成功 diff --git a/docs/apps_libraries/libaio/tc_libaio_func001.yaml b/docs/apps_libraries/libaio/tc_libaio_func001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d06aabf1fdd6f7d728339ccaa741b86f01edecb6 --- /dev/null +++ b/docs/apps_libraries/libaio/tc_libaio_func001.yaml @@ -0,0 +1,73 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: libaio库io_setup函数在不同参数下的行为 +修改人: gaohongmei + +前置条件: +- 创建test_libaio.c脚本,测试io_setup函数在不同参数下的行为,及正确处理各种错误情况。 +#include +#include +#include +#include +#include + +#define EXPECT_SUCCESS 0 +#define EXPECT_FAILURE -1 + +void io_setup_test(int nr_events, int expected_result) { + io_context_t ctx = NULL; + int ret; + + printf("Testing io_setup with nr_events = %d, expecting:", nr_events); + + if (expected_result == EXPECT_SUCCESS) { + printf("success\\n"); + } else { + printf("failure\\n"); + } + + ret = io_setup(nr_events, &ctx); + if (expected_result == EXPECT_SUCCESS) { + if (ret < 0) { + printf("Test failed:io_setup returned %d (%s)\\n", ret, strerror(-ret)); + } else { + printf("Test passed:io_setup returned %d\\n", ret); + io_destroy(ctx); + } + } else { + if (ret >= 0) { + printf("Test failed:io_setup unexpectedly succeeded with return value %d\\n", ret); + io_destroy(ctx); + } else { + // 修改此处:将expected_errno替换为errno + if (errno == expected_result) { + printf("Test passed:io_setup failed with expected errno %d (%s)\\n", errno, strerror(errno)); + } else { + printf("Test failed:io_setup failed with unexpected errno %d (%s), expected %d\\n", errno, strerror(errno), expected_result); + } + } + } +} + +int main() { + // 正常调用测试 + io_setup_test(10, EXPECT_SUCCESS); + + // 参数nr_events小于等于0的测试 + io_setup_test(0, EXPECT_FAILURE); + io_setup_test(-1, EXPECT_FAILURE); + + return 0; +} + +测试步骤: +- 执行命令`gcc -o /tmp/ghm/test_libaio /tmp/ghm/test_libaio.c -laio`,编译脚本 +- 执行命令`/tmp/ghm/test_libaio` + +期望结果: +- 命令执行成功,生成/tmp/ghm/test_libaio脚本 +- 命令执行成功,返回内容中包含:nr_events = 10, expecting:success、nr_events = 0, expecting:failure、nr_events = -1, expecting:failure \ No newline at end of file diff --git a/docs/apps_libraries/libaio/tc_libaio_func002.yaml b/docs/apps_libraries/libaio/tc_libaio_func002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a944f2a9a4d68276f82d1e401aa1b0fd082fe5ee --- /dev/null +++ b/docs/apps_libraries/libaio/tc_libaio_func002.yaml @@ -0,0 +1,75 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: libaio库io_submit函数边界条件测试 +修改人: gaohongmei + +前置条件: +- 创建test_libaio.c脚本,测试io_submit函数边界条件。 +#include +#include +#include +#include +#include +#include +#include + +io_context_t io_ctx; +#define BAD_CTX ((io_context_t)-1) + +void aio_setup(int n) +{ + int res = io_queue_init(n, &io_ctx); + if (res != 0) { + printf("io_queue_setup(%d) returned %d (%s)\\n", + n, res, strerror(-res)); + exit(3); + } +} + +int attempt_io_submit(io_context_t ctx, long nr, struct iocb *ios[], int expect) +{ + int res; + + printf("expect %3d: io_submit(%10p, %3ld, %10p) = ", expect, ctx, nr, ios); + fflush(stdout); + res = io_submit(ctx, nr, ios); + printf("%3d [%s]%s\\n", res, (res <= 0) ? strerror(-res) : "", + (res != expect) ? " -- FAILED" : ""); + if (res != expect) + return 1; + + return 0; +} + +int main(void) +{ + aio_setup(10); + struct iocb a, b; + struct iocb *good_ios[] = { &a, &b }; + struct iocb *bad1_ios[] = { NULL, &b }; + // 替换 KERNEL_RW_POINTER 为已知无效的指针地址 + struct iocb *bad2_ios[] = { (struct iocb *)-1, &a }; + int status = 0; + + status |= attempt_io_submit(BAD_CTX, 1, good_ios, -EINVAL); + status |= attempt_io_submit( io_ctx, 0, good_ios, 0); + status |= attempt_io_submit( io_ctx, 1, NULL, -EFAULT); + status |= attempt_io_submit( io_ctx, 1, (void *)-1, -EFAULT); + status |= attempt_io_submit( io_ctx, 2, bad1_ios, -EFAULT); + status |= attempt_io_submit( io_ctx, 2, bad2_ios, -EFAULT); + status |= attempt_io_submit( io_ctx, -1, good_ios, -EINVAL); + + return status; +} + +测试步骤: +- 执行命令`gcc -o /tmp/ghm/test_libaio /tmp/ghm/test_libaio.c -laio`,编译脚本 +- 执行命令`/tmp/ghm/test_libaio` + +期望结果: +- 命令执行成功,生成/tmp/ghm/test_libaio脚本 +- 命令执行成功,返回预期结果 \ No newline at end of file diff --git a/docs/apps_libraries/libaio/tc_libaio_func003.yaml b/docs/apps_libraries/libaio/tc_libaio_func003.yaml new file mode 100644 index 0000000000000000000000000000000000000000..67939b056a193adb6dbacc3f0f08bd684aa2c55d --- /dev/null +++ b/docs/apps_libraries/libaio/tc_libaio_func003.yaml @@ -0,0 +1,165 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: libaio库异步读写同一文件 +修改人: gaohongmei + +前置条件: +- 创建test_libaio.c脚本,包括初始化异步I/O队列,发起读或写操作,并期望得到特定的结果 +#include +#include +#include +#include +#include +#include +#include +#include + +io_context_t io_ctx; +#define BAD_CTX ((io_context_t)-1) +#define SETUP aio_setup(1024) +#define READ 'r' +#define WRITE 'w' +#define READ_SILENT 'R' +#define WRITE_SILENT 'W' +#define READV '<' +#define WRITEV '>' + +void aio_setup(int n) +{ + int res = io_queue_init(n, &io_ctx); + if (res != 0) { + printf("io_queue_setup(%d) returned %d (%s)\\n", + n, res, strerror(-res)); + exit(3); + } +} + +int sync_submit(struct iocb *iocb) +{ + struct io_event event; + struct iocb *iocbs[] = { iocb }; + int res; + + /* 30 second timeout should be enough */ + struct timespec ts; + ts.tv_sec = 30; + ts.tv_nsec = 0; + + res = io_submit(io_ctx, 1, iocbs); + if (res != 1) { + printf("sync_submit: io_submit res=%d [%s]\\n", res, strerror(-res)); + return res; + } + + res = io_getevents(io_ctx, 0, 1, &event, &ts); + if (res != 1) { + printf("sync_submit: io_getevents res=%d [%s]\\n", res, strerror(-res)); + return res; + } + return event.res; +} + +int attempt_rw(int fd, void *buf, int count, long long pos, int rw, int expect) +{ + struct iocb iocb; + int res; + int silent = 0; + + switch(rw) { + case READ_SILENT: + silent = 1; + case READ: + io_prep_pread (&iocb, fd, buf, count, pos); + break; + case WRITE_SILENT: + silent = 1; + case WRITE: + io_prep_pwrite(&iocb, fd, buf, count, pos); + break; + case WRITEV: + io_prep_pwritev(&iocb, fd, buf, count, pos); + break; + case READV: + io_prep_preadv(&iocb, fd, buf, count, pos); + break; + } + + if (!silent) { + printf("expect %5d: (%c), res = ", expect, rw); + fflush(stdout); + } + res = sync_submit(&iocb); + if (!silent || res != expect) { + if (silent) + printf("expect %5d: (%c), res = ", expect, rw); + printf("%5d [%s]%s\\n", res, + (res <= 0) ? strerror(-res) : "Success", + (res != expect) ? " -- FAILED" : ""); + } + + if (res != expect) + return 1; + + return 0; +} + +int main(void) +{ + SETUP; + int page_size = getpagesize(); +#define SIZE 512 + char *buf; + int rwfd; + int status = 0, res; + + rwfd = open("/tmp/ghm/rwfile", O_RDWR); assert(rwfd != -1); + res = ftruncate(rwfd, 512); assert(res == 0); + + buf = mmap(0, page_size, PROT_READ|PROT_WRITE, MAP_SHARED, rwfd, 0); + assert(buf != (char *)-1); + + status |= attempt_rw(rwfd, buf, SIZE, 0, WRITE, SIZE); + status |= attempt_rw(rwfd, buf, SIZE, 0, READ, SIZE); + + res = munmap(buf, page_size); assert(res == 0); + buf = mmap(0, page_size, PROT_READ|PROT_WRITE, MAP_SHARED, rwfd, 0); + assert(buf != (char *)-1); + + status |= attempt_rw(rwfd, buf, SIZE, 0, READ, SIZE); + status |= attempt_rw(rwfd, buf, SIZE, 0, WRITE, SIZE); + + res = munmap(buf, page_size); assert(res == 0); + buf = mmap(0, page_size, PROT_READ, MAP_SHARED, rwfd, 0); + assert(buf != (char *)-1); + + status |= attempt_rw(rwfd, buf, SIZE, 0, WRITE, SIZE); + status |= attempt_rw(rwfd, buf, SIZE, 0, READ, -EFAULT); + + res = munmap(buf, page_size); assert(res == 0); + buf = mmap(0, page_size, PROT_WRITE, MAP_SHARED, rwfd, 0); + assert(buf != (char *)-1); + + /* Whether PROT_WRITE is readable is arch-dependent. So compare + * against write() result (to make the kernel read from buf). */ + res = write(rwfd, buf, SIZE); + if (res < 0) + res = -errno; + status |= attempt_rw(rwfd, buf, SIZE, 0, READ, SIZE); + status |= attempt_rw(rwfd, buf, SIZE, 0, WRITE, res); + + return status; +} + +测试步骤: +- 执行命令`touch /tmp/ghm/rwfile` +- 执行命令`gcc -o /tmp/ghm/test_libaio /tmp/ghm/test_libaio.c -laio`,编译脚本 +- 执行命令`/tmp/ghm/test_libaio` + +期望结果: +- 命令执行成功,文件创建成功 +- 命令执行成功,生成/tmp/ghm/test_libaio脚本 +- 命令执行成功,返回不同权限(读写、只读、只写)多次操作结果 \ No newline at end of file diff --git a/docs/apps_libraries/libaio/tc_libaio_func004.yaml b/docs/apps_libraries/libaio/tc_libaio_func004.yaml new file mode 100644 index 0000000000000000000000000000000000000000..bf65b84241497d5aa2de3b4945fcdda445ded7cb --- /dev/null +++ b/docs/apps_libraries/libaio/tc_libaio_func004.yaml @@ -0,0 +1,133 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: libaio库对不同文件异步读写操作 +修改人: gaohongmei + +前置条件: +- 创建test_libaio.c脚本,创建三个文件进行一系列合法和非法的操作,以验证异步I/O接口的功能 +#include +#include +#include +#include +#include +#include +#include +#include + +io_context_t io_ctx; +#define BAD_CTX ((io_context_t)-1) +#define SETUP aio_setup(1024) + +void aio_setup(int n) +{ + int res = io_queue_init(n, &io_ctx); + if (res != 0) { + printf("io_queue_setup(%d) returned %d (%s)\\n", + n, res, strerror(-res)); + exit(3); + } +} + +int sync_submit(struct iocb *iocb) +{ + struct io_event event; + struct iocb *iocbs[] = { iocb }; + int res; + + struct timespec ts; + ts.tv_sec = 30; + ts.tv_nsec = 0; + + res = io_submit(io_ctx, 1, iocbs); + if (res != 1) { + printf("sync_submit: io_submit res=%d [%s]\\n", res, strerror(-res)); + return res; + } + + res = io_getevents(io_ctx, 0, 1, &event, &ts); + if (res != 1) { + printf("sync_submit: io_getevents res=%d [%s]\\n", res, strerror(-res)); + return res; + } + return event.res; +} + +#define SIZE 512 +#define READ 'r' +#define WRITE 'w' +int attempt(int fd, void *buf, int count, long long pos, int rw, int expect) +{ + struct iocb iocb; + int res; + + switch(rw) { + case READ: io_prep_pread (&iocb, fd, buf, count, pos); break; + case WRITE: io_prep_pwrite(&iocb, fd, buf, count, pos); break; + } + + printf("expect %3d: (%c), res = ", expect, rw); + fflush(stdout); + res = sync_submit(&iocb); + printf("%3d [%s]%s\\n", res, (res <= 0) ? strerror(-res) : "Success", + (res != expect) ? " -- FAILED" : ""); + if (res != expect) + return 1; + + return 0; +} + +int main(void) +{ + SETUP; + char buf[SIZE]; + int rofd, wofd, rwfd; + int status = 0, res; + + memset(buf, 0, SIZE); + + rofd = open("/tmp/ghm/rofile", O_RDONLY); assert(rofd != -1); + wofd = open("/tmp/ghm/wofile", O_WRONLY); assert(wofd != -1); + rwfd = open("/tmp/ghm/rwfile", O_RDWR); assert(rwfd != -1); + + status |= attempt(rofd, buf, SIZE, 0, WRITE, -EBADF); + status |= attempt(wofd, buf, SIZE, 0, READ, -EBADF); + status |= attempt(rwfd, buf, SIZE, 0, WRITE, SIZE); + status |= attempt(rwfd, buf, SIZE, 0, READ, SIZE); + status |= attempt(rwfd, buf, SIZE, -1, READ, -EINVAL); + status |= attempt(rwfd, buf, SIZE, -1, WRITE, -EINVAL); + + rwfd = open("/tmp/ghm/rwfile", O_RDWR|O_APPEND); assert(rwfd != -1); + res = ftruncate(rwfd, 0); assert(res == 0); + status |= attempt(rwfd, buf, SIZE, 0, READ, 0); + status |= attempt(rwfd, "1234", 4, 0, WRITE, 4); + status |= attempt(rwfd, "5678", 4, 0, WRITE, 4); + memset(buf, 0, SIZE); + status |= attempt(rwfd, buf, SIZE, 0, READ, 8); + printf("read after append: [%s]\\n", buf); + assert(memcmp(buf, "12345678", 8) == 0); + + /* Some architectures map the 0 page. Ugh. */ +#if !defined(__ia64__) + status |= attempt(rwfd, NULL, SIZE, 0, WRITE, -EFAULT); +#endif + + return status; +} + +测试步骤: +- 执行命令`touch /tmp/ghm/rofile` +- 执行命令`touch /tmp/ghm/wofile` +- 执行命令`touch /tmp/ghm/rwfile` +- 执行命令`gcc -o /tmp/ghm/test_libaio /tmp/ghm/test_libaio.c -laio`,编译脚本 +- 执行命令`/tmp/ghm/test_libaio` + +期望结果: +- 命令执行成功,文件创建成功 +- 命令执行成功,文件创建成功 +- 命令执行成功,文件创建成功 +- 命令执行成功,生成/tmp/ghm/test_libaio脚本 +- 命令执行成功,返回不同文件操作预期结果 \ No newline at end of file diff --git a/docs/apps_libraries/libcbor/tc_libcbor_func001.yaml b/docs/apps_libraries/libcbor/tc_libcbor_func001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0eb0af3c62d8ff3383bfb1aba91079fa367ddd65 --- /dev/null +++ b/docs/apps_libraries/libcbor/tc_libcbor_func001.yaml @@ -0,0 +1,28 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: libcbor库输出一些关于CBOR库的信息 +修改人: gaohongmei + +前置条件: +- 创建test_libcbor.c脚本 +#include +#include "cbor.h" + +int main(void) { + printf("Hello from libcbor %s\\n", CBOR_VERSION); + printf("Pretty-printer support: %s\\n", CBOR_PRETTY_PRINTER ? "yes" : "no"); + printf("Buffer growth factor: %f\\n", (float)CBOR_BUFFER_GROWTH); +} + + +测试步骤: +- 执行命令`gcc -o /tmp/ghm/test_libcbor /tmp/ghm/test_libcbor.c -lcbor`,编译脚本 +- 执行命令`/tmp/ghm/test_libcbor` + +期望结果: +- 命令执行成功,生成/tmp/ghm/test_libaio脚本 +- 命令执行成功,返回Hello from libcbor 0.10.2;Pretty-printer support: yes;Buffer growth factor: 2.000000 \ No newline at end of file diff --git a/docs/apps_libraries/libcbor/tc_libcbor_func002.yaml b/docs/apps_libraries/libcbor/tc_libcbor_func002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c07ca85aabe17e6afdc0616937cb32bd1159339b --- /dev/null +++ b/docs/apps_libraries/libcbor/tc_libcbor_func002.yaml @@ -0,0 +1,50 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: libcbor库创建有序数组 +修改人: gaohongmei + +前置条件: +- 创建test_libcbor.c脚本 +#include +#include +#include "cbor.h" + +int compareUint(const void *a, const void *b) { + uint8_t av = cbor_get_uint8(*(cbor_item_t **)a), + bv = cbor_get_uint8(*(cbor_item_t **)b); + + if (av < bv) + return -1; + else if (av == bv) + return 0; + else + return 1; +} + +int main(void) { + cbor_item_t *array = cbor_new_definite_array(4); + bool success = cbor_array_push(array, cbor_move(cbor_build_uint8(4))); + success &= cbor_array_push(array, cbor_move(cbor_build_uint8(3))); + success &= cbor_array_push(array, cbor_move(cbor_build_uint8(1))); + success &= cbor_array_push(array, cbor_move(cbor_build_uint8(2))); + if (!success) return 1; + + qsort(cbor_array_handle(array), cbor_array_size(array), sizeof(cbor_item_t *), + compareUint); + + cbor_describe(array, stdout); + fflush(stdout); +} + + +测试步骤: +- 执行命令`gcc -o /tmp/ghm/test_libcbor /tmp/ghm/test_libcbor.c -lcbor`,编译脚本 +- 执行命令`/tmp/ghm/test_libcbor` + +期望结果: +- 命令执行成功,生成/tmp/ghm/test_libaio脚本 +- 命令执行成功,数组按顺序输出 \ No newline at end of file diff --git a/docs/apps_libraries/libcbor/tc_libcbor_func003.yaml b/docs/apps_libraries/libcbor/tc_libcbor_func003.yaml new file mode 100644 index 0000000000000000000000000000000000000000..07a17224f233e0dcc3c3c46d523972416129bcba --- /dev/null +++ b/docs/apps_libraries/libcbor/tc_libcbor_func003.yaml @@ -0,0 +1,44 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: libcbor库进行内存映射 +修改人: gaohongmei + +前置条件: +- 创建test_libcbor.c脚本 +#include +#include "cbor.h" + +int main(void) { + cbor_item_t* root = cbor_new_definite_map(2); + bool success = cbor_map_add( + root, (struct cbor_pair){ + .key = cbor_move(cbor_build_string("Is CBOR awesome?\\n")), + .value = cbor_move(cbor_build_bool(true))}); + success &= cbor_map_add( + root, (struct cbor_pair){ + .key = cbor_move(cbor_build_uint8(42)), + .value = cbor_move(cbor_build_string("Is the answer\\n"))}); + if (!success) return 1; + unsigned char* buffer; + size_t buffer_size; + cbor_serialize_alloc(root, &buffer, &buffer_size); + + fwrite(buffer, 1, buffer_size, stdout); + free(buffer); + + fflush(stdout); + cbor_decref(&root); +} + + +测试步骤: +- 执行命令`gcc -o /tmp/ghm/test_libcbor /tmp/ghm/test_libcbor.c -lcbor`,编译脚本 +- 执行命令`/tmp/ghm/test_libcbor` + +期望结果: +- 命令执行成功,生成/tmp/ghm/test_libaio脚本 +- 命令执行成功,返回b'\xa2qIs CBOR awesome?\n\xf5\x18*nIs the answer\n' \ No newline at end of file diff --git a/docs/apps_libraries/libcbor/tc_libcbor_func004.yaml b/docs/apps_libraries/libcbor/tc_libcbor_func004.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1c427abf8ab0e123981b7722d172bc87fb841065 --- /dev/null +++ b/docs/apps_libraries/libcbor/tc_libcbor_func004.yaml @@ -0,0 +1,94 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 使用libcbor库读取不同.cbor文件 +修改人: gaohongmei + +前置条件: +- 创建test_libcbor.c脚本,使用Cbor库来读取一个二进制文件中的数据 +#include +#include "cbor.h" + +void usage(void) { + printf("Usage: readfile [input file]\\n"); + exit(1); +} + +int main(int argc, char* argv[]) { + if (argc != 2) usage(); + FILE* f = fopen(argv[1], "rb"); + if (f == NULL) usage(); + fseek(f, 0, SEEK_END); + size_t length = (size_t)ftell(f); + fseek(f, 0, SEEK_SET); + unsigned char* buffer = malloc(length); + fread(buffer, length, 1, f); + + struct cbor_load_result result; + cbor_item_t* item = cbor_load(buffer, length, &result); + free(buffer); + + if (result.error.code != CBOR_ERR_NONE) { + printf( + "There was an error while reading the input near byte %zu (read %zu " + "bytes in total): ", + result.error.position, result.read); + switch (result.error.code) { + case CBOR_ERR_MALFORMATED: { + printf("Malformed data\\n"); + break; + } + case CBOR_ERR_MEMERROR: { + printf("Memory error -- perhaps the input is too large?\\n"); + break; + } + case CBOR_ERR_NODATA: { + printf("The input is empty\\n"); + break; + } + case CBOR_ERR_NOTENOUGHDATA: { + printf("Data seem to be missing -- is the input complete?\\n"); + break; + } + case CBOR_ERR_SYNTAXERROR: { + printf("Syntactically malformed data -- see\\n"); + break; + } + case CBOR_ERR_NONE: { + break; + } + } + exit(1); + } + + cbor_describe(item, stdout); + fflush(stdout); + cbor_decref(&item); + + fclose(f); +} + +测试步骤: +- 执行echo 'ehello' > /tmp/ghm/test01.cbor,创建文件 +- 执行touch /tmp/ghm/test02.cbor,创建空文件 +- 执行echo 't2024-04-08T20:04:00Z' > /tmp/ghm/test03.cbor,创建文件 +- 执行echo 't1234566' > /tmp/ghm/test04.cbor",创建文件 +- 执行gcc -o /tmp/ghm/test_libcbor /tmp/ghm/test_libcbor.c -lcbor,编译脚本 +- 执行/tmp/ghm/test_libcbor /tmp/ghm/test01.cbor +- 执行/tmp/ghm/test_libcbor /tmp/ghm/test02.cbor +- 执行/tmp/ghm/test_libcbor /tmp/ghm/test03.cbor +- 执行/tmp/ghm/test_libcbor /tmp/ghm/test04.cbor + +期望结果: +- 文件创建成功 +- 文件创建成功 +- 文件创建成功 +- 文件创建成功 +- 命令执行成功,生成/tmp/ghm/test_libaio脚本 +- 命令执行成功,返回[CBOR_TYPE_STRING] Definite, length 5B, 5 codepoints/n hello +- 命令执行成功,返回内容包含The input is empty +- 命令执行成功,返回[CBOR_TYPE_STRING] Definite, length 20B, 20 codepoints/n 2024-04-08T20:04:00Z +- 命令执行成功,返回内容包含Data seem to be missing -- is the input complete? \ No newline at end of file diff --git a/docs/apps_libraries/libcbor/tc_libcbor_func005.yaml b/docs/apps_libraries/libcbor/tc_libcbor_func005.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8f69e0461addc321bde210fce3f35ea364adb664 --- /dev/null +++ b/docs/apps_libraries/libcbor/tc_libcbor_func005.yaml @@ -0,0 +1,60 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: libcbor库整数序列化为CBOR格式 +修改人: gaohongmei + +前置条件: +- 创建test_libcbor.c脚本,使用流式编码将一个整数数组序列化为CBOR格式 +#include +#include "cbor.h" + +void usage(void) { + printf("Usage: streaming_array \\n"); + printf("Prints out serialized array [0, ..., N-1]\\n"); + exit(1); +} + +#define BUFFER_SIZE 8 +unsigned char buffer[BUFFER_SIZE]; +FILE* out; + +void flush(size_t bytes) { + if (bytes == 0) exit(1); // All items should be successfully encoded + if (fwrite(buffer, sizeof(unsigned char), bytes, out) != bytes) exit(1); + if (fflush(out)) exit(1); +} + + +int main(int argc, char* argv[]) { + if (argc != 2) usage(); + long n = strtol(argv[1], NULL, 10); + out = freopen(NULL, "wb", stdout); + if (!out) exit(1); + + // Start an indefinite-length array + flush(cbor_encode_indef_array_start(buffer, BUFFER_SIZE)); + printf("\\ncbor \\n"); + for (size_t i = 0; i < n; i++) { + flush(cbor_encode_uint32(i, buffer, BUFFER_SIZE)); + } + + // Close the array + flush(cbor_encode_break(buffer, BUFFER_SIZE)); + printf("\\nthe input is <%d>\\n", n); + if (fclose(out)) exit(1); +} + + +测试步骤: +- 执行命令`gcc -o /tmp/ghm/test_libcbor /tmp/ghm/test_libcbor.c -lcbor`,编译脚本 +- 执行命令`/tmp/ghm/test_libcbor` +- 执行命令`/tmp/ghm/test_libcbor 8` + +期望结果: +- 命令执行成功,生成/tmp/ghm/test_libaio脚本 +- 命令执行成功,返回结果包含Usage: streaming_array +- 命令执行成功,返回结果包含the input is <8> \ No newline at end of file diff --git a/docs/apps_libraries/libkcapi/tc_libkcapi_func001.yaml b/docs/apps_libraries/libkcapi/tc_libkcapi_func001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0bf6aa699da5032d998f3b903eada630b48e5e84 --- /dev/null +++ b/docs/apps_libraries/libkcapi/tc_libkcapi_func001.yaml @@ -0,0 +1,188 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libkcapi库提供的加密功能 +修改人: gaohongmei + +前置条件: +- 创建test_libkcapi.c脚本,包括散列(Hashing)、哈希消息验证码(HMAC)、AES加密(CBC模式和CTR模式)以及随机数生成 +#include +#include +#include +#include + +static int hashtest(void) +{ + char *in = "teststring"; + uint8_t out[64]; + ssize_t ret; + + ret = kcapi_md_sha1((uint8_t*)in, strlen(in), out, sizeof(out)); + if (ret != 20) { + printf("SHA-1 error"); + return 1; + } + + ret = kcapi_md_sha224((uint8_t*)in, strlen(in), out, sizeof(out)); + if (ret != 28) { + printf("SHA-224 error"); + return 1; + } + + ret = kcapi_md_sha256((uint8_t*)in, strlen(in), out, sizeof(out)); + if (ret != 32) { + printf("SHA-256 error"); + return 1; + } + + ret = kcapi_md_sha384((uint8_t*)in, strlen(in), out, sizeof(out)); + if (ret != 48) { + printf("SHA-384 error"); + return 1; + } + + ret = kcapi_md_sha512((uint8_t*)in, strlen(in), out, sizeof(out)); + if (ret != 64) { + printf("SHA-512 error"); + return 1; + } + + return 0; +} + +static int hmactest(void) +{ + char *in = "longteststring"; + uint8_t out[64]; + ssize_t ret; + + ret = kcapi_md_hmac_sha1((uint8_t*)in, (uint32_t)strlen(in), + (uint8_t*)in, strlen(in), out, sizeof(out)); + if (ret != 20) { + printf("HMAC SHA-1 error"); + return 1; + } + + ret = kcapi_md_hmac_sha224((uint8_t*)in, (uint32_t)strlen(in), + (uint8_t*)in, strlen(in), out, sizeof(out)); + if (ret != 28) { + printf("HMAC SHA-224 error"); + return 1; + } + + ret = kcapi_md_hmac_sha256((uint8_t*)in, (uint32_t)strlen(in), + (uint8_t*)in, strlen(in), out, sizeof(out)); + if (ret != 32) { + printf("HMAC SHA-256 error"); + return 1; + } + + ret = kcapi_md_hmac_sha384((uint8_t*)in, (uint32_t)strlen(in), + (uint8_t*)in, strlen(in), out, sizeof(out)); + if (ret != 48) { + printf("HMAC SHA-384 error"); + return 1; + } + + ret = kcapi_md_hmac_sha512((uint8_t*)in, (uint32_t)strlen(in), + (uint8_t*)in, strlen(in), out, sizeof(out)); + if (ret != 64) { + printf("HMAC SHA-512 error"); + return 1; + } + + return 0; +} + +static int ciphertest(void) +{ + uint8_t *origpt = (uint8_t *)"01234567890123450123456789012345"; + uint8_t ct[32]; + uint8_t newpt[32]; + ssize_t ret; + + ret = kcapi_cipher_enc_aes_cbc(origpt, 32, origpt, 32, origpt, + ct, sizeof(ct)); + if (ret != sizeof(ct)) { + printf("AES CBC encrytion error"); + return 1; + } + + ret = kcapi_cipher_dec_aes_cbc(origpt, 32, ct, sizeof(ct), origpt, + newpt, sizeof(newpt)); + if (ret != sizeof(newpt) || memcmp(origpt, newpt, sizeof(newpt))) { + printf("AES CBC decrytion error"); + return 1; + } + + ret = kcapi_cipher_enc_aes_ctr(origpt, 32, origpt, 32, origpt, ct, + sizeof(ct)); + if (ret != sizeof(ct)) { + printf("AES CTR encrytion error"); + return 1; + } + + ret = kcapi_cipher_dec_aes_ctr(origpt, 32, ct, sizeof(ct), origpt, + newpt, sizeof(newpt)); + if (ret != sizeof(newpt) || memcmp(origpt, newpt, sizeof(newpt))) { + printf("AES CTR decrytion error"); + return 1; + } + + return 0; +} + +static int rngtest(void) +{ + uint8_t out[67]; + ssize_t ret; + + ret = kcapi_rng_get_bytes(out, sizeof(out)); + if (ret != sizeof(out)) { + printf("Random number generation error"); + return 1; + } + + return 0; +} + +int main(int argc, char *argv[]) +{ + int ret; + + (void)argc; + (void)argv; + + ret = hashtest(); + printf("hash success\\n"); + if (ret) + return ret; + + ret = hmactest(); + printf("hmac success\\n"); + if (ret) + return ret; + + ret = ciphertest(); + printf("cipher success\\n"); + if (ret) + return ret; + + ret = rngtest(); + printf("Random number generation success\\n"); + if (ret) + return ret; + + return 0; +} + +测试步骤: +- 执行命令`gcc -o /tmp/ghm/test_libkcapi /tmp/ghm/test_libkcapi.c -lkcapi` +- 执行命令`/tmp/ghm/test_libkcapi` + +期望结果: +- 命令执行成功,生成/tmp/ghm/test_libkcapi脚本 +- 命令执行成功,返回hash success\n hmac success\n cipher success\n Random number generation success \ No newline at end of file diff --git a/docs/apps_libraries/libkcapi/tc_libkcapi_func002.yaml b/docs/apps_libraries/libkcapi/tc_libkcapi_func002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e0c1a3c74d07d11e3a7641122ac4771864eeb7bd --- /dev/null +++ b/docs/apps_libraries/libkcapi/tc_libkcapi_func002.yaml @@ -0,0 +1,65 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libkcapi库对数据流连续AES-CBC模式加密 +修改人: gaohongmei + +前置条件: +- 创建test_libkcapi.c脚本,采用同一固定密钥进行初始化后进行50轮循环加密 +#include +#include + +int main(int argc, char *argv[]) +{ + char buf[8192]; + struct kcapi_handle *handle; + struct iovec iov; + ssize_t ret; + int i; + + (void)argc; + (void)argv; + + iov.iov_base = buf; + + ret = kcapi_cipher_init(&handle, "cbc(aes)", 0); + if (ret) + return (int)ret; + + ret = kcapi_cipher_setkey(handle, (unsigned char *)"0123456789abcdef", 16); + if (ret) + return (int)ret; + + ret = kcapi_cipher_stream_init_enc(handle, (unsigned char *)"0123456789abcdef", NULL, 0); + if (ret < 0) + return (int)ret; + + for (i = 0; i < 50; i++) { + printf("round %d\\n", i); + + iov.iov_len = 6182; + ret = kcapi_cipher_stream_update(handle, &iov, 1); + if (ret < 0) + return (int)ret; + + iov.iov_len = 6182; + ret = kcapi_cipher_stream_op(handle, &iov, 1); + if (ret < 0) + return (int)ret; + } + + kcapi_cipher_destroy(handle); + + return 0; +} + +测试步骤: +- 执行命令`gcc -o /tmp/ghm/test_libkcapi /tmp/ghm/test_libkcapi.c -lkcapi` +- 执行命令`/tmp/ghm/test_libkcapi` + +期望结果: +- 命令执行成功,生成/tmp/ghm/test_libkcapi脚本 +- 命令执行成功,返回round 0\n ...round 49 \ No newline at end of file diff --git a/docs/apps_libraries/libkcapi/tc_libkcapi_func003.yaml b/docs/apps_libraries/libkcapi/tc_libkcapi_func003.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e418327eb34d3f0f8b177ecf8e7dafc51be76733 --- /dev/null +++ b/docs/apps_libraries/libkcapi/tc_libkcapi_func003.yaml @@ -0,0 +1,54 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libkcapi库针对密码基密钥派生函数 +修改人: gaohongmei + +前置条件: +- 创建test_libkcapi.c脚本,使用kcapi_pbkdf函数 +#include +#include +#include +#include "kcapi.h" + +#define PASSWORD "my_password" +#define SALT "a_salt_string" +#define KEY_LEN 32 +#define ITERATIONS 10000 // Example iteration count + +int main() { + uint8_t password[strlen(PASSWORD)]; + uint8_t salt[strlen(SALT)]; + uint8_t key[KEY_LEN]; + + // Convert strings to binary arrays + strncpy((char*)password, PASSWORD, sizeof(password)); + password[strlen(PASSWORD)] = '\\0'; + strncpy((char*)salt, SALT, sizeof(salt)); + salt[strlen(SALT)] = '\\0'; + + // Call kcapi_pbkdf function + ssize_t ret = kcapi_pbkdf("hmac(sha256)", password, strlen(PASSWORD), salt, strlen(SALT), ITERATIONS, key, KEY_LEN); + if (ret < 0) { + fprintf(stderr, "Error deriving key using kcapi_pbkdf: %ld\\n", (long)ret); + return EXIT_FAILURE; + } + + printf("Derived key (%zu bytes): ", KEY_LEN); + for(size_t i = 0; i < KEY_LEN; ++i) + printf("%02x", key[i]); + printf("\\n"); + + return EXIT_SUCCESS; +} + +测试步骤: +- 执行命令`gcc -o /tmp/ghm/test_libkcapi /tmp/ghm/test_libkcapi.c -lkcapi` +- 执行命令`/tmp/ghm/test_libkcapi` + +期望结果: +- 命令执行成功,生成/tmp/ghm/test_libkcapi脚本 +- 命令执行成功,返回Derived key (32 bytes): e4915621fe384081653bd51de05a22dbd441e38d38e90c75828966b1830fe076 \ No newline at end of file diff --git a/docs/apps_libraries/libkcapi/tc_libkcapi_func004.yaml b/docs/apps_libraries/libkcapi/tc_libkcapi_func004.yaml new file mode 100644 index 0000000000000000000000000000000000000000..85586114e22a552e14f60c6128a5c95a6609bdb6 --- /dev/null +++ b/docs/apps_libraries/libkcapi/tc_libkcapi_func004.yaml @@ -0,0 +1,80 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libkcapi库实现基于CTR模式的密钥派生 +修改人: gaohongmei + +前置条件: +- 创建test_libkcapi.c脚本,使用kcapi_kdf_ctr函数 +#include +#include +#include +#include +#include "kcapi.h" + +#define PASSWORD "my_password" +#define SALT "a_salt_string" +#define KEY_LEN 32 +#define LABEL "ExampleLabel" +#define CONTEXT "SomeContextData" +#define SHARED_SECRET "ThisIsTheSharedSecret" +#define DIGEST_SIZE 32 // 假设使用的哈希函数的digest大小 + +int main() { + struct kcapi_handle *handle; + ssize_t ret; + uint8_t derived_key[KEY_LEN]; + uint8_t src[strlen(LABEL) + 1 + strlen(CONTEXT) + 1]; // 不需要SHARED_SECRET,因为这是SP800-108的用法 + uint8_t hmac_key[DIGEST_SIZE]; // 创建一个密钥缓冲区,大小等于digest大小 + + // 填充密钥(这里仅做示例,实际应用中应从可靠源获取或生成密钥) + memset(hmac_key, 0x00, DIGEST_SIZE); + + // 将数据填充到src缓冲区 + memcpy(src, LABEL, strlen(LABEL)); + src[strlen(LABEL)] = '\\0'; // 添加0x00分隔符 + memcpy(src + strlen(LABEL) + 1, CONTEXT, strlen(CONTEXT) + 1); + + // 初始化KC-API句柄 + handle = NULL; + ret = kcapi_md_init(&handle, "hmac(sha256)", 0); // 参数3暂时留空,根据实际需求设置 + if (ret < 0) { + perror("Failed to initialize kcapi_handle"); + return EXIT_FAILURE; + } + + // 设置密钥,即使对于SP800-108可能不直接使用 + ret = kcapi_md_setkey(handle, hmac_key, DIGEST_SIZE); + if (ret < 0) { + perror("Failed to set key for HMAC-SHA256"); + kcapi_md_destroy(handle); + return EXIT_FAILURE; + } + + // 示例:使用kcapi_kdf_ctr() + ret = kcapi_kdf_ctr(handle, src, strlen(LABEL) + 1 + strlen(CONTEXT) + 1, derived_key, KEY_LEN); + if (ret < 0) { + perror("Error deriving key using kcapi_kdf_ctr:"); + } else { + printf("Derived key using kcapi_kdf_ctr (%zu bytes): ", KEY_LEN); + for(size_t i = 0; i < KEY_LEN; ++i) + printf("%02x", derived_key[i]); + printf("\\n"); + } + + // 释放KC-API句柄资源 + kcapi_md_destroy(handle); + + return EXIT_SUCCESS; +} + +测试步骤: +- 执行命令`gcc -o /tmp/ghm/test_libkcapi /tmp/ghm/test_libkcapi.c -lkcapi` +- 执行命令`/tmp/ghm/test_libkcapi` + +期望结果: +- 命令执行成功,生成/tmp/ghm/test_libkcapi脚本 +- 命令执行成功,返回Derived key using kcapi_kdf_ctr (32 bytes): fe4f051250badca61caa9b1dfb0245790c91d6aaac65654fb8d86f024f402aeb \ No newline at end of file diff --git a/docs/apps_libraries/protobuf-c/tc_protobuf_c_func001.yaml b/docs/apps_libraries/protobuf-c/tc_protobuf_c_func001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..58f7384fb8f79bcaee0c90c2407165f464070ad0 --- /dev/null +++ b/docs/apps_libraries/protobuf-c/tc_protobuf_c_func001.yaml @@ -0,0 +1,72 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: protobuf-c库对字符和整数类型进行序列化和反序列化测试 +修改人: gaohongmei + +前置条件: +- 定义my_message.proto文件 +syntax = "proto3"; +package MyPackage; + +message MyMessage { + string name = 1; + int32 id = 2; +} +- 编写test_my_message.c文件 +#include +#include +#include "my_message.pb-c.h" +#include +int main() { + MyPackage__MyMessage *message = (MyPackage__MyMessage *) malloc(sizeof(MyPackage__MyMessage)); + if (message == NULL) { + perror("Failed to allocate memory for message\\n"); + return 1; + } + // 注意:这里假设MyPackage__MyMessage的descriptor全局可见 + message->base.descriptor = &my_package__my_message__descriptor; + // 填充字段 + message->name = strdup("Test Message"); + message->id = 42; + // 计算并分配足够的内存来存储序列化后的数据 + size_t packed_size = my_package__my_message__get_packed_size(message); + uint8_t *buffer = malloc(packed_size); + // 序列化到缓冲区 + if (!my_package__my_message__pack(message, buffer)) { + printf("Failed to pack the message.\\n"); + free(message->name); // 释放之前分配的name字符串 + free(message); + free(buffer); + return EXIT_FAILURE; + } + // 解码 + MyPackage__MyMessage *parsed_message = my_package__my_message__unpack(NULL, packed_size, buffer); + assert(parsed_message != NULL); + assert(strcmp(parsed_message->name, message->name) == 0); + assert(parsed_message->id == message->id); + // 清理资源 + free(message->name); + free(message); + my_package__my_message__free_unpacked(parsed_message, NULL); + free(buffer); + + printf("MyMessage serialization and deserialization test succeeded.\\n"); + return EXIT_SUCCESS; +} + +测试步骤: +- 编写my_message.proto文件,定义MyPackage.MyMessage的消息类型 +- 执行"protoc-c --proto_path=/tmp/ghm --c_out=/tmp/ghm /tmp/ghm/my_message.proto",编译my_message.proto文件 +- 编写test_my_message.c文件,包含MyPackage__MyMessage 类型的指针变量 message,对变量进行获取、缓存到序列化、解码、释放操作 +- 执行"gcc -o /tmp/ghm/test_my_message /tmp/ghm/test_my_message.c /tmp/ghm/my_message.pb-c.c -lprotobuf-c",编译脚本后执行 + + +期望结果: +- 文件创建成功 +- 编译成功,生成my_message.pb-c.c和my_message.pb-c.h文件 +- 文件创建成功 +- 编译成功,脚本执行成功 diff --git a/docs/apps_libraries/protobuf-c/tc_protobuf_c_func002.yaml b/docs/apps_libraries/protobuf-c/tc_protobuf_c_func002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..868f004a6d2d344286343e1d3bc2ba6850ceda2f --- /dev/null +++ b/docs/apps_libraries/protobuf-c/tc_protobuf_c_func002.yaml @@ -0,0 +1,119 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: protobuf-c库对枚举类型扩展字段消息进行序列化和反序列化测试 +修改人: gaohongmei + +前置条件: +- 定义enums.proto文件 +syntax = "proto3"; + +package MyPackage; + +enum Color { + RED = 0; + GREEN = 1; + BLUE = 2; +} +- 定义my_message.proto文件 +syntax = "proto3"; + +import "enums.proto"; + +message MyMessage { + string name = 1; + oneof custom_data { + MyPackage.Color favorite_color = 2; + } +} + +- 编写test_my_message.c文件 +#include +#include +#include +#include "enums.pb-c.h" +#include "my_message.pb-c.h" + +// 自定义的字符串复制函数 +static inline char* my_strdup(const char* src) { + size_t len = strlen(src); + char* dest = (char*)malloc(len + 1); + if (dest) { + memcpy(dest, src, len + 1); + } + return dest; +} + +int main() { + // 创建并初始化MyMessage + MyMessage *message = (MyMessage*) calloc(1, sizeof(MyMessage)); + if (message == NULL) { + fprintf(stderr, "Failed to allocate memory for MyMessage.\\n"); + return EXIT_FAILURE; + } + + // 初始化MyMessage结构体 + my_message__init(message); + + // 设置基础字段 + message->name = my_strdup("A Custom Message"); + if (message->name == NULL) { + fprintf(stderr, "Failed to allocate memory for name field.\\n"); + goto cleanup; + } + + // 设置oneof字段(模拟扩展) + message->custom_data_case = MY_MESSAGE__CUSTOM_DATA_FAVORITE_COLOR; + message->favorite_color = MY_PACKAGE__COLOR__GREEN; + + // 序列化与反序列化 + size_t packed_size = my_message__get_packed_size(message); + uint8_t *buffer = malloc(packed_size); + if (!my_message__pack(message, buffer)) { + fprintf(stderr, "Failed to pack the message.\\n"); + goto cleanup; + } + + // 反序列化 + MyMessage *parsed_message = my_message__unpack(NULL, packed_size, buffer); + if (!parsed_message) { + fprintf(stderr, "Failed to unpack the message.\\n"); + goto cleanup; + } + + // 验证oneof字段是否正确恢复 + if (parsed_message->custom_data_case == MY_MESSAGE__CUSTOM_DATA_FAVORITE_COLOR) { + assert(parsed_message->favorite_color == MY_PACKAGE__COLOR__GREEN); + } else { + fprintf(stderr, "Favorite color was not correctly deserialized.\\n"); + goto cleanup; + } + +cleanup: + // 清理资源 + my_message__free_unpacked(parsed_message, NULL); + my_message__free_unpacked(message, NULL); + free(buffer); + + // 如果能到达这里,说明测试通过 + printf("MyMessage serialization and deserialization test succeeded.\\n"); + return EXIT_SUCCESS; +} + +测试步骤: +- 编写enums.proto 和 my_message.proto文件,定义MyPackage.MyMessage的消息类型 +- 执行"protoc-c --proto_path=/tmp/ghm --c_out=/tmp/ghm /tmp/ghm/enums.proto",编译enums.proto文件 +- 执行"protoc-c --proto_path=/tmp/ghm --c_out=/tmp/ghm /tmp/ghm/my_message.proto",编译my_message.proto文件 +- 编写test_my_message.c文件,包含MyPackage__MyMessage 类型的指针变量 message,对变量进行获取、缓存到序列化、解码、释放操作 +- 执行"gcc -o /tmp/ghm/test_my_message /tmp/ghm/test_my_message.c /tmp/ghm/my_message.pb-c.c -lprotobuf-c",编译脚本后执行 + + +期望结果: +- 文件创建成功 +- 编译成功,生成enums.pb-c.c和enums.pb-c.h文件 +- 编译成功,生成my_message.pb-c.c和my_message.pb-c.h文件 +- 文件创建成功 +- 编译成功,脚本执行成功 diff --git a/docs/apps_libraries/protobuf-c/tc_protobuf_c_func003.yaml b/docs/apps_libraries/protobuf-c/tc_protobuf_c_func003.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8728d5694fa2679473473f1d01e23426be26cfdf --- /dev/null +++ b/docs/apps_libraries/protobuf-c/tc_protobuf_c_func003.yaml @@ -0,0 +1,85 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: protobuf-c库序列化异常测试 +修改人: gaohongmei + +前置条件: +- 定义my_message.proto文件 +syntax = "proto3"; +package my_package; +message MyMessage { + string field1 = 1; + int32 field2 = 2; +} +- 编写test_my_message.c文件 +#include +#include +#include +#include +#include "my_message.pb-c.h" + +int main() { + // 创建一个MyMessage实例并初始化 + MyPackage__MyMessage msg = MY_PACKAGE__MY_MESSAGE__INIT; + msg.field1 = strdup("Test Field 1"); // 假设填充字段1 + msg.field2 = 123; // 假设填充字段2 + + // 计算序列化所需内存大小 + size_t packed_size = my_package__my_message__get_packed_size(&msg); + + if (packed_size == 0) { + fprintf(stderr, "Failed to calculate packed size.\\n"); + goto cleanup; + } + + // 分配足够大的缓冲区并序列化,然后模拟复制到较小的缓冲区 + uint8_t *big_buffer = malloc(packed_size); + if (big_buffer == NULL) { + perror("Failed to allocate memory for the big buffer."); + goto cleanup; + } + + // 序列化到足够大的缓冲区 + if (!my_package__my_message__pack(&msg, big_buffer)) { + fprintf(stderr, "Failed to serialize to a properly sized buffer.\\n"); + free(big_buffer); + goto cleanup; + } + + // 尝试将大缓冲区的内容复制到较小的缓冲区,模拟序列化到不足的缓冲区 + uint8_t *small_buffer = malloc(packed_size - 6); + if (small_buffer == NULL) { + perror("Failed to allocate memory for the small buffer."); + free(big_buffer); + goto cleanup; + } + printf("Expected behavior: Serializing to a buffer smaller than %zu bytes would cause an overflow or unexpected behavior.\\n", packed_size); + + // 在此处释放资源并退出 + free(small_buffer); + free(big_buffer); + goto cleanup; + +// 清理部分(无需改动) +cleanup: + free(msg.field1); + + return 0; +} + +测试步骤: +- 编写my_message.proto文件,定义MyPackage.MyMessage的消息类型 +- 执行"protoc-c --proto_path=/tmp/ghm --c_out=/tmp/ghm /tmp/ghm/my_message.proto",编译my_message.proto文件 +- 编写test_my_message.c文件,将nMyMessage对象序列化为一个足够大的缓冲区,然后再将该缓冲区的内容复制到一个更小的缓冲区,预期会遇到的问题。 +- 执行"gcc -o /tmp/ghm/test_my_message /tmp/ghm/test_my_message.c /tmp/ghm/my_message.pb-c.c -lprotobuf-c",编译脚本后执行 + + +期望结果: +- 文件创建成功 +- 编译成功,生成my_message.pb-c.c和my_message.pb-c.h文件 +- 文件创建成功 +- 编译成功,脚本执行成功,返回Expected behavior: Serializing to a buffer smaller than 16 bytes would cause an overflow or unexpected behavior. diff --git a/docs/apps_libraries/protobuf-c/tc_protobuf_c_func004.yaml b/docs/apps_libraries/protobuf-c/tc_protobuf_c_func004.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b8f35e2a6fc7e390456d6faedef81bb63add956b --- /dev/null +++ b/docs/apps_libraries/protobuf-c/tc_protobuf_c_func004.yaml @@ -0,0 +1,55 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: protobuf-c库对空序列化进行反序列化测试 +修改人: gaohongmei + +前置条件: +- 定义my_message.proto文件 +syntax = "proto3"; +package my_package; +message MyMessage { + string field1 = 1; + int32 field2 = 2; +} +- 编写test_my_message.c文件 +#include +#include +#include +#include +#include "my_message.pb-c.h" + +int main() { + // 创建一个空的序列化数据缓冲区 + size_t empty_buffer_size = 0; + uint8_t *empty_buffer = malloc(empty_buffer_size); + + // 尝试从空缓冲区反序列化 + MyPackage__MyMessage *empty_msg = my_package__my_message__unpack(NULL, empty_buffer_size, empty_buffer); + if (empty_msg == NULL) { + printf("Deserializing from an empty buffer failed.\\n"); + } else { + printf("Deserialization from an empty buffer succeeded.\\n"); + my_package__my_message__free_unpacked(empty_msg, NULL); + } + + free(empty_buffer); + + return 0; +} + +测试步骤: +- 编写my_message.proto文件,定义MyPackage.MyMessage的消息类型 +- 执行"protoc-c --proto_path=/tmp/ghm --c_out=/tmp/ghm /tmp/ghm/my_message.proto",编译my_message.proto文件 +- 编写test_my_message.c文件,创建了一个大小为0的空缓冲区,然后尝试从中反序列化成功。 +- 执行"gcc -o /tmp/ghm/test_my_message /tmp/ghm/test_my_message.c /tmp/ghm/my_message.pb-c.c -lprotobuf-c",编译脚本后执行 + + +期望结果: +- 文件创建成功 +- 编译成功,生成my_message.pb-c.c和my_message.pb-c.h文件 +- 文件创建成功 +- 编译成功,反序列化成功 diff --git a/docs/apps_libraries/slang/tc_slang_slsh_func001.yaml b/docs/apps_libraries/slang/tc_slang_slsh_func001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d4167f767e2d9ccc53ad11f9cf06b934335c095d --- /dev/null +++ b/docs/apps_libraries/slang/tc_slang_slsh_func001.yaml @@ -0,0 +1,20 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试slang库slsh命令 +修改人: gaohongmei + +前置条件: + +测试步骤: +- 执行命令`slsh --help` +- 执行命令`slsh --version` +- 执行命令`slsh -e 'printf(\"hello\")'` + +期望结果: +- 命令执行成功 +- 命令执行成功,返回版本 +- 命令执行成功,返回hello \ No newline at end of file diff --git a/docs/apps_libraries/slang/tc_slang_slsh_func002.yaml b/docs/apps_libraries/slang/tc_slang_slsh_func002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5968442989f2ae3df65d07ee5e5758a1c6892693 --- /dev/null +++ b/docs/apps_libraries/slang/tc_slang_slsh_func002.yaml @@ -0,0 +1,38 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: slang库拼接字符和递归函数 +修改人: gaohongmei + +前置条件: +- 创建test_slang.sl脚本 +% declare it for recursion +define factorial (); +define factorial (n){ + if (n < 2) return 1; + return n * factorial (n - 1); +} + +define concat_3_strings (a, b, c) { + return a + b + c; +} + +variable x, y, z; +x = "Hello, "; +y = "World !"; +z = "! How are you?"; +variable result = concat_3_strings(x, y, z); +print(factorial (1)); +print(factorial (5)); +print(result); + +测试步骤: +- 执行命令`chmod +x /tmp/ghm/test_slang.sl` +- 执行命令`slsh /tmp/ghm/test_slang.sl` + +期望结果: +- 命令执行成功 +- 命令执行成功,返回1\n 120\n "Hello, World !! How are you?" \ No newline at end of file diff --git a/docs/apps_libraries/slang/tc_slang_slsh_func003.yaml b/docs/apps_libraries/slang/tc_slang_slsh_func003.yaml new file mode 100644 index 0000000000000000000000000000000000000000..10759b62f1896b9eafb573d72634278c0f50054f --- /dev/null +++ b/docs/apps_libraries/slang/tc_slang_slsh_func003.yaml @@ -0,0 +1,46 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: slang库对创建对象的引用 +修改人: gaohongmei + +前置条件: +- 创建test_slang.sl脚本 +define compute_functional_sum (funct) +{ + variable i, s; + s = 0; + for (i = 0; i < 10; i++) + { + s += (@funct)(i); + } + return s; +} + +variable sin_sum = compute_functional_sum (&sin); +variable cos_sum = compute_functional_sum (&cos); +print(sin_sum); +print(cos_sum); + +define set_xyz (x, y, z) +{ + @x = 1; + @y = 2; + @z = 3; +} +variable X, Y, Z; +set_xyz (&X, &Y, &Z); +print(X); +print(Y); +print(Z); + +测试步骤: +- 执行命令`chmod +x /tmp/ghm/test_slang.sl` +- 执行命令`slsh /tmp/ghm/test_slang.sl` + +期望结果: +- 命令执行成功 +- 命令执行成功,返回1.9552094821073802\n 0.42162378262054656\n 1\n 2\n 3 \ No newline at end of file diff --git a/docs/apps_libraries/slang/tc_slang_slsh_func004.yaml b/docs/apps_libraries/slang/tc_slang_slsh_func004.yaml new file mode 100644 index 0000000000000000000000000000000000000000..9ab2dc84848fd615b56f48abd39e8d7a0eccd6f6 --- /dev/null +++ b/docs/apps_libraries/slang/tc_slang_slsh_func004.yaml @@ -0,0 +1,55 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: slang库数组测试 +修改人: gaohongmei + +前置条件: +- 创建test_slang.sl脚本 +% 定义初始化数组的函数 +define init_array(a) { + variable i, imax; + + imax = length(a); + for (i = 0; i < imax; i++) { + a[i] = 7; + } +} + +% 创建并初始化整型数组 +variable A = Int_Type[2]; +init_array(A); +print(A); + +% 创建不同类型的数组 +variable D = Double_Type [3]; +variable F = Complex_Type [3]; +variable G = String_Type [3]; +variable H = Ref_Type [4]; +print(D); +print(F); + +% 创建Any_Type数组并赋值不同类型的数据后取消引用 +variable I = Any_Type[3]; +I[0] = 1; +I[1] = "string"; +I[2] = (1 + 2i); +print(I); + +% 数组运算示例 +variable X = [0:1*PI:0.1]; +variable Y = 2 * sin(X); +print(X); +print(Y); +print("test success"); + +测试步骤: +- 执行命令`chmod +x /tmp/ghm/test_slang.sl` +- 执行命令`slsh /tmp/ghm/test_slang.sl` + +期望结果: +- 命令执行成功 +- 命令执行成功,返回内容中有test success \ No newline at end of file diff --git a/docs/apps_libraries/slang/tc_slang_slsh_func005.yaml b/docs/apps_libraries/slang/tc_slang_slsh_func005.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f325eb6a2bbfd89e6d9056c015461dbe38488cc8 --- /dev/null +++ b/docs/apps_libraries/slang/tc_slang_slsh_func005.yaml @@ -0,0 +1,65 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: slang库File Input/Output +修改人: gaohongmei + +前置条件: +- 创建test_slang.sl脚本 +define count_lines_in_file (file) +{ + variable fp, line, count; + + fp = fopen (file, "r"); % 以读取模式打开文件 + if (fp == NULL) + throw OpenError, "$file failed to open"$; + + count = 0; + while (-1 != fgets (&line, fp)) + count++; + + () = fclose (fp); + return count; +} + +define count_bytes_in_file (file) +{ + variable fp, line, count; + + fp = fopen (file, "r"); + if (fp == NULL) + throw OpenError, "$file failed to open"$; + + count = 0; + while (-1 != fgets (&line, fp)) + count += strlen (line); + + () = fclose (fp); + return count; +} + +variable V1 = count_lines_in_file("/tmp/ghm/test"); +print(V1); +variable V2 = count_bytes_in_file("/tmp/ghm/test"); +print(V2); +variable V3 = count_bytes_in_file("/tmp/ghm/emptytest"); +print(V3); +variable V4 = count_lines_in_file("/tmp/ghm/emptytest"); +print(V4); +variable V5 = count_lines_in_file("/tmp/ghm/notexit"); +print(V5); + +测试步骤: +- 执行命令`echo 'hello\n world' > /tmp/ghm/test` +- 执行命令`touch /tmp/ghm/emptytest` +- 执行命令`chmod +x /tmp/ghm/test_slang.sl` +- 执行命令`slsh /tmp/ghm/test_slang.sl` + +期望结果: +- 命令执行成功,文件创建成功 +- 命令执行成功,空文件创建成功 +- 命令执行成功,文件可执行 +- 命令执行成功,返回结果2\n 13\n 0\n 0\n failed to open\n /tmp/ghm/test_slang.sl:7:count_lines_in_file:Open failed \ No newline at end of file diff --git a/docs/apps_libraries/snappy/tc_snappy_func001.yaml b/docs/apps_libraries/snappy/tc_snappy_func001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3e7b3443bfdc57016bcc36b0e1fe53885e81a86d --- /dev/null +++ b/docs/apps_libraries/snappy/tc_snappy_func001.yaml @@ -0,0 +1,86 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: snappy对多行字符串进行压缩和解压缩 +修改人: gaohongmei + +前置条件: +- 创建test_snappy.c脚本 +#include +#include +#include +#include "snappy-c.h" + +//TEST_STRING "This is a test string for Snappy compression." +// 定义多行字符串常量 +#define TEST_STRING "This is snappy test \ +..........\ +000000\ +success" +#define MAX_COMPRESSION_RATIO 1.1 /* 假设最大压缩比为1.1倍,用于避免解压缓冲区过小 */ + +int main(void) { + + // 定义原始数据和缓冲区 + const char* original_data = TEST_STRING; + size_t original_len = strlen(TEST_STRING); + size_t compressed_len = snappy_max_compressed_length(original_len); + char* compressed = malloc(compressed_len); + if (!compressed) { + fprintf(stderr, "Failed to allocate memory for compressed data.\\n"); + return EXIT_FAILURE; + } + size_t decompressed_len = original_len * MAX_COMPRESSION_RATIO; + char* decompressed = malloc(decompressed_len); + if (!decompressed) { + fprintf(stderr, "Failed to allocate memory for decompressed data.\\n"); + free(compressed); + return EXIT_FAILURE; + } + + // 压缩原始数据 + snappy_status compress_status = snappy_compress(original_data, original_len, compressed, &compressed_len); + if (compress_status != SNAPPY_OK) { + fprintf(stderr, "Failed to compress data"); + goto cleanup; + } + printf("Original size: %zu, Compressed size: %zu\\n", original_len, compressed_len); + + // 获取解压缩后的长度 + snappy_status len_status = snappy_uncompressed_length(compressed, compressed_len, &decompressed_len); + if (len_status != SNAPPY_OK) { + goto cleanup; + } + printf("Original size: %zu, Deompressed size: %zu\\n", original_len, decompressed_len); + + // 解压缩数据 + snappy_status uncompress_status = snappy_uncompress(compressed, compressed_len, decompressed, &decompressed_len); + if (uncompress_status != SNAPPY_OK) { + fprintf(stderr, "Failed to decompress data"); + goto cleanup; + } + printf("Original size: %zu, Decompressed actual size: %zu\\n", original_len, decompressed_len); + + // 检查解压后的数据是否与原始数据一致 + if (decompressed_len == original_len && memcmp(original_data, decompressed, original_len) == 0) { + printf("Compression and Decompression successful, data matches!\\n"); + } else { + printf("Decompressed data does not match the original data.\\n"); + } + +cleanup: + free(compressed); + free(decompressed); + return uncompress_status == SNAPPY_OK ? EXIT_SUCCESS : EXIT_FAILURE; +} + +测试步骤: +- 执行命令`gcc -o /tmp/ghm/test_snappy /tmp/ghm/test_snappy.c -lsnappy`,编译压缩和解压缩字符串脚本 +- 执行命令`/tmp/ghm/test_snappy` + +期望结果: +- 命令执行成功,生成/tmp/ghm/test_snappy脚本 +- 命令执行成功,返回Compression and Decompression successful, data matches! \ No newline at end of file diff --git a/docs/apps_libraries/snappy/tc_snappy_func002.yaml b/docs/apps_libraries/snappy/tc_snappy_func002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ced25f5e48866171b37faf165d31ce00f1820175 --- /dev/null +++ b/docs/apps_libraries/snappy/tc_snappy_func002.yaml @@ -0,0 +1,128 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: snappy对2G文件进行压缩和解压缩 +修改人: gaohongmei + +前置条件: +- 创建test_snappy.c脚本 +#include +#include +#include +#include "snappy-c.h" + +#define BLOCK_SIZE (1024 * 1024 * 256) +#define INPUT_FILE "/tmp/ghm/snappy.txt" +#define COMPRESSED_OUTPUT_FILE "/tmp/ghm/snappy_compressed.snappy" +#define DECOMPRESSED_OUTPUT_FILE "/tmp/ghm/snappy_decompressed.txt" + +void test_snappy_512mb_file(void) { + FILE *in_file = fopen(INPUT_FILE, "rb"); + if (!in_file) { + perror("Failed to open input file"); + exit(EXIT_FAILURE); + } + + FILE *out_compressed_file = fopen(COMPRESSED_OUTPUT_FILE, "wb"); + if (!out_compressed_file) { + perror("Failed to open compressed output file"); + fclose(in_file); + exit(EXIT_FAILURE); + } + + FILE *out_decompressed_file = fopen(DECOMPRESSED_OUTPUT_FILE, "wb"); + if (!out_decompressed_file) { + perror("Failed to open decompressed output file"); + fclose(in_file); + fclose(out_compressed_file); + exit(EXIT_FAILURE); + } + + char *input_block = malloc(BLOCK_SIZE); + char *compressed_block = malloc(snappy_max_compressed_length(BLOCK_SIZE)); + size_t compressed_length; + + // 分块读取、压缩并写入压缩文件 + while (1) { + size_t read_length = fread(input_block, 1, BLOCK_SIZE, in_file); + compressed_length = snappy_max_compressed_length(read_length); + if (read_length == 0) { + if (feof(in_file)) { + break; // 到达文件末尾 + } else { + perror("Error reading from input file"); + exit(EXIT_FAILURE); + } + } + + snappy_status status = snappy_compress(input_block, read_length, compressed_block, &compressed_length); + if (status != SNAPPY_OK) { + fprintf(stderr, "Compression failed with status: %d\\n", status); + exit(EXIT_FAILURE); + } + printf("Original size: %zu, compressed actual size: %zu\\n", read_length, compressed_length); + fwrite(compressed_block, 1, compressed_length, out_compressed_file); + } + + // 关闭并重新打开压缩文件以进行解压缩 + fclose(out_compressed_file); + out_compressed_file = fopen(COMPRESSED_OUTPUT_FILE, "rb"); + + size_t decompressed_length; + char *decompressed_block = malloc(BLOCK_SIZE); + + while (1) { + size_t read_length = fread(compressed_block, 1, BLOCK_SIZE, out_compressed_file); + if (read_length == 0) { + if (feof(out_compressed_file)) { + break; // 到达文件末尾 + } else { + perror("Error reading from compressed file"); + exit(EXIT_FAILURE); + } + } + + snappy_uncompressed_length(compressed_block, read_length, &decompressed_length); + decompressed_block = realloc(decompressed_block, decompressed_length); + printf("Original size: %zu, Decompressed size: %zu\\n", BLOCK_SIZE, decompressed_length); + snappy_status status = snappy_uncompress(compressed_block, read_length, decompressed_block, &decompressed_length); + if (status != SNAPPY_OK) { + fprintf(stderr, "Decompression failed with status: %d\\n", status); + exit(EXIT_FAILURE); + } + printf("Original size: %zu, Decompressed actual size: %zu\\n", BLOCK_SIZE, decompressed_length); + fwrite(decompressed_block, 1, decompressed_length, out_decompressed_file); + } + // 检查解压后的数据是否与原始数据一致 + if (decompressed_length == BLOCK_SIZE && memcmp(input_block, decompressed_block, BLOCK_SIZE) == 0) { + printf("Compression and Decompression successful, data matches!\\n"); + } else { + printf("Decompressed data does not match the original data.\\n"); + } + + // 清理资源 + free(input_block); + free(compressed_block); + free(decompressed_block); + fclose(in_file); + fclose(out_compressed_file); + fclose(out_decompressed_file); +} + +int main() { + test_snappy_512mb_file(); + return EXIT_SUCCESS; +} + +测试步骤: +- 执行命令`yes a | head -c 268435456 > /tmp/ghm/snappy.txt`,创建256M的文件 +- 执行命令`gcc -o /tmp/ghm/test_snappy02 /tmp/ghm/test_snappy02.c -lsnappy`,编译压缩和解压缩文件脚本 +- 执行命令`/tmp/ghm/test_snappy02` + +期望结果: +- 命令执行成功,创建256M的文件 +- 命令执行成功,生成/tmp/ghm/test_snappy02脚本 +- 命令执行成功,返回Compression and Decompression successful, data matches! \ No newline at end of file diff --git a/docs/apps_libraries/snappy/tc_snappy_func003.yaml b/docs/apps_libraries/snappy/tc_snappy_func003.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3b3c84e67939f97300c5837bef49d9dbc860acf5 --- /dev/null +++ b/docs/apps_libraries/snappy/tc_snappy_func003.yaml @@ -0,0 +1,73 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: snappy对空值进行压缩和解压缩 +修改人: gaohongmei + +前置条件: +- 创建/tmp/ghm/test_snappy_null.c脚本 +#include +#include +#include +#include "snappy-c.h" + +int main() { + // 定义一个空字符串 + char empty_input[1] = {0}; + size_t input_len = 0; + + // 获取压缩后的最大长度 + size_t compressed_len = snappy_max_compressed_length(input_len); + + // 分配压缩缓冲区 + char* compressed_buffer = malloc(compressed_len); + if (compressed_buffer == NULL) { + fprintf(stderr, "Failed to allocate memory for compressed data.\\n"); + return EXIT_FAILURE; + } + + // 压缩空字符串 + snappy_status compress_status = snappy_compress(empty_input, input_len, compressed_buffer, &compressed_len); + if (compress_status != SNAPPY_OK) { + fprintf(stderr, "Failed to compress empty input properly: %d\\n", compress_status); + free(compressed_buffer); + return EXIT_FAILURE; + } + + // 因为snappy_compress在实际压缩空输入时会更新compressed_length,所以这里可以直接使用 + // 但也可以选择保留原样,因为对空输入来说,压缩后的长度总是0 + + // 计算解压缩所需长度 + size_t decompressed_length; + snappy_status status = snappy_uncompressed_length(compressed_buffer, compressed_len, &decompressed_length); + if (status != SNAPPY_OK) { + fprintf(stderr, "Failed to get decompressed length for empty input: %d\\n", status); + free(compressed_buffer); + return EXIT_FAILURE; + } + + // 验证解压缩长度为0 + if (decompressed_length != 0) { + fprintf(stderr, "Unexpected decompressed length for empty input: %zu (expected 0)\\n", decompressed_length); + free(compressed_buffer); + return EXIT_FAILURE; + } + + printf("Successfully compressed and decompressed empty input.\\n"); + + // 无需解压缩,因为我们知道结果应为空 + + free(compressed_buffer); + return 0; +} + +测试步骤: +- 执行命令`gcc -o /tmp/ghm/test_snappy_null /tmp/ghm/test_snappy_null.c -lsnappy`,编译压缩和解压缩字符串脚本 +- 执行命令`/tmp/ghm/test_snappy_null` + +期望结果: +- 命令执行成功,生成/tmp/ghm/test_snappy_null脚本 +- 命令执行成功,返回Successfully compressed and decompressed empty input. \ No newline at end of file diff --git a/docs/apps_libraries/snappy/tc_snappy_func004.yaml b/docs/apps_libraries/snappy/tc_snappy_func004.yaml new file mode 100644 index 0000000000000000000000000000000000000000..dbfe89c2d35409c42bbd2b3a4377e910f7e81197 --- /dev/null +++ b/docs/apps_libraries/snappy/tc_snappy_func004.yaml @@ -0,0 +1,59 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 验证snappy库缓存区过小 +修改人: gaohongmei + +前置条件: +- 创建/tmp/ghm/test_snappy_small.c脚本 +#include +#include +#include +#include "snappy-c.h" + +#define TEST_DATA "This is a test string for Snappy buffer size test." +#define TEST_DATA_LEN (strlen(TEST_DATA)) + +int main(void) { + // 压缩数据 + char compressed[snappy_max_compressed_length(TEST_DATA_LEN)]; + size_t compressed_len; + snappy_status compress_status = snappy_compress(TEST_DATA, TEST_DATA_LEN, compressed, &compressed_len); + if (compress_status != SNAPPY_OK) { + fprintf(stderr, "Failed to compress data\\n"); + return EXIT_FAILURE; + } + + // 获取解压缩后的预期长度 + size_t expected_decompressed_len; + snappy_status len_status = snappy_uncompressed_length(compressed, compressed_len, &expected_decompressed_len); + if (len_status != SNAPPY_OK) { + fprintf(stderr, "Failed to get decompressed length\\n"); + return EXIT_FAILURE; + } + + // 尝试使用比预期长度小的缓冲区解压缩 + size_t small_buffer_len = expected_decompressed_len - 1; + char small_decompressed[small_buffer_len]; + + snappy_status uncompress_status = snappy_uncompress(compressed, compressed_len, small_decompressed, &small_buffer_len); + if (uncompress_status != SNAPPY_BUFFER_TOO_SMALL) { + fprintf(stderr, "Expected SNAPPY_BUFFER_TOO_SMALL error, but got: %d\\n", uncompress_status); + return EXIT_FAILURE; + } + + printf("Successfully tested that snappy returns SNAPPY_BUFFER_TOO_SMALL when provided with a too small buffer.\\n"); + + return EXIT_SUCCESS; +} + +测试步骤: +- 执行命令`gcc -o /tmp/ghm/test_snappy_small /tmp/ghm/test_snappy_small.c -lsnappy`,编译压缩和解压缩字符串脚本 +- 执行命令`/tmp/ghm/test_snappy_small` + +期望结果: +- 命令执行成功,生成/tmp/ghm/test_snappy_small脚本 +- 命令执行成功,返回Successfully tested that snappy returns SNAPPY_BUFFER_TOO_SMALL when provided with a too small buffer. \ No newline at end of file diff --git a/docs/databases/gdbm/tc_gdbm_gdbm_dump_func_001.yaml b/docs/databases/gdbm/tc_gdbm_gdbm_dump_func_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ceac6d8015b6453dc004afca9661bef4816ef639 --- /dev/null +++ b/docs/databases/gdbm/tc_gdbm_gdbm_dump_func_001.yaml @@ -0,0 +1,22 @@ +作者: liuhaiyang +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: gdbm_dump将GDBM数据库转储到文件. +修改人: liuhaiyang + +前置条件: +- 执行'for i in $(seq 1 3); do echo "store key$i value$i"; done | gdbmtool %s' % (self.db_path)命令创建一个3行数据的测试数据库 +- 执行"ls %s && rm -rf %s" % (str(self.db_path.split(".")[0]), str(self.db_path.split(".")[0]))命令,清理测试文件 + +测试步骤: +- 执行"gdbm_dump %s %s" % (self.db_path, str(self.db_path.split(".")[0]))命令,将GDBM数据库转储到文件 +- 执行"ls %s" % (str(self.db_path.split(".")[0]))命令,查看是否生成文件,期望生成/tmp/gdbm-test文件 +- 执行"cat %s | grep '#:file' | awk -F '=' '{print$2}'" % (str(self.db_path.split(".")[0]))命令,期望结果是/tmp/gdbm-test.db + +期望结果: +- 期望命令执行成功,无返回内容 +- 期望命令执行成功,查询到/tmp/gdbm-test文件 +- 期望命令执行成功,结果为/tmp/gdbm-test.db diff --git a/docs/devel_languages/golang/tc_goang_golang_fun001.yaml b/docs/devel_languages/golang/tc_goang_golang_fun001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f523bf381afb8b301b12cdefcb1d0fac91e85acf --- /dev/null +++ b/docs/devel_languages/golang/tc_goang_golang_fun001.yaml @@ -0,0 +1,15 @@ +: douzhichong +ȼ: P1 +ּ֧ܹ: noarch +ִзʽ: Զ +: ܲ +ͨñǩ: local,golang +: golangܲ +޸: douzhichong + +ǰ: + +Բ: +- дgo򣬲ӡ"Hello, World!" +: +- goɹHello, World! diff --git a/docs/devel_languages/lua/tc_lua_lua_fun003.yaml b/docs/devel_languages/lua/tc_lua_lua_fun003.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e62efe0e3ca678f30a68ded32888bd5bf764b9bb --- /dev/null +++ b/docs/devel_languages/lua/tc_lua_lua_fun003.yaml @@ -0,0 +1,54 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: lua实现函数 +修改人: gaohongmei + +前置条件: +- 创建cauclu.lua脚本,计算两数的加减乘除 +-- 定义四个函数分别对应加减乘除四种运算 +function addNumbers(a, b) + return a + b +end + +function subtractNumbers(a, b) + return a - b +end + +function multiplyNumbers(a, b) + return a * b +end + +function divideNumbers(a, b) + if b == 0 then + return "Error: Division by zero is not allowed." + else + return a / b + end +end + +-- 测试这些函数 +local resultAdd = addNumbers(10, 20) +print("Addition: ", resultAdd) + +local resultSubtract = subtractNumbers(30, 20) +print("Subtraction: ", resultSubtract) + +local resultMultiply = multiplyNumbers(5, 7) +print("Multiplication: ", resultMultiply) + +local resultDivide = divideNumbers(40, 5) +print("Division: ", resultDivide) + +-- 尝试除以零以演示错误处理 +local resultDivideByZero = divideNumbers(10, 0) +print("Division by zero: ", resultDivideByZero) + +测试步骤: +- 执行命令`lua /tmp/ghm/func.lua` + +期望结果: +- 命令执行成功,结果符合预期 \ No newline at end of file diff --git a/docs/devel_languages/lua/tc_lua_lua_fun004.yaml b/docs/devel_languages/lua/tc_lua_lua_fun004.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c15c2da4b004a2d762b67bb6f1e908a1b14a0c84 --- /dev/null +++ b/docs/devel_languages/lua/tc_lua_lua_fun004.yaml @@ -0,0 +1,94 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: lua实现文件I/O操作 +修改人: gaohongmei + +前置条件: +- 创建file.lua脚本,进行文件的创建、查询、修改和删除操作 +local io = require("io") +local os = require("os") + +-- 创建文件 +function createFile(filename) + local file, error_message = io.open(filename, "w") + if not file then + print("Error creating file: ", error_message) + else + -- 写入一些内容(可选) + file:write("This is the content of the new file.") + file:close() + print("File created successfully.") + end +end + +-- 查询文件(判断文件是否存在) +function checkFileExists(filename) + local file_exists = os.rename(filename, filename) and true or false + if file_exists then + print(filename, " exists.") + else + print(filename, " does not exist.") + end + return file_exists +end + +-- 修改文件(追加内容) +function appendToFile(filename, content) + local file, error_message = io.open(filename, "a") + if not file then + print("Error opening file: ", error_message) + else + file:write(content) + file:close() + print("Content appended to the file.") + end +end + +-- 读取并验证文件内容 +function readAndVerifyFile(filename, expectedContent) + local file, error_message = io.open(filename, "r") + if not file then + print("Error opening file for reading: ", error_message) + return false + end + + local actualContent = file:read("*a") -- 读取整个文件内容 + file:close() + + if actualContent == expectedContent then + print("File content matches the expected content.") + return true + else + print("File content does not match the expected content.") + return false + end +end + +-- 删除文件 +function deleteFile(filename) + local result, error_message = os.remove(filename) + if result then + print(filename, " has been deleted.") + else + print("Error deleting file: ", error_message) + end +end + +local filename = "/tmp/ghm/file.txt" +local expectedContent = "This is the content of the new file.\\nNew line added." + +createFile(filename) -- 创建文件 +checkFileExists(filename) -- 查询文件是否存在 +appendToFile(filename, "\\nNew line added.") -- 追加内容到文件 +readAndVerifyFile(filename, expectedContent) +deleteFile(filename) -- 删除文件 + +测试步骤: +- 执行命令`lua /tmp/ghm/file.lua` + +期望结果: +- 命令执行成功,结果符合预期 \ No newline at end of file diff --git a/docs/devel_languages/lua/tc_lua_lua_fun005.yaml b/docs/devel_languages/lua/tc_lua_lua_fun005.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a5214269752b1f6b54155295e4e851966c24d9e9 --- /dev/null +++ b/docs/devel_languages/lua/tc_lua_lua_fun005.yaml @@ -0,0 +1,53 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: lua对table操作 +修改人: gaohongmei + +前置条件: +- 创建/tmp/ghm/table.lua脚本 +-- 创建一个空表 +local myTable = {} +myTable = {1, 2, 3, 4, 5} -- 初始化一个包含整数元素的"数组" + +-- 访问和打印数组元素 +print(myTable[1]) -- 输出:1 +print(myTable[3]) -- 输出:3 + +-- 创建一个混合表(既有数字索引也有字符串索引) +myTable["name"] = "Lua Table Example" +myTable[6] = "sixth element" + +-- 访问和打印混合表元素 +print(myTable["name"]) -- 输出:"Lua Table Example" +print(myTable[6]) -- 输出:"sixth element" + +-- 遍历表中的所有元素(注意,遍历会按照插入顺序进行,不会跳过nil值) +for key, value in pairs(myTable) do + print(key, value) +end + +-- 向表中添加元素 +table.insert(myTable, 7, "seventh element") -- 在索引7之前插入元素,使得原索引7及其之后的元素依次后移 +print(myTable[7]) -- 输出:"seventh element" + +-- 删除表中的元素 +table.remove(myTable, 3) -- 删除索引为3的元素 + +-- 计算表的长度(只计算数字连续索引部分的长度) +print(#myTable) -- 输出:6,因为在索引7处插入元素,但并没有改变最大连续数字索引 + +-- 创建一个新的键值对 +myTable["fruit"] = {"apple", "banana", "cherry"} + +-- 访问嵌套表的元素 +print(myTable.fruit[1]) -- 输出:"apple" + +测试步骤: +- 执行命令`lua /tmp/ghm/table.lua` + +期望结果: +- 命令执行成功,结果符合预期 \ No newline at end of file diff --git a/docs/devel_languages/lua/tc_lua_lua_fun006.yaml b/docs/devel_languages/lua/tc_lua_lua_fun006.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b0fd43a42d99cda06cc59142354e2d86816153d0 --- /dev/null +++ b/docs/devel_languages/lua/tc_lua_lua_fun006.yaml @@ -0,0 +1,58 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: lua写个读取文件内容并对每行的单词进行统计的测试 +修改人: gaohongmei + +前置条件: +- 创建/tmp/ghm/table.lua脚本 +-- 读取文件内容并统计单词出现次数 +function countWords(file_path) + local counts = {} + local io_file = io.open(file_path, "r") + + if io_file then + for line in io.lines(file_path) do + -- 分割每行成单词并转换为小写 + for word in string.gmatch(line:lower(), "%w+") do + counts[word] = (counts[word] or 0) + 1 + end + end + io_file:close() + + -- 找出出现次数最多的单词及其出现次数 + local max_count, most_common_word = 0, nil + for word, count in pairs(counts) do + if count > max_count then + max_count = count + most_common_word = word + end + end + + return most_common_word, max_count + else + return nil, "File not found" + end +end + +-- 示例使用 +local file_path = arg[1] -- 从命令行参数获取文件路径 +local most_common_word, occurrences = countWords(file_path) + +if most_common_word then + print("The most common word is:", most_common_word) + print("It appears", occurrences, "times.") +else + print(most_common_word) +end + +测试步骤: +- 执行命令`echo '123456\n hello\n 456789\n world\n hello 123abc\n' > /tmp/ghm/testfile.txt` +- 执行命令`lua /tmp/ghm/table.lua /tmp/ghm/testfile.txt` + +期望结果: +- 命令执行成功,/tmp/ghm/testfile.txt文件创建成功 +- 命令执行成功,结果返回The most common word is:hello\n It appears 2 times. \ No newline at end of file diff --git a/docs/devel_languages/lua/tc_lua_lua_fun007.yaml b/docs/devel_languages/lua/tc_lua_lua_fun007.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5b6833daf07291341c2218489a87408e0916fb2c --- /dev/null +++ b/docs/devel_languages/lua/tc_lua_lua_fun007.yaml @@ -0,0 +1,134 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: lua缓存 +修改人: gaohongmei + +前置条件: +- 创建/tmp/ghm/table.lua脚本 +-- 定义节点类 +local Node = {} +Node.__index = Node + +function Node.new(key, value) + return setmetatable({key = key, value = value, prev = nil, next = nil}, Node) +end + +-- 定义LRUCache类 +local LRUCache = {} +LRUCache.__index = LRUCache + +function LRUCache.new(capacity) + local cache = setmetatable({ + capacity = capacity or 0, + count = 0, + head = Node.new(nil, nil), + tail = Node.new(nil, nil), + storage = {}, + }, LRUCache) + + cache.head.next = cache.tail + cache.tail.prev = cache.head + + -- 将节点移动到链表头部 + function cache:moveToHead(node) + node.prev.next = node.next + node.next.prev = node.prev + node.prev = self.head + node.next = self.head.next + self.head.next.prev = node + self.head.next = node + end + + -- 移除尾部节点 + function cache:removeTail() + local tail = self.tail.prev + tail.prev.next = self.tail + self.tail.prev = tail.prev + self.storage[tail.key] = nil + self.count = self.count - 1 + end + + -- 设置或获取键对应的值,更新LRU状态 + function cache:updateOrSet(key, value) + if self.capacity == 0 then + return nil + end + + local node = self.storage[key] + + if node then + node.value = value + self:moveToHead(node) + else + if self.count == self.capacity then + self:removeTail() + end + self.count = self.count + 1 + + node = Node.new(key, value) + self.storage[key] = node + node.prev = self.head + node.next = self.head.next + self.head.next.prev = node + self.head.next = node + end + return value + end + + -- 获取键对应的值,更新LRU状态 + function cache:get(key) + if self.capacity == 0 then + return nil + end + + local node = self.storage[key] + if node then + self:moveToHead(node) + return node.value + end + return nil + end + + return cache +end + +-- 使用示例: +local cache = LRUCache.new(3) -- 创建一个容量为3的LRU缓存 + +-- 插入四个元素,注意观察当容量满时的行为 +cache:updateOrSet("one", 1) +cache:updateOrSet("two", 2) +cache:updateOrSet("three", 3) +cache:updateOrSet("four", 4) -- 这会淘汰"one" + +-- 访问已存在的元素,然后插入新元素,观察淘汰机制 +print(cache:get("one")) -- 输出:nil +print(cache:get("two")) -- 输出:2 +print(cache:get("three")) -- 输出:3 +print(cache:get("four")) -- 输出:4 +cache:updateOrSet("five", 5) + +-- 访问被淘汰的元素 +print(cache:get("one")) -- 输出:nil,因为"one"已经被淘汰 +print(cache:get("three")) -- 输出:3 +print(cache:get("two")) -- 输出:nil,因为"two"已经被淘汰 +print(cache:get("four")) -- 输出:4 +print(cache:get("five")) -- 输出:5 + +-- 插入元素,观察行为 +cache:updateOrSet("six", 6) -- 这会淘汰"three" + +-- 再次访问被淘汰的元素 +print(cache:get("three")) -- 输出:nil,因为"three"已经被淘汰 +print(cache:get("two")) -- 输出:nil,因为"two"已经被淘汰 +print(cache:get("six")) -- 输出:6 + +测试步骤: +- 执行命令`lua /tmp/ghm/table.lua` + +期望结果: +- 命令执行成功,结果符合预期 \ No newline at end of file diff --git a/docs/devel_languages/python/tc_python_dateutil_func_001.yaml b/docs/devel_languages/python/tc_python_dateutil_func_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..4c6f0c3db0e99ee0364f66a923d890124b800b62 --- /dev/null +++ b/docs/devel_languages/python/tc_python_dateutil_func_001.yaml @@ -0,0 +1,33 @@ +作者: chenchunhu +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local,python +用例描述: 测试python dateutil模块日期字符串解析功能 +修改人: chenchunhu + +前置条件: +- 安装python3-dateutil包 +- 编写测试文件 dateutil_test1.py +""" + #!/usr/bin/python + # -- coding: UTF-8 -- + + from dateutil import parser + + f = open('dateutil_result1.txt', 'w') + date_strings = ["2024-03-13", "March 13, 2024", "13/03/2024"] + + for date_string in date_strings: + parsed_date = parser.parse(date_string) + f.write(f"{date_string} 解析为 {parsed_date} ") +""" + +测试步骤: +- 执行dateutil_test1.py:python3 dateutil_test1.py +- 查看执行结果:cat dateutil_result1.txt + +期望结果: +- 命令执行成功, 生成dateutil_result1.txt文件 +- 命令执行成功,日期字符串解析功能正常 \ No newline at end of file diff --git a/docs/devel_languages/python/tc_python_dateutil_func_002.yaml b/docs/devel_languages/python/tc_python_dateutil_func_002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..4beb671c1e1c39c8fb7b038f86cd6fc09b39d7f0 --- /dev/null +++ b/docs/devel_languages/python/tc_python_dateutil_func_002.yaml @@ -0,0 +1,35 @@ +作者: chenchunhu +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local,python +用例描述: 测试python dateutil模块时区转换功能 +修改人: chenchunhu + +前置条件: +- 安装python3-dateutil包 +- 编写测试文件 dateutil_test2.py +""" + #!/usr/bin/python + # -- coding: UTF-8 -- + + from dateutil import tz + import datetime + + f = open('dateutil_result2.txt', 'w') + + test_date = datetime.datetime(2024, 3, 13, 14, 25, 30) + utc_time = test_date.replace(tzinfo=datetime.timezone.utc) + f.write(f"UTC时间: {utc_time} ") + local_time = utc_time.astimezone(tz.tzlocal()) + f.write(f"本地时间: {local_time}") +""" + +测试步骤: +- 执行dateutil_test2.py:python3 dateutil_test2.py +- 查看执行结果:cat dateutil_result2.txt + +期望结果: +- 命令执行成功, 生成dateutil_result2.txt文件 +- 命令执行成功,时区转换功能正常 \ No newline at end of file diff --git a/docs/devel_languages/python/tc_python_dateutil_func_003.yaml b/docs/devel_languages/python/tc_python_dateutil_func_003.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8436a0e247179d393adc450fe8074b88ce8c64bb --- /dev/null +++ b/docs/devel_languages/python/tc_python_dateutil_func_003.yaml @@ -0,0 +1,34 @@ +作者: chenchunhu +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local,python +用例描述: 测试python dateutil模块相对日期计算功能 +修改人: chenchunhu + +前置条件: +- 安装python3-dateutil包 +- 编写测试文件 dateutil_test3.py +""" + #!/usr/bin/python + # -- coding: UTF-8 -- + + from dateutil.relativedelta import relativedelta + import datetime + + f = open('dateutil_result3.txt', 'w') + + current_date = datetime.datetime(2024, 3, 13, 14, 25, 30) + f.write(f"当前日期: {current_date} ") + next_month = current_date + relativedelta(months=1) + f.write(f"下个月的日期: {next_month}") +""" + +测试步骤: +- 执行dateutil_test3.py:python3 dateutil_test3.py +- 查看执行结果:cat dateutil_result3.txt + +期望结果: +- 命令执行成功, 生成dateutil_result3.txt文件 +- 命令执行成功,相对日期计算功能正常 \ No newline at end of file diff --git a/docs/devel_languages/python/tc_python_dateutil_func_004.yaml b/docs/devel_languages/python/tc_python_dateutil_func_004.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7d88a18c8a119f45a46eb32292141943f376b936 --- /dev/null +++ b/docs/devel_languages/python/tc_python_dateutil_func_004.yaml @@ -0,0 +1,35 @@ +作者: chenchunhu +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local,python +用例描述: 测试python dateutil模块重复规则功能 +修改人: chenchunhu + +前置条件: +- 安装python3-dateutil包 +- 编写测试文件 dateutil_test4.py +""" + #!/usr/bin/python + # -- coding: UTF-8 -- + + import datetime + from dateutil.rrule import rrule, DAILY + + f = open('dateutil_result4.txt', 'w') + + start_date = datetime.datetime(2024, 3, 13) + rrule_dates = list(rrule(DAILY, count=10, dtstart=start_date)) + f.write(f"从 {start_date} 开始连续10天的日期: ") + for date in rrule_dates: + f.write(f"{date.date()} ") +""" + +测试步骤: +- 执行dateutil_test4.py:python3 dateutil_test4.py +- 查看执行结果:cat dateutil_result4.txt + +期望结果: +- 命令执行成功, 生成dateutil_result4.txt文件 +- 命令执行成功,重复规则功能正常 \ No newline at end of file diff --git a/docs/devel_languages/python/tc_python_dateutil_func_005.yaml b/docs/devel_languages/python/tc_python_dateutil_func_005.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f587ac9acddaaceeb2dc4f7fcb2d4ee54eedd6a0 --- /dev/null +++ b/docs/devel_languages/python/tc_python_dateutil_func_005.yaml @@ -0,0 +1,35 @@ +作者: chenchunhu +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local,python +用例描述: 测试python dateutil模块重复规则功能 +修改人: chenchunhu + +前置条件: +- 安装python3-dateutil包 +- 编写测试文件 dateutil_test5.py +""" + #!/usr/bin/python + # -- coding: UTF-8 -- + + import datetime + from dateutil.rrule import rrule, MONTHLY + + f = open('dateutil_result5.txt', 'w') + + start_date = datetime.datetime(2024, 3, 13) + # 获取从开始日期后6个星期一的日期,0 表示星期一 + rule = rrule(MONTHLY, byweekday=0, count=6, dtstart=start_date) + for date in rule: + f.write(f"{date.date()} ") +""" + +测试步骤: +- 执行dateutil_test5.py:python3 dateutil_test5.py +- 查看执行结果:cat dateutil_result5.txt + +期望结果: +- 命令执行成功, 生成dateutil_result5.txt文件 +- 命令执行成功,重复规则功能正常 \ No newline at end of file diff --git a/docs/os_function/common_tools/whois/tc_whois_fun_002.yaml b/docs/os_function/common_tools/whois/tc_whois_fun_002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2d1ebde79a204dd44a7531e09854d9cdcdb97100 --- /dev/null +++ b/docs/os_function/common_tools/whois/tc_whois_fun_002.yaml @@ -0,0 +1,17 @@ +作者: qintingting +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 验证whois可以访问国际化域名 +修改人: qintingting + +前置条件: +- 安装whois + +测试步骤: +- 执行whois 'xn--e1afmkfd.xn--p1ai'(xn--e1afmkfd.xn--p1ai为'пример.рф'进行idn命令后的俄罗斯ccTLD的域名),检查返回值 + +期望结果: +- 命令执行成功,返回该域名的注册信息包含admin-contact:http://www.cctld.ru diff --git a/docs/os_function/common_tools/whois/tc_whois_fun_003.yaml b/docs/os_function/common_tools/whois/tc_whois_fun_003.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f1b350acf5d732785198e4b027ba157456bea9be --- /dev/null +++ b/docs/os_function/common_tools/whois/tc_whois_fun_003.yaml @@ -0,0 +1,36 @@ +作者: qintingting +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: whois的各种参数验证 +修改人: qintingting + +前置条件: +- 安装whois + +测试步骤: +- 执行whois -h whois.iana.org baidu.com +- 执行whois -h whois.iana.org -p 43 baidu.com +- 执行whois -q version +- 执行whois -t domain +- 执行whois -v person +- 执行whois -I baidu.com +- 执行whois -H baidu.com +- 执行whois -c baidu.com +- 执行whois --no-recursion baidu.com +- 执行whois --help +- 执行whois -b '8.8.8.8' +- 执行whois --verbose +- 执行whois --version +- 执行whois -l baidu.com +- 执行whois -L baidu.com +- 执行whois -i mnt-by baidu.com +- 执行whois -T domain baidu.com +- 执行whois -K baidu.com +- 执行whois -r baidu.com +- 执行whois -R baidu.com +- 执行whois -a baidu.com +期望结果: +- 以上均命令执行成功 diff --git a/docs/os_function/development_tools/compile_language/tc_python3_fun_001.yaml b/docs/os_function/development_tools/compile_language/tc_python3_fun_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2f57dab09eb0d59aa23ce5eb3bf3df5b03c8eee6 --- /dev/null +++ b/docs/os_function/development_tools/compile_language/tc_python3_fun_001.yaml @@ -0,0 +1,20 @@ +作者: qintingting +优先级: P0 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 验证系统支持编写并运行Python3程序 +修改人: qintingting + +前置条件: +- 创建一个py文件,cat > test.py < attr_testfile +ln -s attr_testfile test_link + +测试步骤: +- 执行attr -L -s user.comment -V "Test comment" test_link设置文件的扩展属性 +- 执行attr -L -g user.comment test_link获取目录的扩展属性 +- 执行attr -L -g user.comment attr_testfile获取目录的扩展属性 +- 执行attr -lLq test_link列举所有扩展属性 +- 执行attr -lLq attr_testfile列举所有扩展属性 +- 执行attr -L -r user.comment test_link测试移除文件的扩展属性 +- 执行attr -lLq attr_testfile检查返回值 +- 执行attr -lLq test_link检查返回值 + +期望结果: +- 命令执行成功 +- 输出中包含user.comment属性值Test comment +- 输出中包含user.comment属性值Test comment +- 输出中包含属性user.comment和selinux +- 输出中结果和步骤四一致 +- 移除属性值成功 +- 返回值未包含user.comment +- 返回值未包含user.comment,且返回值和步骤七一致 diff --git a/docs/system_base/attr/tc_attr_ea_fun006.yaml b/docs/system_base/attr/tc_attr_ea_fun006.yaml new file mode 100644 index 0000000000000000000000000000000000000000..64dd020109297d9fa23c460e2a0b9f6ab60861ce --- /dev/null +++ b/docs/system_base/attr/tc_attr_ea_fun006.yaml @@ -0,0 +1,26 @@ +作者: qintingting +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试attr通过-RS限制在安全属性和根属性命名空间中使用 +修改人: qintingting + +前置条件: +- 安装attr包 +- 创建attr_testfile + +测试步骤: +- 执行attr -RS -s security.my_attribute -V 'my_policy' attr_testfile设置文件的扩展属性 +- 执行attr --RS -g security.my_attribute attr_testfile获取目录的扩展属性 +- 执行attr -lRq attr_testfile列举所有扩展属性 +- 执行attr -RS -r security.my_attribute attr_testfile测试移除文件的扩展属性 +- 执行attr -lRq attr_testfile检查返回值 + +期望结果: +- 命令执行成功 +- 输出中包含security.my_attribute属性值my_policy +- 输出中包含属性值security.my_attribute +- 移除属性值成功 +- 返回值未包含security.my_attribute diff --git a/docs/system_base/binutils/tc_binutils_command_addr2line.yaml b/docs/system_base/binutils/tc_binutils_command_addr2line.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d5b48cf6960af6ac47f2bd294ea9719c4991e88a --- /dev/null +++ b/docs/system_base/binutils/tc_binutils_command_addr2line.yaml @@ -0,0 +1,19 @@ +作者: douzhichong +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local,binutils +用例描述: 测试binutils命令addr2line +修改人: douzhichong + +前置条件: + +测试步骤: +- 安装依赖包 +- 编写测试函数,测试文件 +- 根据测试文件生成测试代码 +- 执行测试命令 + +期望结果: +- 输出结果不报错,测试命令有回显结果 diff --git a/docs/system_base/binutils/tc_binutils_command_ar.yaml b/docs/system_base/binutils/tc_binutils_command_ar.yaml new file mode 100644 index 0000000000000000000000000000000000000000..24fbaaed4b2932a0ccbaecde46821dd966359ca7 --- /dev/null +++ b/docs/system_base/binutils/tc_binutils_command_ar.yaml @@ -0,0 +1,20 @@ +作者: douzhichong +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local,binutils +用例描述: 测试binutils命令ar +修改人: douzhichong + +前置条件: + +测试步骤: +- 安装依赖包 +- 编写测试函数,测试文件 +- 根据测试文件生成测试代码 +- 执行测试命令 + +期望结果: +- 输出结果不报错,测试命令有回显结果 + diff --git a/docs/system_base/binutils/tc_binutils_command_nm.yaml b/docs/system_base/binutils/tc_binutils_command_nm.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c7c418f387f30852755ad6e8740f91c38c162564 --- /dev/null +++ b/docs/system_base/binutils/tc_binutils_command_nm.yaml @@ -0,0 +1,20 @@ +作者: douzhichong +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local,binutils +用例描述: 测试binutils命令nm +修改人: douzhichong + +前置条件: + +测试步骤: +- 安装依赖包 +- 编写测试函数,测试文件 +- 根据测试文件生成测试代码 +- 执行测试命令 + +期望结果: +- 输出结果不报错,测试命令有回显结果 + diff --git a/docs/system_base/binutils/tc_binutils_command_objcopy.yaml b/docs/system_base/binutils/tc_binutils_command_objcopy.yaml new file mode 100644 index 0000000000000000000000000000000000000000..55e7de36700bfbe4c35ca7386d13664cb95ad957 --- /dev/null +++ b/docs/system_base/binutils/tc_binutils_command_objcopy.yaml @@ -0,0 +1,20 @@ +作者: douzhichong +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local,binutils +用例描述: 测试binutils命令objcopy +修改人: douzhichong + +前置条件: + +测试步骤: +- 安装依赖包 +- 编写测试函数,测试文件 +- 根据测试文件生成测试代码 +- 执行测试命令 + +期望结果: +- 输出结果不报错,测试命令有回显结果 + diff --git a/docs/system_base/binutils/tc_binutils_command_objdump.yaml b/docs/system_base/binutils/tc_binutils_command_objdump.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c962a5891d9ae4636a44b45a3c251ff701bc0c37 --- /dev/null +++ b/docs/system_base/binutils/tc_binutils_command_objdump.yaml @@ -0,0 +1,20 @@ +作者: douzhichong +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local,binutils +用例描述: 测试binutils命令objdump +修改人: douzhichong + +前置条件: + +测试步骤: +- 安装依赖包 +- 编写测试函数,测试文件 +- 根据测试文件生成测试代码 +- 执行测试命令 + +期望结果: +- 输出结果不报错,测试命令有回显结果 + diff --git a/docs/system_base/binutils/tc_binutils_command_readelf.yaml b/docs/system_base/binutils/tc_binutils_command_readelf.yaml new file mode 100644 index 0000000000000000000000000000000000000000..653869eb499ec983a5fb113e57ec88dcecdbb297 --- /dev/null +++ b/docs/system_base/binutils/tc_binutils_command_readelf.yaml @@ -0,0 +1,20 @@ +作者: douzhichong +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local,binutils +用例描述: 测试binutils命令readelf +修改人: douzhichong + +前置条件: + +测试步骤: +- 安装依赖包 +- 编写测试函数,测试文件 +- 根据测试文件生成测试代码 +- 执行测试命令 + +期望结果: +- 输出结果不报错,测试命令有回显结果 + diff --git a/docs/system_base/binutils/tc_binutils_command_size.yaml b/docs/system_base/binutils/tc_binutils_command_size.yaml new file mode 100644 index 0000000000000000000000000000000000000000..dc58b820118c16f5ddcfa4234ee738778053fae5 --- /dev/null +++ b/docs/system_base/binutils/tc_binutils_command_size.yaml @@ -0,0 +1,20 @@ +作者: douzhichong +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local,binutils +用例描述: 测试binutils命令size +修改人: douzhichong + +前置条件: + +测试步骤: +- 安装依赖包 +- 编写测试函数,测试文件 +- 根据测试文件生成测试代码 +- 执行测试命令 + +期望结果: +- 输出结果不报错,测试命令有回显结果 + diff --git a/docs/system_base/binutils/tc_binutils_command_strip.yaml b/docs/system_base/binutils/tc_binutils_command_strip.yaml new file mode 100644 index 0000000000000000000000000000000000000000..4125146ea3792b232556f9f7b5f335f94dcb78a2 --- /dev/null +++ b/docs/system_base/binutils/tc_binutils_command_strip.yaml @@ -0,0 +1,20 @@ +作者: douzhichong +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local,binutils +用例描述: 测试binutils命令strip +修改人: douzhichong + +前置条件: + +测试步骤: +- 安装依赖包 +- 编写测试函数,测试文件 +- 根据测试文件生成测试代码 +- 执行测试命令 + +期望结果: +- 输出结果不报错,测试命令有回显结果 + diff --git a/docs/system_base/checkpolicy/tc_checkpolicy_checkpolicy_func_002.yaml b/docs/system_base/checkpolicy/tc_checkpolicy_checkpolicy_func_002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f7a44bb33ac2314412757330a7c3f100a32df48e --- /dev/null +++ b/docs/system_base/checkpolicy/tc_checkpolicy_checkpolicy_func_002.yaml @@ -0,0 +1,36 @@ +作者: chenchunhu +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试checkpolicy的编译功能 +修改人: chenchunhu + +前置条件: +- 安装selinux-policy-devel checkpolicy包 +- 创建策略文件test_module.te + module test_module 1.0; + + require { + type user_t; + type unlabeled_t; + class file { read write }; + } + + # 定义一个新的类型 + type my_new_type_t; + + # 创建一个新的文件类型 + type my_new_file_type_t; + + # 定义一条允许规则 + allow user_t my_new_file_type_t:file { read write }; + +测试步骤: +- 执行 checkmodule -M -m -o test_module.mod test_module.te +- 执行 semodule_package -o test_module.pp -m test_module.mod + +期望结果: +- 操作成功,生成一个 test_module.mod 文件 +- 操作成功,生成一个 test_module.pp 文件 \ No newline at end of file diff --git a/docs/system_base/checkpolicy/tc_checkpolicy_checkpolicy_func_003.yaml b/docs/system_base/checkpolicy/tc_checkpolicy_checkpolicy_func_003.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1b628ac2665e5e2b2dc297ff7e346dc1e3022c7e --- /dev/null +++ b/docs/system_base/checkpolicy/tc_checkpolicy_checkpolicy_func_003.yaml @@ -0,0 +1,34 @@ +作者: chenchunhu +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试checkpolicy能够正确识别错误的SELinux策略语言的语法 +修改人: chenchunhu + +前置条件: +- 安装selinux-policy-devel checkpolicy包 +- 创建策略文件test_module.te + module test_module 1.0; + + require { + type user_t; + type unlabeled_t; + class file { read write }; + } + + # 定义一个新的类型 + type my_new_type_t; + + # 创建一个新的文件类型 + type my_new_file_type_t; + + # 故意引入一个语法错误来测试错误处理 + allow user_t my_new_file_type_t; + +测试步骤: +- 执行 checkmodule -M -m -o test_module.mod test_module.te + +期望结果: +- 操作成功,正确别错误test_module.te策略文件中的错误语法 \ No newline at end of file diff --git a/docs/system_base/coreutils/tc_coreutils_grep_fun001.yaml b/docs/system_base/coreutils/tc_coreutils_grep_fun001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0101650d6bc1284286c3641ebf5fbb7a9fcc0a5f --- /dev/null +++ b/docs/system_base/coreutils/tc_coreutils_grep_fun001.yaml @@ -0,0 +1,16 @@ +作者: douzhichong +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local,coreutils +用例描述: 测试grep基本功能 +修改人: douzhichong + +前置条件: 安装coreutils包,创建测试文件 + +测试步骤: +- 查找文件中的关键字 + +期望结果: +- 根据查找的关键字可以查到相应的内容 diff --git a/docs/system_base/coreutils/tc_coreutils_sed_fun001.yaml b/docs/system_base/coreutils/tc_coreutils_sed_fun001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..be0bc78bfc23f7100e2272db80a4714747873a70 --- /dev/null +++ b/docs/system_base/coreutils/tc_coreutils_sed_fun001.yaml @@ -0,0 +1,16 @@ +作者: douzhichong +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local,coreutils +用例描述: 测试sed基本功能 +修改人: douzhichong + +前置条件: 安装coreutils包,创建测试文件 + +测试步骤: +- 查找删除替换文件中的关键字 + +期望结果: +- 根据查找的关键字可以查删除替换相应的内容 diff --git a/docs/system_base/gsl/tc_gsl_gsl_fun001.yaml b/docs/system_base/gsl/tc_gsl_gsl_fun001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..55401bafb1e23e13e4bb0b9861f63f5de2da82b4 --- /dev/null +++ b/docs/system_base/gsl/tc_gsl_gsl_fun001.yaml @@ -0,0 +1,27 @@ +: douzhichong +ȼ: P1 +ּ֧ܹ: noarch +ִзʽ: Զ +: ܲ +ͨñǩ: local,gsl +: gslܲ +޸: douzhichong + +ǰ: + +Բ: +- װ +- ָݷֲ gsl-randist 0 10 exppow 1 2 +- flatֲ gsl-randist 1 10 flat 10 1 +- ʷֲ gsl-randist 1 10 gamma 10 1 +- gaussianֲ gsl-randist 1 10 gaussian 10 +- geometricֲ gsl-randist 1 10 geometric 1 +- gumbel1ֲ gsl-randist 1 10 gumbel1 1 2 +: +- ɹװɹ +- ɹexppowֲ +- ɹflatֲ +- ɹgammaֲ +- ɹgaussianֲ +- ɹgeometricֲ +- ɹgumbel1ֲ \ No newline at end of file diff --git a/docs/system_base/jansson/tc_jansson_func001.yaml b/docs/system_base/jansson/tc_jansson_func001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..de1742de517e67fad8967620daf05c527001103b --- /dev/null +++ b/docs/system_base/jansson/tc_jansson_func001.yaml @@ -0,0 +1,82 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: Jansson库基本的创建、序列化、解析JSON数据 +修改人: gaohongmei + +前置条件: +- 创建test_jansson.c脚本,包含姓名、年龄和技能列表的JSON对象,后将对象序列化为JSON字符串,再将字符串解析回JSON对象,并从中提取和验证数据 +#include +#include + +void test_jansson() { + // 创建 JSON 对象 + json_t *root = json_object(); + + // 向 JSON 对象添加键值对 + json_object_set_new(root, "name", json_string("John Doe")); + json_object_set_new(root, "age", json_integer(30)); + json_object_set_new(root, "skills", json_array()); + + // 向数组添加元素 + json_t *skills = json_object_get(root, "skills"); + json_array_append_new(skills, json_string("C programming")); + json_array_append_new(skills, json_string("Networking")); + + // 序列化为 JSON 字符串 + char *serialized_json = json_dumps(root, JSON_INDENT(4)); + + // 输出 JSON 字符串到控制台 + printf("Serialized JSON: %s\\n", serialized_json); + + // 解析 JSON 字符串 + json_error_t error; + json_t *parsed_root = json_loads(serialized_json, 0, &error); + + // 检查解析是否成功,并访问数据 + if(parsed_root) { + json_t *name = json_object_get(parsed_root, "name"); + const char *name_str = json_string_value(name); + printf("Name: %s\\n", name_str); + + json_t *age = json_object_get(parsed_root, "age"); + int age_int = json_integer_value(age); + printf("Age: %d\\n", age_int); + + json_t *skills_list = json_object_get(parsed_root, "skills"); + if(json_is_array(skills_list)) { + size_t i, count = json_array_size(skills_list); + for(i = 0; i < count; i++) { + json_t *skill = json_array_get(skills_list, i); + const char *skill_str = json_string_value(skill); + printf("Skill %lu: %s\\n", i + 1, skill_str); + } + } + + // 清理内存 + json_decref(parsed_root); + } else { + printf("Error while parsing JSON: %s at line %d column %d\\n", + error.text, error.line, error.column); + } + + // 清理创建的 JSON 对象 + json_decref(root); + free(serialized_json); +} + +int main() { + test_jansson(); + return 0; +} + +测试步骤: +- 执行命令`gcc -o /tmp/ghm/test_jansson /tmp/ghm/test_jansson.c -ljansson`,编译脚本 +- 执行命令`/tmp/ghm/test_jansson` + +期望结果: +- 命令执行成功,生成/tmp/ghm/test_jansson脚本 +- 命令执行成功,返回Serialized JSON和Name、Age、Skill 1、Skill 2 \ No newline at end of file diff --git a/docs/system_base/jansson/tc_jansson_func002.yaml b/docs/system_base/jansson/tc_jansson_func002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0c4a315658caef707dda163459608c1fa25fdf5f --- /dev/null +++ b/docs/system_base/jansson/tc_jansson_func002.yaml @@ -0,0 +1,64 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: Jansson库嵌套JSON对象和数组创建、修改 +修改人: gaohongmei + +前置条件: +- 创建test_jansson.c脚本,包含创建JSON对象,在JSON对象中插入新元素并修改嵌套key1对象 +#include +#include + +// 创建并修改嵌套JSON对象和数组 +void create_and_modify_json() { + json_t *root = json_object(); + json_t *array = json_array(); + + // 添加一些数组元素 + json_array_append_new(array, json_string("item1")); + json_array_append_new(array, json_integer(2)); + json_array_append_new(array, json_true()); + + // 将数组添加到根对象中 + json_object_set_new(root, "nestedArray", array); + + // 创建嵌套的对象 + json_t *nested_obj = json_object(); + json_object_set_new(nested_obj, "key1", json_string("value1")); + json_object_set_new(nested_obj, "key2", json_integer(3)); + + // 将嵌套对象添加到根对象中 + json_object_set_new(root, "nestedObject", nested_obj); + + // 序列化为 JSON 字符串并输出 + char *serialized_json = json_dumps(root, JSON_INDENT(4)); + printf("Serialized JSON: %s\\n", serialized_json); + + // 修改数组和嵌套对象 + json_array_insert_new(array, 1, json_string("Inserted Item")); // 在数组索引1的位置插入新元素 + json_object_set_new(nested_obj, "key1", json_string("Modified Value")); // 修改嵌套对象的key1的值 + + // 输出修改后的JSON字符串 + const char *json_str = json_dumps(root, JSON_INDENT(4)); + printf("%s\\n", json_str); + + // 释放内存 + json_decref(root); + json_decref(nested_obj); +} + +int main() { + create_and_modify_json(); + return 0; +} + +测试步骤: +- 执行命令`gcc -o /tmp/ghm/test_jansson /tmp/ghm/test_jansson.c -ljansson`,编译脚本 +- 执行命令`/tmp/ghm/test_jansson` + +期望结果: +- 命令执行成功,生成/tmp/ghm/test_jansson脚本 +- 命令执行成功,返回首次创建和修改后的json对象。 \ No newline at end of file diff --git a/docs/system_base/jansson/tc_jansson_func003.yaml b/docs/system_base/jansson/tc_jansson_func003.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d789c28b54d24b055d8d3f145a071c1bee7bb67f --- /dev/null +++ b/docs/system_base/jansson/tc_jansson_func003.yaml @@ -0,0 +1,65 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: Jansson库的错误处理 +修改人: gaohongmei + +前置条件: +- 创建test_jansson.c脚本,包含访问不存在的键、解析无效的JSON +#include +#include +#include +#include + +// 用于报告JSON解析错误的特殊版本 +void parse_error_exit(const char *message, int line, const char *text) { + fprintf(stderr, "%s: On line %d: %s\\n", message, line, text); + exit(EXIT_FAILURE); +} + +int main() { + // 解析JSON字符串 + const char *json_text = "{\\"name\\":\\"Alice\\",\\"age\\":25}"; + json_error_t error; + json_t *root = json_loads(json_text, 0, &error); + + // 检查是否成功解析 + if (!root) { + parse_error_exit("Failed to parse JSON", error.line, error.text); + } + + char *serialized_json = json_dumps(root, JSON_INDENT(4)); + // 输出 JSON 字符串到控制台 + printf("Serialized JSON: %s\\n", serialized_json); + free(serialized_json); + + // 访问不存在的键 + json_t *nonexistent_value = json_object_get(root, "nonexistent_key"); + if (!nonexistent_value) { + printf("Key 'nonexistent_key' does not exist.\\n"); + } + json_decref(root); + + // 解析无效的JSON + json_text = "{invalid json}"; + root = json_loads(json_text, 0, &error); + if (!root) { + parse_error_exit("Failed to parse invalid JSON", error.line, error.text); + } + + // 释放内存 + json_decref(root); + + return 0; +} + +测试步骤: +- 执行命令`gcc -o /tmp/ghm/test_jansson /tmp/ghm/test_jansson.c -ljansson`,编译脚本 +- 执行命令`/tmp/ghm/test_jansson` + +期望结果: +- 命令执行成功,生成/tmp/ghm/test_jansson脚本 +- 命令执行成功,返回包含:Serialized JSON;Key 'nonexistent_key' does not exist;Failed to parse invalid JSON \ No newline at end of file diff --git a/docs/system_base/jansson/tc_jansson_func004.yaml b/docs/system_base/jansson/tc_jansson_func004.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a3fc2ed309953117cb8e0f91e9310a217c42ad96 --- /dev/null +++ b/docs/system_base/jansson/tc_jansson_func004.yaml @@ -0,0 +1,91 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: Jansson库递归遍历JSON对象的所有键值对 +修改人: gaohongmei + +前置条件: +- 创建test_jansson.c脚本 +#include +#include +#include +#include + +void print_json_value(json_t *value, int indent_level) { + switch (json_typeof(value)) { + case JSON_OBJECT: + const char *key; + json_t *val; + + json_object_foreach(value, key, val) { + for (int i = 0; i < indent_level; ++i) + printf(" "); + + printf("\\"%s\\": ", key); + print_json_value(val, indent_level + 1); + } + break; + + case JSON_ARRAY: + size_t array_size = json_array_size(value); + for (size_t i = 0; i < array_size; ++i) { + json_t *element = json_array_get(value, i); + print_json_value(element, indent_level); + } + break; + + case JSON_STRING: + printf("\\"%s\\"\\n", json_string_value(value)); + break; + + case JSON_INTEGER: + printf("%lld\\n", (long long)json_integer_value(value)); + break; + + case JSON_REAL: + printf("%f\\n", (double)json_real_value(value)); + break; + + case JSON_TRUE: + printf("true\\n"); + break; + + case JSON_FALSE: + printf("false\\n"); + break; + + case JSON_NULL: + printf("null\\n"); + break; + + default: + fprintf(stderr, "Unknown JSON type encountered!\\n"); + break; + } +} + +int main() { + const char *json_text = "{\\"person\\":{\\"name\\":\\"Alice\\",\\"age\\":25},\\"hobbies\\":[\\"Reading\\", \\"Gaming\\"]}"; + json_error_t error; + json_t *root = json_loads(json_text, 0, &error); + + if (!root) { + fprintf(stderr, "Error parsing JSON: %s on line %d\\n", error.text, error.line); + return EXIT_FAILURE; + } + print_json_value(root, 0); + + json_decref(root); + return 0; +} + +测试步骤: +- 执行命令`gcc -o /tmp/ghm/test_jansson /tmp/ghm/test_jansson.c -ljansson`,编译脚本 +- 执行命令`/tmp/ghm/test_jansson` + +期望结果: +- 命令执行成功,生成/tmp/ghm/test_jansson脚本 +- 命令执行成功,返回JSON格式 \ No newline at end of file diff --git a/docs/system_base/less/tc_less_less_fun_001.yaml b/docs/system_base/less/tc_less_less_fun_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..bae9f13701d5f213bf2703f29e9a4d74c3a1a912 --- /dev/null +++ b/docs/system_base/less/tc_less_less_fun_001.yaml @@ -0,0 +1,20 @@ +作者: douzhichong +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local,less +用例描述: 测试less基本功能 +修改人: douzhichong + +前置条件: 安装less包,创建测试文件 + +测试步骤: +- 显示行号 less -N testlog +- 查看less命令所在路径 command -v less +- 显示帮助信息 less --help + +期望结果: +- 操作成功,可以看到连续的行号 +- 操作成功,可以正常输出less命令的所在路径 +- 操作成功,可以显示帮助信息 \ No newline at end of file diff --git a/docs/system_base/libffi/tc_libffi_libffi_func_003.yaml b/docs/system_base/libffi/tc_libffi_libffi_func_003.yaml index e592c246fc4b89d7ea30f61a778222b3a6f813eb..70361ebb71019fe270a8ea194755a706520bba58 100644 --- a/docs/system_base/libffi/tc_libffi_libffi_func_003.yaml +++ b/docs/system_base/libffi/tc_libffi_libffi_func_003.yaml @@ -8,7 +8,7 @@ 修改人: Liujiang 前置条件: -- 安装libffi, libffi-devel软件包 +- 安装libffi, libffi-devel, valgrind软件包 测试步骤: - 新建测试文件my_function.c,my_function.h,libffi_test.c diff --git a/docs/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun001.yaml b/docs/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ee8b76df319f9e87d5c31653e58acb21aa88e493 --- /dev/null +++ b/docs/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun001.yaml @@ -0,0 +1,21 @@ +作者: wangyaru +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libsigsegv库处理空指针解引用的段错误 +修改人: wangyaru + +前置条件: +- 安装libsigsegv、libsigsegv-devel和gcc包 + +测试步骤: +- 创建处理空指针解引用的段错误文件libsigsegv_testfile.c +- gcc -o libsigsegv_testfile libsigsegv_testfile.c -lsigsegv编译文件 +- 执行libsigsegv_testfile.c编译后输出的程序libsigsegv_testfile + +期望结果: +- libsigsegv_testfile.c文件创建执行 +- libsigsegv_testfile.c文件编译成功 +- libsigsegv_testfile执行成功,成功捕获并处理空指针引用的段错误 \ No newline at end of file diff --git a/docs/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun002.yaml b/docs/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a6088aca250deee9229467144f14ba27de7d63a7 --- /dev/null +++ b/docs/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun002.yaml @@ -0,0 +1,21 @@ +作者: wangyaru +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libsigsegv库处理栈溢出场景的段错误 +修改人: wangyaru + +前置条件: +- 安装libsigsegv、libsigsegv-devel和gcc包 + +测试步骤: +- 创建因递归导致段错误的C文件libsigsegv_testfile.c +- gcc -o libsigsegv_testfile libsigsegv_testfile.c -lsigsegv编译文件 +- 执行libsigsegv_testfile.c编译后输出的程序libsigsegv_testfile + +期望结果: +- libsigsegv_testfile.c文件创建执行 +- libsigsegv_testfile.c文件编译成功 +- libsigsegv_testfile执行成功,且返回码为-11 \ No newline at end of file diff --git a/docs/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun003.yaml b/docs/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun003.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d3398b07a3be11d9d168b1592b43296ebeefb75f --- /dev/null +++ b/docs/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun003.yaml @@ -0,0 +1,21 @@ +作者: wangyaru +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libsigsegv库处理堆内存访问错误引起的段错误 +修改人: wangyaru + +前置条件: +- 安装libsigsegv、libsigsegv-devel和gcc包 + +测试步骤: +- 创建释放一个堆内存块之后再次尝试访问它的文件libsigsegv_testfile.c +- gcc -o libsigsegv_testfile libsigsegv_testfile.c -lsigsegv编译文件 +- 执行libsigsegv_testfile.c编译后输出的程序libsigsegv_testfile + +期望结果: +- libsigsegv_testfile.c文件创建执行 +- libsigsegv_testfile.c文件编译成功 +- libsigsegv_testfile执行成功,成功捕获并处理堆内存访问错误的段错误 \ No newline at end of file diff --git a/docs/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun004.yaml b/docs/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun004.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c8df2d044765c521bfe825b0401ae2d8868e58f3 --- /dev/null +++ b/docs/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun004.yaml @@ -0,0 +1,21 @@ +作者: wangyaru +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libsigsegv库处理数组越界引起的段错误 +修改人: wangyaru + +前置条件: +- 安装libsigsegv、libsigsegv-devel和gcc包 + +测试步骤: +- 创建处理数组越界引起的段错误的文件libsigsegv_testfile.c +- gcc -o libsigsegv_testfile libsigsegv_testfile.c -lsigsegv编译文件 +- 执行libsigsegv_testfile.c编译后输出的程序libsigsegv_testfile + +期望结果: +- libsigsegv_testfile.c文件创建执行 +- libsigsegv_testfile.c文件编译成功 +- libsigsegv_testfile执行成功,成功捕获并处理数组越界的段错误 \ No newline at end of file diff --git a/docs/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun005.yaml b/docs/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun005.yaml new file mode 100644 index 0000000000000000000000000000000000000000..70a75e363c322e62764defeb5c1afea3ba4ce6db --- /dev/null +++ b/docs/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun005.yaml @@ -0,0 +1,21 @@ +作者: wangyaru +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libsigsegv库处理内存映射错误引起的段错误 +修改人: wangyaru + +前置条件: +- 安装libsigsegv、libsigsegv-devel和gcc包 + +测试步骤: +- 创建处理内存映射错误引起的段错误的文件libsigsegv_testfile.c +- gcc -o libsigsegv_testfile libsigsegv_testfile.c -lsigsegv编译文件 +- 执行libsigsegv_testfile.c编译后输出的程序libsigsegv_testfile + +期望结果: +- libsigsegv_testfile.c文件创建执行 +- libsigsegv_testfile.c文件编译成功 +- libsigsegv_testfile执行成功,成功捕获并处理内存映射错误引起的段错误 \ No newline at end of file diff --git a/docs/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun006.yaml b/docs/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun006.yaml new file mode 100644 index 0000000000000000000000000000000000000000..4b8ed7199629465dfd93c2a5f2ff9d35537e05c8 --- /dev/null +++ b/docs/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun006.yaml @@ -0,0 +1,21 @@ +作者: wangyaru +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libsigsegv库处理修改只读数据引起的段错误 +修改人: wangyaru + +前置条件: +- 安装libsigsegv、libsigsegv-devel和gcc包 + +测试步骤: +- 创建处理修改只读数据引起的段错误的文件libsigsegv_testfile.c +- gcc -o libsigsegv_testfile libsigsegv_testfile.c -lsigsegv编译文件 +- 执行libsigsegv_testfile.c编译后输出的程序libsigsegv_testfile + +期望结果: +- libsigsegv_testfile.c文件创建执行 +- libsigsegv_testfile.c文件编译成功 +- libsigsegv_testfile执行成功,成功捕获并处理修改只读数据引起的段错误 diff --git a/docs/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun007.yaml b/docs/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun007.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1d6fb43df7fad407e73ac9152239e3c82ac3c9df --- /dev/null +++ b/docs/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun007.yaml @@ -0,0 +1,21 @@ +作者: wangyaru +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libsigsegv库处理多线程环境中触发段错误 +修改人: wangyaru + +前置条件: +- 安装libsigsegv、libsigsegv-devel和gcc包 + +测试步骤: +- 创建处理修改只读数据引起的段错误的文件libsigsegv_testfile.c +- gcc -o libsigsegv_testfile libsigsegv_testfile.c -lsigsegv -pthread编译文件 +- 执行libsigsegv_testfile.c编译后输出的程序libsigsegv_testfile + +期望结果: +- libsigsegv_testfile.c文件创建执行 +- libsigsegv_testfile.c文件编译成功 +- libsigsegv_testfile执行成功,成功捕获并处理多线程环境中触发段错误 diff --git a/docs/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun008.yaml b/docs/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun008.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e0897f48186c14232cf8bc46773cac75a2be96f8 --- /dev/null +++ b/docs/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun008.yaml @@ -0,0 +1,23 @@ +作者: wangyaru +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libsigsegv库验证信号处理程序中的资源清理 +修改人: wangyaru + +前置条件: +- 安装libsigsegv、libsigsegv-devel和gcc包 + +测试步骤: +- 创建测试所需要的测试文件tempfile +- 创建验证信号处理程序执行资源清理(关闭文件描述符、释放内存等)的文件libsigsegv_testfile.c +- gcc -o libsigsegv_testfile libsigsegv_testfile.c -lsigsegv编译文件 +- 执行libsigsegv_testfile.c编译后输出的程序libsigsegv_testfile + +期望结果: +- tempfile创建成功 +- libsigsegv_testfile.c文件创建执行 +- libsigsegv_testfile.c文件编译成功 +- libsigsegv_testfile执行成功,libsigsegv处理程序中可正确执行资源清理(关闭文件描述符、释放内存等) diff --git a/docs/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun009.yaml b/docs/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun009.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a8a85c61037672ec0f74b305ecfb795606100a69 --- /dev/null +++ b/docs/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun009.yaml @@ -0,0 +1,21 @@ +作者: wangyaru +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libsigsegv库验证信号处理程序的嵌套和重入性 +修改人: wangyaru + +前置条件: +- 安装libsigsegv、libsigsegv-devel和gcc包 + +测试步骤: +- 创建信号处理程序本身触发另一个段错误场景的文件libsigsegv_testfile.c +- gcc -o libsigsegv_testfile libsigsegv_testfile.c -lsigsegv编译文件 +- 执行libsigsegv_testfile.c编译后输出的程序libsigsegv_testfile + +期望结果: +- libsigsegv_testfile.c文件创建执行 +- libsigsegv_testfile.c文件编译成功 +- libsigsegv_testfile执行成功,libsigsegv可正常处理步骤一中的场景,不会出现无限递归或死锁的情况 diff --git a/docs/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun010.yaml b/docs/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun010.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ce53d55e8f72b1fa2e44f7bbc7924c3ed91f84f2 --- /dev/null +++ b/docs/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun010.yaml @@ -0,0 +1,21 @@ +作者: wangyaru +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libsigsegv库在捕获段错误后继续执行程序而不终止的场景 +修改人: wangyaru + +前置条件: +- 安装libsigsegv、libsigsegv-devel和gcc包 + +测试步骤: +- 创建捕获段错误后继续执行场景的文件libsigsegv_testfile.c +- gcc -o libsigsegv_testfile libsigsegv_testfile.c -lsigsegv编译文件 +- 执行libsigsegv_testfile.c编译后输出的程序libsigsegv_testfile + +期望结果: +- libsigsegv_testfile.c文件创建执行 +- libsigsegv_testfile.c文件编译成功 +- libsigsegv_testfile执行成功,libsigsegv可在遇到段错误后通过siglongjmp回到之前环境继续执行程序 diff --git a/docs/system_base/libuser/tc_libuser_group_lgroupdel_fun002.yaml b/docs/system_base/libuser/tc_libuser_group_lgroupdel_fun002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8ba88d8dfee3f8d89685877ac878b8551f157858 --- /dev/null +++ b/docs/system_base/libuser/tc_libuser_group_lgroupdel_fun002.yaml @@ -0,0 +1,31 @@ +作者: wangyaru +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试lgroupdel删除组内有用户的场景 +修改人: wangyaru + +前置条件: +- 安装libuser包 + +测试步骤: +- lgroupdel --help查看lgroupdel的帮助信息 +- 创建用户组group_test01 +- 检查/etc/group下是否写入group_test01用户组信息 +- group_test01组内添加新用户testuser_001 +- 验证/etc/passwd下用户信息是否添加成功 +- 删除用户组group_test01 +- 删除用户testuser_001 +- 删除testuser_001用户的主目录和邮箱目录 + +期望结果: +- 展示lgroupdel命令的帮助信息 +- 成功创建group_test01用户组 +- /etc/group下存在用户组group_test01的相关信息 +- 新用户testuser_001添加成功 +- /etc/passwd下用户信息添加成功 +- group_test01删除成功,且/etc/group下无group_test01相关信息,但testuser_001用户仍存在 +- 用户testuser_001删除成功,/etc/passwd下用户信息被删除 +- /home/testuser_001和/var/mail/testuser_001两个目录删除成功 \ No newline at end of file diff --git a/docs/system_base/libuser/tc_libuser_lchfn_lchfn_fun001.yaml b/docs/system_base/libuser/tc_libuser_lchfn_lchfn_fun001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..227e830000573e6e89e029da7e486290b619b058 --- /dev/null +++ b/docs/system_base/libuser/tc_libuser_lchfn_lchfn_fun001.yaml @@ -0,0 +1,22 @@ +作者: wangyaru +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试lchfn命令的基本功能 +修改人: wangyaru + +前置条件: +- 安装libuser包 + +测试步骤: +- lchfn --help查看lchfn的帮助信息 +- 创建用户test_user001 +- lchfn test_user001修改用户的Full Name为new_test_user001 + + +期望结果: +- 展示lchfn命令的帮助信息 +- 用户test_user001创建成功,/etc/passwd下成功写入用户信息 +- 用户的Full Name修改成功,/etc/passwd下的相关信息修改成功 diff --git a/docs/system_base/libuser/tc_libuser_lchsh_lchsh_fun001.yaml b/docs/system_base/libuser/tc_libuser_lchsh_lchsh_fun001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..fcbbaf10e61f5fac82bd8bf6c6ee3ae83414a028 --- /dev/null +++ b/docs/system_base/libuser/tc_libuser_lchsh_lchsh_fun001.yaml @@ -0,0 +1,22 @@ +作者: wangyaru +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试lchsh命令的基本功能 +修改人: wangyaru + +前置条件: +- 安装libuser包 + +测试步骤: +- lchsh --help查看lchfn的帮助信息 +- 创建用户test_user001 +- lchsh test_user001修改用户的shell为“/bin/bash_new” + + +期望结果: +- 展示lchsh命令的帮助信息 +- 用户test_user001创建成功,/etc/passwd下成功写入用户信息 +- 用户的shell修改成功,/etc/passwd下test_user001用户的shell显示为“/bin/bash_new” \ No newline at end of file diff --git a/docs/system_base/libuser/tc_libuser_lpasswd_lpasswd_fun001.yaml b/docs/system_base/libuser/tc_libuser_lpasswd_lpasswd_fun001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..83d84775c8ac9941724724d4b28465a72cf195fc --- /dev/null +++ b/docs/system_base/libuser/tc_libuser_lpasswd_lpasswd_fun001.yaml @@ -0,0 +1,34 @@ +作者: wangyaru +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试lpasswd命令的基本功能 +修改人: wangyaru + +前置条件: +- 安装libuser包 + +测试步骤: +- lpasswd --help查看lpasswd的帮助信息 +- 创建用户test_user001 +- 为用户test_user001设置密码为newpassword +- 创建用户test_user002 +- 由root切换到test_user002用户 +- whoami验证当前用户是否是test_user002 +- 由test_user002切换到test_user001用户 +- whoami验证当前用户是否是test_user001 +- 依次exit两次 + + +期望结果: +- 展示lpasswd命令的帮助信息 +- 用户test_user001创建成功 +- 密码设置成功 +- 用户test_user002创建成功 +- 用户切换成功 +- whoami查看到当前的用户是test_user002 +- 用户切换成功 +- whoami查看到当前的用户是test_user001 +- 两次exit成功 diff --git a/docs/system_base/libuser/tc_libuser_user_luseradd_fun002.yaml b/docs/system_base/libuser/tc_libuser_user_luseradd_fun002.yaml index 184fefb76d384e8531619ca5eef5747e5f7dffc4..88a3920f08876ae634582e4d9ebe54c18913a228 100644 --- a/docs/system_base/libuser/tc_libuser_user_luseradd_fun002.yaml +++ b/docs/system_base/libuser/tc_libuser_user_luseradd_fun002.yaml @@ -12,12 +12,12 @@ 测试步骤: - luseradd --help查看luseradd的帮助信息 -- 创建指定uid为10001和主目录为/tmp/home/testuser1的用户testuser1 -- ls -ld /tmp/home/testuser1验证主目录是否创建 +- 创建指定uid为10001和主目录为/tmp/testuser1的用户testuser1 +- ls -ld /tmp/testuser1验证主目录是否创建 - lid -g testuser1验证新创建的用户testuser1的uid是否为10001 期望结果: - 展示luseradd命令的帮助信息 - 成功创建testuser1用户 - 用户的主目录正常创建 -- testuser1用户的uid为10001 +- testuser1用户的uid为10001 \ No newline at end of file diff --git a/docs/system_base/libutempter/tc_libutempter_libutempter_fun002.yaml b/docs/system_base/libutempter/tc_libutempter_libutempter_fun002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3295b3ce7d470a3208f49dd2137cbb8bf999719c --- /dev/null +++ b/docs/system_base/libutempter/tc_libutempter_libutempter_fun002.yaml @@ -0,0 +1,21 @@ +作者: wangyaru +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libutempte库的异常场景 +修改人: wangyaru + +前置条件: +- 安装libutempter、libutempter-devel和gcc包 + +测试步骤: +- 创建处理验证无效的文件描述符、以NULL作为用户名和空字符串作为用户名的C文件libutempter_testfile.c +- gcc -o libutempter_testfile libutempter_testfile.c -lutempter编译文件 +- 执行libutempter_testfile.c编译后输出的程序libutempter_testfile + +期望结果: +- libutempter_testfile.c文件创建执行 +- libutempter_testfile.c文件编译成功 +- libutempter_testfile执行成功 \ No newline at end of file diff --git a/docs/system_base/libutempter/tc_libutempter_libutempter_fun003.yaml b/docs/system_base/libutempter/tc_libutempter_libutempter_fun003.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ab0bd36d67d88502bd9e98f2b484604cac39c71c --- /dev/null +++ b/docs/system_base/libutempter/tc_libutempter_libutempter_fun003.yaml @@ -0,0 +1,21 @@ +作者: wangyaru +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libutempte库的异常场景 +修改人: wangyaru + +前置条件: +- 安装libutempter、libutempter-devel和gcc包 + +测试步骤: +- 创建处理资源受限场景的C文件libutempter_testfile.c +- gcc -o libutempter_testfile libutempter_testfile.c -lutempter编译文件 +- 执行libutempter_testfile.c编译后输出的程序libutempter_testfile + +期望结果: +- libutempter_testfile.c文件创建执行 +- libutempter_testfile.c文件编译成功 +- libutempter_testfile执行成功 \ No newline at end of file diff --git a/docs/system_base/libutempter/tc_libutempter_libutempter_fun004.yaml b/docs/system_base/libutempter/tc_libutempter_libutempter_fun004.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d8733282bd091edd68528b4e74555001686f4531 --- /dev/null +++ b/docs/system_base/libutempter/tc_libutempter_libutempter_fun004.yaml @@ -0,0 +1,21 @@ +作者: wangyaru +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libutempte库的并发场景 +修改人: wangyaru + +前置条件: +- 安装libutempter、libutempter-devel和gcc包 + +测试步骤: +- 创建10个线程同时对utmp 进行操作的文件libutempter_testfile.c +- gcc -o libutempter_testfile libutempter_testfile.c -lutempter编译文件 +- 执行libutempter_testfile.c编译后输出的程序libutempter_testfile + +期望结果: +- libutempter_testfile.c文件创建执行 +- libutempter_testfile.c文件编译成功 +- libutempter_testfile执行成功 \ No newline at end of file diff --git a/docs/system_base/lsof/tc_lsof_lsof_fun001.yaml b/docs/system_base/lsof/tc_lsof_lsof_fun001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..45afdec1667ebc6f441ad58a89884d583f29a869 --- /dev/null +++ b/docs/system_base/lsof/tc_lsof_lsof_fun001.yaml @@ -0,0 +1,22 @@ +: douzhichong +ȼ: P1 +ּ֧ܹ: noarch +ִзʽ: Զ +: ܲ +ͨñǩ: local,lsof +: lsof +޸: douzhichong + +ǰ: + +Բ: +- װ +- 鿴lsofװ· +- rootû򿪵ļtestlog +- 鿴ļĽ + +: +- ɹɹװ +- ɹĬϰװ·ȷ +- ɹtestlogԳɹʾrootû򿪵ļ +- ɹԲ鿴testlog \ No newline at end of file diff --git a/docs/system_base/net-tools/tc_net_tools_arp_func_001.yaml b/docs/system_base/net-tools/tc_net_tools_arp_func_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c8fc3e32fe088aaee4b73cfc14c3f36fa0366980 --- /dev/null +++ b/docs/system_base/net-tools/tc_net_tools_arp_func_001.yaml @@ -0,0 +1,28 @@ +作者: chenchunhu +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试net_tools arp基本功能 +修改人: chenchunhu + +前置条件: +- 安装net-tools包 +- 执行命令`route -n | grep 'UG[ \t]' | awk '{print $2}'`获取IP地址 + +测试步骤: +- 查看ARP缓存:arp -a +- 查询特定IP的ARP信息:arp -a IP +- 查看帮助信息:arp -help +- 添加一个无效的MAC地址:arp -s 999.999.999.999 00:1C:42:2B:60:5A +- 加一个无效的MAC地址:arp -s 192.168.1.100 00:11:22:33:44:ZZ +- 查询一个不存在的IP:arp -a 192.168.1.123 + +期望结果: +- 操作成功,可以成功显示当前系统的ARP缓存表的所有内容 +- 操作成功,可以成功显示目标IP地址的ARP条目 +- 操作成功,可以成功显示帮助信息 +- 操作成功,可以成功显示一个错误讯息,提示无效的IP地址 +- 操作成功,可以成功显示一个错误讯息,提示无效的硬件地址 +- 操作成功,可以成功显示没有找到该IP地址的ARP条目 diff --git a/docs/system_base/net-tools/tc_net_tools_ifconfig_func_001.yaml b/docs/system_base/net-tools/tc_net_tools_ifconfig_func_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f131d3863257d38c997bb4d8512d768367a9110e --- /dev/null +++ b/docs/system_base/net-tools/tc_net_tools_ifconfig_func_001.yaml @@ -0,0 +1,34 @@ +作者: chenchunhu +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试net_tools ifconfig基本功能 +修改人: chenchunhu + +前置条件: +- 安装net-tools iproute包 +- 执行命令`ip link add test0 type dummy`创建一个虚拟网络接口 +- 执行命令`ifconfig test0 up`启动虚拟网络接口 +- 执行命令`ifconfig test0 192.168.1.1 netmask 255.255.255.0 broadcast 192.168.1.255 hw ether 00:0c:29:3e:47:4b`设置虚拟网络接口信息 + +测试步骤: +- 查看test0接口信息:ifconfig test0 +- 设置接口IP地址是否成功 +- 设置接口子网掩码是否成功 +- 设置接口广播地址是否成功 +- 设置接口硬件地址是否成功 +- 禁用/启用接口功能:ifconfig test0 down;ifconfig test0 up +- 删除虚拟网络接口:ip link delete test0 +- 查看帮助信息:ifconfig -help + +期望结果: +- 操作成功,可以成功显示网络接口信息 +- 操作成功,设置IP地址成功 +- 操作成功,设置子网掩码成功 +- 操作成功,设置广播地址成功 +- 操作成功,设置硬件地址成功 +- 操作成功,成功禁用/启用接口 +- 操作成功, 删除虚拟网络接口 +- 操作成功,可以成功显示帮助信息 diff --git a/docs/system_base/net-tools/tc_net_tools_netstat_func_001.yaml b/docs/system_base/net-tools/tc_net_tools_netstat_func_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..75a5621c8e1d6826418fefc75add0e091d43ad1e --- /dev/null +++ b/docs/system_base/net-tools/tc_net_tools_netstat_func_001.yaml @@ -0,0 +1,42 @@ +作者: chenchunhu +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试net_tools netstat基本功能 +修改人: chenchunhu + +前置条件: +- 安装net-tools包 +- 执行命令`ip add | grep 'state UP' | awk '{print $2}' | awk -F ':' 'NR==1{print $1}'`获取网络接口名 + +测试步骤: +- 列出所有端口:netstat -a +- 列出所有监听端口:netstat -l +- 查看每个协议的统计信息:netstat -s +- 查看TCP连接状态:netstat -t +- 查看UDP协议的端口和连接信息:netstat -u +- 查看路由表:netstat -r +- 查看网络接口列表及其统计信息:netstat -i +- 查看原始网络信息:netstat -w +- 查看IPv4和IPv6的统计信息:netstat -st +- 查看所有监听的TCP端口以及对应服务的名称:netstat -lt +- 查看socket监听信息,不进行域名解析:netstat -ln +- 查看帮助信息:netstat -help +- 查看原始网络信息:netstat -w + +期望结果: +- 操作成功,可以成功列出所有端口 +- 操作成功,可以成功列出所有监听端口 +- 操作成功,可以成功显示每个协议的统计信息 +- 操作成功,可以成功显示TCP连接状态 +- 操作成功,可以成功显示UDP协议的端口和连接信息 +- 操作成功,可以成功显示路由表 +- 操作成功,可以成功显示网络接口列表及其统计信息 +- 操作成功,可以成功显示原始网络信息 +- 操作成功,可以成功显示IPv4和IPv6的统计信息 +- 操作成功,可以成功显示所有监听的TCP端口以及对应服务的名称 +- 操作成功,可以成功显示socket监听信息,不进行域名解析 +- 操作成功,可以成功显示帮助信息 +- 操作成功,可以成功显示一个错误信息 diff --git a/docs/system_base/net-tools/tc_net_tools_ping_func_001.yaml b/docs/system_base/net-tools/tc_net_tools_ping_func_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..14799f2b53e307421b249f38f42b7a3de9901403 --- /dev/null +++ b/docs/system_base/net-tools/tc_net_tools_ping_func_001.yaml @@ -0,0 +1,38 @@ +作者: chenchunhu +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试net_tools ping基本功能 +修改人: chenchunhu + +前置条件: +- 安装net-tools包 +- 执行命令`route -n | grep 'UG[ \t]' | awk '{print $2}'`获取IP地址 + +测试步骤: +- Ping本地主机,Ctrl+C中断命令:ping IP +- Ping指定次数:ping -c 3 IP +- Ping指定数据包大小:ping -c 3 -s 100 IP +- Ping指定运行时间:ping -w 3 IP +- Ping显示时间戳:ping -c 3 -D IP +- Ping极速:ping -c 3 -f IP +- Ping间隔:ping -c 3 -i 2 IP +- Ping静默模式:ping -c 3 -q IP +- 不成功的Ping:ping nonexistentdomain.example +- 使用错误的参数执行ping:ping -c notanumber IP +- 查看帮助信息:ping -help + +期望结果: +- 操作成功,可以成功显示接收主机的响应,并显示往返时间 +- 操作成功,可以成功显示总共ping主机3次,并显示统计数据 +- 操作成功,可以成功显示使用100字节大小的数据包ping主机,并显示统计信息 +- 操作成功,可以成功显示对主机进行Ping测试,总共3秒后结束 +- 操作成功,可以成功显示Ping主机并在每个回应前显示当前时间戳 +- 操作成功,可以成功显示快速发送ping请求,并显示统计数据 +- 操作成功,可以成功显示接收主机的响应,并显示往返时间 +- 操作成功,不显示每个响应的详细信息,只输出汇总的统计信息 +- 操作成功,可以成功显示一个错误讯息,提示名称或服务未知 +- 操作成功,可以成功显示一个错误讯息,提示参数不合法 +- 操作成功,可以成功显示帮助信息 diff --git a/docs/system_base/rpm/tc_rpm_rpm_fun001.yaml b/docs/system_base/rpm/tc_rpm_rpm_fun001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1e98d1793915a6ec9f68dfef31e3426ed0abc780 --- /dev/null +++ b/docs/system_base/rpm/tc_rpm_rpm_fun001.yaml @@ -0,0 +1,23 @@ +: douzhichong +ȼ: P1 +ּ֧ܹ: noarch +ִзʽ: Զ +: ܲ +ͨñǩ: local +: rpmܲ +޸: douzhichong + +ǰ: +زװrpm +Բ: + +- ѯlsof rpm -qip lsof*.rpm +- ѯѰװlsof rpm -qa | grep -v help +- ʾϢ rpm -qi lsof +- гװļ· rpm -ql lsof + +: +- ɹزװɹ +- ɹԲѯѰװlsof +- ɹʾϢơ汾ڡװڡСȣ +- ɹгװļ· diff --git a/docs/system_base/unbound/tc_unbound_unbound_checkconf_fun_001.yaml b/docs/system_base/unbound/tc_unbound_unbound_checkconf_fun_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..94fccd99bb179436667d888c9ea292fec650d7a6 --- /dev/null +++ b/docs/system_base/unbound/tc_unbound_unbound_checkconf_fun_001.yaml @@ -0,0 +1,37 @@ +作者: zhanggaiyan +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 使用unbound-checkconf测配置文件的语法 +修改人: zhanggaiyan + +前置条件: +- 安装unbond包 + +测试步骤: +- 创建一个临时目录,目录里面创建一个合法的配置文件,并进行检测 +mkdir temp_dir +# Create a valid configuration file +cat "temp_dir/valid.conf" +server: + interface: 0.0.0.0 + port: 53 + verbosity: 1 +EOF +unbound-checkconf "temp_dir/valid.conf" + +- 临时目录下创建一个不合法的配置文件,并进行检测 +# Create an invalid configuration file with a syntax error +cat "temp_dir/invalid.conf" +server: + interface: 0.0.0.0 + port: 53 + invalid_key: invalid_value +EOF +unbound-checkconf "temp_dir/invalid.conf" + +期望结果: +- 创建临时目录及合法配置文件成功,检测成功 +- 创建不合法配置文件成功,检测失败,并有报错信息提示 diff --git a/docs/system_base/unbound/tc_unbound_unbound_control_fun_001.yaml b/docs/system_base/unbound/tc_unbound_unbound_control_fun_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..cddce3ea9e1091714ce74560ea0e88485a529ac0 --- /dev/null +++ b/docs/system_base/unbound/tc_unbound_unbound_control_fun_001.yaml @@ -0,0 +1,23 @@ +作者: zhanggaiyan +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试unbound包的unbound-control子命令的基础功能 +修改人: zhanggaiyan + +前置条件: +- 安装unbond包 + +测试步骤: +- 执行unbound-control -c /etc/unbound/unbound.conf status |grep 'is running' 测试unbound守护进程是否运行中 +- 执行unbound-control -c /etc/unbound/unbound.conf reload |grep 'ok' 重新加载unbound配置 +- 执行unbound-control -c /etc/unbound/unbound.conf flush_zone . 使用flush_zone .命令清空缓存 +- 执行unbound-control -c /etc/unbound/unbound.conf stats 使用stats命令获取当前的 unbound 统计信息 + +期望结果: +- unbound守护进程运行中 +- 重新加载unbound配置成功 +- 清空缓存成功 +- stats命令可以获取unbound统计信息 diff --git a/docs/system_base/unbound/tc_unbound_unbound_control_setup_fun_001.yaml b/docs/system_base/unbound/tc_unbound_unbound_control_setup_fun_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a5ed861ed34ae492a6486c60e0a915f93a5dc5a9 --- /dev/null +++ b/docs/system_base/unbound/tc_unbound_unbound_control_setup_fun_001.yaml @@ -0,0 +1,21 @@ +作者: zhanggaiyan +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试unbound-control-setup的文件生成能力 +修改人: zhanggaiyan + +前置条件: +- 安装unbound包 + +测试步骤: +- 创建一个临时目录,mkdir temp_dir +- 执行unbound-control-setup -d 'temp_dir'命令,是否成功 +- 设置control_cert="temp_dir/unbound_control.pem",control_key="temp_dir/unbound_control.key",查看文件是否生成成功 + +期望结果: +- 临时目录创建成功 +- 执行命令成功 +- 文件生成成功 diff --git a/docs/system_base/unbound/tc_unbound_unbound_fun_001.yaml b/docs/system_base/unbound/tc_unbound_unbound_fun_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..af55c14270c73866d21dcde60cf64076544f5537 --- /dev/null +++ b/docs/system_base/unbound/tc_unbound_unbound_fun_001.yaml @@ -0,0 +1,28 @@ +作者: zhanggaiyan +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试unbound包的基础配置及服务启动等功能 +修改人: zhanggaiyan + +前置条件: +- 安装unbond,bind-utils包 + +测试步骤: +- 执行echo 'interface: 1.1.1.1' >> /etc/unbound/unbound.conf;echo 'interface: ::1' >> /etc/unbound/unbound.conf,以允许监听ipv4和ipv6的所有接口 +- 执行echo 'access-control: 0.0.0.0/0 allow' >> /etc/unbound/unbound.conf;echo 'access-control: ::0/0 allow' >> /etc/unbound/unbound.conf, \ + 允许所有客户端查询,找到对应的区域并修改为允许所有 +- 启动unbound服务systemctl start unbound,并查询服务状态是否正常; +- 使用 dig 进行查询测试: + dig @localhost example.com A # 查询 A 记录 + dig @localhost example.com MX # 查询 MX 记录 + dig @localhost example.com NS # 查询 NS 记录 + dig @localhost example.com TXT # 查询 TXT 记录 + +期望结果: +- 修改配置文件成功 +- 修改配置文件成功 +- 服务启动正常 +- 可以查询到对应的DNS信息 diff --git a/docs/system_libraries/expat/tc_expat_fun_001.yaml b/docs/system_libraries/expat/tc_expat_fun_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..54209292c200fb0341d152f694909298dcaa9918 --- /dev/null +++ b/docs/system_libraries/expat/tc_expat_fun_001.yaml @@ -0,0 +1,87 @@ +作者: hongfeng +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 使用expat库解析一个xml,验证解析的结果 +修改人: hongfeng + +前置条件: +- 创建expat.c +#include +#include +#include +#include + +void XMLCALL startElement(void *userData, const char *name, const char **atts) { + // 处理逻辑 + printf("startElement name: %s\\n", name); +} + +void XMLCALL endElement(void *userData, const char *name) { + // 处理逻辑 + printf("endElement name: %s\\n", name); +} + +void XMLCALL characterDataHandler(void *userData, const char *s, int len) { + if(len == 0){ + return; + } + + // 创建一个新的缓冲区用于存储处理过的字符数据 + char* processed_data = malloc(len + 1); + int new_len = 0; + + for (int i = 0; i < len; ++i) { + if (s[i] != '\\r' && s[i] != '\\n' && !isspace((unsigned char)s[i])) { // 忽略回车、换行符以及所有空格字符 + processed_data[new_len++] = s[i]; + } + } + + // 添加字符串结束符 + processed_data[new_len] = '\\0'; + if(new_len != 0) { + printf("characterDataHandler: %s\\n", processed_data); + } + + // 记得在适当的时候释放 processed_data 的内存 + free(processed_data); +} + +int main() { + char buf[1024]; + int done; + XML_Parser parser = XML_ParserCreate(NULL); + if (!parser) { + fprintf(stderr, "Unable to create parser\\n"); + return 1; + } + + XML_SetUserData(parser, NULL); // 设置用户数据指针 + XML_SetElementHandler(parser, startElement, endElement); + XML_SetCharacterDataHandler(parser, characterDataHandler); + + FILE *fp = fopen("test.xml", "r"); + do { + int len = (int)fread(buf, 1, sizeof(buf), fp); + done = len < sizeof(buf); + if (XML_Parse(parser, buf, len, done) == XML_STATUS_ERROR) { + fprintf(stderr, "Error: %s at line %d\\n", + XML_ErrorString(XML_GetErrorCode(parser)), + (int)XML_GetCurrentLineNumber(parser)); + return 1; + } + } while (!done); + + XML_ParserFree(parser); + return 0; +} +- 编译gcc -o expat expat.c `pkg-config --cflags --libs expat` +- 将事先准备好的test.xml拷贝到执行路径 + +测试步骤: +- 执行./expat + +期望结果: +- 命令执行成功,检查解析过程中打印输出是符合解析预期 diff --git a/docs/system_libraries/gnupg2/tc_gnupg_gpg_func_001.yaml b/docs/system_libraries/gnupg2/tc_gnupg_gpg_func_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1cf53734fd9c78bf59628eaff7b6041e0e3b6d31 --- /dev/null +++ b/docs/system_libraries/gnupg2/tc_gnupg_gpg_func_001.yaml @@ -0,0 +1,31 @@ +作者: Liujiang +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 验证GnuPG密钥生成和对文件的加密解密功能 +修改人: Liujiang + +前置条件: +- 安装gnupg2软件包 + +测试步骤: +- 调Gnupg2Manager.generate_fixed_parameter_key_pair方法, 生成密钥对 +- 编写一个简单的文本文件test.txt, 用于测试加密和解密 +- 使用刚刚生成的公钥对test.txt 文件进行加密 +- 确保生成了加密文件(如 test.txt.gpg) +- 尝试使用对应的私钥解密加密的文件 +- 比较原始文件和解密后的文件内容是否一致 +- 清理生成的文件 +- 清理密钥对 + +期望结果: +- 成功生成密钥对 +- 文件创建成功 +- 文件加密成功 +- 生成加密文件 +- 解密成功 +- 原始文件和解密后的文件内容一致 +- 生成的文件清理成功 +- 密钥对清理成功 \ No newline at end of file diff --git a/docs/system_libraries/gnupg2/tc_gnupg_gpg_func_002.yaml b/docs/system_libraries/gnupg2/tc_gnupg_gpg_func_002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..9a281a884dcc97dbd6f7e6dd28f01287c78c4d54 --- /dev/null +++ b/docs/system_libraries/gnupg2/tc_gnupg_gpg_func_002.yaml @@ -0,0 +1,31 @@ +作者: Liujiang +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 验证GnuPG密钥导入/导出功能 +修改人: Liujiang + +前置条件: +- 安装gnupg2软件包 + +测试步骤: +- 调Gnupg2Manager.generate_fixed_parameter_key_pair方法, 生成密钥对 +- 导出公钥 +- 导出私钥 +- 删除密钥对 +- 导入公钥 +- 导入私钥 +- 清理生成的文件 +- 清理密钥对 + +期望结果: +- 成功生成密钥对 +- 导出公钥成功 +- 导出私钥成功 +- 删除成功 +- 导入公钥成功 +- 导入私钥成功 +- 生成文件清理成功 +- 密钥对清理成功 \ No newline at end of file diff --git a/docs/system_libraries/gnupg2/tc_gnupg_gpg_func_003.yaml b/docs/system_libraries/gnupg2/tc_gnupg_gpg_func_003.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5afcce3a5ab8c43b4a37b5dccbef9f46206a10ae --- /dev/null +++ b/docs/system_libraries/gnupg2/tc_gnupg_gpg_func_003.yaml @@ -0,0 +1,33 @@ +作者: Liujiang +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 验证GnuPG能否正常添加和更新密钥的有效期 +修改人: Liujiang + +前置条件: +- 安装gnupg2, expect软件包 + +测试步骤: +- 新建密钥更新的交互脚本update_expire_script.sh +- 调Gnupg2Manager.generate_fixed_parameter_key_pair方法, 生成密钥对 +- 获取创建时间 +- 执行密钥更新的交互脚本update_expire_script.sh,添加密钥有效期 +- 获取密钥有效日期,对比有效日期和创建时间是否符合预期 +- 再次执行密钥更新的交互脚本update_expire_script.sh,更新密钥有效期 +- 获取更新后的密钥有日期,对比更新前后的密钥有效日期 +- 清理生成的文件 +- 清理密钥对 + +期望结果: +- 新建成功 +- 成功生成密钥对 +- 创建时间获取成功 +- 密钥有效期添加成功 +- 有效日期和当前日期的差值符合预期 +- 更新密钥有效期成功 +- 更新前后的密钥有效日期差值正确 +- 生成文件清理成功 +- 密钥对清理成功 \ No newline at end of file diff --git a/docs/system_libraries/gnupg2/tc_gnupg_gpg_func_004.yaml b/docs/system_libraries/gnupg2/tc_gnupg_gpg_func_004.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7ba5da70afcde4bbc7f045af24d18bd153b41a90 --- /dev/null +++ b/docs/system_libraries/gnupg2/tc_gnupg_gpg_func_004.yaml @@ -0,0 +1,45 @@ +作者: Liujiang +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试密钥添加或移除用户ID及签名功能 +修改人: Liujiang + +前置条件: +- 安装gnupg2,expect软件包 + +测试步骤: +- 新建增加用户ID的交互脚本add_userID_script.sh, + 新建删除用户ID的交互脚本remove_userID_script.sh, + 新建删除用户签名的交互脚本remove_sign_script.sh, + 新建添加用户签名的交互脚本add_sign_script.sh +- 调Gnupg2Manager.generate_fixed_parameter_key_pair方法, 生成密钥对 +- 执行交互脚本add_userID_script.sh给密钥添加一个用户ID +- 检查用户ID是否添加成功 +- 执行交互脚本remove_sign_script.sh删除用户签名 +- 检查签名是否删除成功 +- 执行交互脚本add_sign_script.sh添加用户签名 +- 检查签名是否添加成功 +- 执行交互脚本remove_userID_script.sh给密钥删除一个用户ID +- 检查用户ID是否删除成功 +- 清理生成的文件 +- 清理密钥对 + +期望结果: +- 增加用户ID的交互脚本新建成功 + 删除用户ID的交互脚本新建成功 + 删除用户签名的交互脚本新建成功 + 添加用户签名的交互脚本新建成功 +- 成功生成密钥对 +- 用户ID添加脚本执行成功 +- 用户ID添加成功 +- 用户签名删除脚本执行成功 +- 签名删除成功 +- 用户签名添加脚本执行成功 +- 签名添加成功 +- 用户ID删除脚本执行成功 +- 用户ID删除成功 +- 生成文件清理成功 +- 密钥对清理成功 \ No newline at end of file diff --git a/docs/system_libraries/gnupg2/tc_gnupg_gpg_func_005.yaml b/docs/system_libraries/gnupg2/tc_gnupg_gpg_func_005.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c55c04f75c7689fb75ab88a0eb37fa5238b96dba --- /dev/null +++ b/docs/system_libraries/gnupg2/tc_gnupg_gpg_func_005.yaml @@ -0,0 +1,27 @@ +作者: Liujiang +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试吊销密钥及生成吊销证书功能 +修改人: Liujiang + +前置条件: +- 安装gnupg2, expect软件包 + +测试步骤: +- 调Gnupg2Manager.generate_fixed_parameter_key_pair方法,生成密钥对 +- 调Gnupg2Manager.generate_revocation_certificate方法,生成吊销证书 +- 调Gnupg2Manager.revoke_key_with_certificate方法,吊销密钥 +- 用吊销后的密钥签署文件 +- 清理生成的文件 +- 清理密钥对 + +期望结果: +- 成功生成密钥对 +- 吊销证书成功生成 +- 密钥吊销成功 +- 文件签署失败 +- 生成文件清理成功 +- 密钥对清理成功 \ No newline at end of file diff --git a/docs/system_libraries/gnupg2/tc_gnupg_gpg_func_006.yaml b/docs/system_libraries/gnupg2/tc_gnupg_gpg_func_006.yaml new file mode 100644 index 0000000000000000000000000000000000000000..42c6f13943df0f99ab46193bfe2a0d94ecf795a0 --- /dev/null +++ b/docs/system_libraries/gnupg2/tc_gnupg_gpg_func_006.yaml @@ -0,0 +1,31 @@ +作者: Liujiang +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试GnuPG能否使用私钥进行数据的签名,并且使用公钥进行验证。 +修改人: Liujiang + +前置条件: +- 安装gnupg2软件包 + +测试步骤: +- 调Gnupg2Manager.generate_fixed_parameter_key_pair方法,生成密钥对 +- 创建测试文件 +- 调Gnupg2Manager.make_detached_signature方法,生成分离式签名 +- 调Gnupg2Manager.make_clearsign_signature方法,生成联合签名 +- 调Gnupg2Manager.verify_detached_signature方法,确认分离式创建签名是否有效 +- 调Gnupg2Manager.verify_cleartext_signature方法,确认联合创建签名是否有效 +- 清理生成的文件 +- 清理密钥对 + +期望结果: +- 成功生成密钥对 +- 测试文件创建成功 +- 分离式创建签名成功 +- 联合创建签名成功 +- 分离式创建签名有效 +- 联合创建签名有效 +- 生成文件清理成功 +- 密钥对清理成功 \ No newline at end of file diff --git a/docs/system_libraries/gnupg2/tc_gnupg_gpg_func_007.yaml b/docs/system_libraries/gnupg2/tc_gnupg_gpg_func_007.yaml new file mode 100644 index 0000000000000000000000000000000000000000..38ae1cae2c5c967878040cfbe0f741e53001ab49 --- /dev/null +++ b/docs/system_libraries/gnupg2/tc_gnupg_gpg_func_007.yaml @@ -0,0 +1,39 @@ +作者: Liujiang +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 验证gpg.conf文件中的default-key设置是否正确应用于GPG操作。 +修改人: Liujiang + +前置条件: +- 安装gnupg2,expect软件包 + +测试步骤: +- 新建测试文件signature.txt, + 新建创建签名的交互脚本detached_signature.sh +- 执行gpg --batch --gen-key key_params.txt 2>&1, 生成密钥对 +- 检验是否成功生成密钥对 +- 执行创建签名的交互脚本detached_signature.sh, 创建签名 +- 并断言配置是否生效 +- 修改配置,添加默认密钥,并重新加载 +- 执行创建签名的交互脚本detached_signature.sh, 创建签名 +- 断言配置是否生效 +- 还原配置,并重新加载 +- 清理生成的文件 +- 清理密钥对 + +期望结果: +- 测试文件signature.txt新建成功, + 创建签名的交互脚本detached_signature.sh新建成功 +- gpg --batch --gen-key key_params.txt 2>&1执行成功 +- 成功生成密钥对 +- 创建签名成功 +- 配置未生效 +- 配置加载成功 +- 创建签名成功 +- 配置生效 +- 配置还原成功 +- 生成文件清理成功 +- 密钥对清理成功 \ No newline at end of file diff --git a/docs/system_libraries/gnupg2/tc_gnupg_gpg_func_008.yaml b/docs/system_libraries/gnupg2/tc_gnupg_gpg_func_008.yaml new file mode 100644 index 0000000000000000000000000000000000000000..506aa2e642741bc65fc76ed95b7db7325cf789fe --- /dev/null +++ b/docs/system_libraries/gnupg2/tc_gnupg_gpg_func_008.yaml @@ -0,0 +1,35 @@ +作者: Liujiang +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试添加和修改密钥的信任级别功能 +修改人: Liujiang + +前置条件: +- 安装gnupg2, expect软件包 + +测试步骤: +- 新建一个可用的公钥文件publickey.asc, + 新建一个更新信任级别的交互脚本update_trust_script.sh +- 调Gnupg2Manager.import_public_key方法, 导入公钥 +- 检查公钥是否导入成功 +- 调Gnupg2Manager.get_keypair_id方法, 获取公钥id +- 检查公钥信任级别 +- 修改公钥信任级别为"I trust ultimately" +- 检查公钥信任级别 +- 清理生成的文件 +- 清理导入的公钥 + +期望结果: +- 公钥文件publickey.asc新建成功, + 更新信任级别的交互脚本update_trust_script.sh新建成功 +- Gnupg2Manager.import_public_key方法执行成功 +- 公钥导入成功 +- Gnupg2Manager.get_keypair_id方法执行成功 +- 检查公钥信任级别为unknown +- 公钥信任级别修改成功 +- 检查公钥信任级别为ultimate +- 生成文件清理成功 +- 公钥清理成功 \ No newline at end of file diff --git a/docs/system_libraries/gnupg2/tc_gnupg_gpg_func_009.yaml b/docs/system_libraries/gnupg2/tc_gnupg_gpg_func_009.yaml new file mode 100644 index 0000000000000000000000000000000000000000..52d00a65aadae899fbe34edaed3ca8828900b7e9 --- /dev/null +++ b/docs/system_libraries/gnupg2/tc_gnupg_gpg_func_009.yaml @@ -0,0 +1,45 @@ +作者: Liujiang +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试导入公钥后是否能够正确验证签名 +修改人: Liujiang + +前置条件: +- 安装gnupg2软件包 + +测试步骤: +- 新建可用的公钥文件publickey.asc, + 新建测试文件document.txt, + 新建以上测试文件的签名文件document.txt.sig +- 调Gnupg2Manager.import_public_key方法导入公钥 +- 检查公钥是否导入成功 +- 调Gnupg2Manager.verify_detached_signature方法验证签名文件 +- 检查签名是否验证成功 +- 执行sed -i 's/$/./' document.txt, 篡改源文件 +- 调Gnupg2Manager.verify_detached_signature方法验证签名文件 +- 检查签名是否验证成功 +- 执行sed -i 's/i/1/' document.txt.sig, 篡改签名文件 +- 调Gnupg2Manager.verify_detached_signature方法验证签名文件 +- 检查签名是否验证成功 +- 清理生成的文件 +- 清理导入的公钥 + +期望结果: +- 公钥文件publickey.asc新建成功, + 签名的原文件document.txt新建成功, + 签名文件document.txt.sig新建成功 +- Gnupg2Manager.import_public_key方法执行成功 +- 公钥导入成功 +- Gnupg2Manager.verify_detached_signature方法执行成功 +- 签名验证成功 +- 源文件篡改执行成功 +- Gnupg2Manager.verify_detached_signature方法执行成功 +- 签名验证失败 +- 签名文件篡改执行成功 +- Gnupg2Manager.verify_detached_signature方法执行成功 +- 签名验证失败 +- 生成文件清理成功 +- 公钥清理成功 \ No newline at end of file diff --git a/docs/system_libraries/gnutls/tc_gnutls_fun_001.yaml b/docs/system_libraries/gnutls/tc_gnutls_fun_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0e7f573dd52103df9146a4a56f3f02fcb0658b7a --- /dev/null +++ b/docs/system_libraries/gnutls/tc_gnutls_fun_001.yaml @@ -0,0 +1,251 @@ +作者: hongfeng +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 使用gnutls库进行tls的验证 +修改人: hongfeng + +前置条件: +- 创建gnutls_server.c +#include +#include +#include +#include +#include +#include + +#define SERVER_CERTFILE "server.crt" +#define SERVER_KEYFILE "server.key" +#define MAX_BUF 1024 +struct linger so_linger; + +static void terminate(const char *msg) +{ + gnutls_deinit(NULL); + fprintf(stderr, "%s\\n", msg); + exit(1); +} + +int main(int argc, char **argv[]) +{ + int server_sockfd, client_sockfd; + struct sockaddr_in server_addr, client_addr; + socklen_t sin_size; + char buffer[MAX_BUF]; + ssize_t bytes_read; + int ret; + const char *hostname = "localhost"; + gnutls_certificate_credentials_t x509_cred; + gnutls_session_t session; + + /* 初始化GnuTLS */ + gnutls_global_init(); + + /* 创建TCP socket */ + server_sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (server_sockfd == -1) { + perror("socket"); + return 1; + } + // 表示启用LINGER选项 + so_linger.l_onoff = 1; + // 表示立即断开连接,不等待数据发送完 + so_linger.l_linger = 0; + setsockopt(server_sockfd, SOL_SOCKET, SO_LINGER, (void *)&so_linger, sizeof(so_linger)); + + /* 设置服务器地址信息 */ + memset(&server_addr, 0, sizeof(server_addr)); + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(12345); + server_addr.sin_addr.s_addr = htonl(INADDR_ANY); + + /* 绑定地址到socket */ + if (bind(server_sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) { + perror("bind"); + close(server_sockfd); + return 1; + } + + /* 开始监听连接 */ + if (listen(server_sockfd, 5) == -1) { + perror("listen"); + close(server_sockfd); + return 1; + } + + while (1) { + sin_size = sizeof(client_addr); + client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_addr, &sin_size); + if (client_sockfd == -1) { + perror("accept"); + continue; + } + + /* 初始化GnuTLS会话 */ + gnutls_certificate_allocate_credentials(&x509_cred); + gnutls_certificate_set_x509_key_file(x509_cred, SERVER_CERTFILE, SERVER_KEYFILE, GNUTLS_X509_FMT_PEM); + gnutls_init(&session, GNUTLS_SERVER); + gnutls_priority_set_direct(session, "NORMAL:+VERS-TLS1.2:+CTYPE-X509", NULL); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred); + + gnutls_transport_set_int(session, client_sockfd); + + do { + ret = gnutls_handshake(session); + if (ret < 0 && gnutls_error_is_fatal(ret) == 0) { + printf("Handshake.....\\n"); + continue; + } else if (ret < 0) { + terminate("gnutls_handshake"); + } + printf("Handshake successful.\\n"); + break; + } while (ret == 0); + + while ((bytes_read = gnutls_record_recv(session, buffer, MAX_BUF)) > 0) { + printf("Received: %s\\n", buffer); + gnutls_record_send(session, buffer, bytes_read); + } + + if (bytes_read == 0) { + printf("Client disconnected\\n"); + } else if (bytes_read < 0) { + terminate(gnutls_strerror(bytes_read)); + } + + gnutls_bye(session, GNUTLS_SHUT_RDWR); + + /* 清理GnuTLS资源 */ + gnutls_deinit(session); + + /* 关闭客户端连接 */ + close(client_sockfd); + } + + /* 清理全局GnuTLS资源和证书 */ + gnutls_certificate_free_credentials(x509_cred); + close(server_sockfd); + gnutls_global_deinit(); + + return 0; +} +- 创建gnutls_client.c +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_BUF 1024 +#define SERVER_IP "127.0.0.1" // 替换为服务器IP地址 +#define SERVER_PORT 12345 // 使用与服务器相同的端口 + +static void terminate(const char *msg) { + gnutls_perror(msg); + exit(1); +} + +int main() { + int sd; + struct sockaddr_in server_addr; + gnutls_certificate_credentials_t cert_cred; + gnutls_session_t session; + unsigned char buffer[MAX_BUF + 1]; + ssize_t ret; + + /* 初始化GnuTLS */ + gnutls_global_init(); + + /* 设置信任证书链 */ + gnutls_certificate_allocate_credentials(&cert_cred); + gnutls_certificate_set_x509_trust_file(cert_cred, "server.crt", GNUTLS_X509_FMT_PEM); + + + /* 创建TCP套接字 */ + sd = socket(AF_INET, SOCK_STREAM, 0); + if (sd < 0) { + perror("socket"); + exit(1); + } + + memset(&server_addr, 0, sizeof(server_addr)); + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(SERVER_PORT); + inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr); + + if (connect(sd, (struct sockaddr*) &server_addr, sizeof(server_addr)) < 0) { + perror("connect"); + close(sd); + exit(1); + } + + /* 初始化一个GnuTLS会话 */ + gnutls_init(&session, GNUTLS_CLIENT); + + /* 设置会话优先级和信任证书 */ + gnutls_priority_set_direct(session, "NORMAL:+VERS-TLS1.3:+CTYPE-X509", NULL); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, cert_cred); + + /* 将套接字与GnuTLS会话关联起来 */ + gnutls_transport_set_int(session, sd); + + do { + ret = gnutls_handshake(session); + if (ret < 0 && gnutls_error_is_fatal(ret) == 0) { + printf("Handshake.....\\n"); + continue; + } else if (ret < 0) { + terminate("gnutls_handshake"); + } + printf("Handshake successful.\\n"); + break; + } while (ret == 0); + + /* 安全地发送和接收消息 */ + strcpy(buffer, "Hello, Server!"); + gnutls_record_send(session, buffer, strlen(buffer)); + printf("Sending: %s\\n", buffer); + + do { + ret = gnutls_record_recv(session, buffer, MAX_BUF); + if (ret == 0) { /* EOS or error */ + break; + } else if (ret < 0) { + if (gnutls_error_is_fatal(ret) != 0) { + terminate("gnutls_record_recv"); + } + continue; + } + buffer[ret] = '\\0'; + printf("Received: %s\\n", buffer); + break; + } while (1); + + /* 清理会话资源 */ + gnutls_bye(session, GNUTLS_SHUT_RDWR); + gnutls_deinit(session); + + /* 清理全局和证书资源 */ + gnutls_certificate_free_credentials(cert_cred); + gnutls_global_deinit(); + + close(sd); + + return 0; +} +- 编译gcc -o gnutls_server gnutls_server.c `pkg-config --cflags --libs gnutls` +- 编译gcc -o gnutls_client gnutls_client.c `pkg-config --cflags --libs gnutls` +- 将事先准备好的server.crt和server.key拷贝到执行路径 + +测试步骤: +- 执行./gnutls_server &, 让server在后台运行 +- 执行./gnutls_client,启动client + +期望结果: +- 命令执行成功 +- 命令执行成功, 检查client输出,包含握手成功,和收到server消息 diff --git a/docs/system_libraries/gpgme/tc_gpgme_func001.yaml b/docs/system_libraries/gpgme/tc_gpgme_func001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..48f55ddb343f6e120c44bf424744350c2150ff99 --- /dev/null +++ b/docs/system_libraries/gpgme/tc_gpgme_func001.yaml @@ -0,0 +1,42 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 查询gpgme库版本 +修改人: gaohongmei + +前置条件: +- 创建test_gpgme.c脚本,包括检查版本并打印相关版本信息 +#include +#define REQUIRED_VERSION "1.1.0" + +int main(){ + const char *actual_version = gpgme_check_version(REQUIRED_VERSION); + + if (actual_version) + { + printf("The actual GPGME version is at least %s\\n", REQUIRED_VERSION); + printf("Version from header: %s (0x%06x)\\n", + GPGME_VERSION, GPGME_VERSION_NUMBER); + printf("Version from binary: %s\\n", gpgme_check_version(NULL)); + printf("Copyright blurb ...:%s\\n", gpgme_check_version("\\x01\\x01")); + + // 如果实际版本大于等于所需版本,则返回0,表示成功 + return 0; + } + else + { + printf("Error: The actual GPGME version is less than %s\\n", REQUIRED_VERSION); + return 1; // 返回非零值表示版本检查失败 + } +} + +测试步骤: +- 执行命令`gcc -o /tmp/ghm/test_gpgme /tmp/ghm/test_gpgme.c -lgpgme` +- 执行命令`/tmp/ghm/test_gpgme` + +期望结果: +- 命令执行成功,生成/tmp/ghm/test_gpgme脚本 +- 命令执行成功,返回内容包括:This is GPGME 1.21.0 - The GnuPG Made Easy library \ No newline at end of file diff --git a/docs/system_libraries/gpgme/tc_gpgme_func002.yaml b/docs/system_libraries/gpgme/tc_gpgme_func002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1aaf105a06d54b51b2a470fbe5bfd8a98bebcd74 --- /dev/null +++ b/docs/system_libraries/gpgme/tc_gpgme_func002.yaml @@ -0,0 +1,78 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 获取和显示gpgme库相关的引擎信息 +修改人: gaohongmei + +前置条件: +- 创建test_gpgme.c脚本,打印GPGME的相关目录路径信息和可用的加密引擎信息 +#include + +int main (void){ + gpgme_engine_info_t info; + gpgme_error_t err; + + gpgme_check_version (NULL); + + { + const char *keys[] = { + "homedir", + "sysconfdir", + "bindir", + "libexecdir", + "libdir", + "datadir", + "localedir", + "socketdir", + "agent-socket", + "agent-ssh-socket", + "dirmngr-socket", + "uiserver-socket", + "gpgconf-name", + "gpg-name", + "gpgsm-name", + "g13-name", + "keyboxd-name", + "agent-name", + "scdaemon-name", + "dirmngr-name", + "pinentry-name", + "gpg-wks-client-name", + "gpgtar-name", + NULL + }; + const char *s; + int i; + + for (i = 0; keys[i]; i++) + { + if ((s = gpgme_get_dirinfo (keys[i]))) + fprintf (stdout, "dirinfo: %s='%s'\\n", keys[i], s); + } + } + + err = gpgme_get_engine_info (&info); + if (err) + { + fprintf (stderr, "%s:%d: gpgme_error_t %s\\n", __FILE__, __LINE__, gpgme_strerror (err)); + return 1; + } + + for (; info; info = info->next) + fprintf (stdout, "protocol=%d engine='%s' v='%s' (min='%s') home='%s'\\n", + info->protocol, info->file_name, info->version, info->req_version, + info->home_dir ? info->home_dir : "[default]"); + + return 0; +} + +测试步骤: +- 执行命令`gcc -o /tmp/ghm/test_gpgme /tmp/ghm/test_gpgme.c -lgpgme` +- 执行命令`/tmp/ghm/test_gpgme` + +期望结果: +- 命令执行成功,生成/tmp/ghm/test_gpgme脚本 +- 命令执行成功,返回gpgme的相关目录路径信息和可用的加密引擎 \ No newline at end of file diff --git a/docs/system_libraries/gpgme/tc_gpgme_func003.yaml b/docs/system_libraries/gpgme/tc_gpgme_func003.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3adcd10c6830de702d7eb878bc7fc3823e462b69 --- /dev/null +++ b/docs/system_libraries/gpgme/tc_gpgme_func003.yaml @@ -0,0 +1,132 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: gpgme库证书导出 +修改人: gaohongmei + +前置条件: +- 创建test_gpgme.c脚本,根据给定的模式从GnuPG密钥库中导出证书。 +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include + +#define PGM "test_gpgme" + +#define fail_if_err(err) \ + do \ + { \ + if (err) \ + { \ + fprintf (stderr, PGM": file %s line %d: <%s> %s\\n", \ + __FILE__, __LINE__, gpgme_strsource (err), \ + gpgme_strerror (err)); \ + exit (1); \ + } \ + } \ + while (0) + +void +init_gpgme_basic (void) +{ + gpgme_check_version (NULL); + setlocale (LC_ALL, ""); + gpgme_set_locale (NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL)); +#ifndef HAVE_W32_SYSTEM + gpgme_set_locale (NULL, LC_MESSAGES, setlocale (LC_MESSAGES, NULL)); +#endif +} + +void +init_gpgme (gpgme_protocol_t proto) +{ + gpg_error_t err; + + init_gpgme_basic (); + err = gpgme_engine_check_version (proto); + fail_if_err (err); +} + +void +print_data (gpgme_data_t dh) +{ +#define BUF_SIZE 512 + char buf[BUF_SIZE + 1]; + int ret; + + ret = gpgme_data_seek (dh, 0, SEEK_SET); + if (ret) + fail_if_err (gpgme_err_code_from_errno (errno)); + while ((ret = gpgme_data_read (dh, buf, BUF_SIZE)) > 0) + fwrite (buf, ret, 1, stdout); + if (ret < 0) + fail_if_err (gpgme_err_code_from_errno (errno)); +} + +int +main (void) +{ + gpgme_ctx_t ctx; + gpgme_error_t err; + gpgme_data_t out; + const char *pattern1[] = { "DFN Top Level Certification Authority", NULL }; + const char *pattern2[] = { "A782EB7CA56212CF3DEF6088FB6708AE59FAD36E", + "DFN Server Certification Authority", + NULL }; + + init_gpgme (GPGME_PROTOCOL_CMS); + + err = gpgme_new (&ctx); + fail_if_err (err); + gpgme_set_protocol (ctx, GPGME_PROTOCOL_CMS); + + gpgme_set_armor (ctx, 1); + + /* Check exporting of one certificate. */ + err = gpgme_data_new (&out); + fail_if_err (err); + err = gpgme_op_export_ext (ctx, pattern1, 0, out); + fail_if_err (err); + + fflush (NULL); + fputs ("Begin Result:\\n", stdout); + print_data (out); + fputs ("End Result.\\n", stdout); + + gpgme_data_release (out); + + /* Check exporting of 2 certificates. */ + err = gpgme_data_new (&out); + fail_if_err (err); + err = gpgme_op_export_ext (ctx, pattern2, 0, out); + fail_if_err (err); + + fflush (NULL); + fputs ("Begin Result:\\n", stdout); + print_data (out); + fputs ("End Result.\\n", stdout); + + gpgme_data_release (out); + + + gpgme_release (ctx); + + return 0; +} + +测试步骤: +- 执行命令`gcc -o /tmp/ghm/test_gpgme /tmp/ghm/test_gpgme.c -lgpgme` +- 执行命令`/tmp/ghm/test_gpgme` + +期望结果: +- 命令执行成功,生成/tmp/ghm/test_gpgme脚本 +- 命令执行成功,返回预期结果 \ No newline at end of file diff --git a/docs/system_libraries/gpgme/tc_gpgme_func004.yaml b/docs/system_libraries/gpgme/tc_gpgme_func004.yaml new file mode 100644 index 0000000000000000000000000000000000000000..fb262d6bb0ffbf7d1357b89b2954d16d81fc1184 --- /dev/null +++ b/docs/system_libraries/gpgme/tc_gpgme_func004.yaml @@ -0,0 +1,226 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: gpgme库进行CMS协议相关的签名验证 +修改人: gaohongmei + +前置条件: +- 创建test_gpgme.c脚本,测试CMS签名数据的有效性和完整性。 +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#define PGM "test_gpgme" + +#define fail_if_err(err) \ + do \ + { \ + if (err) \ + { \ + fprintf (stderr, PGM": file %s line %d: <%s> %s\\n", \ + __FILE__, __LINE__, gpgme_strsource (err), \ + gpgme_strerror (err)); \ + exit (1); \ + } \ + } \ + while (0) + +static int got_errors; + +static const char test_text1[] = "Hallo Leute!\\n"; +static const char test_text1f[]= "Hallo Leute?\\n"; +static const char test_sig1[] = +"-----BEGIN CMS OBJECT-----\\n" +"MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAA\\n" +"MYIBOTCCATUCAQEwcDBrMQswCQYDVQQGEwJERTETMBEGA1UEBxQKRPxzc2VsZG9y\\n" +"ZjEWMBQGA1UEChMNZzEwIENvZGUgR21iSDEZMBcGA1UECxMQQWVneXB0ZW4gUHJv\\n" +"amVjdDEUMBIGA1UEAxMLdGVzdCBjZXJ0IDECAQAwBwYFKw4DAhqgJTAjBgkqhkiG\\n" +"9w0BCQQxFgQU7FC/ibH3lC9GE24RJJxa8zqP7wEwCwYJKoZIhvcNAQEBBIGAA3oC\\n" +"DUmKERmD1eoJYFw38y/qnncS/6ZPjWINDIphZeK8mzAANpvpIaRPf3sNBznb89QF\\n" +"mRgCXIWcjlHT0DTRLBf192Ve22IyKH00L52CqFsSN3a2sajqRUlXH8RY2D+Al71e\\n" +"MYdRclgjObCcoilA8fZ13VR4DiMJVFCxJL4qVWI=\\n" +"-----END CMS OBJECT-----\\n"; + +void +print_data (gpgme_data_t dh) +{ +#define BUF_SIZE 512 + char buf[BUF_SIZE + 1]; + int ret; + + ret = gpgme_data_seek (dh, 0, SEEK_SET); + if (ret) + fail_if_err (gpgme_err_code_from_errno (errno)); + while ((ret = gpgme_data_read (dh, buf, BUF_SIZE)) > 0) + fwrite (buf, ret, 1, stdout); + if (ret < 0) + fail_if_err (gpgme_err_code_from_errno (errno)); +} + +void +init_gpgme_basic (void) +{ + gpgme_check_version (NULL); + setlocale (LC_ALL, ""); + gpgme_set_locale (NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL)); +#ifndef HAVE_W32_SYSTEM + gpgme_set_locale (NULL, LC_MESSAGES, setlocale (LC_MESSAGES, NULL)); +#endif +} + +void +init_gpgme (gpgme_protocol_t proto) +{ + gpg_error_t err; + + init_gpgme_basic (); + err = gpgme_engine_check_version (proto); + fail_if_err (err); +} + +static void +check_result (gpgme_verify_result_t result, int summary, const char *fpr, + gpgme_error_t status, gpgme_validity_t validity) +{ + gpgme_signature_t sig; + + sig = result->signatures; + if (!sig || sig->next) + { + fprintf (stderr, "%s:%i: Unexpected number of signatures\\n", + __FILE__, __LINE__); + got_errors = 1; + if (!sig) + return; + } + if (sig->summary != summary) + { + fprintf (stderr, "%s:%i: Unexpected signature summary: " + "want=0x%x have=0x%x\\n", + __FILE__, __LINE__, summary, sig->summary); + got_errors = 1; + } + if (sig->fpr && strcmp (sig->fpr, fpr)) + { + fprintf (stderr, "%s:%i: Unexpected fingerprint: %s\\n", + __FILE__, __LINE__, sig->fpr); + got_errors = 1; + } + if (gpgme_err_code (sig->status) != status) + { + fprintf (stderr, "%s:%i: Unexpected signature status: %s\\n", + __FILE__, __LINE__, gpgme_strerror (sig->status)); + got_errors = 1; + } + if (sig->notations) + { + fprintf (stderr, "%s:%i: Unexpected notation data\\n", + __FILE__, __LINE__); + got_errors = 1; + } + if (sig->wrong_key_usage) + { + fprintf (stderr, "%s:%i: Unexpectedly wrong key usage\\n", + __FILE__, __LINE__); + got_errors = 1; + } + if (sig->validity != validity) + { + fprintf (stderr, "%s:%i: Unexpected validity: %i\\n", + __FILE__, __LINE__, sig->validity); + got_errors = 1; + } + if (gpgme_err_code (sig->validity_reason) != GPG_ERR_NO_ERROR) + { + fprintf (stderr, "%s:%i: Unexpected validity reason: %s\\n", + __FILE__, __LINE__, gpgme_strerror (sig->validity_reason)); + got_errors = 1; + } +} + + +static void +show_auditlog (gpgme_ctx_t ctx) +{ + gpgme_error_t err; + gpgme_data_t data; + + err = gpgme_data_new (&data); + fail_if_err (err); + err = gpgme_op_getauditlog (ctx, data, 0); + if (err) + { + fprintf (stderr, "%s:%i: Can't get audit log: %s\\n", + __FILE__, __LINE__, gpgme_strerror (err)); + if (gpgme_err_code (err) != GPG_ERR_ASS_UNKNOWN_CMD) + got_errors = 1; + } + print_data (data); + gpgme_data_release (data); +} + + +int +main (void) +{ + gpgme_ctx_t ctx; + gpgme_error_t err; + gpgme_data_t sig, text; + gpgme_verify_result_t result; + + init_gpgme (GPGME_PROTOCOL_CMS); + + err = gpgme_new (&ctx); + fail_if_err (err); + gpgme_set_protocol (ctx, GPGME_PROTOCOL_CMS); + + /* Checking a valid message. */ + err = gpgme_data_new_from_mem (&text, test_text1, strlen (test_text1), 0); + fail_if_err (err); + err = gpgme_data_new_from_mem (&sig, test_sig1, strlen (test_sig1), 0); + fail_if_err (err); + + err = gpgme_op_verify (ctx, sig, text, NULL); + fail_if_err (err); + result = gpgme_op_verify_result (ctx); + check_result (result, GPGME_SIGSUM_VALID | GPGME_SIGSUM_GREEN, + "A782EB7CA56212CF3DEF6088FB6708AE59FAD36E", + GPG_ERR_NO_ERROR, GPGME_VALIDITY_FULL); + + show_auditlog (ctx); + + /* Checking a manipulated message. */ + gpgme_data_release (text); + err = gpgme_data_new_from_mem (&text, test_text1f, strlen (test_text1f), 0); + fail_if_err (err); + gpgme_data_seek (sig, 0, SEEK_SET); + err = gpgme_op_verify (ctx, sig, text, NULL); + fail_if_err (err); + result = gpgme_op_verify_result (ctx); + check_result (result, GPGME_SIGSUM_RED, + "A782EB7CA56212CF3DEF6088FB6708AE59FAD36E", + GPG_ERR_BAD_SIGNATURE, GPGME_VALIDITY_UNKNOWN); + + show_auditlog (ctx); + + gpgme_data_release (text); + gpgme_data_release (sig); + gpgme_release (ctx); + return got_errors? 1 : 0; +} + +测试步骤: +- 执行命令`gcc -o /tmp/ghm/test_gpgme /tmp/ghm/test_gpgme.c -lgpgme` +- 执行命令`/tmp/ghm/test_gpgme` + +期望结果: +- 命令执行成功,生成/tmp/ghm/test_gpgme脚本 +- 命令执行成功,返回预期结果 \ No newline at end of file diff --git a/docs/system_libraries/initscripts/tc_initscripts_initscripts_func_002.yaml b/docs/system_libraries/initscripts/tc_initscripts_initscripts_func_002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c1b9f52dfbaf1f6d0ffca26424547bb1d04b7385 --- /dev/null +++ b/docs/system_libraries/initscripts/tc_initscripts_initscripts_func_002.yaml @@ -0,0 +1,96 @@ +作者: suomengjun +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试initscripts包管理systemd系统自定义服务的生命周期的基本功能 +修改人: suomengjun + +前置条件: +- 安装initscripts,initscripts-service,systemd +- 自定义服务单元(unit)配置文件 +cat << EOF > /etc/systemd/system/init_ser_test_002.service +[Unit] +Description=My Custom Service +After=network.target + +[Service] +Type=forking +ExecStart=/etc/init.d/init_ser_test_002 start +ExecStop=/etc/init.d/init_ser_test_002 stop +ExecReload=/etc/init.d/init_ser_test_002 restart +PIDFile=/var/run/init_ser_test_002.pid + +[Install] +WantedBy=multi-user.target +EOF + +- 生成执行脚本 #可根据需要自行设计实现过程 +cat << "EOF" > /etc/init.d/init_ser_test_002 +#!/bin/bash + +PIDFILE="/var/run/init_ser_test_002.pid" + +start() { + echo "Starting init_ser_test_002 service..." + nohup watch -n 5 date > /tmp/init_ser_test_002.log 2>&1 & + echo $! > "$PIDFILE" +} + +stop() { + if [ -f "$PIDFILE" ]; then + PID=$(cat "$PIDFILE") + echo "Stopping init_ser_test_002 service..." + kill "$PID" + rm "$PIDFILE" + else + echo "PID file not found. Is the service running?" + fi +} + +status() { + if [ -f "$PIDFILE" ]; then + PID=$(cat "$PIDFILE") + if ps -p "$PID" > /dev/null; then + echo "Service is running (PID: $PID)" + else + echo "Service not running but pid file exists" + fi + else + echo "Service is not running." + fi +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart) + stop + start + ;; + status) + status + ;; + *) + echo "Usage: $0 {start|stop|restart|status}" +esac +EOF +- 添加执行权限 +chmod +x /etc/init.d/init_ser_test_002 + +测试步骤: +- service init_ser_test_002 status +- service init_ser_test_002 start +- service init_ser_test_002 restart +- service init_ser_test_002 stop + +期望结果: +- 服务状态查看成功,包含running +- 服务启动命令执行成功 +- 服务重启动命令执行成功 +- 服务停止命令执行成功 diff --git a/docs/system_libraries/krb5/tc_krb5_fun_001.yaml b/docs/system_libraries/krb5/tc_krb5_fun_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a318653c91a06c4348bbbed8f05d6d1e7894f80d --- /dev/null +++ b/docs/system_libraries/krb5/tc_krb5_fun_001.yaml @@ -0,0 +1,17 @@ +作者: qintingting +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 获取Kerberos 版本 +修改人: qintingting + +前置条件: +- 安装krb5-server、krb5-workstation、krb5-libs包 + +测试步骤: +- 执行klist -V、rpm -q krb5-server命令,检查Kerberos 版本 + +期望结果: +- klist -V、rpm -q krb5-server查看的版本一致 diff --git a/docs/system_libraries/krb5/tc_krb5_fun_002.yaml b/docs/system_libraries/krb5/tc_krb5_fun_002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3d69d4c72835cd1caa337251ef7b2049d98bdc64 --- /dev/null +++ b/docs/system_libraries/krb5/tc_krb5_fun_002.yaml @@ -0,0 +1,67 @@ +作者: qintingting +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: krb5中krb5kdc.service启停测试 +修改人: qintingting + +前置条件: +- 安装krb5-server、krb5-workstation、krb5-libs包 +- 配置/etc/krb5.conf +[logging] + default = FILE:/var/log/krb5libs.log + kdc = FILE:/var/log/krb5kdc.log + admin_server = FILE:/var/log/kadmind.log + +[libdefaults] + default_realm = MYDOMAIN.LOCAL + dns_lookup_realm = false + dns_lookup_kdc = false + ticket_lifetime = 24h + renew_lifetime = 7d + forwardable = true + +[realms] + MYDOMAIN.LOCAL = { + kdc = localhost + admin_server = localhost + } + +[domain_realm] + .mydomain.local = MYDOMAIN.LOCAL + mydomain.local = MYDOMAIN.LOCAL +- 配置/var/kerberos/krb5kdc/kdc.conf +[kdcdefaults] + kdc_ports = 88 + kdc_tcp_ports = 88 + +[realms] + MYDOMAIN.LOCAL = { + # master_key_type在现代Kerberos安装中通常是aes256-cts + master_key_type = aes256-cts + acl_file = /var/kerberos/krb5kdc/kadm5.acl + dict_file = /usr/share/dict/words + admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab + supported_enctypes = aes256-cts:normal aes128-cts:normal + max_renewable_life = 7d + default_principal_flags = +preauth +} +- 修改/var/kerberos/krb5kdc/kadm5.acl文件 +*/admin@MYDOMAIN.LOCAL * +- 初始化 kerberos 数据库,数据库密码为MYDOMAIN@123 +kdb5_util create -s -r MYDOMAIN.LOCAL + + +测试步骤: +- 执行systemctl restart krb5kdc.service +- 执行systemctl stop krb5kdc.service +- 执行systemctl start krb5kdc.service +- 执行systemctl status krb5kdc.service + + + +期望结果: +- 以上命令均执行成功 + diff --git a/docs/system_libraries/krb5/tc_krb5_fun_003.yaml b/docs/system_libraries/krb5/tc_krb5_fun_003.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c6b58c92236006083931c37e09aed5a8b90d20d2 --- /dev/null +++ b/docs/system_libraries/krb5/tc_krb5_fun_003.yaml @@ -0,0 +1,66 @@ +作者: qintingting +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试krb5中创建MYDOMAIN.LOCAL主体的Ticket +修改人: qintingting + +前置条件: +- 安装krb5-server、krb5-workstation、krb5-libs包 +- 配置/etc/krb5.conf +[logging] + default = FILE:/var/log/krb5libs.log + kdc = FILE:/var/log/krb5kdc.log + admin_server = FILE:/var/log/kadmind.log + +[libdefaults] + default_realm = MYDOMAIN.LOCAL + dns_lookup_realm = false + dns_lookup_kdc = false + ticket_lifetime = 24h + renew_lifetime = 7d + forwardable = true + +[realms] + MYDOMAIN.LOCAL = { + kdc = localhost + admin_server = localhost + } + +[domain_realm] + .mydomain.local = MYDOMAIN.LOCAL + mydomain.local = MYDOMAIN.LOCAL +- 配置/var/kerberos/krb5kdc/kdc.conf +[kdcdefaults] + kdc_ports = 88 + kdc_tcp_ports = 88 + +[realms] + MYDOMAIN.LOCAL = { + # master_key_type在现代Kerberos安装中通常是aes256-cts + master_key_type = aes256-cts + acl_file = /var/kerberos/krb5kdc/kadm5.acl + dict_file = /usr/share/dict/words + admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab + supported_enctypes = aes256-cts:normal aes128-cts:normal + max_renewable_life = 7d + default_principal_flags = +preauth +} +- 修改/var/kerberos/krb5kdc/kadm5.acl文件 +*/admin@MYDOMAIN.LOCAL * +- 初始化 kerberos 数据库,数据库密码为MYDOMAIN@123 +kdb5_util create -s -r MYDOMAIN.LOCAL +- 重启服务 +sudo systemctl restart krb5kdc.service + +测试步骤: +- 执行kadmin.local addprinc -pw user@123 user命令,创建一个user用户,设置密码为user@123 +- 执行kinit user用户获取,生成TGT票据凭证 +- 执行klist,检查结果是否包含krbtgt/MYDOMAIN.LOCAL@MYDOMAIN.LOCAL票据凭证 + +期望结果: +- 用户创建成功 +- 生成TGT票据凭证 +- 结果包含krbtgt/MYDOMAIN.LOCAL@MYDOMAIN.LOCAL票据凭证 \ No newline at end of file diff --git a/docs/system_libraries/krb5/tc_krb5_fun_004.yaml b/docs/system_libraries/krb5/tc_krb5_fun_004.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c4fad58168f1ddbf748e73075899c69ccfc93315 --- /dev/null +++ b/docs/system_libraries/krb5/tc_krb5_fun_004.yaml @@ -0,0 +1,66 @@ +作者: qintingting +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试krb5中使用TGT可以获取服务票据 +修改人: qintingting + +前置条件: +- 安装krb5-server、krb5-workstation、krb5-libs包 +- 配置/etc/krb5.conf +[logging] + default = FILE:/var/log/krb5libs.log + kdc = FILE:/var/log/krb5kdc.log + admin_server = FILE:/var/log/kadmind.log + +[libdefaults] + default_realm = MYDOMAIN.LOCAL + dns_lookup_realm = false + dns_lookup_kdc = false + ticket_lifetime = 24h + renew_lifetime = 7d + forwardable = true + +[realms] + MYDOMAIN.LOCAL = { + kdc = localhost + admin_server = localhost + } + +[domain_realm] + .mydomain.local = MYDOMAIN.LOCAL + mydomain.local = MYDOMAIN.LOCAL +- 配置/var/kerberos/krb5kdc/kdc.conf +[kdcdefaults] + kdc_ports = 88 + kdc_tcp_ports = 88 + +[realms] + MYDOMAIN.LOCAL = { + # master_key_type在现代Kerberos安装中通常是aes256-cts + master_key_type = aes256-cts + acl_file = /var/kerberos/krb5kdc/kadm5.acl + dict_file = /usr/share/dict/words + admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab + supported_enctypes = aes256-cts:normal aes128-cts:normal + max_renewable_life = 7d + default_principal_flags = +preauth +} +- 修改/var/kerberos/krb5kdc/kadm5.acl文件 +*/admin@MYDOMAIN.LOCAL * +- 初始化 kerberos 数据库,数据库密码为MYDOMAIN@123 + kdb5_util create -s -r MYDOMAIN.LOCAL +- 重启服务 + sudo systemctl restart krb5kdc.service +- 执行kadmin.local addprinc -pw user@123 user命令,创建一个user用户,设置密码为user@123 +- 执行kinit user生成TGT票据凭证 + +测试步骤: +- 执行kvno user来获取服务票据 +- 执行kvno krbtgt/MYDOMAIN.LOCAL@MYDOMAIN.LOCAL来获取服务票据 + +期望结果: +- 获取服务票据成功,返回kvno = 1 +- 获取服务票据成功,返回kvno = 1 diff --git a/docs/system_libraries/krb5/tc_krb5_fun_005.yaml b/docs/system_libraries/krb5/tc_krb5_fun_005.yaml new file mode 100644 index 0000000000000000000000000000000000000000..173a497a5575b4a249a387eddb0e1880ca38319b --- /dev/null +++ b/docs/system_libraries/krb5/tc_krb5_fun_005.yaml @@ -0,0 +1,65 @@ +作者: qintingting +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试krb5中更改主体密码的功能 +修改人: qintingting + +前置条件: +- 安装krb5-server、krb5-workstation、krb5-libs包 +- 配置/etc/krb5.conf +[logging] + default = FILE:/var/log/krb5libs.log + kdc = FILE:/var/log/krb5kdc.log + admin_server = FILE:/var/log/kadmind.log + +[libdefaults] + default_realm = MYDOMAIN.LOCAL + dns_lookup_realm = false + dns_lookup_kdc = false + ticket_lifetime = 24h + renew_lifetime = 7d + forwardable = true + +[realms] + MYDOMAIN.LOCAL = { + kdc = localhost + admin_server = localhost + } + +[domain_realm] + .mydomain.local = MYDOMAIN.LOCAL + mydomain.local = MYDOMAIN.LOCAL +- 配置/var/kerberos/krb5kdc/kdc.conf +[kdcdefaults] + kdc_ports = 88 + kdc_tcp_ports = 88 + +[realms] + MYDOMAIN.LOCAL = { + # master_key_type在现代Kerberos安装中通常是aes256-cts + master_key_type = aes256-cts + acl_file = /var/kerberos/krb5kdc/kadm5.acl + dict_file = /usr/share/dict/words + admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab + supported_enctypes = aes256-cts:normal aes128-cts:normal + max_renewable_life = 7d + default_principal_flags = +preauth +} +-修改/var/kerberos/krb5kdc/kadm5.acl文件 +*/admin@MYDOMAIN.LOCAL * +- 初始化 kerberos 数据库,数据库密码为MYDOMAIN@123 +kdb5_util create -s -r MYDOMAIN.LOCAL +- 重启服务 +sudo systemctl restart krb5kdc.service +- 执行kadmin.local addprinc -pw user@123 user命令,创建一个user用户,设置密码为user@123 +- 执行kinit user,密码user获取TGT凭证 + +测试步骤: +- 修改user用户的命令为new@123 + + +期望结果: +- 修改密码成功 diff --git a/docs/system_libraries/krb5/tc_krb5_fun_006.yaml b/docs/system_libraries/krb5/tc_krb5_fun_006.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f4d3089bd8afdc35d6995b76752f75af50c253a1 --- /dev/null +++ b/docs/system_libraries/krb5/tc_krb5_fun_006.yaml @@ -0,0 +1,68 @@ +作者: qintingting +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试krb5中可以创建不同权限的用户 +修改人: qintingting + +前置条件: +- 安装krb5-server、krb5-workstation、krb5-libs包 +- 配置/etc/krb5.conf +[logging] + default = FILE:/var/log/krb5libs.log + kdc = FILE:/var/log/krb5kdc.log + admin_server = FILE:/var/log/kadmind.log + +[libdefaults] + default_realm = MYDOMAIN.LOCAL + dns_lookup_realm = false + dns_lookup_kdc = false + ticket_lifetime = 24h + renew_lifetime = 7d + forwardable = true + +[realms] + MYDOMAIN.LOCAL = { + kdc = localhost + admin_server = localhost + } + +[domain_realm] + .mydomain.local = MYDOMAIN.LOCAL + mydomain.local = MYDOMAIN.LOCAL +- 配置/var/kerberos/krb5kdc/kdc.conf +[kdcdefaults] + kdc_ports = 88 + kdc_tcp_ports = 88 + +[realms] + MYDOMAIN.LOCAL = { + # master_key_type在现代Kerberos安装中通常是aes256-cts + master_key_type = aes256-cts + acl_file = /var/kerberos/krb5kdc/kadm5.acl + dict_file = /usr/share/dict/words + admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab + supported_enctypes = aes256-cts:normal aes128-cts:normal + max_renewable_life = 7d + default_principal_flags = +preauth +} +-修改/var/kerberos/krb5kdc/kadm5.acl文件 +*/admin@MYDOMAIN.LOCAL * +- 初始化 kerberos 数据库,数据库密码为MYDOMAIN@123 +kdb5_util create -s -r MYDOMAIN.LOCAL +- 重启服务 +sudo systemctl restart krb5kdc.service + +测试步骤: +-创建 1 个特权主体 (privileged principal),使用 admin 策略 +-创建 1 个无特权主体(unprivileged principal),使用 user 策略 +-创建 1 个无特权主体 + + +期望结果: +-用户创建成功 +-用户创建成功 +-用户创建成功 + diff --git a/docs/system_libraries/krb5/tc_krb5_fun_007.yaml b/docs/system_libraries/krb5/tc_krb5_fun_007.yaml new file mode 100644 index 0000000000000000000000000000000000000000..01d6cc43d05ef7f4570dff88ff41e5be804596e9 --- /dev/null +++ b/docs/system_libraries/krb5/tc_krb5_fun_007.yaml @@ -0,0 +1,68 @@ +作者: qintingting +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试krb5中拥有admin特权的可以免密登录kadmin.local +修改人: qintingting + +前置条件: +- 安装krb5-server、krb5-workstation、krb5-libs包 +- 配置/etc/krb5.conf +[logging] + default = FILE:/var/log/krb5libs.log + kdc = FILE:/var/log/krb5kdc.log + admin_server = FILE:/var/log/kadmind.log + +[libdefaults] + default_realm = MYDOMAIN.LOCAL + dns_lookup_realm = false + dns_lookup_kdc = false + ticket_lifetime = 24h + renew_lifetime = 7d + forwardable = true + +[realms] + MYDOMAIN.LOCAL = { + kdc = localhost + admin_server = localhost + } + +[domain_realm] + .mydomain.local = MYDOMAIN.LOCAL + mydomain.local = MYDOMAIN.LOCAL +- 配置/var/kerberos/krb5kdc/kdc.conf +[kdcdefaults] + kdc_ports = 88 + kdc_tcp_ports = 88 + +[realms] + MYDOMAIN.LOCAL = { + # master_key_type在现代Kerberos安装中通常是aes256-cts + master_key_type = aes256-cts + acl_file = /var/kerberos/krb5kdc/kadm5.acl + dict_file = /usr/share/dict/words + admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab + supported_enctypes = aes256-cts:normal aes128-cts:normal + max_renewable_life = 7d + default_principal_flags = +preauth +} +-修改/var/kerberos/krb5kdc/kadm5.acl文件 +*/admin@MYDOMAIN.LOCAL * +- 初始化 kerberos 数据库,数据库密码为MYDOMAIN@123 +kdb5_util create -s -r MYDOMAIN.LOCAL +- 重启服务 +sudo systemctl restart krb5kdc.service + + +测试步骤: +-执行kadmin.local addprinc -policy admin -pw user@123 root/admin创建 1 个特权主体,使用 admin 策略,并获取kinit root/admin获取TGT +-使用 admin 特权用户凭据进行kadmin.local 登录 + +期望结果: +-用户创建成功 +-可以登录,提示Authenticating as principal root/admin@MYDOMAIN.LOCAL with password + + + diff --git a/docs/system_libraries/krb5/tc_krb5_fun_008.yaml b/docs/system_libraries/krb5/tc_krb5_fun_008.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8bb8961b4e22d489c823b89ed045be382cbb0892 --- /dev/null +++ b/docs/system_libraries/krb5/tc_krb5_fun_008.yaml @@ -0,0 +1,72 @@ +作者: qintingting +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试krb5中续订票据有效期 +修改人: qintingting + +前置条件: +- 安装krb5-server、krb5-workstation、krb5-libs包 +- 配置/etc/krb5.conf +[logging] + default = FILE:/var/log/krb5libs.log + kdc = FILE:/var/log/krb5kdc.log + admin_server = FILE:/var/log/kadmind.log + +[libdefaults] + default_realm = MYDOMAIN.LOCAL + dns_lookup_realm = false + dns_lookup_kdc = false + ticket_lifetime = 24h + renew_lifetime = 7d + forwardable = true + +[realms] + MYDOMAIN.LOCAL = { + kdc = localhost + admin_server = localhost + } + +[domain_realm] + .mydomain.local = MYDOMAIN.LOCAL + mydomain.local = MYDOMAIN.LOCAL +- 配置/var/kerberos/krb5kdc/kdc.conf +[kdcdefaults] + kdc_ports = 88 + kdc_tcp_ports = 88 + +[realms] + MYDOMAIN.LOCAL = { + # master_key_type在现代Kerberos安装中通常是aes256-cts + master_key_type = aes256-cts + acl_file = /var/kerberos/krb5kdc/kadm5.acl + dict_file = /usr/share/dict/words + admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab + supported_enctypes = aes256-cts:normal aes128-cts:normal + max_renewable_life = 7d + default_principal_flags = +preauth +} +- 修改/var/kerberos/krb5kdc/kadm5.acl文件 +*/admin@MYDOMAIN.LOCAL * +- 初始化 kerberos 数据库,数据库密码为MYDOMAIN@123 +kdb5_util create -s -r MYDOMAIN.LOCAL +- 重启服务 +sudo systemctl restart krb5kdc.service + + +测试步骤: +- 执行kadmin.local addprinc -pw user@123 user创建 1 个用户 +- 执行kinit user获取TGT,并执行klist查看Valid starting时间 +- 执行kinit -R 'user@MYDOMAIN.LOCAL'继续续订 +- 再执行kinit user检查Valid starting是否发生变化 + +期望结果: +- 用户创建成功 +- 获取TGT成功 +- 命令执行成功 +- Valid starting的时间晚于之前的Valid starting时间 + + + diff --git a/docs/system_libraries/libcap-ng/tc_libcap-ng_fun_001.yaml b/docs/system_libraries/libcap-ng/tc_libcap-ng_fun_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5d9257ed3e13921ac65c9aede51369299977e404 --- /dev/null +++ b/docs/system_libraries/libcap-ng/tc_libcap-ng_fun_001.yaml @@ -0,0 +1,60 @@ +作者: hongfeng +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 使用libcap-ng库的api检查不同用户的权限 +修改人: hongfeng + +前置条件: +- 创建test01.c +#include +#include +#include +#include +#include +#include + +int main() { + if (capng_have_capability(CAPNG_EFFECTIVE, CAP_SETUID | CAP_SETGID) == CAPNG_NONE) { + printf("Process does not have effective CAP_SETUID and/or CAP_SETGID.\\n"); + } else { + printf("Process has effective CAP_SETUID and/or CAP_SETGID.\\n"); + } + + if (setuid(0)) { + printf("insufficient privilege to setuid.\\n"); + } + if (setgid(0)) { + printf("insufficient privilege to setgid.\\n"); + } + + capng_update(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED, CAP_SETUID | CAP_SETGID); + if (capng_apply(CAPNG_SELECT_BOTH) != 0) { + perror("capng_apply() failed"); + } + + if (capng_have_capability(CAPNG_EFFECTIVE, CAP_SETUID | CAP_SETGID) == CAPNG_NONE) { + printf("Process does not have effective CAP_SETUID and/or CAP_SETGID.\\n"); + } else { + printf("Process has effective CAP_SETUID and/or CAP_SETGID.\\n"); + } + + if (setuid(0)) { + printf("insufficient privilege to setuid.\\n"); + } + if (setgid(0)) { + printf("insufficient privilege to setgid.\\n"); + } +} +- 编译gcc -o test01 test01.c -lcap-ng +- 增加一个测试用户useradd test-user01 + +测试步骤: +- 执行./test01 +- 执行su test-user01 -c './test01' + +期望结果: +- 命令执行成功, 验证root用户有相应权限 +- 命令执行成功,验证测试用户没有相应权限 diff --git a/docs/system_libraries/libdnf/tc_libdnf_libdnf_func_001.yaml b/docs/system_libraries/libdnf/tc_libdnf_libdnf_func_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..80ecc6aa09c9dc80cf416a9f59b406331cc08ef6 --- /dev/null +++ b/docs/system_libraries/libdnf/tc_libdnf_libdnf_func_001.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: libdnf获取当前DNF上下文中所有软件包仓库的列表的基本功能 +修改人: suomengjun + +前置条件: +- 安装gcc,libdnf,libdnf-devel +- 仓库根路径下生成文件test_libdnf_dnf_context_get_repos.c +- 执行编译命令:gcc -o test_libdnf_dnf_context_get_repos test_libdnf_dnf_context_get_repos.c `pkg-config --cflags --libs libdnf glib-2.0 gobject-2.0` + +测试步骤: +- 仓库根路径下执行./test_libdnf_dnf_context_get_repos + +期望结果: +- 所有软件包仓库的列表信息获取成功,命令返回状态码为0 diff --git a/docs/system_libraries/libdnf/tc_libdnf_libdnf_func_002.yaml b/docs/system_libraries/libdnf/tc_libdnf_libdnf_func_002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..200d4afb5090b49e9b4e65d29cc399171b28c93c --- /dev/null +++ b/docs/system_libraries/libdnf/tc_libdnf_libdnf_func_002.yaml @@ -0,0 +1,20 @@ +作者: suomengjun +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: libdnf从配置文件获取系统的架构信息的基本功能 +修改人: suomengjun + +前置条件: +- 安装gcc,libdnf,libdnf-devel +- 仓库根路径下生成配置文件dnf002.conf +- 仓库根路径下生成文件test_dnf_context_get_arch.c +- 执行编译命令:gcc -o test_dnf_context_get_arch test_dnf_context_get_arch.c `pkg-config --cflags --libs libdnf gobject-2.0` + +测试步骤: +- 仓库根路径下执行./test_dnf_context_get_arch dnf002.conf + +期望结果: +- 系统的架构信息获取成功,命令返回状态码为0 diff --git a/docs/system_libraries/libdnf/tc_libdnf_libdnf_func_003.yaml b/docs/system_libraries/libdnf/tc_libdnf_libdnf_func_003.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7f541017b6e9e9b2a5c4bea3f68ece0113825928 --- /dev/null +++ b/docs/system_libraries/libdnf/tc_libdnf_libdnf_func_003.yaml @@ -0,0 +1,20 @@ +作者: suomengjun +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: libdnf解析配置,获取当前DNF上下文的仓库目录路径的基本功能 +修改人: suomengjun + +前置条件: +- 安装gcc,libdnf,libdnf-devel +- 仓库根路径下生成配置文件dnf003.conf +- 仓库根路径下生成文件test_dnf_context_get_repo_dir.c +- 执行编译命令:gcc -o test_dnf_context_get_repo_dir test_dnf_context_get_repo_dir.c `pkg-config --cflags --libs libdnf gobject-2.0` + +测试步骤: +- 仓库根路径下执行./test_dnf_context_get_repo_dir dnf003.conf + +期望结果: +- 仓库目录路径获取成功,命令返回状态码为0 diff --git a/docs/system_libraries/libdnf/tc_libdnf_libdnf_func_004.yaml b/docs/system_libraries/libdnf/tc_libdnf_libdnf_func_004.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5044d7ca8def5893c02b4c4662001c1ce969a114 --- /dev/null +++ b/docs/system_libraries/libdnf/tc_libdnf_libdnf_func_004.yaml @@ -0,0 +1,20 @@ +作者: suomengjun +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: libdnf解析配置,获取当前DNF上下文的系统发行版版本 +修改人: suomengjun + +前置条件: +- 安装gcc,libdnf,libdnf-devel +- 仓库根路径下生成配置文件dnf004.conf +- 仓库根路径下生成文件test_dnf_context_get_release_ver.c +- 执行编译命令:gcc -o test_dnf_context_get_release_ver test_dnf_context_get_release_ver.c `pkg-config --cflags --libs libdnf gobject-2.0` + +测试步骤: +- 仓库根路径下执行./test_dnf_context_get_release_ver dnf004.conf + +期望结果: +- 获取当前DNF上下文的系统发行版版本成功,命令返回状态码为0 diff --git a/docs/system_libraries/libdnf/tc_libdnf_libdnf_func_005.yaml b/docs/system_libraries/libdnf/tc_libdnf_libdnf_func_005.yaml new file mode 100644 index 0000000000000000000000000000000000000000..48ae41fde03f3cbef9a15f38c42e7f00b69d33e9 --- /dev/null +++ b/docs/system_libraries/libdnf/tc_libdnf_libdnf_func_005.yaml @@ -0,0 +1,20 @@ +作者: suomengjun +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: libdnf解析配置,获取当前DNF上下文的平台的模块信息 +修改人: suomengjun + +前置条件: +- 安装gcc,libdnf,libdnf-devel +- 仓库根路径下生成配置文件dnf005.conf +- 仓库根路径下生成文件test_dnf_context_get_platform_module.c +- 执行编译命令:gcc -o test_dnf_context_get_platform_module test_dnf_context_get_platform_module.c `pkg-config --cflags --libs libdnf gobject-2.0` + +测试步骤: +- 仓库根路径下执行./test_dnf_context_get_platform_module dnf005.conf + +期望结果: +- 获取当前DNF上下文的平台的模块信息成功,命令返回状态码为0 diff --git a/docs/system_libraries/libdnf/tc_libdnf_libdnf_func_006.yaml b/docs/system_libraries/libdnf/tc_libdnf_libdnf_func_006.yaml new file mode 100644 index 0000000000000000000000000000000000000000..fdffd95d8bd9ba77d27ef7e11e55750841740e19 --- /dev/null +++ b/docs/system_libraries/libdnf/tc_libdnf_libdnf_func_006.yaml @@ -0,0 +1,20 @@ +作者: suomengjun +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: libdnf解析配置,获取当前DNF上下文的RPM verbosity信息 +修改人: suomengjun + +前置条件: +- 安装gcc,libdnf,libdnf-devel +- 仓库根路径下生成配置文件dnf006.conf +- 仓库根路径下生成文件test_dnf_context_get_rpm_verbosity.c +- 执行编译命令:gcc -o test_dnf_context_get_rpm_verbosity test_dnf_context_get_rpm_verbosity.c `pkg-config --cflags --libs libdnf gobject-2.0` + +测试步骤: +- 仓库根路径下执行./test_dnf_context_get_rpm_verbosity dnf006.conf + +期望结果: +- 获取当前DNF上下文的RPM verbosity信息成功,命令返回状态码为0 diff --git a/docs/system_libraries/libdnf/tc_libdnf_libdnf_func_007.yaml b/docs/system_libraries/libdnf/tc_libdnf_libdnf_func_007.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8b365474a3f27b4c4286e31e953d3fc09f0f49c5 --- /dev/null +++ b/docs/system_libraries/libdnf/tc_libdnf_libdnf_func_007.yaml @@ -0,0 +1,20 @@ +作者: suomengjun +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: libdnf解析配置,检索当前DNF上下文使用的安装根目录的路径 +修改人: suomengjun + +前置条件: +- 安装gcc,libdnf,libdnf-devel +- 仓库根路径下生成配置文件dnf007.conf +- 仓库根路径下生成文件test_dnf_context_get_install_root.c +- 执行编译命令:gcc -o test_dnf_context_get_install_root test_dnf_context_get_install_root.c `pkg-config --cflags --libs libdnf gobject-2.0` + +测试步骤: +- 仓库根路径下执行./test_dnf_context_get_install_root dnf007.conf + +期望结果: +- 检索当前DNF上下文使用的安装根目录的路径成功,命令返回状态码为0 diff --git a/docs/system_libraries/libdnf/tc_libdnf_libdnf_func_008.yaml b/docs/system_libraries/libdnf/tc_libdnf_libdnf_func_008.yaml new file mode 100644 index 0000000000000000000000000000000000000000..fb834c290eb7e16683d0ab407bf637903bf3fa41 --- /dev/null +++ b/docs/system_libraries/libdnf/tc_libdnf_libdnf_func_008.yaml @@ -0,0 +1,20 @@ +作者: suomengjun +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: libdnf解析配置,检索当前DNF上下文使用的http代理 +修改人: suomengjun + +前置条件: +- 安装gcc,libdnf,libdnf-devel +- 仓库根路径下生成配置文件dnf008.conf +- 仓库根路径下生成文件test_dnf_context_get_http_proxy.c +- 执行编译命令:gcc -o test_dnf_context_get_http_proxy test_dnf_context_get_http_proxy.c `pkg-config --cflags --libs libdnf gobject-2.0` + +测试步骤: +- 仓库根路径下执行./test_dnf_context_get_http_proxy dnf008.conf + +期望结果: +- 检索当前DNF上下文使用的http代理成功,命令返回状态码为0 diff --git a/docs/system_libraries/libdnf/tc_libdnf_libdnf_func_009.yaml b/docs/system_libraries/libdnf/tc_libdnf_libdnf_func_009.yaml new file mode 100644 index 0000000000000000000000000000000000000000..39db6c87accdfd314f1ebb9d47af10a71d3885b3 --- /dev/null +++ b/docs/system_libraries/libdnf/tc_libdnf_libdnf_func_009.yaml @@ -0,0 +1,20 @@ +作者: suomengjun +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: libdnf解析配置,获取DNF上下文的元数据缓存的年龄 +修改人: suomengjun + +前置条件: +- 安装gcc,libdnf,libdnf-devel +- 仓库根路径下生成配置文件dnf009.conf +- 仓库根路径下生成文件test_dnf_context_get_cache_age.c +- 执行编译命令:gcc -o test_dnf_context_get_cache_age test_dnf_context_get_cache_age.c `pkg-config --cflags --libs libdnf gobject-2.0` + +测试步骤: +- 仓库根路径下执行./test_dnf_context_get_cache_age dnf009.conf + +期望结果: +- 获取DNF上下文的元数据缓存的年龄成功,命令返回状态码为0 diff --git a/docs/system_libraries/libdnf/tc_libdnf_libdnf_func_010.yaml b/docs/system_libraries/libdnf/tc_libdnf_libdnf_func_010.yaml new file mode 100644 index 0000000000000000000000000000000000000000..06be5a5a82ccd8f434c2e7eba47a55877aa5cbfe --- /dev/null +++ b/docs/system_libraries/libdnf/tc_libdnf_libdnf_func_010.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: libdnf解析配置,获取DNF上下文的元数据arch信息 +修改人: suomengjun + +前置条件: +- 安装gcc,libdnf,libdnf-devel +- 仓库根路径下生成文件test_dnf_package_get_arch.c +- 执行编译命令:gcc -o test_dnf_package_get_arch test_dnf_package_get_arch.c `pkg-config --cflags --libs libdnf gobject-2.0` + +测试步骤: +- 仓库根路径下执行./test_dnf_package_get_arch make + +期望结果: +- 获取DNF上下文的元数据arch信息成功,命令返回状态码为0 diff --git a/docs/system_libraries/libedit/tc_libedit_libedit_func_002.yaml b/docs/system_libraries/libedit/tc_libedit_libedit_func_002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5e4b4bd83a49b97ca0f49e00180bf7ea07eebcf8 --- /dev/null +++ b/docs/system_libraries/libedit/tc_libedit_libedit_func_002.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libedit读取输入的文本的基本功能 +修改人: suomengjun + +前置条件: +- 安装gcc,libedit,libedit-devel +- 仓库根路径下生成文件test_libedit_readline.c +- 执行编译命令:gcc -o test_libedit_readline test_libedit_readline.c -ledit + +测试步骤: +- 仓库根路径下执行echo hello |./test_libedit_readline + +期望结果: +- 读取文本成功,正常输出读取到的内容,命令返回状态码为0 diff --git a/docs/system_libraries/libedit/tc_libedit_libedit_func_003.yaml b/docs/system_libraries/libedit/tc_libedit_libedit_func_003.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f1a6725484fe064c2611ef938301d5664ca6076e --- /dev/null +++ b/docs/system_libraries/libedit/tc_libedit_libedit_func_003.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libedit从编辑行接口获取输入的一行文本 +修改人: suomengjun + +前置条件: +- 安装gcc,libedit,libedit-devel +- 仓库根路径下生成文件test_libedit_el_gets.c +- 执行编译命令:gcc -o test_libedit_el_gets test_libedit_el_gets.c -ledit + +测试步骤: +- 仓库根路径下执行echo abcde| ./test_libedit_el_gets + +期望结果: +- 正常获取并输出输入的文本,命令返回状态码为0 diff --git a/docs/system_libraries/libedit/tc_libedit_libedit_func_004.yaml b/docs/system_libraries/libedit/tc_libedit_libedit_func_004.yaml new file mode 100644 index 0000000000000000000000000000000000000000..aa625fceb2c6b2744c0fe3688e0cc9227082c0e5 --- /dev/null +++ b/docs/system_libraries/libedit/tc_libedit_libedit_func_004.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libedit模拟用户的键入动作的基本功能 +修改人: suomengjun + +前置条件: +- 安装gcc,libedit,libedit-devel +- 仓库根路径下生成文件test_libedit_el_push.c +- 执行编译命令:gcc -o test_libedit_el_push test_libedit_el_push.c -ledit + +测试步骤: +- 仓库根路径下执行./test_libedit_el_push 'hello world' + +期望结果: +- 正常输出键入的操作,命令返回状态码为0 diff --git a/docs/system_libraries/libedit/tc_libedit_libedit_func_005.yaml b/docs/system_libraries/libedit/tc_libedit_libedit_func_005.yaml new file mode 100644 index 0000000000000000000000000000000000000000..cf6ce8d5adc20905218905ce30a6bb110d6c1f7d --- /dev/null +++ b/docs/system_libraries/libedit/tc_libedit_libedit_func_005.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libedit从编辑行中插入字符的功能 +修改人: suomengjun + +前置条件: +- 安装gcc,libedit,libedit-devel +- 仓库根路径下生成文件test_libedit_el_insertstr.c +- 执行编译命令:gcc -o test_libedit_el_insertstr test_libedit_el_insertstr.c -ledit + +测试步骤: +- 仓库根路径下执行echo 11111111 | ./test_libedit_el_insertstr + +期望结果: +- 插入字符操作无异常,正常输出插入的字符,命令返回状态码为0 diff --git a/docs/system_libraries/libedit/tc_libedit_libedit_func_006.yaml b/docs/system_libraries/libedit/tc_libedit_libedit_func_006.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2d23889d484ebdf6e3ed1fe853ebb2070c5a3447 --- /dev/null +++ b/docs/system_libraries/libedit/tc_libedit_libedit_func_006.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libedit删除编辑缓冲区中的字符的功能 +修改人: suomengjun + +前置条件: +- 安装gcc,libedit,libedit-devel +- 仓库根路径下生成文件test_libedit_el_deletestr.c +- 执行编译命令:gcc -o test_libedit_el_deletestr test_libedit_el_deletestr.c -ledit + +测试步骤: +- 仓库根路径下执行echo -e '11111111\n' | ./test_libedit_el_deletestr + +期望结果: +- 删除字符操作无异常,命令返回状态码为0 diff --git a/docs/system_libraries/libedit/tc_libedit_libedit_func_007.yaml b/docs/system_libraries/libedit/tc_libedit_libedit_func_007.yaml new file mode 100644 index 0000000000000000000000000000000000000000..49f1953a24d2d01c8fb89a870399a461f42396ce --- /dev/null +++ b/docs/system_libraries/libedit/tc_libedit_libedit_func_007.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libedit处理宽字符字符串的功能 +修改人: suomengjun + +前置条件: +- 安装gcc,libedit,libedit-devel +- 仓库根路径下生成文件test_libedit_el_wgets.c +- 执行编译命令:gcc -o test_libedit_el_wgets test_libedit_el_wgets.c -ledit + +测试步骤: +- 仓库根路径下执行echo -e '1\n2\n3\n4\n5\n6' | ./test_libedit_el_wgets + +期望结果: +- 正常输出宽字符串的每一个字符,命令返回状态码为0 diff --git a/docs/system_libraries/libedit/tc_libedit_libedit_func_008.yaml b/docs/system_libraries/libedit/tc_libedit_libedit_func_008.yaml new file mode 100644 index 0000000000000000000000000000000000000000..80abe4e55263fe094e5ad18a787ddf5c1af54362 --- /dev/null +++ b/docs/system_libraries/libedit/tc_libedit_libedit_func_008.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libedit将命令压入缓冲区的基本功能 +修改人: suomengjun + +前置条件: +- 安装gcc,libedit,libedit-devel +- 仓库根路径下生成文件test_libedit_el_wpush.c +- 执行编译命令:gcc -o test_libedit_el_wpush test_libedit_el_wpush.c -ledit + +测试步骤: +- 仓库根路径下执行echo -e '0123456789abcdefghijklmnopqrstuvwxyz' | ./test_libedit_el_wpush + +期望结果: +- 压入缓冲区操作无异常,输入内容可以被正常输出,命令返回状态码为0 diff --git a/docs/system_libraries/libedit/tc_libedit_libedit_func_009.yaml b/docs/system_libraries/libedit/tc_libedit_libedit_func_009.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5e8782f9372f30fff39a185b394649eaca3bb1eb --- /dev/null +++ b/docs/system_libraries/libedit/tc_libedit_libedit_func_009.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libedit从EditLine缓冲区检索当前行信息的基本功能 +修改人: suomengjun + +前置条件: +- 安装gcc,libedit,libedit-devel +- 仓库根路径下生成文件test_libedit_el_wline.c +- 执行编译命令:gcc -o test_libedit_el_wline test_libedit_el_wline.c -ledit + +测试步骤: +- 仓库根路径下执行echo -e '0123456789abcdefghijklmnopqrstuvwxyz' | ./test_libedit_el_wline + +期望结果: +- 从EditLine缓冲区检索当前行信息无异常,输入内容可以被正常输出,命令返回状态码为0 diff --git a/docs/system_libraries/libevent/tc_libevent_func001.yaml b/docs/system_libraries/libevent/tc_libevent_func001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..630cdfd71080bae3e368d2b9d3bc128cc6b13430 --- /dev/null +++ b/docs/system_libraries/libevent/tc_libevent_func001.yaml @@ -0,0 +1,43 @@ +作者: gaohongmei +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: libenevt库创建定时器事件 +修改人: gaohongmei + +前置条件: +- 创建test_libenevt.c脚本,设置简单的定时器事件,设置一段时间间隔后触发回调函数。 +#include +#include +#include + +static void timer_cb(evutil_socket_t fd, short what, void *arg) { + printf("Timer event triggered.\\n"); + event_base_loopbreak((struct event_base*)arg); +} + +int main() { + struct event_base *base = event_base_new(); + struct event *timer = event_new(base, -1, 0, timer_cb, base); + struct timeval tv = { .tv_sec = 1, .tv_usec = 0 }; // 1秒后触发 + + if (event_add(timer, &tv) == -1) { + perror("event_add"); + return 1; + } + + event_base_dispatch(base); + event_free(timer); + event_base_free(base); + return 0; +} + +测试步骤: +- 执行命令`gcc -o /tmp/ghm/test_libenevt /tmp/ghm/test_libenevt.c -levent -lpthread`,编译脚本 +- 执行命令`/tmp/ghm/test_libenevt` + +期望结果: +- 命令执行成功,生成/tmp/ghm/test_libenevt脚本 +- 命令执行成功,返回内容Timer event triggered. \ No newline at end of file diff --git a/docs/system_libraries/libgcrypt/tc_libgcrypt_fun_001.yaml b/docs/system_libraries/libgcrypt/tc_libgcrypt_fun_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ec7faad82055805e21cc56eeab636e37323b575d --- /dev/null +++ b/docs/system_libraries/libgcrypt/tc_libgcrypt_fun_001.yaml @@ -0,0 +1,153 @@ +作者: hongfeng +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 使用libgcrypt库的AES256算法加密/解密一个字符串,验证解密的结果 +修改人: hongfeng + +前置条件: +- 创建aes.c +#include +#include +#include + +#define CIPHER_ALGO GCRY_CIPHER_AES256 // 使用AES-256算法 + +void aes_encrypt(const char *plaintext, const char *key, const char *iv, char **ciphertext) { + gcry_error_t err; + gcry_cipher_hd_t hd; + + // 初始化加密上下文 + err = gcry_cipher_open(&hd, CIPHER_ALGO, GCRY_CIPHER_MODE_CBC, 0); + if (err != GPG_ERR_NO_ERROR) { + fprintf(stderr, "Error opening cipher: %s\\n", gcry_strerror(err)); + exit(1); + } + + // 设置密钥和初始化向量 + err = gcry_cipher_setkey(hd, key, 32); + if (err != GPG_ERR_NO_ERROR) { + fprintf(stderr, "Error setting key: %s\\n", gcry_strerror(err)); + gcry_cipher_close(hd); + exit(1); + } + err = gcry_cipher_setiv(hd, iv, 16); + if (err != GPG_ERR_NO_ERROR) { + fprintf(stderr, "Error setting IV: %s\\n", gcry_strerror(err)); + gcry_cipher_close(hd); + exit(1); + } + + // 确保数据长度是块大小的整数倍,并为最后一块添加必要的填充 + size_t plaintext_len = strlen(plaintext); + size_t block_size = gcry_cipher_get_algo_blklen(CIPHER_ALGO); + size_t last_block_size = strlen(plaintext) % block_size; + if (last_block_size > 0) { + // 需要填充到下一个完整块 + plaintext_len += block_size - last_block_size; + } + *ciphertext = malloc(plaintext_len + 1); + + /* 执行加密 */ + err = gcry_cipher_encrypt(hd, *ciphertext, plaintext_len, plaintext, plaintext_len); + if (err != GPG_ERR_NO_ERROR) { + fprintf(stderr, "Error encrypting %s\\n", gcry_strerror(err)); + free(*ciphertext); + gcry_cipher_close(hd); + exit(1); + } + + // 添加NULL终止符 + (*ciphertext)[plaintext_len] = '\\0'; + gcry_cipher_close(hd); +} + +void aes_decrypt(const char *ciphertext, const char *key, const char *iv, char **plaintext) { + gcry_error_t err; + gcry_cipher_hd_t hd; + + // 初始化加密上下文 + err = gcry_cipher_open(&hd, CIPHER_ALGO, GCRY_CIPHER_MODE_CBC, 0); + if (err != GPG_ERR_NO_ERROR) { + fprintf(stderr, "Error opening cipher for decryption: %s\\n", gcry_strerror(err)); + exit(1); + } + + // 设置密钥和初始化向量 + err = gcry_cipher_setkey(hd, key, 32); + if (err != GPG_ERR_NO_ERROR) { + fprintf(stderr, "Error setting decryption key: %s\\n", gcry_strerror(err)); + gcry_cipher_close(hd); + exit(1); + } + err = gcry_cipher_setiv(hd, iv, 16); + if (err != GPG_ERR_NO_ERROR) { + fprintf(stderr, "Error setting decryption IV: %s\\n", gcry_strerror(err)); + gcry_cipher_close(hd); + exit(1); + + } + + // 解密操作需要与加密相同的缓冲区长度 + size_t plaintext_len = strlen(ciphertext); + // 额外空间存放NULL终止符 + *plaintext = malloc(plaintext_len + 1); + + // 执行解密 + err = gcry_cipher_decrypt(hd, *plaintext, plaintext_len, ciphertext, plaintext_len); + if (err != GPG_ERR_NO_ERROR) { + fprintf(stderr, "Error decrypting %s\\n", gcry_strerror(err)); + free(*plaintext); + gcry_cipher_close(hd); + exit(1); + } + + // 添加NULL终止符 + (*plaintext)[plaintext_len] = '\\0'; + gcry_cipher_close(hd); +} + +int main(int argc, char *argv[]) { + if (argc != 2) { + fprintf(stderr, "Usage: %s \\n", argv[0]); + return 1; + } + + char key[32] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, + 0xed, 0xa3, 0xeb, 0xf4, 0xa1, 0x7b, 0x4a, 0x31, + 0xc9, 0x47, 0xae, 0x53, 0x7b, 0x39, 0x31, 0x0 + }; + char iv[16] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x0 + }; + + char *encrypted_text = NULL; + char *decrypted_text = NULL; + + size_t arg_length = strlen(argv[1]) + 1; + char plaintext[arg_length]; + strcpy(plaintext, argv[1]); + + aes_encrypt(plaintext, key, iv, &encrypted_text); + printf("Encrypted Text: %02X\\n", encrypted_text); + + aes_decrypt(encrypted_text, key, iv, &decrypted_text); + printf("Decrypted Text: %s\\n", decrypted_text); + + free(encrypted_text); + free(decrypted_text); + + return 0; +} +- 编译gcc -o aes aes.c `libgcrypt-config --cflags --libs` + +测试步骤: +- 执行./aes 'This is a test message for ace256!' + +期望结果: +- 命令执行成功,检查加密/解密后的字符串就是原来的内容 diff --git a/docs/system_libraries/libgcrypt/tc_libgcrypt_fun_002.yaml b/docs/system_libraries/libgcrypt/tc_libgcrypt_fun_002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1d9698a2a19cbfef10502fbdf01bdb005be50060 --- /dev/null +++ b/docs/system_libraries/libgcrypt/tc_libgcrypt_fun_002.yaml @@ -0,0 +1,89 @@ +作者: hongfeng +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 使用libgcrypt库的SHA-256算法对一个字符串进行哈希,验证哈希的结果 +修改人: hongfeng + +前置条件: +- 创建hash_sha256.c +#include +#include +#include + +#define BUFFER_SIZE 1024 + +void hexlify(char* dest, const void* src, size_t src_len) { + static const char hexdigits[] = "0123456789abcdef"; + for (size_t i = 0; i < src_len; ++i) { + unsigned char byte = ((unsigned char*)src)[i]; + dest[i * 2 + 1] = hexdigits[byte & 0x0F]; + } + // 添加终止符 + dest[src_len * 2] = '\\0'; +} + +void test_hash_function(const char *message, const char *algo_name) { + gcry_error_t err; + gcry_md_hd_t hd; + unsigned char hash[gcry_md_get_algo_dlen(GCRY_MD_SHA256)]; + char computed_hash_hex[BUFFER_SIZE]; + + // 初始化 libgcrypt + if (!gcry_check_version(NULL)) { + fprintf(stderr, "Error: libgcrypt not initialized properly\\n"); + return; + } + + // 设置哈希算法 + err = gcry_md_open(&hd, algo_name, 0); + if (err != GPG_ERR_NO_ERROR) { + fprintf(stderr, "Error setting up %s: %s\\n", algo_name, gcry_strerror(err)); + return; + } + + // 计算哈希值 + gcry_md_write(hd, message, strlen(message)); + + // 获取哈希结果 + gcry_md_final(hd); + // 对于SHA-256,使用这个长度 + memcpy(hash, gcry_md_read(hd, 0), gcry_md_get_algo_dlen(GCRY_MD_SHA256)); + + // 打印哈希结果 + char hex_digest[2 * gcry_md_get_algo_dlen(GCRY_MD_SHA256) + 1]; + for (size_t i = 0; i < gcry_md_get_algo_dlen(GCRY_MD_SHA256); ++i) { + snprintf(hex_digest + 2*i, 3, "%02x", hash[i]); + } + // 添加终止符 + hex_digest[2 * gcry_md_get_algo_dlen(GCRY_MD_SHA256)] = '\\0'; + printf("%s\\n", hex_digest); + + // 清理资源 + gcry_md_close(hd); +} + +int main(int argc, char *argv[]) { + if (argc != 2) { + fprintf(stderr, "Usage: %s \\n", argv[0]); + return 1; + } + + size_t arg_length = strlen(argv[1]) + 1; + char test_string[arg_length]; + strcpy(test_string, argv[1]); + + // 测试SHA-256 + test_hash_function(test_string, GCRY_MD_SHA256); + + return 0; +} +- 编译gcc -o hash_sha256 hash_sha256.c `libgcrypt-config --cflags --libs` + +测试步骤: +- 执行./hash_sha256 'This is a test message.' + +期望结果: +- 命令执行成功,检查哈希结果符合预期 diff --git a/docs/system_libraries/libgcrypt/tc_libgcrypt_fun_003.yaml b/docs/system_libraries/libgcrypt/tc_libgcrypt_fun_003.yaml new file mode 100644 index 0000000000000000000000000000000000000000..15e6e98751fc76b30751942449270a334836d603 --- /dev/null +++ b/docs/system_libraries/libgcrypt/tc_libgcrypt_fun_003.yaml @@ -0,0 +1,45 @@ +作者: hongfeng +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 使用libgcrypt库的随机函数生成随机数据 +修改人: hongfeng + +前置条件: +- 创建random.c +#include +#include +#include +#include + +int main() { + // 初始化Libgcrypt + if (!gcry_check_version(NULL)) { + fprintf(stderr, "Error: libgcrypt version check failed\\n"); + return 1; + } + gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); + + // 定义一个缓冲区来存放随机数据 + unsigned char random_data[32]; + + // 使用GCRY_VERY_STRONG_RANDOM作为随机质量级别 + gcry_randomize(random_data, sizeof(random_data), GCRY_STRONG_RANDOM); + + // 成功生成随机数据,将其打印出来(这里转换为十六进制以便阅读) + for (size_t i = 0; i < sizeof(random_data); ++i) { + printf("%02X", random_data[i]); + } + printf("\\n"); + + return 0; +} +- 编译gcc -o random random.c `libgcrypt-config --cflags --libs` + +测试步骤: +- 执行./random 3次 + +期望结果: +- 命令执行成功,验证3次的内容不同 diff --git a/docs/system_libraries/libgpg-error/tc_libgpg-error_fun_001.yaml b/docs/system_libraries/libgpg-error/tc_libgpg-error_fun_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..bfa44bf046b138d6a3f81bcc5c9d4a03c29be8b7 --- /dev/null +++ b/docs/system_libraries/libgpg-error/tc_libgpg-error_fun_001.yaml @@ -0,0 +1,39 @@ +作者: hongfeng +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 使用libgpg-error库的api调用检查返回的错误代码 +修改人: hongfeng + +前置条件: +- 创建test01.c +#include +#include + +int main() { + // 使用实际API调用返回的错误代码 + gpg_error_t err = gpg_error(GPG_ERR_GENERAL); + + const char *msg = gpg_strerror(err); + const char *src = gpg_strsource(err); + + printf("Error message: %s\\n", msg); + printf("Error source: %s\\n", src); + + gpg_error_t base_err = gpg_error(GPG_ERR_GENERAL); + gpg_error_t wrapped_err = gpg_err_make(GPG_ERR_SOURCE_USER_1, base_err); + + // 验证错误代码未变 + assert(gpg_err_code(wrapped_err) == base_err); + // 验证来源已更改为USER_1 + assert(gpg_err_source(wrapped_err) == GPG_ERR_SOURCE_USER_1); +} +- 编译gcc -o test01 test01.c -lgpg-error + +测试步骤: +- 执行./test01 + +期望结果: +- 命令执行成功 diff --git a/docs/system_libraries/libgpg-error/tc_libgpg-error_fun_002.yaml b/docs/system_libraries/libgpg-error/tc_libgpg-error_fun_002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..23fd3ee183f4c19af128bfdad5b4d339204b27a9 --- /dev/null +++ b/docs/system_libraries/libgpg-error/tc_libgpg-error_fun_002.yaml @@ -0,0 +1,32 @@ +作者: hongfeng +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 使用libgpg-error库的api验证libgcrypt的错误代码 +修改人: hongfeng + +前置条件: +- 创建test02.c +#include +#include +#include + +#define CIPHER_ALGO GCRY_CIPHER_AES256 // 使用AES-256算法 + +int main() { + gcry_cipher_hd_t hd; + gcry_error_t gpg_err; + + // 没有指定cipher algorithm + gpg_err = gcry_cipher_open(&hd, NULL, GCRY_CIPHER_MODE_CBC, 200); + printf("%s\\n", gpg_strerror(gpg_err)); +} +- 编译gcc -o test02 test02.c -lgpg-error -lgcrypt + +测试步骤: +- 执行./test02 + +期望结果: +- 命令执行成功,验证输出信息符合预期 diff --git a/docs/system_libraries/libgpg-error/tc_libgpg-error_fun_003.yaml b/docs/system_libraries/libgpg-error/tc_libgpg-error_fun_003.yaml new file mode 100644 index 0000000000000000000000000000000000000000..96859df3fbb952d66e376b9c65b6cd4a45dd2993 --- /dev/null +++ b/docs/system_libraries/libgpg-error/tc_libgpg-error_fun_003.yaml @@ -0,0 +1,50 @@ +作者: hongfeng +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 使用libgpg-error库的api验证自定义错误代码 +修改人: hongfeng + +前置条件: +- 创建test03.c +#include +#include +#include +#include + +int main(void) { + // 自定义error代码 + int custom_error_code = 5; + // 自定义error来源 + gpg_err_source_t custom_error_source = GPG_ERR_SOURCE_USER_1; + + // 使用gpg_err_make()创建gpg_error_t. + gpg_error_t custom_gpg_error = gpg_err_make(custom_error_source, custom_error_code); + + printf("Custom gpg_error_t value: %lu\\n", (unsigned long) custom_gpg_error); + + // Extract the error source from the custom gpg_error_t value. + gpg_err_source_t extracted_error_source = gpg_err_source(custom_gpg_error); + gpg_err_code_t extracted_error_code = gpg_err_code(custom_gpg_error); + + printf("Extracted error source: %d\\n", extracted_error_source); + printf("Extracted error source: %d\\n", extracted_error_code); + + // Compare the original and extracted error sources. + if (custom_error_source == extracted_error_source) { + printf("Error source extraction successful.\\n"); + } else { + printf("Error source extraction failed.\\n"); + } + + return 0; +} +- 编译gcc -o test03 test03.c -lgpg-error + +测试步骤: +- 执行./test03 + +期望结果: +- 命令执行成功,验证输出信息符合预期 diff --git a/docs/system_libraries/libldb/tc_libldb_libldb_func_001.yaml b/docs/system_libraries/libldb/tc_libldb_libldb_func_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c2d4d65d0898d78923f423fcd74df67411c6a4d7 --- /dev/null +++ b/docs/system_libraries/libldb/tc_libldb_libldb_func_001.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: libldb包base64解码功能 +修改人: suomengjun + +前置条件: +- 安装gcc,libldb,libldb-devel +- 仓库根路径下生成test_libldb_ldb_base64_decode.c +- 执行编译命令:gcc -o test_libldb_ldb_base64_decode test_libldb_ldb_base64_decode.c -lldb + +测试步骤: +- 仓库根路径下执行./test_libldb_ldb_base64_decode cm9vdAo= + +期望结果: +- base64编码cm9vdAo=被成功解码为root字符串,命令返回状态码为0 diff --git a/docs/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_002.yaml b/docs/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5faecc8d8ab95f6d0c30bbfd74d190cd20f32939 --- /dev/null +++ b/docs/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_002.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libmodulemd操作YAML格式模块元数据,检索模块流中组件的名称的基本功能 +修改人: suomengjun + +前置条件: +- 安装gcc,libmodulemd,libmodulemd-devel +- 仓库根路径下生成文件libmodulemd_modulemd_component_get_name.c +- 执行编译命令:gcc -o libmodulemd_modulemd_component_get_name libmodulemd_modulemd_component_get_name.c `pkg-config --cflags --libs modulemd-2.0 glib-2.0` + +测试步骤: +- 仓库根路径下执行./libmodulemd_modulemd_component_get_name component_name + +期望结果: +- 可以正常获取组件名,命令返回状态码为0 diff --git a/docs/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_003.yaml b/docs/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_003.yaml new file mode 100644 index 0000000000000000000000000000000000000000..82d495d04c485da1b1ada868857f097f792ca520 --- /dev/null +++ b/docs/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_003.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libmodulemd操作YAML格式模块元数据,检索两个ModulemdBuildConfig对象顺序的基本功能 +修改人: suomengjun + +前置条件: +- 安装gcc,libmodulemd,libmodulemd-devel +- 仓库根路径下生成文件libmodulemd_modulemd_build_config_compare.c +- 执行编译命令:gcc -o libmodulemd_modulemd_build_config_compare libmodulemd_modulemd_build_config_compare.c `pkg-config --cflags --libs modulemd-2.0 glib-2.0` + +测试步骤: +- 仓库根路径下执行./libmodulemd_modulemd_build_config_compare config1 config2 + +期望结果: +- 构建配置顺序是config1 < config2, 命令返回状态码为0 diff --git a/docs/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_004.yaml b/docs/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_004.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a562673f31194a297c8accc6c4b4fbe80606b527 --- /dev/null +++ b/docs/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_004.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libmodulemd操作YAML格式模块元数据,各种数据类型的验证的基本功能 +修改人: suomengjun + +前置条件: +- 安装gcc,libmodulemd,libmodulemd-devel +- 仓库根路径下生成文件libmodulemd_modulemd_build_config_validate.c +- 执行编译命令:gcc -o libmodulemd_modulemd_build_config_validate libmodulemd_modulemd_build_config_validate.c `pkg-config --cflags --libs modulemd-2.0 glib-2.0` + +测试步骤: +- 仓库根路径下执行./libmodulemd_modulemd_build_config_validate c0ffee42 f33 bash + +期望结果: +- 构建配置数据验证通过,命令返回状态码为0 diff --git a/docs/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_005.yaml b/docs/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_005.yaml new file mode 100644 index 0000000000000000000000000000000000000000..fb1043566e1bee968d7c170a354c1515439752ae --- /dev/null +++ b/docs/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_005.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libmodulemd操作YAML格式模块元数据,获取rpm宏的基本功能 +修改人: suomengjun + +前置条件: +- 安装gcc,libmodulemd,libmodulemd-devel +- 仓库根路径下生成文件libmodulemd_modulemd_buildopts_get_rpm_macros.c +- 执行编译命令:gcc -o libmodulemd_modulemd_buildopts_get_rpm_macros libmodulemd_modulemd_buildopts_get_rpm_macros.c `pkg-config --cflags --libs modulemd-2.0 glib-2.0` + +测试步骤: +- 仓库根路径下执行./libmodulemd_modulemd_buildopts_get_rpm_macros 'rpm -E %{getenv:HOME}' + +期望结果: +- 获取宏的值成功,命令返回状态码为0 diff --git a/docs/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_006.yaml b/docs/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_006.yaml new file mode 100644 index 0000000000000000000000000000000000000000..15857efacbd37343df0655e39fd5582ced14dd14 --- /dev/null +++ b/docs/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_006.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libmodulemd操作YAML格式模块元数据,检索被列入白名单以便在模块构建中包含的二进制RPM包名称列表的功能 +修改人: suomengjun + +前置条件: +- 安装gcc,libmodulemd,libmodulemd-devel +- 仓库根路径下生成文件libmodulemd_modulemd_buildopts_get_rpm_whitelist_as_strv.c +- 执行编译命令:gcc -o libmodulemd_modulemd_buildopts_get_rpm_whitelist_as_strv libmodulemd_modulemd_buildopts_get_rpm_whitelist_as_strv.c `pkg-config --cflags --libs modulemd-2.0 glib-2.0` + +测试步骤: +- 仓库根路径下执行./libmodulemd_modulemd_buildopts_get_rpm_whitelist_as_strv gcc make bash cmake + +期望结果: +- 添加白名单和获取白名单操作成功,命令返回状态码为0 diff --git a/docs/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_007.yaml b/docs/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_007.yaml new file mode 100644 index 0000000000000000000000000000000000000000..78cb204652dad7388618864aa3987da52b6cc99f --- /dev/null +++ b/docs/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_007.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libmodulemd操作YAML格式模块元数据,检索多架构的基本功能 +修改人: suomengjun + +前置条件: +- 安装gcc,libmodulemd,libmodulemd-devel +- 仓库根路径下生成文件libmodulemd_modulemd_buildopts_get_arches_as_strv.c +- 执行编译命令:gcc -o libmodulemd_modulemd_buildopts_get_arches_as_strv libmodulemd_modulemd_buildopts_get_arches_as_strv.c `pkg-config --cflags --libs modulemd-2.0 glib-2.0` + +测试步骤: +- 仓库根路径下执行 + +期望结果: +- 添加多架构和检索多架构的操作成功,命令返回状态码为0 diff --git a/docs/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_008.yaml b/docs/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_008.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d736cf7bfd044fdad9e4e26422c21801cd0ad0ea --- /dev/null +++ b/docs/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_008.yaml @@ -0,0 +1,20 @@ +作者: suomengjun +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libmodulemd操作YAML格式模块元数据,检索存储库名称的基本功能 +修改人: suomengjun + +前置条件: +- 安装gcc,libmodulemd,libmodulemd-devel +- 仓库根路径下生成文件libmodulemd_modulemd_component_rpm_get_repository.c +- 仓库根路径下生成配置文件gen_yaml_to_get_repos.yaml +- 执行编译命令:gcc -o libmodulemd_modulemd_component_rpm_get_repository libmodulemd_modulemd_component_rpm_get_repository.c `pkg-config --cflags --libs modulemd-2.0` + +测试步骤: +- 仓库根路径下执行./libmodulemd_modulemd_component_rpm_get_repository gen_yaml_to_get_repos.yaml mymodule mystream 1 c0ffee43 noarch + +期望结果: +- 检索存储库名称成功,命令返回状态码为0 diff --git a/docs/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_009.yaml b/docs/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_009.yaml new file mode 100644 index 0000000000000000000000000000000000000000..65927f1289f7e370a956c77fe750fe6b40fa0b4d --- /dev/null +++ b/docs/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_009.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libmodulemd操作YAML格式模块元数据,检索rpm构建根路径基本功能 +修改人: suomengjun + +前置条件: +- 安装gcc,libmodulemd,libmodulemd-devel +- 仓库根路径下生成文件libmodulemd_modulemd_component_rpm_get_srpm_buildroot.c +- 执行编译命令:gcc -o libmodulemd_modulemd_component_rpm_get_srpm_buildroot libmodulemd_modulemd_component_rpm_get_srpm_buildroot.c `pkg-config --cflags --libs modulemd-2.0 glib-2.0` + +测试步骤: +- 仓库根路径下执行./libmodulemd_modulemd_component_rpm_get_srpm_buildroot pkg true + +期望结果: +- 检索rpm构建根路径成功,命令返回状态码为0 diff --git a/docs/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_010.yaml b/docs/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_010.yaml new file mode 100644 index 0000000000000000000000000000000000000000..797f4dadedb5c0e698b0e40fc390f2010d20c8d5 --- /dev/null +++ b/docs/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_010.yaml @@ -0,0 +1,20 @@ +作者: suomengjun +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libmodulemd操作YAML格式模块元数据,检索模块名称基本功能 +修改人: suomengjun + +前置条件: +- 安装gcc,libmodulemd,libmodulemd-devel +- 仓库根路径下生成配置文件gen_yaml_to_get_module_name.yaml +- 仓库根路径下生成文件libmodulemd_modulemd_defaults_get_module_name.c +- 执行编译命令:gcc -o libmodulemd_modulemd_defaults_get_module_name libmodulemd_modulemd_defaults_get_module_name.c `pkg-config --cflags --libs modulemd-2.0 glib-2.0` + +测试步骤: +- 仓库根路径下执行./libmodulemd_modulemd_defaults_get_module_name gen_yaml_to_get_module_name.yaml + +期望结果: +- 检索模块名称成功,命令返回状态码为0 diff --git a/docs/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_011.yaml b/docs/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_011.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e06cb7aadefa6f742ca11bcd6097cb207b8596d1 --- /dev/null +++ b/docs/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_011.yaml @@ -0,0 +1,20 @@ +作者: suomengjun +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试libmodulemd操作YAML格式模块元数据,将配置的整个内容序列化(转换为字符串)为一个YAML字符串的基本功能 +修改人: suomengjun + +前置条件: +- 安装gcc,libmodulemd,libmodulemd-devel +- 仓库根路径下生成配置文件gen_yaml_to_get_content.yaml +- 仓库根路径下生成文件libmodulemd_modulemd_module_index_dump_to_string.c +- 执行编译命令:gcc -o libmodulemd_modulemd_module_index_dump_to_string libmodulemd_modulemd_module_index_dump_to_string.c `pkg-config --cflags --libs modulemd-2.0 glib-2.0` + +测试步骤: +- 仓库根路径下执行./libmodulemd_modulemd_module_index_dump_to_string gen_yaml_to_get_content.yaml + +期望结果: +- 将配置的整个内容序列化(转换为字符串)为一个YAML字符串操作成功,可以正常无乱码输出内容,命令返回状态码为0 diff --git a/docs/system_libraries/libndp/tc_libndp_libndp_func_001.yaml b/docs/system_libraries/libndp/tc_libndp_libndp_func_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..280ecb01a9feb4a8ea17a1f76faede4819748837 --- /dev/null +++ b/docs/system_libraries/libndp/tc_libndp_libndp_func_001.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 获取NDP日志优先级 +修改人: suomengjun + +前置条件: +- 安装gcc,libndp,libndp-devel +- 仓库根路径下生成test_libndp_ndp_get_log_priority.c +- 执行编译命令:gcc -o test_libndp_ndp_get_log_priority test_libndp_ndp_get_log_priority.c -lndp + +测试步骤: +- 仓库根路径下执行./test_libndp_ndp_get_log_priority 1 + +期望结果: +- 获取NDP日志优先级为3,命令返回状态码为0 diff --git a/docs/system_libraries/libndp/tc_libndp_libndp_func_002.yaml b/docs/system_libraries/libndp/tc_libndp_libndp_func_002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..865fb9967417a5968be064e50cc7fff588c7f800 --- /dev/null +++ b/docs/system_libraries/libndp/tc_libndp_libndp_func_002.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 从NDP消息中获取前缀有效时间 +修改人: suomengjun + +前置条件: +- 安装gcc,libndp,libndp-devel +- 仓库根路径下生成test_libndp_ndp_get_log_priority.c +- 执行编译命令:gcc -o test_libndp_ndp_msg_opt_prefix_valid_time test_libndp_ndp_get_log_priority.c -lndp + +测试步骤: +- 仓库根路径下执行./test_libndp_ndp_msg_opt_prefix_valid_time 134 16 + +期望结果: +- 成功从NDP消息中获取前缀有效时间,命令返回状态码为0 \ No newline at end of file diff --git a/docs/system_libraries/librepo/tc_librepo_librepo_func_001.yaml b/docs/system_libraries/librepo/tc_librepo_librepo_func_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..fcecf53e7941cc6f541a78133ff4e47ab80761e4 --- /dev/null +++ b/docs/system_libraries/librepo/tc_librepo_librepo_func_001.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: librepo从远端yum repo下载元数据 +修改人: suomengjun + +前置条件: +- 安装gcc,librepo,librepo-devel +- 仓库根路径下生成test_librepo_download_meta_data.c +- 执行编译命令:gcc -o test_librepo_download_meta_data test_librepo_download_meta_data.c `pkg-config --cflags --libs librepo glib-2.0` + +测试步骤: +- 仓库根路径下执行./test_librepo_download_meta_data https://mirrors.openanolis.cn/anolis/epao/23/{ARCH}/ /tmp/librepo/ #架构ARCH根据实际环境替换 + +期望结果: +- 下载元数据成功,命令返回状态码为0 diff --git a/docs/system_libraries/librepo/tc_librepo_librepo_func_002.yaml b/docs/system_libraries/librepo/tc_librepo_librepo_func_002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..74bf1623ea71b472657abffa0eb9e364132a68a3 --- /dev/null +++ b/docs/system_libraries/librepo/tc_librepo_librepo_func_002.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: librepo获取有关下载句柄(LrHandle)的信息 +修改人: suomengjun + +前置条件: +- 安装gcc,librepo,librepo-devel +- 仓库根路径下生成test_librepo_get_info.c +- 执行编译命令:gcc -o test_librepo_get_info test_librepo_get_info.c `pkg-config --cflags --libs librepo` + +测试步骤: +- 仓库根路径下执行./test_librepo_get_info https://mirrors.openanolis.cn/ + +期望结果: +- 获取LrHandle相关信息成功,命令返回状态码为0 diff --git a/docs/system_libraries/librepo/tc_librepo_librepo_func_003.yaml b/docs/system_libraries/librepo/tc_librepo_librepo_func_003.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0840e26e1088dbdf7667c73d983e832e5e5f13f9 --- /dev/null +++ b/docs/system_libraries/librepo/tc_librepo_librepo_func_003.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: librepo加载指定目录下的yum仓库配置 +修改人: suomengjun + +前置条件: +- 安装gcc,librepo,librepo-devel +- 仓库根路径下生成test_librepo_repoconfs_load_dir.c +- 执行编译命令:gcc -o test_librepo_repoconfs_load_dir test_librepo_repoconfs_load_dir.c `pkg-config --cflags --libs librepo` + +测试步骤: +- 仓库根路径下执行./test_librepo_repoconfs_load_dir /etc/yum.repos.d/ + +期望结果: +- 加载/etc/yum.repos.d/目录下的yum仓库配置成功,命令返回状态码为0 diff --git a/docs/system_libraries/librepo/tc_librepo_librepo_func_004.yaml b/docs/system_libraries/librepo/tc_librepo_librepo_func_004.yaml new file mode 100644 index 0000000000000000000000000000000000000000..fa6da844e6bb1c703bd4c17dd74d9f9c7018902c --- /dev/null +++ b/docs/system_libraries/librepo/tc_librepo_librepo_func_004.yaml @@ -0,0 +1,20 @@ +作者: suomengjun +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: librepo解析特定的YUM repo config +修改人: suomengjun + +前置条件: +- 安装gcc,librepo,librepo-devel +- 仓库根路径下生成特定的YUM repo config, repoconf.repo +- 仓库根路径下生成test_librepo_repoconfs_parse.c +- 执行编译命令:gcc -o test_librepo_repoconfs_parse test_librepo_repoconfs_parse.c `pkg-config --cflags --libs librepo` + +测试步骤: +- 仓库根路径下执行./test_librepo_repoconfs_parse repoconf.repo + +期望结果: +- 解析repoconf.repo成功,命令返回状态码为0 diff --git a/docs/system_libraries/librepo/tc_librepo_librepo_func_005.yaml b/docs/system_libraries/librepo/tc_librepo_librepo_func_005.yaml new file mode 100644 index 0000000000000000000000000000000000000000..503f35e64719d77195591e098d3e88f199b33309 --- /dev/null +++ b/docs/system_libraries/librepo/tc_librepo_librepo_func_005.yaml @@ -0,0 +1,20 @@ +作者: suomengjun +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: librepo解析YUM/DNF存储库中的元数据repomd.xml +修改人: suomengjun + +前置条件: +- 安装gcc,librepo,librepo-devel +- 仓库根路径下生成配置文件repomd_005.xml +- 仓库根路径下生成test_librepo_repomd_parse_file.c +- 执行编译命令:gcc -o test_librepo_repomd_parse_file test_librepo_repomd_parse_file.c `pkg-config --cflags --libs librepo` -Wno-int-conversion -Wno-incompatible-pointer-types + +测试步骤: +- 仓库根路径下执行./test_librepo_repomd_parse_file repomd_005.xml + +期望结果: +- 解析repomd_005.xml成功,命令返回状态码为0 diff --git a/docs/system_libraries/librepo/tc_librepo_librepo_func_006.yaml b/docs/system_libraries/librepo/tc_librepo_librepo_func_006.yaml new file mode 100644 index 0000000000000000000000000000000000000000..cf869df7e4598615f257f1c340ea6f2fd348c3a0 --- /dev/null +++ b/docs/system_libraries/librepo/tc_librepo_librepo_func_006.yaml @@ -0,0 +1,20 @@ +作者: suomengjun +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: librepo从YUM存储库的repomd.xml文件中检索特定的元数据记录 +修改人: suomengjun + +前置条件: +- 安装gcc,librepo,librepo-devel +- 仓库根路径下生成配置文件repomd_006.xml +- 仓库根路径下生成test_librepo_repomd_get_record.c +- 执行编译命令:gcc -o test_librepo_repomd_get_record test_librepo_repomd_get_record.c `pkg-config --cflags --libs librepo` -Wno-int-conversion -Wno-incompatible-pointer-types + +测试步骤: +- 仓库根路径下执行./test_librepo_repomd_get_record repomd_006.xml + +期望结果: +- 检索repomd_006.xml文件特定元数据成功,命令返回状态码为0 diff --git a/docs/system_libraries/libseccomp/tc_libseccomp_fun_001.yaml b/docs/system_libraries/libseccomp/tc_libseccomp_fun_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d21dd95033deb2365feed84f1ea4e695e51578fa --- /dev/null +++ b/docs/system_libraries/libseccomp/tc_libseccomp_fun_001.yaml @@ -0,0 +1,50 @@ +作者: hongfeng +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 使用libseccomp库的api验证设置SCMP_ACT_ALLOW后,没有allow的fork()系统可以被调用 +修改人: hongfeng + +前置条件: +- 创建test01.c +#include +#include + +int main() { + int rc; + + // 创建一个新的过滤上下文 + scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_ALLOW); + if (ctx == NULL) { + fprintf(stderr, "seccomp_init failed\\n"); + return 1; + } + + rc = seccomp_load(ctx); + if (rc != 0) { + fprintf(stderr, "seccomp_load failed: %d\\n", rc); + seccomp_release(ctx); + return 1; + } + + printf("Seccomp filter successfully installed.\\n"); + + // 尝试一个未seccomp_rule_add的系统调用,比如 fork(),验证可以运行 + fork(); + + printf("fork is allowed.\\n"); + + // 在程序结束时释放过滤上下文 + seccomp_release(ctx); + + return 0; +} +- 编译gcc -o test01 test01.c `pkg-config --cflags --libs libseccomp` + +测试步骤: +- 执行./test01 + +期望结果: +- 命令执行成功,验证fork()系统调用被允许 diff --git a/docs/system_libraries/libseccomp/tc_libseccomp_fun_002.yaml b/docs/system_libraries/libseccomp/tc_libseccomp_fun_002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c9129c0b097d48c43ab53a0e3834f914d2639cd5 --- /dev/null +++ b/docs/system_libraries/libseccomp/tc_libseccomp_fun_002.yaml @@ -0,0 +1,86 @@ +作者: hongfeng +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 使用libseccomp库的api验证设置后SCMP_ACT_KILL,没有seccomp_rule_add的系统调用被禁止 +修改人: hongfeng + +前置条件: +- 创建test02.c +#include +#include + +int main() { + int rc; + + // 创建一个新的过滤上下文 + scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_KILL); + if (ctx == NULL) { + fprintf(stderr, "seccomp_init failed\\n"); + return 1; + } + + // 允许read(), write(), exit(), newfstatat系统调用 + rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0); + if (rc != 0) { + fprintf(stderr, "seccomp_rule_add for read() failed: %d\\n", rc); + seccomp_release(ctx); + return 1; + } + + rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0); + if (rc != 0) { + fprintf(stderr, "seccomp_rule_add for write() failed: %d\\n", rc); + seccomp_release(ctx); + return 1; + } + + rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit), 0); + if (rc != 0) { + fprintf(stderr, "seccomp_rule_add for exit() failed: %d\\n", rc); + seccomp_release(ctx); + return 1; + } + rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(newfstatat), 0); + if (rc < 0) { + fprintf(stderr, "seccomp_rule_add for newfstatat() failed: %d\\n", rc); + seccomp_release(ctx); + return 1; + } + rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0); + if (rc != 0) { + fprintf(stderr, "seccomp_rule_add for exit_group() failed: %d\\n", rc); + seccomp_release(ctx); + return 1; + } + + // 设置默认动作为禁止(KILL进程) + rc = seccomp_load(ctx); + if (rc != 0) { + fprintf(stderr, "seccomp_load failed: %d\\n", rc); + seccomp_release(ctx); + return 1; + } + + printf("Seccomp filter successfully installed.\\n"); + + // 在这里您可以添加您的程序逻辑,现在它将在受限的系统调用环境中运行 + // 尝试一个未被允许的系统调用,比如 fork() + fork(); // 注释这行以避免程序因违反seccomp规则而崩溃 + + printf("It will not be here.\\n"); + + // 在程序结束时释放过滤上下文 + seccomp_release(ctx); + + return 0; +} +- 编译gcc -o test02 test02.c `pkg-config --cflags --libs libseccomp` + +测试步骤: +- 执行./test02 + +期望结果: +- 命令执行成功,验证fork()系统调用被禁止 diff --git a/docs/system_libraries/libselinux/tc_libselinux_fun_001.yaml b/docs/system_libraries/libselinux/tc_libselinux_fun_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8f144d72c542b9ee9d1df874b6caaa71bd6fafdc --- /dev/null +++ b/docs/system_libraries/libselinux/tc_libselinux_fun_001.yaml @@ -0,0 +1,61 @@ +作者: hongfeng +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 使用libselinux库的api检查SELINUX设置 +修改人: hongfeng + +前置条件: +- 创建test01.c +#include +#include +#include +#include + +/* Assume that `selinux_getenforce()` is already defined and implemented elsewhere. */ + +int main() { + int enforce_status; + int result; + + /* Call the selinux_getenforce() function to retrieve the enforcement status */ + result = selinux_getenforcemode(&enforce_status); + + /* Print the result based on the returned value */ + switch (enforce_status) { + case 0: + printf("SELinux is currently in 'Permissive' mode.\\n"); + break; + case 1: + printf("SELinux is currently in 'Enforcing' mode.\\n"); + break; + case -1: + printf("SELinux is currently in 'Disabled' mode.\\n"); + break; + default: + fprintf(stderr, "Unknown SELinux enforcement status returned: %d\\n", enforce_status); + return 1; + } + + return 0; +} +- 编译gcc -o test01 test01.c -lselinux +- 备份/etc/selinux/config + +测试步骤: +- 执行sed -i 's/^SELINUX=.*/SELINUX=permissive/' /etc/selinux/config, 将SELINUX设置为SELINUX=permissive +- 执行./test01 +- 执行sed -i 's/^SELINUX=.*/SELINUX=enforcing/' /etc/selinux/config,将SELINUX设置为SELINUX=enforcing +- 执行./test01 +- 执行sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config, 将SELINUX设置为SELINUX=disabled +- 执行./test01 + +期望结果: +- 命令执行成功 +- 命令执行成功,验证取回的结果跟设置一致 +- 命令执行成功 +- 命令执行成功,验证取回的结果跟设置一致 +- 命令执行成功 +- 命令执行成功,验证取回的结果跟设置一致 diff --git a/docs/system_libraries/libselinux/tc_libselinux_fun_002.yaml b/docs/system_libraries/libselinux/tc_libselinux_fun_002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..bb47398325163b028cfa518a17774bbf571c3798 --- /dev/null +++ b/docs/system_libraries/libselinux/tc_libselinux_fun_002.yaml @@ -0,0 +1,103 @@ +作者: hongfeng +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 使用libselinux库的api设置不同上下文 +修改人: hongfeng + +前置条件: +- 创建test02.c +#include +#include +#include +#include + +#define TEST_FILE_PATH "/tmp/test_file.txt" + +int main(int argc, char *argv[]) { + if (argc != 2) { + printf("Usage: %s 'context'\\n", argv[0]); + printf("Where:\\n"); + printf(" - The context, like: 'user_u:object_r:test_file_t:s0';\\n"); + } + + size_t arg_length = strlen(argv[1]) + 1; + char new_context[arg_length]; + strcpy(new_context, argv[1]); + + int ret; + char *current_context = NULL; + security_context_t file_context; + + // 创建测试文件 + FILE *test_file = fopen(TEST_FILE_PATH, "w"); + if (!test_file) { + fprintf(stderr, "Failed to create test file: %s\\n", strerror(errno)); + return EXIT_FAILURE; + } + fclose(test_file); + + // 获取当前文件的安全上下文 + ret = getfilecon(TEST_FILE_PATH, ¤t_context); + if (ret < 0) { + fprintf(stderr, "Failed to get file context: %s\\n", strerror(errno)); + return EXIT_FAILURE; + } else { + printf("Current file context: %s\\n", current_context); + freecon(current_context); + } + + // 设置文件的安全上下文 + ret = setfilecon(TEST_FILE_PATH, new_context); + if (ret < 0) { + fprintf(stderr, "Failed to set file context: %s\\n", strerror(errno)); + return EXIT_FAILURE; + } + + // 验证文件上下文是否已成功更新 + ret = getfilecon(TEST_FILE_PATH, ¤t_context); + if (ret < 0) { + fprintf(stderr, "Failed to get updated file context: %s\\n", strerror(errno)); + return EXIT_FAILURE; + } else { + if (strcmp(current_context, new_context) == 0) { + printf("File context successfully updated to: %s\\n", current_context); + } else { + fprintf(stderr, "Error: File context not updated correctly.\\n"); + freecon(current_context); + return EXIT_FAILURE; + } + freecon(current_context); + } + + // 使用security_context_t类型进行上下文操作 + if (getfilecon_raw(TEST_FILE_PATH, &file_context) < 0) { + fprintf(stderr, "Failed to get file context using security_context_t: %s\\n", strerror(errno)); + return EXIT_FAILURE; + } else { + printf("File context (security_context_t): %s\\n", file_context); + freecon(file_context); + } + + // 清理:删除测试文件 + if (remove(TEST_FILE_PATH) != 0) { + fprintf(stderr, "Failed to remove test file: %s\\n", strerror(errno)); + return EXIT_FAILURE; + } + + printf("All test cases passed.\\n"); + return EXIT_SUCCESS; +} +- 编译gcc -o test02 test02.c -lselinux + +测试步骤: +- 执行./test02 'user_u:object_r:test_file_t:s0' +- 执行./test02 'unconfined_u:user_r:ssh_home_t:s0' +- 执行./test02 'system_u:sysadm_r:httpd_sys_content_t:s0' + +期望结果: +- 命令执行成功,检查测试点通过 +- 命令执行成功,检查测试点通过 +- 命令执行成功,检查测试点通过 diff --git a/docs/system_libraries/libselinux/tc_libselinux_fun_003.yaml b/docs/system_libraries/libselinux/tc_libselinux_fun_003.yaml new file mode 100644 index 0000000000000000000000000000000000000000..37e7e5d29b8d73d730e496632ee6b38a131c6f20 --- /dev/null +++ b/docs/system_libraries/libselinux/tc_libselinux_fun_003.yaml @@ -0,0 +1,85 @@ +作者: hongfeng +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 使用libselinux库的api进行权限检查 +修改人: hongfeng + +前置条件: +- 创建test03.c +#include +#include +#include +#include +#include +#include + +#define TEST_FILE "test_file" +#define TEST_OPERATION "read" + +int main(int argc, char *argv[]) { + if (argc != 2) { + printf("Usage: %s 'file_context'\\n", argv[0]); + printf("Where:\\n"); + printf(" - The file_context, like: 'user_u:object_r:test_file_t:s0';\\n"); + return 1; + } + + size_t arg_length = strlen(argv[1]) + 1; + char file_context[arg_length]; + strcpy(file_context, argv[1]); + + int ret; + char *current_context; + + // Create test files and set their contexts + int fd = open(TEST_FILE, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR); + if (fd == -1) { + perror("Failed to create test_file_1"); + return 1; + } + if (fsetfilecon(fd, file_context) != 0) { + fprintf(stderr, "Failed to set context for test_file\\n"); + close(fd); + unlink(TEST_FILE); + return 1; + } + close(fd); + + ret = getcon(¤t_context); + if (ret != 0) { + perror("getcon() failed"); + exit(EXIT_FAILURE); + } + + printf("Current process context: %s\\n", current_context); + + // Check access permissions + ret = selinux_check_access(current_context, file_context, "file", TEST_OPERATION, NULL); + printf("Access check for %s on %s: %s\\n", TEST_OPERATION, TEST_FILE, ret == 0 ? "Allowed" : "Denied"); + + // Clean up + freecon(current_context); + unlink(TEST_FILE); + + return 0; +} +- 编译gcc -o test03 test03.c -lselinux + +测试步骤: +- 执行setenforce 0 +- 执行./test03 user_u:object_r:test_file_t:s0 +- 执行./test03 system_u:object_r:secret_file_t:s0 +- 执行setenforce 1 +- 执行./test03 user_u:object_r:test_file_t:s0 +- 执行./test03 system_u:object_r:secret_file_t:s0 + +期望结果: +- 命令执行成功 +- 命令执行成功,检查Access check成功 +- 命令执行成功,检查Access check成功 +- 命令执行成功 +- 命令执行成功,检查Access check成功 +- 命令执行成功,检查设置为失败 diff --git a/docs/system_libraries/libsemanage/tc_libsemanage_fun_001.yaml b/docs/system_libraries/libsemanage/tc_libsemanage_fun_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..bdfc367a4d7cc59c99e7f2e7e2a04d349f8cecfd --- /dev/null +++ b/docs/system_libraries/libsemanage/tc_libsemanage_fun_001.yaml @@ -0,0 +1,69 @@ +作者: hongfeng +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 使用libsemanage库的api检查semanage boolean +修改人: hongfeng + +前置条件: +- 创建test01.c +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + semanage_handle_t *handle; + semanage_bool_t **records = NULL; + unsigned int count = 0; + int rc; + + if (argc != 2) { + fprintf(stderr, "Usage: test_semanage \\n"); + return 1; + } + size_t arg_length = strlen(argv[1]) + 1; + char test_name[arg_length]; + strcpy(test_name, argv[1]); + + // 1. 创建和初始化 semanage_handle_t + if ((handle = semanage_handle_create()) == NULL) { + fprintf(stderr, "Failed to create semanage handle: %s\\n", strerror(errno)); + return 1; + } + + // 2. 连接到 semanage + if ((rc = semanage_connect(handle)) < 0) { + fprintf(stderr, "Failed to connect to semanage: %s\\n", strerror(-rc)); + semanage_handle_destroy(handle); + return 1; + } + + // 3: Open the current policy for reading and retrieve boolean records + semanage_bool_list(handle, &records, &count); + + // 4: Iterate over retrieved boolean records and filter by name + for (unsigned int i = 0; i < count; ++i) { + semanage_bool_t *boolean = records[i]; + const char *name = semanage_bool_get_name(boolean); + int state = semanage_bool_get_value(boolean); + // Filter by test_name + if (strstr(name, test_name) != NULL) { + printf("%s, %d\\n", name, state); + } + } + + return 0; +} +- 编译gcc -o test01 test01.c -lsemanage + +测试步骤: +- 执行./test01 ssh_sysadm_login +- 执行semanage boolean --list | grep ssh_sysadm_login | awk -F'[()]' '{split($2, values, \", \"); print values[1]}' + +期望结果: +- 命令执行成功 +- 命令执行成功,验证取回的结果跟api获取的结果一致 diff --git a/docs/system_libraries/libsemanage/tc_libsemanage_fun_002.yaml b/docs/system_libraries/libsemanage/tc_libsemanage_fun_002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6fbfa4fbbd36e692c15a510506c237c90c68e2e2 --- /dev/null +++ b/docs/system_libraries/libsemanage/tc_libsemanage_fun_002.yaml @@ -0,0 +1,123 @@ +作者: hongfeng +优先级: P2 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 使用libsemanage库的api设置file context +修改人: hongfeng + +前置条件: +- 创建test02.c +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + semanage_handle_t *handle; + semanage_fcontext_t *fcontext = NULL; + semanage_context_t *con = NULL; + int rc; + semanage_fcontext_key_t *k; + int exist = 0; + + if (argc != 4) { + fprintf(stderr, "Usage: test_fcontext \\n"); + return 1; + } + + const char *file_pattern = argv[1]; + const char *context_str = argv[2]; + int fcontext_type = atoi(argv[3]); + + // 1. 创建和初始化 semanage_handle_t + if ((handle = semanage_handle_create()) == NULL) { + fprintf(stderr, "Failed to create semanage handle: %s\\n", strerror(errno)); + return 1; + } + + // 2. 连接到 semanage + if ((rc = semanage_connect(handle)) < 0) { + fprintf(stderr, "Failed to connect to semanage: %s\\n", strerror(-rc)); + semanage_handle_destroy(handle); + return 1; + } + + if ((rc = semanage_begin_transaction(handle)) < 0) { + fprintf(stderr, "Failed to begin transaction: %s\\n", strerror(-rc)); + goto cleanup; + } + + if (semanage_fcontext_key_create(handle, argv[2], SEMANAGE_FCONTEXT_REG, &k) < 0) { + fprintf(stderr, "Could not create key for %s", argv[2]); + return -1; + } + + if(semanage_fcontext_exists(handle, k, &exist) < 0) { + return -1; + } + if (exist) { + return -1; + } + + // 3. 创建 semanage_fcontext_t 结构体 + if ((rc = semanage_fcontext_create(handle, &fcontext)) < 0) { + fprintf(stderr, "Failed to create file context object: %s\\n", strerror(-rc)); + goto cleanup; + } + + // 4. 设置文件路径模式 + if ((rc = semanage_fcontext_set_expr(handle, fcontext, file_pattern)) < 0) { + fprintf(stderr, "Failed to set file path pattern '%s': %s\\n", file_pattern, strerror(-rc)); + goto cleanup; + } + + // 5. 解析上下文字符串并设置上下文 + if ((rc = semanage_context_from_string(handle, context_str, &con)) < 0) { + fprintf(stderr, "Could not create context using '%s' for file context '%s'\\n", context_str, file_pattern); + goto cleanup; + } + + if ((rc = semanage_fcontext_set_con(handle, fcontext, con)) < 0) { + fprintf(stderr, "Could not set file context for '%s'\\n", file_pattern); + goto cleanup; + } + + semanage_fcontext_set_type(fcontext, fcontext_type); + + // 7. 将新的文件上下文规则添加到策略数据库(此处仅为示例,实际应用中应根据需要考虑事务提交等操作) + if(semanage_fcontext_modify_local(handle, k, fcontext) < 0) { + fprintf(stderr,"Could not add file context for %s", argv[2]); + return -1; + } + + if ((rc = semanage_commit(handle)) < 0) { + fprintf(stderr, "Failed to commit transaction: %s\\n", strerror(-rc)); + return -1; + } + + printf("Successfully created file context rule for pattern '%s' with context '%s' and type %d\\n", + file_pattern, context_str, fcontext_type); + +cleanup: + semanage_context_free(con); + semanage_fcontext_free(fcontext); + semanage_disconnect(handle); + semanage_handle_destroy(handle); + + return rc >= 0 ? 0 : 1; +} +- 编译gcc -o test02 test02.c -lsemanage + +测试步骤: +- 执行./test02 '/tmp/test02' 'system_u:object_r:httpd_sys_content_t:s0' SEMANAGE_FCONTEXT_REG +- 执行semanage fcontext -l | grep '/tmp/test02' +- semanage fcontext -d -t 'all files' /tmp/test02 + +期望结果: +- 命令执行成功,验证获取到期望的输出 +- 命令执行成功,验证取回的结果跟api设置的结果一致 +- 命令执行成功,恢复默认设置 + diff --git a/docs/system_libraries/libsolv/tc_libsolv_libsolv_func_001.yaml b/docs/system_libraries/libsolv/tc_libsolv_libsolv_func_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1a7cd18bc11c67eb6d9f59c675f42299ce6bacee --- /dev/null +++ b/docs/system_libraries/libsolv/tc_libsolv_libsolv_func_001.yaml @@ -0,0 +1,20 @@ +作者: suomengjun +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 检索libsolv使用的根目录 +修改人: suomengjun + +前置条件: +- 安装gcc,libsolv,libsolv-devel +- 仓库根路径下生成libsolv_pool_get_rootdir_test.c +- 执行编译命令:gcc -o libsolv_pool_get_rootdir_test libsolv_pool_get_rootdir_test.c `pkg-config --cflags --libs libsolv` + +测试步骤: +- 仓库根路径下执行./libsolv_pool_get_rootdir_test + +期望结果: +-检索libsolv使用的根目录成功,命令返回状态码为0 + diff --git a/docs/system_libraries/libsolv/tc_libsolv_libsolv_func_002.yaml b/docs/system_libraries/libsolv/tc_libsolv_libsolv_func_002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3372b05fdce73f2f9a777ad5cc06027e609d2a39 --- /dev/null +++ b/docs/system_libraries/libsolv/tc_libsolv_libsolv_func_002.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 自定义一个包添加到包池,以可读形式输出包信息 +修改人: suomengjun + +前置条件: +- 安装gcc,libsolv,libsolv-devel +- 仓库根路径下生成libsolv_get_pkginfo_test.c +- 执行编译命令:gcc -o libsolv_get_pkginfo_test libsolv_get_pkginfo_test.c `pkg-config --cflags --libs libsolv` + +测试步骤: +- 仓库根路径下执行./libsolv_get_pkginfo_test + +期望结果: +- 自定包数据解析无异常,成功输出自定义包信息,命令返回状态码为0 \ No newline at end of file diff --git a/docs/system_libraries/libsolv/tc_libsolv_libsolv_func_003.yaml b/docs/system_libraries/libsolv/tc_libsolv_libsolv_func_003.yaml new file mode 100644 index 0000000000000000000000000000000000000000..4ddc09e87aff73ef9a085fa7f1d446ddc3a83d75 --- /dev/null +++ b/docs/system_libraries/libsolv/tc_libsolv_libsolv_func_003.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 创建并填充一个测试仓库来搜索包 +修改人: suomengjun + +前置条件: +- 安装gcc,libsolv,libsolv-devel +- 仓库根路径下生成test_libsolv_repo_search.c +- 执行编译命令:gcc -o test_libsolv_repo_search test_libsolv_repo_search.c `pkg-config --cflags --libs libsolv` + +测试步骤: +- 仓库根路径下执行./test_libsolv_repo_search + +期望结果: +- package打头的数个包到仓库,成功的检索到package包,检索过程无报错,命令返回状态码为0 \ No newline at end of file diff --git a/docs/system_libraries/libsolv/tc_libsolv_libsolv_func_004.yaml b/docs/system_libraries/libsolv/tc_libsolv_libsolv_func_004.yaml new file mode 100644 index 0000000000000000000000000000000000000000..755e5e830a9b6261b74fc8861a0b99572612315d --- /dev/null +++ b/docs/system_libraries/libsolv/tc_libsolv_libsolv_func_004.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: libsolv创建一个Dataiterator来搜索名称中包含"example"的软件包 +修改人: suomengjun + +前置条件: +- 安装gcc,libsolv,libsolv-devel +- 仓库根路径下生成test_libsolv_dataiterator_match.c +- 执行编译命令:gcc -o test_libsolv_dataiterator_match test_libsolv_dataiterator_match.c `pkg-config --cflags --libs libsolv` + +测试步骤: +- 仓库根路径下执行./test_libsolv_dataiterator_match + +期望结果: +- 成功搜索名称中包含"example"的软件包,命令返回状态码为0 \ No newline at end of file diff --git a/docs/system_libraries/libsolv/tc_libsolv_libsolv_func_005.yaml b/docs/system_libraries/libsolv/tc_libsolv_libsolv_func_005.yaml new file mode 100644 index 0000000000000000000000000000000000000000..15ae9fb954780788ed74c87c7a5973a2b7baa147 --- /dev/null +++ b/docs/system_libraries/libsolv/tc_libsolv_libsolv_func_005.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: libsolv匹配依赖 +修改人: suomengjun + +前置条件: +- 安装gcc,libsolv,libsolv-devel +- 仓库根路径下生成test_libsolv_pool_match_dep.c +- 执行编译命令:gcc -o test_libsolv_pool_match_dep test_libsolv_pool_match_dep.c `pkg-config --cflags --libs libsolv` + +测试步骤: +- 仓库根路径下执行./test_libsolv_pool_match_dep libfoo libfoo + +期望结果: +- 创建测试仓库并添加libfoo包到仓库,可以成功匹配libfoo,命令返回状态码为0 \ No newline at end of file diff --git a/docs/system_libraries/libsolv/tc_libsolv_libsolv_func_006.yaml b/docs/system_libraries/libsolv/tc_libsolv_libsolv_func_006.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d098c755ce860c28669f10fae89b9e61d26b797e --- /dev/null +++ b/docs/system_libraries/libsolv/tc_libsolv_libsolv_func_006.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: libsolv计算在给定的一系列软件包操作(安装、升级或卸载)后,系统上安装的软件包总大小将如何变化 +修改人: suomengjun + +前置条件: +- 安装gcc,libsolv,libsolv-devel +- 仓库根路径下生成test_libsolv_pool_calc_installsizechange.c +- 执行编译命令:gcc -o test_libsolv_pool_calc_installsizechange test_libsolv_pool_calc_installsizechange.c `pkg-config --cflags --libs libsolv` + +测试步骤: +- 仓库根路径下执行./test_libsolv_pool_calc_installsizechange 1 2 3 + +期望结果: +-检索libsolv使用的根目录成功,命令返回状态码为0 \ No newline at end of file diff --git a/docs/system_libraries/libverto/tc_libverto_libverto_func_001.yaml b/docs/system_libraries/libverto/tc_libverto_libverto_func_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..9f4459551e31013a32c9b1c2ff95ac2c389e952e --- /dev/null +++ b/docs/system_libraries/libverto/tc_libverto_libverto_func_001.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: libverto检测支持的事件循环 +修改人: suomengjun + +前置条件: +- 安装gcc,libverto,libverto-devel,libevent +- 仓库根路径下生成test_verto_check_event_is_supported.c +- 执行编译命令:gcc -o test_verto_check_event_is_supported test_verto_check_event_is_supported.c `pkg-config --cflags --libs libverto libevent` + +测试步骤: +- 仓库根路径下执行./test_verto_check_event_is_supported libevent + +期望结果: +- 成功获取事件循环支持情况,命令返回状态码为0 diff --git a/docs/system_libraries/openldap/tc_openldap_openldap_func_001.yaml b/docs/system_libraries/openldap/tc_openldap_openldap_func_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..4b13e6cd8cda2c25fb6b24a179ac4db87ceff4b9 --- /dev/null +++ b/docs/system_libraries/openldap/tc_openldap_openldap_func_001.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: LDAP服务指定协议版本 +修改人: suomengjun + +前置条件: +- 安装gcc,openldap,openldap-devel +- 仓库根路径下生成openldap_set_option.c +- 执行编译命令:gcc -o openldap_set_option openldap_set_option.c -lldap + +测试步骤: +- 仓库根路径下执行./openldap_set_option + +期望结果: +- LDAP服务指定协议版本成功,命令返回状态码为0 diff --git a/docs/system_libraries/openldap/tc_openldap_openldap_func_002.yaml b/docs/system_libraries/openldap/tc_openldap_openldap_func_002.yaml new file mode 100644 index 0000000000000000000000000000000000000000..673bdc6abf59a4191137440bf0b4f025ddd09833 --- /dev/null +++ b/docs/system_libraries/openldap/tc_openldap_openldap_func_002.yaml @@ -0,0 +1,19 @@ +作者: suomengjun +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 从LDAP服务器返回的控制响应数组中查找特定类型的LDAP控制 +修改人: suomengjun + +前置条件: +- 安装gcc,openldap,openldap-devel +- 仓库根路径下生成openldap_ldap_control_find.c +- 执行编译命令:gcc -o openldap_ldap_control_find openldap_ldap_control_find.c -lldap -llber + +测试步骤: +- 仓库根路径下执行./openldap_ldap_control_find '1.2.840.113556.1.4.319' + +期望结果: +- 模拟传入的LDAP控制数组中成功查到对象标识符(OID)字符串,即'1.2.840.113556.1.4.319',命令返回状态码为0 diff --git a/docs/system_libraries/openldap/tc_openldap_openldap_func_003.yaml b/docs/system_libraries/openldap/tc_openldap_openldap_func_003.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f5dc06604ef065bace6daefa22a9728ad9f3a35e --- /dev/null +++ b/docs/system_libraries/openldap/tc_openldap_openldap_func_003.yaml @@ -0,0 +1,22 @@ +作者: suomengjun +优先级: P3 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 绑定到LDAP服务器的用户问询自己的身份 +修改人: suomengjun + +前置条件: +- 安装gcc,openldap,openldap-devel +- 运行提供的脚本完成setup的所有操作,执行:bash openldap_pre.sh +- 仓库根路径下生成openldap_ldap_whoami.c +- 执行编译命令:gcc -o openldap_ldap_whoami openldap_ldap_whoami.c -lldap -llber + +测试步骤: +- 仓库根路径下执行./openldap_ldap_whoami 'ldap://localhost:389' 'cn=admin,dc=domain,dc=com' 'root' +- 执行LDAP服务清理脚本bash openldap_post.sh + +期望结果: +- LDAP服务器成功解析到用户身份,命令返回状态码为0 +- 成功清理服务残留 \ No newline at end of file diff --git a/docs/system_services/acpid/tc_acpid_acpid_fun001.yaml b/docs/system_services/acpid/tc_acpid_acpid_fun001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2777619da663c093275b6d1958a7bed7f34b11fb --- /dev/null +++ b/docs/system_services/acpid/tc_acpid_acpid_fun001.yaml @@ -0,0 +1,20 @@ +: douzhichong +ȼ: P1 +ּ֧ܹ: noarch +ִзʽ: Զ +: ܲ +ͨñǩ: local,acpid +: acpidֹͣ +޸: douzhichong + +ǰ: + +Բ: +- ִacpid systemctl start acpid.service 鿴״̬systemctl status acpid.service +- ִacpid systemctl restart acpid.service 鿴״̬systemctl status acpid.service +- ִֹͣacpid systemctl stop acpid.service 鿴״̬systemctl status acpid.service +: +- ɹԿѿ +- ɹԿɹ +- ɹԿѹر + diff --git a/docs/system_services/at/tc_at_at_fun001.yaml b/docs/system_services/at/tc_at_at_fun001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7d1a0b943600f32304ca3dd81595262ba968b73f --- /dev/null +++ b/docs/system_services/at/tc_at_at_fun001.yaml @@ -0,0 +1,20 @@ +: douzhichong +ȼ: P1 +ּ֧ܹ: noarch +ִзʽ: Զ +: ܲ +ͨñǩ: local,at +: atֹͣ +޸: douzhichong + +ǰ: + +Բ: +- ִat systemctl start atd.service 鿴״̬systemctl status atd.service +- ִat systemctl restart atd.service 鿴״̬systemctl status atd.service +- ִֹͣat systemctl stop atd.service 鿴״̬systemctl status atd.service +: +- ɹԿѿ +- ɹԿɹ +- ɹԿѹر + diff --git a/docs/system_services/numad/tc_numad_numad_func_001.yaml b/docs/system_services/numad/tc_numad_numad_func_001.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0b3e3178ab992020090fa7e7c36ee1aa70e8462b --- /dev/null +++ b/docs/system_services/numad/tc_numad_numad_func_001.yaml @@ -0,0 +1,26 @@ +作者: chenchunhu +优先级: P1 +支持架构: noarch +执行方式: 自动 +测试类型: 功能测试 +通用标签: local +用例描述: 测试numad基本功能 +修改人: chenchunhu + +前置条件: +- 安装numad包 + +测试步骤: +- 启动numad服务:service numad start;查看状态:service numad status +- 重启numad服务:service numad restart;查看状态:service numad status +- 查看dnsmasq版本:numad -V +- 查看帮助信息:numad -h +- 停止numad服务:service numad stop;查看状态:service numad status + +期望结果: +- 操作成功,可以成功启动numad服务 +- 操作成功,可以成功重启numad服务 +- 操作成功,可以成功显示numad服务版本号 +- 操作成功,可以成功显示numad服务帮助信息 +- 操作成功,可以成功停止numad服务 + diff --git a/plugins/anolis_test_plugin.py b/plugins/anolis_test_plugin.py new file mode 100644 index 0000000000000000000000000000000000000000..d8d4a56e110890bb25a4b7e8a4109b3bfa1f22ae --- /dev/null +++ b/plugins/anolis_test_plugin.py @@ -0,0 +1,214 @@ +import os +import time + +from avocado.core.plugin_interfaces import JobPre, JobPost +from avocado.core.output import LOG_UI +from avocado.utils import process +from os_env import OSType, Env, Image + +class AnolisPrePost(JobPre, JobPost): + """ + pre/post set before/after Job + """ + name = 'Anolis test PrePost' + description = 'setup and teardown Anolis test envoriment' + def __init__(self): + self.test_engine = os.environ.get("TEST_ENGINE") + self.image_info = self._get_image_info() + self.registry = os.environ.get("REGISTRY_ADDR") + self.container_id = None + + def _get_image_info(self): + image = Image() + _, output = self.cmd('find /etc -name "image-id"') + if output: + image.env = Env.ECS + _, output = self.cmd('cat /etc/image-id | grep image_id') + image.id = output.split('=')[1].strip('"') + else: + image.env = Env.PHY + _,output = self.cmd('cat /etc/os-release') + for line in output.split('\n'): + if line.startswith('ID='): + image.ostype = OSType[line.split('=')[1].strip('"').upper()] + elif line.startswith('VERSION_ID='): + image.version = line.split('=')[1].strip('"') + _, image.arch = self.cmd('arch') + _, image.kernel = self.cmd('uname -r') + return image + + def create_container(self,container_engine,image,version,container_id): + http_str="" + if os.environ.get('TONE_OSS_PROXY_HOST') is not None: + http_str = "-e http_proxy={0} -e https_proxy={0}".format(os.environ.get('TONE_OSS_PROXY_HOST')) + if container_engine == 'docker': + ret_c,ret_o = self.cmd(" rpm -qa | grep podman ",ignore_status=True) + if ret_c == 0: + self.cmd('yum remove podman -y') + if image.ostype == OSType.ANOLIS: + self.cmd('yum install -y yum-utils') + if image.ostype == OSType.ANOLIS and image.version.startswith('23'): + self.cmd('yum install docker -y --enablerepo=os') + else: + self.cmd('yum install docker -y --enablerepo=Plus') + elif image.ostype == OSType.CENTOS or image.ostype == OSType.ALINUX: + self.cmd('yum install -y yum-utils') + self.cmd('yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo') + self.cmd('yum install docker-ce -y') + elif image.ostype == OSType.FEDORA: + self.cmd('dnf -y install dnf-plugins-core') + self.cmd('dnf config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/fedora/docker-ce.repo') + self.cmd('dnf update -y') + self.cmd('dnf install docker-ce -y') + elif image.ostype == OSType.OPENSUSE_LEAP: + self.cmd('zypper install -y docker') + elif image.ostype == OSType.UBUNTU: + if image.version == '18.04': + self.cmd('apt-get update -y') + self.cmd('apt-get -y install software-properties-common 1>/dev/null',ignore_status=True) + self.cmd('curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -') + self.cmd('add-apt-repository "deb [arch=$(dpkg --print-architecture)] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"') + self.cmd('apt-get update -y') + if image.arch == 'aarch64': + self.cmd('rm -rf /etc/grub.d/10_linux*') + self.cmd('rm -rf /var/lib/dpkg/updates/*') + self.cmd('DEBIAN_FRONTEND=noninteractive apt-get -y install docker-ce --no-install-recommends 1>/dev/null',ignore_status=True) + ret_c,output = self.cmd('service docker start',ignore_status=True) + if 'docker.service is masked' in output: + self.cmd('systemctl unmask docker.service && systemctl unmask docker.socket') + self.cmd('systemctl start containerd.service') + elif image.ostype == OSType.DEBIAN: + self.cmd('apt-get update -y') + self.cmd('apt-get install apt-transport-https ca-certificates curl gnupg software-properties-common -y 1>/dev/null') + self.cmd('curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -') + self.cmd('add-apt-repository "deb [arch=$(dpkg --print-architecture)] https://download.docker.com/linux/debian $(lsb_release -cs) stable"') + self.cmd('apt-get update -y') + self.cmd('apt-get -y install docker-ce 1>/dev/null',ignore_status=True) + self.cmd('cat /etc/containers/registries.conf | grep docker.io',ignore_status=True) + else: + self.log.debug("docker install: this operating system does not require testing") + + ret_c,containerd_status = self.cmd('systemctl is-active containerd.service',ignore_status=True) + if containerd_status != 'active': + self.cmd('systemctl start containerd.service') + for i in range(30): + ret_c,docker_status = self.cmd('systemctl is-active '+container_engine,ignore_status=True) + if docker_status != 'active': + time.sleep(20) + self.cmd('systemctl reset-failed '+container_engine,ignore_status=True) + self.cmd('systemctl start '+container_engine,ignore_status=True) + else: + break + elif container_engine == 'podman': + ret_c,ret_o = self.cmd("rpm -qa | grep docker",ignore_status=True) + if ret_c == 0: + self.cmd('yum remove docker* -y') + self.cmd('yum install -y yum-utils') + self.cmd('yum install podman -y') + ret_c,ret_o = self.cmd("podman ps -q") + if ret_o != "": + self.cmd(f" podman stop {ret_o} && podman rm $(podman ps -a -q) ") + + if 'tar' in version: + self.cmd('wget '+version+' 1>/dev/null 2>&1', ignore_status=True) + self.cmd(container_engine+' import '+version.split('/')[-1]+' anolis:23') + ret_c,image_exist = self.cmd(container_engine+' image ls') + if not 'anolis' in image_exist: + LOG_UI.error("import image failed") + raise SystemExit(1) + ret_c,container_id = self.cmd(container_engine+' run -dit --privileged=true -v /home:/home anolis:23 bash') + else: + http_proxy = os.environ.get('TONE_OSS_PROXY_HOST') + if http_proxy is not None and container_engine == "docker": + file_path = '/etc/systemd/system/docker.service.d/http-proxy.conf' + os.makedirs(os.path.dirname(file_path), exist_ok=True) + with open(file_path, 'w') as f: + f.write('[Service]\n') + f.write(f'Environment="HTTP_PROXY={http_proxy}"\n') + f.write(f'Environment="HTTPS_PROXY={http_proxy}"\n') + f.write('Environment="NO_PROXY=localhost,127.0.0.1"\n') + self.cmd("systemctl daemon-reload") + self.cmd("systemctl restart docker") + self.cmd(container_engine+' pull '+version) + ret_c,output1 = self.cmd(container_engine+' image ls') + print("output1:%s" % output1) + if ':' in version: + self.image_name = version.split(':')[0] + else: + self.image_name = version + if not self.image_name in output1: + LOG_UI.error("pull image failed") + raise SystemExit(1) + if 'anolis' or 'alinux' not in self.image_name.split('/')[-1]: + ret_c1,container_id = self.cmd(container_engine+' run '+http_str+ ' -dit --privileged=true -v /home:/home '+version,ignore_status=True) + command = container_engine +' exec '+container_id+' '+' echo "$LANG" ' + ret_c2,lang_ret = self.cmd(command,ignore_status=True) + if ret_c1 != 0 or ret_c2 != 0: + ret_c,container_id = self.cmd(container_engine+' run '+http_str+ ' -dit --privileged=true '+version+' bash') + else: + ret_c,container_id = self.cmd(container_engine+' run '+http_str+ ' -dit --privileged=true -v /home:/home '+version+' /usr/sbin/init') + + ret_c,container_status = self.cmd(container_engine+' ps -a | grep Up -wo') + if not 'Up' in container_status: + LOG_UI.error("run image failed") + raise SystemExit(1) + return container_id + + def destroy_container(self,container_engine,container_id,version,image): + if container_id: + self.cmd(container_engine+' stop '+container_id+' && '+container_engine+' container prune -f') + if 'tar' in version: + self.cmd(container_engine+' image rm anolis:23') + else: + self.cmd(container_engine+' rmi '+version) + self.cmd(container_engine+' container prune -f') + if image.ostype == OSType.ANOLIS: + self.cmd('yum remove -y '+container_engine) + elif image.ostype == OSType.CENTOS or image.ostype == OSType.ALINUX: + if 'docker' == container_engine: + self.cmd('yum remove -y docker-ce') + elif 'podman' == container_engine: + self.cmd('yum remove -y '+container_engine) + elif image.ostype == OSType.FEDORA: + if 'docker' == container_engine: + self.cmd('dnf remove -y docker-ce') + elif 'podman' == container_engine: + self.cmd('dnf remove -y '+container_engine) + elif image.ostype == OSType.OPENSUSE_LEAP: + self.cmd('zypper remove -y '+container_engine) + elif image.ostype == OSType.UBUNTU or image.ostype == OSType.DEBIAN: + if 'docker' == container_engine: + self.cmd('apt-get -y remove docker-ce') + elif 'podman' == container_engine: + self.cmd('apt-get -y remove '+container_engine) + + def cmd(self, command, ignore_status=False): + if ignore_status: + result = process.run(command, ignore_status=ignore_status, shell=True) + + if result.exit_status == 0: + return result.exit_status, result.stdout_text.strip() + else: + return result.exit_status, result.stderr_text.strip() + else: + try: + result = process.run(command, ignore_status=ignore_status, shell=True) + if result.exit_status == 0: + return result.exit_status, result.stdout_text.strip() + else: + raise ValueError(result.stderr_text.strip()) + except Exception as e: + LOG_UI.error(str(e)) + raise SystemExit(1) + + def pre(self, job): + LOG_UI.info("-------do the pre action.-----------") + if self.test_engine is not None: + self.container_id = self.create_container(self.test_engine, self.image_info, self.registry, self.container_id) + os.environ['TEST_CONTAINER_ID'] = self.container_id + + def post(self, job): + LOG_UI.info("-------do the post action.-----------") + if self.container_id is not None: + self.destroy_container(self.test_engine, self.container_id, self.registry, self.image_info) + diff --git a/plugins/os_env.py b/plugins/os_env.py new file mode 100644 index 0000000000000000000000000000000000000000..830ef9b5d8d2265a48662d8fd120a2f3d0783365 --- /dev/null +++ b/plugins/os_env.py @@ -0,0 +1,29 @@ +from enum import Enum +class OSType(Enum): + ALINUX = 'alinux' + ANOLIS = 'anolis' + ALIOS = 'alios' + CENTOS = 'centos' + FEDORA = 'fedora' + UBUNTU = 'ubuntu' + OPENSUSE_LEAP = 'opensuse_leap' + DEBIAN = 'debian' + BCLINUX = 'bclinux' + KOS = 'kos' + UOS = 'uos' + CQOS = 'cqos' + +class Env(Enum): + ECS = 'ecs' + PHY = 'phy' + + +class Image(object): + + def __init__(self): + self.env = None + self.id = None + self.arch = None + self.kernel = None + self.ostype = None + self.version = None diff --git a/plugins/setup.py b/plugins/setup.py new file mode 100644 index 0000000000000000000000000000000000000000..5c865b8a051d11dc5dfc9618d8525aea0d17c786 --- /dev/null +++ b/plugins/setup.py @@ -0,0 +1,12 @@ +from setuptools import setup + + +setup( + name='anolis_test_plugin', + version='1.1', + description='Avocado Plugin for Anolis tests', + py_modules=['anolis_test_plugin'], + entry_points={ + 'avocado.plugins.job.prepost': ['anolis_test_plugin = anolis_test_plugin:AnolisPrePost'], + } +) diff --git a/requirements.txt b/requirements.txt index bea54840b2b0e6ef1ee4cc1898c3701e1748d6dd..6c57b0a9fb2ef6580b46aa718fe6687b810830c5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,3 +2,5 @@ avocado-framework==94.0 avocado-framework-plugin-varianter-yaml-to-mux==94.0 ntplib pexpect + +-e plugins/ \ No newline at end of file diff --git a/tests/accelerator-test/Readme.md b/tests/accelerator/Readme.md similarity index 100% rename from tests/accelerator-test/Readme.md rename to tests/accelerator/Readme.md diff --git a/tests/accelerator-test/lib/lib.sh b/tests/accelerator/lib/lib.sh similarity index 100% rename from tests/accelerator-test/lib/lib.sh rename to tests/accelerator/lib/lib.sh diff --git a/tests/accelerator-test/runtest.sh b/tests/accelerator/runtest.sh similarity index 100% rename from tests/accelerator-test/runtest.sh rename to tests/accelerator/runtest.sh diff --git a/tests/accelerator-test/tests/kmod_udma_test.sh b/tests/accelerator/tests/kmod_udma_test.sh similarity index 100% rename from tests/accelerator-test/tests/kmod_udma_test.sh rename to tests/accelerator/tests/kmod_udma_test.sh diff --git a/tests/accelerator-test/tests/qatzip_test.sh b/tests/accelerator/tests/qatzip_test.sh similarity index 100% rename from tests/accelerator-test/tests/qatzip_test.sh rename to tests/accelerator/tests/qatzip_test.sh diff --git a/tests/accelerator-test/tests/qpl_test.sh b/tests/accelerator/tests/qpl_test.sh similarity index 100% rename from tests/accelerator-test/tests/qpl_test.sh rename to tests/accelerator/tests/qpl_test.sh diff --git a/tests/accelerator-test/tests/rocksdbnew_test.sh b/tests/accelerator/tests/rocksdbnew_test.sh similarity index 100% rename from tests/accelerator-test/tests/rocksdbnew_test.sh rename to tests/accelerator/tests/rocksdbnew_test.sh diff --git a/tests/accelerator-test/tests/udma_test.sh b/tests/accelerator/tests/udma_test.sh similarity index 100% rename from tests/accelerator-test/tests/udma_test.sh rename to tests/accelerator/tests/udma_test.sh diff --git a/tests/ai/cuda/tc_ai_cuda_env_check.py b/tests/ai/cuda/tc_ai_cuda_env_check.py new file mode 100644 index 0000000000000000000000000000000000000000..7e5ce4e99bb892dfa24530b9b540141f6cec0345 --- /dev/null +++ b/tests/ai/cuda/tc_ai_cuda_env_check.py @@ -0,0 +1,47 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +import os +from common.basetest import LocalTest +class Test(LocalTest): + """ + See tc_ai_cuda_env_check.yaml for details + + :avocado: tags=fix,P1,noarch,local,cuda_ai_container + """ + + def setUp(self): + super().setUp() + self.cuda_version = os.environ.get('CUDA_VERSION') + if not self.cuda_version: + self.cuda_version = "12.1.1" + self.os_type = os.environ.get('OS_TYPE') + if not self.os_type: + self.os_type = "ubi9" + self.image_add = os.environ.get('REGISTRY_ADDR') + self.image_test = "base" + if "devel" in self.image_add: + self.image_test = "devel" + elif "runtime" in self.image_add: + self.image_test = "runtime" + self.cmd("git clone https://gitlab.com/nvidia/container-images/cuda.git cuda") + + + def test(self): + envs = set() + filepath = os.path.join("cuda/dist", self.cuda_version, self.os_type, self.image_test, "Dockerfile") + with open(filepath) as file: + line = file.readline() + while line: + words = line.split() + if len(words) >= 2: + if words[0] == "ENV": + envs.add(words[1]) + line = file.readline() + for env in envs: + _, output = self.cmd("echo %s" % env,container_flag=1) + self.assertTrue(output != "", "Cuda image env check failed, Please check env "+env) + + def tearDown(self): + super().tearDown() + self.cmd("rm -rf cuda") diff --git a/tests/apps/duktape/tc_duktape_fun_001.py b/tests/apps/duktape/tc_duktape_fun_001.py new file mode 100644 index 0000000000000000000000000000000000000000..ee87762955878655d6eb099cc38d56c55ad0e3ab --- /dev/null +++ b/tests/apps/duktape/tc_duktape_fun_001.py @@ -0,0 +1,58 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_duktape_fun_001.py +@Time: 2024/04/18 17:11:50 +@Author: zhixin +@Version: 1.0 +@Contact: zx01468051@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: zhixin +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_duktape_fun_001.yaml for details + + :avocado: tags=fix,P3,noarch,local + """ + PARAM_DIC = {"pkg_name": "duktape duktape-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = """cat > javascript_sim.c < + +int main(void) { + duk_context *ctx = duk_create_heap_default(); + if (!ctx) { + printf("Failed to create a Duktape heap.\\n"); + return 1; + } + + duk_eval_string(ctx, "123 + 456"); + if (duk_is_number(ctx, -1)) { + printf("123 + 456 = %.6f\\n", duk_get_number(ctx, -1)); + } else { + printf("The evaluation did not return a number!\\n"); + } + + duk_destroy_heap(ctx); + return 0; +} +EOF""" + self.cmd(cmdline) + + def test(self): + self.cmd('gcc -o javascript_sim javascript_sim.c -lduktape') + ret_c, ret_o = self.cmd('ldd ./javascript_sim') + self.assertTrue('libduktape.so' in ret_o, 'check output error1.') + ret_c, ret_o = self.cmd('./javascript_sim') + self.assertTrue('123 + 456 = 579.000000' == ret_o, 'check output error2.') + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd('rm -rf javascript_sim*') diff --git a/tests/apps/inih/tc_inih_fun_001.py b/tests/apps/inih/tc_inih_fun_001.py new file mode 100644 index 0000000000000000000000000000000000000000..24b95db7cbcd7007544061e1716709a112ab7c82 --- /dev/null +++ b/tests/apps/inih/tc_inih_fun_001.py @@ -0,0 +1,72 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_inih_fun_001.py +@Time: 2024/04/01 14:51:50 +@Author: zhixin +@Version: 1.0 +@Contact: zx01468051@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: zhixin +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_inih_fun_001.yaml for details + + :avocado: tags=fix,P3,noarch,local + """ + PARAM_DIC = {"pkg_name": "inih inih-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = """cat > print_ini.c < +#include + +// 定义解析INI文件时的回调函数 +static int handler(void* user, const char* section, const char* name, const char* value) +{ + printf("Section [%s] Key %s = %s\\n", section, name, value); + return 1; // 返回1表示成功解析 +} + +int main(int argc, char* argv[]) +{ + if (argc < 2) { + fputs("Usage: print_ini \\n", stderr); + return 1; + } + + if (ini_parse(argv[1], handler, NULL) < 0) { + printf("Can't load '%s' file\\n", argv[1]); + return 1; + } + return 0; +} +EOF""" + self.cmd(cmdline) + cmdline = """cat > file.ini << EOF +[database] +server=127.0.0.1 +port=3306 +user=root +password=s3cr3t +EOF""" + self.cmd(cmdline) + + def test(self): + self.cmd('gcc print_ini.c -o print_ini -linih') + ret_c, ret_o = self.cmd('ldd ./print_ini') + self.assertTrue("libinih.so.0" in ret_o, 'check output error1.') + ret_c, ret_o = self.cmd('./print_ini file.ini') + self.assertTrue('Section [database] Key server = 127.0.0.1' in ret_o, 'check output error2.') + self.assertTrue('Section [database] Key port = 3306' in ret_o, 'check output error3.') + self.assertTrue('Section [database] Key user = root' in ret_o, 'check output error4.') + self.assertTrue('Section [database] Key password = s3cr3t' in ret_o, 'check output error5.') + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd('rm -rf print_ini* file.ini') diff --git a/tests/apps/inih/tc_inih_fun_002.py b/tests/apps/inih/tc_inih_fun_002.py new file mode 100644 index 0000000000000000000000000000000000000000..6eb6fb588e635e22a5bc1cbce153610874ecfc18 --- /dev/null +++ b/tests/apps/inih/tc_inih_fun_002.py @@ -0,0 +1,68 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_inih_fun_002.py +@Time: 2024/04/02 16:51:50 +@Author: zhixin +@Version: 1.0 +@Contact: zx01468051@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: zhixin +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_inih_fun_002.yaml for details + + :avocado: tags=fix,P3,noarch,local + """ + PARAM_DIC = {"pkg_name": "inih inih-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = """cat > myapp.cpp < +#include + +int main() { + INIReader reader("example.ini"); + + if (reader.ParseError() < 0) { + std::cout << "Can't load 'example.ini'\\n"; + return 1; + } + + std::string name = reader.Get("owner", "name", "UNKNOWN"); + std::string organization = reader.Get("owner", "organization", "UNKNOWN"); + + std::cout << "Owner name: " << name << "\\n" + << "Organization: " << organization << std::endl; + + return 0; +} +EOF""" + self.cmd(cmdline) + cmdline = """cat > example.ini << EOF +[owner] +name=John Doe +organization=Acme Widgets Inc. +EOF""" + self.cmd(cmdline) + + def test(self): + self.cmd('g++ myapp.cpp -o myapp -lINIReader') + ret_c, ret_o = self.cmd('ldd ./myapp') + self.assertTrue("libINIReader.so.0" in ret_o, 'check output error1.') + self.assertTrue("libinih.so.0" in ret_o, 'check output error2.') + ret_c, ret_o = self.cmd('./myapp') + self.assertTrue("Owner name: John Doe\nOrganization: Acme Widgets Inc." == ret_o, 'check output error3.') + self.cmd('rm -rf example.ini') + self.cmd('./myapp > result.log 2>&1', ignore_status=True) + ret_c, ret_o = self.cmd('cat result.log') + self.assertIn("Can't load 'example.ini'", ret_o) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd('rm -rf myapp* example.ini result.log') diff --git a/tests/apps/inih/tc_inih_fun_003.py b/tests/apps/inih/tc_inih_fun_003.py new file mode 100644 index 0000000000000000000000000000000000000000..4ecaa90f8cf870c7a137e499ebd7193d5cfe4ea2 --- /dev/null +++ b/tests/apps/inih/tc_inih_fun_003.py @@ -0,0 +1,76 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_inih_fun_003.py +@Time: 2024/04/01 14:51:50 +@Author: zhixin +@Version: 1.0 +@Contact: zx01468051@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: zhixin +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_inih_fun_003.yaml for details + + :avocado: tags=fix,P3,noarch,local + """ + PARAM_DIC = {"pkg_name": "inih inih-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = """cat > print_ini.c < +#include + +// 定义解析INI文件时的回调函数 +static int handler(void* user, const char* section, const char* name, const char* value) +{ + printf("Section [%s] Key %s = %s\\n", section, name, value); + return 1; // 返回1表示成功解析 +} + +int main(int argc, char* argv[]) +{ + if (argc < 2) { + fputs("Usage: print_ini \\n", stderr); + return 1; + } + + if (ini_parse(argv[1], handler, NULL) < 0) { + printf("Can't load '%s' file\\n", argv[1]); + return 1; + } + return 0; +} +EOF""" + self.cmd(cmdline) + cmdline = """cat > file.ini << EOF +[database] +server=127.0.0.1 +port=3306 +user=root +user=root +#name=John +password=s3cr3t +[owner] +name=John Doe +organization=Acme Widgets Inc. +EOF""" + self.cmd(cmdline) + + def test(self): + self.cmd('gcc print_ini.c -o print_ini -linih') + self.cmd('./print_ini file.ini > result.log') + ret_c, ret_o = self.cmd('cat result.log') + self.assertTrue("Section [database] Key name = John" not in ret_o, 'check output error1.') + self.assertTrue("Section [owner] Key name = John Doe" in ret_o, 'check output error2.') + ret_c, ret_o = self.cmd("cat result.log |grep 'Key user = root' |wc -l") + self.assertTrue("2" == ret_o, 'check output error3.') + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd('rm -rf print_ini* file.ini result.log') diff --git a/tests/apps/inih/tc_inih_fun_004.py b/tests/apps/inih/tc_inih_fun_004.py new file mode 100644 index 0000000000000000000000000000000000000000..85f7f5cb56496747c398f1f23bca57797ac04789 --- /dev/null +++ b/tests/apps/inih/tc_inih_fun_004.py @@ -0,0 +1,78 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_inih_fun_004.py +@Time: 2024/04/01 14:51:50 +@Author: zhixin +@Version: 1.0 +@Contact: zx01468051@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: zhixin +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_inih_fun_004.yaml for details + + :avocado: tags=fix,P3,noarch,local + """ + PARAM_DIC = {"pkg_name": "inih inih-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = """cat > print_ini.c < +#include + +// 定义解析INI文件时的回调函数 +static int handler(void* user, const char* section, const char* name, const char* value) +{ + printf("Section [%s] Key %s = %s\\n", section, name, value); + return 1; // 返回1表示成功解析 +} + +int main(int argc, char* argv[]) +{ + if (argc < 2) { + fputs("Usage: print_ini \\n", stderr); + return 1; + } + + if (ini_parse(argv[1], handler, NULL) < 0) { + printf("Can't load '%s' file\\n", argv[1]); + return 1; + } + return 0; +} +EOF""" + self.cmd(cmdline) + cmdline = """cat > file_end_txt.txt << EOF +[owner] +name=John Doe +organization=Acme Widgets Inc. +EOF""" + self.cmd(cmdline) + cmdline = """cat > file_no_header.ini << EOF +name=John Doe +organization=Acme Widgets Inc. +EOF""" + self.cmd(cmdline) + + def test(self): + self.cmd('gcc print_ini.c -o print_ini -linih') + # run with non-existent file + self.cmd('./print_ini aaa.ini > result.log 2>&1', ignore_status=True) + ret_c, ret_o = self.cmd('cat result.log') + self.assertIn("Can't load 'aaa.ini' file", ret_o) + # run files ending in txt + ret_c, ret_o = self.cmd('./print_ini file_end_txt.txt') + self.assertTrue("Section [owner] Key name = John Doe\nSection [owner] Key organization = Acme Widgets Inc." == ret_o, 'check output error1.') + # run with no header file + ret_c, ret_o = self.cmd('./print_ini file_no_header.ini') + self.assertTrue("Section [] Key name = John Doe\nSection [] Key organization = Acme Widgets Inc." == ret_o, 'check output error2.') + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd('rm -rf print_ini* file_end_txt.txt file_no_header.ini result.log') diff --git a/tests/apps/polkit-pkla-compat/tc_polkit_pkla_compat_func001.py b/tests/apps/polkit-pkla-compat/tc_polkit_pkla_compat_func001.py new file mode 100644 index 0000000000000000000000000000000000000000..70424624d07f0423f267835efcdccfd8aacaf015 --- /dev/null +++ b/tests/apps/polkit-pkla-compat/tc_polkit_pkla_compat_func001.py @@ -0,0 +1,49 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_polkit_pkla_compat_func001.py +@Time: 2024/04/29 14:11:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_polkit_pkla_compat_func001.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "polkit-pkla-compat cloud-init"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = """cat > /etc/polkit-1/localauthority/50-local.d/allow_ghm_cloud-init.pkla < /etc/polkit-1/localauthority/50-local.d/allow_testuser_timedatectl.pkla < /etc/polkit-1/localauthority/50-local.d/allow_syslog_viewer_journalctl.pkla < /tmp/ghm/test_tpm2_tss.c < +#include +#include +#include +#include +#include +#include + +int main() { + TSS2_RC rc; + TSS2_TCTI_CONTEXT *tctiContext = NULL; + TSS2_SYS_CONTEXT *sysContext = NULL; + size_t size; + + printf("TPM2-TSS Example Running\\n"); + + //初始化TCTI + rc = Tss2_TctiLdr_Initialize("tabrmd", &tctiContext); + if (rc != TSS2_RC_SUCCESS) { + fprintf(stderr, "Failed to initialize TCTI: 0x%x\\n", rc); + return 1; + } + + // 计算SYS上下文所需大小并分配 + size = Tss2_Sys_GetContextSize(0); + sysContext = (TSS2_SYS_CONTEXT*)malloc(size); + if (!sysContext) { + fprintf(stderr, "Memory allocation failed\\n"); + Tss2_TctiLdr_Finalize(&tctiContext); + return 1; + } + + // 初始化SYS上下文 + rc = Tss2_Sys_Initialize(sysContext, size, tctiContext, NULL); + if (rc != TSS2_RC_SUCCESS) { + fprintf(stderr, "Failed to initialize Sys Context: 0x%x\\n", rc); + free(sysContext); + Tss2_TctiLdr_Finalize(&tctiContext); + return 1; + } + + printf("TPM2-TSS Context Initialized Successfully\\n"); + + // 清理资源 + Tss2_Sys_Finalize(sysContext); + free(sysContext); + Tss2_TctiLdr_Finalize(&tctiContext); + + return 0; +} +""" + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o /tmp/ghm/test_tpm2_tss /tmp/ghm/test_tpm2_tss.c -ltss2-esys -ltss2-tcti-mssim -ltss2-tcti-device -ltss2-tctildr -ltss2-sys") + ret_o = subprocess.run("/tmp/ghm/test_tpm2_tss", capture_output=True, shell=True) + self.log.info(ret_o) + self.assertIn(b'TPM2-TSS Example Running', ret_o.stdout) + self.assertIn(b'ERROR:tcti', ret_o.stderr) + self.assertIn(b'Failed to initialize TCTI', ret_o.stderr) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") + \ No newline at end of file diff --git a/tests/apps/tpm2-tss/tc_tpm2_tss_func002.py b/tests/apps/tpm2-tss/tc_tpm2_tss_func002.py new file mode 100644 index 0000000000000000000000000000000000000000..ed31c3e232121baf50872cdedf804101444b74d6 --- /dev/null +++ b/tests/apps/tpm2-tss/tc_tpm2_tss_func002.py @@ -0,0 +1,57 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_tpm2_tss_func002.py +@Time: 2024/04/28 15:31:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_tpm2_tss_func002.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "tpm2-tss-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline = """cat > /tmp/ghm/test_tpm2_tss.c < +#include // 或其他包含TSS2_ABI_VERSION定义的头文件 + +int main() { + // 直接访问TSS2_ABI_VERSION_CURRENT宏来获取当前版本信息 + TSS2_ABI_VERSION currentVersion = TSS2_ABI_VERSION_CURRENT; + + printf("TPM2-TSS Library ABI Version:\\n"); + printf("Creator: %u\\n", currentVersion.tssCreator); + printf("Family: %u\\n", currentVersion.tssFamily); + printf("Level: %u\\n", currentVersion.tssLevel); + printf("Version: %u\\n", currentVersion.tssVersion); + + return 0; +} +""" + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o /tmp/ghm/test_tpm2_tss /tmp/ghm/test_tpm2_tss.c") + ret_c, ret_o = self.cmd("/tmp/ghm/test_tpm2_tss") + self.log.info(ret_o) + self.assertIn("Creator: 1", ret_o) + self.assertIn("Family: 2", ret_o) + self.assertIn("Level: 1", ret_o) + self.assertIn("Version: 108", ret_o) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") + \ No newline at end of file diff --git a/tests/apps_libraries/c-ares/tc_c-ares_fun_001.py b/tests/apps_libraries/c-ares/tc_c-ares_fun_001.py new file mode 100644 index 0000000000000000000000000000000000000000..6740bdfc485928c8936b63f1f6f8b4a5ac3ba1e3 --- /dev/null +++ b/tests/apps_libraries/c-ares/tc_c-ares_fun_001.py @@ -0,0 +1,108 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_c-ares_fun_001.py +@Time: 2024/04/08 14:51:50 +@Author: zhixin +@Version: 1.0 +@Contact: zx01468051@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: zhixin +""" + +from common.basetest import LocalTest +import re + +class Test(LocalTest): + """ + See tc_c-ares_fun_001.yaml for details + + :avocado: tags=fix,P3,noarch,local + """ + PARAM_DIC = {"pkg_name": "c-ares c-ares-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = """cat > dnsquery.c < +#include +#include +#include + +void callback(void *arg, int status, int timeouts, struct hostent *host) { + if(!host || status != ARES_SUCCESS) { + printf("Failed to lookup: %s\\n", ares_strerror(status)); + return; + } + + printf("Found address name %s\\n", host->h_name); + for (int i = 0; host->h_addr_list[i]; ++i) { + struct in_addr addr; + addr.s_addr = *(in_addr_t *) host->h_addr_list[i]; + printf("Found address: %s\\n", inet_ntoa(addr)); + } +} + +int main(int argc, char **argv) { + ares_channel channel; + int status; + + // 初始化 c-ares + status = ares_library_init(ARES_LIB_INIT_ALL); + if (status != ARES_SUCCESS) { + printf("ares_library_init: %s\\n", ares_strerror(status)); + return 1; + } + + // 创建 c-ares 通道 + status = ares_init(&channel); + if(status != ARES_SUCCESS) { + printf("ares_init: %s\\n", ares_strerror(status)); + return 1; + } + + // 开始解析 + ares_gethostbyname(channel, "www.example.com", AF_INET, callback, NULL); + + // 等待所有解析完成 + for(;;) { + struct timeval *tvp, tv; + fd_set read_fds, write_fds; + int nfds; + + FD_ZERO(&read_fds); + FD_ZERO(&write_fds); + nfds = ares_fds(channel, &read_fds, &write_fds); + + if(nfds == 0) { + break; + } + + tvp = ares_timeout(channel, NULL, &tv); + select(nfds, &read_fds, &write_fds, NULL, tvp); + + // 处理事件 + ares_process(channel, &read_fds, &write_fds); + } + + // 清理 + ares_destroy(channel); + ares_library_cleanup(); + return 0; +} +EOF""" + + self.cmd(cmdline) + + def test(self): + self.cmd('gcc -o dnsquery dnsquery.c -lcares') + ret_c, ret_o = self.cmd('ldd ./dnsquery') + self.assertTrue('libcares.so.2' in ret_o, 'check output error1.') + ret_c, ret_o = self.cmd('./dnsquery') + self.assertTrue('Found address name www.example.com' in ret_o, 'check output error2.') + search_ip = "Found address:\s+[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" + self.assertTrue(re.compile(search_ip).search(ret_o), 'check output error3.') + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd('rm -rf dnsquery*') diff --git a/tests/apps_libraries/c-ares/tc_c-ares_fun_002.py b/tests/apps_libraries/c-ares/tc_c-ares_fun_002.py new file mode 100644 index 0000000000000000000000000000000000000000..c23434c324f542123eeed9f9623646ed67daf1af --- /dev/null +++ b/tests/apps_libraries/c-ares/tc_c-ares_fun_002.py @@ -0,0 +1,101 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_c-ares_fun_002.py +@Time: 2024/04/09 14:31:50 +@Author: zhixin +@Version: 1.0 +@Contact: zx01468051@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: zhixin +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_c-ares_fun_002.yaml for details + + :avocado: tags=fix,P3,noarch,local + """ + PARAM_DIC = {"pkg_name": "c-ares c-ares-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = """cat > nonvalid.c < +#include +#include + +void query_callback(void *arg, int status, int timeouts, unsigned char *abuf, int alen) { + char* domain = (char*)arg; + if (status != ARES_SUCCESS) { + fprintf(stderr, "Domain %s: %s\\n", domain, ares_strerror(status)); + } else { + fprintf(stderr, "Domain %s: Unexpected successful response\\n", domain); + } +} + +int main(void) { + ares_channel channel; + int status; + + status = ares_library_init(ARES_LIB_INIT_ALL); + if (status != ARES_SUCCESS) { + fprintf(stderr, "ares_library_init failed: %s\\n", ares_strerror(status)); + return 1; + } + + status = ares_init(&channel); + if (status != ARES_SUCCESS) { + fprintf(stderr, "ares_init failed: %s\\n", ares_strerror(status)); + return 1; + } + + // 准备一组无效域名进行测试 + const char* invalid_domains[] = { + "invalid_domain", // 格式错误 + "unlikely-exist-123457.com", // 很可能不存在 + "no-this-site-abcdefg.net" // 很可能不存在 + }; + + for (int i = 0; i < sizeof(invalid_domains)/sizeof(invalid_domains[0]); ++i) { + ares_query(channel, invalid_domains[i], ns_c_in, ns_t_a, query_callback, + (void*)invalid_domains[i]); + } + + // 事件循环处理DNS响应 + for (;;) { + struct timeval *tvp, tv; + fd_set read_fds, write_fds; + + FD_ZERO(&read_fds); + FD_ZERO(&write_fds); + int nfds = ares_fds(channel, &read_fds, &write_fds); + if (nfds == 0) + break; + + tvp = ares_timeout(channel, NULL, &tv); + select(nfds, &read_fds, &write_fds, NULL, tvp); + ares_process(channel, &read_fds, &write_fds); + } + + ares_destroy(channel); + ares_library_cleanup(); + return 0; +} +EOF""" + + self.cmd(cmdline) + + def test(self): + self.cmd('gcc -o nonvalid nonvalid.c -lcares') + self.cmd('./nonvalid > result.log 2>&1', ignore_status=True) + ret_c, ret_o = self.cmd('cat result.log') + self.assertTrue('Domain no-this-site-abcdefg.net: Domain name not found' in ret_o, 'check output error1.') + self.assertTrue('Domain unlikely-exist-123457.com: Domain name not found' in ret_o, 'check output error2.') + self.assertTrue('Domain invalid_domain: Could not contact DNS servers' in ret_o, 'check output error3.') + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd('rm -rf nonvalid* result.log') diff --git a/tests/apps_libraries/c-ares/tc_c-ares_fun_003.py b/tests/apps_libraries/c-ares/tc_c-ares_fun_003.py new file mode 100644 index 0000000000000000000000000000000000000000..4faf0fdecebb632c7d80f63f42238cbe8ff3feae --- /dev/null +++ b/tests/apps_libraries/c-ares/tc_c-ares_fun_003.py @@ -0,0 +1,148 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_c-ares_fun_003.py +@Time: 2024/04/10 14:31:50 +@Author: zhixin +@Version: 1.0 +@Contact: zx01468051@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: zhixin +""" + +from common.basetest import LocalTest +import re + +class Test(LocalTest): + """ + See tc_c-ares_fun_003.yaml for details + + :avocado: tags=fix,P3,noarch,local + """ + PARAM_DIC = {"pkg_name": "c-ares c-ares-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = """cat > query_dns.c < +#include +#include +#include +#include +#include +#include +#include + +// A记录的回调 +void a_record_callback(void* arg, int status, int timeouts, unsigned char* abuf, int alen) { + struct hostent* host = NULL; + char* query = (char*) arg; + + if(status == ARES_SUCCESS) { + status = ares_parse_a_reply(abuf, alen, &host, NULL, NULL); + if(status == ARES_SUCCESS) { + printf("A record for %s: %s\\n", query, inet_ntoa(*(struct in_addr*)host->h_addr)); + free(host); + } + } + if(status != ARES_SUCCESS) { + fprintf(stderr, "Failed to find A record for %s with status: %s\\n", query, ares_strerror(status)); + } +} + +// AAAA记录的回调 +void aaaa_record_callback(void* arg, int status, int timeouts, unsigned char* abuf, int alen) { + struct hostent* host = NULL; + char ip[INET6_ADDRSTRLEN]; + char* query = (char*) arg; + + if(status == ARES_SUCCESS) { + status = ares_parse_aaaa_reply(abuf, alen, &host, NULL, NULL); + if(status == ARES_SUCCESS) { + inet_ntop(AF_INET6, host->h_addr, ip, INET6_ADDRSTRLEN); + printf("AAAA record for %s: %s\\n", query, ip); + free(host); + } + } + if(status != ARES_SUCCESS) { + fprintf(stderr, "Failed to find AAAA record for %s with status: %s\\n", query, ares_strerror(status)); + } +} + +// MX记录的回调 +void mx_record_callback(void* arg, int status, int timeouts, unsigned char* abuf, int alen) { + struct ares_mx_reply* mx_reply = NULL; + char* query = (char*) arg; + + if(status == ARES_SUCCESS) { + status = ares_parse_mx_reply(abuf, alen, &mx_reply); + if(status == ARES_SUCCESS) { + printf("MX record for %s: %s with priority %u\\n", query, mx_reply->host, mx_reply->priority); + ares_free_data(mx_reply); + } + } + if(status != ARES_SUCCESS) { + fprintf(stderr, "Failed to find MX record for %s with status: %s\\n", query, ares_strerror(status)); + } +} + +int main(int argc, char* argv[]) { + if(argc != 2) { + printf("Usage: %s \\n", argv[0]); + exit(1); + } + + ares_channel channel; + int status = ares_library_init(ARES_LIB_INIT_ALL); + if(status != ARES_SUCCESS) return 1; + + status = ares_init(&channel); + if(status != ARES_SUCCESS) return 1; + + // 查询指定的DNS记录类型 + ares_query(channel, argv[1], ns_c_in, ns_t_a, a_record_callback, strdup(argv[1])); + ares_query(channel, argv[1], ns_c_in, ns_t_aaaa, aaaa_record_callback, strdup(argv[1])); + ares_query(channel, argv[1], ns_c_in, ns_t_mx, mx_record_callback, strdup(argv[1])); + + // 处理响应 + for(;;) { + struct timeval* tvp, tv; + fd_set read_fds, write_fds; + FD_ZERO(&read_fds); + FD_ZERO(&write_fds); + int nfds = ares_fds(channel, &read_fds, &write_fds); + if(nfds == 0) + break; + tvp = ares_timeout(channel, NULL, &tv); + select(nfds, &read_fds, &write_fds, NULL, tvp); + ares_process(channel, &read_fds, &write_fds); + } + + // 清理 + ares_destroy(channel); + ares_library_cleanup(); + return 0; +} +EOF""" + self.cmd(cmdline) + + def test(self): + self.cmd('gcc -o query_dns query_dns.c -lcares') + # run with valid domain + self.cmd('./query_dns www.example.com > result.log 2>&1', ignore_status=True) + ret_c, ret_o = self.cmd('cat result.log') + search_ip = "A record for www.example.com:\s+[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" + search_ipv6 = "AAAA record for www.example.com:\s[0-9]+:[0-9]+" + self.assertTrue(re.compile(search_ipv6).search(ret_o), 'check output error1') + self.assertTrue(re.compile(search_ip).search(ret_o), 'check output error2') + self.assertTrue('Failed to find MX record for www.example.com with status: DNS server returned answer with no data' in ret_o, 'check output error3') + # run with invalid domain + self.cmd('./query_dns invalid_domain > result.log 2>&1', ignore_status=True) + ret_c, ret_o = self.cmd('cat result.log') + self.assertIn('Failed to find AAAA record for invalid_domain with status: Domain name not found', ret_o) + self.assertIn('Failed to find MX record for invalid_domain with status: Domain name not found', ret_o) + self.assertIn('Failed to find A record for invalid_domain with status: Could not contact DNS servers', ret_o) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd('rm -rf query_dns* result.log') diff --git a/tests/apps_libraries/c-ares/tc_c-ares_fun_004.py b/tests/apps_libraries/c-ares/tc_c-ares_fun_004.py new file mode 100644 index 0000000000000000000000000000000000000000..3c5fc65711158261f5870fe240f8e4ce359cd799 --- /dev/null +++ b/tests/apps_libraries/c-ares/tc_c-ares_fun_004.py @@ -0,0 +1,118 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_c-ares_fun_004.py +@Time: 2024/04/10 17:31:50 +@Author: zhixin +@Version: 1.0 +@Contact: zx01468051@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: zhixin +""" + +from common.basetest import LocalTest +import re + +class Test(LocalTest): + """ + See tc_c-ares_fun_004.yaml for details + + :avocado: tags=fix,P3,noarch,local + """ + PARAM_DIC = {"pkg_name": "c-ares c-ares-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = """cat > query.c < +#include +#include +#include +#include +#include +#include + +void callback(void *arg, int status, int timeouts, struct hostent *host) { + if(!host || status != ARES_SUCCESS) { + printf("Failed to lookup %s\\n", ares_strerror(status)); + return; + } + + printf("Found address name %s\\n", host->h_name); + for (int i = 0; host->h_addr_list[i]; ++i) { + char ip[INET6_ADDRSTRLEN]; + inet_ntop(host->h_addrtype, host->h_addr_list[i], ip, sizeof(ip)); + printf("%s\\n", ip); + } +} + +int main(int argc, char **argv) +{ + if(argc != 2) { + printf("Usage: %s \\n", argv[0]); + exit(1); + } + + ares_channel channel; + int status, nfds, count; + fd_set read_fds, write_fds; + struct timeval *tvp, tv; + + /* 初始化 c-ares 库 */ + status = ares_library_init(ARES_LIB_INIT_ALL); + if (status != ARES_SUCCESS) { + fprintf(stderr, "ares_library_init: %s\\n", ares_strerror(status)); + return 1; + } + + /* 创建 channel */ + status = ares_init(&channel); + if (status != ARES_SUCCESS) { + fprintf(stderr, "ares_init: %s\\n", ares_strerror(status)); + return 1; + } + + /* 设置不同的地址类型 */ + ares_gethostbyname(channel, argv[1], AF_INET, callback, NULL); + ares_gethostbyname(channel, argv[1], AF_INET6, callback, NULL); + + /* 主循环处理 */ + while (1) { + FD_ZERO(&read_fds); + FD_ZERO(&write_fds); + nfds = ares_fds(channel, &read_fds, &write_fds); + if (nfds == 0) { + break; + } + tvp = ares_timeout(channel, NULL, &tv); + count = select(nfds, &read_fds, &write_fds, NULL, tvp); + if (count <= 0) { + continue; + } + ares_process(channel, &read_fds, &write_fds); + } + + ares_destroy(channel); + ares_library_cleanup(); + return 0; +} +EOF""" + self.cmd(cmdline) + + def test(self): + self.cmd('gcc -o query query.c -lcares') + # run with valid domain + self.cmd('./query www.example.com > result.log 2>&1') + ret_c, ret_o = self.cmd('cat result.log') + search_ip = "Found address name www.example.com\\n[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" + search_ipv6 = "Found address name www.example.com\\n[0-9]+:[0-9]+" + self.assertTrue(re.compile(search_ipv6).search(ret_o), 'check output error1') + self.assertTrue(re.compile(search_ip).search(ret_o), 'check output error2') + # run with invalid domain + self.cmd('./query invalid_domain > result.log 2>&1', ignore_status=True) + ret_c, ret_o = self.cmd('cat result.log') + self.assertIn('Failed to lookup Misformatted domain name', ret_o) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd('rm -rf query* result.log') diff --git a/tests/apps_libraries/cyrus-sasl/tc_cyrus_sasl_func_001.py b/tests/apps_libraries/cyrus-sasl/tc_cyrus_sasl_func_001.py new file mode 100644 index 0000000000000000000000000000000000000000..3bba18ccf276d6621437bff1db1155f7e881b8dc --- /dev/null +++ b/tests/apps_libraries/cyrus-sasl/tc_cyrus_sasl_func_001.py @@ -0,0 +1,31 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_cyrus_sasl_func_001.py +@Time: 2024/04/15 15:00:00 +@Author: liuhaiyang +@Version: 1.0 +@Contact: lhy01509690@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: liuhaiyang +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_cyrus_sasl_func_001.yaml for details + + :avocado: tags=fix,P3,noarch,local + """ + PARAM_DIC = {"pkg_name": "cyrus-sasl"} + def setUp(self): + super().setUp(self.PARAM_DIC) + + def test(self): + self.cmd("pluginviewer") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + diff --git a/tests/apps_libraries/libaio/tc_libaio_func001.py b/tests/apps_libraries/libaio/tc_libaio_func001.py new file mode 100644 index 0000000000000000000000000000000000000000..f99d8c048487f722bac7d0ee0e14f945ca98b068 --- /dev/null +++ b/tests/apps_libraries/libaio/tc_libaio_func001.py @@ -0,0 +1,95 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libaio_func001.py +@Time: 2024/04/09 13:12:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libaio_func001.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libaio libaio-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline = """cat > /tmp/ghm/test_libaio.c < +#include +#include +#include +#include + +#define EXPECT_SUCCESS 0 +#define EXPECT_FAILURE -1 + +void io_setup_test(int nr_events, int expected_result) { + io_context_t ctx = NULL; + int ret; + + printf("Testing io_setup with nr_events = %d, expecting:", nr_events); + + if (expected_result == EXPECT_SUCCESS) { + printf("success\\n"); + } else { + printf("failure\\n"); + } + + ret = io_setup(nr_events, &ctx); + if (expected_result == EXPECT_SUCCESS) { + if (ret < 0) { + printf("Test failed:io_setup returned %d (%s)\\n", ret, strerror(-ret)); + } else { + printf("Test passed:io_setup returned %d\\n", ret); + io_destroy(ctx); + } + } else { + if (ret >= 0) { + printf("Test failed:io_setup unexpectedly succeeded with return value %d\\n", ret); + io_destroy(ctx); + } else { + // 修改此处:将expected_errno替换为errno + if (errno == expected_result) { + printf("Test passed:io_setup failed with expected errno %d (%s)\\n", errno, strerror(errno)); + } else { + printf("Test failed:io_setup failed with unexpected errno %d (%s), expected %d\\n", errno, strerror(errno), expected_result); + } + } + } +} + +int main() { + // 正常调用测试 + io_setup_test(10, EXPECT_SUCCESS); + + // 参数nr_events小于等于0的测试 + io_setup_test(0, EXPECT_FAILURE); + io_setup_test(-1, EXPECT_FAILURE); + + return 0; +} +""" + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o /tmp/ghm/test_libaio /tmp/ghm/test_libaio.c -laio") + ret_c1, ret_o1 = self.cmd("/tmp/ghm/test_libaio") + self.assertIn("Testing io_setup with nr_events = 10, expecting:success", ret_o1) + self.assertIn("Test passed:io_setup returned 0", ret_o1) + self.assertIn("Testing io_setup with nr_events = 0, expecting:failure", ret_o1) + self.assertIn("Testing io_setup with nr_events = -1, expecting:failure", ret_o1) + self.assertIn("Test failed:io_setup failed with unexpected errno 0 (Success), expected -1", ret_o1) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") \ No newline at end of file diff --git a/tests/apps_libraries/libaio/tc_libaio_func002.py b/tests/apps_libraries/libaio/tc_libaio_func002.py new file mode 100644 index 0000000000000000000000000000000000000000..0d95b8727fb4acc99cec470d2680777b92ccb423 --- /dev/null +++ b/tests/apps_libraries/libaio/tc_libaio_func002.py @@ -0,0 +1,95 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libaio_func002.py +@Time: 2024/04/10 10:12:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libaio_func002.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libaio libaio-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline = """cat > /tmp/ghm/test_libaio.c < +#include +#include +#include +#include +#include +#include + +io_context_t io_ctx; +#define BAD_CTX ((io_context_t)-1) + +void aio_setup(int n) +{ + int res = io_queue_init(n, &io_ctx); + if (res != 0) { + printf("io_queue_setup(%d) returned %d (%s)\\n", + n, res, strerror(-res)); + exit(3); + } +} + +int attempt_io_submit(io_context_t ctx, long nr, struct iocb *ios[], int expect) +{ + int res; + + printf("expect %3d: io_submit(%10p, %3ld, %10p) = ", expect, ctx, nr, ios); + fflush(stdout); + res = io_submit(ctx, nr, ios); + printf("%3d [%s]%s\\n", res, (res <= 0) ? strerror(-res) : "", + (res != expect) ? " -- FAILED" : ""); + if (res != expect) + return 1; + + return 0; +} + +int main(void) +{ + aio_setup(10); + struct iocb a, b; + struct iocb *good_ios[] = { &a, &b }; + struct iocb *bad1_ios[] = { NULL, &b }; + // 替换 KERNEL_RW_POINTER 为已知无效的指针地址 + struct iocb *bad2_ios[] = { (struct iocb *)-1, &a }; + int status = 0; + + status |= attempt_io_submit(BAD_CTX, 1, good_ios, -EINVAL); + status |= attempt_io_submit( io_ctx, 0, good_ios, 0); + status |= attempt_io_submit( io_ctx, 1, NULL, -EFAULT); + status |= attempt_io_submit( io_ctx, 1, (void *)-1, -EFAULT); + status |= attempt_io_submit( io_ctx, 2, bad1_ios, -EFAULT); + status |= attempt_io_submit( io_ctx, 2, bad2_ios, -EFAULT); + status |= attempt_io_submit( io_ctx, -1, good_ios, -EINVAL); + + return status; +} +""" + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o /tmp/ghm/test_libaio /tmp/ghm/test_libaio.c -laio") + ret_c1, ret_o1 = self.cmd("/tmp/ghm/test_libaio", ignore_status=True) + self.assertIn("0 [Success]", ret_o1) + self.assertIn("-14 [Bad address]", ret_o1) + self.assertIn("-22 [Invalid argument]", ret_o1) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") \ No newline at end of file diff --git a/tests/apps_libraries/libaio/tc_libaio_func003.py b/tests/apps_libraries/libaio/tc_libaio_func003.py new file mode 100644 index 0000000000000000000000000000000000000000..00f776d71186d15677b0fcaed79a66c8fc839616 --- /dev/null +++ b/tests/apps_libraries/libaio/tc_libaio_func003.py @@ -0,0 +1,197 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libaio_func003.py +@Time: 2024/04/10 13:12:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libaio_func003.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libaio libaio-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline = """cat > /tmp/ghm/test_libaio.c < +#include +#include +#include +#include +#include +#include +#include + +io_context_t io_ctx; +#define BAD_CTX ((io_context_t)-1) +#define SETUP aio_setup(1024) +#define READ 'r' +#define WRITE 'w' +#define READ_SILENT 'R' +#define WRITE_SILENT 'W' +#define READV '<' +#define WRITEV '>' + + +void aio_setup(int n) +{ + int res = io_queue_init(n, &io_ctx); + if (res != 0) { + printf("io_queue_setup(%d) returned %d (%s)\\n", + n, res, strerror(-res)); + exit(3); + } +} + +int sync_submit(struct iocb *iocb) +{ + struct io_event event; + struct iocb *iocbs[] = { iocb }; + int res; + + /* 30 second timeout should be enough */ + struct timespec ts; + ts.tv_sec = 30; + ts.tv_nsec = 0; + + res = io_submit(io_ctx, 1, iocbs); + if (res != 1) { + printf("sync_submit: io_submit res=%d [%s]\\n", res, strerror(-res)); + return res; + } + + res = io_getevents(io_ctx, 0, 1, &event, &ts); + if (res != 1) { + printf("sync_submit: io_getevents res=%d [%s]\\n", res, strerror(-res)); + return res; + } + return event.res; +} + +int attempt_rw(int fd, void *buf, int count, long long pos, int rw, int expect) +{ + struct iocb iocb; + int res; + int silent = 0; + + switch(rw) { + case READ_SILENT: + silent = 1; + case READ: + io_prep_pread (&iocb, fd, buf, count, pos); + break; + case WRITE_SILENT: + silent = 1; + case WRITE: + io_prep_pwrite(&iocb, fd, buf, count, pos); + break; + case WRITEV: + io_prep_pwritev(&iocb, fd, buf, count, pos); + break; + case READV: + io_prep_preadv(&iocb, fd, buf, count, pos); + break; + } + + if (!silent) { + printf("expect %5d: (%c), res = ", expect, rw); + fflush(stdout); + } + res = sync_submit(&iocb); + if (!silent || res != expect) { + if (silent) + printf("expect %5d: (%c), res = ", expect, rw); + printf("%5d [%s]%s\\n", res, + (res <= 0) ? strerror(-res) : "Success", + (res != expect) ? " -- FAILED" : ""); + } + + if (res != expect) + return 1; + + return 0; +} + +int main(void) +{ + SETUP; + int page_size = getpagesize(); +#define SIZE 512 + char *buf; + int rwfd; + int status = 0, res; + + rwfd = open("/tmp/ghm/rwfile", O_RDWR); assert(rwfd != -1); + res = ftruncate(rwfd, 512); assert(res == 0); + + buf = mmap(0, page_size, PROT_READ|PROT_WRITE, MAP_SHARED, rwfd, 0); + assert(buf != (char *)-1); + + status |= attempt_rw(rwfd, buf, SIZE, 0, WRITE, SIZE); + status |= attempt_rw(rwfd, buf, SIZE, 0, READ, SIZE); + + res = munmap(buf, page_size); assert(res == 0); + buf = mmap(0, page_size, PROT_READ|PROT_WRITE, MAP_SHARED, rwfd, 0); + assert(buf != (char *)-1); + + status |= attempt_rw(rwfd, buf, SIZE, 0, READ, SIZE); + status |= attempt_rw(rwfd, buf, SIZE, 0, WRITE, SIZE); + + res = munmap(buf, page_size); assert(res == 0); + buf = mmap(0, page_size, PROT_READ, MAP_SHARED, rwfd, 0); + assert(buf != (char *)-1); + + status |= attempt_rw(rwfd, buf, SIZE, 0, WRITE, SIZE); + status |= attempt_rw(rwfd, buf, SIZE, 0, READ, -EFAULT); + + res = munmap(buf, page_size); assert(res == 0); + buf = mmap(0, page_size, PROT_WRITE, MAP_SHARED, rwfd, 0); + assert(buf != (char *)-1); + + /* Whether PROT_WRITE is readable is arch-dependent. So compare + * against write() result (to make the kernel read from buf). */ + res = write(rwfd, buf, SIZE); + if (res < 0) + res = -errno; + status |= attempt_rw(rwfd, buf, SIZE, 0, READ, SIZE); + status |= attempt_rw(rwfd, buf, SIZE, 0, WRITE, res); + + return status; +} +""" + self.cmd(cmdline) + + def test(self): + self.cmd("touch /tmp/ghm/rwfile") + self.cmd("gcc -o /tmp/ghm/test_libaio /tmp/ghm/test_libaio.c -laio") + ret_c1, ret_o1 = self.cmd("/tmp/ghm/test_libaio") + self.expected_re1 = """ +expect 512: (w), res = 512 [Success] +expect 512: (r), res = 512 [Success] +expect 512: (r), res = 512 [Success] +expect 512: (w), res = 512 [Success] +expect 512: (w), res = 512 [Success] +expect -14: (r), res = -14 [Bad address] +expect 512: (r), res = 512 [Success] +expect 512: (w), res = 512 [Success] +""" + actual_res1 = ret_o1.strip().splitlines() + expected_res1 = self.expected_re1.strip().splitlines() + for expected1 in expected_res1: + self.assertIn(expected1, actual_res1) + self.log.info("%s exist." % expected1) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") \ No newline at end of file diff --git a/tests/apps_libraries/libaio/tc_libaio_func004.py b/tests/apps_libraries/libaio/tc_libaio_func004.py new file mode 100644 index 0000000000000000000000000000000000000000..9841c963a0e48394481b1eede76d3777831287a5 --- /dev/null +++ b/tests/apps_libraries/libaio/tc_libaio_func004.py @@ -0,0 +1,170 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libaio_func004.py +@Time: 2024/04/10 13:12:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libaio_func004.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libaio libaio-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline = """cat > /tmp/ghm/test_libaio.c < +#include +#include +#include +#include +#include +#include +#include + +io_context_t io_ctx; +#define BAD_CTX ((io_context_t)-1) +#define SETUP aio_setup(1024) + +void aio_setup(int n) +{ + int res = io_queue_init(n, &io_ctx); + if (res != 0) { + printf("io_queue_setup(%d) returned %d (%s)\\n", + n, res, strerror(-res)); + exit(3); + } +} + +int sync_submit(struct iocb *iocb) +{ + struct io_event event; + struct iocb *iocbs[] = { iocb }; + int res; + + struct timespec ts; + ts.tv_sec = 30; + ts.tv_nsec = 0; + + res = io_submit(io_ctx, 1, iocbs); + if (res != 1) { + printf("sync_submit: io_submit res=%d [%s]\\n", res, strerror(-res)); + return res; + } + + res = io_getevents(io_ctx, 0, 1, &event, &ts); + if (res != 1) { + printf("sync_submit: io_getevents res=%d [%s]\\n", res, strerror(-res)); + return res; + } + return event.res; +} + +#define SIZE 512 +#define READ 'r' +#define WRITE 'w' +int attempt(int fd, void *buf, int count, long long pos, int rw, int expect) +{ + struct iocb iocb; + int res; + + switch(rw) { + case READ: io_prep_pread (&iocb, fd, buf, count, pos); break; + case WRITE: io_prep_pwrite(&iocb, fd, buf, count, pos); break; + } + + printf("expect %3d: (%c), res = ", expect, rw); + fflush(stdout); + res = sync_submit(&iocb); + printf("%3d [%s]%s\\n", res, (res <= 0) ? strerror(-res) : "Success", + (res != expect) ? " -- FAILED" : ""); + if (res != expect) + return 1; + + return 0; +} + +int main(void) +{ + SETUP; + char buf[SIZE]; + int rofd, wofd, rwfd; + int status = 0, res; + + memset(buf, 0, SIZE); + + rofd = open("/tmp/ghm/rofile", O_RDONLY); assert(rofd != -1); + wofd = open("/tmp/ghm/wofile", O_WRONLY); assert(wofd != -1); + rwfd = open("/tmp/ghm/rwfile", O_RDWR); assert(rwfd != -1); + + status |= attempt(rofd, buf, SIZE, 0, WRITE, -EBADF); + status |= attempt(wofd, buf, SIZE, 0, READ, -EBADF); + status |= attempt(rwfd, buf, SIZE, 0, WRITE, SIZE); + status |= attempt(rwfd, buf, SIZE, 0, READ, SIZE); + status |= attempt(rwfd, buf, SIZE, -1, READ, -EINVAL); + status |= attempt(rwfd, buf, SIZE, -1, WRITE, -EINVAL); + + rwfd = open("/tmp/ghm/rwfile", O_RDWR|O_APPEND); assert(rwfd != -1); + res = ftruncate(rwfd, 0); assert(res == 0); + status |= attempt(rwfd, buf, SIZE, 0, READ, 0); + status |= attempt(rwfd, "1234", 4, 0, WRITE, 4); + status |= attempt(rwfd, "5678", 4, 0, WRITE, 4); + memset(buf, 0, SIZE); + status |= attempt(rwfd, buf, SIZE, 0, READ, 8); + printf("read after append: [%s]\\n", buf); + assert(memcmp(buf, "12345678", 8) == 0); + + /* Some architectures map the 0 page. Ugh. */ +#if !defined(__ia64__) + status |= attempt(rwfd, NULL, SIZE, 0, WRITE, -EFAULT); +#endif + + return status; +} +""" + self.cmd(cmdline) + + def test(self): + self.cmd("touch /tmp/ghm/rofile") + self.cmd("touch /tmp/ghm/wofile") + self.cmd("touch /tmp/ghm/rwfile") + self.cmd("gcc -o /tmp/ghm/test_libaio /tmp/ghm/test_libaio.c -laio") + ret_c1, ret_o1 = self.cmd("/tmp/ghm/test_libaio") + self.expected_re1 = """ +expect -9: (w), res = sync_submit: io_submit res=-9 [Bad file descriptor] + -9 [Bad file descriptor] +expect -9: (r), res = sync_submit: io_submit res=-9 [Bad file descriptor] + -9 [Bad file descriptor] +expect 512: (w), res = 512 [Success] +expect 512: (r), res = 512 [Success] +expect -22: (r), res = sync_submit: io_submit res=-22 [Invalid argument] +-22 [Invalid argument] +expect -22: (w), res = sync_submit: io_submit res=-22 [Invalid argument] +-22 [Invalid argument] +expect 0: (r), res = 0 [Success] +expect 4: (w), res = 4 [Success] +expect 4: (w), res = 4 [Success] +expect 8: (r), res = 8 [Success] +read after append: [12345678] +expect -14: (w), res = -14 [Bad address] +""" + actual_res1 = ret_o1.strip().splitlines() + expected_res1 = self.expected_re1.strip().splitlines() + for expected1 in expected_res1: + self.assertIn(expected1, actual_res1) + self.log.info("%s exist." % expected1) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") \ No newline at end of file diff --git a/tests/apps_libraries/libcbor/tc_libcbor_func001.py b/tests/apps_libraries/libcbor/tc_libcbor_func001.py new file mode 100644 index 0000000000000000000000000000000000000000..3db4bb42f0c5c0f0c8a5ec9b1c75b58bd2ea5b46 --- /dev/null +++ b/tests/apps_libraries/libcbor/tc_libcbor_func001.py @@ -0,0 +1,46 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libcbor_func001.py +@Time: 2024/04/03 16:12:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libcbor_func001.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libcbor libcbor-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline = """cat > /tmp/ghm/test_libcbor.c < +#include "cbor.h" + +int main(void) { + printf("Hello from libcbor %s\\n", CBOR_VERSION); + printf("Pretty-printer support: %s\\n", CBOR_PRETTY_PRINTER ? "yes" : "no"); + printf("Buffer growth factor: %f\\n", (float)CBOR_BUFFER_GROWTH); +} +""" + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o /tmp/ghm/test_libcbor /tmp/ghm/test_libcbor.c -lcbor") + ret_c1, ret_o1 = self.cmd("/tmp/ghm/test_libcbor") + self.assertIn("Hello from libcbor", ret_o1) + self.assertIn("Pretty-printer support", ret_o1) + self.assertIn("Buffer growth factor", ret_o1) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") \ No newline at end of file diff --git a/tests/apps_libraries/libcbor/tc_libcbor_func002.py b/tests/apps_libraries/libcbor/tc_libcbor_func002.py new file mode 100644 index 0000000000000000000000000000000000000000..7dbfe6ca5962423f16efb4ddc18faa2039332d4e --- /dev/null +++ b/tests/apps_libraries/libcbor/tc_libcbor_func002.py @@ -0,0 +1,79 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libcbor_func002.py +@Time: 2024/04/03 18:02:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libcbor_func002.yaml for details + + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libcbor libcbor-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline = """cat > /tmp/ghm/test_libcbor.c < +#include +#include "cbor.h" + +int compareUint(const void *a, const void *b) { + uint8_t av = cbor_get_uint8(*(cbor_item_t **)a), + bv = cbor_get_uint8(*(cbor_item_t **)b); + + if (av < bv) + return -1; + else if (av == bv) + return 0; + else + return 1; +} + +int main(void) { + cbor_item_t *array = cbor_new_definite_array(4); + bool success = cbor_array_push(array, cbor_move(cbor_build_uint8(4))); + success &= cbor_array_push(array, cbor_move(cbor_build_uint8(3))); + success &= cbor_array_push(array, cbor_move(cbor_build_uint8(1))); + success &= cbor_array_push(array, cbor_move(cbor_build_uint8(2))); + if (!success) return 1; + + qsort(cbor_array_handle(array), cbor_array_size(array), sizeof(cbor_item_t *), + compareUint); + + cbor_describe(array, stdout); + fflush(stdout); +} +""" + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o /tmp/ghm/test_libcbor /tmp/ghm/test_libcbor.c -lcbor") + ret_c1, ret_o1 = self.cmd("/tmp/ghm/test_libcbor") + expected_result1 = """ + [CBOR_TYPE_ARRAY] Definite, size: 4 + [CBOR_TYPE_UINT] Width: 1B, Value: 1 + [CBOR_TYPE_UINT] Width: 1B, Value: 2 + [CBOR_TYPE_UINT] Width: 1B, Value: 3 + [CBOR_TYPE_UINT] Width: 1B, Value: 4 +""" + actual_lines = ret_o1.strip().split('\n') + expected_lines = expected_result1.strip().split('\n') + self.assertEqual(len(actual_lines), len(expected_lines)) + for actual_line, expected_line in zip(actual_lines, expected_lines): + self.assertEqual(actual_line, expected_line) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") \ No newline at end of file diff --git a/tests/apps_libraries/libcbor/tc_libcbor_func003.py b/tests/apps_libraries/libcbor/tc_libcbor_func003.py new file mode 100644 index 0000000000000000000000000000000000000000..075fc79259e0e561dff67f3b697519af312a3383 --- /dev/null +++ b/tests/apps_libraries/libcbor/tc_libcbor_func003.py @@ -0,0 +1,67 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libcbor_func003.py +@Time: 2024/04/07 10:02:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" + +import subprocess +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libcbor_func003.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libcbor libcbor-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline = """cat > /tmp/ghm/test_libcbor.c < +#include "cbor.h" + +int main(void) { + cbor_item_t* root = cbor_new_definite_map(2); + bool success = cbor_map_add( + root, (struct cbor_pair){ + .key = cbor_move(cbor_build_string("Is CBOR awesome?\\n")), + .value = cbor_move(cbor_build_bool(true))}); + success &= cbor_map_add( + root, (struct cbor_pair){ + .key = cbor_move(cbor_build_uint8(42)), + .value = cbor_move(cbor_build_string("Is the answer\\n"))}); + if (!success) return 1; + unsigned char* buffer; + size_t buffer_size; + cbor_serialize_alloc(root, &buffer, &buffer_size); + + fwrite(buffer, 1, buffer_size, stdout); + free(buffer); + + fflush(stdout); + cbor_decref(&root); +} +""" + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o /tmp/ghm/test_libcbor /tmp/ghm/test_libcbor.c -lcbor") + ret_o1 = subprocess.run("/tmp/ghm/test_libcbor", capture_output=True, shell=True) + self.log.info(type(ret_o1.stdout)) + self.a = b'Is CBOR awesome?' + self.b = b'Is the answer' + self.assertIn(self.a, ret_o1.stdout) + self.assertIn(self.b, ret_o1.stdout) + self.log.info(ret_o1.stdout) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") \ No newline at end of file diff --git a/tests/apps_libraries/libcbor/tc_libcbor_func004.py b/tests/apps_libraries/libcbor/tc_libcbor_func004.py new file mode 100644 index 0000000000000000000000000000000000000000..bb4dc4d31df252ae629a284a31263506a889eab7 --- /dev/null +++ b/tests/apps_libraries/libcbor/tc_libcbor_func004.py @@ -0,0 +1,112 @@ + #!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libcbor_func004.py +@Time: 2024/04/08 13:12:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" + +import subprocess +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libcbor_func004.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libcbor libcbor-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline = """cat > /tmp/ghm/test_libcbor.c < +#include "cbor.h" + +void usage(void) { + printf("Usage: readfile [input file]\\n"); + exit(1); +} + +int main(int argc, char* argv[]) { + if (argc != 2) usage(); + FILE* f = fopen(argv[1], "rb"); + if (f == NULL) usage(); + fseek(f, 0, SEEK_END); + size_t length = (size_t)ftell(f); + fseek(f, 0, SEEK_SET); + unsigned char* buffer = malloc(length); + fread(buffer, length, 1, f); + + struct cbor_load_result result; + cbor_item_t* item = cbor_load(buffer, length, &result); + free(buffer); + + if (result.error.code != CBOR_ERR_NONE) { + printf( + "There was an error while reading the input near byte %zu (read %zu " + "bytes in total): ", + result.error.position, result.read); + switch (result.error.code) { + case CBOR_ERR_MALFORMATED: { + printf("Malformed data\\n"); + break; + } + case CBOR_ERR_MEMERROR: { + printf("Memory error -- perhaps the input is too large?\\n"); + break; + } + case CBOR_ERR_NODATA: { + printf("The input is empty\\n"); + break; + } + case CBOR_ERR_NOTENOUGHDATA: { + printf("Data seem to be missing -- is the input complete?\\n"); + break; + } + case CBOR_ERR_SYNTAXERROR: { + printf("Syntactically malformed data -- see\\n"); + break; + } + case CBOR_ERR_NONE: { + break; + } + } + exit(1); + } + + cbor_describe(item, stdout); + fflush(stdout); + cbor_decref(&item); + + fclose(f); +} +""" + self.cmd(cmdline) + + def test(self): + self.cmd("echo 'ehello' > /tmp/ghm/test01.cbor") + self.cmd("touch /tmp/ghm/test02.cbor") + self.cmd("echo 't2024-04-08T20:04:00Z' > /tmp/ghm/test03.cbor") + self.cmd("echo 't1234566' > /tmp/ghm/test04.cbor") + self.cmd("gcc -o /tmp/ghm/test_libcbor /tmp/ghm/test_libcbor.c -lcbor") + ret_c1, ret_o1 = self.cmd("/tmp/ghm/test_libcbor /tmp/ghm/test01.cbor") + self.assertIn("CBOR_TYPE_STRING", ret_o1) + self.assertIn("hello", ret_o1) + ret_o2 = subprocess.run("/tmp/ghm/test_libcbor /tmp/ghm/test02.cbor", capture_output=True, shell=True, text=True) + self.assertIn("The input is empty", ret_o2.stdout) + self.log.info(ret_o2.stdout) + ret_c3, ret_o3 = self.cmd("/tmp/ghm/test_libcbor /tmp/ghm/test03.cbor") + self.assertIn("2024-04-08T20:04:00", ret_o3) + ret_o4 = subprocess.run("/tmp/ghm/test_libcbor /tmp/ghm/test04.cbor", capture_output=True, shell=True, text=True) + self.assertIn("Data seem to be missing -- is the input complete?", ret_o4.stdout) + self.log.info(ret_o4.stdout) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") \ No newline at end of file diff --git a/tests/apps_libraries/libcbor/tc_libcbor_func005.py b/tests/apps_libraries/libcbor/tc_libcbor_func005.py new file mode 100644 index 0000000000000000000000000000000000000000..855b6454c4545b317931f652fc4d09ab018ca29b --- /dev/null +++ b/tests/apps_libraries/libcbor/tc_libcbor_func005.py @@ -0,0 +1,82 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libcbor_func005.py +@Time: 2024/04/08 16:12:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" +import subprocess +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libcbor_func005.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libcbor libcbor-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline = """cat > /tmp/ghm/test_libcbor.c < +#include "cbor.h" + +void usage(void) { + printf("Usage: streaming_array \\n"); + printf("Prints out serialized array [0, ..., N-1]\\n"); + exit(1); +} + +#define BUFFER_SIZE 8 +unsigned char buffer[BUFFER_SIZE]; +FILE* out; + +void flush(size_t bytes) { + if (bytes == 0) exit(1); // All items should be successfully encoded + if (fwrite(buffer, sizeof(unsigned char), bytes, out) != bytes) exit(1); + if (fflush(out)) exit(1); +} + + +int main(int argc, char* argv[]) { + if (argc != 2) usage(); + long n = strtol(argv[1], NULL, 10); + out = freopen(NULL, "wb", stdout); + if (!out) exit(1); + + // Start an indefinite-length array + flush(cbor_encode_indef_array_start(buffer, BUFFER_SIZE)); + printf("\\ncbor \\n"); + for (size_t i = 0; i < n; i++) { + flush(cbor_encode_uint32(i, buffer, BUFFER_SIZE)); + } + + // Close the array + flush(cbor_encode_break(buffer, BUFFER_SIZE)); + printf("\\nthe input is <%d>\\n", n); + if (fclose(out)) exit(1); +} +""" + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o /tmp/ghm/test_libcbor /tmp/ghm/test_libcbor.c -lcbor") + ret_o1 = subprocess.run("/tmp/ghm/test_libcbor", capture_output=True, shell=True) + self.re = b'Usage: streaming_array ' + self.assertIn(self.re, ret_o1.stdout) + ret_o2 = subprocess.run("/tmp/ghm/test_libcbor 8", capture_output=True, shell=True) + self.re1 = b'the input is <8>' + self.re2 = b'cbor' + self.assertIn(self.re1, ret_o2.stdout) + self.assertIn(self.re2, ret_o2.stdout) + self.log.info(ret_o2.stdout) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") \ No newline at end of file diff --git a/tests/apps_libraries/libkcapi/tc_libkcapi_func001.py b/tests/apps_libraries/libkcapi/tc_libkcapi_func001.py new file mode 100644 index 0000000000000000000000000000000000000000..677f7bbfa31a86368346f41b6ec07a4efd8783dd --- /dev/null +++ b/tests/apps_libraries/libkcapi/tc_libkcapi_func001.py @@ -0,0 +1,209 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libkcapi_func001.py +@Time: 2024/04/17 11:31:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libkcapi_func001.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libkcapi libkcapi-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline = """cat > /tmp/ghm/test_libkcapi.c < +#include +#include +#include + +static int hashtest(void) +{ + char *in = "teststring"; + uint8_t out[64]; + ssize_t ret; + + ret = kcapi_md_sha1((uint8_t*)in, strlen(in), out, sizeof(out)); + if (ret != 20) { + printf("SHA-1 error"); + return 1; + } + + ret = kcapi_md_sha224((uint8_t*)in, strlen(in), out, sizeof(out)); + if (ret != 28) { + printf("SHA-224 error"); + return 1; + } + + ret = kcapi_md_sha256((uint8_t*)in, strlen(in), out, sizeof(out)); + if (ret != 32) { + printf("SHA-256 error"); + return 1; + } + + ret = kcapi_md_sha384((uint8_t*)in, strlen(in), out, sizeof(out)); + if (ret != 48) { + printf("SHA-384 error"); + return 1; + } + + ret = kcapi_md_sha512((uint8_t*)in, strlen(in), out, sizeof(out)); + if (ret != 64) { + printf("SHA-512 error"); + return 1; + } + + return 0; +} + +static int hmactest(void) +{ + char *in = "longteststring"; + uint8_t out[64]; + ssize_t ret; + + ret = kcapi_md_hmac_sha1((uint8_t*)in, (uint32_t)strlen(in), + (uint8_t*)in, strlen(in), out, sizeof(out)); + if (ret != 20) { + printf("HMAC SHA-1 error"); + return 1; + } + + ret = kcapi_md_hmac_sha224((uint8_t*)in, (uint32_t)strlen(in), + (uint8_t*)in, strlen(in), out, sizeof(out)); + if (ret != 28) { + printf("HMAC SHA-224 error"); + return 1; + } + + ret = kcapi_md_hmac_sha256((uint8_t*)in, (uint32_t)strlen(in), + (uint8_t*)in, strlen(in), out, sizeof(out)); + if (ret != 32) { + printf("HMAC SHA-256 error"); + return 1; + } + + ret = kcapi_md_hmac_sha384((uint8_t*)in, (uint32_t)strlen(in), + (uint8_t*)in, strlen(in), out, sizeof(out)); + if (ret != 48) { + printf("HMAC SHA-384 error"); + return 1; + } + + ret = kcapi_md_hmac_sha512((uint8_t*)in, (uint32_t)strlen(in), + (uint8_t*)in, strlen(in), out, sizeof(out)); + if (ret != 64) { + printf("HMAC SHA-512 error"); + return 1; + } + + return 0; +} + +static int ciphertest(void) +{ + uint8_t *origpt = (uint8_t *)"01234567890123450123456789012345"; + uint8_t ct[32]; + uint8_t newpt[32]; + ssize_t ret; + + ret = kcapi_cipher_enc_aes_cbc(origpt, 32, origpt, 32, origpt, + ct, sizeof(ct)); + if (ret != sizeof(ct)) { + printf("AES CBC encrytion error"); + return 1; + } + + ret = kcapi_cipher_dec_aes_cbc(origpt, 32, ct, sizeof(ct), origpt, + newpt, sizeof(newpt)); + if (ret != sizeof(newpt) || memcmp(origpt, newpt, sizeof(newpt))) { + printf("AES CBC decrytion error"); + return 1; + } + + ret = kcapi_cipher_enc_aes_ctr(origpt, 32, origpt, 32, origpt, ct, + sizeof(ct)); + if (ret != sizeof(ct)) { + printf("AES CTR encrytion error"); + return 1; + } + + ret = kcapi_cipher_dec_aes_ctr(origpt, 32, ct, sizeof(ct), origpt, + newpt, sizeof(newpt)); + if (ret != sizeof(newpt) || memcmp(origpt, newpt, sizeof(newpt))) { + printf("AES CTR decrytion error"); + return 1; + } + + return 0; +} + +static int rngtest(void) +{ + uint8_t out[67]; + ssize_t ret; + + ret = kcapi_rng_get_bytes(out, sizeof(out)); + if (ret != sizeof(out)) { + printf("Random number generation error"); + return 1; + } + + return 0; +} + +int main(int argc, char *argv[]) +{ + int ret; + + (void)argc; + (void)argv; + + ret = hashtest(); + printf("hash success\\n"); + if (ret) + return ret; + + ret = hmactest(); + printf("hmac success\\n"); + if (ret) + return ret; + + ret = ciphertest(); + printf("cipher success\\n"); + if (ret) + return ret; + + ret = rngtest(); + printf("Random number generation success\\n"); + if (ret) + return ret; + + return 0; +} +""" + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o /tmp/ghm/test_libkcapi /tmp/ghm/test_libkcapi.c -lkcapi") + ret_c, ret_o = self.cmd("/tmp/ghm/test_libkcapi") + self.assertIn("hash success", ret_o) + self.assertIn("hmac success", ret_o) + self.assertIn("cipher success", ret_o) + self.assertIn("Random number generation success", ret_o) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") diff --git a/tests/apps_libraries/libkcapi/tc_libkcapi_func002.py b/tests/apps_libraries/libkcapi/tc_libkcapi_func002.py new file mode 100644 index 0000000000000000000000000000000000000000..81241575452af6d3276d1f9ff3c8b255b78e4e74 --- /dev/null +++ b/tests/apps_libraries/libkcapi/tc_libkcapi_func002.py @@ -0,0 +1,84 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libkcapi_func002.py +@Time: 2024/04/17 16:31:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libkcapi_func002.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libkcapi libkcapi-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline = """cat > /tmp/ghm/test_libkcapi.c < +#include + +int main(int argc, char *argv[]) +{ + char buf[8192]; + struct kcapi_handle *handle; + struct iovec iov; + ssize_t ret; + int i; + + (void)argc; + (void)argv; + + iov.iov_base = buf; + + ret = kcapi_cipher_init(&handle, "cbc(aes)", 0); + if (ret) + return (int)ret; + + ret = kcapi_cipher_setkey(handle, (unsigned char *)"0123456789abcdef", 16); + if (ret) + return (int)ret; + + ret = kcapi_cipher_stream_init_enc(handle, (unsigned char *)"0123456789abcdef", NULL, 0); + if (ret < 0) + return (int)ret; + + for (i = 0; i < 50; i++) { + printf("round %d\\n", i); + + iov.iov_len = 6182; + ret = kcapi_cipher_stream_update(handle, &iov, 1); + if (ret < 0) + return (int)ret; + + iov.iov_len = 6182; + ret = kcapi_cipher_stream_op(handle, &iov, 1); + if (ret < 0) + return (int)ret; + } + + kcapi_cipher_destroy(handle); + + return 0; +} +""" + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o /tmp/ghm/test_libkcapi /tmp/ghm/test_libkcapi.c -lkcapi") + ret_c, ret_o = self.cmd("/tmp/ghm/test_libkcapi") + self.assertIn("round 0", ret_o) + self.assertIn("round 49", ret_o) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") diff --git a/tests/apps_libraries/libkcapi/tc_libkcapi_func003.py b/tests/apps_libraries/libkcapi/tc_libkcapi_func003.py new file mode 100644 index 0000000000000000000000000000000000000000..e825de41f85f3c6b9bfe02c6f792ab774871688c --- /dev/null +++ b/tests/apps_libraries/libkcapi/tc_libkcapi_func003.py @@ -0,0 +1,72 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libkcapi_func003.py +@Time: 2024/04/18 10:31:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libkcapi_func003.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libkcapi libkcapi-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline = """cat > /tmp/ghm/test_libkcapi.c < +#include +#include +#include "kcapi.h" + +#define PASSWORD "my_password" +#define SALT "a_salt_string" +#define KEY_LEN 32 +#define ITERATIONS 10000 // Example iteration count + +int main() { + uint8_t password[strlen(PASSWORD)]; + uint8_t salt[strlen(SALT)]; + uint8_t key[KEY_LEN]; + + // Convert strings to binary arrays + strncpy((char*)password, PASSWORD, sizeof(password)); + password[strlen(PASSWORD)] = '\\0'; + strncpy((char*)salt, SALT, sizeof(salt)); + salt[strlen(SALT)] = '\\0'; + + // Call kcapi_pbkdf function + ssize_t ret = kcapi_pbkdf("hmac(sha256)", password, strlen(PASSWORD), salt, strlen(SALT), ITERATIONS, key, KEY_LEN); + if (ret < 0) { + fprintf(stderr, "Error deriving key using kcapi_pbkdf: %ld\\n", (long)ret); + return EXIT_FAILURE; + } + + printf("Derived key (%zu bytes): ", KEY_LEN); + for(size_t i = 0; i < KEY_LEN; ++i) + printf("%02x", key[i]); + printf("\\n"); + + return EXIT_SUCCESS; +} +""" + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o /tmp/ghm/test_libkcapi /tmp/ghm/test_libkcapi.c -lkcapi") + ret_c, ret_o = self.cmd("/tmp/ghm/test_libkcapi") + self.assertIn("Derived key (32 bytes)", ret_o) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") diff --git a/tests/apps_libraries/libkcapi/tc_libkcapi_func004.py b/tests/apps_libraries/libkcapi/tc_libkcapi_func004.py new file mode 100644 index 0000000000000000000000000000000000000000..f73add2dd91e1f3462688d751b879aed4bcc26bf --- /dev/null +++ b/tests/apps_libraries/libkcapi/tc_libkcapi_func004.py @@ -0,0 +1,98 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libkcapi_func004.py +@Time: 2024/04/18 14:31:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libkcapi_func004.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libkcapi libkcapi-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline = """cat > /tmp/ghm/test_libkcapi.c < +#include +#include +#include +#include "kcapi.h" + +#define PASSWORD "my_password" +#define SALT "a_salt_string" +#define KEY_LEN 32 +#define LABEL "ExampleLabel" +#define CONTEXT "SomeContextData" +#define SHARED_SECRET "ThisIsTheSharedSecret" +#define DIGEST_SIZE 32 // 假设使用的哈希函数的digest大小 + +int main() { + struct kcapi_handle *handle; + ssize_t ret; + uint8_t derived_key[KEY_LEN]; + uint8_t src[strlen(LABEL) + 1 + strlen(CONTEXT) + 1]; // 不需要SHARED_SECRET,因为这是SP800-108的用法 + uint8_t hmac_key[DIGEST_SIZE]; // 创建一个密钥缓冲区,大小等于digest大小 + + // 填充密钥(这里仅做示例,实际应用中应从可靠源获取或生成密钥) + memset(hmac_key, 0x00, DIGEST_SIZE); + + // 将数据填充到src缓冲区 + memcpy(src, LABEL, strlen(LABEL)); + src[strlen(LABEL)] = '\\0'; // 添加0x00分隔符 + memcpy(src + strlen(LABEL) + 1, CONTEXT, strlen(CONTEXT) + 1); + + // 初始化KC-API句柄 + handle = NULL; + ret = kcapi_md_init(&handle, "hmac(sha256)", 0); // 参数3暂时留空,根据实际需求设置 + if (ret < 0) { + perror("Failed to initialize kcapi_handle"); + return EXIT_FAILURE; + } + + // 设置密钥,即使对于SP800-108可能不直接使用 + ret = kcapi_md_setkey(handle, hmac_key, DIGEST_SIZE); + if (ret < 0) { + perror("Failed to set key for HMAC-SHA256"); + kcapi_md_destroy(handle); + return EXIT_FAILURE; + } + + // 示例:使用kcapi_kdf_ctr() + ret = kcapi_kdf_ctr(handle, src, strlen(LABEL) + 1 + strlen(CONTEXT) + 1, derived_key, KEY_LEN); + if (ret < 0) { + perror("Error deriving key using kcapi_kdf_ctr:"); + } else { + printf("Derived key using kcapi_kdf_ctr (%zu bytes): ", KEY_LEN); + for(size_t i = 0; i < KEY_LEN; ++i) + printf("%02x", derived_key[i]); + printf("\\n"); + } + + // 释放KC-API句柄资源 + kcapi_md_destroy(handle); + + return EXIT_SUCCESS; +} +""" + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o /tmp/ghm/test_libkcapi /tmp/ghm/test_libkcapi.c -lkcapi") + ret_c, ret_o = self.cmd("/tmp/ghm/test_libkcapi") + self.assertIn("Derived key using kcapi_kdf_ctr (32 bytes)", ret_o) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") diff --git a/tests/apps_libraries/protobuf-c/tc_protobuf_c_func001.py b/tests/apps_libraries/protobuf-c/tc_protobuf_c_func001.py new file mode 100644 index 0000000000000000000000000000000000000000..fdc1a475d1dd5fd771e63d7c59027cac25921c0a --- /dev/null +++ b/tests/apps_libraries/protobuf-c/tc_protobuf_c_func001.py @@ -0,0 +1,91 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_protobuf_c_func001.py +@Time: 2024/03/22 14:12:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_protobuf_c_func001.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "protobuf-c protobuf-c-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline1 = """cat > /tmp/ghm/my_message.proto < /tmp/ghm/test_my_message.c < +#include +#include "my_message.pb-c.h" +#include +int main() { + MyPackage__MyMessage *message = (MyPackage__MyMessage *) malloc(sizeof(MyPackage__MyMessage)); + if (message == NULL) { + perror("Failed to allocate memory for message\\n"); + return 1; + } + // 注意:这里假设MyPackage__MyMessage的descriptor全局可见 + message->base.descriptor = &my_package__my_message__descriptor; + // 填充字段 + message->name = strdup("Test Message"); + message->id = 42; + // 计算并分配足够的内存来存储序列化后的数据 + size_t packed_size = my_package__my_message__get_packed_size(message); + uint8_t *buffer = malloc(packed_size); + // 序列化到缓冲区 + if (!my_package__my_message__pack(message, buffer)) { + printf("Failed to pack the message.\\n"); + free(message->name); // 释放之前分配的name字符串 + free(message); + free(buffer); + return EXIT_FAILURE; + } + // 解码 + MyPackage__MyMessage *parsed_message = my_package__my_message__unpack(NULL, packed_size, buffer); + assert(parsed_message != NULL); + assert(strcmp(parsed_message->name, message->name) == 0); + assert(parsed_message->id == message->id); + // 清理资源 + free(message->name); + free(message); + my_package__my_message__free_unpacked(parsed_message, NULL); + free(buffer); + + printf("MyMessage serialization and deserialization test succeeded.\\n"); + return EXIT_SUCCESS; +} +""" + self.cmd(cmdline2) + + def test(self): + self.cmd("protoc-c --proto_path=/tmp/ghm/ --c_out=/tmp/ghm/ /tmp/ghm/my_message.proto") + ret_c1, ret_o1 = self.cmd("ls -l /tmp/ghm/") + self.assertIn("my_message.pb-c.c", ret_o1) + self.assertIn("my_message.pb-c.h", ret_o1) + self.cmd("gcc -o /tmp/ghm/test_my_message /tmp/ghm/test_my_message.c /tmp/ghm/my_message.pb-c.c -lprotobuf-c") + ret_c2, ret_o2 = self.cmd("/tmp/ghm/test_my_message") + self.assertIn("MyMessage serialization and deserialization test succeeded.", ret_o2) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") \ No newline at end of file diff --git a/tests/apps_libraries/protobuf-c/tc_protobuf_c_func002.py b/tests/apps_libraries/protobuf-c/tc_protobuf_c_func002.py new file mode 100644 index 0000000000000000000000000000000000000000..fdbb6f7fe618cb8dcb0b1d058da97698ba1109b6 --- /dev/null +++ b/tests/apps_libraries/protobuf-c/tc_protobuf_c_func002.py @@ -0,0 +1,140 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_protobuf_c_func002.py +@Time: 2024/03/22 16:12:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_protobuf_c_func002.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "protobuf-c protobuf-c-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline1 = """cat > /tmp/ghm/enums.proto < /tmp/ghm/my_message.proto < /tmp/ghm/test_my_message.c < +#include +#include +#include "enums.pb-c.h" +#include "my_message.pb-c.h" + +// 自定义的字符串复制函数 +static inline char* my_strdup(const char* src) { + size_t len = strlen(src); + char* dest = (char*)malloc(len + 1); + if (dest) { + memcpy(dest, src, len + 1); + } + return dest; +} + +int main() { + // 创建并初始化MyMessage + MyMessage *message = (MyMessage*) calloc(1, sizeof(MyMessage)); + if (message == NULL) { + fprintf(stderr, "Failed to allocate memory for MyMessage.\\n"); + return EXIT_FAILURE; + } + + // 初始化MyMessage结构体 + my_message__init(message); + + // 设置基础字段 + message->name = my_strdup("A Custom Message"); + if (message->name == NULL) { + fprintf(stderr, "Failed to allocate memory for name field.\\n"); + goto cleanup; + } + + // 设置oneof字段(模拟扩展) + message->custom_data_case = MY_MESSAGE__CUSTOM_DATA_FAVORITE_COLOR; + message->favorite_color = MY_PACKAGE__COLOR__GREEN; + + // 序列化与反序列化 + size_t packed_size = my_message__get_packed_size(message); + uint8_t *buffer = malloc(packed_size); + if (!my_message__pack(message, buffer)) { + fprintf(stderr, "Failed to pack the message.\\n"); + goto cleanup; + } + + // 反序列化 + MyMessage *parsed_message = my_message__unpack(NULL, packed_size, buffer); + if (!parsed_message) { + fprintf(stderr, "Failed to unpack the message.\\n"); + goto cleanup; + } + + // 验证oneof字段是否正确恢复 + if (parsed_message->custom_data_case == MY_MESSAGE__CUSTOM_DATA_FAVORITE_COLOR) { + assert(parsed_message->favorite_color == MY_PACKAGE__COLOR__GREEN); + } else { + fprintf(stderr, "Favorite color was not correctly deserialized.\\n"); + goto cleanup; + } + +cleanup: + // 清理资源 + my_message__free_unpacked(parsed_message, NULL); + my_message__free_unpacked(message, NULL); + free(buffer); + + // 如果能到达这里,说明测试通过 + printf("MyMessage serialization and deserialization test succeeded.\\n"); + return EXIT_SUCCESS; +} +""" + self.cmd(cmdline3) + + def test(self): + self.cmd("protoc-c --proto_path=/tmp/ghm/ --c_out=/tmp/ghm/ /tmp/ghm/enums.proto") + self.cmd("protoc-c --proto_path=/tmp/ghm/ --c_out=/tmp/ghm/ /tmp/ghm/my_message.proto") + ret_c1, ret_o1 = self.cmd("ls -l /tmp/ghm/") + self.assertIn("enums.pb-c.c", ret_o1) + self.assertIn("enums.pb-c.h", ret_o1) + self.assertIn("my_message.pb-c.c", ret_o1) + self.assertIn("my_message.pb-c.h", ret_o1) + self.cmd("gcc -o /tmp/ghm/test_my_message /tmp/ghm/test_my_message.c /tmp/ghm/enums.pb-c.c /tmp/ghm/my_message.pb-c.c -lprotobuf-c") + ret_c2, ret_o2 = self.cmd("/tmp/ghm/test_my_message") + self.assertIn("MyMessage serialization and deserialization test succeeded.", ret_o2) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") \ No newline at end of file diff --git a/tests/apps_libraries/protobuf-c/tc_protobuf_c_func003.py b/tests/apps_libraries/protobuf-c/tc_protobuf_c_func003.py new file mode 100644 index 0000000000000000000000000000000000000000..a2f2ab9018554ec3385718e435479ac03a164cf4 --- /dev/null +++ b/tests/apps_libraries/protobuf-c/tc_protobuf_c_func003.py @@ -0,0 +1,104 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_protobuf_c_func003.py +@Time: 2024/03/25 10:12:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_protobuf_c_func003.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "protobuf-c protobuf-c-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline1 = """cat > /tmp/ghm/my_message.proto < /tmp/ghm/test_my_message.c < +#include +#include +#include +#include "my_message.pb-c.h" + +int main() { + // 创建一个MyMessage实例并初始化 + MyPackage__MyMessage msg = MY_PACKAGE__MY_MESSAGE__INIT; + msg.field1 = strdup("Test Field 1"); // 假设填充字段1 + msg.field2 = 123; // 假设填充字段2 + + // 计算序列化所需内存大小 + size_t packed_size = my_package__my_message__get_packed_size(&msg); + + if (packed_size == 0) { + fprintf(stderr, "Failed to calculate packed size.\\n"); + goto cleanup; + } + + // 分配足够大的缓冲区并序列化,然后模拟复制到较小的缓冲区 + uint8_t *big_buffer = malloc(packed_size); + if (big_buffer == NULL) { + perror("Failed to allocate memory for the big buffer."); + goto cleanup; + } + + // 序列化到足够大的缓冲区 + if (!my_package__my_message__pack(&msg, big_buffer)) { + fprintf(stderr, "Failed to serialize to a properly sized buffer.\\n"); + free(big_buffer); + goto cleanup; + } + + // 尝试将大缓冲区的内容复制到较小的缓冲区,模拟序列化到不足的缓冲区 + uint8_t *small_buffer = malloc(packed_size - 6); + if (small_buffer == NULL) { + perror("Failed to allocate memory for the small buffer."); + free(big_buffer); + goto cleanup; + } + printf("Expected behavior: Serializing to a buffer smaller than %zu bytes would cause an overflow or unexpected behavior.\\n", packed_size); + + // 在此处释放资源并退出 + free(small_buffer); + free(big_buffer); + goto cleanup; + +// 清理部分(无需改动) +cleanup: + free(msg.field1); + + return 0; +} +""" + self.cmd(cmdline2) + + def test(self): + self.cmd("protoc-c --proto_path=/tmp/ghm/ --c_out=/tmp/ghm/ /tmp/ghm/my_message.proto") + ret_c1, ret_o1 = self.cmd("ls -l /tmp/ghm/") + self.assertIn("my_message.pb-c.c", ret_o1) + self.assertIn("my_message.pb-c.h", ret_o1) + self.cmd("gcc -o /tmp/ghm/test_my_message /tmp/ghm/test_my_message.c /tmp/ghm/my_message.pb-c.c -lprotobuf-c") + ret_c2, ret_o2 = self.cmd("/tmp/ghm/test_my_message") + self.assertIn("Expected behavior: Serializing to a buffer smaller than 16 bytes would cause an overflow or unexpected behavior.", ret_o2) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") \ No newline at end of file diff --git a/tests/apps_libraries/protobuf-c/tc_protobuf_c_func004.py b/tests/apps_libraries/protobuf-c/tc_protobuf_c_func004.py new file mode 100644 index 0000000000000000000000000000000000000000..12cef20ceb16301357990ce53047110b4226ee12 --- /dev/null +++ b/tests/apps_libraries/protobuf-c/tc_protobuf_c_func004.py @@ -0,0 +1,74 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_protobuf_c_func004.py +@Time: 2024/03/25 14:12:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_protobuf_c_func004.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "protobuf-c protobuf-c-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline1 = """cat > /tmp/ghm/my_message.proto < /tmp/ghm/test_my_message.c < +#include +#include +#include +#include "my_message.pb-c.h" + +int main() { + // 创建一个空的序列化数据缓冲区 + size_t empty_buffer_size = 0; + uint8_t *empty_buffer = malloc(empty_buffer_size); + + // 尝试从空缓冲区反序列化 + MyPackage__MyMessage *empty_msg = my_package__my_message__unpack(NULL, empty_buffer_size, empty_buffer); + if (empty_msg == NULL) { + printf("Deserializing from an empty buffer failed.\\n"); + } else { + printf("Deserialization from an empty buffer succeeded.\\n"); + my_package__my_message__free_unpacked(empty_msg, NULL); + } + + free(empty_buffer); + + return 0; +} +""" + self.cmd(cmdline2) + + def test(self): + self.cmd("protoc-c --proto_path=/tmp/ghm/ --c_out=/tmp/ghm/ /tmp/ghm/my_message.proto") + ret_c1, ret_o1 = self.cmd("ls -l /tmp/ghm/") + self.assertIn("my_message.pb-c.c", ret_o1) + self.assertIn("my_message.pb-c.h", ret_o1) + self.cmd("gcc -o /tmp/ghm/test_my_message /tmp/ghm/test_my_message.c /tmp/ghm/my_message.pb-c.c -lprotobuf-c") + ret_c2, ret_o2 = self.cmd("/tmp/ghm/test_my_message") + self.assertIn("Deserialization from an empty buffer succeeded.", ret_o2) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") \ No newline at end of file diff --git a/tests/apps_libraries/slang/tc_slang_slsh_func001.py b/tests/apps_libraries/slang/tc_slang_slsh_func001.py new file mode 100644 index 0000000000000000000000000000000000000000..54dacc60fcf4bdc0191d2098753e1512a51d9ab0 --- /dev/null +++ b/tests/apps_libraries/slang/tc_slang_slsh_func001.py @@ -0,0 +1,38 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_slang_slsh_func001.py +@Time: 2024/04/15 11:12:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" + +from common.basetest import LocalTest +import subprocess + +class Test(LocalTest): + """ + See tc_slang_slsh_func001.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "slang slang-slsh"} + def setUp(self): + super().setUp(self.PARAM_DIC) + + def test(self): + self.cmd("slsh --help", ignore_status=True) + ret_c1, ret_o1 = self.cmd("slsh --version") + self.assertIn("slsh version", ret_o1) + self.assertIn("S-Lang version", ret_o1) + command = "slsh -e 'printf(\"hello\")'" + ret_o2 = subprocess.run(command, capture_output=True, shell=True, text=True) + self.log.info(ret_o2) + self.assertIn("hello", ret_o2.stdout) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) \ No newline at end of file diff --git a/tests/apps_libraries/slang/tc_slang_slsh_func002.py b/tests/apps_libraries/slang/tc_slang_slsh_func002.py new file mode 100644 index 0000000000000000000000000000000000000000..9356055ac63b439383557c75d3c74f59910914fd --- /dev/null +++ b/tests/apps_libraries/slang/tc_slang_slsh_func002.py @@ -0,0 +1,59 @@ + #!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_slang_slsh_func002.py +@Time: 2024/04/15 15:12:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_slang_slsh_func002.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "slang slang-slsh"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline = """cat > /tmp/ghm/test_slang.sl < /tmp/ghm/test_slang.sl < /tmp/ghm/test_slang.sl < /tmp/ghm/test_slang.sl < /tmp/ghm/test") + self.cmd("touch /tmp/ghm/emptytest") + self.cmd("wc -m /tmp/ghm/test") + self.cmd("chmod +x /tmp/ghm/test_slang.sl") + ret_o1 = subprocess.run("slsh /tmp/ghm/test_slang.sl", capture_output=True, shell=True, text=True) + self.log.info(ret_o1) + self.assertIn("2", ret_o1.stdout) + self.assertIn("13", ret_o1.stdout) + self.assertIn("0", ret_o1.stdout) + self.assertIn("failed to open", ret_o1.stderr) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") \ No newline at end of file diff --git a/tests/apps_libraries/snappy/tc_snappy_func001.py b/tests/apps_libraries/snappy/tc_snappy_func001.py new file mode 100644 index 0000000000000000000000000000000000000000..698606024439301086c87e1167bcd041f6eefe7f --- /dev/null +++ b/tests/apps_libraries/snappy/tc_snappy_func001.py @@ -0,0 +1,104 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_snappy_func001.py +@Time: 2024/03/28 14:12:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_snappy_func001.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "snappy snappy-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline = """cat > /tmp/ghm/test_snappy.c < +#include +#include +#include "snappy-c.h" + +//TEST_STRING "This is a test string for Snappy compression." +// 定义多行字符串常量 +#define TEST_STRING "This is snappy test \ +..........\ +000000\ +success" +#define MAX_COMPRESSION_RATIO 1.1 /* 假设最大压缩比为1.1倍,用于避免解压缓冲区过小 */ + +int main(void) { + + // 定义原始数据和缓冲区 + const char* original_data = TEST_STRING; + size_t original_len = strlen(TEST_STRING); + size_t compressed_len = snappy_max_compressed_length(original_len); + char* compressed = malloc(compressed_len); + if (!compressed) { + fprintf(stderr, "Failed to allocate memory for compressed data.\\n"); + return EXIT_FAILURE; + } + size_t decompressed_len = original_len * MAX_COMPRESSION_RATIO; + char* decompressed = malloc(decompressed_len); + if (!decompressed) { + fprintf(stderr, "Failed to allocate memory for decompressed data.\\n"); + free(compressed); + return EXIT_FAILURE; + } + + // 压缩原始数据 + snappy_status compress_status = snappy_compress(original_data, original_len, compressed, &compressed_len); + if (compress_status != SNAPPY_OK) { + fprintf(stderr, "Failed to compress data"); + goto cleanup; + } + printf("Original size: %zu, Compressed size: %zu\\n", original_len, compressed_len); + + // 获取解压缩后的长度 + snappy_status len_status = snappy_uncompressed_length(compressed, compressed_len, &decompressed_len); + if (len_status != SNAPPY_OK) { + goto cleanup; + } + printf("Original size: %zu, Deompressed size: %zu\\n", original_len, decompressed_len); + + // 解压缩数据 + snappy_status uncompress_status = snappy_uncompress(compressed, compressed_len, decompressed, &decompressed_len); + if (uncompress_status != SNAPPY_OK) { + fprintf(stderr, "Failed to decompress data"); + goto cleanup; + } + printf("Original size: %zu, Decompressed actual size: %zu\\n", original_len, decompressed_len); + + // 检查解压后的数据是否与原始数据一致 + if (decompressed_len == original_len && memcmp(original_data, decompressed, original_len) == 0) { + printf("Compression and Decompression successful, data matches!\\n"); + } else { + printf("Decompressed data does not match the original data.\\n"); + } + +cleanup: + free(compressed); + free(decompressed); + return uncompress_status == SNAPPY_OK ? EXIT_SUCCESS : EXIT_FAILURE; +} +""" + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o /tmp/ghm/test_snappy /tmp/ghm/test_snappy.c -lsnappy") + ret_c1, ret_o1 = self.cmd("/tmp/ghm/test_snappy") + self.assertIn("Compression and Decompression successful, data matches!", ret_o1) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") \ No newline at end of file diff --git a/tests/apps_libraries/snappy/tc_snappy_func002.py b/tests/apps_libraries/snappy/tc_snappy_func002.py new file mode 100644 index 0000000000000000000000000000000000000000..ca0aea7ecaa695e370f918848f8c407b55ee677d --- /dev/null +++ b/tests/apps_libraries/snappy/tc_snappy_func002.py @@ -0,0 +1,145 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_snappy_func002.py +@Time: 2024/03/29 10:12:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_snappy_func002.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "snappy snappy-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline = """cat > /tmp/ghm/test_snappy.c < +#include +#include +#include "snappy-c.h" + +#define BLOCK_SIZE (1024 * 1024 * 256) +#define INPUT_FILE "/tmp/ghm/snappy.txt" +#define COMPRESSED_OUTPUT_FILE "/tmp/ghm/snappy_compressed.snappy" +#define DECOMPRESSED_OUTPUT_FILE "/tmp/ghm/snappy_decompressed.txt" + +void test_snappy_512mb_file(void) { + FILE *in_file = fopen(INPUT_FILE, "rb"); + if (!in_file) { + perror("Failed to open input file"); + exit(EXIT_FAILURE); + } + + FILE *out_compressed_file = fopen(COMPRESSED_OUTPUT_FILE, "wb"); + if (!out_compressed_file) { + perror("Failed to open compressed output file"); + fclose(in_file); + exit(EXIT_FAILURE); + } + + FILE *out_decompressed_file = fopen(DECOMPRESSED_OUTPUT_FILE, "wb"); + if (!out_decompressed_file) { + perror("Failed to open decompressed output file"); + fclose(in_file); + fclose(out_compressed_file); + exit(EXIT_FAILURE); + } + + char *input_block = malloc(BLOCK_SIZE); + char *compressed_block = malloc(snappy_max_compressed_length(BLOCK_SIZE)); + size_t compressed_length; + + // 分块读取、压缩并写入压缩文件 + while (1) { + size_t read_length = fread(input_block, 1, BLOCK_SIZE, in_file); + compressed_length = snappy_max_compressed_length(read_length); + if (read_length == 0) { + if (feof(in_file)) { + break; // 到达文件末尾 + } else { + perror("Error reading from input file"); + exit(EXIT_FAILURE); + } + } + + snappy_status status = snappy_compress(input_block, read_length, compressed_block, &compressed_length); + if (status != SNAPPY_OK) { + fprintf(stderr, "Compression failed with status: %d\\n", status); + exit(EXIT_FAILURE); + } + printf("Original size: %zu, compressed actual size: %zu\\n", read_length, compressed_length); + fwrite(compressed_block, 1, compressed_length, out_compressed_file); + } + + // 关闭并重新打开压缩文件以进行解压缩 + fclose(out_compressed_file); + out_compressed_file = fopen(COMPRESSED_OUTPUT_FILE, "rb"); + + size_t decompressed_length; + char *decompressed_block = malloc(BLOCK_SIZE); + + while (1) { + size_t read_length = fread(compressed_block, 1, BLOCK_SIZE, out_compressed_file); + if (read_length == 0) { + if (feof(out_compressed_file)) { + break; // 到达文件末尾 + } else { + perror("Error reading from compressed file"); + exit(EXIT_FAILURE); + } + } + + snappy_uncompressed_length(compressed_block, read_length, &decompressed_length); + decompressed_block = realloc(decompressed_block, decompressed_length); + printf("Original size: %zu, Decompressed size: %zu\\n", BLOCK_SIZE, decompressed_length); + snappy_status status = snappy_uncompress(compressed_block, read_length, decompressed_block, &decompressed_length); + if (status != SNAPPY_OK) { + fprintf(stderr, "Decompression failed with status: %d\\n", status); + exit(EXIT_FAILURE); + } + printf("Original size: %zu, Decompressed actual size: %zu\\n", BLOCK_SIZE, decompressed_length); + fwrite(decompressed_block, 1, decompressed_length, out_decompressed_file); + } + // 检查解压后的数据是否与原始数据一致 + if (decompressed_length == BLOCK_SIZE && memcmp(input_block, decompressed_block, BLOCK_SIZE) == 0) { + printf("Compression and Decompression successful, data matches!\\n"); + } else { + printf("Decompressed data does not match the original data.\\n"); + } + + // 清理资源 + free(input_block); + free(compressed_block); + free(decompressed_block); + fclose(in_file); + fclose(out_compressed_file); + fclose(out_decompressed_file); +} + +int main() { + test_snappy_512mb_file(); + return EXIT_SUCCESS; +} +""" + self.cmd(cmdline) + + def test(self): + self.cmd("yes a | head -c 268435456 > /tmp/ghm/snappy.txt") + self.cmd("gcc -o /tmp/ghm/test_snappy02 /tmp/ghm/test_snappy02.c -lsnappy") + ret_c1, ret_o1 = self.cmd("/tmp/ghm/test_snappy02") + self.assertIn("Compression and Decompression successful, data matches!", ret_o1) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") \ No newline at end of file diff --git a/tests/apps_libraries/snappy/tc_snappy_func003.py b/tests/apps_libraries/snappy/tc_snappy_func003.py new file mode 100644 index 0000000000000000000000000000000000000000..f2e88a7fd5fe5db79bbd26661279e64c48653f7f --- /dev/null +++ b/tests/apps_libraries/snappy/tc_snappy_func003.py @@ -0,0 +1,93 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_snappy_func003.py +@Time: 2024/04/01 10:12:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_snappy_func003.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "snappy snappy-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline1 = """cat > /tmp/ghm/test_snappy_null.c < +#include +#include +#include "snappy-c.h" + +int main() { + // 定义一个空字符串 + char empty_input[1] = {0}; + size_t input_len = 0; + + // 获取压缩后的最大长度(对空输入而言,这个值应该很小,但我们仍然计算它) + size_t compressed_len = snappy_max_compressed_length(input_len); + + // 分配压缩缓冲区 + char* compressed_buffer = malloc(compressed_len); + if (compressed_buffer == NULL) { + fprintf(stderr, "Failed to allocate memory for compressed data.\\n"); + return EXIT_FAILURE; + } + + // 压缩空字符串 + snappy_status compress_status = snappy_compress(empty_input, input_len, compressed_buffer, &compressed_len); + if (compress_status != SNAPPY_OK) { + fprintf(stderr, "Failed to compress empty input properly: %d\\n", compress_status); + free(compressed_buffer); + return EXIT_FAILURE; + } + + // 因为snappy_compress在实际压缩空输入时会更新compressed_length,所以这里可以直接使用 + // 但也可以选择保留原样,因为对空输入来说,压缩后的长度总是0 + + // 计算解压缩所需长度 + size_t decompressed_length; + snappy_status status = snappy_uncompressed_length(compressed_buffer, compressed_len, &decompressed_length); + // 注意:这里使用了正确的变量名 compressed_len 而不是之前错误的 compressed_length + + if (status != SNAPPY_OK) { + fprintf(stderr, "Failed to get decompressed length for empty input: %d\\n", status); + free(compressed_buffer); + return EXIT_FAILURE; + } + + // 验证解压缩长度为0 + if (decompressed_length != 0) { + fprintf(stderr, "Unexpected decompressed length for empty input: %zu (expected 0)\\n", decompressed_length); + free(compressed_buffer); + return EXIT_FAILURE; + } + + printf("Successfully compressed and decompressed empty input.\\n"); + + // 无需解压缩,因为我们知道结果应为空 + + free(compressed_buffer); + return 0; +} +""" + self.cmd(cmdline1) + + def test(self): + self.cmd("gcc -o /tmp/ghm/test_snappy_null /tmp/ghm/test_snappy_null.c -lsnappy") + ret_c1, ret_o1 = self.cmd("/tmp/ghm/test_snappy_null") + self.assertIn("Successfully compressed and decompressed empty input.", ret_o1) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") \ No newline at end of file diff --git a/tests/apps_libraries/snappy/tc_snappy_func004.py b/tests/apps_libraries/snappy/tc_snappy_func004.py new file mode 100644 index 0000000000000000000000000000000000000000..b6ca871db494e184da69f622922e2ee749e43f70 --- /dev/null +++ b/tests/apps_libraries/snappy/tc_snappy_func004.py @@ -0,0 +1,77 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_snappy_func004.py +@Time: 2024/04/01 15:12:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_snappy_func004.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "snappy snappy-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline1 = """cat > /tmp/ghm/test_snappy_small.c < +#include +#include +#include "snappy-c.h" + +#define TEST_DATA "This is a test string for Snappy buffer size test." +#define TEST_DATA_LEN (strlen(TEST_DATA)) + +int main(void) { + // 压缩数据 + char compressed[snappy_max_compressed_length(TEST_DATA_LEN)]; + size_t compressed_len; + snappy_status compress_status = snappy_compress(TEST_DATA, TEST_DATA_LEN, compressed, &compressed_len); + if (compress_status != SNAPPY_OK) { + fprintf(stderr, "Failed to compress data\\n"); + return EXIT_FAILURE; + } + + // 获取解压缩后的预期长度 + size_t expected_decompressed_len; + snappy_status len_status = snappy_uncompressed_length(compressed, compressed_len, &expected_decompressed_len); + if (len_status != SNAPPY_OK) { + fprintf(stderr, "Failed to get decompressed length\\n"); + return EXIT_FAILURE; + } + + // 尝试使用比预期长度小的缓冲区解压缩 + size_t small_buffer_len = expected_decompressed_len - 1; + char small_decompressed[small_buffer_len]; + + snappy_status uncompress_status = snappy_uncompress(compressed, compressed_len, small_decompressed, &small_buffer_len); + if (uncompress_status != SNAPPY_BUFFER_TOO_SMALL) { + fprintf(stderr, "Expected SNAPPY_BUFFER_TOO_SMALL error, but got: %d\\n", uncompress_status); + return EXIT_FAILURE; + } + + printf("Successfully tested that snappy returns SNAPPY_BUFFER_TOO_SMALL when provided with a too small buffer.\\n"); + + return EXIT_SUCCESS; +} +""" + self.cmd(cmdline1) + + def test(self): + self.cmd("gcc -o /tmp/ghm/test_snappy_small /tmp/ghm/test_snappy_small.c -lsnappy") + ret_c1, ret_o1 = self.cmd("/tmp/ghm/test_snappy_small") + self.assertIn("Successfully tested that snappy returns SNAPPY_BUFFER_TOO_SMALL when provided with a too small buffer.", ret_o1) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") \ No newline at end of file diff --git a/tests/common/basetest.py b/tests/common/basetest.py index a95e6a77535d20d4b9e32f2f811104d0e48cbe9a..dd6f69c8543b2c6d953f34ed13a771cd9bd67d61 100644 --- a/tests/common/basetest.py +++ b/tests/common/basetest.py @@ -10,6 +10,7 @@ """ import time +import os from enum import Enum from avocado import Test from common.hosts import LocalHost, RemoteHost @@ -76,13 +77,12 @@ class LocalTest(BaseTest): port=self.params.get('port', default=22), key=self.params.get('key', default=None), password=self.params.get('password')) - self.container_id = None - self.version = self.params.get('registry') self.image = self._get_image_info() + self.container_engine = self.params.get('engine') + self.version = self.params.get('registry') + self.container_id = os.environ.get('TEST_CONTAINER_ID') + self.log.info("从插件获取的数据: %s", self.container_id) self.pkg_name = param_dic.get("pkg_name") - if self.params.get('engine') is not None: - self.container_engine = self.params.get('engine') - self.container_id = Container.create_container(self,self.container_engine,self.image,self.version,self.container_id) if self.pkg_name: self.RPM_FLAG = self.setup_rpm_install(self.pkg_name) @@ -97,8 +97,6 @@ class LocalTest(BaseTest): super().tearDown() if self.pkg_name: self.rpm_uninstall(self.RPM_FLAG) - if self.container_id is not None: - Container.destroy_container(self,self.container_engine,self.container_id,self.version,self.image) def setup_rpm_install(self, pkg_name, flag=0): rpm_flag = {} @@ -166,16 +164,16 @@ class RemoteTest(BaseTest): port=self.params.get('port', default=22), key=self.params.get('key', default=None), password=self.params.get('password')) - self.container_id = None - self.version = self.params.get('registry') + if self.remote.host and self.remote.host != 'localhost': self.session = ssh.Session(self.remote.host, user=self.remote.username, password=self.remote.password) self.session.connect() self.local = LocalHost() self.image = self._get_image_info() - if self.params.get('engine') is not None: - self.container_engine = self.params.get('engine') - self.container_id = Container.create_container(self,self.container_engine,self.image,self.version,self.container_id) + self.container_engine = self.params.get('engine') + self.version = self.params.get('registry') + self.container_id = os.environ.get('TEST_CONTAINER_ID') + self.log.info("从插件获取的数据: %s", self.container_id) self.pkg_name = param_dic.get("pkg_name") if self.pkg_name: self.RPM_FLAG = self.setup_rpm_install(self.pkg_name) @@ -203,8 +201,6 @@ class RemoteTest(BaseTest): super().tearDown() if self.pkg_name: self.rpm_uninstall(self.RPM_FLAG) - if self.container_id is not None: - Container.destroy_container(self,self.container_engine,self.container_id,self.version,self.image) def setup_rpm_install(self, pkg_name, flag=0): rpm_flag = {} diff --git a/tests/common/container.py b/tests/common/container.py index 0eb7be1e4174cc4ae16060a6d3b69053892730aa..0fed427eed606b815a9e9cd70541b3cf6c75cb8c 100644 --- a/tests/common/container.py +++ b/tests/common/container.py @@ -92,7 +92,10 @@ class Container(SysInfo): if ret_c == 0: self.cmd('yum remove docker* -y') self.cmd('yum install -y yum-utils') - self.cmd('yum install podman -y') + self.cmd('yum install podman -y') + ret_c,ret_o = self.cmd("podman ps -q") + if ret_o != "": + self.cmd(f" podman stop {ret_o} && podman rm $(podman ps -a -q) ") if 'tar' in version: self.cmd('wget '+version+' 1>/dev/null 2>&1', ignore_status=True) self.cmd(container_engine+' import '+version.split('/')[-1]+' anolis:23') diff --git a/tests/common/disk.py b/tests/common/disk.py index 827e2bad57fd2c867139aa873227fbcbb0264b3d..8a8a10174e504200b11481da2d4548c1ad087fb1 100644 --- a/tests/common/disk.py +++ b/tests/common/disk.py @@ -9,6 +9,7 @@ @License: Mulan PSL v2 """ +import pexpect from common.sysinfo import SysInfo class DiskManager(): @@ -44,3 +45,27 @@ class DiskManager(): continue else: return disk + + def create_new_part(self, disk, part_type="p", part_num="1", first_sect="", last_sect=""): + child = pexpect.spawn("fdisk %s" % disk) + child.expect(["Command"], timeout=2) + child.sendline("n") + child.sendline("%s" % part_type) + child.sendline("%s" % part_num) + child.sendline("%s" % first_sect) + child.sendline("%s" % last_sect) + child.sendline("w") + child.sendline("q") + new_part = disk + "1" + ret_c, _ = self.cmd("fdisk -l %s" % new_part,ignore_status=True) + return ret_c + + def delete_part(self, disk, part_num="1"): + child = pexpect.spawn("fdisk %s" % disk) + child.expect(["Command"], timeout=2) + child.sendline("d") + i = child.expect(["Partition number", "has been deleted"], timeout=2) + if i == 0: + child.sendline("%s" % part_num) + child.sendline("w") + child.sendline("q") diff --git a/tests/common/gpg.py b/tests/common/gpg.py new file mode 100644 index 0000000000000000000000000000000000000000..30be9fade394da761365f1e1487cab89dd3b26a3 --- /dev/null +++ b/tests/common/gpg.py @@ -0,0 +1,433 @@ +# -*- encoding: utf-8 -*- + +""" +@File: gpg.py +@Time: 2024/03/15 +@Author: Liujiang +@Version: 1.0 +@Contact: Liujiang +@License: Mulan PSL v2 +""" + +import os, binascii, re +import subprocess +from common.sysinfo import SysInfo + +class Gnupg2Manager(object): + def __init__(self) -> None: + self.cmd = SysInfo.cmd() + self.keypair_id = "" + self.pubkey_id = "" + self.subkey_id = "" + self.seckey_id = "" + self.ssbkey_id = "" + + def get_pubkey_id(self, user, host="local", ignore_status=True): + ''' + Get public key ID. + user: Username, user email, or keypair id. + ''' + + _, pubkey_id = self.cmd( + "gpg --with-colons --list-keys %s |awk -F':' '/pub/ {print $5}'" %(user), + ignore_status=ignore_status) + if pubkey_id: + self.pubkey_id = pubkey_id + return pubkey_id + + def get_subkey_id(self, user, host="local", ignore_status=True): + ''' + Get public sub key ID. + user: Username, user email, or keypair id. + ''' + + _, subkey_id = self.cmd( + "gpg --with-colons --list-keys %s |awk -F':' '/sub/ {print $5}'" %(user), + ignore_status=ignore_status) + if subkey_id: + self.subkey_id = subkey_id + return subkey_id + + def get_seckey_id(self, user, host="local", ignore_status=True): + ''' + Get private key ID. + user: Username, user email, or keypair id. + ''' + + _, seckey_id = self.cmd( + "gpg --with-colons --list-secret-keys %s |awk -F':' '/sec/ {print $5}'" %(user), + ignore_status=ignore_status) + if seckey_id: + self.seckey_id = seckey_id + return seckey_id + + def get_ssbkey_id(self, user, host="local", ignore_status=True): + ''' + get private sub key ID + user: Username, user email, or keypair id. + ''' + + _, ssbkey_id = self.cmd( + "gpg --with-colons --list-keys %s |awk -F':' '/ssb/ {print $5}'" %(user), + ignore_status=ignore_status) + if ssbkey_id: + self.seckey_id = ssbkey_id + return ssbkey_id + + def get_keypair_id(self, user, host="local", ignore_status=True): + ''' + get key pair ID + user: Username, user email, or keypair id. + ''' + _, keypair_id = self.cmd( + "gpg --with-colons --list-keys %s |grep 'pub' -A 1 |awk -F':' '/fpr/ {print $10}'" %(user), + ignore_status=ignore_status) + if keypair_id: + self.keypair_id = keypair_id + return keypair_id + + def generate_fixed_parameter_key_pair(self, name, email, testpasswd, host="local", ignore_status=True): + ''' + Generate a fixed parameter key pair + name: User name for generating key pairs + email: Email for generating key pairs + testpasswd: Generate password for key pairs + retrun: Key pair ID list + ''' + + cmdline_generate_params = """cat >key_params.txt<&1") + hex_pattern = r'[0-9a-fA-F]{10,}' + self.keypair_id = re.findall(hex_pattern, gpg_result)[0] + return self.keypair_id + + def delete_key_pair(self, keypair_id, email): + ''' + Used to delete key pairs + keypair_id: + email: The email address for the key + return: Boolean(Ture, False) + ''' + + self.cmd("gpg --batch --yes --delete-secret-and-public-keys %s" %keypair_id) + _, list_keys = self.cmd("gpg --list-keys") + _, list_secret_keys = self.cmd("gpg --list-secret-keys") + if email not in list_keys and email not in list_secret_keys: + return True + else: + return False + + def encryption_data(self, recipient, file, host="local", ignore_status=True): + ''' + Use Gnupg2 data encryption. + recipient: Username, user email, or key id + file: Used for encrypted file. + return: Boolean(Ture, False) + ''' + try: + binascii.unhexlify(recipient) + self.cmd("gpg --encrypt --recipient %s! %s" %(recipient, file), + ignore_status=ignore_status) + except binascii.Error: + self.cmd("gpg --encrypt --recipient %s %s" %(recipient, file), + ignore_status=ignore_status) + encrypted_file = "%s.gpg" %file + if os.path.isfile(encrypted_file) and os.path.getsize(encrypted_file) > 0: + return True + else: + return False + + def decryption_data(self, decrypted_file, testpasswd, host="local", ignore_status=True): + ''' + Use Gnupg2 data dncryption. + decrypted_file: Decrypted files + testpasswd: The password for the key + return: Boolean(Ture, False) + ''' + + file = "%s.txt" %decrypted_file + self.cmd("gpg --batch --yes --pinentry-mode loopback --passphrase" + + " %s --decrypt %s > %s" %(testpasswd, decrypted_file, file)) + if os.path.isfile(file) and os.path.getsize(file) > 0: + return True + else: + return False + + def export_public_key(self, keypair_id, publickey_file, host="local", ignore_status=True): + ''' + Export public key. + keypair_id: The public key ID that needs to be exported + publickey_file: The file that needs to save the public key + return Boolean(Ture, False) + ''' + + self.cmd("gpg --export -a %s > %s" %(keypair_id, publickey_file)) + if os.path.isfile(publickey_file) and os.path.getsize(publickey_file) > 0: + return True + else: + return False + + def import_public_key(self, publickey_file, email, host="local", ignore_status=True): + ''' + Import public key. + publickey_file: The public key file that needs to be imported + email: User email corresponding to public key + return Boolean(Ture, False) + ''' + + self.cmd("gpg --import %s" %publickey_file) + code, list_keys = self.cmd("gpg --list-keys") + if email in list_keys: + return True + else: + return False + + def import_private_key(self, privatekey_file, email, host="local", ignore_status=True): + ''' + Import private key. + publickey_file: The private key file that needs to be imported + email: User email corresponding to public key + return Boolean(Ture, False) + ''' + + self.cmd("gpg --batch --passphrase 'mysecretpassphrase' --import %s" %privatekey_file) + code, list_keys = self.cmd("gpg --list-secret-keys") + if email in list_keys: + return True + else: + return False + + def generate_revocation_certificate(self, user, certificate_file, host="local", ignore_status=True): + ''' + Generate revocation certificate. + user: Username, user email, or keypair id + certificate_file: Used to save revoked certificates + return Boolean(Ture, False) + ''' + + cmdline_generate_revocation_certificate_script = """cat >generate_revocation_certificate.exp< \$arg2\\r"} +} +expect { + "Create a revocation certificate for this key? (y/N) " { send "y\\r";} +} +expect { + "Your decision? " {send "0\\r"} +} +expect { + "> " {send "\\r"} +} +expect { + "Is this okay? (y/N) " {send "y\\r"} +} +expect { + "Passphrase: " {send "mysecretpassphrase\\r"} +} +expect eof +exit +EOF +""" + self.cmd(cmdline_generate_revocation_certificate_script) + self.cmd( + "chmod +x generate_revocation_certificate.exp; " + + "./generate_revocation_certificate.exp %s %s" %(user, certificate_file)) + _, revoke_certificate = self.cmd("file %s" %certificate_file) + self.cmd("rm -f generate_revocation_certificate.exp") + if "PGP public key block Signature" in revoke_certificate: + return True + else: + return False + + def revoke_key_with_certificate(self, certificate, host="local", ignore_status=True): + ''' + Use certificate revocation key + certificate: Specify revocation certificate + return Boolean(Ture, False) + ''' + + self.cmd("gpg --import %s" %certificate) + _, list_keys = self.cmd("gpg --list-secret-keys") + if "revoked:" in list_keys: + return True + else: + return False + + def make_detached_signature(self, user, testpasswd, signature_file, file, host="local", ignore_status=True): + ''' + Make detached signature + user: Username, user email, or keypair id + testpasswd: The password for the key + signature_file: Save signed files + file: Source file + return Boolean(Ture, False) + ''' + + #gpg --local-user johndoe_001@example.com --batch --yes --pinentry-mode loopback + #--passphrase "mysecretpassphrase" --armor --output file.txt.sig --detach-sign file.txt + self.cmd( + "gpg --local-user {_user} --batch --yes --pinentry-mode loopback \ + --passphrase {_passwd} --armor --output {_sig_file} --detach-sign {_file}".format( + _user = user, + _passwd = testpasswd, + _sig_file = signature_file, + _file = file, + ), + ignore_status=ignore_status + ) + _, sig_output = self.cmd("file %s" %signature_file) + if "PGP signature Signature" in sig_output: + return True + else: + return False + + def make_clearsign_signature(self, user, testpasswd, signature_file, file, host="local", ignore_status=True): + ''' + Make clearsign signature + user: Username, user email, or keypair id + testpasswd: The password for the key + signature_file: Save signed files + file: Source file + return Boolean(Ture, False) + ''' + + # gpg --local-user 95DB082E3D0F0E2E5CDA5E312B459F66A03CD415 --batch --yes --pinentry-mode loopback + # --passphrase mysecretpassphrase --armor --output file.txt.asc --clearsign file.txt + self.cmd( + "gpg --local-user {_user} --batch --yes --pinentry-mode loopback \ + --passphrase {_passwd} --armor --output {_sig_file} --clearsign {_file}".format( + _user = user, + _passwd = testpasswd, + _sig_file = signature_file, + _file = file, + ), + ignore_status=ignore_status + ) + _, sig_output = self.cmd("file %s" %signature_file) + if "PGP signed message" in sig_output: + return True + else: + return False + + def make_signature(self, pubkeyid, testpasswd, signature_file, file, host="local", ignore_status=True): + ''' + Make signature + pubkeyid: public key id + testpasswd: The password for the key + signature_file: Save signed files + file: Source file + return Boolean(Ture, False) + ''' + + self.cmd( + "gpg --local-user {_pubkeyid}! --batch --yes --pinentry-mode loopback \ + --passphrase {_passwd} --armor --output {_sig_file} --sign {_file}".format( + _pubkeyid = pubkeyid, + _passwd = testpasswd, + _sig_file = signature_file, + _file = file, + ), + ignore_status=ignore_status + ) + _, sig_output = self.cmd("file %s" %signature_file) + if "PGP message Compressed" in sig_output: + return True + else: + return False + + def sign_other_keys(self, pubkeyid, other_pubkeyid, testpasswd, host="local", ignore_status=True): + ''' + Authenticate other keys + pubkeyid: Main public key id + other_pubkeyid: Authenticated public key ID + testpasswd: The password for the key + return tuple(code, sign_output) + ''' + + code, sign_output = self.cmd( + "gpg --local-user {_pubkeyid}! --batch --yes --pinentry-mode loopback \ + --passphrase {_passwd} --sign-key {_other_pubkeyid}".format( + _pubkeyid = pubkeyid, + _passwd = testpasswd, + _other_pubkeyid = other_pubkeyid, + ) + ) + return code, sign_output + + def verify_detached_signature(self, user, signature_file, file, host="local", ignore_status=True): + ''' + Verify detached signature + user: Username, user email, or keypair id + signature_file: Verified file + file: Source file + return tuple(code, output) + ''' + + code, verify_detached_signature_output = self.cmd( + "gpg --local-user %s --batch --yes --verify %s %s" %(user, signature_file, file), + ignore_status=ignore_status + ) + return code, verify_detached_signature_output + + def verify_cleartext_signature(self, user, signature_file, host="local", ignore_status=True): + ''' + Verify cleartext signature + user: Username, user email, or keypair id + signature_file: Verified file + return tuple(code, output) + ''' + + code, verify_cleartext_signature_output = self.cmd( + "gpg --local-user %s --batch --yes --verify %s" %(user, signature_file), + ignore_status= ignore_status + ) + return code, verify_cleartext_signature_output + + def symmetric_encryption_messages(self, messages_file, testpasswd, host="local", ignore_status=True): + ''' + Asynchronous message encryption + messages_file: Encrypted message file + testpasswd: The password for the key + return tuple(code, output) + ''' + + code, symmetric_encryption_messages_output = self.cmd( + "gpg --batch --yes --passphrase %s --symmetric --cipher-algo AES256 %s" + %(testpasswd, messages_file) + ) + return code, symmetric_encryption_messages_output + + def symmetric_decrypt_messages(self, encryption_messages_file, decrypt_messages_file, + testpasswd, host="local", ignore_status=True): + ''' + Asynchronous message decryption. + encryption_messages_file: Specify encrypted message file + decrypt_messages_file: Save decrypted content + testpasswd: The password for the key + return tuple(code, output) + ''' + + code, symmetric_decrypt_messages_output = self.cmd( + "gpg --batch --yes --passphrase %s --decrypt %s > %s" + %(testpasswd, encryption_messages_file, decrypt_messages_file) + ) + return code, symmetric_decrypt_messages_output + \ No newline at end of file diff --git a/tests/databases/gdbm/tc_gdbm_gdbm_dump_func_001.py b/tests/databases/gdbm/tc_gdbm_gdbm_dump_func_001.py new file mode 100644 index 0000000000000000000000000000000000000000..7b256bcbb500a9ef328d641f90eb195e6f337fd3 --- /dev/null +++ b/tests/databases/gdbm/tc_gdbm_gdbm_dump_func_001.py @@ -0,0 +1,39 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_gdbm_gdbm_dump_func_001.py +@Time: 2024/04/15 15:00:00 +@Author: liuhaiyang +@Version: 1.0 +@Contact: lhy01509690@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: liuhaiyang +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_gdbm_gdbm_dump_func_001.yaml for details + + :avocado: tags=fix,P3,noarch,local + """ + db_path = '/tmp/gdbm-test.db' + PARAM_DIC = {"pkg_name": "gdbm"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd('for i in $(seq 1 3); do echo "store key$i value$i"; done | gdbmtool %s' % (self.db_path)) + self.cmd("ls %s && rm -rf %s" % (str(self.db_path.split(".")[0]), str(self.db_path.split(".")[0])), ignore_status=True) + + def test(self): + self.cmd("gdbm_dump %s %s" % (self.db_path, str(self.db_path.split(".")[0]))) + self.cmd("ls %s" % (str(self.db_path.split(".")[0]))) + _, output = self.cmd("cat %s | grep '#:file' | awk -F '=' '{print$2}'" % (str(self.db_path.split(".")[0]))) + self.assertTrue(output == self.db_path, "export data fail") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf %s" % (self.db_path)) + self.cmd("rm -rf %s" % (str(self.db_path.split(".")[0]))) + diff --git a/tests/devel_languages/golang/tc_golang_golang_fun001.py b/tests/devel_languages/golang/tc_golang_golang_fun001.py new file mode 100644 index 0000000000000000000000000000000000000000..92567ad120366f20ec3006a2c69b06072c3c9f3d --- /dev/null +++ b/tests/devel_languages/golang/tc_golang_golang_fun001.py @@ -0,0 +1,43 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_golang_golang_fun001.py +@Time: 2024/5/14 15:30:20 +@Author: douzhichong +@Version: 1.0 +@Contact: douzhichong@inspur.com +@License: Mulan PSL v2 +@Modify: douzhichong +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_golang_golang_fun001.yaml for details + + :avocado: tags=P1,noarch,local,golang + """ + PARAM_DIC = {"pkg_name": "golang"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = """cat > hello.go << EOF +package main + import ( + "fmt" + ) +func main() { + fmt.Println("Hello, World!") +} + +EOF""" + self.cmd(cmdline) + + def test(self): + code,result=self.cmd("go run hello.go ") + self.assertIn("Hello, World!",result) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf hello.go") \ No newline at end of file diff --git a/tests/devel_languages/lua/tc_lua_lua_fun_001.py b/tests/devel_languages/lua/tc_lua_lua_fun001.py similarity index 87% rename from tests/devel_languages/lua/tc_lua_lua_fun_001.py rename to tests/devel_languages/lua/tc_lua_lua_fun001.py index 42792e72dc81d385f4efb59709d0299c66c53b94..34f73ea32e8afdd20833260b5dcea5baae81f00d 100644 --- a/tests/devel_languages/lua/tc_lua_lua_fun_001.py +++ b/tests/devel_languages/lua/tc_lua_lua_fun001.py @@ -1,7 +1,8 @@ +#!/usr/bin/python # -*- encoding: utf-8 -*- """ -@File: tc_lua_lua_fun_001.py +@File: tc_lua_lua_fun001.py @Time: 2023/3/27 15:47:20 @Author: gaoshuaishuai @Version: 1.0 @@ -14,9 +15,9 @@ from common.basetest import LocalTest class Test(LocalTest): """ - See tc_lua_lua_fun_001 for details + See tc_lua_lua_fun001 for details - :avocado: tags=P1,noarch,local + :avocado: tags=P1,noarch,local,fix """ PARAM_DIC = {"pkg_name": "lua"} def setUp(self): @@ -34,6 +35,7 @@ EOF''' self.cmd(cmd) code, result = self.cmd('lua hello.lua') self.assertIn('Hello World!', result) + def tearDown(self): super().tearDown(self.PARAM_DIC) self.cmd("rm -f hello.lua") diff --git a/tests/devel_languages/lua/tc_lua_lua_fun002.py b/tests/devel_languages/lua/tc_lua_lua_fun002.py index 5f4433a1d0ffc17cc22f0bf68645f84e46849613..e3a8aa8baea81ed6e15322e2a6eb954c296b4f28 100644 --- a/tests/devel_languages/lua/tc_lua_lua_fun002.py +++ b/tests/devel_languages/lua/tc_lua_lua_fun002.py @@ -1,3 +1,4 @@ +#!/usr/bin/python # -*- encoding: utf-8 -*- """ @@ -16,20 +17,18 @@ class Test(LocalTest): """ See tc_lua_lua_fun002.yaml for details - :avocado: tags=P2,noarch,local,lua + :avocado: tags=P2,noarch,local,lua,fix """ PARAM_DIC = {"pkg_name": "lua"} def setUp(self): super().setUp(self.PARAM_DIC) - def test(self): self.cmd("lua -v") - code,result=self.cmd("lua -h",ignore_status=True) + code,result=self.cmd("lua -h", ignore_status=True) self.assertIn("unrecognized option", result) code,result=self.cmd("lua -e'a=666' -e 'print(a)'") self.assertIn("666", result) - def tearDown(self): super().tearDown(self.PARAM_DIC) diff --git a/tests/devel_languages/lua/tc_lua_lua_fun003.py b/tests/devel_languages/lua/tc_lua_lua_fun003.py new file mode 100644 index 0000000000000000000000000000000000000000..5c6d0723615323d12f093df3ff25949c556dd1ba --- /dev/null +++ b/tests/devel_languages/lua/tc_lua_lua_fun003.py @@ -0,0 +1,77 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_lua_lua_fun003.py +@Time: 2024/04/16 17:12:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_lua_lua_fun003.yaml for details + + :avocado: tags=P2,noarch,local,lua,fix + """ + PARAM_DIC = {"pkg_name": "lua"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline = """cat > /tmp/ghm/func.lua < /tmp/ghm/file.lua < /tmp/ghm/table.lua < /tmp/ghm/table.lua < max_count then + max_count = count + most_common_word = word + end + end + + return most_common_word, max_count + else + return nil, "File not found" + end +end + +-- 示例使用 +local file_path = arg[1] -- 从命令行参数获取文件路径 +local most_common_word, occurrences = countWords(file_path) + +if most_common_word then + print("The most common word is:", most_common_word) + print("It appears", occurrences, "times.") +else + print(most_common_word) +end +""" + self.cmd(cmdline) + + def test(self): + self.cmd("echo '123456\n hello\n 456789\n world\n hello 123abc\n' > /tmp/ghm/testfile.txt") + code, result = self.cmd("lua /tmp/ghm/table.lua /tmp/ghm/testfile.txt") + self.assertIn("The most common word is:", result) + self.assertIn("hello", result) + self.assertIn("It appears", result) + self.assertIn("2", result) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") diff --git a/tests/devel_languages/lua/tc_lua_lua_fun007.py b/tests/devel_languages/lua/tc_lua_lua_fun007.py new file mode 100644 index 0000000000000000000000000000000000000000..880a6dc26320abc5607e191a66c29a13968c7bea --- /dev/null +++ b/tests/devel_languages/lua/tc_lua_lua_fun007.py @@ -0,0 +1,153 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_lua_lua_fun007.py +@Time: 2024/04/19 10:42:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_lua_lua_fun007.yaml for details + + :avocado: tags=P2,noarch,local,lua,fix + """ + PARAM_DIC = {"pkg_name": "lua"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline = """cat > /tmp/ghm/table.lua < dateutil_test1.py << EOF +#!/usr/bin/python +# -- coding: UTF-8 -- + +from dateutil import parser + +f = open('dateutil_result1.txt', 'w') +date_strings = ["2024-03-13", "March 13, 2024", "13/03/2024"] + +for date_string in date_strings: + parsed_date = parser.parse(date_string) + f.write(f"{date_string} 解析为 {parsed_date} ") +EOF''' + self.cmd(cmdline) + + def test(self): + self.cmd("python3 dateutil_test1.py") + code, dateutil_result = self.cmd("cat dateutil_result1.txt") + self.assertIn("2024-03-13 解析为 2024-03-13 00:00:00", dateutil_result) + self.assertIn("March 13, 2024 解析为 2024-03-13 00:00:00", dateutil_result) + self.assertIn("13/03/2024 解析为 2024-03-13 00:00:00", dateutil_result) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf dateutil_test1.py dateutil_result1.txt") \ No newline at end of file diff --git a/tests/devel_languages/python/tc_python_dateutil_func_002.py b/tests/devel_languages/python/tc_python_dateutil_func_002.py new file mode 100644 index 0000000000000000000000000000000000000000..d7941e5a62f0e73595686c926272a8353cc8d37e --- /dev/null +++ b/tests/devel_languages/python/tc_python_dateutil_func_002.py @@ -0,0 +1,49 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_python_dateutil_func_002.py +@Time: 2024/03/15 14:33:20 +@Author: chenchunhu +@Version: 1.0 +@Contact: wb-cch358909@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: chenchunhu +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_python_dateutil_func_002.yaml for details + + :avocado: tags=P2,noarch,local,fix,python + """ + PARAM_DIC = {"pkg_name": "python3-dateutil"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = '''cat > dateutil_test2.py << EOF +#!/usr/bin/python +# -- coding: UTF-8 -- + +from dateutil import tz +import datetime + +f = open('dateutil_result2.txt', 'w') + +test_date = datetime.datetime(2024, 3, 13, 14, 25, 30) +utc_time = test_date.replace(tzinfo=datetime.timezone.utc) +f.write(f"UTC时间: {utc_time} ") +local_time = utc_time.astimezone(tz.tzlocal()) +f.write(f"本地时间: {local_time}") +EOF''' + self.cmd(cmdline) + + def test(self): + self.cmd("python3 dateutil_test2.py") + code, dateutil_result = self.cmd("cat dateutil_result2.txt") + self.assertIn("UTC时间: 2024-03-13 14:25:30+00:00", dateutil_result) + self.assertIn("本地时间: 2024-03-13 22:25:30+08:00", dateutil_result) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf dateutil_test2.py dateutil_result2.txt") \ No newline at end of file diff --git a/tests/devel_languages/python/tc_python_dateutil_func_003.py b/tests/devel_languages/python/tc_python_dateutil_func_003.py new file mode 100644 index 0000000000000000000000000000000000000000..108dbf8678e871a69ef185ae30afbaea62c2b9c6 --- /dev/null +++ b/tests/devel_languages/python/tc_python_dateutil_func_003.py @@ -0,0 +1,48 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_python_dateutil_func_003.py +@Time: 2024/03/15 14:33:20 +@Author: chenchunhu +@Version: 1.0 +@Contact: wb-cch358909@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: chenchunhu +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_python_dateutil_func_003.yaml for details + + :avocado: tags=P2,noarch,local,fix,python + """ + PARAM_DIC = {"pkg_name": "python3-dateutil"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = '''cat > dateutil_test3.py << EOF +#!/usr/bin/python +# -- coding: UTF-8 -- + +from dateutil.relativedelta import relativedelta +import datetime + +f = open('dateutil_result3.txt', 'w') + +current_date = datetime.datetime(2024, 3, 13, 14, 25, 30) +f.write(f"当前日期: {current_date} ") +next_month = current_date + relativedelta(months=1) +f.write(f"下个月的日期: {next_month}") +EOF''' + self.cmd(cmdline) + + def test(self): + self.cmd("python3 dateutil_test3.py") + code, dateutil_result = self.cmd("cat dateutil_result3.txt") + self.assertIn("当前日期: 2024-03-13 14:25:30", dateutil_result) + self.assertIn("下个月的日期: 2024-04-13 14:25:30", dateutil_result) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf dateutil_test3.py dateutil_result3.txt") \ No newline at end of file diff --git a/tests/devel_languages/python/tc_python_dateutil_func_004.py b/tests/devel_languages/python/tc_python_dateutil_func_004.py new file mode 100644 index 0000000000000000000000000000000000000000..346062870a2abc19cc2215833a5450ee9341643a --- /dev/null +++ b/tests/devel_languages/python/tc_python_dateutil_func_004.py @@ -0,0 +1,49 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_python_dateutil_func_004.py +@Time: 2024/03/15 14:33:20 +@Author: chenchunhu +@Version: 1.0 +@Contact: wb-cch358909@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: chenchunhu +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_python_dateutil_func_004.yaml for details + + :avocado: tags=P2,noarch,local,fix,python + """ + PARAM_DIC = {"pkg_name": "python3-dateutil"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = '''cat > dateutil_test4.py << EOF +#!/usr/bin/python +# -- coding: UTF-8 -- + +import datetime +from dateutil.rrule import rrule, DAILY + +f = open('dateutil_result4.txt', 'w') + +start_date = datetime.datetime(2024, 3, 13) +rrule_dates = list(rrule(DAILY, count=10, dtstart=start_date)) +f.write(f"从 {start_date} 开始连续10天的日期: ") +for date in rrule_dates: + f.write(f"{date.date()} ") +EOF''' + self.cmd(cmdline) + + def test(self): + self.cmd("python3 dateutil_test4.py") + code, dateutil_result = self.cmd("cat dateutil_result4.txt") + self.assertIn("2024-03-13", dateutil_result) + self.assertIn("2024-03-22", dateutil_result) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf dateutil_test4.py dateutil_result4.txt") \ No newline at end of file diff --git a/tests/devel_languages/python/tc_python_dateutil_func_005.py b/tests/devel_languages/python/tc_python_dateutil_func_005.py new file mode 100644 index 0000000000000000000000000000000000000000..761c212ead52ff79106deaec4c7c94cbc351ead9 --- /dev/null +++ b/tests/devel_languages/python/tc_python_dateutil_func_005.py @@ -0,0 +1,49 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_python_dateutil_func_005.py +@Time: 2024/03/15 14:33:20 +@Author: chenchunhu +@Version: 1.0 +@Contact: wb-cch358909@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: chenchunhu +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_python_dateutil_func_005.yaml for details + + :avocado: tags=P2,noarch,local,fix,python + """ + PARAM_DIC = {"pkg_name": "python3-dateutil"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = '''cat > dateutil_test5.py << EOF +#!/usr/bin/python +# -- coding: UTF-8 -- + +import datetime +from dateutil.rrule import rrule, MONTHLY + +f = open('dateutil_result5.txt', 'w') + +start_date = datetime.datetime(2024, 3, 13) +# 获取从开始日期后6个星期一的日期,0 表示星期一 +rule = rrule(MONTHLY, byweekday=0, count=6, dtstart=start_date) +for date in rule: + f.write(f"{date.date()} ") +EOF''' + self.cmd(cmdline) + + def test(self): + self.cmd("python3 dateutil_test5.py") + code, dateutil_result = self.cmd("cat dateutil_result5.txt") + self.assertIn("2024-03-18", dateutil_result) + self.assertIn("2024-04-22", dateutil_result) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf dateutil_test5.py dateutil_result5.txt") \ No newline at end of file diff --git a/tests/os_function/common_tools/whois/tc_whois_fun_002.py b/tests/os_function/common_tools/whois/tc_whois_fun_002.py new file mode 100644 index 0000000000000000000000000000000000000000..4b9fff553a59aa291f101b3f11209f84624f96d8 --- /dev/null +++ b/tests/os_function/common_tools/whois/tc_whois_fun_002.py @@ -0,0 +1,44 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_whois_fun_002.py +@Time: 2024/03/19 13:01:50 +@Author: qintingting +@Version: 1.0 +@Contact: wb-qtt862918@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: qintingting +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_whois_fun_002.yaml for details. + + Test specifically checks the admin-contact information for the IDN domain. + The domain and expected string are kept in configuration for maintainability. + + :avocado: tags = fixed,P2,noarch,local + """ + + PARAM_DIC = {"pkg_name": "whois"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.DOMAIN = "xn--e1afmkfd.xn--p1ai" # IDN domain for test + self.EXPECTED_OUPTUT = "admin-contact: http://www.cctld.ru" + + def test(self): + try: + ret_c, ret_o = self.cmd(f"whois '{self.DOMAIN}'") + + if ret_c != 0: + self.fail(f"Command failed with exit code: {ret_c}, Output: {ret_o}") + + self.assertIn(self.EXPECTED_OUPTUT, ret_o, 'IDN Domain Test fail') + except Exception as e: + self.fail(f"An unexpected error occurred: {str(e)}") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) \ No newline at end of file diff --git a/tests/os_function/common_tools/whois/tc_whois_fun_003.py b/tests/os_function/common_tools/whois/tc_whois_fun_003.py new file mode 100644 index 0000000000000000000000000000000000000000..2d2c8878bbcd53faf69b064dba2ecf7ff148b663 --- /dev/null +++ b/tests/os_function/common_tools/whois/tc_whois_fun_003.py @@ -0,0 +1,67 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_whois_fun_003.py +@Time: 2024/03/20 13:48:50 +@Author: qintingting +@Version: 1.0 +@Contact: wb-qtt862918@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: qintingting +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_whois_fun_003.yaml for details. + + Test specifically checks the admin-contact information for the IDN domain. + The domain and expected string are kept in configuration for maintainability. + + :avocado: tags = fixed,P2,noarch,local + """ + + PARAM_DIC = {"pkg_name": "whois"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.DOMAIN = 'baidu.com' + self.SERVICE = 'whois.iana.org' + self.Ip = '8.8.8.8' + self.command_list = [ + ['-h', self.SERVICE, self.DOMAIN], + ['-h', self.SERVICE, '-p', '43', self.DOMAIN], + ['-q', 'version'], + ['-t', 'domain'], + ['-v', 'person'], + ['-I', self.DOMAIN], + ['-H', self.DOMAIN], + ['-c', self.DOMAIN], + ['--no-recursion', self.DOMAIN], + ['--help'], + ['-b', self.Ip], + ['--verbose', self.DOMAIN], + ['--version'], + ['-l', self.DOMAIN], + ['-L', self.DOMAIN], + ['-i mnt-by', self.DOMAIN], + ['-T domain', self.DOMAIN], + ['-K', self.DOMAIN], + ['-r', self.DOMAIN], + ['-R', self.DOMAIN], + ['-a', self.DOMAIN] + + ] + + def test(self): + for item in self.command_list: + try: + ret_c, ret_o = self.cmd(f"whois {' '.join(item)}") + if ret_c != 0: + self.fail(f"Command failed with exit code: {ret_c}, Output: {ret_o}") + except Exception as e: + self.fail(f"An unexpected error occurred: {str(e)}") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) \ No newline at end of file diff --git a/tests/os_function/development_tools/compile_language/tc_python3_fun_001.py b/tests/os_function/development_tools/compile_language/tc_python3_fun_001.py new file mode 100644 index 0000000000000000000000000000000000000000..666fbe3faa97905c786100668b8908d81f0c9445 --- /dev/null +++ b/tests/os_function/development_tools/compile_language/tc_python3_fun_001.py @@ -0,0 +1,40 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_python3_fun_001.py +@Time: 2024/03/15 10:12:50 +@Author: qintingting +@Version: 1.0 +@Contact: wb-qtt862918@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: qintingting +""" + +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_python3_fun_001.yaml for details + + :avocado: tags = fix,P0,noarch,local + """ + + PARAM_DIC = {"pkg_name": "python3"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = """cat > test.py </dev/null || exit 1 +source ../.env + +CPU_SYSFS_PATH="/sys/devices/system/cpu" +CPU_BUS_SYSFS_PATH="/sys/bus/cpu/devices/" +CPU_IDLE_SYSFS_PATH="/sys/devices/system/cpu/cpuidle" +PKG_CST_CTL="0xe2" +MSR_PKG2="0x60d" +MSR_PKG6="0x3f9" + +current_cpuidle_driver=$(cat "$CPU_IDLE_SYSFS_PATH"/current_driver) + +# Turbostat tool is required to run core cstate cases +if which turbostat 1>/dev/null 2>&1; then + turbostat sleep 1 1>/dev/null || block_test "Failed to run turbostat tool, +please check turbostat tool error message." +else + block_test "Turbostat tool is required to run CSTATE cases, +please get it from latest upstream kernel-tools." +fi + +# Perf tool is required to run this cstate perf cases +if which perf 1>/dev/null 2>&1; then + perf list 1>/dev/null || block_test "Failed to run perf tool, +please check perf tool error message." +else + block_test "perf tool is required to run CSTATE cases, +please get it from latest upstream kernel-tools." +fi + +# Function to verify if Intel_idle driver refer to BIOS _CST table +test_cstate_table_name() { + local cstate_name="" + local name="" + + cstate_name=$(cat "$CPU_SYSFS_PATH"/cpu0/cpuidle/state*/name) + name=$(echo "$cstate_name" | grep ACPI) + if [[ -n $name ]]; then + test_print_trc "$cstate_name" + die "Intel_idle driver refers to ACPI cstate table." + else + test_print_trc "$cstate_name" + test_print_trc "Intel_idle driver refers to BIOS _CST table." + fi +} + +# Function to verify if current idle driver is intel_idle +check_intel_idle() { + [[ $current_cpuidle_driver == "intel_idle" ]] || { + block_test "If the platform does not support Intel_Idle driver yet, \ +please ignore this test case." + } +} + +# Function to switch each core cstate +test_cstate_switch_idle() { + local usage_before=() + local usage_after=() + local cpus="" + local states="" + local cpu_num="" + + cpus=$(ls "$CPU_BUS_SYSFS_PATH" | xargs) + cpu_num=$(lscpu | grep "^CPU(s)" | awk '{print $2}') + + if [[ -n "$cpus" ]]; then + for cpu in $cpus; do + states=$(ls "$CPU_BUS_SYSFS_PATH"/"$cpu"/cpuidle | grep state | xargs) + if [[ -n "$states" ]]; then + for state in $states; do + # Disable stateX of cpuX + echo 1 >"${CPU_SYSFS_PATH}/${cpu}/cpuidle/${state}/disable" + done + else + die "fail to get state node for $cpu" + fi + done + else + die "fail to get cpu sysfs directory" + fi + + for state in $states; do + test_print_trc ------ loop for "$state" ------ + + # Count usage of the stateX of cpuX before enable stateX + i=0 + while [[ "$i" != "$cpu_num" ]]; do + usage_before[$i]=$(cat "$CPU_SYSFS_PATH"/cpu"${i}"/cpuidle/"$state"/usage) + [[ -n ${usage_before[$i]} ]] || die "fail to count usage_before of $state of cpu${i}" + i=$(("$i" + 1)) + done + + # Enable stateX of cpuX + for cpu in $cpus; do + echo 0 >"${CPU_SYSFS_PATH}/${cpu}/cpuidle/${state}/disable" + done + + # Sleep and wait for entry of the state + sleep 30 + + # Count usage of the stateX for cpuX after enable stateX + i=0 + while [[ "$i" != "$cpu_num" ]]; do + usage_after[$i]=$(cat "$CPU_SYSFS_PATH"/cpu"${i}"/cpuidle/"$state"/usage) + [[ -n ${usage_after[$i]} ]] || die "fail to count usage_after of $state of cpu${i}" + i=$(("$i" + 1)) + done + + # Compare the usage to see if the cpuX enter stateX + i=0 + while [[ "$i" != "$cpu_num" ]]; do + if [[ ${usage_after[${i}]} -gt ${usage_before[${i}]} ]]; then + test_print_trc "cpu${i} enter $state successfully" + else + die "cpu${i} fail to enter $state" + fi + i=$(("$i" + 1)) + done + done +} + +test_cstate_switch_intel_idle() { + check_intel_idle + test_cstate_switch_idle +} + +# The Core C7 is only supported on Intel® Client platform +# This function is to check Core C7 residency during runtime +judge_cc7_residency_during_idle() { + columns="Core,CPU%c1,CPU%c6,CPU%c7" + turbostat_output=$(turbostat -i 10 --quiet \ + --show $columns sleep 10 2>&1) + test_print_trc "$turbostat_output" + CC7_val=$(echo "$turbostat_output" | grep -E "^-" | awk '{print $4}') + test_print_trc "CPU Core C7 residency :$CC7_val" + [[ $CC7_val == "0.00" ]] && die "CPU Core C7 residency is not available." + + # Judge whether CC7 residency is available during idle + turbostat_CC7_value=$(echo "scale=2; $CC7_val > 0.00" | bc) + [[ $turbostat_CC7_value -eq 1 ]] || + die "Did not get CPU Core C7 residency during idle \ +when $current_cpuidle_driver is running." + test_print_trc "CPU Core C7 residency is available during idle \ +when $current_cpuidle_driver is running" +} + +# The Core C7 is only supported on Intel® Client platforms +# This function is to check Core C7 residency for S2idle path +judge_cc7_residency_during_s2idle() { + columns="Core,CPU%c1,CPU%c6,CPU%c7" + turbostat_output=$( + turbostat --show $columns \ + rtcwake -m freeze -s 15 2>&1 + ) + turbostat_output=$(grep "CPU%c7" -A1 <<<"$turbostat_output") + test_print_trc "$turbostat_output" + CC7_val=$(echo "$turbostat_output" | grep -E "^-" | awk '{print $4}') + test_print_trc "CPU Core C7 residency :$CC7_val" + [[ $CC7_val == "0.00" ]] && die "CPU Core C7 residency is not available." + + # Judge whether CC7 residency is available during idle + turbostat_CC7_value=$(echo "scale=2; $CC7_val > 0.00" | bc) + [[ $turbostat_CC7_value -eq 1 ]] || + die "Did not get CPU Core C7 residency during S2idle \ +when $current_cpuidle_driver is running" + test_print_trc "CPU Core C7 residency is available during S2idle \ +when $current_cpuidle_driver is running." +} + +# The Core C6 is the deepest cstate on Intel® Server platforms +test_server_all_cpus_deepest_cstate() { + local unexpected_cstate=0.00 + + columns="sysfs,CPU%c1,CPU%c6" + turbostat_output=$(turbostat -i 10 --quiet \ + --show $columns sleep 10 2>&1) + test_print_trc "Turbostat log: $turbostat_output" + all_deepest_cstate=$(echo "$turbostat_output" | + awk '{for(i=0;++i<=NF;)a[i]=a[i]?a[i] FS $i:$i} END{for(i=0;i++<=NF;)print a[i]}' | grep "CPU%c6") + test_print_trc "The deepest core cstate is: $all_deepest_cstate" + if [[ -z $all_deepest_cstate ]]; then + block_test "The CPUs cstate is not available." + elif [[ $all_deepest_cstate =~ $unexpected_cstate ]] && [[ ! "$all_deepest_cstate" == *"100.00"* ]]; then + test_print_trc "Getting CPU C6 state by reading MSR 0x3fd:" + rdmsr -a 0x3fd + die "The CPU Core did not enter the deepest cstate!" + else + test_print_trc "All the CPUs core enter the deepest cstate!" + fi +} + +# Verify if the ATOM server platform CPUs can enter the MC6 state +test_server_all_cpus_mc6() { + local unexpected_cstate=0.00 + local cpu_model="" + + cpu_model=$(lscpu | grep Model: | awk '{print $2}') + if [[ $cpu_model -eq 175 ]] || [[ $cpu_model -eq 221 ]]; then + columns="sysfs,CPU%c1,CPU%c6,Mod%c6" + turbostat_output=$(turbostat -i 10 --quiet \ + --show $columns sleep 10 2>&1) + test_print_trc "Turbostat log: $turbostat_output" + all_mc6_cstate=$(echo "$turbostat_output" | + awk '{for(i=0;++i<=NF;)a[i]=a[i]?a[i] FS $i:$i} END{for(i=0;i++<=NF;)print a[i]}' | grep "Mod%c6") + test_print_trc "The MC6 cstate is: $all_mc6_cstate" + if [[ -z $all_mc6_cstate ]]; then + block_test "The CPUs cstate is not available." + elif [[ $all_mc6_cstate =~ $unexpected_cstate ]] && [[ ! "$all_mc6_cstate" == *"100.00"* ]]; then + test_print_trc "Getting CPU MC6 state by reading MSR 0x664:" + rdmsr -a 0x664 + die "The CPU did not enter the MC6 cstate!" + else + test_print_trc "All the CPUs enter the MC6 cstate!" + fi + else + skip_test "SUT does not support module cstate." + fi +} + +# The Core C6 is only supported on Intel® Server platform +# This function is to check Core C6 residency during runtime +judge_cc6_residency_during_idle() { + columns="Core,CPU%c1,CPU%c6" + turbostat_output=$(turbostat -i 10 --quiet \ + --show $columns sleep 10 2>&1) + test_print_trc "Turbostat log: $turbostat_output" + CC6_val=$(echo "$turbostat_output" | grep -E "^-" | awk '{print $3}') + test_print_trc "CPU Core C6 residency :$CC6_val" + [[ -n $CC6_val ]] || die "CPU Core C6 residency is not available." + + # Judge whether CC6 residency is available during idle + turbostat_CC6_value=$(echo "scale=2; $CC6_val > 0.00" | bc) + if [[ $turbostat_CC6_value -eq 1 ]]; then + test_print_trc "CPU Core C6 residency is available \ +during idle when $current_cpuidle_driver is running" + else + die "Did not get CPU Core C6 residency during idle \ +when $current_cpuidle_driver is running" + fi +} + +test_cpu_core_c7_residency_intel_idle() { + check_intel_idle + judge_cc7_residency_during_idle +} + +test_cpu_core_c7_residency_intel_s2idle() { + check_intel_idle + judge_cc7_residency_during_s2idle +} + +test_cpu_core_c6_residency_intel_idle() { + check_intel_idle + judge_cc6_residency_during_idle +} + +cc_state_disable_enable() { + local cc=$1 + local setting=$2 + + for ((i = 0; i < cpu_num; i++)); do + # Find Core Cx state + cc_num=$(grep . /sys/devices/system/cpu/cpu0/cpuidle/state*/name | + sed -n "/$cc$/p" | awk -F "/" '{print $8}' | cut -c 6) + test_print_trc "Core $cc state name is: $cc_num" + [[ -n "$cc_num" ]] || block_test "Did not get Core $cc state." + # Change Core Cx state + do_cmd "echo $setting > /sys/devices/system/cpu/cpu$i/cpuidle/state$cc_num/disable" + deeper=$(("$cc_num" + 1)) + # Change deeper Core Cx state + for ((j = deeper; j < state_num; j++)); do + do_cmd "echo $setting > /sys/devices/system/cpu/cpu$i/cpuidle/state$j/disable" + done + done +} + +disable_cc_check_pc() { + local cc=$1 + local pc_y=$2 + local pc_n=$3 + local cpu_num="" + local columns="" + + cpu_num=$(lscpu | grep "^CPU(s)" | awk '{print $2}') + state_num=$(ls "$CPU_BUS_SYSFS_PATH"/cpu0/cpuidle | grep -c state) + columns="Pkg%pc2,Pkg%pc3,Pkg%pc6,Pkg%pc7,Pkg%pc8,Pkg%pc9,Pk%pc10" + + cc_state_disable_enable "$cc" 1 + + # Check Package Cstates, CC10 disable--> expect PC8 only + # CC8 and deeper disable--> PC6 only + tc_out=$(turbostat -q --show $columns -i 1 sleep 20 2>&1) + [[ -n "$tc_out" ]] || die "Did not get turbostat log" + test_print_trc "turbostat tool output: $tc_out" + pc_y_res=$(echo "$tc_out" | + awk '{for(k=0;++k<=NF;)a[k]=a[k]?a[k] FS $k:$k} END{for(k=0;k++ 0.00" | bc) -eq 1 ]] && [[ $pc_n_res == "0.00" ]]; then + cc_state_disable_enable "$cc" 0 + test_print_trc "Expected to get $pc_y only when disable $cc and deeper state.\ +$pc_y residency: $pc_y_res; $pc_n residency: $pc_n_res" + else + cc_state_disable_enable "$cc" 0 + die "Did not get $pc_y residency after disable $cc and deeper states. \ +$pc_y residency: $pc_y_res; $pc_n residency: $pc_n_res" + fi +} + +# perf tool listed cstate is based on kernel MSRs, turbostat tool listed +# cstate is based on user space MSRs, these two outputs should be aligned +# also client and server platforms support different core and pkg cstates. +perf_client_cstate_list() { + tc_out=$(turbostat -q --show idle sleep 1 2>&1) + [[ -n "$tc_out" ]] || block_test "Did not get turbostat log" + test_print_trc "turbostat tool output: $tc_out" + tc_out_cstate_list=$(echo "$tc_out" | grep -E "^POLL") + + perf_cstates=$(perf list | grep cstate) + [[ -n "$perf_cstates" ]] || block_test "Did not get cstate events by perf list" + test_print_trc "perf list shows cstate events: $perf_cstates" + perf_core_cstate_num=$(perf list | grep -c cstate_core) + for ((i = 1; i <= perf_core_cstate_num; i++)); do + perf_core_cstate=$(perf list | grep cstate_core | sed -n "$i, 1p") + if [[ $perf_core_cstate =~ c1 ]] && [[ $tc_out_cstate_list =~ CPU%c1 ]]; then + test_print_trc "$perf_core_cstate is supported and aligned with turbostat" + elif [[ $perf_core_cstate =~ c6 ]] && [[ $tc_out_cstate_list =~ CPU%c6 ]]; then + test_print_trc "$perf_core_cstate is supported and aligned with turbostat" + elif [[ $perf_core_cstate =~ c7 ]] && [[ $tc_out_cstate_list =~ CPU%c7 ]]; then + test_print_trc "$perf_core_cstate is supported and aligned with turbostat" + else + die "perf list shows unexpected core_cstate event." + fi + done + + perf_pkg_cstate_num=$(perf list | grep -c cstate_pkg) + for ((i = 1; i <= perf_pkg_cstate_num; i++)); do + perf_pkg_cstate=$(perf list | grep cstate_pkg | sed -n "$i, 1p") + if [[ $perf_pkg_cstate =~ c2 ]] && [[ $tc_out_cstate_list =~ Pkg%pc2 ]]; then + test_print_trc "$perf_pkg_cstate is supported and aligned with turbostat" + elif [[ $perf_pkg_cstate =~ c3 ]] && [[ $tc_out_cstate_list =~ Pkg%pc3 ]]; then + test_print_trc "$perf_pkg_cstate is supported and aligned with turbostat" + elif [[ $perf_pkg_cstate =~ c6 ]] && [[ $tc_out_cstate_list =~ Pkg%pc6 ]]; then + test_print_trc "$perf_pkg_cstate is supported and aligned with turbostat" + elif [[ $perf_pkg_cstate =~ c7 ]] && [[ $tc_out_cstate_list =~ Pkg%pc7 ]]; then + test_print_trc "$perf_pkg_cstate is supported and aligned with turbostat" + elif [[ $perf_pkg_cstate =~ c8 ]] && [[ $tc_out_cstate_list =~ Pkg%pc8 ]]; then + test_print_trc "$perf_pkg_cstate is supported and aligned with turbostat" + elif [[ $perf_pkg_cstate =~ c9 ]] && [[ $tc_out_cstate_list =~ Pkg%pc9 ]]; then + test_print_trc "$perf_pkg_cstate is supported and aligned with turbostat" + elif [[ $perf_pkg_cstate =~ c10 ]] && [[ $tc_out_cstate_list =~ Pk%pc10 ]]; then + test_print_trc "$perf_pkg_cstate is supported and aligned with turbostat" + else + die "perf list shows unexpected pkg_cstate event." + fi + done +} + +override_residency_latency() { + local idle_debugfs="/sys/kernel/debug/intel_idle" + test_print_trc "Will override state3 with new target residency:100 us,new exit latency value\ +to 30 us:" + [[ -e "$idle_debugfs"/control ]] || block_test "Intel idle debugfs file does not exist" + do_cmd "echo 3:100:30 > $idle_debugfs/control" + + test_print_trc "Switch to the default intel idle driver" + do_cmd "echo > $idle_debugfs/control" + + test_print_trc "Change two changes together" + do_cmd "echo 1:0:10 3:100:30 > $idle_debugfs/control" + + test_print_trc "Switch to the default intel idle driver" + do_cmd "echo > $idle_debugfs/control" +} + +# Server platforms support different core cstate and package cstate +perf_server_cstate_list() { + tc_out=$(turbostat -q --show idle sleep 1 2>&1) + [[ -n "$tc_out" ]] || block_test "Did not get turbostat log" + test_print_trc "turbostat tool output: $tc_out" + tc_out_cstate_list=$(echo "$tc_out" | grep -E "^POLL") + + perf_cstates=$(perf list | grep cstate) + [[ -n "$perf_cstates" ]] || block_test "Did not get cstate events by perf list" + test_print_trc "perf list shows cstate events: $perf_cstates" + perf_core_cstate_num=$(perf list | grep -c cstate_core) + for ((i = 1; i <= perf_core_cstate_num; i++)); do + perf_core_cstate=$(perf list | grep cstate_core | sed -n "$i, 1p") + if [[ $perf_core_cstate =~ c1 ]] && [[ $tc_out_cstate_list =~ CPU%c1 ]]; then + test_print_trc "$perf_core_cstate is supported and aligned with turbostat" + elif [[ $perf_core_cstate =~ c6 ]] && [[ $tc_out_cstate_list =~ CPU%c6 ]]; then + test_print_trc "$perf_core_cstate is supported and aligned with turbostat" + else + die "perf list shows unexpected core_cstate event." + fi + done + + perf_pkg_cstate_num=$(perf list | grep -c cstate_pkg) + for ((i = 1; i <= perf_pkg_cstate_num; i++)); do + perf_pkg_cstate=$(perf list | grep cstate_pkg | sed -n "$i, 1p") + if [[ $perf_pkg_cstate =~ c2 ]] && [[ $tc_out_cstate_list =~ Pkg%pc2 ]]; then + test_print_trc "$perf_pkg_cstate is supported and aligned with turbostat" + elif [[ $perf_pkg_cstate =~ c6 ]] && [[ $tc_out_cstate_list =~ Pkg%pc6 ]]; then + test_print_trc "$perf_pkg_cstate is supported and aligned with turbostat" + else + die "perf list shows unexpected pkg_cstate event." + fi + done +} + +# Verify if server cstate_core or cstate_pkg pmu event updates during idle +perf_server_cstat_update() { + local cstate_name=$1 + + perf_cstates=$(perf list | grep "$cstate_name" 2>&1) + perf_cstates_num=$(perf list | grep -c "$cstate_name" 2>&1) + [[ -n $perf_cstates ]] || block_test "Did not get $cstate_name event by perf list" + + # Sleep 20 seconds to capture the cstate counter update + for ((i = 1; i <= perf_cstates_num; i++)); do + perf_cstate=$(echo "$perf_cstates" | awk '{print $1}' | sed -n "$i, 1p" 2>&1) + test_print_trc "perf event name: $perf_cstate" + option="$option -e $perf_cstate" + test_print_trc "option name: $option" + done + do_cmd "perf stat -o out.txt --per-socket $option sleep 20" + test_print_trc "$cstate_name perf events log:" + do_cmd "cat out.txt" + perf_cstates_sockets=$(grep cstate out.txt | awk '{print $NF}' | wc -l 2>&1) + + if ! counter=$(grep cstate out.txt | awk '{print $3}'); then + block_test "Did not get $cstate_name perf event: $counter" + else + for ((i = 1; i <= perf_cstates_sockets; i++)); do + perf_cstat_counter=$(grep cstate out.txt | awk '{print $3}' | sed -n "$i, 1p" 2>&1) + perf_cstat_name=$(grep cstate out.txt | awk '{print $4}' | sed -n "$i, 1p" 2>&1) + if [[ $perf_cstat_counter -eq 0 ]]; then + die "$perf_cstat_name event counter shows 0" + else + test_print_trc "$perf_cstat_name event counter is updated" + fi + done + fi +} + +# Function to check if the server platform can enter the runtime PC2 state +# by reading the data using the turbostat tool +runtime_pc2_entry() { + local pc2_val="" + local time_to_enter_pc2=10 + local pkg_limit="" + + # Judge if the deeper pkg cstate is supported + do_cmd "turbostat --debug -o tc.out sleep 1" + pkg_limit=$(grep "pkg-cstate-limit=0" tc.out) + + if [[ -n $pkg_limit ]]; then + block_test "The platform does not support deeper pkg cstate." + fi + + pkg_cst_ctl=$(rdmsr -a $PKG_CST_CTL 2>/dev/null) + + msr_pkg2_before=$(rdmsr -a $MSR_PKG2 2>/dev/null) + test_print_trc "MSR_PKG_C2_RESIDENCY before: $msr_pkg2_before" + + sleep $time_to_enter_pc2 + + columns="Core,CPU,CPU%c1,CPU%c6,Pkg%pc2,Pkg%pc6" + turbostat_output=$(turbostat -i 10 --quiet --show $columns sleep 10 2>&1) + test_print_trc "turbostat log: $turbostat_output" + + pc2_val=$(echo "$turbostat_output" | awk '/^-/{print $5}') + msr_pkg2_after=$(rdmsr -a $MSR_PKG2 2>/dev/null) + test_print_trc "MSR_PKG_C2_RESIDENCY after: $msr_pkg2_after" + + [[ -n $pc2_val ]] || block_test "PC2 was not detected by the turbostat tool. +Please check the turbostat tool version or if the BIOS has disabled Pkg cstate." + test_print_trc "PC2 residency for all CPUs: $pc2_val" + test_print_trc "MSR_PKG_CST_CONFIG_CONTROL: $pkg_cst_ctl" + + if [ "$(echo "scale=2; $pc2_val > 0.01" | bc)" -eq 1 ]; then + test_print_trc "The system successfully enters the runtime PC2 state." + else + die "The system fails to enter the runtime PC2 state." + fi +} + +# Function to check if the server platform can enter the runtime PC6 state +# by reading the data using the turbostat tool +runtime_pc6_entry() { + local pc6_residency="" + local time_to_enter_pc6=10 + local pkg_limit="" + + # Judge if the deeper pkg cstate is supported + do_cmd "turbostat --debug -o tc.out sleep 1" + pkg_limit=$(grep "pkg-cstate-limit=0" tc.out) + + if [[ -n $pkg_limit ]]; then + block_test "The platform does not support deeper pkg cstate." + fi + + # Read MSR_PKG_CST_CONFIG_CONTROL: 0xe2 + pkg_cst_ctl=$(rdmsr -a $PKG_CST_CTL 2>/dev/null) + + # Read MSR_PKG_C6_RESIDENCY: 0x3f9 + msr_pkg6_before=$(rdmsr -a $MSR_PKG6 2>/dev/null) + test_print_trc "MSR_PKG_C6_RESIDENCY before: $msr_pkg6_before" + + sleep $time_to_enter_pc6 + + # Check PC6 residency after idling for the specified time + columns="Core,CPU,CPU%c1,CPU%c6,Pkg%pc2,Pkg%pc6" + turbostat_output=$(turbostat -i 10 --quiet --show $columns sleep 10 2>&1) + test_print_trc "turbostat log: $turbostat_output" + pc6_residency=$(echo "$turbostat_output" | grep -E "^-" | awk '{print $6}') + msr_pkg6_after=$(rdmsr -a $MSR_PKG6 2>/dev/null) + test_print_trc "MSR_PKG_C6_RESIDENCY after: $msr_pkg6_after" + + [ -z "$pc6_residency" ] && die "Did not receive PC6 data from the turbostat tool. +Please check the turbostat tool version or if the BIOS has disabled Pkg cstate." + test_print_trc "PC6 residency for all CPUs: $pc6_residency" + test_print_trc "MSR_PKG_CST_CONFIG_CONTROL: $pkg_cst_ctl" + + if [ "$(echo "scale=2; $pc6_residency > 0.01" | bc)" -eq 1 ]; then + test_print_trc "The system has entered the runtime PC6 state." + else + die "The system has failed to enter the runtime PC6 state." + fi +} + +# Function to check runtime PC6 residency and stability +runtime_pc6_residency() { + local pkg_limit="" + + # Judge if the deeper pkg cstate is supported + do_cmd "turbostat --debug -o tc.out sleep 1" + pkg_limit=$(grep "pkg-cstate-limit=0" tc.out) + + if [[ -n $pkg_limit ]]; then + block_test "The platform does not support deeper pkg cstate." + fi + + pkg_cst_ctl=$(rdmsr -a $PKG_CST_CTL 2>/dev/null) + + for ((i = 1; i <= 10; i++)); do + columns="Core,CPU,CPU%c1,CPU%c6,Pkg%pc2,Pkg%pc6" + turbostat_output=$(turbostat -i 10 --quiet --show $columns sleep 10 2>&1) + test_print_trc "turbostat log: $turbostat_output" + pc6_res=$(echo "$turbostat_output" | awk '/^-/{print $6}') + + if (($(echo "$pc6_res > 90.01" | bc -l))); then + test_print_trc "Cycle $i: The system enters runtime PC6 state with good residency (>90%)" + elif (($(echo "$pc6_res > 70.01" | bc -l))); then + test_print_trc "Cycle $i: The system enters runtime PC6 state but with less than 90% residency" + elif (($(echo "$pc6_res > 5.01" | bc -l))); then + die "Cycle $i: The system enters runtime PC6 state with low residency" + else + die "Cycle $i: The system fails to enter runtime PC6 state or the residency is extremely low" + fi + done +} + +# Function to do CPU offline and online short stress +cpu_off_on_stress() { + local cycle=$1 + local dmesg_log + + last_dmesg_timestamp + + cpu_num=$(lscpu | grep "On-line CPU" | awk '{print $NF}' | awk -F "-" '{print $2}') + [ -n "$cpu_num" ] || block_test "On-line CPU is not available." + test_print_trc "The max CPU number is: $cpu_num " + + for ((i = 1; i <= cycle; i++)); do + test_print_trc "CPUs offline online stress cycle$i" + for ((j = 1; j <= cpu_num; j++)); do + do_cmd "echo 0 > /sys/devices/system/cpu/cpu$j/online" + done + sleep 1 + for ((j = 1; j <= cpu_num; j++)); do + do_cmd "echo 1 > /sys/devices/system/cpu/cpu$j/online" + done + done + + dmesg_log=$(extract_case_dmesg) + if echo "$dmesg_log" | grep -v "IRQ request may fail" | grep -iE "fail|Call Trace|error|BUG|err"; then + die "Kernel dmesg shows failure after CPU offline/online stress: $dmesg_log" + else + test_print_trc "Kernel dmesg shows Okay after CPU offline/online stress." + fi +} + +while getopts :t:H arg; do + case $arg in + t) + TEST_SCENARIO=$OPTARG + ;; + H) + usage && exit 0 + ;; + \?) + usage + die "Invalid Option -$OPTARG" + ;; + :) + usage + die "Option -$OPTARG requires an argument." + ;; + esac +done + +core_cstate_test() { + case $TEST_SCENARIO in + verify_cstate_name) + test_cstate_table_name + ;; + verify_cstate_switch) + test_cstate_switch_intel_idle + ;; + verify_client_core_c7_residency_during_runtime) + test_cpu_core_c7_residency_intel_idle + ;; + verify_client_core_c7_residency_during_s2idle) + test_cpu_core_c7_residency_intel_s2idle + ;; + verify_client_pkg6_by_disabling_cc8) + disable_cc_check_pc C8 Pkg%pc6 Pkg%pc8 + ;; + verify_client_pkg8_by_disabling_cc10) + disable_cc_check_pc C10 Pkg%pc8 Pk%pc10 + ;; + verify_cstate_list_by_perf) + perf_client_cstate_list + ;; + verify_residency_latency_override) + override_residency_latency + ;; + verify_server_core_cstate6_residency) + test_cpu_core_c6_residency_intel_idle + ;; + verify_server_all_cores_cstate6) + test_server_all_cpus_deepest_cstate + ;; + verify_server_all_cpus_mc6) + test_server_all_cpus_mc6 + ;; + verify_server_cstate_list) + perf_server_cstate_list + ;; + verify_server_perf_core_cstat_update) + perf_server_cstat_update cstate_core + ;; + verify_server_perf_pkg_cstat_update) + perf_server_cstat_update cstate_pkg + ;; + verify_server_perf_module_cstat_update) + perf_server_cstat_update cstate_module + ;; + verify_server_pc2_entry) + runtime_pc2_entry + ;; + verify_server_pc6_entry) + runtime_pc6_entry + ;; + verify_server_pc6_residency) + runtime_pc6_residency + ;; + verify_cpu_offline_online_stress) + cpu_off_on_stress 5 + ;; + *) + block_test "Wrong Case Id is assigned: $CASE_ID" + ;; + esac +} + +core_cstate_test diff --git a/tests/platform/intel/cstate/tests-client b/tests/platform/intel/cstate/tests-client new file mode 100755 index 0000000000000000000000000000000000000000..cfa5731b65439de2a7c7f8b54ec5d898f206519c --- /dev/null +++ b/tests/platform/intel/cstate/tests-client @@ -0,0 +1,15 @@ +# This file collects the CPU Core cstate cases which can run +# on Intel® Architecture-based client platforms. +# @hw_dep: +# @other_dep: +# @other_warn: + +powermgr_cstate_tests.sh -t verify_cstate_name +powermgr_cstate_tests.sh -t verify_cstate_switch +powermgr_cstate_tests.sh -t verify_client_core_c7_residency_during_runtime +powermgr_cstate_tests.sh -t verify_client_core_c7_residency_during_s2idle +powermgr_cstate_tests.sh -t verify_client_pkg6_by_disabling_cc8 +powermgr_cstate_tests.sh -t verify_client_pkg8_by_disabling_cc10 +powermgr_cstate_tests.sh -t verify_cstate_list_by_perf +powermgr_cstate_tests.sh -t verify_residency_latency_override +powermgr_cstate_tests.sh -t verify_cpu_offline_online_stress diff --git a/tests/platform/intel/cstate/tests-server b/tests/platform/intel/cstate/tests-server new file mode 100755 index 0000000000000000000000000000000000000000..ffcc297c7308ff1b59e4794be2340d759bf58002 --- /dev/null +++ b/tests/platform/intel/cstate/tests-server @@ -0,0 +1,19 @@ +# This file collects the CPU Core cstate cases which can run +# on Intel® Architecture-based server platforms. +# @hw_dep: +# @other_dep: +# @other_warn: + +powermgr_cstate_tests.sh -t verify_cstate_name +powermgr_cstate_tests.sh -t verify_server_all_cores_cstate6 +powermgr_cstate_tests.sh -t verify_server_all_cpus_mc6 +powermgr_cstate_tests.sh -t verify_server_core_cstate6_residency +powermgr_cstate_tests.sh -t verify_residency_latency_override +powermgr_cstate_tests.sh -t verify_server_cstate_list +powermgr_cstate_tests.sh -t verify_server_perf_core_cstat_update +powermgr_cstate_tests.sh -t verify_server_perf_pkg_cstat_update +powermgr_cstate_tests.sh -t verify_server_perf_module_cstat_update +powermgr_cstate_tests.sh -t verify_server_pc2_entry +powermgr_cstate_tests.sh -t verify_server_pc6_entry +powermgr_cstate_tests.sh -t verify_server_pc6_residency +powermgr_cstate_tests.sh -t verify_cpu_offline_online_stress diff --git a/tests/platform/intel/dsa/README.md b/tests/platform/intel/dsa/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a9de0b7037c953d740a0d66e08e202b46369c4e4 --- /dev/null +++ b/tests/platform/intel/dsa/README.md @@ -0,0 +1,45 @@ +# DSA(Data Streaming Accelerator) Test Cases + +## Description +Intel DSA is a high-performance data copy and transformation accelerator that +will be integrated in SPR, targeted for optimizing streaming data movement and +transformation operations common with applications for high-performance storage, +networking, persistent memory, and various data processing applications. IAA is +a similar accelerator which is more focused on data encryption and decryption. +DSA and IAA share the same Linux Kernel driver “IDXD” + +## Usage +IDXD is the DSA driver name and enabled after kernel 5.19, it is better to do tests +newer than that. + +## Run +### Manually + +Go through file tests-* , each line works as a single test. + +### Automatically +Leverage `runtests` in the root folder: + +``` +cd lkvs +./runtests BM/dsa/tests-dsa1 +``` +## Expected result +All test results should show pass, no fail. + +## accel-config +accel-config - configure and control DSA(data streaminng accelerator) subsystem +devices. The git repo is https://github.com/intel/idxd-config.git. +`accel-config -h` and `accel-config --list-cmds` introduce how to use the tool. + +#### compile +``` +cd lkvs/tools/idxd-config +./autogen.sh + +./configure CFLAGS='-g -O2' --prefix=/usr --sysconfdir=/etc --libdir=/usr/lib64 --enable-test=yes +make +make install +``` + +`--enable-test=yes` is required for all DSA and IAX related tests. diff --git a/tests/platform/intel/dsa/configs/1d2g2q_user.conf b/tests/platform/intel/dsa/configs/1d2g2q_user.conf new file mode 100755 index 0000000000000000000000000000000000000000..73df221c6b1bfaa33b96f3e51b42eeaf0a7897cc --- /dev/null +++ b/tests/platform/intel/dsa/configs/1d2g2q_user.conf @@ -0,0 +1,67 @@ +[ + { + "dev":"dsa0", + "groups":[ + { + "dev":"group0.0", + "grouped_workqueues":[ + { + "dev":"wq0.0", + "mode":"shared", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "type":"user", + "name":"app1", + "driver_name":"user", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine0.0", + "group_id":0 + }, + { + "dev":"engine0.1", + "group_id":0 + } + ] + }, + { + "dev":"group0.1", + "grouped_workqueues":[ + { + "dev":"wq0.1", + "mode":"dedicated", + "size":16, + "group_id":1, + "priority":10, + "block_on_fault":1, + "type":"user", + "name":"app2", + "driver_name":"user", + "threshold":0 + } + ], + "grouped_engines":[ + { + "dev":"engine0.2", + "group_id":1 + }, + { + "dev":"engine0.3", + "group_id":1 + } + ] + }, + { + "dev":"group0.2", + }, + { + "dev":"group0.3", + } + ] + } +] diff --git a/tests/platform/intel/dsa/configs/1d4g8q_user.conf b/tests/platform/intel/dsa/configs/1d4g8q_user.conf new file mode 100755 index 0000000000000000000000000000000000000000..78b2f416aa35c6bc4eb9d672575cb957f7496de3 --- /dev/null +++ b/tests/platform/intel/dsa/configs/1d4g8q_user.conf @@ -0,0 +1,163 @@ +[ + { + "dev":"dsa0", + "groups":[ + { + "dev":"group0.0", + "grouped_workqueues":[ + { + "dev":"wq0.0", + "mode":"shared", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "name":"app1", + "driver_name":"user", + "threshold":15 + }, + { + "dev":"wq0.4", + "mode":"shared", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "name":"app2", + "driver_name":"user", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine0.0", + "group_id":0 + } + ] + }, + { + "dev":"group0.1", + "grouped_workqueues":[ + { + "dev":"wq0.1", + "mode":"dedicated", + "size":16, + "group_id":1, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "name":"app3", + "driver_name":"user", + "threshold":15 + }, + { + "dev":"wq0.5", + "mode":"shared", + "size":16, + "group_id":1, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "name":"app4", + "driver_name":"user", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine0.1", + "group_id":1 + }, + ] + }, + { + "dev":"group0.2", + "grouped_workqueues":[ + { + "dev":"wq0.2", + "mode":"shared", + "size":16, + "group_id":2, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "name":"app5", + "driver_name":"user", + "threshold":15 + }, + { + "dev":"wq0.6", + "mode":"dedicated", + "size":16, + "group_id":2, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "name":"app6", + "driver_name":"user", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine0.2", + "group_id":2 + } + ] + }, + { + "dev":"group0.3", + "grouped_workqueues":[ + { + "dev":"wq0.3", + "mode":"dedicated", + "size":16, + "group_id":3, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "name":"app7", + "driver_name":"user", + "threshold":15 + }, + { + "dev":"wq0.7", + "mode":"dedicated", + "size":16, + "group_id":3, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "name":"app8", + "driver_name":"user", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine0.3", + "group_id":3 + }, + ] + } + ] + } +] diff --git a/tests/platform/intel/dsa/configs/2g2q_user_1.conf b/tests/platform/intel/dsa/configs/2g2q_user_1.conf new file mode 100644 index 0000000000000000000000000000000000000000..6e7fa563e440e1037f81637f09910349b559f5a5 --- /dev/null +++ b/tests/platform/intel/dsa/configs/2g2q_user_1.conf @@ -0,0 +1,80 @@ +[ + { + "dev":"dsa0", + "read_buffer_limit":0, + "groups":[ + { + "dev":"group0.0", + "read_buffers_reserved":0, + "use_read_buffer_limit":0, + "read_buffers_allowed":8, + "grouped_workqueues":[ + { + "dev":"wq0.0", + "mode":"shared", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "type":"user", + "driver_name":"user", + "name":"app1", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine0.0", + "group_id":0 + }, + { + "dev":"engine0.1", + "group_id":0 + } + ] + }, + { + "dev":"group0.1", + "read_buffers_reserved":0, + "use_read_buffer_limit":0, + "read_buffers_allowed":8, + "grouped_workqueues":[ + { + "dev":"wq0.1", + "mode":"dedicated", + "size":16, + "group_id":1, + "priority":10, + "block_on_fault":1, + "type":"user", + "driver_name":"user", + "name":"app2", + "threshold":0 + } + ], + "grouped_engines":[ + { + "dev":"engine0.2", + "group_id":1 + }, + { + "dev":"engine0.3", + "group_id":1 + } + ] + }, + { + "dev":"group0.2", + "read_buffers_reserved":0, + "use_read_buffer_limit":0, + "read_buffers_allowed":8, + }, + { + "dev":"group0.3", + "read_buffers_reserved":0, + "use_read_buffer_limit":0, + "read_buffers_allowed":8, + } + ] + } +] diff --git a/tests/platform/intel/dsa/configs/2g2q_user_2.conf b/tests/platform/intel/dsa/configs/2g2q_user_2.conf new file mode 100644 index 0000000000000000000000000000000000000000..64f3babd10d82d84fbf146ffb574f27bca423ea0 --- /dev/null +++ b/tests/platform/intel/dsa/configs/2g2q_user_2.conf @@ -0,0 +1,81 @@ +[ + { + "dev":"iax1", + "groups":[ + { + "dev":"group1.0", + }, + { + "dev":"group1.1", + "grouped_workqueues":[ + { + "dev":"wq1.1", + "mode":"dedicated", + "size":16, + "group_id":1, + "priority":10, + "block_on_fault":1, + "max_transfer_size":4194304, + "type":"user", + "name":"wq1.1", + "driver_name":"user", + "threshold":0, + } + ], + "grouped_engines":[ + { + "dev":"engine1.1", + "group_id":1 + } + ] + }, + { + "dev":"group1.2", + "grouped_workqueues":[ + { + "dev":"wq1.4", + "mode":"shared", + "size":40, + "group_id":2, + "priority":10, + "block_on_fault":1, + "max_transfer_size":4194304, + "type":"user", + "name":"wq1.4", + "driver_name":"user", + "threshold":40, + } + ], + "grouped_engines":[ + { + "dev":"engine1.3", + "group_id":2 + } + ] + }, + { + "dev":"group1.3", + } + ], + "ungrouped_engines":[ + { + "dev":"engine1.0" + }, + { + "dev":"engine1.2" + }, + { + "dev":"engine1.4" + }, + { + "dev":"engine1.5" + }, + { + "dev":"engine1.6" + }, + { + "dev":"engine1.7" + } + ] + } +] diff --git a/tests/platform/intel/dsa/configs/4d16g32q_user.conf b/tests/platform/intel/dsa/configs/4d16g32q_user.conf new file mode 100755 index 0000000000000000000000000000000000000000..575a1e840be0d1b37cc57c501f93927028fa79c2 --- /dev/null +++ b/tests/platform/intel/dsa/configs/4d16g32q_user.conf @@ -0,0 +1,646 @@ +[ + { + "dev":"dsa0", + "groups":[ + { + "dev":"group0.0", + "grouped_workqueues":[ + { + "dev":"wq0.0", + "mode":"dedicated", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app1", + "threshold":15 + }, + { + "dev":"wq0.4", + "mode":"dedicated", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app2", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine0.0", + "group_id":0 + } + ] + }, + { + "dev":"group0.1", + "grouped_workqueues":[ + { + "dev":"wq0.1", + "mode":"dedicated", + "size":16, + "group_id":1, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app3", + "threshold":15 + }, + { + "dev":"wq0.5", + "mode":"dedicated", + "size":16, + "group_id":1, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app4", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine0.1", + "group_id":1 + }, + ] + }, + { + "dev":"group0.2", + "grouped_workqueues":[ + { + "dev":"wq0.2", + "mode":"dedicated", + "size":16, + "group_id":2, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app5", + "threshold":15 + }, + { + "dev":"wq0.6", + "mode":"dedicated", + "size":16, + "group_id":2, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app6", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine0.2", + "group_id":2 + } + ] + }, + { + "dev":"group0.3", + "grouped_workqueues":[ + { + "dev":"wq0.3", + "mode":"dedicated", + "size":16, + "group_id":3, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app7", + "threshold":15 + }, + { + "dev":"wq0.7", + "mode":"dedicated", + "size":16, + "group_id":3, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app8", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine0.3", + "group_id":3 + }, + ] + } + ] + }, + { + "dev":"dsa2", + "groups":[ + { + "dev":"group2.0", + "grouped_workqueues":[ + { + "dev":"wq2.0", + "mode":"shared", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app1", + "threshold":15 + }, + { + "dev":"wq2.4", + "mode":"shared", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app2", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine2.0", + "group_id":0 + } + ] + }, + { + "dev":"group2.1", + "grouped_workqueues":[ + { + "dev":"wq2.1", + "mode":"shared", + "size":16, + "group_id":1, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app3", + "threshold":15 + }, + { + "dev":"wq2.5", + "mode":"dedicated", + "size":16, + "group_id":1, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app4", + "threshold":0 + } + ], + "grouped_engines":[ + { + "dev":"engine2.1", + "group_id":1 + } + ] + }, + { + "dev":"group2.2", + "grouped_workqueues":[ + { + "dev":"wq2.2", + "mode":"dedicated", + "size":16, + "group_id":2, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app5", + "threshold":0 + }, + { + "dev":"wq2.6", + "mode":"shared", + "size":16, + "group_id":2, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app6", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine2.2", + "group_id":2 + } + ] + }, + { + "dev":"group2.3", + "grouped_workqueues":[ + { + "dev":"wq2.3", + "mode":"dedicated", + "size":16, + "group_id":3, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app7", + "threshold":0 + }, + { + "dev":"wq2.7", + "mode":"dedicated", + "size":16, + "group_id":3, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app8", + "threshold":0 + } + ], + "grouped_engines":[ + { + "dev":"engine2.3", + "group_id":3 + } + ] + } + ] + }, + { + "dev":"dsa4", + "groups":[ + { + "dev":"group4.0", + "grouped_workqueues":[ + { + "dev":"wq4.0", + "mode":"dedicated", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app1", + "threshold":15 + }, + { + "dev":"wq4.4", + "mode":"dedicated", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app2", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine4.0", + "group_id":0 + } + ] + }, + { + "dev":"group4.1", + "grouped_workqueues":[ + { + "dev":"wq4.1", + "mode":"dedicated", + "size":16, + "group_id":1, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app3", + "threshold":15 + }, + { + "dev":"wq4.5", + "mode":"shared", + "size":16, + "group_id":1, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app4", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine4.1", + "group_id":1 + }, + ] + }, + { + "dev":"group4.2", + "grouped_workqueues":[ + { + "dev":"wq4.2", + "mode":"shared", + "size":16, + "group_id":2, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app5", + "threshold":15 + }, + { + "dev":"wq4.6", + "mode":"dedicated", + "size":16, + "group_id":2, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app6", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine4.2", + "group_id":2 + } + ] + }, + { + "dev":"group4.3", + "grouped_workqueues":[ + { + "dev":"wq4.3", + "mode":"shared", + "size":16, + "group_id":3, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app7", + "threshold":15 + }, + { + "dev":"wq4.7", + "mode":"shared", + "size":16, + "group_id":3, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app8", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine4.3", + "group_id":3 + }, + ] + } + ] + }, + { + "dev":"dsa6", + "groups":[ + { + "dev":"group6.0", + "grouped_workqueues":[ + { + "dev":"wq6.0", + "mode":"shared", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app1", + "threshold":15 + }, + { + "dev":"wq6.4", + "mode":"shared", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app2", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine6.0", + "group_id":0 + } + ] + }, + { + "dev":"group6.1", + "grouped_workqueues":[ + { + "dev":"wq6.1", + "mode":"shared", + "size":16, + "group_id":1, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app3", + "threshold":15 + }, + { + "dev":"wq6.5", + "mode":"shared", + "size":16, + "group_id":1, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app4", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine6.1", + "group_id":1 + } + ] + }, + { + "dev":"group6.2", + "grouped_workqueues":[ + { + "dev":"wq6.2", + "mode":"shared", + "size":16, + "group_id":2, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app5", + "threshold":15 + }, + { + "dev":"wq6.6", + "mode":"shared", + "size":16, + "group_id":2, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app6", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine6.2", + "group_id":2 + } + ] + }, + { + "dev":"group6.3", + "grouped_workqueues":[ + { + "dev":"wq6.3", + "mode":"shared", + "size":16, + "group_id":3, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app7", + "threshold":15 + }, + { + "dev":"wq6.7", + "mode":"shared", + "size":16, + "group_id":3, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app8", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine6.3", + "group_id":3 + } + ] + } + ] + } +] diff --git a/tests/platform/intel/dsa/configs/4d4g4q_user.conf b/tests/platform/intel/dsa/configs/4d4g4q_user.conf new file mode 100755 index 0000000000000000000000000000000000000000..87db923909005569b232dec4dee2275ae893c5d5 --- /dev/null +++ b/tests/platform/intel/dsa/configs/4d4g4q_user.conf @@ -0,0 +1,138 @@ +[ + { + "dev":"dsa0", + "groups":[ + { + "dev":"group0.0", + "grouped_workqueues":[ + { + "dev":"wq0.0", + "mode":"shared", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app1", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine0.0", + "group_id":0 + }, + { + "dev":"engine0.1", + "group_id":0 + } + ] + } + ] + }, + { + "dev":"dsa2", + "groups":[ + { + "dev":"group2.0", + "grouped_workqueues":[ + { + "dev":"wq2.0", + "mode":"dedicated", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app2", + "threshold":0 + } + ], + "grouped_engines":[ + { + "dev":"engine2.0", + "group_id":0 + }, + { + "dev":"engine2.1", + "group_id":0 + } + ] + } + ] + }, + { + "dev":"dsa4", + "groups":[ + { + "dev":"group4.0", + "grouped_workqueues":[ + { + "dev":"wq4.0", + "mode":"shared", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app3", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine4.0", + "group_id":0 + }, + { + "dev":"engine4.1", + "group_id":0 + } + ] + } + ] + }, + { + "dev":"dsa6", + "groups":[ + { + "dev":"group6.0", + "grouped_workqueues":[ + { + "dev":"wq6.0", + "mode":"dedicated", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app4", + "threshold":0 + } + ], + "grouped_engines":[ + { + "dev":"engine6.0", + "group_id":0 + }, + { + "dev":"engine6.1", + "group_id":0 + } + ] + } + ] + } +] diff --git a/tests/platform/intel/dsa/configs/8d32g64q_user.conf b/tests/platform/intel/dsa/configs/8d32g64q_user.conf new file mode 100755 index 0000000000000000000000000000000000000000..e8892817119d019ca025c881a3fbe8159f268d05 --- /dev/null +++ b/tests/platform/intel/dsa/configs/8d32g64q_user.conf @@ -0,0 +1,1290 @@ +[ + { + "dev":"dsa0", + "groups":[ + { + "dev":"group0.0", + "grouped_workqueues":[ + { + "dev":"wq0.0", + "mode":"shared", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app1", + "threshold":15 + }, + { + "dev":"wq0.4", + "mode":"shared", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app2", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine0.0", + "group_id":0 + } + ] + }, + { + "dev":"group0.1", + "grouped_workqueues":[ + { + "dev":"wq0.1", + "mode":"shared", + "size":16, + "group_id":1, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app3", + "threshold":15 + }, + { + "dev":"wq0.5", + "mode":"shared", + "size":16, + "group_id":1, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app4", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine0.1", + "group_id":1 + }, + ] + }, + { + "dev":"group0.2", + "grouped_workqueues":[ + { + "dev":"wq0.2", + "mode":"shared", + "size":16, + "group_id":2, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app5", + "threshold":15 + }, + { + "dev":"wq0.6", + "mode":"shared", + "size":16, + "group_id":2, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app6", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine0.2", + "group_id":2 + } + ] + }, + { + "dev":"group0.3", + "grouped_workqueues":[ + { + "dev":"wq0.3", + "mode":"shared", + "size":16, + "group_id":3, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app7", + "threshold":15 + }, + { + "dev":"wq0.7", + "mode":"shared", + "size":16, + "group_id":3, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app8", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine0.3", + "group_id":3 + }, + ] + } + ] + }, + { + "dev":"dsa2", + "groups":[ + { + "dev":"group2.0", + "grouped_workqueues":[ + { + "dev":"wq2.0", + "mode":"dedicated", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app1", + "threshold":0 + }, + { + "dev":"wq2.4", + "mode":"dedicated", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app2", + "threshold":0 + } + ], + "grouped_engines":[ + { + "dev":"engine2.0", + "group_id":0 + } + ] + }, + { + "dev":"group2.1", + "grouped_workqueues":[ + { + "dev":"wq2.1", + "mode":"dedicated", + "size":16, + "group_id":1, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app3", + "threshold":0 + }, + { + "dev":"wq2.5", + "mode":"dedicated", + "size":16, + "group_id":1, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app4", + "threshold":0 + } + ], + "grouped_engines":[ + { + "dev":"engine2.1", + "group_id":1 + } + ] + }, + { + "dev":"group2.2", + "grouped_workqueues":[ + { + "dev":"wq2.2", + "mode":"dedicated", + "size":16, + "group_id":2, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app5", + "threshold":0 + }, + { + "dev":"wq2.6", + "mode":"dedicated", + "size":16, + "group_id":2, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app6", + "threshold":0 + } + ], + "grouped_engines":[ + { + "dev":"engine2.2", + "group_id":2 + } + ] + }, + { + "dev":"group2.3", + "grouped_workqueues":[ + { + "dev":"wq2.3", + "mode":"dedicated", + "size":16, + "group_id":3, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app7", + "threshold":0 + }, + { + "dev":"wq2.7", + "mode":"dedicated", + "size":16, + "group_id":3, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app8", + "threshold":0 + } + ], + "grouped_engines":[ + { + "dev":"engine2.3", + "group_id":3 + } + ] + } + ] + }, + { + "dev":"dsa4", + "groups":[ + { + "dev":"group4.0", + "grouped_workqueues":[ + { + "dev":"wq4.0", + "mode":"shared", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app1", + "threshold":15 + }, + { + "dev":"wq4.4", + "mode":"shared", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app2", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine4.0", + "group_id":0 + } + ] + }, + { + "dev":"group4.1", + "grouped_workqueues":[ + { + "dev":"wq4.1", + "mode":"shared", + "size":16, + "group_id":1, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app3", + "threshold":15 + }, + { + "dev":"wq4.5", + "mode":"shared", + "size":16, + "group_id":1, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app4", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine4.1", + "group_id":1 + }, + ] + }, + { + "dev":"group4.2", + "grouped_workqueues":[ + { + "dev":"wq4.2", + "mode":"shared", + "size":16, + "group_id":2, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app5", + "threshold":15 + }, + { + "dev":"wq4.6", + "mode":"shared", + "size":16, + "group_id":2, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app6", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine4.2", + "group_id":2 + } + ] + }, + { + "dev":"group4.3", + "grouped_workqueues":[ + { + "dev":"wq4.3", + "mode":"shared", + "size":16, + "group_id":3, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app7", + "threshold":15 + }, + { + "dev":"wq4.7", + "mode":"shared", + "size":16, + "group_id":3, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app8", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine4.3", + "group_id":3 + }, + ] + } + ] + }, + { + "dev":"dsa6", + "groups":[ + { + "dev":"group6.0", + "grouped_workqueues":[ + { + "dev":"wq6.0", + "mode":"dedicated", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app1", + "threshold":0 + }, + { + "dev":"wq6.4", + "mode":"dedicated", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app2", + "threshold":0 + } + ], + "grouped_engines":[ + { + "dev":"engine6.0", + "group_id":0 + } + ] + }, + { + "dev":"group6.1", + "grouped_workqueues":[ + { + "dev":"wq6.1", + "mode":"dedicated", + "size":16, + "group_id":1, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app3", + "threshold":0 + }, + { + "dev":"wq6.5", + "mode":"dedicated", + "size":16, + "group_id":1, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app4", + "threshold":0 + } + ], + "grouped_engines":[ + { + "dev":"engine6.1", + "group_id":1 + } + ] + }, + { + "dev":"group6.2", + "grouped_workqueues":[ + { + "dev":"wq6.2", + "mode":"dedicated", + "size":16, + "group_id":2, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app5", + "threshold":0 + }, + { + "dev":"wq6.6", + "mode":"dedicated", + "size":16, + "group_id":2, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app6", + "threshold":0 + } + ], + "grouped_engines":[ + { + "dev":"engine6.2", + "group_id":2 + } + ] + }, + { + "dev":"group6.3", + "grouped_workqueues":[ + { + "dev":"wq6.3", + "mode":"dedicated", + "size":16, + "group_id":3, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app7", + "threshold":0 + }, + { + "dev":"wq6.7", + "mode":"dedicated", + "size":16, + "group_id":3, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app8", + "threshold":0 + } + ], + "grouped_engines":[ + { + "dev":"engine6.3", + "group_id":3 + } + ] + } + ] + }, + { + "dev":"dsa8", + "groups":[ + { + "dev":"group8.0", + "grouped_workqueues":[ + { + "dev":"wq8.0", + "mode":"shared", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app1", + "threshold":15 + }, + { + "dev":"wq8.4", + "mode":"shared", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app2", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine8.0", + "group_id":0 + } + ] + }, + { + "dev":"group8.1", + "grouped_workqueues":[ + { + "dev":"wq8.1", + "mode":"shared", + "size":16, + "group_id":1, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app3", + "threshold":15 + }, + { + "dev":"wq8.5", + "mode":"shared", + "size":16, + "group_id":1, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app4", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine8.1", + "group_id":1 + }, + ] + }, + { + "dev":"group8.2", + "grouped_workqueues":[ + { + "dev":"wq8.2", + "mode":"shared", + "size":16, + "group_id":2, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app5", + "threshold":15 + }, + { + "dev":"wq8.6", + "mode":"shared", + "size":16, + "group_id":2, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app6", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine8.2", + "group_id":2 + } + ] + }, + { + "dev":"group8.3", + "grouped_workqueues":[ + { + "dev":"wq8.3", + "mode":"shared", + "size":16, + "group_id":3, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app7", + "threshold":15 + }, + { + "dev":"wq8.7", + "mode":"shared", + "size":16, + "group_id":3, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app8", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine8.3", + "group_id":3 + }, + ] + } + ] + }, + { + "dev":"dsa10", + "groups":[ + { + "dev":"group10.0", + "grouped_workqueues":[ + { + "dev":"wq10.0", + "mode":"dedicated", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app1", + "threshold":0 + }, + { + "dev":"wq10.4", + "mode":"dedicated", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app2", + "threshold":0 + } + ], + "grouped_engines":[ + { + "dev":"engine10.0", + "group_id":0 + } + ] + }, + { + "dev":"group10.1", + "grouped_workqueues":[ + { + "dev":"wq10.1", + "mode":"dedicated", + "size":16, + "group_id":1, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app3", + "threshold":0 + }, + { + "dev":"wq10.5", + "mode":"dedicated", + "size":16, + "group_id":1, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app4", + "threshold":0 + } + ], + "grouped_engines":[ + { + "dev":"engine10.1", + "group_id":1 + } + ] + }, + { + "dev":"group10.2", + "grouped_workqueues":[ + { + "dev":"wq10.2", + "mode":"dedicated", + "size":16, + "group_id":2, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app5", + "threshold":0 + }, + { + "dev":"wq10.6", + "mode":"dedicated", + "size":16, + "group_id":2, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app6", + "threshold":0 + } + ], + "grouped_engines":[ + { + "dev":"engine10.2", + "group_id":2 + } + ] + }, + { + "dev":"group10.3", + "grouped_workqueues":[ + { + "dev":"wq10.3", + "mode":"dedicated", + "size":16, + "group_id":3, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app7", + "threshold":0 + }, + { + "dev":"wq10.7", + "mode":"dedicated", + "size":16, + "group_id":3, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app8", + "threshold":0 + } + ], + "grouped_engines":[ + { + "dev":"engine10.3", + "group_id":3 + } + ] + } + ] + }, + { + "dev":"dsa12", + "groups":[ + { + "dev":"group12.0", + "grouped_workqueues":[ + { + "dev":"wq12.0", + "mode":"shared", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app1", + "threshold":15 + }, + { + "dev":"wq12.4", + "mode":"shared", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app2", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine12.0", + "group_id":0 + } + ] + }, + { + "dev":"group12.1", + "grouped_workqueues":[ + { + "dev":"wq12.1", + "mode":"shared", + "size":16, + "group_id":1, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app3", + "threshold":15 + }, + { + "dev":"wq12.5", + "mode":"shared", + "size":16, + "group_id":1, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app4", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine12.1", + "group_id":1 + }, + ] + }, + { + "dev":"group12.2", + "grouped_workqueues":[ + { + "dev":"wq12.2", + "mode":"shared", + "size":16, + "group_id":2, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app5", + "threshold":15 + }, + { + "dev":"wq12.6", + "mode":"shared", + "size":16, + "group_id":2, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app6", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine12.2", + "group_id":2 + } + ] + }, + { + "dev":"group12.3", + "grouped_workqueues":[ + { + "dev":"wq12.3", + "mode":"shared", + "size":16, + "group_id":3, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app7", + "threshold":15 + }, + { + "dev":"wq12.7", + "mode":"shared", + "size":16, + "group_id":3, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app8", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine12.3", + "group_id":3 + }, + ] + } + ] + }, + { + "dev":"dsa14", + "groups":[ + { + "dev":"group14.0", + "grouped_workqueues":[ + { + "dev":"wq14.0", + "mode":"dedicated", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app1", + "threshold":0 + }, + { + "dev":"wq14.4", + "mode":"dedicated", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app2", + "threshold":0 + } + ], + "grouped_engines":[ + { + "dev":"engine14.0", + "group_id":0 + } + ] + }, + { + "dev":"group14.1", + "grouped_workqueues":[ + { + "dev":"wq14.1", + "mode":"dedicated", + "size":16, + "group_id":1, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app3", + "threshold":0 + }, + { + "dev":"wq14.5", + "mode":"dedicated", + "size":16, + "group_id":1, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app4", + "threshold":0 + } + ], + "grouped_engines":[ + { + "dev":"engine14.1", + "group_id":1 + } + ] + }, + { + "dev":"group14.2", + "grouped_workqueues":[ + { + "dev":"wq14.2", + "mode":"dedicated", + "size":16, + "group_id":2, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app5", + "threshold":0 + }, + { + "dev":"wq14.6", + "mode":"dedicated", + "size":16, + "group_id":2, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app6", + "threshold":0 + } + ], + "grouped_engines":[ + { + "dev":"engine14.2", + "group_id":2 + } + ] + }, + { + "dev":"group14.3", + "grouped_workqueues":[ + { + "dev":"wq14.3", + "mode":"dedicated", + "size":16, + "group_id":3, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app7", + "threshold":0 + }, + { + "dev":"wq14.7", + "mode":"dedicated", + "size":16, + "group_id":3, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app8", + "threshold":0 + } + ], + "grouped_engines":[ + { + "dev":"engine14.3", + "group_id":3 + } + ] + } + ] + } +] diff --git a/tests/platform/intel/dsa/configs/8d8g8q_user.conf b/tests/platform/intel/dsa/configs/8d8g8q_user.conf new file mode 100755 index 0000000000000000000000000000000000000000..e5a7363d7bc5ff0aeb9e5a79168a90c0de683685 --- /dev/null +++ b/tests/platform/intel/dsa/configs/8d8g8q_user.conf @@ -0,0 +1,274 @@ +[ + { + "dev":"dsa0", + "groups":[ + { + "dev":"group0.0", + "grouped_workqueues":[ + { + "dev":"wq0.0", + "mode":"shared", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app1", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine0.0", + "group_id":0 + }, + { + "dev":"engine0.1", + "group_id":0 + } + ] + } + ] + }, + { + "dev":"dsa2", + "groups":[ + { + "dev":"group2.0", + "grouped_workqueues":[ + { + "dev":"wq2.0", + "mode":"dedicated", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app2", + "threshold":0 + } + ], + "grouped_engines":[ + { + "dev":"engine2.0", + "group_id":0 + }, + { + "dev":"engine2.1", + "group_id":0 + } + ] + } + ] + }, + { + "dev":"dsa4", + "groups":[ + { + "dev":"group4.0", + "grouped_workqueues":[ + { + "dev":"wq4.0", + "mode":"shared", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app3", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine4.0", + "group_id":0 + }, + { + "dev":"engine4.1", + "group_id":0 + } + ] + } + ] + }, + { + "dev":"dsa6", + "groups":[ + { + "dev":"group6.0", + "grouped_workqueues":[ + { + "dev":"wq6.0", + "mode":"dedicated", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app4", + "threshold":0 + } + ], + "grouped_engines":[ + { + "dev":"engine6.0", + "group_id":0 + }, + { + "dev":"engine6.1", + "group_id":0 + } + ] + } + ] + }, + { + "dev":"dsa8", + "groups":[ + { + "dev":"group8.0", + "grouped_workqueues":[ + { + "dev":"wq8.0", + "mode":"shared", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app5", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine8.0", + "group_id":0 + }, + { + "dev":"engine8.1", + "group_id":0 + } + ] + } + ] + }, + { + "dev":"dsa10", + "groups":[ + { + "dev":"group10.0", + "grouped_workqueues":[ + { + "dev":"wq10.0", + "mode":"dedicated", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app6", + "threshold":0 + } + ], + "grouped_engines":[ + { + "dev":"engine10.0", + "group_id":0 + }, + { + "dev":"engine10.1", + "group_id":0 + } + ] + } + ] + }, + { + "dev":"dsa12", + "groups":[ + { + "dev":"group12.0", + "grouped_workqueues":[ + { + "dev":"wq12.0", + "mode":"shared", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app7", + "threshold":15 + } + ], + "grouped_engines":[ + { + "dev":"engine12.0", + "group_id":0 + }, + { + "dev":"engine12.1", + "group_id":0 + } + ] + } + ] + }, + { + "dev":"dsa14", + "groups":[ + { + "dev":"group14.0", + "grouped_workqueues":[ + { + "dev":"wq14.0", + "mode":"dedicated", + "size":16, + "group_id":0, + "priority":10, + "block_on_fault":1, + "max_batch_size":1024, + "max_transfer_size":2147483648, + "type":"user", + "driver_name":"user", + "name":"app8", + "threshold":0 + } + ], + "grouped_engines":[ + { + "dev":"engine14.0", + "group_id":0 + }, + { + "dev":"engine14.1", + "group_id":0 + } + ] + } + ] + } +] diff --git a/tests/platform/intel/dsa/dsa_user.sh b/tests/platform/intel/dsa/dsa_user.sh new file mode 100755 index 0000000000000000000000000000000000000000..dd9ae848a947744c07713c94ac18614349c5ab1d --- /dev/null +++ b/tests/platform/intel/dsa/dsa_user.sh @@ -0,0 +1,85 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) 2023 Intel Corporation +# Description: Test script for Data Streaming Accelerator(DSA) + +cd "$(dirname "$0")" 2>/dev/null && source ../.env + +: "${CASE_NAME:="check_dsa_driver"}" + +usage() { + cat <<__EOF + usage: ./${0##*/} [-t TESTCASE_ID] [-H] + -t TEST CASE ID + -H show this +__EOF +} + +# Check if idxd driver is loaded +# Return: 0 for true, otherwise false +check_dsa_driver() { + if lsmod | grep -q "idxd"; then + test_print_trc "dsa: idxd driver is loaded [PASS]" + else + die "dsa: idxd driver is not loaded [FAIL]" + fi +} + +# Check if there is dsa device dsa0 +check_dsa0_device() { + if [ -d "/sys/bus/dsa/devices/dsa0" ]; then + test_print_trc "dsa: there is dsa0 device [PASS]" + else + die "dsa: no dsa0 device [FAIL]" + fi +} + +# check if pasid is supported +check_shared_mode() { + [ ! -f "/sys/bus/dsa/devices/dsa0/pasid_enabled" ] && echo "No SVM support" && exit 1 + pasid_en=$(cat /sys/bus/dsa/devices/dsa0/pasid_enabled) + if [ "$pasid_en" -eq 1 ]; then + test_print_trc "dsa: shared mode is enabled [PASS]" + else + die "dsa: shared mode is not enabled [FAIL]" + fi +} + +dsa_test() { + case $TEST_SCENARIO in + check_dsa_driver) + check_dsa_driver + ;; + check_dsa0_device) + check_dsa0_device + ;; + check_shared_mode) + check_shared_mode + ;; + *) + block_test "Invalid NAME:$NAME for test number." + ;; + esac + return 0 +} + +while getopts :t:H arg; do + case $arg in + t) + TEST_SCENARIO=$OPTARG + ;; + H) + usage && exit 0 + ;; + \?) + usage + die "Invalid Option -$OPTARG" + ;; + :) + usage + die "Option -$OPTARG requires an argument." + ;; + esac +done + +dsa_test diff --git a/tests/platform/intel/dsa/dsa_user_test.sh b/tests/platform/intel/dsa/dsa_user_test.sh new file mode 100755 index 0000000000000000000000000000000000000000..f3f1afb5a40e785b8f338807dea0634dab7b6517 --- /dev/null +++ b/tests/platform/intel/dsa/dsa_user_test.sh @@ -0,0 +1,375 @@ +#!/usr/bin/env bash + +# +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2021 Intel Corporation +# +# Description: Call dsa_test to run dsa user test +DIRNAME=$(dirname "$0") +DSA_DIR="$PWD/$DIRNAME" +CONFIG_DIR="$DSA_DIR/configs" +ACCFG=/usr/bin/accel-config +TEST_DIR=/usr/libexec/accel-config/test +DSATEST=$TEST_DIR/dsa_test + +source "$PWD/$DIRNAME/../common/common.sh" +############################# FUNCTIONS ####################################### + +# Global variables +export SIZE_1=1 +export SIZE_512=512 +export SIZE_1K=1024 +export SIZE_4K=4096 +export SIZE_64K=65536 +export SIZE_1M=1048576 +export SIZE_2M=2097152 +export EXIT_FAILURE=1 +export EXIT_SKIP=77 + +usage() { + cat <<__EOF + usage: ./${0##*/} [-c CONFIG_NAME] [-g GUEST_ONLY] [-o OPCODE] [-h] + -c dsa config file + -g set 1 if guest + -o test opcoce + -h show this +__EOF +} + +# translate opcode to name +# $1 opcode +# +opcode2name() +{ + local opcode="$1" + dec_opcode=$((opcode)) + case $dec_opcode in + "3") + echo "MEMMOVE" + ;; + "4") + echo "MEMFILL" + ;; + "5") + echo "COMPARE" + ;; + "6") + echo "COMPVAL" + ;; + "9") + echo "DUALCAST" + ;; + *) + echo "UNKNOWN" + ;; + esac +} + +# translate WQ mode code to name +# $1 Wq mode code +# +wq_mode2name() +{ + local wq_mode="$1" + dec_wq_mode=$((wq_mode)) + case $dec_wq_mode in + "0") + echo "dedicated" + ;; + "1") + echo "shared" + ;; + *) + echo "UNKNOWN" + ;; + esac +} + +# Check if accel-config and dsa_test installed and worked. +function checking_test_precondition() +{ + # ACCFG + if [ -f "$ACCFG" ] && [ -x "$ACCFG" ]; then + test_print_trc "accfg1:$ACCFG" + else + test_print_trc "Couldn't find an accel-config binary" + exit "$EXIT_FAILURE" + fi + + # DSATEST + if [ -f "$DSATEST" ] && [ -x "$DSATEST" ]; then + test_print_trc "dsa_test1:$DSATEST" + else + test_print_trc "Couldn't find an dsa_test binary" + exit "$EXIT_FAILURE" + fi + + return 0 +} + +# If idxd module is not loaded, load it +load_idxd_module() { + lsmod | grep -w -q "idxd" || { + modprobe idxd + sleep 1 + } +} + +# load/unload drivers to make sure load config file successfully +reset_idxd() +{ + lsmod | grep -q "iaa_crypto" && { + rmmod iaa_crypto + } + lsmod | grep -q "iax_crypto" && { + rmmod iax_crypto + } + lsmod | grep -q "idxd_mdev" && { + rmmod idxd_mdev + } + lsmod | grep -q "idxd_vdev" && { + rmmod idxd_vdev + } + lsmod | grep -q "idxd_uacce" && { + rmmod idxd_uacce + } + lsmod | grep -q "idxd" && { + rmmod idxd + } + sleep 1 + modprobe idxd + sleep 1 +} + +load_config() +{ + # CONFIGS + if [ -f "$CONFIG_DIR/$CONFIG_NAME.conf" ]; then + export CONFIG1=$DSA_DIR/configs/${CONFIG_NAME}.conf + else + test_print_trc "Can't find config file $CONFIG_DIR/configs/$CONFIG_NAME.conf" + exit "$EXIT_FAILURE" + fi + configurable=$(cat /sys/bus/dsa/devices/dsa0/configurable) + if [ "$configurable" ]; then + do_cmd "$ACCFG" load-config -c "$CONFIG1" + fi +} + +# Disable all active devices dsa/iax and enabled wqs. +# Use accel-config tool to disable the device and wq. +disable_all() { + test_print_trc "Start to disable the device and wq" + for device_type in 'dsa' 'iax'; do + # Kernel before 5.13 has dsa and iax bus. Because of ABI change, iax + # bus is removed. All devices are in /sys/bus/das/devices. + if [ -d /sys/bus/iax ] && [ $device_type == 'iax' ]; then + DSA_DEVICE_PATH="/sys/bus/iax/devices" + else + DSA_DEVICE_PATH="/sys/bus/dsa/devices" + fi + # Get available devices + for device_path in "${DSA_DEVICE_PATH}"/"${device_type}"* ; do + [[ $(echo "$device_path" | grep -c '!') -eq 0 ]] && { + # Get wqs and disable it if the status is enabled + for wqp in "${device_path}"/wq* ; do + [[ $( cat "${wqp}"/state ) == "enabled" ]] && { + wq=${wqp##"${DSA_DEVICE_PATH}"/} + test_print_trc "info:disable wq $wq" + "$ACCFG" disable-wq "${wq}" + echo "-1" > "${wqp}"/group_id + } + done + # Disable device + [[ $( cat "${device_path}"/state ) == "enabled" ]] && { + test_print_trc "info:disable ${device_path##"${DSA_DEVICE_PATH}"/}" + "$ACCFG" disable-device "${device_path##"${DSA_DEVICE_PATH}"/}" + } + # Remove group id of engine + for engine in "${device_path}"/engine* ; do + echo -1 > "$engine"/group_id + done + } + done + done + test_print_trc "disable_all is end" +} + +dsa_user_teardown(){ + if [ "$GUEST_ONLY" == "0" ]; then + disable_all + fi +} + +# Test operation with a given opcode +# $1: opcode (e.g. 0x3 for memmove) +# $2: flag (optional, default 0x3 for BOF on, 0x2 for BOF off) +# +test_op() +{ + local opcode="$1" + local flag="$2" + local op_name + op_name=$(opcode2name "$opcode") + local wq_mode_code + local wq_mode_name + local xfer_size + + for wq_mode_code in 0 1; do + wq_mode_name=$(wq_mode2name "$wq_mode_code") + test_print_trc "Performing $wq_mode_name WQ $op_name testing" + for xfer_size in $SIZE_512 $SIZE_1K $SIZE_4K; do + test_print_trc "Testing $xfer_size bytes" + do_cmd "$DSATEST" -w "$wq_mode_code" -l "$xfer_size" -o "$opcode" \ + -f "$flag" t200 -v + done + done +} + +# Test operation in batch mode with a given opcode +# $1: opcode (e.g. 0x3 for memmove) +# $2: flag (optional, default 0x3 for BOF on, 0x2 for BOF off) +# +test_op_batch() +{ + local opcode="$1" + local flag="$2" + local op_name + op_name=$(opcode2name "$opcode") + local wq_mode_code + local wq_mode_name + local xfer_size + + if [ "$opcode" == "0x2" ];then + return 0 + fi + + for wq_mode_code in 0 1; do + wq_mode_name=$(wq_mode2name "$wq_mode_code") + test_print_trc "Performing $wq_mode_name WQ batched $op_name testing" + for xfer_size in $SIZE_512 $SIZE_1K $SIZE_4K; do + test_print_trc "Testing $xfer_size bytes" + do_cmd "$DSATEST" -w "$wq_mode_code" -l "$xfer_size" -o 0x1 -b "$opcode" \ + -c 16 -f "$flag" t2000 -v + done + done +} + +dsa_user_test() { + + reset_idxd + # skip if no pasid support as dsa_test does not support operation w/o pasid yet. + [ ! -f "/sys/bus/dsa/devices/dsa0/pasid_enabled" ] && test_print_trc "No SVM support" && exit "$EXIT_SKIP" + + checking_test_precondition + + if [ "$GUEST_ONLY" == "0" ]; then + load_config + case $CONFIG_NAME in + 1d2g2q_user) + "$ACCFG" enable-device "dsa0" + "$ACCFG" enable-wq "dsa0/wq0.0" + "$ACCFG" enable-wq "dsa0/wq0.1" + ;; + 1d4g8q_user) + "$ACCFG" enable-device "dsa0" + "$ACCFG" enable-wq "dsa0/wq0.0" + "$ACCFG" enable-wq "dsa0/wq0.1" + "$ACCFG" enable-wq "dsa0/wq0.2" + "$ACCFG" enable-wq "dsa0/wq0.3" + "$ACCFG" enable-wq "dsa0/wq0.4" + "$ACCFG" enable-wq "dsa0/wq0.5" + "$ACCFG" enable-wq "dsa0/wq0.6" + "$ACCFG" enable-wq "dsa0/wq0.7" + ;; + 4d4g4q_user) + for i in {0..6..2} + do + "$ACCFG" enable-device "dsa$i" + "$ACCFG" enable-wq "dsa$i/wq$i.0" + done + ;; + 4d16g32q_user) + for i in {0..6..2} + do + "$ACCFG" enable-device "dsa$i" + "$ACCFG" enable-wq "dsa$i/wq$i.0" + "$ACCFG" enable-wq "dsa$i/wq$i.1" + "$ACCFG" enable-wq "dsa$i/wq$i.2" + "$ACCFG" enable-wq "dsa$i/wq$i.3" + "$ACCFG" enable-wq "dsa$i/wq$i.4" + "$ACCFG" enable-wq "dsa$i/wq$i.5" + "$ACCFG" enable-wq "dsa$i/wq$i.6" + "$ACCFG" enable-wq "dsa$i/wq$i.7" + done + ;; + 8d8g8q_user) + for i in {0..14..2} + do + "$ACCFG" enable-device "dsa$i" + "$ACCFG" enable-wq "dsa$i/wq$i.0" + done + ;; + 8d32g64q_user) + for i in {0..14..2} + do + "$ACCFG" enable-device "dsa$i" + "$ACCFG" enable-wq "dsa$i/wq$i.0" + "$ACCFG" enable-wq "dsa$i/wq$i.1" + "$ACCFG" enable-wq "dsa$i/wq$i.2" + "$ACCFG" enable-wq "dsa$i/wq$i.3" + "$ACCFG" enable-wq "dsa$i/wq$i.4" + "$ACCFG" enable-wq "dsa$i/wq$i.5" + "$ACCFG" enable-wq "dsa$i/wq$i.6" + "$ACCFG" enable-wq "dsa$i/wq$i.7" + done + ;; + *) + die "Invalid config file name!" + ;; + esac + fi + + for flag in 0x0 0x1; do + test_print_trc "Testing with 'block on fault' flag ON OFF" + test_op "$OPCODE" "$flag" + test_op_batch "$OPCODE" "$flag" + done + + return 0 +} + +################################ DO THE WORK ################################## + +CONFIG_NAME="1d2g2q_user_1" +GUEST_ONLY="0" +OPCODE="0x03" + +while getopts :c:g:o:h arg; do + case $arg in + c) + CONFIG_NAME=$OPTARG + ;; + g) + GUEST_ONLY=$OPTARG + ;; + o) + OPCODE=$OPTARG + ;; + h) + usage && exit 0 + ;; + \?) + usage + die "Invalid Option -$OPTARG" + ;; + :) + usage + die "Option -$OPTARG requires an argument." + ;; + esac +done + +dsa_user_test +#teardown_handler="dsa_user_teardown" +exec_teardown diff --git a/tests/platform/intel/dsa/iax_user_test.sh b/tests/platform/intel/dsa/iax_user_test.sh new file mode 100755 index 0000000000000000000000000000000000000000..436498c577ada740d9875f96ad4363819ca46974 --- /dev/null +++ b/tests/platform/intel/dsa/iax_user_test.sh @@ -0,0 +1,495 @@ +#!/usr/bin/env bash +# +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2021 Intel Corporation +# +# Description: Call iaa_test to run iax user test + +source "$PWD/$DIRNAME/../common/common.sh" + +DIRNAME=$(dirname "$0") +IAX_DIR=$PWD/$DIRNAME +CONFIG_DIR=$IAX_DIR/configs +ACCFG=/usr/bin/accel-config +TEST_DIR=/usr/libexec/accel-config/test +IAXTEST=$TEST_DIR/iaa_test + +############################# FUNCTIONS ####################################### + +# Global variables +export SIZE_1=1 +export SIZE_16=16 +export SIZE_32=32 +export SIZE_64=64 +export SIZE_128=128 +export SIZE_256=256 +export SIZE_512=512 +export SIZE_1K=1024 +export SIZE_2K=2048 +export SIZE_4K=4096 +export SIZE_16K=16384 +export SIZE_32K=32768 +export SIZE_64K=65536 +export SIZE_128K=131072 +export SIZE_256K=262144 +export SIZE_512K=524288 +export SIZE_1M=1048576 +export SIZE_2M=2097152 +export EXIT_FAILURE=1 +export EXIT_SKIP=77 +TESTDIR=/usr/share/accel-config/test +BINDIR=/usr/bin + +usage() { + cat <<__EOF + usage: ./${0##*/} [-c CONFIG_NAME] [-g GUEST_ONLY] [-o OPCODE] [-w WQ_MODE] [-h] + -c iax config file + -g set 1 if guest + -o test opcoce + -w shared mode or dedicated mode work queue + -h show this +__EOF +} + +# translate opcode to name +# $1 opcode +# +opcode2name() +{ + local opcode="$1" + case $opcode in + 0x42) + echo "Decompress" + ;; + 0x43) + echo "Compress" + ;; + 0x44) + echo "CRC64" + ;; + 0x48) + echo "Zdecompress32" + ;; + 0x49) + echo "Zdecompress16" + ;; + 0x4c) + echo "Zcompress32" + ;; + 0x4d) + echo "Zcompress16" + ;; + 0x50) + echo "Scan" + ;; + 0x51) + echo "Set Membership" + ;; + 0x52) + echo "Extract" + ;; + 0x53) + echo "Select" + ;; + 0x54) + echo "RLE Burst" + ;; + 0x55) + echo "Find Unique" + ;; + 0x56) + echo "Expand" + ;; + *) + echo "UNKNOWN" + ;; + esac +} + +# translate WQ mode code to name +# $1 Wq mode code +# +wq_mode2name() +{ + local wq_mode="$1" + dec_wq_mode=$((wq_mode)) + case $dec_wq_mode in + "0") + echo "dedicated" + ;; + "1") + echo "shared" + ;; + *) + echo "UNKNOWN" + ;; + esac +} + +# Check if accel-config and iaa_test installed and worked. +function checking_test_precondition() +{ + # ACCFG + if [ -f "$BINDIR/accel-config" ] && [ -x "$BINDIR/accel-config" ]; then + export ACCFG="$BINDIR"/accel-config + test_print_trc "accfg1:$ACCFG" + else + test_print_trc "Couldn't find an accel-config binary" + exit "$EXIT_FAILURE" + fi + + # IAXTEST + if [ -f "$IAXTEST" ] && [ -x "$IAXTEST" ]; then + export IAXTEST=$IAXTEST + test_print_trc "iax_test1:$IAXTEST" + elif [ -f "$TESTDIR/iaa_test" ] && [ -x "$TESTDIR/iaa_test" ]; then + export IAXTEST="$IAXTEST" + test_print_trc "iax_test2:$IAXTEST" + else + test_print_trc "Couldn't find an iaa_test binary" + exit "$EXIT_FAILURE" + fi + + return 0 +} + +# If idxd module is not loaded, load it +load_idxd_module() { + lsmod | grep -w -q "idxd" || { + modprobe idxd + sleep 1 + } +} + +# load/unload drivers to make sure load config file successfully +reset_idxd() +{ + lsmod | grep -q "iaa_crypto" && { + rmmod iaa_crypto + } + lsmod | grep -q "iax_crypto" && { + rmmod iax_crypto + } + lsmod | grep -q "idxd_mdev" && { + rmmod idxd_mdev + } + lsmod | grep -q "idxd_vdev" && { + rmmod idxd_vdev + } + lsmod | grep -q "idxd_uacce" && { + rmmod idxd_uacce + } + lsmod | grep -q "idxd" && { + rmmod idxd + } + sleep 1 + modprobe idxd + sleep 1 +} + +load_config() +{ + iax_disable_wq + # CONFIGS + if [ -f "$CONFIG_DIR/$CONFIG_NAME.conf" ]; then + export CONFIG1=$CONFIG_DIR/${CONFIG_NAME}.conf + else + test_print_trc "Can't find config file $CONFIG_DIR/$CONFIG_NAME.conf" + exit "$EXIT_FAILURE" + fi + configurable=$(cat /sys/bus/dsa/devices/iax1/configurable) + if [ "$configurable" ]; then + do_cmd "$ACCFG" load-config -c "$CONFIG1" + fi +} + +# Disable all active devices iax/iax and enabled wqs. +# Use accel-config tool to disable the device and wq. +disable_all() { + test_print_trc "Start to disable the device and wq" + for device_type in 'dsa' 'iax'; do + # Kernel before 5.13 has iax and iax bus. Because of ABI change, iax + # bus is removed. All devices are in /sys/bus/dsa/devices. + if [ -d /sys/bus/iax ] && [ $device_type == 'iax' ]; then + IAX_DEVICE_PATH="/sys/bus/iax/devices" + else + IAX_DEVICE_PATH="/sys/bus/dsa/devices" + fi + # Get available devices + for device_path in "${IAX_DEVICE_PATH}"/"${device_type}"* ; do + [[ $(echo "$device_path" | grep -c '!') -eq 0 ]] && { + # Get wqs and disable it if the status is enabled + for wqp in "${device_path}"/wq* ; do + [[ $( cat "${wqp}"/state ) == "enabled" ]] && { + wq=${wqp##"${IAX_DEVICE_PATH}"/} + test_print_trc "info:disable wq $wq" + "$ACCFG" disable-wq "${wq}" + echo "-1" > "${wqp}"/group_id + } + done + # Disable device + [[ $( cat "${device_path}"/state ) == "enabled" ]] && { + test_print_trc "info:disable ${device_path##"${IAX_DEVICE_PATH}"/}" + "$ACCFG" disable-device "${device_path##"${IAX_DEVICE_PATH}"/}" + } + # Remove group id of engine + for engine in "${device_path}"/engine* ; do + echo -1 > "$engine"/group_id + done + } + done + done + test_print_trc "disable_all is end" +} + +iax_disable_wq() { + iaa_dev_id="0cfe" + num_iaa=$(lspci -d:${iaa_dev_id} | wc -l) + + for ((i = 1; i < num_iaa * 2; i += 2)); do + echo disable wq iax${i}/wq${i}.0 + accel-config disable-wq iax${i}/wq${i}.0 + + echo disable iaa iax${i} + accel-config disable-device iax${i} + done +} + +iax_user_teardown(){ + if [ "$GUEST_ONLY" == "0" ]; then + disable_all + reset_idxd + iax_disable_wq + fi +} + +# Test operation with a given opcode +# $1: opcode (e.g. 0x0 for No-op) +# $2: flag (optional, default 0x3 for BOF on, 0x2 for BOF off) +# +test_op() +{ + local opcode="$1" + local flag="$2" + local wq_mode="$3" + local op_name + op_name=$(opcode2name "$opcode") + local wq_mode_name + local xfer_size + + wq_mode_name=$(wq_mode2name "$wq_mode") + test_print_trc "Performing $wq_mode_name WQ $op_name testing" + case $opcode in + 0x44) + for xfer_size in $SIZE_1 $SIZE_4K $SIZE_64K $SIZE_1M $SIZE_2M; do + test_print_trc "Testing $xfer_size bytes" + "$IAXTEST" -w "$wq_mode" -l "$xfer_size" \ + -o "$opcode" -1 "0x8000" -f "$flag" t200 -v + done + for xfer_size in $SIZE_1 $SIZE_4K $SIZE_64K $SIZE_1M $SIZE_2M; do + test_print_trc "Testing $xfer_size bytes" + "$IAXTEST" -w "$wq_mode" -l "$xfer_size" \ + -o "$opcode" -1 "0x4000" -f "$flag" t200 -v + done + ;; + 0x42|0x43|0x48|0x49|0x4c|0x4d) + for xfer_size in $SIZE_4K $SIZE_64K $SIZE_1M $SIZE_2M; do + test_print_trc "Testing $xfer_size bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$xfer_size" \ + -o "$opcode" -f "$flag" t200 -v + done + ;; + 0x50|0x52|0x53|0x56) + test_print_trc "Testing $SIZE_512 bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$SIZE_512" -2 "0x7c" \ + -3 "$SIZE_128" -o "$opcode" -f "$flag" t200 -v + + test_print_trc "Testing $SIZE_1K bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$SIZE_1K" -2 "0x7c" \ + -3 "$SIZE_256" -o "$opcode" -f "$flag" t200 -v + + test_print_trc "Testing $SIZE_4K bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$SIZE_4K" -2 "0x7c" \ + -3 "$SIZE_1K" -o "$opcode" -f "$flag" t200 -v + + test_print_trc "Testing $SIZE_64K bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$SIZE_64K" -2 "0x7c" \ + -3 "$SIZE_16K" -o "$opcode" -f "$flag" t200 -v + + test_print_trc "Testing $SIZE_1M bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$SIZE_1M" -2 "0x7c" \ + -3 "$SIZE_256K" -o "$opcode" -f "$flag" t200 -v + + test_print_trc "Testing $SIZE_2M bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$SIZE_2M" -2 "0x7c" \ + -3 "$SIZE_512K" -o "$opcode" -f "$flag" t200 -v + ;; + 0x51|0x55) + test_print_trc "Testing $SIZE_512 bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$SIZE_512" -2 "0x38" \ + -3 "$SIZE_256" -o "$opcode" -f "$flag" t200 -v + + test_print_trc "Testing $SIZE_1K bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$SIZE_1K" -2 "0x38" \ + -3 "$SIZE_512" -o "$opcode" -f "$flag" t200 -v + + test_print_trc "Testing $SIZE_4K bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$SIZE_4K" -2 "0x38" \ + -3 "$SIZE_2K" -o "$opcode" -f "$flag" t200 -v + + test_print_trc "Testing $SIZE_64K bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$SIZE_64K" -2 "0x38" \ + -3 "$SIZE_32K" -o "$opcode" -f "$flag" t200 -v + + test_print_trc "Testing $SIZE_1M bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$SIZE_1M" -2 "0x38" \ + -3 "$SIZE_512K" -o "$opcode" -f "$flag" t200 -v + + test_print_trc "Testing $SIZE_2M bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$SIZE_2M" -2 "0x38" \ + -3 "$SIZE_1M" -o "$opcode" -f "$flag" t200 -v + ;; + 0x54) + test_print_trc "Testing $SIZE_512 bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$SIZE_512" -2 "0x1c" \ + -3 "$SIZE_512" -o "$opcode" -f "$flag" t200 -v + + test_print_trc "Testing $SIZE_1K bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$SIZE_1K" -2 "0x1c" \ + -3 "$SIZE_1K" -o "$opcode" -f "$flag" t200 -v + + test_print_trc "Testing $SIZE_4K bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$SIZE_4K" -2 "0x1c" \ + -3 "$SIZE_4K" -o "$opcode" -f "$flag" t200 -v + + test_print_trc "Testing $SIZE_32K bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$SIZE_32K" -2 "0x1c" \ + -3 "$SIZE_32K" -o "$opcode" -f "$flag" t200 -v + + test_print_trc "Testing $SIZE_64K bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$SIZE_64K" -2 "0x1c" \ + -3 "$SIZE_64K" -o "$opcode" -f "$flag" t200 -v + + test_print_trc "Testing $SIZE_128K bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$SIZE_128K" -2 "0x1c" \ + -3 "$SIZE_128K" -o "$opcode" -f "$flag" t200 -v + + test_print_trc "Testing $SIZE_32 bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$SIZE_32" -2 "0x3c" \ + -3 "$SIZE_16" -o "$opcode" -f "$flag" t200 -v + + test_print_trc "Testing $SIZE_64 bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$SIZE_64" -2 "0x3c" \ + -3 "$SIZE_32" -o "$opcode" -f "$flag" t200 -v + + test_print_trc "Testing $SIZE_128 bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$SIZE_128" -2 "0x3c" \ + -3 "$SIZE_64" -o "$opcode" -f "$flag" t200 -v + + test_print_trc "Testing $SIZE_256 bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$SIZE_256" -2 "0x3c" \ + -3 "$SIZE_128" -o "$opcode" -f "$flag" t200 -v + + test_print_trc "Testing $SIZE_512 bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$SIZE_512" -2 "0x3c" \ + -3 "$SIZE_256" -o "$opcode" -f "$flag" t200 -v + + test_print_trc "Testing $SIZE_1K bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$SIZE_1K" -2 "0x3c" \ + -3 "$SIZE_512" -o "$opcode" -f "$flag" t200 -v + + test_print_trc "Testing $SIZE_64 bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$SIZE_64" -2 "0x7c" \ + -3 "$SIZE_16" -o "$opcode" -f "$flag" t200 -v + + test_print_trc "Testing $SIZE_128 bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$SIZE_128" -2 "0x7c" \ + -3 "$SIZE_32" -o "$opcode" -f "$flag" t200 -v + + test_print_trc "Testing $SIZE_256 bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$SIZE_256" -2 "0x7c" \ + -3 "$SIZE_64" -o "$opcode" -f "$flag" t200 -v + + test_print_trc "Testing $SIZE_512 bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$SIZE_512" -2 "0x7c" \ + -3 "$SIZE_128" -o "$opcode" -f "$flag" t200 -v + + test_print_trc "Testing $SIZE_1K bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$SIZE_1K" -2 "0x7c" \ + -3 "$SIZE_256" -o "$opcode" -f "$flag" t200 -v + + test_print_trc "Testing $SIZE_2K bytes" + do_cmd "$IAXTEST" -w "$wq_mode" -l "$SIZE_2K" -2 "0x7c" \ + -3 "$SIZE_512" -o "$opcode" -f "$flag" t200 -v + ;; + esac +} + +iax_user_test() { + + load_idxd_module + # skip if no pasid support as iax_test does not support operation w/o pasid yet. + [ ! -f "/sys/bus/dsa/devices/iax1/pasid_enabled" ] && test_print_trc "No SVM support" && exit "$EXIT_SKIP" + + checking_test_precondition + + if [ "$GUEST_ONLY" == "0" ]; then + load_config + case $CONFIG_NAME in + 2g2q_user_2) + "$ACCFG" enable-device "iax1" + "$ACCFG" enable-wq "iax1/wq1.1" + "$ACCFG" enable-wq "iax1/wq1.4" + ;; + *) + die "Invalid config file name!" + ;; + esac + fi + + for flag in 0x0 0x1; do + test_print_trc "Testing with 'block on fault' flag ON OFF" + test_op "$OPCODE" "$flag" "$WQ_MODE" + done + + return 0 +} + +################################ DO THE WORK ################################## + +CONFIG_NAME="2g2q_user_2" +GUEST_ONLY="0" +OPCODE="0x00" +WQ_MODE="0" + +while getopts :c:g:o:w:h arg; do + case $arg in + c) + CONFIG_NAME=$OPTARG + ;; + g) + GUEST_ONLY=$OPTARG + ;; + o) + OPCODE=$OPTARG + ;; + w) + WQ_MODE=$OPTARG + ;; + h) + usage && exit 0 + ;; + \?) + usage + die "Invalid Option -$OPTARG" + ;; + :) + usage + die "Option -$OPTARG requires an argument." + ;; + esac +done + +iax_user_test +#teardown_handler="iax_user_teardown" +exec_teardown diff --git a/tests/platform/intel/dsa/tests b/tests/platform/intel/dsa/tests new file mode 100755 index 0000000000000000000000000000000000000000..8c5191e4a5e1042c690af7b748030d799b439dfb --- /dev/null +++ b/tests/platform/intel/dsa/tests @@ -0,0 +1,7 @@ +# This file collects the DSA feature tests on +# Intel® Architecture-based platforms. + +# DSA basic tests, it works on SPR(Sapphire Rapids) platform and future server +dsa_user.sh -t check_dsa_driver +dsa_user.sh -t check_dsa0_device +dsa_user.sh -t check_shared_mode diff --git a/tests/platform/intel/dsa/tests-bat b/tests/platform/intel/dsa/tests-bat new file mode 100644 index 0000000000000000000000000000000000000000..e9b3d512dfb4d15c6cbe8c76c0145bcee4852664 --- /dev/null +++ b/tests/platform/intel/dsa/tests-bat @@ -0,0 +1,3 @@ +./dsa_user.sh -t check_dsa_driver +./dsa_user.sh -t check_dsa0_device +./dsa_user.sh -t check_shared_mode diff --git a/tests/platform/intel/dsa/tests-dsa1 b/tests/platform/intel/dsa/tests-dsa1 new file mode 100644 index 0000000000000000000000000000000000000000..d318038a938e13c81b970ea87fd72d86c6143849 --- /dev/null +++ b/tests/platform/intel/dsa/tests-dsa1 @@ -0,0 +1,105 @@ + +#DSA_XS_FUNC_GUEST_USER_MEMMOVE_4D4G4Q +./dsa_user_test.sh -c 4d4g4q_user -o 0x03 -g 1 +#DSA_XS_FUNC_GUEST_USER_MEMFILL_4D4G4Q +./dsa_user_test.sh -c 4d4g4q_user -o 0x04 -g 1 +#DSA_XS_FUNC_GUEST_USER_COMPARE_4D4G4Q +./dsa_user_test.sh -c 4d4g4q_user -o 0x05 -g 1 +#DSA_XS_FUNC_GUEST_USER_COMPVAL_4D4G4Q +./dsa_user_test.sh -c 4d4g4q_user -o 0x06 -g 1 +#DSA_XS_FUNC_USER_MEMMOVE_1D2G2Q +./dsa_user_test.sh -c 1d2g2q_user -o 0x03 +#DSA_XS_FUNC_USER_MEMMOVE_1D4G8Q +./dsa_user_test.sh -c 1d4g8q_user -o 0x03 +#DSA_XS_FUNC_USER_MEMMOVE_4D4G4Q +./dsa_user_test.sh -c 4d4g4q_user -o 0x03 +#DSA_XS_FUNC_USER_MEMMOVE_4D16G32Q +./dsa_user_test.sh -c 4d16g32q_user -o 0x03 +#DSA_XS_FUNC_USER_MEMMOVE_8D8G8Q +./dsa_user_test.sh -c 8d8g8q_user -o 0x03 +#DSA_XS_FUNC_USER_MEMMOVE_8D32G64Q +./dsa_user_test.sh -c 8d32g64q_user -o 0x03 +#DSA_XS_FUNC_USER_MEMFILL_1D2G2Q +./dsa_user_test.sh -c 1d2g2q_user -o 0x04 +#DSA_XS_FUNC_USER_MEMFILL_1D4G8Q +./dsa_user_test.sh -c 1d4g8q_user -o 0x04 +#DSA_XS_FUNC_USER_MEMFILL_4D4G4Q +./dsa_user_test.sh -c 4d4g4q_user -o 0x04 +#DSA_XS_FUNC_USER_MEMFILL_4D16G32Q +./dsa_user_test.sh -c 4d16g32q_user -o 0x04 +#DSA_XS_FUNC_USER_MEMFILL_8D8G8Q +./dsa_user_test.sh -c 8d8g8q_user -o 0x04 +#DSA_XS_FUNC_USER_MEMFILL_8D32G64Q +./dsa_user_test.sh -c 8d32g64q_user -o 0x04 +#DSA_XS_FUNC_USER_COMPARE_1D2G2Q +./dsa_user_test.sh -c 1d2g2q_user -o 0x05 +#DSA_XS_FUNC_USER_COMPARE_1D4G8Q +./dsa_user_test.sh -c 1d4g8q_user -o 0x05 +#DSA_XS_FUNC_USER_COMPARE_4D4G4Q +./dsa_user_test.sh -c 4d4g4q_user -o 0x05 +#DSA_XS_FUNC_USER_COMPARE_4D16G32Q +./dsa_user_test.sh -c 4d16g32q_user -o 0x05 +#DSA_XS_FUNC_USER_COMPARE_8D8G8Q +./dsa_user_test.sh -c 8d8g8q_user -o 0x05 +#DSA_XS_FUNC_USER_COMPARE_8D32G64Q +./dsa_user_test.sh -c 8d32g64q_user -o 0x05 +#DSA_XS_FUNC_USER_COMPVAL_1D2G2Q +./dsa_user_test.sh -c 1d2g2q_user -o 0x06 +#DSA_XS_FUNC_USER_COMPVAL_1D4G8Q +./dsa_user_test.sh -c 1d4g8q_user -o 0x06 +#DSA_XS_FUNC_USER_COMPVAL_4D4G4Q +./dsa_user_test.sh -c 4d4g4q_user -o 0x06 +#DSA_XS_FUNC_USER_COMPVAL_4D16G32Q +./dsa_user_test.sh -c 4d16g32q_user -o 0x06 +#DSA_XS_FUNC_USER_COMPVAL_8D8G8Q +./dsa_user_test.sh -c 8d8g8q_user -o 0x06 +#DSA_XS_FUNC_USER_COMPVAL_8D32G64Q +./dsa_user_test.sh -c 8d32g64q_user -o 0x06 +#DSA_XS_FUNC_USER_DUALCAST_1D2G2Q +./dsa_user_test.sh -c 1d2g2q_user -o 0x09 +#DSA_XS_FUNC_USER_DUALCAST_1D4G8Q +./dsa_user_test.sh -c 1d4g8q_user -o 0x09 +#DSA_XS_FUNC_USER_DUALCAST_4D4G4Q +./dsa_user_test.sh -c 4d4g4q_user -o 0x09 +#DSA_XS_FUNC_USER_DUALCAST_4D16G32Q +./dsa_user_test.sh -c 4d16g32q_user -o 0x09 +#DSA_XS_FUNC_USER_DUALCAST_8D8G8Q +./dsa_user_test.sh -c 8d8g8q_user -o 0x09 +#DSA_XS_FUNC_USER_DUALCAST_8D32G64Q +./dsa_user_test.sh -c 8d32g64q_user -o 0x09 +#DSA_XS_FUNC_USER_NOOP_1D2G2Q +./dsa_user_test.sh -c 1d2g2q_user -o 0x0 +#DSA_XS_FUNC_USER_NOOP_1D4G8Q +./dsa_user_test.sh -c 1d4g8q_user -o 0x0 +#DSA_XS_FUNC_USER_DRAIN_1D2G2Q +./dsa_user_test.sh -c 1d2g2q_user -o 0x2 +#DSA_XS_FUNC_USER_DRAIN_1D4G8Q +./dsa_user_test.sh -c 1d4g8q_user -o 0x2 +#DSA_XS_FUNC_USER_CRCGEN_1D2G2Q +./dsa_user_test.sh -c 1d2g2q_user -o 0x10 +#DSA_XS_FUNC_USER_CRCGEN_1D4G8Q +./dsa_user_test.sh -c 1d4g8q_user -o 0x10 +#DSA_XS_FUNC_USER_COPYCRC_1D2G2Q +./dsa_user_test.sh -c 1d2g2q_user -o 0x11 +#DSA_XS_FUNC_USER_COPYCRC_1D4G8Q +./dsa_user_test.sh -c 1d4g8q_user -o 0x11 +#DSA_XS_FUNC_USER_CFLUSH_1D2G2Q +./dsa_user_test.sh -c 1d2g2q_user -o 0x20 +#DSA_XS_FUNC_USER_CFLUSH_1D4G8Q +./dsa_user_test.sh -c 1d4g8q_user -o 0x20 +#DSA_XS_FUNC_USER_DIFCHECK_1D2G2Q +./dsa_user_test.sh -c 1d2g2q_user -o 0x12 +#DSA_XS_FUNC_USER_DIFCHECK_1D4G8Q +./dsa_user_test.sh -c 1d4g8q_user -o 0x12 +#DSA_XS_FUNC_USER_DIFINS_1D2G2Q +./dsa_user_test.sh -c 1d2g2q_user -o 0x13 +#DSA_XS_FUNC_USER_DIFINS_1D4G8Q +./dsa_user_test.sh -c 1d4g8q_user -o 0x13 +#DSA_XS_FUNC_USER_DIFSTRP_1D2G2Q +./dsa_user_test.sh -c 1d2g2q_user -o 0x14 +#DSA_XS_FUNC_USER_DIFSTRP_1D4G8Q +./dsa_user_test.sh -c 1d4g8q_user -o 0x14 +#DSA_XS_FUNC_USER_DIFUPDT_1D2G2Q +./dsa_user_test.sh -c 1d2g2q_user -o 0x15 +#DSA_XS_FUNC_USER_DIFUPDT_1D4G8Q +./dsa_user_test.sh -c 1d4g8q_user -o 0x15 diff --git a/tests/platform/intel/dsa/tests-dsa2 b/tests/platform/intel/dsa/tests-dsa2 new file mode 100644 index 0000000000000000000000000000000000000000..4db7dfed968f27b4d576e0608396cdc7851ff365 --- /dev/null +++ b/tests/platform/intel/dsa/tests-dsa2 @@ -0,0 +1,9 @@ + +#DSA_XS_FUNC_USER_TRANSLFETCH_1D2G2Q +./dsa_user_test.sh -c 1d2g2q_user -o 0xa +#DSA_XS_FUNC_USER_TRANSLFETCH_1D4G8Q +./dsa_user_test.sh -c 1d4g8q_user -o 0xa +#DSA_XS_FUNC_USER_DIXGEN_1D2G2Q +./dsa_user_test.sh -c 1d2g2q_user -o 0x17 +#DSA_XS_FUNC_USER_DIXGEN_1D4G8Q +./dsa_user_test.sh -c 1d4g8q_user -o 0x17 diff --git a/tests/platform/intel/dsa/tests-iax b/tests/platform/intel/dsa/tests-iax new file mode 100644 index 0000000000000000000000000000000000000000..1e0c0fc0c0e8005183f9a3f0d1d28ae21bf9c2d8 --- /dev/null +++ b/tests/platform/intel/dsa/tests-iax @@ -0,0 +1,57 @@ + +#IAX_XS_FUNC_USER_DECOMPRESS_DEDICATED +./iax_user_test.sh -c 2g2q_user_2 -o 0x42 -w 0 +#IAX_XS_FUNC_USER_COMPRESS_DEDICATED +./iax_user_test.sh -c 2g2q_user_2 -o 0x43 -w 0 +#IAX_XS_FUNC_USER_CRC64_DEDICATED +./iax_user_test.sh -c 2g2q_user_2 -o 0x44 -w 0 +#IAX_XS_FUNC_USER_ZDECOMPRESS32_DEDICATED +./iax_user_test.sh -c 2g2q_user_2 -o 0x48 -0 +#IAX_XS_FUNC_USER_ZDECOMPRESS16_DEDICATED +./iax_user_test.sh -c 2g2q_user_2 -o 0x49 -w 0 +#IAX_XS_FUNC_USER_ZCOMPRESS32_DEDICATED +./iax_user_test.sh -c 2g2q_user_2 -o 0x4c -w 0 +#IAX_XS_FUNC_USER_ZCOMPRESS16_DEDICATED +./iax_user_test.sh -c 2g2q_user_2 -o 0x4d -w 0 +#IAX_XS_FUNC_USER_SCAN_DEDICATED +./iax_user_test.sh -c 2g2q_user_2 -o 0x50 -w 0 +#IAX_XS_FUNC_USER_SET_DEDICATED +./iax_user_test.sh -c 2g2q_user_2 -o 0x51 -w 0 +#IAX_XS_FUNC_USER_EXTRACT_DEDICATED +./iax_user_test.sh -c 2g2q_user_2 -o 0x52 -w 0 +#IAX_XS_FUNC_USER_SELECT_DEDICATED +./iax_user_test.sh -c 2g2q_user_2 -o 0x53 -w 0 +#IAX_XS_FUNC_USER_RLE_DEDICATED +./iax_user_test.sh -c 2g2q_user_2 -o 0x54 -w 0 +#IAX_XS_FUNC_USER_FIND_DEDICATED +./iax_user_test.sh -c 2g2q_user_2 -o 0x55 -w 0 +#IAX_XS_FUNC_USER_EXPAND_DEDICATED +./iax_user_test.sh -c 2g2q_user_2 -o 0x56 -w 0 +#IAX_XS_FUNC_USER_DECOMPRESS_SHARED +./iax_user_test.sh -c 2g2q_user_2 -o 0x42 -w 1 +#IAX_XS_FUNC_USER_COMPRESS_SHARED +./iax_user_test.sh -c 2g2q_user_2 -o 0x43 -w 1 +#IAX_XS_FUNC_USER_CRC64_SHARED +./iax_user_test.sh -c 2g2q_user_2 -o 0x44 -w 1 +#IAX_XS_FUNC_USER_ZDECOMPRESS32_SHARED +./iax_user_test.sh -c 2g2q_user_2 -o 0x48 -w 1 +#IAX_XS_FUNC_USER_ZDECOMPRESS16_SHARED +./iax_user_test.sh -c 2g2q_user_2 -o 0x49 -w 1 +#IAX_XS_FUNC_USER_ZCOMPRESS32_SHARED +./iax_user_test.sh -c 2g2q_user_2 -o 0x4c -w 1 +#IAX_XS_FUNC_USER_ZCOMPRESS16_SHARED +./iax_user_test.sh -c 2g2q_user_2 -o 0x4d -w 1 +#IAX_XS_FUNC_USER_SCAN_SHARED +./iax_user_test.sh -c 2g2q_user_2 -o 0x50 -w 1 +#IAX_XS_FUNC_USER_SET_SHARED +./iax_user_test.sh -c 2g2q_user_2 -o 0x51 -w 1 +#IAX_XS_FUNC_USER_EXTRACT_SHARED +./iax_user_test.sh -c 2g2q_user_2 -o 0x52 -w 1 +#IAX_XS_FUNC_USER_SELECT_SHARED +./iax_user_test.sh -c 2g2q_user_2 -o 0x53 -w 1 +#IAX_XS_FUNC_USER_RLE_SHARED +./iax_user_test.sh -c 2g2q_user_2 -o 0x54 -w 1 +#IAX_XS_FUNC_USER_FIND_SHARED +./iax_user_test.sh -c 2g2q_user_2 -o 0x55 -w 1 +#IAX_XS_FUNC_USER_EXPAND_SHARED +./iax_user_test.sh -c 2g2q_user_2 -o 0x56 -w 1 diff --git a/tests/platform/intel/edac/README.md b/tests/platform/intel/edac/README.md new file mode 100644 index 0000000000000000000000000000000000000000..2ba710a2dfd051cbc3738d63241e3fbddadade99 --- /dev/null +++ b/tests/platform/intel/edac/README.md @@ -0,0 +1,19 @@ +# EDAC + +EDAC (Error Detection and Correction) framework provides support for detecting and correcting memory errors on systems with ECC (Error-Correcting Code) memory or other error detection mechanism. + +Intel i10nm EDAC driver supports the Intel 10nm series server integrated memory controller. + +## Usage + +You can run the cases one by one, e.g. command + +``` +./intel_edac.sh -t check_edac_bus +``` +You also can run the cases together with runtests command, e.g. + +``` +cd .. +./runtests -f edac/tests -o logfile +``` diff --git a/tests/platform/intel/edac/intel_edac.sh b/tests/platform/intel/edac/intel_edac.sh new file mode 100755 index 0000000000000000000000000000000000000000..f6cefac655fb8640613fccd1fedab5778c25039c --- /dev/null +++ b/tests/platform/intel/edac/intel_edac.sh @@ -0,0 +1,66 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) 2022 Intel Corporation +# Description: Test script for Intel i10nm EDAC driver, which supports 10nm series server +# EDAC: Error Detection and Correction +# @Author Yi Lai yi1.lai@intel.com + + +cd "$(dirname "$0")" 2>/dev/null || exit 1 +source ../.env + +EDAC_BUS="/sys/bus/edac" +EDAC_DRIVER=i10nm_edac + +: "${CASE_NAME:=""}" + +usage() { + cat <<__EOF + usage: ./${0##*/} [-t TESTCASE_ID] [-H] + -t TEST CASE ID + -H show this +__EOF +} + +edac_test() { + case $TEST_SCENARIO in + check_edac_bus) + edac_bus=$(ls $EDAC_BUS) + if [ -n "$edac_bus" ]; then + test_print_trc "EDAC bus is found" + else + die "EDAC bus is not found" + fi + ;; + check_edac_driver) + test_print_trc "Check Intel i10nm edac driver" + lsmod | grep -q $EDAC_DRIVER + if ! lsmod | grep -q $EDAC_DRIVER; then + die "Intel i10nm edac driver is not loaded" + else + test_print_trc "Intel i10nm edac driver is loaded" + fi + ;; + esac +} + +while getopts :t:H arg; do + case $arg in + t) + TEST_SCENARIO=$OPTARG + ;; + H) + usage && exit 0 + ;; + \?) + usage + die "Invalid Option -$OPTARG" + ;; + :) + usage + die "Option -$OPTARG requires an argument." + ;; + esac +done + +edac_test diff --git a/tests/platform/intel/edac/tests b/tests/platform/intel/edac/tests new file mode 100644 index 0000000000000000000000000000000000000000..84f3bfc63593a4ad0d3bac3151b1357793ddb83e --- /dev/null +++ b/tests/platform/intel/edac/tests @@ -0,0 +1,5 @@ +# This file collects Intel EDAC driver testcases which can run against +# on Intel 10nm series server + +intel_edac.sh -t check_edac_bus +intel_edac.sh -t check_edac_driver diff --git a/tests/platform/intel/isst/README.md b/tests/platform/intel/isst/README.md new file mode 100644 index 0000000000000000000000000000000000000000..df9b40a3d2bc88ad0f026f58cb75b67e27ba303d --- /dev/null +++ b/tests/platform/intel/isst/README.md @@ -0,0 +1,32 @@ +# Release Notes for Intel® Speed Select Technology test cases + +Intel® Speed Select Technology: a collection of features improve performance +and optimizes the total cost of ownership (TCO) by proving more control +over the CPU performance. + +The isst cases are designed for Intel® Architecture-based server platforms, +supported beginning from Cascade lake, then Cooper lake, Icelake and future platforms + +The prerequisites to run the ISST cases: +- The server CPU supports the ISST feature +- BIOS enabled Dynamic SST-PP setting +- User needs intel-speed-select, turbostat, stress tools + +tests file collects the cases for Intel® server platforms where assume SUT supports +SST perf profile level 0,3,4, users can add other SST-PP level cases +for the futhur platforms who may support full SST-PP levels 0,1,2,3,4 + +You can run the cases one by one, e.g. command + +``` +./intel_sst.sh -t isst_info +``` +You also can run the cases together with runtests command, e.g. + +``` +cd .. +./runtests -f isst/tests -o logfile +``` + +These are the basic cases for ISST testing, If you have good idea to +improve cases, you are welcomed to send us the patches, thanks! diff --git a/tests/platform/intel/isst/intel_sst.sh b/tests/platform/intel/isst/intel_sst.sh new file mode 100755 index 0000000000000000000000000000000000000000..6f901a975832613f0aed9d2d31ae33ecc45a4b3e --- /dev/null +++ b/tests/platform/intel/isst/intel_sst.sh @@ -0,0 +1,1035 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) 2022 Intel Corporation +# Description: Test script for Intel SST feature, which is supported on server platforms +# ISST:Intel Speed Select Technology +# PP: perf-profile +# CP: core-power +# BF: base-freq +# TF: turbo-freq +# @Author wendy.wang@intel.com +# @History Created Dec 05 2022 - Created + +cd "$(dirname "$0")" 2>/dev/null || exit 1 +source ../.env + +ISST_IF_MMIO_DRIVER_PATH="/sys/module/isst_if_mmio/drivers/pci" +ISST_IF_MBOX_PCI_DRIVER_PATH="/sys/module/isst_if_mbox_pci/drivers/pci" +CPU_SYSFS_PATH="/sys/devices/system/cpu" +COLUMNS="Package,Core,CPU,Busy%,Bzy_MHz,PkgWatt" + +# Turbostat tool is required to run ISST cases +if which turbostat 1>/dev/null 2>&1; then + turbostat sleep 1 1>/dev/null || block_test "Failed to run turbostat tool, +please check turbostat tool error message." +else + block_test "Turbostat tool is required to run ISST cases, +please get it from latest upstream kernel-tools." +fi + +# intel-speed-select tool is required to run ISST cases +if which intel-speed-select 1>/dev/null 2>&1; then + intel-speed-select --info 1>/dev/null || block_test "Failed to run isst tool, +please check isst tool error message." +else + block_test "intel-speed-select tool is required to run ISST cases, +please get it from latest upstream kernel-tools." +fi + +# stress tool is required to run ISST cases +if which stress 1>/dev/null 2>&1; then + stress --help 1>/dev/null || block_test "Failed to run stress tool, +please check stress tool error message" +else + block_test "stress tool is required to run ISST cases, +please get it from latest upstream kernel-tools." +fi + +: "${CASE_NAME:=""}" + +usage() { + cat <<__EOF + usage: ./${0##*/} [-t TESTCASE_ID] [-H] + -t TEST CASE ID + -H show this +__EOF +} + +isst_legacy_driver_interface() { + test_print_trc "Check ISST_IF_MMIO driver interface:" + + [[ -d "$ISST_IF_MMIO_DRIVER_PATH":isst_if_pci ]] || + die "ISST_IF_MMIO driver SYSFS does not exist!" + + lines=$(ls "$ISST_IF_MMIO_DRIVER_PATH":isst_if_pci 2>&1) + for line in $lines; do + test_print_trc "$line" + done + + test_print_trc "Check ISST_IF_MBOX_PCI driver interface:" + + [[ -d "$ISST_IF_MBOX_PCI_DRIVER_PATH":isst_if_mbox_pci ]] || + die "ISST_IF_MBOX_PCI driver SYSFS does not exist!" + + lines=$(ls "$ISST_IF_MBOX_PCI_DRIVER_PATH":isst_if_mbox_pci 2>&1) + for line in $lines; do + test_print_trc "$line" + done +} + +power_limit_check() { + pkg_power_limitation_log=$(rdmsr -p 1 0x1b1 -f 11:11 2>/dev/null) + test_print_trc "The power limitation log from package thermal status 0x1b1 bit 11 is: \ +$pkg_power_limitation_log" + core_power_limitation_log=$(rdmsr -p 1 0x19c -f 11:11 2>/dev/null) + test_print_trc "The power limitation log from IA32 thermal status 0x19c bit 11 is: \ +$core_power_limitation_log" + hwp_cap_value=$(rdmsr -a 0x771 2>/dev/null) + test_print_trc "MSR HWP Capabilities shows: $hwp_cap_value" + hwp_req_value=$(rdmsr -a 0x774 2>/dev/null) + test_print_trc "MSR HWP Request shows: $hwp_req_value" + + core_perf_limit_reason=$(rdmsr -a 0x64f 2>/dev/null) + test_print_trc "The core perf limit reasons msr 0x64f value is: $core_perf_limit_reason" + if [ "$pkg_power_limitation_log" == "1" ] && [ "$core_power_limitation_log" == "1" ]; then + return 0 + else + return 1 + fi +} + +# Function to check ISST features support status +isst_info() { + do_cmd "intel-speed-select -o info.out -i" + test_print_trc "The platform and driver capabilities are:" + do_cmd "cat info.out" + isst_pp_cap=$(grep SST-PP info.out | grep "not supported") + isst_cp_cap=$(grep SST-CP info.out | grep "not supported") + isst_bf_cap=$(grep SST-BF info.out | grep "not supported") + isst_tf_cap=$(grep SST-TF info.out | grep "not supported") + + if [[ -z "$isst_pp_cap" ]] && [[ -z "$isst_cp_cap" ]] && + [[ -z "$isst_bf_cap" ]] && [[ -z "$isst_tf_cap" ]]; then + test_print_trc "The ISST-PP, ISST-CP, ISST-BF, ISST-TF features are supported" + else + block_test "There is ISST feature not supported." + fi +} + +# Function to check isst lock status, if locked, then does not support the dynamic +# isst perf profile level change +isst_unlock_status() { + expected_lock_status=unlocked + do_cmd "intel-speed-select -o pp.out perf-profile get-lock-status" + test_print_trc "The system lock status is:" + do_cmd "cat pp.out" + isst_lock_status=$(grep get-lock-status pp.out | awk -F ":" '{print $2}') + isst_lock_status_num=$(grep get-lock-status pp.out | awk -F ":" '{print $2}' | wc -l) + + for ((i = 1; i <= isst_lock_status_num; i++)); do + j=$(("$i" - 1)) + isst_lock_status_by_num=$(echo "$isst_lock_status" | sed -n "$i, 1p") + if [ "$isst_lock_status_by_num" = "$expected_lock_status" ]; then + test_print_trc "The system package $j isst lock status is: $isst_lock_status_by_num" + test_print_trc "The system package $j is unlocked for different profiles change." + else + test_print_trc "The system package $j isst lock status is: $isst_lock_status_by_num" + block_test "The system is locked for package $j, user may need to check BIOS to unlock." + fi + done +} + +# Function to check if the isst perf profile config enable or not +isst_pp_config_enable() { + expected_config_status=enabled + do_cmd "intel-speed-select -o pp.out perf-profile get-config-enabled" + test_print_trc "The system perf profile config enable status:" + do_cmd "cat pp.out" + + isst_config_status=$(grep get-config-enabled pp.out | awk -F ":" '{print $2}') + isst_config_status_num=$(grep get-config-enabled pp.out | awk -F ":" '{print $2}' | wc -l) + + for ((i = 1; i <= isst_config_status_num; i++)); do + j=$(("$i" - 1)) + isst_config_status_by_num=$(echo "$isst_config_status" | sed -n "$i, 1p") + if [ "$isst_config_status_by_num" = "$expected_config_status" ]; then + test_print_trc "The system package $j isst config status is: $isst_config_status_by_num" + else + die "The system package $j isst config status is: $isst_config_status_by_num" + fi + done +} + +# Function to do different supported perf profile levels change +# Input: +# $1: select different perf profile level +isst_pp_level_change() { + local level_id=$1 + do_cmd "intel-speed-select -o pp.out perf-profile get-config-current-level" + test_print_trc "The system perf profile config current level info:" + do_cmd "cat pp.out" + + cur_level=$(grep get-config-current_level pp.out | awk -F ":" '{print $2}') + cur_level_num=$(grep get-config-current_level pp.out | awk -F ":" '{print $2}' | wc -l) + + test_print_trc "Will change the config level from $cur_level to $level_id:" + do_cmd "intel-speed-select -o pp.out perf-profile set-config-level -l $level_id -o" + test_print_trc "The system perf profile config level change log:" + do_cmd "cat pp.out" + + set_tdp_level_status=$(grep set_tdp_level pp.out | awk -F ":" '{print $2}') + set_tdp_level_status_num=$(grep set_tdp_level pp.out | awk -F ":" '{print $2}' | wc -l) + + for ((i = 1; i <= set_tdp_level_status_num; i++)); do + j=$(("$i" - 1)) + set_tdp_level_status_by_num=$(echo "$set_tdp_level_status" | sed -n "$i, 1p") + if [ "$set_tdp_level_status_by_num" = success ]; then + test_print_trc "The system package $j set tdp level status is $set_tdp_level_status_by_num" + test_print_trc "The system package $j set tdp level success." + else + test_print_trc "The system package $j set tdp level status is $set_tdp_level_status_by_num" + die "The system package $j set tdp level fails" + fi + done + + test_print_trc "Confirm the changed config current level:" + do_cmd "intel-speed-select -o pp.out perf-profile get-config-current-level" + test_print_trc "The system perf profile config current level info:" + do_cmd "cat pp.out" + + cur_level=$(grep get-config-current_level pp.out | awk -F ":" '{print $2}') + cur_level_num=$(grep get-config-current_level pp.out | awk -F ":" '{print $2}' | wc -l) + + for ((i = 1; i <= cur_level_num; i++)); do + j=$(("$i" - 1)) + cur_level_by_num=$(echo "$cur_level" | sed -n "$i, 1p") + if [ "$cur_level_by_num" -eq "$level_id" ]; then + test_print_trc "The system package $j config current level: $cur_level_by_num" + test_print_trc "The system package $j config current level is $level_id after successfully setting" + else + test_print_trc "The system package $j config current level: $cur_level_by_num" + die "The system package $j set tdp level fails" + fi + done + + test_print_trc "Recover the config level to the default setting: 0" + do_cmd "intel-speed-select -o pp.out perf-profile set-config-level -l 0 -o" +} + +# Function to check the base frequency alignment between sysfs and isst tool for each profile level +# Input: +# $1: select different perf profile level +isst_base_freq_pp_level_change() { + local level_id=$1 + + test_print_trc "Recover the config level to the default setting: 0" + do_cmd "intel-speed-select -o pp.out perf-profile set-config-level -l 0 -o" + sleep 2 + # Read the base_freqency by default ISST perf-profile level + base_freq_bf_khz=$(cat "$CPU_SYSFS_PATH"/cpu0/cpufreq/base_frequency 2>&1) + base_freq_bf_mhz=$(echo "$base_freq_bf_khz/1000" | bc) + [[ -n "$base_freq_bf_khz" ]] || block_test "Did not get base_frequency from sysfs" + test_print_trc "The default CPU base frequency is: $base_freq_bf_mhz" + + # Change the PP level + do_cmd "intel-speed-select -o pp.out perf-profile set-config-level -l $level_id -o" + test_print_trc "The system perf profile level change status:" + do_cmd "cat pp.out" + + # Read the base-frequency(MHz) of enabled CPUs from isst perf-profile info + do_cmd "intel-speed-select -o pp_info.out perf-profile info" + do_cmd "cat pp_info.out" + sleep 5 + package_number=$(grep -c "die-0" pp_info.out) + test_print_trc "Package number: $package_number" + for ((i = 1; i <= "$package_number"; i++)); do + enabled_cpu=$(grep -A 10 "perf-profile-level-$level_id" pp_info.out | + grep "enable-cpu-list" | awk -F ":" '{print $2}' | awk -F "," '{print $1}' | + sed -n "$i,1p") + test_print_trc "The test enabled the cpu number is: $enabled_cpu" + [[ -n "$enabled_cpu" ]] || block_test "Did not get enabled CPU number" + + # High PP level should have the new CPU base_freqency + base_freq_af_khz=$(cat "$CPU_SYSFS_PATH"/cpu"$enabled_cpu"/cpufreq/base_frequency 2>&1) + base_freq_af_mhz=$(echo "$base_freq_af_khz/1000" | bc) + test_print_trc "The base_frequency_af read from sysfs:$base_freq_af_mhz" + + # Read the base-frequency(MHz) value from ISST log + base_freq_tool=$(grep -A 10 "perf-profile-level-$level_id" pp_info.out | + grep "base-frequency(MHz)" | awk -F ":" '{print $2}' | sed -n "$i,1p") + [[ -n "$base_freq_tool" ]] || block_test "Did not get base-freq value from ISST log." + test_print_trc "The base-frequency(MHz) read from ISST log of CPU$i:$base_freq_tool" + + # The base_freq reported from sysfs and isst tool should be the same value + if [[ "$base_freq_af_mhz" -eq "$base_freq_tool" ]]; then + test_print_trc "The CPU base frequency change from sysfs and isst tool are expected \ +for PP Level $level_id change, the new CPU base frequency is: $base_freq_af_mhz" + else + die "The CPU base frequency change is NOT expected for PP Level $level_id change,\ +the tool report: $base_freq_tool, the sysfs reports: $base_freq_af_mhz" + fi + done + + test_print_trc "Recover the config level to the default setting: 0" + do_cmd "intel-speed-select -o pp.out perf-profile set-config-level -l 0 -o" +} + +# Function to check isst core power feature enable and disable +isst_cp_enable_disable() { + local expected_status=$1 + local action=$2 + local type=$3 + + do_cmd "intel-speed-select -o cp.out core-power $action -p $type" + test_print_trc "The system isst core power enable status:" + do_cmd "cat cp.out" + + do_cmd "intel-speed-select -o cp.out core-power info" + test_print_trc "The system isst core power info:" + do_cmd "cat cp.out" + + isst_cp_status=$(grep clos-enable-status cp.out | awk -F ":" '{print $2}') + isst_cp_status_num=$(grep clos-enable-status cp.out | awk -F ":" '{print $2}' | wc -l) + isst_cp_pri_type=$(grep priority-type cp.out | awk -F ":" '{print $2}') + + for ((i = 1; i <= isst_cp_status_num; i++)); do + j=$(("$i" - 1)) + isst_cp_status_by_num=$(echo "$isst_cp_status" | sed -n "$i, 1p") + test_print_trc "Print clos-enable-status:$isst_cp_status_by_num" + if [ "$isst_cp_status_by_num" = "$expected_status" ]; then + test_print_trc "The system package $j isst core power status is: $isst_cp_status_by_num" + else + die "The system package $j isst core power status is: $isst_cp_status_by_num" + fi + done + + for ((i = 1; i <= isst_cp_status_num; i++)); do + j=$(("$i" - 1)) + isst_cp_pri_type_by_num=$(echo "$isst_cp_pri_type" | sed -n "$i, 1p") + test_print_trc "Print priority-type: $isst_cp_pri_type" + if [ "$type" -eq 0 ] && [ "$isst_cp_pri_type_by_num" = "proportional" ]; then + test_print_trc "The system package $j isst core power priority-type is $isst_cp_pri_type_by_num" + elif [ "$type" -eq 1 ] && [ "$isst_cp_pri_type_by_num" = "ordered" ]; then + test_print_trc "The system package $j isst core power priority-type is $isst_cp_pri_type_by_num" + else + die "The system package $j isst core power priority-type is not expected: $isst_cp_pri_type_by_num" + fi + done +} + +# Function to set isst core power configuration for clos id and min freq +# Input: +# $1: select different class of service ID +isst_cp_config_clos_min_set_get() { + local clos_id=$1 + local min_khz="" + min_khz=$(cat /sys/devices/system/cpu/cpu0/cpufreq/base_frequency 2>&1) + [[ -n "$min_khz" ]] || block_test "Did not get base frequency from sysfs" + min_mhz=$(("$min_khz" / 1000)) + do_cmd "intel-speed-select -o cp.out core-power config -n $min_mhz -c $clos_id" + test_print_trc "The system isst core power config change to:" + do_cmd "cat cp.out" + + do_cmd "intel-speed-select -o cp.out core-power get-config -c $clos_id" + test_print_trc "The system isst core power get config:" + do_cmd "cat cp.out" + + isst_clos_status=$(grep clos: cp.out | awk -F ":" '{print $2}') + isst_cp_status=$(grep clos-min cp.out | awk -F ":" '{print $2}') + isst_cp_status_num=$(grep clos-min cp.out | awk -F ":" '{print $2}' | wc -l) + + for ((i = 1; i <= isst_cp_status_num; i++)); do + j=$(("$i" - 1)) + isst_cp_status_by_num=$(echo "$isst_cp_status" | sed -n "$i, 1p") + isst_clos_status_by_num=$(echo "$isst_clos_status" | sed -n "$i, 1p") + if [[ "$isst_cp_status_by_num" = "$min_mhz MHz" ]] && [[ "$isst_clos_status_by_num" = "$clos_id" ]]; then + test_print_trc "The system package $j isst core power clos is: $isst_clos_status_by_num" + test_print_trc "The system package $j isst core power clos min freq is: $isst_cp_status_by_num" + else + die "The system package $j isst core power clos is: $isst_clos_status_by_num, \ +The system package $j isst core power clos min freq is: $isst_cp_status_by_num" + fi + done +} + +# Function to set isst core power configuration for clos id and max freq +# Input: +# $1: select different class of service ID +isst_cp_config_clos_max_set_get() { + local clos_id=$1 + local max_khz="" + max_khz=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq 2>&1) + [[ -n "$max_khz" ]] || block_test "Did not get scaling_max_freq from sysfs" + max_mhz=$(("$max_khz" / 1000)) + do_cmd "intel-speed-select -o cp.out core-power config -m $max_mhz -c $clos_id" + test_print_trc "The system isst core power config change to:" + do_cmd "cat cp.out" + + do_cmd "intel-speed-select -o cp.out core-power get-config -c $clos_id" + test_print_trc "The system isst core power get config:" + do_cmd "cat cp.out" + + isst_clos_status=$(grep clos: cp.out | awk -F ":" '{print $2}') + isst_cp_status=$(grep clos-max cp.out | awk -F ":" '{print $2}') + isst_cp_status_num=$(grep clos-max cp.out | awk -F ":" '{print $2}' | wc -l) + + for ((i = 1; i <= isst_cp_status_num; i++)); do + j=$(("$i" - 1)) + isst_cp_status_by_num=$(echo "$isst_cp_status" | sed -n "$i, 1p") + isst_clos_status_by_num=$(echo "$isst_clos_status" | sed -n "$i, 1p") + if [[ "$isst_cp_status_by_num" = "$max_mhz MHz" ]] && [[ "$isst_clos_status_by_num" = "$clos_id" ]]; then + test_print_trc "The system package $j isst core power clos is: $isst_clos_status_by_num" + test_print_trc "The system package $j isst core power clos max freq is: $isst_cp_status_by_num" + else + die "The system package $j isst core power clos is: $isst_clos_status_by_num, \ +The system package $j isst core power clos max freq is: $isst_cp_status_by_num" + fi + done +} + +# Function to set isst core power configuration for clos id and clos-proportional-priority +# Input: +# $1: select different class of service ID +isst_cp_config_clos_prop_set_get() { + local clos_id=$1 + local prop_pri="" + prop_pri=10 + + do_cmd "intel-speed-select -o cp.out core-power config -w $prop_pri -c $clos_id" + test_print_trc "The system isst core power config change to:" + do_cmd "cat cp.out" + + do_cmd "intel-speed-select -o cp.out core-power get-config -c $clos_id" + test_print_trc "The system isst core power get config:" + do_cmd "cat cp.out" + + isst_clos_status=$(grep clos: cp.out | awk -F ":" '{print $2}') + isst_cp_status=$(grep clos-proportional-priority cp.out | awk -F ":" '{print $2}') + isst_cp_status_num=$(grep clos-proportional-priority cp.out | awk -F ":" '{print $2}' | wc -l) + + for ((i = 1; i <= isst_cp_status_num; i++)); do + j=$(("$i" - 1)) + isst_cp_status_by_num=$(echo "$isst_cp_status" | sed -n "$i, 1p") + isst_clos_status_by_num=$(echo "$isst_clos_status" | sed -n "$i, 1p") + if [[ "$isst_cp_status_by_num" = "$prop_pri" ]] && [[ "$isst_clos_status_by_num" = "$clos_id" ]]; then + test_print_trc "The system package $j isst core power clos is: $isst_clos_status_by_num" + test_print_trc "The system package $j isst core power clos proportional priority is: $isst_cp_status_by_num" + else + die "The system package $j isst core power clos is: $isst_clos_status_by_num, \ +The system package $j isst core power clos proportional priority is: $isst_cp_status_by_num" + fi + done +} + +# Function to set and get one CPU1 association +# Input: +# $1: select different class of service ID +isst_cp_assoc_set_get() { + local clos_id=$1 + + do_cmd "intel-speed-select -o cp.out -c 1 core-power assoc -c $clos_id" + test_print_trc "The system's CPU1 is associated to CLOS $clos_id" + do_cmd "cat cp.out" + + isst_cp_assoc_status=$(grep assoc cp.out | awk -F ":" '{print $2}') + if [[ "$isst_cp_assoc_status" = "success" ]]; then + test_print_trc "The system's CPU1 is associated to CLOS $clos_id successfully" + else + die "The system's CPU1 is associated to CLOS $clos_id failed" + fi + + do_cmd "intel-speed-select -o cp.out -c 1 core-power get-assoc" + test_print_trc "The system's CPU1 is associated to CLOS $clos_id" + do_cmd "cat cp.out" + + isst_cp_assoc_clos=$(grep clos cp.out | awk -F ":" '{print $2}') + if [[ "$isst_cp_assoc_clos" = "$clos_id" ]]; then + test_print_trc "The system's CPU1 gets core power association info." + else + die "The system's CPU1 failed to get core power association info" + fi +} + +# Function to set and get the max CPU association +# Input: +# $1: select different class of service ID +isst_cp_max_cpu_assoc_set_get() { + local clos_id=$1 + local max_cpu="" + + max_cpu=$(lscpu --online --extended | awk '{print $1}' | sed -n '$p' 2>&1) + test_print_trc "The max cpu number is: $max_cpu" + + do_cmd "intel-speed-select -o cp.out -c $max_cpu core-power assoc -c $clos_id" + test_print_trc "The system's CPU $max_cpu is associated to CLOS $clos_id" + do_cmd "cat cp.out" + + isst_cp_assoc_status=$(grep assoc cp.out | awk -F ":" '{print $2}') + if [[ "$isst_cp_assoc_status" = "success" ]]; then + test_print_trc "The system's CPU $max_cpu is associated to CLOS $clos_id successfully" + else + die "The system's CPU $max_cpu is associated to CLOS $clos_id failed" + fi + + do_cmd "intel-speed-select -o cp.out -c $max_cpu core-power get-assoc" + test_print_trc "The system's CPU $max_cpu is associated to CLOS $clos_id" + do_cmd "cat cp.out" + + isst_cp_assoc_clos=$(grep clos cp.out | awk -F ":" '{print $2}') + if [[ "$isst_cp_assoc_clos" = "$clos_id" ]]; then + test_print_trc "The system's CPU $max_cpu gets core power association info." + else + die "The system's CPU $max_cpu failed to get core power association info" + fi +} + +# This function will check the baseline base_freq is reachable before enabling isst_bf +isst_bf_baseline_test() { + # Get base_freq from isst tool, the unit is MHz + do_cmd "intel-speed-select -o pp.out perf-profile info -l 0" + do_cmd "cat pp.out" + base_freq_isst_raw=$(grep "base-frequency(MHz)" pp.out | awk -F ":" '{print $2}' | sed -n "1, 1p") + base_freq_isst=$(echo "$base_freq_isst_raw*1000" | bc) + test_print_trc "The base_freq from isst tool is: $base_freq_isst KHz" + + # Get base_freq from sysfs, the unit is KHz + base_freq_sysfs=$(cat "$CPU_SYSFS_PATH"/cpu0/cpufreq/base_frequency 2>&1) + [[ -n "$base_freq_sysfs" ]] || block_test "Did not get base frequency from sysfs" + test_print_trc "The base_freq from sysfs is: $base_freq_sysfs KHz" + + if [ "$base_freq_sysfs" = "$base_freq_isst" ]; then + test_print_trc "The base_freq from sysfs is aligned with isst tool" + else + die "The base_freq from sysfs is not match with isst tool" + fi + + # Run stress to check if the system can reach the base_freq + cpu_num=$(lscpu --online --extended | awk '{print $1}' | sed -n '$p' 2>&1) + cpu_num_all=$(("$cpu_num" + 1)) + test_print_trc "The online CPUs number is:$cpu_num_all" + + # Add 100% workload for the online CPUs + test_print_trc "Executing stress -c $cpu_num_all -t 90 & in background" + do_cmd "stress -c $cpu_num_all -t 90 &" + stress_pid=$! + [[ -n "$stress_pid" ]] || block_test "stress is not launched." + + cpu_stat=$(turbostat -q --show $COLUMNS -i 10 sleep 10 2>&1) + [[ -n "$cpu_stat" ]] || block_test "Did not get turbostat log" + test_print_trc "Turbostat output when 100% workload stress running is:" + echo -e "$cpu_stat" + + first_cpu_freq_temp=$(echo "$cpu_stat" | + awk '{for(k=0;++k<=NF;)a[k]=a[k]?a[k] FS $k:$k} END{for(k=0;k++ 100000" | bc) -eq 1 ]] || + [[ $(echo "$last_delta > 100000" | bc) -eq 1 ]] || + [[ $(echo "$core_delta > 200000" | bc) -eq 1 ]]; then + if power_limit_check; then + test_print_trc "The package and core power limitation is assert." + test_print_trc "The average CPU freq gap is 100Mhz larger than expected base_freq \ +with power limitation log observed." + else + test_print_trc "The package and core power limitation is not assert." + die "The CPUs base freq is 100Mhz larger than expected base_freq without power limitation assert." + fi + else + test_print_trc "The CPUs base freq when 100% workload stress running: PASS" + fi +} + +# Function to check isst high priority base freq feature +# Input: +# $1: select different perf profile level +isst_bf_freq_test() { + local level_id=$1 + + # Get the base_freq from sysfs, the unit is KHz + base_freq_sysfs=$(cat "$CPU_SYSFS_PATH"/cpu0/cpufreq/base_frequency 2>&1) + [[ -n "$base_freq_sysfs" ]] || block_test "Did not get base frequency from sysfs" + test_print_trc "The base_freq from sysfs is: $base_freq_sysfs KHz" + + # Set SST Perf profile level to $level_id + test_print_trc "Will change Perf profile config level to $level_id:" + do_cmd "intel-speed-select -o pp.out perf-profile set-config-level -l $level_id -o" + test_print_trc "The system perf profile config level change log:" + do_cmd "cat pp.out" + + # Disable CPU turbo + test_print_trc "Disable CPU Turbo" + do_cmd "echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo" + + # Enable ISST base_freq feature, -a option is used to enable core power CLOS related parameters + do_cmd "intel-speed-select -o bf.out base-freq enable -a" + test_print_trc "Intel SST base_freq enable status:" + do_cmd "cat bf.out" + + isst_bf_status=$(grep "enable" bf.out | awk -F ":" '{print $2}') + isst_bf_status_num=$(grep "enable" bf.out | awk -F ":" '{print $2}' | wc -l) + + for ((i = 1; i <= isst_bf_status_num; i++)); do + j=$(("$i" - 1)) + isst_bf_status_by_num=$(echo "$isst_bf_status" | sed -n "$i, 1p") + if [ "$isst_bf_status_by_num" = "success" ]; then + test_print_trc "The system package $j isst bf enable status is: $isst_bf_status_by_num" + else + die "The system package $j isst bf enable status is: $isst_bf_status_by_num" + fi + done + + # Get High and low priority base freq with perf profile level 0 from ISST tool + do_cmd "intel-speed-select -o bf.out base-freq info -l 0" + test_print_trc "Intel SST base_freq info with perf profile level 0:" + do_cmd "cat bf.out" + + # Freq unit from ISST is: MHz + hp_base_freq_isst=$(grep "high-priority-base-frequency(MHz)" bf.out | awk -F ":" '{print $2}' | sed -n "1, 1p") + test_print_trc "The high priority base freq from ISST tool is: $hp_base_freq_isst MHz" + + lp_base_freq_isst=$(grep "low-priority-base-frequency(MHz)" bf.out | awk -F ":" '{print $2}' | sed -n "1, 1p") + test_print_trc "The low priority base freq from ISST tool is: $lp_base_freq_isst MHz" + + # Get the actual package number which support base_freq feature + hp_bf_cpus_num=$(grep "high-priority-cpu-list" bf.out | grep -v -c none) + for ((i = 1; i <= hp_bf_cpus_num; i++)); do + # Get two high priority CPUs on the same package + hp_bf_cpus_2nd=$(grep "high-priority-cpu-list" bf.out | grep -v none | awk -F "," '{print $2}' | sed -n "$i, 1p") + hp_bf_cpus_3rd=$(grep "high-priority-cpu-list" bf.out | grep -v none | awk -F "," '{print $3}' | sed -n "$i, 1p") + # j below is used to check package number + j=$(("$i" - 1)) + test_print_trc "The 2nd high priority cpu in package$j is: $hp_bf_cpus_2nd" + test_print_trc "The 3rd high priority cpu in package$j is: $hp_bf_cpus_3rd" + + # Run stress on 2 high priority CPUs + test_print_trc "Executing 100% workload stress on two high priority CPUs" + do_cmd "taskset -c 0,$hp_bf_cpus_2nd,$hp_bf_cpus_3rd stress -c 3 -t 90 &" + stress_pid=$! + [[ -n "$stress_pid" ]] || block_test "stress is not launched." + + cpu_stat=$(turbostat -q -c 0,"$hp_bf_cpus_2nd","$hp_bf_cpus_3rd" --show "$COLUMNS" -i 10 sleep 10 2>&1) + [[ -n "$cpu_stat" ]] || block_test "Did not get turbostat log" + test_print_trc "Turbostat output when 100% workload stress running is:" + echo -e "$cpu_stat" + + # Assume CPU0 is the low priority CPU + actual_lp_cpu0_freq=$(echo "$cpu_stat" | + awk '{for(k=0;++k<=NF;)a[k]=a[k]?a[k] FS $k:$k} END{for(k=0;k++ /sys/devices/system/cpu/intel_pstate/no_turbo" + + # Set the error deviation is 100 MHz + if [[ $(echo "$delta_2nd_cpu > 100" | bc) -eq 1 ]] || + [[ $(echo "$delta_3rd_cpu > 100" | bc) -eq 1 ]] || + [[ "$actual_lp_cpu0_freq" -ne "$lp_base_freq_isst" ]]; then + #Invoking power limit check function + if power_limit_check; then + test_print_trc "The package$j and core power limitation is assert." + test_print_trc "The 2nd and 3rd CPUs of package$j did not reach ISST HP base freq when power limitation assert." + else + test_print_trc "The package$j and core power limitation is not assert." + die "The 2nd and 3rd CPUs of package$j did not reach ISST HP base freq without power limitation assert." + fi + else + test_print_trc "The isst high priority and low priority base freq of package$j reached \ +expectation when stress is running." + fi + done +} + +# Function to check isst high priority turbo freq feature +# Input: +# $1: select different perf profile level +isst_tf_freq_test() { + local level_id=$1 + + # Make sure CPU turbo is enabled + test_print_trc "Make sure CPU Turbo is enabled by default" + do_cmd "echo 0 > /sys/devices/system/cpu/intel_pstate/no_turbo" + + # Set SST Perf profile level to $level_id + test_print_trc "Will change Perf profile config level to $level_id:" + do_cmd "intel-speed-select -o pp.out perf-profile set-config-level -l $level_id -o" + test_print_trc "The system perf profile config level change log:" + do_cmd "cat pp.out" + + # Make sure ISST TF is disabled at beginning + do_cmd "intel-speed-select -c 8,9 turbo-freq disable -a" + test_print_trc "Make sure the default isst turbo freq setting:disable" + + # Keep ISST TF disable to get base turbo freq when all CPUs running stress + test_print_trc "Executing 100% workload on all CPUs to get the base turbo freq:" + cpu_num=$(lscpu --online --extended | awk '{print $1}' | sed -n '$p') + [[ -n "$cpu_num" ]] || block_test "Did not get online cpu list" + all_cpus_num=$(("$cpu_num" + 1)) + do_cmd "stress -c $all_cpus_num -t 120 &" + stress_pid=$! + [[ -n "$stress_pid" ]] || block_test "stress is not launched." + + # List Core0 15 CPUs freq status by turbostat tool + cpu_stat=$(turbostat -q -c 0-14 --show $COLUMNS -i 10 sleep 10 2>&1) + [[ -n "$cpu_stat" ]] || block_test "Did not get turbostat log" + test_print_trc "Turbostat output when 100% workload stress running with turbo enabled:" + echo -e "$cpu_stat" + # Take CPU8 and CPU9 to check the base turbo freq + base_turbo_freq_cpu8=$(echo "$cpu_stat" | + awk '{for(k=0;++k<=NF;)a[k]=a[k]?a[k] FS $k:$k} END{for(k=0;k++&1) + [[ -n "$cpu_stat" ]] || block_test "Did not get expected turbostat output." + test_print_trc "Turbostat output when 100% workload stress and hackbench workload running:" + echo -e "$cpu_stat" + # Take CPU8 and CPU9 to check high priority turbo freq + hp_turbo_freq_cpu8=$(echo "$cpu_stat" | + awk '{for(k=0;++k<=NF;)a[k]=a[k]?a[k] FS $k:$k} END{for(k=0;k++ +#include +#include "../common/kselftest.h" + +#define CPUID_LEAF7_EDX_PREFETCHI_MASK (1 << 14) /* PREFETCHI instructions */ + +static void check_cpuid_prefetchi(void) +{ + uint32_t eax, ebx, ecx, edx; + + /* + * CPUID.(EAX=07H, ECX=01H).EDX.PREFETCHI[bit 14] enumerates + * support for PREFETCHIT0/1 instructions. + */ + __cpuid_count(7, 1, eax, ebx, ecx, edx); + if (!(edx & CPUID_LEAF7_EDX_PREFETCHI_MASK)) + printf("cpuid: CPU doesn't support PREFETCHIT0/1.\n"); + else + printf("Test passed\n"); +} + +int main(void) +{ + check_cpuid_prefetchi(); + return 0; +} diff --git a/tests/platform/intel/pmu/README.md b/tests/platform/intel/pmu/README.md new file mode 100644 index 0000000000000000000000000000000000000000..0a4d3f1f0991913dbdae3b0ead7fbb265d3f708a --- /dev/null +++ b/tests/platform/intel/pmu/README.md @@ -0,0 +1,14 @@ +# PMU and adaptive PEBS basic functional check + +## Usage + +1. Make sure latest perf is there. +2. Run case as +``` +./pmu_tests.sh -t +./apebs_tests.sh -t +``` + +## Expected result + +All test results should show pass, no fail. diff --git a/tests/platform/intel/pmu/apebs_tests.sh b/tests/platform/intel/pmu/apebs_tests.sh new file mode 100755 index 0000000000000000000000000000000000000000..e04936370ac8d919bb3c15cbf15358b90a63a921 --- /dev/null +++ b/tests/platform/intel/pmu/apebs_tests.sh @@ -0,0 +1,152 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) 2022 Intel Corporation + +# Author: Ammy Yi +# +# History: 26. Dec, 2022 - (Ammy Yi)Creation + + +# @desc This script verify pmu adaptive PEBS functional tests +# @returns Fail the test if return code is non-zero (value set not found) + +cd "$(dirname "$0")" 2>/dev/null || exit 1 +source ../.env + + +: "${CASE_NAME:=""}" +: "${WATCHDOG:=0}" +: "${RAWFILE:="perf.data"}" + +usage() { + cat <<__EOF + usage: ./${0##*/} [-t TESTCASE_ID] [-H] + -t TEST CASE ID + -H show this +__EOF +} + +lbr_test() { + level=$1 + perfdata="pebs.data" + logfile="temp.txt" + perf record -o "$perfdata" -b -e cycles:"$level" -a sleep 1 2> "$logfile" + sample_count=$(grep "sample" $logfile | awk '{print $10}' | tr -cd "0-9") + lbr_count=$(perf report -D -i $perfdata| grep -c "branch stack") + test_print_trc "sample_count = $sample_count; lbr_count = $lbr_count" + [[ $sample_count -eq 0 ]] && die "samples = 0!" + [[ $sample_count -eq $lbr_count ]] || die "samples does not match!" +} + +lbr_test() { + level=$1 + perfdata="pebs.data" + logfile="temp.txt" + perf record -o "$perfdata" -b -e cycles:"$level" -a sleep 1 2> "$logfile" + sample_count=$(grep "sample" $logfile | awk '{print $10}' | tr -cd "0-9") + count=$(perf report -D -i $perfdata| grep -c "branch stack") + test_print_trc "sample_count = $sample_count; count = $count" + [[ $sample_count -eq 0 ]] && die "samples = 0!" + [[ $sample_count -eq $count ]] || die "samples does not match!" +} + +xmm_test() { + level=$1 + perfdata="pebs.data" + logfile="temp.txt" + perf record -o "$perfdata" -IXMM0 -e cycles:"$level" -a sleep 1 2> "$logfile" + sample_count=$(grep "sample" $logfile | awk '{print $10}' | tr -cd "0-9") + count=$(perf report -D -i $perfdata| grep -c "XMM0") + test_print_trc "before sample_count = $sample_count; count = $count" + sample_count=$((sample_count * 2)) + test_print_trc "after sample_count = $sample_count; count = $count" + [[ $sample_count -eq 0 ]] && die "samples = 0!" + [[ $sample_count -eq $count ]] || die "samples does not match!" +} + +ip_test() { + level=$1 + perfdata="pebs.data" + logfile="temp.txt" + task="mem-loads" + model=$(grep model /proc/cpuinfo | awk '{print $3}' | head -1) + [[ $model -eq 150 ]] && task="cycles" + [[ $model -eq 156 ]] && task="cycles" + test_print_trc "task=$task" + perf mem record -o "$perfdata" -t load -a sleep 1 2> "$logfile" + sample_count=$(grep "sample" $logfile | awk '{print $10}' | tr -cd "0-9") + count=$(perf report -D -i $perfdata| grep -c "data_src") + test_print_trc "sample_count = $sample_count; count = $count" + [[ $sample_count -eq 0 ]] && die "samples = 0!" + [[ $sample_count -eq $count ]] || die "samples does not match!" +} + +data_src_test() { + level=$1 + perfdata="pebs.data" + logfile="temp.txt" + perf record -o "$perfdata" -b -e cycles:"$level" -d -a sleep 1 2> "$logfile" + sync + sync + sleep 1 + sample_count=$(grep "sample" $logfile | awk '{print $10}' | tr -cd "0-9") + count=$(perf report -D -i $perfdata| grep -c "data_src") + [[ $sample_count -eq 0 ]] && die "samples = 0!" + [[ $sample_count -eq $count ]] || die "samples does not match!" +} + +apebs_test() { + echo $WATCHDOG > /proc/sys/kernel/nmi_watchdog + wd_value=$(cat /proc/sys/kernel/nmi_watchdog) + test_print_trc "nmi_watchdog = $wd_value" + case $TEST_SCENARIO in + lbr_1) + lbr_test p + ;; + lbr_2) + lbr_test P + ;; + xmm_1) + xmm_test p + ;; + xmm_2) + xmm_test P + ;; + ip_1) + ip_test p + ;; + ip_2) + ip_test P + ;; + data_src) + data_src_test p + ;; + esac + return 0 +} + +while getopts :t:w:H arg; do + case $arg in + t) + TEST_SCENARIO=$OPTARG + ;; + w) + WATCHDOG=$OPTARG + ;; + H) + usage && exit 0 + ;; + \?) + usage + die "Invalid Option -$OPTARG" + ;; + :) + usage + die "Option -$OPTARG requires an argument." + ;; + esac +done + +apebs_test +# Call teardown for passing case +exec_teardown diff --git a/tests/platform/intel/pmu/pmu_tests.sh b/tests/platform/intel/pmu/pmu_tests.sh new file mode 100755 index 0000000000000000000000000000000000000000..61fa241c616523479d7717f6fe6c172e495666b3 --- /dev/null +++ b/tests/platform/intel/pmu/pmu_tests.sh @@ -0,0 +1,188 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) 2022 Intel Corporation + +# Author: Ammy Yi +# +# History: 26. Dec, 2022 - (Ammy Yi)Creation + + +# @desc This script verify pmu functional tests +# @returns Fail the test if return code is non-zero (value set not found) + + +cd "$(dirname "$0")" 2>/dev/null || exit 1 +source ../.env + + +: "${CASE_NAME:=""}" + +usage() { + cat <<__EOF + usage: ./${0##*/} [-t TESTCASE_ID] [-H] + -t TEST CASE ID + -H show this +__EOF +} + +fix_counter_test() { + # platform before ICL: uncore_cbox_0/clockticks/ + flag=0 + clockticks="uncore_cbox_0/clockticks/" + logfile="temp.txt" + + if ! perf stat -e $clockticks -a -x, sleep 1 2> $logfile; then + flag=$((flag + 1)) + else + sync + sync + sleep 1 + value=$(cat $logfile) + test_print_trc "value = $value" + value=$(echo "$value" | cut -d "," -f 1) + test_print_trc "value_2 = $value" + if [[ $value -le 1000000 ]] || [[ $value -gt 10000000000 ]]; then + die "Counters are not correct!" + fi + fi + + # platform after ICL: uncore_clock/clockticks + clockticks="uncore_clock/clockticks/" + logfile="temp.txt" + if ! perf stat -e $clockticks -a -x, sleep 1 2> $logfile; then + flag=$((flag + 1)) + else + sync + sync + sleep 1 + value=$(cat $logfile) + test_print_trc "value = $value" + value=$(echo "$value" | cut -d "," -f 1) + test_print_trc "value_2 = $value" + if [[ $value -le 1000000 ]] || [[ $value -gt 10000000000 ]]; then + die "Counters are not correct!" + fi + fi + + test_print_trc "flag = $flag" + [[ $flag -eq 2 ]] && die "Fix counter is not working!" + +} + +basic_test() { + do_cmd "dmesg | grep 'Intel PMU driver'" + should_fail "dmesg | grep 'generic architected perfmon'" +} + +lbr_events_cpuid_test() { + #CPUID leaf 0x1c ECX (19:16) must be all 1 for SRF. + for((i=16;i<=19;i++)); do + do_cmd "cpuid_check 1c 0 0 0 c $i" + done +} + +lbr_events_s_test() { + perfdata="perf.data" + logfile="temp.txt" + do_cmd "perf record -o $perfdata -e "{branch-instructions,branch-misses}:S" -j any,counter sleep 1 >& $logfile" + sample_count=$(grep "sample" $logfile| awk '{print $10}' | tr -cd "0-9") + [[ $sample_count -eq 0 ]] && die "samples = 0!" + val=$(perf report -D -i $perfdata | grep -c "branch stack counters") + [[ $val -eq 0 ]] && die "branch stack counters val = 0!" + lbr_vals=$(perf report -D -i $perfdata | grep "branch stack counters" | awk '{print $5}') + for lbr_val in $lbr_vals; do + temp=$(echo "$lbr_val" | cut -d ":" -f 2) + test_print_trc "counts=$temp, lbr_val=$lbr_val!" + [[ $temp -eq 0 ]] && die "branch stack counters = 0!" + done +} + +lbr_events_all_test() { + perfdata="perf.data" + logfile="temp.txt" + do_cmd "perf record -o $perfdata -e "{cpu/branch-instructions,branch_type=any/, cpu/branch-misses,branch_type=counter/}" sleep 1 >& $logfile" + sample_count=$(grep "sample" $logfile| awk '{print $10}' | tr -cd "0-9") + [[ $sample_count -eq 0 ]] && die "samples = 0!" + val=$(perf report -D -i $perfdata | grep -c "branch stack counters") + [[ $val -eq 0 ]] && die "branch stack counters val = 0!" + lbr_vals=$(perf report -D -i $perfdata | grep "branch stack counters" | awk '{print $5}') + for lbr_val in $lbr_vals; do + temp=$(echo "$lbr_val" | cut -d ":" -f 2) + test_print_trc "counts=$temp, lbr_val=$lbr_val!" + [[ $temp -eq 0 ]] && die "branch stack counters = 0!" + done +} + +timed_pebs_msr_test() { + #MSR_IA32_PERF_CAPABILITIES(0x345) bit 17 for Timed PEBs + bit_17=$(rdmsr 0x345 -f 17:17) + test_print_trc "MSR IA32_PERF_CAPABILITIES(0x345) bit 17 is: $bit_17" + [[ $bit_17 -eq 1 ]] || die "Timed PEBS msr bit is not set!" +} + +uncore_events_test() { + uncore_events=$(perf list | grep uncore | grep PMU | awk '{print $1}') + for uncore_event in $uncore_events; do + test_print_trc "uncore_event=$uncore_event" + do_cmd "perf stat -e $uncore_event sleep 1" + done +} + +pmu_test() { + echo "$WATCHDOG" > /proc/sys/kernel/nmi_watchdog + value=$(cat /proc/sys/kernel/nmi_watchdog) + test_print_trc "nmi_watchdog = $value" + case $TEST_SCENARIO in + fix_counter) + fix_counter_test + ;; + basic) + basic_test + ;; + uncore) + do_cmd "ls /sys/devices/ | grep uncore" + ;; + lbr_events_cpuid) + lbr_events_cpuid_test + ;; + lbr_events_s) + lbr_events_s_test + ;; + lbr_events_all) + lbr_events_all_test + ;; + timed_pebs_msr) + timed_pebs_msr_test + ;; + uncore_events) + uncore_events_test + ;; + esac + return 0 +} + +while getopts :t:w:H arg; do + case $arg in + t) + TEST_SCENARIO=$OPTARG + ;; + w) + WATCHDOG=$OPTARG + ;; + H) + usage && exit 0 + ;; + \?) + usage + die "Invalid Option -$OPTARG" + ;; + :) + usage + die "Option -$OPTARG requires an argument." + ;; + esac +done + +pmu_test +# Call teardown for passing case +exec_teardown diff --git a/tests/platform/intel/pmu/tests b/tests/platform/intel/pmu/tests new file mode 100644 index 0000000000000000000000000000000000000000..52f137eb44932c1197c77d02a38691aeba4a1eb9 --- /dev/null +++ b/tests/platform/intel/pmu/tests @@ -0,0 +1,23 @@ +# This file collects the PMU cases +pmu_tests.sh -t fix_counter +pmu_tests.sh -t basic +pmu_tests.sh -t uncore +apebs_tests.sh -t lbr_1 -w 1 +apebs_tests.sh -t lbr_2 -w 1 +apebs_tests.sh -t xmm_1 -w 1 +apebs_tests.sh -t xmm_2 -w 1 +apebs_tests.sh -t ip_1 -w 1 +apebs_tests.sh -t ip_2 -w 1 +apebs_tests.sh -t data_src -w 1 +apebs_tests.sh -t lbr_1 -w 1 +apebs_tests.sh -t lbr_2 -w 1 +apebs_tests.sh -t xmm_1 -w 1 +apebs_tests.sh -t xmm_2 -w 1 +apebs_tests.sh -t ip_1 -w 1 +apebs_tests.sh -t ip_2 -w 1 +apebs_tests.sh -t data_src -w 1 +pmu_tests.sh -t lbr_events_cpuid +pmu_tests.sh -t lbr_events_s +pmu_tests.sh -t lbr_events_all +pmu_tests.sh -t timed_pebs_msr +pmu_tests.sh -t uncore_events diff --git a/tests/platform/intel/rapl/README.md b/tests/platform/intel/rapl/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ce8eeceaec6589388cf5db0e0507521b80102e67 --- /dev/null +++ b/tests/platform/intel/rapl/README.md @@ -0,0 +1,26 @@ +# Release Notes for Running Average Power Limiting test cases + +The RAPL cases are designed for intel_rapl driver on Intel® Architecture-based platforms. +Considering Intel® Server and Client platforms have different rapl domains. +So created two tests files to distinguish the cases running on different test units. + +The prerequisites to run the RAPL cases: +- User needs turbostat, stress, perf tools + +tests-client file collects the cases for Intel® client platforms +You can run the cases one by one, e.g. command + +``` +./intel_rapl_test.sh -t check_sysfs +``` +You also can run the cases together with runtests command, e.g. + +``` +cd .. +./runtests -f rapl/tests-client -o logfile +``` + +tests-server file collects the cases for Intel® server platforms. + +These are the basic cases for Intel_RAPL driver, If you have good idea to +improve cstate cases, you are welcomed to send us the patches, thanks! diff --git a/tests/platform/intel/rapl/intel_rapl_test.sh b/tests/platform/intel/rapl/intel_rapl_test.sh new file mode 100755 index 0000000000000000000000000000000000000000..267c6b4abdf86168c47c7e45bc85e52a6e701d29 --- /dev/null +++ b/tests/platform/intel/rapl/intel_rapl_test.sh @@ -0,0 +1,1621 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) 2022 Intel Corporation +# Description: Test script for Intel_RAPL(Running Average Power Limiting) +# driver which is supported on both Intel® client and server platforms +# @Author wendy.wang@intel.com +# @History Created Jan 05 2023 - Created + +cd "$(dirname "$0")" 2>/dev/null || exit 1 +source ../.env + +RAPL_SYSFS_PATH="/sys/class/powercap" +CPU_SYSFS="/sys/devices/system/cpu" +NUM_CPU_PACKAGES=$(lscpu | grep "Socket(s)" | awk '{print $2}') + +RAPL_TIME_UNIT=0 #Micro-second (us) +RAPL_ENERGY_UNIT=0 #Micro-Joules (uJ) +RAPL_POWER_UNIT=0 #Watts + +MSR_RAPL_POWER_UNIT="0x606" +MSR_PKG_POWER_LIMIT="0x610" +MSR_PKG_ENERGY_STATUS="0x611" +MSR_DRAM_ENERGY_STATUS="0x619" +MSR_PP0_ENERGY_STATUS="0x639" +MSR_PP1_ENERGY_STATUS="0x641" +MSR_PLATFORM_ENERGY_STATUS="0X64D" + +GPU_LOAD="glxgears" +GPU_LOAD_ARG="-display :1" + +declare -A CPU_TOPOLOGY + +# Turbostat tool is required to run RAPL cases +if which turbostat 1>/dev/null 2>&1; then + turbostat sleep 1 1>/dev/null || block_test "Failed to run turbostat tool, +please check turbostat tool error message." +else + block_test "Turbostat tool is required to run RAPL cases, +please get it from latest upstream kernel-tools." +fi + +# stress tool is required to run RAPL cases +if which stress 1>/dev/null 2>&1; then + stress --help 1>/dev/null || block_test "Failed to run stress tool, +please check stress tool error message." +else + block_test "stress tool is required to run RAPL cases, +please get it from latest upstream kernel-tools." +fi + +# perf tool is required to run RAPL cases +if which perf 1>/dev/null 2>&1; then + perf list 1>/dev/null || block_test "Failed to run perf tool, +please check perf tool error message." +else + block_test "perf tool is required to run RAPL cases, +please get it from latest upstream kernel-tools." +fi + +# Read value from MSR +# Input: +# $1: Bit range to be read +# $2: MSR Address +# $3: (Optional) Select processor - default 0 +# Output: +# MSR_VAL: Value obtain from MSR +read_msr() { + local fld=$1 + local reg=$2 + local cpu=$3 + + : "${cpu:=0}" + + [[ -z $fld || $fld =~ [0-9]+:[0-9]+ ]] || die "Incorrect field format!" + [[ -n $reg ]] || die "Unable to read register information" + + MSR_VAL="" + + if [[ $fld == "" ]]; then + MSR_VAL=$(rdmsr -p "$cpu" "$reg") + else + MSR_VAL=$(rdmsr -p "$cpu" -f "$fld" "$reg") + fi + + [[ -n $MSR_VAL ]] || die "Unable to read data from MSR $reg!" + test_print_trc "Read MSR \"$reg\": value = \"$MSR_VAL\"" +} + +# Write value to MSR +# Input: +# $1: ["h:l"] Bit range to be written into MSR +# $2: MSR Address +# $3: Value to be written (Hex: Start with 0x, Dec: Numbers) +# $4: (Optional) Select processor - default 0 +write_msr() { + local fld=$1 + local reg=$2 + local val=$3 + local cpu=$4 + + : "${cpu:=0}" + + [[ $# -ge 3 ]] || die "Invalid input parameters!" + + # Check input value + [[ $val =~ ^0x[0-9a-fA-F]+$ || $val =~ ^[0-9]+$ ]] || die "Invalid input value!" + + # Prepare input value in binary form + [[ $fld == "" ]] && fld="0:63" + st=$(echo "$fld" | cut -d":" -f2) + en=$(echo "$fld" | cut -d":" -f1) + bit_range=$((en - st + 1)) + [[ $bit_range -lt 0 ]] && die "Bit range is incorrect!" + + bin_val=$(perl -e "printf \"%b\", $val") + [[ ${#bin_val} -le $bit_range ]] || die "Input value is greater the field range!" + + # Add zero padding on input binary value + while [[ ${#bin_val} -lt $bit_range ]]; do + bin_val="0$bin_val" + done + + bin_val=$(echo "$bin_val" | rev) + + # Read register value and overwrite input value to form new register value + read_msr "" "$reg" + reg_val=$(perl -e "printf \"%064b\", 0x$MSR_VAL" | rev) + new_val=$(echo "${reg_val:0:st}""$bin_val""${reg_val:$((st + ${#bin_val}))}" | rev) + new_val=$(perl -e "printf \"%016x\n\", $((2#$new_val))") + + # write back to the register + do_cmd "wrmsr -p \"$cpu\" \"$reg\" 0x$new_val" +} + +# Read total energy comsumption from MSR +# Input: +# $1: Select Processor +# $2: Select Domain +# Output: +# CUR_ENERGY: Current energy obtain from MSR +get_total_energy_consumed_msr() { + local cpu=$1 + local domain=$2 + local reg="" + + [[ $# -eq 2 ]] || die "Invalid number of parameters - $#" + [[ $RAPL_ENERGY_UNIT != 0 ]] || read_rapl_unit + + domain=$(echo "$domain" | awk '{print tolower($0)}') + case $domain in + pkg) + reg=$MSR_PKG_ENERGY_STATUS + ;; + core) + reg=$MSR_PP0_ENERGY_STATUS + ;; + uncore) + reg=$MSR_PP1_ENERGY_STATUS + ;; + dram) + reg=$MSR_DRAM_ENERGY_STATUS + ;; + *) + die "Invalid Power Domain" + ;; + esac + + read_msr "31:0" "$reg" "$cpu" + CUR_ENERGY=$(echo "$((16#$MSR_VAL)) * $RAPL_ENERGY_UNIT" | bc) + CUR_ENERGY=${CUR_ENERGY%.*} + test_print_trc "Total $domain Energy: $CUR_ENERGY uj" +} + +# Read total energy comsumption from SYSFS +# Input: +# $1: Select Package +# $2: Select Domain +# Output: +# CUR_ENERY: Current energy obtained from SYSFS +get_total_energy_consumed_sysfs() { + local pkg=$1 + local domain=$2 + + domain=$(echo "$domain" | awk '{print tolower($0)}') + get_domain_path "$pkg" "$domain" + + local energy_path="$DOMAIN_PATH/energy_uj" + [[ -f $energy_path ]] || die "Unable to find the energy data in SYSFS" + CUR_ENERGY=$(cat "$energy_path") + test_print_trc "Package-$pkg - Total $domain Energy: $CUR_ENERGY uj" +} + +# Calculate power consumption over a set period +# Input: +# $1: Energy measurement method (MSR or SYSFS) +# $2: Select CPU package +# $3: Select power domain +# $4: (Optional) Measurement duration (Default: 15s) +get_power_consumed() { + local method=$1 + local pkg=$2 + local domain=$3 + local duration=$4 + + : "${duration:=15}" + + [[ $# -ge 3 ]] || die "Invalid parameters!" + + method=$(echo "$method" | awk '{print tolower($0)}') + domain=$(echo "$domain" | awk '{print tolower($0)}') + + [[ $pkg -le $NUM_CPU_PACKAGES ]] || die "Package number is out of range!" + [[ $domain =~ (pkg|core|uncore|dram) ]] || die "Invalid power domain!" + + case $method in + msr) + cpu=$(echo "${CPU_TOPOLOGY[$pkg]}" | cut -d" " -f1) + get_total_energy_consumed_msr "$cpu" "$domain" + energy_b4=$CUR_ENERGY + + sleep "$duration" + + get_total_energy_consumed_msr "$cpu" "$domain" + energy_af=$CUR_ENERGY + ;; + sysfs) + get_total_energy_consumed_sysfs "$pkg" "$domain" + energy_b4=$CUR_ENERGY + + sleep "$duration" + + get_total_energy_consumed_sysfs "$pkg" "$domain" + energy_af=$CUR_ENERGY + ;; + turbostat) + columns="CPU,PkgWatt,CorWatt,GFXWatt,RAMWatt" + do_cmd "turbostat --quiet --show $columns -o ts.log sleep $duration" + test_print_trc "Turbostat log:" + cat ts.log + + res=$(grep -e "^-" ts.log | awk '{print $2,$3,$4}' | head -1) + test_print_trc "Supported Domain zone columns from turbostat log: $res" + [[ -n $res ]] || die "No result is obtained from turbostat!" + + case $domain in + pkg) + CUR_POWER=$(echo "$res" | awk '{print $1}') + ;; + core) + CUR_POWER=$(echo "$res" | awk '{print $2}') + ;; + uncore) + CUR_POWER=$(echo "$res" | awk '{print $3}') + ;; + dram) + CUR_POWER=$(echo "$res" | awk '{print $4}') + ;; + *) + die "Invalid Power Domain!" + ;; + esac + return 0 + ;; + *) + die "Invalid Measurement Method!" + ;; + esac + CUR_POWER=$(echo "scale=6;($energy_af - $energy_b4) / $duration / 10^6" | bc) + test_print_trc "Package-$pkg $domain Power = $CUR_POWER Watts" +} + +get_power_consumed_server() { + local method=$1 + local pkg=$2 + local domain=$3 + local duration=$4 + + : "${duration:=15}" + + [[ $# -ge 3 ]] || die "Invalid parameters!" + + method=$(echo "$method" | awk '{print tolower($0)}') + domain=$(echo "$domain" | awk '{print tolower($0)}') + + [[ $pkg -le $NUM_CPU_PACKAGES ]] || die "Package number is out of range!" + [[ $domain =~ (pkg|dram) ]] || die "Invalid power domain!" + + case $method in + msr) + cpu=$(echo "${CPU_TOPOLOGY[$pkg]}" | cut -d" " -f1) + get_total_energy_consumed_msr "$cpu" "$domain" + energy_b4=$CUR_ENERGY + + sleep "$duration" + + get_total_energy_consumed_msr "$cpu" "$domain" + energy_af=$CUR_ENERGY + ;; + sysfs) + get_total_energy_consumed_sysfs "$pkg" "$domain" + energy_b4=$CUR_ENERGY + + sleep "$duration" + + get_total_energy_consumed_sysfs "$pkg" "$domain" + energy_af=$CUR_ENERGY + ;; + turbostat) + columns="CPU,PkgWatt,RAMWatt" + do_cmd "turbostat --quiet --show $columns -o ts.log sleep $duration" + test_print_trc "Turbostat log:" + cat ts.log + + res=$(grep -e "^-" ts.log | awk '{print $2,$3}' | head -1) + test_print_trc "Supported Domain zone columns from turbostat log: $res" + [[ -n $res ]] || die "No result is obtained from turbostat!" + + case $domain in + pkg) + CUR_POWER=$(echo "$res" | awk '{print $1}') + test_print_trc "Pkg current power: $CUR_POWER" + ;; + dram) + CUR_POWER=$(echo "$res" | awk '{print $2}') + test_print_trc "Dram current power: $CUR_POWER" + ;; + *) + die "Invalid Power Domain!" + ;; + esac + return 0 + ;; + *) + die "Invalid Measurement Method!" + ;; + esac + CUR_POWER=$(echo "scale=6;($energy_af - $energy_b4) / $duration / 10^6" | bc) + test_print_trc "Package-$pkg $domain Power = $CUR_POWER Watts" +} + +# Get the corresponding domain SYSFS path +# Input: +# $1: Select CPU Package +# $2: Select Power Domain +# Output: +# DOMAIN_PATH: SYSFS PATH for the select domain +get_domain_path() { + local pkg=$1 + local domain=$2 + + DOMAIN_PATH="$RAPL_SYSFS_PATH/intel-rapl:$pkg" + + [[ -d $DOMAIN_PATH ]] || die "RAPL PKG Path does not exist!" + + domain=$(echo "$domain" | awk '{print tolower($0)}') + + case $domain in + pkg) + DOMAIN_PATH="$RAPL_SYSFS_PATH/intel-rapl:$pkg" + ;; + core) + DOMAIN_PATH="$DOMAIN_PATH:0" + ;; + uncore) + DOMAIN_PATH="$DOMAIN_PATH:1" + ;; + dram) + DOMAIN_PATH="$DOMAIN_PATH/intel-rapl:$pkg:0" + ;; + *) + die "Invalid Power Domain!" + ;; + esac +} + +# Enable power limit from sysfs +# Inputs: +# $1: Select CPU package +# $2: Select Domain +# $3: Select state (0=disable, 1=enable) +enable_power_limit() { + local pkg=$1 + local domain=$2 + local state=$3 + + [[ $# -ge 3 ]] || die "Invalid inputs!" + + domain=$(echo "$domain" | awk '{print tolower($0)}') + get_domain_path "$pkg" "$domain" + + do_cmd "echo \"$state\" > \"$DOMAIN_PATH/enabled\"" +} + +power_limit_unlock_check() { + # domain name should be PKG or PP0 + declare -u domain=$1 + local power_limit_unlock="" + + do_cmd "turbostat --debug -o ts.log sleep 2" + test_print_trc "Turbostat log to check power limit unlock status:" + cat ts.log + power_limit_unlock=$(grep UNlocked ts.log | + grep MSR_"$domain"_POWER_LIMIT) + test_print_trc "RAPL test domain name: MSR_${domain}_POWER_LIMIT" + if [[ -n $power_limit_unlock ]]; then + test_print_trc "RAPL $domain Power limit is unlocked" + else + block_test "RAPL $domain Power limit is locked by BIOS, block this case." + fi + return 0 +} + +# Enable power limit from sysfs +# Inputs: +# $1: Select CPU package +# $2: Select Domain +# $3: Select Power Limit +# $4: Select Time Windows +set_power_limit() { + local pkg=$1 + local domain=$2 + local limit=$3 + local time_win=$4 + + domain=$(echo "$domain" | awk '{print tolower($0)}') + test_print_trc "The RAPL pkg name is: $pkg" + test_print_trc "The RAPL domain name is: $domain" + get_domain_path "$pkg" "$domain" + + do_cmd "echo \"$time_win\" > \"$DOMAIN_PATH/constraint_0_time_window_us\"" + do_cmd "echo \"$limit\" > \"$DOMAIN_PATH/constraint_0_power_limit_uw\"" +} + +# Create workloads on the specified domain +# Input: +# $1: Select Domain +# Output: +# LOAD_PID: PID of the test workload +create_test_load() { + local domain=$1 + + domain=$(echo "$domain" | awk '{print tolower($0)}') + case $domain in + pkg | core) + cpu_avail=$(grep processor /proc/cpuinfo | tail -1 | awk '{print $NF}') + cpu_test=$(("$cpu_avail" + 1)) + do_cmd "stress -c $cpu_test -t 60 > /dev/null &" + ;; + uncore) + which "$GPU_LOAD" &>/dev/null || die "glxgears does not exist" + do_cmd "$GPU_LOAD $GPU_LOAD_ARG > /dev/null &" + ;; + dram) + mem_avail=$(grep MemAvailable /proc/meminfo | awk -F " " '{print $2}') + mem_test=$(echo "$mem_avail"/10000000 | bc) + do_cmd "stress --vm $mem_test --vm-bytes 1024M -t 30 > /dev/null &" + ;; + *) + die "Invalid domain!" + ;; + esac + + LOAD_PID=$! +} + +# Clear all workload from system +clear_all_test_load() { + for load in "stress" "$GPU_LOAD"; do + for pid in $(pgrep "$load"); do + do_cmd "kill -9 $pid" + done + done +} + +# Read the scaling factors for the respective RAPL value. +read_rapl_unit() { + read_msr "3:0" "$MSR_RAPL_POWER_UNIT" + RAPL_POWER_UNIT=$(echo "scale=12; 1 / 2^$((16#$MSR_VAL))" | bc) + test_print_trc "RAPL Power Unit = $RAPL_POWER_UNIT Watts" + + read_msr "12:8" "$MSR_RAPL_POWER_UNIT" + RAPL_ENERGY_UNIT=$(echo "scale=12; 1 / 2^$((16#$MSR_VAL)) * 10^6" | bc) + test_print_trc "RAPL Energy Unit = $RAPL_ENERGY_UNIT uj" + + read_msr "19:16" "$MSR_RAPL_POWER_UNIT" + RAPL_TIME_UNIT=$(echo "scale=12; 1 / 2^$((16#$MSR_VAL)) * 10^6" | bc) + test_print_trc "RAPL Time Unit = $RAPL_TIME_UNIT micro-seconds" +} + +# Build CPU Package Topology +# Output: +# CPU_TOPOLOGY: an array of packages each containing a list of CPUs +build_cpu_topology() { + CPU_TOPOLOGY=() + + for ((i = 0; i < NUM_CPU_PACKAGES; i++)); do + CPU_TOPOLOGY+=([$i]="") + done + + for topo in $(grep . $CPU_SYSFS/cpu*/topology/physical_package_id); do + pkg=$(echo "$topo" | cut -d":" -f2) + cpu=$(echo "$topo" | cut -d"/" -f6) + CPU_TOPOLOGY[$pkg]+="${cpu:3} " + done + + for pkg in "${!CPU_TOPOLOGY[@]}"; do + test_print_trc "Package $pkg has CPUs: ${CPU_TOPOLOGY[$pkg]}" + done +} + +# Check if the target machine is a server platform +is_server_platform() { + local rc + + grep "dram" $RAPL_SYSFS_PATH/intel-rapl:*/name 2>&1 + rc=$? + + [[ $rc -eq 0 ]] && { + NAMES=$(grep -E "package-([0-9]{1})" $RAPL_SYSFS_PATH/intel-rapl:*/name) + PKG_NUM=$(awk -F- '{print $3}' <<<"$NAMES" | sort -n | tail -n1) + MAX_PKG_NUM=$((PKG_NUM + 1)) + DIE_NUM=$(awk -F- '{print $NF}' <<<"$NAMES" | sort -n | tail -n1) + MAX_DIE_NUM=$((DIE_NUM + 1)) + } + + return $rc +} + +# RAPL_XS_FUNC_CHK_INTERFACE +rapl_check_interface() { + test_print_trc "Check SYSFS - \"$RAPL_SYSFS_PATH\"intel-rapl..." + [[ -d "$RAPL_SYSFS_PATH"/intel-rapl ]] || + die "Intel-RAPL SYSFS does not exist!" + lines=$(grep . "$RAPL_SYSFS_PATH"/intel-rapl*/* 2>&1 | + grep -v "Is a directory" | grep -v "No data available") + for line in $lines; do + test_print_trc "$line" + done +} + +# RAPL_XS_FUNC_CHK_PKG_DOMAIN +rapl_check_pkg_domain() { + local domain_path="$RAPL_SYSFS_PATH/intel-rapl:" + test_print_trc "Check SYSFS - \"$domain_path\"X..." + + if is_server_platform; then + for ((i = 0; i < MAX_PKG_NUM; i++)); do + for ((j = 0; j < MAX_DIE_NUM; j++)); do + [[ -d "$domain_path""$i" ]] || + die "Intel-RAPL package domain folder does not exist!" + grep -q "package-${i}-die-${j}" "${domain_path}${i}/name" || + test_print_trc "This server does not support package-${i}-die-${j}!" + done + done + else + for ((i = 0; i < NUM_CPU_PACKAGES; i++)); do + [[ -d "$domain_path""$i" ]] || + die "Intel-RAPL package domain folder does not exist!" + grep -q "package-${i}" "${domain_path}${i}/name" || + die "Intel-RAPL package domain name does not match!" + done + fi + test_print_trc "\"$domain_path\"X existed!" +} + +# RAPL_XS_FUNC_CHK_PSYS_DOMAIN +rapl_check_psys_domain() { + local domain_path="$RAPL_SYSFS_PATH/intel-rapl:" + test_print_trc "Check Platform domain sysfs - ${domain_path}X..." + [[ -d "${domain_path}1" ]] || + block_test "Intel-RAPL Platform domain folder does not exist!" + + grep -q "psys" "${domain_path}1/name" || + block_test "Intel-RAPL Platform domain (aka Psys) does not exit!" + test_print_trc "${domain_path}1/name psys file exists" +} + +# RAPL_XS_FUNC_CHK_PP0_DOMAIN +rapl_check_pp0_domain() { + local domain_path="$RAPL_SYSFS_PATH/intel-rapl:" + test_print_trc "Check SYSFS - \"$domain_path\"X:0..." + for ((i = 0; i < NUM_CPU_PACKAGES; i++)); do + [[ -d "$domain_path""$i":0 ]] || + block_test "Intel-RAPL CPU domain folder does not exist!" + grep -q "core" "${domain_path}${i}:0/name" || + block_test "Intel-RAPL CPU domain name does not match!" + done + test_print_trc "\"$domain_path\"X:0 existed!" +} + +# RAPL_XS_FUNC_CHK_PP1_DOMAIN +rapl_check_pp1_domain() { + local domain_path="$RAPL_SYSFS_PATH/intel-rapl:" + test_print_trc "Check SYSFS - \"$domain_path\"X:1..." + for ((i = 0; i < NUM_CPU_PACKAGES; i++)); do + [[ -d "$domain_path""$i":1 ]] || + block_test "Intel-RAPL Graphic domain folder does not exist!" + grep -q "uncore" "${domain_path}${i}:1/name" || + block_test "Intel-RAPL Graphic domain name does not match!" + done + test_print_trc "\"$domain_path\"X:1 existed!" +} + +# RAPL_XS_FUNC_CHK_DRAM_DOMAIN +rapl_check_dram_domain() { + domain_name=$(cat /sys/class/powercap/intel-rapl:*/*/name) + test_print_trc "RAPL Domain name: $domain_name" + [[ "$domain_name" =~ dram ]] || + block_test "intel_rapl DRAM domain folder does not exist!" + test_print_trc "DRAM domain exists" +} + +# RAPL_XS_FUNC_CHK_PKG_ENERGY_STATUS_MSR +rapl_check_pkg_energy_status_msr() { + local pkg_energy_status_msr + + pkg_energy_status_msr=$(read_msr "" "$MSR_PKG_ENERGY_STATUS") + test_print_trc "read_msr \"\" $MSR_PKG_ENERGY_STATUS" + echo "$pkg_energy_status_msr" + pkg_energy_status_msr=$(echo "$pkg_energy_status_msr" | awk -F"\"" END'{print $4}') + pkg_energy_status_msr_10=$((16#${pkg_energy_status_msr})) + + if [[ "$pkg_energy_status_msr_10" -eq 0 ]]; then + die "Your system failed to enable PKG RAPL ENERGY STATUS MSR: 0x611" + fi + test_print_trc "Your system enabled PKG RAPL ENERGY STATUS MSR 0x611 \ +successfully: $pkg_energy_status_msr" +} + +# RAPL_XS_FUNC_CHK_PSYS_ENERGY_STATUS_MSR +rapl_check_psys_domain_msr() { + local psys_domain_msr + + psys_domain_msr=$(read_msr "31:0" "$MSR_PLATFORM_ENERGY_STATUS") + test_print_trc "read_msr \"31:0\" $MSR_PLATFORM_ENERGY_STATUS" + echo "$psys_domain_msr" + psys_domain_msr=$(echo "$psys_domain_msr" | awk -F"\"" END'{print $4}') + psys_domain_msr_10=$((16#${psys_domain_msr})) + + if [[ "$psys_domain_msr_10" -eq 0 ]]; then + die "Your system failed to enable Platform RAPL Domain MSR: 0x64D" + fi + test_print_trc "Your system enabled Platform RAPL Domain MSR 0x64D \ +successfully: $psys_domain_msr" +} + +# RAPL_XS_FUNC_CHK_PKG_POWER_LIMIT_MSR +rapl_check_pkg_power_limit_msr() { + local pkg_power_limit_msr + + pkg_power_limit_msr=$(read_msr "23:0" "$MSR_PKG_POWER_LIMIT") + test_print_trc "The Package RAPL POWER LIMIT MSR 0x610 \"23:0\" shows value: $pkg_power_limit_msr" + pkg_power_limit_msr=$(echo "$pkg_power_limit_msr" | awk -F"\"" END'{print $4}') + pkg_power_limit_msr_10=$((16#${pkg_power_limit_msr})) + + if [[ "$pkg_power_limit_msr_10" -eq 0 ]]; then + die "Your system failed to enable PKG RAPL POWER LIMIT MSR: 0x610" + fi + test_print_trc "Your system enabled PKG RAPL POWER LIMIT MSR 0x610 \ +successfully: $pkg_power_limit_msr" +} + +# Initialize RAPL +init_rapl() { + clear_all_test_load + read_rapl_unit + build_cpu_topology +} + +# intel_rapl power test function +# Input: +# $1: Domain to be tested +rapl_power_check() { + local domain=$1 + local cpu="" + local power_limit_ori="" + local power_limit_up="" + local power_limit_down=100 + local power_limit_after="" + local time_ori="" + local limit="" + local pl=$2 + local rc="" + local sp="" + + domain=$(echo "$domain" | awk '{print tolower($0)}') + [[ -n $domain ]] || "Please specify RAPL domain to be tested!" + [[ $domain =~ (pkg|core|uncore|dram) ]] || + die "Invalid RAPL domain. Must be pkg|core|uncore|dram." + + if [[ $CHECK_ENERGY -eq 1 ]]; then + for ((pkg = 0; pkg < NUM_CPU_PACKAGES; pkg++)); do + cpu=$(echo "${CPU_TOPOLOGY[$pkg]}" | cut -d" " -f1) + get_total_energy_consumed_msr "$cpu" "$domain" + msr_energy=$CUR_ENERGY + + get_total_energy_consumed_sysfs "$pkg" "$domain" + sysfs_energy=$CUR_ENERGY + + test_print_trc "MSR: $msr_energy, SYSFS: $sysfs_energy" + + diff=$(echo "scale=3;$msr_energy / $sysfs_energy * 100" | bc) + diff=${diff%.*} + [[ $diff -le 105 && $diff -ge 95 ]] || + die "The delta between MSR and SYSFS is exceeding 5% range: $diff" + done + elif [[ $CHECK_POWER_LOAD -eq 1 ]]; then + # create display :1 for graphic tests + if [[ $domain == "uncore" ]]; then + do_cmd "startx -- :1 &> /dev/null &" + sleep 5 + fi + + if is_server_platform; then + for ((pkg = 0; pkg < NUM_CPU_PACKAGES; pkg++)); do + sleep 20 + get_power_consumed_server "turbostat" "$pkg" "$domain" "$MEASURE_INTERVAL" + [[ -n "$CUR_POWER" ]] || die "Fail to get current power(before)." + power_b4=$CUR_POWER + + create_test_load "$domain" + + sleep 2 + get_power_consumed_server "turbostat" "$pkg" "$domain" "$MEASURE_INTERVAL" + [[ -n "$CUR_POWER" ]] || die "Fail to get current power(after)." + power_af=$CUR_POWER + + test_print_trc "Package-$pkg: $domain Power before workload: $power_b4 Watts" + test_print_trc "Package-$pkg: $domain Power after workload: $power_af Watts" + + diff=$(echo "scale=3;$power_af / $power_b4 * 100" | bc) + diff=${diff%.*} + test_print_trc "Package-$pkg: $domain Power is increased by $diff percentage!" + + [[ $diff -gt 100 ]] || die "Package-$pkg: $domain no significant power increase after workload!" + # Kill the workload if has + clear_all_test_load + done + else + for ((pkg = 0; pkg < NUM_CPU_PACKAGES; pkg++)); do + sleep 20 + get_power_consumed "turbostat" "$pkg" "$domain" "$MEASURE_INTERVAL" + [[ -n "$CUR_POWER" ]] || die "Fail to get current power(before)." + power_b4=$CUR_POWER + + create_test_load "$domain" + + sleep 2 + get_power_consumed "turbostat" "$pkg" "$domain" "$MEASURE_INTERVAL" + [[ -n "$CUR_POWER" ]] || die "Fail to get current power(after)." + power_af=$CUR_POWER + + test_print_trc "Package-$pkg: $domain Power before workload: $power_b4 Watts" + test_print_trc "Package-$pkg: $domain Power after workload: $power_af Watts" + + diff=$(echo "scale=3;$power_af / $power_b4 * 100" | bc) + diff=${diff%.*} + test_print_trc "Package-$pkg: $domain Power is increased by $diff percentage!" + + [[ $diff -gt 100 ]] || die "Package-$pkg: $domain no significant power increase after workload!" + # Kill the workload if has + clear_all_test_load + done + fi + elif [[ $CHECK_POWER_LIMIT -eq 1 ]]; then + # Judge whether power limit is unlocked or not in BIOS + # Skip this case if BIOS locked pkg or core power limit change + + if power_limit_unlock_check "$domain"; then + for ((pkg = 0; pkg < NUM_CPU_PACKAGES; pkg++)); do + # Save the original power limit and time value + get_domain_path "$pkg" "$domain" + client_domain=$(cat "$DOMAIN_PATH"/name) + [[ "$client_domain" != psys ]] || break + test_print_trc "Original $domain sysfs path: $DOMAIN_PATH" + power_limit_ori="$(cat "$DOMAIN_PATH"/constraint_0_power_limit_uw)" + time_ori="$(cat "$DOMAIN_PATH"/constraint_0_power_limit_uw)" + test_print_trc "Original $domain power limit: $power_limit_ori uwatts" + + # Set the power limit and time value + echo "Received power limit test value: $pl percentage" + limit=$(("$pl" * "$power_limit_ori" / 100)) + test_print_trc "Real Power limit test value: $limit uwatts" + power_limit_up=$((10 * "$power_limit_ori" / 100)) + time_win=1000000 + set_power_limit "$pkg" "$domain" "$limit" "$time_win" + + # Run workload to get rapl domain power watt after setting power limit + create_test_load "$domain" + sleep 2 + + if is_server_platform; then + sp=$(("$pkg" + 3)) + do_cmd "turbostat --quiet --show Package,Core,PkgWatt -o tc.log sleep 1" + test_print_trc "Server turbostat log:" + cat tc.log + if [[ $NUM_CPU_PACKAGES -eq 1 ]]; then + power_limit_after="$(awk '{print $2}' tc.log | sed '/^\s*$/d' | + sed -n ''"$sp"',1p')" + else + power_limit_after="$(awk '{print $3}' tc.log | sed '/^\s*$/d' | + sed -n ''"$sp"',1p')" + fi + test_print_trc "Server power limit after: $power_limit_after" + [[ -n "$power_limit_after" ]] || + die "Fail to get current power from server turbostat" + power_limit_after="$(echo "scale=2;$power_limit_after * 1000000" | bc)" + else + get_power_consumed_server "turbostat" "$pkg" "$domain" "$MEASURE_INTERVAL" + test_print_trc "$domain power after setting limit: $CUR_POWER watts" + [[ -n "$CUR_POWER" ]] || die "Fail to get current power from turbostat" + power_limit_after="$(echo "scale=2;$CUR_POWER * 1000000" | bc)" + fi + power_limit_after="${power_limit_after%.*}" + clear_all_test_load + + # Restore the power limit value to origin + set_power_limit "$pkg" "$domain" "$power_limit_ori" "$time_ori" + + test_print_trc "Original power limit value: $power_limit_ori uwatts" + test_print_trc "Configured power limit value: $limit uwatts" + test_print_trc "After setting power limit value: $power_limit_after uwatts" + delta=$(("$limit" - "$power_limit_after")) + if [[ $delta -lt 0 ]]; then + delta=$((0 - "$delta")) + fi + test_print_trc "The delta power after setting limit: $delta uwatts" + + # The accepted pkg watts error range is 100 uwatts to 10% of TDP + if [[ "$delta" -gt "$power_limit_down" ]] && + [[ "$delta" -lt "$power_limit_up" ]]; then + test_print_trc "Setting RAPL $domain rapl power limit to $pl is PASS" + else + die "The power gap after setting limit to $pl percentage: $delta uwatts" + fi + done + else + block_test "$domain power limit is locked by BIOS, block this case." + fi + else + die "Test type is empty! Please specific energy or power tests!" + fi +} + +# Function to check any error after power limit change and rapl control enable +enable_rapl_control() { + domain_num=$(ls /sys/class/powercap/ | grep -c intel-rapl:) + [[ -n "$domain_num" ]] || block_test "intel-rapl sysfs is not available." + + for ((i = 1; i <= domain_num; i++)); do + domain_name=$(ls /sys/class/powercap/ | grep intel-rapl: | sed -n "$i,1p") + # Change each domain's power limit setting then enable the RAPL control + + default_power_limit=$(cat /sys/class/powercap/"$domain_name"/constraint_0_max_power_uw) + if [[ "$default_power_limit" -eq 0 ]]; then + continue + else + test_power_limit=$(("$default_power_limit" - 2000000)) + test_print_trc "Test power limit is: $test_power_limit uw" + fi + do_cmd "echo $test_power_limit > /sys/class/powercap/$domain_name/constraint_0_power_limit_uw" + do_cmd "echo 1 > /sys/class/powercap/$domain_name/enabled" + enabled_knob=$(cat /sys/class/powercap/"$domain_name"/enabled) + # Recover the default constraint_0_power_limit_uw setting + do_cmd "echo $default_power_limit > /sys/class/powercap/$domain_name/constraint_0_power_limit_uw" + if [[ "$enabled_knob" -eq 1 ]]; then + test_print_trc "Enabling RAPL control for $domain_name is PASS after power limit change." + else + die "Enabling RAPL control for $domain_name is Fail after power limit change" + fi + done +} + +# Function to compare supported domain names among sysfs, perf and turbostat tool +rapl_perf_name_compare() { + local driver_name=$1 + + sysfs_names=$(cat /sys/class/powercap/"$driver_name":*/name 2>&1) + test_print_trc "sysfs domain name: $sysfs_names" + perf_names=$(perf list | grep energy 2>&1) + test_print_trc "Perf event name: $perf_names" + energy_event_sysfs=$(ls /sys/devices/power/events/ 2>&1) + test_print_trc "Perf sysfs events:$energy_event_sysfs" + turbostat_names=$(turbostat -q --show power sleep 1 2>&1) + test_print_trc "Turbostat log: $turbostat_names" + + sysfs_rapl_num=$(cat /sys/class/powercap/"$driver_name":*/name | wc -l 2>&1) + perf_name_num=$(perf list | grep -c energy 2>&1) + # Take RAPL sysfs domain as base, if perf energy name number + # Is not aligned with sysfs, then fail the case + [[ -n "$sysfs_names" ]] || block_test "RAPL sysfs does not exist: $sysfs_names" + [[ -n "$perf_names" ]] || block_test "Did not get RAPL event by perf list:\ + $energy_event_sysfs" + if [[ "$sysfs_rapl_num" -eq "$perf_name_num" ]]; then + test_print_trc "RAPL domain number is aligned between sysfs and perf" + else + # Here will not die because perf list cannot display --per-socket energy value on server + # So the rapl domain cannot compare between perf list tool and sysfs on server, only + # Print the message, but not fail. + test_print_trc "RAPL domain number is not aligned between sysfs and perf. \ +sysfs shows: $sysfs_names, perf event shows:$perf_names" + fi + + # Check sysfs,perf,turbostat tool RAPL domain name, take sysfs as base + for ((i = 1; i <= sysfs_rapl_num; i++)); do + sysfs_name=$(cat /sys/class/powercap/"$driver_name":*/name | sed -n "$i,1p") + test_print_trc "RAPL Domain test name: $sysfs_name" + if [[ $sysfs_name =~ package ]] && [[ $perf_names =~ pkg ]] && + [[ $turbostat_names =~ PkgWatt ]]; then + test_print_trc "Package domain name is aligned among sysfs,perf and turbostat tool" + elif [[ $sysfs_name =~ core ]] && [[ $perf_names =~ core ]] && + [[ $turbostat_names =~ CorWatt ]]; then + test_print_trc "Core domain name is aligned among sysfs,perf and turbostat tool" + elif [[ $sysfs_name =~ uncore ]] && [[ $perf_names =~ gpu ]] && + [[ $turbostat_names =~ GFXWatt ]]; then + test_print_trc "Uncore(GFX) domain name is aligned among sysfs,perf and turbostat tool" + elif [[ $sysfs_name =~ dram ]] && [[ $perf_names =~ ram ]] && + [[ $turbostat_names =~ RAMWatt ]]; then + test_print_trc "Dram domain name is aligned among sysfs,perf and turbostat tool" + elif [[ $sysfs_name =~ psys ]] && [[ $perf_names =~ psys ]]; then + test_print_trc "Turbostat will not show psys, but sysfs and perf shows up, it's expected." + else + die "There is a domain name exception among sysfs, perf and turbostat comparing\ +sysfs names: $sysfs_names, perf names: $perf_names, turbostat_name: $turbostat_names" + fi + done +} + +# Function to check supported domain energy joules between sysfs and perf tool +# when workload is running +rapl_perf_energy_compare() { + local driver_name=$1 + local load=$2 + local load=$3 + local option + local j=0 + local p=0 + local pkg0=package-0 + local pkg1=package-1 + + sysfs_names=$(cat /sys/class/powercap/"$driver_name":*/name 2>&1) + sysfs_rapl_num=$(cat /sys/class/powercap/"$driver_name":*/name | wc -l 2>&1) + perf_names=$(perf list | grep energy 2>&1) + perf_name_num=$(perf list | grep -c energy 2>&1) + [[ -n $sysfs_names ]] || block_test "Please check if rapl driver loaded or not." + [[ -n $perf_names ]] || block_test "Did not get RAPL event by perf list" + + # Read MSR RAW data before sleep + # Package MSR is: 0x611 + # Core MSR is: 0x639 + # Psys MSR is: 0x64d + # Dram MSR is: 0x619 + for ((i = 1; i <= sysfs_rapl_num; i++)); do + sysfs_name=$(cat /sys/class/powercap/"$driver_name":*/name | sed -n "$i,1p" 2>&1) + if [[ $sysfs_name =~ package ]]; then + msr_raw_bf=$(rdmsr -f 31:0 $MSR_PKG_ENERGY_STATUS) + test_print_trc "$sysfs_name MSR RAW value before: $msr_raw_bf" + elif [[ $sysfs_name =~ core ]]; then + msr_raw_bf=$(rdmsr -f 31:0 $MSR_PP0_ENERGY_STATUS) + test_print_trc "$sysfs_name MSR RAW value before: $msr_raw_bf" + elif [[ $sysfs_name =~ psys ]]; then + msr_raw_bf=$(rdmsr -f 31:0 $MSR_PLATFORM_ENERGY_STATUS) + test_print_trc "$sysfs_name MSR RAW value before: $msr_raw_bf" + elif [[ $sysfs_name =~ dram ]]; then + msr_raw_bf=$(rdmsr -f 31:0 $MSR_DRAM_ENERGY_STATUS) + test_print_trc "$sysfs_name MSR RAW value before: $msr_raw_bf" + fi + done + + load=$(echo "$load" | awk '{print tolower($0)}') + case $load in + pkg | core) + cpu_avail=$(grep processor /proc/cpuinfo | tail -1 | awk '{print $NF}') + cpu_test=$(("$cpu_avail" + 1)) + do_cmd "stress -c $cpu_test -t 60 > /dev/null &" + ;; + uncore) + which "$GPU_LOAD" &>/dev/null || die "glxgears does not exist" + do_cmd "$GPU_LOAD $GPU_LOAD_ARG > /dev/null &" + ;; + dram) + which "stress" &>/dev/null || die "stress does not exist" + mem_avail=$(grep MemAvailable /proc/meminfo | awk -F " " '{print $2}') + mem_test=$(echo "$mem_avail"/10000000 | bc) + do_cmd "stress --vm $mem_test --vm-bytes 1024M -t 30 > /dev/null &" + ;; + *) + test_print_trc "Will not run workload but idle!" + do_cmd "sleep 20" + ;; + esac + + LOAD_PID=$! + + # Read sysfs energy value before sleep + sysfs_energy_uj_bf=$(cat /sys/class/powercap/"$driver_name":*/energy_uj 2>&1) + test_print_trc "Sysfs energy events before:$sysfs_energy_uj_bf" + # Sleep 20 seconds to capture the RAPL energy value + for ((i = 1; i <= perf_name_num; i++)); do + perf_name=$(echo "$perf_names" | awk '{print $1}' | sed -n "$i, 1p" 2>&1) + test_print_trc "perf event name: $perf_name" + option="$option -e $perf_name" + test_print_trc "option name: $option" + done + do_cmd "perf stat -o out.txt --per-socket $option sleep 20" + sysfs_energy_uj_af=$(cat /sys/class/powercap/"$driver_name":*/energy_uj 2>&1) + + # Print the logs after sleep + test_print_trc "Sysfs domain name after: $sysfs_names" + test_print_trc "Sysfs energy events after: $sysfs_energy_uj_af" + test_print_trc "Perf energy events log:" + do_cmd "cat out.txt" + # Kill the workload if has + clear_all_test_load + + # Calculate each energy delta in past 20 seconds idle, the unit is Joules + for ((i = 1; i <= sysfs_rapl_num; i++)); do + sysfs_name=$(cat /sys/class/powercap/"$driver_name":*/name | sed -n "$i,1p" 2>&1) + sysfs_energy_uj_bf_per_domain=$(echo "$sysfs_energy_uj_bf" | sed -n "$i,1p") + test_print_trc "Sysfs energy uj before for domain name $sysfs_name is: $sysfs_energy_uj_bf_per_domain" + sysfs_energy_uj_af_per_domain=$(echo "$sysfs_energy_uj_af" | sed -n "$i,1p") + test_print_trc "Sysfs energy uj after for domain name $sysfs_name is: $sysfs_energy_uj_af_per_domain" + if [[ $sysfs_name =~ package ]]; then + msr_raw_af=$(rdmsr -f 31:0 $MSR_PKG_ENERGY_STATUS) + test_print_trc "$sysfs_name MSR RAW value after: $msr_raw_af" + elif [[ $sysfs_name =~ core ]]; then + msr_raw_af=$(rdmsr -f 31:0 $MSR_PP0_ENERGY_STATUS) + test_print_trc "$sysfs_name MSR RAW value after: $msr_raw_af" + elif [[ $sysfs_name =~ psys ]]; then + msr_raw_af=$(rdmsr -f 31:0 $MSR_PLATFORM_ENERGY_STATUS) + test_print_trc "$sysfs_name MSR RAW value after: $msr_raw_af" + elif [[ $sysfs_name =~ dram ]]; then + msr_raw_af=$(rdmsr -f 31:0 $MSR_DRAM_ENERGY_STATUS) + test_print_trc "$sysfs_name MSR RAW value after: $msr_raw_af" + fi + sysfs_energy_delta_uj=$(echo "scale=2; $sysfs_energy_uj_af_per_domain-$sysfs_energy_uj_bf_per_domain" | bc) + test_print_trc "Sysfs energy delta ujoules for $sysfs_name is: $sysfs_energy_delta_uj" + sysfs_energy_delta_j=$(echo "scale=2; $sysfs_energy_delta_uj/1000000" | bc) + test_print_trc "Sysfs energy delta joules for $sysfs_name is: $sysfs_energy_delta_j" + + # Calculate perf energy delta, which is directly reading from perf log + if ! counter=$(grep energy out.txt | awk '{print $3}'); then + block_test "Did not get energy $sysfs_name counter: $counter" + else + [[ $sysfs_name =~ dram ]] && + perf_energy_j=$(grep energy-ram out.txt | grep S$j | awk '{print $3}' 2>&1) && + j=$(("$j" + 1)) + # Use j variable to judge how many dram domain name, initial value is 0 + [[ $sysfs_name == "$pkg0" ]] && + perf_energy_j=$(grep "energy-pkg" out.txt | grep S0 | awk '{print $3}' 2>&1) + [[ $sysfs_name == "$pkg1" ]] && + perf_energy_j=$(grep "energy-pkg" out.txt | grep S1 | awk '{print $3}' 2>&1) + [[ $sysfs_name =~ core ]] && + perf_energy_j=$(grep "energy-cores" out.txt | grep S0 | awk '{print $3}' 2>&1) + [[ $sysfs_name =~ uncore ]] && + perf_energy_j=$(grep "energy-gpu" out.txt | grep S0 | awk '{print $3}' 2>&1) + [[ $sysfs_name =~ psys ]] && + perf_energy_j=$(grep "energy-psys" out.txt | grep S$p | awk '{print $3}' 2>&1) && + p=$(("$p" + 1)) + # Use p variable to judge how many psys domain name, initial value is 0 + # Perf tool will display 1,000 for 1000, so need to remove "," + perf_energy_j_modify=${perf_energy_j/,/} + test_print_trc "Perf energy joules for $sysfs_name is: $perf_energy_j_modify" + fi + + # Compare the sysfs_energy and perf_energy value + energy_delta_j=$(awk -v x="$sysfs_energy_delta_j" -v y="$perf_energy_j_modify" \ + 'BEGIN{printf "%.1f\n", x-y}') + test_print_trc "The domain $sysfs_name energy delta joules between sysfs and perf event is:$energy_delta_j" + + #Set the error deviation is 20% of sysfs energy Joules + energy_low_j=$(echo "scale=2; 20*$sysfs_energy_delta_j/100" | bc) + energy_low_j=$(echo "scale=2; $sysfs_energy_delta_j-$energy_low_j" | bc) + test_print_trc "The low energy error deviation is:$energy_low_j" + energy_high_j=$(echo "scale=2; $sysfs_energy_delta_j+$energy_low_j" | bc) + test_print_trc "The high energy error deviation is:$energy_high_j" + if [[ $(echo "$perf_energy_j_modify < $energy_high_j" | bc -l) ]] && + [[ $(echo "$perf_energy_j_modify > $energy_low_j" | bc -l) ]]; then + test_print_trc "The domain $sysfs_name energy delta between sysfs and perf event \ +is within 20% of sysfs energy joules gap" + elif [[ $(echo "$perf_energy_j_modify == 0" | bc -l) ]]; then + test_print_trc "The domain $sysfs_name energy shows 0, if GFX related, it may be expected" + else + die "The domain $sysfs_name energy delta between sysfs and perf event is \ +beyond 20% of sysfs energy joules gap: $energy_delta_j" + fi + done +} + +# Function to check supported domain energy joules between sysfs and turbostat tool +# when workload is running +rapl_turbostat_energy_compare() { + local driver_name=$1 + local load=$2 + local load=$3 + local j=3 + local pkg0=package-0 + local pkg1=package-1 + local corename=core + local uncorename=uncore + local dramname=dram + local psysname=psys + + sysfs_names=$(cat /sys/class/powercap/"$driver_name":*/name 2>&1) + sysfs_rapl_num=$(cat /sys/class/powercap/"$driver_name":*/name | wc -l 2>&1) + [[ -n $sysfs_names ]] || block_test "Please check if rapl driver loaded or not" + + # Read MSR RAW data before sleep + # Package MSR is: 0x611 + # Core MSR is: 0x639 + # Psys MSR is: 0x64d + # Dram MSR is: 0x619 + for ((i = 1; i <= sysfs_rapl_num; i++)); do + sysfs_name=$(cat /sys/class/powercap/"$driver_name":*/name | sed -n "$i,1p" 2>&1) + if [[ $sysfs_name =~ package ]]; then + msr_raw_bf=$(rdmsr -f 31:0 $MSR_PKG_ENERGY_STATUS) + test_print_trc "$sysfs_name MSR RAW value before: $msr_raw_bf" + elif [[ $sysfs_name =~ core ]]; then + msr_raw_bf=$(rdmsr -f 31:0 $MSR_PP0_ENERGY_STATUS) + test_print_trc "$sysfs_name MSR RAW value before: $msr_raw_bf" + elif [[ $sysfs_name =~ psys ]]; then + msr_raw_bf=$(rdmsr -f 31:0 $MSR_PLATFORM_ENERGY_STATUS) + test_print_trc "$sysfs_name MSR RAW value before: $msr_raw_bf" + elif [[ $sysfs_name =~ dram ]]; then + msr_raw_bf=$(rdmsr -f 31:0 $MSR_DRAM_ENERGY_STATUS) + test_print_trc "$sysfs_name MSR RAW value before: $msr_raw_bf" + fi + done + + load=$(echo "$load" | awk '{print tolower($0)}') + case $load in + pkg | core) + cpu_avail=$(grep processor /proc/cpuinfo | tail -1 | awk '{print $NF}') + cpu_test=$(("$cpu_avail" + 1)) + do_cmd "stress -c $cpu_test -t 60 > /dev/null &" + ;; + uncore) + which "$GPU_LOAD" &>/dev/null || die "glxgears does not exist" + do_cmd "$GPU_LOAD $GPU_LOAD_ARG > /dev/null &" + ;; + dram) + which "stress" &>/dev/null || die "stress does not exist" + mem_avail=$(grep MemAvailable /proc/meminfo | awk -F " " '{print $2}') + mem_test=$(echo "$mem_avail"/10000000 | bc) + do_cmd "stress --vm $mem_test --vm-bytes 1024M -t 90 > /dev/null &" + ;; + *) + test_print_trc "Will not run workload but idle!" + do_cmd "sleep 20" + ;; + esac + + LOAD_PID=$! + + # Read sysfs energy value before sleep + sysfs_energy_uj_bf=$(cat /sys/class/powercap/"$driver_name":*/energy_uj 2>&1) + test_print_trc "Sysfs energy events before:$sysfs_energy_uj_bf" + + # Sleep 20 seconds to capture the RAPL energy value + tc_out=$(turbostat -q --show power -i 1 sleep 20 2>&1) + sysfs_energy_uj_af=$(cat /sys/class/powercap/"$driver_name":*/energy_uj 2>&1) + + # Print the logs after sleep + test_print_trc "Sysfs domain name after: $sysfs_names" + test_print_trc "Sysfs energy events after: $sysfs_energy_uj_af" + test_print_trc "Turbostat output: $tc_out" + # Kill the workload if has + [[ -z "$LOAD_PID" ]] || do_cmd "kill -9 $LOAD_PID" + + # Calculate each energy delta in past 20 seconds idle, the unit is Joules + for ((i = 1; i <= sysfs_rapl_num; i++)); do + sysfs_name=$(cat /sys/class/powercap/"$driver_name":*/name | sed -n "$i,1p" 2>&1) + sysfs_energy_uj_bf_per_domain=$(echo "$sysfs_energy_uj_bf" | sed -n "$i,1p") + test_print_trc "Sysfs energy uj before for domain name $sysfs_name is: $sysfs_energy_uj_bf_per_domain" + sysfs_energy_uj_af_per_domain=$(echo "$sysfs_energy_uj_af" | sed -n "$i,1p") + test_print_trc "Sysfs energy uj after for domain name $sysfs_name is: $sysfs_energy_uj_af_per_domain" + if [[ $sysfs_name =~ package ]]; then + msr_raw_af=$(rdmsr -f 31:0 $MSR_PKG_ENERGY_STATUS) + test_print_trc "$sysfs_name MSR RAW value after: $msr_raw_af" + elif [[ $sysfs_name =~ core ]]; then + msr_raw_af=$(rdmsr -f 31:0 $MSR_PP0_ENERGY_STATUS) + test_print_trc "$sysfs_name MSR RAW value after: $msr_raw_af" + elif [[ $sysfs_name =~ psys ]]; then + msr_raw_af=$(rdmsr -f 31:0 $MSR_PLATFORM_ENERGY_STATUS) + test_print_trc "$sysfs_name MSR RAW value after: $msr_raw_af" + elif [[ $sysfs_name =~ dram ]]; then + msr_raw_af=$(rdmsr -f 31:0 $MSR_DRAM_ENERGY_STATUS) + test_print_trc "$sysfs_name MSR RAW value after: $msr_raw_af" + fi + sysfs_energy_delta_uj=$(echo "scale=2; $sysfs_energy_uj_af_per_domain-$sysfs_energy_uj_bf_per_domain" | bc) + test_print_trc "Sysfs energy delta ujoules for $sysfs_name is: $sysfs_energy_delta_uj" + sysfs_energy_delta_j=$(echo "scale=2; $sysfs_energy_delta_uj/1000000" | bc) + test_print_trc "Sysfs energy delta joules for $sysfs_name is: $sysfs_energy_delta_j" + + # Calculate energy delta from turbostat tool, which unit is Watts + # Joules=Watts * Seconds + [[ -n "$tc_out" ]] || block_test "Did not get turbostat log" + if [[ $sysfs_name == "$pkg0" ]]; then + turbostat_watts=$(echo "$tc_out" | awk '{print $3}' | sed '/^$/d' | sed -n '3,1p' 2>&1) + test_print_trc "Turbostat watts for $sysfs_name is: $turbostat_watts" + elif [[ $sysfs_name == "$pkg1" ]]; then + turbostat_watts=$(echo "$tc_out" | awk '{print $3}' | sed '/^$/d' | sed -n '4,1p' 2>&1) + test_print_trc "Turbostat watts for $sysfs_name is: $turbostat_watts" + elif [[ $sysfs_name == "$corename" ]]; then + turbostat_watts=$(echo "$tc_out" | awk '{$1 = "";print $0}' | sed '/^$/d' | + awk '{for(k=0;++k<=NF;)a[k]=a[k]?a[k] FS $k:$k} END{for(k=0;k++ $energy_low_j" | bc -l) ]]; then + test_print_trc "The domain $sysfs_name energy delta between sysfs and turbostat tool \ +is within 20% of sysfs energy joules gap" + elif [[ $(echo "$turbostat_joules == 0" | bc -l) ]]; then + test_print_trc "The domain $sysfs_name energy shows 0, if GFX related, it may be expected" + else + die "The domain $sysfs_name energy delta between sysfs and turbostat tool is \ +beyond 20% of sysfs energy joules gap: $energy_delta_j" + fi + done +} + +# Function to verify if 0x601 (PL4) will change after RAPL control enable and disable +# Also PL1/PL2 power limit value change will not impact PL4 +# Meanwhile judge if RAPL control disable expected or not +# PL1 is mapping constraint_0 (long term) +# PL2 is mapping constraint_1 (short term) +# PL4 is mapping constraint_2 (peak power) +# Linux does not support PL3 +rapl_control_enable_disable_pl() { + local pl_id=$1 + + domain_num=$(ls /sys/class/powercap/ | grep -c intel-rapl:) + [[ -n "$domain_num" ]] || block_test "intel-rapl sysfs is not available." + + for ((i = 1; i <= domain_num; i++)); do + domain_name=$(ls /sys/class/powercap/ | grep intel-rapl: | sed -n "$i,1p") + test_print_trc "------Testing domain name: $domain_name------" + + # Read default PL4, PL1, PL2 value + pl4_default=$(rdmsr 0x601) + [[ -n "$pl4_default" ]] && test_print_trc "PL4 value before RAPL Control enable and disable: $pl4_default" + + pl1_default=$(cat /sys/class/powercap/"$domain_name"/constraint_0_max_power_uw) + [[ -n "$pl1_default" ]] && test_print_trc "PL1 value before RAPL Control enable and disable: $pl1_default" + + pl2_default=$(cat /sys/class/powercap/"$domain_name"/constraint_1_max_power_uw) + [[ -n "$pl2_default" ]] && test_print_trc "PL2 value before RAPL Control enable and disable: $pl2_default" + + # Enable RAPL control + do_cmd "echo 1 > /sys/class/powercap/$domain_name/enabled" + enabled_knob=$(cat /sys/class/powercap/"$domain_name"/enabled) + if [[ "$enabled_knob" -eq 1 ]]; then + test_print_trc "Enabling RAPL control for $domain_name is PASS" + else + die "Enabling RAPL control for $domain_name is Fail" + fi + + # Change each domain's $pl_id power limit setting then enable the RAPL control + default_power_limit=$(cat /sys/class/powercap/"$domain_name"/constraint_"$pl_id"_max_power_uw) + [[ -n "$default_power_limit" ]] && test_print_trc "Domain $domain_name's constraint_'$pl_id'_max_power_uw \ +default value is: $default_power_limit" + # Use package PL1 to judge SUT is client or Server + # Usually the largest PL1 for Client Desktop is 125 Watts, Client mobile PL1 will be 9/15/45/65 Watts etc. + pl1_edge=$(cat /sys/class/powercap/intel-rapl/intel-rapl:0/constraint_0_max_power_uw) + [[ -n "$pl1_edge" ]] || block_test "Package PL1 power value is not available." + if [[ $pl1_edge -le 125000000 ]]; then + test_print_trc "The SUT should be client:" + if [[ "$default_power_limit" -eq 0 ]]; then + test_power_limit=$(("$default_power_limit" + 10000000)) + test_print_trc "Test power limit is: $test_power_limit uw" + else + test_power_limit=$(("$default_power_limit" - 5000000)) + [[ $test_power_limit -lt 0 ]] && test_power_limit=0 + test_print_trc "Test power limit is: $test_power_limit uw" + fi + else + test_print_trc "The SUT should be server:" + if [[ "$default_power_limit" -eq 0 ]]; then + test_power_limit=$(("$default_power_limit" + 100000000)) + test_print_trc "Test power limit is: $test_power_limit uw" + else + test_power_limit=$(("$default_power_limit" - 100000000)) + [[ $test_power_limit -lt 0 ]] && test_power_limit=0 + test_print_trc "Test power limit is: $test_power_limit uw" + fi + fi + [[ -d /sys/class/powercap/"$domain_name"/constraint_"$pl_id"_power_limit_uw ]] && + echo "$test_power_limit" >/sys/class/powercap/"$domain_name"/constraint_"$pl_id"_power_limit_uw + + # Recover the default constraint_$pl_id_power_limit_uw setting + [[ -d /sys/class/powercap/"$domain_name"/constraint_"$pl_id"_power_limit_uw ]] && + echo "$default_power_limit" >/sys/class/powercap/"$domain_name"/constraint_"$pl_id"_power_limit_uw + + # Disable RAPL control + do_cmd "echo 0 > /sys/class/powercap/$domain_name/enabled" + disabled_knob=$(cat /sys/class/powercap/"$domain_name"/enabled) + + # Get Enable power limit value by reading 0x610 bit 15 + enable_power_limit=$(rdmsr 0x610 -f 15:15) + test_print_trc "Enable RAPL Limit shows: $enable_power_limit" + + # Check if RAPL control disable works as expected + if [[ $disabled_knob -eq 0 ]]; then + test_print_trc "RAPL Control is not expected to be set to 0." + elif [[ $enable_power_limit -eq 0 ]]; then + die "System allows to disable PL, while writing RAPL control disable fail." + else + # Trying to manually write 0x610 bit 15 to 0 + # If it can't be set then you are OK as system is not allowing to disable PL1. + # But wrmsr can write bit 15 to 0 and enabled is still 1, then this is a bug + change_bit15=$(wrmsr 0x610 $(($(rdmsr -d 0x610) & ~(1 << 15)))) + test_print_trc "Verify if 0x610 bit 15 can be set to 0: $change_bit15" + read_bit15=$(rdmsr 0x610 -f 15:15) + if [[ $read_bit15 -eq 0 ]]; then + die "0x610 bit 15 can change to 0, while RAPL control disable still 1." + else + test_print_trc "0x610 bit 15 cannot change to 0, so RAPL control enable shows 1 is expected." + fi + fi + + # Check if PL4 value changed after RAPL control enable and disable + pl4_test=$(rdmsr 0x601) + test_print_trc "PL4 value after RAPL Control enable and disable: $pl4_test" + if [[ "$pl4_test" == "$pl4_default" ]]; then + test_print_trc "PL4 shows the same value as default after RAPL Control enable and disable" + else + die "PL4 value changed after RAPL Control enable and disable: $pl4_test" + fi + + # Check if PL1 value changed after RAPL control enable and disable + pl1_recovered=$(cat /sys/class/powercap/"$domain_name"/constraint_0_max_power_uw) + if [[ -z "$pl1_default" ]]; then + test_print_trc "constraint_0_max_power_uw is not available for $domain_name" + elif [[ "$pl1_recovered" == "$pl1_default" ]]; then + test_print_trc "PL1 shows the same value as default after RAPL Control enable and disable" + else + die "PL1 value changed after RAPL Control enable and disable: $pl1_recovered" + fi + + # Check if PL2 value changed after RAPL control enable and disable + pl2_recovered=$(cat /sys/class/powercap/"$domain_name"/constraint_1_max_power_uw) + if [[ -z "$pl2_default" ]]; then + test_print_trc "constraint_1_max_power_uw is not available for $domain_name" + elif [[ "$pl2_recovered" == "$pl2_default" ]]; then + test_print_trc "PL2 shows the same value as default after RAPL Control enable and disable" + else + die "PL2 value changed after RAPL Control enable and disable: $pl2_recovered" + fi + + # Re-enable RAPL control + do_cmd "echo 1 > /sys/class/powercap/$domain_name/enabled" + + done +} + +# Function to change 0x601 (PL4) value and RAPL control enable and disable +# Meanwhile judge if RAPL control disable expected or not +rapl_control_enable_disable_pl4() { + local test_pl4=$1 + + domain_num=$(ls /sys/class/powercap/ | grep -c intel-rapl:) + [[ -n "$domain_num" ]] || block_test "intel-rapl sysfs is not available." + + for ((i = 1; i <= domain_num; i++)); do + domain_name=$(ls /sys/class/powercap/ | grep intel-rapl: | sed -n "$i,1p") + test_print_trc "------Testing domain name: $domain_name------" + ori_pl4=$(rdmsr 0x601) + + # Read default PL4, PL1, PL2 value + pl4_default=$(cat /sys/class/powercap/"$domain_name"/constraint_2_max_power_uw) + [[ -n "$pl4_default" ]] && test_print_trc "PL4 value before RAPL Control enable and disable: $pl4_default" + + pl1_default=$(cat /sys/class/powercap/"$domain_name"/constraint_0_max_power_uw) + [[ -n "$pl1_default" ]] && test_print_trc "PL1 value before RAPL Control enable and disable: $pl1_default" + + pl2_default=$(cat /sys/class/powercap/"$domain_name"/constraint_1_max_power_uw) + [[ -n "$pl2_default" ]] && test_print_trc "PL2 value before RAPL Control enable and disable: $pl2_default" + + # Enable RAPL control + do_cmd "echo 1 > /sys/class/powercap/$domain_name/enabled" + enabled_knob=$(cat /sys/class/powercap/"$domain_name"/enabled) + if [[ "$enabled_knob" -eq 1 ]]; then + test_print_trc "Enabling RAPL control for $domain_name is PASS" + else + die "Enabling RAPL control for $domain_name is Fail" + fi + + # Write a low value to 0x601 then enable the RAPL control + # Only cover on Client platform + # Low value will be written 0 + # High value will be written + do_cmd "wrmsr 0x601 $test_pl4" + + # Disable RAPL control + do_cmd "echo 0 > /sys/class/powercap/$domain_name/enabled" + disabled_knob=$(cat /sys/class/powercap/"$domain_name"/enabled) + + # Get Enable power limit value by reading 0x610 bit 15 + enable_power_limit=$(rdmsr 0x610 -f 15:15) + test_print_trc "Enable RAPL Limit shows: $enable_power_limit" + + # Check if RAPL control disable works as expected + if [[ $disabled_knob -eq 0 ]]; then + test_print_trc "RAPL Control is not expected to be set to 0, so 1 is PASS." + elif [[ $enable_power_limit -eq 0 ]]; then + die "System allows to disable PL, while writing RAPL control disable fail." + else + # Trying to manually write 0x610 bit 15 to 0 + # If it can't be set then you are OK as system is not allowing to disable PL1. + # But wrmsr can write bit 15 to 0 and enabled is still 1, then this is a bug + change_bit15=$(wrmsr 0x610 $(($(rdmsr -d 0x610) & ~(1 << 15)))) + test_print_trc "Verify if 0x610 bit 15 can be set to 0: $change_bit15" + read_bit15=$(rdmsr 0x610 -f 15:15) + if [[ $read_bit15 -eq 0 ]]; then + die "0x610 bit 15 can change to 0, while RAPL control disable still 1." + else + test_print_trc "0x610 bit 15 cannot change to 0, so RAPL control enable shows 1 is expected." + fi + fi + + # Check if PL4 value changed after RAPL control enable and disable + pl4_recovered=$(cat /sys/class/powercap/"$domain_name"/constraint_2_max_power_uw) + test_print_trc "PL4 value after RAPL Control enable and disable: $pl4_recovered" + if [[ -z "$pl4_recovered" ]]; then + test_print_trc "constraint_2_max_power_uw is not available for $domain_name" + elif [[ "$pl4_recovered" == "$pl4_default" ]]; then + test_print_trc "PL4 shows the same value as default after RAPL Control enable and disable" + else + die "PL4 value changed after RAPL Control enable and disable: $pl4_recovered" + fi + + # Check if PL1 value changed after RAPL control enable and disable + pl1_recovered=$(cat /sys/class/powercap/"$domain_name"/constraint_0_max_power_uw) + if [[ -z "$pl1_default" ]]; then + test_print_trc "constraint_0_max_power_uw is not available for $domain_name" + elif [[ "$pl1_recovered" == "$pl1_default" ]]; then + test_print_trc "PL1 value after RAPL Control enable and disable:$pl1_recovered" + test_print_trc "PL1 shows the same value as default after RAPL Control enable and disable" + else + die "PL1 value changed after RAPL Control enable and disable: $pl1_recovered" + fi + + # Check if PL2 value changed after RAPL control enable and disable + pl2_recovered=$(cat /sys/class/powercap/"$domain_name"/constraint_1_max_power_uw) + if [[ -z "$pl2_default" ]]; then + test_print_trc "constraint_1_max_power_uw is not available for $domain_name" + elif [[ "$pl2_recovered" == "$pl2_default" ]]; then + test_print_trc "PL2 value after RAPL Control enable and disable:$pl2_recovered" + test_print_trc "PL2 shows the same value as default after RAPL Control enable and disable" + else + die "PL2 value changed after RAPL Control enable and disable: $pl2_recovered" + fi + + # Re-enable RAPL control + do_cmd "echo 1 > /sys/class/powercap/$domain_name/enabled" + + # Re-cover the 0x601 original setting + do_cmd "wrmsr 0x601 $ori_pl4" + + done +} + +: "${CHECK_ENERGY:=0}" +: "${CHECK_POWER_LOAD:=0}" +: "${CHECK_POWER_LIMIT:=0}" + +intel_rapl_test() { + case $TEST_SCENARIO in + check_sysfs) + rapl_check_interface + ;; + check_pkg_domain) + rapl_check_pkg_domain + ;; + check_psys_domain) + rapl_check_psys_domain + ;; + check_pp0_domain) + rapl_check_pp0_domain + ;; + check_pp1_domain) + rapl_check_pp1_domain + ;; + check_dram_domain) + rapl_check_dram_domain + ;; + check_pkg_domain_msr) + rapl_check_pkg_energy_status_msr + ;; + check_psys_domain_msr) + rapl_check_psys_domain_msr + ;; + check_pkg_power_limit_msr) + rapl_check_pkg_power_limit_msr + ;; + check_pkg_energy_status) + CHECK_ENERGY=1 + rapl_power_check pkg + ;; + check_pkg_energy_status_with_workload) + CHECK_POWER_LOAD=1 + rapl_power_check pkg + ;; + check_pkg_power_limit_75) + CHECK_POWER_LIMIT=1 + rapl_power_check pkg 75 + ;; + check_pkg_power_limit_50) + CHECK_POWER_LIMIT=1 + rapl_power_check pkg 50 + ;; + check_pp0_energy_status) + CHECK_ENERGY=1 + rapl_power_check core + ;; + check_pp0_energy_status_with_workload) + CHECK_POWER_LOAD=1 + rapl_power_check core + ;; + check_dram_energy_status) + CHECK_ENERGY=1 + rapl_power_check dram + ;; + check_dram_energy_status_with_workload) + CHECK_POWER_LOAD=1 + rapl_power_check dram + ;; + check_pp1_energy_status) + CHECK_ENERGY=1 + rapl_power_check uncore + ;; + check_rapl_control_after_power_limit_change) + enable_rapl_control + ;; + sysfs_perf_name_compare) + rapl_perf_name_compare intel-rapl + ;; + sysfs_perf_energy_compare_workload_server) + rapl_perf_energy_compare intel-rapl pkg dram + ;; + sysfs_perf_energy_compare_workload_client) + rapl_perf_energy_compare intel-rapl pkg uncore + ;; + sysfs_turbostat_energy_compare_workload_server) + rapl_turbostat_energy_compare intel-rapl pkg dram + ;; + sysfs_turbostat_energy_compare_workload_client) + rapl_turbostat_energy_compare intel-rapl pkg uncore + ;; + rapl_control_enable_disable_pl1) + rapl_control_enable_disable_pl 0 + ;; + rapl_control_enable_disable_pl2) + rapl_control_enable_disable_pl 1 + ;; + rapl_control_enable_disable_pl4) + rapl_control_enable_disable_pl 2 + ;; + rapl_control_pl4_low_value) + rapl_control_enable_disable_pl4 0 + ;; + rapl_control_pl4_high_value) + rapl_control_enable_disable_pl4 0x500 + ;; + esac + return 0 +} + +while getopts :t:H arg; do + case $arg in + t) + TEST_SCENARIO=$OPTARG + ;; + H) + usage && exit 0 + ;; + \?) + usage + die "Invalid Option -$OPTARG" + ;; + :) + usage + die "Option -$OPTARG requires an argument." + ;; + esac +done + +init_rapl +intel_rapl_test diff --git a/tests/platform/intel/rapl/tests-client b/tests/platform/intel/rapl/tests-client new file mode 100755 index 0000000000000000000000000000000000000000..48955d293f7bdf3538fdab55ccda6b6dc3726b57 --- /dev/null +++ b/tests/platform/intel/rapl/tests-client @@ -0,0 +1,25 @@ +# This file collects RAPL cases which can run against intel_rapl driver +# on Intel® Architecture-based client platforms. + +intel_rapl_test.sh -t check_sysfs +intel_rapl_test.sh -t check_pkg_domain +intel_rapl_test.sh -t check_pp0_domain +intel_rapl_test.sh -t check_pp1_domain +intel_rapl_test.sh -t check_pkg_domain_msr +intel_rapl_test.sh -t check_pkg_power_limit_msr +intel_rapl_test.sh -t check_pkg_energy_status +intel_rapl_test.sh -t check_pkg_energy_status_with_workload +intel_rapl_test.sh -t check_pkg_power_limit_75 +intel_rapl_test.sh -t check_pkg_power_limit_50 +intel_rapl_test.sh -t check_pp0_energy_status +intel_rapl_test.sh -t check_pp0_energy_status_with_workload +intel_rapl_test.sh -t check_pp1_energy_status +intel_rapl_test.sh -t check_rapl_control_after_power_limit_change +intel_rapl_test.sh -t sysfs_perf_name_compare +intel_rapl_test.sh -t sysfs_perf_energy_compare_workload_client +intel_rapl_test.sh -t sysfs_turbostat_energy_compare_workload_client +intel_rapl_test.sh -t rapl_control_enable_disable_pl1 +intel_rapl_test.sh -t rapl_control_enable_disable_pl2 +intel_rapl_test.sh -t rapl_control_enable_disable_pl4 +intel_rapl_test.sh -t rapl_control_pl4_low_value +intel_rapl_test.sh -t rapl_control_pl4_high_value diff --git a/tests/platform/intel/rapl/tests-server b/tests/platform/intel/rapl/tests-server new file mode 100755 index 0000000000000000000000000000000000000000..34a17e1849d3306be55ad243788a7fef46783302 --- /dev/null +++ b/tests/platform/intel/rapl/tests-server @@ -0,0 +1,23 @@ +# This file collects RAPL cases which can run against intel_rapl driver +# on Intel® Architecture-based server platforms. + +intel_rapl_test.sh -t check_sysfs +intel_rapl_test.sh -t check_pkg_domain +intel_rapl_test.sh -t check_psys_domain +intel_rapl_test.sh -t check_dram_domain +intel_rapl_test.sh -t check_psys_domain_msr +intel_rapl_test.sh -t check_pkg_domain_msr +intel_rapl_test.sh -t check_pkg_power_limit_msr +intel_rapl_test.sh -t check_pkg_energy_status +intel_rapl_test.sh -t check_pkg_energy_status_with_workload +intel_rapl_test.sh -t check_pkg_power_limit_75 +intel_rapl_test.sh -t check_pkg_power_limit_50 +intel_rapl_test.sh -t check_dram_energy_status +intel_rapl_test.sh -t check_dram_energy_status_with_workload +intel_rapl_test.sh -t check_rapl_control_after_power_limit_change +intel_rapl_test.sh -t sysfs_perf_name_compare +intel_rapl_test.sh -t sysfs_perf_energy_compare_workload_server +intel_rapl_test.sh -t sysfs_turbostat_energy_compare_workload_server +intel_rapl_test.sh -t rapl_control_enable_disable_pl1 +intel_rapl_test.sh -t rapl_control_enable_disable_pl2 +intel_rapl_test.sh -t rapl_control_enable_disable_pl4 diff --git a/tests/platform/intel/tpmi/README.md b/tests/platform/intel/tpmi/README.md new file mode 100644 index 0000000000000000000000000000000000000000..d039b0e96a8e34274df78aada5aba3df3baae828 --- /dev/null +++ b/tests/platform/intel/tpmi/README.md @@ -0,0 +1,23 @@ +# Release Notes for Topology Aware Register and PM Capsule Interface test cases + +The tpmi cases are designed to test the basic functionality of the intel_vsec +and intel_tpmi driver modules on Intel® Architecture-based server platforms. +These cases are supported on the GRANITERAPIDS and will be compatibale with +subsequent platforms as well. + + +You can run the cases one by one, e.g. command + +``` +./intel_tpmi.sh -t pm_feature_list +``` +You also can run the cases together with runtests command, e.g. + +``` +cd .. +./runtests -f tpmi/tests -o logfile +``` + +These are the basic cases for intel_vsec and intel_tpmi driver module, +If you have good idea to improve cstate cases, you are welcomed to +send us the patches, thanks! diff --git a/tests/platform/intel/tpmi/intel_tpmi.sh b/tests/platform/intel/tpmi/intel_tpmi.sh new file mode 100755 index 0000000000000000000000000000000000000000..01307ca079c610487455ddc0dcb100326baa2458 --- /dev/null +++ b/tests/platform/intel/tpmi/intel_tpmi.sh @@ -0,0 +1,416 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) 2024 Intel Corporation +# Description: Test script for Intel_TPMI(Topology Aware Register and PM Capsule Interface) +# driver which is supported on both Intel® server platforms: GRANITERAPIDS and is +# compatible with subsequent server platforms +# @Author wendy.wang@intel.com +# @History Created May 06 2024 - Created + +cd "$(dirname "$0")" 2>/dev/null || exit 1 +source ../.env + +TPMI_DRIVER_PATH="/sys/module/intel_vsec_tpmi/drivers/auxiliary" +TPMI_DEBUGFS_PATH="/sys/kernel/debug" + +: "${CASE_NAME:=""}" + +usage() { + cat <<__EOF + usage: ./${0##*/} [-t TESTCASE_ID] [-H] + -t TEST CASE ID + -H show this +__EOF +} + +get_vsec_oobmsm_device() { + dev_lines=$(lspci -d 8086:09a7 | wc -l 2>&1) + if [[ $dev_lines == 0 ]]; then + dev_lines=$(lspci -d 8086:09a1 | wc -l 2>&1) + fi + [[ "$dev_lines" -ne 0 ]] || block_test "Did not detect tpmi pci device." +} + +unload_module() { + # $1 is the driver module name + local module_name=$1 + is_kmodule_builtin "$module_name" && skip_test + load_unload_module.sh -c -d "$module_name" && + do_cmd "load_unload_module.sh -u -d $module_name" +} + +load_module() { + # $1 is the driver module name + local module_name=$1 + is_kmodule_builtin "$module_name" && skip_test + do_cmd "load_unload_module.sh -l -d $module_name" && + load_unload_module.sh -c -d "$module_name" +} + +tpmi_driver_interface() { + test_print_trc "Check intel_vsec_tpmi driver interface:" + + [[ -d "$TPMI_DRIVER_PATH":intel_vsec_tpmi ]] || + die "intel_vsec_tpmi driver SYSFS does not exist!" + + lines=$(ls "$TPMI_DRIVER_PATH":intel_vsec_tpmi 2>&1) + for line in $lines; do + test_print_trc "$line" + done +} + +tpmi_debugfs_interface() { + local socket_num + local tpmi_debugfs_instance + local tpmi_debugfs_instance_num + local tpmi_pci_device + + socket_num=$(lscpu | grep "Socket(s)" | awk -F " " '{print $2}' 2>&1) + test_print_trc "Check how many socket the system supports: $socket_num" + + tpmi_debugfs_instance=$(ls "$TPMI_DEBUGFS_PATH" | grep "tpmi-*" 2>&1) + tpmi_debugfs_instance_num=$(ls "$TPMI_DEBUGFS_PATH" | grep -c "tpmi-*" 2>&1) + test_print_trc "Check how many intel_vesc_tpmi debugfs instance:" + test_print_trc "$tpmi_debugfs_instance" + + get_vsec_oobmsm_device + + test_print_trc "Check tpmi pci device:" + tpmi_pci_device=$(lspci -d 8086:09a7 2>&1) + test_print_trc "$tpmi_pci_device" + + if [[ -n "$tpmi_debugfs_instance" ]] && [[ -n "$tpmi_pci_device" ]] && + [[ "$socket_num" -eq "$tpmi_debugfs_instance_num" ]] && + [[ "$socket_num" -eq "$dev_lines" ]]; then + test_print_trc "intel_vsec_tpmi 09a7 debugfs file exist and instance number is correct" + elif [[ -z "$tpmi_pci_device" ]]; then + tpmi_pci_device=$(lspci -d 8086:09a1 2>&1) + socket_num=$((socket_num * 2)) + if [[ -n "$tpmi_debugfs_instance" ]] && [[ -n "$tpmi_pci_device" ]] && + [[ "$socket_num" -eq "$tpmi_debugfs_instance_num" ]] && + [[ "$socket_num" -eq "$dev_lines" ]]; then + test_print_trc "intel_vsec_tpmi debugfs file exist and instance number is correct" + else + die "intel_vsec_tpmi 09a1 debugfs file and instance number is not correct!" + fi + else + die "intel_vsec_tpmi debugfs is not correct!" + fi + + lines=$(ls -A "$TPMI_DEBUGFS_PATH"/tpmi-* 2>&1) + for line in $lines; do + test_print_trc "$line" + done +} + +# PFS: PM Feature Structure +dump_pfs_pm_feature_list() { + local expected_tpmi_id="0x80 0x00 0x01 0x02 0x03 0x04 0x05 0x0a 0x06 0x0c 0x0d 0x81 0xfd 0xfe 0xff" + local test_tpmi_id="" + local line_num="" + local dev_name="" + local pfs_item="" + + get_vsec_oobmsm_device + + test_print_trc "Dump PM Feature Structure:" + for ((i = 1; i <= dev_lines; i++)); do + dev_name=$(lspci -d 8086:09a7 | awk -F " " '{print $1}' | sed -n "$i, 1p") + [[ -e "$TPMI_DEBUGFS_PATH"/tpmi-0000:"$dev_name"/pfs_dump ]] || + block_test "tpmi debugfs pfs_dump does not exist." + test_print_trc "The $TPMI_DEBUGFS_PATH/tpmi-0000:$dev_name/pfs_dump is:" + cat "$TPMI_DEBUGFS_PATH"/tpmi-0000:"$dev_name"/pfs_dump 2>&1 + done + + test_print_trc "Check if all the PFS TPMI_ID are expected:" + # Calculate the tpmi debugfs device lines num + for ((i = 1; i <= dev_lines; i++)); do + dev_name=$(lspci -d 8086:09a7 | awk -F " " '{print $1}' | sed -n "$i, 1p") + + # Calculate the TPMI_ID lines num + line_num=$(awk 'END { print NR}' "$TPMI_DEBUGFS_PATH"/tpmi-0000:"$dev_name"/pfs_dump 2>&1) + # Calculate if the pfs_dump shows the duplicated features + pfs_item=$(uniq -c "$TPMI_DEBUGFS_PATH"/tpmi-0000:"$dev_name"/pfs_dump | wc -l 2>&1) + [[ $pfs_item -eq 17 ]] || die "$TPMI_DEBUGFS_PATH/tpmi-0000:$dev_name/pfs_dump \ +shows feature list is not align with spec." + + # Check each TPMI_ID in PFS dump + for ((j = 3; j <= line_num; j++)); do + test_tpmi_id=$(awk '{print $1}' "$TPMI_DEBUGFS_PATH"/tpmi-0000:"$dev_name"/pfs_dump 2>&1 | + sed -n "$j, 1p") + if [[ $expected_tpmi_id =~ $test_tpmi_id ]]; then + test_print_trc "PFS TPMI_ID $test_tpmi_id in tpmi-0000:$dev_name is detected." + else + die "PFS TPMI_ID $test_tpmi_id in tpmi-0000:$dev_name is not detected." + fi + done + done +} + +dump_pfs_lock_disable_status() { + local line_num="" + local dev_name="" + local disabled_status="" + + get_vsec_oobmsm_device + + test_print_trc "Check intel_vsec_tpmi dump_pfs lock and disable status:" + for ((i = 1; i <= dev_lines; i++)); do + dev_name=$(lspci -d 8086:09a7 | awk -F " " '{print $1}' | sed -n "$i, 1p") + if [[ -n "$dev_name" ]]; then + [[ -e "$TPMI_DEBUGFS_PATH"/tpmi-0000:"$dev_name"/pfs_dump ]] || + block_test "tpmi debugfs pfs_dump does not exist." + test_print_trc "The $TPMI_DEBUGFS_PATH/tpmi-0000:$dev_name/pfs_dump is:" + cat "$TPMI_DEBUGFS_PATH"/tpmi-0000:"$dev_name"/pfs_dump 2>&1 + + disabled_status=$(awk '{for(k=0;++k<=NF;)a[k]=a[k]?a[k] FS $k:$k} END{for(k=0;k++&1 + + disabled_status=$(awk '{for(k=0;++k<=NF;)a[k]=a[k]?a[k] FS $k:$k} END{for(k=0;k++&1) + if [[ -n "$dev_name" ]]; then + test_print_trc "$TPMI_DEBUGFS_PATH/tpmi-0000:$dev_name/tpmi-id-$id/mem_dump is:" + if [[ -e "$TPMI_DEBUGFS_PATH/tpmi-0000:$dev_name/tpmi-id-$id/mem_dump" ]]; then + cat "$TPMI_DEBUGFS_PATH"/tpmi-0000:"$dev_name"/tpmi-id-"$id"/mem_dump + else + die "$TPMI_DEBUGFS_PATH/tpmi-0000:$dev_name/tpmi-id-$id/mem_dump does not exist." + fi + mem_value=$(cut -d ] -f 2 "$TPMI_DEBUGFS_PATH"/tpmi-0000:"$dev_name"/tpmi-id-"$id"/mem_dump 2>&1 | + sed -n '/[1-9a-fA-F]/p') + if [[ -z "$mem_value" ]]; then + die "The tpmi-0000:$dev_name tpmi-id-$id pm feature mem_value is not expected" + else + test_print_trc "The tpmi-0000:$dev_name tpmi-id-$id pm feature mem_value is non-zero." + fi + + else + dev_name=$(lspci -d 8086:09a1 | awk -F " " '{print $1}' | sed -n "$i, 1p") + test_print_trc "$TPMI_DEBUGFS_PATH/tpmi-$dev_name/tpmi-id-$id/mem_dump is:" + if [[ -e "$TPMI_DEBUGFS_PATH/tpmi-$dev_name/tpmi-id-$id/mem_dump" ]]; then + cat "$TPMI_DEBUGFS_PATH"/tpmi-"$dev_name"/tpmi-id-"$id"/mem_dump + else + die "$TPMI_DEBUGFS_PATH/tpmi-$dev_name/tpmi-id-$id/mem_dump does not exist." + fi + mem_value=$(cut -d ] -f 2 "$TPMI_DEBUGFS_PATH"/tpmi-"$dev_name"/tpmi-id-"$id"/mem_dump 2>&1 | + sed -n '/[1-9a-fA-F]/p') + if [[ -z "$mem_value" ]]; then + die "The tpmi-$dev_name tpmi-id-$id pm feature mem_value is not expected" + else + test_print_trc "The tpmi-$dev_name tpmi-id-$id pm feature mem_value is non-zero." + fi + fi + done +} + +mem_write_read() { + local dev_name="" + local mem_ori="" + local mem_aft="" + + get_vsec_oobmsm_device + + test_print_trc "Check mem_write and mem_dump:" + for ((i = 1; i <= dev_lines; i++)); do + dev_name=$(lspci -d 8086:09a7 | awk -F " " '{print $1}' | sed -n "$i, 1p") + if [[ -n "$dev_name" ]]; then + test_print_trc "Choose tpmi-id-02 UFS feature to check mem_write and mem_dump for device $dev_name:" + mem_ori=$(cat $TPMI_DEBUGFS_PATH/tpmi-0000:"$dev_name"/tpmi-id-02/mem_dump | grep "00000020" | head -1 | awk '{print $2}') + test_print_trc "The tpmi-id-02 feature instance 0 mem original value at 0x0020 is: $mem_ori" + test_print_trc "Will write 0x1234 to tpmi-id-02 UFS feature instance 0 with mem address 0x0020" + do_cmd "echo 0,0x20,0x1234 > $TPMI_DEBUGFS_PATH/tpmi-0000:$dev_name/tpmi-id-02/mem_write" + + test_print_trc "Confirm if mem_write successful:" + mem_aft=$(cat $TPMI_DEBUGFS_PATH/tpmi-0000:"$dev_name"/tpmi-id-02/mem_dump | grep "00000020" | head -1 | awk '{print $2}') + test_print_trc "The tpmi-id-02 UFS feature mem value after writing 0x1234 at 0x0020 is: $mem_aft" + if [[ "$mem_aft" == 00001234 ]]; then + test_print_trc "mem_write is successful." + else + die "mem_dump is not expected after mem_write: $mem_aft" + fi + + test_print_trc "Recover mem_dump to the original value:" + do_cmd "echo 0,0x20,0x$mem_ori > $TPMI_DEBUGFS_PATH/tpmi-0000:$dev_name/tpmi-id-02/mem_write" + + else + dev_name=$(lspci -d 8086:09a1 | awk -F " " '{print $1}' | sed -n "$i, 1p") + + test_print_trc "Choose tpmi-id-02 UFS feature to check mem_write and mem_dump for device $dev_name:" + mem_ori=$(cat $TPMI_DEBUGFS_PATH/tpmi-"$dev_name"/tpmi-id-02/mem_dump | grep "00000020" | head -1 | awk '{print $2}') + test_print_trc "The tpmi-id-02 feature instance 0 mem original value at 0x0020 is: $mem_ori" + test_print_trc "Will write 0x1234 to tpmi-id-02 UFS feature instance 0 with mem address 0x0020" + do_cmd "echo 0,0x20,0x1234 > $TPMI_DEBUGFS_PATH/tpmi-$dev_name/tpmi-id-02/mem_write" + + test_print_trc "Confirm if mem_write successful:" + mem_aft=$(cat $TPMI_DEBUGFS_PATH/tpmi-"$dev_name"/tpmi-id-02/mem_dump | grep "00000020" | head -1 | awk '{print $2}') + test_print_trc "The tpmi-id-02 UFS feature mem value after writing 0x1234 at 0x0020 is: $mem_aft" + if [[ "$mem_aft" == 00001234 ]]; then + test_print_trc "mem_write is successful." + else + die "mem_dump is not expected after mem_write: $mem_aft" + fi + + test_print_trc "Recover mem_dump to the original value:" + do_cmd "echo 0,0x20,0x$mem_ori > $TPMI_DEBUGFS_PATH/tpmi-$dev_name/tpmi-id-02/mem_write" + + fi + done +} + +dmesg_check() { + local dmesg_log + + dmesg_log=$(extract_case_dmesg) + + if echo "$dmesg_log" | grep -iE "fail|Call Trace|error"; then + die "Kernel dmesg shows failure: $dmesg_log" + else + test_print_trc "Kernel dmesg shows Okay." + fi + should_fail "extract_case_dmesg | grep Unsupported" +} + +intel_tpmi_test() { + case $TEST_SCENARIO in + tpmi_remove_all_drivers) + unload_module intel_rapl_tpmi + unload_module isst_tpmi + unload_module isst_tpmi_core + unload_module isst_if_mmio + unload_module intel_uncore_frequency_tpmi + unload_module intel_vsec_tpmi + unload_module intel_vsec + load_module intel_vsec + load_module intel_vsec_tpmi + load_module intel_rapl_tpmi + load_module isst_if_mmio + load_module isst_tpmi_core + load_module isst_tpmi + load_module intel_uncore_frequency_tpmi + ;; + tpmi_sysfs) + tpmi_driver_interface + ;; + tpmi_debugfs) + tpmi_debugfs_interface + ;; + pm_feature_list) + dump_pfs_pm_feature_list + ;; + dump_pfs_locked_disabled_status) + dump_pfs_lock_disable_status + ;; + mem_value_00) + tpmi_id_mem_value_read 00 + ;; + mem_value_01) + tpmi_id_mem_value_read 01 + ;; + mem_value_02) + tpmi_id_mem_value_read 02 + ;; + mem_value_03) + tpmi_id_mem_value_read 03 + ;; + mem_value_04) + tpmi_id_mem_value_read 04 + ;; + mem_value_05) + tpmi_id_mem_value_read 05 + ;; + mem_value_0a) + tpmi_id_mem_value_read 0a + ;; + mem_value_06) + tpmi_id_mem_value_read 06 + ;; + mem_value_0c) + tpmi_id_mem_value_read 0c + ;; + mem_value_0d) + tpmi_id_mem_value_read 0d + ;; + mem_value_80) + tpmi_id_mem_value_read 80 + ;; + mem_value_81) + tpmi_id_mem_value_read 81 + ;; + mem_value_fd) + tpmi_id_mem_value_read fd + ;; + mem_value_fe) + tpmi_id_mem_value_read fe + ;; + mem_value_ff) + tpmi_id_mem_value_read ff + ;; + mem_write_read) + mem_write_read + ;; + esac + dmesg_check + return 0 +} + +while getopts :t:H arg; do + case $arg in + t) + TEST_SCENARIO=$OPTARG + ;; + H) + usage && exit 0 + ;; + \?) + usage + die "Invalid Option -$OPTARG" + ;; + :) + usage + die "Option -$OPTARG requires an argument." + ;; + esac +done + +intel_tpmi_test diff --git a/tests/platform/intel/tpmi/tests b/tests/platform/intel/tpmi/tests new file mode 100755 index 0000000000000000000000000000000000000000..323bf8cda1072f6a73d84c8d20f909d6f865601a --- /dev/null +++ b/tests/platform/intel/tpmi/tests @@ -0,0 +1,43 @@ +# This file collects the test cases which can run against intel_tpmi driver +# on Intel® Architecture-based server platforms. +# @hw_dep: general_test.sh -t fms -p "tpmi_fms_list" @ CPU Model doesn't support tpmi +# @other_dep: general_test.sh -t kconfig -k "CONFIG_INTEL_TPMI=m" +# @other_warn: +# Encoding of TPMI_ID(hex): +# 0x0: RAPL - Socket RAPL, DRAM RAPL, Platform RAPL, etc. +# 0x1: PEM - Power and Performance Excursion Monitors +# 0x2: UFS - Uncore Frequency Scaling +# 0x3: PMAX, +# 0x4: DRC +# 0x5: SST - Intel Speed Select Technology +# 0x6: MISC_CTRL - Misc control and status registers - package root instance +# 0xA: FHM - FIVR Health Monitor +# 0xC: PLR - Perf Limit Reason +# 0xD: BMC_CTL - BMC to Primecode mailbox interface +# 0x80: TPMI Control Interface +# 0x81: TPMI Info Registers +# 0xFD: CSR on all punits +# 0xFE: CSR on compute punit(s) +# 0xFF: CSR on package root punit + +intel_tpmi.sh -t tpmi_remove_all_drivers +intel_tpmi.sh -t tpmi_sysfs +intel_tpmi.sh -t tpmi_debugfs +intel_tpmi.sh -t pm_feature_list +intel_tpmi.sh -t dump_pfs_locked_disabled_status +intel_tpmi.sh -t mem_value_00 +intel_tpmi.sh -t mem_value_01 +intel_tpmi.sh -t mem_value_02 +intel_tpmi.sh -t mem_value_03 +intel_tpmi.sh -t mem_value_04 +intel_tpmi.sh -t mem_value_05 +intel_tpmi.sh -t mem_value_06 +intel_tpmi.sh -t mem_value_0a +intel_tpmi.sh -t mem_value_0c +intel_tpmi.sh -t mem_value_0d +intel_tpmi.sh -t mem_value_80 +intel_tpmi.sh -t mem_value_81 +intel_tpmi.sh -t mem_value_fd +intel_tpmi.sh -t mem_value_fe +intel_tpmi.sh -t mem_value_ff +intel_tpmi.sh -t mem_write_read diff --git a/tests/platform/intel/tpmi/tpmi_fms_list b/tests/platform/intel/tpmi/tpmi_fms_list new file mode 100755 index 0000000000000000000000000000000000000000..d4ca301c10de364219c70a834b232e8b8195d64d --- /dev/null +++ b/tests/platform/intel/tpmi/tpmi_fms_list @@ -0,0 +1,3 @@ +# Family 06 CPUs from arch/x86/include/asm/intel-family.h +# GNR_X GNR_D SRF +06:ad ae af diff --git a/tests/system_base/at/tc_at_command_func001.py b/tests/system_base/at/tc_at_command_func001.py new file mode 100644 index 0000000000000000000000000000000000000000..3a89b1dc45ed862945beb2d1f1cedca7e23ec55a --- /dev/null +++ b/tests/system_base/at/tc_at_command_func001.py @@ -0,0 +1,37 @@ +#! /usr/bin/env python3 +# -*- encoding: utf-8 -*- +""" +@File: tc_at_command_func001.py +@Time: 2024/05/14 14:46:26 +@Author: douzhichong +@Version: 1.0 +@Contact: douzhichong@inspur.com +@License: Mulan PSL v2 +@Modify: douzhichong +""" + +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_at_command_func001.yaml for details + + :avocado: tags=P1,noarch,local + """ + PARAM_DIC = {"pkg_name": "at"} + def setUp(self): + super().setUp(self.PARAM_DIC) + + def test(self): + self.cmd('at 15:30 -f /usr/bin/ls') + self.cmd('atq |grep "15:30"') + self.cmd('echo "hello world" | at 14:30 -m') + self.cmd('atq | grep "14:30"') + self.cmd('echo "hello world" | at -q b 15:31') + self.cmd('atq | grep "15:31" | grep b') + self.cmd('at -V') + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + diff --git a/tests/system_base/attr/tc_attr_ea_fun003.py b/tests/system_base/attr/tc_attr_ea_fun003.py new file mode 100644 index 0000000000000000000000000000000000000000..86792ad01e309d479739e72d68956787b33efcfe --- /dev/null +++ b/tests/system_base/attr/tc_attr_ea_fun003.py @@ -0,0 +1,47 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_attr_ea_fun003.py +@Time: 2024/03/18 10:12:50 +@Author: qintingting +@Version: 1.0 +@Contact: wb-qtt862918@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: qintingting +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_attr_ea_fun003.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "attr"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.file = 'attr_testfile' + self.attribute = 'user.comment' + self.value = 'Test comment' + cmdline=f'''cat > {self.file} < {self.file} < {self.file}") + self.cmd(f"ln -s {self.file} {self.linkfile}") + + def test(self): + self.log.info("Start set extended properties:") + self.cmd(f"attr -L -s {self.attribute} -V '{self.value}' {self.linkfile}") + self.log.info("Start query extended properties:") + code, link_result = self.cmd(f"attr -Lg {self.attribute} {self.linkfile}") + self.assertIn(f'{self.value}', link_result) + code, attr_result = self.cmd(f"attr -Lg {self.attribute} {self.file}") + self.assertIn(f'{self.value}', attr_result) + code, link_result = self.cmd(f"attr -lLq {self.linkfile}") + self.assertIn(f'{self.attribute}', link_result) + code, attr_result = self.cmd(f"attr -lLq {self.file}") + self.assertEqual(attr_result, link_result) + self.log.info("Start cleaning up extended properties:") + self.cmd(f"attr -L -r {self.attribute} {self.linkfile}") + code, link_result = self.cmd(f"attr -lLq {self.linkfile}") + self.assertNotIn(f'{self.attribute}', link_result) + code, link_result = self.cmd(f"attr -lLq {self.file}") + self.assertNotIn(f'{self.attribute}', link_result) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd(f"rm -rf {self.file} {self.linkfile}") \ No newline at end of file diff --git a/tests/system_base/attr/tc_attr_ea_fun006.py b/tests/system_base/attr/tc_attr_ea_fun006.py new file mode 100644 index 0000000000000000000000000000000000000000..3060e3c1113e8cb32d38ee688eae3570e8ebde70 --- /dev/null +++ b/tests/system_base/attr/tc_attr_ea_fun006.py @@ -0,0 +1,41 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_attr_ea_fun006.py +@Time: 2024/03/18 10:12:50 +@Author: qintingting +@Version: 1.0 +@Contact: wb-qtt862918@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: qintingting +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_attr_ea_fun006.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "attr"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.file = 'attr_testfile' + self.attribute = 'security.my_attribute' + self.value = 'my_policy' + self.cmd(f"echo 'hello' > {self.file}") + + def test(self): + self.cmd(f"attr -RS -s {self.attribute} -V '{self.value}' {self.file}") + code, attr_result = self.cmd(f"attr -RS -g {self.attribute} {self.file}") + self.assertIn(f'{self.value}', attr_result) + code, attr_result = self.cmd(f"attr -lRq {self.file}") + self.assertIn(f'{self.attribute}', attr_result) + self.cmd(f"attr -RS -r {self.attribute} {self.file}") + code, attr_result = self.cmd(f"attr -lRq {self.file}") + self.assertNotIn(f'{self.attribute}', attr_result) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd(f"rm -rf {self.file}") \ No newline at end of file diff --git a/tests/system_base/bash-completion/tc_bash_completion_func_001.py b/tests/system_base/bash-completion/tc_bash_completion_func_001.py index e724a4aa87a6118d657df0eb415fbd07ac4e075c..a0cba941bdb7bbf1367d4ab60e6b9208034fb5bf 100644 --- a/tests/system_base/bash-completion/tc_bash_completion_func_001.py +++ b/tests/system_base/bash-completion/tc_bash_completion_func_001.py @@ -2,7 +2,7 @@ """ @File: tc_bash_completion_func_001.py -@Time: 20224/02/28 14:33:20 +@Time: 2024/02/28 14:33:20 @Author: chenchunhu @Version: 1.0 @Contact: wb-cch358909@alibaba-inc.com @@ -17,7 +17,7 @@ class Test(LocalTest): """ See tc_bash_completion_func_001.yaml for details - :avocado: tags=P1,noarch,local + :avocado: tags=P1,noarch,local,fix """ PARAM_DIC = {"pkg_name": "bash-completion"} diff --git a/tests/system_base/bash-completion/tc_bash_completion_func_002.py b/tests/system_base/bash-completion/tc_bash_completion_func_002.py index c9eb068280ce6691b8d60aa4c8f1f9a350da526f..7d51dd6b5c91bdac2928bc1029ea7d1ece040b1e 100644 --- a/tests/system_base/bash-completion/tc_bash_completion_func_002.py +++ b/tests/system_base/bash-completion/tc_bash_completion_func_002.py @@ -2,7 +2,7 @@ """ @File: tc_bash_completion_func_002.py -@Time: 20224/02/28 14:33:20 +@Time: 2024/02/28 14:33:20 @Author: chenchunhu @Version: 1.0 @Contact: wb-cch358909@alibaba-inc.com @@ -17,7 +17,7 @@ class Test(LocalTest): """ See tc_bash_completion_func_002.yaml for details - :avocado: tags=P1,noarch,local + :avocado: tags=P1,noarch,local,fix """ PARAM_DIC = {"pkg_name": "bash-completion"} diff --git a/tests/system_base/bash-completion/tc_bash_completion_func_003.py b/tests/system_base/bash-completion/tc_bash_completion_func_003.py index aac4742a249047b56562a008a68903684528e8ac..aab8f65903c15925fcf55d6104fc47526ce92b3b 100644 --- a/tests/system_base/bash-completion/tc_bash_completion_func_003.py +++ b/tests/system_base/bash-completion/tc_bash_completion_func_003.py @@ -2,7 +2,7 @@ """ @File: tc_bash_completion_func_003.py -@Time: 20224/02/28 14:33:20 +@Time: 2024/02/28 14:33:20 @Author: chenchunhu @Version: 1.0 @Contact: wb-cch358909@alibaba-inc.com @@ -17,7 +17,7 @@ class Test(LocalTest): """ See tc_bash_completion_func_003.yaml for details - :avocado: tags=P1,noarch,local + :avocado: tags=P1,noarch,local,fix """ PARAM_DIC = {"pkg_name": "bash-completion"} diff --git a/tests/system_base/bash-completion/tc_bash_completion_func_004.py b/tests/system_base/bash-completion/tc_bash_completion_func_004.py index ed8cd9af467efa46218d78554c97db770a65f133..6c2ef61ee5a1ff3280ac54727accb76c1d0ab76c 100644 --- a/tests/system_base/bash-completion/tc_bash_completion_func_004.py +++ b/tests/system_base/bash-completion/tc_bash_completion_func_004.py @@ -2,7 +2,7 @@ """ @File: tc_bash_completion_func_004.py -@Time: 20224/02/28 14:33:20 +@Time: 2024/02/28 14:33:20 @Author: chenchunhu @Version: 1.0 @Contact: wb-cch358909@alibaba-inc.com @@ -17,7 +17,7 @@ class Test(LocalTest): """ See tc_bash_completion_func_004.yaml for details - :avocado: tags=P1,noarch,local + :avocado: tags=P1,noarch,local,fix """ PARAM_DIC = {"pkg_name": "bash-completion"} diff --git a/tests/system_base/bash-completion/tc_bash_completion_func_005.py b/tests/system_base/bash-completion/tc_bash_completion_func_005.py index 9edc19130cf367a793a72698bab38c6046976a0c..d1133d1e2bb79eb198475ef4012ac46bb8569d06 100644 --- a/tests/system_base/bash-completion/tc_bash_completion_func_005.py +++ b/tests/system_base/bash-completion/tc_bash_completion_func_005.py @@ -2,7 +2,7 @@ """ @File: tc_bash_completion_func_005.py -@Time: 20224/02/28 14:33:20 +@Time: 2024/02/28 14:33:20 @Author: chenchunhu @Version: 1.0 @Contact: wb-cch358909@alibaba-inc.com @@ -17,7 +17,7 @@ class Test(LocalTest): """ See tc_bash_completion_func_005.yaml for details - :avocado: tags=P1,noarch,local + :avocado: tags=P1,noarch,local,fix """ PARAM_DIC = {"pkg_name": "bash-completion git"} diff --git a/tests/system_base/bash-completion/tc_bash_completion_func_006.py b/tests/system_base/bash-completion/tc_bash_completion_func_006.py index 66cdd663f7efd6c5b0c249c7e2126c7001d875da..6265094d7f5b71c7ae6afacba0d42a6553abffe9 100644 --- a/tests/system_base/bash-completion/tc_bash_completion_func_006.py +++ b/tests/system_base/bash-completion/tc_bash_completion_func_006.py @@ -2,7 +2,7 @@ """ @File: tc_bash_completion_func_006.py -@Time: 20224/02/28 14:33:20 +@Time: 2024/02/28 14:33:20 @Author: chenchunhu @Version: 1.0 @Contact: wb-cch358909@alibaba-inc.com @@ -17,7 +17,7 @@ class Test(LocalTest): """ See tc_bash_completion_func_006.yaml for details - :avocado: tags=P1,noarch,local + :avocado: tags=P1,noarch,local,fix """ PARAM_DIC = {"pkg_name": "bash-completion git"} diff --git a/tests/system_base/bash-completion/tc_bash_completion_func_007.py b/tests/system_base/bash-completion/tc_bash_completion_func_007.py index 7b802e880a3ab0b452198093f71c9c223e90e02e..69fced196a4c953a903aebddc0868ee342a57c61 100644 --- a/tests/system_base/bash-completion/tc_bash_completion_func_007.py +++ b/tests/system_base/bash-completion/tc_bash_completion_func_007.py @@ -2,7 +2,7 @@ """ @File: tc_bash_completion_func_007.py -@Time: 20224/02/28 14:33:20 +@Time: 2024/02/28 14:33:20 @Author: chenchunhu @Version: 1.0 @Contact: wb-cch358909@alibaba-inc.com @@ -17,7 +17,7 @@ class Test(LocalTest): """ See tc_bash_completion_func_007.yaml for details - :avocado: tags=P1,noarch,local + :avocado: tags=P1,noarch,local,fix """ PARAM_DIC = {"pkg_name": "bash-completion"} diff --git a/tests/system_base/binutils/tc_binutils_command_addr2line.py b/tests/system_base/binutils/tc_binutils_command_addr2line.py new file mode 100644 index 0000000000000000000000000000000000000000..b6add00e2515d74a354d4aebc42cb01814eb1755 --- /dev/null +++ b/tests/system_base/binutils/tc_binutils_command_addr2line.py @@ -0,0 +1,52 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_binutils_func_addr2line.py +@Time: 2024/04/18 14:21:20 +@Author: douzhichong +@Version: 1.0 +@Contact: douzhichong@inspur.com +@License: Mulan PSL v2 +@Modify: douzhichong +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_binutils_func_addr2line.yaml for details + + :avocado: tags=P1,noarch,local,binutils + """ + PARAM_DIC = {"pkg_name": "binutils gcc gcc-c++"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.str = """#include +int divide(int x, int y) +{ +return x/y; +} +int main() +{ +printf("hello world"); +int x = 3; +int y = 0; +int div = divide(x, y); +printf("%d / %d = %d", x, y, div); +return 0; +} +""" + with open("/tmp/test.cpp",mode="wt",encoding="utf-8")as f: + f.write(self.str) + def test(self): + self.cmd("addr2line -v|grep addr2line") + self.cmd("g++ -Wl,-Map=/tmp/test.map -g /tmp/test.cpp -o /tmp/testfile") + self.cmd('ls /tmp | grep -E "testfile|test.map"') + code,address = self.cmd("grep divide /tmp/test.map |awk '{print $1}'") + self.cmd(f"addr2line {address} -e /tmp/testfile -f -C -s |grep cpp") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -f /tmp/test.cpp") + self.cmd("rm -f /tmp/test.map") + self.cmd("rm -f /tmp/testfile") diff --git a/tests/system_base/binutils/tc_binutils_command_ar.py b/tests/system_base/binutils/tc_binutils_command_ar.py new file mode 100644 index 0000000000000000000000000000000000000000..1bc3c214599afc74f61b0eb6a0e197eec1d0ba5c --- /dev/null +++ b/tests/system_base/binutils/tc_binutils_command_ar.py @@ -0,0 +1,39 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_binutils_command_ar.py +@Time: 2024/04/18 15:06:12 +@Author: douzhichong +@Version: 1.0 +@Contact: douzhichong@inspur.com +@License: Mulan PSL v2 +@Modify: douzhichong +""" +import logging + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_binutils_command_ar.yaml for details + + :avocado: tags=P1,noarch,local,binutils + """ + PARAM_DIC = {"pkg_name": "binutils gcc"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("touch file1.c file2.c file3.c") + + def test(self): + self.cmd("gcc -Wall -c file1.c file2.c file3.c") + self.cmd('ls | grep -E "file[1-3]{1}.o" >test-binutils.txt') + _,result = self.cmd('cat test-binutils.txt') + self.cmd("ar rv libNAME.a file1.o file2.o file3.o") + + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf file* libNAME.a") + self.cmd("rm -rf test-binutils.txt") + diff --git a/tests/system_base/binutils/tc_binutils_command_nm.py b/tests/system_base/binutils/tc_binutils_command_nm.py new file mode 100644 index 0000000000000000000000000000000000000000..53bdc8dd354e5bd6ec71dfe2f1a8112c504a8061 --- /dev/null +++ b/tests/system_base/binutils/tc_binutils_command_nm.py @@ -0,0 +1,61 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_binutils_command_nm.py +@Time: 2024/04/18 15:25:31 +@Author: douzhichong +@Version: 1.0 +@Contact: douzhichong@inspur.com +@License: Mulan PSL v2 +@Modify: douzhichong +""" +import logging + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_binutils_command_nm.yaml for details + + :avocado: tags=P1,noarch,local,binutils + """ + PARAM_DIC = {"pkg_name": "binutils gcc"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/test") + main_str = '''int main(int argc,char *argv[]) +{ +hello(); +bye(); +return 0; +}''' + hello_str = """void hello(void) +{ +printf("hello!"); +} +""" + bye_str = '''void bye(void) +{ +printf("good bye!"); +} +''' + with open("/tmp/test/main.c",mode="wt",encoding="utf-8")as f: + f.write(main_str) + with open("/tmp/test/hello.c", mode="wt", encoding="utf-8") as f: + f.write(hello_str) + with open("/tmp/test/bye.c", mode="wt", encoding="utf-8") as f: + f.write(bye_str) + + def test(self): + self.cmd("cd /tmp/test/ && gcc -Wall -c main.c hello.c bye.c") + self.cmd("ls -al /tmp/test | grep 'main.o\|hello.o\|bye.o'") + self.cmd('cd /tmp/test && nm main.o hello.o bye.o > nm.txt') + self.cmd("test -f nm.txt") + self.cmd('grep -E "T main|T hello|T bye" /tmp/test/nm.txt') + + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/test") + diff --git a/tests/system_base/binutils/tc_binutils_command_objcopy.py b/tests/system_base/binutils/tc_binutils_command_objcopy.py new file mode 100644 index 0000000000000000000000000000000000000000..300ed839ad28549bd8759b16dd488d26e6cf6593 --- /dev/null +++ b/tests/system_base/binutils/tc_binutils_command_objcopy.py @@ -0,0 +1,56 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_binutils_command_objcopy.py +@Time: 2024/04/18 16:04:14 +@Author: douzhichong +@Version: 1.0 +@Contact: douzhichong@inspur.com +@License: Mulan PSL v2 +@Modify: douzhichong +""" +import logging + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_binutils_command_objcopy.yaml for details + + :avocado: tags=P1,noarch,local,binutils + """ + PARAM_DIC = {"pkg_name": "binutils gcc gcc-c++"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + + self.cmd("mkdir /tmp/test") + test_str = '''#include +int divide(int x, int y) +{ +return x/y; +} +int main() +{ +printf("hello world"); +int x = 3; +int y = 0; +int div = divide(x, y); +printf("%d / %d = %d", x, y, div); +return 0; +} + +''' + with open("/tmp/test/test.cpp",mode="wt",encoding="utf-8")as f: + f.write(test_str) + + def test(self): + self.cmd("g++ -Wl,-Map=/tmp/test/test.map -g /tmp/test/test.cpp -o /tmp/test/testfile") + self.cmd('ls /tmp/test | grep -E "testfile|test.map"') + self.cmd('objcopy -O srec /tmp/test/testfile /tmp/test/test.srec') + self.cmd('head /tmp/test/test.srec | grep "S"') + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/test") + diff --git a/tests/system_base/binutils/tc_binutils_command_objdump.py b/tests/system_base/binutils/tc_binutils_command_objdump.py new file mode 100644 index 0000000000000000000000000000000000000000..f44f4251fd3c3dac20633e2598ed3c07c03583c4 --- /dev/null +++ b/tests/system_base/binutils/tc_binutils_command_objdump.py @@ -0,0 +1,61 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_binutils_command_objdump.py +@Time: 2024/04/18 16:52:46 +@Author: douzhichong +@Version: 1.0 +@Contact: douzhichong@inspur.com +@License: Mulan PSL v2 +@Modify: douzhichong +""" +import logging + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_binutils_command_objdump.yaml for details + + :avocado: tags=P1,noarch,local,binutils + """ + PARAM_DIC = {"pkg_name": "binutils gcc"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/test") + main_str = '''int main(int argc,char *argv[]) +{ +hello(); +bye(); +return 0; +}''' + hello_str = """void hello(void) +{ +printf("hello!"); +} +""" + bye_str = '''void bye(void) +{ +printf("good bye!"); +} +''' + with open("/tmp/test/main.c",mode="wt",encoding="utf-8")as f: + f.write(main_str) + with open("/tmp/test/hello.c", mode="wt", encoding="utf-8") as f: + f.write(hello_str) + with open("/tmp/test/bye.c", mode="wt", encoding="utf-8") as f: + f.write(bye_str) + + def test(self): + self.cmd("cd /tmp/test/ && gcc -Wall -c main.c hello.c bye.c") + self.cmd("ls -al /tmp/test | grep 'main.o\|hello.o\|bye.o'") + self.cmd('cd /tmp/test && nm main.o hello.o bye.o > nm.txt') + self.cmd("cd /tmp/test && test -f nm.txt") + self.cmd("cd /tmp/test && objdump -d hello.o") + + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/test") + diff --git a/tests/system_base/binutils/tc_binutils_command_readelf.py b/tests/system_base/binutils/tc_binutils_command_readelf.py new file mode 100644 index 0000000000000000000000000000000000000000..c1d57da6520e92ac5e87aa64a4c8025ee4746825 --- /dev/null +++ b/tests/system_base/binutils/tc_binutils_command_readelf.py @@ -0,0 +1,59 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_binutils_command_readelf.py +@Time: 2024/04/18 16:52:46 +@Author: douzhichong +@Version: 1.0 +@Contact: douzhichong@inspur.com +@License: Mulan PSL v2 +@Modify: douzhichong +""" +import logging + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_binutils_command_readelf.yaml for details + + :avocado: tags=P1,noarch,local,binutils + """ + PARAM_DIC = {"pkg_name": "binutils gcc"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/test") + main_str = '''int main(int argc,char *argv[]) +{ +hello(); +bye(); +return 0; +}''' + hello_str = """void hello(void) +{ +printf("hello!"); +} +""" + bye_str = '''void bye(void) +{ +printf("good bye!"); +} +''' + with open("/tmp/test/main.c",mode="wt",encoding="utf-8")as f: + f.write(main_str) + with open("/tmp/test/hello.c", mode="wt", encoding="utf-8") as f: + f.write(hello_str) + with open("/tmp/test/bye.c", mode="wt", encoding="utf-8") as f: + f.write(bye_str) + + def test(self): + self.cmd("cd /tmp/test/ && gcc -Wall -c main.c hello.c bye.c") + self.cmd("ls -al /tmp/test | grep 'main.o\|hello.o\|bye.o'") + for file in "main.o hello.o bye.o".split(): + self.cmd(f"cd /tmp/test && readelf -h {file} | grep 'ELF64'") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/test") + diff --git a/tests/system_base/binutils/tc_binutils_command_size.py b/tests/system_base/binutils/tc_binutils_command_size.py new file mode 100644 index 0000000000000000000000000000000000000000..fbbada60bca607747951d8bb9d5b06ae70ac7b5e --- /dev/null +++ b/tests/system_base/binutils/tc_binutils_command_size.py @@ -0,0 +1,53 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_binutils_command_size.py +@Time: 2024/04/18 16:52:46 +@Author: douzhichong +@Version: 1.0 +@Contact: douzhichong@inspur.com +@License: Mulan PSL v2 +@Modify: douzhichong +""" +import logging + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_binutils_command_size.yaml for details + + :avocado: tags=P1,noarch,local,binutils + """ + PARAM_DIC = {"pkg_name": "binutils gcc gcc-c++"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/test") + test_str = '''#include +int divide(int x, int y) +{ +return x/y; +} +int main() +{ +printf("hello world"); +int x = 3; +int y = 0; +int div = divide(x, y); +printf("%d / %d = %d", x, y, div); +return 0; +} +''' + with open("/tmp/test/test.cpp",mode="wt",encoding="utf-8")as f: + f.write(test_str) + + def test(self): + self.cmd("cd /tmp/test && g++ -Wl,-Map=test.map -g test.cpp -o testfile") + self.cmd('ls -al /tmp/test | grep -E "testfile|test.map"') + self.cmd(f'size /tmp/test/testfile |grep -E "hex|testfile" |grep "testfile"') + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/test") + diff --git a/tests/system_base/binutils/tc_binutils_command_strip.py b/tests/system_base/binutils/tc_binutils_command_strip.py new file mode 100644 index 0000000000000000000000000000000000000000..4e34410e585d992eb389d95327e5a1f16168a6f2 --- /dev/null +++ b/tests/system_base/binutils/tc_binutils_command_strip.py @@ -0,0 +1,53 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_binutils_command_strip.py +@Time: 2024/04/19 10:12:46 +@Author: douzhichong +@Version: 1.0 +@Contact: douzhichong@inspur.com +@License: Mulan PSL v2 +@Modify: douzhichong +""" +import logging + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_binutils_command_strip.yaml for details + + :avocado: tags=P1,noarch,local,binutils + """ + PARAM_DIC = {"pkg_name": "binutils gcc gcc-c++"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/test") + test_str = '''#include +int divide(int x, int y) +{ +return x/y; +} +int main() +{ +printf("hello world"); +int x = 3; +int y = 0; +int div = divide(x, y); +printf("%d / %d = %d", x, y, div); +return 0; +} +''' + with open("/tmp/test/test.cpp",mode="wt",encoding="utf-8")as f: + f.write(test_str) + + def test(self): + self.cmd("cd /tmp/test && g++ -Wl,-Map=test.map -g test.cpp -o testfile") + self.cmd('ls -al /tmp/test | grep -E "testfile|test.map"') + self.cmd('strip /tmp/test/testfile') + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/test") + diff --git a/tests/system_base/checkpolicy/tc_checkpolicy_checkpolicy_func_002.py b/tests/system_base/checkpolicy/tc_checkpolicy_checkpolicy_func_002.py new file mode 100644 index 0000000000000000000000000000000000000000..d760a1143c298b3274c46c49fb00c31c3548fef6 --- /dev/null +++ b/tests/system_base/checkpolicy/tc_checkpolicy_checkpolicy_func_002.py @@ -0,0 +1,52 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_checkpolicy_checkpolicy_func_002.py +@Time: 2024/03/01 14:33:20 +@Author: chenchunhu +@Version: 1.0 +@Contact: wb-cch358909@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: chenchunhu +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_checkpolicy_checkpolicy_func_002.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "selinux-policy-devel checkpolicy"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = """cat > test_module.te < test_module.te < /tmp/ghm/test_jansson.c < +#include + +void test_jansson() { + // 创建 JSON 对象 + json_t *root = json_object(); + + // 向 JSON 对象添加键值对 + json_object_set_new(root, "name", json_string("John Doe")); + json_object_set_new(root, "age", json_integer(30)); + json_object_set_new(root, "skills", json_array()); + + // 向数组添加元素 + json_t *skills = json_object_get(root, "skills"); + json_array_append_new(skills, json_string("C programming")); + json_array_append_new(skills, json_string("Networking")); + + // 序列化为 JSON 字符串 + char *serialized_json = json_dumps(root, JSON_INDENT(4)); + + // 输出 JSON 字符串到控制台 + printf("Serialized JSON: %s\\n", serialized_json); + + // 解析 JSON 字符串 + json_error_t error; + json_t *parsed_root = json_loads(serialized_json, 0, &error); + + // 检查解析是否成功,并访问数据 + if(parsed_root) { + json_t *name = json_object_get(parsed_root, "name"); + const char *name_str = json_string_value(name); + printf("Name: %s\\n", name_str); + + json_t *age = json_object_get(parsed_root, "age"); + int age_int = json_integer_value(age); + printf("Age: %d\\n", age_int); + + json_t *skills_list = json_object_get(parsed_root, "skills"); + if(json_is_array(skills_list)) { + size_t i, count = json_array_size(skills_list); + for(i = 0; i < count; i++) { + json_t *skill = json_array_get(skills_list, i); + const char *skill_str = json_string_value(skill); + printf("Skill %lu: %s\\n", i + 1, skill_str); + } + } + + // 清理内存 + json_decref(parsed_root); + } else { + printf("Error while parsing JSON: %s at line %d column %d\\n", + error.text, error.line, error.column); + } + + // 清理创建的 JSON 对象 + json_decref(root); + free(serialized_json); +} + +int main() { + test_jansson(); + return 0; +} +""" + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o /tmp/ghm/test_jansson /tmp/ghm/test_jansson.c -ljansson") + ret_c1, ret_o1 = self.cmd("/tmp/ghm/test_jansson") + self.assertIn("Serialized JSON", ret_o1) + self.assertIn("Name: John Doe", ret_o1) + self.assertIn("Age: 30", ret_o1) + self.assertIn("Skill 1: C programming", ret_o1) + self.assertIn("Skill 2: Networking", ret_o1) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") \ No newline at end of file diff --git a/tests/system_base/jansson/tc_jansson_func002.py b/tests/system_base/jansson/tc_jansson_func002.py new file mode 100644 index 0000000000000000000000000000000000000000..cfc29abe2b605a0f76ed177d3e3a4d719c293750 --- /dev/null +++ b/tests/system_base/jansson/tc_jansson_func002.py @@ -0,0 +1,85 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_jansson_func002.py +@Time: 2024/04/02 10:00:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_jansson_func002.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "jansson jansson-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline = """cat > /tmp/ghm/test_jansson.c < +#include + +// 创建并修改嵌套JSON对象和数组 +void create_and_modify_json() { + json_t *root = json_object(); + json_t *array = json_array(); + + // 添加一些数组元素 + json_array_append_new(array, json_string("item1")); + json_array_append_new(array, json_integer(2)); + json_array_append_new(array, json_true()); + + // 将数组添加到根对象中 + json_object_set_new(root, "nestedArray", array); + + // 创建嵌套的对象 + json_t *nested_obj = json_object(); + json_object_set_new(nested_obj, "key1", json_string("value1")); + json_object_set_new(nested_obj, "key2", json_integer(3)); + + // 将嵌套对象添加到根对象中 + json_object_set_new(root, "nestedObject", nested_obj); + + // 序列化为 JSON 字符串并输出 + char *serialized_json = json_dumps(root, JSON_INDENT(4)); + printf("Serialized JSON: %s\\n", serialized_json); + + // 修改数组和嵌套对象 + json_array_insert_new(array, 1, json_string("Inserted Item")); // 在数组索引1的位置插入新元素 + json_object_set_new(nested_obj, "key1", json_string("Modified Value")); // 修改嵌套对象的key1的值 + + // 输出修改后的JSON字符串 + const char *json_str = json_dumps(root, JSON_INDENT(4)); + printf("%s\\n", json_str); + + // 释放内存 + json_decref(root); + json_decref(nested_obj); +} + +int main() { + create_and_modify_json(); + return 0; +} +""" + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o /tmp/ghm/test_jansson /tmp/ghm/test_jansson.c -ljansson") + ret_c1, ret_o1 = self.cmd("/tmp/ghm/test_jansson") + self.log.info(ret_o1) + self.assertIn("value1", ret_o1) + self.assertIn("Inserted Item", ret_o1) + self.assertIn("Modified Value", ret_o1) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") \ No newline at end of file diff --git a/tests/system_base/jansson/tc_jansson_func003.py b/tests/system_base/jansson/tc_jansson_func003.py new file mode 100644 index 0000000000000000000000000000000000000000..8b9fa9913a81d6805493d21e2a4d9d95a47f3117 --- /dev/null +++ b/tests/system_base/jansson/tc_jansson_func003.py @@ -0,0 +1,85 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_jansson_func003.py +@Time: 2024/04/01 13:12:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" +import subprocess +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_jansson_func003.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "jansson jansson-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline = """cat > /tmp/ghm/test_jansson.c < +#include +#include +#include + +// 用于报告JSON解析错误的特殊版本 +void parse_error_exit(const char *message, int line, const char *text) { + fprintf(stderr, "%s: On line %d: %s\\n", message, line, text); + exit(EXIT_FAILURE); +} + +int main() { + // 解析JSON字符串 + const char *json_text = "{\\"name\\":\\"Alice\\",\\"age\\":25}"; + json_error_t error; + json_t *root = json_loads(json_text, 0, &error); + + // 检查是否成功解析 + if (!root) { + parse_error_exit("Failed to parse JSON", error.line, error.text); + } + + char *serialized_json = json_dumps(root, JSON_INDENT(4)); + // 输出 JSON 字符串到控制台 + printf("Serialized JSON: %s\\n", serialized_json); + free(serialized_json); + + // 访问不存在的键 + json_t *nonexistent_value = json_object_get(root, "nonexistent_key"); + if (!nonexistent_value) { + printf("Key 'nonexistent_key' does not exist.\\n"); + } + json_decref(root); + + // 解析无效的JSON + json_text = "{invalid json}"; + root = json_loads(json_text, 0, &error); + if (!root) { + parse_error_exit("Failed to parse invalid JSON", error.line, error.text); + } + + // 此处应当不会执行,因为上面的json_loads应该已经抛出了错误 + json_decref(root); + + return 0; +} +""" + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o /tmp/ghm/test_jansson /tmp/ghm/test_jansson.c -ljansson") + ret_o1 = subprocess.run("/tmp/ghm/test_jansson", capture_output = True, text = True, shell = True) + self.assertIn("Serialized JSON", ret_o1.stdout) + self.assertIn("Key 'nonexistent_key' does not exist.", ret_o1.stdout) + self.assertIn("Failed to parse invalid JSON: On line 1: string or '}' expected near 'invalid'", ret_o1.stderr) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") \ No newline at end of file diff --git a/tests/system_base/jansson/tc_jansson_func004.py b/tests/system_base/jansson/tc_jansson_func004.py new file mode 100644 index 0000000000000000000000000000000000000000..451fc11b08f2525fd0608b5facb44e49704513c6 --- /dev/null +++ b/tests/system_base/jansson/tc_jansson_func004.py @@ -0,0 +1,116 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_jansson_func004.py +@Time: 2024/04/01 14:12:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_jansson_func004.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "jansson jansson-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline = """cat > /tmp/ghm/test_jansson.c < +#include +#include +#include + +void print_json_value(json_t *value, int indent_level) { + switch (json_typeof(value)) { + case JSON_OBJECT: + const char *key; + json_t *val; + + json_object_foreach(value, key, val) { + for (int i = 0; i < indent_level; ++i) + printf(" "); + + printf("\\"%s\\": ", key); + print_json_value(val, indent_level + 1); + } + break; + + case JSON_ARRAY: + size_t array_size = json_array_size(value); + for (size_t i = 0; i < array_size; ++i) { + json_t *element = json_array_get(value, i); + print_json_value(element, indent_level); + } + break; + + case JSON_STRING: + printf("\\"%s\\"\\n", json_string_value(value)); + break; + + case JSON_INTEGER: + printf("%lld\\n", (long long)json_integer_value(value)); + break; + + case JSON_REAL: + printf("%f\\n", (double)json_real_value(value)); + break; + + case JSON_TRUE: + printf("true\\n"); + break; + + case JSON_FALSE: + printf("false\\n"); + break; + + case JSON_NULL: + printf("null\\n"); + break; + + default: + fprintf(stderr, "Unknown JSON type encountered!\\n"); + break; + } +} + +int main() { + const char *json_text = "{\\"person\\":{\\"name\\":\\"Alice\\",\\"age\\":25},\\"hobbies\\":[\\"Reading\\", \\"Gaming\\"]}"; + json_error_t error; + json_t *root = json_loads(json_text, 0, &error); + + if (!root) { + fprintf(stderr, "Error parsing JSON: %s on line %d\\n", error.text, error.line); + return EXIT_FAILURE; + } + print_json_value(root, 0); + + json_decref(root); + return 0; +} +""" + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o /tmp/ghm/test_jansson /tmp/ghm/test_jansson.c -ljansson") + ret_c1, ret_o1 = self.cmd("/tmp/ghm/test_jansson") + self.assertIn("person", ret_o1) + self.assertIn("name", ret_o1) + self.assertIn("Alice", ret_o1) + self.assertIn("age", ret_o1) + self.assertIn("25", ret_o1) + self.assertIn("hobbies", ret_o1) + self.assertIn("Reading", ret_o1) + self.assertIn("Gaming", ret_o1) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") \ No newline at end of file diff --git a/tests/system_base/less/tc_less_less_fun001.py b/tests/system_base/less/tc_less_less_fun001.py new file mode 100644 index 0000000000000000000000000000000000000000..34ab757dca1e8ae9bd1bf40912f0a1dbe9a18744 --- /dev/null +++ b/tests/system_base/less/tc_less_less_fun001.py @@ -0,0 +1,40 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_less_less_fun001.py +@Time: 2024/04/18 14:21:20 +@Author: douzhichong +@Version: 1.0 +@Contact: douzhichong@inspur.com +@License: Mulan PSL v2 +@Modify: douzhichong +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_less_less_fun001.yaml for details + + :avocado: tags=P1,noarch,local,less + """ + PARAM_DIC = {"pkg_name": "less"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("less /var/log/messages >testlog") + + def test(self): + + code,result=self.cmd("less -N testlog") + self.assertTrue("1 2 3 4 5 6 7 8 9 10",result) + + code,result=self.cmd("command -v less | grep /usr/bin/less") + self.assertIn("/usr/bin/less",result) + + code,result=self.cmd("less --help") + self.assertIn("pattern",result) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf testlog") + diff --git a/tests/system_base/libffi/tc_libffi_libffi_func_003.py b/tests/system_base/libffi/tc_libffi_libffi_func_003.py index ecec31cdc9e36188f096761e252dc2019971de69..ed229b9512e9544e82b18bfae295f4c7cece585d 100644 --- a/tests/system_base/libffi/tc_libffi_libffi_func_003.py +++ b/tests/system_base/libffi/tc_libffi_libffi_func_003.py @@ -20,7 +20,7 @@ class Test(LocalTest): :avocado: tags=P1,noarch,local,fixed """ - PARAM_DIC = {"pkg_name": "libffi libffi-devel"} + PARAM_DIC = {"pkg_name": "libffi libffi-devel valgrind"} def setUp(self): super().setUp(self.PARAM_DIC) self.cmd("rpm -qa |grep 'libffi'") diff --git a/tests/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun001.py b/tests/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun001.py new file mode 100644 index 0000000000000000000000000000000000000000..8b474729b6a3909bc5f6c0f9c7d8f15de1e2d527 --- /dev/null +++ b/tests/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun001.py @@ -0,0 +1,64 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_libsigsegv_libsigsegv_fun001.py +@Time: 2024/3/11 10:18:20 +@Author: wangyaru +@Version: 1.0 +@Contact: wb-wyr940190@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: wangyaru +""" + +import subprocess +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libsigsegv_libsigsegv_fun001.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libsigsegv libsigsegv-devel gcc"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = '''cat >libsigsegv_testfile.c<<"EOF" +#include +#include +#include +#include + +/* 段错误处理函数 */ +static int handle_sigsegv(void *fault_address, int serious) +{ + printf("Segmentation fault at address: %p\\n", fault_address); + exit(2); /* 退出程序,并返回特定的错误码表示段错误 */ + return 0; /* 这行不会被执行,因为前面已经退出了程序 */ +} + +int main(void) +{ + /* 安装 libsigsegv 的段错误处理程序 */ + sigsegv_install_handler(handle_sigsegv); + + /* 故意制造段错误 */ + int *p = NULL; + *p = 42; /* 这里将会触发段错误 */ + + /* 如果处理函数可以正常恢复,这行代码将不会执行 */ + printf("This line will not be executed.\\n"); + + return 0; +} +EOF''' + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o libsigsegv_testfile libsigsegv_testfile.c -lsigsegv") + result = subprocess.run(["./libsigsegv_testfile"], stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.decode() + self.log.info(result) + self.assertIn("Segmentation fault at address:", result) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf libsigsegv_testfile*") \ No newline at end of file diff --git a/tests/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun002.py b/tests/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun002.py new file mode 100644 index 0000000000000000000000000000000000000000..3401e61e77dc0a7ae01c188147e5f088ec2b40e6 --- /dev/null +++ b/tests/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun002.py @@ -0,0 +1,74 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_libsigsegv_libsigsegv_fun002.py +@Time: 2024/3/11 10:18:20 +@Author: wangyaru +@Version: 1.0 +@Contact: wb-wyr940190@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: wangyaru +""" + +import subprocess +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libsigsegv_libsigsegv_fun002.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libsigsegv libsigsegv-devel gcc"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = '''cat >libsigsegv_testfile.c<<"EOF" +#include +#include +#include + +/* 栈溢出处理函数 */ +static int overflow_handler(void *fault_address, int serious) +{ + fprintf(stderr, "Stack overflow detected at address: %p\\n", fault_address); + exit(2); + return 0; +} + +/* 一个递归函数,会导致栈溢出 */ +void cause_stack_overflow(size_t count) +{ + volatile char buffer[1024 * 1024]; // Allocate a buffer on the stack + buffer[0] = count; // Use the buffer to avoid optimization out by the compiler + if (count > 0) { + cause_stack_overflow(count - 1); // Recurse until the stack overflows + } +} + +int main(void) +{ + /* 安装 libsigsegv 的栈溢出处理程序 */ + sigsegv_install_handler(overflow_handler); + + printf("Causing stack overflow...\\n"); + cause_stack_overflow(1000000); // Start the recursion, adjust the count as needed + + /* 如果栈溢出处理程序可以正常恢复,以下行将不会执行 */ + printf("This line should not be executed.\\n"); + + return 0; +} +EOF''' + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o libsigsegv_testfile libsigsegv_testfile.c -lsigsegv") + # libsigsegv 可以处理很多种内存访问错误,但是栈溢出(stack overflow)可能不总是能被它捕获,因为栈溢出通常是由于无限或深度递归导致的,这种情况下可能没有触发页面错误(page fault),而是直接触发了程序的终止 + # https://bugzilla.openanolis.cn/show_bug.cgi?id=8618 + code, result = self.cmd("./libsigsegv_testfile", ignore_status=True) + self.assertTrue(code == -11) + self.assertNotIn("This line should not be executed", result) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf libsigsegv_testfile*") \ No newline at end of file diff --git a/tests/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun003.py b/tests/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun003.py new file mode 100644 index 0000000000000000000000000000000000000000..0d06c92a7cd227b9cbc88070f48b6f6d9a8b60f2 --- /dev/null +++ b/tests/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun003.py @@ -0,0 +1,76 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_libsigsegv_libsigsegv_fun003.py +@Time: 2024/3/11 10:18:20 +@Author: wangyaru +@Version: 1.0 +@Contact: wb-wyr940190@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: wangyaru +""" + +import subprocess +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libsigsegv_libsigsegv_fun003.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libsigsegv libsigsegv-devel gcc"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = '''cat >libsigsegv_testfile.c<<"EOF" +#include +#include +#include +#include + +/* 段错误处理函数 */ +static int segv_handler(void *address, int serious) +{ + printf("Invalid memory access at address: %p\\n", address); + exit(1); + return 0; +} + +int main(void) +{ + /* 安装 libsigsegv 的段错误处理程序 */ + sigsegv_install_handler(segv_handler); + + /* 分配堆内存 */ + int *p = malloc(sizeof(int)); + if (p == NULL) { + perror("Failed to allocate memory"); + return EXIT_FAILURE; + } + + /* 释放堆内存 */ + free(p); + p = NULL; + + /* 尝试访问释放的内存 */ + printf("Attempting to access freed memory...\\n"); + *p = 42; /* 这里将触发段错误 */ + + /* 如果段错误处理程序可以正常恢复,以下行将不会执行 */ + printf("This line should not be executed.\\n"); + + return 0; +} +EOF''' + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o libsigsegv_testfile libsigsegv_testfile.c -lsigsegv") + result = subprocess.run(["./libsigsegv_testfile"], stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.decode() + self.log.info(result) + self.assertIn("Attempting to access freed memory", result) + self.assertIn("Invalid memory access at address", result) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf libsigsegv_testfile*") \ No newline at end of file diff --git a/tests/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun004.py b/tests/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun004.py new file mode 100644 index 0000000000000000000000000000000000000000..f23a46bc1267acbc85bad7da65035b9fab0e67cc --- /dev/null +++ b/tests/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun004.py @@ -0,0 +1,72 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_libsigsegv_libsigsegv_fun004.py +@Time: 2024/3/11 10:18:20 +@Author: wangyaru +@Version: 1.0 +@Contact: wb-wyr940190@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: wangyaru +""" + +import subprocess +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libsigsegv_libsigsegv_fun004.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libsigsegv libsigsegv-devel gcc"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = '''cat >libsigsegv_testfile.c<<"EOF" +#include +#include +#include +#include + +/* 段错误处理函数 */ +void segv_handler(int signum, siginfo_t *info, void *context) { + printf("Caught segmentation fault! Faulty address is %p\\n", info->si_addr); + exit(1); +} + +int main() { + struct sigaction sa; + + sa.sa_sigaction = segv_handler; // 设置段错误处理函数 + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; // 使用信号扩展信息 + + /* 安装信号处理程序 */ + if (sigaction(SIGSEGV, &sa, NULL) == -1) { + perror("Failed to install SIGSEGV signal handler"); + return EXIT_FAILURE; + } + + /* 创建一个数组 */ + int array[10]; + + /* 故意造成数组越界 */ + array[10000] = 42; /* 这一行可能会触发段错误 */ + + /* 如果段错误处理程序可以正常恢复,以下行将不会执行 */ + printf("This line should not be executed.\\n"); + + return 0; +} +EOF''' + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o libsigsegv_testfile libsigsegv_testfile.c -lsigsegv") + result = subprocess.run(["./libsigsegv_testfile"], stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.decode() + self.log.info(result) + self.assertIn("Caught segmentation fault!", result) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf libsigsegv_testfile*") \ No newline at end of file diff --git a/tests/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun005.py b/tests/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun005.py new file mode 100644 index 0000000000000000000000000000000000000000..f92a3bc912d34734bbc982cf329524ea2f13ba55 --- /dev/null +++ b/tests/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun005.py @@ -0,0 +1,86 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_libsigsegv_libsigsegv_fun005.py +@Time: 2024/3/11 10:18:20 +@Author: wangyaru +@Version: 1.0 +@Contact: wb-wyr940190@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: wangyaru +""" + +import subprocess +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libsigsegv_libsigsegv_fun005.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libsigsegv libsigsegv-devel gcc"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = '''cat >libsigsegv_testfile.c<<"EOF" +#include +#include +#include +#include +#include +#include + +/* 段错误处理函数 */ +void segv_handler(int signum, siginfo_t *info, void *context) { + printf("Caught segmentation fault! Faulty address is %p\\n", info->si_addr); + exit(1); +} + +int main() { + struct sigaction sa; + + sa.sa_sigaction = segv_handler; // 设置段错误处理函数 + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; // 使用信号扩展信息 + + /* 安装信号处理程序 */ + if (sigaction(SIGSEGV, &sa, NULL) == -1) { + perror("Failed to install SIGSEGV signal handler"); + return EXIT_FAILURE; + } + + /* 分配一块内存,然后立即解除映射 */ + size_t size = 4096; // 一页内存的大小 + void *buffer = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + if (buffer == MAP_FAILED) { + perror("Failed to map memory"); + return EXIT_FAILURE; + } + + /* 解除内存映射 */ + if (munmap(buffer, size) == -1) { + perror("Failed to unmap memory"); + return EXIT_FAILURE; + } + + /* 故意造成未映射的内存区域的访问 */ + int *p = (int *)buffer; + *p = 42; /* 这一行将会触发段错误 */ + + /* 如果段错误处理程序可以正常恢复,以下行将不会执行 */ + printf("This line should not be executed.\\n"); + + return 0; +} +EOF''' + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o libsigsegv_testfile libsigsegv_testfile.c -lsigsegv") + result = subprocess.run(["./libsigsegv_testfile"], stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.decode() + self.log.info(result) + self.assertIn("Caught segmentation fault!", result) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf libsigsegv_testfile*") \ No newline at end of file diff --git a/tests/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun006.py b/tests/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun006.py new file mode 100644 index 0000000000000000000000000000000000000000..a839cadf925bf5a6e34cffb5332b3bb37cd2b3ae --- /dev/null +++ b/tests/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun006.py @@ -0,0 +1,73 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_libsigsegv_libsigsegv_fun006.py +@Time: 2024/3/11 10:18:20 +@Author: wangyaru +@Version: 1.0 +@Contact: wb-wyr940190@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: wangyaru +""" + +import subprocess +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libsigsegv_libsigsegv_fun006.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libsigsegv libsigsegv-devel gcc"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = '''cat >libsigsegv_testfile.c<<"EOF" +#include +#include +#include +#include +#include + +/* 段错误处理函数 */ +void segv_handler(int signum, siginfo_t *info, void *context) { + printf("Caught segmentation fault! Faulty address is %p\\n", info->si_addr); + exit(1); +} + +int main() { + struct sigaction sa; + + sa.sa_sigaction = segv_handler; // 设置段错误处理函数 + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + + /* 安装信号处理程序 */ + if (sigaction(SIGSEGV, &sa, NULL) == -1) { + perror("Failed to install SIGSEGV signal handler"); + return EXIT_FAILURE; + } + + /* 字符串常量,存储在只读数据段 */ + char *str = "This is a read-only string"; + + /* 故意尝试修改只读字符串 */ + str[0] = 't'; /* 这一行将会触发段错误 */ + + /* 如果段错误处理程序可以正常恢复,以下行将不会执行 */ + printf("This line should not be executed.\\n"); + + return 0; +} +EOF''' + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o libsigsegv_testfile libsigsegv_testfile.c -lsigsegv") + result = subprocess.run(["./libsigsegv_testfile"], stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.decode() + self.log.info(result) + self.assertIn("Caught segmentation fault!", result) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf libsigsegv_testfile*") diff --git a/tests/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun007.py b/tests/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun007.py new file mode 100644 index 0000000000000000000000000000000000000000..9a0db131e5c7c976b628def7987f0e2c53164468 --- /dev/null +++ b/tests/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun007.py @@ -0,0 +1,87 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_libsigsegv_libsigsegv_fun007.py +@Time: 2024/3/11 10:18:20 +@Author: wangyaru +@Version: 1.0 +@Contact: wb-wyr940190@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: wangyaru +""" + +import subprocess +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libsigsegv_libsigsegv_fun007.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libsigsegv libsigsegv-devel gcc"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = '''cat >libsigsegv_testfile.c<<"EOF" +#include +#include +#include +#include +#include + +/* 段错误处理函数 */ +void segv_handler(int signum, siginfo_t *info, void *context) { + printf("Caught segmentation fault in thread! Faulty address is %p\\n", info->si_addr); + exit(1); +} + +/* 线程工作函数,将导致段错误 */ +void* thread_func(void *arg) { + /* 故意造成段错误 */ + int *p = NULL; + *p = 42; /* 这一行将会触发段错误 */ + return NULL; +} + +int main() { + pthread_t thread; + struct sigaction sa; + + sa.sa_sigaction = segv_handler; // 设置段错误处理函数 + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + + /* 安装信号处理程序 */ + if (sigaction(SIGSEGV, &sa, NULL) == -1) { + perror("Failed to install SIGSEGV signal handler"); + return EXIT_FAILURE; + } + + /* 创建一个新线程,线程将执行 thread_func 函数 */ + if (pthread_create(&thread, NULL, thread_func, NULL) != 0) { + perror("Failed to create thread"); + return EXIT_FAILURE; + } + + /* 等待线程结束 */ + if (pthread_join(thread, NULL) != 0) { + perror("Failed to join thread"); + return EXIT_FAILURE; + } + + printf("This line should not be executed if segmentation fault occurred.\\n"); + + return 0; +} +EOF''' + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o libsigsegv_testfile libsigsegv_testfile.c -lsigsegv -pthread") + result = subprocess.run(["./libsigsegv_testfile"], stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.decode() + self.log.info(result) + self.assertIn("Caught segmentation fault in thread!", result) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf libsigsegv_testfile*") diff --git a/tests/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun008.py b/tests/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun008.py new file mode 100644 index 0000000000000000000000000000000000000000..a15a856e66d586232e3310be67b65cf08184f698 --- /dev/null +++ b/tests/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun008.py @@ -0,0 +1,114 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_libsigsegv_libsigsegv_fun008.py +@Time: 2024/3/12 10:18:20 +@Author: wangyaru +@Version: 1.0 +@Contact: wb-wyr940190@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: wangyaru +""" + +import subprocess +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libsigsegv_libsigsegv_fun008.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libsigsegv libsigsegv-devel gcc"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = '''cat >tempfile<<"EOF" +test +test +test +} +EOF''' + self.cmd(cmdline) + cmdline = '''cat >libsigsegv_testfile.c<<"EOF" +#include +#include +#include +#include +#include + +int volatile should_exit = 0; // 用于指示程序应该退出 +int *volatile dynamic_memory = NULL; // 动态分配的内存 +FILE *volatile file_resource = NULL; // 文件资源 + +/* 段错误处理函数 */ +void segv_handler(int signum, siginfo_t *info, void *context) { + write(STDERR_FILENO, "Caught segmentation fault! Performing cleanup and exiting.\\n", 60); + + // 关闭文件描述符 + if (file_resource != NULL) { + fclose(file_resource); // 请注意,fclose本身并不是异步信号安全的 + file_resource = NULL; + } + + // 释放动态分配的内存 + if (dynamic_memory != NULL) { + free((void*)dynamic_memory); // 同样,free不是异步信号安全的 + dynamic_memory = NULL; + } + printf("关闭文件描述符、释放内存等成功.\\n"); + should_exit = 1; // 设置退出标志 + _exit(1); // 退出程序 +} + +int main() { + struct sigaction sa; + + sa.sa_sigaction = segv_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + + // 安装信号处理程序 + if (sigaction(SIGSEGV, &sa, NULL) == -1) { + perror("Failed to install SIGSEGV signal handler"); + return EXIT_FAILURE; + } + + // 打开文件资源 + file_resource = fopen("tempfile", "w+"); + if (!file_resource) { + perror("Failed to open file"); + return EXIT_FAILURE; + } + + // 分配动态内存 + dynamic_memory = (int *)malloc(sizeof(int) * 100); + if (!dynamic_memory) { + perror("Failed to allocate memory"); + fclose(file_resource); + return EXIT_FAILURE; + } + + // 故意触发段错误 + int *p = NULL; + *p = 42; + + // 段错误处理程序将接管,以下代码应该不会执行 + printf("This line should not be executed.\\n"); + + // 清理资源 + fclose(file_resource); + free(dynamic_memory); + + return 0; +} +EOF''' + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o libsigsegv_testfile libsigsegv_testfile.c -lsigsegv") + code, result = self.cmd("./libsigsegv_testfile", ignore_status=True) + self.assertIn("Caught segmentation fault! Performing cleanup and exiting.", result) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf libsigsegv_testfile* tempfile") diff --git a/tests/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun009.py b/tests/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun009.py new file mode 100644 index 0000000000000000000000000000000000000000..d23e168bb83baa3078923c590f9c0bd07a83fe08 --- /dev/null +++ b/tests/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun009.py @@ -0,0 +1,85 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_libsigsegv_libsigsegv_fun009.py +@Time: 2024/3/12 10:18:20 +@Author: wangyaru +@Version: 1.0 +@Contact: wb-wyr940190@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: wangyaru +""" + +import subprocess +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libsigsegv_libsigsegv_fun009.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libsigsegv libsigsegv-devel gcc"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = '''cat >libsigsegv_testfile.c<<"EOF" +#include +#include +#include +#include +#include + +volatile sig_atomic_t in_handler = 0; // 标记是否已经在信号处理程序中 +jmp_buf escape_point; // 用于长跳转以从嵌套的信号处理程序中恢复 + +/* 段错误处理函数 */ +void segv_handler(int signum, siginfo_t *info, void *context) { + if (!in_handler) { + // 如果我们已经在处理程序中,使用长跳转来恢复 + siglongjmp(escape_point, 1); + } + in_handler = 1; // 标记我们正在处理段错误 + + // 执行一些可能触发段错误的操作 + char *p = NULL; + p[0] = 'a'; // 故意触发另一个段错误 + in_handler = 0; // 重置标记 +} + +int main() { + struct sigaction sa; + + sa.sa_sigaction = segv_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + // 安装信号处理程序 + if (sigaction(SIGSEGV, &sa, NULL) == -1) { + perror("Failed to install SIGSEGV signal handler"); + return EXIT_FAILURE; + } + + if (sigsetjmp(escape_point, 1) == 0) { + // 故意触发段错误 + char *p = NULL; + p[0] = 'a'; // 这会导致第一个段错误 + } else { + // 如果通过长跳转恢复,执行必要的清理 + printf("Recovered from nested segmentation fault.\\n"); + } + + // 如果处理程序可以正常恢复,以下代码将会执行 + printf("Program recovered and continuing normal execution.\\n"); + return 0; +} +EOF''' + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o libsigsegv_testfile libsigsegv_testfile.c -lsigsegv") + code, result = self.cmd("./libsigsegv_testfile", ignore_status=True) + self.assertIn("Recovered from nested segmentation fault.", result) + self.assertIn("Program recovered and continuing normal execution.", result) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf libsigsegv_testfile*") diff --git a/tests/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun010.py b/tests/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun010.py new file mode 100644 index 0000000000000000000000000000000000000000..6e3f09e06ad5567e8c2b4d1d87962a23993ae17d --- /dev/null +++ b/tests/system_base/libsigsegv/tc_libsigsegv_libsigsegv_fun010.py @@ -0,0 +1,81 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_libsigsegv_libsigsegv_fun010.py +@Time: 2024/3/12 10:18:20 +@Author: wangyaru +@Version: 1.0 +@Contact: wb-wyr940190@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: wangyaru +""" + +import subprocess +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libsigsegv_libsigsegv_fun010.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libsigsegv libsigsegv-devel gcc"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = '''cat >libsigsegv_testfile.c<<"EOF" +#include +#include +#include +#include + +static sigjmp_buf jump_buffer; + +/* 段错误处理函数 */ +void segv_handler(int signum) { + // 输出消息 + printf("Segmentation fault caught! Attempting to recover...\\n"); + // 使用 siglongjmp 跳回到之前的环境,恢复执行 + siglongjmp(jump_buffer, 1); +} + +int main() { + struct sigaction sa; + sa.sa_handler = segv_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + + // 安装信号处理程序 + if (sigaction(SIGSEGV, &sa, NULL) == -1) { + perror("Failed to install SIGSEGV signal handler"); + return EXIT_FAILURE; + } + + // 设置跳转点,如果 sigsetjmp 返回非零值,表示从信号处理程序返回 + if (sigsetjmp(jump_buffer, 1)) { + // 从信号处理程序返回到这里 + printf("Program has recovered from segmentation fault.\\n"); + } else { + // 正常程序执行路径 + // 故意触发段错误 + int *p = NULL; + *p = 42; + } + + // 程序恢复执行,预期的结果是程序会捕获段错误,然后从信号处理程序中恢复,并继续执行后续的 printf 语句 + printf("Continuing execution...\\n"); + + return 0; +} +EOF''' + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o libsigsegv_testfile libsigsegv_testfile.c -lsigsegv") + code, result = self.cmd("./libsigsegv_testfile", ignore_status=True) + self.assertIn("Segmentation fault caught! Attempting to recover", result) + self.assertIn("Program has recovered from segmentation fault", result) + self.assertIn("Continuing execution", result) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf libsigsegv_testfile*") diff --git a/tests/system_base/libuser/tc_libuser_group_lgroupdel_fun002.py b/tests/system_base/libuser/tc_libuser_group_lgroupdel_fun002.py new file mode 100644 index 0000000000000000000000000000000000000000..a8c855c743d1d0b49f68707b17fabc782fdece87 --- /dev/null +++ b/tests/system_base/libuser/tc_libuser_group_lgroupdel_fun002.py @@ -0,0 +1,63 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_libuser_group_lgroupdel_fun002.py +@Time: 2024/2/22 15:47:20 +@Author: wangyaru +@Version: 1.0 +@Contact: wb-wyr940190@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: wangyaru +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libuser_group_lgroupdel_fun002.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libuser"} + group_name = 'group_test01' + + def setUp(self): + super().setUp(self.PARAM_DIC) + result = list(self.cmd("cat /etc/group| awk -F ':' '{print $1}'", ignore_status=True))[-1] + if self.group_name in result: + self.cmd(f'lgroupdel {self.group_name}', ignore_status=True) + result = list(self.cmd("cat /etc/passwd| awk -F ':' '{print $1}'", ignore_status=True))[-1] + if "testuser_001" in result: + self.cmd(f'luserdel -r testuser_001', ignore_status=True) + + def test(self): + code, result = self.cmd('lgroupdel --help') + self.assertIn('lgroupdel', result) + self.cmd(f'lgroupadd {self.group_name}') + self.cmd(f'luseradd -g {self.group_name} testuser_001') + code, result = self.cmd('cat /etc/passwd') + self.assertIn('testuser_001', result) + + # try to remove the primary group of user + # https://bugzilla.openanolis.cn/show_bug.cgi?id=8566 + # https://bugzilla.openanolis.cn/show_bug.cgi?id=8445 + # self.cmd(f'lgroupdel {self.group_name}') + # code, result = self.cmd('cat /etc/group') + # self.assertIn(f'{self.group_name}', result) + # code, result = self.cmd('ls /home/testuser_001') + # self.assertTrue(code != 0, "用户主目录资源残留") + + self.cmd(f'lgroupdel {self.group_name}') + code, result = self.cmd('cat /etc/group') + self.assertNotIn(f'{self.group_name}', result) + code, result = self.cmd('cat /etc/passwd') + self.assertIn('testuser_001', result) + + self.cmd('luserdel -r testuser_001', ignore_status=True) + code, result = self.cmd('cat /etc/passwd') + self.assertNotIn('testuser_001', result) + self.cmd('rm -rf /home/testuser_001 /var/mail/testuser_001', ignore_status=True) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + \ No newline at end of file diff --git a/tests/system_base/libuser/tc_libuser_lchfn_lchfn_fun001.py b/tests/system_base/libuser/tc_libuser_lchfn_lchfn_fun001.py new file mode 100644 index 0000000000000000000000000000000000000000..6ee8eb5dd8723b6aad82e31544e1d12036c68609 --- /dev/null +++ b/tests/system_base/libuser/tc_libuser_lchfn_lchfn_fun001.py @@ -0,0 +1,49 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_libuser_lchfn_lchfn_fun001.py +@Time: 2024/3/18 15:34:20 +@Author: wangyaru +@Version: 1.0 +@Contact: wb-wyr940190@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: wangyaru +""" + +import pexpect +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libuser_lchfn_lchfn_fun001.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libuser"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + + def test(self): + code, result = self.cmd("lchfn --help") + self.assertIn("lchfn", result) + self.cmd("luseradd test_user001") + code, result = self.cmd('cat /etc/passwd') + self.assertIn("test_user001", result) + + # check lchfn + command = "lchfn test_user001" + child = pexpect.spawn(command) + child.expect('Full Name',timeout=2) + child.sendline('new_test_user001\n') + child.expect('Office',timeout=2) + child.sendline('') + child.expect('Home Phone',timeout=2) + child.sendline('') + child.expect(pexpect.EOF) + code, result = self.cmd('cat /etc/passwd') + self.assertIn("new_test_user001", result) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("userdel -r test_user001") diff --git a/tests/system_base/libuser/tc_libuser_lchsh_lchsh_fun001.py b/tests/system_base/libuser/tc_libuser_lchsh_lchsh_fun001.py new file mode 100644 index 0000000000000000000000000000000000000000..5448c00b7816c5c83d152a645f7e40fb5418d4c6 --- /dev/null +++ b/tests/system_base/libuser/tc_libuser_lchsh_lchsh_fun001.py @@ -0,0 +1,46 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_libuser_lchsh_lchsh_fun001.py +@Time: 2024/3/18 15:34:20 +@Author: wangyaru +@Version: 1.0 +@Contact: wb-wyr940190@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: wangyaru +""" + +import pexpect +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libuser_lchsh_lchsh_fun001.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libuser"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + + def test(self): + code, result = self.cmd('lchsh --help') + self.assertIn('lchsh', result) + self.cmd('luseradd test_user001') + code, result = self.cmd('cat /etc/passwd') + self.assertIn('test_user001', result) + + # check lchsh + newshell = '/bin/bash_new' + command = 'lchsh test_user001' + child = pexpect.spawn(command) + child.expect('New Shell',timeout=5) + child.sendline(newshell) + child.expect(pexpect.EOF) + code, result = self.cmd('cat /etc/passwd') + self.assertIn(newshell, result) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("userdel -r test_user001") diff --git a/tests/system_base/libuser/tc_libuser_lpasswd_lpasswd_fun001.py b/tests/system_base/libuser/tc_libuser_lpasswd_lpasswd_fun001.py new file mode 100644 index 0000000000000000000000000000000000000000..cfc4499ce0451d78fe55cf3d77b766ddaa073dee --- /dev/null +++ b/tests/system_base/libuser/tc_libuser_lpasswd_lpasswd_fun001.py @@ -0,0 +1,68 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_libuser_lpasswd_lpasswd_fun001.py +@Time: 2024/3/18 16:42:20 +@Author: wangyaru +@Version: 1.0 +@Contact: wb-wyr940190@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: wangyaru +""" + +import pexpect +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libuser_lpasswd_lpasswd_fun001.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libuser"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + + def test(self): + code, result = self.cmd('lpasswd --help') + self.assertIn('lpasswd', result) + self.cmd('luseradd test_user001') + new_password = 'newpassword' + command = 'lpasswd test_user001' + child = pexpect.spawn('/bin/bash', timeout=5) + child.sendline(command) + child.expect('New password', timeout=5) + child.sendline(new_password) + child.expect('confirm', timeout=5) + child.sendline(new_password) + child.expect('Password changed.') + self.log.info("set passwd soccessed!") + + # su 切换用户验证 + self.cmd('luseradd test_user002') + command = 'su - test_user002' + child.sendline(command) + child.expect(['test_user002','\$'], timeout=5) + child.sendline('whoami') + child.expect('test_user002', timeout=5) + self.log.info("root切换普通用户成功!") + + command = 'su - test_user001' + child.sendline(command) + child.expect('.*Password:\s*', timeout=10) + child.sendline(new_password) + child.expect(['test_user001','\$ '], timeout=5) + child.sendline('whoami') + child.expect('test_user001', timeout=5) + child.sendline('exit') # exit test_user001 + child.expect('logout', timeout=5) + child.sendline('exit') # exit test_user002 + child.expect('logout', timeout=5) + self.log.info('密码设置成功生效!') + child.close() + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("luserdel -r test_user001") + self.cmd("luserdel -r test_user002") diff --git a/tests/system_base/libuser/tc_libuser_user_luseradd_fun002.py b/tests/system_base/libuser/tc_libuser_user_luseradd_fun002.py index 3986e878c433db633a0484b7ef93c4cdf09a63a8..ee46c16e39d4acbf7c44fdfeee99975a1c8df0d9 100644 --- a/tests/system_base/libuser/tc_libuser_user_luseradd_fun002.py +++ b/tests/system_base/libuser/tc_libuser_user_luseradd_fun002.py @@ -16,7 +16,7 @@ class Test(LocalTest): """ See tc_libuser_user_luseradd_fun002.yaml for details - :avocado: tags=P2,noarch,local,fixed + :avocado: tags=P2,noarch,local,fix """ PARAM_DIC = {"pkg_name": "libuser"} username = 'testuser1' @@ -30,8 +30,8 @@ class Test(LocalTest): def test(self): code, result = self.cmd('luseradd --help') self.assertIn('luseradd', result) - self.cmd(f'luseradd -u 10001 -d /tmp/home/{self.username} {self.username}') - self.cmd(f'ls -ld /tmp/home/{self.username}') + self.cmd(f'luseradd -u 10001 -d /tmp/{self.username} {self.username}') + self.cmd(f'ls -ld /tmp/{self.username}') code, result = self.cmd(f'lid -g {self.username}') self.assertIn('10001', result) diff --git a/tests/system_base/libutempter/tc_libutempter_libutempter_fun002.py b/tests/system_base/libutempter/tc_libutempter_libutempter_fun002.py new file mode 100644 index 0000000000000000000000000000000000000000..d2efdc761dde87490724ef2770f53835276a3d96 --- /dev/null +++ b/tests/system_base/libutempter/tc_libutempter_libutempter_fun002.py @@ -0,0 +1,64 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_libutempter_libutempter_fun002.py +@Time: 2024/3/8 15:25:20 +@Author: wangyaru +@Version: 1.0 +@Contact: wb-wyr940190@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: wangyaru +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libutempter_libutempter_fun002.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libutempter libutempter-devel gcc"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = '''cat >libutempter_testfile.c<<"EOF" +#include +#include +#include +#include + +int main() { + // 测试提供无效的文件描述符 + if (utempter_add_record(-1, "testuser") == 0) { + fprintf(stderr, "Unexpected success with invalid file descriptor\\n"); + } else { + printf("Correctly handled invalid file descriptor\\n"); + } + + // 测试提供NULL作为用户名 + if (utempter_add_record(STDIN_FILENO, NULL) == 0) { + fprintf(stderr, "Unexpected success with NULL username\\n"); + } else { + printf("Correctly handled NULL username\\n"); + } + + // 测试提供空字符串作为用户名 + if (utempter_add_record(STDIN_FILENO, "") == 0) { + fprintf(stderr, "Unexpected success with empty username\\n"); + } else { + printf("Correctly handled empty username\\n"); + } + + return 0; +} +EOF''' + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o libutempter_testfile libutempter_testfile.c -lutempter") + code, result = self.cmd("./libutempter_testfile") + self.assertTrue(code == 0, msg="无效参数验证失败!") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf libutempter_testfile*") \ No newline at end of file diff --git a/tests/system_base/libutempter/tc_libutempter_libutempter_fun003.py b/tests/system_base/libutempter/tc_libutempter_libutempter_fun003.py new file mode 100644 index 0000000000000000000000000000000000000000..f30ebf801f5cb94112b780c85c29507449b23ed7 --- /dev/null +++ b/tests/system_base/libutempter/tc_libutempter_libutempter_fun003.py @@ -0,0 +1,67 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_libutempter_libutempter_fun003.py +@Time: 2024/3/8 15:25:20 +@Author: wangyaru +@Version: 1.0 +@Contact: wb-wyr940190@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: wangyaru +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libutempter_libutempter_fun003.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libutempter libutempter-devel gcc"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = '''cat >libutempter_testfile.c<<"EOF" +#include +#include +#include +#include +#include +#include +#include + +int main() { + struct rlimit rl; + int result = getrlimit(RLIMIT_NOFILE, &rl); + if (result != 0) { + perror("Failed to get file descriptor limit"); + return 1; + } + + // 设置软限制为当前打开文件描述符数量 + rl.rlim_cur = rl.rlim_max; + setrlimit(RLIMIT_NOFILE, &rl); + + // 尝试打开文件直到达到限制 + while (open("/dev/null", O_RDONLY) != -1) {} + + // 测试添加记录时的行为 + if (utempter_add_record(STDIN_FILENO, "testuser") == 0) { + fprintf(stderr, "Unexpected success when resource limits are reached\\n"); + } else { + printf("Correctly handled situation when resource limits are reached\\n"); + } + + return 0; +} +EOF''' + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o libutempter_testfile libutempter_testfile.c -lutempter") + code, result = self.cmd("./libutempter_testfile") + self.assertTrue(code == 0, msg="测试资源受限场景失败!") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf libutempter_testfile*") \ No newline at end of file diff --git a/tests/system_base/libutempter/tc_libutempter_libutempter_fun004.py b/tests/system_base/libutempter/tc_libutempter_libutempter_fun004.py new file mode 100644 index 0000000000000000000000000000000000000000..2638e0ca5d38ca04f53d4c78d28f4165cadfa1ec --- /dev/null +++ b/tests/system_base/libutempter/tc_libutempter_libutempter_fun004.py @@ -0,0 +1,83 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_libutempter_libutempter_fun004.py +@Time: 2024/3/8 15:25:20 +@Author: wangyaru +@Version: 1.0 +@Contact: wb-wyr940190@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: wangyaru +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libutempter_libutempter_fun004.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libutempter libutempter-devel gcc"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = '''cat >libutempter_testfile.c<<"EOF" +#include +#include +#include +#include +#include +#include +#include +#include + +#define NUM_PROCESSES 10 + +int main() { + pid_t pids[NUM_PROCESSES]; + int i; + + for (i = 0; i < NUM_PROCESSES; i++) { + pids[i] = fork(); + if (pids[i] < 0) { + perror("fork failed"); + exit(EXIT_FAILURE); + } else if (pids[i] == 0) { // Child process + char username[32]; + sprintf(username, "testuser%d", i); + if (utempter_add_record(STDIN_FILENO, username) != 0) { + fprintf(stderr, "Failed to add utmp record for user %s\\n", username); + exit(EXIT_FAILURE); + } + sleep(1); // Simulate some work + if (utempter_remove_added_record() != 0) { + fprintf(stderr, "Failed to remove utmp record for user %s\\n", username); + exit(EXIT_FAILURE); + } + exit(EXIT_SUCCESS); + } + } + + // Wait for all children to finish + for (i = 0; i < NUM_PROCESSES; i++) { + int status; + waitpid(pids[i], &status, 0); + if (status != 0) { + printf("Process %d exited with error status.\\n", pids[i]); + } + } + + printf("All processes finished.\\n"); + return 0; +} +EOF''' + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o libutempter_testfile libutempter_testfile.c -lutempter") + code, result = self.cmd("./libutempter_testfile") + self.assertEqual("All processes finished.", result, msg="多线程场景失败!") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf libutempter_testfile*") \ No newline at end of file diff --git a/tests/system_base/lsof/tc_lsof_lsof_fun001.py b/tests/system_base/lsof/tc_lsof_lsof_fun001.py new file mode 100644 index 0000000000000000000000000000000000000000..95220f9637c3423ff45a25d7fc1bd68d6aabd084 --- /dev/null +++ b/tests/system_base/lsof/tc_lsof_lsof_fun001.py @@ -0,0 +1,36 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_lsof_lsof_fun001.py +@Time: 2024/4/25 10:30:20 +@Author: douzhichong +@Version: 1.0 +@Contact: douzhichong@inspur.com +@License: Mulan PSL v2 +@Modify: douzhichong +""" + +from common.basetest import LocalTest +from common.service import ServiceManager + +class Test(LocalTest): + """ + See tc_lsof_lsof_fun001.yaml for details + + :avocado: tags=P1,noarch,local,lsof + """ + PARAM_DIC = {"pkg_name": "lsof"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + + + def test(self): + self.cmd("command -v lsof|grep /usr/bin/lsof") + self.cmd("lsof -u root >testlog &") + self.cmd("grep -i pid testlog") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf testlog") + diff --git a/tests/system_base/net-tools/tc_net_tools_arp_func_001.py b/tests/system_base/net-tools/tc_net_tools_arp_func_001.py new file mode 100644 index 0000000000000000000000000000000000000000..87290c5e67cf8da885b3b17adedea6a4c975e5f1 --- /dev/null +++ b/tests/system_base/net-tools/tc_net_tools_arp_func_001.py @@ -0,0 +1,42 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_net_tools_arp_func_001.py +@Time: 2024/03/05 14:33:20 +@Author: chenchunhu +@Version: 1.0 +@Contact: wb-cch358909@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: chenchunhu +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_net_tools_arp_func_001.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "net-tools"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code, self.ip = self.cmd("route -n | grep 'UG[ \t]' | awk '{print $2}'") + + def test(self): + code, arp_result = self.cmd("arp -a") + self.assertIn(self.ip, arp_result) + code, arp_result = self.cmd("arp -a %s"%self.ip) + self.assertIn(self.ip, arp_result) + code, arp_result = self.cmd("arp -help") + self.assertIn("Usage:", arp_result) + code, arp_result = self.cmd("arp -s 999.999.999.999 00:1C:42:2B:60:5A", ignore_status=True) + self.assertIn("Unknown host", arp_result) + code, arp_result = self.cmd("arp -s 192.168.1.100 00:11:22:33:44:ZZ", ignore_status=True) + self.assertIn("invalid hardware address", arp_result) + code, arp_result = self.cmd("arp -a 192.168.1.123", ignore_status=True) + self.assertIn("entries no match found", arp_result) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) diff --git a/tests/system_base/net-tools/tc_net_tools_ifconfig_func_001.py b/tests/system_base/net-tools/tc_net_tools_ifconfig_func_001.py new file mode 100644 index 0000000000000000000000000000000000000000..8d66ba2bc30f30122fcc4cd2c7e82f6a05446cf6 --- /dev/null +++ b/tests/system_base/net-tools/tc_net_tools_ifconfig_func_001.py @@ -0,0 +1,43 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_net_tools_ifconfig_func_001.py +@Time: 2024/03/05 14:33:20 +@Author: chenchunhu +@Version: 1.0 +@Contact: wb-cch358909@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: chenchunhu +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_net_tools_ifconfig_func_001.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "net-tools iproute"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("ip link add test0 type dummy") + self.cmd("ifconfig test0 up") + + def test(self): + self.cmd("ifconfig test0 192.168.1.1 netmask 255.255.255.0 broadcast 192.168.1.255 hw ether 00:0c:29:3e:47:4b") + code, ifconfig_result = self.cmd("ifconfig test0") + self.assertIn("192.168.1.1", ifconfig_result) + self.assertIn("255.255.255.0", ifconfig_result) + self.assertIn("192.168.1.255", ifconfig_result) + self.assertIn("00:0c:29:3e:47:4b", ifconfig_result) + self.cmd("ifconfig test0 down") + self.cmd("ifconfig test0 up") + self.assertIn("UP", ifconfig_result) + self.cmd("ip link delete test0") + code, ifconfig_result = self.cmd("ifconfig -help") + self.assertIn("Usage:", ifconfig_result) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) diff --git a/tests/system_base/net-tools/tc_net_tools_netstat_func_001.py b/tests/system_base/net-tools/tc_net_tools_netstat_func_001.py new file mode 100644 index 0000000000000000000000000000000000000000..0d3bca6e2b2cbaae5dd197919b70fc12f779f031 --- /dev/null +++ b/tests/system_base/net-tools/tc_net_tools_netstat_func_001.py @@ -0,0 +1,56 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_net_tools_netstat_func_001.py +@Time: 2024/03/05 14:33:20 +@Author: chenchunhu +@Version: 1.0 +@Contact: wb-cch358909@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: chenchunhu +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_net_tools_netstat_func_001.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "net-tools"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + ret_c, self.eth_name = self.cmd("ip add | grep 'state UP' | awk '{print $2}' | awk -F ':' 'NR==1{print $1}'") + + def test(self): + code, netstat_result = self.cmd("netstat -a") + self.assertIn("LISTENING", netstat_result) + code, netstat_result = self.cmd("netstat -l") + self.assertIn("LISTENING", netstat_result) + code, netstat_result = self.cmd("netstat -s") + self.assertIn("TCP", netstat_result) + code, netstat_result = self.cmd("netstat -t") + self.assertIn("tcp", netstat_result) + code, netstat_result = self.cmd("netstat -u") + self.assertIn("udp", netstat_result) + code, netstat_result = self.cmd("netstat -r") + self.assertIn(self.eth_name, netstat_result) + code, netstat_result = self.cmd("netstat -i") + self.assertIn(self.eth_name, netstat_result) + code, netstat_result = self.cmd("netstat -w") + self.assertIn("Active Internet connections (w/o servers)", netstat_result) + code, netstat_result = self.cmd("netstat -st") + self.assertIn("TCP", netstat_result) + code, netstat_result = self.cmd("netstat -lt") + self.assertIn("LISTEN", netstat_result) + code, netstat_result = self.cmd("netstat -ln") + self.assertIn("LISTENING", netstat_result) + code, netstat_result = self.cmd("netstat -help") + self.assertIn("usage:", netstat_result) + code, netstat_result = self.cmd("netstat -z", ignore_status=True) + self.assertIn("invalid option -- 'z'", netstat_result) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) diff --git a/tests/system_base/net-tools/tc_net_tools_ping_func_001.py b/tests/system_base/net-tools/tc_net_tools_ping_func_001.py new file mode 100644 index 0000000000000000000000000000000000000000..72b70c67828b9cb956f7505f00e14c9975b53982 --- /dev/null +++ b/tests/system_base/net-tools/tc_net_tools_ping_func_001.py @@ -0,0 +1,57 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_net_tools_ping_func_001.py +@Time: 2024/03/05 14:33:20 +@Author: chenchunhu +@Version: 1.0 +@Contact: wb-cch358909@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: chenchunhu +""" + +import time +import pexpect +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_net_tools_ping_func_001.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "net-tools"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code, self.ip = self.cmd("route -n | grep 'UG[ \t]' | awk '{print $2}'") + + def test(self): + child = pexpect.spawn('ping %s' % self.ip) + time.sleep(1) + child.sendcontrol('c') + child.expect(pexpect.EOF, timeout=1) + self.assertIn("1 packets transmitted", child.before.decode()) + code, ping_result = self.cmd("ping -c 3 %s" % self.ip) + self.assertIn("3 packets transmitted", ping_result) + code, ping_result = self.cmd("ping -c 3 -s 100 %s" % self.ip) + self.assertIn("108 bytes from %s" % self.ip, ping_result) + code, ping_result = self.cmd("ping -w 3 %s" % self.ip) + self.assertIn("3 packets transmitted", ping_result) + code, ping_result = self.cmd("ping -c 3 -D %s" % self.ip) + self.assertRegex(ping_result, r"\d{10}\.\d{6}") + code, ping_result = self.cmd("ping -c 3 -f %s" % self.ip) + self.assertIn("3 packets transmitted", ping_result) + code, ping_result = self.cmd("ping -c 3 -i 1 %s" % self.ip) + self.assertIn("3 packets transmitted", ping_result) + code, ping_result = self.cmd("ping -c 3 -q %s" % self.ip) + self.assertIn("3 packets transmitted", ping_result) + code, ping_result = self.cmd("ping nonexistentdomain.example", ignore_status=True) + self.assertIn("Name or service not known", ping_result) + code, ping_result = self.cmd("ping -c notanumber %s" % self.ip, ignore_status=True) + self.assertIn("invalid argument", ping_result) + code, ping_result = self.cmd("ping -help", ignore_status=True) + self.assertIn("Usage", ping_result) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) diff --git a/tests/system_base/rpm/tc_rpm_rpm_fun001.py b/tests/system_base/rpm/tc_rpm_rpm_fun001.py new file mode 100644 index 0000000000000000000000000000000000000000..c300a5eb56ebf17fa0531ac31e8abbf54041e8c9 --- /dev/null +++ b/tests/system_base/rpm/tc_rpm_rpm_fun001.py @@ -0,0 +1,41 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_rpm_rpm_fun001.py +@Time: 2024/5/13 15:30:20 +@Author: douzhichong +@Version: 1.0 +@Contact: douzhichong@inspur.com +@License: Mulan PSL v2 +@Modify: douzhichong +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_rpm_rpm_fun001.yaml for details + + :avocado: tags=P1,noarch,local,less + """ + PARAM_DIC = {"pkg_name": "rpm"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("dnf download lsof") + self.cmd("rpm -ivh lsof*.rpm ") + + def test(self): + code, result = self.cmd("rpm -qip lsof*.rpm") + self.assertIn("lsof", result) + code, result = self.cmd("rpm -qa | grep -v help") + self.assertIn("lsof", result) + code, result = self.cmd("rpm -qi lsof") + self.assertIn("Name", result) + code, result = self.cmd("rpm -ql lsof") + self.assertIn("/usr/bin/lsof", result) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rpm -e lsof") + self.cmd("rm -rf lsof*.rpm") \ No newline at end of file diff --git a/tests/system_base/unbound/tc_unbound_unbound_checkconf_fun_001.py b/tests/system_base/unbound/tc_unbound_unbound_checkconf_fun_001.py new file mode 100644 index 0000000000000000000000000000000000000000..32f70cf0326775eebd7fedfbd26b0668fb1bd7e6 --- /dev/null +++ b/tests/system_base/unbound/tc_unbound_unbound_checkconf_fun_001.py @@ -0,0 +1,52 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_unbound_unbound_checkconf_fun_001.py +@Time: 2024/04/18 14:05 +@Author: zhanggaiyan +@Version: 1.0 +@Contact: zhanggaiyan@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: zhanggaiyan +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_unbound_unbound_checkconf_fun_001.yaml for details + + :avocado: tags=P3,noarch,locali,fix + """ + PARAM_DIC = {"pkg_name": "unbound"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir temp_dir") + # Create a valid configuration file + cmdline_va = """cat > temp_dir/valid.conf < temp_dir/invalid.conf <> /etc/unbound/unbound.conf") + self.cmd("echo 'interface: ::1' >> /etc/unbound/unbound.conf") + self.cmd("echo 'access-control: 0.0.0.0/0 allow' >> /etc/unbound/unbound.conf") + self.cmd("echo 'access-control: ::0/0 allow' >> /etc/unbound/unbound.conf") + + def test(self): + # start unbound service + self.cmd("systemctl start unbound") + self.cmd("systemctl status unbound |grep running") + ret_c, ret_o = self.cmd("dig @localhost example.com A") + self.assertTrue("93.184.216.34" in ret_o, 'check output error') + ret_c, ret_o = self.cmd("dig @localhost example.com NS") + self.assertTrue("a.iana-servers.net" in ret_o, 'check output error') + ret_c, ret_o = self.cmd("dig @localhost example.com TXT") + self.assertTrue("wgyf8z8cgvm2qmxpnbnldrcltvk4xqfn" in ret_o, 'check output error') + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("mv /etc/unbound/unbound.conf-bak /etc/unbound/unbound.conf") diff --git a/tests/system_base/util-linux/tc_ag_util-linux_chrt_fun_002.py b/tests/system_base/util-linux/tc_ag_util-linux_chrt_fun_002.py index 80c07a2d5644fb34cebc1c2159e35164d648a92e..ef7f07e83c53945d23f4cfa4a3293dfad3ac5782 100644 --- a/tests/system_base/util-linux/tc_ag_util-linux_chrt_fun_002.py +++ b/tests/system_base/util-linux/tc_ag_util-linux_chrt_fun_002.py @@ -19,7 +19,7 @@ class Test(LocalTest): :avocado: tags=fix,P1,noarch,local,ag """ - PARAM_DIC = {"pkg_name": "util-linux"} + PARAM_DIC = {"pkg_name": "util-linux procps-ng"} def setUp(self): super().setUp(self.PARAM_DIC) os.system('sleep 1000 &') diff --git a/tests/system_base/util-linux/tc_ag_util-linux_prlimit_fun_002.py b/tests/system_base/util-linux/tc_ag_util-linux_prlimit_fun_002.py index 9c0248f976205ca4baa1d1333e81f18ec0289923..b40229c9e412ab85ef3c8b2d16819a9b0c892d21 100644 --- a/tests/system_base/util-linux/tc_ag_util-linux_prlimit_fun_002.py +++ b/tests/system_base/util-linux/tc_ag_util-linux_prlimit_fun_002.py @@ -19,7 +19,7 @@ class Test(LocalTest): :avocado: tags=fix,P1,noarch,local,ag """ - PARAM_DIC = {"pkg_name": "util-linux"} + PARAM_DIC = {"pkg_name": "util-linux procps-ng"} def setUp(self): super().setUp(self.PARAM_DIC) os.system('sleep 1000 &') @@ -37,4 +37,4 @@ class Test(LocalTest): def tearDown(self): super().tearDown(self.PARAM_DIC) - self.cmd("kill -9 %s" % self.pid) \ No newline at end of file + self.cmd("kill -9 %s" % self.pid) diff --git a/tests/system_base/util-linux/tc_ag_util-linux_prlimit_fun_003.py b/tests/system_base/util-linux/tc_ag_util-linux_prlimit_fun_003.py index 717ecd7c14cfadd3da904ceb28ce97cc72944eba..a450d50dbc40e6a7996d576a9530ad325a012614 100644 --- a/tests/system_base/util-linux/tc_ag_util-linux_prlimit_fun_003.py +++ b/tests/system_base/util-linux/tc_ag_util-linux_prlimit_fun_003.py @@ -19,7 +19,7 @@ class Test(LocalTest): :avocado: tags=fix,P1,noarch,local,ag """ - PARAM_DIC = {"pkg_name": "util-linux"} + PARAM_DIC = {"pkg_name": "util-linux procps-ng"} def setUp(self): super().setUp(self.PARAM_DIC) os.system('sleep 1000 &') @@ -34,4 +34,4 @@ class Test(LocalTest): def tearDown(self): super().tearDown(self.PARAM_DIC) - self.cmd("kill -9 %s" % self.pid) \ No newline at end of file + self.cmd("kill -9 %s" % self.pid) diff --git a/tests/system_base/util-linux/tc_ag_util-linux_taskset_fun_001.py b/tests/system_base/util-linux/tc_ag_util-linux_taskset_fun_001.py index d6095e50d5bae1044cce86c76d402c20fda57873..b2aea9d30a9a46ac124bc80e580edb39cf5c77e0 100644 --- a/tests/system_base/util-linux/tc_ag_util-linux_taskset_fun_001.py +++ b/tests/system_base/util-linux/tc_ag_util-linux_taskset_fun_001.py @@ -19,7 +19,7 @@ class Test(LocalTest): :avocado: tags=fix,P1,noarch,local,ag """ - PARAM_DIC = {"pkg_name": "util-linux"} + PARAM_DIC = {"pkg_name": "util-linux procps-ng"} def setUp(self): super().setUp(self.PARAM_DIC) os.system('sleep 1000 &') @@ -31,4 +31,4 @@ class Test(LocalTest): def tearDown(self): super().tearDown(self.PARAM_DIC) - self.cmd("kill -9 %s" % self.pid) \ No newline at end of file + self.cmd("kill -9 %s" % self.pid) diff --git a/tests/system_base/util-linux/tc_ag_util-linux_taskset_fun_002.py b/tests/system_base/util-linux/tc_ag_util-linux_taskset_fun_002.py index 10981357ad0d7e06b8c347082aa5ce9161819261..7afb7abfc89e130521305a4803b01f83d0896c93 100644 --- a/tests/system_base/util-linux/tc_ag_util-linux_taskset_fun_002.py +++ b/tests/system_base/util-linux/tc_ag_util-linux_taskset_fun_002.py @@ -19,7 +19,7 @@ class Test(LocalTest): :avocado: tags=fix,P1,noarch,local,ag """ - PARAM_DIC = {"pkg_name": "util-linux"} + PARAM_DIC = {"pkg_name": "util-linux procps-ng"} def setUp(self): super().setUp(self.PARAM_DIC) os.system('sleep 1000 &') diff --git a/tests/system_base/util-linux/tc_ag_util-linux_taskset_fun_003.py b/tests/system_base/util-linux/tc_ag_util-linux_taskset_fun_003.py index aebf4a602143095ec628b28a32a08f1d327596c2..24bd6e4407b991f706cdf65a59615b7cc1e2fe0d 100644 --- a/tests/system_base/util-linux/tc_ag_util-linux_taskset_fun_003.py +++ b/tests/system_base/util-linux/tc_ag_util-linux_taskset_fun_003.py @@ -19,7 +19,7 @@ class Test(LocalTest): :avocado: tags=fix,P1,noarch,local,ag """ - PARAM_DIC = {"pkg_name": "util-linux"} + PARAM_DIC = {"pkg_name": "util-linux procps-ng"} def setUp(self): super().setUp(self.PARAM_DIC) diff --git a/tests/system_base/util-linux/tc_ag_util-linux_taskset_fun_004.py b/tests/system_base/util-linux/tc_ag_util-linux_taskset_fun_004.py index cd98c024c307fbef148fc266342d794be50a947e..927eb67df4298222ba78a4a7528dc03de650ef5a 100644 --- a/tests/system_base/util-linux/tc_ag_util-linux_taskset_fun_004.py +++ b/tests/system_base/util-linux/tc_ag_util-linux_taskset_fun_004.py @@ -19,7 +19,7 @@ class Test(LocalTest): :avocado: tags=fix,P1,noarch,local,ag """ - PARAM_DIC = {"pkg_name": "util-linux"} + PARAM_DIC = {"pkg_name": "util-linux procps-ng"} def setUp(self): super().setUp(self.PARAM_DIC) diff --git a/tests/system_base/util-linux/tc_ag_util-linux_taskset_fun_005.py b/tests/system_base/util-linux/tc_ag_util-linux_taskset_fun_005.py index 8b9cab7542dc916cf195cbe3721657628e6632de..c473aaadd579c89926ec7a6881532a26c584259a 100644 --- a/tests/system_base/util-linux/tc_ag_util-linux_taskset_fun_005.py +++ b/tests/system_base/util-linux/tc_ag_util-linux_taskset_fun_005.py @@ -19,7 +19,7 @@ class Test(LocalTest): :avocado: tags=fix,P1,noarch,local,ag """ - PARAM_DIC = {"pkg_name": "util-linux"} + PARAM_DIC = {"pkg_name": "util-linux procps-ng"} def setUp(self): super().setUp(self.PARAM_DIC) diff --git a/tests/system_libraries/expat/tc_expat_fun_001.py b/tests/system_libraries/expat/tc_expat_fun_001.py new file mode 100644 index 0000000000000000000000000000000000000000..7db741400eb7f2c2c4a4a03ca14a2ce6ccbc8829 --- /dev/null +++ b/tests/system_libraries/expat/tc_expat_fun_001.py @@ -0,0 +1,139 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_expat_fun_001.py +@Time: 2024/04/02 11:12:50 +@Author: hongfeng +@Version: 1.0 +@Contact: wb-zhf668260@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: hongfeng +""" + +import os +from common.basetest import LocalTest +class Test(LocalTest): + """ + See tc_expat_fun_001.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "expat-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = """cat > expat.c < +#include +#include +#include + +void XMLCALL startElement(void *userData, const char *name, const char **atts) { + // 处理逻辑 + printf("startElement name: %s\\n", name); +} + +void XMLCALL endElement(void *userData, const char *name) { + // 处理逻辑 + printf("endElement name: %s\\n", name); +} + +void XMLCALL characterDataHandler(void *userData, const char *s, int len) { + if(len == 0){ + return; + } + + // 创建一个新的缓冲区用于存储处理过的字符数据 + char* processed_data = malloc(len + 1); + int new_len = 0; + + for (int i = 0; i < len; ++i) { + if (s[i] != '\\r' && s[i] != '\\n' && !isspace((unsigned char)s[i])) { // 忽略回车、换行符以及所有空格字符 + processed_data[new_len++] = s[i]; + } + } + + // 添加字符串结束符 + processed_data[new_len] = '\\0'; + if(new_len != 0) { + printf("characterDataHandler: %s\\n", processed_data); + } + + // 记得在适当的时候释放 processed_data 的内存 + free(processed_data); +} + +int main() { + char buf[1024]; + int done; + XML_Parser parser = XML_ParserCreate(NULL); + if (!parser) { + fprintf(stderr, "Unable to create parser\\n"); + return 1; + } + + XML_SetUserData(parser, NULL); // 设置用户数据指针 + XML_SetElementHandler(parser, startElement, endElement); + XML_SetCharacterDataHandler(parser, characterDataHandler); + + FILE *fp = fopen("test.xml", "r"); + do { + int len = (int)fread(buf, 1, sizeof(buf), fp); + done = len < sizeof(buf); + if (XML_Parse(parser, buf, len, done) == XML_STATUS_ERROR) { + fprintf(stderr, "Error: %s at line %d\\n", + XML_ErrorString(XML_GetErrorCode(parser)), + (int)XML_GetCurrentLineNumber(parser)); + return 1; + } + } while (!done); + + XML_ParserFree(parser); + return 0; +} +EOF""" + self.cmd(cmdline) + self.cmd("gcc -o expat expat.c `pkg-config --cflags --libs expat`") + file_dir = os.path.dirname(__file__) + self.cmd(f"cp {file_dir}/test.xml ./test.xml") + + def test(self): + ret_c, ret_o = self.cmd("./expat") + + # 期望解析的结果 + expected_sequence = [ + ("startElement name", "note"), + ("startElement name", "from"), + ("characterDataHandler", "A"), + ("endElement name", "from"), + ("startElement name", "to"), + ("characterDataHandler", "B"), + ("endElement name", "to"), + ("startElement name", "heading"), + ("characterDataHandler", "Test"), + ("endElement name", "heading"), + ("startElement name", "body"), + ("characterDataHandler", "Helloworld!"), + ("endElement name", "body"), + ("endElement name", "note") + ] + + # 将输出字符串分割为行 + output_lines = ret_o.split("\n") + self.assertEqual(len(expected_sequence), len(output_lines), "%s should equal to %s" % (len(expected_sequence), len(output_lines))) + + # 遍历每一行, 检查输出是按照解析顺序打印的 + current_position = 0 + for line in output_lines: + # 去除末尾空格并按冒号拆分以获取事件类型和数据 + event_info = line.strip().split(":") + event_type, data = event_info[0].strip(), event_info[1].strip() if len(event_info) > 1 else None + expected_event_type, expected_data = expected_sequence[current_position] + + self.assertEqual(expected_event_type, event_type, "%s should equal to %s" % (expected_event_type, event_type)) + self.assertEqual(expected_data, data, "%s should equal to %s" % (expected_data, data)) + current_position += 1 + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm expat.c expat test.xml") diff --git a/tests/system_libraries/expat/test.xml b/tests/system_libraries/expat/test.xml new file mode 100644 index 0000000000000000000000000000000000000000..c0d2573edae4c99ab37380a4318a5a9c5f47f7d9 --- /dev/null +++ b/tests/system_libraries/expat/test.xml @@ -0,0 +1,7 @@ + + + A + B + Test + Hello world! + diff --git a/tests/system_libraries/gnupg2/tc_gnupg_gpg_func_001.py b/tests/system_libraries/gnupg2/tc_gnupg_gpg_func_001.py new file mode 100644 index 0000000000000000000000000000000000000000..58489ebb041d2f181ea3c79be8836cf2630b64f6 --- /dev/null +++ b/tests/system_libraries/gnupg2/tc_gnupg_gpg_func_001.py @@ -0,0 +1,57 @@ +#! /usr/bin/env python3 +# -*- encoding: utf-8 -*- +""" +@File: tc_gnupg_gpg_func_001.py +@Time: 2024年02月29日16:06:08 +@Author: Liujiang +@License: Mulan PSL v2 +@Modified: Liujiang +""" + +from common.basetest import LocalTest +from common.gpg import Gnupg2Manager + +class Test(LocalTest): + """ + Ensure that gnupg2 can successfully generate a new key pair, + encrypt the file with the generated public key, + and then decrypt the file with the corresponding private key. + See tc_gnupg_gpg_func_001.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + + PARAM_DIC = {"pkg_name": "gnupg2"} + def setUp(self): + super().setUp(self.PARAM_DIC) + + def test(self): + # Generate the key pair + keypair_id = Gnupg2Manager.generate_fixed_parameter_key_pair( + self, + name="John Doe", + email="johndoe_001@example.com", + testpasswd="mysecretpassphrase",) + + # Encrypt and decrypt files + ## encrypt + self.cmd("echo 'This is a test' > test.txt") + statu = Gnupg2Manager.encryption_data( + self, recipient='johndoe_001@example.com', file="test.txt") + self.assertTrue(statu, msg="Encryption failed.") + + ## decrypt + statu = Gnupg2Manager.decryption_data( + self, decrypted_file="test.txt.gpg", testpasswd="mysecretpassphrase") + self.assertTrue(statu, msg="Encryption failed.") + + ## Compare whether the file encryption and decryption are + ## consistent before and after comparison + self.cmd("diff test.txt test.txt.gpg.txt") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf test.txt test.txt.gpg test.txt.gpg.txt ") + keypair_id = Gnupg2Manager.get_keypair_id(self, user="johndoe_001@example.com") + statu = Gnupg2Manager.delete_key_pair(self, keypair_id, email="johndoe_001@example.com") + self.assertTrue(statu, msg="Delete keypair failed.") diff --git a/tests/system_libraries/gnupg2/tc_gnupg_gpg_func_002.py b/tests/system_libraries/gnupg2/tc_gnupg_gpg_func_002.py new file mode 100644 index 0000000000000000000000000000000000000000..40f2b329cec27bc7e95c5a524ed4ec1158407275 --- /dev/null +++ b/tests/system_libraries/gnupg2/tc_gnupg_gpg_func_002.py @@ -0,0 +1,92 @@ +#! /usr/bin/env python +# -*- encoding: utf-8 -*- +""" +@File: tc_gnupg_gpg_func_002.py +@Time: 2024年02月29日16:06:08 +@Author: Liujiang +@License: Mulan PSL v2 +@Modified: Liujiang +""" + +from common.basetest import LocalTest +from common.gpg import Gnupg2Manager + +class Test(LocalTest): + """ + Verify the GnuPG key key import/export function + See tc_gnupg_gpg_func_002.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + + PARAM_DIC = {"pkg_name": "gnupg2"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline_generate_script = """cat > export_private_key.sh < myprivatekey.asc\\r"} +} +expect { + "Passphrase: " { send "mysecretpassphrase\\r";} +} +expect { + "# " {send "\\r"} +} +set sensitive_data "" +expect eof +exit +EOF +""" + self.cmd(cmdline_generate_script) + + def test(self): + # Generate the key pair + keypair_id = Gnupg2Manager.generate_fixed_parameter_key_pair( + self, + name="John Doe", + email="johndoe_002@example.com", + testpasswd="mysecretpassphrase",) + + # Export public and private keys of self + ## Export public + statu = Gnupg2Manager.export_public_key( + self, keypair_id, publickey_file="mypublickey.asc" + ) + self.assertTrue(statu, msg="Export public failed.") + + ## Export private + self.cmd("chmod +x export_private_key.sh; ./export_private_key.sh %s" %keypair_id) + code, publickey_res = self.cmd("file mypublickey.asc") + code, privatekey_res = self.cmd("file myprivatekey.asc") + self.assertIn("PGP public key block", publickey_res) + self.assertIn("PGP private key block", privatekey_res) + + # Delete key pair + keypair_id = Gnupg2Manager.get_keypair_id(self, user="johndoe_002@example.com") + statu = Gnupg2Manager.delete_key_pair(self, keypair_id, email="johndoe_002@example.com") + self.assertTrue(statu, msg="Delete keypair failed.") + + # Import public and private key of self + ## Import public key + statu = Gnupg2Manager.import_public_key( + self, publickey_file="mypublickey.asc", email="johndoe_002@example.com" + ) + self.assertTrue(statu, msg="Import public key failed.") + + ## Import private key + statu = Gnupg2Manager.import_private_key( + self, privatekey_file="myprivatekey.asc", email="johndoe_002@example.com" + ) + self.assertTrue(statu, msg="Import private key failed.") + Gnupg2Manager.get_keypair_id(self, user="johndoe_002@example.com") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf key_params.txt export_private_key.sh mypublickey.asc myprivatekey.asc") + keypair_id = Gnupg2Manager.get_keypair_id(self, user="johndoe_002@example.com") + statu = Gnupg2Manager.delete_key_pair(self, keypair_id, email="johndoe_002@example.com") + self.assertTrue(statu, msg="Delete keypair failed.") \ No newline at end of file diff --git a/tests/system_libraries/gnupg2/tc_gnupg_gpg_func_003.py b/tests/system_libraries/gnupg2/tc_gnupg_gpg_func_003.py new file mode 100644 index 0000000000000000000000000000000000000000..87f30fe67a17ff2c442fc183a4bfaab4d6189075 --- /dev/null +++ b/tests/system_libraries/gnupg2/tc_gnupg_gpg_func_003.py @@ -0,0 +1,94 @@ +#! /usr/bin/env python +# -*- encoding: utf-8 -*- +""" +@File: tc_gnupg_gpg_func_003.py +@Time: 2024年02月29日16:06:08 +@Author: Liujiang +@License: Mulan PSL v2 +@Modified: Liujiang +""" + +from common.basetest import LocalTest +from datetime import datetime +from common.gpg import Gnupg2Manager + +class Test(LocalTest): + """ + Verify whether gpg can add and update the validity period of keys normally + See tc_gnupg_gpg_func_003.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + + PARAM_DIC = {"pkg_name": "gnupg2 expect"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline_generate_script = """cat >update_expire_script.sh< " { send "expire\\r";} +} +expect { + "Key is valid for\? \(0\) " {send "\$arg2\\r"} +} +expect { + "Is this correct\? \(y/N\) " {send "y\\r"} +} +expect { + "Passphrase: " {send "mysecretpassphrase\\r"} +} +expect { + "gpg> " {send "save\\r"} +} +set sensitive_data "" +expect eof +exit +EOF +""" + self.cmd(cmdline_generate_script) + + def test(self): + # Generate the key pair + keypair_id = Gnupg2Manager.generate_fixed_parameter_key_pair( + self, + name="John Doe", + email="johndoe_003@example.com", + testpasswd="mysecretpassphrase",) + + # Add the validity period of the key + expire_value = 1 + coed, create_date = self.cmd( + "gpg --list-keys johndoe_003@example.com |awk '/pub/ {print $3}'") + + self.cmd("chmod +x update_expire_script.sh; ./update_expire_script.sh %s %s" + %(keypair_id, expire_value)) + code, expires_date = self.cmd( + "gpg --list-keys johndoe_003@example.com |awk -F']|[[:space:]]' '/pub/ {print $9}'") + datetime1 = datetime.strptime(create_date, "%Y-%m-%d") + datetime2 = datetime.strptime(expires_date, "%Y-%m-%d") + date_diff = datetime2 - datetime1 + self.assertEquals(date_diff.days, expire_value) + + # Update the validity period of the key + expire_value = 2 + self.cmd("./update_expire_script.sh %s %s" %(keypair_id, expire_value)) + code, update_date = self.cmd( + "gpg --list-keys johndoe_003@example.com |awk -F']|[[:space:]]' '/pub/ {print $9}'") + datetime3 = datetime.strptime(update_date, "%Y-%m-%d") + date_diff = datetime3 - datetime2 + self.assertEquals(date_diff.days, expire_value-1) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf key_params.txt update_expire_script.sh") + keypair_id = Gnupg2Manager.get_keypair_id(self, user="johndoe_003@example.com") + statu = Gnupg2Manager.delete_key_pair(self, keypair_id, email="johndoe_003@example.com") + self.assertTrue(statu, msg="Delete keypair failed.") + diff --git a/tests/system_libraries/gnupg2/tc_gnupg_gpg_func_004.py b/tests/system_libraries/gnupg2/tc_gnupg_gpg_func_004.py new file mode 100644 index 0000000000000000000000000000000000000000..cc5ab0e9084c18265b963eac40c57f2e96187d61 --- /dev/null +++ b/tests/system_libraries/gnupg2/tc_gnupg_gpg_func_004.py @@ -0,0 +1,218 @@ +#! /usr/bin/env python +# -*- encoding: utf-8 -*- +""" +@File: tc_gnupg_gpg_func_004.py +@Time: 2024年02月29日16:06:08 +@Author: Liujiang +@License: Mulan PSL v2 +@Modified: Liujiang +""" + +from common.basetest import LocalTest +from common.gpg import Gnupg2Manager + +class Test(LocalTest): + """ + Test key addition or removal of user ID and signature functionality + See tc_gnupg_gpg_func_004.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + + PARAM_DIC = {"pkg_name": "gnupg2 expect"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline_generate_add_userid_script = """cat >add_userID_script.sh< " { send "adduid\\r";} +} +expect { + "Real name: " {send "Klay Thompson\\r"} +} +expect { + "Email address: " {send "Thompson@example.com\\r"} +} +expect { + "Comment: " {send "This is a test\\r"} +} +expect { + "Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit?" {send "O\\r"} +} +expect { + "Passphrase: " {send "mysecretpassphrase\\r"} +} +expect { + "gpg> " {send "save\\r"} +} +expect eof +exit +EOF +""" + cmdline_generate_remove_sign_script = '''cat >remove_sign_script.sh< " { send "uid 1\\r";} +} +expect { + "gpg> " { send "revsig\\r";} +} +expect { + "Create a revocation certificate for this signature? (y/N) " { send "y\\r";} +} +expect { + "Really create the revocation certificates? (y/N) " { send "y\\r";} +} +expect { + "Your decision? " { send "0\\r";} +} +expect { + "> " {send "\\r"} +} +expect { + "Is this okay? (y/N) " {send "y\\r"} +} +expect { + "Passphrase: " {send "mysecretpassphrase\\r"} +} +expect { + "gpg> " {send "delsig\\r"} +} +expect { + "Delete this good signature? (y/N/q)" {send "y\\r"} +} +expect { + "Really delete this self-signature? (y/N)" {send "y\\r"} +} +expect { + "Delete this good signature? (y/N/q)" {send "y\\r"} +} +expect { + "Really delete this self-signature? (y/N)" {send "y\\r"} +} +expect { + "gpg> " {send "save\\r"} +} +expect eof +exit +EOF +''' + cmdline_generate_add_sign_script = '''cat >add_sign_script.sh< " { send "uid 2\\r";} +} +expect { + "gpg> " { send "sign\\r";} +} +expect { + "Really sign? (y/N) " { send "y\\r";} +} +expect { + "Passphrase: " {send "mysecretpassphrase\\r"} +} +expect { + "gpg> " {send "save\\r"} +} +expect eof +exit +EOF +''' + cmdline_generate_remove_userid_script = '''cat >remove_userID_script.sh< " { send "uid 1\\r";} +} +expect { + "gpg> " {send "revuid\\r"} +} +expect { + "Really revoke this user ID? (y/N) " {send "y\\r"} +} +expect { + "Your decision? " {send "0\\r"} +} +expect { + "> " {send "\\r"} +} +expect { + "Is this okay? (y/N) " {send "y\\r"} +} +expect { + "Passphrase: " {send "mysecretpassphrase\\r"} +} +expect { + "gpg> " {send "save\\r"} +} +expect eof +exit +EOF +''' + self.cmd(cmdline_generate_add_userid_script) + self.cmd(cmdline_generate_remove_sign_script) + self.cmd(cmdline_generate_add_sign_script) + self.cmd(cmdline_generate_remove_userid_script) + + def test(self): + # Generate the key pair + keypair_id = Gnupg2Manager.generate_fixed_parameter_key_pair( + self, + name="John Doe", + email="johndoe_004@example.com", + testpasswd="mysecretpassphrase",) + + # Add user IDs for the key. + self.cmd("chmod +x add_userID_script.sh; ./add_userID_script.sh %s" %(keypair_id)) + code, list_keys = self.cmd("gpg --list-keys") + self.assertIn("Klay Thompson", list_keys) + code, list_secret_keys = self.cmd("gpg --list-secret-keys") + self.assertIn("Klay Thompson", list_secret_keys) + + # Remove + code, list_sign = self.cmd("gpg --list-sigs |grep 'Thompson@example.com' -A 1") + self.assertIn("sig", list_sign) + self.cmd("chmod +x remove_sign_script.sh; ./remove_sign_script.sh %s" %(keypair_id)) + code, list_sign = self.cmd("gpg --list-sigs |grep 'Thompson@example.com' -A 1") + self.assertNotIn("sig", list_sign) + + # Add + self.cmd("chmod +x add_sign_script.sh; ./add_sign_script.sh %s" %(keypair_id)) + code, list_sign = self.cmd("gpg --list-sigs |grep 'Thompson@example.com' -A 1") + self.assertIn("sig", list_sign) + + # remove user IDs for the key. + self.cmd("chmod +x remove_userID_script.sh; ./remove_userID_script.sh %s" %(keypair_id)) + code, list_keys = self.cmd("gpg --list-keys") + self.assertNotIn("Klay Thompson", list_keys) + code, list_secret_keys = self.cmd("gpg --list-secret-keys") + self.assertNotIn("Klay Thompson", list_secret_keys) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf key_params.txt add_userID_script.sh remove_userID_script.sh "+ + "remove_sign_script.sh add_sign_script.sh") + keypair_id = Gnupg2Manager.get_keypair_id(self, + user="johndoe_004@example.com") + statu = Gnupg2Manager.delete_key_pair(self, keypair_id, + email="johndoe_004@example.com") + self.assertTrue(statu, msg="Delete keypair failed.") \ No newline at end of file diff --git a/tests/system_libraries/gnupg2/tc_gnupg_gpg_func_005.py b/tests/system_libraries/gnupg2/tc_gnupg_gpg_func_005.py new file mode 100644 index 0000000000000000000000000000000000000000..bc138620f31690d68263f35f9eca49b35b1a31dd --- /dev/null +++ b/tests/system_libraries/gnupg2/tc_gnupg_gpg_func_005.py @@ -0,0 +1,73 @@ +#! /usr/bin/env python +# -*- encoding: utf-8 -*- +""" +@File: tc_gnupg_gpg_func_005.py +@Time: 2024年02月29日16:06:08 +@Author: Liujiang +@License: Mulan PSL v2 +@Modified: Liujiang +""" + +from common.basetest import LocalTest +from common.gpg import Gnupg2Manager + +class Test(LocalTest): + """ + Test revocation key and generate revocation certificate functionality + See tc_gnupg_gpg_func_005.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + + PARAM_DIC = {"pkg_name": "gnupg2 expect"} + def setUp(self): + super().setUp(self.PARAM_DIC) + + def test(self): + # Generate the key pair + keypair_id = Gnupg2Manager.generate_fixed_parameter_key_pair( + self, + name="John Doe", + email="johndoe_005@example.com", + testpasswd="mysecretpassphrase",) + + # Generate Revocation Certificate + statu = Gnupg2Manager.generate_revocation_certificate( + self, + user="johndoe_005@example.com", + certificate_file="revoke_certificate.crs" + ) + self.assertTrue(statu, msg="Generate revocation failed.") + + # Revoke Key + code, list_keys = self.cmd("gpg --list-secret-keys") + self.assertNotIn("revoked:", list_keys) + statu = Gnupg2Manager.revoke_key_with_certificate( + self, + certificate="revoke_certificate.crs" + ) + self.assertTrue(statu, msg="revoke key failed.") + + # signature file + self.cmd("echo 'This is a test file' > file.txt") + statu = Gnupg2Manager.make_detached_signature( + self, + user="johndoe_005@example.com", + testpasswd="mysecretpassphrase", + signature_file="file.txt.gpg", + file="file.txt" + ) + self.assertFalse(statu, + msg="The expected result is that the key has been revoked and" + + "the file signature has failed.") + self.log.info("Key revocation and file signing failure are expected.") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf key_params.txt generate_certificate.sh \ + revoke_key_script.sh revoke_certificate.crs") + keypair_id = Gnupg2Manager.get_keypair_id(self, + user="johndoe_005@example.com") + statu = Gnupg2Manager.delete_key_pair(self, keypair_id, + email="johndoe_005@example.com") + self.assertTrue(statu, msg="Delete keypair failed.") \ No newline at end of file diff --git a/tests/system_libraries/gnupg2/tc_gnupg_gpg_func_006.py b/tests/system_libraries/gnupg2/tc_gnupg_gpg_func_006.py new file mode 100644 index 0000000000000000000000000000000000000000..f8d7b21eb75bd6a1ab6b55ca697af0b1aaf8fa60 --- /dev/null +++ b/tests/system_libraries/gnupg2/tc_gnupg_gpg_func_006.py @@ -0,0 +1,85 @@ +#! /usr/bin/env python +# -*- encoding: utf-8 -*- +""" +@File: tc_gnupg_gpg_func_006.py +@Time: 2024年02月29日16:06:08 +@Author: Liujiang +@License: Mulan PSL v2 +@Modified: Liujiang +""" + +from common.basetest import LocalTest +from common.gpg import Gnupg2Manager + +class Test(LocalTest): + """ + Test whether the GPG can use a private key for + data signing and verify it using a public key. + See tc_gnupg_gpg_func_006.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + + PARAM_DIC = {"pkg_name": "gnupg2"} + def setUp(self): + super().setUp(self.PARAM_DIC) + + def test(self): + # Generate the key pair + keypair_id = Gnupg2Manager.generate_fixed_parameter_key_pair( + self, + name="John Doe", + email="johndoe_006@example.com", + testpasswd="mysecretpassphrase",) + + # Create signature + ## Detached signature + self.cmd("echo 'This is a test file' > file.txt") + statu = Gnupg2Manager.make_detached_signature( + self, + user="johndoe_006@example.com", + testpasswd="mysecretpassphrase", + signature_file="file.txt.detached.gpg", + file="file.txt" + ) + self.assertTrue(statu, msg="make detached signature faild.") + + ## Cleartext Signature + statu = Gnupg2Manager.make_clearsign_signature( + self, + user="johndoe_006@example.com", + testpasswd="mysecretpassphrase", + signature_file="file.txt.clearsign.gpg", + file="file.txt" + ) + self.assertTrue(statu, msg="make clearsign signature faild.") + self.cmd("cat file.txt.clearsign.gpg |grep 'This is a test file'") + + # Verify signature + ## Detached signature + context = Gnupg2Manager.verify_detached_signature( + self, + user="johndoe_006@example.com", + file="file.txt", + signature_file="file.txt.detached.gpg", + ) + self.assertEqual(context[0], 0, msg="verify detached signature failed.") + + ## Cleartext Signature + context = Gnupg2Manager.verify_cleartext_signature( + self, + user="johndoe_006@example.com", + signature_file="file.txt.clearsign.gpg", + ) + self.assertEqual(context[0], 0, msg="verify cleartext signature failed.") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf file.txt file.txt.clearsign.gpg file.txt.detached.gpg") + keypair_id = Gnupg2Manager.get_keypair_id(self, + user="johndoe_006@example.com") + statu = Gnupg2Manager.delete_key_pair(self, keypair_id, + email="johndoe_006@example.com") + self.assertTrue(statu, msg="Delete keypair failed.") + + diff --git a/tests/system_libraries/gnupg2/tc_gnupg_gpg_func_007.py b/tests/system_libraries/gnupg2/tc_gnupg_gpg_func_007.py new file mode 100644 index 0000000000000000000000000000000000000000..66515cf405ffe7320985571aea2c8a3800777005 --- /dev/null +++ b/tests/system_libraries/gnupg2/tc_gnupg_gpg_func_007.py @@ -0,0 +1,94 @@ +#! /usr/bin/env python +# -*- encoding: utf-8 -*- +""" +@File: tc_gnupg_gpg_func_007.py +@Time: 2024年02月29日16:06:08 +@Author: Liujiang +@License: Mulan PSL v2 +@Modified: Liujiang +""" + +from common.basetest import LocalTest +from common.gpg import Gnupg2Manager + +class Test(LocalTest): + """ + Verify if the default key setting in the gpg.conf file is + correctly applied to GPG operations. + See tc_gnupg_gpg_func_007.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + + PARAM_DIC = {"pkg_name": "gnupg2 expect"} + def setUp(self): + super().setUp(self.PARAM_DIC) +# cmdline_generate_params = """cat >key_params.txt<signature.txt<detached_signature.sh<> /root/.gnupg/gpg.conf" %keypair_id) + self.cmd("gpg-connect-agent reloadagent /bye") + self.cmd("gpgconf --reload gpg-agent") + + # Create signature and assert configuration taking effect. + code, signature_output = self.cmd( + "chmod +x detached_signature.sh; ./detached_signature.sh") + self.assertIn("as default secret key for signing" , signature_output) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("sed -i '/default-key/d' /root/.gnupg/gpg.conf") + self.cmd("gpg-connect-agent reloadagent /bye") + self.cmd("gpgconf --reload gpg-agent") + self.cmd("rm -rf key_params.txt signature.txt \ + detached_signature.sh signature.txt.sig") + keypair_id = Gnupg2Manager.get_keypair_id(self, + user="johndoe_007@example.com") + statu = Gnupg2Manager.delete_key_pair(self, keypair_id, + email="johndoe_007@example.com") + self.assertTrue(statu, msg="Delete keypair failed.") + diff --git a/tests/system_libraries/gnupg2/tc_gnupg_gpg_func_008.py b/tests/system_libraries/gnupg2/tc_gnupg_gpg_func_008.py new file mode 100644 index 0000000000000000000000000000000000000000..2d0dd78b04d0a3d3defd1651a0378c2471b3d306 --- /dev/null +++ b/tests/system_libraries/gnupg2/tc_gnupg_gpg_func_008.py @@ -0,0 +1,111 @@ +#! /usr/bin/env python +# -*- encoding: utf-8 -*- +""" +@File: tc_gnupg_gpg_func_008.py +@Time: 2024年02月29日16:06:08 +@Author: Liujiang +@License: Mulan PSL v2 +@Modified: Liujiang +""" + +from common.basetest import LocalTest +from common.gpg import Gnupg2Manager + +class Test(LocalTest): + """ + Test the trust level functionality of adding and modifying keys + See tc_gnupg_gpg_func_008.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + + PARAM_DIC = {"pkg_name": "gnupg2 expect"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline_generate_publickey = """cat >publickey.asc<update_trust_script.sh< " {send "trust\\r"} +} +expect { + "Your decision? " {send "5\\r"} +} +expect { + "Do you really want to set this key to ultimate trust? (y/N) " {send "y\\r"} +} +expect { + "gpg> " {send "save\\r"} +} +expect eof +exit +EOF +''' + self.cmd(cmdline_generate_publickey) + self.cmd(cmdline_generate_update_trust_script) + + def test(self): + statu = Gnupg2Manager.import_public_key( + self, + publickey_file="publickey.asc", + email="anliu@123.com") + self.assertTrue(statu, msg="import public key failed.") + + # Get the key_id of the key pair + keypair_id = Gnupg2Manager.get_keypair_id(self, user="anliu@123.com") + + # Check trust level + code, list_keys = self.cmd("gpg --list-keys") + self.assertIn("[ unknown]" , list_keys) + # Update trust level + self.cmd("chmod +x update_trust_script.sh; ./update_trust_script.sh %s" %(keypair_id)) + # Check trust level + code, list_keys = self.cmd("gpg --list-keys") + self.assertIn("[ultimate]" , list_keys) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf key_params.txt publickey.asc update_trust_script.sh") + keypair_id = Gnupg2Manager.get_keypair_id(self, + user="anliu@123.com") + statu = Gnupg2Manager.delete_key_pair(self, keypair_id, + email="anliu@123.com") + self.assertTrue(statu, msg="Delete keypair failed.") diff --git a/tests/system_libraries/gnupg2/tc_gnupg_gpg_func_009.py b/tests/system_libraries/gnupg2/tc_gnupg_gpg_func_009.py new file mode 100644 index 0000000000000000000000000000000000000000..ad1fc2cb722a5a8c43b24b59ca5da494e168d561 --- /dev/null +++ b/tests/system_libraries/gnupg2/tc_gnupg_gpg_func_009.py @@ -0,0 +1,138 @@ +#! /usr/bin/env python +# -*- encoding: utf-8 -*- +""" +@File: tc_gnupg_gpg_func_009.py +@Time: 2024年02月29日16:06:08 +@Author: Liujiang +@License: Mulan PSL v2 +@Modified: Liujiang +""" + +from common.basetest import LocalTest +from common.gpg import Gnupg2Manager + +class Test(LocalTest): + """ + Test whether the signature can be correctly verified + after importing the public key + See tc_gnupg_gpg_func_009.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + + PARAM_DIC = {"pkg_name": "gnupg2"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline_generate_publickey = """cat >publickey.asc<document.txt<document.txt.sig<"', context[1], + msg="The verification result does not meet expectations, " + + "please manually check") + + # ampering signature files + self.cmd("sed -i 's/i/1/' document.txt.sig") + # Verify signature + context = Gnupg2Manager.verify_detached_signature(self, + user="anliu@123.com", + file="document.txt", + signature_file="document.txt.sig", + ignore_status=True + ) + self.assertNotEqual(context[0], 0, + msg="Tampering the signature file," + + " expected verification result failed.") + self.assertIn('the signature could not be verified', context[1], + msg="The result does not meet expectations, " + + "please manually check") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf publickey.asc document.txt document.txt.sig") + keypair_id = Gnupg2Manager.get_keypair_id(self, + user="anliu@123.com") + statu = Gnupg2Manager.delete_key_pair(self, keypair_id, + email="anliu@123.com") + self.assertTrue(statu, msg="Delete keypair failed.") + diff --git a/tests/system_libraries/gnutls/server.crt b/tests/system_libraries/gnutls/server.crt new file mode 100644 index 0000000000000000000000000000000000000000..6cf6569e328eb9f9cf09459fdff7127fba5003f9 --- /dev/null +++ b/tests/system_libraries/gnutls/server.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDTCCAfUCFCDsCgKOZI0WvRZ6fnWxNFuAL1LHMA0GCSqGSIb3DQEBCwUAMEIx +CzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0Rl +ZmF1bHQgQ29tcGFueSBMdGQwIBcNMjQwNDEwMDU1OTI2WhgPMjEyNDAzMTcwNTU5 +MjZaMEIxCzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNV +BAoME0RlZmF1bHQgQ29tcGFueSBMdGQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQCcTGbCjnPgn09XAny8T87ZNPS7Vr/JpHziAO/2blon9dSDC0mCeTNm +vuqJ11cEItgaFooV4325kcFlKQIF+L8p3+DpZVHMmPpv604/CHnjzFKpsAv3FflA +X3uFf6nYprojnhOcqwPedzW3qT0S34rBY2pQV9FPuUWZ85B8N5QOQ1RmIRaml7qB +VOlLABuH2bcb3nKr+HlihM/a/YWu9wVHhmA1ffJDN6HOnPcBTJQEK2dnrobEcee1 +0eqNKhDETK8Wk3dv1ZscmCeitpbYVYWnfjSgik4/tmPBgXlOF6WzxM7vql9wlXVl +kN1rV+7WoxpgUxPWCwr7dOTjZet2YpExAgMBAAEwDQYJKoZIhvcNAQELBQADggEB +AI1aor8hhqIEgcFrSLBsMfon+d5DTL1CUY9pRvnXObAiwyVL5W6r0NrhLyB+aEDj +zUvBwXAq8H1M8JQDoyPcgb5uh/vMlfuVDU04t0Aum4Tmwqa3Fa+Te9rIv4AuxoPw +nmeDcLSO+sTYEr+dfwLCwqgXHLhIVTtgbriOYRM0y2+TOAbPHQQtCBhFdXc1cnGY +eD67GU7K7O5pgBUa3ql1IjBEkTApM+aAiolnEUoecYMm35zfdeI8VIfnep6iWat6 +eUZaZw/4vus0n9ErUAzszpnX/acOfoPCGrD4yDJAPHHJ6f/hBUko4CsnTey7AlEj +FNIMKs5t1dnoFwmnXeYbnck= +-----END CERTIFICATE----- diff --git a/tests/system_libraries/gnutls/server.key b/tests/system_libraries/gnutls/server.key new file mode 100644 index 0000000000000000000000000000000000000000..f0b24593448dc7f14006fe3c987e536af37ed055 --- /dev/null +++ b/tests/system_libraries/gnutls/server.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCcTGbCjnPgn09X +Any8T87ZNPS7Vr/JpHziAO/2blon9dSDC0mCeTNmvuqJ11cEItgaFooV4325kcFl +KQIF+L8p3+DpZVHMmPpv604/CHnjzFKpsAv3FflAX3uFf6nYprojnhOcqwPedzW3 +qT0S34rBY2pQV9FPuUWZ85B8N5QOQ1RmIRaml7qBVOlLABuH2bcb3nKr+HlihM/a +/YWu9wVHhmA1ffJDN6HOnPcBTJQEK2dnrobEcee10eqNKhDETK8Wk3dv1ZscmCei +tpbYVYWnfjSgik4/tmPBgXlOF6WzxM7vql9wlXVlkN1rV+7WoxpgUxPWCwr7dOTj +Zet2YpExAgMBAAECggEATLpS7eq5pwj+DXRKoLU7EbUl+TueXhJSPi6AnoTQ3HIZ +d5VYamUuXx+VCsL8VCr41GHBOvqZMzqC6rLFbAIPcjKV+m3DSMHGm5+zo0z5bWNW +Jzglv4/5cukMvd4Mlq9OjIKjFRN9DD6QT8+UjEnSF5rCy5s4xT7qFKgVg21TUOZn +J6Eq7duDEHUN4dO3EeK9hpZ6peFXuHPZu3VaKSOELTa5R2arRwVyzfcq2Gskat6a +MpqNH+PgFtlNHAjkSB4T7eTQ3rW3GYwxKVugUpXRpvEod4a+jel+nb9ZiIC4CiOx +edQY8zcpJEmACfSd0zi5j5Qy36KOPbkDiell8E2JwwKBgQDPZcI98ohspgTB0q6Z +k74ZQ10XrAmbG6vSOq+Pmp6TtEkOKYKALLX9KasvlhmpPru69hlbZCsuFaCQk44p +mH/Gl5AljnjJKm0sH9YIv1e0pmGoNwMlrs5J7Pwky6MUtd+QmKCROKE/vZu8DiAp +OuXCxcu/mzD8S2S0E3dkR1V/FwKBgQDA7RiHcffxU+Xrjc5HpKA37raqjEzsqCiS +f0ktlpwf0WrKm5/Sd4OApKBa/JA6Nf5JzUEpFLcw5aKkHuNV3cYvHqJxpyC4ulGR +nBZDnAYkQu4jruyXTci5zkxzUxzOnuXQxT1aet9QvApHGNpnrAoTBdwm84hmB9sf +ZhEifCne9wKBgD2aEgnoYhEzdrJDa8z+DzbdxWbkmK3TmEOHXuIeoP9qS1DDj5mW +ri+WEty9jr2wfn5X3sxAgnrbvadzzIQaYcmQ9yXQnZvS2D6E7kQG4Xws91DJlku5 +Elju5S3gtn3OT6tZSkgYM/0Eyp8e6vqUHe6uZYhyBijKFA1QwuOsNH7dAoGBAKtc +LRRpW4SEM82VCCtEg3cK1j8IHW97MYZl/ra6dvQgC43oyv2jYC+Mik4m1WiO+s3M +vVri5pBM97h1IxHqyZSizkDK5NqPy9Hc5T2qQR5GQMV7IvSFh4vaPLeWlBjGtHRK +LWPHjcFlNG/QGHZLLiuVYeVLHNUblzr9aqzJwlsjAoGBAKKlis+Dn3j4sMCcViS8 +9LtMYUlyauO3FyfpMU9Yd2cZbsBYyiR8WbJsdSHOcA11nMskeOY3WkHkx2OXDz5v +5FdpM7UvqX2qxm8HtmAPUs0i/SbecJQ4VhihvglxDfvYOjxx/fnBgnZLPOo1DlMB +Ez7u4Bb8NMrA7kcXENSOqsDZ +-----END PRIVATE KEY----- diff --git a/tests/system_libraries/gnutls/tc_gnutls_fun_001.py b/tests/system_libraries/gnutls/tc_gnutls_fun_001.py new file mode 100644 index 0000000000000000000000000000000000000000..765a91808928cd6f566151b44b7e915b115c0363 --- /dev/null +++ b/tests/system_libraries/gnutls/tc_gnutls_fun_001.py @@ -0,0 +1,276 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_gnutls_fun_001.py +@Time: 2024/04/10 09:42:50 +@Author: hongfeng +@Version: 1.0 +@Contact: wb-zhf668260@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: hongfeng +""" + +from common.basetest import LocalTest +import os +class Test(LocalTest): + """ + See tc_gnutls_fun_001.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gnutls-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = """cat > gnutls_server.c < +#include +#include +#include +#include +#include + +#define SERVER_CERTFILE "server.crt" +#define SERVER_KEYFILE "server.key" +#define MAX_BUF 1024 +struct linger so_linger; + +static void terminate(const char *msg) +{ + gnutls_deinit(NULL); + fprintf(stderr, "%s\\n", msg); + exit(1); +} + +int main(int argc, char **argv[]) +{ + int server_sockfd, client_sockfd; + struct sockaddr_in server_addr, client_addr; + socklen_t sin_size; + char buffer[MAX_BUF]; + ssize_t bytes_read; + int ret; + const char *hostname = "localhost"; + gnutls_certificate_credentials_t x509_cred; + gnutls_session_t session; + + /* 初始化GnuTLS */ + gnutls_global_init(); + + /* 创建TCP socket */ + server_sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (server_sockfd == -1) { + perror("socket"); + return 1; + } + // 表示启用LINGER选项 + so_linger.l_onoff = 1; + // 表示立即断开连接,不等待数据发送完 + so_linger.l_linger = 0; + setsockopt(server_sockfd, SOL_SOCKET, SO_LINGER, (void *)&so_linger, sizeof(so_linger)); + + /* 设置服务器地址信息 */ + memset(&server_addr, 0, sizeof(server_addr)); + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(12345); + server_addr.sin_addr.s_addr = htonl(INADDR_ANY); + + /* 绑定地址到socket */ + if (bind(server_sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) { + perror("bind"); + close(server_sockfd); + return 1; + } + + /* 开始监听连接 */ + if (listen(server_sockfd, 5) == -1) { + perror("listen"); + close(server_sockfd); + return 1; + } + + while (1) { + sin_size = sizeof(client_addr); + client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_addr, &sin_size); + if (client_sockfd == -1) { + perror("accept"); + continue; + } + + /* 初始化GnuTLS会话 */ + gnutls_certificate_allocate_credentials(&x509_cred); + gnutls_certificate_set_x509_key_file(x509_cred, SERVER_CERTFILE, SERVER_KEYFILE, GNUTLS_X509_FMT_PEM); + gnutls_init(&session, GNUTLS_SERVER); + gnutls_priority_set_direct(session, "NORMAL:+VERS-TLS1.2:+CTYPE-X509", NULL); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred); + + gnutls_transport_set_int(session, client_sockfd); + + do { + ret = gnutls_handshake(session); + if (ret < 0 && gnutls_error_is_fatal(ret) == 0) { + printf("Handshake.....\\n"); + continue; + } else if (ret < 0) { + terminate("gnutls_handshake"); + } + printf("Handshake successful.\\n"); + break; + } while (ret == 0); + + while ((bytes_read = gnutls_record_recv(session, buffer, MAX_BUF)) > 0) { + printf("Received: %s\\n", buffer); + gnutls_record_send(session, buffer, bytes_read); + } + + if (bytes_read == 0) { + printf("Client disconnected\\n"); + } else if (bytes_read < 0) { + terminate(gnutls_strerror(bytes_read)); + } + + gnutls_bye(session, GNUTLS_SHUT_RDWR); + + /* 清理GnuTLS资源 */ + gnutls_deinit(session); + + /* 关闭客户端连接 */ + close(client_sockfd); + } + + /* 清理全局GnuTLS资源和证书 */ + gnutls_certificate_free_credentials(x509_cred); + close(server_sockfd); + gnutls_global_deinit(); + + return 0; +} +EOF""" + + self.cmd(cmdline) + cmdline = """cat > gnutls_client.c < +#include +#include +#include +#include +#include +#include +#include + +#define MAX_BUF 1024 +#define SERVER_IP "127.0.0.1" // 替换为服务器IP地址 +#define SERVER_PORT 12345 // 使用与服务器相同的端口 + +static void terminate(const char *msg) { + gnutls_perror(msg); + exit(1); +} + +int main() { + int sd; + struct sockaddr_in server_addr; + gnutls_certificate_credentials_t cert_cred; + gnutls_session_t session; + unsigned char buffer[MAX_BUF + 1]; + ssize_t ret; + + /* 初始化GnuTLS */ + gnutls_global_init(); + + /* 设置信任证书链 */ + gnutls_certificate_allocate_credentials(&cert_cred); + gnutls_certificate_set_x509_trust_file(cert_cred, "server.crt", GNUTLS_X509_FMT_PEM); + + + /* 创建TCP套接字 */ + sd = socket(AF_INET, SOCK_STREAM, 0); + if (sd < 0) { + perror("socket"); + exit(1); + } + + memset(&server_addr, 0, sizeof(server_addr)); + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(SERVER_PORT); + inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr); + + if (connect(sd, (struct sockaddr*) &server_addr, sizeof(server_addr)) < 0) { + perror("connect"); + close(sd); + exit(1); + } + + /* 初始化一个GnuTLS会话 */ + gnutls_init(&session, GNUTLS_CLIENT); + + /* 设置会话优先级和信任证书 */ + gnutls_priority_set_direct(session, "NORMAL:+VERS-TLS1.3:+CTYPE-X509", NULL); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, cert_cred); + + /* 将套接字与GnuTLS会话关联起来 */ + gnutls_transport_set_int(session, sd); + + do { + ret = gnutls_handshake(session); + if (ret < 0 && gnutls_error_is_fatal(ret) == 0) { + printf("Handshake.....\\n"); + continue; + } else if (ret < 0) { + terminate("gnutls_handshake"); + } + printf("Handshake successful.\\n"); + break; + } while (ret == 0); + + /* 安全地发送和接收消息 */ + strcpy(buffer, "Hello, Server!"); + gnutls_record_send(session, buffer, strlen(buffer)); + printf("Sending: %s\\n", buffer); + + do { + ret = gnutls_record_recv(session, buffer, MAX_BUF); + if (ret == 0) { /* EOS or error */ + break; + } else if (ret < 0) { + if (gnutls_error_is_fatal(ret) != 0) { + terminate("gnutls_record_recv"); + } + continue; + } + buffer[ret] = '\\0'; + printf("Received: %s\\n", buffer); + break; + } while (1); + + /* 清理会话资源 */ + gnutls_bye(session, GNUTLS_SHUT_RDWR); + gnutls_deinit(session); + + /* 清理全局和证书资源 */ + gnutls_certificate_free_credentials(cert_cred); + gnutls_global_deinit(); + + close(sd); + + return 0; +} +EOF""" + self.cmd(cmdline) + self.cmd("gcc -o gnutls_server gnutls_server.c `pkg-config --cflags --libs gnutls`") + self.cmd("gcc -o gnutls_client gnutls_client.c `pkg-config --cflags --libs gnutls`") + file_dir = os.path.dirname(__file__) + self.cmd(f"cp {file_dir}/server.crt ./server.crt") + self.cmd(f"cp {file_dir}/server.key ./server.key") + + def test(self): + os.system("./gnutls_server &") + ret_c, ret_o = self.cmd("./gnutls_client") + + self.assertTrue("Handshake successful." in ret_o, "check output error.") + self.assertTrue("Received: Hello, Server!" in ret_o, "check output error.") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("killall -9 'gnutls_server'", ignore_status=True) + self.cmd("rm gnutls_server.c gnutls_server gnutls_client.c gnutls_client server.crt server.key") diff --git a/tests/system_libraries/gpgme/tc_gpgme_func001.py b/tests/system_libraries/gpgme/tc_gpgme_func001.py new file mode 100644 index 0000000000000000000000000000000000000000..228011d262b983ef899c23d50b3cf4adbee50a59 --- /dev/null +++ b/tests/system_libraries/gpgme/tc_gpgme_func001.py @@ -0,0 +1,63 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_gpgme_func001.py +@Time: 2024/04/22 11:31:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_gpgme_func001.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gpgme-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline = """cat > /tmp/ghm/test_gpgme.c < +#define REQUIRED_VERSION "1.1.0" + +int main(){ + const char *actual_version = gpgme_check_version(REQUIRED_VERSION); + + if (actual_version) + { + printf("The actual GPGME version is at least %s\\n", REQUIRED_VERSION); + printf("Version from header: %s (0x%06x)\\n", + GPGME_VERSION, GPGME_VERSION_NUMBER); + printf("Version from binary: %s\\n", gpgme_check_version(NULL)); + printf("Copyright blurb ...:%s\\n", gpgme_check_version("\\x01\\x01")); + + // 如果实际版本大于等于所需版本,则返回0,表示成功 + return 0; + } + else + { + printf("Error: The actual GPGME version is less than %s\\n", REQUIRED_VERSION); + return 1; // 返回非零值表示版本检查失败 + } +} +""" + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o /tmp/ghm/test_gpgme /tmp/ghm/test_gpgme.c -lgpgme") + ret_c, ret_o = self.cmd("/tmp/ghm/test_gpgme") + self.assertIn("Version from header: 1.21.0", ret_o) + self.assertIn("Version from binary: 1.21.0", ret_o) + self.assertIn("This is GPGME 1.21.0 - The GnuPG Made Easy library", ret_o) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") + \ No newline at end of file diff --git a/tests/system_libraries/gpgme/tc_gpgme_func002.py b/tests/system_libraries/gpgme/tc_gpgme_func002.py new file mode 100644 index 0000000000000000000000000000000000000000..7bd026f7af149291feb1a8ed97ddbb660d426099 --- /dev/null +++ b/tests/system_libraries/gpgme/tc_gpgme_func002.py @@ -0,0 +1,100 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_gpgme_func002.py +@Time: 2024/04/22 16:31:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_gpgme_func002.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gpgme-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline = """cat > /tmp/ghm/test_gpgme.c < + +int main (void){ + gpgme_engine_info_t info; + gpgme_error_t err; + + gpgme_check_version (NULL); + + { + const char *keys[] = { + "homedir", + "sysconfdir", + "bindir", + "libexecdir", + "libdir", + "datadir", + "localedir", + "socketdir", + "agent-socket", + "agent-ssh-socket", + "dirmngr-socket", + "uiserver-socket", + "gpgconf-name", + "gpg-name", + "gpgsm-name", + "g13-name", + "keyboxd-name", + "agent-name", + "scdaemon-name", + "dirmngr-name", + "pinentry-name", + "gpg-wks-client-name", + "gpgtar-name", + NULL + }; + const char *s; + int i; + + for (i = 0; keys[i]; i++) + { + if ((s = gpgme_get_dirinfo (keys[i]))) + fprintf (stdout, "dirinfo: %s='%s'\\n", keys[i], s); + } + } + + err = gpgme_get_engine_info (&info); + if (err) + { + fprintf (stderr, "%s:%d: gpgme_error_t %s\\n", __FILE__, __LINE__, gpgme_strerror (err)); + return 1; + } + + for (; info; info = info->next) + fprintf (stdout, "protocol=%d engine='%s' v='%s' (min='%s') home='%s'\\n", + info->protocol, info->file_name, info->version, info->req_version, + info->home_dir ? info->home_dir : "[default]"); + + return 0; +} +""" + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o /tmp/ghm/test_gpgme /tmp/ghm/test_gpgme.c -lgpgme") + ret_c, ret_o = self.cmd("/tmp/ghm/test_gpgme") + self.log.info(ret_o) + self.assertIn("dirinfo: homedir", ret_o) + self.assertIn("dirinfo: sysconfdir", ret_o) + self.assertIn("dirinfo: bindir", ret_o) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") + \ No newline at end of file diff --git a/tests/system_libraries/gpgme/tc_gpgme_func003.py b/tests/system_libraries/gpgme/tc_gpgme_func003.py new file mode 100644 index 0000000000000000000000000000000000000000..ef81c882a5979d3cfb05a4e7e915d6c1cb38f76c --- /dev/null +++ b/tests/system_libraries/gpgme/tc_gpgme_func003.py @@ -0,0 +1,153 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_gpgme_func003.py +@Time: 2024/04/23 09:31:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_gpgme_func003.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gpgme-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline = """cat > /tmp/ghm/test_gpgme.c < +#endif +#include +#include +#include +#include +#include +#include +#include + +#define PGM "test_gpgme" + +#define fail_if_err(err) \ + do \ + { \ + if (err) \ + { \ + fprintf (stderr, PGM": file %s line %d: <%s> %s\\n", \ + __FILE__, __LINE__, gpgme_strsource (err), \ + gpgme_strerror (err)); \ + exit (1); \ + } \ + } \ + while (0) + +void +init_gpgme_basic (void) +{ + gpgme_check_version (NULL); + setlocale (LC_ALL, ""); + gpgme_set_locale (NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL)); +#ifndef HAVE_W32_SYSTEM + gpgme_set_locale (NULL, LC_MESSAGES, setlocale (LC_MESSAGES, NULL)); +#endif +} + +void +init_gpgme (gpgme_protocol_t proto) +{ + gpg_error_t err; + + init_gpgme_basic (); + err = gpgme_engine_check_version (proto); + fail_if_err (err); +} + +void +print_data (gpgme_data_t dh) +{ +#define BUF_SIZE 512 + char buf[BUF_SIZE + 1]; + int ret; + + ret = gpgme_data_seek (dh, 0, SEEK_SET); + if (ret) + fail_if_err (gpgme_err_code_from_errno (errno)); + while ((ret = gpgme_data_read (dh, buf, BUF_SIZE)) > 0) + fwrite (buf, ret, 1, stdout); + if (ret < 0) + fail_if_err (gpgme_err_code_from_errno (errno)); +} + +int +main (void) +{ + gpgme_ctx_t ctx; + gpgme_error_t err; + gpgme_data_t out; + const char *pattern1[] = { "DFN Top Level Certification Authority", NULL }; + const char *pattern2[] = { "A782EB7CA56212CF3DEF6088FB6708AE59FAD36E", + "DFN Server Certification Authority", + NULL }; + + init_gpgme (GPGME_PROTOCOL_CMS); + + err = gpgme_new (&ctx); + fail_if_err (err); + gpgme_set_protocol (ctx, GPGME_PROTOCOL_CMS); + + gpgme_set_armor (ctx, 1); + + /* Check exporting of one certificate. */ + err = gpgme_data_new (&out); + fail_if_err (err); + err = gpgme_op_export_ext (ctx, pattern1, 0, out); + fail_if_err (err); + + fflush (NULL); + fputs ("Begin Result:\\n", stdout); + print_data (out); + fputs ("End Result.\\n", stdout); + + gpgme_data_release (out); + + /* Check exporting of 2 certificates. */ + err = gpgme_data_new (&out); + fail_if_err (err); + err = gpgme_op_export_ext (ctx, pattern2, 0, out); + fail_if_err (err); + + fflush (NULL); + fputs ("Begin Result:\\n", stdout); + print_data (out); + fputs ("End Result.\\n", stdout); + + gpgme_data_release (out); + + + gpgme_release (ctx); + + return 0; +} +""" + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o /tmp/ghm/test_gpgme /tmp/ghm/test_gpgme.c -lgpgme") + ret_c, ret_o = self.cmd("/tmp/ghm/test_gpgme") + self.log.info(ret_o) + self.assertIn("Begin Result", ret_o) + self.assertIn("End Result", ret_o) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") + \ No newline at end of file diff --git a/tests/system_libraries/gpgme/tc_gpgme_func004.py b/tests/system_libraries/gpgme/tc_gpgme_func004.py new file mode 100644 index 0000000000000000000000000000000000000000..69c781fcd2a1415556b7594032444d2d3131f6fe --- /dev/null +++ b/tests/system_libraries/gpgme/tc_gpgme_func004.py @@ -0,0 +1,248 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_gpgme_func004.py +@Time: 2024/04/24 10:31:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" +import subprocess +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_gpgme_func004.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gpgme-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline = """cat > /tmp/ghm/test_gpgme.c < +#endif +#include +#include +#include +#include +#include +#include +#define PGM "test_gpgme" + +#define fail_if_err(err) \ + do \ + { \ + if (err) \ + { \ + fprintf (stderr, PGM": file %s line %d: <%s> %s\\n", \ + __FILE__, __LINE__, gpgme_strsource (err), \ + gpgme_strerror (err)); \ + exit (1); \ + } \ + } \ + while (0) + +static int got_errors; + +static const char test_text1[] = "Hallo Leute!\\n"; +static const char test_text1f[]= "Hallo Leute?\\n"; +static const char test_sig1[] = +"-----BEGIN CMS OBJECT-----\\n" +"MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAA\\n" +"MYIBOTCCATUCAQEwcDBrMQswCQYDVQQGEwJERTETMBEGA1UEBxQKRPxzc2VsZG9y\\n" +"ZjEWMBQGA1UEChMNZzEwIENvZGUgR21iSDEZMBcGA1UECxMQQWVneXB0ZW4gUHJv\\n" +"amVjdDEUMBIGA1UEAxMLdGVzdCBjZXJ0IDECAQAwBwYFKw4DAhqgJTAjBgkqhkiG\\n" +"9w0BCQQxFgQU7FC/ibH3lC9GE24RJJxa8zqP7wEwCwYJKoZIhvcNAQEBBIGAA3oC\\n" +"DUmKERmD1eoJYFw38y/qnncS/6ZPjWINDIphZeK8mzAANpvpIaRPf3sNBznb89QF\\n" +"mRgCXIWcjlHT0DTRLBf192Ve22IyKH00L52CqFsSN3a2sajqRUlXH8RY2D+Al71e\\n" +"MYdRclgjObCcoilA8fZ13VR4DiMJVFCxJL4qVWI=\\n" +"-----END CMS OBJECT-----\\n"; + +void +print_data (gpgme_data_t dh) +{ +#define BUF_SIZE 512 + char buf[BUF_SIZE + 1]; + int ret; + + ret = gpgme_data_seek (dh, 0, SEEK_SET); + if (ret) + fail_if_err (gpgme_err_code_from_errno (errno)); + while ((ret = gpgme_data_read (dh, buf, BUF_SIZE)) > 0) + fwrite (buf, ret, 1, stdout); + if (ret < 0) + fail_if_err (gpgme_err_code_from_errno (errno)); +} + +void +init_gpgme_basic (void) +{ + gpgme_check_version (NULL); + setlocale (LC_ALL, ""); + gpgme_set_locale (NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL)); +#ifndef HAVE_W32_SYSTEM + gpgme_set_locale (NULL, LC_MESSAGES, setlocale (LC_MESSAGES, NULL)); +#endif +} + +void +init_gpgme (gpgme_protocol_t proto) +{ + gpg_error_t err; + + init_gpgme_basic (); + err = gpgme_engine_check_version (proto); + fail_if_err (err); +} + +static void +check_result (gpgme_verify_result_t result, int summary, const char *fpr, + gpgme_error_t status, gpgme_validity_t validity) +{ + gpgme_signature_t sig; + + sig = result->signatures; + if (!sig || sig->next) + { + fprintf (stderr, "%s:%i: Unexpected number of signatures\\n", + __FILE__, __LINE__); + got_errors = 1; + if (!sig) + return; + } + if (sig->summary != summary) + { + fprintf (stderr, "%s:%i: Unexpected signature summary: " + "want=0x%x have=0x%x\\n", + __FILE__, __LINE__, summary, sig->summary); + got_errors = 1; + } + if (sig->fpr && strcmp (sig->fpr, fpr)) + { + fprintf (stderr, "%s:%i: Unexpected fingerprint: %s\\n", + __FILE__, __LINE__, sig->fpr); + got_errors = 1; + } + if (gpgme_err_code (sig->status) != status) + { + fprintf (stderr, "%s:%i: Unexpected signature status: %s\\n", + __FILE__, __LINE__, gpgme_strerror (sig->status)); + got_errors = 1; + } + if (sig->notations) + { + fprintf (stderr, "%s:%i: Unexpected notation data\\n", + __FILE__, __LINE__); + got_errors = 1; + } + if (sig->wrong_key_usage) + { + fprintf (stderr, "%s:%i: Unexpectedly wrong key usage\\n", + __FILE__, __LINE__); + got_errors = 1; + } + if (sig->validity != validity) + { + fprintf (stderr, "%s:%i: Unexpected validity: %i\\n", + __FILE__, __LINE__, sig->validity); + got_errors = 1; + } + if (gpgme_err_code (sig->validity_reason) != GPG_ERR_NO_ERROR) + { + fprintf (stderr, "%s:%i: Unexpected validity reason: %s\\n", + __FILE__, __LINE__, gpgme_strerror (sig->validity_reason)); + got_errors = 1; + } +} + + +static void +show_auditlog (gpgme_ctx_t ctx) +{ + gpgme_error_t err; + gpgme_data_t data; + + err = gpgme_data_new (&data); + fail_if_err (err); + err = gpgme_op_getauditlog (ctx, data, 0); + if (err) + { + fprintf (stderr, "%s:%i: Can't get audit log: %s\\n", + __FILE__, __LINE__, gpgme_strerror (err)); + if (gpgme_err_code (err) != GPG_ERR_ASS_UNKNOWN_CMD) + got_errors = 1; + } + print_data (data); + gpgme_data_release (data); +} + + +int +main (void) +{ + gpgme_ctx_t ctx; + gpgme_error_t err; + gpgme_data_t sig, text; + gpgme_verify_result_t result; + + init_gpgme (GPGME_PROTOCOL_CMS); + + err = gpgme_new (&ctx); + fail_if_err (err); + gpgme_set_protocol (ctx, GPGME_PROTOCOL_CMS); + + /* Checking a valid message. */ + err = gpgme_data_new_from_mem (&text, test_text1, strlen (test_text1), 0); + fail_if_err (err); + err = gpgme_data_new_from_mem (&sig, test_sig1, strlen (test_sig1), 0); + fail_if_err (err); + + err = gpgme_op_verify (ctx, sig, text, NULL); + fail_if_err (err); + result = gpgme_op_verify_result (ctx); + check_result (result, GPGME_SIGSUM_VALID | GPGME_SIGSUM_GREEN, + "A782EB7CA56212CF3DEF6088FB6708AE59FAD36E", + GPG_ERR_NO_ERROR, GPGME_VALIDITY_FULL); + + show_auditlog (ctx); + + /* Checking a manipulated message. */ + gpgme_data_release (text); + err = gpgme_data_new_from_mem (&text, test_text1f, strlen (test_text1f), 0); + fail_if_err (err); + gpgme_data_seek (sig, 0, SEEK_SET); + err = gpgme_op_verify (ctx, sig, text, NULL); + fail_if_err (err); + result = gpgme_op_verify_result (ctx); + check_result (result, GPGME_SIGSUM_RED, + "A782EB7CA56212CF3DEF6088FB6708AE59FAD36E", + GPG_ERR_BAD_SIGNATURE, GPGME_VALIDITY_UNKNOWN); + + show_auditlog (ctx); + + gpgme_data_release (text); + gpgme_data_release (sig); + gpgme_release (ctx); + return got_errors? 1 : 0; +} +""" + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o /tmp/ghm/test_gpgme /tmp/ghm/test_gpgme.c -lgpgme") + ret_o = subprocess.run("/tmp/ghm/test_gpgme", capture_output=True, shell=True) + self.log.info(ret_o) + self.assertIn(b'Data verification succeeded', ret_o.stdout) + self.assertIn(b'Data available', ret_o.stdout) + self.assertIn(b'Signature available:', ret_o.stdout) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") + \ No newline at end of file diff --git a/tests/system_libraries/initscripts/tc_initscripts_initscripts_func_002.py b/tests/system_libraries/initscripts/tc_initscripts_initscripts_func_002.py new file mode 100644 index 0000000000000000000000000000000000000000..198c147ec43e6e55f172d0e868e3fd78e5d60b99 --- /dev/null +++ b/tests/system_libraries/initscripts/tc_initscripts_initscripts_func_002.py @@ -0,0 +1,113 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_initscripts_initscripts_func_002.py +@Time: 2024/03/22 16:05:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_initscripts_initscripts_func_002.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "initscripts initscripts-service systemd"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + gen_ser_conf = r'''cat << EOF > /etc/systemd/system/init_ser_test_002.service +[Unit] +Description=My Custom Service +After=network.target + +[Service] +Type=forking +ExecStart=/etc/init.d/init_ser_test_002 start +ExecStop=/etc/init.d/init_ser_test_002 stop +ExecReload=/etc/init.d/init_ser_test_002 restart +PIDFile=/var/run/init_ser_test_002.pid + +[Install] +WantedBy=multi-user.target +EOF''' + gen_ser_scripts = r'''cat << "EOF" > /etc/init.d/init_ser_test_002 +#!/bin/bash + +PIDFILE="/var/run/init_ser_test_002.pid" + +start() { + echo "Starting init_ser_test_002 service..." + nohup watch -n 5 date > /tmp/init_ser_test_002.log 2>&1 & + echo $! > "$PIDFILE" +} + +stop() { + if [ -f "$PIDFILE" ]; then + PID=$(cat "$PIDFILE") + echo "Stopping init_ser_test_002 service..." + kill "$PID" + rm "$PIDFILE" + else + echo "PID file not found. Is the service running?" + fi +} + +status() { + if [ -f "$PIDFILE" ]; then + PID=$(cat "$PIDFILE") + if ps -p "$PID" > /dev/null; then + echo "Service is running (PID: $PID)" + else + echo "Service not running but pid file exists" + fi + else + echo "Service is not running." + fi +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart) + stop + start + ;; + status) + status + ;; + *) + echo "Usage: $0 {start|stop|restart|status}" +esac +EOF''' + self.cmd(gen_ser_conf) + self.cmd(gen_ser_scripts) + self.cmd('mkdir -p /var/run/') + self.cmd('chmod +x /etc/init.d/init_ser_test_002') + + def test(self): + self.cmd('service init_ser_test_002 status') + self.cmd('service init_ser_test_002 start') + self.cmd('service init_ser_test_002 restart') + self.cmd('service init_ser_test_002 stop') + + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd('systemctl daemon-reload', ignore_status=True) + for file in ['/etc/systemd/system/init_ser_test_002.service', '/etc/init.d/init_ser_test_002', '/var/run/init_ser_test_002.pid', '/tmp/init_ser_test_002.log']: + if os.path.exists(file): + self.cmd(f'rm -rf {file}') diff --git a/tests/system_libraries/krb5/krb5.py b/tests/system_libraries/krb5/krb5.py new file mode 100644 index 0000000000000000000000000000000000000000..5037664cbbde52f6297b433d4f7be8b2f00e2ebb --- /dev/null +++ b/tests/system_libraries/krb5/krb5.py @@ -0,0 +1,146 @@ +import logging +import pexpect + +class Krb5Test(): + database_password = 'MYDOMAIN@123' + user_name = 'user' + user_password = 'user@123' + realms = 'MYDOMAIN.LOCAL' + Keytab_path = '/var/kerberos/krb5kdc/kadm5.keytab' + + @staticmethod + def create_krb5conf(self): + cmdline='''cat > /etc/krb5.conf < /var/kerberos/krb5kdc/kdc.conf < /var/kerberos/krb5kdc/kadm5.acl < /var/kerberos/krb5kdc/kadm5.acl") + self.cmd('rm -f /var/kerberos/krb5kdc/principal*') + diff --git a/tests/system_libraries/krb5/tc_krb5_fun_001.py b/tests/system_libraries/krb5/tc_krb5_fun_001.py new file mode 100644 index 0000000000000000000000000000000000000000..f0c60de9475f9348189c40f6b2a4493db82d3013 --- /dev/null +++ b/tests/system_libraries/krb5/tc_krb5_fun_001.py @@ -0,0 +1,34 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_krb5_fun_001.py +@Time: 2024-03-11 17:53:55 +@Author: qintingting +@Version: 1.0 +@Contact: wb-qtt862918@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: qintingting +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_krb5_fun_001.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "krb5-server krb5-workstation krb5-libs"} + def setUp(self): + super().setUp(self.PARAM_DIC) + + def test(self): + code, klist_ver = self.cmd("klist -V|awk '{print $4}'") + code, Rpm_Ver = self.cmd("rpm -q krb5-server|awk -F- '{print $3}'") + if klist_ver is not None and Rpm_Ver is not None: + self.assertEqual(klist_ver, Rpm_Ver) + else: + print("其中一个命令执行失败或未获取到版本信息,请检查。") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) diff --git a/tests/system_libraries/krb5/tc_krb5_fun_002.py b/tests/system_libraries/krb5/tc_krb5_fun_002.py new file mode 100644 index 0000000000000000000000000000000000000000..59116de4f1d0984853832e46b6fadff97388b9f7 --- /dev/null +++ b/tests/system_libraries/krb5/tc_krb5_fun_002.py @@ -0,0 +1,36 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_krb5_fun_002.py +@Time: 2024-03-12 14:53:55 +@Author: qintingting +@Version: 1.0 +@Contact: wb-qtt862918@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: qintingting +""" +from system_libraries.krb5.krb5 import Krb5Test +from common.service import ServiceManager +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_krb5_fun_002.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "krb5-server krb5-workstation krb5-libs"} + def setUp(self): + self.servicename = 'krb5kdc.service' + super().setUp(self.PARAM_DIC) + Krb5Test.create_krb5conf(self) + Krb5Test.create_kdc_conf(self) + Krb5Test.create_kadm5_acl(self) + Krb5Test.init_database(Krb5Test.realms, Krb5Test.database_password) + + def test(self): + ServiceManager.service_test(self, self.servicename) + def tearDown(self): + Krb5Test.del_env(self) + super().tearDown(self.PARAM_DIC) + \ No newline at end of file diff --git a/tests/system_libraries/krb5/tc_krb5_fun_003.py b/tests/system_libraries/krb5/tc_krb5_fun_003.py new file mode 100644 index 0000000000000000000000000000000000000000..eb8b6f53a3238d89427935a66a283c457f76a489 --- /dev/null +++ b/tests/system_libraries/krb5/tc_krb5_fun_003.py @@ -0,0 +1,51 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_krb5_fun_003.py +@Time: 2024-03-12 14:53:55 +@Author: qintingting +@Version: 1.0 +@Contact: wb-qtt862918@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: qintingting +""" +from system_libraries.krb5.krb5 import Krb5Test +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_krb5_fun_003.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "krb5-server krb5-workstation krb5-libs"} + def setUp(self): + super().setUp(self.PARAM_DIC) + Krb5Test.create_krb5conf(self) + Krb5Test.create_kdc_conf(self) + Krb5Test.create_kadm5_acl(self) + Krb5Test.init_database(Krb5Test.realms, Krb5Test.database_password) + Krb5Test.start_krb5kdcservice(self) + + + + def test(self): + #create user + Krb5Test.create_user(self, Krb5Test.user_name, Krb5Test.user_password) + #Obtain TGT ticket + Krb5Test.init_tgt(self, Krb5Test.user_name, Krb5Test.user_password, Krb5Test.realms) + # Check if the output of klist contains krbtgt + try: + code, result = self.cmd('klist') + if f"krbtgt/{Krb5Test.realms}@{Krb5Test.realms}" in result: + self.log.info("TGT 获取成功") + else: + self.log.error("TGT 获取失败,未找到 krbtgt 票据") + except Exception as e: + self.log.error(f"执行 klist 时出错: {e}") + + def tearDown(self): + Krb5Test.destory_ticket(self, Krb5Test.user_name) + Krb5Test.del_user(self, Krb5Test.user_name) + Krb5Test.del_env(self) + super().tearDown(self.PARAM_DIC) \ No newline at end of file diff --git a/tests/system_libraries/krb5/tc_krb5_fun_004.py b/tests/system_libraries/krb5/tc_krb5_fun_004.py new file mode 100644 index 0000000000000000000000000000000000000000..acc4cd67cb45b56448bd8d52621ed0f627b43128 --- /dev/null +++ b/tests/system_libraries/krb5/tc_krb5_fun_004.py @@ -0,0 +1,58 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_krb5_fun_004.py +@Time: 2024-03-12 14:53:55 +@Author: qintingting +@Version: 1.0 +@Contact: wb-qtt862918@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: qintingting +""" +from system_libraries.krb5.krb5 import Krb5Test +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_krb5_fun_004.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + def execute_and_check_kvno(self, command): + """ + 执行 kvno 命令并检查结果 + """ + try: + code, result = self.cmd(command) + if "kvno = 1" in result: + self.log.info("获取服务票据成功") + else: + self.log.error("服务票据获取失败,未找到票据") + except Exception as e: + self.log.error(f"执行 kvno 时出错: {e}") + + PARAM_DIC = {"pkg_name": "krb5-server krb5-workstation krb5-libs"} + def setUp(self): + super().setUp(self.PARAM_DIC) + Krb5Test.create_krb5conf(self) + Krb5Test.create_kdc_conf(self) + Krb5Test.create_kadm5_acl(self) + Krb5Test.init_database(Krb5Test.realms, Krb5Test.database_password) + Krb5Test.start_krb5kdcservice(self) + + + def test(self): + #create user + Krb5Test.create_user(self, Krb5Test.user_name, Krb5Test.user_password) + #Obtain TGT ticket + Krb5Test.init_tgt(self, Krb5Test.user_name, Krb5Test.user_password, Krb5Test.realms) + #Check whether the command is executed successfully + self.execute_and_check_kvno(f'kvno {Krb5Test.user_name}') + self.execute_and_check_kvno(f'kvno krbtgt/{Krb5Test.realms}@{Krb5Test.realms}') + + def tearDown(self): + Krb5Test.destory_ticket(self, Krb5Test.user_name) + Krb5Test.del_user(self, Krb5Test.user_name) + Krb5Test.del_env(self) + super().tearDown(self.PARAM_DIC) + \ No newline at end of file diff --git a/tests/system_libraries/krb5/tc_krb5_fun_005.py b/tests/system_libraries/krb5/tc_krb5_fun_005.py new file mode 100644 index 0000000000000000000000000000000000000000..6952329909771224e664840305f4f1c8654574ee --- /dev/null +++ b/tests/system_libraries/krb5/tc_krb5_fun_005.py @@ -0,0 +1,42 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_krb5_fun_005.py +@Time: 2024-03-13 10:38:55 +@Author: qintingting +@Version: 1.0 +@Contact: wb-qtt862918@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: qintingting +""" +from system_libraries.krb5.krb5 import Krb5Test +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_krb5_fun_005.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "krb5-server krb5-workstation krb5-libs"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.new_password = 'new@123' + Krb5Test.create_krb5conf(self) + Krb5Test.create_kdc_conf(self) + Krb5Test.create_kadm5_acl(self) + Krb5Test.init_database(Krb5Test.realms, Krb5Test.database_password) + Krb5Test.start_krb5kdcservice(self) + Krb5Test.create_user(self, Krb5Test.user_name, Krb5Test.user_password) + Krb5Test.init_tgt(self, Krb5Test.user_name, Krb5Test.user_password, Krb5Test.realms) + + def test(self): + Krb5Test.change_pwd(self, Krb5Test.user_name, self.new_password) + Krb5Test.init_tgt(self, Krb5Test.user_name, self.new_password, Krb5Test.realms) + + def tearDown(self): + Krb5Test.destory_ticket(self, Krb5Test.user_name) + Krb5Test.del_user(self, Krb5Test.user_name) + Krb5Test.del_env(self) + super().tearDown(self.PARAM_DIC) + \ No newline at end of file diff --git a/tests/system_libraries/krb5/tc_krb5_fun_006.py b/tests/system_libraries/krb5/tc_krb5_fun_006.py new file mode 100644 index 0000000000000000000000000000000000000000..18109a1d4fc4efef24525c5a9c448e5e0da1da73 --- /dev/null +++ b/tests/system_libraries/krb5/tc_krb5_fun_006.py @@ -0,0 +1,46 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_krb5_fun_006.py +@Time: 2024-03-13 10:38:55 +@Author: qintingting +@Version: 1.0 +@Contact: wb-qtt862918@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: qintingting +""" +from system_libraries.krb5.krb5 import Krb5Test +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_krb5_fun_006.yaml for details + + :avocado: tags=P2,noarch,local,fixed + """ + PARAM_DIC = {"pkg_name": "krb5-server krb5-workstation krb5-libs"} + def setUp(self): + super().setUp(self.PARAM_DIC) + Krb5Test.create_krb5conf(self) + Krb5Test.create_kdc_conf(self) + Krb5Test.create_kadm5_acl(self) + Krb5Test.init_database(Krb5Test.realms, Krb5Test.database_password) + Krb5Test.start_krb5kdcservice(self) + self.user_list = ['root/admin', 'test', 'user'] + self.policy_list = ['admin', 'user'] + + def test(self): + #create user with admin policy + Krb5Test.create_user_policy(self, self.user_list[0], Krb5Test.user_password, self.policy_list[0]) + #create user with user policy + Krb5Test.create_user_policy(self, self.user_list[1], Krb5Test.user_password, self.policy_list[1]) + #create user without policy + Krb5Test.create_user(self, self.user_list[2], 'test@123') + + + def tearDown(self): + for item in self.user_list: + Krb5Test.del_user(self, item) + Krb5Test.del_env(self) + super().tearDown(self.PARAM_DIC) + \ No newline at end of file diff --git a/tests/system_libraries/krb5/tc_krb5_fun_007.py b/tests/system_libraries/krb5/tc_krb5_fun_007.py new file mode 100644 index 0000000000000000000000000000000000000000..3fa55853ba6d98ab32330ac8f4e8f2651c449786 --- /dev/null +++ b/tests/system_libraries/krb5/tc_krb5_fun_007.py @@ -0,0 +1,47 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_krb5_fun_007.py +@Time: 2024-03-13 10:38:55 +@Author: qintingting +@Version: 1.0 +@Contact: wb-qtt862918@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: qintingting +""" +import pexpect +from system_libraries.krb5.krb5 import Krb5Test +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_krb5_fun_007.yaml for details + + :avocado: tags=P2,noarch,local,fixed + """ + PARAM_DIC = {"pkg_name": "krb5-server krb5-workstation krb5-libs"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.user_name = 'root/admin' + self.policy = 'admin' + Krb5Test.create_krb5conf(self) + Krb5Test.create_kdc_conf(self) + Krb5Test.create_kadm5_acl(self) + Krb5Test.init_database(Krb5Test.realms, Krb5Test.database_password) + Krb5Test.start_krb5kdcservice(self) + #create user with admin policy + Krb5Test.create_user_policy(self, self.user_name, Krb5Test.user_password, self.policy) + + def test(self): + #obtain TGT + Krb5Test.init_tgt(self, self.user_name, Krb5Test.user_password, Krb5Test.realms) + #loggin kadmin.local + child = pexpect.spawn('kadmin.local') + child.expect(f"Authenticating as principal {self.user_name}@{Krb5Test.realms} with password.") + child.sendline('q') + + def tearDown(self): + Krb5Test.del_user(self, self.user_name) + Krb5Test.del_env(self) + super().tearDown(self.PARAM_DIC) + \ No newline at end of file diff --git a/tests/system_libraries/krb5/tc_krb5_fun_008.py b/tests/system_libraries/krb5/tc_krb5_fun_008.py new file mode 100644 index 0000000000000000000000000000000000000000..b3af150d38bf1a2ba31055c809da2dbc51e86c1b --- /dev/null +++ b/tests/system_libraries/krb5/tc_krb5_fun_008.py @@ -0,0 +1,54 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_krb5_fun_008.py +@Time: 2024-03-13 10:38:55 +@Author: qintingting +@Version: 1.0 +@Contact: wb-qtt862918@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: qintingting +""" +import time +from datetime import datetime +from system_libraries.krb5.krb5 import Krb5Test +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_krb5_fun_008.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "krb5-server krb5-workstation krb5-libs"} + def setUp(self): + super().setUp(self.PARAM_DIC) + Krb5Test.create_krb5conf(self) + Krb5Test.create_kdc_conf(self) + Krb5Test.create_kadm5_acl(self) + Krb5Test.init_database(Krb5Test.realms, Krb5Test.database_password) + Krb5Test.start_krb5kdcservice(self) + self.time_format = "%m/%d/%Y %H:%M:%S" + + + def test(self): + #create user + Krb5Test.create_user(self, Krb5Test.user_name, Krb5Test.user_password) + #Obtain TGT ticket + Krb5Test.init_tgt(self, Krb5Test.user_name, Krb5Test.user_password, Krb5Test.realms) + code, old_start_time = self.cmd("klist|grep 'krbtgt'|awk '{print $1,$2}'") + time.sleep(2) + #renew Valid start time + self.cmd(f"kinit -R {Krb5Test.user_name}@{Krb5Test.realms}") + code, new_start_time = self.cmd("klist|grep 'krbtgt'|awk '{print $1,$2}'") + start_time = datetime.strptime(old_start_time, self.time_format) + renew_time = datetime.strptime(new_start_time, self.time_format) + self.assertGreater(renew_time, start_time) + + + def tearDown(self): + Krb5Test.destory_ticket(self, Krb5Test.user_name) + Krb5Test.del_user(self, Krb5Test.user_name) + Krb5Test.del_env(self) + super().tearDown(self.PARAM_DIC) + \ No newline at end of file diff --git a/tests/system_libraries/libcap-ng/tc_libcap-ng_fun_001.py b/tests/system_libraries/libcap-ng/tc_libcap-ng_fun_001.py new file mode 100644 index 0000000000000000000000000000000000000000..293d85b4ac6b56af649c7baaff47135e90a2960e --- /dev/null +++ b/tests/system_libraries/libcap-ng/tc_libcap-ng_fun_001.py @@ -0,0 +1,83 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libcap-ng_fun_001.py +@Time: 2024/04/18 13:32:50 +@Author: hongfeng +@Version: 1.0 +@Contact: wb-zhf668260@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: hongfeng +""" + +from common.basetest import LocalTest +class Test(LocalTest): + """ + See tc_libcap-ng_fun_001.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libcap-ng-devel libcap-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = """cat > test01.c < +#include +#include +#include +#include +#include + +int main() { + if (capng_have_capability(CAPNG_EFFECTIVE, CAP_SETUID | CAP_SETGID) == CAPNG_NONE) { + printf("Process does not have effective CAP_SETUID and/or CAP_SETGID.\\n"); + } else { + printf("Process has effective CAP_SETUID and/or CAP_SETGID.\\n"); + } + + if (setuid(0)) { + printf("insufficient privilege to setuid.\\n"); + } + if (setgid(0)) { + printf("insufficient privilege to setgid.\\n"); + } + + capng_update(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED, CAP_SETUID | CAP_SETGID); + if (capng_apply(CAPNG_SELECT_BOTH) != 0) { + perror("capng_apply() failed"); + } + + if (capng_have_capability(CAPNG_EFFECTIVE, CAP_SETUID | CAP_SETGID) == CAPNG_NONE) { + printf("Process does not have effective CAP_SETUID and/or CAP_SETGID.\\n"); + } else { + printf("Process has effective CAP_SETUID and/or CAP_SETGID.\\n"); + } + + if (setuid(0)) { + printf("insufficient privilege to setuid.\\n"); + } + if (setgid(0)) { + printf("insufficient privilege to setgid.\\n"); + } +} +EOF""" + self.cmd(cmdline) + self.cmd("gcc -o test01 test01.c -lcap-ng") + self.cmd("useradd test-user01") + + def test(self): + # 验证root用户有权限 + ret_c, ret_o = self.cmd("./test01") + self.assertTrue("Process has effective CAP_SETUID and/or CAP_SETGID" in ret_o, 'check output error.') + + # 验证test-user01用户无权限 + ret_c, ret_o = self.cmd("su test-user01 -c './test01'") + self.assertTrue("insufficient privilege to setuid" in ret_o, 'check output error.') + self.assertTrue("insufficient privilege to setgid" in ret_o, 'check output error.') + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("userdel -rf test-user01") + self.cmd("rm test01.c test01") + diff --git a/tests/system_libraries/libdnf/tc_libdnf_libdnf_func_001.py b/tests/system_libraries/libdnf/tc_libdnf_libdnf_func_001.py new file mode 100644 index 0000000000000000000000000000000000000000..58a7d5e91cd051a52177e162c9b27ede7383d176 --- /dev/null +++ b/tests/system_libraries/libdnf/tc_libdnf_libdnf_func_001.py @@ -0,0 +1,94 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libdnf_libdnf_func_001.py +@Time: 2024/03/26 14:08:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libdnf_libdnf_func_001.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libdnf libdnf-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > test_libdnf_dnf_context_get_repos.c << EOF +#include +#include +#include +#include + +int main() { + GError *error = NULL; + DnfContext *context; + GPtrArray *repos; + DnfRepo *repo; + guint i; + + // 初始化 DnfContext + context = dnf_context_new(); + // Set the solv_dir for the context; adjust the path as needed + dnf_context_set_solv_dir(context, "/var/cache/dnf/solv"); + if (error) { + fprintf(stderr, "Error setting solv_dir: %s\n", error->message); + g_error_free(error); + g_object_unref(context); + return EXIT_FAILURE; + } + + if (!dnf_context_setup(context, NULL, &error)) { + // 错误处理 + fprintf(stderr, "Error setting up DNF context: %s\n", error->message); + g_clear_error(&error); + g_object_unref(context); + return 1; + } + // 加载仓库 + if (!dnf_context_get_repos(context)) { + // 错误处理 + fprintf(stderr, "Error loading repositories: %s\n", error->message); + g_clear_error(&error); + g_object_unref(context); + return 1; + } + // 获取仓库列表 + repos = dnf_context_get_repos(context); + // 遍历并打印仓库信息 + for (i = 0; i < repos->len; i++) { + repo = g_ptr_array_index(repos, i); + printf("dnf_repo_get_id: %s\n", dnf_repo_get_id(repo)); + printf("dnf_repo_get_location: %s\n", dnf_repo_get_location(repo)); + printf("dnf_repo_get_filename: %s\n", dnf_repo_get_filename(repo)); + printf("dnf_repo_get_packages: %s\n", dnf_repo_get_packages(repo)); + printf("dnf_repo_get_description: %s\n", dnf_repo_get_description(repo)); + printf("\n\n"); + } + // 清理资源 + g_object_unref(context); + return 0; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o test_libdnf_dnf_context_get_repos test_libdnf_dnf_context_get_repos.c `pkg-config --cflags --libs libdnf glib-2.0 gobject-2.0`") + + def test(self): + self.cmd("./test_libdnf_dnf_context_get_repos") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for file in ['test_libdnf_dnf_context_get_repos', 'test_libdnf_dnf_context_get_repos.c']: + if os.path.exists(file): + self.cmd(f"rm -rf {file}") diff --git a/tests/system_libraries/libdnf/tc_libdnf_libdnf_func_002.py b/tests/system_libraries/libdnf/tc_libdnf_libdnf_func_002.py new file mode 100644 index 0000000000000000000000000000000000000000..66705de4ee17a6f83f4db8502a5f7127526d6125 --- /dev/null +++ b/tests/system_libraries/libdnf/tc_libdnf_libdnf_func_002.py @@ -0,0 +1,109 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libdnf_libdnf_func_002.py +@Time: 2024/03/26 14:08:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libdnf_libdnf_func_002.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libdnf libdnf-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + gen_dnf_conf = r'''cat < dnf002.conf +[main] +arch=x86_64 +EOF''' + code = r'''cat > test_dnf_context_get_arch.c << EOF +#include +#include +#include + +int main(int argc, char **argv) { + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + // 创建 KeyFile对象以读取配置文件 + GKeyFile *config_file = g_key_file_new(); + GError *error = NULL; + gboolean key_file_load_success = g_key_file_load_from_file(config_file, argv[1], G_KEY_FILE_NONE, &error); + if (!key_file_load_success) { + fprintf(stderr, "Failed to load config file: %s\n", error ? error->message : "Unknown error"); + if (error) g_error_free(error); + g_key_file_free(config_file); + return 1; + } + + // 从配置文件中获取'arch'信息 + gchar *arch = g_key_file_get_string(config_file, "main", "arch", &error); + if (error != NULL) { + fprintf(stderr, "Failed to get 'arch' from config file: %s\n", error->message); + g_error_free(error); + g_key_file_free(config_file); + return 1; + } + + // 初始化libdnf上下文 + DnfContext *context = dnf_context_new(); + if (context == NULL) { + fprintf(stderr, "Failed to create DnfContext.\n"); + g_free(arch); + g_key_file_free(config_file); + return 1; + } + + // 指定 DNF 配置文件路径 + dnf_context_set_config_file_path(argv[1]); + dnf_context_set_solv_dir(context, "/var/dnf/solv"); + + // 初始化 DnfContext,使其读取配置文件 + if (!dnf_context_setup(context, NULL, &error)) { + fprintf(stderr, "Failed to setup DnfContext: %s\n", error ? error->message : "Unknown error"); + if (error) g_error_free(error); + g_object_unref(context); + return 1; + } + + // 输出获取到的架构信息 + const gchar *arch_res = dnf_context_get_arch(context); + if (arch_res == NULL) { + dnf_context_set_arch(context, arch); + } + printf("Arch set in DnfContext: %s\n", dnf_context_get_arch(context)); + + // 清理资源 + g_object_unref(context); + g_free(arch); + g_key_file_free(config_file); + return 0; +} +EOF''' + self.cmd(gen_dnf_conf) + self.cmd(code) + self.cmd("gcc -o test_dnf_context_get_arch test_dnf_context_get_arch.c `pkg-config --cflags --libs libdnf gobject-2.0`") + + def test(self): + self.cmd("./test_dnf_context_get_arch dnf002.conf") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for file in ['test_dnf_context_get_arch', 'test_dnf_context_get_arch.c', 'dnf002.conf']: + if os.path.exists(file): + self.cmd(f"rm -rf {file}") diff --git a/tests/system_libraries/libdnf/tc_libdnf_libdnf_func_003.py b/tests/system_libraries/libdnf/tc_libdnf_libdnf_func_003.py new file mode 100644 index 0000000000000000000000000000000000000000..b190e48c11a55af38ffa67f83f41665cb66a3704 --- /dev/null +++ b/tests/system_libraries/libdnf/tc_libdnf_libdnf_func_003.py @@ -0,0 +1,105 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libdnf_libdnf_func_003.py +@Time: 2024/03/26 14:08:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libdnf_libdnf_func_003.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libdnf libdnf-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + gen_dnf_conf = r'''cat < dnf003.conf +[main] +repo_dir=/etc/yum.repos.d +EOF''' + code = r'''cat > test_dnf_context_get_repo_dir.c << EOF +#include +#include +#include + +int main(int argc, char **argv) { + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + // 创建KeyFile对象以读取配置文件 + GKeyFile *config_file = g_key_file_new(); + GError *error = NULL; + gboolean key_file_load_success = g_key_file_load_from_file(config_file, argv[1], G_KEY_FILE_NONE, &error); + if (!key_file_load_success) { + fprintf(stderr, "Failed to load config file: %s\n", error ? error->message : "Unknown error"); + if (error) g_error_free(error); + g_key_file_free(config_file); + return 1; + } + + // 从配置文件中获取'repo_dir'信息 + gchar *get_repo_dir = g_key_file_get_string(config_file, "main", "repo_dir", &error); + if (error != NULL) { + fprintf(stderr, "Failed to get 'repo_dir' from config file: %s\n", error->message); + g_error_free(error); + g_key_file_free(config_file); + return 1; + } + + // 初始化 DnfContext + DnfContext *context = dnf_context_new(); + if (!context) { + fprintf(stderr, "Failed to create DnfContext.\n"); + return 1; + } + + // 指定 DNF 配置文件路径 + dnf_context_set_config_file_path(argv[1]); + dnf_context_set_solv_dir(context, "/var/dnf/solv"); + + // 初始化 DnfContext,使其读取配置文件 + if (!dnf_context_setup(context, NULL, &error)) { + fprintf(stderr, "Failed to setup DnfContext: %s\n", error ? error->message : "Unknown error"); + if (error) g_error_free(error); + g_object_unref(context); + return 1; + } + + // 获取仓库目录 + const gchar *repo_dir = dnf_context_get_repo_dir(context); + if (repo_dir == NULL) { + dnf_context_set_repo_dir(context, get_repo_dir); + } + + printf("Repository directory: %s\n", dnf_context_get_repo_dir(context)); + // 清理资源 + g_object_unref(context); + return 0; +} +EOF''' + self.cmd(gen_dnf_conf) + self.cmd(code) + self.cmd("gcc -o test_dnf_context_get_repo_dir test_dnf_context_get_repo_dir.c `pkg-config --cflags --libs libdnf gobject-2.0`") + + def test(self): + self.cmd("./test_dnf_context_get_repo_dir dnf003.conf") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for file in ['test_dnf_context_get_repo_dir', 'test_dnf_context_get_repo_dir.c', 'dnf003.conf']: + if os.path.exists(file): + self.cmd(f"rm -rf {file}") diff --git a/tests/system_libraries/libdnf/tc_libdnf_libdnf_func_004.py b/tests/system_libraries/libdnf/tc_libdnf_libdnf_func_004.py new file mode 100644 index 0000000000000000000000000000000000000000..c73c85ae39191c34aa8d16d200b1e1df8f4cba70 --- /dev/null +++ b/tests/system_libraries/libdnf/tc_libdnf_libdnf_func_004.py @@ -0,0 +1,106 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libdnf_libdnf_func_004.py +@Time: 2024/03/26 14:08:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libdnf_libdnf_func_004.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libdnf libdnf-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + gen_dnf_conf = r'''cat < dnf004.conf +[main] +releasever=23 +EOF''' + code = r'''cat > test_dnf_context_get_release_ver.c << EOF +#include +#include +#include +#include + +int main(int argc, char **argv) { + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + // 创建 KeyFile对象以读取配置文件 + GKeyFile *config_file = g_key_file_new(); + GError *error = NULL; + gboolean key_file_load_success = g_key_file_load_from_file(config_file, argv[1], G_KEY_FILE_NONE, &error); + if (!key_file_load_success) { + fprintf(stderr, "Failed to load config file: %s\n", error ? error->message : "Unknown error"); + if (error) g_error_free(error); + g_key_file_free(config_file); + return 1; + } + + // 从配置文件中获取releasever信息 + gchar *releasever = g_key_file_get_string(config_file, "main", "releasever", &error); + if (error != NULL) { + fprintf(stderr, "Failed to get 'releasever' from config file: %s\n", error->message); + g_error_free(error); + g_key_file_free(config_file); + return 1; + } + + // 初始化DnfContext + DnfContext *context = dnf_context_new(); + if (context == NULL) { + fprintf(stderr, "Failed to create DnfContext.\n"); + return 1; + } + + // 指定DNF配置文件路径 + dnf_context_set_config_file_path(argv[1]); + dnf_context_set_solv_dir(context, "/var/dnf/solv"); + + // 初始化DnfContext,使其读取配置文件 + if (!dnf_context_setup(context, NULL, &error)) { + fprintf(stderr, "Failed to setup DnfContext: %s\n", error ? error->message : "Unknown error"); + if (error) g_error_free(error); + g_object_unref(context); + return 1; + } + + // 获取发行版版本 + const gchar *release_ver = dnf_context_get_release_ver(context); + if (release_ver == NULL) { + dnf_context_set_release_ver(context, releasever); + } + + printf("Release version: %s\n", dnf_context_get_release_ver(context)); + // 清理资源 + g_object_unref(context); + return 0; +} +EOF''' + self.cmd(gen_dnf_conf) + self.cmd(code) + self.cmd("gcc -o test_dnf_context_get_release_ver test_dnf_context_get_release_ver.c `pkg-config --cflags --libs libdnf gobject-2.0`") + + def test(self): + self.cmd("./test_dnf_context_get_release_ver dnf004.conf") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for file in ['test_dnf_context_get_release_ver', 'test_dnf_context_get_release_ver.c', 'dnf004.conf']: + if os.path.exists(file): + self.cmd(f"rm -rf {file}") diff --git a/tests/system_libraries/libdnf/tc_libdnf_libdnf_func_005.py b/tests/system_libraries/libdnf/tc_libdnf_libdnf_func_005.py new file mode 100644 index 0000000000000000000000000000000000000000..ca952a115787053dcb0118fdad40be782cb602a9 --- /dev/null +++ b/tests/system_libraries/libdnf/tc_libdnf_libdnf_func_005.py @@ -0,0 +1,105 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libdnf_libdnf_func_005.py +@Time: 2024/03/26 14:08:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libdnf_libdnf_func_005.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libdnf libdnf-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + gen_dnf_conf = r'''cat < dnf005.conf +[main] +platform_module=an23 +EOF''' + code = r'''cat > test_dnf_context_get_platform_module.c << EOF +#include +#include +#include +#include + +int main(int argc, char **argv) { + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + // 创建 KeyFile对象以读取配置文件 + GKeyFile *config_file = g_key_file_new(); + GError *error = NULL; + gboolean key_file_load_success = g_key_file_load_from_file(config_file, argv[1], G_KEY_FILE_NONE, &error); + if (!key_file_load_success) { + fprintf(stderr, "Failed to load config file: %s\n", error ? error->message : "Unknown error"); + if (error) g_error_free(error); + g_key_file_free(config_file); + return 1; + } + + // 从配置文件中获取platform_module信息 + gchar *p_module = g_key_file_get_string(config_file, "main", "platform_module", &error); + if (error != NULL) { + fprintf(stderr, "Failed to get 'platform_module' from config file: %s\n", error->message); + g_error_free(error); + g_key_file_free(config_file); + return 1; + } + + // 初始化 DnfContext + DnfContext *context = dnf_context_new(); + if (!context) { + fprintf(stderr, "Failed to create DnfContext.\n"); + return 1; + } + + // 指定DNF配置文件路径 + dnf_context_set_config_file_path(argv[1]); + dnf_context_set_solv_dir(context, "/var/dnf/solv"); + + // 初始化DnfContext,使其读取配置文件 + if (!dnf_context_setup(context, NULL, &error)) { + fprintf(stderr, "Failed to setup DnfContext: %s\n", error ? error->message : "Unknown error"); + if (error) g_error_free(error); + g_object_unref(context); + return 1; + } + + // 假设获取平台模块信息的函数存在 + const gchar *platform_module = dnf_context_get_platform_module(context); + if (platform_module == NULL) { + dnf_context_set_platform_module(context, p_module); + } + printf("Platform module: %s\n", dnf_context_get_platform_module(context)); + // 清理资源 + g_object_unref(context); + return 0; +} +EOF''' + self.cmd(gen_dnf_conf) + self.cmd(code) + self.cmd("gcc -o test_dnf_context_get_platform_module test_dnf_context_get_platform_module.c `pkg-config --cflags --libs libdnf gobject-2.0`") + + def test(self): + self.cmd("./test_dnf_context_get_platform_module dnf005.conf") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for file in ['test_dnf_context_get_platform_module', 'test_dnf_context_get_platform_module.c', 'dnf005.conf']: + if os.path.exists(file): + self.cmd(f"rm -rf {file}") diff --git a/tests/system_libraries/libdnf/tc_libdnf_libdnf_func_006.py b/tests/system_libraries/libdnf/tc_libdnf_libdnf_func_006.py new file mode 100644 index 0000000000000000000000000000000000000000..3f24e9e32ee86a0ef002862dd366f0fb14dff1d8 --- /dev/null +++ b/tests/system_libraries/libdnf/tc_libdnf_libdnf_func_006.py @@ -0,0 +1,99 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libdnf_libdnf_func_006.py +@Time: 2024/03/26 14:08:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libdnf_libdnf_func_006.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libdnf libdnf-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + gen_dnf_conf = r'''cat < dnf006.conf +[main] +rpm_verbosity=info +EOF''' + code = r'''cat > test_dnf_context_get_rpm_verbosity.c << EOF +#include +#include +#include +#include + +int main(int argc, char **argv) { + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + // 创建 GKeyFile 对象以读取配置文件 + GKeyFile *key_file = g_key_file_new(); + GError *error = NULL; + + // 加载 DNF 配置文件 + if (!g_key_file_load_from_file(key_file, argv[1], G_KEY_FILE_NONE, &error)) { + fprintf(stderr, "Failed to load config file: %s\n", error ? error->message : "Unknown error"); + if (error) g_error_free(error); + g_key_file_free(key_file); + return 1; + } + + // 获取 'rpm_verbosity' 配置项 + gchar *rpm_verbosity = g_key_file_get_string(key_file, "main", "rpm_verbosity", &error); + if (error != NULL) { + fprintf(stderr, "Failed to get 'rpm_verbosity' from config file: %s\n", error->message); + g_error_free(error); + g_key_file_free(key_file); + return 1; + } + + // 初始化 DnfContext + DnfContext *context = dnf_context_new(); + if (!context) { + fprintf(stderr, "Failed to create DnfContext.\n"); + g_free(rpm_verbosity); + g_key_file_free(key_file); + return 1; + } + + // 获取RPM详细信息级别 + const gchar *obtained_verbosity = dnf_context_get_rpm_verbosity(context); + if (obtained_verbosity == NULL) { + dnf_context_set_rpm_verbosity(context, rpm_verbosity); + } + + printf("RPM verbosity: %s\n", dnf_context_get_rpm_verbosity(context)); + // 清理资源 + g_object_unref(context); + g_free(rpm_verbosity); + g_key_file_free(key_file); + return 0; +} +EOF''' + self.cmd(gen_dnf_conf) + self.cmd(code) + self.cmd("gcc -o test_dnf_context_get_rpm_verbosity test_dnf_context_get_rpm_verbosity.c `pkg-config --cflags --libs libdnf gobject-2.0`") + + def test(self): + self.cmd("./test_dnf_context_get_rpm_verbosity dnf006.conf") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for file in ['test_dnf_context_get_rpm_verbosity', 'test_dnf_context_get_rpm_verbosity.c', 'dnf006.conf']: + if os.path.exists(file): + self.cmd(f"rm -rf {file}") diff --git a/tests/system_libraries/libdnf/tc_libdnf_libdnf_func_007.py b/tests/system_libraries/libdnf/tc_libdnf_libdnf_func_007.py new file mode 100644 index 0000000000000000000000000000000000000000..776a7b708e10fc10aed500d21aa55d589d8643a9 --- /dev/null +++ b/tests/system_libraries/libdnf/tc_libdnf_libdnf_func_007.py @@ -0,0 +1,98 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libdnf_libdnf_func_007.py +@Time: 2024/03/26 14:08:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libdnf_libdnf_func_007.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libdnf libdnf-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + gen_dnf_conf = r'''cat < dnf007.conf +[main] +install_root=/var/root +EOF''' + code = r'''cat > test_dnf_context_get_install_root.c << EOF +#include +#include +#include +#include + +int main(int argc, char **argv) { + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + // 创建 GKeyFile 对象以读取配置文件 + GKeyFile *key_file = g_key_file_new(); + GError *error = NULL; + + // 加载配置文件 + if (!g_key_file_load_from_file(key_file, argv[1], G_KEY_FILE_NONE, &error)) { + fprintf(stderr, "Failed to load config file: %s\n", error ? error->message : "Unknown error"); + if (error) g_error_free(error); + g_key_file_free(key_file); + return 1; + } + + // 从配置文件中获取 'install_root' 配置项 + gchar *install_root = g_key_file_get_string(key_file, "main", "install_root", &error); + if (error != NULL) { + fprintf(stderr, "Failed to get 'install_root' from config file: %s\n", error->message); + g_error_free(error); + g_key_file_free(key_file); + return 1; + } + + // 初始化 DnfContext + DnfContext *context = dnf_context_new(); + if (!context) { + fprintf(stderr, "Failed to create DnfContext.\n"); + g_free(install_root); + g_key_file_free(key_file); + return 1; + } + + // 获取并打印安装根目录信息 + const gchar *obtained_install_root = dnf_context_get_install_root(context); + if (obtained_install_root == NULL) { + dnf_context_set_install_root(context, install_root); + } + printf("Install root: %s\n", dnf_context_get_install_root(context)); + // 清理资源 + g_object_unref(context); + g_free(install_root); + g_key_file_free(key_file); + return 0; +} +EOF''' + self.cmd(gen_dnf_conf) + self.cmd(code) + self.cmd("gcc -o test_dnf_context_get_install_root test_dnf_context_get_install_root.c `pkg-config --cflags --libs libdnf gobject-2.0`") + + def test(self): + self.cmd("./test_dnf_context_get_install_root dnf007.conf") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for file in ['test_dnf_context_get_install_root', 'test_dnf_context_get_install_root.c', 'dnf007.conf']: + if os.path.exists(file): + self.cmd(f"rm -rf {file}") diff --git a/tests/system_libraries/libdnf/tc_libdnf_libdnf_func_008.py b/tests/system_libraries/libdnf/tc_libdnf_libdnf_func_008.py new file mode 100644 index 0000000000000000000000000000000000000000..92beae76113675876a65fd1f565c6762e4da85f7 --- /dev/null +++ b/tests/system_libraries/libdnf/tc_libdnf_libdnf_func_008.py @@ -0,0 +1,99 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libdnf_libdnf_func_008.py +@Time: 2024/03/26 14:08:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libdnf_libdnf_func_008.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libdnf libdnf-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + gen_dnf_conf = r'''cat < dnf008.conf +[main] +proxy=http://myproxy.example.com:3128 +EOF''' + code = r'''cat > test_dnf_context_get_http_proxy.c << EOF +#include +#include +#include +#include + +int main(int argc, char **argv) { + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + // 创建 GKeyFile 对象以读取配置文件 + GKeyFile *key_file = g_key_file_new(); + GError *error = NULL; + + // 加载配置文件 + if (!g_key_file_load_from_file(key_file, argv[1], G_KEY_FILE_NONE, &error)) { + fprintf(stderr, "Failed to load config file: %s\n", error ? error->message : "Unknown error"); + if (error) g_error_free(error); + g_key_file_free(key_file); + return 1; + } + + // 从配置文件中获取 'proxy' 配置项 + gchar *http_proxy = g_key_file_get_string(key_file, "main", "proxy", &error); + if (error != NULL) { + fprintf(stderr, "Failed to get 'proxy' from config file: %s\n", error->message); + g_error_free(error); + g_key_file_free(key_file); + return 1; + } + + // 初始化 DnfContext + DnfContext *context = dnf_context_new(); + if (!context) { + fprintf(stderr, "Failed to create DnfContext.\n"); + g_free(http_proxy); + g_key_file_free(key_file); + return 1; + } + + // 获取并打印 HTTP 代理信息 + const gchar *obtained_http_proxy = dnf_context_get_http_proxy(context); + if (obtained_http_proxy == NULL) { + dnf_context_set_http_proxy(context, http_proxy); + } + + printf("HTTP proxy: %s\n", dnf_context_get_http_proxy(context)); + // 清理资源 + g_object_unref(context); + g_free(http_proxy); + g_key_file_free(key_file); + return 0; +} +EOF''' + self.cmd(gen_dnf_conf) + self.cmd(code) + self.cmd("gcc -o test_dnf_context_get_http_proxy test_dnf_context_get_http_proxy.c `pkg-config --cflags --libs libdnf gobject-2.0`") + + def test(self): + self.cmd("./test_dnf_context_get_http_proxy dnf008.conf") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for file in ['test_dnf_context_get_http_proxy', 'test_dnf_context_get_http_proxy.c', 'dnf008.conf']: + if os.path.exists(file): + self.cmd(f"rm -rf {file}") diff --git a/tests/system_libraries/libdnf/tc_libdnf_libdnf_func_009.py b/tests/system_libraries/libdnf/tc_libdnf_libdnf_func_009.py new file mode 100644 index 0000000000000000000000000000000000000000..0712de43a917760f6546a8ee438614d6a0a5bccd --- /dev/null +++ b/tests/system_libraries/libdnf/tc_libdnf_libdnf_func_009.py @@ -0,0 +1,99 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libdnf_libdnf_func_009.py +@Time: 2024/03/26 14:08:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libdnf_libdnf_func_009.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libdnf libdnf-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + gen_dnf_conf = r'''cat < dnf009.conf +[main] +# 缓存有效期设置(以秒为单位) +metadata_expire=3600 +EOF''' + code = r'''cat > test_dnf_context_get_cache_age.c << EOF +#include +#include +#include +#include + +int main(int argc, char **argv) { + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + // 创建 GKeyFile 对象以读取配置文件 + GKeyFile *key_file = g_key_file_new(); + GError *error = NULL; + + // 加载配置文件 + if (!g_key_file_load_from_file(key_file, argv[1], G_KEY_FILE_NONE, &error)) { + fprintf(stderr, "Failed to load config file: %s\n", error ? error->message : "Unknown error"); + if (error) g_error_free(error); + g_key_file_free(key_file); + return 1; + } + + // 从配置文件中获取 'metadata_expire' 配置项 + guint cache_age = g_key_file_get_uint64(key_file, "main", "metadata_expire", &error); + if (error != NULL) { + fprintf(stderr, "Failed to get 'metadata_expire' from config file: %s\n", error->message); + g_error_free(error); + g_key_file_free(key_file); + return 1; + } + + // 初始化 DnfContext + DnfContext *context = dnf_context_new(); + if (!context) { + fprintf(stderr, "Failed to create DnfContext.\n"); + g_key_file_free(key_file); + return 1; + } + + // 获取并打印缓存有效期信息 + guint obtained_cache_age = dnf_context_get_cache_age(context); + if (!obtained_cache_age){ + // 设置缓存有效期到DnfContext + dnf_context_set_cache_age(context, cache_age); + } + + printf("Cache age: %u seconds\n", dnf_context_get_cache_age(context)); + // 清理资源 + g_object_unref(context); + g_key_file_free(key_file); + return 0; +} +EOF''' + self.cmd(gen_dnf_conf) + self.cmd(code) + self.cmd("gcc -o test_dnf_context_get_cache_age test_dnf_context_get_cache_age.c `pkg-config --cflags --libs libdnf gobject-2.0`") + + def test(self): + self.cmd("./test_dnf_context_get_cache_age dnf009.conf") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for file in ['test_dnf_context_get_cache_age', 'test_dnf_context_get_cache_age.c', 'dnf009.conf']: + if os.path.exists(file): + self.cmd(f"rm -rf {file}") diff --git a/tests/system_libraries/libdnf/tc_libdnf_libdnf_func_010.py b/tests/system_libraries/libdnf/tc_libdnf_libdnf_func_010.py new file mode 100644 index 0000000000000000000000000000000000000000..b26120e24213945bcf24434f40f2c2e9f0eefdd7 --- /dev/null +++ b/tests/system_libraries/libdnf/tc_libdnf_libdnf_func_010.py @@ -0,0 +1,90 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libdnf_libdnf_func_010.py +@Time: 2024/03/26 14:08:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libdnf_libdnf_func_010.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libdnf libdnf-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > test_dnf_package_get_arch.c << EOF +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + const char *package_name = argv[1]; + g_autoptr(GError) error = NULL; + g_autoptr(DnfSack) sack = dnf_sack_new(); + gboolean loaded; + + // Load system repository + loaded = dnf_sack_load_system_repo(sack, NULL, 0, &error); + if (!loaded) { + fprintf(stderr, "Error loading system repo: %s\n", error->message); + return 1; + } + + // Create a query to search for the provided package name + HyQuery query = hy_query_create(sack); + hy_query_filter(query, HY_PKG_NAME, HY_EQ, package_name); + + // Get list of packages that matches the query + GPtrArray *packages = hy_query_run(query); + if (packages->len == 0) { + fprintf(stderr, "No packages named '%s' found.\n", package_name); + hy_query_free(query); + return 1; + } + + // Get architecture information for the first package + DnfPackage *pkg = g_ptr_array_index(packages, 0); + const char *arch = dnf_package_get_arch(pkg); + printf("The architecture of the '%s' package is: %s\n", package_name, arch); + + // Cleanup + hy_query_free(query); + g_ptr_array_unref(packages); + + return 0; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o test_dnf_package_get_arch test_dnf_package_get_arch.c `pkg-config --cflags --libs libdnf gobject-2.0`") + + def test(self): + self.cmd("./test_dnf_package_get_arch make") + self.cmd("./test_dnf_package_get_arch bash") + self.cmd("./test_dnf_package_get_arch gcc") + self.cmd("./test_dnf_package_get_arch libdnf") + self.cmd("./test_dnf_package_get_arch python3") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for file in ['test_dnf_package_get_arch', 'test_dnf_package_get_arch.c']: + if os.path.exists(file): + self.cmd(f"rm -rf {file}") diff --git a/tests/system_libraries/libedit/tc_libedit_libedit_func_002.py b/tests/system_libraries/libedit/tc_libedit_libedit_func_002.py new file mode 100644 index 0000000000000000000000000000000000000000..a0a83fe726c3c2d0dd3197ceee216446606d4645 --- /dev/null +++ b/tests/system_libraries/libedit/tc_libedit_libedit_func_002.py @@ -0,0 +1,71 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libedit_libedit_func_002.py +@Time: 2024/03/15 14:20:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libedit_libedit_func_002.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libedit libedit-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > test_libedit_readline.c << EOF +#include +#include +#include + +int main() { + // Initialize readline (optional) + rl_initialize(); + + char *input; + // Prompt the user for input + input = readline("Enter some text: "); + // Check if EOF was reached (Ctrl+D) + if (input == NULL) { + printf("\nEOF reached.\n"); + return EXIT_SUCCESS; + } + // Check for empty input + if (input && *input) { + // Output the entered line + printf("You entered: '%s'\n", input); + } + // Free the memory allocated by readline + free(input); + return EXIT_SUCCESS; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o test_libedit_readline test_libedit_readline.c -ledit") + + def test(self): + ret_c, _ = self.cmd("echo hello |./test_libedit_readline", ignore_status=True) + self.assertEqual(0, ret_c) + ret_c, _ = self.cmd("echo 111 |./test_libedit_readline", ignore_status=True) + self.assertEqual(0, ret_c) + ret_c, _ = self.cmd("./test_libedit_readline <<<'龙蜥'", ignore_status=True) + self.assertEqual(0, ret_c) + self.cmd("./test_libedit_readline <<<'this a test for readline,0.0'") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for file in ['test_libedit_readline', 'test_libedit_readline.c']: + if os.path.exists(file): + self.cmd(f"rm -rf {file}") diff --git a/tests/system_libraries/libedit/tc_libedit_libedit_func_003.py b/tests/system_libraries/libedit/tc_libedit_libedit_func_003.py new file mode 100644 index 0000000000000000000000000000000000000000..7b692ddf0f7b20b058fee57120a12f97cabf31a4 --- /dev/null +++ b/tests/system_libraries/libedit/tc_libedit_libedit_func_003.py @@ -0,0 +1,84 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libedit_libedit_func_003.py +@Time: 2024/03/15 14:20:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libedit_libedit_func_003.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libedit libedit-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > test_libedit_el_gets.c << EOF +#include +#include +#include +#include + +int main() { + // Initialize EditLine and the associated history + EditLine *el = el_init("myprog", stdin, stdout, stderr); + History *hist = history_init(); + if (!el || !hist) { + fprintf(stderr, "EditLine or history initialization failed\n"); + return EXIT_FAILURE; + } + + // Configure history + HistEvent ev; + history(hist, &ev, H_SETSIZE, 100); + el_set(el, EL_HIST, history, hist); + + // Prompt and read a line from the user + int count; + const char *line = el_gets(el, &count); + + // Display the entered line + if (line) { + printf("You entered: %s", line); + } else { + printf("No input or error\n"); + } + + // Retrieve and display the current line buffer and cursor position + const LineInfo *li = el_line(el); + if (li) { + printf("Current line buffer: %.*s\n", (int)(li->lastchar - li->buffer), li->buffer); + printf("Cursor position: %td\n", li->cursor - li->buffer); + } + + // Clean up + history_end(hist); + el_end(el); + return EXIT_SUCCESS; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o test_libedit_el_gets test_libedit_el_gets.c -ledit") + + def test(self): + self.cmd("echo | ./test_libedit_el_gets") + self.cmd("./test_libedit_el_gets <<<'1234567'") + self.cmd("echo abcde| ./test_libedit_el_gets") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for file in ['test_libedit_el_gets', 'test_libedit_el_gets.c']: + if os.path.exists(file): + self.cmd(f"rm -rf {file}") diff --git a/tests/system_libraries/libedit/tc_libedit_libedit_func_004.py b/tests/system_libraries/libedit/tc_libedit_libedit_func_004.py new file mode 100644 index 0000000000000000000000000000000000000000..e52afe18a0f46a4b9a73fea28e60c68492ba0591 --- /dev/null +++ b/tests/system_libraries/libedit/tc_libedit_libedit_func_004.py @@ -0,0 +1,83 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libedit_libedit_func_004.py +@Time: 2024/03/15 14:20:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +import pexpect +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libedit_libedit_func_004.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libedit libedit-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > test_libedit_el_push.c << EOF +#include +#include +#include + +const char *prompt(EditLine *e) { + return "myprog> "; +} + +int main(int argc, char **argv) { + // Check if an argument is provided + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return EXIT_FAILURE; + } + // The string to push onto the input stream is the first argument + const char *str_to_push = argv[1]; + // Initialize EditLine + EditLine *el = el_init("myprog", stdin, stdout, stderr); + if (!el) { + fprintf(stderr, "EditLine initialization failed\n"); + return EXIT_FAILURE; + } + // Set the prompt function + el_set(el, EL_PROMPT, prompt); + // Push the external string onto the input stream + el_push(el, str_to_push); + // Add a newline to mark the end of the input + el_push(el, "\n"); + // Process the input that was pushed + int count; + const char *line; + if ((line = el_gets(el, &count)) != NULL && count > 0) { + printf("You entered: %s", line); // Echo the line back + // In a real application, you would parse and execute the command here + } + // Clean up + el_end(el); + // Explicitly exit the program + return EXIT_SUCCESS; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o test_libedit_el_push test_libedit_el_push.c -ledit") + + def test(self): + res,code = pexpect.run("./test_libedit_el_push 'hello world\n'", withexitstatus=True) + [ print(l) for l in res.decode("utf-8").strip().split('\n\n') ] + self.assertEqual(code, 0) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for file in ['test_libedit_el_push', 'test_libedit_el_push.c']: + if os.path.exists(file): + self.cmd(f"rm -rf {file}") \ No newline at end of file diff --git a/tests/system_libraries/libedit/tc_libedit_libedit_func_005.py b/tests/system_libraries/libedit/tc_libedit_libedit_func_005.py new file mode 100644 index 0000000000000000000000000000000000000000..2aae8284074b3a5b622d3c4a05473c82156eb530 --- /dev/null +++ b/tests/system_libraries/libedit/tc_libedit_libedit_func_005.py @@ -0,0 +1,88 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libedit_libedit_func_005.py +@Time: 2024/03/15 14:20:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +import pexpect +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libedit_libedit_func_005.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libedit libedit-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > test_libedit_el_insertstr.c << EOF +#include +#include +#include + +// Prompt function +const char *prompt(EditLine *e) { + return "Input> "; +} + +int main() { + // Initialize EditLine + EditLine *el = el_init("myprog", stdin, stdout, stderr); + if (!el) { + fprintf(stderr, "Failed to initialize EditLine\n"); + return EXIT_FAILURE; + } + + // Set the prompt function + el_set(el, EL_PROMPT, prompt); + + // Insert a string at the current cursor position + const char *insert_str = "Hello, "; + if (el_insertstr(el, insert_str) == -1) { + fprintf(stderr, "Failed to insert string\n"); + el_end(el); + return EXIT_FAILURE; + } + + // Process user input + int count; + const char *line; + while ((line = el_gets(el, &count)) != NULL) { + if (count > 0) { + printf("You entered: %s", line); + } else { + // User pressed Ctrl+D on an empty line + printf("\nCtrl+D pressed. Exiting.\n"); + break; + } + } + + // Clean up + el_end(el); + return EXIT_SUCCESS; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o test_libedit_el_insertstr test_libedit_el_insertstr.c -ledit") + + def test(self): + self.cmd("echo 11111111 | ./test_libedit_el_insertstr") + self.cmd("echo 'hello world' | ./test_libedit_el_insertstr") + self.cmd("./test_libedit_el_insertstr <<<'this a test about libedit'") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for file in ['test_libedit_el_insertstr', 'test_libedit_el_insertstr.c']: + if os.path.exists(file): + self.cmd(f"rm -rf {file}") \ No newline at end of file diff --git a/tests/system_libraries/libedit/tc_libedit_libedit_func_006.py b/tests/system_libraries/libedit/tc_libedit_libedit_func_006.py new file mode 100644 index 0000000000000000000000000000000000000000..176fe7c9abb41fbdfbc04f67968d6b247bec119e --- /dev/null +++ b/tests/system_libraries/libedit/tc_libedit_libedit_func_006.py @@ -0,0 +1,100 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libedit_libedit_func_006.py +@Time: 2024/03/15 14:20:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +import pexpect +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libedit_libedit_func_006.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libedit libedit-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > test_libedit_el_deletestr.c << EOF +#include +#include +#include + +// Prompt function +const char *prompt(EditLine *e) { + return "Input> "; +} + +int main() { + // Initialize EditLine + EditLine *el = el_init("myprog", stdin, stdout, stderr); + if (!el) { + fprintf(stderr, "Failed to initialize EditLine\n"); + return EXIT_FAILURE; + } + + // Set the prompt function + el_set(el, EL_PROMPT, prompt); + + // Insert an initial string that the user will be editing + const char *initial_str = "initial string"; + if (el_insertstr(el, initial_str) == -1) { + fprintf(stderr, "Failed to insert string\n"); + el_end(el); + return EXIT_FAILURE; + } + + // Allow the user to edit the line + int count; + const char *line = el_gets(el, &count); + if (count > 0) { + printf("Before deletion: %s", line); + + // Assume we want to delete the last 3 characters entered by the user + // Move the cursor to the end minus the number of characters to delete + if (el_cursor(el, count - 3) == -1) { + fprintf(stderr, "Failed to move cursor\n"); + el_end(el); + return EXIT_FAILURE; + } + + // Delete the last 3 characters + el_deletestr(el, 3); + + // Get the current content of the line + const LineInfo *li = el_line(el); + printf("After deletion: %.*s", (int)(li->lastchar - li->buffer), li->buffer); + } else { + // User pressed Ctrl+D on an empty line + printf("\nCtrl+D pressed. Exiting.\n"); + } + + // Clean up + el_end(el); + return EXIT_SUCCESS; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o test_libedit_el_deletestr test_libedit_el_deletestr.c -ledit") + + def test(self): + self.cmd("echo -e '11111111\n' | ./test_libedit_el_deletestr") + self.cmd("echo -e 'hello world\n' | ./test_libedit_el_deletestr") + self.cmd("./test_libedit_el_deletestr <<<'this a test about libedit\n'") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for file in ['test_libedit_el_deletestr', 'test_libedit_el_deletestr.c']: + if os.path.exists(file): + self.cmd(f"rm -rf {file}") \ No newline at end of file diff --git a/tests/system_libraries/libedit/tc_libedit_libedit_func_007.py b/tests/system_libraries/libedit/tc_libedit_libedit_func_007.py new file mode 100644 index 0000000000000000000000000000000000000000..e48dd35f1db110bbb2cf11aa571b6f198351616f --- /dev/null +++ b/tests/system_libraries/libedit/tc_libedit_libedit_func_007.py @@ -0,0 +1,86 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libedit_libedit_func_007.py +@Time: 2024/03/15 14:20:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +import pexpect +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libedit_libedit_func_007.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libedit libedit-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > test_libedit_el_wgets.c << EOF +#include +#include +#include +#include +#include + +// Prompt function +const wchar_t *prompt(EditLine *e) { + return L"Input> "; +} + +int main() { + // Set the locale to the user's default (usually specified in the LANG environment variable) + setlocale(LC_ALL, ""); + + // Initialize EditLine + EditLine *el = el_init("myprog", stdin, stdout, stderr); + if (!el) { + fwprintf(stderr, L"Failed to initialize EditLine\n"); + return EXIT_FAILURE; + } + + // Set the prompt function + el_set(el, EL_PROMPT_ESC, prompt, L'\1'); + + // Process user input + int count; + const wchar_t *line; + while ((line = el_wgets(el, &count)) != NULL) { + if (count > 0) { + // Echo the wide-character line back + wprintf(L"You entered: %ls", line); + } else if (count == 0) { + // User pressed Ctrl+D on an empty line + wprintf(L"\nCtrl+D pressed. Exiting.\n"); + break; + } + } + + // Clean up + el_end(el); + return EXIT_SUCCESS; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o test_libedit_el_wgets test_libedit_el_wgets.c -ledit") + + def test(self): + self.cmd("echo -e '1\n2\n3\n4\n5\n6' | ./test_libedit_el_wgets") + self.cmd("echo -e 'h\ne\nl\nl\no' | ./test_libedit_el_wgets") + self.cmd("./test_libedit_el_wgets <<<'t\nh\ni\ns\n \na\n \nt\ne\ns\nt\n \na\nb\no\nu\nt\n \nl\ni\nb\ne\nd\ni\nt'") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for file in ['test_libedit_el_wgets', 'test_libedit_el_wgets.c']: + if os.path.exists(file): + self.cmd(f"rm -rf {file}") \ No newline at end of file diff --git a/tests/system_libraries/libedit/tc_libedit_libedit_func_008.py b/tests/system_libraries/libedit/tc_libedit_libedit_func_008.py new file mode 100644 index 0000000000000000000000000000000000000000..0ba16d59a56808ebf9ecd720b7ce0611f1329a18 --- /dev/null +++ b/tests/system_libraries/libedit/tc_libedit_libedit_func_008.py @@ -0,0 +1,90 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libedit_libedit_func_008.py +@Time: 2024/03/15 14:20:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +import pexpect +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libedit_libedit_func_008.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libedit libedit-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > test_libedit_el_wpush.c << EOF +#include +#include +#include +#include +#include + +// Set the locale to the user's default (usually specified in the LANG environment variable) +void set_locale() { + if (setlocale(LC_ALL, "") == NULL) { + fwprintf(stderr, L"Unable to set locale. Make sure your LANG environment variable is set correctly.\n"); + exit(EXIT_FAILURE); + } +} + +// Prompt function +const wchar_t *prompt(EditLine *e) { + return L"Input> "; +} + +int main() { + // Set the locale + set_locale(); + + // Initialize EditLine + EditLine *el = el_init("myprog", stdin, stdout, stderr); + if (!el) { + fwprintf(stderr, L"Failed to initialize EditLine\n"); + return EXIT_FAILURE; + } + + // Set the prompt function + el_set(el, EL_PROMPT_ESC, prompt, L'\1'); + // Since we are using `el_wgets`, the `EditLine` library expects an ENTER key + // to process the input. We simulate this by pushing a newline character. + el_wpush(el, L"\n"); + + // Process the input that was pushed + int count; + const wchar_t *line = el_wgets(el, &count); + if (line != NULL && count > 0) { + wprintf(L"You entered: %ls\n", line); // Echo the line back + } + + // Clean up + el_end(el); + return EXIT_SUCCESS; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o test_libedit_el_wpush test_libedit_el_wpush.c -ledit") + + def test(self): + self.cmd("echo -e '0123456789abcdefghijklmnopqrstuvwxyz' | ./test_libedit_el_wpush") + self.cmd("echo -e 'hello world!,this is a test about libeit packages' | ./test_libedit_el_wpush") + + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for file in ['test_libedit_el_wpush', 'test_libedit_el_wpush.c']: + if os.path.exists(file): + self.cmd(f"rm -rf {file}") \ No newline at end of file diff --git a/tests/system_libraries/libedit/tc_libedit_libedit_func_009.py b/tests/system_libraries/libedit/tc_libedit_libedit_func_009.py new file mode 100644 index 0000000000000000000000000000000000000000..d4f7345d552aa5261a7b7ca47ed69dfb63fbd28c --- /dev/null +++ b/tests/system_libraries/libedit/tc_libedit_libedit_func_009.py @@ -0,0 +1,98 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libedit_libedit_func_009.py +@Time: 2024/03/15 14:20:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +import pexpect +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libedit_libedit_func_009.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libedit libedit-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > test_libedit_el_wline.c << EOF +#include +#include +#include +#include +#include + +// Set the locale to the user's default (usually specified in the LANG environment variable) +void set_locale() { + if (setlocale(LC_ALL, "") == NULL) { + fwprintf(stderr, L"Unable to set locale. Make sure your LANG environment variable is set correctly.\n"); + exit(EXIT_FAILURE); + } +} + +// Prompt function +const wchar_t *prompt(EditLine *e) { + return L"Input> "; +} + +int main() { + // Set the locale + set_locale(); + + // Initialize EditLine + EditLine *el = el_init("myprog", stdin, stdout, stderr); + if (!el) { + fwprintf(stderr, L"Failed to initialize EditLine\n"); + return EXIT_FAILURE; + } + + // Set the prompt function + el_set(el, EL_PROMPT_ESC, prompt, L'\1'); + + // Process user input + int count; + const wchar_t *line; + while ((line = el_wgets(el, &count)) != NULL && count > 0) { + // Use el_wline to get information about the current line + const LineInfoW *li = el_wline(el); + fwprintf(stdout, L"Whole line: '%.*ls'\n", li->lastchar - li->buffer, li->buffer); + fwprintf(stdout, L"Cursor position: %ld\n", li->cursor - li->buffer); + + // Print a marker to show the cursor position visually + for (const wchar_t *p = li->buffer; p < li->cursor; ++p) { + fwprintf(stdout, L" "); + } + fwprintf(stdout, L"^\n"); + + // Echo the line back + wprintf(L"You entered: %ls", line); + } + + // Clean up + el_end(el); + return EXIT_SUCCESS; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o test_libedit_el_wline test_libedit_el_wline.c -ledit") + + def test(self): + self.cmd("echo -e '0123456789abcdefghijklmnopqrstuvwxyz' | ./test_libedit_el_wline") + self.cmd("echo -e 'this is a test about libeit packages.' | ./test_libedit_el_wline") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for file in ['test_libedit_el_wline', 'test_libedit_el_wline.c']: + if os.path.exists(file): + self.cmd(f"rm -rf {file}") \ No newline at end of file diff --git a/tests/system_libraries/libevent/tc_libevent_func001.py b/tests/system_libraries/libevent/tc_libevent_func001.py new file mode 100644 index 0000000000000000000000000000000000000000..3348af860a0056fd2019f35c923d566b4bbd5267 --- /dev/null +++ b/tests/system_libraries/libevent/tc_libevent_func001.py @@ -0,0 +1,60 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libevent_func001.py +@Time: 2024/04/11 13:12:50 +@Author: gaohongmei +@Version: 1.0 +@Contact: wb-ghm935099@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: gaohongmei +""" +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_libevent_func001.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libevent libevent-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + self.cmd("mkdir /tmp/ghm/") + cmdline = """cat > /tmp/ghm/test_libevent.c < +#include +#include + +static void timer_cb(evutil_socket_t fd, short what, void *arg) { + printf("Timer event triggered.\\n"); + event_base_loopbreak((struct event_base*)arg); +} + +int main() { + struct event_base *base = event_base_new(); + struct event *timer = event_new(base, -1, 0, timer_cb, base); + struct timeval tv = { .tv_sec = 1, .tv_usec = 0 }; // 1秒后触发 + + if (event_add(timer, &tv) == -1) { + perror("event_add"); + return 1; + } + + event_base_dispatch(base); + event_free(timer); + event_base_free(base); + return 0; +} +""" + self.cmd(cmdline) + + def test(self): + self.cmd("gcc -o /tmp/ghm/test_libevent /tmp/ghm/test_libevent.c -levent -lpthread") + ret_c1, ret_o1 = self.cmd("/tmp/ghm/test_libevent") + self.assertIn("Timer event triggered.", ret_o1) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf /tmp/ghm/") \ No newline at end of file diff --git a/tests/system_libraries/libgcrypt/tc_libgcrypt_fun_001.py b/tests/system_libraries/libgcrypt/tc_libgcrypt_fun_001.py new file mode 100644 index 0000000000000000000000000000000000000000..47982042f3f4d0c870d079a7a1e04dc7cfd83bfc --- /dev/null +++ b/tests/system_libraries/libgcrypt/tc_libgcrypt_fun_001.py @@ -0,0 +1,170 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libgcrypt_fun_001.py +@Time: 2024/04/7 10:12:50 +@Author: hongfeng +@Version: 1.0 +@Contact: wb-zhf668260@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: hongfeng +""" + +from common.basetest import LocalTest +class Test(LocalTest): + """ + See tc_libgcrypt_fun_001.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libgcrypt-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = """cat > aes.c < +#include +#include + +#define CIPHER_ALGO GCRY_CIPHER_AES256 // 使用AES-256算法 + +void aes_encrypt(const char *plaintext, const char *key, const char *iv, char **ciphertext) { + gcry_error_t err; + gcry_cipher_hd_t hd; + + // 初始化加密上下文 + err = gcry_cipher_open(&hd, CIPHER_ALGO, GCRY_CIPHER_MODE_CBC, 0); + if (err != GPG_ERR_NO_ERROR) { + fprintf(stderr, "Error opening cipher: %s\\n", gcry_strerror(err)); + exit(1); + } + + // 设置密钥和初始化向量 + err = gcry_cipher_setkey(hd, key, 32); + if (err != GPG_ERR_NO_ERROR) { + fprintf(stderr, "Error setting key: %s\\n", gcry_strerror(err)); + gcry_cipher_close(hd); + exit(1); + } + err = gcry_cipher_setiv(hd, iv, 16); + if (err != GPG_ERR_NO_ERROR) { + fprintf(stderr, "Error setting IV: %s\\n", gcry_strerror(err)); + gcry_cipher_close(hd); + exit(1); + } + + // 确保数据长度是块大小的整数倍,并为最后一块添加必要的填充 + size_t plaintext_len = strlen(plaintext); + size_t block_size = gcry_cipher_get_algo_blklen(CIPHER_ALGO); + size_t last_block_size = strlen(plaintext) % block_size; + if (last_block_size > 0) { + // 需要填充到下一个完整块 + plaintext_len += block_size - last_block_size; + } + *ciphertext = malloc(plaintext_len + 1); + + /* 执行加密 */ + err = gcry_cipher_encrypt(hd, *ciphertext, plaintext_len, plaintext, plaintext_len); + if (err != GPG_ERR_NO_ERROR) { + fprintf(stderr, "Error encrypting %s\\n", gcry_strerror(err)); + free(*ciphertext); + gcry_cipher_close(hd); + exit(1); + } + + // 添加NULL终止符 + (*ciphertext)[plaintext_len] = '\\0'; + gcry_cipher_close(hd); +} + +void aes_decrypt(const char *ciphertext, const char *key, const char *iv, char **plaintext) { + gcry_error_t err; + gcry_cipher_hd_t hd; + + // 初始化加密上下文 + err = gcry_cipher_open(&hd, CIPHER_ALGO, GCRY_CIPHER_MODE_CBC, 0); + if (err != GPG_ERR_NO_ERROR) { + fprintf(stderr, "Error opening cipher for decryption: %s\\n", gcry_strerror(err)); + exit(1); + } + + // 设置密钥和初始化向量 + err = gcry_cipher_setkey(hd, key, 32); + if (err != GPG_ERR_NO_ERROR) { + fprintf(stderr, "Error setting decryption key: %s\\n", gcry_strerror(err)); + gcry_cipher_close(hd); + exit(1); + } + err = gcry_cipher_setiv(hd, iv, 16); + if (err != GPG_ERR_NO_ERROR) { + fprintf(stderr, "Error setting decryption IV: %s\\n", gcry_strerror(err)); + gcry_cipher_close(hd); + exit(1); + + } + + // 解密操作需要与加密相同的缓冲区长度 + size_t plaintext_len = strlen(ciphertext); + // 额外空间存放NULL终止符 + *plaintext = malloc(plaintext_len + 1); + + // 执行解密 + err = gcry_cipher_decrypt(hd, *plaintext, plaintext_len, ciphertext, plaintext_len); + if (err != GPG_ERR_NO_ERROR) { + fprintf(stderr, "Error decrypting %s\\n", gcry_strerror(err)); + free(*plaintext); + gcry_cipher_close(hd); + exit(1); + } + + // 添加NULL终止符 + (*plaintext)[plaintext_len] = '\\0'; + gcry_cipher_close(hd); +} + +int main(int argc, char *argv[]) { + if (argc != 2) { + fprintf(stderr, "Usage: %s \\n", argv[0]); + return 1; + } + + char key[32] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, + 0xed, 0xa3, 0xeb, 0xf4, 0xa1, 0x7b, 0x4a, 0x31, + 0xc9, 0x47, 0xae, 0x53, 0x7b, 0x39, 0x31, 0x0 + }; + char iv[16] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x0 + }; + + char *encrypted_text = NULL; + char *decrypted_text = NULL; + + size_t arg_length = strlen(argv[1]) + 1; + char plaintext[arg_length]; + strcpy(plaintext, argv[1]); + + aes_encrypt(plaintext, key, iv, &encrypted_text); + printf("Encrypted Text: %02X\\n", encrypted_text); + + aes_decrypt(encrypted_text, key, iv, &decrypted_text); + printf("Decrypted Text: %s\\n", decrypted_text); + + free(encrypted_text); + free(decrypted_text); + + return 0; +} +EOF""" + self.cmd(cmdline) + self.cmd("gcc -o aes aes.c `libgcrypt-config --cflags --libs`") + + def test(self): + ret_c,ret_o = self.cmd("./aes 'This is a test message for aes256!'") + self.assertTrue("Decrypted Text: This is a test message for aes256!" in ret_o, 'check output error.') + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm aes.c aes") diff --git a/tests/system_libraries/libgcrypt/tc_libgcrypt_fun_002.py b/tests/system_libraries/libgcrypt/tc_libgcrypt_fun_002.py new file mode 100644 index 0000000000000000000000000000000000000000..d037c78d9443d0388a454d147c138dbbdf1c34b7 --- /dev/null +++ b/tests/system_libraries/libgcrypt/tc_libgcrypt_fun_002.py @@ -0,0 +1,107 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libgcrypt_fun_002.py +@Time: 2024/04/08 11:12:50 +@Author: hongfeng +@Version: 1.0 +@Contact: wb-zhf668260@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: hongfeng +""" + +from common.basetest import LocalTest +class Test(LocalTest): + """ + See tc_libgcrypt_fun_002.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libgcrypt-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = """cat > hash_sha256.c < +#include +#include + +#define BUFFER_SIZE 1024 + +void hexlify(char* dest, const void* src, size_t src_len) { + static const char hexdigits[] = "0123456789abcdef"; + for (size_t i = 0; i < src_len; ++i) { + unsigned char byte = ((unsigned char*)src)[i]; + dest[i * 2 + 1] = hexdigits[byte & 0x0F]; + } + // 添加终止符 + dest[src_len * 2] = '\\0'; +} + +void test_hash_function(const char *message, const char *algo_name) { + gcry_error_t err; + gcry_md_hd_t hd; + unsigned char hash[gcry_md_get_algo_dlen(GCRY_MD_SHA256)]; + char computed_hash_hex[BUFFER_SIZE]; + + // 初始化 libgcrypt + if (!gcry_check_version(NULL)) { + fprintf(stderr, "Error: libgcrypt not initialized properly\\n"); + return; + } + + // 设置哈希算法 + err = gcry_md_open(&hd, algo_name, 0); + if (err != GPG_ERR_NO_ERROR) { + fprintf(stderr, "Error setting up %s: %s\\n", algo_name, gcry_strerror(err)); + return; + } + + // 计算哈希值 + gcry_md_write(hd, message, strlen(message)); + + // 获取哈希结果 + gcry_md_final(hd); + // 对于SHA-256,使用这个长度 + memcpy(hash, gcry_md_read(hd, 0), gcry_md_get_algo_dlen(GCRY_MD_SHA256)); + + // 打印哈希结果 + char hex_digest[2 * gcry_md_get_algo_dlen(GCRY_MD_SHA256) + 1]; + for (size_t i = 0; i < gcry_md_get_algo_dlen(GCRY_MD_SHA256); ++i) { + snprintf(hex_digest + 2*i, 3, "%02x", hash[i]); + } + // 添加终止符 + hex_digest[2 * gcry_md_get_algo_dlen(GCRY_MD_SHA256)] = '\\0'; + printf("%s\\n", hex_digest); + + // 清理资源 + gcry_md_close(hd); +} + +int main(int argc, char *argv[]) { + if (argc != 2) { + fprintf(stderr, "Usage: %s \\n", argv[0]); + return 1; + } + + size_t arg_length = strlen(argv[1]) + 1; + char test_string[arg_length]; + strcpy(test_string, argv[1]); + + // 测试SHA-256 + test_hash_function(test_string, GCRY_MD_SHA256); + + return 0; +} +EOF""" + self.cmd(cmdline) + self.cmd("gcc -o hash_sha256 hash_sha256.c `libgcrypt-config --cflags --libs`") + + def test(self): + ret_c,ret_o = self.cmd("./hash_sha256 'This is a test message.'") + expected_hash_value = "0668b515bfc41b90b6a90a6ae8600256e1c76a67d17c78a26127ddeb9b324435" + self.assertTrue(ret_o == expected_hash_value, 'The generated hash value is not correct.') + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm hash_sha256.c hash_sha256") diff --git a/tests/system_libraries/libgcrypt/tc_libgcrypt_fun_003.py b/tests/system_libraries/libgcrypt/tc_libgcrypt_fun_003.py new file mode 100644 index 0000000000000000000000000000000000000000..08369b47df23e1db1a815319fe181238b49f8694 --- /dev/null +++ b/tests/system_libraries/libgcrypt/tc_libgcrypt_fun_003.py @@ -0,0 +1,64 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libgcrypt_fun_003.py +@Time: 2024/04/09 10:12:50 +@Author: hongfeng +@Version: 1.0 +@Contact: wb-zhf668260@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: hongfeng +""" + +from common.basetest import LocalTest +class Test(LocalTest): + """ + See tc_libgcrypt_fun_003.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libgcrypt-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = """cat > random.c < +#include +#include +#include + +int main() { + // 初始化Libgcrypt + if (!gcry_check_version(NULL)) { + fprintf(stderr, "Error: libgcrypt version check failed\\n"); + return 1; + } + gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); + + // 定义一个缓冲区来存放随机数据 + unsigned char random_data[32]; + + // 使用GCRY_VERY_STRONG_RANDOM作为随机质量级别 + gcry_randomize(random_data, sizeof(random_data), GCRY_STRONG_RANDOM); + + // 成功生成随机数据,将其打印出来(这里转换为十六进制以便阅读) + for (size_t i = 0; i < sizeof(random_data); ++i) { + printf("%02X", random_data[i]); + } + printf("\\n"); + + return 0; +} +EOF""" + self.cmd(cmdline) + self.cmd("gcc -o random random.c `libgcrypt-config --cflags --libs`") + + def test(self): + ret_c, random1 = self.cmd("./random") + ret_c, random2 = self.cmd("./random") + ret_c, random3 = self.cmd("./random") + self.assertTrue(random1 != random2 and random2 != random3 and random1 != random3, "The generated random numbers are the same.") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm random.c random") diff --git a/tests/system_libraries/libgpg-error/tc_libgpg-error_fun_001.py b/tests/system_libraries/libgpg-error/tc_libgpg-error_fun_001.py new file mode 100644 index 0000000000000000000000000000000000000000..fa3c9cf0f197da2252a9b8049f14a64efdcae75c --- /dev/null +++ b/tests/system_libraries/libgpg-error/tc_libgpg-error_fun_001.py @@ -0,0 +1,57 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libgpg-error_fun_001.py +@Time: 2024/04/22 10:32:50 +@Author: hongfeng +@Version: 1.0 +@Contact: wb-zhf668260@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: hongfeng +""" + +from common.basetest import LocalTest +class Test(LocalTest): + """ + See tc_libgpg-error_fun_001.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libgpg-error-devel gcc"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = """cat > test01.c < +#include + +int main() { + // 使用实际API调用返回的错误代码 + gpg_error_t err = gpg_error(GPG_ERR_GENERAL); + + const char *msg = gpg_strerror(err); + const char *src = gpg_strsource(err); + + printf("Error message: %s\\n", msg); + printf("Error source: %s\\n", src); + + gpg_error_t base_err = gpg_error(GPG_ERR_GENERAL); + gpg_error_t wrapped_err = gpg_err_make(GPG_ERR_SOURCE_USER_1, base_err); + + // 验证错误代码未变 + assert(gpg_err_code(wrapped_err) == base_err); + // 验证来源已更改为USER_1 + assert(gpg_err_source(wrapped_err) == GPG_ERR_SOURCE_USER_1); +} +EOF""" + self.cmd(cmdline) + self.cmd("gcc -o test01 test01.c -lgpg-error") + + def test(self): + # 验证执行成功 + self.cmd("./test01") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm test01.c test01") + diff --git a/tests/system_libraries/libgpg-error/tc_libgpg-error_fun_002.py b/tests/system_libraries/libgpg-error/tc_libgpg-error_fun_002.py new file mode 100644 index 0000000000000000000000000000000000000000..6550d46cbbe2498eeb137f1d6a570c938725b481 --- /dev/null +++ b/tests/system_libraries/libgpg-error/tc_libgpg-error_fun_002.py @@ -0,0 +1,51 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libgpg-error_fun_002.py +@Time: 2024/04/22 10:32:50 +@Author: hongfeng +@Version: 1.0 +@Contact: wb-zhf668260@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: hongfeng +""" + +from common.basetest import LocalTest +class Test(LocalTest): + """ + See tc_libgpg-error_fun_002.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libgpg-error-devel libgcrypt-devel gcc"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = """cat > test02.c < +#include +#include + +#define CIPHER_ALGO GCRY_CIPHER_AES256 // 使用AES-256算法 + +int main() { + gcry_cipher_hd_t hd; + gcry_error_t gpg_err; + + // 没有指定cipher algorithm + gpg_err = gcry_cipher_open(&hd, NULL, GCRY_CIPHER_MODE_CBC, 200); + printf("%s\\n", gpg_strerror(gpg_err)); +} +EOF""" + self.cmd(cmdline) + self.cmd("gcc -o test02 test02.c -lgpg-error -lgcrypt") + + def test(self): + # 验证执行成功 + ret_c, ret_o = self.cmd("./test02") + self.assertTrue("Invalid cipher algorithm" in ret_o, 'check output error.') + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm test02.c test02") + diff --git a/tests/system_libraries/libgpg-error/tc_libgpg-error_fun_003.py b/tests/system_libraries/libgpg-error/tc_libgpg-error_fun_003.py new file mode 100644 index 0000000000000000000000000000000000000000..eab13dcb7fde58ba687ab936b623244dd4931d5e --- /dev/null +++ b/tests/system_libraries/libgpg-error/tc_libgpg-error_fun_003.py @@ -0,0 +1,71 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libgpg-error_fun_003.py +@Time: 2024/04/22 10:32:50 +@Author: hongfeng +@Version: 1.0 +@Contact: wb-zhf668260@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: hongfeng +""" + +from common.basetest import LocalTest +class Test(LocalTest): + """ + See tc_libgpg-error_fun_003.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libgpg-error-devel gcc"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = """cat > test03.c < +#include +#include +#include + +int main(void) { + // 自定义error代码 + int custom_error_code = 5; + // 自定义error来源 + gpg_err_source_t custom_error_source = GPG_ERR_SOURCE_USER_1; + + // 使用gpg_err_make()创建gpg_error_t. + gpg_error_t custom_gpg_error = gpg_err_make(custom_error_source, custom_error_code); + + printf("Custom gpg_error_t value: %lu\\n", (unsigned long) custom_gpg_error); + + // Extract the error source from the custom gpg_error_t value. + gpg_err_source_t extracted_error_source = gpg_err_source(custom_gpg_error); + gpg_err_code_t extracted_error_code = gpg_err_code(custom_gpg_error); + + printf("Extracted error source: %d\\n", extracted_error_source); + printf("Extracted error source: %d\\n", extracted_error_code); + + // Compare the original and extracted error sources. + if (custom_error_source == extracted_error_source) { + printf("Error source extraction successful.\\n"); + } else { + printf("Error source extraction failed.\\n"); + } + + return 0; +} +EOF""" + self.cmd(cmdline) + self.cmd("gcc -o test03 test03.c -lgpg-error") + + def test(self): + # 验证执行成功, 并且输出正确 + ret_c, ret_o = self.cmd("./test03") + self.assertTrue("Extracted error source: 32" in ret_o, 'check output error.') + self.assertTrue("Extracted error source: 5" in ret_o, 'check output error.') + self.assertTrue("Error source extraction successful" in ret_o, 'check output error.') + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm test03.c test03") + diff --git a/tests/system_libraries/libldb/tc_libldb_libldb_func_001.py b/tests/system_libraries/libldb/tc_libldb_libldb_func_001.py new file mode 100644 index 0000000000000000000000000000000000000000..398754eb0835d2f7be052dfab473a2cbe4199b2a --- /dev/null +++ b/tests/system_libraries/libldb/tc_libldb_libldb_func_001.py @@ -0,0 +1,80 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libldb_libldb_func_001.py +@Time: 2024/04/12 15:08:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libldb_libldb_func_001.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libldb libldb-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > test_libldb_ldb_base64_decode.c << EOF +#include +#include +#include + +int main(int argc, char *argv[]) { + // 检查是否提供了一个命令行参数(Base64编码的字符串) + if (argc != 2) { + fprintf(stderr, "用法: %s \n", argv[0]); + return EXIT_FAILURE; + } + + // 获取Base64编码字符串参数 + char *base64_encoded_string = argv[1]; + + // 输出原始的Base64编码字符串 + printf("原始Base64编码字符串: %s\n", base64_encoded_string); + + // 解码Base64编码字符串 + int bytes_decoded = ldb_base64_decode(base64_encoded_string); + + if (bytes_decoded < 0) { + fprintf(stderr, "解码失败\n"); + return EXIT_FAILURE; + } else { + printf("解码成功: %d 字节\n", bytes_decoded); + // 打印解码后的字符串 + // 注意:Base64解码后的数据可能不是一个以NULL结尾的字符串 + // 所以我们不能使用 %s 格式化字符串直接打印 + fwrite(base64_encoded_string, 1, bytes_decoded, stdout); + printf("\n"); + } + return EXIT_SUCCESS; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o test_libldb_ldb_base64_decode test_libldb_ldb_base64_decode.c -lldb") + + def test(self): + _, res = self.cmd("./test_libldb_ldb_base64_decode cm9vdAo=", ignore_status=True) + self.assertTrue('root' in res, 'Failed to base64 decode cm9vdAo=') + _, res = self.cmd("./test_libldb_ldb_base64_decode dGVzdAo=", ignore_status=True) + self.assertTrue('test' in res, 'Failed to base64 decode dGVzdAo=') + _, res = self.cmd("./test_libldb_ldb_base64_decode MTExMQo=", ignore_status=True) + self.assertTrue('1111' in res, 'Failed to base64 decode MTExMQo=') + _, res = self.cmd("./test_libldb_ldb_base64_decode dGVzdDAwMQo=", ignore_status=True) + self.assertTrue('test001' in res, 'Failed to base64 decode dGVzdDAwMQo=') + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for file in ['test_libldb_ldb_base64_decode', 'test_libldb_ldb_base64_decode.c']: + if os.path.exists(file): + self.cmd(f"rm -rf {file}") \ No newline at end of file diff --git a/tests/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_002.py b/tests/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_002.py new file mode 100644 index 0000000000000000000000000000000000000000..be7ef99f78585c94cd2e3af38e1a47ca98f087b8 --- /dev/null +++ b/tests/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_002.py @@ -0,0 +1,70 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libmodulemd_libmodulemd_func_002.py +@Time: 2024/03/05 09:20:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libmodulemd_libmodulemd_func_002.yaml for details + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libmodulemd libmodulemd-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > libmodulemd_modulemd_component_get_name.c << EOF +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + ModulemdComponentRpm *rpm_component; + const gchar *component_name; + + // Ensure the correct number of command-line arguments + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return EXIT_FAILURE; + } + + // Create a ModulemdComponentRpm object using the provided key (component name) + rpm_component = modulemd_component_rpm_new(argv[1]); + + // Since ModulemdComponentRpm is a subclass of ModulemdComponent, we can use + // modulemd_component_get_name to retrieve the name (key) of the component + component_name = modulemd_component_get_name(MODULEMD_COMPONENT(rpm_component)); + printf("The component name is: %s\n", component_name); + + // Clean up resources + g_object_unref(rpm_component); // Or if you're using g_autoptr: g_clear_object(&rpm_component); + + return EXIT_SUCCESS; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o libmodulemd_modulemd_component_get_name libmodulemd_modulemd_component_get_name.c `pkg-config --cflags --libs modulemd-2.0 glib-2.0`") + + def test(self): + self.cmd("./libmodulemd_modulemd_component_get_name COMPONENT_NAME") + self.cmd("./libmodulemd_modulemd_component_get_name component_name") + self.cmd("./libmodulemd_modulemd_component_get_name component::name") + + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for f in ['libmodulemd_modulemd_component_get_name.c', 'libmodulemd_modulemd_component_get_name']: + if os.path.exists(f): + self.cmd(f"rm -rf {f}") diff --git a/tests/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_003.py b/tests/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_003.py new file mode 100644 index 0000000000000000000000000000000000000000..b4027cfc0041838772466196ae2c7f1e19bd0da0 --- /dev/null +++ b/tests/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_003.py @@ -0,0 +1,81 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libmodulemd_libmodulemd_func_003.py +@Time: 2024/03/05 09:20:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libmodulemd_libmodulemd_func_003.yaml for details + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libmodulemd libmodulemd-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > libmodulemd_modulemd_build_config_compare.c << EOF +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + g_autoptr(ModulemdBuildConfig) build_config_1 = NULL; + g_autoptr(ModulemdBuildConfig) build_config_2 = NULL; + gint comparison_result; + + // Ensure the correct number of command-line arguments + if (argc != 3) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return EXIT_FAILURE; + } + + // Create two ModulemdBuildConfig objects and set their names + build_config_1 = modulemd_build_config_new(); + modulemd_build_config_set_context(build_config_1, argv[1]); + + build_config_2 = modulemd_build_config_new(); + modulemd_build_config_set_context(build_config_2, argv[2]); + + // Compare the two ModulemdBuildConfig objects + comparison_result = modulemd_build_config_compare(build_config_1, build_config_2); + + // Print the comparison result + if (comparison_result < 0) { + printf("BuildConfig '%s' is less than BuildConfig '%s'\n", argv[1], argv[2]); + } else if (comparison_result > 0) { + printf("BuildConfig '%s' is greater than BuildConfig '%s'\n", argv[1], argv[2]); + } else { + printf("BuildConfig '%s' is equal to BuildConfig '%s'\n", argv[1], argv[2]); + } + + // Cleanup is automatic due to the use of g_autoptr + return EXIT_SUCCESS; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o libmodulemd_modulemd_build_config_compare libmodulemd_modulemd_build_config_compare.c `pkg-config --cflags --libs modulemd-2.0 glib-2.0`") + + def test(self): + self.cmd("./libmodulemd_modulemd_build_config_compare config1 config2") + self.cmd("./libmodulemd_modulemd_build_config_compare test test") + self.cmd("./libmodulemd_modulemd_build_config_compare test test123") + self.cmd("./libmodulemd_modulemd_build_config_compare 123 123") + self.cmd("./libmodulemd_modulemd_build_config_compare 123 1234") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for f in ['libmodulemd_modulemd_build_config_compare.c', 'libmodulemd_modulemd_build_config_compare']: + if os.path.exists(f): + self.cmd(f"rm -rf {f}") diff --git a/tests/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_004.py b/tests/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_004.py new file mode 100644 index 0000000000000000000000000000000000000000..3be645e10e5580f4e1d6d62f6a10490fc21a0420 --- /dev/null +++ b/tests/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_004.py @@ -0,0 +1,79 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libmodulemd_libmodulemd_func_004.py +@Time: 2024/03/05 09:20:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libmodulemd_libmodulemd_func_004.yaml for details + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libmodulemd libmodulemd-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > libmodulemd_modulemd_build_config_validate.c << EOF +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + g_autoptr(ModulemdBuildConfig) build_config = NULL; + g_autoptr(GError) error = NULL; + gboolean valid; + + // Ensure the correct number of command-line arguments + if (argc != 4) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return EXIT_FAILURE; + } + + // Create a ModulemdBuildConfig object + build_config = modulemd_build_config_new(); + + // Set properties from command-line arguments + modulemd_build_config_set_context(build_config, argv[1]); + modulemd_build_config_set_platform(build_config, argv[2]); + modulemd_build_config_add_buildtime_requirement(build_config, argv[3], "1.0-1"); + + // Validate the ModulemdBuildConfig object + valid = modulemd_build_config_validate(build_config, &error); + + if (!valid) { + // If validation failed, print the error message + fprintf(stderr, "Validation failed: %s\n", error->message); + return EXIT_FAILURE; + } + + // If validation succeeded, print a success message + printf("Validation succeeded!\n"); + + return EXIT_SUCCESS; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o libmodulemd_modulemd_build_config_validate libmodulemd_modulemd_build_config_validate.c `pkg-config --cflags --libs modulemd-2.0 glib-2.0`") + + def test(self): + self.cmd("./libmodulemd_modulemd_build_config_validate c0ffee42 f33 bash") + self.cmd("./libmodulemd_modulemd_build_config_validate mytest an23 gcc") + self.cmd("./libmodulemd_modulemd_build_config_validate context platform1 component") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for f in ['libmodulemd_modulemd_build_config_validate.c', 'libmodulemd_modulemd_build_config_validate']: + if os.path.exists(f): + self.cmd(f"rm -rf {f}") diff --git a/tests/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_005.py b/tests/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_005.py new file mode 100644 index 0000000000000000000000000000000000000000..118e5e673836b91624792935b0521f23aa3a4737 --- /dev/null +++ b/tests/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_005.py @@ -0,0 +1,97 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libmodulemd_libmodulemd_func_005.py +@Time: 2024/03/05 09:20:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libmodulemd_libmodulemd_func_005.yaml for details + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libmodulemd libmodulemd-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > libmodulemd_modulemd_buildopts_get_rpm_macros.c << EOF +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + g_autoptr(ModulemdBuildopts) buildopts = NULL; + FILE *popen_result = NULL; // Use a regular pointer instead of g_autoptr + const gchar *rpm_macros; + char macro_buffer[256]; + + // Ensure the correct number of command-line arguments + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return EXIT_FAILURE; + } + + // Create a ModulemdBuildopts object + buildopts = modulemd_buildopts_new(); + + // Execute the user provided RPM command to get macros and read the output + popen_result = popen(argv[1], "r"); + if (!popen_result) { + fprintf(stderr, "Failed to run rpm command\n"); + return EXIT_FAILURE; + } + + // Read the output from the RPM command into the buffer + if (fgets(macro_buffer, sizeof(macro_buffer), popen_result) == NULL) { + fprintf(stderr, "Failed to read rpm macros\n"); + pclose(popen_result); // Make sure to close the popen result + return EXIT_FAILURE; + } + + // Close the popen result to avoid resource leaks + pclose(popen_result); + + // Remove any trailing newline character from the command output + macro_buffer[strcspn(macro_buffer, "\n")] = 0; + + // Set the RPM macros property using the output from the user provided command + modulemd_buildopts_set_rpm_macros(buildopts, macro_buffer); + + // Retrieve and print out the RPM macros + rpm_macros = modulemd_buildopts_get_rpm_macros(buildopts); + printf("The RPM macros for the build options are: %s\n", rpm_macros); + + return EXIT_SUCCESS; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o libmodulemd_modulemd_buildopts_get_rpm_macros libmodulemd_modulemd_buildopts_get_rpm_macros.c `pkg-config --cflags --libs modulemd-2.0 glib-2.0`") + + def test(self): + self.cmd("./libmodulemd_modulemd_buildopts_get_rpm_macros 'rpm -E %{?dist}'") + self.cmd("./libmodulemd_modulemd_buildopts_get_rpm_macros 'rpm -E %{getenv:HOME}'") + self.cmd("./libmodulemd_modulemd_buildopts_get_rpm_macros 'rpm -E %{u2p:%{_sourcedir}}'") + self.cmd("./libmodulemd_modulemd_buildopts_get_rpm_macros 'rpm -E %{u2p:%{_builddir}}'") + self.cmd("./libmodulemd_modulemd_buildopts_get_rpm_macros 'rpm -E %{u2p:%{buildroot}}'") + self.cmd("./libmodulemd_modulemd_buildopts_get_rpm_macros 'rpm -E %{u2p:%{_host_cpu}}'") + self.cmd("./libmodulemd_modulemd_buildopts_get_rpm_macros 'rpm -E %{_target_cpu}'") + self.cmd("./libmodulemd_modulemd_buildopts_get_rpm_macros 'rpm -E %{__mkdir_p}'") + self.cmd("./libmodulemd_modulemd_buildopts_get_rpm_macros 'rpm -E %{python3}'") + + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for f in ['libmodulemd_modulemd_buildopts_get_rpm_macros.c', 'libmodulemd_modulemd_buildopts_get_rpm_macros']: + if os.path.exists(f): + self.cmd(f"rm -rf {f}") diff --git a/tests/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_006.py b/tests/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_006.py new file mode 100644 index 0000000000000000000000000000000000000000..ccc752cbdb18ece2ba9de494e498fde6bd8b4fb9 --- /dev/null +++ b/tests/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_006.py @@ -0,0 +1,74 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libmodulemd_libmodulemd_func_006.py +@Time: 2024/03/05 09:20:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libmodulemd_libmodulemd_func_006.yaml for details + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libmodulemd libmodulemd-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > libmodulemd_modulemd_buildopts_get_rpm_whitelist_as_strv.c << EOF +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + g_autoptr(ModulemdBuildopts) buildopts = NULL; + g_auto(GStrv) whitelist = NULL; + const gchar *rpm; + + // Ensure at least one RPM package is provided as a command-line argument + if (argc < 2) { + fprintf(stderr, "Usage: %s [rpm_package...]\n", argv[0]); + return EXIT_FAILURE; + } + + // Create a ModulemdBuildopts object + buildopts = modulemd_buildopts_new(); + + // Add RPM packages to the whitelist from the command-line arguments + for (int i = 1; i < argc; i++) { + rpm = argv[i]; + modulemd_buildopts_add_rpm_to_whitelist(buildopts, rpm); + } + + // Retrieve and print out the RPM whitelist + whitelist = modulemd_buildopts_get_rpm_whitelist_as_strv(buildopts); + printf("RPM whitelist:\n"); + for (gchar **rpm_ptr = whitelist; rpm_ptr && *rpm_ptr; rpm_ptr++) { + printf(" - %s\n", *rpm_ptr); + } + + return EXIT_SUCCESS; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o libmodulemd_modulemd_buildopts_get_rpm_whitelist_as_strv libmodulemd_modulemd_buildopts_get_rpm_whitelist_as_strv.c `pkg-config --cflags --libs modulemd-2.0 glib-2.0`") + + def test(self): + self.cmd("./libmodulemd_modulemd_buildopts_get_rpm_whitelist_as_strv gcc make bash cmake") + + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for f in ['libmodulemd_modulemd_buildopts_get_rpm_whitelist_as_strv.c', 'libmodulemd_modulemd_buildopts_get_rpm_whitelist_as_strv']: + if os.path.exists(f): + self.cmd(f"rm -rf {f}") diff --git a/tests/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_007.py b/tests/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_007.py new file mode 100644 index 0000000000000000000000000000000000000000..eaf44d52e8a905f161dd48b041dd7e1e9d986d0f --- /dev/null +++ b/tests/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_007.py @@ -0,0 +1,74 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libmodulemd_libmodulemd_func_007.py +@Time: 2024/03/05 09:20:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libmodulemd_libmodulemd_func_007.yaml for details + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libmodulemd libmodulemd-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > libmodulemd_modulemd_buildopts_get_arches_as_strv.c << EOF +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + g_autoptr(ModulemdBuildopts) buildopts = NULL; + g_auto(GStrv) arches = NULL; + const gchar *arch; + + // Ensure at least one architecture is provided as a command-line argument + if (argc < 2) { + fprintf(stderr, "Usage: %s [arch...]\n", argv[0]); + return EXIT_FAILURE; + } + + // Create a ModulemdBuildopts object + buildopts = modulemd_buildopts_new(); + + // Add architectures to the build options from the command-line arguments + for (int i = 1; i < argc; i++) { + arch = argv[i]; + modulemd_buildopts_add_arch(buildopts, arch); + } + + // Retrieve and print out the list of architectures + arches = modulemd_buildopts_get_arches_as_strv(buildopts); + printf("Architectures in the build options:\n"); + for (gchar **arch_ptr = arches; arch_ptr && *arch_ptr; arch_ptr++) { + printf(" - %s\n", *arch_ptr); + } + + return EXIT_SUCCESS; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o libmodulemd_modulemd_buildopts_get_arches_as_strv libmodulemd_modulemd_buildopts_get_arches_as_strv.c `pkg-config --cflags --libs modulemd-2.0 glib-2.0`") + + def test(self): + self.cmd("./libmodulemd_modulemd_buildopts_get_arches_as_strv x86_64 aarch64 ppc64le") + + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for f in ['libmodulemd_modulemd_buildopts_get_arches_as_strv.c', 'libmodulemd_modulemd_buildopts_get_arches_as_strv']: + if os.path.exists(f): + self.cmd(f"rm -rf {f}") diff --git a/tests/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_008.py b/tests/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_008.py new file mode 100644 index 0000000000000000000000000000000000000000..dcd4bba920e3af235af770dd815d9417e0ee0163 --- /dev/null +++ b/tests/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_008.py @@ -0,0 +1,158 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libmodulemd_libmodulemd_func_008.py +@Time: 2024/03/05 09:20:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libmodulemd_libmodulemd_func_008.yaml for details + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libmodulemd libmodulemd-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + gen_yaml_f = r'''cat > gen_yaml_to_get_repos.yaml <- + A simple module for demonstration purposes. + license: + module: [ MIT ] + components: + rpms: + examplerpm: + rationale: Required for the example module + ref: main + repository: https://example.com/repositories/examplerpm + cache: https://example.com/cache + buildorder: 10 +EOF''' + code = r'''cat > libmodulemd_modulemd_component_rpm_get_repository.c << EOF +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + g_autoptr(GError) error = NULL; + g_autoptr(ModulemdModuleIndex) index = NULL; + g_autoptr(GPtrArray) failures = NULL; + ModulemdModule *module = NULL; + ModulemdModuleStream *stream = NULL; + ModulemdComponentRpm *component_rpm = NULL; + const gchar *repository = NULL; + FILE *yaml_stream = NULL; + guint64 version; + const gchar *context; + const gchar *arch; + + // Ensure the correct number of command-line arguments + if (argc != 7) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return EXIT_FAILURE; + } + + const gchar *yaml_file_path = argv[1]; + const gchar *module_name = argv[2]; + const gchar *stream_name = argv[3]; + version = g_ascii_strtoull(argv[4], NULL, 10); // Assuming version is passed as a string + context = argv[5]; + arch = argv[6]; + + // Check if the YAML file exists and is readable + if (access(yaml_file_path, R_OK) != 0) { + perror("Error accessing the specified YAML file"); + return EXIT_FAILURE; + } + + // Open the YAML file as a stream + yaml_stream = fopen(yaml_file_path, "rb"); + if (!yaml_stream) { + fprintf(stderr, "Failed to open the YAML file: %s\n", yaml_file_path); + return EXIT_FAILURE; + } + + // Create a new module index + index = modulemd_module_index_new(); + if (!index) { + fprintf(stderr, "Could not create a new ModulemdModuleIndex object.\n"); + fclose(yaml_stream); + return EXIT_FAILURE; + } + + // Update the index with the contents of the YAML file + if (!modulemd_module_index_update_from_stream(index, yaml_stream, TRUE, &failures, &error)) { + fprintf(stderr, "Failed to update the module index: %s\n", error->message); + fclose(yaml_stream); + g_clear_error(&error); + return EXIT_FAILURE; + } + + // Close the YAML file stream + fclose(yaml_stream); + + // Retrieve the specified module from the index + module = modulemd_module_index_get_module(index, module_name); + if (!module) { + fprintf(stderr, "Module '%s' could not be found in the index.\n", module_name); + return EXIT_FAILURE; + } + + // Retrieve the specific stream of the module + stream = modulemd_module_get_stream_by_NSVCA(module, stream_name, version, context, arch, &error); + if (!stream) { + fprintf(stderr, "Stream '%s' for module '%s' with version '%lu', context '%s', and architecture '%s' could not be found: %s\n", + stream_name, module_name, (unsigned long)version, context, arch, error->message); + g_clear_error(&error); + return EXIT_FAILURE; + } + + // Retrieve the specific RPM component from the stream + const gchar *rpm_component_name = "examplerpm"; // Replace with actual component name if needed. + component_rpm = modulemd_module_stream_v2_get_rpm_component(MODULEMD_MODULE_STREAM_V2(stream), rpm_component_name); + if (!component_rpm) { + fprintf(stderr, "RPM component '%s' could not be found in stream '%s' of module '%s'.\n", rpm_component_name, stream_name, module_name); + return EXIT_FAILURE; + } + + // Get repository information from the RPM component + repository = modulemd_component_rpm_get_repository(component_rpm); + printf("RPM Component: %s, Repository: %s\n", rpm_component_name, (repository ? repository : "(not available)")); + + return EXIT_SUCCESS; +} +EOF''' + self.cmd(gen_yaml_f) + self.cmd(code) + self.cmd("gcc -o libmodulemd_modulemd_component_rpm_get_repository libmodulemd_modulemd_component_rpm_get_repository.c `pkg-config --cflags --libs modulemd-2.0`") + + def test(self): + self.cmd("./libmodulemd_modulemd_component_rpm_get_repository gen_yaml_to_get_repos.yaml mymodule mystream 1 c0ffee43 noarch") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for f in ['libmodulemd_modulemd_component_rpm_get_repository.c', 'libmodulemd_modulemd_component_rpm_get_repository', 'gen_yaml_to_get_repos.yaml']: + if os.path.exists(f): + self.cmd(f"rm -rf {f}") diff --git a/tests/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_009.py b/tests/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_009.py new file mode 100644 index 0000000000000000000000000000000000000000..3d5b87d853b2d9726b370db1720c2ef68ba76134 --- /dev/null +++ b/tests/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_009.py @@ -0,0 +1,85 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libmodulemd_libmodulemd_func_009.py +@Time: 2024/03/05 09:20:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libmodulemd_libmodulemd_func_009.yaml for details + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libmodulemd libmodulemd-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > libmodulemd_modulemd_component_rpm_get_srpm_buildroot.c << EOF +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + g_autoptr(ModulemdComponentRpm) component_rpm = NULL; + gboolean buildroot; + + // Ensure the correct number of command-line arguments + if (argc != 3) { + fprintf(stderr, "Usage: %s \n", argv[0]); + fprintf(stderr, "BuildrootFlag should be 'true' or 'false'.\n"); + return EXIT_FAILURE; + } + + // Get the RPM_KEY from the command-line argument + const gchar *key = argv[1]; + + // Parse the BuildrootFlag from the command-line argument + if (g_strcmp0(argv[2], "true") == 0) { + buildroot = TRUE; + } else if (g_strcmp0(argv[2], "false") == 0) { + buildroot = FALSE; + } else { + fprintf(stderr, "Invalid BuildrootFlag value: %s\n", argv[2]); + return EXIT_FAILURE; + } + + // Create a ModulemdComponentRpm object with the key + component_rpm = modulemd_component_rpm_new(key); + if (!component_rpm) { + fprintf(stderr, "Failed to create ModulemdComponentRpm object\n"); + return EXIT_FAILURE; + } + + // Set the SRPM buildroot flag + modulemd_component_rpm_set_srpm_buildroot(component_rpm, buildroot); + + // Output the buildroot flag to confirm it's set correctly + gboolean current_buildroot = modulemd_component_rpm_get_srpm_buildroot(component_rpm); + printf("The SRPM buildroot for component RPM '%s' is set to: %s\n", + key, current_buildroot ? "true" : "false"); + + return EXIT_SUCCESS; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o libmodulemd_modulemd_component_rpm_get_srpm_buildroot libmodulemd_modulemd_component_rpm_get_srpm_buildroot.c `pkg-config --cflags --libs modulemd-2.0 glib-2.0`") + + def test(self): + self.cmd("./libmodulemd_modulemd_component_rpm_get_srpm_buildroot pkg true") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for f in ['libmodulemd_modulemd_component_rpm_get_srpm_buildroot.c', 'libmodulemd_modulemd_component_rpm_get_srpm_buildroot']: + if os.path.exists(f): + self.cmd(f"rm -rf {f}") diff --git a/tests/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_010.py b/tests/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_010.py new file mode 100644 index 0000000000000000000000000000000000000000..5504352319eb90511e0248668d0df7a67e7b34d9 --- /dev/null +++ b/tests/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_010.py @@ -0,0 +1,150 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libmodulemd_libmodulemd_func_010.py +@Time: 2024/03/05 09:20:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libmodulemd_libmodulemd_func_010.yaml for details + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libmodulemd libmodulemd-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + gen_yaml_f = r'''cat > gen_yaml_to_get_module_name.yaml < libmodulemd_modulemd_defaults_get_module_name.c << EOF +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + g_autoptr(GError) error = NULL; + g_autoptr(ModulemdModuleIndex) index = NULL; + g_autoptr(GPtrArray) failures = NULL; + GHashTable *default_streams = NULL; + const gchar *module_name; + const gchar *default_stream; + GHashTableIter iter; + gpointer key, value; + + // Check command-line arguments + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return EXIT_FAILURE; + } + + // Create a new ModuleIndex + index = modulemd_module_index_new(); + if (!index) { + fprintf(stderr, "Could not create module index object.\n"); + return EXIT_FAILURE; + } + + // Initialize the array for collecting failures + failures = g_ptr_array_new_with_free_func(g_object_unref); + + // Read the YAML file and update the index + if (!modulemd_module_index_update_from_file(index, argv[1], TRUE, &failures, &error)) { + fprintf(stderr, "Error parsing module metadata: %s\n", error->message); + // Handle each parsing failure (if any) + if (failures != NULL) { + for (guint i = 0; i < failures->len; i++) { + ModulemdSubdocumentInfo *failure = (ModulemdSubdocumentInfo *)g_ptr_array_index(failures, i); + fprintf(stderr, "Subdocument failed to parse: %s\n", modulemd_subdocument_info_get_gerror(failure)->message); + } + } + return EXIT_FAILURE; + } + + // Get the default streams as a hash table + default_streams = modulemd_module_index_get_default_streams_as_hash_table(index, NULL); + if (!default_streams) { + fprintf(stderr, "Could not retrieve default streams hash table.\n"); + return EXIT_FAILURE; + } + + // Iterate over the hash table and print the module names and default streams + g_hash_table_iter_init(&iter, default_streams); + while (g_hash_table_iter_next(&iter, &key, &value)) { + module_name = (const gchar *)key; + default_stream = (const gchar *)value; + printf("Module name: %s, Default stream: %s\n", module_name, default_stream); + } + + // Clean up + g_hash_table_unref(default_streams); + + return EXIT_SUCCESS; +} +EOF''' + self.cmd(gen_yaml_f) + self.cmd(code) + self.cmd("gcc -o libmodulemd_modulemd_defaults_get_module_name libmodulemd_modulemd_defaults_get_module_name.c `pkg-config --cflags --libs modulemd-2.0 glib-2.0`") + + def test(self): + self.cmd("./libmodulemd_modulemd_defaults_get_module_name gen_yaml_to_get_module_name.yaml") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for f in ['libmodulemd_modulemd_defaults_get_module_name.c', 'libmodulemd_modulemd_defaults_get_module_name', 'gen_yaml_to_get_module_name.yaml']: + if os.path.exists(f): + self.cmd(f"rm -rf {f}") diff --git a/tests/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_011.py b/tests/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_011.py new file mode 100644 index 0000000000000000000000000000000000000000..f07e613c876f480694cb744678c696631da6ff1d --- /dev/null +++ b/tests/system_libraries/libmodulemd/tc_libmodulemd_libmodulemd_func_011.py @@ -0,0 +1,131 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libmodulemd_libmodulemd_func_011.py +@Time: 2024/03/05 09:20:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libmodulemd_libmodulemd_func_011.yaml for details + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libmodulemd libmodulemd-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + gen_yaml_f = r'''cat > gen_yaml_to_get_content.yaml < libmodulemd_modulemd_module_index_dump_to_string.c << EOF +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + g_autoptr(GError) error = NULL; + g_autoptr(ModulemdModuleIndex) index = NULL; + g_autoptr(GPtrArray) failures = NULL; + gchar *yaml_content = NULL; + + // Check command-line arguments + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return EXIT_FAILURE; + } + + // Create a new ModuleIndex + index = modulemd_module_index_new(); + if (!index) { + fprintf(stderr, "Could not create module index object.\n"); + return EXIT_FAILURE; + } + + // Initialize the array for collecting failures + failures = g_ptr_array_new_with_free_func(g_object_unref); + + // Read the YAML file and update the index + if (!modulemd_module_index_update_from_file(index, argv[1], TRUE, &failures, &error)) { + fprintf(stderr, "Error parsing module metadata: %s\n", error->message); + // Handle each parsing failure (if any) + if (failures != NULL) { + for (guint i = 0; i < failures->len; i++) { + ModulemdSubdocumentInfo *failure = (ModulemdSubdocumentInfo *)g_ptr_array_index(failures, i); + fprintf(stderr, "Subdocument failed to parse: %s\n", modulemd_subdocument_info_get_gerror(failure)->message); + } + } + return EXIT_FAILURE; + } + + // Serialize the ModuleIndex back into a YAML string + yaml_content = modulemd_module_index_dump_to_string(index, &error); + if (!yaml_content) { + fprintf(stderr, "Error serializing module metadata back to string: %s\n", error->message); + return EXIT_FAILURE; + } + + // Output the entire YAML content + printf("%s\n", yaml_content); + + // Clean up + g_free(yaml_content); + + return EXIT_SUCCESS; +} +EOF''' + self.cmd(gen_yaml_f) + self.cmd(code) + self.cmd("gcc -o libmodulemd_modulemd_module_index_dump_to_string libmodulemd_modulemd_module_index_dump_to_string.c `pkg-config --cflags --libs modulemd-2.0 glib-2.0`") + + def test(self): + self.cmd("./libmodulemd_modulemd_module_index_dump_to_string gen_yaml_to_get_content.yaml") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for f in ['libmodulemd_modulemd_module_index_dump_to_string.c', 'libmodulemd_modulemd_module_index_dump_to_string', 'gen_yaml_to_get_content.yaml']: + if os.path.exists(f): + self.cmd(f"rm -rf {f}") diff --git a/tests/system_libraries/libndp/tc_libndp_libndp_func_001.py b/tests/system_libraries/libndp/tc_libndp_libndp_func_001.py new file mode 100644 index 0000000000000000000000000000000000000000..14ef1350d16ea4885c2869269fbdb1f1a81676f7 --- /dev/null +++ b/tests/system_libraries/libndp/tc_libndp_libndp_func_001.py @@ -0,0 +1,67 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libndp_libndp_func_001.py +@Time: 2024/04/15 14:18:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libndp_libndp_func_001.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libndp libndp-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > test_libndp_ndp_get_log_priority.c << EOF +#include +#include +#include + +int main(int argc, char *argv[]) { + struct ndp *ndp_instance; + int log_priority; + + // 检查命令行参数 + if (argc != 2) { + fprintf(stderr, "用法: %s <日志优先级数字>\n", argv[0]); + return EXIT_FAILURE; + } + + // 打开NDP库 + if (ndp_open(&ndp_instance) < 0) { + fprintf(stderr, "无法打开NDP库\n"); + return EXIT_FAILURE; + } + // 接检索日志优先级 + log_priority = ndp_get_log_priority(ndp_instance); + + printf("当前的NDP日志优先级是: %d\n", log_priority); + ndp_close(ndp_instance); + return EXIT_SUCCESS; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o test_libndp_ndp_get_log_priority test_libndp_ndp_get_log_priority.c -lndp") + + def test(self): + self.cmd("./test_libndp_ndp_get_log_priority 1") + + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for file in ['test_libndp_ndp_get_log_priority', 'test_libndp_ndp_get_log_priority.c']: + if os.path.exists(file): + self.cmd(f"rm -rf {file}") \ No newline at end of file diff --git a/tests/system_libraries/libndp/tc_libndp_libndp_func_002.py b/tests/system_libraries/libndp/tc_libndp_libndp_func_002.py new file mode 100644 index 0000000000000000000000000000000000000000..4c6813ec8cc8dbd078de94c2ecacb9cd028f57c5 --- /dev/null +++ b/tests/system_libraries/libndp/tc_libndp_libndp_func_002.py @@ -0,0 +1,81 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libndp_libndp_func_002.py +@Time: 2024/04/15 14:18:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libndp_libndp_func_002.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libndp libndp-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > test_libndp_ndp_msg_opt_prefix_valid_time.c << EOF +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + struct ndp_msg *msg; + uint32_t valid_time; + int offset; + + if (argc != 3) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return EXIT_FAILURE; + } + + enum ndp_msg_type msg_type = atoi(argv[1]); + offset = atoi(argv[2]); + + /* 使用ndp_msg_new根据指定的消息类型创建ndp_msg */ + if (ndp_msg_new(&msg, msg_type) != 0) { + fprintf(stderr, "Failed to create ndp_msg.\n"); + return EXIT_FAILURE; + } + + /* 准备消息 - 在示例中, 这个步骤不会真正执行任何操作 */ + // prepare_ndp_msg(msg); + + /* 从消息中获取前缀有效时间 */ + valid_time = ndp_msg_opt_prefix_valid_time(msg, offset); + + /* 输出获取到的时间 */ + printf("Prefix valid time at offset %d is %u seconds.\n", offset, valid_time); + + /* 清理 */ + ndp_msg_destroy(msg); + + return EXIT_SUCCESS; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o test_libndp_ndp_msg_opt_prefix_valid_time test_libndp_ndp_msg_opt_prefix_valid_time.c -lndp") + + def test(self): + # 134:这是NDP_MSG_RA(路由器广告)消息的示例值,实际值取决于您处理的特定消息类型。 + # 16:这是示例偏移量,实际值应该基于您的NDP消息中前缀信息选项的位置。 + self.cmd("./test_libndp_ndp_msg_opt_prefix_valid_time 134 16") + + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for file in ['test_libndp_ndp_msg_opt_prefix_valid_time', 'test_libndp_ndp_msg_opt_prefix_valid_time.c']: + if os.path.exists(file): + self.cmd(f"rm -rf {file}") \ No newline at end of file diff --git a/tests/system_libraries/librepo/tc_librepo_librepo_func_001.py b/tests/system_libraries/librepo/tc_librepo_librepo_func_001.py new file mode 100644 index 0000000000000000000000000000000000000000..7d0e75972c35c7505c617a4c5f61e8f2019a3d48 --- /dev/null +++ b/tests/system_libraries/librepo/tc_librepo_librepo_func_001.py @@ -0,0 +1,112 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_librepo_librepo_func_001.py +@Time: 2024/02/26 15:15:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_librepo_librepo_func_001.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc librepo librepo-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + ret_c, self.arch = self.cmd("arch") + self.assertEqual(0, ret_c) + self.cmd("mkdir -p /tmp/librepo/", ignore_status=True) + code = r'''cat > test_librepo_download_meta_data.c << EOF +#include +#include +#include + +int main(int argc, char *argv[]) { + if (argc != 3) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return EXIT_FAILURE; + } + + LrHandle *handle = NULL; + LrResult *result = NULL; + GError *err = NULL; + gboolean ret = FALSE; + + // Create a new handle + handle = lr_handle_init(); + if (handle == NULL) { + fprintf(stderr, "Cannot create librepo handle\n"); + return EXIT_FAILURE; + } + + // Set the repository URL from command line argument + const char *url[] = {argv[1], NULL}; + ret = lr_handle_setopt(handle, NULL, LRO_URLS, url); + if (!ret) { + fprintf(stderr, "Cannot set URL option\n"); + goto cleanup; + } + + // Set the destination directory for the metadata from command line argument + ret = lr_handle_setopt(handle, &err, LRO_DESTDIR, argv[2]); + if (!ret) { + fprintf(stderr, "Cannot set destination directory option, %s\n", err->message); + goto cleanup; + } + + // Set the repository type to YUM + ret = lr_handle_setopt(handle, NULL, LRO_REPOTYPE, LR_YUMREPO); + if (!ret) { + fprintf(stderr, "Cannot set repository type option\n"); + goto cleanup; + } + + // Initialize the result object + result = lr_result_init(); + if (result == NULL) { + fprintf(stderr, "Cannot create librepo result\n"); + goto cleanup; + } + + // Download repository metadata + ret = lr_handle_perform(handle, result, &err); + if (!ret) { + fprintf(stderr, "Error downloading metadata: %s\n", err->message); + goto cleanup; + } + + // Successfully downloaded, you can add checks on the actual metadata here + printf("Repository metadata successfully downloaded to %s\n", argv[2]); + +cleanup: + if (err) { + g_error_free(err); + } + lr_handle_free(handle); + lr_result_free(result); + return ret ? EXIT_SUCCESS : EXIT_FAILURE; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o test_librepo_download_meta_data test_librepo_download_meta_data.c `pkg-config --cflags --libs librepo glib-2.0`") + + def test(self): + self.cmd(f"./test_librepo_download_meta_data https://mirrors.openanolis.cn/anolis/epao/23/{self.arch}/ /tmp/librepo/") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for f in ['test_librepo_download_meta_data.c', 'test_librepo_download_meta_data', '/tmp/librepo']: + if os.path.exists(f): + self.cmd(f"rm -rf {f}", ignore_status=True) diff --git a/tests/system_libraries/librepo/tc_librepo_librepo_func_002.py b/tests/system_libraries/librepo/tc_librepo_librepo_func_002.py new file mode 100644 index 0000000000000000000000000000000000000000..2502f821e5b29955f76153bfdec41f039e2f94fe --- /dev/null +++ b/tests/system_libraries/librepo/tc_librepo_librepo_func_002.py @@ -0,0 +1,123 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_librepo_librepo_func_002.py +@Time: 2024/02/26 15:15:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_librepo_librepo_func_002.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc librepo librepo-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > test_librepo_get_info.c << EOF +#include +#include +#include + +int main(int argc, char *argv[]) { + if (argc < 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + GError *error = NULL; + LrHandle *handle = lr_handle_init(); + char *value = NULL; + long long_value; + GHashTable *varsub = NULL; + + if (handle == NULL) { + fprintf(stderr, "无法初始化 librepo 句柄\n"); + return 1; + } + + // 从命令行参数设置仓库URL + const char *urls[] = {argv[1], NULL}; + // 为句柄设置一些选项 + lr_handle_setopt(handle, NULL, LRO_URLS, urls); + lr_handle_setopt(handle, NULL, LRO_REPOTYPE, LR_YUMREPO); + + // 获取镜像列表地址 + if (!lr_handle_getinfo(handle, &error, LRO_MIRRORLIST, &value)) { + fprintf(stderr, "获取镜像列表地址失败: %s\n", error->message); + } else { + printf("镜像列表地址: %s\n", value); + g_free(value); + } + + // 获取代理类型 + if (!lr_handle_getinfo(handle, &error, LRO_PROXYTYPE, &long_value)) { + fprintf(stderr, "获取代理类型失败: %s\n", error->message); + } else { + printf("代理类型: %ld\n", long_value); + } + + // 获取最大下载速度 + if (!lr_handle_getinfo(handle, &error, LRO_MAXSPEED, &long_value)) { + fprintf(stderr, "获取最大下载速度失败: %s\n", error->message); + } else { + printf("最大下载速度: %ld\n", long_value); + } + + // 获取目标目录 + if (!lr_handle_getinfo(handle, &error, LRO_DESTDIR, &value)) { + fprintf(stderr, "获取目标目录失败: %s\n", error->message); + } else { + printf("目标目录: %s\n", value); + g_free(value); + } + + // 获取连接超时时间 + if (!lr_handle_getinfo(handle, &error, LRO_CONNECTTIMEOUT, &long_value)) { + fprintf(stderr, "获取连接超时时间失败: %s\n", error->message); + } else { + printf("连接超时时间: %ld\n", long_value); + } + + // 获取变量替换表 + if (!lr_handle_getinfo(handle, &error, LRI_VARSUB, &varsub)) { + fprintf(stderr, "获取变量替换表失败: %s\n", error->message); + } else { + if (varsub) { // 确保varsub不是NULL + printf("变量替换表:\n"); + GHashTableIter iter; + gpointer key, value; + g_hash_table_iter_init(&iter, varsub); + while (g_hash_table_iter_next(&iter, &key, &value)) { + printf(" %s = %s\n", (char *)key, (char *)value); + } + // 注意:这里不释放varsub,因为它是内部数据结构的引用 + } else { + printf("变量替换表: NULL\n"); + } + } + return 0; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o test_librepo_get_info test_librepo_get_info.c `pkg-config --cflags --libs librepo`") + + def test(self): + self.cmd(f"./test_librepo_get_info https://mirrors.openanolis.cn/") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for f in ['test_librepo_get_info.c', 'test_librepo_get_info']: + if os.path.exists(f): + self.cmd(f"rm -rf {f}", ignore_status=True) diff --git a/tests/system_libraries/librepo/tc_librepo_librepo_func_003.py b/tests/system_libraries/librepo/tc_librepo_librepo_func_003.py new file mode 100644 index 0000000000000000000000000000000000000000..19bac0716e7826d194863bb1ad96e97fcceafe29 --- /dev/null +++ b/tests/system_libraries/librepo/tc_librepo_librepo_func_003.py @@ -0,0 +1,84 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_librepo_librepo_func_003.py +@Time: 2024/02/26 15:15:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_librepo_librepo_func_003.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc librepo librepo-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > test_librepo_repoconfs_load_dir.c << EOF +#include +#include +#include + +int main(int argc, char **argv) { + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return EXIT_FAILURE; + } + + const char *repo_config_dir = argv[1]; + GError *error = NULL; + LrYumRepoConfs *confs = lr_yum_repoconfs_init(); + + if (!confs) { + fprintf(stderr, "Cannot initialize YUM repo configs\n"); + return EXIT_FAILURE; + } + + // 加载指定目录下的 yum 仓库配置 + if (!lr_yum_repoconfs_load_dir(confs, repo_config_dir, &error)) { + fprintf(stderr, "Cannot load YUM repo configs from directory '%s': %s\n", + repo_config_dir, error->message); + g_error_free(error); + lr_yum_repoconfs_free(confs); + return EXIT_FAILURE; + } + + // 从 LrYumRepoConfs 对象获取加载的配置列表 + GPtrArray *repoconfs = lr_yum_repoconfs_get_list(confs, &error); + if (!repoconfs) { + fprintf(stderr, "Cannot get YUM repo configs list: %s\n", error->message); + g_error_free(error); + lr_yum_repoconfs_free(confs); + return EXIT_FAILURE; + } + + // 打印加载的配置数量 + printf("Loaded %u YUM repo configs.\n", repoconfs->len); + + // 清理资源 + lr_yum_repoconfs_free(confs); + return EXIT_SUCCESS; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o test_librepo_repoconfs_load_dir test_librepo_repoconfs_load_dir.c `pkg-config --cflags --libs librepo`") + + def test(self): + self.cmd(f"./test_librepo_repoconfs_load_dir /etc/yum.repos.d/") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for f in ['test_librepo_repoconfs_load_dir.c', 'test_librepo_repoconfs_load_dir']: + if os.path.exists(f): + self.cmd(f"rm -rf {f}", ignore_status=True) diff --git a/tests/system_libraries/librepo/tc_librepo_librepo_func_004.py b/tests/system_libraries/librepo/tc_librepo_librepo_func_004.py new file mode 100644 index 0000000000000000000000000000000000000000..bb5ab10cc3fd060ecef034aa9e99bf02992d7f7c --- /dev/null +++ b/tests/system_libraries/librepo/tc_librepo_librepo_func_004.py @@ -0,0 +1,90 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_librepo_librepo_func_004.py +@Time: 2024/02/26 15:15:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_librepo_librepo_func_004.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc librepo librepo-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + repoconf = r'''cat > repoconf.repo << EOF +[repositoryid] +name= +baseurl= +enabled= +gpgcheck= +gpgkey= +metalink= +mirrorlist= +failovermethod= +priority= +exclude= #与includepkgs互斥 +includepkgs= +sslverify= +proxy= +timeout= +skip_if_unavailable= +enabled_metadata= +EOF''' + code = r'''cat > test_librepo_repoconfs_parse.c << EOF +#include +#include +#include + +int main(int argc, char **argv) { + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return EXIT_FAILURE; + } + + const char *repo_file_path = argv[1]; + GError *error = NULL; + LrYumRepoConfs *confs = lr_yum_repoconfs_init(); + + if (!confs) { + fprintf(stderr, "Cannot initialize YUM repo configs\n"); + return EXIT_FAILURE; + } + + // Parse the specified .repo file + if (!lr_yum_repoconfs_parse(confs, repo_file_path, &error)) { + fprintf(stderr, "Cannot parse YUM repo config file '%s': %s\n", repo_file_path, error->message); + g_error_free(error); + lr_yum_repoconfs_free(confs); + return EXIT_FAILURE; + } + printf("Successfully parsed YUM repo config file '%s'\n", repo_file_path); + lr_yum_repoconfs_free(confs); + return EXIT_SUCCESS; +} +EOF''' + self.cmd(repoconf) + self.cmd(code) + self.cmd("gcc -o test_librepo_repoconfs_parse test_librepo_repoconfs_parse.c `pkg-config --cflags --libs librepo`") + + def test(self): + self.cmd(f"./test_librepo_repoconfs_parse 'repoconf.repo'") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for f in ['test_librepo_repoconfs_parse.c', 'test_librepo_repoconfs_parse', 'repoconf.repo']: + if os.path.exists(f): + self.cmd(f"rm -rf {f}", ignore_status=True) diff --git a/tests/system_libraries/librepo/tc_librepo_librepo_func_005.py b/tests/system_libraries/librepo/tc_librepo_librepo_func_005.py new file mode 100644 index 0000000000000000000000000000000000000000..d8e2d58abda8d19cd9bd9d74256c9ae054f249d1 --- /dev/null +++ b/tests/system_libraries/librepo/tc_librepo_librepo_func_005.py @@ -0,0 +1,112 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_librepo_librepo_func_005.py +@Time: 2024/02/26 15:15:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_librepo_librepo_func_005.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc librepo librepo-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + repomod_file = r'''cat << EOF > repomd_005.xml + + + 1590492027 + + 1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef + + 123456789 + 1234 + 1 + + + abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890 + + 123456789 + 5678 + 1 + + +EOF''' + code = r'''cat > test_librepo_repomd_parse_file.c << EOF +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + const char *repomd_path = argv[1]; + GError *err = NULL; + LrYumRepoMd *repomd = lr_yum_repomd_init(); + int fd = open(repomd_path, O_RDONLY); + if (fd == -1) { + perror("Error opening file"); + lr_yum_repomd_free(repomd); + return 1; + } + + // 解析repomd.xml文件 + if (!lr_yum_repomd_parse_file(repomd, fd, NULL, NULL, &err)) { + fprintf(stderr, "Error parsing repomd.xml: %s\n", err->message); + g_error_free(err); + close(fd); + lr_yum_repomd_free(repomd); + return 1; + } + + // 输出解析结果 + if (repomd->records == NULL) { + printf("No records found in repomd.xml\n"); + } else { + for (GList *elem = repomd->records; elem; elem = g_list_next(elem)) { + LrYumRepoMdRecord *record = elem->data; + printf("\n==========\n"); + printf("Type: %s\n", record->type); + printf("Location: %s\n", record->location_href); + printf("size: %ld\n", record->size); + printf("timestamp: %ld\n", record->timestamp); + printf("database_version: %d\n", record->db_version); + } + } + + // 清理工作 + close(fd); + lr_yum_repomd_free(repomd); + return 0; +} +EOF''' + self.cmd(repomod_file) + self.cmd(code) + self.cmd("gcc -o test_librepo_repomd_parse_file test_librepo_repomd_parse_file.c `pkg-config --cflags --libs librepo` -Wno-int-conversion -Wno-incompatible-pointer-types") + + def test(self): + self.cmd(f"./test_librepo_repomd_parse_file repomd_005.xml") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for f in ['test_librepo_repomd_parse_file.c', 'test_librepo_repomd_parse_file', 'repomd_005.xml']: + if os.path.exists(f): + self.cmd(f"rm -rf {f}", ignore_status=True) diff --git a/tests/system_libraries/librepo/tc_librepo_librepo_func_006.py b/tests/system_libraries/librepo/tc_librepo_librepo_func_006.py new file mode 100644 index 0000000000000000000000000000000000000000..a6c03e0cb1008a9083400e4a5eaa15dd390e65b4 --- /dev/null +++ b/tests/system_libraries/librepo/tc_librepo_librepo_func_006.py @@ -0,0 +1,129 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_librepo_librepo_func_006.py +@Time: 2024/02/26 15:15:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_librepo_librepo_func_006.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc librepo librepo-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + repomod_file = r'''cat << EOF > repomd_006.xml + + + 1590492027 + + 1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef + + 123456789 + 1234 + 10 + + + abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890 + + 987654321 + 5678 + 20 + + +EOF''' + code = r'''cat > test_librepo_repomd_get_record.c << EOF +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return EXIT_FAILURE; + } + const char *repomd_path = argv[1]; + GError *err = NULL; + + // Initialize the LrYumRepoMd structure + LrYumRepoMd *repomd = lr_yum_repomd_init(); + if (!repomd) { + fprintf(stderr, "Failed to initialize repomd\n"); + return EXIT_FAILURE; + } + + // Open the repomd.xml file + int fd = open(repomd_path, O_RDONLY); + if (fd == -1) { + perror("Error opening file"); + lr_yum_repomd_free(repomd); + return EXIT_FAILURE; + } + + // Parse the repomd.xml file + if (!lr_yum_repomd_parse_file(repomd, fd, NULL, NULL, &err)) { + fprintf(stderr, "Error parsing repomd.xml: %s\n", err->message); + g_error_free(err); + close(fd); + lr_yum_repomd_free(repomd); + return EXIT_FAILURE; + } + + // Get the primary record from repomd + LrYumRepoMdRecord *primary_record = lr_yum_repomd_get_record(repomd, "primary"); + if (primary_record) { + printf("Record type: %s\n", primary_record->type); + printf("Record location: %s\n", primary_record->location_href); + printf("Record size: %ld\n", primary_record->size); + printf("Record timestamp: %ld\n", primary_record->timestamp); + printf("Record database_version: %ld\n", primary_record->db_version); + } else { + fprintf(stderr, "Failed to get 'primary' record\n"); + } + + LrYumRepoMdRecord *filelists_record = lr_yum_repomd_get_record(repomd, "filelists"); + if (filelists_record) { + printf("Record type: %s\n", filelists_record->type); + printf("Record location: %s\n", filelists_record->location_href); + printf("Record size: %ld\n", filelists_record->size); + printf("Record timestamp: %ld\n", filelists_record->timestamp); + printf("Record database_version: %ld\n", filelists_record->db_version); + + } else { + fprintf(stderr, "Failed to get 'filelists' record\n"); + } + + // Cleanup resources + close(fd); + lr_yum_repomd_free(repomd); + return EXIT_SUCCESS; +} +EOF''' + self.cmd(repomod_file) + self.cmd(code) + self.cmd("gcc -o test_librepo_repomd_get_record test_librepo_repomd_get_record.c `pkg-config --cflags --libs librepo` -Wno-int-conversion -Wno-incompatible-pointer-types") + + def test(self): + self.cmd(f"./test_librepo_repomd_get_record repomd_006.xml") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for f in ['test_librepo_repomd_get_record.c', 'test_librepo_repomd_get_record', 'repomd_006.xml']: + if os.path.exists(f): + self.cmd(f"rm -rf {f}", ignore_status=True) diff --git a/tests/system_libraries/libseccomp/tc_libseccomp_fun_001.py b/tests/system_libraries/libseccomp/tc_libseccomp_fun_001.py new file mode 100644 index 0000000000000000000000000000000000000000..52bd03cc0cb26bf25f746e8d06315ed89eb49125 --- /dev/null +++ b/tests/system_libraries/libseccomp/tc_libseccomp_fun_001.py @@ -0,0 +1,67 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libseccomp_fun_001.py +@Time: 2024/04/29 10:12:50 +@Author: hongfeng +@Version: 1.0 +@Contact: wb-zhf668260@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: hongfeng +""" + +from common.basetest import LocalTest +class Test(LocalTest): + """ + See tc_libseccomp_fun_001.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libseccomp-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = """cat > test01.c < +#include + +int main() { + int rc; + + // 创建一个新的过滤上下文 + scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_ALLOW); + if (ctx == NULL) { + fprintf(stderr, "seccomp_init failed\\n"); + return 1; + } + + rc = seccomp_load(ctx); + if (rc != 0) { + fprintf(stderr, "seccomp_load failed: %d\\n", rc); + seccomp_release(ctx); + return 1; + } + + printf("Seccomp filter successfully installed.\\n"); + + // 尝试一个未seccomp_rule_add的系统调用,比如 fork(),验证可以运行 + fork(); + + printf("fork is allowed.\\n"); + + // 在程序结束时释放过滤上下文 + seccomp_release(ctx); + + return 0; +} +EOF""" + self.cmd(cmdline) + self.cmd("gcc -o test01 test01.c `pkg-config --cflags --libs libseccomp`") + + def test(self): + ret_c, ret_o = self.cmd("./test01") + self.assertTrue("fork is allowed." in ret_o, 'check output error.') + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm test01.c test01") diff --git a/tests/system_libraries/libseccomp/tc_libseccomp_fun_002.py b/tests/system_libraries/libseccomp/tc_libseccomp_fun_002.py new file mode 100644 index 0000000000000000000000000000000000000000..934301b6c000c42013b66e2b0436e1791a281eac --- /dev/null +++ b/tests/system_libraries/libseccomp/tc_libseccomp_fun_002.py @@ -0,0 +1,103 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libseccomp_fun_002.py +@Time: 2024/04/29 10:12:50 +@Author: hongfeng +@Version: 1.0 +@Contact: wb-zhf668260@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: hongfeng +""" + +from common.basetest import LocalTest +class Test(LocalTest): + """ + See tc_libseccomp_fun_002.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libseccomp-devel"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = """cat > test02.c < +#include + +int main() { + int rc; + + // 创建一个新的过滤上下文 + scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_KILL); + if (ctx == NULL) { + fprintf(stderr, "seccomp_init failed\\n"); + return 1; + } + + // 允许read(), write(), exit(), newfstatat系统调用 + rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0); + if (rc != 0) { + fprintf(stderr, "seccomp_rule_add for read() failed: %d\\n", rc); + seccomp_release(ctx); + return 1; + } + + rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0); + if (rc != 0) { + fprintf(stderr, "seccomp_rule_add for write() failed: %d\\n", rc); + seccomp_release(ctx); + return 1; + } + + rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit), 0); + if (rc != 0) { + fprintf(stderr, "seccomp_rule_add for exit() failed: %d\\n", rc); + seccomp_release(ctx); + return 1; + } + rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(newfstatat), 0); + if (rc < 0) { + fprintf(stderr, "seccomp_rule_add for newfstatat() failed: %d\\n", rc); + seccomp_release(ctx); + return 1; + } + rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0); + if (rc != 0) { + fprintf(stderr, "seccomp_rule_add for exit_group() failed: %d\\n", rc); + seccomp_release(ctx); + return 1; + } + + // 设置默认动作为禁止(KILL进程) + rc = seccomp_load(ctx); + if (rc != 0) { + fprintf(stderr, "seccomp_load failed: %d\\n", rc); + seccomp_release(ctx); + return 1; + } + + printf("Seccomp filter successfully installed.\\n"); + + // 在这里您可以添加您的程序逻辑,现在它将在受限的系统调用环境中运行 + // 尝试一个未被允许的系统调用,比如 fork() + fork(); // 注释这行以避免程序因违反seccomp规则而崩溃 + + printf("It will not be here.\\n"); + + // 在程序结束时释放过滤上下文 + seccomp_release(ctx); + + return 0; +} +EOF""" + self.cmd(cmdline) + self.cmd("gcc -o test02 test02.c `pkg-config --cflags --libs libseccomp`") + + def test(self): + ret_c, ret_o = self.cmd("./test02", ignore_status=True) + self.assertTrue("It will not be here" not in ret_o, 'check output error.') + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm test02.c test02") diff --git a/tests/system_libraries/libselinux/tc_libselinux_fun_001.py b/tests/system_libraries/libselinux/tc_libselinux_fun_001.py new file mode 100644 index 0000000000000000000000000000000000000000..d64847c73d613355766a1919da0ccabb70a2dec2 --- /dev/null +++ b/tests/system_libraries/libselinux/tc_libselinux_fun_001.py @@ -0,0 +1,81 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libselinux_fun_001.py +@Time: 2024/04/14 10:12:50 +@Author: hongfeng +@Version: 1.0 +@Contact: wb-zhf668260@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: hongfeng +""" + +from common.basetest import LocalTest +class Test(LocalTest): + """ + See tc_libselinux_fun_001.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libselinux-devel gcc"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = """cat > test01.c < +#include +#include +#include + +/* Assume that `selinux_getenforce()` is already defined and implemented elsewhere. */ + +int main() { + int enforce_status; + int result; + + /* Call the selinux_getenforce() function to retrieve the enforcement status */ + result = selinux_getenforcemode(&enforce_status); + + /* Print the result based on the returned value */ + switch (enforce_status) { + case 0: + printf("SELinux is currently in 'Permissive' mode.\\n"); + break; + case 1: + printf("SELinux is currently in 'Enforcing' mode.\\n"); + break; + case -1: + printf("SELinux is currently in 'Disabled' mode.\\n"); + break; + default: + fprintf(stderr, "Unknown SELinux enforcement status returned: %d\\n", enforce_status); + return 1; + } + + return 0; +} +EOF""" + self.cmd(cmdline) + self.cmd("gcc -o test01 test01.c -lselinux") + self.cmd("cp /etc/selinux/config /etc/selinux/config.bak") + + def test(self): + # 将SELINUX设为permissive,用代码验证 + self.cmd("sed -i 's/^SELINUX=.*/SELINUX=permissive/' /etc/selinux/config") + ret_c, ret_o = self.cmd("./test01") + self.assertTrue("Permissive" in ret_o, 'check output error.') + + # 将SELINUX设为enforcing,用代码验证 + self.cmd("sed -i 's/^SELINUX=.*/SELINUX=enforcing/' /etc/selinux/config") + ret_c, ret_o = self.cmd("./test01") + self.assertTrue("Enforcing" in ret_o, 'check output error.') + + # 将SELINUX设为disabled,用代码验证 + self.cmd("sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config") + ret_c, ret_o = self.cmd("./test01") + self.assertTrue("Disabled" in ret_o, 'check output error.') + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("mv -f /etc/selinux/config.bak /etc/selinux/config") + self.cmd("rm test01.c test01") diff --git a/tests/system_libraries/libselinux/tc_libselinux_fun_002.py b/tests/system_libraries/libselinux/tc_libselinux_fun_002.py new file mode 100644 index 0000000000000000000000000000000000000000..2fdc836b49bfd30f5305d7afc4cfa9363f91e5d1 --- /dev/null +++ b/tests/system_libraries/libselinux/tc_libselinux_fun_002.py @@ -0,0 +1,122 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libselinux_fun_002.py +@Time: 2024/04/14 10:12:50 +@Author: hongfeng +@Version: 1.0 +@Contact: wb-zhf668260@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: hongfeng +""" + +from common.basetest import LocalTest +class Test(LocalTest): + """ + See tc_libselinux_fun_002.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libselinux-devel gcc"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = """cat > test02.c < +#include +#include +#include + +#define TEST_FILE_PATH "test_file02.txt" + +int main(int argc, char *argv[]) { + if (argc != 2) { + printf("Usage: %s 'context'\\n", argv[0]); + printf("Where:\\n"); + printf(" - The context, like: 'user_u:object_r:test_file_t:s0';\\n"); + } + + size_t arg_length = strlen(argv[1]) + 1; + char new_context[arg_length]; + strcpy(new_context, argv[1]); + + int ret; + char *current_context = NULL; + security_context_t file_context; + + // 创建测试文件 + FILE *test_file = fopen(TEST_FILE_PATH, "w"); + if (!test_file) { + fprintf(stderr, "Failed to create test file: %s\\n", strerror(errno)); + return EXIT_FAILURE; + } + fclose(test_file); + + // 获取当前文件的安全上下文 + ret = getfilecon(TEST_FILE_PATH, ¤t_context); + if (ret < 0) { + fprintf(stderr, "Failed to get file context: %s\\n", strerror(errno)); + return EXIT_FAILURE; + } else { + printf("Current file context: %s\\n", current_context); + freecon(current_context); + } + + // 设置文件的安全上下文 + ret = setfilecon(TEST_FILE_PATH, new_context); + if (ret < 0) { + fprintf(stderr, "Failed to set file context: %s\\n", strerror(errno)); + return EXIT_FAILURE; + } + + // 验证文件上下文是否已成功更新 + ret = getfilecon(TEST_FILE_PATH, ¤t_context); + if (ret < 0) { + fprintf(stderr, "Failed to get updated file context: %s\\n", strerror(errno)); + return EXIT_FAILURE; + } else { + if (strcmp(current_context, new_context) == 0) { + printf("File context successfully updated to: %s\\n", current_context); + } else { + fprintf(stderr, "Error: File context not updated correctly.\\n"); + freecon(current_context); + return EXIT_FAILURE; + } + freecon(current_context); + } + + // 使用security_context_t类型进行上下文操作 + if (getfilecon_raw(TEST_FILE_PATH, &file_context) < 0) { + fprintf(stderr, "Failed to get file context using security_context_t: %s\\n", strerror(errno)); + return EXIT_FAILURE; + } else { + printf("File context (security_context_t): %s\\n", file_context); + freecon(file_context); + } + + // 清理:删除测试文件 + if (remove(TEST_FILE_PATH) != 0) { + fprintf(stderr, "Failed to remove test file: %s\\n", strerror(errno)); + return EXIT_FAILURE; + } + + printf("All test cases passed.\\n"); + return EXIT_SUCCESS; +} +EOF""" + self.cmd(cmdline) + self.cmd("gcc -o test02 test02.c -lselinux") + + def test(self): + ret_c, ret_o = self.cmd("./test02 'user_u:object_r:test_file_t:s0'") + self.assertTrue("All test cases passed" in ret_o ,'check output error.') + + ret_c, ret_o = self.cmd("./test02 'unconfined_u:user_r:ssh_home_t:s0'") + self.assertTrue("All test cases passed" in ret_o ,'check output error.') + + ret_c, ret_o = self.cmd("./test02 'system_u:sysadm_r:httpd_sys_content_t:s0'") + self.assertTrue("All test cases passed" in ret_o ,'check output error.') + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm test02.c test02") diff --git a/tests/system_libraries/libselinux/tc_libselinux_fun_003.py b/tests/system_libraries/libselinux/tc_libselinux_fun_003.py new file mode 100644 index 0000000000000000000000000000000000000000..10032fef2da0a4a2f95ca0586775cc7bae84b301 --- /dev/null +++ b/tests/system_libraries/libselinux/tc_libselinux_fun_003.py @@ -0,0 +1,110 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libselinux_fun_003.py +@Time: 2024/04/14 10:12:50 +@Author: hongfeng +@Version: 1.0 +@Contact: wb-zhf668260@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: hongfeng +""" + +from common.basetest import LocalTest +class Test(LocalTest): + """ + See tc_libselinux_fun_003.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "libselinux-devel gcc"} + enforce = "" + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = """cat > test03.c < +#include +#include +#include +#include +#include + +#define TEST_FILE "test_file" +#define TEST_OPERATION "read" + +int main(int argc, char *argv[]) { + if (argc != 2) { + printf("Usage: %s 'file_context'\\n", argv[0]); + printf("Where:\\n"); + printf(" - The file_context, like: 'user_u:object_r:test_file_t:s0';\\n"); + return 1; + } + + size_t arg_length = strlen(argv[1]) + 1; + char file_context[arg_length]; + strcpy(file_context, argv[1]); + + int ret; + char *current_context; + + // Create test files and set their contexts + int fd = open(TEST_FILE, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR); + if (fd == -1) { + perror("Failed to create test_file_1"); + return 1; + } + if (fsetfilecon(fd, file_context) != 0) { + fprintf(stderr, "Failed to set context for test_file\\n"); + close(fd); + unlink(TEST_FILE); + return 1; + } + close(fd); + + ret = getcon(¤t_context); + if (ret != 0) { + perror("getcon() failed"); + exit(EXIT_FAILURE); + } + + printf("Current process context: %s\\n", current_context); + + // Check access permissions + ret = selinux_check_access(current_context, file_context, "file", TEST_OPERATION, NULL); + printf("Access check for %s on %s: %s\\n", TEST_OPERATION, TEST_FILE, ret == 0 ? "Allowed" : "Denied"); + + // Clean up + freecon(current_context); + unlink(TEST_FILE); + + return 0; +} +EOF""" + self.cmd(cmdline) + self.cmd("gcc -o test03 test03.c -lselinux") + ret_c, ret_o = self.cmd("getenforce") + self.enforce = ret_o.strip() + + def test(self): + self.cmd("setenforce 0") + ret_c, ret_o = self.cmd("./test03 user_u:object_r:test_file_t:s0") + self.assertTrue("Access check for read on test_file: Allowed" in ret_o, 'check output error.') + + ret_c, ret_o = self.cmd("./test03 system_u:object_r:secret_file_t:s0", ignore_status=True) + self.assertTrue("Access check for read on test_file: Allowed" in ret_o, 'check output error.') + + self.cmd("setenforce 1") + ret_c, ret_o = self.cmd("./test03 user_u:object_r:test_file_t:s0") + self.assertTrue("Access check for read on test_file: Allowed" in ret_o, 'check output error.') + + ret_c, ret_o = self.cmd("./test03 system_u:object_r:secret_file_t:s0", ignore_status=True) + self.assertTrue("Failed to set context for test_file" in ret_o, 'check output error.') + self.assertTrue("Access check for read on test_file: Allowed" not in ret_o, 'check output error.') + + def tearDown(self): + enforce_dict = {"Permissive": "0", "Enforcing": "1"} + enforce = enforce_dict[self.enforce] + self.cmd(f"setenforce {enforce}" ) + super().tearDown(self.PARAM_DIC) + self.cmd("rm test03.c test03") diff --git a/tests/system_libraries/libsemanage/tc_libsemanage_fun_001.py b/tests/system_libraries/libsemanage/tc_libsemanage_fun_001.py new file mode 100644 index 0000000000000000000000000000000000000000..c865bea744d749e2a006dc52db23ff31830dc1dd --- /dev/null +++ b/tests/system_libraries/libsemanage/tc_libsemanage_fun_001.py @@ -0,0 +1,88 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libsemanage_fun_001.py +@Time: 2024/04/17 10:12:50 +@Author: hongfeng +@Version: 1.0 +@Contact: wb-zhf668260@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: hongfeng +""" + +from common.basetest import LocalTest +class Test(LocalTest): + """ + See tc_libsemanage_fun_001.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libsemanage-devel policycoreutils-python-utils"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = """cat > test01.c < +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + semanage_handle_t *handle; + semanage_bool_t **records = NULL; + unsigned int count = 0; + int rc; + + if (argc != 2) { + fprintf(stderr, "Usage: test_semanage \\n"); + return 1; + } + size_t arg_length = strlen(argv[1]) + 1; + char test_name[arg_length]; + strcpy(test_name, argv[1]); + + // 1. 创建和初始化 semanage_handle_t + if ((handle = semanage_handle_create()) == NULL) { + fprintf(stderr, "Failed to create semanage handle: %s\\n", strerror(errno)); + return 1; + } + + // 2. 连接到 semanage + if ((rc = semanage_connect(handle)) < 0) { + fprintf(stderr, "Failed to connect to semanage: %s\\n", strerror(-rc)); + semanage_handle_destroy(handle); + return 1; + } + + // 3: Open the current policy for reading and retrieve boolean records + semanage_bool_list(handle, &records, &count); + + // 4: Iterate over retrieved boolean records and filter by name + for (unsigned int i = 0; i < count; ++i) { + semanage_bool_t *boolean = records[i]; + const char *name = semanage_bool_get_name(boolean); + int state = semanage_bool_get_value(boolean); + // Filter by test_name + if (strstr(name, test_name) != NULL) { + printf("%s, %d\\n", name, state); + } + } + + return 0; +} +EOF""" + self.cmd(cmdline) + self.cmd("gcc -o test01 test01.c -lsemanage") + + def test(self): + ret_c, ret_o = self.cmd("./test01 ssh_sysadm_login") + expect_state = "off" if "0" in ret_o else "on" + + # 用命令检查和api取回一致 + ret_c, ret_o = self.cmd("semanage boolean --list | grep ssh_sysadm_login | awk -F'[()]' '{split($2, values, \", \"); print values[1]}'") + self.assertTrue(expect_state == ret_o, "The state is not correct.") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm test01.c test01") diff --git a/tests/system_libraries/libsemanage/tc_libsemanage_fun_002.py b/tests/system_libraries/libsemanage/tc_libsemanage_fun_002.py new file mode 100644 index 0000000000000000000000000000000000000000..ef717fc6e4912f307f05f5d76037eeec34bfb902 --- /dev/null +++ b/tests/system_libraries/libsemanage/tc_libsemanage_fun_002.py @@ -0,0 +1,140 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libsemanage_fun_002.py +@Time: 2024/04/17 10:12:50 +@Author: hongfeng +@Version: 1.0 +@Contact: wb-zhf668260@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: hongfeng +""" + +from common.basetest import LocalTest +class Test(LocalTest): + """ + See tc_libsemanage_fun_002.yaml for details + + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libsemanage-devel policycoreutils-python-utils"} + def setUp(self): + super().setUp(self.PARAM_DIC) + cmdline = """cat > test02.c < +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + semanage_handle_t *handle; + semanage_fcontext_t *fcontext = NULL; + semanage_context_t *con = NULL; + int rc; + semanage_fcontext_key_t *k; + int exist = 0; + + if (argc != 4) { + fprintf(stderr, "Usage: test_fcontext \\n"); + return 1; + } + + const char *file_pattern = argv[1]; + const char *context_str = argv[2]; + int fcontext_type = atoi(argv[3]); + + // 1. 创建和初始化 semanage_handle_t + if ((handle = semanage_handle_create()) == NULL) { + fprintf(stderr, "Failed to create semanage handle: %s\\n", strerror(errno)); + return 1; + } + + // 2. 连接到 semanage + if ((rc = semanage_connect(handle)) < 0) { + fprintf(stderr, "Failed to connect to semanage: %s\\n", strerror(-rc)); + semanage_handle_destroy(handle); + return 1; + } + + if ((rc = semanage_begin_transaction(handle)) < 0) { + fprintf(stderr, "Failed to begin transaction: %s\\n", strerror(-rc)); + goto cleanup; + } + + if (semanage_fcontext_key_create(handle, argv[2], SEMANAGE_FCONTEXT_REG, &k) < 0) { + fprintf(stderr, "Could not create key for %s", argv[2]); + return -1; + } + + if(semanage_fcontext_exists(handle, k, &exist) < 0) { + return -1; + } + if (exist) { + return -1; + } + + // 3. 创建 semanage_fcontext_t 结构体 + if ((rc = semanage_fcontext_create(handle, &fcontext)) < 0) { + fprintf(stderr, "Failed to create file context object: %s\\n", strerror(-rc)); + goto cleanup; + } + + // 4. 设置文件路径模式 + if ((rc = semanage_fcontext_set_expr(handle, fcontext, file_pattern)) < 0) { + fprintf(stderr, "Failed to set file path pattern '%s': %s\\n", file_pattern, strerror(-rc)); + goto cleanup; + } + + // 5. 解析上下文字符串并设置上下文 + if ((rc = semanage_context_from_string(handle, context_str, &con)) < 0) { + fprintf(stderr, "Could not create context using '%s' for file context '%s'\\n", context_str, file_pattern); + goto cleanup; + } + + if ((rc = semanage_fcontext_set_con(handle, fcontext, con)) < 0) { + fprintf(stderr, "Could not set file context for '%s'\\n", file_pattern); + goto cleanup; + } + + semanage_fcontext_set_type(fcontext, fcontext_type); + + // 7. 将新的文件上下文规则添加到策略数据库(此处仅为示例,实际应用中应根据需要考虑事务提交等操作) + if(semanage_fcontext_modify_local(handle, k, fcontext) < 0) { + fprintf(stderr,"Could not add file context for %s", argv[2]); + return -1; + } + + if ((rc = semanage_commit(handle)) < 0) { + fprintf(stderr, "Failed to commit transaction: %s\\n", strerror(-rc)); + return -1; + } + + printf("Successfully created file context rule for pattern '%s' with context '%s' and type %d\\n", + file_pattern, context_str, fcontext_type); + +cleanup: + semanage_context_free(con); + semanage_fcontext_free(fcontext); + semanage_disconnect(handle); + semanage_handle_destroy(handle); + + return rc >= 0 ? 0 : 1; +} +EOF""" + self.cmd(cmdline) + self.cmd("gcc -o test02 test02.c -lsemanage") + + def test(self): + ret_c, ret_o = self.cmd("./test02 '/tmp/test02' 'system_u:object_r:httpd_sys_content_t:s0' SEMANAGE_FCONTEXT_REG") + self.assertTrue("Successfully created file context rule" in ret_o, 'check output error.') + + # 检查设置成功 + ret_c, ret_o = self.cmd("semanage fcontext -l | grep '/tmp/test02'") + self.assertTrue("system_u:object_r:httpd_sys_content_t:s0" in ret_o, 'check output error.') + self.cmd("semanage fcontext -d -t 'all files' /tmp/test02") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm test02.c test02") diff --git a/tests/system_libraries/libsolv/tc_libsolv_libsolv_func_001.py b/tests/system_libraries/libsolv/tc_libsolv_libsolv_func_001.py new file mode 100644 index 0000000000000000000000000000000000000000..6f85a7818d2c709bec328c70c3ad50e4cf634e16 --- /dev/null +++ b/tests/system_libraries/libsolv/tc_libsolv_libsolv_func_001.py @@ -0,0 +1,59 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libsolv_libsolv_func_001.py +@Time: 2024/03/04 11:20:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libsolv_libsolv_func_001.yaml for details + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libsolv libsolv-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > libsolv_pool_get_rootdir_test.c << EOF +#include +#include +#include + +int main() { + Pool *pool = pool_create(); + pool_set_rootdir(pool, "/tmp"); + + // 获取目录 + const char *rootdir = pool_get_rootdir(pool); + if (rootdir != NULL) { + printf("The root directory is set to: %s\n", rootdir); + } else { + printf("No root directory is set.\n"); + } + + // 清理资源 + pool_free(pool); + return 0; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o libsolv_pool_get_rootdir_test libsolv_pool_get_rootdir_test.c `pkg-config --cflags --libs libsolv`") + + def test(self): + self.cmd("./libsolv_pool_get_rootdir_test") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for f in ['libsolv_pool_get_rootdir_test.c', 'libsolv_pool_get_rootdir_test']: + if os.path.exists(f): + self.cmd(f"rm -rf {f}") diff --git a/tests/system_libraries/libsolv/tc_libsolv_libsolv_func_002.py b/tests/system_libraries/libsolv/tc_libsolv_libsolv_func_002.py new file mode 100644 index 0000000000000000000000000000000000000000..ea5eb5d07cc68b52974e0a99ad9ee7ea7193d9f4 --- /dev/null +++ b/tests/system_libraries/libsolv/tc_libsolv_libsolv_func_002.py @@ -0,0 +1,98 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libsolv_libsolv_func_002.py +@Time: 2024/03/04 11:20:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libsolv_libsolv_func_002.yaml for details + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libsolv libsolv-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > libsolv_get_pkginfo_test.c << EOF +#include +#include +#include +#include + +int main() { + // 创建 pool + Pool *pool = pool_create(); + if (!pool) { + fprintf(stderr, "Failed to create the pool.\n"); + return EXIT_FAILURE; + } + + // 添加一个软件包到pool + Repo *repo = repo_create(pool, "example_repo"); + if (!repo) { + fprintf(stderr, "Failed to create the repo.\n"); + pool_free(pool); + return EXIT_FAILURE; + } + Solvable *s = pool_id2solvable(pool, repo_add_solvable(repo)); + if (!s) { + fprintf(stderr, "Failed to add a solvable to the repo.\n"); + repo_free(repo, 0); + pool_free(pool); + return EXIT_FAILURE; + } + s->name = pool_str2id(pool, "example_package", 1); + s->evr = pool_str2id(pool, "1.0.0", 1); + s->arch = pool_str2id(pool, "noarch", 1); + + // 将名称、版本、架构的Id转换为字符串并打印 + const char *name_str = pool_id2str(pool, s->name); + const char *version_str = pool_id2str(pool, s->evr); + const char *arch_str = pool_id2str(pool, s->arch); + if (!name_str || !version_str || !arch_str) { + fprintf(stderr, "Failed to convert Ids to strings.\n"); + repo_free(repo, 0); + pool_free(pool); + return EXIT_FAILURE; + } + printf("Package: %s, Version: %s, Architecture: %s\n", name_str, version_str, arch_str); + + // 将Solvable的Id转换为字符串并打印整个Solvable + Id solvable_id = s - pool->solvables; + const char *solvable_str = pool_solvid2str(pool, solvable_id); + if (!solvable_str) { + fprintf(stderr, "Failed to convert solvable Id to string.\n"); + repo_free(repo, 0); + pool_free(pool); + return EXIT_FAILURE; + } + printf("Solvable: %s\n", solvable_str); + + // 清理资源 + repo_free(repo, 0); + pool_free(pool); + return EXIT_SUCCESS; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o libsolv_get_pkginfo_test libsolv_get_pkginfo_test.c `pkg-config --cflags --libs libsolv`") + + def test(self): + self.cmd("./libsolv_get_pkginfo_test") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for f in ['libsolv_get_pkginfo_test.c', 'libsolv_get_pkginfo_test']: + if os.path.exists(f): + self.cmd(f"rm -rf {f}") diff --git a/tests/system_libraries/libsolv/tc_libsolv_libsolv_func_003.py b/tests/system_libraries/libsolv/tc_libsolv_libsolv_func_003.py new file mode 100644 index 0000000000000000000000000000000000000000..bd66f589736587636b0706ae6f843311e32de82f --- /dev/null +++ b/tests/system_libraries/libsolv/tc_libsolv_libsolv_func_003.py @@ -0,0 +1,104 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libsolv_libsolv_func_003.py +@Time: 2024/03/04 11:20:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libsolv_libsolv_func_003.yaml for details + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libsolv libsolv-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > test_libsolv_repo_search.c << EOF +#include +#include +#include +#include +#include +#include + +// 回调函数,每找到一个匹配的软件包就会被调用 +int search_callback(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv) { + // 增加计数器 + int *found_count = (int *)cbdata; + (*found_count)++; + + printf("Found package: %s-%s\n", pool_id2str(s->repo->pool, s->name), pool_id2str(s->repo->pool, s->evr)); + return 0; // 返回0继续搜索 +} + +// 创建一个具有假数据的仓库 +Repo *create_test_repo(Pool *pool) { + Repo *repo = repo_create(pool, "test_repo"); + Repodata *data = repo_add_repodata(repo, 0); + + // 添加假的软件包到仓库 + for (int i = 0; i < 10; ++i) { + Solvable *s = pool_id2solvable(pool, repo_add_solvable(repo)); + char name[32]; + sprintf(name, "package%d", i); + s->name = pool_str2id(pool, name, 1); + s->evr = pool_str2id(pool, "1.0.0", 1); + s->arch = pool_str2id(pool, "noarch", 1); + repodata_add_poolstr_array(data, s - pool->solvables, SOLVABLE_SUMMARY, "A dummy package"); + } + + repodata_internalize(data); + return repo; +} + +int main() { + // 创建库池 + Pool *pool = pool_create(); + + // 创建并填充一个测试仓库 + Repo *repo = create_test_repo(pool); + + // 初始化找到的软件包数量为0 + int found_count = 0; + + // 为搜索准备库池 + pool_createwhatprovides(pool); + + // 执行搜索,这里我们搜索名称中包含 "package" 的软件包 + repo_search(repo, 0, SOLVABLE_NAME, "package", SEARCH_SUBSTRING, search_callback, &found_count); + + // 检查搜索结果 + if (found_count == 0) { + fprintf(stderr, "Error: No packages found matching the search criteria.\n"); + } + + // 释放资源 + repo_free(repo, 0); + pool_free(pool); + + return found_count == 0 ? EXIT_FAILURE : EXIT_SUCCESS; // 如果未找到软件包,则返回错误 +} +EOF''' + self.cmd(code) + self.cmd("gcc -o test_libsolv_repo_search test_libsolv_repo_search.c `pkg-config --cflags --libs libsolv`") + + def test(self): + self.cmd("./test_libsolv_repo_search") + + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for f in ['test_libsolv_repo_search.c', 'test_libsolv_repo_search']: + if os.path.exists(f): + self.cmd(f"rm -rf {f}") diff --git a/tests/system_libraries/libsolv/tc_libsolv_libsolv_func_004.py b/tests/system_libraries/libsolv/tc_libsolv_libsolv_func_004.py new file mode 100644 index 0000000000000000000000000000000000000000..521a8dc44dd9eb0c1fcb0972d61e0cb70232c94f --- /dev/null +++ b/tests/system_libraries/libsolv/tc_libsolv_libsolv_func_004.py @@ -0,0 +1,115 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libsolv_libsolv_func_004.py +@Time: 2024/03/04 11:20:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libsolv_libsolv_func_004.yaml for details + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libsolv libsolv-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > test_libsolv_dataiterator_match.c << EOF +#include +#include +#include +#include +#include + +int main() { + // 创建库池 + Pool *pool = pool_create(); + if (!pool) { + fprintf(stderr, "Failed to create a pool.\n"); + return EXIT_FAILURE; + } + + // 添加一个软件包到 pool + Repo *repo = repo_create(pool, "example_repo"); + if (!repo) { + fprintf(stderr, "Failed to create a repo.\n"); + pool_free(pool); + return EXIT_FAILURE; + } + + // 添加一些假的软件包到仓库 + const char *names[] = {"example_package", "another_package", "example_app", NULL}; + for (int i = 0; names[i]; ++i) { + Solvable *s = pool_id2solvable(pool, repo_add_solvable(repo)); + if (!s) { + fprintf(stderr, "Failed to add a solvable to the repo.\n"); + repo_free(repo, 0); + pool_free(pool); + return EXIT_FAILURE; + } + s->name = pool_str2id(pool, names[i], 1); + s->evr = pool_str2id(pool, "1.0.0", 1); + s->arch = pool_str2id(pool, "noarch", 1); + // 检查 pool_str2id 返回的 ID 是否有效 + if (s->name == ID_EMPTY || s->evr == ID_EMPTY || s->arch == ID_EMPTY) { + fprintf(stderr, "Failed to create solvable details.\n"); + repo_free(repo, 0); + pool_free(pool); + return EXIT_FAILURE; + } + } + + pool_createwhatprovides(pool); + + // 创建一个 Dataiterator 来搜索名称中包含 "example" 的软件包 + Dataiterator di; + dataiterator_init(&di, pool, repo, 0, SOLVABLE_NAME, "example", SEARCH_SUBSTRING); + int found = 0; // 用于跟踪是否找到了软件包 + while (dataiterator_step(&di)) { + Solvable *s = pool_id2solvable(pool, di.solvid); + if (s) { + const char *name = pool_id2str(pool, s->name); + if (name) { + printf("Found package: %s\n", name); + found = 1; // Mark that we found at least one package + } + } + } + dataiterator_free(&di); + + // 检查是否找到了软件包 + if (!found) { + fprintf(stderr, "No packages found containing the substring 'example'.\n"); + repo_free(repo, 0); + pool_free(pool); + return EXIT_FAILURE; + } + + // 清理资源 + repo_free(repo, 0); + pool_free(pool); + return EXIT_SUCCESS; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o test_libsolv_dataiterator_match test_libsolv_dataiterator_match.c `pkg-config --cflags --libs libsolv`") + + def test(self): + self.cmd("./test_libsolv_dataiterator_match") + + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for f in ['test_libsolv_dataiterator_match.c', 'test_libsolv_dataiterator_match']: + if os.path.exists(f): + self.cmd(f"rm -rf {f}") diff --git a/tests/system_libraries/libsolv/tc_libsolv_libsolv_func_005.py b/tests/system_libraries/libsolv/tc_libsolv_libsolv_func_005.py new file mode 100644 index 0000000000000000000000000000000000000000..2dd5c7e4d79e49e02625f9b06db7badc78839701 --- /dev/null +++ b/tests/system_libraries/libsolv/tc_libsolv_libsolv_func_005.py @@ -0,0 +1,117 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libsolv_libsolv_func_005.py +@Time: 2024/03/04 11:20:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libsolv_libsolv_func_005.yaml for details + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libsolv libsolv-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > test_libsolv_pool_match_dep.c << EOF +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + if (argc != 3) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return EXIT_FAILURE; + } + + const char *provided_dep_str = argv[1]; + const char *required_dep_str = argv[2]; + Pool *pool; + Repo *repo; + Solvable *s1, *s2; + Id dep1, dep2; + int match; + + // Initialize the pool + pool = pool_create(); + if (!pool) { + fprintf(stderr, "Failed to create pool.\n"); + return EXIT_FAILURE; + } + + // Create a repository + repo = repo_create(pool, "test_repo"); + if (!repo) { + fprintf(stderr, "Failed to create repository.\n"); + pool_free(pool); + return EXIT_FAILURE; + } + + // Add two solvables to the repo + s1 = pool_id2solvable(pool, repo_add_solvable(repo)); + s2 = pool_id2solvable(pool, repo_add_solvable(repo)); + if (!s1 || !s2) { + fprintf(stderr, "Failed to add solvables to the repository.\n"); + repo_free(repo, 0); + pool_free(pool); + return EXIT_FAILURE; + } + + // Add a provided feature to the first solvable (e.g., a package name and version) + dep1 = pool_str2id(pool, provided_dep_str, 1); + if (!dep1) { + fprintf(stderr, "Failed to create provided dependency.\n"); + repo_free(repo, 0); + pool_free(pool); + return EXIT_FAILURE; + } + s1->provides = repo_addid_dep(repo, s1->provides, dep1, 0); + + // Add a required feature to the second solvable (e.g., a dependency) + dep2 = pool_str2id(pool, required_dep_str, 1); + if (!dep2) { + fprintf(stderr, "Failed to create required dependency.\n"); + repo_free(repo, 0); + pool_free(pool); + return EXIT_FAILURE; + } + s2->requires = repo_addid_dep(repo, s2->requires, dep2, 0); + + // Check if the dependency provided by s1 matches the requirement of s2 + match = pool_match_dep(pool, dep1, dep2); + printf("The dependencies match: %s(req:%s pro:%s)\n", match ? "Yes" : "No", required_dep_str, provided_dep_str); + + // Clean up + repo_free(repo, 0); + pool_free(pool); + return EXIT_SUCCESS; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o test_libsolv_pool_match_dep test_libsolv_pool_match_dep.c `pkg-config --cflags --libs libsolv`") + + def test(self): + self.cmd("./test_libsolv_pool_match_dep libfoo libfoo") + self.cmd("./test_libsolv_pool_match_dep libfoo-1.0.1 libfoo") + self.cmd("./test_libsolv_pool_match_dep libfoo libfoo-1.0.1") + self.cmd("./test_libsolv_pool_match_dep 'libfoo>=1.0.1' 'libfoo>=1.0.1'") + + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for f in ['test_libsolv_pool_match_dep.c', 'test_libsolv_pool_match_dep']: + if os.path.exists(f): + self.cmd(f"rm -rf {f}") diff --git a/tests/system_libraries/libsolv/tc_libsolv_libsolv_func_006.py b/tests/system_libraries/libsolv/tc_libsolv_libsolv_func_006.py new file mode 100644 index 0000000000000000000000000000000000000000..e362caddbe1ea1df2442c62d9b9fedd4842c7099 --- /dev/null +++ b/tests/system_libraries/libsolv/tc_libsolv_libsolv_func_006.py @@ -0,0 +1,127 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libsolv_libsolv_func_006.py +@Time: 2024/03/04 11:20:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libsolv_libsolv_func_006.yaml for details + :avocado: tags=P2,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libsolv libsolv-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > test_libsolv_pool_calc_installsizechange.c << EOF +#include +#include +#include +#include +#include +#include +#include + +int create_test_repo(Pool *pool, Repo *repo) { + Repodata *data = repo_add_repodata(repo, 0); + if (!data) { + fprintf(stderr, "Failed to add repodata to the repository.\n"); + return -1; + } + + for (int i = 0; i < 10; ++i) { + Solvable *s = pool_id2solvable(pool, repo_add_solvable(repo)); + // The ID for the installation size attribute + Id handle = s - pool->solvables; + + // For simplicity, let's assume each package has a size of 100 bytes + unsigned long long installsize = 100; + + // Set the installation size for the solvable + repodata_set_num(data, handle, SOLVABLE_INSTALLSIZE, installsize); + } + + // Internalize the in-memory changes into persistent storage + repodata_internalize(data); + return 0; +} + +int main(int argc, char *argv[]) { + if (argc < 2) { + fprintf(stderr, "Usage: %s ... (list of installed solvable IDs)\n", argv[0]); + return EXIT_FAILURE; + } + + Pool *pool = pool_create(); + if (!pool) { + fprintf(stderr, "Failed to create pool.\n"); + return EXIT_FAILURE; + } + + Repo *repo = repo_create(pool, "test_repo"); + if (!repo) { + fprintf(stderr, "Failed to create repository.\n"); + pool_free(pool); + return EXIT_FAILURE; + } + + if (create_test_repo(pool, repo)) { + fprintf(stderr, "Failed to create test repository with solvables.\n"); + repo_free(repo, 0); + pool_free(pool); + return EXIT_FAILURE; + } + + // Initialize the installed map + Map installedmap; + map_init(&installedmap, pool->nsolvables); + for (int i = 1; i < argc; ++i) { + Id id = atoi(argv[i]); + if (id <= 0 || id >= pool->nsolvables) { + fprintf(stderr, "Invalid solvable ID: %s\n", argv[i]); + map_free(&installedmap); + repo_free(repo, 0); + pool_free(pool); + return EXIT_FAILURE; + } + MAPSET(&installedmap, id); + } + + long long size_change = pool_calc_installsizechange(pool, &installedmap); + printf("The installation size change is: %lld bytes\n", size_change); + + // Clean up + map_free(&installedmap); + repo_free(repo, 0); + pool_free(pool); + return EXIT_SUCCESS; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o test_libsolv_pool_calc_installsizechange test_libsolv_pool_calc_installsizechange.c `pkg-config --cflags --libs libsolv`") + + def test(self): + self.cmd("./test_libsolv_pool_calc_installsizechange 1 2 3") + self.cmd("./test_libsolv_pool_calc_installsizechange 1 3 3") + self.cmd("./test_libsolv_pool_calc_installsizechange 1 11") + self.cmd("./test_libsolv_pool_calc_installsizechange 11 11") + self.cmd("./test_libsolv_pool_calc_installsizechange 11 11 2 11 4 11") + self.cmd("./test_libsolv_pool_calc_installsizechange 9 1 2 3 4 5 6 7 8") + self.cmd("./test_libsolv_pool_calc_installsizechange 9 1 2 3 4 5 6 7 8 9 10 11") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for f in ['test_libsolv_pool_calc_installsizechange.c', 'test_libsolv_pool_calc_installsizechange']: + if os.path.exists(f): + self.cmd(f"rm -rf {f}") diff --git a/tests/system_libraries/libverto/tc_libverto_libverto_func_001.py b/tests/system_libraries/libverto/tc_libverto_libverto_func_001.py new file mode 100644 index 0000000000000000000000000000000000000000..d699fa8b213dad1cf7cc84ce22db9a26a25716ba --- /dev/null +++ b/tests/system_libraries/libverto/tc_libverto_libverto_func_001.py @@ -0,0 +1,62 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_libverto_libverto_func_001.py +@Time: 2024/02/22 14:20:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_libverto_libverto_func_001.yaml for details + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc libverto libverto-devel libevent"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > test_verto_check_event_is_supported.c << EOF +#include +#include +#include + +int main(int argc, char *argv[]) { + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return EXIT_FAILURE; + } + + const char *backend = argv[1]; + verto_ctx *ctx = verto_default(backend, VERTO_EV_TYPE_NONE); // 使用 VERTO_EV_TYPE_NONE,因为我们只是在检查后端 + + if (ctx != NULL) { + printf("%s backend is supported.\n", backend); + verto_free(ctx); + } else { + printf("%s backend is not supported or could not be initialized.\n", backend); + } + return 0; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o test_verto_check_event_is_supported test_verto_check_event_is_supported.c `pkg-config --cflags --libs libverto libevent`") + + def test(self): + self.cmd("./test_verto_check_event_is_supported libevent") + self.cmd("./test_verto_check_event_is_supported glib") + self.cmd("./test_verto_check_event_is_supported libev") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for f in ['test_verto_check_event_is_supported.c', 'test_verto_check_event_is_supported']: + if os.path.exists(f): + self.cmd(f"rm -rf {f}") diff --git a/tests/system_libraries/openldap/openldap_post.sh b/tests/system_libraries/openldap/openldap_post.sh new file mode 100644 index 0000000000000000000000000000000000000000..e75709b869d07337a5c9241759309fda3c09346a --- /dev/null +++ b/tests/system_libraries/openldap/openldap_post.sh @@ -0,0 +1,20 @@ +#! /usr/bin/bash + +clean() { + LDAP_CONF_P="/etc/openldap/slapd.d/cn=config" + systemctl is-active slapd && systemctl stop slapd + if [ -f "/tmp/monitor.ldif" ];then + [ -f ${LDAP_CONF_P}/'olcDatabase={1}monitor.ldif' ] && rm -rf ${LDAP_CONF_P}/'olcDatabase={1}monitor.ldif' + mv "/tmp/monitor.ldif" ${LDAP_CONF_P}/'olcDatabase={1}monitor.ldif' + fi + if [ -f "/tmp/mdb.ldif" ];then + [ -f ${LDAP_CONF_P}/'olcDatabase={2}mdb.ldif' ] && rm -rfv ${LDAP_CONF_P}/'olcDatabase={2}mdb.ldif' + mv /tmp/mdb.ldif ${LDAP_CONF_P}/'olcDatabase={2}mdb.ldif' + fi + + [ -f /tmp/user_base.ldif ] && rm -rfv /tmp/user_base.ldif + [ -f /tmp/delete_entries.ldif ] && rm -rfv /tmp/delete_entries.ldif + yum remove openldap-devel openldap-servers openldap-clients -y -q +} + +clean \ No newline at end of file diff --git a/tests/system_libraries/openldap/openldap_pre.sh b/tests/system_libraries/openldap/openldap_pre.sh new file mode 100644 index 0000000000000000000000000000000000000000..afedc9c019e4c9f66e6528b1f6d0bef72bd7e871 --- /dev/null +++ b/tests/system_libraries/openldap/openldap_pre.sh @@ -0,0 +1,120 @@ + +#! /usr/bin/bash + +check_cmd() { + if ! command -v "$1" &>/dev/null;then + echo "Error: $1 not found";exit 1 + fi +} + +delete_entries() { + check_cmd ldapdelete + cat << EOF > /tmp/delete_entries.ldif +dn: ou=groups,${BASE//\"/} +changetype: delete + +dn: ou=users,${BASE//\"/} +changetype: delete + +dn: ${BASE//\"/} +changetype: delete +EOF + echo -e "===ldapmodify -x -D ${DN_BASE} -f /tmp/delete_entries.ldif -w root\n" + ldapmodify -x -D ${DN_BASE//\"/} -f /tmp/delete_entries.ldif -w root + # ldapdelete -x -D "cn=admin,dc=domain,dc=com" -w root "ou=users,dc=domain,dc=com" + # ldapdelete -x -D "cn=admin,dc=domain,dc=com" -w root "ou=groups,dc=domain,dc=com" + # ldapdelete -x -D "cn=admin,dc=domain,dc=com" -w root "dc=domain,dc=com" +} + +func_step1() { + # 安装服务包,并停掉服务 + if ! yum install openldap openldap-devel openldap-servers openldap-clients -y -q;then + echo "Failed to install openldap* by yum!";exit 1 + fi + sleep 0.5 + + if [ "`systemctl is-active slapd`" = "active" ];then + systemctl stop slapd + systemctl status slapd + fi +} + +func_step2() { + # 生成管理员密码 + check_cmd slappasswd + ADMIN_PW=root + DEFAULT_PW=`slappasswd -h {SSHA} -s $ADMIN_PW` +} + +func_step3() { + # 修改配置 + LDAP_CONF_P="/etc/openldap/slapd.d/cn=config" + DN_BASE='"cn=admin,dc=domain,dc=com"' + BASE='"dc=domain,dc=com"' + if [ -f ${LDAP_CONF_P}/'olcDatabase={1}monitor.ldif' ];then + \cp -avrf ${LDAP_CONF_P}/'olcDatabase={1}monitor.ldif' /tmp/monitor.ldif + sed -r -i 's/dn.base="(.*)"/dn.base='$DN_BASE'/g' ${LDAP_CONF_P}/'olcDatabase={1}monitor.ldif' + sed -r -i '/^#\s+CRC32.*/d' ${LDAP_CONF_P}/'olcDatabase={1}monitor.ldif' + else + echo "Error: no such ${LDAP_CONF_P}/'olcDatabase={1}monitor.ldif'";exit 1 + fi + + if [ -f ${LDAP_CONF_P}/'olcDatabase={2}mdb.ldif' ];then + \cp -avrf ${LDAP_CONF_P}/'olcDatabase={2}mdb.ldif' /tmp/mdb.ldif + sed -r -i '/^olcSuffix:/ s/(olcSuffix:\s+).*/\1'${BASE//\"/}'/; /^olcRootDN:/ s/(olcRootDN:\s+).*/\1'${DN_BASE//\"/}'/' ${LDAP_CONF_P}/'olcDatabase={2}mdb.ldif' + sed -i '/^olcRootPW:.*/d' ${LDAP_CONF_P}/'olcDatabase={2}mdb.ldif' + sed -r -i '/^#\s+CRC32.*/d' ${LDAP_CONF_P}/'olcDatabase={2}mdb.ldif' + echo "olcRootPW: ${DEFAULT_PW}" >> ${LDAP_CONF_P}/'olcDatabase={2}mdb.ldif' + else + echo "Error: no such ${LDAP_CONF_P}/'olcDatabase={2}mdb.ldif'";exit 1 + fi + + echo -e "===cat ${LDAP_CONF_P}/'olcDatabase={2}mdb.ldif' ${LDAP_CONF_P}/'olcDatabase={2}mdb.ldif'\n" + cat ${LDAP_CONF_P}/'olcDatabase={2}mdb.ldif' ${LDAP_CONF_P}/'olcDatabase={2}mdb.ldif' + check_cmd slaptest + slaptest -u +} + +func_setp4() { + cat > /tmp/user_base.ldif < openldap_set_option.c << EOF +#include +#include + +int main() { + LDAP *ld; + int version = LDAP_VERSION3; + int rc; + + // 初始化LDAP结构 + rc = ldap_initialize(&ld, "ldap:///"); + if (rc != LDAP_SUCCESS) { + fprintf(stderr, "ldap_initialize: %s\n", ldap_err2string(rc)); + return 1; + } + fprintf(stdout, "ldap was successfully initialized\n"); + + // 设置LDAP版本 + rc = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version); + if (rc != LDAP_SUCCESS) { + ldap_unbind_ext(ld, NULL, NULL); + fprintf(stderr, "ldap_set_option: %s\n", ldap_err2string(rc)); + return 1; + } + fprintf(stdout, "Succeeded in setting the LDAP version\n"); + + //清理LDAP结构 + ldap_unbind_ext(ld, NULL, NULL); + return 0; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o openldap_set_option openldap_set_option.c -lldap") + + def test(self): + self.cmd("./openldap_set_option") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for f in ['openldap_set_option.c', 'openldap_set_option']: + if os.path.exists(f): + self.cmd(f"rm -rf {f}") \ No newline at end of file diff --git a/tests/system_libraries/openldap/tc_openldap_openldap_func_002.py b/tests/system_libraries/openldap/tc_openldap_openldap_func_002.py new file mode 100644 index 0000000000000000000000000000000000000000..ca23d5faee713d20c2f5cf52a719bc482dcf5849 --- /dev/null +++ b/tests/system_libraries/openldap/tc_openldap_openldap_func_002.py @@ -0,0 +1,71 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_openldap_openldap_func_002.py +@Time: 2024/03/22 14:20:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_openldap_openldap_func_002.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc openldap openldap-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > openldap_ldap_control_find.c << EOF +#include +#include + +int main(int argc, char *argv[]) { + if (argc < 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + // 模拟传入的LDAP控制数组 + // struct berval val1 = {0, NULL}; + LDAPControl ctrl1 = {argv[1], 1, {0, NULL}}; // 分页控制的示例OID + // 假设有更多控制... + LDAPControl *ctrls[] = {&ctrl1, NULL}; // 控制数组结束应该用NULL保持显式 + + // 从命令行参数获取 OID + char *search_oid = argv[1]; + LDAPControl **next_ctrl = NULL; // 如果你想获取后续的控制,这里应该分配内存 + + // 查找控制 + LDAPControl *found_ctrl = ldap_control_find(search_oid, ctrls, &next_ctrl); + + if (found_ctrl != NULL) { + printf("Found control with OID: %s\n", found_ctrl->ldctl_oid); + } else { + printf("Control with OID %s not found.\n", search_oid); + } + + return 0; +} +EOF''' + self.cmd(code) + self.cmd("gcc -o openldap_ldap_control_find openldap_ldap_control_find.c -lldap -llber") + + def test(self): + self.cmd("./openldap_ldap_control_find '1.2.840.113556.1.4.319'") + self.cmd("./openldap_ldap_control_find 'ctr000000'") + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + for f in ['openldap_ldap_control_find.c', 'openldap_ldap_control_find']: + if os.path.exists(f): + self.cmd(f"rm -rf {f}") \ No newline at end of file diff --git a/tests/system_libraries/openldap/tc_openldap_openldap_func_003.py b/tests/system_libraries/openldap/tc_openldap_openldap_func_003.py new file mode 100644 index 0000000000000000000000000000000000000000..41f022cf41bf89d1670fdca9b1befce14fc112ea --- /dev/null +++ b/tests/system_libraries/openldap/tc_openldap_openldap_func_003.py @@ -0,0 +1,116 @@ +#!/usr/bin/python +# -*- encoding: utf-8 -*- + +""" +@File: tc_openldap_openldap_func_003.py +@Time: 2024/03/22 14:20:00 +@Author: suomengjun +@Version: 1.0 +@Contact: smj01095381@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: suomengjun +""" + +import os +from common.basetest import LocalTest + + +class Test(LocalTest): + """ + See tc_openldap_openldap_func_003.yaml for details + + :avocado: tags=P3,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "gcc openldap openldap-devel"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + code = r'''cat > openldap_ldap_whoami.c << EOF +#include +#include +#include + +int main(int argc, char **argv) { + if (argc != 4) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(EXIT_FAILURE); + } + + LDAP *ld; + int rc, version = LDAP_VERSION3; + char *ldap_uri = argv[1]; + char *bind_dn = argv[2]; + char *password = argv[3]; + int msgid; + + // 初始化LDAP库并设置版本 + ldap_initialize(&ld, ldap_uri); + if (ld == NULL) { + fprintf(stderr, "ldap_initialize failed\n"); + exit(EXIT_FAILURE); + } + + ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version); + + // 绑定到LDAP服务器 + struct berval cred; + cred.bv_val = password; + cred.bv_len = strlen(password); + + rc = ldap_sasl_bind_s(ld, bind_dn, LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL); + if (rc != LDAP_SUCCESS) { + ldap_unbind_ext_s(ld, NULL, NULL); + fprintf(stderr, "ldap_sasl_bind_s: %s\n", ldap_err2string(rc)); + exit(EXIT_FAILURE); + } + + // 进行Who am I?操作 + rc = ldap_whoami(ld, NULL, NULL, &msgid); + if (rc != LDAP_SUCCESS) { + ldap_unbind_ext_s(ld, NULL, NULL); + fprintf(stderr, "ldap_whoami: %s\n", ldap_err2string(rc)); + exit(EXIT_FAILURE); + } + + // 等待返回结果 + LDAPMessage *res; + struct berval *authzid; + + rc = ldap_result(ld, msgid, LDAP_MSG_ALL, NULL, &res); + if (rc == -1) { + ldap_unbind_ext_s(ld, NULL, NULL); + fprintf(stderr, "ldap_result failed\n"); + exit(EXIT_FAILURE); + } + rc = ldap_parse_whoami(ld, res, &authzid); + if (rc != LDAP_SUCCESS) { + ldap_unbind_ext_s(ld, NULL, NULL); + fprintf(stderr, "ldap_parse_whoami: %s\n", ldap_err2string(rc)); + exit(EXIT_FAILURE); + } + ldap_msgfree(res); + + printf("Authorized identity: %s\n", authzid->bv_val); + ber_bvfree(authzid); + + // 清理 + ldap_unbind_ext_s(ld, NULL, NULL); + + return 0; +} +EOF''' + self.cmd(code) + self.pwd = os.path.realpath(os.path.dirname(__file__)) + self.cmd(f'bash {self.pwd}/openldap_pre.sh') + self.cmd("gcc -o openldap_ldap_whoami openldap_ldap_whoami.c -lldap -llber") + + def test(self): + self.cmd("./openldap_ldap_whoami 'ldap://localhost:389' 'cn=admin,dc=domain,dc=com' 'root'") + + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd(f'bash {self.pwd}/openldap_post.sh') + for f in ['openldap_ldap_whoami.c', 'openldap_ldap_whoami']: + if os.path.exists(f): + self.cmd(f"rm -rf {f}") \ No newline at end of file diff --git a/tests/system_services/acpid/tc_acpid_acpid_fun001.py b/tests/system_services/acpid/tc_acpid_acpid_fun001.py new file mode 100644 index 0000000000000000000000000000000000000000..2760c5f364274336b7fc102d660aad47737e1121 --- /dev/null +++ b/tests/system_services/acpid/tc_acpid_acpid_fun001.py @@ -0,0 +1,40 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_acpid_acpid_fun001.py +@Time: 2024/05/16 14:21:20 +@Author: douzhichong +@Version: 1.0 +@Contact: douzhichong@inspur.com +@License: Mulan PSL v2 +@Modify: douzhichong +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_acpid_acpid_fun001.yaml for details + + :avocado: tags=P1,noarch,local,acpid + """ + PARAM_DIC = {"pkg_name": "acpid"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + + def test(self): + self.cmd("systemctl start acpid") + code, result=self.cmd("systemctl status acpid") + self.assertIn("active (running)", result) + self.cmd("systemctl restart acpid") + code, result=self.cmd("systemctl status acpid") + self.assertIn("active (running)", result) + self.cmd("systemctl stop acpid") + self.cmd("systemctl status acpid > acpid.log", ignore_status=True) + code, result=self.cmd("cat acpid.log", ignore_status=True) + self.assertIn("inactive (dead)", result) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd(" rm -rf acpid.log") diff --git a/tests/system_services/at/tc_at_at_fun001.py b/tests/system_services/at/tc_at_at_fun001.py new file mode 100644 index 0000000000000000000000000000000000000000..d102bde970fc27990bb23820703767f651dea7eb --- /dev/null +++ b/tests/system_services/at/tc_at_at_fun001.py @@ -0,0 +1,40 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_at_at_fun001.py +@Time: 2024/05/28 16:51:20 +@Author: douzhichong +@Version: 1.0 +@Contact: douzhichong@inspur.com +@License: Mulan PSL v2 +@Modify: douzhichong +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_at_at_fun001.yaml for details + + :avocado: tags=P1,noarch,local,at + """ + PARAM_DIC = {"pkg_name": "at"} + + def setUp(self): + super().setUp(self.PARAM_DIC) + + def test(self): + self.cmd("systemctl start atd") + code, result=self.cmd("systemctl status atd") + self.assertIn("active (running)", result) + self.cmd("systemctl restart atd") + code, result=self.cmd("systemctl status atd") + self.assertIn("active (running)", result) + self.cmd("systemctl stop atd") + self.cmd("systemctl status atd > atd.log", ignore_status=True) + code, result=self.cmd("cat atd.log", ignore_status=True) + self.assertIn("inactive (dead)", result) + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd(" rm -rf atd.log") diff --git a/tests/system_services/numad/tc_numad_numad_func_001.py b/tests/system_services/numad/tc_numad_numad_func_001.py new file mode 100644 index 0000000000000000000000000000000000000000..b68abbf7cf6006fe33c28ab0a86049dd15ada6b3 --- /dev/null +++ b/tests/system_services/numad/tc_numad_numad_func_001.py @@ -0,0 +1,44 @@ +# -*- encoding: utf-8 -*- + +""" +@File: tc_numad_numad_func_001.py +@Time: 2024/03/08 14:33:20 +@Author: chenchunhu +@Version: 1.0 +@Contact: wb-cch358909@alibaba-inc.com +@License: Mulan PSL v2 +@Modify: chenchunhu +""" + +from common.basetest import LocalTest + +class Test(LocalTest): + """ + See tc_numad_numad_func_001.yaml for details + + :avocado: tags=P1,noarch,local,fix + """ + PARAM_DIC = {"pkg_name": "numad"} + def setUp(self): + super().setUp(self.PARAM_DIC) + + def test(self): + self.cmd("service numad start") + code, numad_result = self.cmd("service numad status") + self.assertIn("active (running)", numad_result) + self.cmd("service numad restart") + code, numad_result = self.cmd("service numad status") + self.assertIn("active (running)", numad_result) + code, numad_result = self.cmd("numad -V") + self.assertIn("numad version:", numad_result) + code, numad_result = self.cmd("numad -h", ignore_status=True) + self.assertIn("Usage:", numad_result) + self.cmd("service numad stop") + self.cmd("service numad status > numad.log", ignore_status=True) + code, numad_result = self.cmd("cat numad.log", ignore_status=True) + self.assertIn("inactive (dead)", numad_result) + + + def tearDown(self): + super().tearDown(self.PARAM_DIC) + self.cmd("rm -rf numad.log") diff --git a/tests/system_services/systemd/tc_systemd_sysinfo_failed_func_001.py b/tests/system_services/systemd/tc_systemd_sysinfo_failed_func_001.py index c794933623d018a28c63d679e0d139d9d6d16b13..f9799e3b5d0101e872bec7d22e0ae009568ad785 100644 --- a/tests/system_services/systemd/tc_systemd_sysinfo_failed_func_001.py +++ b/tests/system_services/systemd/tc_systemd_sysinfo_failed_func_001.py @@ -13,7 +13,7 @@ from common.basetest import RemoteTest class ServiceTest(RemoteTest): """ See tc_systemd_sysinfo_failed_func_001.yaml for details - :avocado: tags=fix,P1,noarch,remote,vhd_img,baseos_container_default + :avocado: tags=fix,P1,noarch,remote,vhd_img """ """