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
30using namespace testing::ext;
31
32const char *TEST_DATA = "Hello tee!";
33const int TEST_DATA_LEN = strlen(TEST_DATA);
34static const int BUFFER_MAX_LEN = 128;
35
36class HatsTeeTest : public testing::Test {
37public:
38static void SetUpTestCase();
39static void TearDownTestCase();
40void SetUp();
41void TearDown();
42private:
43};
44void HatsTeeTest::SetUp()
45{
46}
47void HatsTeeTest::TearDown()
48{
49}
50void HatsTeeTest::SetUpTestCase()
51{
52}
53void 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 */
65HWTEST_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 */
101HWTEST_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 */
148HWTEST_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 */
173HWTEST_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