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

Commit 76a3e59e authored by Leon Scroggins's avatar Leon Scroggins Committed by Android (Google) Code Review
Browse files

Merge "Add tests for VsyncSchedule" into udc-dev

parents 2a8ad28b 4d5db7ab
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <string>

#include <ThreadContext.h>
#include <android-base/thread_annotations.h>
#include <ftl/enum.h>
#include <ftl/optional.h>
#include <scheduler/Features.h>
@@ -27,6 +28,7 @@

namespace android {
class EventThreadTest;
class VsyncScheduleTest;
}

namespace android::fuzz {
@@ -96,6 +98,7 @@ public:
private:
    friend class TestableScheduler;
    friend class android::EventThreadTest;
    friend class android::VsyncScheduleTest;
    friend class android::fuzz::SchedulerFuzzer;

    using TrackerPtr = std::unique_ptr<VsyncTracker>;
+1 −0
Original line number Diff line number Diff line
@@ -134,6 +134,7 @@ cc_test {
        "VSyncPredictorTest.cpp",
        "VSyncReactorTest.cpp",
        "VsyncConfigurationTest.cpp",
        "VsyncScheduleTest.cpp",
    ],
}

+215 −0
Original line number Diff line number Diff line
/*
 * Copyright 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#undef LOG_TAG
#define LOG_TAG "LibSurfaceFlingerUnittests"

#include <ftl/fake_guard.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <log/log.h>

#include <scheduler/Fps.h>
#include "Scheduler/VsyncSchedule.h"
#include "ThreadContext.h"
#include "mock/MockSchedulerCallback.h"
#include "mock/MockVSyncDispatch.h"
#include "mock/MockVSyncTracker.h"
#include "mock/MockVsyncController.h"

using testing::_;

namespace android {

class VsyncScheduleTest : public testing::Test {
protected:
    VsyncScheduleTest();
    ~VsyncScheduleTest() override;

    scheduler::mock::SchedulerCallback mCallback;
    const std::unique_ptr<scheduler::VsyncSchedule> mVsyncSchedule =
            std::unique_ptr<scheduler::VsyncSchedule>(
                    new scheduler::VsyncSchedule(std::make_unique<mock::VSyncTracker>(),
                                                 std::make_unique<mock::VSyncDispatch>(),
                                                 std::make_unique<mock::VsyncController>()));

    mock::VsyncController& getController() {
        return *static_cast<mock::VsyncController*>(&mVsyncSchedule->getController());
    }
};

VsyncScheduleTest::VsyncScheduleTest() {
    const ::testing::TestInfo* const test_info =
            ::testing::UnitTest::GetInstance()->current_test_info();
    ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
}

VsyncScheduleTest::~VsyncScheduleTest() {
    const ::testing::TestInfo* const test_info =
            ::testing::UnitTest::GetInstance()->current_test_info();
    ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
}

namespace {

using namespace testing;

TEST_F(VsyncScheduleTest, InitiallyDisallowed) {
    ASSERT_FALSE(mVsyncSchedule->isHardwareVsyncAllowed(false /* makeAllowed */));
}

TEST_F(VsyncScheduleTest, EnableDoesNothingWhenDisallowed) {
    EXPECT_CALL(mCallback, setVsyncEnabled(_)).Times(0);

    mVsyncSchedule->enableHardwareVsync(mCallback);
}

TEST_F(VsyncScheduleTest, DisableDoesNothingWhenDisallowed) {
    EXPECT_CALL(mCallback, setVsyncEnabled(_)).Times(0);

    mVsyncSchedule->disableHardwareVsync(mCallback, false /* disallow */);
}

TEST_F(VsyncScheduleTest, MakeAllowed) {
    ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */));
}

TEST_F(VsyncScheduleTest, DisableDoesNothingWhenDisabled) {
    ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */));
    EXPECT_CALL(mCallback, setVsyncEnabled(_)).Times(0);

    mVsyncSchedule->disableHardwareVsync(mCallback, false /* disallow */);
}

TEST_F(VsyncScheduleTest, EnableWorksWhenDisabled) {
    ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */));
    EXPECT_CALL(mCallback, setVsyncEnabled(true));

    mVsyncSchedule->enableHardwareVsync(mCallback);
}

TEST_F(VsyncScheduleTest, EnableWorksOnce) {
    ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */));
    EXPECT_CALL(mCallback, setVsyncEnabled(true));

    mVsyncSchedule->enableHardwareVsync(mCallback);

    EXPECT_CALL(mCallback, setVsyncEnabled(_)).Times(0);
    mVsyncSchedule->enableHardwareVsync(mCallback);
}

