execution_context_registry_impl_unittest.cc 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/performance_manager/execution_context/execution_context_registry_impl.h"
  5. #include <memory>
  6. #include "base/memory/raw_ptr.h"
  7. #include "base/test/gtest_util.h"
  8. #include "components/performance_manager/execution_context/execution_context_impl.h"
  9. #include "components/performance_manager/public/execution_context/execution_context.h"
  10. #include "components/performance_manager/test_support/graph_test_harness.h"
  11. #include "components/performance_manager/test_support/mock_graphs.h"
  12. #include "testing/gmock/include/gmock/gmock.h"
  13. #include "testing/gtest/include/gtest/gtest.h"
  14. #include "third_party/blink/public/common/tokens/tokens.h"
  15. namespace performance_manager {
  16. namespace execution_context {
  17. namespace {
  18. class LenientMockExecutionContextObserver : public ExecutionContextObserver {
  19. public:
  20. LenientMockExecutionContextObserver() = default;
  21. LenientMockExecutionContextObserver(
  22. const LenientMockExecutionContextObserver&) = delete;
  23. LenientMockExecutionContextObserver& operator=(
  24. const LenientMockExecutionContextObserver&) = delete;
  25. ~LenientMockExecutionContextObserver() override = default;
  26. // ExecutionContextObserver implementation:
  27. MOCK_METHOD(void, OnExecutionContextAdded, (const ExecutionContext*), ());
  28. MOCK_METHOD(void,
  29. OnBeforeExecutionContextRemoved,
  30. (const ExecutionContext*),
  31. ());
  32. MOCK_METHOD(void,
  33. OnPriorityAndReasonChanged,
  34. (const ExecutionContext*,
  35. const PriorityAndReason& previous_value),
  36. ());
  37. };
  38. using MockExecutionContextObserver =
  39. testing::StrictMock<LenientMockExecutionContextObserver>;
  40. class ExecutionContextRegistryImplTest : public GraphTestHarness {
  41. public:
  42. using Super = GraphTestHarness;
  43. ExecutionContextRegistryImplTest() = default;
  44. ExecutionContextRegistryImplTest(const ExecutionContextRegistryImplTest&) =
  45. delete;
  46. ExecutionContextRegistryImplTest& operator=(
  47. const ExecutionContextRegistryImplTest&) = delete;
  48. ~ExecutionContextRegistryImplTest() override = default;
  49. void SetUp() override {
  50. Super::SetUp();
  51. graph()->PassToGraph(std::make_unique<ExecutionContextRegistryImpl>());
  52. registry_ = GraphRegisteredImpl<ExecutionContextRegistryImpl>::GetFromGraph(
  53. graph());
  54. ASSERT_TRUE(registry_);
  55. }
  56. protected:
  57. raw_ptr<ExecutionContextRegistryImpl> registry_ = nullptr;
  58. };
  59. using ExecutionContextRegistryImplDeathTest = ExecutionContextRegistryImplTest;
  60. } // namespace
  61. TEST_F(ExecutionContextRegistryImplTest, RegistryWorks) {
  62. // Ensure that the public getter works.
  63. EXPECT_EQ(registry_, ExecutionContextRegistry::GetFromGraph(graph()));
  64. // Create some mock nodes. This creates a graph with 1 page containing 2
  65. // frames in 1 process.
  66. MockMultiplePagesInSingleProcessGraph mock_graph(graph());
  67. // Only the frames are in the map at this point.
  68. EXPECT_EQ(2u, registry_->GetExecutionContextCountForTesting());
  69. // Creating a worker should create another entry in the map.
  70. auto worker_node = CreateNode<WorkerNodeImpl>(
  71. WorkerNode::WorkerType::kDedicated, mock_graph.process.get());
  72. EXPECT_EQ(3u, registry_->GetExecutionContextCountForTesting());
  73. auto* frame1 = mock_graph.frame.get();
  74. auto* frame2 = mock_graph.other_frame.get();
  75. auto* worker = worker_node.get();
  76. // Get the execution contexts for each node directly.
  77. auto* frame1_ec = GetOrCreateExecutionContextForFrameNode(frame1);
  78. auto* frame2_ec = GetOrCreateExecutionContextForFrameNode(frame2);
  79. auto* worker_ec = GetOrCreateExecutionContextForWorkerNode(worker);
  80. // Expect the FrameExecutionContext implementation to work.
  81. EXPECT_EQ(ExecutionContextType::kFrameNode, frame1_ec->GetType());
  82. EXPECT_EQ(frame1->frame_token().value(), frame1_ec->GetToken().value());
  83. EXPECT_EQ(frame1->url(), frame1_ec->GetUrl());
  84. EXPECT_EQ(frame1->process_node(), frame1_ec->GetProcessNode());
  85. EXPECT_EQ(frame1, frame1_ec->GetFrameNode());
  86. EXPECT_FALSE(frame1_ec->GetWorkerNode());
  87. // Expect the WorkerExecutionContext implementation to work.
  88. EXPECT_EQ(ExecutionContextType::kWorkerNode, worker_ec->GetType());
  89. EXPECT_EQ(worker->worker_token().value(), worker_ec->GetToken().value());
  90. EXPECT_EQ(worker->url(), worker_ec->GetUrl());
  91. EXPECT_EQ(worker->process_node(), worker_ec->GetProcessNode());
  92. EXPECT_FALSE(worker_ec->GetFrameNode());
  93. EXPECT_EQ(worker, worker_ec->GetWorkerNode());
  94. // Getting ExecutionContexts for a node should work.
  95. EXPECT_EQ(frame1_ec, registry_->GetExecutionContextForFrameNode(frame1));
  96. EXPECT_EQ(frame2_ec, registry_->GetExecutionContextForFrameNode(frame2));
  97. EXPECT_EQ(worker_ec, registry_->GetExecutionContextForWorkerNode(worker));
  98. // Lookup by ExecutionContextToken should work.
  99. EXPECT_EQ(frame1_ec,
  100. registry_->GetExecutionContextByToken(frame1_ec->GetToken()));
  101. EXPECT_EQ(frame2_ec,
  102. registry_->GetExecutionContextByToken(frame2_ec->GetToken()));
  103. EXPECT_EQ(worker_ec,
  104. registry_->GetExecutionContextByToken(worker_ec->GetToken()));
  105. // Lookup by typed tokens should work.
  106. EXPECT_EQ(frame1, registry_->GetFrameNodeByFrameToken(frame1->frame_token()));
  107. EXPECT_EQ(frame2, registry_->GetFrameNodeByFrameToken(frame2->frame_token()));
  108. EXPECT_EQ(worker,
  109. registry_->GetWorkerNodeByWorkerToken(worker->worker_token()));
  110. // Querying a random token should fail.
  111. EXPECT_FALSE(
  112. registry_->GetExecutionContextByToken(blink::ExecutionContextToken()));
  113. EXPECT_FALSE(registry_->GetFrameNodeByFrameToken(blink::LocalFrameToken()));
  114. EXPECT_FALSE(registry_->GetWorkerNodeByWorkerToken(blink::WorkerToken()));
  115. }
  116. TEST_F(ExecutionContextRegistryImplTest, Observers) {
  117. // Create an observer.
  118. MockExecutionContextObserver obs;
  119. EXPECT_FALSE(registry_->HasObserver(&obs));
  120. registry_->AddObserver(&obs);
  121. EXPECT_TRUE(registry_->HasObserver(&obs));
  122. // Create some mock nodes. This creates a graph with 1 page containing 1 frame
  123. // and 1 worker in a single process.
  124. EXPECT_CALL(obs, OnExecutionContextAdded(testing::_)).Times(2);
  125. MockSinglePageWithFrameAndWorkerInSingleProcessGraph mock_graph(graph());
  126. // The registry has 2 entries: the frame and the worker.
  127. EXPECT_EQ(2u, registry_->GetExecutionContextCountForTesting());
  128. auto* frame = mock_graph.frame.get();
  129. auto* worker = mock_graph.worker.get();
  130. // Get the execution contexts for each node directly.
  131. auto* frame_ec = GetOrCreateExecutionContextForFrameNode(frame);
  132. auto* worker_ec = GetOrCreateExecutionContextForWorkerNode(worker);
  133. // Set the priority and reason of the frame and expect a notification.
  134. EXPECT_CALL(obs, OnPriorityAndReasonChanged(frame_ec, testing::_));
  135. frame->SetPriorityAndReason(
  136. PriorityAndReason(base::TaskPriority::HIGHEST, "frame reason"));
  137. // Set the priority and reason of the worker and expect a notification.
  138. EXPECT_CALL(obs, OnPriorityAndReasonChanged(worker_ec, testing::_));
  139. worker->SetPriorityAndReason(
  140. PriorityAndReason(base::TaskPriority::HIGHEST, "worker reason"));
  141. // Destroy nodes one by one and expect observer notifications.
  142. EXPECT_CALL(obs, OnBeforeExecutionContextRemoved(worker_ec));
  143. mock_graph.DeleteWorker();
  144. EXPECT_EQ(1u, registry_->GetExecutionContextCountForTesting());
  145. EXPECT_CALL(obs, OnBeforeExecutionContextRemoved(frame_ec));
  146. mock_graph.frame.reset();
  147. EXPECT_EQ(0u, registry_->GetExecutionContextCountForTesting());
  148. // Unregister the observer so that the registry doesn't explode when it is
  149. // torn down.
  150. registry_->RemoveObserver(&obs);
  151. }
  152. TEST_F(ExecutionContextRegistryImplDeathTest, EnforceObserversRemoved) {
  153. // Create an observer.
  154. MockExecutionContextObserver obs;
  155. registry_->AddObserver(&obs);
  156. // The registry should explode if we kill it without unregistering observers.
  157. EXPECT_DCHECK_DEATH(graph()->TakeFromGraph(registry_));
  158. // Unregister the observer so that the registry doesn't explode when it is
  159. // torn down.
  160. registry_->RemoveObserver(&obs);
  161. }
  162. } // namespace execution_context
  163. } // namespace performance_manager