/* * Copyright (C) 2021 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. */ #include "perfetto/ext/base/threading/future.h" #include #include "perfetto/base/flat_set.h" #include "perfetto/base/platform_handle.h" #include "test/gtest_and_gmock.h" namespace perfetto { namespace base { namespace { using testing::_; using testing::Return; template class MockPollable : public FuturePollable { public: MOCK_METHOD(FuturePollResult, Poll, (PollContext*), (override)); }; class FutureUnittest : public ::testing::Test { public: base::FlatSet interested_; base::FlatSet ready_; PollContext ctx_{&interested_, &ready_}; }; TEST_F(FutureUnittest, PollableImmediateResult) { std::unique_ptr> int_pollable(new MockPollable()); EXPECT_CALL(*int_pollable, Poll(_)) .WillOnce(Return(FuturePollResult(0))); base::Future future(std::move(int_pollable)); auto res = future.Poll(&ctx_); ASSERT_FALSE(res.IsPending()); ASSERT_EQ(res.item(), 0); } TEST_F(FutureUnittest, PollablePendingThenResult) { std::unique_ptr> int_pollable(new MockPollable()); EXPECT_CALL(*int_pollable, Poll(_)) .WillOnce(Return(PendingPollResult())) .WillOnce(Return(FuturePollResult(1))); base::Future future(std::move(int_pollable)); ASSERT_TRUE(future.Poll(&ctx_).IsPending()); ASSERT_EQ(future.Poll(&ctx_).item(), 1); } TEST_F(FutureUnittest, ImmediateFuture) { base::Future future(100); ASSERT_EQ(future.Poll(&ctx_).item(), 100); } TEST_F(FutureUnittest, ContinueWithBothImmediate) { auto future = base::Future(100).ContinueWith( [](int res) -> Future { return res * 2; }); ASSERT_EQ(future.Poll(&ctx_).item(), 200); } TEST_F(FutureUnittest, ImmediateContinueWithPending) { auto future = base::Future(100).ContinueWith([](int res) { std::unique_ptr> pollable(new MockPollable()); EXPECT_CALL(*pollable, Poll(_)) .WillOnce(Return(PendingPollResult())) .WillOnce(Return(FuturePollResult(res * 2))); return Future(std::move(pollable)); }); ASSERT_TRUE(future.Poll(&ctx_).IsPending()); ASSERT_EQ(future.Poll(&ctx_).item(), 200); } TEST_F(FutureUnittest, PendingContinueWithImmediate) { std::unique_ptr> pollable(new MockPollable()); EXPECT_CALL(*pollable, Poll(_)) .WillOnce(Return(PendingPollResult())) .WillOnce(Return(FuturePollResult(100))); auto future = base::Future(std::move(pollable)) .ContinueWith([](int res) -> Future { return res * 2; }); ASSERT_TRUE(future.Poll(&ctx_).IsPending()); ASSERT_EQ(future.Poll(&ctx_).item(), 200); } } // namespace } // namespace base } // namespace perfetto