• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #define LOG_TAG "AsyncIO_test.cpp"
17 
18 #include <android-base/test_utils.h>
19 #include <fcntl.h>
20 #include <gtest/gtest.h>
21 #include <string>
22 #include <unistd.h>
23 #include <utils/Log.h>
24 
25 #include "AsyncIO.h"
26 
27 namespace android {
28 
29 constexpr int TEST_PACKET_SIZE = 512;
30 constexpr int POOL_COUNT = 10;
31 
32 static const std::string dummyDataStr =
33     "/*\n * Copyright 2015 The Android Open Source Project\n *\n * Licensed un"
34     "der the Apache License, Version 2.0 (the \"License\");\n * you may not us"
35     "e this file except in compliance with the License.\n * You may obtain a c"
36     "opy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE"
37     "-2.0\n *\n * Unless required by applicable law or agreed to in writing, s"
38     "oftware\n * distributed under the License is distributed on an \"AS IS\" "
39     "BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express o"
40     "r implied.\n * Se";
41 
42 
43 class AsyncIOTest : public ::testing::Test {
44 protected:
45     TemporaryFile dummy_file;
46 
AsyncIOTest()47     AsyncIOTest() {}
~AsyncIOTest()48     ~AsyncIOTest() {}
49 };
50 
TEST_F(AsyncIOTest,testRead)51 TEST_F(AsyncIOTest, testRead) {
52     char buf[TEST_PACKET_SIZE + 1];
53     buf[TEST_PACKET_SIZE] = '\0';
54     EXPECT_EQ(write(dummy_file.fd, dummyDataStr.c_str(), TEST_PACKET_SIZE), TEST_PACKET_SIZE);
55     struct aiocb aio;
56     struct aiocb *aiol[] = {&aio};
57     aio.aio_fildes = dummy_file.fd;
58     aio.aio_buf = buf;
59     aio.aio_offset = 0;
60     aio.aio_nbytes = TEST_PACKET_SIZE;
61 
62     EXPECT_EQ(aio_read(&aio), 0);
63     EXPECT_EQ(aio_suspend(aiol, 1, nullptr), 0);
64     EXPECT_EQ(aio_return(&aio), TEST_PACKET_SIZE);
65     EXPECT_STREQ(buf, dummyDataStr.c_str());
66 }
67 
TEST_F(AsyncIOTest,testWrite)68 TEST_F(AsyncIOTest, testWrite) {
69     char buf[TEST_PACKET_SIZE + 1];
70     buf[TEST_PACKET_SIZE] = '\0';
71     struct aiocb aio;
72     struct aiocb *aiol[] = {&aio};
73     aio.aio_fildes = dummy_file.fd;
74     aio.aio_buf = const_cast<char*>(dummyDataStr.c_str());
75     aio.aio_offset = 0;
76     aio.aio_nbytes = TEST_PACKET_SIZE;
77 
78     EXPECT_EQ(aio_write(&aio), 0);
79     EXPECT_EQ(aio_suspend(aiol, 1, nullptr), 0);
80     EXPECT_EQ(aio_return(&aio), TEST_PACKET_SIZE);
81     EXPECT_EQ(read(dummy_file.fd, buf, TEST_PACKET_SIZE), TEST_PACKET_SIZE);
82     EXPECT_STREQ(buf, dummyDataStr.c_str());
83 }
84 
TEST_F(AsyncIOTest,testError)85 TEST_F(AsyncIOTest, testError) {
86     char buf[TEST_PACKET_SIZE + 1];
87     buf[TEST_PACKET_SIZE] = '\0';
88     struct aiocb aio;
89     struct aiocb *aiol[] = {&aio};
90     aio.aio_fildes = -1;
91     aio.aio_buf = const_cast<char*>(dummyDataStr.c_str());
92     aio.aio_offset = 0;
93     aio.aio_nbytes = TEST_PACKET_SIZE;
94 
95     EXPECT_EQ(aio_write(&aio), 0);
96     EXPECT_EQ(aio_suspend(aiol, 1, nullptr), 0);
97     EXPECT_EQ(aio_return(&aio), -1);
98     EXPECT_EQ(aio_error(&aio), EBADF);
99 }
100 
TEST_F(AsyncIOTest,testSpliceRead)101 TEST_F(AsyncIOTest, testSpliceRead) {
102     char buf[TEST_PACKET_SIZE + 1];
103     buf[TEST_PACKET_SIZE] = '\0';
104     int pipeFd[2];
105     EXPECT_EQ(pipe(pipeFd), 0);
106     EXPECT_EQ(write(dummy_file.fd, dummyDataStr.c_str(), TEST_PACKET_SIZE), TEST_PACKET_SIZE);
107     struct aiocb aio;
108     struct aiocb *aiol[] = {&aio};
109     aio.aio_fildes = dummy_file.fd;
110     aio.aio_sink = pipeFd[1];
111     aio.aio_offset = 0;
112     aio.aio_nbytes = TEST_PACKET_SIZE;
113 
114     EXPECT_EQ(aio_splice_read(&aio), 0);
115     EXPECT_EQ(aio_suspend(aiol, 1, nullptr), 0);
116     EXPECT_EQ(aio_return(&aio), TEST_PACKET_SIZE);
117 
118     EXPECT_EQ(read(pipeFd[0], buf, TEST_PACKET_SIZE), TEST_PACKET_SIZE);
119     EXPECT_STREQ(buf, dummyDataStr.c_str());
120 }
121 
TEST_F(AsyncIOTest,testSpliceWrite)122 TEST_F(AsyncIOTest, testSpliceWrite) {
123     char buf[TEST_PACKET_SIZE + 1];
124     buf[TEST_PACKET_SIZE] = '\0';
125     int pipeFd[2];
126     EXPECT_EQ(pipe(pipeFd), 0);
127     EXPECT_EQ(write(pipeFd[1], dummyDataStr.c_str(), TEST_PACKET_SIZE), TEST_PACKET_SIZE);
128     struct aiocb aio;
129     struct aiocb *aiol[] = {&aio};
130     aio.aio_fildes = pipeFd[0];
131     aio.aio_sink = dummy_file.fd;
132     aio.aio_offset = 0;
133     aio.aio_nbytes = TEST_PACKET_SIZE;
134 
135     EXPECT_EQ(aio_splice_write(&aio), 0);
136     EXPECT_EQ(aio_suspend(aiol, 1, nullptr), 0);
137     EXPECT_EQ(aio_return(&aio), TEST_PACKET_SIZE);
138     EXPECT_EQ(read(dummy_file.fd, buf, TEST_PACKET_SIZE), TEST_PACKET_SIZE);
139     EXPECT_STREQ(buf, dummyDataStr.c_str());
140 }
141 
TEST_F(AsyncIOTest,testPoolWrite)142 TEST_F(AsyncIOTest, testPoolWrite) {
143     aio_pool_write_init();
144     char buf[TEST_PACKET_SIZE * POOL_COUNT + 1];
145     buf[TEST_PACKET_SIZE * POOL_COUNT] = '\0';
146 
147     for (int i = 0; i < POOL_COUNT; i++) {
148         struct aiocb *aiop = new struct aiocb;
149         aiop->aio_fildes = dummy_file.fd;
150         aiop->aio_pool_buf = std::unique_ptr<char[]>(new char[TEST_PACKET_SIZE]);
151         memcpy(aiop->aio_pool_buf.get(), dummyDataStr.c_str(), TEST_PACKET_SIZE);
152         aiop->aio_offset = i * TEST_PACKET_SIZE;
153         aiop->aio_nbytes = TEST_PACKET_SIZE;
154         EXPECT_EQ(aio_pool_write(aiop), 0);
155     }
156     aio_pool_end();
157     EXPECT_EQ(read(dummy_file.fd, buf, TEST_PACKET_SIZE * POOL_COUNT), TEST_PACKET_SIZE * POOL_COUNT);
158 
159     std::stringstream ss;
160     for (int i = 0; i < POOL_COUNT; i++)
161         ss << dummyDataStr;
162 
163     EXPECT_STREQ(buf, ss.str().c_str());
164 }
165 
TEST_F(AsyncIOTest,testSplicePoolWrite)166 TEST_F(AsyncIOTest, testSplicePoolWrite) {
167     aio_pool_splice_init();
168     char buf[TEST_PACKET_SIZE * POOL_COUNT + 1];
169     buf[TEST_PACKET_SIZE * POOL_COUNT] = '\0';
170 
171     for (int i = 0; i < POOL_COUNT; i++) {
172         int pipeFd[2];
173         EXPECT_EQ(pipe(pipeFd), 0);
174         EXPECT_EQ(write(pipeFd[1], dummyDataStr.c_str(), TEST_PACKET_SIZE), TEST_PACKET_SIZE);
175         struct aiocb *aiop = new struct aiocb;
176         aiop->aio_fildes = pipeFd[0];
177         aiop->aio_sink = dummy_file.fd;
178         aiop->aio_offset = i * TEST_PACKET_SIZE;
179         aiop->aio_nbytes = TEST_PACKET_SIZE;
180         EXPECT_EQ(aio_pool_write(aiop), 0);
181     }
182     aio_pool_end();
183     EXPECT_EQ(read(dummy_file.fd, buf, TEST_PACKET_SIZE * POOL_COUNT), TEST_PACKET_SIZE * POOL_COUNT);
184 
185     std::stringstream ss;
186     for (int i = 0; i < POOL_COUNT; i++)
187         ss << dummyDataStr;
188 
189     EXPECT_STREQ(buf, ss.str().c_str());
190 }
191 
192 } // namespace android
193