/* * Copyright (c) 2021 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include #include "utils.h" #include "log.h" #include "KernelConstants.h" #include using namespace testing::ext; class PipeTest : public::testing::Test { }; /** * @tc.number SUB_KERNEL_IPC_PIPE_0100 * @tc.name basic function test * @tc.desc [C- SOFTWARE -0200] */ HWTEST_F(PipeTest, testHelloWorld, Function | MediumTest | Level0) { int fd[2]; char readBuffer[100]; int ret; ret = pipe(fd); ASSERT_EQ(ret, 0) << "> parent: pipe errno = " << errno; pid_t pid = fork(); ASSERT_TRUE(pid >= 0) << "> parent: fork errno = " << errno; if (pid == 0) { close(fd[1]); if (read(fd[0], readBuffer, 20) == -1) { close(fd[0]); exit(1); } if (strncmp(readBuffer, "hello world", sizeof("hello world")) != 0) { close(fd[0]); exit(1); } close(fd[0]); exit(0); } // parent close(fd[0]); ret = write(fd[1], "hello world", sizeof("hello world")); EXPECT_NE(ret, -1) << "> write errno = " << errno; close(fd[1]); Msleep(100); AssertProcExitedOK(pid); } /** * @tc.number SUB_KERNEL_IPC_PIPE_0200 * @tc.name O_NONBLOCK read test * @tc.desc [C- SOFTWARE -0200] */ HWTEST_F(PipeTest, tesPipeNonblack, Function | MediumTest | Level1) { int fd[2]; int ret = pipe(fd); ASSERT_EQ(ret, 0) << "> parent: pipe error ret = %d" << ret; pid_t pid = fork(); ASSERT_TRUE(pid >= 0) << "> parent: fork errno = " << errno; if (pid == 0) { // child --- O_NONBLOCK R test, should be failed char readBuffer[100]; close(fd[1]); if (fcntl(fd[0], F_SETFL, O_NONBLOCK) == -1) { LOG("> child fcntl errno = %d", errno); } ret = read(fd[0], readBuffer, 20); if ((ret != -1) || (errno != EAGAIN)) { LOG("> child : O_NONBLOCK R testfaild"); close(fd[0]); exit(1); } Msleep(100); close(fd[0]); exit(0); } // parent --- use O_NONBLOCK W test close(fd[0]); Msleep(50); ret = write(fd[1], "O_NONBLOCK R test", sizeof("O_NONBLOCK R test")); ASSERT_NE(ret, -1) << "> parent : O_NONBLOCK write error"; close(fd[1]); Msleep(150); AssertProcExitedOK(pid); } /** * @tc.number SUB_KERNEL_IPC_PIPE_0300 * @tc.name pipe buffer teset * @tc.desc [C- SOFTWARE -0200] */ HWTEST_F(PipeTest, testPipeBuf, Function | MediumTest | Level3) { const int arrSize = MAX_PIPE_BUFFER + 1000; int fd[2]; int tmpInt; char testBuffer[arrSize]; memset_s(testBuffer, sizeof(testBuffer), '1', sizeof(testBuffer)); tmpInt = pipe(fd); ASSERT_EQ(tmpInt, 0) << "> parent: Create Pipe Error! "; pid_t pid = fork(); ASSERT_TRUE(pid >= 0) << "> parent: error : fork"; if (pid == 0) { char readBuffer[arrSize]; memset_s(readBuffer, sizeof(readBuffer), 0, sizeof(readBuffer)); close(fd[1]); Msleep(60); if (fcntl(fd[0], F_SETFL, O_NONBLOCK) == -1) { LOG("> child fcntl errno = %d", errno); } tmpInt = read(fd[0], readBuffer, arrSize); if (tmpInt != MAX_PIPE_BUFFER) { LOG("> child: error : read MAX_PIPE_BUFFER = %d, not %d", tmpInt, MAX_PIPE_BUFFER); close(fd[0]); exit(1); } if (strncmp(testBuffer, readBuffer, MAX_PIPE_BUFFER) != 0) { close(fd[0]); exit(1); } close(fd[0]); exit(0); } // parent char writeBuffer[arrSize]; memset_s(writeBuffer, sizeof(writeBuffer), '1', sizeof(writeBuffer)); close(fd[0]); Msleep(30); EXPECT_NE(fcntl(fd[1], F_SETFL, O_NONBLOCK), -1) << "> fcntl errno = " << errno; tmpInt = write(fd[1], writeBuffer, arrSize); LOG("> parent: write num = %d", tmpInt); EXPECT_NE(tmpInt, -1) << "> parent: error : write num = "<< tmpInt; close(fd[1]); Msleep(100); AssertProcExitedOK(pid); } /** * @tc.number SUB_KERNEL_IPC_PIPE_0400 * @tc.name block pipe teset: MAX_PIPE_BUFFER * @tc.desc [C- SOFTWARE -0200] */ HWTEST_F(PipeTest, testPipeBlock, Function | MediumTest | Level2) { const int arrSize = MAX_PIPE_BUFFER + 1000; int fd[2]; int ret; char testBuffer[arrSize]; memset_s(testBuffer, sizeof(testBuffer), '1', sizeof(testBuffer)); ret = pipe(fd); ASSERT_EQ(ret, 0) << "> parent: Create Pipe Error! "; pid_t pid = fork(); ASSERT_TRUE(pid >= 0) << "> parent: error : fork"; if (pid == 0) { char readBuffer[arrSize]; memset_s(readBuffer, sizeof(readBuffer), 0, sizeof(readBuffer)); close(fd[1]); Msleep(60); ret = read(fd[0], readBuffer, arrSize); if (ret != arrSize) { LOG("> child: error : read bytes = %d, not %d", ret, arrSize); close(fd[0]); exit(1); } if (strncmp(testBuffer, readBuffer, arrSize) != 0) { close(fd[0]); exit(1); } close(fd[0]); exit(0); } // parent char writeBuffer[arrSize]; memset_s(writeBuffer, sizeof(writeBuffer), '1', sizeof(writeBuffer)); close(fd[0]); Msleep(30); ret = write(fd[1], writeBuffer, arrSize); LOG("> parent: write num = %d", ret); EXPECT_NE(ret, -1) << "> parent: error : write num = "<< ret; close(fd[1]); Msleep(100); AssertProcExitedOK(pid); } /** * @tc.number SUB_KERNEL_IPC_PIPE_0600 * @tc.name test pipe-ipc between brother * @tc.desc [C- SOFTWARE -0200] */ HWTEST_F(PipeTest, testBrotherHelloWorld, Function | MediumTest | Level1) { int fd[2]; char readBuffer[100]; int ret; ret = pipe(fd); ASSERT_EQ(ret, 0) << "> parent: pipe errno = " << errno; pid_t pidChild1 = fork(); ASSERT_TRUE(pidChild1 >= 0) << "> parent: fork errno = " << errno; if (pidChild1 == 0) { close(fd[1]); if (read(fd[0], readBuffer, 20) == -1) { close(fd[0]); exit(1); } if (strncmp(readBuffer, "hello world", sizeof("hello world")) != 0) { close(fd[0]); exit(1); } close(fd[0]); exit(0); } pid_t pidChild2 = fork(); ASSERT_TRUE(pidChild2 >= 0) << "> parent: fork errno = " << errno; if (pidChild2 == 0) { close(fd[0]); ret = write(fd[1], "hello world", sizeof("hello world")); if (ret == -1) { LOG("> child write errno = %d", errno); } close(fd[1]); exit(0); } close(fd[0]); close(fd[1]); Msleep(100); AssertProcExitedOK(pidChild1); AssertProcExitedOK(pidChild2); }