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 char testBuffer[arrSize]; 125 memset_s(testBuffer, sizeof(testBuffer), '1', sizeof(testBuffer)); 126 printf("abcd \n"); 127 tmpInt = pipe(fd); 128 ASSERT_EQ(tmpInt, 0) << "> parent: Create Pipe Error! "; 129 printf("fd %d, %d\n", fd[0], fd[1]); 130 131 pid_t pid = fork(); 132 ASSERT_TRUE(pid >= 0) << "> parent: error : fork"; 133 if (pid == 0) { 134 char readBuffer[arrSize]; 135 memset_s(readBuffer, sizeof(readBuffer), 0, sizeof(readBuffer)); 136 close(fd[1]); 137 138 Msleep(60); 139 if (fcntl(fd[0], F_SETFL, O_NONBLOCK) == -1) { 140 LOG("> child fcntl errno = %d", errno); 141 } 142 tmpInt = read(fd[0], readBuffer, arrSize); 143 if (tmpInt != MAX_PIPE_BUFFER) { 144 LOG("> child: error : read MAX_PIPE_BUFFER = %d, not %d", tmpInt, MAX_PIPE_BUFFER); 145 close(fd[0]); 146 exit(1); 147 } 148 if (strncmp(testBuffer, readBuffer, MAX_PIPE_BUFFER) != 0) { 149 close(fd[0]); 150 exit(1); 151 } 152 close(fd[0]); 153 exit(0); 154 } 155 156 // parent 157 char writeBuffer[arrSize]; 158 memset_s(writeBuffer, sizeof(writeBuffer), '1', sizeof(writeBuffer)); 159 close(fd[0]); 160 161 Msleep(30); 162 EXPECT_NE(fcntl(fd[1], F_SETFL, O_NONBLOCK), -1) << "> fcntl errno = " << errno; 163 printf("efg \n"); 164 tmpInt = write(fd[1], writeBuffer, arrSize); 165 LOG("> parent: write num = %d", tmpInt); 166 EXPECT_NE(tmpInt, -1) << "> parent: error : write num = "<< tmpInt; 167 close(fd[1]); 168 169 Msleep(100); 170 WaitProcExitedOK(pid); 171 } 172 173 /** 174 * @tc.number SUB_KERNEL_IPC_PIPE_0400 175 * @tc.name block pipe teset: MAX_PIPE_BUFFER 176 * @tc.desc [C- SOFTWARE -0200] 177 */ 178 HWTEST_F(PipeTest, testPipeBlock, Function | MediumTest | Level2) 179 { 180 const int arrSize = MAX_PIPE_BUFFER + 1000; 181 int fd[2]; 182 int ret; 183 char testBuffer[arrSize]; 184 memset_s(testBuffer, sizeof(testBuffer), '1', sizeof(testBuffer)); 185 186 ret = pipe(fd); 187 ASSERT_EQ(ret, 0) << "> parent: Create Pipe Error! "; 188 189 pid_t pid = fork(); 190 ASSERT_TRUE(pid >= 0) << "> parent: error : fork"; 191 if (pid == 0) { 192 char readBuffer[arrSize]; 193 memset_s(readBuffer, sizeof(readBuffer), 0, sizeof(readBuffer)); 194 close(fd[1]); 195 196 Msleep(60); 197 ret = read(fd[0], readBuffer, arrSize); 198 if (ret != arrSize) { 199 LOG("> child: error : read bytes = %d, not %d", ret, arrSize); 200 close(fd[0]); 201 exit(1); 202 } 203 if (strncmp(testBuffer, readBuffer, arrSize) != 0) { 204 close(fd[0]); 205 exit(1); 206 } 207 close(fd[0]); 208 exit(0); 209 } 210 211 // parent 212 char writeBuffer[arrSize]; 213 memset_s(writeBuffer, sizeof(writeBuffer), '1', sizeof(writeBuffer)); 214 close(fd[0]); 215 216 Msleep(30); 217 ret = write(fd[1], writeBuffer, arrSize); 218 LOG("> parent: write num = %d", ret); 219 EXPECT_NE(ret, -1) << "> parent: error : write num = "<< ret; 220 close(fd[1]); 221 222 Msleep(100); 223 WaitProcExitedOK(pid); 224 } 225 226 /** 227 * @tc.number SUB_KERNEL_IPC_PIPE_0600 228 * @tc.name test pipe-ipc between brother 229 * @tc.desc [C- SOFTWARE -0200] 230 */ 231 HWTEST_F(PipeTest, testBrotherHelloWorld, Function | MediumTest | Level1) 232 { 233 int fd[2]; 234 char readBuffer[100]; 235 int ret; 236 237 ret = pipe(fd); 238 ASSERT_EQ(ret, 0) << "> parent: pipe errno = " << errno; 239 240 pid_t pidChild1 = fork(); 241 ASSERT_TRUE(pidChild1 >= 0) << "> parent: fork errno = " << errno; 242 if (pidChild1 == 0) { 243 close(fd[1]); 244 if (read(fd[0], readBuffer, 20) == -1) { 245 close(fd[0]); 246 exit(1); 247 } 248 if (strncmp(readBuffer, "hello world", sizeof("hello world")) != 0) { 249 close(fd[0]); 250 exit(1); 251 } 252 close(fd[0]); 253 exit(0); 254 } 255 256 pid_t pidChild2 = fork(); 257 ASSERT_TRUE(pidChild2 >= 0) << "> parent: fork errno = " << errno; 258 if (pidChild2 == 0) { 259 close(fd[0]); 260 ret = write(fd[1], "hello world", sizeof("hello world")); 261 if (ret == -1) { 262 LOG("> child write errno = %d", errno); 263 } 264 close(fd[1]); 265 exit(0); 266 } 267 268 close(fd[0]); 269 close(fd[1]); 270 271 Msleep(100); 272 WaitProcExitedOK(pidChild1); 273 WaitProcExitedOK(pidChild2); 274 } 275