| Index: services/resource_coordinator/coordination_unit/coordination_unit_impl_unittest.cc
|
| diff --git a/services/resource_coordinator/coordination_unit/coordination_unit_impl_unittest.cc b/services/resource_coordinator/coordination_unit/coordination_unit_impl_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..559ab075e2c09eaff495eedfb689b01cd4fac6e3
|
| --- /dev/null
|
| +++ b/services/resource_coordinator/coordination_unit/coordination_unit_impl_unittest.cc
|
| @@ -0,0 +1,194 @@
|
| +// Copyright 2017 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 <memory>
|
| +#include <vector>
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/message_loop/message_loop.h"
|
| +#include "base/run_loop.h"
|
| +#include "services/resource_coordinator/coordination_unit/coordination_unit_provider_impl.h"
|
| +#include "services/service_manager/public/cpp/service_context_ref.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace resource_coordinator {
|
| +
|
| +namespace {
|
| +
|
| +void OnLastServiceRefDestroyed() {
|
| + // No-op. This is required by service_manager::ServiceContextRefFactory
|
| + // construction but not needed for the tests.
|
| +}
|
| +
|
| +class CoordinationUnitImplTest : public testing::Test {
|
| + public:
|
| + CoordinationUnitImplTest()
|
| + : service_ref_factory_(base::Bind(&OnLastServiceRefDestroyed)),
|
| + provider_(&service_ref_factory_) {}
|
| + ~CoordinationUnitImplTest() override {}
|
| +
|
| + // testing::Test:
|
| + void TearDown() override { base::RunLoop().RunUntilIdle(); }
|
| +
|
| + protected:
|
| + CoordinationUnitProviderImpl* provider() { return &provider_; }
|
| +
|
| + private:
|
| + base::MessageLoop message_loop_;
|
| +
|
| + service_manager::ServiceContextRefFactory service_ref_factory_;
|
| + CoordinationUnitProviderImpl provider_;
|
| +};
|
| +
|
| +class TestCoordinationUnit : public mojom::PolicyCallback {
|
| + public:
|
| + TestCoordinationUnit(CoordinationUnitProviderImpl* provider,
|
| + const CoordinationUnitType& type,
|
| + const std::string& id)
|
| + : binding_(this) {
|
| + CHECK(provider);
|
| +
|
| + CoordinationUnitID new_cu_id(type, id);
|
| + mojom::CoordinationUnitPtr coordination_unit;
|
| + provider->CreateCoordinationUnit(mojo::MakeRequest(&coordination_unit_),
|
| + new_cu_id);
|
| +
|
| + base::RunLoop callback;
|
| + SetGetIDClosure(callback.QuitClosure());
|
| + coordination_unit_->SetPolicyCallback(GetPolicyCallback());
|
| + // Forces us to wait for the creation of the CUID to finish.
|
| + coordination_unit_->GetID(base::Bind(&TestCoordinationUnit::GetIDCallback,
|
| + base::Unretained(this)));
|
| +
|
| + callback.Run();
|
| + }
|
| +
|
| + void GetIDCallback(const CoordinationUnitID& cu_id) {
|
| + id_ = cu_id;
|
| + get_id_closure_.Run();
|
| + }
|
| +
|
| + void SetGetIDClosure(const base::Closure& get_id_closure) {
|
| + get_id_closure_ = get_id_closure;
|
| + }
|
| +
|
| + void SetPolicyClosure(const base::Closure& policy_closure) {
|
| + policy_update_closure_ = policy_closure;
|
| + }
|
| +
|
| + mojom::PolicyCallbackPtr GetPolicyCallback() {
|
| + return binding_.CreateInterfacePtrAndBind();
|
| + }
|
| +
|
| + // The CU will always send policy updates on events (including parent events)
|
| + void ForcePolicyUpdates() {
|
| + base::RunLoop callback;
|
| + SetPolicyClosure(callback.QuitClosure());
|
| + mojom::EventPtr event = mojom::Event::New();
|
| + event->type = mojom::EventType::TEST_EVENT;
|
| + coordination_unit_->SendEvent(std::move(event));
|
| + callback.Run();
|
| + }
|
| +
|
| + const mojom::CoordinationUnitPtr& interface() const {
|
| + return coordination_unit_;
|
| + }
|
| +
|
| + const CoordinationUnitID& id() const { return id_; }
|
| +
|
| + // mojom::PolicyCallback:
|
| + void SetPolicy(resource_coordinator::mojom::PolicyPtr policy) override {
|
| + if (policy_update_closure_)
|
| + policy_update_closure_.Run();
|
| + }
|
| +
|
| + private:
|
| + base::Closure policy_update_closure_;
|
| + base::Closure get_id_closure_;
|
| +
|
| + mojo::Binding<mojom::PolicyCallback> binding_;
|
| + mojom::CoordinationUnitPtr coordination_unit_;
|
| + CoordinationUnitID id_;
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +TEST_F(CoordinationUnitImplTest, BasicPolicyCallback) {
|
| + TestCoordinationUnit test_coordination_unit(
|
| + provider(), CoordinationUnitType::WEBCONTENTS, "test_id");
|
| + test_coordination_unit.ForcePolicyUpdates();
|
| +}
|
| +
|
| +TEST_F(CoordinationUnitImplTest, AddChild) {
|
| + TestCoordinationUnit parent_unit(
|
| + provider(), CoordinationUnitType::WEBCONTENTS, "parent_unit");
|
| +
|
| + TestCoordinationUnit child_unit(provider(), CoordinationUnitType::WEBCONTENTS,
|
| + "child_unit");
|
| +
|
| + child_unit.ForcePolicyUpdates();
|
| + parent_unit.ForcePolicyUpdates();
|
| +
|
| + {
|
| + base::RunLoop callback;
|
| + child_unit.SetPolicyClosure(callback.QuitClosure());
|
| + parent_unit.interface()->AddChild(child_unit.id());
|
| + callback.Run();
|
| + }
|
| +
|
| + {
|
| + base::RunLoop parent_callback;
|
| + base::RunLoop child_callback;
|
| + parent_unit.SetPolicyClosure(parent_callback.QuitClosure());
|
| + child_unit.SetPolicyClosure(child_callback.QuitClosure());
|
| +
|
| + // This event should force the policy to recalculated for all children.
|
| + mojom::EventPtr event = mojom::Event::New();
|
| + event->type = mojom::EventType::TEST_EVENT;
|
| + parent_unit.interface()->SendEvent(std::move(event));
|
| +
|
| + parent_callback.Run();
|
| + child_callback.Run();
|
| + }
|
| +}
|
| +
|
| +TEST_F(CoordinationUnitImplTest, CyclicGraphUnits) {
|
| + TestCoordinationUnit parent_unit(
|
| + provider(), CoordinationUnitType::WEBCONTENTS, std::string());
|
| +
|
| + TestCoordinationUnit child_unit(provider(), CoordinationUnitType::WEBCONTENTS,
|
| + std::string());
|
| +
|
| + child_unit.ForcePolicyUpdates();
|
| + parent_unit.ForcePolicyUpdates();
|
| +
|
| + {
|
| + base::RunLoop callback;
|
| + child_unit.SetPolicyClosure(callback.QuitClosure());
|
| + parent_unit.interface()->AddChild(child_unit.id());
|
| + callback.Run();
|
| + }
|
| +
|
| + // This should fail, due to the existing child-parent relationship.
|
| + // Otherwise we end up with infinite recursion and crash when recalculating
|
| + // policies below.
|
| + child_unit.interface()->AddChild(parent_unit.id());
|
| +
|
| + {
|
| + base::RunLoop parent_callback;
|
| + base::RunLoop child_callback;
|
| + parent_unit.SetPolicyClosure(parent_callback.QuitClosure());
|
| + child_unit.SetPolicyClosure(child_callback.QuitClosure());
|
| +
|
| + // This event should force the policy to recalculated for all children.
|
| + mojom::EventPtr event = mojom::Event::New();
|
| + event->type = mojom::EventType::TEST_EVENT;
|
| + parent_unit.interface()->SendEvent(std::move(event));
|
| +
|
| + parent_callback.Run();
|
| + child_callback.Run();
|
| + }
|
| +}
|
| +
|
| +} // namespace resource_coordinator
|
|
|