123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- // Copyright 2020 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "components/memory_pressure/system_memory_pressure_evaluator_fuchsia.h"
- #include <fuchsia/memorypressure/cpp/fidl.h>
- #include <fuchsia/memorypressure/cpp/fidl_test_base.h>
- #include "base/fuchsia/scoped_service_binding.h"
- #include "base/fuchsia/test_component_context_for_process.h"
- #include "base/run_loop.h"
- #include "base/test/task_environment.h"
- #include "components/memory_pressure/multi_source_memory_pressure_monitor.h"
- #include "testing/gmock/include/gmock/gmock.h"
- #include "testing/gtest/include/gtest/gtest.h"
- namespace memory_pressure {
- namespace {
- class MockMemoryPressureVoter : public MemoryPressureVoter {
- public:
- MOCK_METHOD2(SetVote,
- void(base::MemoryPressureListener::MemoryPressureLevel, bool));
- };
- class TestSystemMemoryPressureEvaluator
- : public SystemMemoryPressureEvaluatorFuchsia {
- public:
- TestSystemMemoryPressureEvaluator(std::unique_ptr<MemoryPressureVoter> voter)
- : SystemMemoryPressureEvaluatorFuchsia(std::move(voter)) {}
- TestSystemMemoryPressureEvaluator(const TestSystemMemoryPressureEvaluator&) =
- delete;
- TestSystemMemoryPressureEvaluator& operator=(
- const TestSystemMemoryPressureEvaluator&) = delete;
- MOCK_METHOD1(OnMemoryPressure,
- void(base::MemoryPressureListener::MemoryPressureLevel level));
- };
- } // namespace
- class SystemMemoryPressureEvaluatorFuchsiaTest
- : public testing::Test,
- public fuchsia::memorypressure::testing::Provider_TestBase {
- public:
- SystemMemoryPressureEvaluatorFuchsiaTest()
- : task_environment_(base::test::TaskEnvironment::MainThreadType::IO,
- base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
- void SendPressureLevel(fuchsia::memorypressure::Level level) {
- base::RunLoop wait_loop;
- watcher_->OnLevelChanged(
- level, [quit_loop = wait_loop.QuitClosure()]() { quit_loop.Run(); });
- wait_loop.Run();
- }
- bool have_watcher() const { return watcher_.is_bound(); }
- // fuchsia::memorypressure::Provider implementation.
- void RegisterWatcher(fidl::InterfaceHandle<fuchsia::memorypressure::Watcher>
- watcher) override {
- watcher_.Bind(std::move(watcher));
- SendPressureLevel(fuchsia::memorypressure::Level::NORMAL);
- }
- protected:
- // fuchsia::memorypressure::testing::Provider_TestBase implementation.
- void NotImplemented_(const std::string& name) override {
- ADD_FAILURE() << "Unexpected call to method: " << name;
- }
- base::test::SingleThreadTaskEnvironment task_environment_;
- base::TestComponentContextForProcess test_context_;
- fuchsia::memorypressure::WatcherPtr watcher_;
- };
- using SystemMemoryPressureEvaluatorFuchsiaDeathTest =
- SystemMemoryPressureEvaluatorFuchsiaTest;
- TEST_F(SystemMemoryPressureEvaluatorFuchsiaDeathTest, ProviderUnavailable) {
- auto voter = std::make_unique<MockMemoryPressureVoter>();
- TestSystemMemoryPressureEvaluator evaluator(std::move(voter));
- // Spin the loop to allow the evaluator to notice that the Provider is not
- // available and verify that this causes a fatal failure.
- ASSERT_DEATH(base::RunLoop().RunUntilIdle(),
- "fuchsia\\.memorypressure\\.Provider disconnected unexpectedly, "
- "exiting: ZX_ERR_PEER_CLOSED \\(-24\\)");
- }
- TEST_F(SystemMemoryPressureEvaluatorFuchsiaTest, Basic) {
- base::ScopedServiceBinding<::fuchsia::memorypressure::Provider>
- publish_provider(test_context_.additional_services(), this);
- auto voter = std::make_unique<MockMemoryPressureVoter>();
- // NONE pressure will be reported once the first Watch() call returns, and
- // then again when the fakes system level transitions from CRITICAL->NORMAL.
- EXPECT_CALL(
- *voter,
- SetVote(base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE, false))
- .Times(2);
- EXPECT_CALL(
- *voter,
- SetVote(base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
- true));
- EXPECT_CALL(
- *voter,
- SetVote(base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
- true));
- TestSystemMemoryPressureEvaluator evaluator(std::move(voter));
- // Spin the loop to ensure that RegisterWatcher() is processed.
- base::RunLoop().RunUntilIdle();
- ASSERT_TRUE(have_watcher());
- SendPressureLevel(fuchsia::memorypressure::Level::CRITICAL);
- EXPECT_EQ(evaluator.current_vote(),
- base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
- SendPressureLevel(fuchsia::memorypressure::Level::NORMAL);
- EXPECT_EQ(evaluator.current_vote(),
- base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE);
- SendPressureLevel(fuchsia::memorypressure::Level::WARNING);
- EXPECT_EQ(evaluator.current_vote(),
- base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
- }
- TEST_F(SystemMemoryPressureEvaluatorFuchsiaTest, Periodic) {
- base::ScopedServiceBinding<fuchsia::memorypressure::Provider>
- publish_provider(test_context_.additional_services(), this);
- MultiSourceMemoryPressureMonitor monitor;
- monitor.ResetSystemEvaluatorForTesting();
- testing::StrictMock<TestSystemMemoryPressureEvaluator> evaluator(
- monitor.CreateVoter());
- // Spin the loop to ensure that RegisterWatcher() is processed.
- base::RunLoop().RunUntilIdle();
- ASSERT_TRUE(have_watcher());
- base::MemoryPressureListener listener(
- FROM_HERE,
- base::BindRepeating(&TestSystemMemoryPressureEvaluator::OnMemoryPressure,
- base::Unretained(&evaluator)));
- EXPECT_CALL(
- evaluator,
- OnMemoryPressure(
- base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE));
- SendPressureLevel(fuchsia::memorypressure::Level::WARNING);
- EXPECT_EQ(evaluator.current_vote(),
- base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
- testing::Mock::VerifyAndClearExpectations(&evaluator);
- // Verify that MODERATE pressure level is reported periodically.
- EXPECT_CALL(
- evaluator,
- OnMemoryPressure(
- base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE));
- task_environment_.FastForwardBy(evaluator.kRenotifyVotePeriod);
- testing::Mock::VerifyAndClearExpectations(&evaluator);
- EXPECT_CALL(
- evaluator,
- OnMemoryPressure(
- base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL));
- SendPressureLevel(fuchsia::memorypressure::Level::CRITICAL);
- EXPECT_EQ(evaluator.current_vote(),
- base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
- testing::Mock::VerifyAndClearExpectations(&evaluator);
- // Verify that CRITICAL pressure level is reported periodically.
- EXPECT_CALL(
- evaluator,
- OnMemoryPressure(
- base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL));
- task_environment_.FastForwardBy(evaluator.kRenotifyVotePeriod);
- testing::Mock::VerifyAndClearExpectations(&evaluator);
- SendPressureLevel(fuchsia::memorypressure::Level::NORMAL);
- EXPECT_EQ(evaluator.current_vote(),
- base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE);
- // Verify that NONE pressure level is not reported periodically.
- task_environment_.FastForwardBy(evaluator.kRenotifyVotePeriod);
- testing::Mock::VerifyAndClearExpectations(&evaluator);
- }
- } // namespace memory_pressure
|