1 /*
2 * Copyright (C) 2024 HiHope Open Source Organization.
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 <cerrno>
17 #include <cstdio>
18 #include <cstdlib>
19 #include <string>
20 #include <vector>
21 #include <fcntl.h>
22 #include <unistd.h>
23 #include <arpa/inet.h>
24 #include <gtest/gtest.h>
25 #include <netinet/in.h>
26 #include <sys/stat.h>
27 #include <sys/socket.h>
28 #include <sys/types.h>
29
30 using namespace testing::ext;
31
32 const char *TEST_DATA = "Hello tee!";
33 const int TEST_DATA_LEN = strlen(TEST_DATA);
34 static const int BUFFER_MAX_LEN = 128;
35
36 class HatsTeeTest : public testing::Test {
37 public:
38 static void SetUpTestCase();
39 static void TearDownTestCase();
40 void SetUp();
41 void TearDown();
42 private:
43 };
SetUp()44 void HatsTeeTest::SetUp()
45 {
46 }
TearDown()47 void HatsTeeTest::TearDown()
48 {
49 }
SetUpTestCase()50 void HatsTeeTest::SetUpTestCase()
51 {
52 }
TearDownTestCase()53 void HatsTeeTest::TearDownTestCase()
54 {
55 }
56
57 /*
58 * @tc.number : SUB_KERNEL_SYSCALL_TEE_0100
59 * @tc.name : TeeCopyDataSuccess_0001
60 * @tc.desc : Tee copys data from pipe1 to pipe2 success.
61 * @tc.size : MediumTest
62 * @tc.type : Function
63 * @tc.level : Level 1
64 */
HWTEST_F(HatsTeeTest, TeeCopyDataSuccess_0001, Function | MediumTest | Level1)65 HWTEST_F(HatsTeeTest, TeeCopyDataSuccess_0001, Function | MediumTest | Level1)
66 {
67 int ret;
68 int pipeFd1[2];
69 int pipeFd2[2];
70 char buffer[BUFFER_MAX_LEN] = { 0 };
71
72 ret = pipe(pipeFd1);
73 EXPECT_EQ(ret, 0);
74 ret = pipe(pipeFd2);
75 EXPECT_EQ(ret, 0);
76
77 ssize_t size = write(pipeFd1[1], TEST_DATA, TEST_DATA_LEN);
78 EXPECT_EQ(size, TEST_DATA_LEN);
79
80 size = tee(pipeFd1[0], pipeFd2[1], TEST_DATA_LEN, SPLICE_F_NONBLOCK);
81 EXPECT_EQ(size, TEST_DATA_LEN);
82
83 size = read(pipeFd2[0], buffer, sizeof(buffer));
84 EXPECT_EQ(size, TEST_DATA_LEN);
85 EXPECT_STREQ(buffer, TEST_DATA);
86
87 close(pipeFd1[0]);
88 close(pipeFd1[1]);
89 close(pipeFd2[0]);
90 close(pipeFd2[1]);
91 }
92
93 /*
94 * @tc.number : SUB_KERNEL_SYSCALL_TEE_0200
95 * @tc.name : TeeTestFileFdFail_0002
96 * @tc.desc : Tee fd is file fd instead of pipe fd fail.
97 * @tc.size : MediumTest
98 * @tc.type : Function
99 * @tc.level : Level 2
100 */
HWTEST_F(HatsTeeTest, TeeTestFileFdFail_0002, Function | MediumTest | Level2)101 HWTEST_F(HatsTeeTest, TeeTestFileFdFail_0002, Function | MediumTest | Level2)
102 {
103 int ret;
104 int fd1;
105 int fd2;
106 int pipeFd[2];
107
108 const char *teeFile1 = "/data/local/tmp/tryTee1.txt";
109 const char *teeFile2 = "/data/local/tmp/tryTee2.txt";
110
111 fd1 = open(teeFile1, O_RDWR | O_CREAT | O_TRUNC, 0644);
112 EXPECT_TRUE(fd1 >= 0);
113 fd2 = open(teeFile2, O_RDWR | O_CREAT | O_TRUNC, 0644);
114 EXPECT_TRUE(fd2 >= 0);
115 ret = pipe(pipeFd);
116 EXPECT_EQ(ret, 0);
117
118 errno = 0;
119 ssize_t size = tee(fd1, fd2, TEST_DATA_LEN, SPLICE_F_NONBLOCK);
120 EXPECT_EQ(size, -1);
121 EXPECT_EQ(errno, EINVAL);
122
123 errno = 0;
124 size = tee(fd1, pipeFd[1], TEST_DATA_LEN, SPLICE_F_NONBLOCK);
125 EXPECT_EQ(size, -1);
126 EXPECT_EQ(errno, EINVAL);
127
128 errno = 0;
129 size = tee(pipeFd[0], fd2, TEST_DATA_LEN, SPLICE_F_NONBLOCK);
130 EXPECT_EQ(size, -1);
131 EXPECT_EQ(errno, EINVAL);
132
133 close(pipeFd[0]);
134 close(pipeFd[1]);
135
136 close(fd1);
137 close(fd2);
138 }
139
140 /*
141 * @tc.number : SUB_KERNEL_SYSCALL_TEE_0300
142 * @tc.name : TeeFdsReferToSamePipeFail_0003
143 * @tc.desc : Tee fds refer to same pipe fail.
144 * @tc.size : MediumTest
145 * @tc.type : Function
146 * @tc.level : Level 2
147 */
HWTEST_F(HatsTeeTest, TeeFdsReferToSamePipeFail_0003, Function | MediumTest | Level2)148 HWTEST_F(HatsTeeTest, TeeFdsReferToSamePipeFail_0003, Function | MediumTest | Level2)
149 {
150 int ret;
151 int pipeFd[2];
152
153 ret = pipe(pipeFd);
154 EXPECT_TRUE(ret == 0);
155
156 errno = 0;
157 ssize_t size = tee(pipeFd[0], pipeFd[1], TEST_DATA_LEN, SPLICE_F_NONBLOCK);
158 EXPECT_EQ(size, -1);
159 EXPECT_EQ(errno, EINVAL);
160
161 close(pipeFd[0]);
162 close(pipeFd[1]);
163 }
164
165 /*
166 * @tc.number : SUB_KERNEL_SYSCALL_TEE_0400
167 * @tc.name : TeeInvalidFdFail_0004
168 * @tc.desc : Tee fd is not valid fail.
169 * @tc.size : MediumTest
170 * @tc.type : Function
171 * @tc.level : Level 2
172 */
HWTEST_F(HatsTeeTest, TeeInvalidFdFail_0004, Function | MediumTest | Level2)173 HWTEST_F(HatsTeeTest, TeeInvalidFdFail_0004, Function | MediumTest | Level2)
174 {
175 errno = 0;
176 ssize_t size = tee(-1, -1, TEST_DATA_LEN, SPLICE_F_NONBLOCK);
177 EXPECT_EQ(size, -1);
178 EXPECT_EQ(errno, EBADF);
179 }
180