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