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 <gtest/gtest.h>
24 #include <sys/stat.h>
25 #include <sys/types.h>
26 #include <sys/uio.h>
27 #include "securec.h"
28 
29 
30 using namespace testing::ext;
31 using namespace std;
32 
33 static const char *TEST_FILE = "/data/local/tmp/readv_test_file.txt";
34 static const char *TEST_DATA = "Hello World!";
35 static const int TEST_DATA_LEN = strlen(TEST_DATA);
36 static const int MAX_LEN = 128;
37 
38 class ReadvApiTest : public testing::Test {
39 public:
40     static void SetUpTestCase();
41     static void TearDownTestCase();
42     void SetUp();
43     void TearDown();
44 private:
45 };
SetUp()46 void ReadvApiTest::SetUp()
47 {
48     int fd = open(TEST_FILE, O_WRONLY | O_CREAT, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
49     write(fd, TEST_DATA, TEST_DATA_LEN);
50     close(fd);
51 }
TearDown()52 void ReadvApiTest::TearDown()
53 {
54     (void)remove(TEST_FILE);
55 }
SetUpTestCase()56 void ReadvApiTest::SetUpTestCase()
57 {
58 }
TearDownTestCase()59 void ReadvApiTest::TearDownTestCase()
60 {
61 }
62 
63 /*
64  * @tc.number : SUB_KERNEL_SYSCALL_READV_0100
65  * @tc.name   : ReadvFileSuccess_0001
66  * @tc.desc   : readv read file Success.
67  * @tc.size   : MediumTest
68  * @tc.type   : Function
69  * @tc.level  : Level 1
70  */
HWTEST_F(ReadvApiTest, ReadvReadEmptyFileSuccess_0001, Function | MediumTest | Level1)71 HWTEST_F(ReadvApiTest, ReadvReadEmptyFileSuccess_0001, Function | MediumTest | Level1)
72 {
73     char buffer[MAX_LEN] = { 0 };
74     struct iovec iov[2] = {
75         {
76             .iov_base = buffer,
77             .iov_len = TEST_DATA_LEN,
78         }, {
79             .iov_base = &buffer[TEST_DATA_LEN],
80             .iov_len = TEST_DATA_LEN,
81         }
82     };
83 
84     int fd = open(TEST_FILE, O_RDONLY, 0644);
85     EXPECT_TRUE(fd > 0);
86 
87     ssize_t size = readv(fd, iov, 2);
88     EXPECT_EQ(size, TEST_DATA_LEN);
89     EXPECT_STREQ(static_cast<char *>(iov[0].iov_base), TEST_DATA);
90 
91     close(fd);
92 }
93 
94 /*
95  * @tc.number : SUB_KERNEL_SYSCALL_READV_0200
96  * @tc.name   : ReadvInvalidFdFailed_0002
97  * @tc.desc   : readv read with invalid fd failed.
98  * @tc.size   : MediumTest
99  * @tc.type   : Function
100  * @tc.level  : Level 2
101  */
HWTEST_F(ReadvApiTest, ReadvInvalidFdFailed_0002, Function | MediumTest | Level2)102 HWTEST_F(ReadvApiTest, ReadvInvalidFdFailed_0002, Function | MediumTest | Level2)
103 {
104     char buffer[MAX_LEN] = { 0 };
105     struct iovec iov[2] = {
106         {
107             .iov_base = buffer,
108             .iov_len = TEST_DATA_LEN,
109         }, {
110             .iov_base = &buffer[TEST_DATA_LEN],
111             .iov_len = TEST_DATA_LEN,
112         }
113     };
114 
115     errno = 0;
116     ssize_t size = readv(-1, iov, 2);
117     EXPECT_EQ(size, -1);
118     EXPECT_EQ(errno, EBADF);
119 }
120 
121 /*
122  * @tc.number : SUB_KERNEL_SYSCALL_READV_0300
123  * @tc.name   : ReadvReadUseTwoBufferSuccess_0003
124  * @tc.desc   : readv file use two iov buffer success.
125  * @tc.size   : MediumTest
126  * @tc.type   : Function
127  * @tc.level  : Level 1
128  */
HWTEST_F(ReadvApiTest, ReadvReadUseTwoBufferSuccess_0003, Function | MediumTest | Level1)129 HWTEST_F(ReadvApiTest, ReadvReadUseTwoBufferSuccess_0003, Function | MediumTest | Level1)
130 {
131     ssize_t size;
132     const char *content = "this is a test file.";
133     char buffer[MAX_LEN] = { 0 };
134     struct iovec iov[2] = {
135         {
136             .iov_base = buffer,
137             .iov_len = TEST_DATA_LEN,
138         }, {
139             .iov_base = &buffer[MAX_LEN / 2],
140             .iov_len = strlen(content),
141         }
142     };
143 
144     int fd = open(TEST_FILE, O_RDWR | O_APPEND, 0644);
145     write(fd, content, strlen(content));
146     close(fd);
147 
148     fd = open(TEST_FILE, O_RDWR, 0644);
149 
150     // readv content to 2 iovec
151     size = readv(fd, iov, 2);
152     EXPECT_EQ(size, TEST_DATA_LEN + strlen(content));
153     EXPECT_STREQ(static_cast<char *>(iov[0].iov_base), TEST_DATA);
154     EXPECT_STREQ(static_cast<char *>(iov[1].iov_base), content);
155 
156     close(fd);
157 }