Home | History | Annotate | Download | only in tests
      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