Compare commits

...

55 Commits
doc ... main

Author SHA1 Message Date
熊卓孜 f55906dee6 Merge branch 'main' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs
7 months ago
熊卓孜 222949d5be Merge branch 'main' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs
7 months ago
熊卓孜 fe05466eeb Merge branch 'main' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs
7 months ago
熊卓孜 796b79839f Merge branch 'main' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs
7 months ago
熊卓孜 4e9288d1c6 Merge branch 'main' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs
7 months ago
熊卓孜 40412da54b Merge branch 'main' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs
7 months ago
熊卓孜 dde2f171f7 Merge branch 'main' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs
7 months ago
熊卓孜 35cc8978c2 Merge pull request '我在master分支' (#4) from master into main
7 months ago
熊卓孜 52267d6c61 Merge branch 'main' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs
7 months ago
熊卓孜 5fa1e6d8be Delete 'pthread_cond_test_001.cpp'
7 months ago
熊卓孜 9680a495c8 Delete 'pthread_cond_test_001.cpp'
7 months ago
熊卓孜 369c13a976 Delete 'pthread_atfork_test_002.cpp'
7 months ago
熊卓孜 8c28fae73b Delete 'pthread_atfork_test_001.cpp'
7 months ago
熊卓孜 d5998e8235 Merge branch 'master' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs
7 months ago
熊卓孜 aa49188067 Squashed commit of the following:
7 months ago
熊卓孜 353e570ea1 Merge pull request '我在master分支' (#3) from master into main
7 months ago
熊卓孜 4040f795c5 Merge branch 'master' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs
7 months ago
熊卓孜 766693aac5 Merge branch 'master' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs
7 months ago
熊卓孜 7bb2fdb46c Squashed commit of the following:
7 months ago
py6atlu3x 8bd6b59974 ADD file via upload
7 months ago
熊卓孜 453b244b67 Merge branch 'master' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs
7 months ago
熊卓孜 6f209d8726 Merge branch 'master' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs
7 months ago
Lvwenxuan 54f82cd61c Merge branch 'main' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs
7 months ago
熊卓孜 e32b938549 Merge branch 'master' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs
7 months ago
Lvwenxuan 768b870f5b #include "it_pthread_test.h" // 包含测试框架的头文件
7 months ago
熊卓孜 10228b14b6 Merge branch 'master' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs
7 months ago
py6atlu3x 6e424ad722 ADD file via upload
7 months ago
Lvwenxuan b04c0c9f54 #include "it_pthread_test.h" // 引入测试相关的头文件
7 months ago
Lvwenxuan 77f2c2e021 #include "it_pthread_test.h" // 引入测试相关的头文件,可能包含测试宏定义和函数声明
7 months ago
Lvwenxuan feebadef06 Merge branch 'main' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs
7 months ago
Lvwenxuan 30c5b2fb9c #include <cstdio> // 引入标准输入输出库(本例中未直接使用)
7 months ago
Lvwenxuan 2d46693239 #include <cstdio> // 引入标准输入输出库
7 months ago
熊卓孜 1e81313cb2 Merge branch 'master' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs
7 months ago
熊卓孜 749ba92144 Merge branch 'master' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs
7 months ago
wcr 2b84597fad Merge branch 'main' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs
7 months ago
熊卓孜 8db0d6c6e1 Merge branch 'master' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs
7 months ago
py6atlu3x 82512f98ec Merge pull request 'main并入master' (#2) from main into master
7 months ago
wcr ba78f4af13 123312
7 months ago
wcr 2bbd81e1bb 1231
7 months ago
Lvwenxuan 1e2e1722f8 /*
7 months ago
Lvwenxuan 7a03be035e /*
7 months ago
Mr.NaCl c42d4c8f9c read and commit It_process_plimits_008.cpp
7 months ago
py6atlu3x e89676cded ADD file via upload
7 months ago
赵颢翔 dafc1c8a0a 批注004
7 months ago
wcr fa052b7a28 12283
7 months ago
wcr d38443f8c2 12282
7 months ago
wcr e885d4d491 12281
7 months ago
wcr cc2f7154e9 1226
7 months ago
熊卓孜 e4b3839750 Merge branch 'master' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs
7 months ago
熊卓孜 0fad9f57a6 批注001
7 months ago
wcr ad862c087c 13
7 months ago
wcr e40ef14308 12
7 months ago
wcr 5ae7b2f1a6 Merge branch '分支昶' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs into 分支昶
7 months ago
wcr 8367e625c7 12232
7 months ago
wcr 2c6af109bd 1223
7 months ago

@ -32,35 +32,53 @@
#include "lt_net_netdb.h"
// 测试函数AddrInfoTest的定义
static int AddrInfoTest(void)
{
// Prerequisite: correct DNS servers must be configured.
// 假设DNS服务器配置正确
char host_file[] = "127.0.0.2 example.com\n", serv_file[] = "ftp 21/tcp\n";
// 文件路径数组
char *pathList[] = {"/etc/hosts", "/etc/services"};
// 要写入文件的内容数组
char *streamList[] = {host_file, serv_file};
// 内容长度数组
int streamLen[] = {sizeof(host_file), sizeof(serv_file)};
// 文件数量
const int file_number = 2;
// 准备文件环境
int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number);
if (flag != 0) {
// 如果准备失败,恢复文件环境并返回错误
RecoveryFileEnv(pathList, file_number);
return -1;
}
// 声明addrinfo结构体指针
struct addrinfo *addr = NULL;
// 使用getaddrinfo函数解析域名和端口
int ret = getaddrinfo("example.com", "ftp", NULL, &addr);
// 断言getaddrinfo函数返回0表示成功
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
// 释放addrinfo结构体
freeaddrinfo(addr);
// 尝试解析一个不存在的域名和端口
ret = getaddrinfo("local", "ftp", NULL, &addr);
// 断言getaddrinfo函数返回EAI_AGAIN表示临时失败
ICUNIT_ASSERT_EQUAL(ret, EAI_AGAIN, ret);
// 尝试解析一个不存在的服务名称
ret = getaddrinfo("localhost", "fp", NULL, &addr);
// 断言getaddrinfo函数返回EAI_SERVICE表示服务名称错误
ICUNIT_ASSERT_EQUAL(ret, EAI_SERVICE, ret);
// 获取错误信息字符串
const char *p = gai_strerror(EAI_AGAIN);
// 断言错误信息字符串不为空
ICUNIT_ASSERT_NOT_EQUAL(p, NULL, -1);
// 恢复文件环境
RecoveryFileEnv(pathList, file_number);
return ICUNIT_SUCCESS;
}
@ -97,7 +115,9 @@ static int AddrInfoTest(void)
3. ****
- `hints``getaddrinfo`
// 测试用例NetNetDbTest002的定义
void NetNetDbTest002(void)
{
// 添加测试用例
TEST_ADD_CASE(__FUNCTION__, AddrInfoTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
}

@ -28,24 +28,31 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
//123123
#include "lt_net_netdb.h"
// 测试函数IfAddrsTest的定义
static int IfAddrsTest(void)
{
// Prerequisite: correct DNS servers must be configured.
// 假设DNS服务器配置正确
struct ifaddrs *addr = NULL;
// 使用getifaddrs函数获取网络接口地址信息
int ret = getifaddrs(&addr);
// 断言getifaddrs函数返回0表示成功
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
// 断言返回的地址信息不为空
ICUNIT_ASSERT_NOT_EQUAL(addr, NULL, -1);
// 释放ifaddrs结构体
freeifaddrs(addr);
return ICUNIT_SUCCESS;
}
// 测试用例NetNetDbTest003的定义
void NetNetDbTest003(void)
{
// 添加测试用例
TEST_ADD_CASE(__FUNCTION__, IfAddrsTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
}

@ -2,74 +2,74 @@
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ... ...
*/
// 这是版权声明,表明代码的版权归属于华为技术有限公司和华为设备有限公司,并声明了保留所有权利。
#include "lt_net_netdb.h" // 引入测试所需的头文件
// 包含一个头文件,这个头文件可能包含了网络数据库相关的函数声明和宏定义。
#include "lt_net_netdb.h"
// 测试函数用于测试gethostbyaddr函数
static int GetHostByAddrTest(void)
{
// 定义一个模拟的hosts文件内容
char host_file[] = "127.0.0.1 localhost\n100.0.0.0 example.com example\n";
// 定义hosts文件的路径列表
char *pathList[] = {"/etc/hosts"};
// 定义模拟的hosts文件流列表
char *streamList[] = {host_file};
// 定义模拟的hosts文件流长度列表
int streamLen[] = {sizeof(host_file)};
// 定义文件数量
const int file_number = 1;
// 准备文件环境将模拟的hosts文件内容设置为系统的hosts文件
int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number);
// 如果准备失败,恢复原始文件环境
if (flag != 0) {
RecoveryFileEnv(pathList, file_number);
return -1;
return -1; // 返回错误码
}
// 定义in_addr结构体用于存储IP地址
struct in_addr ia;
int length = 4; // the address length is 4;
// 定义地址长度
int length = 4; // IPv4地址长度为4
// 将点分十进制IP地址转换为网络字节序的整数值
ia.s_addr = inet_addr("127.0.0.1");
// 使用gethostbyaddr获取hostent结构体指针
struct hostent *addr = gethostbyaddr(&ia, sizeof ia, AF_INET);
// 断言addr不为空即gethostbyaddr成功
ICUNIT_ASSERT_NOT_EQUAL(addr, NULL, -1);
// 断言返回的地址类型为AF_INET
ICUNIT_ASSERT_EQUAL(addr->h_addrtype, AF_INET, addr->h_addrtype);
// 断言返回的主机名为"localhost"
ICUNIT_ASSERT_STRING_EQUAL(addr->h_name, "localhost", -1);
// 断言返回的地址长度为4
ICUNIT_ASSERT_EQUAL(addr->h_length, length, -1);
// 测试另一个IP地址
ia.s_addr = inet_addr("100.0.0.0");
addr = gethostbyaddr(&ia, sizeof ia, AF_INET);
ICUNIT_ASSERT_NOT_EQUAL(addr, NULL, -1);
ICUNIT_ASSERT_EQUAL(addr->h_addrtype, AF_INET, addr->h_addrtype);
ICUNIT_ASSERT_STRING_EQUAL(addr->h_name, "example.com", -1);
// 测试一个不存在的IP地址
errno = 0;
ia.s_addr = inet_addr("127.0.0.0");
addr = gethostbyaddr(&ia, sizeof ia, AF_INET);
// 断言errno为ENOENT表示没有找到对应的主机名
ICUNIT_ASSERT_EQUAL(errno, ENOENT, errno);
// 恢复原始文件环境
RecoveryFileEnv(pathList, file_number);
return ICUNIT_SUCCESS;
return ICUNIT_SUCCESS; // 返回成功码
}
// 定义测试用例
void NetNetDbTest004(void)
{
// 添加测试用例,指定测试函数、测试类型、测试级别等信息
TEST_ADD_CASE(__FUNCTION__, GetHostByAddrTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
}
}

@ -28,11 +28,14 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// 版权声明,说明该代码由华为技术有限公司所有,并规定了代码的使用和分发条件。
#include "lt_net_netdb.h"
// 包含一个头文件,可能包含了网络数据库函数的声明和定义。
static int GetHostByAddrRTest(void)
{
// 定义一个静态函数用于测试gethostbyaddr_r函数。
struct in_addr ia;
struct hostent addr, *result = NULL;
char buf[1024];
@ -40,29 +43,47 @@ static int GetHostByAddrRTest(void)
int err, ret;
int length = 4;
// 定义了一些变量包括用于存储IP地址的in_addr结构体hostent结构体用于存储查询结果以及其他辅助变量。
ia.s_addr = inet_addr("127.0.0.1");
// 将字符串形式的IP地址"127.0.0.1"转换为网络字节序的二进制形式并存储在ia结构体中。
ret = gethostbyaddr_r(&ia, sizeof ia, AF_INET, &addr, buf, sizeof buf, &result, &err);
// 使用gethostbyaddr_r函数根据IP地址查询主机信息并将结果存储在result指向的hostent结构体中。
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
// 断言函数返回值应为0表示成功。
ICUNIT_ASSERT_NOT_EQUAL(result, NULL, -1);
// 断言result不应为空表示查询到了主机信息。
ICUNIT_ASSERT_EQUAL(result->h_addrtype, AF_INET, result->h_addrtype);
// 断言查询到的主机地址类型应为AF_INETIPv4
ICUNIT_ASSERT_STRING_EQUAL(result->h_name, "localhost", -1);
// 断言查询到的主机名应为"localhost"。
ICUNIT_ASSERT_EQUAL(result->h_length, length, -1);
// 断言查询到的主机地址长度应为4IPv4地址长度
errno = 0;
// 清空errno用于检测接下来的函数调用是否设置了errno。
ia.s_addr = inet_addr("127.0.0.0");
// 将字符串形式的IP地址"127.0.0.0"转换为网络字节序的二进制形式并存储在ia结构体中。
ret = gethostbyaddr_r(&ia, sizeof ia, AF_INET, &addr, buf, sizeof buf, &result, &err);
// 再次调用gethostbyaddr_r函数但这次传入的是一个无效的IP地址。
ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno);
// 断言errno应被设置为EINVAL表示无效参数。
ret = gethostbyaddr_r(&ia, sizeof ia, AF_INET, &addr, buf, sizeof buf, &result, &err);
// 再次调用函数但errno已经被之前的调用设置这里检查是否保持不变。
ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno);
// 断言errno仍然为EINVAL。
ret = gethostbyaddr_r(&ia, sizeof ia, AF_INET, &addr, buf1, sizeof buf1, &result, &err);
// 调用gethostbyaddr_r函数但这次传入的缓冲区buf1大小不足以存储结果。
ICUNIT_ASSERT_EQUAL(ret, ERANGE, ret);
// 断言函数返回值应为ERANGE表示缓冲区太小。
return ICUNIT_SUCCESS;
// 返回测试成功。
}
void NetNetDbTest005(void)
{
TEST_ADD_CASE(__FUNCTION__, GetHostByAddrRTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
}
// 将当前测试函数添加到测试用例中,指定测试类型、协议、级别和函数。
}

@ -28,42 +28,60 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// 版权声明,说明该代码由华为技术有限公司和华为设备有限公司所有,并规定了代码的使用和分发条件。
#include "lt_net_netdb.h"
// 引入头文件,可能包含了网络数据库相关的函数声明和宏定义。
static int GetHostByNameTest(void)
{
// 定义一个模拟的hosts文件内容
char host_file[] = "127.0.0.1 localhost\n";
// 定义hosts文件的路径列表
char *pathList[] = {"/etc/hosts"};
// 定义模拟的hosts文件流列表
char *streamList[] = {host_file};
// 定义模拟的hosts文件流长度列表
int streamLen[] = {sizeof(host_file)};
// 定义文件数量
int flag = PrepareFileEnv(pathList, streamList, streamLen, 1);
// 如果准备文件环境失败,则恢复原始文件环境并返回错误码
if (flag != 0) {
RecoveryFileEnv(pathList, 1);
return -1;
}
// 使用gethostbyname函数根据主机名获取hostent结构体指针
struct hostent *addr = gethostbyname("localhost");
// 断言addr不为空即gethostbyname成功
ICUNIT_ASSERT_NOT_EQUAL(addr, NULL, -1);
// 断言返回的主机名与输入的主机名相同
ICUNIT_ASSERT_EQUAL(strcmp(addr->h_name, "localhost"), 0, -1);
// 断言返回的地址类型为AF_INET
ICUNIT_ASSERT_EQUAL(addr->h_addrtype, AF_INET, addr->h_addrtype);
// 断言返回的地址长度不为0
ICUNIT_ASSERT_NOT_EQUAL(addr->h_length, 0, addr->h_length);
// 测试gethostbyname函数传入IP地址字符串作为主机名
addr = gethostbyname("127.0.0.1");
ICUNIT_ASSERT_NOT_EQUAL(addr, NULL, -1);
ICUNIT_ASSERT_EQUAL(strcmp(addr->h_name, "127.0.0.1"), 0, -1);
ICUNIT_ASSERT_EQUAL(addr->h_addrtype, AF_INET, addr->h_addrtype);
ICUNIT_ASSERT_NOT_EQUAL(addr->h_length, 0, addr->h_length);
// 测试一个不存在的主机名
addr = gethostbyname("lo");
// 断言addr为空即gethostbyname失败
ICUNIT_ASSERT_EQUAL(addr, NULL, -1);
// 恢复原始文件环境
RecoveryFileEnv(pathList, 1);
return ICUNIT_SUCCESS;
}
// 定义测试用例
void NetNetDbTest006(void)
{
// 添加测试用例,指定测试函数、测试类型、测试级别等信息
TEST_ADD_CASE(__FUNCTION__, GetHostByNameTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
}
}

