Home | History | Annotate | Download | only in tests
      1 //
      2 // Copyright 2010 The Android Open Source Project
      3 //
      4 
      5 #include <utils/Looper.h>
      6 #include <utils/Timers.h>
      7 #include <utils/StopWatch.h>
      8 #include <gtest/gtest.h>
      9 #include <unistd.h>
     10 #include <time.h>
     11 
     12 #include "TestHelpers.h"
     13 
     14 // # of milliseconds to fudge stopwatch measurements
     15 #define TIMING_TOLERANCE_MS 25
     16 
     17 namespace android {
     18 
     19 class DelayedWake : public DelayedTask {
     20     sp<Looper> mLooper;
     21 
     22 public:
     23     DelayedWake(int delayMillis, const sp<Looper> looper) :
     24         DelayedTask(delayMillis), mLooper(looper) {
     25     }
     26 
     27 protected:
     28     virtual void doTask() {
     29         mLooper->wake();
     30     }
     31 };
     32 
     33 class DelayedWriteSignal : public DelayedTask {
     34     Pipe* mPipe;
     35 
     36 public:
     37     DelayedWriteSignal(int delayMillis, Pipe* pipe) :
     38         DelayedTask(delayMillis), mPipe(pipe) {
     39     }
     40 
     41 protected:
     42     virtual void doTask() {
     43         mPipe->writeSignal();
     44     }
     45 };
     46 
     47 class CallbackHandler {
     48 public:
     49     void setCallback(const sp<Looper>& looper, int fd, int events) {
     50         looper->addFd(fd, 0, events, staticHandler, this);
     51     }
     52 
     53 protected:
     54     virtual ~CallbackHandler() { }
     55 
     56     virtual int handler(int fd, int events) = 0;
     57 
     58 private:
     59     static int staticHandler(int fd, int events, void* data) {
     60         return static_cast<CallbackHandler*>(data)->handler(fd, events);
     61     }
     62 };
     63 
     64 class StubCallbackHandler : public CallbackHandler {
     65 public:
     66     int nextResult;
     67     int callbackCount;
     68 
     69     int fd;
     70     int events;
     71 
     72     StubCallbackHandler(int nextResult) : nextResult(nextResult),
     73             callbackCount(0), fd(-1), events(-1) {
     74     }
     75 
     76 protected:
     77     virtual int handler(int fd, int events) {
     78         callbackCount += 1;
     79         this->fd = fd;
     80         this->events = events;
     81         return nextResult;
     82     }
     83 };
     84 
     85 class LooperTest : public testing::Test {
     86 protected:
     87     sp<Looper> mLooper;
     88 
     89     virtual void SetUp() {
     90         mLooper = new Looper(true);
     91     }
     92 
     93     virtual void TearDown() {
     94         mLooper.clear();
     95     }
     96 };
     97 
     98 
     99 TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndNotAwoken_WaitsForTimeout) {
    100     StopWatch stopWatch("pollOnce");
    101     int result = mLooper->pollOnce(100);
    102     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
    103 
    104     EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
    105             << "elapsed time should approx. equal timeout";
    106     EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result)
    107             << "pollOnce result should be ALOOPER_POLL_TIMEOUT";
    108 }
    109 
    110 TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndAwokenBeforeWaiting_ImmediatelyReturns) {
    111     mLooper->wake();
    112 
    113     StopWatch stopWatch("pollOnce");
    114     int result = mLooper->pollOnce(1000);
    115     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
    116 
    117     EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
    118             << "elapsed time should approx. zero because wake() was called before waiting";
    119     EXPECT_EQ(ALOOPER_POLL_WAKE, result)
    120             << "pollOnce result should be ALOOPER_POLL_CALLBACK because loop was awoken";
    121 }
    122 
    123 TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndAwokenWhileWaiting_PromptlyReturns) {
    124     sp<DelayedWake> delayedWake = new DelayedWake(100, mLooper);
    125     delayedWake->run();
    126 
    127     StopWatch stopWatch("pollOnce");
    128     int result = mLooper->pollOnce(1000);
    129     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
    130 
    131     EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
    132             << "elapsed time should approx. equal wake delay";
    133     EXPECT_EQ(ALOOPER_POLL_WAKE, result)
    134             << "pollOnce result should be ALOOPER_POLL_CALLBACK because loop was awoken";
    135 }
    136 
    137 TEST_F(LooperTest, PollOnce_WhenZeroTimeoutAndNoRegisteredFDs_ImmediatelyReturns) {
    138     StopWatch stopWatch("pollOnce");
    139     int result = mLooper->pollOnce(0);
    140     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
    141 
    142     EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
    143             << "elapsed time should be approx. zero";
    144     EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result)
    145             << "pollOnce result should be ALOOPER_POLL_TIMEOUT";
    146 }
    147 
    148 TEST_F(LooperTest, PollOnce_WhenZeroTimeoutAndNoSignalledFDs_ImmediatelyReturns) {
    149     Pipe pipe;
    150     StubCallbackHandler handler(true);
    151 
    152     handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT);
    153 
    154     StopWatch stopWatch("pollOnce");
    155     int result = mLooper->pollOnce(0);
    156     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
    157 
    158     EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
    159             << "elapsed time should be approx. zero";
    160     EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result)
    161             << "pollOnce result should be ALOOPER_POLL_TIMEOUT";
    162     EXPECT_EQ(0, handler.callbackCount)
    163             << "callback should not have been invoked because FD was not signalled";
    164 }
    165 
    166 TEST_F(LooperTest, PollOnce_WhenZeroTimeoutAndSignalledFD_ImmediatelyInvokesCallbackAndReturns) {
    167     Pipe pipe;
    168     StubCallbackHandler handler(true);
    169 
    170     ASSERT_EQ(OK, pipe.writeSignal());
    171     handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT);
    172 
    173     StopWatch stopWatch("pollOnce");
    174     int result = mLooper->pollOnce(0);
    175     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
    176 
    177     EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
    178             << "elapsed time should be approx. zero";
    179     EXPECT_EQ(ALOOPER_POLL_CALLBACK, result)
    180             << "pollOnce result should be ALOOPER_POLL_CALLBACK because FD was signalled";
    181     EXPECT_EQ(1, handler.callbackCount)
    182             << "callback should be invoked exactly once";
    183     EXPECT_EQ(pipe.receiveFd, handler.fd)
    184             << "callback should have received pipe fd as parameter";
    185     EXPECT_EQ(ALOOPER_EVENT_INPUT, handler.events)
    186             << "callback should have received ALOOPER_EVENT_INPUT as events";
    187 }
    188 
    189 TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndNoSignalledFDs_WaitsForTimeoutAndReturns) {
    190     Pipe pipe;
    191     StubCallbackHandler handler(true);
    192 
    193     handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT);
    194 
    195     StopWatch stopWatch("pollOnce");
    196     int result = mLooper->pollOnce(100);
    197     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
    198 
    199     EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
    200             << "elapsed time should approx. equal timeout";
    201     EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result)
    202             << "pollOnce result should be ALOOPER_POLL_TIMEOUT";
    203     EXPECT_EQ(0, handler.callbackCount)
    204             << "callback should not have been invoked because FD was not signalled";
    205 }
    206 
    207 TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndSignalledFDBeforeWaiting_ImmediatelyInvokesCallbackAndReturns) {
    208     Pipe pipe;
    209     StubCallbackHandler handler(true);
    210 
    211     pipe.writeSignal();
    212     handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT);
    213 
    214     StopWatch stopWatch("pollOnce");
    215     int result = mLooper->pollOnce(100);
    216     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
    217 
    218     ASSERT_EQ(OK, pipe.readSignal())
    219             << "signal should actually have been written";
    220     EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
    221             << "elapsed time should be approx. zero";
    222     EXPECT_EQ(ALOOPER_POLL_CALLBACK, result)
    223             << "pollOnce result should be ALOOPER_POLL_CALLBACK because FD was signalled";
    224     EXPECT_EQ(1, handler.callbackCount)
    225             << "callback should be invoked exactly once";
    226     EXPECT_EQ(pipe.receiveFd, handler.fd)
    227             << "callback should have received pipe fd as parameter";
    228     EXPECT_EQ(ALOOPER_EVENT_INPUT, handler.events)
    229             << "callback should have received ALOOPER_EVENT_INPUT as events";
    230 }
    231 
    232 TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndSignalledFDWhileWaiting_PromptlyInvokesCallbackAndReturns) {
    233     Pipe pipe;
    234     StubCallbackHandler handler(true);
    235     sp<DelayedWriteSignal> delayedWriteSignal = new DelayedWriteSignal(100, & pipe);
    236 
    237     handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT);
    238     delayedWriteSignal->run();
    239 
    240     StopWatch stopWatch("pollOnce");
    241     int result = mLooper->pollOnce(1000);
    242     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
    243 
    244     ASSERT_EQ(OK, pipe.readSignal())
    245             << "signal should actually have been written";
    246     EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
    247             << "elapsed time should approx. equal signal delay";
    248     EXPECT_EQ(ALOOPER_POLL_CALLBACK, result)
    249             << "pollOnce result should be ALOOPER_POLL_CALLBACK because FD was signalled";
    250     EXPECT_EQ(1, handler.callbackCount)
    251             << "callback should be invoked exactly once";
    252     EXPECT_EQ(pipe.receiveFd, handler.fd)
    253             << "callback should have received pipe fd as parameter";
    254     EXPECT_EQ(ALOOPER_EVENT_INPUT, handler.events)
    255             << "callback should have received ALOOPER_EVENT_INPUT as events";
    256 }
    257 
    258 TEST_F(LooperTest, PollOnce_WhenCallbackAddedThenRemoved_CallbackShouldNotBeInvoked) {
    259     Pipe pipe;
    260     StubCallbackHandler handler(true);
    261 
    262     handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT);
    263     pipe.writeSignal(); // would cause FD to be considered signalled
    264     mLooper->removeFd(pipe.receiveFd);
    265 
    266     StopWatch stopWatch("pollOnce");
    267     int result = mLooper->pollOnce(100);
    268     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
    269 
    270     ASSERT_EQ(OK, pipe.readSignal())
    271             << "signal should actually have been written";
    272     EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
    273             << "elapsed time should approx. equal timeout because FD was no longer registered";
    274     EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result)
    275             << "pollOnce result should be ALOOPER_POLL_TIMEOUT";
    276     EXPECT_EQ(0, handler.callbackCount)
    277             << "callback should not be invoked";
    278 }
    279 
    280 TEST_F(LooperTest, PollOnce_WhenCallbackReturnsFalse_CallbackShouldNotBeInvokedAgainLater) {
    281     Pipe pipe;
    282     StubCallbackHandler handler(false);
    283 
    284     handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT);
    285 
    286     // First loop: Callback is registered and FD is signalled.
    287     pipe.writeSignal();
    288 
    289     StopWatch stopWatch("pollOnce");
    290     int result = mLooper->pollOnce(0);
    291     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
    292 
    293     ASSERT_EQ(OK, pipe.readSignal())
    294             << "signal should actually have been written";
    295     EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
    296             << "elapsed time should approx. equal zero because FD was already signalled";
    297     EXPECT_EQ(ALOOPER_POLL_CALLBACK, result)
    298             << "pollOnce result should be ALOOPER_POLL_CALLBACK because FD was signalled";
    299     EXPECT_EQ(1, handler.callbackCount)
    300             << "callback should be invoked";
    301 
    302     // Second loop: Callback is no longer registered and FD is signalled.
    303     pipe.writeSignal();
    304 
    305     stopWatch.reset();
    306     result = mLooper->pollOnce(0);
    307     elapsedMillis = ns2ms(stopWatch.elapsedTime());
    308 
    309     ASSERT_EQ(OK, pipe.readSignal())
    310             << "signal should actually have been written";
    311     EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
    312             << "elapsed time should approx. equal zero because timeout was zero";
    313     EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result)
    314             << "pollOnce result should be ALOOPER_POLL_TIMEOUT";
    315     EXPECT_EQ(1, handler.callbackCount)
    316             << "callback should not be invoked this time";
    317 }
    318 
    319 TEST_F(LooperTest, PollOnce_WhenNonCallbackFdIsSignalled_ReturnsIdent) {
    320     const int expectedIdent = 5;
    321     void* expectedData = this;
    322 
    323     Pipe pipe;
    324 
    325     pipe.writeSignal();
    326     mLooper->addFd(pipe.receiveFd, expectedIdent, ALOOPER_EVENT_INPUT, NULL, expectedData);
    327 
    328     StopWatch stopWatch("pollOnce");
    329     int fd;
    330     int events;
    331     void* data;
    332     int result = mLooper->pollOnce(100, &fd, &events, &data);
    333     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
    334 
    335     ASSERT_EQ(OK, pipe.readSignal())
    336             << "signal should actually have been written";
    337     EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
    338             << "elapsed time should be approx. zero";
    339     EXPECT_EQ(expectedIdent, result)
    340             << "pollOnce result should be the ident of the FD that was signalled";
    341     EXPECT_EQ(pipe.receiveFd, fd)
    342             << "pollOnce should have returned the received pipe fd";
    343     EXPECT_EQ(ALOOPER_EVENT_INPUT, events)
    344             << "pollOnce should have returned ALOOPER_EVENT_INPUT as events";
    345     EXPECT_EQ(expectedData, data)
    346             << "pollOnce should have returned the data";
    347 }
    348 
    349 TEST_F(LooperTest, AddFd_WhenCallbackAdded_ReturnsOne) {
    350     Pipe pipe;
    351     int result = mLooper->addFd(pipe.receiveFd, 0, ALOOPER_EVENT_INPUT, NULL, NULL);
    352 
    353     EXPECT_EQ(1, result)
    354             << "addFd should return 1 because FD was added";
    355 }
    356 
    357 TEST_F(LooperTest, AddFd_WhenIdentIsNegativeAndCallbackIsNull_ReturnsError) {
    358     Pipe pipe;
    359     int result = mLooper->addFd(pipe.receiveFd, -1, ALOOPER_EVENT_INPUT, NULL, NULL);
    360 
    361     EXPECT_EQ(-1, result)
    362             << "addFd should return -1 because arguments were invalid";
    363 }
    364 
    365 TEST_F(LooperTest, AddFd_WhenNoCallbackAndAllowNonCallbacksIsFalse_ReturnsError) {
    366     Pipe pipe;
    367     sp<Looper> looper = new Looper(false /*allowNonCallbacks*/);
    368     int result = looper->addFd(pipe.receiveFd, 0, 0, NULL, NULL);
    369 
    370     EXPECT_EQ(-1, result)
    371             << "addFd should return -1 because arguments were invalid";
    372 }
    373 
    374 TEST_F(LooperTest, RemoveFd_WhenCallbackNotAdded_ReturnsZero) {
    375     int result = mLooper->removeFd(1);
    376 
    377     EXPECT_EQ(0, result)
    378             << "removeFd should return 0 because FD not registered";
    379 }
    380 
    381 TEST_F(LooperTest, RemoveFd_WhenCallbackAddedThenRemovedTwice_ReturnsOnceFirstTimeAndReturnsZeroSecondTime) {
    382     Pipe pipe;
    383     StubCallbackHandler handler(false);
    384     handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT);
    385 
    386     // First time.
    387     int result = mLooper->removeFd(pipe.receiveFd);
    388 
    389     EXPECT_EQ(1, result)
    390             << "removeFd should return 1 first time because FD was registered";
    391 
    392     // Second time.
    393     result = mLooper->removeFd(pipe.receiveFd);
    394 
    395     EXPECT_EQ(0, result)
    396             << "removeFd should return 0 second time because FD was no longer registered";
    397 }
    398 
    399 TEST_F(LooperTest, PollOnce_WhenCallbackAddedTwice_OnlySecondCallbackShouldBeInvoked) {
    400     Pipe pipe;
    401     StubCallbackHandler handler1(true);
    402     StubCallbackHandler handler2(true);
    403 
    404     handler1.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT);
    405     handler2.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT); // replace it
    406     pipe.writeSignal(); // would cause FD to be considered signalled
    407 
    408     StopWatch stopWatch("pollOnce");
    409     int result = mLooper->pollOnce(100);
    410     int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
    411 
    412     ASSERT_EQ(OK, pipe.readSignal())
    413             << "signal should actually have been written";
    414     EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
    415             << "elapsed time should approx. zero because FD was already signalled";
    416     EXPECT_EQ(ALOOPER_POLL_CALLBACK, result)
    417             << "pollOnce result should be ALOOPER_POLL_CALLBACK because FD was signalled";
    418     EXPECT_EQ(0, handler1.callbackCount)
    419             << "original handler callback should not be invoked because it was replaced";
    420     EXPECT_EQ(1, handler2.callbackCount)
    421             << "replacement handler callback should be invoked";
    422 }
    423 
    424 
    425 } // namespace android
    426