blob: 3cd3aae600f646ced5e32415f01b704d63ebb161 [file] [log] [blame]
// 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 "base/util/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 "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace util {
namespace {
class MockMemoryPressureVoter : public MemoryPressureVoter {
public:
MOCK_METHOD2(SetVote,
void(base::MemoryPressureListener::MemoryPressureLevel, bool));
};
} // namespace
class SystemMemoryPressureEvaluatorFuchsiaTest
: public testing::Test,
public fuchsia::memorypressure::testing::Provider_TestBase {
public:
SystemMemoryPressureEvaluatorFuchsiaTest()
: task_environment_(base::test::TaskEnvironment::MainThreadType::IO) {}
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;
}
const 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>();
SystemMemoryPressureEvaluatorFuchsia 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: "
"ZX_ERR_PEER_CLOSED \\(-24\\)");
}
TEST_F(SystemMemoryPressureEvaluatorFuchsiaTest, Basic) {
base::fuchsia::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));
SystemMemoryPressureEvaluatorFuchsia 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);
}
} // namespace util