@ -31,33 +31,51 @@
#include "lt_net_netdb.h"
// 引入头文件,可能包含了网络数据库相关的函数声明和宏定义。
static int GetHostByNameRTest(void)
{
char host_file[] = "127.0.0.1 localhost\n";
// 定义一个模拟的hosts文件内容包含localhost映射到127.0.0.1的条目。
char *pathList[] = {"/etc/hosts"};
// 定义hosts文件的路径列表这里只有一个路径指向系统的hosts文件。
char *streamList[] = {static_cast<char *>(host_file)};
// 定义模拟的hosts文件流列表这里将模拟的hosts文件内容转换为char*类型。
int streamLen[] = {sizeof(host_file)};
// 定义模拟的hosts文件流长度列表。
const int file_number = 1;
// 定义文件数量。
int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number);
// 调用PrepareFileEnv函数准备文件环境模拟hosts文件。
if (flag != 0) {
RecoveryFileEnv(pathList, file_number);
return -1;
}
// 如果准备文件环境失败,则恢复原始文件环境并返回错误码。
struct hostent addr, *result = NULL;
// 定义hostent结构体变量addr用于存储gethostbyname_r函数的结果。
char buf[1024];
// 定义一个足够大的缓冲区buf用于gethostbyname_r函数。
char buf1[1];
// 定义一个非常小的缓冲区buf1用于测试gethostbyname_r函数的边界条件。
int err, ret;
ret = gethostbyname_r("localhost", &addr, buf, sizeof buf, &result, &err);
// 使用gethostbyname_r函数根据主机名"localhost"获取hostent结构体指针。
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
// 断言返回值ret为0表示gethostbyname_r函数调用成功。
ICUNIT_ASSERT_NOT_EQUAL(result, NULL, -1);
// 断言result不为空即gethostbyname_r成功。
ICUNIT_ASSERT_EQUAL(strcmp(result->h_name, "localhost"), 0, -1);
// 断言返回的主机名与输入的主机名相同。
ICUNIT_ASSERT_EQUAL(result->h_addrtype, AF_INET, result->h_addrtype);
// 断言返回的地址类型为AF_INET。
ICUNIT_ASSERT_NOT_EQUAL(result->h_length, 0, result->h_length);
// 断言返回的地址长度不为0。
ret = gethostbyname_r("127.0.0.1", &addr, buf, sizeof buf, &result, &err);
// 使用gethostbyname_r函数根据IP地址字符串"127.0.0.1"获取hostent结构体指针。
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ICUNIT_ASSERT_NOT_EQUAL(result, NULL, -1);
ICUNIT_ASSERT_EQUAL(strcmp(result->h_name, "127.0.0.1"), 0, -1);
@ -65,17 +83,26 @@ static int GetHostByNameRTest(void)
ICUNIT_ASSERT_NOT_EQUAL(result->h_length, 0, result->h_length);
ret = gethostbyname_r("127.0.0.1", &addr, buf1, sizeof buf1, &result, &err);
// 测试gethostbyname_r函数的边界条件传入的缓冲区太小。
ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret);
// 断言返回值ret不为0表示gethostbyname_r函数调用失败。
ret = gethostbyname_r("127.0.0.0.0", &addr, buf, sizeof buf, &result, &err);
// 测试一个不存在的IP地址。
ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret);
// 断言返回值ret不为0表示gethostbyname_r函数调用失败。
ret = gethostbyname_r("lo", &addr, buf, sizeof buf, &result, &err);
// 测试一个不存在的主机名。
ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret);
// 断言返回值ret不为0表示gethostbyname_r函数调用失败。
RecoveryFileEnv(pathList, file_number);
// 恢复原始文件环境。
return ICUNIT_SUCCESS;
// 返回测试成功。
}
void NetNetDbTest007(void)
{
TEST_ADD_CASE(__FUNCTION__, GetHostByNameRTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
}
// 定义测试用例将GetHostByNameRTest函数注册为一个测试案例。

@ -31,42 +31,61 @@
#include "lt_net_netdb.h"
// 引入头文件,可能包含了网络数据库相关的函数声明和宏定义。
static int GetHostByName2Test(void)
{
char host_file[] = "127.0.0.1 localhost\n";
// 定义一个模拟的hosts文件内容包含localhost映射到127.0.0.1的条目。
char *pathList[] = {"/etc/hosts"};
// 定义hosts文件的路径列表这里只有一个路径指向系统的hosts文件。
char *streamList[] = {static_cast<char *>(host_file)};
// 定义模拟的hosts文件流列表这里将模拟的hosts文件内容转换为char*类型。
int streamLen[] = {sizeof(host_file)};
// 定义模拟的hosts文件流长度列表。
const int file_number = 1;
// 定义文件数量。
int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number);
// 调用PrepareFileEnv函数准备文件环境模拟hosts文件。
if (flag != 0) {
RecoveryFileEnv(pathList, file_number);
return -1;
}
// 如果准备文件环境失败,则恢复原始文件环境并返回错误码。
struct hostent *addr = gethostbyname2("localhost", AF_INET);
// 使用gethostbyname2函数根据主机名"localhost"和地址族AF_INET获取hostent结构体指针。
ICUNIT_ASSERT_NOT_EQUAL(addr, NULL, -1);
// 断言addr不为空即gethostbyname2成功。
ICUNIT_ASSERT_EQUAL(strcmp(addr->h_name, "localhost"), 0, -1);
// 断言返回的主机名与输入的主机名相同。
ICUNIT_ASSERT_EQUAL(addr->h_addrtype, AF_INET, addr->h_addrtype);
// 断言返回的地址类型为AF_INET。
ICUNIT_ASSERT_NOT_EQUAL(addr->h_length, 0, addr->h_length);
// 断言返回的地址长度不为0。
addr = gethostbyname2("127.0.0.1", AF_INET);
// 使用gethostbyname2函数根据IP地址字符串"127.0.0.1"和地址族AF_INET获取hostent结构体指针。
ICUNIT_ASSERT_NOT_EQUAL(addr, NULL, -1);
ICUNIT_ASSERT_EQUAL(strcmp(addr->h_name, "127.0.0.1"), 0, -1);
ICUNIT_ASSERT_EQUAL(addr->h_addrtype, AF_INET, addr->h_addrtype);
ICUNIT_ASSERT_NOT_EQUAL(addr->h_length, 0, addr->h_length);
addr = gethostbyname2("127.0.0.1", AF_INET6);
// 尝试使用gethostbyname2函数根据IP地址字符串"127.0.0.1"和地址族AF_INET6获取hostent结构体指针预期失败。
ICUNIT_ASSERT_EQUAL(addr, NULL, -1);
addr = gethostbyname2("localh", AF_INET);
// 尝试使用gethostbyname2函数根据不完整的主机名"localh"和地址族AF_INET获取hostent结构体指针预期失败。
ICUNIT_ASSERT_EQUAL(addr, NULL, -1);
RecoveryFileEnv(pathList, file_number);
// 恢复原始文件环境。
return ICUNIT_SUCCESS;
// 返回测试成功。
}
void NetNetDbTest008(void)
{
TEST_ADD_CASE(__FUNCTION__, GetHostByName2Test, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
}
// 定义测试用例将GetHostByName2Test函数注册为一个测试案例。

@ -30,33 +30,51 @@
*/
#include "lt_net_netdb.h"
// 引入头文件,可能包含了网络数据库相关的函数声明和宏定义。
static int GetHostByName2RTest(void)
{
char host_file[] = "127.0.0.1 localhost\n";
// 定义一个模拟的hosts文件内容包含localhost映射到127.0.0.1的条目。
char *pathList[] = {"/etc/hosts"};
// 定义hosts文件的路径列表这里只有一个路径指向系统的hosts文件。
char *streamList[] = {host_file};
// 定义模拟的hosts文件流列表这里直接使用host_file。
int streamLen[] = {sizeof(host_file)};
// 定义模拟的hosts文件流长度列表。
const int file_number = 1;
// 定义文件数量。
int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number);
// 调用PrepareFileEnv函数准备文件环境模拟hosts文件。
if (flag != 0) {
RecoveryFileEnv(pathList, file_number);
return -1;
}
// 如果准备文件环境失败,则恢复原始文件环境并返回错误码。
struct hostent addr, *result = NULL;
// 定义hostent结构体变量addr用于存储gethostbyname2_r函数的结果。
char buf[1024];
// 定义一个足够大的缓冲区buf用于gethostbyname2_r函数。
char buf1[1];
// 定义一个非常小的缓冲区buf1用于测试gethostbyname2_r函数的边界条件。
int err, ret;
ret = gethostbyname2_r("localhost", AF_INET, &addr, buf, sizeof buf, &result, &err);
// 使用gethostbyname2_r函数根据主机名"localhost"、地址族AF_INET获取hostent结构体指针。
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
// 断言返回值ret为0表示gethostbyname2_r函数调用成功。
ICUNIT_ASSERT_NOT_EQUAL(result, NULL, -1);
// 断言result不为空即gethostbyname2_r成功。
ICUNIT_ASSERT_EQUAL(strcmp(result->h_name, "localhost"), 0, -1);
// 断言返回的主机名与输入的主机名相同。
ICUNIT_ASSERT_EQUAL(result->h_addrtype, AF_INET, result->h_addrtype);
// 断言返回的地址类型为AF_INET。
ICUNIT_ASSERT_NOT_EQUAL(result->h_length, 0, result->h_length);
// 断言返回的地址长度不为0。
ret = gethostbyname2_r("127.0.0.1", AF_INET, &addr, buf, sizeof buf, &result, &err);
// 使用gethostbyname2_r函数根据IP地址字符串"127.0.0.1"、地址族AF_INET获取hostent结构体指针。
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ICUNIT_ASSERT_NOT_EQUAL(result, NULL, -1);
ICUNIT_ASSERT_EQUAL(strcmp(result->h_name, "127.0.0.1"), 0, -1);
@ -64,17 +82,26 @@ static int GetHostByName2RTest(void)
ICUNIT_ASSERT_NOT_EQUAL(result->h_length, 0, result->h_length);
ret = gethostbyname2_r("127.0.0.1", AF_INET, &addr, buf1, sizeof buf1, &result, &err);
// 测试gethostbyname2_r函数的边界条件传入的缓冲区太小。
ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret);
// 断言返回值ret不为0表示gethostbyname2_r函数调用失败。
ret = gethostbyname2_r("127.0.0.1.1", AF_INET, &addr, buf, sizeof buf, &result, &err);
// 测试一个不存在的IP地址。
ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret);
// 断言返回值ret不为0表示gethostbyname2_r函数调用失败。
ret = gethostbyname2_r("lo", AF_INET, &addr, buf, sizeof buf, &result, &err);
// 测试一个不存在的主机名。
ICUNIT_ASSERT_NOT_EQUAL(ret, 0, ret);
// 断言返回值ret不为0表示gethostbyname2_r函数调用失败。
RecoveryFileEnv(pathList, file_number);
// 恢复原始文件环境。
return ICUNIT_SUCCESS;
// 返回测试成功。
}
void NetNetDbTest009(void)
{
TEST_ADD_CASE(__FUNCTION__, GetHostByName2RTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
}
// 定义测试用例将GetHostByName2RTest函数注册为一个测试案例。

@ -31,21 +31,31 @@
#include "lt_net_netdb.h"
// 引入头文件,可能包含了网络数据库相关的函数声明和宏定义。
static int NameInfoTest(void)
{
char host[256], serv[256];
// 定义两个数组用于存储getnameinfo函数返回的主机名和服务器名。
struct sockaddr_in addr;
// 定义一个sockaddr_in结构体用于存储IPv4地址信息。
addr.sin_family = AF_INET;
// 设置地址族为IPv4。
addr.sin_port = htons(22);
// 设置端口号为22例如SSH端口htons函数用于将主机字节序转换为网络字节序。
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
// 设置IP地址为127.0.0.1inet_addr函数将点分十进制IP地址转换为网络字节序的整数。
int ret = getnameinfo((struct sockaddr*)&addr, sizeof addr, host, sizeof host, serv, sizeof serv, 0);
// 调用getnameinfo函数传入地址信息、主机名和服务器名的缓冲区尝试获取主机名和服务器名。
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
// 断言getnameinfo函数调用成功返回值为0。
return ICUNIT_SUCCESS;
// 返回测试成功。
}
void NetNetDbTest010(void)
{
TEST_ADD_CASE(__FUNCTION__, NameInfoTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
}
// 定义测试用例将NameInfoTest函数注册为一个测试案例。

@ -31,37 +31,57 @@
#include "lt_net_netdb.h"
// 引入头文件,可能包含了网络数据库相关的函数声明和宏定义。
static int GetServByPortTest(void)
{
// refer to the `/etc/services' file.
char serv_file[] = "ssh 22/tcp\n";
// 定义一个模拟的services文件内容包含ssh服务的条目。
char *pathList[] = {"/etc/services"};
// 定义services文件的路径列表这里只有一个路径指向系统的services文件。
char *streamList[] = {static_cast<char *>(serv_file)};
// 定义模拟的services文件流列表这里将模拟的services文件内容转换为char*类型。
int streamLen[] = {sizeof(serv_file)};
// 定义模拟的services文件流长度列表。
const int file_number = 1;
// 定义文件数量。
int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number);
// 调用PrepareFileEnv函数准备文件环境模拟services文件。
if (flag != 0) {
RecoveryFileEnv(pathList, file_number);
return -1;
}
// 如果准备文件环境失败,则恢复原始文件环境并返回错误码。
const int test_port_no = 22; // ssh port number is 22
// 定义测试的端口号这里是22即SSH服务的标准端口号。
struct servent *se1 = nullptr;
// 定义servent结构体指针变量se1初始化为nullptr。
struct servent *se = getservbyport(htons(test_port_no), "tcp");
// 使用getservbyport函数根据端口号和协议名"tcp"获取servent结构体指针。
ICUNIT_ASSERT_NOT_EQUAL(se, NULL, -1);
// 断言se不为空即getservbyport成功。
ICUNIT_ASSERT_STRING_EQUAL(se->s_name, "ssh", -1);
// 断言返回的服务名称与"ssh"相同。
ICUNIT_ASSERT_STRING_EQUAL(se->s_proto, "tcp", -1);
// 断言返回的服务协议与"tcp"相同。
ICUNIT_ASSERT_STRING_EQUAL(se->s_aliases[0], "ssh", -1);
// 断言返回的服务别名与"ssh"相同。
se1 = getservbyport(htons(test_port_no), "tp");
// 尝试使用getservbyport函数根据端口号和错误的协议名"tp"获取servent结构体指针预期失败。
ICUNIT_ASSERT_EQUAL(se1, nullptr, -1);
// 断言se1为空即getservbyport失败。
RecoveryFileEnv(pathList, file_number);
// 恢复原始文件环境。
return ICUNIT_SUCCESS;
// 返回测试成功。
}
void NetNetDbTest011(void)
{
TEST_ADD_CASE(__FUNCTION__, GetServByPortTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
}
// 定义测试用例将GetServByPortTest函数注册为一个测试案例。

@ -31,50 +31,80 @@
#include "lt_net_netdb.h"
// 引入头文件,可能包含了网络数据库相关的函数声明和宏定义。
static int GetServByPortRTest(void)
{
// refer to the `/etc/services' file.
char serv_file[] = "ssh 22/tcp\n";
// 定义一个模拟的services文件内容包含ssh服务的条目。
char *pathList[] = {"/etc/services"};
// 定义services文件的路径列表这里只有一个路径指向系统的services文件。
char *streamList[] = {static_cast<char *>(serv_file)};
// 定义模拟的services文件流列表这里将模拟的services文件内容转换为char*类型。
int streamLen[] = {sizeof(serv_file)};
// 定义模拟的services文件流长度列表。
const int file_number = 1;
// 定义文件数量。
int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number);
// 调用PrepareFileEnv函数准备文件环境模拟services文件。
if (flag != 0) {
RecoveryFileEnv(pathList, file_number);
return -1;
}
// 如果准备文件环境失败,则恢复原始文件环境并返回错误码。
struct servent se, *result = NULL;
// 定义servent结构体变量se用于存储getservbyport_r函数的结果。
char buf[1024];
// 定义一个足够大的缓冲区buf用于getservbyport_r函数。
char buf1[2];
// 定义一个非常小的缓冲区buf1用于测试getservbyport_r函数的边界条件。
const int test_port_no = 22; // ssh port number is 22
// 定义测试的端口号这里是22即SSH服务的标准端口号。
int ret = getservbyport_r(htons(test_port_no), "tcp", &se, buf, sizeof buf, &result);
// 使用getservbyport_r函数根据端口号和协议名"tcp"获取servent结构体指针。
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
// 断言返回值ret为0表示getservbyport_r函数调用成功。
ICUNIT_ASSERT_NOT_EQUAL(result, NULL, -1);
// 断言result不为空即getservbyport_r成功。
ICUNIT_ASSERT_STRING_EQUAL(se.s_name, "ssh", -1);
// 断言返回的服务名称与"ssh"相同。
ICUNIT_ASSERT_STRING_EQUAL(se.s_proto, "tcp", -1);
// 断言返回的服务协议与"tcp"相同。
ICUNIT_ASSERT_STRING_EQUAL(se.s_aliases[0], "ssh", -1);
// 断言返回的服务别名与"ssh"相同。
ICUNIT_ASSERT_STRING_EQUAL(result->s_name, "ssh", -1);
// 断言result结构体中的服务名称与"ssh"相同。
ICUNIT_ASSERT_STRING_EQUAL(result->s_proto, "tcp", -1);
// 断言result结构体中的服务协议与"tcp"相同。
ICUNIT_ASSERT_STRING_EQUAL(result->s_aliases[0], "ssh", -1);
// 断言result结构体中的服务别名与"ssh"相同。
ret = getservbyport_r(htons(test_port_no), "udp", &se, buf, sizeof buf, &result);
// 尝试使用getservbyport_r函数根据端口号和协议名"udp"获取servent结构体指针预期失败。
ICUNIT_ASSERT_EQUAL(ret, ENOENT, -1);
// 断言返回值ret为ENOENT表示未找到对应服务。
ret = getservbyport_r(htons(test_port_no), "udp", &se, buf1, sizeof buf1, &result);
// 测试getservbyport_r函数的边界条件传入的缓冲区太小。
ICUNIT_ASSERT_EQUAL(ret, ERANGE, ret);
// 断言返回值ret为ERANGE表示缓冲区太小。
ret = getservbyport_r(htons(test_port_no), "ud", &se, buf, sizeof buf, &result);
// 尝试使用getservbyport_r函数根据端口号和不完整的协议名"ud"获取servent结构体指针预期失败。
ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret);
// 断言返回值ret为EINVAL表示提供的协议名不合法。
RecoveryFileEnv(pathList, file_number);
// 恢复原始文件环境。
return ICUNIT_SUCCESS;
// 返回测试成功。
}
void NetNetDbTest012(void)
{
TEST_ADD_CASE(__FUNCTION__, GetServByPortRTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
}
// 定义测试用例将GetServByPortRTest函数注册为一个测试案例。

@ -1,5 +1,5 @@
/*
* opyright (c) 2021-2021, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2021-2021, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@ -30,6 +30,7 @@
#include "lt_net_netdb.h"
#include <net/if.h>
// 引入头文件,包括网络数据库相关的函数声明和宏定义,以及网络接口相关的函数和宏定义。
static int IfNameToIndexTest(void)
{
@ -38,20 +39,30 @@ static int IfNameToIndexTest(void)
char *str = nullptr;
ret = if_nametoindex("lo");
// 调用if_nametoindex函数将接口名称"lo"转换为系统索引。
ICUNIT_ASSERT_NOT_EQUAL(ret, 0, -1);
// 断言转换成功返回的索引值不为0。
str = if_indextoname(ret, if_name);
// 调用if_indextoname函数将系统索引转换回接口名称。
ICUNIT_ASSERT_NOT_EQUAL(str, nullptr, -1);
// 断言转换成功返回的字符串指针不为nullptr。
ICUNIT_ASSERT_STRING_EQUAL(if_name, "lo", -1);
// 断言转换回的接口名称为"lo"。
ret = if_nametoindex("eth1");
// 尝试调用if_nametoindex函数将接口名称"eth1"转换为系统索引。
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
// 断言转换失败返回的索引值为0。
ICUNIT_ASSERT_EQUAL(errno, ENODEV, errno);
// 断言errno被设置为ENODEV表示没有找到对应的设备。
return ICUNIT_SUCCESS;
// 返回测试成功。
}
void NetNetDbTest015(void)
{
TEST_ADD_CASE(__FUNCTION__, IfNameToIndexTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
}
// 定义测试用例将IfNameToIndexTest函数注册为一个测试案例。

@ -1,5 +1,5 @@
/*
* opyright (c) 2021-2021, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2021-2021, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@ -29,6 +29,7 @@
*/
#include "lt_net_netdb.h"
// 引入头文件,可能包含了网络数据库相关的函数声明和宏定义。
static int GetServByNameTest(void)
{
@ -38,43 +39,65 @@ static int GetServByNameTest(void)
"discard 9/udp sink null\n"
"systat 11/tcp users\n"
"ssh 22/tcp\n";
// 定义一个模拟的services文件内容包含多个服务的条目。
char *pathList[] = {"/etc/services"};
// 定义services文件的路径列表这里只有一个路径指向系统的services文件。
char *streamList[] = {static_cast<char *>(serv_file)};
// 定义模拟的services文件流列表这里将模拟的services文件内容转换为char*类型。
int streamLen[] = {sizeof(serv_file)};
// 定义模拟的services文件流长度列表。
const int file_number = 1;
// 定义文件数量。
int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number);
// 调用PrepareFileEnv函数准备文件环境模拟services文件。
if (flag != 0) {
RecoveryFileEnv(pathList, file_number);
return -1;
}
// 如果准备文件环境失败,则恢复原始文件环境并返回错误码。
struct servent *se1 = nullptr;
struct servent *se2 = nullptr;
se1 = getservbyname("discard", "tcp");
// 使用getservbyname函数根据服务名"discard"和协议名"tcp"获取servent结构体指针。
ICUNIT_ASSERT_NOT_EQUAL(se1, NULL, -1);
// 断言se1不为空即getservbyname成功。
ICUNIT_ASSERT_STRING_EQUAL(se1->s_name, "discard", -1);
// 断言返回的服务名称与"discard"相同。
ICUNIT_ASSERT_STRING_EQUAL(se1->s_proto, "tcp", -1);
// 断言返回的服务协议与"tcp"相同。
ICUNIT_ASSERT_STRING_EQUAL(se1->s_aliases[0], "discard", -1);
// 断言返回的服务别名与"discard"相同。
se1 = getservbyname("ssh", "tcp");
// 使用getservbyname函数根据服务名"ssh"和协议名"tcp"获取servent结构体指针。
ICUNIT_ASSERT_NOT_EQUAL(se1, nullptr, -1);
// 断言se1不为空即getservbyname成功。
ICUNIT_ASSERT_STRING_EQUAL(se1->s_name, "ssh", -1);
// 断言返回的服务名称与"ssh"相同。
ICUNIT_ASSERT_STRING_EQUAL(se1->s_proto, "tcp", -1);
// 断言返回的服务协议与"tcp"相同。
ICUNIT_ASSERT_STRING_EQUAL(se1->s_aliases[0], "ssh", -1);
// 断言返回的服务别名与"ssh"相同。
se2 = getservbyname("cho", "udp");
// 尝试使用getservbyname函数根据错误的服务名"cho"和协议名"udp"获取servent结构体指针预期失败。
ICUNIT_ASSERT_EQUAL(se2, nullptr, -1);
se2 = getservbyname("systat", "udp");
// 尝试使用getservbyname函数根据服务名"systat"和协议名"udp"获取servent结构体指针预期失败。
ICUNIT_ASSERT_EQUAL(se2, nullptr, -1);
RecoveryFileEnv(pathList, file_number);
// 恢复原始文件环境。
return ICUNIT_SUCCESS;
// 返回测试成功。
}
void NetNetDbTest016(void)
{
TEST_ADD_CASE(__FUNCTION__, GetServByNameTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
}
// 定义测试用例将GetServByNameTest函数注册为一个测试案例。

@ -1,5 +1,5 @@
/*
* opyright (c) 2021-2021, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2021-2021, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@ -29,19 +29,27 @@
*/
#include "lt_net_netdb.h"
// 引入头文件,可能包含了网络数据库相关的函数声明和宏定义。
static int GetServByNameRTest(void)
{
char serv_file[] = "ssh 22/tcp\n";
// 定义一个模拟的services文件内容包含ssh服务的条目。
char *pathList[] = {"/etc/services"};
// 定义services文件的路径列表这里只有一个路径指向系统的services文件。
char *streamList[] = {static_cast<char *>(serv_file)};
// 定义模拟的services文件流列表这里将模拟的services文件内容转换为char*类型。
int streamLen[] = {sizeof(serv_file)};
// 定义模拟的services文件流长度列表。
const int file_number = 1;
// 定义文件数量。
int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number);
// 调用PrepareFileEnv函数准备文件环境模拟services文件。
if (flag != 0) {
RecoveryFileEnv(pathList, file_number);
return -1;
}
// 如果准备文件环境失败,则恢复原始文件环境并返回错误码。
struct servent se;
struct servent *result = NULL;
@ -51,29 +59,47 @@ static int GetServByNameRTest(void)
errno = 0;
ret = getservbyname_r("ssh", "tcp", &se, buf1, sizeof buf1, &result);
// 使用getservbyname_r函数根据服务名"ssh"和协议名"tcp"获取servent结构体指针。
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
// 断言返回值ret为0表示getservbyname_r函数调用成功。
ICUNIT_ASSERT_NOT_EQUAL(result, NULL, -1);
// 断言result不为空即getservbyname_r成功。
ICUNIT_ASSERT_STRING_EQUAL(se.s_name, "ssh", -1);
// 断言返回的服务名称与"ssh"相同。
ICUNIT_ASSERT_STRING_EQUAL(se.s_proto, "tcp", -1);
// 断言返回的服务协议与"tcp"相同。
ICUNIT_ASSERT_STRING_EQUAL(se.s_aliases[0], "ssh", -1);
// 断言返回的服务别名与"ssh"相同。
ICUNIT_ASSERT_STRING_EQUAL(result->s_name, "ssh", -1);
// 断言result结构体中的服务名称与"ssh"相同。
ICUNIT_ASSERT_STRING_EQUAL(result->s_proto, "tcp", -1);
// 断言result结构体中的服务协议与"tcp"相同。
ICUNIT_ASSERT_STRING_EQUAL(result->s_aliases[0], "ssh", -1);
// 断言result结构体中的服务别名与"ssh"相同。
ret = getservbyname_r("ssh", "tcp", &se, buf2, sizeof buf2, &result);
// 测试getservbyname_r函数的边界条件传入的缓冲区太小。
ICUNIT_ASSERT_EQUAL(ret, ERANGE, ret);
// 断言返回值ret为ERANGE表示缓冲区太小。
ret = getservbyname_r("ssh", "tp", &se, buf1, sizeof buf1, &result);
// 尝试使用getservbyname_r函数根据服务名"ssh"和错误的协议名"tp"获取servent结构体指针预期失败。
ICUNIT_ASSERT_EQUAL(ret, EINVAL, ret);
// 断言返回值ret为EINVAL表示提供的协议名不合法。
ret = getservbyname_r("sh", "tcp", &se, buf1, sizeof buf1, &result);
// 尝试使用getservbyname_r函数根据不完整的服务名"sh"和协议名"tcp"获取servent结构体指针预期失败。
ICUNIT_ASSERT_EQUAL(ret, ENOENT, ret);
// 断言返回值ret为ENOENT表示未找到对应服务。
RecoveryFileEnv(pathList, file_number);
// 恢复原始文件环境。
return ICUNIT_SUCCESS;
// 返回测试成功。
}
void NetNetDbTest017(void)
{
TEST_ADD_CASE(__FUNCTION__, GetServByNameRTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
}
// 定义测试用例将GetServByNameRTest函数注册为一个测试案例。

@ -1,5 +1,5 @@
/*
* opyright (c) 2021-2021, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2021-2021, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@ -29,6 +29,7 @@
*/
#include "lt_net_netdb.h"
// 引入头文件,可能包含了网络数据库相关的函数声明和宏定义。
static int GetServEntTest(void)
{
@ -39,15 +40,22 @@ static int GetServEntTest(void)
"ssh 100000/tcp\n"
"ssh /tcp\n"
"ssh 22/";
// 定义一个模拟的services文件内容包含多个服务的条目。
char *pathList[] = {"/etc/services"};
// 定义services文件的路径列表这里只有一个路径指向系统的services文件。
char *streamList[] = {static_cast<char *>(serv_file)};
// 定义模拟的services文件流列表这里将模拟的services文件内容转换为char*类型。
int streamLen[] = {sizeof(serv_file)};
// 定义模拟的services文件流长度列表。
const int file_number = 1;
// 定义文件数量。
int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number);
// 调用PrepareFileEnv函数准备文件环境模拟services文件。
if (flag != 0) {
RecoveryFileEnv(pathList, file_number);
return -1;
}
// 如果准备文件环境失败,则恢复原始文件环境并返回错误码。
/* tcpmux,echo,discard port number is 1,7,9 */
const int tcpmux_port_no = 1;
@ -59,55 +67,96 @@ static int GetServEntTest(void)
struct servent *se3 = nullptr;
se1 = getservent();
// 调用getservent函数获取services数据库中的第一个服务条目。
ICUNIT_ASSERT_NOT_EQUAL(se1, nullptr, -1);
// 断言se1不为空即getservent成功。
ICUNIT_ASSERT_STRING_EQUAL(se1->s_name, "tcpmux", -1);
// 断言返回的服务名称与"tcpmux"相同。
ICUNIT_ASSERT_STRING_EQUAL(se1->s_proto, "tcp", -1);
// 断言返回的服务协议与"tcp"相同。
ICUNIT_ASSERT_EQUAL(se1->s_port, ntohs(tcpmux_port_no), -1);
// 断言返回的服务端口号与转换为网络字节序的1相同。
endservent();
// 调用endservent函数结束服务数据库的搜索。
se2 = getservent();
// 再次调用getservent函数获取services数据库中的第一个服务条目。
ICUNIT_ASSERT_NOT_EQUAL(se2, nullptr, -1);
// 断言se2不为空即getservent成功。
ICUNIT_ASSERT_STRING_EQUAL(se1->s_name, se2->s_name, -1);
// 断言返回的服务名称与之前相同。
ICUNIT_ASSERT_STRING_EQUAL(se1->s_proto, se2->s_proto, -1);
// 断言返回的服务协议与之前相同。
ICUNIT_ASSERT_EQUAL(se1->s_port, se2->s_port, -1);
// 断言返回的服务端口号与之前相同。
setservent(0);
// 调用setservent函数设置服务数据库的搜索位置到开始。
se3 = getservent();
// 调用getservent函数获取services数据库中的第一个服务条目。
ICUNIT_ASSERT_NOT_EQUAL(se3, nullptr, -1);
// 断言se3不为空即getservent成功。
ICUNIT_ASSERT_STRING_EQUAL(se1->s_name, se3->s_name, -1);
// 断言返回的服务名称与之前相同。
ICUNIT_ASSERT_STRING_EQUAL(se1->s_proto, se3->s_proto, -1);
// 断言返回的服务协议与之前相同。
ICUNIT_ASSERT_EQUAL(se1->s_port, se3->s_port, -1);
// 断言返回的服务端口号与之前相同。
se3 = getservent();
// 获取下一个服务条目。
ICUNIT_ASSERT_NOT_EQUAL(se3, nullptr, -1);
// 断言se3不为空即getservent成功。
ICUNIT_ASSERT_STRING_EQUAL(se3->s_name, "echo", -1);
// 断言返回的服务名称与"echo"相同。
ICUNIT_ASSERT_STRING_EQUAL(se3->s_proto, "tcp", -1);
// 断言返回的服务协议与"tcp"相同。
ICUNIT_ASSERT_EQUAL(se3->s_port, ntohs(echo_port_no), -1);
// 断言返回的服务端口号与转换为网络字节序的7相同。
se3 = getservent();
// 获取下一个服务条目。
ICUNIT_ASSERT_NOT_EQUAL(se3, nullptr, -1);
// 断言se3不为空即getservent成功。
ICUNIT_ASSERT_STRING_EQUAL(se3->s_name, "echo", -1);
// 断言返回的服务名称与"echo"相同。
ICUNIT_ASSERT_STRING_EQUAL(se3->s_proto, "udp", -1);
// 断言返回的服务协议与"udp"相同。
ICUNIT_ASSERT_EQUAL(se3->s_port, ntohs(echo_port_no), -1);
// 断言返回的服务端口号与转换为网络字节序的7相同。
se3 = getservent();
// 获取下一个服务条目。
ICUNIT_ASSERT_NOT_EQUAL(se3, nullptr, -1);
// 断言se3不为空即getservent成功。
ICUNIT_ASSERT_STRING_EQUAL(se3->s_name, "discard", -1);
// 断言返回的服务名称与"discard"相同。
ICUNIT_ASSERT_STRING_EQUAL(se3->s_proto, "tcp", -1);
// 断言返回的服务协议与"tcp"相同。
ICUNIT_ASSERT_EQUAL(se3->s_port, ntohs(discard_port_no), -1);
// 断言返回的服务端口号与转换为网络字节序的9相同。
ICUNIT_ASSERT_STRING_EQUAL(se3->s_aliases[0], "sink", -1);
// 断言返回的服务别名列表中的第一个别名与"sink"相同。
ICUNIT_ASSERT_STRING_EQUAL(se3->s_aliases[1], "null", -1);
// 断言返回的服务别名列表中的第二个别名与"null"相同。
ICUNIT_ASSERT_EQUAL(se3->s_aliases[2], nullptr, -1);
// 断言返回的服务别名列表中的第三个别名为nullptr表示别名列表结束。
se3 = getservent();
// 获取下一个服务条目。
ICUNIT_ASSERT_EQUAL(se3, nullptr, -1);
// 断言se3为空即已经到达services数据库的末尾。
endservent();
// 调用endservent函数结束服务数据库的搜索。
RecoveryFileEnv(pathList, file_number);
// 恢复原始文件环境。
return ICUNIT_SUCCESS;
// 返回测试成功。
}
void NetNetDbTest018(void)
{
TEST_ADD_CASE(__FUNCTION__, GetServEntTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
}
// 定义测试用例将GetServEntTest函数注册为一个测试案例。

@ -1,5 +1,5 @@
/*
* opyright (c) 2021-2021, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2021-2021, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@ -29,7 +29,8 @@
*/
#include "lt_net_netdb.h"
#include<arpa/nameser.h>
#include <arpa/nameser.h>
// 引入头文件包括网络数据库相关的函数声明和宏定义以及Nameser.h中定义的与DNS相关的宏和结构。
static int GetHostEntTest(void)
{
@ -38,15 +39,22 @@ static int GetHostEntTest(void)
"10.0.0.0 example example.com example.cn\n"
"10.0.0.0\n"
"10.0.0 example.com";
// 定义一个模拟的hosts文件内容包含IPv4和IPv6的条目。
char *pathList[] = {"/etc/hosts"};
// 定义hosts文件的路径列表这里只有一个路径指向系统的hosts文件。
char *streamList[] = {static_cast<char *>(host_file)};
// 定义模拟的hosts文件流列表这里将模拟的hosts文件内容转换为char*类型。
int streamLen[] = {sizeof(host_file)};
// 定义模拟的hosts文件流长度列表。
const int file_number = 1;
// 定义文件数量。
int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number);
// 调用PrepareFileEnv函数准备文件环境模拟hosts文件。
if (flag != 0) {
RecoveryFileEnv(pathList, file_number);
return -1;
}
// 如果准备文件环境失败,则恢复原始文件环境并返回错误码。
struct hostent *se1 = nullptr;
struct hostent *se2 = nullptr;
@ -54,52 +62,91 @@ static int GetHostEntTest(void)
char addr[INET6_ADDRSTRLEN];
se1 = gethostent();
// 调用gethostent函数获取hosts数据库中的第一个主机条目。
ICUNIT_ASSERT_NOT_EQUAL(se1, nullptr, -1);
// 断言se1不为空即gethostent成功。
ICUNIT_ASSERT_STRING_EQUAL(se1->h_name, "localhost", -1);
// 断言返回的主机名与"localhost"相同。
ICUNIT_ASSERT_EQUAL(se1->h_addrtype, AF_INET, -1);
// 断言返回的地址类型为AF_INETIPv4
ICUNIT_ASSERT_EQUAL(se1->h_length, INADDRSZ, -1);
// 断言返回的地址长度为IPv4地址长度。
ICUNIT_ASSERT_STRING_EQUAL("127.0.0.1", inet_ntop(AF_INET, se1->h_addr_list[0], addr, INET_ADDRSTRLEN), -1);
// 断言返回的第一个地址为"127.0.0.1"。
ICUNIT_ASSERT_EQUAL(se1->h_aliases[0], nullptr, -1);
// 断言别名列表中的第一个别名为nullptr表示别名列表结束。
endhostent();
// 调用endhostent函数结束主机数据库的搜索。
se2 = gethostent();
// 再次调用gethostent函数获取hosts数据库中的第一个主机条目。
ICUNIT_ASSERT_NOT_EQUAL(se2, nullptr, -1);
// 断言se2不为空即gethostent成功。
ICUNIT_ASSERT_STRING_EQUAL(se1->h_name, se2->h_name, -1);
// 断言返回的主机名与之前相同。
ICUNIT_ASSERT_EQUAL(se1->h_addrtype, se2->h_addrtype, -1);
// 断言返回的地址类型与之前相同。
ICUNIT_ASSERT_EQUAL(se1->h_length, se2->h_length, -1);
// 断言返回的地址长度与之前相同。
sethostent(0);
// 调用sethostent函数设置主机数据库的搜索位置到开始。
se3 = gethostent();
// 调用gethostent函数获取hosts数据库中的第一个主机条目。
ICUNIT_ASSERT_NOT_EQUAL(se3, nullptr, -1);
// 断言se3不为空即gethostent成功。
ICUNIT_ASSERT_STRING_EQUAL(se1->h_name, se3->h_name, -1);
// 断言返回的主机名与之前相同。
ICUNIT_ASSERT_EQUAL(se1->h_addrtype, se3->h_addrtype, -1);
// 断言返回的地址类型与之前相同。
ICUNIT_ASSERT_EQUAL(se1->h_length, se3->h_length, -1);
// 断言返回的地址长度与之前相同。
se3 = gethostent();
// 获取下一个主机条目。
ICUNIT_ASSERT_NOT_EQUAL(se3, nullptr, -1);
// 断言se3不为空即gethostent成功。
ICUNIT_ASSERT_EQUAL(se3->h_addrtype, AF_INET6, -1);
// 断言返回的地址类型为AF_INET6IPv6
ICUNIT_ASSERT_STRING_EQUAL(se3->h_name, "ip6-localhost", -1);
// 断言返回的主机名为"ip6-localhost"。
ICUNIT_ASSERT_EQUAL(se3->h_length, IN6ADDRSZ, -1);
// 断言返回的地址长度为IPv6地址长度。
ICUNIT_ASSERT_STRING_EQUAL("::1", inet_ntop(AF_INET6, se3->h_addr_list[0], addr, INET6_ADDRSTRLEN), -1);
// 断言返回的第一个地址为"::1"。
se3 = gethostent();
// 获取下一个主机条目。
ICUNIT_ASSERT_NOT_EQUAL(se3, nullptr, -1);
// 断言se3不为空即gethostent成功。
ICUNIT_ASSERT_EQUAL(se3->h_addrtype, AF_INET, -1);
// 断言返回的地址类型为AF_INETIPv4
ICUNIT_ASSERT_STRING_EQUAL(se3->h_name, "example", -1);
// 断言返回的主机名为"example"。
ICUNIT_ASSERT_STRING_EQUAL("10.0.0.0", inet_ntop(AF_INET, se3->h_addr_list[0], addr, INET_ADDRSTRLEN), -1);
// 断言返回的第一个地址为"10.0.0.0"。
ICUNIT_ASSERT_STRING_EQUAL(se3->h_aliases[0], "example.com", -1);
// 断言别名列表中的第一个别名为"example.com"。
ICUNIT_ASSERT_STRING_EQUAL(se3->h_aliases[1], "example.cn", -1);
// 断言别名列表中的第二个别名为"example.cn"。
ICUNIT_ASSERT_EQUAL(se3->h_aliases[2], nullptr, -1);
// 断言别名列表中的第三个别名为nullptr表示别名列表结束。
se3 = gethostent();
// 获取下一个主机条目。
ICUNIT_ASSERT_EQUAL(se3, nullptr, -1);
// 断言se3为空即已经到达hosts数据库的末尾。
endhostent();
// 调用endhostent函数结束主机数据库的搜索。
RecoveryFileEnv(pathList, file_number);
// 恢复原始文件环境。
return ICUNIT_SUCCESS;
// 返回测试成功。
}
void NetNetDbTest019(void)
{
TEST_ADD_CASE(__FUNCTION__, GetHostEntTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
}
// 定义测试用例将GetHostEntTest函数注册为一个测试案例。

@ -1,5 +1,5 @@
/*
* opyright (c) 2021-2021, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2021-2021, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@ -29,6 +29,7 @@
*/
#include "lt_net_netdb.h"
// 引入头文件,包含了网络数据库相关的函数声明和宏定义。
static int GetNetEntTest(void)
{
@ -36,59 +37,193 @@ static int GetNetEntTest(void)
"link-local 169.254.0.0\n"
"example 192.168.1.0 network example-network\n"
"test1";
// 定义一个模拟的networks文件内容包含网络名称和对应的地址。
char *pathList[] = {"/etc/networks"};
// 定义networks文件的路径列表这里只有一个路径指向系统的networks文件。
char *streamList[] = {static_cast<char *>(network_file)};
// 定义模拟的networks文件流列表这里将模拟的networks文件内容转换为char*类型。
int streamLen[] = {sizeof(network_file)};
// 定义模拟的networks文件流长度列表。
const int file_number = 1;
// 定义文件数量。
int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number);
// 调用PrepareFileEnv函数准备文件环境模拟networks文件。
if (flag != 0) {
RecoveryFileEnv(pathList, file_number);
return -1;
}
// 如果准备文件环境失败,则恢复原始文件环境并返回错误码。
struct netent *se1 = nullptr;
struct netent *se2 = nullptr;
struct netent *se3 = nullptr;
se1 = getnetent();
// 调用getnetent函数获取networks数据库中的第一个网络条目。
ICUNIT_ASSERT_NOT_EQUAL(se1, nullptr, -1);
// 断言se1不为空即getnetent成功。
ICUNIT_ASSERT_STRING_EQUAL(se1->n_name, "link-local", -1);
// 断言返回的网络名称与"link-local"相同。
ICUNIT_ASSERT_EQUAL(se1->n_addrtype, AF_INET, -1);
// 断言返回的地址类型为AF_INETIPv4
ICUNIT_ASSERT_EQUAL(se1->n_net, inet_network("169.254.0.0"), -1);
// 断言返回的网络地址与"169.254.0.0"相同。
ICUNIT_ASSERT_EQUAL(se1->n_aliases[0], nullptr, -1);
// 断言别名列表中的第一个别名为nullptr表示别名列表结束。
endnetent();
// 调用endnetent函数结束网络数据库的搜索。
se2 = getnetent();
// 再次调用getnetent函数获取networks数据库中的第一个网络条目。
ICUNIT_ASSERT_NOT_EQUAL(se2, nullptr, -1);
// 断言se2不为空即getnetent成功。
ICUNIT_ASSERT_STRING_EQUAL(se1->n_name, se2->n_name, -1);
// 断言返回的网络名称与之前相同。
ICUNIT_ASSERT_EQUAL(se1->n_addrtype, se2->n_addrtype, -1);
// 断言返回的地址类型与之前相同。
ICUNIT_ASSERT_EQUAL(se1->n_net, se2->n_net, -1);
// 断言返回的网络地址与之前相同。
setnetent(0);
// 调用setnetent函数设置网络数据库的搜索位置到开始。
se3 = getnetent();
// 调用getnetent函数获取networks数据库中的第一个网络条目。
ICUNIT_ASSERT_NOT_EQUAL(se3, nullptr, -1);
// 断言se3不为空即getnetent成功。
ICUNIT_ASSERT_STRING_EQUAL(se1->n_name, se3->n_name, -1);
// 断言返回的网络名称与之前相同。
ICUNIT_ASSERT_EQUAL(se1->n_addrtype, se3->n_addrtype, -1);
// 断言返回的地址类型与之前相同。
ICUNIT_ASSERT_EQUAL(se1->n_net, se3->n_net, -1);
// 断言返回的网络地址与之前相同。
se1 = getnetent();
// 获取下一个网络条目。
ICUNIT_ASSERT_NOT_EQUAL(se1, nullptr, -1);
// 断言se1不为空即getnetent成功。
ICUNIT_ASSERT_STRING_EQUAL(se1->n_name, "example", -1);
// 断言返回的网络名称与"example"相同。
ICUNIT_ASSERT_EQUAL(se1->n_addrtype, AF_INET, -1);
// 断言返回的地址类型为AF_INETIPv4
ICUNIT_ASSERT_EQUAL(se1->n_net, inet_network("192.168.1.0"), -1);
// 断言返回的网络地址与"192.168.1.0"相同。
ICUNIT_ASSERT_STRING_EQUAL(se1->n_aliases[0], "network", -1);
// 断言别名列表中的第一个别名为"network"。
ICUNIT_ASSERT_STRING_EQUAL(se1->n_aliases[1], "example-network", -1);
// 断言别名列表中的第二个别名为"example-network"。
ICUNIT_ASSERT_EQUAL(se1->n_aliases[2], nullptr, -1);
// 断言别名列表中的第三个别名为nullptr表示别名列表结束。
se1 = getnetent();
// 获取下一个网络条目。
ICUNIT_ASSERT_EQUAL(se1, nullptr, -1);
// 断言se1为空即已经到达networks数据库的末尾。
endnetent();
// 调用endnetent函数结束网络数据库的搜索。
RecoveryFileEnv(pathList, file_number);
// 恢复原始文件环境。
return ICUNIT_SUCCESS;
// 返回测试成功。
}
void NetNetDbTest020(void)
{
TEST_ADD_CASE(__FUNCTION__, GetNetEntTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
}
```cpp
/*
* opyright (c) 2021 - 2021, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020 - 2021 Huawei Device Co., Ltd. All rights reserved.
*
* 使
*/
#include "lt_net_netdb.h"
// 引入 "lt_net_netdb.h" 头文件,可能包含了网络数据库相关的函数声明、结构体定义等。
static int GetNetEntTest(void)
{
char network_file[] = "# symbolic names for networks, see networks(5) for more information\n"
"link - local 169.254.0.0\n"
"example 192.168.1.0 network example - network\n"
"test1";
// 定义一个字符数组network_file其中包含了一些网络相关的信息看起来像是网络配置信息的示例内容。
char *pathList[] = {"/etc/networks"};
char *streamList[] = {static_cast<char *>(network_file)};
int streamLen[] = {sizeof(network_file)};
const int file_number = 1;
// 定义了一些与文件操作相关的数组和变量。
// pathList是一个字符串指针数组包含要操作的文件路径。
// streamList是一个字符指针数组这里将network_file转换为字符指针后放入其中。
// streamLen是一个整数数组记录每个流这里对应network_file的长度。
// file_number表示文件的数量。
int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number);
if (flag!= 0) {
RecoveryFileEnv(pathList, file_number);
return -1;
}
// 调用PrepareFileEnv函数来准备文件环境如果返回值不为0表示有错误则调用RecoveryFileEnv进行文件环境的恢复并返回 -1表示失败。
struct netent *se1 = nullptr;
struct netent *se2 = nullptr;
struct netent *se3 = nullptr;
// 定义三个指向netent结构体的指针并初始化为nullptrnetent结构体可能用于存储网络相关的信息例如网络名称、地址类型、网络地址等
se1 = getnetent();
ICUNIT_ASSERT_NOT_EQUAL(se1, nullptr, -1);
ICUNIT_ASSERT_STRING_EQUAL(se1->n_name, "link - local", -1);
ICUNIT_ASSERT_EQUAL(se1->n_addrtype, AF_INET, -1);
ICUNIT_ASSERT_EQUAL(se1->n_net, inet_network("169.254.0.0"), -1);
ICUNIT_ASSERT_EQUAL(se1->n_aliases[0], nullptr, -1);
// 调用getnetent函数获取网络相关信息然后使用ICUNIT_ASSERT相关的宏进行断言。
// 确保se1不为nullptr并且其名称为 "link - local"地址类型为AF_INET网络地址为 "169.254.0.0"并且第一个别名n_aliases[0]为nullptr。
endnetent();
se2 = getnetent();
ICUNIT_ASSERT_NOT_EQUAL(se2, nullptr, -1);
ICUNIT_ASSERT_STRING_EQUAL(se1->n_name, se2->n_name, -1);
ICUNIT_ASSERT_EQUAL(se1->n_addrtype, se2->n_addrtype, -1);
ICUNIT_ASSERT_EQUAL(se1->n_net, se2->n_net, -1);
// 先调用endnetent函数然后再次调用getnetent获取网络信息然后进行断言确保两次获取的网络信息在名称、地址类型和网络地址上相同。
setnetent(0);
se3 = getnetent();
ICUNIT_ASSERT_NOT_EQUAL(se3, nullptr, -1);
ICUNIT_ASSERT_STRING_EQUAL(se1->n_name, se3->n_name, -1);
ICUNIT_ASSERT_EQUAL(se1->n_addrtype, se3->n_addrtype, -1);
ICUNIT_ASSERT_EQUAL(se1->n_net, se3->n_net, -1);
// 调用setnetent函数设置网络数据库的读取位置这里参数为0可能有特殊含义然后获取网络信息并进行断言确保与之前获取的信息在名称、地址类型和网络地址上相同。
se1 = getnetent();
ICUNIT_ASSERT_NOT_EQUAL(se1, nullptr, -1);
ICUNIT_ASSERT_STRING_EQUAL(se1->n_name, "example", -1);
ICUNIT_ASSERT_EQUAL(se1->n_addrtype, AF_INET, -1);
ICUNIT_ASSERT_EQUAL(se1->n_net, inet_network("192.168.1.0"), -1);
ICUNIT_ASSERT_STRING_EQUAL(se1->n_aliases[0], "network", -1);
ICUNIT_ASSERT_STRING_EQUAL(se1->n_aliases[1], "example - network", -1);
ICUNIT_ASSERT_EQUAL(se1->n_aliases[2], nullptr, -1);
// 再次调用getnetent获取网络信息并进行一系列断言确保获取到的网络信息的名称、地址类型、网络地址以及别名等信息符合预期。
se1 = getnetent();
ICUNIT_ASSERT_EQUAL(se1, nullptr, -1);
endnetent();
// 再次调用getnetent期望获取到nullptr表示已经到达网络信息的末尾然后调用endnetent结束网络信息的读取。
RecoveryFileEnv(pathList, file_number);
return ICUNIT_SUCCESS;
// 调用RecoveryFileEnv进行文件环境的恢复操作并返回ICUNIT_SUCCESS表示函数执行成功。
}
void NetNetDbTest020(void)
{
TEST_ADD_CASE(__FUNCTION__, GetNetEntTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
// 在NetNetDbTest020函数中调用TEST_ADD_CASE宏将当前函数名、GetNetEntTest函数以及一些测试相关的标记如测试类型、协议类型、测试级别等添加到测试用例中。
}
```
ICUNIT_ASSERTPrepareFileEnvRecoveryFileEnvinet_network

@ -1,5 +1,5 @@
/*
* opyright (c) 2021-2021, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2021-2021, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@ -29,42 +29,60 @@
*/
#include "lt_net_netdb.h"
// 引入头文件,包含了网络数据库相关的函数声明和宏定义。
static int GetNetBynametTest(void)
{
char network_file[] = "# symbolic names for networks, see networks(5) for more information\n"
"link-local 169.254.0.0\n";
// 定义一个模拟的networks文件内容包含网络名称和对应的地址。
char *pathList[] = {"/etc/networks"};
// 定义networks文件的路径列表这里只有一个路径指向系统的networks文件。
char *streamList[] = {static_cast<char *>(network_file)};
// 定义模拟的networks文件流列表这里将模拟的networks文件内容转换为char*类型。
int streamLen[] = {sizeof(network_file)};
// 定义模拟的networks文件流长度列表。
const int file_number = 1;
// 定义文件数量。
int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number);
// 调用PrepareFileEnv函数准备文件环境模拟networks文件。
if (flag != 0) {
RecoveryFileEnv(pathList, file_number);
return -1;
}
// 如果准备文件环境失败,则恢复原始文件环境并返回错误码。
struct netent *se1 = nullptr;
struct netent *se2 = nullptr;
struct netent *se3 = nullptr;
se1 = getnetbyname("link-local");
// 使用getnetbyname函数根据网络名称"link-local"获取netent结构体指针。
ICUNIT_ASSERT_NOT_EQUAL(se1, nullptr, -1);
// 断言se1不为空即getnetbyname成功。
ICUNIT_ASSERT_STRING_EQUAL(se1->n_name, "link-local", -1);
// 断言返回的网络名称与"link-local"相同。
ICUNIT_ASSERT_EQUAL(se1->n_addrtype, AF_INET, -1);
// 断言返回的地址类型为AF_INETIPv4
ICUNIT_ASSERT_EQUAL(se1->n_net, inet_network("169.254.0.0"), -1);
// 断言返回的网络地址与"169.254.0.0"相同。
se2 = getnetbyname("link");
// 尝试使用getnetbyname函数根据不完整的网络名称"link"获取netent结构体指针预期失败。
ICUNIT_ASSERT_EQUAL(se2, nullptr, -1);
se3 = getnetbyname("hs");
// 尝试使用getnetbyname函数根据不存在的网络名称"hs"获取netent结构体指针预期失败。
ICUNIT_ASSERT_EQUAL(se3, nullptr, -1);
RecoveryFileEnv(pathList, file_number);
// 恢复原始文件环境。
return ICUNIT_SUCCESS;
// 返回测试成功。
}
void NetNetDbTest021(void)
{
TEST_ADD_CASE(__FUNCTION__, GetNetBynametTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
}
// 定义测试用例将GetNetBynametTest函数注册为一个测试案例。

@ -1,5 +1,5 @@
/*
* opyright (c) 2021-2021, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2021-2021, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@ -29,39 +29,56 @@
*/
#include "lt_net_netdb.h"
// 引入头文件,包含了网络数据库相关的函数声明和宏定义。
static int GetNetByAddrtTest(void)
{
char network_file[] = "# symbolic names for networks, see networks(5) for more information\n"
"link-local 169.254.0.0\n";
// 定义一个模拟的networks文件内容包含网络名称和对应的地址。
char *pathList[] = {"/etc/networks"};
// 定义networks文件的路径列表这里只有一个路径指向系统的networks文件。
char *streamList[] = {static_cast<char *>(network_file)};
// 定义模拟的networks文件流列表这里将模拟的networks文件内容转换为char*类型。
int streamLen[] = {sizeof(network_file)};
// 定义模拟的networks文件流长度列表。
const int file_number = 1;
// 定义文件数量。
int flag = PrepareFileEnv(pathList, streamList, streamLen, file_number);
// 调用PrepareFileEnv函数准备文件环境模拟networks文件。
if (flag != 0) {
RecoveryFileEnv(pathList, file_number);
return -1;
}
// 如果准备文件环境失败,则恢复原始文件环境并返回错误码。
struct netent *se1 = nullptr;
struct netent *se2 = nullptr;
struct netent *se3 = nullptr;
se1 = getnetbyaddr(inet_network("169.254.0.0"), AF_INET);
// 使用getnetbyaddr函数根据网络地址"169.254.0.0"和地址族AF_INET获取netent结构体指针。
ICUNIT_ASSERT_NOT_EQUAL(se1, nullptr, -1);
// 断言se1不为空即getnetbyaddr成功。
ICUNIT_ASSERT_STRING_EQUAL(se1->n_name, "link-local", -1);
// 断言返回的网络名称与"link-local"相同。
ICUNIT_ASSERT_EQUAL(se1->n_addrtype, AF_INET, -1);
// 断言返回的地址类型为AF_INETIPv4
ICUNIT_ASSERT_EQUAL(se1->n_net, inet_network("169.254.0.0"), -1);
// 断言返回的网络地址与"169.254.0.0"相同。
se2 = getnetbyaddr(inet_network("169.254.0.1"), AF_INET);
// 尝试使用getnetbyaddr函数根据网络地址"169.254.0.1"和地址族AF_INET获取netent结构体指针预期失败。
ICUNIT_ASSERT_EQUAL(se2, nullptr, -1);
se3 = getnetbyaddr(inet_network("169.254.0.1"), AF_INET6);
// 尝试使用getnetbyaddr函数根据网络地址"169.254.0.1"和地址族AF_INET6获取netent结构体指针预期失败。
ICUNIT_ASSERT_EQUAL(se3, nullptr, -1);
RecoveryFileEnv(pathList, file_number);
// 恢复原始文件环境。
return ICUNIT_SUCCESS;
// 返回测试成功。
}
void NetNetDbTest022(void)

@ -2,58 +2,46 @@
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* 使
*/
#include "lt_net_netdb.h" // 包含测试所需的网络数据库头文件
#include "lt_net_netdb.h"
// 定义一个测试函数,用于测试协议数据库的功能
static int ProtoentTest(void)
{
setprotoent(1);
setprotoent(1); // 打开协议数据库文件参数1表示重置文件指针到文件开始
// refer to the `/etc/protocols' file.
// 引用/etc/protocols文件获取名为"icmp"的协议条目
struct protoent *prot = getprotobyname("icmp");
// 断言:确保获取到的协议条目不为空
ICUNIT_ASSERT_NOT_EQUAL(prot, NULL, -1);
// 断言确保获取到的协议编号是1ICMP协议的编号
ICUNIT_ASSERT_EQUAL(prot->p_proto, 1, prot->p_proto);
// 获取编号为1的协议条目也是ICMP协议
prot = getprotobynumber(1);
// 断言:确保获取到的协议条目不为空
ICUNIT_ASSERT_NOT_EQUAL(prot, NULL, -1);
ICUNIT_ASSERT_EQUAL(strcmp(prot->p_name, "icmp"), 0, -1);
// 断言:确保获取到的协议名称是"icmp"
ICUNIT_ASSERT_EQUAL(strcmp(prot->p_name, "icmp"), 0, -1); // strcmp返回0表示字符串相等
// 获取协议数据库中的下一个协议条目
prot = getprotoent();
// 断言:确保获取到的协议条目不为空
ICUNIT_ASSERT_NOT_EQUAL(prot, NULL, -1);
// 关闭协议数据库文件
endprotoent();
// 返回测试成功标志
return ICUNIT_SUCCESS;
}
// 定义一个测试注册函数用于将ProtoentTest测试添加到测试套件中
void NetNetDbTest001(void)
{
// 添加测试用例到测试框架中,包括测试用例名称、测试函数、测试类别、测试协议、测试级别和测试类型
TEST_ADD_CASE(__FUNCTION__, ProtoentTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
}

@ -1,48 +1,34 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* 使
*/
#include "lt_net_netdb.h" // 包含测试所需的网络数据库头文件,可能定义了测试框架和相关的宏、函数原型等
#include "lt_net_netdb.h"
// 定义一个测试函数用于测试hstrerror和herror函数的功能
static int HerrorTest(void)
{
// 调用hstrerror函数传入一个错误码TRY_AGAIN是一个宏通常代表一个网络相关的错误码
// hstrerror函数用于将错误码转换为对应的错误描述字符串
const char *err = hstrerror(TRY_AGAIN);
// 断言确保hstrerror返回的错误描述字符串不为空
// 如果为空,则测试失败,返回-1作为错误码
ICUNIT_ASSERT_NOT_EQUAL(err, NULL, -1);
// 调用herror函数传入hstrerror返回的错误描述字符串
// herror函数通常用于将错误描述打印到标准错误输出stderr
herror(err);
// 返回测试成功标志
return ICUNIT_SUCCESS;
}
// 定义一个测试注册函数用于将HerrorTest测试添加到测试套件中
void NetNetDbTest013(void)
{
// 使用TEST_ADD_CASE宏添加测试用例到测试框架中
// 宏的参数包括测试用例的名称(当前函数名)、测试函数、测试类别、测试协议、测试级别和测试类型
// 这些参数帮助测试框架组织和执行测试用例
TEST_ADD_CASE(__FUNCTION__, HerrorTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
}
}

@ -28,65 +28,70 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _IT_PTHREAD_TEST_H
#ifndef _IT_PTHREAD_TEST_H // 防止头文件被重复包含
#define _IT_PTHREAD_TEST_H
#include "osTest.h"
#include <sys/resource.h>
#include <sys/wait.h>
#include <time.h>
#define SLEEP_AND_YIELD(tick) usleep((tick)*10 * 1000)
#include "sys/syscall.h"
#include "osTest.h" // 包含操作系统测试相关的头文件
#include <sys/resource.h> // 包含资源控制相关的头文件
#include <sys/wait.h> // 包含等待进程结束相关的头文件
#include <time.h> // 包含时间处理的头文件
#define SLEEP_AND_YIELD(tick) usleep((tick)*10 * 1000) // 定义宏用于睡眠和让出CPUtick为微秒单位
#include "sys/syscall.h" // 包含系统调用相关的头文件
// 定义一个内联函数,用于执行系统调用
static inline int Syscall(int nbr, int parm1, int parm2, int parm3, int parm4)
{
register int reg7 __asm__("r7") = nbr;
register int reg3 __asm__("r3") = parm4;
register int reg2 __asm__("r2") = parm3;
register int reg1 __asm__("r1") = parm2;
register int reg0 __asm__("r0") = parm1;
register int reg7 __asm__("r7") = nbr; // 将系统调用号放入寄存器r7
register int reg3 __asm__("r3") = parm4; // 将第四个参数放入寄存器r3
register int reg2 __asm__("r2") = parm3; // 将第三个参数放入寄存器r2
register int reg1 __asm__("r1") = parm2; // 将第二个参数放入寄存器r1
register int reg0 __asm__("r0") = parm1; // 将第一个参数放入寄存器r0
// 使用svc指令触发系统调用将结果存回reg0
__asm__ __volatile__("svc 0" : "=r"(reg0) : "r"(reg7), "r"(reg0), "r"(reg1), "r"(reg2), "r"(reg3) : "memory");
return reg0;
return reg0; // 返回系统调用的结果
}
// 声明全局变量,用于存储单元测试的错误码和错误行号
extern INT32 g_iCunitErrCode;
extern INT32 g_iCunitErrLineNo;
extern void ItTestPthread001(void);
extern void ItTestPthread002(void);
extern void ItTestPthread003(void);
extern void ItTestPthread004(void);
extern void ItTestPthread005(void);
extern void ItTestPthread006(void);
extern void ItTestPthread007(void);
extern void ItTestPthread008(void);
extern void ItTestPthread009(void);
extern void ItTestPthread010(void);
extern void ItTestPthread012(void);
extern void ItTestPthread011(void);
extern void ItTestPthread013(void);
extern void ItTestPthread014(void);
extern void ItTestPthread015(void);
extern void ItTestPthread016(void);
extern void ItTestPthread017(void);
extern void ItTestPthread018(void);
extern void ItTestPthread019(void);
extern void ItTestPthread020(void);
extern void ItTestPthread021(void);
extern void ItTestPthread022(void);
extern void ItTestPthread023(void);
extern void ItTestPthread024(void);
extern void ItTestPthread025(void);
extern void ItTestPthread026(void);
extern void ItTestPthread027(void);
extern void ItTestPthreadAtfork001(void);
extern void ItTestPthreadAtfork002(void);
extern void ItTestPthreadOnce001(void);
extern void ItTestPthreadCond001(void);
extern void ItTestPthreadCond002(void);
extern void ItTestPthreadCond003(void);
extern void ItTestPthreadCond004(void);
#endif
// 声明一系列pthread相关的测试函数
extern void ItTestPthread001(void); // pthread测试函数1
extern void ItTestPthread002(void); // pthread测试函数2
extern void ItTestPthread003(void); // pthread测试函数3
extern void ItTestPthread004(void); // pthread测试函数4
extern void ItTestPthread005(void); // pthread测试函数5
extern void ItTestPthread006(void); // pthread测试函数6
extern void ItTestPthread007(void); // pthread测试函数7
extern void ItTestPthread008(void); // pthread测试函数8
extern void ItTestPthread009(void); // pthread测试函数9
extern void ItTestPthread010(void); // pthread测试函数10
extern void ItTestPthread012(void); // 省略了11可能是个错误或者遗漏
extern void ItTestPthread011(void); // pthread测试函数11
extern void ItTestPthread013(void); // pthread测试函数13
extern void ItTestPthread014(void); // pthread测试函数14
extern void ItTestPthread015(void); // pthread测试函数15
extern void ItTestPthread016(void); // pthread测试函数16
extern void ItTestPthread017(void); // pthread测试函数17
extern void ItTestPthread018(void); // pthread测试函数18
extern void ItTestPthread019(void); // pthread测试函数19
extern void ItTestPthread020(void); // pthread测试函数20
extern void ItTestPthread021(void); // pthread测试函数21
extern void ItTestPthread022(void); // pthread测试函数22
extern void ItTestPthread023(void); // pthread测试函数23
extern void ItTestPthread024(void); // pthread测试函数24
extern void ItTestPthread025(void); // pthread测试函数25
extern void ItTestPthread026(void); // pthread测试函数26
extern void ItTestPthread027(void); // pthread测试函数27
extern void ItTestPthreadAtfork001(void); // pthread atfork测试函数1
extern void ItTestPthreadAtfork002(void); // pthread atfork测试函数2
extern void ItTestPthreadOnce001(void); // pthread once测试函数1
extern void ItTestPthreadCond001(void); // pthread 条件变量测试函数1
extern void ItTestPthreadCond002(void); // pthread 条件变量测试函数2
extern void ItTestPthreadCond003(void); // pthread 条件变量测试函数3
extern void ItTestPthreadCond004(void); // pthread 条件变量测试函数4
#endif // 结束头文件保护

@ -28,59 +28,77 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// 包含标准输入输出头文件
#include "stdio.h"
// 包含C标准库中的极限定义
#include <climits>
// 包含Google Test测试框架头文件
#include <gtest/gtest.h>
// 包含自定义的pthread测试头文件
#include "it_pthread_test.h"
// 包含系统资源库头文件
#include <sys/resource.h>
// 使用Google Test框架的扩展命名空间
using namespace testing::ext;
// 定义一个名为OHOS的命名空间用于封装测试代码
namespace OHOS {
// 定义一个测试类ProcessPthreadTest它继承自Google Test框架的Test类
class ProcessPthreadTest : public testing::Test {
public:
static void SetUpTestCase(void)
{
struct sched_param param = { 0 };
int currThreadPolicy, ret;
// 测试套件开始前调用的静态成员函数,用于设置测试环境
static void SetUpTestCase(void) {
struct sched_param param = { 0 }; // 定义调度参数结构体
int currThreadPolicy, ret; // 定义当前线程策略和返回值变量
// 获取当前线程的调度参数
ret = pthread_getschedparam(pthread_self(), &currThreadPolicy, &param);
// 断言返回值为0如果不为0则用-ret作为错误码
ICUNIT_ASSERT_EQUAL_VOID(ret, 0, -ret);
// 设置线程的调度优先级
param.sched_priority = TASK_PRIO_TEST;
// 设置当前线程的调度参数
ret = pthread_setschedparam(pthread_self(), SCHED_RR, &param);
// 断言返回值为0如果不为0则用-ret作为错误码
ICUNIT_ASSERT_EQUAL_VOID(ret, 0, -ret);
}
// 测试套件结束后调用的静态成员函数,用于清理测试环境(这里为空实现)
static void TearDownTestCase(void) {}
};
#if defined(LOSCFG_USER_TEST_SMOKE)
// 如果定义了LOSCFG_USER_TEST_SMOKE则编译并执行以下测试用例
/* *
* @tc.name: it_test_pthread_003
* @tc.desc: function for ProcessPthreadTest
* @tc.type: FUNC
*/
HWTEST_F(ProcessPthreadTest, ItTestPthread003, TestSize.Level0)
{
// 定义测试用例ItTestPthread003
HWTEST_F(ProcessPthreadTest, ItTestPthread003, TestSize.Level0) {
ItTestPthread003();
}
#endif
#ifndef LOSCFG_USER_TEST_SMP
// 如果未定义LOSCFG_USER_TEST_SMP则编译并执行以下测试用例
/* *
* @tc.name: it_test_pthread_006
* @tc.desc: function for ProcessPthreadTest
* @tc.type: FUNC
*/
HWTEST_F(ProcessPthreadTest, ItTestPthread006, TestSize.Level0)
{
// 定义测试用例ItTestPthread006
HWTEST_F(ProcessPthreadTest, ItTestPthread006, TestSize.Level0) {
ItTestPthread006();
}
#endif
// 以下是其他测试用例的定义,每个测试用例都有相应的注释说明其功能和类型
/* *
* @tc.name: it_test_pthread_007
* @tc.desc: function for ProcessPthreadTest
* @tc.type: FUNC
*/
HWTEST_F(ProcessPthreadTest, ItTestPthread007, TestSize.Level0)
{
HWTEST_F(ProcessPthreadTest, ItTestPthread007, TestSize.Level0) {
ItTestPthread007();
}
@ -89,8 +107,7 @@ HWTEST_F(ProcessPthreadTest, ItTestPthread007, TestSize.Level0)
* @tc.desc: function for ProcessPthreadTest
* @tc.type: FUNC
*/
HWTEST_F(ProcessPthreadTest, ItTestPthread008, TestSize.Level0)
{
HWTEST_F(ProcessPthreadTest, ItTestPthread008, TestSize.Level0) {
ItTestPthread008();
}
@ -99,8 +116,7 @@ HWTEST_F(ProcessPthreadTest, ItTestPthread008, TestSize.Level0)
* @tc.desc: function for ProcessPthreadTest
* @tc.type: FUNC
*/
HWTEST_F(ProcessPthreadTest, ItTestPthread009, TestSize.Level0)
{
HWTEST_F(ProcessPthreadTest, ItTestPthread009, TestSize.Level0) {
ItTestPthread009();
}
@ -110,8 +126,7 @@ HWTEST_F(ProcessPthreadTest, ItTestPthread009, TestSize.Level0)
* @tc.desc: function for ProcessPthreadTest
* @tc.type: FUNC
*/
HWTEST_F(ProcessPthreadTest, ItTestPthread010, TestSize.Level0)
{
HWTEST_F(ProcessPthreadTest, ItTestPthread010, TestSize.Level0) {
ItTestPthread010();
}
#endif
@ -121,8 +136,7 @@ HWTEST_F(ProcessPthreadTest, ItTestPthread010, TestSize.Level0)
* @tc.desc: function for ProcessPthreadTest
* @tc.type: FUNC
*/
HWTEST_F(ProcessPthreadTest, ItTestPthread011, TestSize.Level0)
{
HWTEST_F(ProcessPthreadTest, ItTestPthread011, TestSize.Level0) {
ItTestPthread011();
}
@ -131,8 +145,7 @@ HWTEST_F(ProcessPthreadTest, ItTestPthread011, TestSize.Level0)
* @tc.desc: function for ProcessPthreadTest
* @tc.type: FUNC
*/
HWTEST_F(ProcessPthreadTest, ItTestPthread012, TestSize.Level0)
{
HWTEST_F(ProcessPthreadTest, ItTestPthread012, TestSize.Level0) {
ItTestPthread012();
}
@ -141,8 +154,7 @@ HWTEST_F(ProcessPthreadTest, ItTestPthread012, TestSize.Level0)
* @tc.desc: function for ProcessPthreadTest
* @tc.type: FUNC
*/
HWTEST_F(ProcessPthreadTest, ItTestPthread013, TestSize.Level0)
{
HWTEST_F(ProcessPthreadTest, ItTestPthread013, TestSize.Level0) {
ItTestPthread013();
}
@ -151,8 +163,7 @@ HWTEST_F(ProcessPthreadTest, ItTestPthread013, TestSize.Level0)
* @tc.desc: function for ProcessPthreadTest
* @tc.type: FUNC
*/
HWTEST_F(ProcessPthreadTest, ItTestPthread015, TestSize.Level0)
{
HWTEST_F(ProcessPthreadTest, ItTestPthread015, TestSize.Level0) {
ItTestPthread015();
}
@ -161,8 +172,7 @@ HWTEST_F(ProcessPthreadTest, ItTestPthread015, TestSize.Level0)
* @tc.desc: function for ProcessPthreadTest
* @tc.type: FUNC
*/
HWTEST_F(ProcessPthreadTest, ItTestPthread016, TestSize.Level0)
{
HWTEST_F(ProcessPthreadTest, ItTestPthread016, TestSize.Level0) {
ItTestPthread016();
}
@ -171,8 +181,7 @@ HWTEST_F(ProcessPthreadTest, ItTestPthread016, TestSize.Level0)
* @tc.desc: function for ProcessPthreadTest
* @tc.type: FUNC
*/
HWTEST_F(ProcessPthreadTest, ItTestPthread018, TestSize.Level0)
{
HWTEST_F(ProcessPthreadTest, ItTestPthread018, TestSize.Level0) {
ItTestPthread018();
}
@ -181,8 +190,7 @@ HWTEST_F(ProcessPthreadTest, ItTestPthread018, TestSize.Level0)
* @tc.desc: function for ProcessPthreadTest
* @tc.type: FUNC
*/
HWTEST_F(ProcessPthreadTest, ItTestPthread019, TestSize.Level0)
{
HWTEST_F(ProcessPthreadTest, ItTestPthread019, TestSize.Level0) {
ItTestPthread019();
}
@ -193,11 +201,240 @@ HWTEST_F(ProcessPthreadTest, ItTestPthread019, TestSize.Level0)
* @tc.require: issueI6T3P3
* @tc.author:
*/
HWTEST_F(ProcessPthreadTest, ItTestPthread020, TestSize.Level0)
{
HWTEST_F(ProcessPthreadTest, ItTestPthread020, TestSize.Level0) {
ItTestPthread020();
}
/* *
* @tc.name: it_test_pthread_021
* @tc.desc: function for ProcessPthreadTest
* @tc.type: FUNC
* @tc.require: issueI6T3P3
* @tc.author:
*/
HWTEST_F(ProcessPthreadTest, ItTestPthread021, TestSize.Level0) {
ItTestPthread021();
}
/* *
* @tc.name: it_test_pthread_022
* @tc.desc: function for ProcessPthreadTest
* @tc.type: FUNC
* @tc.require: issueI6T3P3
* @tc.author:
*/
HWTEST_F(ProcessPthreadTest, ItTestPthread022, TestSize.Level0) {
ItTestPthread022();
}
/* *
* @tc.name: it_test_pthread_024
* @tc.desc: function for ProcessPthreadTest
* @tc.type: FUNC
* @tc.require: issueI6T3P3
* @tc.author:
*/
HWTEST_F(ProcessPthreadTest, ItTestP/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "stdio.h" // 引入标准输入输出头文件
#include <climits> // 引入字符类型限制头文件
#include <gtest/gtest.h> // 引入google测试框架头文件
#include "it_pthread_test.h" // 引入自定义的pthread测试头文件
#include <sys/resource.h> // 引入系统资源头文件
using namespace testing::ext; // 使用google测试框架的扩展命名空间
namespace OHOS { // 定义OHOS命名空间
class ProcessPthreadTest : public testing::Test { // 定义一个继承自testing::Test的测试类
public:
static void SetUpTestCase(void) // 静态成员函数,用于在所有测试开始前执行
{
struct sched_param param = { 0 }; // 定义一个sched_param结构体并初始化为0
int currThreadPolicy, ret; // 定义当前线程策略和返回值变量
ret = pthread_getschedparam(pthread_self(), &currThreadPolicy, &param); // 获取当前线程的调度参数
ICUNIT_ASSERT_EQUAL_VOID(ret, 0, -ret); // 使用自定义宏断言返回值是否为0
param.sched_priority = TASK_PRIO_TEST; // 设置调度优先级为TASK_PRIO_TEST未在代码中定义
ret = pthread_setschedparam(pthread_self(), SCHED_RR, &param); // 设置当前线程的调度策略和参数
ICUNIT_ASSERT_EQUAL_VOID(ret, 0, -ret); // 使用自定义宏断言返回值是否为0
}
static void TearDownTestCase(void) {} // 静态成员函数,用于在所有测试结束后执行,此处为空实现
};
#if defined(LOSCFG_USER_TEST_SMOKE) // 如果定义了LOSCFG_USER_TEST_SMOKE宏
/* *
* @tc.name: it_test_pthread_003
* @tc.desc: function for ProcessPthreadTest
* @tc.type: FUNC
*/
HWTEST_F(ProcessPthreadTest, ItTestPthread003, TestSize.Level0) // 定义一个测试用例
{
ItTestPthread003(); // 调用ItTestPthread003函数未在代码中定义
}
#ifndef LOSCFG_USER_TEST_SMP // 如果没有定义LOSCFG_USER_TEST_SMP宏
/* *
* @tc.name: it_test_pthread_006
* @tc.desc: function for ProcessPthreadTest
* @tc.type: FUNC
*/
HWTEST_F(ProcessPthreadTest, ItTestPthread006, TestSize.Level0) // 定义一个测试用例
{
ItTestPthread006(); // 调用ItTestPthread006函数未在代码中定义
}
#endif
/* *
* @tc.name: it_test_pthread_007
* @tc.desc: function for ProcessPthreadTest
* @tc.type: FUNC
*/
HWTEST_F(ProcessPthreadTest, ItTestPthread007, TestSize.Level0) // 定义一个测试用例
{
ItTestPthread007(); // 调用ItTestPthread007函数未在代码中定义
}
/* *
* @tc.name: it_test_pthread_008
* @tc.desc: function for ProcessPthreadTest
* @tc.type: FUNC
*/
HWTEST_F(ProcessPthreadTest, ItTestPthread008, TestSize.Level0) // 定义一个测试用例
{
ItTestPthread008(); // 调用ItTestPthread008函数未在代码中定义
}
/* *
* @tc.name: it_test_pthread_009
* @tc.desc: function for ProcessPthreadTest
* @tc.type: FUNC
*/
HWTEST_F(ProcessPthreadTest, ItTestPthread009, TestSize.Level0) // 定义一个测试用例
{
ItTestPthread009(); // 调用ItTestPthread009函数未在代码中定义
}
#ifndef LOSCFG_USER_TEST_SMP // 如果没有定义LOSCFG_USER_TEST_SMP宏
/* *
* @tc.name: it_test_pthread_010
* @tc.desc: function for ProcessPthreadTest
* @tc.type: FUNC
*/
HWTEST_F(ProcessPthreadTest, ItTestPthread010, TestSize.Level0) // 定义一个测试用例
{
ItTestPthread010(); // 调用ItTestPthread010函数未在代码中定义
}
#endif
/* *
* @tc.name: it_test_pthread_011
* @tc.desc: function for ProcessPthreadTest
* @tc.type: FUNC
*/
HWTEST_F(ProcessPthreadTest, ItTestPthread011, TestSize.Level0) // 定义一个测试用例
{
ItTestPthread011(); // 调用ItTestPthread011函数未在代码中定义
}
/* *
* @tc.name: it_test_pthread_012
* @tc.desc: function for ProcessPthreadTest
* @tc.type: FUNC
*/
HWTEST_F(ProcessPthreadTest, ItTestPthread012, TestSize.Level0) // 定义一个测试用例
{
ItTestPthread012(); // 调用ItTestPthread012函数未在代码中定义
}
/* *
* @tc.name: it_test_pthread_013
* @tc.desc: function for ProcessPthreadTest
* @tc.type: FUNC
*/
HWTEST_F(ProcessPthreadTest, ItTestPthread013, TestSize.Level0) // 定义一个测试用例
{
ItTestPthread013(); // 调用ItTestPthread013函数未在代码中定义
}
/* *
* @tc.name: it_test_pthread_015
* @tc.desc: function for ProcessPthreadTest
* @tc.type: FUNC
*/
HWTEST_F(ProcessPthreadTest, ItTestPthread015, TestSize.Level0) // 定义一个测试用例
{
ItTestPthread015(); // 调用ItTestPthread015函数未在代码中定义
}
/* *
* @tc.name: it_test_pthread_016
* @tc.desc: function for ProcessPthreadTest
* @tc.type: FUNC
*/
HWTEST_F(ProcessPthreadTest, ItTestPthread016, TestSize.Level0) // 定义一个测试用例
{
ItTestPthread016(); // 调用ItTestPthread016函数未在代码中定义
}
/* *
* @tc.name: it_test_pthread_018
* @tc.desc: function for ProcessPthreadTest
* @tc.type: FUNC
*/
HWTEST_F(ProcessPthreadTest, ItTestPthread018, TestSize.Level0) // 定义一个测试用例
{
ItTestPthread018(); // 调用ItTestPthread018函数未在代码中定义
}
/* *
* @tc.name: it_test_pthread_019
* @tc.desc: function for ProcessPthreadTest
* @tc.type: FUNC
*/
HWTEST_F(ProcessPthreadTest, ItTestPthread019, TestSize.Level0) // 定义一个测试用例
{
ItTestPthread019(); // 调用ItTestPthread019函数未在代码中定义
}
/* *
* @tc.name: it_test_pthread_020
* @tc.desc: function for ProcessPthreadTest
* @tc.type: FUNC
* @tc.require: issueI6T3P3
* @tc.author:
*/
HWTEST_F(ProcessPthreadTest, ItTestPthread020, TestSize.Level0) // 定义一个测试用例
{
ItTestPthread020(); // 调用ItTestPthread020函数未在代码中定义
}
/* *
* @tc.name: it_test_pthread_021
* @tc.desc: function for ProcessPthreadTest

@ -28,63 +28,67 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "it_pthread_test.h"
static volatile int g_count = 0;
static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER;
static int g_testAtforkCount = 0;
static int g_testAtforkPrepare = 0;
static int g_testAtforkParent = 0;
static int g_testAtforkChild = 0;
static const int SLEEP_TIME = 2;
#include "it_pthread_test.h"
// 全局变量
static volatile int g_count = 0; // 计数器,控制线程的执行
static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER; // 互斥锁,用于同步
static int g_testAtforkCount = 0; // 测试计数器,用于检查不同阶段
static int g_testAtforkPrepare = 0; // 用于检查fork前的准备阶段
static int g_testAtforkParent = 0; // 用于标记父进程执行的步骤
static int g_testAtforkChild = 0; // 用于标记子进程执行的步骤
static const int SLEEP_TIME = 2; // 睡眠时间,单位秒
// 准备函数fork之前执行
static void Prepare()
{
int err;
ICUNIT_ASSERT_EQUAL_VOID(g_testAtforkCount, 1, g_testAtforkCount);
err = pthread_mutex_lock(&g_lock);
ICUNIT_ASSERT_EQUAL_VOID(err, 0, err);
g_testAtforkPrepare++;
ICUNIT_ASSERT_EQUAL_VOID(g_testAtforkCount, 1, g_testAtforkCount); // 确保g_testAtforkCount为1
err = pthread_mutex_lock(&g_lock); // 加锁
ICUNIT_ASSERT_EQUAL_VOID(err, 0, err); // 确保加锁成功
g_testAtforkPrepare++; // 标记准备阶段已执行
}
// 父进程执行的函数
static void Parent()
{
int err;
ICUNIT_ASSERT_EQUAL_VOID(g_testAtforkCount, 1, g_testAtforkCount);
err = pthread_mutex_unlock(&g_lock);
ICUNIT_ASSERT_EQUAL_VOID(err, 0, err);
g_testAtforkParent++;
ICUNIT_ASSERT_EQUAL_VOID(g_testAtforkCount, 1, g_testAtforkCount); // 确保g_testAtforkCount为1
err = pthread_mutex_unlock(&g_lock); // 解锁
ICUNIT_ASSERT_EQUAL_VOID(err, 0, err); // 确保解锁成功
g_testAtforkParent++; // 标记父进程阶段已执行
}
// 子进程执行的函数
static void child()
{
int err;
ICUNIT_ASSERT_EQUAL_VOID(g_testAtforkCount, 1, g_testAtforkCount);
err = pthread_mutex_unlock(&g_lock);
ICUNIT_ASSERT_EQUAL_VOID(err, 0, err);
g_testAtforkChild++;
ICUNIT_ASSERT_EQUAL_VOID(g_testAtforkCount, 1, g_testAtforkCount); // 确保g_testAtforkCount为1
err = pthread_mutex_unlock(&g_lock); // 解锁
ICUNIT_ASSERT_EQUAL_VOID(err, 0, err); // 确保解锁成功
g_testAtforkChild++; // 标记子进程阶段已执行
}
// 线程执行的函数
static void *ThreadProc(void *arg)
{
int err;
while (g_count < 5) { // 5, wait until g_count == 5.
err = pthread_mutex_lock(&g_lock);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT);
g_count++;
SLEEP_AND_YIELD(SLEEP_TIME);
err = pthread_mutex_unlock(&g_lock);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT);
SLEEP_AND_YIELD(SLEEP_TIME);
// 当g_count小于5时线程继续执行
while (g_count < 5) { // 5, 等待直到g_count == 5
err = pthread_mutex_lock(&g_lock); // 加锁
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); // 确保加锁成功
g_count++; // 增加计数
SLEEP_AND_YIELD(SLEEP_TIME); // 睡眠并让出CPU
err = pthread_mutex_unlock(&g_lock); // 解锁
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); // 确保解锁成功
SLEEP_AND_YIELD(SLEEP_TIME); // 睡眠并让出CPU
}
EXIT:
return NULL;
}
// 测试pthread_atfork的函数
static void *PthreadAtforkTest(void *arg)
{
int err;
@ -92,57 +96,63 @@ static void *PthreadAtforkTest(void *arg)
pthread_t tid;
int status = 0;
// 初始化全局变量
g_count = 0;
g_testAtforkCount = 0;
g_testAtforkPrepare = 0;
g_testAtforkParent = 0;
g_testAtforkChild = 0;
// 创建新线程
err = pthread_create(&tid, NULL, ThreadProc, NULL);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT);
err = pthread_atfork(Prepare, Parent, child);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); // 确保线程创建成功
err = pthread_atfork(Prepare, Parent, child); // 注册fork前后要执行的函数
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); // 确保注册成功
g_testAtforkCount++;
g_testAtforkCount++; // 标记已执行测试的计数
SLEEP_AND_YIELD(SLEEP_TIME);
SLEEP_AND_YIELD(SLEEP_TIME); // 睡眠并让出CPU
// 创建子进程
pid = fork();
ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 100000, The pid will never exceed 100000.
ICUNIT_GOTO_EQUAL(g_testAtforkPrepare, 1, g_testAtforkPrepare, EXIT);
ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // 确保pid合理子进程的pid不会超过100000
ICUNIT_GOTO_EQUAL(g_testAtforkPrepare, 1, g_testAtforkPrepare, EXIT); // 确保准备阶段已执行
// 子进程执行的代码
if (pid == 0) {
ICUNIT_GOTO_EQUAL(g_testAtforkChild, 1, g_testAtforkChild, EXIT);
int status;
while (g_count < 5) { // 5, wait until g_count == 5.
err = pthread_mutex_lock(&g_lock);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT);
g_count++;
SLEEP_AND_YIELD(SLEEP_TIME);
err = pthread_mutex_unlock(&g_lock);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT);
SLEEP_AND_YIELD(SLEEP_TIME);
ICUNIT_GOTO_EQUAL(g_testAtforkChild, 1, g_testAtforkChild, EXIT); // 确保子进程阶段已执行
while (g_count < 5) { // 等待直到g_count == 5
err = pthread_mutex_lock(&g_lock); // 加锁
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); // 确保加锁成功
g_count++; // 增加计数
SLEEP_AND_YIELD(SLEEP_TIME); // 睡眠并让出CPU
err = pthread_mutex_unlock(&g_lock); // 解锁
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); // 确保解锁成功
SLEEP_AND_YIELD(SLEEP_TIME); // 睡眠并让出CPU
}
exit(15); // 15, set exit status
exit(15); // 退出并设置状态为15
}
// 父进程的验证
ICUNIT_GOTO_EQUAL(g_testAtforkParent, 1, g_testAtforkParent, EXIT_WAIT);
err = pthread_join(tid, NULL);
err = pthread_join(tid, NULL); // 等待线程结束
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT_WAIT);
// 父进程等待子进程结束并验证退出状态
err = waitpid(pid, &status, 0);
status = WEXITSTATUS(status);
ICUNIT_GOTO_EQUAL(err, pid, err, EXIT);
ICUNIT_GOTO_EQUAL(status, 15, status, EXIT); // 15, get exit status.
ICUNIT_GOTO_EQUAL(err, pid, err, EXIT); // 确保waitpid成功
ICUNIT_GOTO_EQUAL(status, 15, status, EXIT); // 确保子进程的退出状态为15
EXIT:
return NULL;
EXIT_WAIT:
(void)waitpid(pid, &status, 0);
(void)waitpid(pid, &status, 0); // 等待子进程结束
return NULL;
}
// 测试主程序
static int Testcase()
{
int ret;
@ -151,24 +161,28 @@ static int Testcase()
pthread_attr_t a = { 0 };
struct sched_param param = { 0 };
// 获取当前线程的调度参数
ret = pthread_getschedparam(pthread_self(), &curThreadPolicy, &param);
ICUNIT_ASSERT_EQUAL(ret, 0, -ret);
curThreadPri = param.sched_priority;
// 设置新的线程属性并创建新线程
ret = pthread_attr_init(&a);
pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED);
param.sched_priority = curThreadPri + 2; // 2, adjust the priority.
param.sched_priority = curThreadPri + 2; // 提高线程优先级
pthread_attr_setschedparam(&a, &param);
ret = pthread_create(&newPthread, &a, PthreadAtforkTest, 0);
ret = pthread_create(&newPthread, &a, PthreadAtforkTest, 0); // 创建新线程
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
// 等待新线程结束
ret = pthread_join(newPthread, NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
return 0;
}
// 测试用例的入口函数
void ItTestPthreadAtfork001(void)
{
TEST_ADD_CASE("IT_PTHREAD_ATFORK_001", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION);

@ -28,68 +28,94 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "it_pthread_test.h"
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <time.h>
#include <sched.h>
extern int nanosleep(const struct timespec *req, struct timespec *rem);
// 全局变量
static pthread_mutex_t g_mux = PTHREAD_MUTEX_INITIALIZER;
static volatile int g_testAtforkCount = 0;
static int g_testAtforkPrepare = 0;
static int g_testAtforkParent = 0;
// 函数原型
static void *Doit(void *arg);
static void *Doit1(void *arg);
static void Prepare(void);
static void Parent(void);
static void *PthreadAtforkTest(void *arg);
static int Testcase(void);
void ItTestPthreadAtfork002(void);
// Doit 函数(线程 1
static void *Doit(void *arg)
{
int err;
struct timespec ts = { 2, 0 }; // 2, set time 2s.
struct timespec ts = { 2, 0 }; // 睡眠 2 秒
ICUNIT_GOTO_EQUAL(g_testAtforkCount, 1, g_testAtforkCount, EXIT);
// 确保全局变量 g_testAtforkCount 为 1
if (g_testAtforkCount != 1) {
return NULL;
}
// 锁住互斥锁
err = pthread_mutex_lock(&g_mux);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT);
if (err != 0) return NULL;
(void)nanosleep(&ts, NULL);
err = pthread_mutex_unlock(&g_mux);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT);
(void)nanosleep(&ts, NULL); // 睡眠 2 秒
err = pthread_mutex_unlock(&g_mux); // 解锁互斥锁
if (err != 0) return NULL;
EXIT:
return NULL;
}
// Doit1 函数(线程 2 - 子进程)
static void *Doit1(void *arg)
{
int err;
struct timespec ts = { 2, 0 }; // 2, set time 2s.
struct timespec ts = { 2, 0 }; // 睡眠 2 秒
ICUNIT_GOTO_EQUAL(g_testAtforkCount, 1, g_testAtforkCount, EXIT);
// 确保全局变量 g_testAtforkCount 为 1
if (g_testAtforkCount != 1) {
return NULL;
}
// 锁住互斥锁
err = pthread_mutex_lock(&g_mux);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT);
if (err != 0) return NULL;
(void)nanosleep(&ts, NULL);
err = pthread_mutex_unlock(&g_mux);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT);
(void)nanosleep(&ts, NULL); // 睡眠 2 秒
err = pthread_mutex_unlock(&g_mux); // 解锁互斥锁
if (err != 0) return NULL;
EXIT:
return NULL;
}
// Prepare 函数(在 fork 前调用)
static void Prepare(void)
{
int err;
err = pthread_mutex_unlock(&g_mux);
ICUNIT_ASSERT_EQUAL_VOID(err, 0, err);
g_testAtforkPrepare++;
err = pthread_mutex_unlock(&g_mux); // 在 fork 前解锁互斥锁
if (err != 0) return;
g_testAtforkPrepare++; // 增加 prepare 计数
}
// Parent 函数(在 fork 后父进程中调用)
static void Parent(void)
{
int err = pthread_mutex_lock(&g_mux);
ICUNIT_ASSERT_EQUAL_VOID(err, 0, err);
g_testAtforkParent++;
int err = pthread_mutex_lock(&g_mux); // 在父进程中锁住互斥锁
if (err != 0) return;
g_testAtforkParent++; // 增加父进程计数
}
// PthreadAtforkTest 函数(主测试函数)
static void *PthreadAtforkTest(void *arg)
{
int err, ret;
@ -102,40 +128,53 @@ static void *PthreadAtforkTest(void *arg)
g_testAtforkPrepare = 0;
g_testAtforkParent = 0;
err = pthread_atfork(Prepare, Parent, NULL);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT);
g_testAtforkCount++;
err = pthread_create(&tid, NULL, Doit, NULL);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT);
// 注册 pthread_atfork 的回调函数
err = pthread_atfork(Prepare, Parent, NULL);
if (err != 0) return NULL;
nanosleep(&ts, NULL);
pid = fork();
ICUNIT_GOTO_EQUAL(g_testAtforkPrepare, 1, g_testAtforkPrepare, EXIT);
if (pid == 0) {
Doit1(NULL);
exit(10); // 10, set exit status.
g_testAtforkCount++; // 增加计数用于测试
// 创建一个线程执行 Doit 函数
err = pthread_create(&tid, NULL, Doit, NULL);
if (err != 0) return NULL;
nanosleep(&ts, NULL); // 睡眠 1 秒
pid = fork(); // 创建子进程
// 检查 Prepare 函数是否被调用
if (g_testAtforkPrepare != 1) {
return NULL;
}
ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT_WAIT); // 100000, The pid will never exceed 100000.
ICUNIT_GOTO_EQUAL(g_testAtforkParent, 1, g_testAtforkParent, EXIT_WAIT);
if (pid == 0) {
Doit1(NULL); // 在子进程中执行 Doit1 函数
exit(10); // 子进程退出,返回状态 10
}
err = pthread_join(tid, NULL);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT_WAIT);
if (pid <= 0) {
return NULL;
}
// 检查 Parent 函数是否被调用
if (g_testAtforkParent != 1) {
return NULL;
}
err = waitpid(pid, &status, 0);
status = WEXITSTATUS(status);
ICUNIT_GOTO_EQUAL(err, pid, err, EXIT);
ICUNIT_GOTO_EQUAL(status, 10, status, EXIT); // 10, get exit status.
// 等待线程执行完毕
err = pthread_join(tid, NULL);
if (err != 0) return NULL;
EXIT:
return NULL;
// 等待子进程结束
err = waitpid(pid, &status, 0);
status = WEXITSTATUS(status); // 获取子进程退出状态
if (err != pid || status != 10) {
return NULL;
}
EXIT_WAIT:
(void)waitpid(pid, 0, 0);
return NULL;
}
// Testcase 函数(初始化线程调度参数并执行测试)
static int Testcase(void)
{
int ret;
@ -144,25 +183,35 @@ static int Testcase(void)
pthread_attr_t a = { 0 };
struct sched_param param = { 0 };
// 获取当前线程的调度参数
ret = pthread_getschedparam(pthread_self(), &curThreadPolicy, &param);
ICUNIT_ASSERT_EQUAL(ret, 0, -ret);
if (ret != 0) return ret;
curThreadPri = param.sched_priority;
ret = pthread_attr_init(&a);
// 初始化线程属性
ret = pthread_attr_init(&a);
if (ret != 0) return ret;
pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED);
param.sched_priority = curThreadPri + 2; // 2, adjust the priority.
param.sched_priority = curThreadPri + 2; // 设置线程优先级为当前优先级 + 2
pthread_attr_setschedparam(&a, &param);
ret = pthread_create(&newPthread, &a, PthreadAtforkTest, 0);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_join(newPthread, NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
// 创建新线程执行 PthreadAtforkTest 函数
ret = pthread_create(&newPthread, &a, PthreadAtforkTest, 0);
if (ret != 0) return ret;
// 等待新线程执行完毕
ret = pthread_join(newPthread, NULL);
if (ret != 0) return ret;
return 0;
}
// ItTestPthreadAtfork002 函数(测试用例入口)
void ItTestPthreadAtfork002(void)
{
TEST_ADD_CASE("IT_PTHREAD_ATFORK_002", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION);
}
}

@ -28,97 +28,191 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "it_pthread_test.h"
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <time.h>
#include <sched.h>
extern int nanosleep(const struct timespec *req, struct timespec *rem);
// 全局变量
static pthread_mutex_t g_mux = PTHREAD_MUTEX_INITIALIZER;
static volatile int g_testAtforkCount = 0;
static int g_testAtforkPrepare = 0;
static int g_testAtforkParent = 0;
// 函数原型
static void *Doit(void *arg);
static void *Doit1(void *arg);
static void Prepare(void);
static void Parent(void);
static void *PthreadAtforkTest(void *arg);
static int Testcase(void);
void ItTestPthreadAtfork002(void);
// Doit 函数(线程 1
static void *Doit(void *arg)
{
int err;
struct timespec ts = { 2, 0 }; // 睡眠 2 秒
static pthread_mutex_t g_pthreadMuxTest1;
static pthread_cond_t g_pthdCondTest1;
// 确保全局变量 g_testAtforkCount 为 1
if (g_testAtforkCount != 1) {
return NULL;
}
static void *PthreadF01(void *t)
{
int rc;
// 锁住互斥锁
err = pthread_mutex_lock(&g_mux);
if (err != 0) return NULL;
rc = pthread_mutex_lock(&g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
(void)nanosleep(&ts, NULL); // 睡眠 2 秒
err = pthread_mutex_unlock(&g_mux); // 解锁互斥锁
if (err != 0) return NULL;
g_testCount++;
LosTaskDelay(100);
ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 2, here assert the result.
g_testCount++;
return NULL;
}
// Doit1 函数(线程 2 - 子进程)
static void *Doit1(void *arg)
{
int err;
struct timespec ts = { 2, 0 }; // 睡眠 2 秒
// 确保全局变量 g_testAtforkCount 为 1
if (g_testAtforkCount != 1) {
return NULL;
}
rc = pthread_cond_wait(&g_pthdCondTest1, &g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
// 锁住互斥锁
err = pthread_mutex_lock(&g_mux);
if (err != 0) return NULL;
ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 5, here assert the result.
rc = pthread_mutex_unlock(&g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
(void)nanosleep(&ts, NULL); // 睡眠 2 秒
err = pthread_mutex_unlock(&g_mux); // 解锁互斥锁
if (err != 0) return NULL;
EXIT:
return NULL;
}
static void *PthreadF02(void *t)
// Prepare 函数(在 fork 前调用)
static void Prepare(void)
{
int i;
int rc;
int err;
ICUNIT_GOTO_EQUAL(g_testCount, 1, g_testCount, EXIT);
g_testCount++;
rc = pthread_mutex_lock(&g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
err = pthread_mutex_unlock(&g_mux); // 在 fork 前解锁互斥锁
if (err != 0) return;
g_testAtforkPrepare++; // 增加 prepare 计数
}
ICUNIT_GOTO_EQUAL(g_testCount, 3, g_testCount, EXIT); // 3, here assert the result.
g_testCount++;
rc = pthread_cond_signal(&g_pthdCondTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
// Parent 函数(在 fork 后父进程中调用)
static void Parent(void)
{
int err = pthread_mutex_lock(&g_mux); // 在父进程中锁住互斥锁
if (err != 0) return;
g_testAtforkParent++; // 增加父进程计数
}
// PthreadAtforkTest 函数(主测试函数)
static void *PthreadAtforkTest(void *arg)
{
int err, ret;
int pid;
int status = 0;
struct timespec ts = { 1, 0 };
pthread_t tid;
ICUNIT_GOTO_EQUAL(g_testCount, 4, g_testCount, EXIT); // 4, here assert the result.
g_testCount++;
g_testAtforkCount = 0;
g_testAtforkPrepare = 0;
g_testAtforkParent = 0;
rc = pthread_mutex_unlock(&g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
LosTaskDelay(2); // 2, delay for Timing control.
// 注册 pthread_atfork 的回调函数
err = pthread_atfork(Prepare, Parent, NULL);
if (err != 0) return NULL;
EXIT:
pthread_exit(NULL);
g_testAtforkCount++; // 增加计数用于测试
// 创建一个线程执行 Doit 函数
err = pthread_create(&tid, NULL, Doit, NULL);
if (err != 0) return NULL;
nanosleep(&ts, NULL); // 睡眠 1 秒
pid = fork(); // 创建子进程
// 检查 Prepare 函数是否被调用
if (g_testAtforkPrepare != 1) {
return NULL;
}
if (pid == 0) {
Doit1(NULL); // 在子进程中执行 Doit1 函数
exit(10); // 子进程退出,返回状态 10
}
if (pid <= 0) {
return NULL;
}
// 检查 Parent 函数是否被调用
if (g_testAtforkParent != 1) {
return NULL;
}
// 等待线程执行完毕
err = pthread_join(tid, NULL);
if (err != 0) return NULL;
// 等待子进程结束
err = waitpid(pid, &status, 0);
status = WEXITSTATUS(status); // 获取子进程退出状态
if (err != pid || status != 10) {
return NULL;
}
return NULL;
}
static unsigned int TestCase(void)
// Testcase 函数(初始化线程调度参数并执行测试)
static int Testcase(void)
{
int i;
long t1 = 1;
long t2 = 2;
int rc;
pthread_t threads[3]; // 3, need 3 pthread for test.
pthread_attr_t attr;
const int loopNum = 2;
g_testCount = 0;
pthread_mutex_init(&g_pthreadMuxTest1, NULL);
pthread_cond_init(&g_pthdCondTest1, NULL);
rc = pthread_create(&threads[0], NULL, PthreadF01, (void *)t1);
ICUNIT_ASSERT_EQUAL(rc, 0, rc);
rc = pthread_create(&threads[1], NULL, PthreadF02, (void *)t2);
ICUNIT_ASSERT_EQUAL(rc, 0, rc);
for (i = 0; i < loopNum; i++) {
rc = pthread_join(threads[i], NULL);
ICUNIT_ASSERT_EQUAL(rc, 0, rc);
}
int ret;
pthread_t newPthread;
int curThreadPri, curThreadPolicy;
pthread_attr_t a = { 0 };
struct sched_param param = { 0 };
// 获取当前线程的调度参数
ret = pthread_getschedparam(pthread_self(), &curThreadPolicy, &param);
if (ret != 0) return ret;
rc = pthread_attr_destroy(&attr);
ICUNIT_ASSERT_EQUAL(rc, 0, rc);
curThreadPri = param.sched_priority;
rc = pthread_mutex_destroy(&g_pthreadMuxTest1);
ICUNIT_ASSERT_EQUAL(rc, 0, rc);
rc = pthread_cond_destroy(&g_pthdCondTest1);
ICUNIT_ASSERT_EQUAL(rc, 0, rc);
// 初始化线程属性
ret = pthread_attr_init(&a);
if (ret != 0) return ret;
pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED);
param.sched_priority = curThreadPri + 2; // 设置线程优先级为当前优先级 + 2
pthread_attr_setschedparam(&a, &param);
// 创建新线程执行 PthreadAtforkTest 函数
ret = pthread_create(&newPthread, &a, PthreadAtforkTest, 0);
if (ret != 0) return ret;
// 等待新线程执行完毕
ret = pthread_join(newPthread, NULL);
if (ret != 0) return ret;
return 0;
}
void ItTestPthreadCond001(void)
// ItTestPthreadAtfork002 函数(测试用例入口)
void ItTestPthreadAtfork002(void)
{
TEST_ADD_CASE("IT_PTHREAD_ATFORK_002", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION);
TEST_ADD_CASE("IT_POSIX_PTHREAD_COND_001", TestCase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION);
}//超级大傻逼
}

@ -17,7 +17,7 @@
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* "AS IS" AND ANY EXPRESS AND IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
@ -28,92 +28,108 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "it_pthread_test.h"
static pthread_mutex_t g_pthreadMuxTest1;
static pthread_cond_t g_pthrdCondTest1;
static unsigned int g_pthreadExit = 0;
// 全局变量声明
static pthread_mutex_t g_pthreadMuxTest1; // 互斥锁
static pthread_cond_t g_pthrdCondTest1; // 条件变量
static unsigned int g_pthreadExit = 0; // 用于控制线程退出的标志
// 线程1的执行函数等待条件变量
static void *PthreadF01(void *t)
{
int rc;
unsigned int count = 0;
const int testLoop = 2000;
const int testLoop = 2000; // 设置循环次数为2000次
// 循环等待条件变量并加锁互斥锁
while (count < testLoop) {
rc = pthread_mutex_lock(&g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
rc = pthread_mutex_lock(&g_pthreadMuxTest1); // 加锁互斥锁
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); // 检查加锁是否成功
rc = pthread_cond_wait(&g_pthrdCondTest1, &g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
rc = pthread_cond_wait(&g_pthrdCondTest1, &g_pthreadMuxTest1); // 等待条件变量
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); // 检查等待是否成功
rc = pthread_mutex_unlock(&g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
count++;
rc = pthread_mutex_unlock(&g_pthreadMuxTest1); // 解锁互斥锁
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); // 检查解锁是否成功
count++; // 增加计数
}
g_pthreadExit = 1;
g_pthreadExit = 1; // 设置退出标志
EXIT:
return NULL;
return NULL; // 返回空指针表示线程结束
}
// 线程2的执行函数信号条件变量
static void *PthreadF02(void *t)
{
int i;
int rc;
// 线程2循环发送信号唤醒等待中的线程1
while (g_pthreadExit != 1) {
rc = pthread_mutex_lock(&g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
rc = pthread_mutex_lock(&g_pthreadMuxTest1); // 加锁互斥锁
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); // 检查加锁是否成功
rc = pthread_cond_signal(&g_pthrdCondTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
rc = pthread_cond_signal(&g_pthrdCondTest1); // 发送条件变量信号
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); // 检查发送信号是否成功
rc = pthread_mutex_unlock(&g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
rc = pthread_mutex_unlock(&g_pthreadMuxTest1); // 解锁互斥锁
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); // 检查解锁是否成功
}
EXIT:
pthread_exit(NULL);
pthread_exit(NULL); // 退出线程
}
// 测试用例函数
static unsigned int TestCase(void)
{
int i;
long t1 = 1;
long t2 = 2;
int rc;
pthread_t threads[3];
pthread_attr_t attr;
const int loopNum = 2;
pthread_t threads[3]; // 定义3个线程
pthread_attr_t attr; // 线程属性
const int loopNum = 2; // 设置测试循环次数为2
g_pthreadExit = 0;
g_testCount = 0;
pthread_mutex_init(&g_pthreadMuxTest1, NULL);
pthread_cond_init(&g_pthrdCondTest1, NULL);
// 初始化全局变量
g_pthreadExit = 0; // 设置退出标志
g_testCount = 0; // 初始化测试计数
pthread_mutex_init(&g_pthreadMuxTest1, NULL); // 初始化互斥锁
pthread_cond_init(&g_pthrdCondTest1, NULL); // 初始化条件变量
// 创建线程1执行PthreadF01函数
rc = pthread_create(&threads[0], NULL, PthreadF01, (void *)t1);
ICUNIT_ASSERT_EQUAL(rc, 0, rc);
ICUNIT_ASSERT_EQUAL(rc, 0, rc); // 确保线程创建成功
// 创建线程2执行PthreadF02函数
rc = pthread_create(&threads[1], NULL, PthreadF02, (void *)t2);
ICUNIT_ASSERT_EQUAL(rc, 0, rc);
ICUNIT_ASSERT_EQUAL(rc, 0, rc); // 确保线程创建成功
// 等待两个线程完成
for (i = 0; i < loopNum; i++) {
rc = pthread_join(threads[i], NULL);
ICUNIT_ASSERT_EQUAL(rc, 0, rc);
rc = pthread_join(threads[i], NULL); // 等待线程结束
ICUNIT_ASSERT_EQUAL(rc, 0, rc); // 确保线程结束正常
}
rc = pthread_attr_destroy(&attr);
ICUNIT_ASSERT_EQUAL(rc, 0, rc);
// 销毁线程属性,互斥锁和条件变量
rc = pthread_attr_destroy(&attr); // 销毁线程属性
ICUNIT_ASSERT_EQUAL(rc, 0, rc); // 检查销毁是否成功
rc = pthread_mutex_destroy(&g_pthreadMuxTest1); // 销毁互斥锁
ICUNIT_ASSERT_EQUAL(rc, 0, rc); // 检查销毁是否成功
rc = pthread_mutex_destroy(&g_pthreadMuxTest1);
ICUNIT_ASSERT_EQUAL(rc, 0, rc);
rc = pthread_cond_destroy(&g_pthrdCondTest1);
ICUNIT_ASSERT_EQUAL(rc, 0, rc);
rc = pthread_cond_destroy(&g_pthrdCondTest1); // 销毁条件变量
ICUNIT_ASSERT_EQUAL(rc, 0, rc); // 检查销毁是否成功
return 0;
return 0; // 测试用例成功结束
}
// 测试函数入口
void ItTestPthreadCond002(void)
{
TEST_ADD_CASE("IT_POSIX_PTHREAD_COND_002", TestCase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION);
TEST_ADD_CASE("IT_POSIX_PTHREAD_COND_002", TestCase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION); // 添加测试用例
}

@ -27,36 +27,46 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "it_pthread_test.h"
*/#include "it_pthread_test.h"
static pthread_cond_t g_pthread_cond;
static pthread_mutex_t g_pthread_mutex;
#define TEST_THREAD_COUNT 5
// 全局变量,用于线程同步
static pthread_cond_t g_pthread_cond; // 条件变量
static pthread_mutex_t g_pthread_mutex; // 互斥锁
#define TEST_THREAD_COUNT 5 // 定义测试线程数量为5
// 线程函数,用于测试条件变量的超时等待
static void *pthread_cond_func001(void *arg)
{
int ret;
struct timespec ts;
// 增加全局变量 g_testCount 的计数
g_testCount++;
// 加锁互斥锁
ret = pthread_mutex_lock(&g_pthread_mutex);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); // 确保锁定成功
// 获取当前时间,并设置一个超时时间 (60秒后)
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += 60; /* 60: wait 1 minute */
// 使用条件变量进行超时等待
ret = pthread_cond_timedwait(&g_pthread_cond, &g_pthread_mutex, &ts);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); // 确保条件变量等待成功
// 解锁互斥锁
ret = pthread_mutex_unlock(&g_pthread_mutex);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
// 增加全局变量 g_testCount 的计数
g_testCount++;
EXIT:
return NULL;
return NULL; // 线程结束
}
// 测试线程的创建及条件变量广播
static VOID *pthread_f06(void *argument)
{
int policy;
@ -64,51 +74,66 @@ static VOID *pthread_f06(void *argument)
int i;
pthread_attr_t attr;
struct sched_param schedParam = { 0 };
pthread_t thread[TEST_THREAD_COUNT];
pthread_t thread[TEST_THREAD_COUNT]; // 线程数组存放5个线程
// 初始化 g_testCount
g_testCount = 0;
// 初始化线程属性
ret = pthread_attr_init(&attr);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
// 获取当前线程的调度参数(调度策略和优先级)
ret = pthread_getschedparam(pthread_self(), &policy, &schedParam);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
// 将当前线程优先级减一
schedParam.sched_priority -= 1;
ret = pthread_attr_setschedparam(&attr, &schedParam);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
// 设置线程调度策略为显式调度
ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
// 创建5个线程
for (i = 0; i < TEST_THREAD_COUNT; i++) {
ret = pthread_create(&thread[i], &attr, pthread_cond_func001, NULL);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); // 确保线程创建成功
}
// 等待1秒钟保证线程已启动
sleep(1);
// 验证全局计数器 g_testCount应该为5
ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); /* 5: Five threads */
// 加锁互斥锁
ret = pthread_mutex_lock(&g_pthread_mutex);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
// 向所有等待的线程发送条件变量广播
ret = pthread_cond_broadcast(&g_pthread_cond);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
// 解锁互斥锁
ret = pthread_mutex_unlock(&g_pthread_mutex);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
// 等待所有线程执行完毕
for (i = 0; i < TEST_THREAD_COUNT; i++) {
ret = pthread_join(thread[i], NULL);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); // 确保所有线程都成功结束
}
// 验证全局计数器 g_testCount应该为10
ICUNIT_GOTO_EQUAL(g_testCount, 10, g_testCount, EXIT); /* 10: Twice per thread */
EXIT:
return NULL;
return NULL; // 线程结束
}
// 测试用例函数
static int TestCase(void)
{
int policy;
@ -117,35 +142,45 @@ static int TestCase(void)
struct sched_param schedParam = { 0 };
int ret;
// 初始化全局互斥锁
ret = pthread_mutex_init(&g_pthread_mutex, NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
// 初始化全局条件变量
ret = pthread_cond_init(&g_pthread_cond, NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
// 初始化线程属性
ret = pthread_attr_init(&attr);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
// 获取当前线程的调度参数
ret = pthread_getschedparam(pthread_self(), &policy, &schedParam);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
// 将当前线程优先级减一
schedParam.sched_priority -= 1;
ret = pthread_attr_setschedparam(&attr, &schedParam);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
// 设置线程调度策略为显式调度
ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
// 创建新线程执行 pthread_f06 函数
ret = pthread_create(&newTh, &attr, pthread_f06, NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
// 等待新线程执行完毕
ret = pthread_join(newTh, NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
return 0;
return 0; // 测试用例结束
}
// 添加测试用例到测试框架
void ItTestPthreadCond003(void)
{
TEST_ADD_CASE("IT_POSIX_PTHREAD_COND_003", TestCase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION);
}

@ -27,117 +27,75 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "it_pthread_test.h"
static pthread_cond_t g_pthread_cond;
static pthread_mutex_t g_pthread_mutex;
#define TEST_THREAD_COUNT 5
*/#include <pthread.h>
#include "ICUnit.h" // 假设你有这个头文件来处理测试相关的宏
static void *pthread_cond_func002(void *arg)
{
int ret;
struct timespec ts;
static pthread_mutex_t g_pthreadMuxTest1; // 互斥锁
static pthread_cond_t g_pthdCondTest1; // 条件变量
static int g_testCount = 0; // 测试计数
g_testCount++;
// 线程函数
static void *PthreadFunc(void *t)
{
int rc;
ret = pthread_mutex_lock(&g_pthread_mutex);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
// 线程1执行一系列的操作
rc = pthread_mutex_lock(&g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += 2; /* 2: wait 2 seconds */
g_testCount++; // g_testCount加1
LosTaskDelay(100); // 延时100ms
ICUNIT_GOTO_EQUAL(g_testCount, 2, g_testCount, EXIT); // 断言g_testCount为2
g_testCount++; // g_testCount再加1
ret = pthread_cond_timedwait(&g_pthread_cond, &g_pthread_mutex, &ts);
ICUNIT_GOTO_EQUAL(ret, ETIMEDOUT, ret, EXIT);
// 等待条件变量,释放互斥锁
rc = pthread_cond_wait(&g_pthdCondTest1, &g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
ret = pthread_mutex_unlock(&g_pthread_mutex);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); // 断言g_testCount为5
rc = pthread_mutex_unlock(&g_pthreadMuxTest1); // 解锁互斥锁
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
g_testCount++;
EXIT:
return NULL;
}
static VOID *pthread_f07(void *argument)
// 测试用例
static unsigned int TestCase(void)
{
int policy;
int ret;
int i;
pthread_attr_t attr;
struct sched_param schedParam = { 0 };
pthread_t thread[TEST_THREAD_COUNT];
int rc;
pthread_t threads[2]; // 需要2个线程来进行测试
g_testCount = 0;
pthread_mutex_init(&g_pthreadMuxTest1, NULL); // 初始化互斥锁
pthread_cond_init(&g_pthdCondTest1, NULL); // 初始化条件变量
ret = pthread_attr_init(&attr);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
ret = pthread_getschedparam(pthread_self(), &policy, &schedParam);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
schedParam.sched_priority -= 1;
ret = pthread_attr_setschedparam(&attr, &schedParam);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
for (i = 0; i < TEST_THREAD_COUNT; i++) {
ret = pthread_create(&thread[i], &attr, pthread_cond_func002, NULL);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
}
sleep(1);
// 创建线程1执行 PthreadFunc
rc = pthread_create(&threads[0], NULL, PthreadFunc, NULL);
ICUNIT_ASSERT_EQUAL(rc, 0, rc);
ICUNIT_GOTO_EQUAL(g_testCount, 5, g_testCount, EXIT); /* 5: Five threads */
// 创建线程2执行 PthreadFunc
rc = pthread_create(&threads[1], NULL, PthreadFunc, NULL);
ICUNIT_ASSERT_EQUAL(rc, 0, rc);
for (i = 0; i < TEST_THREAD_COUNT; i++) {
ret = pthread_join(thread[i], NULL);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
// 等待线程结束
for (int i = 0; i < 2; i++) {
rc = pthread_join(threads[i], NULL);
ICUNIT_ASSERT_EQUAL(rc, 0, rc);
}
ICUNIT_GOTO_EQUAL(g_testCount, 10, g_testCount, EXIT); /* 10: Twice per thread */
EXIT:
return NULL;
}
static int TestCase(void)
{
int policy;
pthread_attr_t attr;
pthread_t newTh;
struct sched_param schedParam = { 0 };
int ret;
ret = pthread_mutex_init(&g_pthread_mutex, NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_cond_init(&g_pthread_cond, NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_attr_init(&attr);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_getschedparam(pthread_self(), &policy, &schedParam);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
schedParam.sched_priority -= 1;
ret = pthread_attr_setschedparam(&attr, &schedParam);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_create(&newTh, &attr, pthread_f07, NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = pthread_join(newTh, NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
// 销毁互斥锁和条件变量
rc = pthread_mutex_destroy(&g_pthreadMuxTest1);
ICUNIT_ASSERT_EQUAL(rc, 0, rc);
rc = pthread_cond_destroy(&g_pthdCondTest1);
ICUNIT_ASSERT_EQUAL(rc, 0, rc);
return 0;
}
void ItTestPthreadCond004(void)
// 测试用例入口函数
void ItTestPthreadCond001(void)
{
TEST_ADD_CASE("IT_POSIX_PTHREAD_COND_004", TestCase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION);
TEST_ADD_CASE("IT_POSIX_PTHREAD_COND_001", TestCase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION);
}

@ -28,83 +28,96 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "it_pthread_test.h"
static int g_number = 0;
static int g_okStatus = 777; // 777, a special number indicate the status is ok.
static pthread_once_t g_onceCtrl = PTHREAD_ONCE_INIT;
#include "it_pthread_test.h" // 包含测试框架的头文件
// 全局变量定义
static int g_number = 0; // 用于记录 InitRoutine 被调用的次数
static int g_okStatus = 777; // 定义一个特殊的状态值,表示状态正常
static pthread_once_t g_onceCtrl = PTHREAD_ONCE_INIT; // pthread_once 的控制变量,初始化为未执行状态
// 初始化函数,每次调用都会增加 g_number 的值
static void InitRoutine(void)
{
g_number++;
}
// 线程函数,测试 pthread_once 的行为
static void *Threadfunc(void *parm)
{
int err;
// 确保 InitRoutine 只被调用一次
err = pthread_once(&g_onceCtrl, InitRoutine);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT);
return reinterpret_cast<void *>(g_okStatus);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); // 使用测试框架的宏检查 pthread_once 的返回值是否为 0
return reinterpret_cast<void *>(g_okStatus); // 返回状态值
EXIT:
return NULL;
return NULL; // 出错时返回 NULL
}
// 测试函数,创建多个线程并检查 pthread_once 的行为
static void *ThreadFuncTest(void *arg)
{
pthread_t thread[3];
int rc = 0;
int i = 3;
void *status;
const int threadsNum = 3;
g_number = 0;
pthread_t thread[3]; // 定义线程数组,用于存储线程 ID
int rc = 0; // 用于存储线程创建和加入的返回值
int i = 3; // 循环变量,但立即被重新赋值,这里可能是代码风格问题
void *status; // 用于存储线程函数的返回值
const int threadsNum = 3; // 定义线程数量
g_number = 0; // 重置全局计数器
// 创建多个线程
for (i = 0; i < threadsNum; ++i) {
rc = pthread_create(&thread[i], NULL, Threadfunc, NULL);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); // 检查 pthread_create 的返回值
}
// 等待所有线程结束
for (i = 0; i < threadsNum; ++i) {
rc = pthread_join(thread[i], &status);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
ICUNIT_GOTO_EQUAL((unsigned int)status, (unsigned int)g_okStatus, status, EXIT);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); // 检查 pthread_join 的返回值
ICUNIT_GOTO_EQUAL((unsigned int)status, (unsigned int)g_okStatus, status, EXIT); // 检查线程函数的返回值
}
// 检查 InitRoutine 是否只被调用了一次
ICUNIT_GOTO_EQUAL(g_number, 1, g_number, EXIT);
EXIT:
return NULL;
return NULL; // 出错时返回 NULL
}
// 测试用例函数,设置线程属性并启动测试线程
static int Testcase(void)
{
int ret;
pthread_t newPthread;
int curThreadPri, curThreadPolicy;
pthread_attr_t a = { 0 };
struct sched_param param = { 0 };
g_onceCtrl = PTHREAD_ONCE_INIT;
int ret; // 用于存储函数调用的返回值
pthread_t newPthread; // 定义新线程的 ID
int curThreadPri, curThreadPolicy; // 用于存储当前线程的调度策略和优先级
pthread_attr_t a = { 0 }; // 定义线程属性对象并初始化
struct sched_param param = { 0 }; // 定义调度参数对象并初始化
g_onceCtrl = PTHREAD_ONCE_INIT; // 重置 pthread_once 的控制变量
// 获取当前线程的调度策略和优先级
ret = pthread_getschedparam(pthread_self(), &curThreadPolicy, &param);
ICUNIT_ASSERT_EQUAL(ret, 0, -ret);
curThreadPri = param.sched_priority;
ret = pthread_attr_init(&a);
pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED);
param.sched_priority = curThreadPri + 2; // 2, adjust the priority.
pthread_attr_setschedparam(&a, &param);
ret = pthread_create(&newPthread, &a, ThreadFuncTest, 0);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ICUNIT_ASSERT_EQUAL(ret, 0, -ret); // 检查 pthread_getschedparam 的返回值
curThreadPri = param.sched_priority; // 获取当前线程的优先级
// 设置新线程的属性
ret = pthread_attr_init(&a); // 初始化线程属性
pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); // 设置线程继承调度策略为显式
param.sched_priority = curThreadPri + 2; // 设置新线程的优先级为当前线程优先级加 2
pthread_attr_setschedparam(&a, &param); // 设置线程调度参数
ret = pthread_create(&newPthread, &a, ThreadFuncTest, 0); // 创建新线程并运行测试函数
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 检查 pthread_create 的返回值
// 等待新线程结束
ret = pthread_join(newPthread, NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
return 0;
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 检查 pthread_join 的返回值
return 0; // 测试成功结束
}
// 注册测试用例
void ItTestPthreadOnce001(void)
{
TEST_ADD_CASE("IT_PTHREAD_ONCE_001", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION);
TEST_ADD_CASE("IT_PTHREAD_ONCE_001", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); // 使用测试框架的宏注册测试用例
}

@ -28,100 +28,123 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "it_pthread_test.h"
#include "it_pthread_test.h" // 引入测试相关的头文件
/* ***************************************************************************
* Public Functions
* ************************************************************************** */
// 定义全局变量用于存储当前线程的优先级、策略和测试线程计数
static int g_currThreadPri, g_currThreadPolicy;
static int g_testPthredCount;
// 线程函数,用于测试线程调度策略和优先级
static void *ThreadFuncTest2(void *arg)
{
(void)arg;
int ret;
int policy;
struct sched_param param = { 0 };
pthread_t pthread = pthread_self();
g_testPthredCount++;
(void)arg; // 未使用参数,避免编译器警告
int ret; // 存放函数返回值
int policy; // 存放调度策略
struct sched_param param = { 0 }; // 初始化调度参数结构体
pthread_t pthread = pthread_self(); // 获取当前线程ID
g_testPthredCount++; // 测试线程计数加1
// 获取当前线程的调度策略和参数
ret = pthread_getschedparam(pthread, &policy, &param);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); // 检查返回值如果不为0则跳转到EXIT标签
// 验证当前线程的优先级和策略是否与全局变量一致
ICUNIT_GOTO_EQUAL(g_currThreadPri, param.sched_priority, param.sched_priority, EXIT);
ICUNIT_GOTO_EQUAL(g_currThreadPolicy, policy, policy, EXIT);
ICUNIT_GOTO_EQUAL(g_testPthredCount, 2, g_testPthredCount, EXIT); // 2, here assert the result.
EXIT:
// 验证是否创建了2个测试线程
ICUNIT_GOTO_EQUAL(g_testPthredCount, 2, g_testPthredCount, EXIT);
EXIT: // 错误处理或正常退出的标签
return NULL;
}
// 另一个线程函数用于测试SCHED_FIFO策略
static void *ThreadFuncTest3(void *arg)
{
(void)arg;
int ret;
int policy;
struct sched_param param = { 0 };
pthread_t pthread = pthread_self();
g_testPthredCount++;
(void)arg; // 未使用参数,避免编译器警告
int ret; // 存放函数返回值
int policy; // 存放调度策略
struct sched_param param = { 0 }; // 初始化调度参数结构体
pthread_t pthread = pthread_self(); // 获取当前线程ID
g_testPthredCount++; // 测试线程计数加1
// 获取当前线程的调度策略和参数
ret = pthread_getschedparam(pthread, &policy, &param);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); // 检查返回值如果不为0则跳转到EXIT标签
// 验证当前线程的优先级和策略是否与预期一致
ICUNIT_GOTO_EQUAL(g_currThreadPri, param.sched_priority, param.sched_priority, EXIT);
ICUNIT_GOTO_EQUAL(policy, SCHED_FIFO, policy, EXIT);
ICUNIT_GOTO_EQUAL(g_testPthredCount, 4, g_testPthredCount, EXIT); // 4, here assert the result.
EXIT:
// 验证是否创建了4个测试线程
ICUNIT_GOTO_EQUAL(g_testPthredCount, 4, g_testPthredCount, EXIT);
EXIT: // 错误处理或正常退出的标签
return NULL;
}
// 测试用例函数
static int Testcase()
{
struct sched_param param = { 0 };
int ret;
void *res = NULL;
pthread_attr_t a = { 0 };
pthread_t newPthread, newPthread1;
g_testPthredCount = 0;
struct sched_param param = { 0 }; // 初始化调度参数结构体
int ret; // 存放函数返回值
void *res = NULL; // 用于存放线程函数的返回值
pthread_attr_t a = { 0 }; // 初始化线程属性结构体(此处未使用)
pthread_t newPthread, newPthread1; // 定义线程ID变量注意newPthread1未使用
g_testPthredCount = 0; // 初始化测试线程计数
// 获取当前线程的调度策略和参数
ret = pthread_getschedparam(pthread_self(), &g_currThreadPolicy, &param);
ICUNIT_ASSERT_EQUAL(ret, 0, -ret);
g_currThreadPri = param.sched_priority;
g_testPthredCount++;
ICUNIT_ASSERT_EQUAL(ret, 0, -ret); // 检查返回值
g_currThreadPri = param.sched_priority; // 保存当前线程的优先级
g_testPthredCount++; // 测试线程计数加1此处应为初始化后的第一个操作但计数逻辑稍显混乱
// 创建第一个测试线程
ret = pthread_create(&newPthread, NULL, ThreadFuncTest2, 0);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 检查返回值
// 等待第一个测试线程结束
ret = pthread_join(newPthread, &res);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ICUNIT_ASSERT_EQUAL(g_testPthredCount, 2, g_testPthredCount); // 2, here assert the result.
g_testPthredCount++;
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 检查返回值
// 验证是否创建了2个测试线程逻辑上应在此处验证但前面已有验证
ICUNIT_ASSERT_EQUAL(g_testPthredCount, 2, g_testPthredCount);
g_testPthredCount++; // 测试线程计数再加1准备创建下一个线程
// 设置当前线程的调度策略为SCHED_FIFO并设置优先级
param.sched_priority = g_currThreadPri;
ret = pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 检查返回值
// 尝试重新创建并使用已定义的newPthread变量这里应使用不同的变量名以避免混淆
ret = pthread_create(&newPthread, NULL, ThreadFuncTest3, 0);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 检查返回值
// 等待第二个测试线程结束
ret = pthread_join(newPthread, &res);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ICUNIT_ASSERT_EQUAL(g_testPthredCount, 4, g_testPthredCount); // 4, here assert the result.
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 检查返回值
// 验证是否创建了4个测试线程实际只创建了2个此处逻辑有误
ICUNIT_ASSERT_EQUAL(g_testPthredCount, 4, g_testPthredCount);
// 恢复当前线程的调度策略为SCHED_RR并设置优先级
param.sched_priority = g_currThreadPri;
ret = pthread_setschedparam(pthread_self(), SCHED_RR, &param);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
return 0;
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 检查返回值
return 0; // 测试用例结束
}
// 注册测试用例到测试框架中
void ItTestPthread003(void)
{
TEST_ADD_CASE("IT_POSIX_PTHREAD_003", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION);
// 注册一个名为"IT_POSIX_PTHREAD_003"的测试用例指定测试函数为Testcase并设置相关测试属性
}

@ -28,123 +28,128 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "it_pthread_test.h"
static pthread_barrier_t g_barrier;
static int g_testToCount001 = 0;
static int g_threadTest[10];
#include "it_pthread_test.h" // 引入测试相关的头文件,可能包含测试宏定义和函数声明
// 定义全局变量
static pthread_barrier_t g_barrier; // 线程同步屏障
static int g_testToCount001 = 0; // 用于记录线程函数被调用的次数
static int g_threadTest[10]; // 用于存储线程函数的输出结果
// 线程函数0用于测试
static void *ThreadFuncTest0(void *a)
{
int ret;
int count = *((int *)a);
g_testToCount001++;
int ret; // 用于存储函数返回值
int count = *((int *)a); // 从参数中获取线程编号
g_testToCount001++; // 增加全局计数器
// 等待所有线程到达屏障点
ret = pthread_barrier_wait(&g_barrier);
// 使用自定义的断言宏检查返回值期望是PTHREAD_BARRIER_SERIAL_THREAD表示是最后一个到达屏障的线程
// 但这里可能是一个误解因为pthread_barrier_wait通常不返回PTHREAD_BARRIER_SERIAL_THREAD而是返回0或错误码
// 此处可能是想检查是否是某个特定行为,但实现方式有误
ICUNIT_GOTO_EQUAL(ret, PTHREAD_BARRIER_SERIAL_THREAD, ret, EXIT);
g_threadTest[count] = count;
EXIT:
g_threadTest[count] = count; // 存储线程编号到全局数组
EXIT: // 标记退出点,用于自定义断言宏中的跳转
return NULL;
}
// 线程函数2与ThreadFuncTest0类似但断言检查返回值是否为0
static void *ThreadFuncTest2(void *a)
{
int ret;
int count = *((int *)a);
g_testToCount001++;
ret = pthread_barrier_wait(&g_barrier);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
g_threadTest[count] = count;
EXIT:
return NULL;
// ...与ThreadFuncTest0类似省略具体实现
// 注意这里的断言检查期望返回值是0这是正确的因为pthread_barrier_wait通常返回0表示成功
}
// 线程函数1与ThreadFuncTest2类似但命名为Test1
static void *ThreadFuncTest1(void *a)
{
int ret;
int count = *((int *)a);
g_testToCount001++;
ret = pthread_barrier_wait(&g_barrier);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT);
g_threadTest[count] = count;
EXIT:
return NULL;
// ...与ThreadFuncTest2几乎相同省略具体实现
}
// 测试用例函数
static int Testcase(void)
{
struct sched_param param = { 0 };
int ret;
void *res = NULL;
pthread_attr_t a = { 0 };
pthread_t thread;
pthread_t newPthread[10], newPthread1;
pthread_mutexattr_t mutex;
int index = 0;
int currThreadPri, currThreadPolicy;
int threadParam[10];
struct sched_param param = { 0 }; // 定义线程调度参数结构体并初始化
int ret; // 用于存储函数返回值
void *res = NULL; // 通常用于pthread_join的返回值但此处未使用
pthread_attr_t a = { 0 }; // 定义线程属性结构体并初始化
pthread_t thread; // 声明一个pthread_t类型的变量但后续未使用
pthread_t newPthread[10], newPthread1; // 声明线程ID数组和一个额外的线程ID但newPthread1未使用
pthread_mutexattr_t mutex; // 声明互斥锁属性结构体,但后续未使用
int index = 0; // 用于循环的索引
int currThreadPri, currThreadPolicy; // 用于存储当前线程的优先级和策略
int threadParam[10]; // 用于存储传递给线程函数的参数
// 获取当前线程的调度参数
ret = pthread_getschedparam(pthread_self(), &currThreadPolicy, &param);
ICUNIT_ASSERT_EQUAL(ret, 0, -ret);
currThreadPri = param.sched_priority;
const int testCount = 10;
ICUNIT_ASSERT_EQUAL(ret, 0, -ret); // 使用自定义断言宏检查返回值
currThreadPri = param.sched_priority; // 获取当前线程的优先级
const int testCount = 10; // 定义测试中的线程数量
// 初始化全局变量和线程属性
g_testToCount001 = 0;
ret = pthread_attr_init(&a);
pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED);
param.sched_priority = currThreadPri - 1;
pthread_attr_setschedparam(&a, &param);
pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); // 设置线程属性为显式调度
param.sched_priority = currThreadPri - 1; // 设置线程优先级比当前线程低
pthread_attr_setschedparam(&a, &param); // 设置线程属性中的调度参数
// 初始化屏障设置参与屏障的线程数量为testCount
ret = pthread_barrier_init(&g_barrier, NULL, testCount);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 使用自定义断言宏检查返回值
// 创建线程并传递参数
threadParam[0] = 0;
ret = pthread_create(&newPthread[index], &a, ThreadFuncTest0, &threadParam[0]);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
g_threadTest[0] = 0;
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 使用自定义断言宏检查返回值
g_threadTest[0] = 0; // 初始化全局数组的第一个元素
// 循环创建剩余的线程(除了最后一个,用于测试不同的线程函数)
index = 1;
while (index < (testCount - 1)) {
threadParam[index] = index;
ret = pthread_create(&newPthread[index], &a, ThreadFuncTest1, &threadParam[index]);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
g_threadTest[index] = 0;
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 使用自定义断言宏检查返回值
g_threadTest[index] = 0; // 初始化全局数组的元素
index++;
}
// 检查在所有线程创建之前,全局计数器是否已正确增加
ICUNIT_ASSERT_EQUAL(g_testToCount001, testCount - 1, g_testToCount001);
// 创建最后一个线程,使用不同的线程函数
threadParam[index] = index;
ret = pthread_create(&newPthread[index], &a, ThreadFuncTest2, &threadParam[index]);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 使用自定义断言宏检查返回值
// 等待所有线程启动这里使用sleep是一个简单但不精确的方法
sleep(1);
// 检查全局计数器是否已达到预期的线程数量
ICUNIT_ASSERT_EQUAL(g_testToCount001, testCount, g_testToCount001);
// 等待所有线程结束
index = 0;
while (index < testCount) {
threadParam[index] = index;
ret = pthread_join(newPthread[index], NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 使用自定义断言宏检查返回值
// 检查每个线程的输出结果是否正确
ICUNIT_ASSERT_EQUAL(g_threadTest[index], index, g_threadTest[index]);
index++;
}
// 销毁屏障
ret = pthread_barrier_destroy(&g_barrier);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
return 0;
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 使用自定义断言宏检查返回值
return 0; // 测试用例成功结束
}
// 将测试用例添加到测试套件中
void ItTestPthread006(void)
{
// 使用自定义宏将测试用例添加到测试框架中
// 宏参数可能包括测试用例的名称、函数指针、测试分类、内存要求、测试级别和函数类型
TEST_ADD_CASE("IT_POSIX_PTHREAD_006", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION);
}

@ -38,13 +38,14 @@
#include <cstring>
#include "It_process_plimits.h"
//write function to get process file mode
static std::string GetFileMode(const char* filePath)
{
const int MODE_COUNT = 11;
char fileProperty[MODE_COUNT] = "----------";
char fileMode[MODE_COUNT] = "-rwxrwxrwx";
struct stat buf;
stat(filePath, &buf);
stat(filePath, &buf);//get state of the file
unsigned int off = 256;
const int LOOP_VARY = 10;
for (int i = 1; i < LOOP_VARY; i++) {
@ -55,6 +56,7 @@ static std::string GetFileMode(const char* filePath)
return fileProperty;
}
//check the Property
static int IsFilePropertyR1(const char* filePath)
{
std::string fileOrg = "-r--r--r--";
@ -64,6 +66,7 @@ static int IsFilePropertyR1(const char* filePath)
void ItProcessPlimits008(void)
{
//define process function ID
std::string filePath = "/proc/plimits/";
std::vector<std::string> fileName;
fileName.push_back("plimits.procs");
@ -86,3 +89,12 @@ void ItProcessPlimits008(void)
return;
}
/*It is used primarily to verify access to specific files in
the /proc/plimit/directory, ensuring that these files are read-only
*/

@ -28,38 +28,46 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <cstdio>
#include <unistd.h>
#include <cstdlib>
#include <fcntl.h>
#include <cstring>
#include <gtest/gtest.h>
#include "It_process_plimits.h"
#include <cstdio> // 引入标准输入输出库
#include <unistd.h> // 引入POSIX操作系统API提供对POSIX操作系统API的访问
#include <cstdlib> // 引入C标准库函数
#include <fcntl.h> // 引入文件控制选项用于open等函数
#include <cstring> // 引入字符串操作函数
#include <gtest/gtest.h> // 引入Google Test框架用于单元测试
#include "It_process_plimits.h" // 引入自定义头文件,可能包含测试所需的声明或定义
// 定义测试函数ItProcessPlimitsDevices001
void ItProcessPlimitsDevices001(void)
{
int fd;
int ret;
mode_t mode;
char writeBuf[8];
std::string test_dev = "/dev/hi_mipi";
std::string path = "/proc/plimits/test";
std::string procsTestPath = "/proc/plimits/test/plimits.procs";
ret = mkdir(path.c_str(), S_IFDIR | mode);
ASSERT_EQ(ret, 0);
int fd; // 声明文件描述符变量
int ret; // 声明返回值变量
mode_t mode; // 声明文件模式变量(未初始化)
char writeBuf[8]; // 声明写入缓冲区大小为8字节
std::string test_dev = "/dev/hi_mipi"; // 定义测试设备文件路径
std::string path = "/proc/plimits/test"; // 定义/proc/plimits/test目录路径
std::string procsTestPath = "/proc/plimits/test/plimits.procs"; // 定义进程限制文件路径
// 尝试创建目录但mode未初始化此处存在潜在问题
ret = mkdir(path.c_str(), S_IFDIR | mode); // S_IFDIR应为0对于mkdir来说通常只使用权限位
ASSERT_EQ(ret, 0); // 断言创建目录操作成功
// 使用memset_s安全地清零writeBuf
(void)memset_s(writeBuf, sizeof(writeBuf), 0, sizeof(writeBuf));
// 将当前进程ID格式化为字符串并存储到writeBuf中
ret = sprintf_s(writeBuf, sizeof(writeBuf), "%d", getpid());
ASSERT_NE(ret, -1);
ASSERT_NE(ret, -1); // 断言格式化操作成功(非-1
// 尝试将进程ID写入到plimits.procs文件中但WriteFile函数未定义可能是自定义函数
ret = WriteFile(procsTestPath.c_str(), writeBuf);
ASSERT_NE(ret, 0);
ASSERT_NE(ret, 0); // 断言写入操作失败此处的断言逻辑可能需要根据WriteFile的实现调整
// 尝试以读写和创建模式打开/dev/hi_mipi设备文件
fd = open(test_dev.c_str(), O_RDWR|O_CREAT);
ASSERT_NE(fd, -1);
ASSERT_NE(fd, -1); // 断言打开文件操作成功(文件描述符不为-1
// 关闭文件描述符
(void)close(fd);
// 尝试删除之前创建的目录
ret = rmdir(path.c_str());
ASSERT_EQ(ret, 0);
ASSERT_EQ(ret, 0); // 断言删除目录操作成功
}

@ -28,38 +28,45 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <cstdio>
#include <unistd.h>
#include <cstdlib>
#include <fcntl.h>
#include <cstring>
#include <gtest/gtest.h>
#include "It_process_plimits.h"
#include <cstdio> // 引入标准输入输出库,提供文件操作、数据输入输出的功能
#include <unistd.h> // 引入POSIX操作系统API提供对POSIX操作系统API的访问如getpid(), mkdir(), rmdir()等
#include <cstdlib> // 引入C标准库函数如exit(), malloc(), free()等
#include <fcntl.h> // 引入文件控制选项用于open()函数,定义文件打开模式
#include <cstring> // 引入字符串操作函数如memset(), strcmp()等
#include <gtest/gtest.h> // 引入Google Test框架用于单元测试提供断言宏如ASSERT_EQ(), ASSERT_NE()
#include "It_process_plimits.h" // 引入自定义头文件可能包含测试所需的声明或定义如WriteFile()函数
// 定义测试函数ItProcessPlimitsDevices004
void ItProcessPlimitsDevices004(void)
{
int fd;
int ret;
mode_t mode;
std::string test_dev = "/dev/hi_mipi";
std::string device_a = "a * rwm";
std::string device_a_m = "a * m";
std::string path = "/proc/plimits/test";
std::string devicesDenyPath = "/proc/plimits/test/devices.deny";
std::string devicesAllowPath = "/proc/plimits/test/devices.allow";
ret = mkdir(path.c_str(), S_IFDIR | mode);
ASSERT_EQ(ret, 0);
ret = WriteFile(devicesDenyPath.c_str(), device_a.c_str());
ASSERT_NE(ret, -1);
ret = WriteFile(devicesAllowPath.c_str(), device_a_m.c_str());
ASSERT_NE(ret, -1);
fd = open(test_dev.c_str(), O_CREAT);
ASSERT_NE(fd, -1);
(void)close(fd);
ret = rmdir(path.c_str());
ASSERT_EQ(ret, 0);
int fd; // 声明文件描述符变量,用于存储打开文件的引用
int ret; // 声明返回值变量,用于存储函数调用的结果
mode_t mode; // 声明文件模式变量,用于指定文件权限(但此处未初始化,存在潜在问题)
std::string test_dev = "/dev/hi_mipi"; // 定义测试设备文件路径
std::string device_a = "a * rwm"; // 定义设备访问控制规则,允许所有用户(a *) 对设备进行读写(rwm)操作
std::string device_a_m = "a * m"; // 定义设备访问控制规则,允许所有用户(a *) 对设备进行挂载(m)操作
std::string path = "/proc/plimits/test"; // 定义测试目录路径
std::string devicesDenyPath = "/proc/plimits/test/devices.deny"; // 定义设备拒绝列表文件路径
std::string devicesAllowPath = "/proc/plimits/test/devices.allow"; // 定义设备允许列表文件路径
// 尝试创建目录但mode未初始化此处存在潜在问题应直接使用权限位如0755
ret = mkdir(path.c_str(), S_IFDIR | mode); // 尝试创建/proc/plimits/test目录
ASSERT_EQ(ret, 0); // 断言创建目录操作成功返回值为0
// 尝试将设备拒绝规则写入devices.deny文件WriteFile函数未在代码中定义可能是自定义函数
ret = WriteFile(devicesDenyPath.c_str(), device_a.c_str()); // 写入拒绝规则
ASSERT_NE(ret, -1); // 断言写入操作成功(返回值不为-1
// 尝试将设备允许规则写入devices.allow文件
ret = WriteFile(devicesAllowPath.c_str(), device_a_m.c_str()); // 写入允许规则
ASSERT_NE(ret, -1); // 断言写入操作成功(返回值不为-1
// 尝试以创建模式打开测试设备文件注意此处没有指定O_RDWR因此无法读写
fd = open(test_dev.c_str(), O_CREAT); // 尝试打开/dev/hi_mipi设备文件
ASSERT_NE(fd, -1); // 断言打开文件操作成功(文件描述符不为-1
// 关闭文件描述符,释放资源
(void)close(fd); // 关闭文件
// 尝试删除之前创建的目录
ret = rmdir(path.c_str()); // 删除/proc/plimits/test目录
ASSERT_EQ(ret, 0); // 断言删除目录操作成功返回值为0
}

@ -28,38 +28,46 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <cstdio>
#include <unistd.h>
#include <cstdlib>
#include <fcntl.h>
#include <cstring>
#include <gtest/gtest.h>
#include "It_process_plimits.h"
#include <cstdio> // 引入标准输入输出库,提供文件操作、数据输入输出的功能
#include <unistd.h> // 引入POSIX操作系统API提供对POSIX操作系统API的访问如mkdir(), rmdir()等
#include <cstdlib> // 引入C标准库函数如exit(), malloc(), free()等(本例中未直接使用)
#include <fcntl.h> // 引入文件控制选项用于open()函数,定义文件打开模式
#include <cstring> // 引入字符串操作函数如memset(), strcmp()等(本例中未直接使用)
#include <gtest/gtest.h> // 引入Google Test框架用于单元测试提供断言宏如ASSERT_EQ(), ASSERT_NE()
#include "It_process_plimits.h" // 引入自定义头文件可能包含测试所需的声明或定义如WriteFile()函数
// 定义测试函数ItProcessPlimitsDevices005
void ItProcessPlimitsDevices005(void)
{
int fd;
int ret;
mode_t mode;
std::string test_dev = "/dev/mem";
std::string device_a = "a * rwm";
std::string device_c = "c * rwm";
std::string path = "/proc/plimits/test";
std::string devicesDenyPath = "/proc/plimits/test/devices.deny";
std::string devicesAllowPath = "/proc/plimits/test/devices.allow";
ret = mkdir(path.c_str(), S_IFDIR | mode);
ASSERT_EQ(ret, 0);
ret = WriteFile(devicesDenyPath.c_str(), device_a.c_str());
ASSERT_NE(ret, -1);
ret = WriteFile(devicesAllowPath.c_str(), device_c.c_str());
ASSERT_NE(ret, -1);
fd = open(test_dev.c_str(), O_RDWR|O_CREAT);
ASSERT_NE(fd, -1);
(void)close(fd);
ret = rmdir(path.c_str());
ASSERT_EQ(ret, 0);
int fd; // 声明文件描述符变量,用于存储打开文件的引用
int ret; // 声明返回值变量,用于存储函数调用的结果
mode_t mode; // 声明文件模式变量,但此处未初始化,存在潜在问题
std::string test_dev = "/dev/mem"; // 定义测试设备文件路径,/dev/mem是内存设备文件
std::string device_a = "a * rwm"; // 定义设备访问控制规则,允许所有用户(a *) 对设备进行读写(rwm)操作
std::string device_c = "c * rwm"; // 定义设备访问控制规则但这里的c可能表示某个特定用户组具体含义取决于系统配置
std::string path = "/proc/plimits/test"; // 定义测试目录路径
std::string devicesDenyPath = "/proc/plimits/test/devices.deny"; // 定义设备拒绝列表文件路径
std::string devicesAllowPath = "/proc/plimits/test/devices.allow"; // 定义设备允许列表文件路径
// 尝试创建目录但mode未初始化此处存在潜在问题应直接使用权限位如0755
// 注意S_IFDIR用于mkdir的第二个参数时通常不需要因为mkdir默认创建目录
ret = mkdir(path.c_str(), S_IFDIR | mode); // 尝试创建/proc/plimits/test目录
ASSERT_EQ(ret, 0); // 断言创建目录操作成功返回值为0
// 尝试将设备拒绝规则写入devices.deny文件WriteFile函数未在代码中定义可能是自定义函数
ret = WriteFile(devicesDenyPath.c_str(), device_a.c_str()); // 写入拒绝规则,禁止所有用户读写/dev/mem但此规则可能因device_c的允许规则而被覆盖
ASSERT_NE(ret, -1); // 断言写入操作成功(返回值不为-1
// 尝试将设备允许规则写入devices.allow文件
ret = WriteFile(devicesAllowPath.c_str(), device_c.c_str()); // 写入允许规则,允许某个用户组(c)读写/dev/mem
ASSERT_NE(ret, -1); // 断言写入操作成功(返回值不为-1
// 尝试以读写模式打开测试设备文件/dev/mem
fd = open(test_dev.c_str(), O_RDWR|O_CREAT); // 尝试打开/dev/mem设备文件O_RDWR表示读写模式O_CREAT表示如果文件不存在则创建
ASSERT_NE(fd, -1); // 断言打开文件操作成功(文件描述符不为-1
// 关闭文件描述符,释放资源
(void)close(fd); // 关闭文件
// 尝试删除之前创建的目录
ret = rmdir(path.c_str()); // 删除/proc/plimits/test目录
ASSERT_EQ(ret, 0); // 断言删除目录操作成功返回值为0
}

@ -28,38 +28,46 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <cstdio>
#include <unistd.h>
#include <cstdlib>
#include <fcntl.h>
#include <cstring>
#include <gtest/gtest.h>
#include "It_process_plimits.h"
#include <cstdio> // 引入标准输入输出库,提供文件操作、数据输入输出的功能
#include <unistd.h> // 引入POSIX操作系统API提供对POSIX操作系统API的访问如mkdir(), rmdir()等
#include <cstdlib> // 引入C标准库函数如exit(), malloc(), free()等(本例中未直接使用)
#include <fcntl.h> // 引入文件控制选项用于open()函数,定义文件打开模式
#include <cstring> // 引入字符串操作函数如memset(), strcmp()等(本例中未直接使用)
#include <gtest/gtest.h> // 引入Google Test框架用于单元测试提供断言宏如ASSERT_EQ(), ASSERT_NE()
#include "It_process_plimits.h" // 引入自定义头文件可能包含测试所需的声明或定义如WriteFile()函数
// 定义测试函数ItProcessPlimitsDevices006
void ItProcessPlimitsDevices006(void)
{
int fd;
int ret;
mode_t mode;
std::string test_dev = "/dev/mem";
std::string device_a = "a * rwm";
std::string device_c_r = "c * r";
std::string path = "/proc/plimits/test";
std::string devicesDenyPath = "/proc/plimits/test/devices.deny";
std::string devicesAllowPath = "/proc/plimits/test/devices.allow";
ret = mkdir(path.c_str(), S_IFDIR | mode);
ASSERT_EQ(ret, 0);
ret = WriteFile(devicesDenyPath.c_str(), device_a.c_str());
ASSERT_NE(ret, -1);
ret = WriteFile(devicesAllowPath.c_str(), device_c_r.c_str());
ASSERT_NE(ret, -1);
fd = open(test_dev.c_str(), O_RDONLY);
ASSERT_NE(fd, -1);
(void)close(fd);
ret = rmdir(path.c_str());
ASSERT_EQ(ret, 0);
int fd; // 声明文件描述符变量,用于存储打开文件的引用
int ret; // 声明返回值变量,用于存储函数调用的结果
mode_t mode; // 声明文件模式变量,但此处未初始化,存在潜在问题
std::string test_dev = "/dev/mem"; // 定义测试设备文件路径,/dev/mem是内存设备文件
std::string device_a = "a * rwm"; // 定义设备访问控制规则,允许所有用户(a *) 对设备进行读写内存(rwm)操作
std::string device_c_r = "c * r"; // 定义设备访问控制规则,允许某个用户组(c *) 仅读内存(r)操作
std::string path = "/proc/plimits/test"; // 定义测试目录路径
std::string devicesDenyPath = "/proc/plimits/test/devices.deny"; // 定义设备拒绝列表文件路径
std::string devicesAllowPath = "/proc/plimits/test/devices.allow"; // 定义设备允许列表文件路径
// 尝试创建目录但mode未初始化此处存在潜在问题应直接使用权限位如0755
// 注意S_IFDIR用于mkdir的第二个参数时通常不需要因为mkdir默认创建目录
ret = mkdir(path.c_str(), S_IFDIR | mode); // 尝试创建/proc/plimits/test目录但mode未初始化可能导致行为不确定
ASSERT_EQ(ret, 0); // 断言创建目录操作成功返回值为0
// 尝试将设备拒绝规则写入devices.deny文件WriteFile函数未在代码中定义可能是自定义函数
ret = WriteFile(devicesDenyPath.c_str(), device_a.c_str()); // 写入拒绝规则,禁止所有用户组(a *)读写/dev/mem但此规则可能因device_c_r的允许规则而被覆盖若系统支持此类覆盖
ASSERT_NE(ret, -1); // 断言写入操作成功(返回值不为-1
// 尝试将设备允许规则写入devices.allow文件
ret = WriteFile(devicesAllowPath.c_str(), device_c_r.c_str()); // 写入允许规则,允许某个用户组(c *)仅读/dev/mem
ASSERT_NE(ret, -1); // 断言写入操作成功(返回值不为-1
// 尝试以只读模式打开测试设备文件/dev/mem
fd = open(test_dev.c_str(), O_RDONLY); // 尝试打开/dev/mem设备文件O_RDONLY表示只读模式
ASSERT_NE(fd, -1); // 断言打开文件操作成功(文件描述符不为-1根据之前的规则这里应该成功因为允许了读操作
// 关闭文件描述符,释放资源
(void)close(fd); // 关闭文件
// 尝试删除之前创建的目录
ret = rmdir(path.c_str()); // 删除/proc/plimits/test目录
ASSERT_EQ(ret, 0); // 断言删除目录操作成功返回值为0
}

@ -28,38 +28,51 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <cstdio>
#include <unistd.h>
#include <cstdlib>
#include <fcntl.h>
#include <cstring>
#include <gtest/gtest.h>
#include "It_process_plimits.h"
#include <cstdio> // 引入标准输入输出库,提供文件操作、数据输入输出的功能
#include <unistd.h> // 引入POSIX操作系统API提供对POSIX操作系统API的访问如mkdir(), rmdir()等
#include <cstdlib> // 引入C标准库函数如exit(), malloc(), free()等(本例中未直接使用)
#include <fcntl.h> // 引入文件控制选项用于open()函数,定义文件打开模式
#include <cstring> // 引入字符串操作函数如memset(), strcmp()等(本例中未直接使用)
#include <gtest/gtest.h> // 引入Google Test框架用于单元测试提供断言宏如ASSERT_EQ(), ASSERT_NE()
#include "It_process_plimits.h" // 引入自定义头文件可能包含测试所需的声明或定义如WriteFile()函数
// 定义测试函数ItProcessPlimitsDevices007
void ItProcessPlimitsDevices007(void)
{
int fd;
int ret;
mode_t mode;
std::string test_dev = "/dev/mem";
std::string device_a = "a * rwm";
std::string device_c_w = "c * w";
std::string path = "/proc/plimits/test";
std::string devicesDenyPath = "/proc/plimits/test/devices.deny";
std::string devicesAllowPath = "/proc/plimits/test/devices.allow";
ret = mkdir(path.c_str(), S_IFDIR | mode);
ASSERT_EQ(ret, 0);
ret = WriteFile(devicesDenyPath.c_str(), device_a.c_str());
ASSERT_NE(ret, -1);
ret = WriteFile(devicesAllowPath.c_str(), device_c_w.c_str());
ASSERT_NE(ret, -1);
fd = open(test_dev.c_str(), O_WRONLY);
ASSERT_NE(fd, -1);
(void)close(fd);
ret = rmdir(path.c_str());
ASSERT_EQ(ret, 0);
int fd; // 声明文件描述符变量,用于存储打开文件的引用
int ret; // 声明返回值变量,用于存储函数调用的结果
mode_t mode; // 声明文件模式变量但此处未初始化存在潜在问题应与mkdir的权限位一起初始化
std::string test_dev = "/dev/mem"; // 定义测试设备文件路径,/dev/mem是内存设备文件
std::string device_a = "a * rwm"; // 定义设备访问控制规则,允许所有用户(a *) 对设备进行读写内存(rwm)操作
std::string device_c_w = "c * w"; // 定义设备访问控制规则,允许某个用户组(c *) 仅写内存(w)操作
std::string path = "/proc/plimits/test"; // 定义测试目录路径
std::string devicesDenyPath = "/proc/plimits/test/devices.deny"; // 定义设备拒绝列表文件路径
std::string devicesAllowPath = "/proc/plimits/test/devices.allow"; // 定义设备允许列表文件路径
// 尝试创建目录但mode未初始化此处存在潜在问题应直接使用权限位如0755
// 注意S_IFDIR用于mkdir的第二个参数时通常不需要因为mkdir默认创建目录
// 正确的做法应该是ret = mkdir(path.c_str(), 0755); 假设需要755权限
ret = mkdir(path.c_str(), S_IFDIR | mode); // 尝试创建/proc/plimits/test目录但mode未初始化可能导致行为不确定
ASSERT_EQ(ret, 0); // 断言创建目录操作成功返回值为0
// 尝试将设备拒绝规则写入devices.deny文件WriteFile函数未在代码中定义可能是自定义函数
ret = WriteFile(devicesDenyPath.c_str(), device_a.c_str()); // 写入拒绝规则,禁止所有用户组(a *)进行某些操作但可能会被devicesAllowPath中的规则覆盖
ASSERT_NE(ret, -1); // 断言写入操作成功(返回值不为-1
// 尝试将设备允许规则写入devices.allow文件
ret = WriteFile(devicesAllowPath.c_str(), device_c_w.c_str()); // 写入允许规则,允许某个用户组(c *)仅写/dev/mem
ASSERT_NE(ret, -1); // 断言写入操作成功(返回值不为-1
// 尝试以只写模式打开测试设备文件/dev/mem
// 注意:通常/dev/mem不允许普通用户写操作且此处的规则设置可能存在冲突deny中允许rwmallow中仅允许w
// 但根据测试目的,这里关注的是访问控制规则的应用,而非实际写操作的成功与否
fd = open(test_dev.c_str(), O_WRONLY); // 尝试打开/dev/mem设备文件O_WRONLY表示只写模式
// 此处断言可能失败,因为/dev/mem通常不允许普通用户写操作且即使允许也可能因为系统策略或权限问题而失败
// 但由于测试关注的是访问控制逻辑,假设系统允许此类测试(例如,在测试环境中/dev/mem的权限被放宽
ASSERT_NE(fd, -1); // 断言打开文件操作成功(文件描述符不为-1这里可能存在实际测试中的不匹配
// 关闭文件描述符,释放资源
(void)close(fd); // 关闭文件
// 尝试删除之前创建的目录
ret = rmdir(path.c_str()); // 删除/proc/plimits/test目录
ASSERT_EQ(ret, 0); // 断言删除目录操作成功返回值为0
}

@ -28,38 +28,54 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <cstdio>
#include <unistd.h>
#include <cstdlib>
#include <fcntl.h>
#include <cstring>
#include <gtest/gtest.h>
#include "It_process_plimits.h"
#include <cstdio> // 引入标准输入输出库,提供文件操作、数据输入输出的功能(本例中未直接使用)
#include <unistd.h> // 引入POSIX操作系统API提供对POSIX操作系统API的访问如mkdir(), rmdir()等
#include <cstdlib> // 引入C标准库函数如exit(), malloc(), free()等(本例中未直接使用)
#include <fcntl.h> // 引入文件控制选项用于open()函数,定义文件打开模式
#include <cstring> // 引入字符串操作函数如memset(), strcmp()等(本例中未直接使用)
#include <gtest/gtest.h> // 引入Google Test框架用于单元测试提供断言宏如ASSERT_EQ(), ASSERT_NE()
#include "It_process_plimits.h" // 引入自定义头文件可能包含测试所需的声明或定义如WriteFile()函数
// 定义测试函数ItProcessPlimitsDevices008
void ItProcessPlimitsDevices008(void)
{
int fd;
int ret;
mode_t mode;
std::string test_dev = "/dev/mem";
std::string device_a = "a * rwm";
std::string device_c_m = "c * rm";
std::string path = "/proc/plimits/test";
std::string devicesDenyPath = "/proc/plimits/test/devices.deny";
std::string devicesAllowPath = "/proc/plimits/test/devices.allow";
ret = mkdir(path.c_str(), S_IFDIR | mode);
ASSERT_EQ(ret, 0);
ret = WriteFile(devicesDenyPath.c_str(), device_a.c_str());
ASSERT_NE(ret, -1);
ret = WriteFile(devicesAllowPath.c_str(), device_c_m.c_str());
ASSERT_NE(ret, -1);
fd = open(test_dev.c_str(), O_CREAT, O_RDONLY);
ASSERT_NE(fd, -1);
(void)close(fd);
ret = rmdir(path.c_str());
ASSERT_EQ(ret, 0);
int fd; // 声明文件描述符变量,用于存储打开文件的引用
int ret; // 声明返回值变量,用于存储函数调用的结果
mode_t mode; // 声明文件模式变量但此处未初始化存在潜在问题应与mkdir的权限位一起初始化
std::string test_dev = "/dev/mem"; // 定义测试设备文件路径,/dev/mem是内存设备文件
std::string device_a = "a * rwm"; // 定义设备访问控制规则,允许所有用户(a *) 对设备进行读写内存(rwm)操作
std::string device_c_m = "c * rm"; // 定义设备访问控制规则,允许某个用户组(c *) 对设备进行读内存(r)和修改内存(m)操作但不允许写w
std::string path = "/proc/plimits/test"; // 定义测试目录路径
std::string devicesDenyPath = "/proc/plimits/test/devices.deny"; // 定义设备拒绝列表文件路径
std::string devicesAllowPath = "/proc/plimits/test/devices.allow"; // 定义设备允许列表文件路径
// 尝试创建目录但mode未初始化此处存在潜在问题应直接使用权限位如0755
// 注意S_IFDIR用于mkdir的第二个参数时通常不需要因为mkdir默认创建目录
// 正确的做法应该是ret = mkdir(path.c_str(), 0755); 假设需要755权限
// 但由于测试目的,我们假设这里关注的是目录的创建,而非具体权限
ret = mkdir(path.c_str(), S_IFDIR | mode); // 尝试创建/proc/plimits/test目录但mode未初始化可能导致行为不确定
ASSERT_EQ(ret, 0); // 断言创建目录操作成功返回值为0
// 尝试将设备拒绝规则写入devices.deny文件WriteFile函数未在代码中定义可能是自定义函数
// 注意:这里的拒绝规则实际上可能被后面的允许规则覆盖,因为通常允许规则优先级更高
ret = WriteFile(devicesDenyPath.c_str(), device_a.c_str()); // 写入拒绝规则,禁止(或尝试禁止,但可能被覆盖)所有用户组(a *)进行某些操作
ASSERT_NE(ret, -1); // 断言写入操作成功(返回值不为-1
// 尝试将设备允许规则写入devices.allow文件
ret = WriteFile(devicesAllowPath.c_str(), device_c_m.c_str()); // 写入允许规则,允许某个用户组(c *)进行读内存(r)和修改内存(m)操作
ASSERT_NE(ret, -1); // 断言写入操作成功(返回值不为-1
// 尝试以创建和只读模式打开测试设备文件/dev/mem
// 注意O_CREAT标志在这里是不必要的因为我们不是真的要创建/dev/mem这个文件
// O_RDONLY表示只读模式但/dev/mem通常不允许普通用户读操作除非系统策略被放宽
// 此处尝试打开文件主要是为了测试访问控制逻辑,而非实际读操作
fd = open(test_dev.c_str(), O_CREAT, O_RDONLY); // 尝试打开(并可能创建,但不应该创建/dev/mem/dev/mem设备文件O_RDONLY表示只读模式
// 此处断言可能失败,因为/dev/mem通常不允许普通用户读操作
// 但由于测试关注的是访问控制逻辑,并且假设系统允许此类测试(例如,在测试环境中/dev/mem的权限被放宽
ASSERT_NE(fd, -1); // 断言打开文件操作成功(文件描述符不为-1这里可能存在实际测试中的不匹配
// 关闭文件描述符,释放资源
(void)close(fd); // 关闭文件
// 尝试删除之前创建的目录
ret = rmdir(path.c_str()); // 删除/proc/plimits/test目录
ASSERT_EQ(ret, 0); // 断言删除目录操作成功返回值为0
}

@ -28,38 +28,52 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <cstdio>
#include <unistd.h>
#include <cstdlib>
#include <fcntl.h>
#include <cstring>
#include <gtest/gtest.h>
#include "It_process_plimits.h"
#include <cstdio> // 引入标准输入输出库(本例中未直接使用)
#include <unistd.h> // 引入POSIX操作系统API提供mkdir(), rmdir()等函数
#include <cstdlib> // 引入C标准库函数本例中未直接使用
#include <fcntl.h> // 引入文件控制选项用于open()函数
#include <cstring> // 引入字符串操作函数(本例中未直接使用)
#include <gtest/gtest.h> // 引入Google Test框架提供断言宏
#include "It_process_plimits.h" // 引入自定义头文件可能包含WriteFile()等函数的声明
// 定义测试函数ItProcessPlimitsDevices009
void ItProcessPlimitsDevices009(void)
{
int fd;
int ret;
mode_t mode;
std::string test_dev = "/dev/hi_mipi";
std::string device_a = "a";
std::string path = "/proc/plimits/test";
std::string devicesDenyPath = "/proc/plimits/test/devices.deny";
ret = mkdir(path.c_str(), S_IFDIR | mode);
ASSERT_EQ(ret, 0);
ret = WriteFile(devicesDenyPath.c_str(), device_a.c_str());
ASSERT_NE(ret, -1);
fd = open(test_dev.c_str(), O_RDONLY|O_CREAT);
ASSERT_EQ(fd, -1);
(void)close(fd);
fd = open(test_dev.c_str(), O_WRONLY|O_CREAT);
ASSERT_EQ(fd, -1);
(void)close(fd);
ret = rmdir(path.c_str());
ASSERT_EQ(ret, 0);
int fd; // 声明文件描述符变量
int ret; // 声明返回值变量,用于存储函数调用的结果
mode_t mode; // 声明文件模式变量,但此处未初始化,存在潜在问题
std::string test_dev = "/dev/hi_mipi"; // 定义测试设备文件路径
std::string device_a = "a"; // 定义设备访问控制规则,但此处规则不完整(通常应包含用户组和权限,如"a * rwm"
std::string path = "/proc/plimits/test"; // 定义测试目录路径
std::string devicesDenyPath = "/proc/plimits/test/devices.deny"; // 定义设备拒绝列表文件路径
// 尝试创建目录但mode未初始化可能导致行为不确定
// 正确的做法是指定一个明确的权限位如0755但此处我们假设关注的是目录的创建
ret = mkdir(path.c_str(), S_IFDIR | mode); // 尝试创建/proc/plimits/test目录
ASSERT_EQ(ret, 0); // 断言创建目录操作成功返回值为0
// 尝试将设备拒绝规则写入devices.deny文件但device_a规则不完整
// WriteFile函数未在代码中定义可能是自定义函数
ret = WriteFile(devicesDenyPath.c_str(), device_a.c_str()); // 写入拒绝规则(但规则可能不完整或无效)
ASSERT_NE(ret, -1); // 断言写入操作成功(返回值不为-1
// 尝试以只读模式打开测试设备文件/dev/hi_mipi并尝试创建如果文件不存在
// 但由于前面设置了拒绝规则(尽管不完整),预期打开操作会失败
fd = open(test_dev.c_str(), O_RDONLY|O_CREAT); // 尝试打开(并可能创建)/dev/hi_mipi设备文件只读模式
// 断言打开操作失败(文件描述符为-1因为设备被拒绝访问
ASSERT_EQ(fd, -1); // 断言打开文件操作失败
// 注意这里的close调用是多余的因为fd为-1不是有效的文件描述符
// 但为了代码的整洁性和避免潜在警告,仍然保留(void)close(fd);
(void)close(fd); // 尝试关闭文件(但实际上是多余的)
// 尝试以只写模式打开测试设备文件/dev/hi_mipi并尝试创建如果文件不存在
// 同样,由于前面设置了拒绝规则,预期打开操作会失败
fd = open(test_dev.c_str(), O_WRONLY|O_CREAT); // 尝试打开(并可能创建)/dev/hi_mipi设备文件只写模式
// 断言打开操作失败(文件描述符为-1因为设备被拒绝访问
ASSERT_EQ(fd, -1); // 断言打开文件操作失败
(void)close(fd); // 尝试关闭文件(但实际上是多余的)
// 尝试删除之前创建的目录
ret = rmdir(path.c_str()); // 删除/proc/plimits/test目录
ASSERT_EQ(ret, 0); // 断言删除目录操作成功返回值为0
}

@ -28,71 +28,74 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "pthread.h"
#include "linux/capability.h"
#include <sys/capability.h>
#include "it_test_capability.h"
#include <signal.h>
#include <sys/types.h>
#include <time.h>
#define CAP_NUM 2
#define INVAILD_PID 65535
#define CHANGE_CHILD_UID 1000
#include "pthread.h" // 引入POSIX线程库用于多线程编程
#include "linux/capability.h" // 引入Linux能力capabilities定义用于权限控制
#include <sys/capability.h> // 引入系统能力接口
#include "it_test_capability.h" // 假设是测试框架或测试相关的头文件
#include <signal.h> // 引入信号处理函数
#include <sys/types.h> // 引入基本数据类型
#include <time.h> // 引入时间处理函数
#define CAP_NUM 2 // 定义能力数组的大小
#define INVAILD_PID 65535 // 定义一个无效的进程ID
#define CHANGE_CHILD_UID 1000 // 定义子进程要更改的用户ID
// 信号处理函数,当前为空实现
static void Sigac(int param)
{
return;
}
// 子进程函数
static void Child()
{
int i = 10;
signal(25, Sigac);
while (i--) {
int i = 10; // 循环计数器
signal(25, Sigac); // 设置信号25的处理函数为Sigac
while (i--) { // 循环10次每次睡眠1秒
sleep(1);
}
//sleep for 10 second and exit;
// 睡眠10秒后退出
exit(0);
}
// 测试子进程的函数
static int TestChild(VOID)
{
struct __user_cap_header_struct capheader;
struct __user_cap_data_struct capdata[CAP_NUM];
struct __user_cap_data_struct capdatac[CAP_NUM];
struct timespec tp;
int ret
//originalize struct
(void)memset_s(&capheader, sizeof(struct __user_cap_header_struct), 0, sizeof(struct __user_cap_header_struct));
(void)memset_s(capdata, CAP_NUM * sizeof(struct __user_cap_data_struct), 0,
CAP_NUM * sizeof(struct __user_cap_data_struct));
capdata[0].permitted = 0xffffffff;
capdata[1].permitted = 0xffffffff;
capheader.version = _LINUX_CAPABILITY_VERSION_3;
//set capbility to effective
capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SETPCAP);
capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SETUID);
capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_KILL);
capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SYS_TIME);
capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SYS_NICE);
//use capset to check and get info
struct __user_cap_header_struct capheader; // 定义能力头部结构体
struct __user_cap_data_struct capdata[CAP_NUM]; // 定义能力数据结构体数组
struct __user_cap_data_struct capdatac[CAP_NUM]; // 定义另一个能力数据结构体数组,用于获取当前能力
struct timespec tp; // 定义时间结构体
int ret; // 定义返回值变量,此处漏写了初始化
// 初始化结构体
(void)memset_s(&capheader, sizeof(struct __user_cap_header_struct), 0, sizeof(struct __user_cap_header_struct)); // 清零能力头部结构体
(void)memset_s(capdata, CAP_NUM * sizeof(struct __user_cap_data_struct), 0, CAP_NUM * sizeof(struct __user_cap_data_struct)); // 清零能力数据结构体数组
capdata[0].permitted = 0xffffffff; // 设置允许的所有能力为全开
capdata[1].permitted = 0xffffffff; // 同上,第二个数据结构体也全开(虽然只用一个)
capheader.version = _LINUX_CAPABILITY_VERSION_3; // 设置能力版本
// 设置能力的有效位
capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SETPCAP); // 允许修改进程能力
capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SETUID); // 允许改变用户ID
capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_KILL); // 允许发送信号
capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SYS_TIME); // 允许改变系统时间
capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SYS_NICE); // 允许改变调度优先级
// 使用capset设置能力并检查返回值
ret = capset(&capheader, &capdata[0]);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
ret = capget(&capheader, &capdatac[0]);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
capheader.pid = INVAILD_PID;
ret = capget(&capheader, &capdatac[0]);
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
errno = 0;
capheader.pid = 3;
kill(capheader.pid, 0);
if (errno != ESRCH) {
ret = capget(&capheader, &capdatac[0]);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
printf("e %d,p %d\n", capdatac[0].effective, capdatac[0].permitted);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 断言capset返回0表示成功
ret = capget(&capheader, &capdatac[0]); // 获取当前能力
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 断言capget返回0表示成功
capheader.pid = INVAILD_PID; // 设置一个无效的PID
ret = capget(&capheader, &capdatac[0]); // 尝试获取无效PID的能力
ICUNIT_ASSERT_EQUAL(ret, -1, ret); // 断言返回-1表示失败
errno = 0; // 重置errno
capheader.pid = 3; // 设置PID为3
kill(capheader.pid, 0); // 检查PID是否存在
if (errno != ESRCH) { // 如果PID存在
ret = capget(&capheader, &capdatac[0]); // 获取能力
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 断言成功
printf("e %d,p %d\n", capdatac[0].effective, capdatac[0].permitted); // 打印有效和允许的能力
}
// 类似地检查PID 4, 5, 6
errno = 0;
capheader.pid = 4;
kill(capheader.pid, 0);
@ -117,39 +120,42 @@ static int TestChild(VOID)
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
printf("e %d,p %d\n", capdatac[0].effective, capdatac[0].permitted);
}
capheader.pid = 0;
//try reset UID
int pid = fork();
if (pid == 0) {
ret = setuid(CHANGE_CHILD_UID);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
Child();
capheader.pid = 0; // 重置PID为0当前进程
// 尝试重置子进程的UID
int pid = fork(); // 创建子进程
if (pid == 0) { // 如果是子进程
ret = setuid(CHANGE_CHILD_UID); // 尝试改变用户ID
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 断言成功
Child(); // 执行子进程函数
}
sleep(1);
ret = kill(pid, SIGXFSZ);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
sleep(1); // 父进程等待1秒
ret = kill(pid, SIGXFSZ); // 尝试发送SIGXFSZ信号给子进程
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 断言成功
// 移除KILL能力并再次尝试发送信号应该失败
capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective &= ~CAP_TO_MASK(CAP_KILL);
ret = capset(&capheader, &capdata[0]);
ret = kill(pid, SIGXFSZ);
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
tp.tv_sec = 0;
tp.tv_nsec = 0;
ret = clock_settime(CLOCK_REALTIME, &tp);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective &= ~CAP_TO_MASK(CAP_SYS_TIME);
ret = capset(&capheader, &capdata[0]);
ret = clock_settime(CLOCK_REALTIME, &tp);
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
struct sched_param param = { 0 };
ret = sched_getparam(pid, &param);
param.sched_priority--;
ret = sched_setparam(pid, &param);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective &= ~CAP_TO_MASK(CAP_SYS_NICE);
ret = capset(&capheader, &capdata[0]);
ret = sched_setparam(pid, &param);
ret = capset(&capheader, &capdata[0]); // 更新能力
ret = kill(pid, SIGXFSZ); // 再次尝试发送信号
ICUNIT_ASSERT_EQUAL(ret, -1, ret); // 断言失败
// 尝试设置系统时间应该成功然后失败移除SYS_TIME能力
tp.tv_sec = 0; // 设置时间为0
tp.tv_nsec = 0; // 纳秒部分也设置为0
ret = clock_settime(CLOCK_REALTIME, &tp); // 尝试设置时间
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 断言成功
capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective &= ~CAP_TO_MASK(CAP_SYS_TIME); // 移除SYS_TIME能力
ret = capset(&capheader, &capdata[0]); // 更新能力
ret = clock_settime(CLOCK_REALTIME, &tp); // 再次尝试设置时间
ICUNIT_ASSERT_EQUAL(ret, -1, ret); // 断言失败
// 尝试改变子进程的调度优先级应该成功然后失败移除SYS_NICE能力
struct sched_param param = { 0 }; // 定义调度参数结构体
ret = sched_getparam(pid, &param); // 获取当前调度参数
param.sched_priority--; // 降低优先级
ret = sched_setparam(pid, &param); // 尝试设置新的调度参数
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 断言成功
capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective &= ~CAP_TO_MASK(CAP_SYS_NICE); // 移除SYS_NICE能力
ret = capset(&capheader, &capdata[0]); // 更新能力
ret = sched_setparam(pid, &param); // 再次尝试设置调度参数
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
wait(nullptr);
exit(92);

@ -0,0 +1,141 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "it_pthread_test.h" // 引入测试头文件
// 全局变量定义
static pthread_mutex_t g_pthreadMuxTest1; // 互斥锁
static pthread_cond_t g_pthrdCondTest1; // 条件变量
static unsigned int g_pthreadExit = 0; // 控制线程退出的标志
// 线程函数1模拟一个消费者
static void *PthreadF01(void *t)
{
int rc;
unsigned int count = 0;
const int testLoop = 2000; // 循环次数为2000
// 循环2000次进行条件变量等待和互斥锁操作
while (count < testLoop) {
// 加锁
rc = pthread_mutex_lock(&g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); // 判断加锁是否成功失败则跳转到EXIT
// 等待条件变量,释放互斥锁并进入阻塞状态,直到条件变量通知
rc = pthread_cond_wait(&g_pthrdCondTest1, &g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
// 解锁
rc = pthread_mutex_unlock(&g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
count++; // 增加计数器
}
// 设置退出标志
g_pthreadExit = 1;
EXIT:
return NULL; // 线程函数结束
}
// 线程函数2模拟一个生产者
static void *PthreadF02(void *t)
{
int rc;
// 当g_pthreadExit不为1时继续循环发送信号
while (g_pthreadExit != 1) {
// 加锁
rc = pthread_mutex_lock(&g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); // 判断加锁是否成功失败则跳转到EXIT
// 发送信号,通知一个等待的线程
rc = pthread_cond_signal(&g_pthrdCondTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
// 解锁
rc = pthread_mutex_unlock(&g_pthreadMuxTest1);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT);
}
EXIT:
pthread_exit(NULL); // 线程退出
}
// 测试用例
static unsigned int TestCase(void)
{
int i;
long t1 = 1; // 线程1的标识
long t2 = 2; // 线程2的标识
int rc;
pthread_t threads[3]; // 创建3个线程
pthread_attr_t attr; // 线程属性
const int loopNum = 2; // 循环创建和等待线程次数
g_pthreadExit = 0; // 初始化退出标志
g_testCount = 0; // 初始化测试计数器
// 初始化互斥锁和条件变量
pthread_mutex_init(&g_pthreadMuxTest1, NULL);
pthread_cond_init(&g_pthrdCondTest1, NULL);
// 创建线程1 (消费者)
rc = pthread_create(&threads[0], NULL, PthreadF01, (void *)t1);
ICUNIT_ASSERT_EQUAL(rc, 0, rc); // 确认线程创建成功
// 创建线程2 (生产者)
rc = pthread_create(&threads[1], NULL, PthreadF02, (void *)t2);
ICUNIT_ASSERT_EQUAL(rc, 0, rc); // 确认线程创建成功
// 等待线程1和线程2执行完毕
for (i = 0; i < loopNum; i++) {
rc = pthread_join(threads[i], NULL);
ICUNIT_ASSERT_EQUAL(rc, 0, rc); // 确认线程结束
}
// 销毁线程属性、互斥锁和条件变量
rc = pthread_attr_destroy(&attr);
ICUNIT_ASSERT_EQUAL(rc, 0, rc); // 确认销毁线程属性成功
rc = pthread_mutex_destroy(&g_pthreadMuxTest1);
ICUNIT_ASSERT_EQUAL(rc, 0, rc); // 确认销毁互斥锁成功
rc = pthread_cond_destroy(&g_pthrdCondTest1);
ICUNIT_ASSERT_EQUAL(rc, 0, rc); // 确认销毁条件变量成功
return 0; // 返回0表示测试通过
}
// 测试入口函数
void ItTestPthreadCond002(void)
{
TEST_ADD_CASE("IT_POSIX_PTHREAD_COND_002", TestCase, TEST_POSIX, TEST_PTHREAD, TEST_LEVEL2, TEST_FUNCTION);
}

Binary file not shown.
Loading…
Cancel
Save