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 47 AsyncIOTest() {} 48 ~AsyncIOTest() {} 49 }; 50 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 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 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 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 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 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 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