1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include <stdio.h> 17 #include <string.h> 18 #include <stdlib.h> 19 #include <sys/types.h> 20 #include <sys/stat.h> 21 #include <fcntl.h> 22 #include <unistd.h> 23 #include <gtest/gtest.h> 24 #include "utils.h" 25 #include "log.h" 26 #include "KernelConstants.h" 27 #include <securec.h> 28 29 using namespace testing::ext; 30 31 class PipeTest : public::testing::Test { 32 }; 33 34 /** 35 * @tc.number SUB_KERNEL_IPC_PIPE_0100 36 * @tc.name basic function test 37 * @tc.desc [C- SOFTWARE -0200] 38 */ 39 HWTEST_F(PipeTest, testHelloWorld, Function | MediumTest | Level0) 40 { 41 int fd[2]; 42 char readBuffer[100]; 43 int ret; 44 45 ret = pipe(fd); 46 ASSERT_EQ(ret, 0) << "> parent: pipe errno = " << errno; 47 48 pid_t pid = fork(); 49 ASSERT_TRUE(pid >= 0) << "> parent: fork errno = " << errno; 50 if (pid == 0) { 51 close(fd[1]); 52 if (read(fd[0], readBuffer, 20) == -1) { 53 close(fd[0]); 54 exit(1); 55 } 56 if (strncmp(readBuffer, "hello world", sizeof("hello world")) != 0) { 57 close(fd[0]); 58 exit(1); 59 } 60 close(fd[0]); 61 exit(0); 62 } 63 64 // parent 65 close(fd[0]); 66 ret = write(fd[1], "hello world", sizeof("hello world")); 67 EXPECT_NE(ret, -1) << "> write errno = " << errno; 68 close(fd[1]); 69 70 Msleep(100); 71 WaitProcExitedOK(pid); 72 } 73 74 /** 75 * @tc.number SUB_KERNEL_IPC_PIPE_0200 76 * @tc.name O_NONBLOCK read test 77 * @tc.desc [C- SOFTWARE -0200] 78 */ 79 HWTEST_F(PipeTest, tesPipeNonblack, Function | MediumTest | Level1) 80 { 81 int fd[2]; 82 int ret = pipe(fd); 83 ASSERT_EQ(ret, 0) << "> parent: pipe error ret = %d" << ret; 84 printf("fd %d, %d\n", fd[0], fd[1]); 85 pid_t pid = fork(); 86 ASSERT_TRUE(pid >= 0) << "> parent: fork errno = " << errno; 87 if (pid == 0) { // child --- O_NONBLOCK R test, should be failed 88 char readBuffer[100]; 89 close(fd[1]); 90 if (fcntl(fd[0], F_SETFL, O_NONBLOCK) == -1) { 91 LOG("> child fcntl errno = %d", errno); 92 } 93 ret = read(fd[0], readBuffer, 20); 94 if ((ret != -1) || (errno != EAGAIN)) { 95 LOG("> child : O_NONBLOCK R testfaild"); 96 close(fd[0]); 97 exit(1); 98 } 99 Msleep(100); 100 close(fd[0]); 101 printf("1234 \n"); 102 exit(0); 103 } 104 // parent --- use O_NONBLOCK W test 105 close(fd[0]); 106 Msleep(50); 107 close(fd[1]); 108 109 Msleep(150); 110 WaitProcExitedOK(pid); 111 printf("5678 \n"); 112 } 113 114 /** 115 * @tc.number SUB_KERNEL_IPC_PIPE_0300 116 * @tc.name pipe buffer teset 117 * @tc.desc [C- SOFTWARE -0200] 118 */ 119 HWTEST_F(PipeTest, testPipeBuf, Function | MediumTest | Level3) 120 { 121 const int arrSize = MAX_PIPE_BUFFER + 1000; 122 int fd[2]; 123 int tmpInt; 124 int memRet = -1; 125 char testBuffer[arrSize]; 126 memRet = memset_s(testBuffer, sizeof(testBuffer), '1', sizeof(testBuffer)); 127 EXPECT_EQ(0, memRet); 128 printf("abcd \n"); 129 tmpInt = pipe(fd); 130 ASSERT_EQ(tmpInt, 0) << "> parent: Create Pipe Error! "; 131 printf("fd %d, %d\n", fd[0], fd[1]); 132 133 pid_t pid = fork(); 134 ASSERT_TRUE(pid >= 0) << "> parent: error : fork"; 135 if (pid == 0) { 136 char readBuffer[arrSize]; 137 memRet = memset_s(readBuffer, sizeof(readBuffer), 0, sizeof(readBuffer)); 138 EXPECT_EQ(0, memRet); 139 close(fd[1]); 140 141 Msleep(60); 142 if (fcntl(fd[0], F_SETFL, O_NONBLOCK) == -1) { 143 LOG("> child fcntl errno = %d", errno); 144 } 145 tmpInt = read(fd[0], readBuffer, arrSize); 146 if (tmpInt != MAX_PIPE_BUFFER) { 147 LOG("> child: error : read MAX_PIPE_BUFFER = %d, not %d", tmpInt, MAX_PIPE_BUFFER); 148 close(fd[0]); 149 exit(1); 150 } 151 if (strncmp(testBuffer, readBuffer, MAX_PIPE_BUFFER) != 0) { 152 close(fd[0]); 153 exit(1); 154 } 155 close(fd[0]); 156 exit(0); 157 } 158 159 // parent 160 char writeBuffer[arrSize]; 161 memRet = memset_s(writeBuffer, sizeof(writeBuffer), '1', sizeof(writeBuffer)); 162 EXPECT_EQ(0, memRet); 163 close(fd[0]); 164 165 Msleep(30); 166 EXPECT_NE(fcntl(fd[1], F_SETFL, O_NONBLOCK), -1) << "> fcntl errno = " << errno; 167 printf("efg \n"); 168 tmpInt = write(fd[1], writeBuffer, arrSize); 169 LOG("> parent: write num = %d", tmpInt); 170 EXPECT_NE(tmpInt, -1) << "> parent: error : write num = "<< tmpInt; 171 close(fd[1]); 172 173 Msleep(100); 174 WaitProcExitedOK(pid); 175 } 176 177 /** 178 * @tc.number SUB_KERNEL_IPC_PIPE_0400 179 * @tc.name block pipe teset: MAX_PIPE_BUFFER 180 * @tc.desc [C- SOFTWARE -0200] 181 */ 182 HWTEST_F(PipeTest, testPipeBlock, Function | MediumTest | Level2) 183 { 184 const int arrSize = MAX_PIPE_BUFFER + 1000; 185 int fd[2]; 186 int ret; 187 char testBuffer[arrSize]; 188 int memRet = -1; 189 memRet = memset_s(testBuffer, sizeof(testBuffer), '1', sizeof(testBuffer)); 190 EXPECT_EQ(0, memRet); 191 ret = pipe(fd); 192 ASSERT_EQ(ret, 0) << "> parent: Create Pipe Error! "; 193 194 pid_t pid = fork(); 195 ASSERT_TRUE(pid >= 0) << "> parent: error : fork"; 196 if (pid == 0) { 197 char readBuffer[arrSize]; 198 memRet = memset_s(readBuffer, sizeof(readBuffer), 0, sizeof(readBuffer)); 199 EXPECT_EQ(0, memRet); 200 close(fd[1]); 201 202 Msleep(60); 203 ret = read(fd[0], readBuffer, arrSize); 204 if (ret != arrSize) { 205 LOG("> child: error : read bytes = %d, not %d", ret, arrSize); 206 close(fd[0]); 207 exit(1); 208 } 209 if (strncmp(testBuffer, readBuffer, arrSize) != 0) { 210 close(fd[0]); 211 exit(1); 212 } 213 close(fd[0]); 214 exit(0); 215 } 216 217 // parent 218 char writeBuffer[arrSize]; 219 memRet = memset_s(writeBuffer, sizeof(writeBuffer), '1', sizeof(writeBuffer)); 220 EXPECT_EQ(0, memRet); 221 close(fd[0]); 222 223 Msleep(30); 224 ret = write(fd[1], writeBuffer, arrSize); 225 LOG("> parent: write num = %d", ret); 226 EXPECT_NE(ret, -1) << "> parent: error : write num = "<< ret; 227 close(fd[1]); 228 229 Msleep(100); 230 WaitProcExitedOK(pid); 231 } 232 233 /** 234 * @tc.number SUB_KERNEL_IPC_PIPE_0600 235 * @tc.name test pipe-ipc between brother 236 * @tc.desc [C- SOFTWARE -0200] 237 */ 238 HWTEST_F(PipeTest, testBrotherHelloWorld, Function | MediumTest | Level1) 239 { 240 int fd[2]; 241 char readBuffer[100]; 242 int ret; 243 244 ret = pipe(fd); 245 ASSERT_EQ(ret, 0) << "> parent: pipe errno = " << errno; 246 247 pid_t pidChild1 = fork(); 248 ASSERT_TRUE(pidChild1 >= 0) << "> parent: fork errno = " << errno; 249 if (pidChild1 == 0) { 250 close(fd[1]); 251 if (read(fd[0], readBuffer, 20) == -1) { 252 close(fd[0]); 253 exit(1); 254 } 255 if (strncmp(readBuffer, "hello world", sizeof("hello world")) != 0) { 256 close(fd[0]); 257 exit(1); 258 } 259 close(fd[0]); 260 exit(0); 261 } 262 263 pid_t pidChild2 = fork(); 264 ASSERT_TRUE(pidChild2 >= 0) << "> parent: fork errno = " << errno; 265 if (pidChild2 == 0) { 266 close(fd[0]); 267 ret = write(fd[1], "hello world", sizeof("hello world")); 268 if (ret == -1) { 269 LOG("> child write errno = %d", errno); 270 } 271 close(fd[1]); 272 exit(0); 273 } 274 275 close(fd[0]); 276 close(fd[1]); 277 278 Msleep(100); 279 WaitProcExitedOK(pidChild1); 280 WaitProcExitedOK(pidChild2); 281 } 282