Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright 2018 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 
     17 #define LOG_TAG "BufferHubEventFdTest"
     18 
     19 #include <sys/epoll.h>
     20 #include <sys/eventfd.h>
     21 
     22 #include <array>
     23 #include <condition_variable>
     24 #include <mutex>
     25 #include <thread>
     26 
     27 #include <gmock/gmock.h>
     28 #include <gtest/gtest.h>
     29 #include <log/log.h>
     30 #include <ui/BufferHubEventFd.h>
     31 
     32 namespace android {
     33 
     34 namespace {
     35 
     36 const int kTimeout = 100;
     37 const std::chrono::milliseconds kTimeoutMs(kTimeout);
     38 const int kTestRuns = 5;
     39 
     40 using ::testing::Contains;
     41 using BufferHubEventFdTest = ::testing::Test;
     42 
     43 } // namespace
     44 
     45 TEST_F(BufferHubEventFdTest, EventFd_testSingleEpollFd) {
     46     BufferHubEventFd eventFd;
     47     ASSERT_TRUE(eventFd.isValid());
     48 
     49     base::unique_fd epollFd(epoll_create(64));
     50     ASSERT_GE(epollFd.get(), 0);
     51 
     52     epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}};
     53     ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
     54 
     55     std::array<epoll_event, 1> events;
     56     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
     57 
     58     eventFd.signal();
     59     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
     60 
     61     // The epoll fd is edge triggered, so it only responds to the eventFd once.
     62     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
     63 
     64     // Check that it can receive consecutive signal.
     65     eventFd.signal();
     66     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
     67     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
     68 
     69     // Check that it can receive consecutive signal from a duplicated eventfd.
     70     BufferHubEventFd dupEventFd(dup(eventFd.get()));
     71     ASSERT_TRUE(dupEventFd.isValid());
     72     dupEventFd.signal();
     73     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
     74     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
     75     dupEventFd.signal();
     76     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
     77     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
     78 }
     79 
     80 TEST_F(BufferHubEventFdTest, EventFd_testCreateEpollFdAndAddSignaledEventFd) {
     81     BufferHubEventFd eventFd;
     82     ASSERT_TRUE(eventFd.isValid());
     83     eventFd.signal();
     84 
     85     base::unique_fd epollFd(epoll_create(64));
     86     ASSERT_GE(epollFd.get(), 0);
     87 
     88     // Make sure that the epoll set has not been signal yet.
     89     std::array<epoll_event, 1> events;
     90     ASSERT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
     91 
     92     // Check that adding an signaled fd into this epoll set will trigger the epoll set.
     93     epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}};
     94     ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
     95     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
     96 
     97     // The epoll fd is edge triggered, so it only responds to the eventFd once.
     98     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
     99 }
    100 
    101 TEST_F(BufferHubEventFdTest, EventFd_testAddSignaledEventFdToEpollFd) {
    102     BufferHubEventFd eventFd;
    103     ASSERT_TRUE(eventFd.isValid());
    104 
    105     base::unique_fd epollFd(epoll_create(64));
    106     ASSERT_GE(epollFd.get(), 0);
    107 
    108     eventFd.signal();
    109 
    110     epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}};
    111     ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
    112 
    113     std::array<epoll_event, 1> events;
    114     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
    115 
    116     // The epoll fd is edge triggered, so it only responds to the eventFd once.
    117     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
    118 }
    119 
    120 TEST_F(BufferHubEventFdTest, EventFd_testConsecutiveSignalsFromAEventFd) {
    121     BufferHubEventFd eventFd;
    122     ASSERT_TRUE(eventFd.isValid());
    123     base::unique_fd epollFd(epoll_create(64));
    124     ASSERT_GE(epollFd.get(), 0);
    125     epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}};
    126     ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
    127 
    128     std::array<epoll_event, 1> events;
    129     for (int i = 0; i < kTestRuns; ++i) {
    130         eventFd.signal();
    131         EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
    132         EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
    133     }
    134 }
    135 
    136 TEST_F(BufferHubEventFdTest, EventFd_testConsecutiveSignalsFromADuplicatedEventFd) {
    137     BufferHubEventFd eventFd;
    138     ASSERT_TRUE(eventFd.isValid());
    139     base::unique_fd epollFd(epoll_create(64));
    140     ASSERT_GE(epollFd.get(), 0);
    141     epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}};
    142     ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
    143 
    144     BufferHubEventFd dupEventFd(dup(eventFd.get()));
    145     ASSERT_TRUE(dupEventFd.isValid());
    146 
    147     std::array<epoll_event, 1> events;
    148     for (int i = 0; i < kTestRuns; ++i) {
    149         dupEventFd.signal();
    150         EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
    151         EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
    152     }
    153 }
    154 
    155 TEST_F(BufferHubEventFdTest, EventFd_testClear) {
    156     BufferHubEventFd eventFd;
    157     ASSERT_TRUE(eventFd.isValid());
    158 
    159     base::unique_fd epollFd(epoll_create(64));
    160     epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}};
    161 
    162     ASSERT_GE(epollFd.get(), 0);
    163     ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
    164 
    165     eventFd.signal();
    166     eventFd.clear();
    167 
    168     std::array<epoll_event, 1> events;
    169     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
    170 }
    171 
    172 TEST_F(BufferHubEventFdTest, EventFd_testDupEventFd) {
    173     BufferHubEventFd eventFd;
    174     ASSERT_TRUE(eventFd.isValid());
    175 
    176     base::unique_fd epollFd(epoll_create(64));
    177     epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}};
    178 
    179     ASSERT_GE(epollFd.get(), 0);
    180     ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
    181 
    182     // Technically, the dupliated eventFd and the original eventFd are pointing
    183     // to the same kernel object. This test signals the duplicated eventFd but epolls the origianl
    184     // eventFd.
    185     BufferHubEventFd dupedEventFd(dup(eventFd.get()));
    186     ASSERT_GE(dupedEventFd.get(), 0);
    187 
    188     std::array<epoll_event, 1> events;
    189     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
    190 
    191     dupedEventFd.signal();
    192     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
    193 
    194     // The epoll fd is edge triggered, so it only responds to the eventFd once.
    195     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
    196 
    197     dupedEventFd.signal();
    198 
    199     dupedEventFd.clear();
    200     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
    201 }
    202 
    203 TEST_F(BufferHubEventFdTest, EventFd_testTwoEpollFds) {
    204     BufferHubEventFd eventFd;
    205     ASSERT_TRUE(eventFd.isValid());
    206 
    207     base::unique_fd epollFd1(epoll_create(64));
    208     base::unique_fd epollFd2(epoll_create(64));
    209     epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}};
    210 
    211     ASSERT_GE(epollFd1.get(), 0);
    212     ASSERT_GE(epollFd2.get(), 0);
    213 
    214     // Register the same eventFd to two EpollFds.
    215     ASSERT_EQ(epoll_ctl(epollFd1.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
    216     ASSERT_EQ(epoll_ctl(epollFd2.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
    217 
    218     std::array<epoll_event, 1> events;
    219     EXPECT_EQ(epoll_wait(epollFd1.get(), events.data(), events.size(), 0), 0);
    220     EXPECT_EQ(epoll_wait(epollFd2.get(), events.data(), events.size(), 0), 0);
    221 
    222     eventFd.signal();
    223     EXPECT_EQ(epoll_wait(epollFd1.get(), events.data(), events.size(), 0), 1);
    224     EXPECT_EQ(epoll_wait(epollFd2.get(), events.data(), events.size(), 0), 1);
    225 
    226     // The epoll fd is edge triggered, so it only responds to the eventFd once.
    227     EXPECT_EQ(epoll_wait(epollFd1.get(), events.data(), events.size(), 0), 0);
    228     EXPECT_EQ(epoll_wait(epollFd2.get(), events.data(), events.size(), 0), 0);
    229 
    230     eventFd.signal();
    231     EXPECT_EQ(epoll_wait(epollFd1.get(), events.data(), events.size(), 0), 1);
    232 
    233     eventFd.clear();
    234     EXPECT_EQ(epoll_wait(epollFd1.get(), events.data(), events.size(), 0), 0);
    235     EXPECT_EQ(epoll_wait(epollFd2.get(), events.data(), events.size(), 0), 0);
    236 }
    237 
    238 TEST_F(BufferHubEventFdTest, EventFd_testTwoEventFds) {
    239     BufferHubEventFd eventFd1;
    240     BufferHubEventFd eventFd2;
    241 
    242     ASSERT_TRUE(eventFd1.isValid());
    243     ASSERT_TRUE(eventFd2.isValid());
    244 
    245     base::unique_fd epollFd(epoll_create(64));
    246     epoll_event e1 = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 1}};
    247     epoll_event e2 = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 2}};
    248 
    249     ASSERT_GE(epollFd.get(), 0);
    250     ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd1.get(), &e1), 0);
    251     ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd2.get(), &e2), 0);
    252 
    253     std::array<epoll_event, 2> events;
    254     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
    255 
    256     // Signal one by one.
    257     eventFd1.signal();
    258     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
    259     EXPECT_EQ(events[0].data.u32, e1.data.u32);
    260 
    261     eventFd2.signal();
    262     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
    263     EXPECT_EQ(events[0].data.u32, e2.data.u32);
    264 
    265     // Signal both.
    266     eventFd1.signal();
    267     eventFd2.signal();
    268     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 2);
    269 
    270     uint32_t u32s[] = {events[0].data.u32, events[1].data.u32};
    271     EXPECT_THAT(u32s, Contains(e1.data.u32));
    272     EXPECT_THAT(u32s, Contains(e2.data.u32));
    273 
    274     // The epoll fd is edge triggered, so it only responds to the eventFd once.
    275     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
    276 
    277     eventFd1.signal();
    278     eventFd2.signal();
    279     eventFd2.clear();
    280     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
    281 }
    282 
    283 TEST_F(BufferHubEventFdTest, EventFd_testPollingThreadWithTwoEventFds) {
    284     BufferHubEventFd eventFd1;
    285     BufferHubEventFd eventFd2;
    286 
    287     ASSERT_TRUE(eventFd1.isValid());
    288     ASSERT_TRUE(eventFd2.isValid());
    289 
    290     base::unique_fd epollFd(epoll_create(64));
    291     epoll_event e1 = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 1}};
    292     epoll_event e2 = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 2}};
    293 
    294     ASSERT_GE(epollFd.get(), 0);
    295     ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd1.get(), &e1), 0);
    296     ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd2.get(), &e2), 0);
    297 
    298     int countEvent1 = 0;
    299     int countEvent2 = 0;
    300     std::atomic<bool> stop{false};
    301     std::mutex mx;
    302     std::condition_variable cv;
    303 
    304     std::thread pollingThread([&] {
    305         std::array<epoll_event, 2> events;
    306         while (true) {
    307             if (stop.load()) {
    308                 break;
    309             }
    310             int ret = epoll_wait(epollFd.get(), events.data(), events.size(), kTimeout);
    311             ALOGE_IF(ret < 0 && errno != ETIMEDOUT, "Epoll failed.");
    312 
    313             std::lock_guard<std::mutex> lock(mx);
    314             for (int i = 0; i < ret; i++) {
    315                 if (events[i].data.u32 == e1.data.u32) {
    316                     countEvent1++;
    317                     cv.notify_one();
    318                 } else if (events[i].data.u32 == e2.data.u32) {
    319                     countEvent2++;
    320                     cv.notify_one();
    321                 }
    322             }
    323         }
    324     });
    325 
    326     {
    327         std::unique_lock<std::mutex> lock(mx);
    328 
    329         eventFd1.signal();
    330         EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEvent1 == 1; }));
    331 
    332         eventFd1.signal();
    333         EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEvent1 == 2; }));
    334 
    335         eventFd2.signal();
    336         EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEvent2 == 1; }));
    337 
    338         eventFd1.clear();
    339         eventFd2.clear();
    340         EXPECT_EQ(countEvent1, 2);
    341         EXPECT_EQ(countEvent2, 1);
    342 
    343         eventFd1.signal();
    344         EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEvent1 == 3; }));
    345 
    346         eventFd2.signal();
    347         EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEvent2 == 2; }));
    348     }
    349 
    350     stop.store(true);
    351     pollingThread.join();
    352 }
    353 
    354 TEST_F(BufferHubEventFdTest, EventFd_testTwoPollingThreads) {
    355     BufferHubEventFd eventFd;
    356     ASSERT_TRUE(eventFd.isValid());
    357 
    358     base::unique_fd epollFd1(epoll_create(64));
    359     base::unique_fd epollFd2(epoll_create(64));
    360     epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}};
    361 
    362     ASSERT_GE(epollFd1.get(), 0);
    363     ASSERT_GE(epollFd2.get(), 0);
    364 
    365     // Register the same eventFd to two EpollFds.
    366     ASSERT_EQ(epoll_ctl(epollFd1.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
    367     ASSERT_EQ(epoll_ctl(epollFd2.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
    368 
    369     int countEpoll1 = 0;
    370     int countEpoll2 = 0;
    371     std::atomic<bool> stop{false};
    372     std::mutex mx;
    373     std::condition_variable cv;
    374 
    375     std::thread pollingThread1([&] {
    376         std::array<epoll_event, 1> events;
    377         while (!stop.load()) {
    378             int ret = epoll_wait(epollFd1.get(), events.data(), events.size(), kTimeout);
    379             ALOGE_IF(ret < 0 && errno != ETIMEDOUT, "Epoll failed.");
    380 
    381             if (ret > 0) {
    382                 std::lock_guard<std::mutex> lock(mx);
    383                 countEpoll1++;
    384                 cv.notify_one();
    385             }
    386         }
    387     });
    388 
    389     std::thread pollingThread2([&] {
    390         std::array<epoll_event, 1> events;
    391         while (!stop.load()) {
    392             int ret = epoll_wait(epollFd2.get(), events.data(), events.size(), kTimeout);
    393             ALOGE_IF(ret < 0 && errno != ETIMEDOUT, "Epoll failed.");
    394 
    395             if (ret > 0) {
    396                 std::lock_guard<std::mutex> lock(mx);
    397                 countEpoll2++;
    398                 cv.notify_one();
    399             }
    400         }
    401     });
    402 
    403     {
    404         std::unique_lock<std::mutex> lock(mx);
    405 
    406         eventFd.signal();
    407         EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEpoll1 == 1; }));
    408         EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEpoll2 == 1; }));
    409 
    410         eventFd.signal();
    411         EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEpoll1 == 2; }));
    412         EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEpoll2 == 2; }));
    413 
    414         eventFd.clear();
    415         EXPECT_EQ(countEpoll1, 2);
    416         EXPECT_EQ(countEpoll2, 2);
    417 
    418         eventFd.signal();
    419         EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEpoll1 == 3; }));
    420         EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEpoll2 == 3; }));
    421     }
    422 
    423     stop.store(true);
    424     pollingThread1.join();
    425     pollingThread2.join();
    426 }
    427 
    428 } // namespace android
    429