TEST_F(VsyncScheduleTest, AllowedIsSticky) {
    ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */));
    ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(false /* makeAllowed */));
}

TEST_F(VsyncScheduleTest, EnableDisable) {
    ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */));
    EXPECT_CALL(mCallback, setVsyncEnabled(true));

    mVsyncSchedule->enableHardwareVsync(mCallback);

    EXPECT_CALL(mCallback, setVsyncEnabled(false));
    mVsyncSchedule->disableHardwareVsync(mCallback, false /* disallow */);
}

TEST_F(VsyncScheduleTest, StartPeriodTransition) {
    // Note: startPeriodTransition is only called when hardware vsyncs are
    // allowed.
    ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */));

    const Period period = (60_Hz).getPeriod();

    EXPECT_CALL(mCallback, setVsyncEnabled(true));
    EXPECT_CALL(getController(), startPeriodTransition(period.ns()));

    mVsyncSchedule->startPeriodTransition(mCallback, period);
}

TEST_F(VsyncScheduleTest, StartPeriodTransitionAlreadyEnabled) {
    ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */));
    mVsyncSchedule->enableHardwareVsync(mCallback);

    const Period period = (60_Hz).getPeriod();

    EXPECT_CALL(mCallback, setVsyncEnabled(_)).Times(0);
    EXPECT_CALL(getController(), startPeriodTransition(period.ns()));

    mVsyncSchedule->startPeriodTransition(mCallback, period);
}

TEST_F(VsyncScheduleTest, AddResyncSampleDisallowed) {
    const Period period = (60_Hz).getPeriod();
    const auto timestamp = TimePoint::now();

    EXPECT_CALL(mCallback, setVsyncEnabled(_)).Times(0);
    EXPECT_CALL(getController(), addHwVsyncTimestamp(_, _, _)).Times(0);

    mVsyncSchedule->addResyncSample(mCallback, timestamp, period);
}

TEST_F(VsyncScheduleTest, AddResyncSampleDisabled) {
    ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */));
    const Period period = (60_Hz).getPeriod();
    const auto timestamp = TimePoint::now();

    EXPECT_CALL(mCallback, setVsyncEnabled(_)).Times(0);
    EXPECT_CALL(getController(), addHwVsyncTimestamp(_, _, _)).Times(0);

    mVsyncSchedule->addResyncSample(mCallback, timestamp, period);
}

TEST_F(VsyncScheduleTest, AddResyncSampleReturnsTrue) {
    ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */));
    mVsyncSchedule->enableHardwareVsync(mCallback);

    const Period period = (60_Hz).getPeriod();
    const auto timestamp = TimePoint::now();

    EXPECT_CALL(mCallback, setVsyncEnabled(_)).Times(0);
    EXPECT_CALL(getController(),
                addHwVsyncTimestamp(timestamp.ns(), std::optional<nsecs_t>(period.ns()), _))
            .WillOnce(Return(true));

    mVsyncSchedule->addResyncSample(mCallback, timestamp, period);
}

TEST_F(VsyncScheduleTest, AddResyncSampleReturnsFalse) {
    ASSERT_TRUE(mVsyncSchedule->isHardwareVsyncAllowed(true /* makeAllowed */));
    mVsyncSchedule->enableHardwareVsync(mCallback);

    const Period period = (60_Hz).getPeriod();
    const auto timestamp = TimePoint::now();

    EXPECT_CALL(mCallback, setVsyncEnabled(false));
    EXPECT_CALL(getController(),
                addHwVsyncTimestamp(timestamp.ns(), std::optional<nsecs_t>(period.ns()), _))
            .WillOnce(Return(false));

    mVsyncSchedule->addResyncSample(mCallback, timestamp, period);
}

TEST_F(VsyncScheduleTest, PendingState) FTL_FAKE_GUARD(kMainThreadContext) {
    ASSERT_FALSE(mVsyncSchedule->getPendingHardwareVsyncState());
    mVsyncSchedule->setPendingHardwareVsyncState(true);
    ASSERT_TRUE(mVsyncSchedule->getPendingHardwareVsyncState());

    mVsyncSchedule->setPendingHardwareVsyncState(false);
    ASSERT_FALSE(mVsyncSchedule->getPendingHardwareVsyncState());
}

} // namespace
} // namespace android
+1 −1
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@

#include <gmock/gmock.h>

#include "Scheduler/Scheduler.h"
#include "Scheduler/ISchedulerCallback.h"

namespace android::scheduler::mock {