feat: 支持网络容器
BREAKING CHANGE: 支持网络容器对外变更: 1.支持网络容器 2.setns, clone, unshare接口支持CLONE_NEWNET Close #I6HPH2 Signed-off-by: zhushengle <zhushengle@huawei.com> Change-Id: Ibaa11056982d465d4006680c8d3fa4ae2b9f25b5
This commit is contained in:
@@ -50,6 +50,9 @@ config("container_config") {
|
||||
if (defined(LOSCFG_USER_TEST_USER_CONTAINER)) {
|
||||
cflags += [ "-DLOSCFG_USER_TEST_USER_CONTAINER" ]
|
||||
}
|
||||
if (defined(LOSCFG_USER_TEST_NET_CONTAINER)) {
|
||||
cflags += [ "-DLOSCFG_USER_TEST_NET_CONTAINER" ]
|
||||
}
|
||||
cflags_cc = cflags
|
||||
}
|
||||
|
||||
|
||||
@@ -181,7 +181,151 @@ HWTEST_F(ContainerTest, ItContainer001, TestSize.Level0)
|
||||
{
|
||||
ItContainer001();
|
||||
}
|
||||
#if defined(LOSCFG_USER_TEST_NET_CONTAINER)
|
||||
/**
|
||||
* @tc.name: Container_NET_Test_001
|
||||
* @tc.desc: uts container function test case
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: issueI6HPH2
|
||||
* @tc.author:
|
||||
*/
|
||||
HWTEST_F(ContainerTest, ItNetContainer001, TestSize.Level0)
|
||||
{
|
||||
ItNetContainer001();
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: Container_NET_Test_002
|
||||
* @tc.desc: uts container function test case
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: issueI6HPH2
|
||||
* @tc.author:
|
||||
*/
|
||||
HWTEST_F(ContainerTest, ItNetContainer002, TestSize.Level0)
|
||||
{
|
||||
ItNetContainer002();
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: Container_NET_Test_003
|
||||
* @tc.desc: uts container function test case
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: issueI6HPH2
|
||||
* @tc.author:
|
||||
*/
|
||||
HWTEST_F(ContainerTest, ItNetContainer003, TestSize.Level0)
|
||||
{
|
||||
ItNetContainer003();
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: Container_NET_Test_004
|
||||
* @tc.desc: uts container function test case
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: issueI6HPH2
|
||||
* @tc.author:
|
||||
*/
|
||||
HWTEST_F(ContainerTest, ItNetContainer004, TestSize.Level0)
|
||||
{
|
||||
ItNetContainer004();
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: Container_NET_Test_005
|
||||
* @tc.desc: uts container function test case
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: issueI6HPH2
|
||||
* @tc.author:
|
||||
*/
|
||||
HWTEST_F(ContainerTest, ItNetContainer005, TestSize.Level0)
|
||||
{
|
||||
ItNetContainer005();
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: Container_NET_Test_006
|
||||
* @tc.desc: uts container function test case
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: issueI6HPH2
|
||||
* @tc.author:
|
||||
*/
|
||||
HWTEST_F(ContainerTest, ItNetContainer006, TestSize.Level0)
|
||||
{
|
||||
ItNetContainer006();
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: Container_NET_Test_007
|
||||
* @tc.desc: uts container function test case
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: issueI6HPH2
|
||||
* @tc.author:
|
||||
*/
|
||||
HWTEST_F(ContainerTest, ItNetContainer007, TestSize.Level0)
|
||||
{
|
||||
ItNetContainer007();
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: Container_NET_Test_008
|
||||
* @tc.desc: uts container function test case
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: issueI6HPH2
|
||||
* @tc.author:
|
||||
*/
|
||||
HWTEST_F(ContainerTest, ItNetContainer008, TestSize.Level0)
|
||||
{
|
||||
ItNetContainer008();
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: Container_NET_Test_009
|
||||
* @tc.desc: uts container function test case
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: issueI6HPH2
|
||||
* @tc.author:
|
||||
*/
|
||||
HWTEST_F(ContainerTest, ItNetContainer009, TestSize.Level0)
|
||||
{
|
||||
ItNetContainer009();
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: Container_NET_Test_010
|
||||
* @tc.desc: uts container function test case
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: issueI6HPH2
|
||||
* @tc.author:
|
||||
*/
|
||||
HWTEST_F(ContainerTest, ItNetContainer010, TestSize.Level0)
|
||||
{
|
||||
ItNetContainer010();
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: Container_NET_Test_011
|
||||
* @tc.desc: uts container function test case
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: issueI6HPH2
|
||||
* @tc.author:
|
||||
*/
|
||||
HWTEST_F(ContainerTest, ItNetContainer011, TestSize.Level0)
|
||||
{
|
||||
ItNetContainer011();
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: Container_NET_Test_012
|
||||
* @tc.desc: uts container function test case
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: issueI6HPH2
|
||||
* @tc.author:
|
||||
*/
|
||||
HWTEST_F(ContainerTest, ItNetContainer012, TestSize.Level0)
|
||||
{
|
||||
ItNetContainer012();
|
||||
}
|
||||
#endif
|
||||
#if defined(LOSCFG_USER_TEST_USER_CONTAINER)
|
||||
/**
|
||||
* @tc.name: Container_UTS_Test_001
|
||||
|
||||
@@ -220,5 +220,16 @@ void ItPidContainer021(void);
|
||||
void ItPidContainer022(void);
|
||||
void ItPidContainer024(void);
|
||||
void ItUtsContainer003(void);
|
||||
|
||||
void ItNetContainer001(void);
|
||||
void ItNetContainer002(void);
|
||||
void ItNetContainer003(void);
|
||||
void ItNetContainer004(void);
|
||||
void ItNetContainer005(void);
|
||||
void ItNetContainer006(void);
|
||||
void ItNetContainer007(void);
|
||||
void ItNetContainer008(void);
|
||||
void ItNetContainer009(void);
|
||||
void ItNetContainer010(void);
|
||||
void ItNetContainer011(void);
|
||||
void ItNetContainer012(void);
|
||||
#endif /* _IT_CONTAINER_TEST_H */
|
||||
|
||||
@@ -149,3 +149,19 @@ if (defined(LOSCFG_USER_TEST_USER_CONTAINER)) {
|
||||
sources_full +=
|
||||
[ "$TEST_UNITTEST_DIR/container/full/It_user_container_005.cpp" ]
|
||||
}
|
||||
if (defined(LOSCFG_USER_TEST_NET_CONTAINER)) {
|
||||
sources_smoke += [
|
||||
"$TEST_UNITTEST_DIR/container/smoke/It_net_container_001.cpp",
|
||||
"$TEST_UNITTEST_DIR/container/smoke/It_net_container_002.cpp",
|
||||
"$TEST_UNITTEST_DIR/container/smoke/It_net_container_003.cpp",
|
||||
"$TEST_UNITTEST_DIR/container/smoke/It_net_container_004.cpp",
|
||||
"$TEST_UNITTEST_DIR/container/smoke/It_net_container_005.cpp",
|
||||
"$TEST_UNITTEST_DIR/container/smoke/It_net_container_006.cpp",
|
||||
"$TEST_UNITTEST_DIR/container/smoke/It_net_container_007.cpp",
|
||||
"$TEST_UNITTEST_DIR/container/smoke/It_net_container_008.cpp",
|
||||
"$TEST_UNITTEST_DIR/container/smoke/It_net_container_009.cpp",
|
||||
"$TEST_UNITTEST_DIR/container/smoke/It_net_container_010.cpp",
|
||||
"$TEST_UNITTEST_DIR/container/smoke/It_net_container_011.cpp",
|
||||
"$TEST_UNITTEST_DIR/container/smoke/It_net_container_012.cpp",
|
||||
]
|
||||
}
|
||||
|
||||
144
testsuites/unittest/container/smoke/It_net_container_001.cpp
Normal file
144
testsuites/unittest/container/smoke/It_net_container_001.cpp
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2023 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 <arpa/inet.h>
|
||||
#include <net/if.h>
|
||||
#include "It_container_test.h"
|
||||
|
||||
using namespace std;
|
||||
const int IpLen = 16;
|
||||
|
||||
static int GetLocalIP(char *ip)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
int inet_sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (inet_sock < 0) {
|
||||
return -1;
|
||||
}
|
||||
int ret = strcpy_s(ifr.ifr_name, sizeof(ifr.ifr_name), "eth0");
|
||||
if (ret != EOK) {
|
||||
(void)close(inet_sock);
|
||||
return -1;
|
||||
}
|
||||
ioctl(inet_sock, SIOCGIFADDR, &ifr);
|
||||
ret = strcpy_s(ip, IpLen, inet_ntoa((reinterpret_cast<struct sockaddr_in *>(&ifr.ifr_addr))->sin_addr));
|
||||
if (ret != EOK) {
|
||||
(void)close(inet_sock);
|
||||
return -1;
|
||||
}
|
||||
ret = close(inet_sock);
|
||||
if (ret != 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int SetIP(char *ip)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
|
||||
if (fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
int ret = strncpy_s(ifr.ifr_name, sizeof(ifr.ifr_name), "eth0", IFNAMSIZ);
|
||||
if (ret != EOK) {
|
||||
(void)close(fd);
|
||||
return -1;
|
||||
}
|
||||
ifr.ifr_addr.sa_family = AF_INET;
|
||||
inet_pton(AF_INET, ip, ifr.ifr_addr.sa_data + 2); /* 2: offset */
|
||||
ioctl(fd, SIOCSIFADDR, &ifr);
|
||||
ret = close(fd);
|
||||
if (ret != 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ChildFunc(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
int ret;
|
||||
char oldIp[IpLen] = {NULL};
|
||||
char newIp[IpLen] = {NULL};
|
||||
|
||||
ret = GetLocalIP(oldIp);
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_1;
|
||||
}
|
||||
|
||||
ret = SetIP("192.168.1.233");
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_2;
|
||||
}
|
||||
|
||||
ret = GetLocalIP(newIp);
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_3;
|
||||
}
|
||||
|
||||
ret = strcmp(oldIp, newIp);
|
||||
if (ret == 0) {
|
||||
return EXIT_CODE_ERRNO_4;
|
||||
}
|
||||
|
||||
printf("%s %d\n", __FUNCTION__, __LINE__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ItNetContainer001(void)
|
||||
{
|
||||
int ret;
|
||||
char oldIp[IpLen] = {NULL};
|
||||
char newIp[IpLen] = {NULL};
|
||||
|
||||
char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0);
|
||||
EXPECT_STRNE(stack, NULL);
|
||||
char *stackTop = stack + STACK_SIZE;
|
||||
|
||||
ret = GetLocalIP(oldIp);
|
||||
ASSERT_EQ(ret, 0);
|
||||
|
||||
int arg = CHILD_FUNC_ARG;
|
||||
auto pid = clone(ChildFunc, stackTop, SIGCHLD | CLONE_NEWNET, &arg);
|
||||
ASSERT_NE(pid, -1);
|
||||
|
||||
int status;
|
||||
ret = waitpid(pid, &status, 0);
|
||||
ASSERT_EQ(ret, pid);
|
||||
|
||||
int exitCode = WEXITSTATUS(status);
|
||||
ASSERT_EQ(exitCode, 0);
|
||||
|
||||
ret = GetLocalIP(newIp);
|
||||
ASSERT_EQ(ret, 0);
|
||||
|
||||
ret = strcmp(oldIp, newIp);
|
||||
ASSERT_EQ(ret, 0);
|
||||
}
|
||||
148
testsuites/unittest/container/smoke/It_net_container_002.cpp
Normal file
148
testsuites/unittest/container/smoke/It_net_container_002.cpp
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2023 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 <arpa/inet.h>
|
||||
#include <net/if.h>
|
||||
#include "It_container_test.h"
|
||||
|
||||
using namespace std;
|
||||
const int IpLen = 16;
|
||||
|
||||
static int GetLocalIP(char *ip)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
int inet_sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (inet_sock < 0) {
|
||||
return -1;
|
||||
}
|
||||
int ret = strcpy_s(ifr.ifr_name, sizeof(ifr.ifr_name), "eth0");
|
||||
if (ret != EOK) {
|
||||
(void)close(inet_sock);
|
||||
return -1;
|
||||
}
|
||||
ioctl(inet_sock, SIOCGIFADDR, &ifr);
|
||||
ret = strcpy_s(ip, IpLen, inet_ntoa((reinterpret_cast<struct sockaddr_in *>(&ifr.ifr_addr))->sin_addr));
|
||||
if (ret != EOK) {
|
||||
(void)close(inet_sock);
|
||||
return -1;
|
||||
}
|
||||
ret = close(inet_sock);
|
||||
if (ret != 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int SetIP(char *ip)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
|
||||
if (fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
int ret = strncpy_s(ifr.ifr_name, sizeof(ifr.ifr_name), "eth0", IFNAMSIZ);
|
||||
if (ret != EOK) {
|
||||
(void)close(fd);
|
||||
return -1;
|
||||
}
|
||||
ifr.ifr_addr.sa_family = AF_INET;
|
||||
inet_pton(AF_INET, ip, ifr.ifr_addr.sa_data + 2); /* 2: offset */
|
||||
ioctl(fd, SIOCSIFADDR, &ifr);
|
||||
ret = close(fd);
|
||||
if (ret != 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ChildFunc(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
int ret;
|
||||
char oldIp[IpLen] = {NULL};
|
||||
char newIp[IpLen] = {NULL};
|
||||
|
||||
ret = GetLocalIP(oldIp);
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_1;
|
||||
}
|
||||
|
||||
ret = unshare(CLONE_NEWNET);
|
||||
if (ret < 0) {
|
||||
return EXIT_CODE_ERRNO_2;
|
||||
}
|
||||
|
||||
ret = SetIP("192.168.1.234");
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_3;
|
||||
}
|
||||
|
||||
ret = GetLocalIP(newIp);
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_4;
|
||||
}
|
||||
|
||||
ret = strcmp(oldIp, newIp);
|
||||
if (ret == 0) {
|
||||
return EXIT_CODE_ERRNO_5;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ItNetContainer002(void)
|
||||
{
|
||||
int ret;
|
||||
char oldIp[IpLen] = {NULL};
|
||||
char newIp[IpLen] = {NULL};
|
||||
|
||||
char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0);
|
||||
EXPECT_STRNE(stack, NULL);
|
||||
char *stackTop = stack + STACK_SIZE;
|
||||
|
||||
ret = GetLocalIP(oldIp);
|
||||
ASSERT_EQ(ret, 0);
|
||||
|
||||
int arg = CHILD_FUNC_ARG;
|
||||
auto pid = clone(ChildFunc, stackTop, SIGCHLD, &arg);
|
||||
ASSERT_NE(pid, -1);
|
||||
|
||||
int status;
|
||||
ret = waitpid(pid, &status, 0);
|
||||
ASSERT_EQ(ret, pid);
|
||||
|
||||
int exitCode = WEXITSTATUS(status);
|
||||
ASSERT_EQ(exitCode, 0);
|
||||
|
||||
ret = GetLocalIP(newIp);
|
||||
ASSERT_EQ(ret, 0);
|
||||
|
||||
ret = strcmp(oldIp, newIp);
|
||||
ASSERT_EQ(ret, 0);
|
||||
}
|
||||
78
testsuites/unittest/container/smoke/It_net_container_003.cpp
Normal file
78
testsuites/unittest/container/smoke/It_net_container_003.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2023 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 <string>
|
||||
#include <iostream>
|
||||
#include <regex>
|
||||
#include "It_container_test.h"
|
||||
|
||||
static std::string GenNetLinkPath(int pid)
|
||||
{
|
||||
std::ostringstream buf;
|
||||
buf << "/proc/" << pid << "/container/net";
|
||||
return buf.str();
|
||||
}
|
||||
|
||||
static std::string ReadlinkNet(int pid)
|
||||
{
|
||||
auto path = GenNetLinkPath(pid);
|
||||
struct stat sb;
|
||||
|
||||
int ret = lstat(path.data(), &sb);
|
||||
if (ret == -1) {
|
||||
perror("lstat");
|
||||
return std::string();
|
||||
}
|
||||
|
||||
auto bufsiz = sb.st_size + 1;
|
||||
if (sb.st_size == 0) {
|
||||
bufsiz = PATH_MAX;
|
||||
}
|
||||
|
||||
std::vector<char> buf(bufsiz);
|
||||
auto nbytes = readlink(path.c_str(), buf.data(), bufsiz);
|
||||
if (nbytes == -1) {
|
||||
perror("readlink");
|
||||
return std::string();
|
||||
}
|
||||
|
||||
return buf.data();
|
||||
}
|
||||
|
||||
void ItNetContainer003(void)
|
||||
{
|
||||
std::string zerolink("'net:[0]'");
|
||||
auto netlink = ReadlinkNet(getpid());
|
||||
int ret = zerolink.compare(netlink);
|
||||
ASSERT_NE(ret, 0);
|
||||
|
||||
std::regex reg("'net:\\[[0-9]+\\]'");
|
||||
ret = std::regex_match(netlink, reg);
|
||||
ASSERT_EQ(ret, 1);
|
||||
}
|
||||
121
testsuites/unittest/container/smoke/It_net_container_004.cpp
Normal file
121
testsuites/unittest/container/smoke/It_net_container_004.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2023 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 <sys/stat.h>
|
||||
#include <iostream>
|
||||
#include <regex>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include "It_container_test.h"
|
||||
|
||||
static const char *CONTAINER_TYPE = "net";
|
||||
static const int SLEEP_SECONDS = 2;
|
||||
static const int TEST_PATH_MAX = 100;
|
||||
|
||||
static int NewnetChildFun(void *)
|
||||
{
|
||||
sleep(SLEEP_SECONDS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ChildFun(void *p)
|
||||
{
|
||||
(void)p;
|
||||
int ret;
|
||||
int status;
|
||||
char path[TEST_PATH_MAX];
|
||||
|
||||
char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0);
|
||||
EXPECT_STRNE(stack, nullptr);
|
||||
char *stackTop = stack + STACK_SIZE;
|
||||
int arg = CHILD_FUNC_ARG;
|
||||
auto childPid = clone(NewnetChildFun, stackTop, SIGCHLD | CLONE_NEWNET, &arg);
|
||||
if (childPid == -1) {
|
||||
return EXIT_CODE_ERRNO_1;
|
||||
}
|
||||
auto oldReadLink = ReadlinkContainer(getpid(), CONTAINER_TYPE);
|
||||
|
||||
if (sprintf_s(path, TEST_PATH_MAX, "/proc/%d/container/net", childPid) < 0) {
|
||||
(void)waitpid(childPid, &status, 0);
|
||||
return EXIT_CODE_ERRNO_8;
|
||||
}
|
||||
int fd = open(path, O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
return EXIT_CODE_ERRNO_2;
|
||||
}
|
||||
|
||||
ret = setns(fd, CLONE_NEWNET);
|
||||
if (ret != 0) {
|
||||
(void)close(fd);
|
||||
return EXIT_CODE_ERRNO_3;
|
||||
}
|
||||
|
||||
ret = close(fd);
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_4;
|
||||
}
|
||||
|
||||
auto newReadLink = ReadlinkContainer(getpid(), CONTAINER_TYPE);
|
||||
|
||||
ret = strcmp(oldReadLink.c_str(), newReadLink.c_str());
|
||||
if (ret == 0) {
|
||||
return EXIT_CODE_ERRNO_5;
|
||||
}
|
||||
|
||||
ret = waitpid(childPid, &status, 0);
|
||||
if (ret != childPid) {
|
||||
return EXIT_CODE_ERRNO_6;
|
||||
}
|
||||
|
||||
int exitCode = WEXITSTATUS(status);
|
||||
if (exitCode != 0) {
|
||||
return EXIT_CODE_ERRNO_7;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ItNetContainer004(void)
|
||||
{
|
||||
int status;
|
||||
|
||||
char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0);
|
||||
EXPECT_STRNE(stack, nullptr);
|
||||
char *stackTop = stack + STACK_SIZE;
|
||||
int arg = CHILD_FUNC_ARG;
|
||||
auto childPid = clone(ChildFun, stackTop, SIGCHLD | CLONE_NEWNET, &arg);
|
||||
ASSERT_NE(childPid, -1);
|
||||
|
||||
int ret = waitpid(childPid, &status, 0);
|
||||
ASSERT_EQ(ret, childPid);
|
||||
|
||||
int exitCode = WEXITSTATUS(status);
|
||||
ASSERT_EQ(exitCode, 0);
|
||||
}
|
||||
267
testsuites/unittest/container/smoke/It_net_container_005.cpp
Normal file
267
testsuites/unittest/container/smoke/It_net_container_005.cpp
Normal file
@@ -0,0 +1,267 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2023 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 <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
#include "It_container_test.h"
|
||||
|
||||
static const char *NETMASK = "255.255.255.0";
|
||||
static const char *GW = "192.168.100.1";
|
||||
static const char *IFNAME = "veth0";
|
||||
static const char *SERVER_IP = "192.168.100.6";
|
||||
static const int SERVER_PORT = 8000;
|
||||
static const char *PEER_IP = "192.168.100.5";
|
||||
static const int PEER_PORT = 8001;
|
||||
static const int DATA_LEN = 128;
|
||||
static const char *SERVER_MSG = "===Hi, I'm Server.===";
|
||||
static const char *PEER_MSG = "===Hi, I'm Peer.===";
|
||||
static const int TRY_COUNT = 5;
|
||||
static const int OFFSET = 2;
|
||||
|
||||
static int TryResetNetaddr(const char *ifname, const char *ip, const char *netmask, const char *gw)
|
||||
{
|
||||
int ret;
|
||||
struct ifreq ifr;
|
||||
struct rtentry rt;
|
||||
|
||||
int fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
|
||||
if (fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
ret = strncpy_s(ifr.ifr_name, sizeof(ifr.ifr_name), ifname, IFNAMSIZ);
|
||||
if (ret != EOK) {
|
||||
(void)close(fd);
|
||||
return -1;
|
||||
}
|
||||
ifr.ifr_addr.sa_family = AF_INET;
|
||||
|
||||
inet_pton(AF_INET, netmask, ifr.ifr_addr.sa_data + OFFSET);
|
||||
ret = ioctl(fd, SIOCSIFNETMASK, &ifr);
|
||||
if (ret == 0) {
|
||||
inet_pton(AF_INET, ip, ifr.ifr_addr.sa_data + OFFSET);
|
||||
ret = ioctl(fd, SIOCSIFADDR, &ifr);
|
||||
if (ret == 0) {
|
||||
struct sockaddr_in* addr = reinterpret_cast<struct sockaddr_in *>(&rt.rt_gateway);
|
||||
addr->sin_family = AF_INET;
|
||||
addr->sin_addr.s_addr = inet_addr(GW);
|
||||
rt.rt_flags = RTF_GATEWAY;
|
||||
ret = ioctl(fd, SIOCADDRT, &rt);
|
||||
}
|
||||
}
|
||||
if (ret != 0) {
|
||||
(void)close(fd);
|
||||
return ret;
|
||||
}
|
||||
ret = close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ResetNetaddr(const char *ifname, const char *ip, const char *netmask, const char *gw)
|
||||
{
|
||||
int ret;
|
||||
int try_count = TRY_COUNT;
|
||||
|
||||
while (try_count--) {
|
||||
ret = TryResetNetaddr(ifname, ip, netmask, gw);
|
||||
if (ret == 0) {
|
||||
break;
|
||||
}
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int UdpClient(void)
|
||||
{
|
||||
int ret = 0;
|
||||
int peer;
|
||||
int try_count = TRY_COUNT;
|
||||
char recv_data[DATA_LEN];
|
||||
struct sockaddr_in server_addr;
|
||||
struct sockaddr_in peer_addr;
|
||||
|
||||
peer = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (peer < 0) {
|
||||
return EXIT_CODE_ERRNO_1;
|
||||
}
|
||||
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
|
||||
server_addr.sin_port = htons(SERVER_PORT);
|
||||
(void)memset_s(&(server_addr.sin_zero), sizeof(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
|
||||
|
||||
peer_addr.sin_family = AF_INET;
|
||||
peer_addr.sin_addr.s_addr = inet_addr(PEER_IP);
|
||||
peer_addr.sin_port = htons(PEER_PORT);
|
||||
(void)memset_s(&(peer_addr.sin_zero), sizeof(peer_addr.sin_zero), 0, sizeof(peer_addr.sin_zero));
|
||||
|
||||
ret = bind(peer, const_cast<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&peer_addr)),
|
||||
sizeof(struct sockaddr));
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_2;
|
||||
}
|
||||
|
||||
timeval tv = {1, 0};
|
||||
ret = setsockopt(peer, SOL_SOCKET, SO_RCVTIMEO, const_cast<void *>(reinterpret_cast<void *>(&tv)), sizeof(timeval));
|
||||
|
||||
/* loop try util server is ready */
|
||||
while (try_count--) {
|
||||
ret = sendto(peer, PEER_MSG, strlen(PEER_MSG) + 1, 0,
|
||||
const_cast<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&server_addr)),
|
||||
(socklen_t)sizeof(server_addr));
|
||||
if (ret == -1) {
|
||||
continue;
|
||||
}
|
||||
ret = recvfrom(peer, recv_data, DATA_LEN, 0, nullptr, nullptr);
|
||||
if (ret != -1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ret < 0) {
|
||||
return EXIT_CODE_ERRNO_3;
|
||||
}
|
||||
|
||||
(void)close(peer);
|
||||
|
||||
ret = strcmp(recv_data, SERVER_MSG);
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_4;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ChildFunc(void *arg)
|
||||
{
|
||||
int ret = ResetNetaddr(IFNAME, PEER_IP, NETMASK, GW);
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_1;
|
||||
}
|
||||
|
||||
return UdpClient();
|
||||
}
|
||||
|
||||
static int UdpServer(void)
|
||||
{
|
||||
int ret = 0;
|
||||
int server;
|
||||
int try_count = TRY_COUNT;
|
||||
char recv_data[DATA_LEN];
|
||||
struct sockaddr_in server_addr;
|
||||
struct sockaddr_in peer_addr;
|
||||
socklen_t peer_addr_len = sizeof(struct sockaddr);
|
||||
|
||||
server = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (server < 0) {
|
||||
return EXIT_CODE_ERRNO_1;
|
||||
}
|
||||
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
|
||||
server_addr.sin_port = htons(SERVER_PORT);
|
||||
(void)memset_s(&(server_addr.sin_zero), sizeof(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
|
||||
|
||||
ret = bind(server, const_cast<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&server_addr)),
|
||||
sizeof(struct sockaddr));
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_2;
|
||||
}
|
||||
|
||||
ret = recvfrom(server, recv_data, DATA_LEN, 0, reinterpret_cast<struct sockaddr *>(&peer_addr), &peer_addr_len);
|
||||
if (ret < 0) {
|
||||
return EXIT_CODE_ERRNO_3;
|
||||
}
|
||||
|
||||
ret = sendto(server, SERVER_MSG, strlen(SERVER_MSG) + 1, 0,
|
||||
const_cast<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&peer_addr)), peer_addr_len);
|
||||
if (ret < 0) {
|
||||
return EXIT_CODE_ERRNO_4;
|
||||
}
|
||||
|
||||
(void)close(server);
|
||||
|
||||
ret = strcmp(recv_data, PEER_MSG);
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_5;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *UdpServerThread(void *arg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ResetNetaddr(IFNAME, SERVER_IP, NETMASK, GW);
|
||||
if (ret != 0) {
|
||||
return (void *)(intptr_t)ret;
|
||||
}
|
||||
|
||||
ret = UdpServer();
|
||||
|
||||
return (void *)(intptr_t)ret;
|
||||
}
|
||||
|
||||
void ItNetContainer005(void)
|
||||
{
|
||||
int ret = 0;
|
||||
int status;
|
||||
void *tret = nullptr;
|
||||
pthread_t srv;
|
||||
pthread_attr_t attr;
|
||||
|
||||
ret = pthread_attr_init(&attr);
|
||||
ASSERT_EQ(ret, 0);
|
||||
|
||||
ret = pthread_create(&srv, &attr, UdpServerThread, nullptr);
|
||||
ASSERT_EQ(ret, 0);
|
||||
|
||||
char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0);
|
||||
EXPECT_STRNE(stack, nullptr);
|
||||
char *stackTop = stack + STACK_SIZE;
|
||||
|
||||
int arg = CHILD_FUNC_ARG;
|
||||
auto pid = clone(ChildFunc, stackTop, SIGCHLD | CLONE_NEWNET, &arg);
|
||||
ASSERT_NE(pid, -1);
|
||||
|
||||
ret = waitpid(pid, &status, 0);
|
||||
ASSERT_EQ(ret, pid);
|
||||
|
||||
int exitCode = WEXITSTATUS(status);
|
||||
ASSERT_EQ(exitCode, 0);
|
||||
|
||||
ret = pthread_join(srv, &tret);
|
||||
ASSERT_EQ(ret, 0);
|
||||
|
||||
ret = pthread_attr_destroy(&attr);
|
||||
ASSERT_EQ(ret, 0);
|
||||
}
|
||||
181
testsuites/unittest/container/smoke/It_net_container_006.cpp
Normal file
181
testsuites/unittest/container/smoke/It_net_container_006.cpp
Normal file
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2023 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 <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <semaphore.h>
|
||||
#include <sys/socket.h>
|
||||
#include <poll.h>
|
||||
#include "It_container_test.h"
|
||||
|
||||
static const char *SERVER_IP = "127.0.0.1";
|
||||
static const int SERV_PORT = 8002;
|
||||
static const char *SERVER_MSG = "Hi, I'm Tcp Server!";
|
||||
static const char *PEER_MSG = "Hi, I'm Tcp Client!";
|
||||
static const int DATA_LEN = 128;
|
||||
|
||||
static int TcpClient(void *arg)
|
||||
{
|
||||
int ret;
|
||||
int client;
|
||||
char buffer[DATA_LEN];
|
||||
struct sockaddr_in server_addr;
|
||||
|
||||
client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (client < 0) {
|
||||
return EXIT_CODE_ERRNO_1;
|
||||
}
|
||||
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
server_addr.sin_port = htons(SERV_PORT);
|
||||
(void)memset_s(&(server_addr.sin_zero), sizeof(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
|
||||
|
||||
ret = connect(client, const_cast<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&server_addr)),
|
||||
sizeof(server_addr));
|
||||
if (ret < 0) {
|
||||
return EXIT_CODE_ERRNO_2;
|
||||
}
|
||||
|
||||
ret = send(client, PEER_MSG, strlen(PEER_MSG) + 1, 0);
|
||||
if (ret < 0) {
|
||||
return EXIT_CODE_ERRNO_3;
|
||||
}
|
||||
|
||||
ret = recv(client, buffer, sizeof(buffer), 0);
|
||||
if (ret < 0) {
|
||||
return EXIT_CODE_ERRNO_4;
|
||||
}
|
||||
|
||||
ret = strcmp(buffer, SERVER_MSG);
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_5;
|
||||
}
|
||||
|
||||
(void)close(client);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ChildFunc(void *)
|
||||
{
|
||||
int ret;
|
||||
int server;
|
||||
int status;
|
||||
char *stack = nullptr;
|
||||
char *stackTop = nullptr;
|
||||
char buffer[DATA_LEN];
|
||||
struct sockaddr_in server_addr;
|
||||
|
||||
server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (server < 0) {
|
||||
return EXIT_CODE_ERRNO_1;
|
||||
}
|
||||
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
server_addr.sin_port = htons(SERV_PORT);
|
||||
(void)memset_s(&(server_addr.sin_zero), sizeof(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
|
||||
|
||||
ret = bind(server, const_cast<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&server_addr)),
|
||||
sizeof(server_addr));
|
||||
if (ret < 0) {
|
||||
return EXIT_CODE_ERRNO_2;
|
||||
}
|
||||
|
||||
ret = listen(server, 1);
|
||||
if (ret < 0) {
|
||||
return EXIT_CODE_ERRNO_3;
|
||||
}
|
||||
|
||||
stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0);
|
||||
EXPECT_STRNE(stack, nullptr);
|
||||
stackTop = stack + STACK_SIZE;
|
||||
|
||||
int arg = CHILD_FUNC_ARG;
|
||||
int pid = clone(TcpClient, stackTop, SIGCHLD, &arg);
|
||||
if (pid == -1) {
|
||||
return EXIT_CODE_ERRNO_4;
|
||||
}
|
||||
|
||||
int client = accept(server, nullptr, nullptr);
|
||||
if (ret < 0) {
|
||||
return EXIT_CODE_ERRNO_5;
|
||||
}
|
||||
|
||||
ret = recv(client, buffer, sizeof(buffer), 0);
|
||||
if (ret < 0) {
|
||||
return EXIT_CODE_ERRNO_6;
|
||||
}
|
||||
|
||||
ret = strcmp(buffer, PEER_MSG);
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_7;
|
||||
}
|
||||
|
||||
ret = send(client, SERVER_MSG, strlen(SERVER_MSG) + 1, 0);
|
||||
if (ret < 0) {
|
||||
return EXIT_CODE_ERRNO_8;
|
||||
}
|
||||
|
||||
(void)close(client);
|
||||
(void)close(server);
|
||||
|
||||
ret = waitpid(pid, &status, 0);
|
||||
if (ret != pid) {
|
||||
return EXIT_CODE_ERRNO_9;
|
||||
}
|
||||
|
||||
int exitCode = WEXITSTATUS(status);
|
||||
if (exitCode != 0) {
|
||||
return EXIT_CODE_ERRNO_10;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ItNetContainer006(void)
|
||||
{
|
||||
int ret = 0;
|
||||
int status;
|
||||
|
||||
char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0);
|
||||
EXPECT_STRNE(stack, nullptr);
|
||||
char *stackTop = stack + STACK_SIZE;
|
||||
|
||||
int arg = CHILD_FUNC_ARG;
|
||||
int pid = clone(ChildFunc, stackTop, SIGCHLD | CLONE_NEWNET, &arg);
|
||||
ASSERT_NE(pid, -1);
|
||||
|
||||
ret = waitpid(pid, &status, 0);
|
||||
ASSERT_EQ(ret, pid);
|
||||
|
||||
int exitCode = WEXITSTATUS(status);
|
||||
ASSERT_EQ(exitCode, 0);
|
||||
}
|
||||
102
testsuites/unittest/container/smoke/It_net_container_007.cpp
Normal file
102
testsuites/unittest/container/smoke/It_net_container_007.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2023 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 <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include "It_container_test.h"
|
||||
|
||||
static const char *LOCALHOST = "127.0.0.1";
|
||||
static const int LOCALPORT = 8003;
|
||||
static const char *MSG = "Tis is UDP Test!";
|
||||
static const int DATA_LEN = 128;
|
||||
|
||||
static int ChildFunc(void *arg)
|
||||
{
|
||||
int ret;
|
||||
int sock;
|
||||
int recv_data_len;
|
||||
char recv_data[DATA_LEN];
|
||||
struct sockaddr_in addr;
|
||||
|
||||
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sock < 0) {
|
||||
return EXIT_CODE_ERRNO_1;
|
||||
}
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = inet_addr(LOCALHOST);
|
||||
addr.sin_port = htons(LOCALPORT);
|
||||
(void)memset_s(&(addr.sin_zero), sizeof(addr.sin_zero), 0, sizeof(addr.sin_zero));
|
||||
|
||||
ret = bind(sock, const_cast<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&addr)),
|
||||
sizeof(struct sockaddr));
|
||||
if (ret < 0) {
|
||||
return EXIT_CODE_ERRNO_2;
|
||||
}
|
||||
|
||||
ret = sendto(sock, MSG, DATA_LEN, 0, const_cast<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&addr)),
|
||||
(socklen_t)sizeof(addr));
|
||||
if (ret < 0) {
|
||||
return EXIT_CODE_ERRNO_3;
|
||||
}
|
||||
|
||||
ret = recvfrom(sock, recv_data, DATA_LEN, 0, nullptr, nullptr);
|
||||
if (ret < 0) {
|
||||
return EXIT_CODE_ERRNO_4;
|
||||
}
|
||||
|
||||
ret = strcmp(recv_data, MSG);
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_5;
|
||||
}
|
||||
|
||||
(void)close(sock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ItNetContainer007(void)
|
||||
{
|
||||
int ret = 0;
|
||||
int status;
|
||||
|
||||
char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0);
|
||||
EXPECT_STRNE(stack, nullptr);
|
||||
char *stackTop = stack + STACK_SIZE;
|
||||
|
||||
int arg = CHILD_FUNC_ARG;
|
||||
auto pid = clone(ChildFunc, stackTop, SIGCHLD | CLONE_NEWNET, &arg);
|
||||
ASSERT_NE(pid, -1);
|
||||
|
||||
ret = waitpid(pid, &status, 0);
|
||||
ASSERT_EQ(ret, pid);
|
||||
|
||||
int exitCode = WEXITSTATUS(status);
|
||||
ASSERT_EQ(exitCode, 0);
|
||||
}
|
||||
119
testsuites/unittest/container/smoke/It_net_container_008.cpp
Normal file
119
testsuites/unittest/container/smoke/It_net_container_008.cpp
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2023 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 <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#include <poll.h>
|
||||
#include "It_container_test.h"
|
||||
|
||||
static const int PORT = 8004;
|
||||
static const char *LOCALHOST = "127.0.0.1";
|
||||
|
||||
static int UdpTcpBind(int *sock1, int *sock2)
|
||||
{
|
||||
int ret;
|
||||
int udp_sock;
|
||||
int tcp_sock;
|
||||
|
||||
udp_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (udp_sock < 0) {
|
||||
return EXIT_CODE_ERRNO_1;
|
||||
}
|
||||
|
||||
struct sockaddr_in sa;
|
||||
sa.sin_family = AF_INET;
|
||||
sa.sin_addr.s_addr = inet_addr(LOCALHOST);
|
||||
sa.sin_port = htons(PORT);
|
||||
|
||||
ret = bind(udp_sock, const_cast<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&sa)), sizeof(sa));
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_2;
|
||||
}
|
||||
|
||||
tcp_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (tcp_sock < 0) {
|
||||
return EXIT_CODE_ERRNO_3;
|
||||
}
|
||||
|
||||
ret = bind(tcp_sock, const_cast<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&sa)), sizeof(sa));
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_4;
|
||||
}
|
||||
|
||||
(*sock1) = udp_sock;
|
||||
(*sock2) = tcp_sock;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ClientFunc(void *param)
|
||||
{
|
||||
(void)param;
|
||||
int ret;
|
||||
int udp_sock;
|
||||
int tcp_sock;
|
||||
|
||||
ret = UdpTcpBind(&udp_sock, &tcp_sock);
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_1;
|
||||
}
|
||||
|
||||
(void)close(udp_sock);
|
||||
(void)close(tcp_sock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ItNetContainer008(void)
|
||||
{
|
||||
int ret;
|
||||
int status;
|
||||
int udp_sock;
|
||||
int tcp_sock;
|
||||
|
||||
ret = UdpTcpBind(&udp_sock, &tcp_sock);
|
||||
ASSERT_EQ(ret, 0);
|
||||
|
||||
char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0);
|
||||
EXPECT_STRNE(stack, nullptr);
|
||||
char *stackTop = stack + STACK_SIZE;
|
||||
int arg = CHILD_FUNC_ARG;
|
||||
int pid = clone(ClientFunc, stackTop, SIGCHLD | CLONE_NEWNET, &arg);
|
||||
ASSERT_NE(pid, -1);
|
||||
|
||||
ret = waitpid(pid, &status, 0);
|
||||
ASSERT_EQ(ret, pid);
|
||||
|
||||
int exitCode = WEXITSTATUS(status);
|
||||
ASSERT_EQ(exitCode, 0);
|
||||
|
||||
(void)close(udp_sock);
|
||||
(void)close(tcp_sock);
|
||||
}
|
||||
260
testsuites/unittest/container/smoke/It_net_container_009.cpp
Normal file
260
testsuites/unittest/container/smoke/It_net_container_009.cpp
Normal file
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2023 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 <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
#include "It_container_test.h"
|
||||
|
||||
static const char *NETMASK = "255.255.255.0";
|
||||
static const char *GW = "192.168.100.1";
|
||||
static const char *IFNAME = "veth0";
|
||||
static const char *SERVER_IP = "192.168.100.6";
|
||||
static const int SERVER_PORT = 8005;
|
||||
static const char *PEER_IP = "192.168.100.5";
|
||||
static const char *SERVER_MSG = "===Hi, I'm Server.===";
|
||||
static const char *PEER_MSG = "===Hi, I'm Peer.===";
|
||||
static const int TRY_COUNT = 5;
|
||||
static const int DATA_LEN = 128;
|
||||
|
||||
static int TryResetNetaddr(const char *ifname, const char *ip, const char *netmask, const char *gw)
|
||||
{
|
||||
int ret;
|
||||
struct ifreq ifr;
|
||||
struct rtentry rt;
|
||||
|
||||
int fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
|
||||
if (fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
ret = strncpy_s(ifr.ifr_name, sizeof(ifr.ifr_name), ifname, IFNAMSIZ);
|
||||
if (ret != EOK) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
ifr.ifr_addr.sa_family = AF_INET;
|
||||
|
||||
inet_pton(AF_INET, netmask, ifr.ifr_addr.sa_data + 2); /* 2: offset */
|
||||
ret = ioctl(fd, SIOCSIFNETMASK, &ifr);
|
||||
if (ret == 0) {
|
||||
inet_pton(AF_INET, ip, ifr.ifr_addr.sa_data + 2); /* 2: offset */
|
||||
ret = ioctl(fd, SIOCSIFADDR, &ifr);
|
||||
if (ret == 0) {
|
||||
struct sockaddr_in* addr = reinterpret_cast<struct sockaddr_in *>(&rt.rt_gateway);
|
||||
addr->sin_family = AF_INET;
|
||||
addr->sin_addr.s_addr = inet_addr(GW);
|
||||
rt.rt_flags = RTF_GATEWAY;
|
||||
ret = ioctl(fd, SIOCADDRT, &rt);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
(void)close(fd);
|
||||
return ret;
|
||||
}
|
||||
ret = close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ResetNetaddr(const char *ifname, const char *ip, const char *netmask, const char *gw)
|
||||
{
|
||||
int ret;
|
||||
int try_count = TRY_COUNT;
|
||||
|
||||
while (try_count--) {
|
||||
ret = TryResetNetaddr(ifname, ip, netmask, gw);
|
||||
if (ret == 0) {
|
||||
break;
|
||||
}
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int TcpClient(void)
|
||||
{
|
||||
int ret = 0;
|
||||
int peer;
|
||||
int try_count = TRY_COUNT;
|
||||
char recv_data[DATA_LEN];
|
||||
struct sockaddr_in server_addr;
|
||||
|
||||
peer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (peer < 0) {
|
||||
return EXIT_CODE_ERRNO_1;
|
||||
}
|
||||
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
|
||||
server_addr.sin_port = htons(SERVER_PORT);
|
||||
(void)memset_s(&(server_addr.sin_zero), sizeof(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
|
||||
|
||||
do {
|
||||
sleep(1);
|
||||
ret = connect(peer, const_cast<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&server_addr)),
|
||||
sizeof(struct sockaddr));
|
||||
} while (ret !=0 && (try_count--));
|
||||
|
||||
if (ret < 0) {
|
||||
return EXIT_CODE_ERRNO_2;
|
||||
}
|
||||
|
||||
ret = send(peer, PEER_MSG, strlen(PEER_MSG) + 1, 0);
|
||||
if (ret < 0) {
|
||||
return EXIT_CODE_ERRNO_3;
|
||||
}
|
||||
|
||||
ret = recv(peer, recv_data, sizeof(recv_data), 0);
|
||||
if (ret < 0) {
|
||||
return EXIT_CODE_ERRNO_4;
|
||||
}
|
||||
|
||||
ret = strcmp(recv_data, SERVER_MSG);
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_5;
|
||||
}
|
||||
|
||||
(void)close(peer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int TcpServer(void)
|
||||
{
|
||||
int ret = 0;
|
||||
int server;
|
||||
int peer;
|
||||
char recv_data[DATA_LEN];
|
||||
struct sockaddr_in server_addr;
|
||||
socklen_t client_addr_len = sizeof(struct sockaddr);
|
||||
|
||||
server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (server < 0) {
|
||||
return EXIT_CODE_ERRNO_1;
|
||||
}
|
||||
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
|
||||
server_addr.sin_port = htons(SERVER_PORT);
|
||||
(void)memset_s(&(server_addr.sin_zero), sizeof(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
|
||||
|
||||
ret = bind(server, const_cast<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&server_addr)),
|
||||
sizeof(struct sockaddr));
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_2;
|
||||
}
|
||||
|
||||
ret = listen(server, 1);
|
||||
if (ret < 0) {
|
||||
return EXIT_CODE_ERRNO_3;
|
||||
}
|
||||
|
||||
peer = accept(server, nullptr, nullptr);
|
||||
if (peer < 0) {
|
||||
return EXIT_CODE_ERRNO_4;
|
||||
}
|
||||
|
||||
(void)close(server);
|
||||
|
||||
ret = recv(peer, recv_data, sizeof(recv_data), 0);
|
||||
if (ret < 0) {
|
||||
return EXIT_CODE_ERRNO_5;
|
||||
}
|
||||
|
||||
ret = strcmp(recv_data, PEER_MSG);
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_6;
|
||||
}
|
||||
|
||||
ret = send(peer, SERVER_MSG, strlen(SERVER_MSG) + 1, 0);
|
||||
if (ret < 0) {
|
||||
return EXIT_CODE_ERRNO_7;
|
||||
}
|
||||
|
||||
(void)close(peer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *TcpClientThread(void *arg)
|
||||
{
|
||||
int ret = ResetNetaddr(IFNAME, PEER_IP, NETMASK, GW);
|
||||
if (ret == 0) {
|
||||
ret = TcpClient();
|
||||
}
|
||||
|
||||
return (void *)(intptr_t)ret;
|
||||
}
|
||||
|
||||
static int ChildFunc(void *arg)
|
||||
{
|
||||
int ret = ret = ResetNetaddr(IFNAME, SERVER_IP, NETMASK, GW);
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_1;
|
||||
}
|
||||
|
||||
return TcpServer();
|
||||
}
|
||||
|
||||
VOID ItNetContainer009(void)
|
||||
{
|
||||
int ret = 0;
|
||||
int status;
|
||||
void *tret = nullptr;
|
||||
pthread_t srv;
|
||||
pthread_attr_t attr;
|
||||
|
||||
char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0);
|
||||
EXPECT_STRNE(stack, nullptr);
|
||||
char *stackTop = stack + STACK_SIZE;
|
||||
|
||||
int arg = CHILD_FUNC_ARG;
|
||||
int pid = clone(ChildFunc, stackTop, SIGCHLD | CLONE_NEWNET, &arg);
|
||||
ASSERT_NE(pid, -1);
|
||||
|
||||
ret = pthread_attr_init(&attr);
|
||||
ASSERT_EQ(ret, 0);
|
||||
|
||||
ret = pthread_create(&srv, &attr, TcpClientThread, nullptr);
|
||||
ASSERT_EQ(ret, 0);
|
||||
|
||||
ret = pthread_join(srv, &tret);
|
||||
ASSERT_EQ(ret, 0);
|
||||
|
||||
ret = pthread_attr_destroy(&attr);
|
||||
ASSERT_EQ(ret, 0);
|
||||
|
||||
ret = waitpid(pid, &status, 0);
|
||||
ASSERT_EQ(ret, pid);
|
||||
|
||||
int exitCode = WEXITSTATUS(status);
|
||||
ASSERT_EQ(exitCode, 0);
|
||||
}
|
||||
80
testsuites/unittest/container/smoke/It_net_container_010.cpp
Normal file
80
testsuites/unittest/container/smoke/It_net_container_010.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2023 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 "sys/resource.h"
|
||||
#include "sys/wait.h"
|
||||
#include "pthread.h"
|
||||
#include "sched.h"
|
||||
#include "It_container_test.h"
|
||||
|
||||
const int MAX_PID_RANGE = 100000;
|
||||
const int SLEEP_TIME_US = 1000;
|
||||
const int LOOP_NUM = 100;
|
||||
|
||||
static int ChildFunc(void *arg)
|
||||
{
|
||||
usleep(SLEEP_TIME_US);
|
||||
exit(EXIT_CODE_ERRNO_5);
|
||||
}
|
||||
|
||||
static int GroupProcess(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
int ret;
|
||||
int status = 0;
|
||||
|
||||
for (int i = 0; i < LOOP_NUM; i++) {
|
||||
int argTmp = CHILD_FUNC_ARG;
|
||||
auto pid = CloneWrapper(ChildFunc, CLONE_NEWNET, &argTmp);
|
||||
if (pid == -1) {
|
||||
return EXIT_CODE_ERRNO_1;
|
||||
}
|
||||
ret = waitpid(pid, &status, 0);
|
||||
status = WEXITSTATUS(status);
|
||||
if (status != EXIT_CODE_ERRNO_5) {
|
||||
return EXIT_CODE_ERRNO_2;
|
||||
}
|
||||
}
|
||||
|
||||
exit(EXIT_CODE_ERRNO_5);
|
||||
}
|
||||
|
||||
void ItNetContainer010(void)
|
||||
{
|
||||
int ret;
|
||||
int status = 0;
|
||||
int arg = CHILD_FUNC_ARG;
|
||||
auto pid = CloneWrapper(GroupProcess, CLONE_NEWNET, &arg);
|
||||
ASSERT_NE(pid, -1);
|
||||
|
||||
ret = waitpid(pid, &status, 0);
|
||||
ASSERT_EQ(ret, pid);
|
||||
status = WEXITSTATUS(status);
|
||||
ASSERT_EQ(status, EXIT_CODE_ERRNO_5);
|
||||
}
|
||||
100
testsuites/unittest/container/smoke/It_net_container_011.cpp
Normal file
100
testsuites/unittest/container/smoke/It_net_container_011.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2023 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 <cstdio>
|
||||
#include "It_container_test.h"
|
||||
|
||||
static int const configLen = 16;
|
||||
static const int MAX_CONTAINER = 10;
|
||||
static const int g_buffSize = 512;
|
||||
static const int g_arryLen = 4;
|
||||
static const int g_readLen = 254;
|
||||
|
||||
static int childFunc(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
sleep(2); /* 2: delay 2s */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ItNetContainer011(void)
|
||||
{
|
||||
std::string path = "/proc/sys/user/max_net_container";
|
||||
char *array[g_arryLen] = { nullptr };
|
||||
char buf[g_buffSize] = { 0 };
|
||||
|
||||
int ret = ReadFile(path.c_str(), buf);
|
||||
ASSERT_NE(ret, -1);
|
||||
|
||||
GetLine(buf, g_arryLen, g_readLen, array);
|
||||
|
||||
int value = atoi(array[1] + strlen("limit: "));
|
||||
ASSERT_EQ(value, MAX_CONTAINER);
|
||||
|
||||
int usedCount = atoi(array[2] + strlen("count: "));
|
||||
|
||||
(void)memset_s(buf, configLen, 0, configLen);
|
||||
ret = sprintf_s(buf, configLen, "%d", usedCount + 1);
|
||||
ASSERT_GT(ret, 0);
|
||||
|
||||
ret = WriteFile(path.c_str(), buf);
|
||||
ASSERT_NE(ret, -1);
|
||||
|
||||
char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK,
|
||||
-1, 0);
|
||||
ASSERT_NE(stack, nullptr);
|
||||
char *stackTop = stack + STACK_SIZE;
|
||||
|
||||
auto pid1 = clone(childFunc, stackTop, CLONE_NEWNET, NULL);
|
||||
ASSERT_NE(pid1, -1);
|
||||
|
||||
auto pid2 = clone(childFunc, stackTop, CLONE_NEWNET, NULL);
|
||||
ASSERT_EQ(pid2, -1);
|
||||
|
||||
ret = waitpid(pid1, NULL, 0);
|
||||
ASSERT_EQ(ret, pid1);
|
||||
|
||||
(void)memset_s(buf, configLen, 0, configLen);
|
||||
ret = sprintf_s(buf, configLen, "%d", value);
|
||||
ASSERT_GT(ret, 0);
|
||||
|
||||
ret = WriteFile(path.c_str(), buf);
|
||||
ASSERT_NE(ret, -1);
|
||||
|
||||
(void)memset_s(buf, configLen, 0, configLen);
|
||||
ret = ReadFile(path.c_str(), buf);
|
||||
ASSERT_NE(ret, -1);
|
||||
|
||||
GetLine(buf, g_arryLen, g_readLen, array);
|
||||
|
||||
value = atoi(array[1] + strlen("limit: "));
|
||||
ASSERT_EQ(value, MAX_CONTAINER);
|
||||
}
|
||||
105
testsuites/unittest/container/smoke/It_net_container_012.cpp
Normal file
105
testsuites/unittest/container/smoke/It_net_container_012.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2023 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 <cstdio>
|
||||
#include "It_container_test.h"
|
||||
|
||||
static int const configLen = 16;
|
||||
static const int MAX_CONTAINER = 10;
|
||||
static const int g_buffSize = 512;
|
||||
static const int g_arryLen = 4;
|
||||
static const int g_readLen = 254;
|
||||
|
||||
static int childFunc(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
|
||||
int ret = unshare(CLONE_NEWNET);
|
||||
if (ret != 0) {
|
||||
return EXIT_CODE_ERRNO_1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ItNetContainer012(void)
|
||||
{
|
||||
std::string path = "/proc/sys/user/max_net_container";
|
||||
char *array[g_arryLen] = { nullptr };
|
||||
char buf[g_buffSize] = { 0 };
|
||||
int status = 0;
|
||||
|
||||
int ret = ReadFile(path.c_str(), buf);
|
||||
ASSERT_NE(ret, -1);
|
||||
|
||||
GetLine(buf, g_arryLen, g_readLen, array);
|
||||
|
||||
int value = atoi(array[1] + strlen("limit: "));
|
||||
ASSERT_EQ(value, MAX_CONTAINER);
|
||||
|
||||
int usedCount = atoi(array[2] + strlen("count: "));
|
||||
|
||||
(void)memset_s(buf, configLen, 0, configLen);
|
||||
ret = sprintf_s(buf, configLen, "%d", usedCount + 1);
|
||||
ASSERT_GT(ret, 0);
|
||||
|
||||
ret = WriteFile(path.c_str(), buf);
|
||||
ASSERT_NE(ret, -1);
|
||||
|
||||
char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK,
|
||||
-1, 0);
|
||||
ASSERT_NE(stack, nullptr);
|
||||
char *stackTop = stack + STACK_SIZE;
|
||||
|
||||
auto pid1 = clone(childFunc, stackTop, CLONE_NEWNET, NULL);
|
||||
ASSERT_NE(pid1, -1);
|
||||
|
||||
ret = waitpid(pid1, &status, 0);
|
||||
ASSERT_EQ(ret, pid1);
|
||||
ret = WIFEXITED(status);
|
||||
ASSERT_NE(ret, 0);
|
||||
ret = WEXITSTATUS(status);
|
||||
ASSERT_EQ(ret, EXIT_CODE_ERRNO_1);
|
||||
|
||||
(void)memset_s(buf, configLen, 0, configLen);
|
||||
ret = sprintf_s(buf, configLen, "%d", value);
|
||||
ASSERT_GT(ret, 0);
|
||||
|
||||
ret = WriteFile(path.c_str(), buf);
|
||||
ASSERT_NE(ret, -1);
|
||||
|
||||
(void)memset_s(buf, configLen, 0, configLen);
|
||||
ret = ReadFile(path.c_str(), buf);
|
||||
ASSERT_NE(ret, -1);
|
||||
|
||||
GetLine(buf, g_arryLen, g_readLen, array);
|
||||
|
||||
value = atoi(array[1] + strlen("limit: "));
|
||||
ASSERT_EQ(value, MAX_CONTAINER);
|
||||
}
|
||||
Reference in New Issue
Block a user