Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 81d5649f authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix VibratorCallbackSchedulerTest flakiness" into main

parents 352ed22a f2afa6b8
Loading
Loading
Loading
Loading
+25 −17
Original line number Diff line number Diff line
@@ -38,6 +38,9 @@ using namespace testing;

// -------------------------------------------------------------------------------------------------

// Delay allowed for the scheduler to process callbacks during this test.
static const auto TEST_TIMEOUT = 50ms;

class VibratorCallbackSchedulerTest : public Test {
public:
    void SetUp() override {
@@ -67,46 +70,51 @@ protected:
        return std::vector<int32_t>(mExpiredCallbacks);
    }

    bool waitForCallbacks(uint32_t callbackCount, milliseconds timeout) {
        time_point<steady_clock> expiration = steady_clock::now() + timeout;
    int32_t waitForCallbacks(int32_t callbackCount, milliseconds timeout) {
        time_point<steady_clock> expiration = steady_clock::now() + timeout + TEST_TIMEOUT;
        int32_t expiredCallbackCount = 0;
        while (steady_clock::now() < expiration) {
            std::lock_guard<std::mutex> lock(mMutex);
            if (callbackCount <= mExpiredCallbacks.size()) {
                return true;
            expiredCallbackCount = mExpiredCallbacks.size();
            if (callbackCount <= expiredCallbackCount) {
                return expiredCallbackCount;
            }
            mCondition.wait_until(mMutex, expiration);
        }
        return false;
        return expiredCallbackCount;
    }
};

// -------------------------------------------------------------------------------------------------

TEST_F(VibratorCallbackSchedulerTest, TestScheduleRunsOnlyAfterDelay) {
    mScheduler->schedule(createCallback(1), 15ms);
    time_point<steady_clock> startTime = steady_clock::now();
    mScheduler->schedule(createCallback(1), 50ms);

    // Not triggered before delay.
    ASSERT_FALSE(waitForCallbacks(1, 10ms));
    ASSERT_TRUE(getExpiredCallbacks().empty());
    ASSERT_EQ(1, waitForCallbacks(1, 50ms));
    time_point<steady_clock> callbackTime = steady_clock::now();

    ASSERT_TRUE(waitForCallbacks(1, 10ms));
    // Callback happened at least 50ms after the beginning of the test.
    ASSERT_TRUE(startTime + 50ms <= callbackTime);
    ASSERT_THAT(getExpiredCallbacks(), ElementsAre(1));
}

TEST_F(VibratorCallbackSchedulerTest, TestScheduleMultipleCallbacksRunsInDelayOrder) {
    mScheduler->schedule(createCallback(1), 10ms);
    mScheduler->schedule(createCallback(2), 5ms);
    mScheduler->schedule(createCallback(3), 1ms);
    // Schedule first callbacks long enough that all 3 will be scheduled together and run in order.
    mScheduler->schedule(createCallback(1), 50ms);
    mScheduler->schedule(createCallback(2), 40ms);
    mScheduler->schedule(createCallback(3), 10ms);

    ASSERT_TRUE(waitForCallbacks(3, 15ms));
    ASSERT_EQ(3, waitForCallbacks(3, 50ms));
    ASSERT_THAT(getExpiredCallbacks(), ElementsAre(3, 2, 1));
}

TEST_F(VibratorCallbackSchedulerTest, TestDestructorDropsPendingCallbacksAndKillsThread) {
    mScheduler->schedule(createCallback(1), 5ms);
    // Schedule callback long enough that scheduler will be destroyed while it's still scheduled.
    mScheduler->schedule(createCallback(1), 50ms);
    mScheduler.reset(nullptr);

    // Should timeout waiting for callback to run.
    ASSERT_FALSE(waitForCallbacks(1, 10ms));
    ASSERT_EQ(0, waitForCallbacks(1, 50ms));
    ASSERT_TRUE(getExpiredCallbacks().empty());
}