Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2017 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 | |
| 5 #include <string> | |
| 6 | |
| 7 #include "base/process/process_handle.h" | |
| 8 #include "base/run_loop.h" | |
| 9 #include "services/resource_coordinator/coordination_unit/coordination_unit_fact ory.h" | |
| 10 #include "services/resource_coordinator/coordination_unit/coordination_unit_grap h_observer.h" | |
| 11 #include "services/resource_coordinator/coordination_unit/coordination_unit_impl .h" | |
| 12 #include "services/resource_coordinator/coordination_unit/coordination_unit_impl _unittest_util.h" | |
| 13 #include "services/resource_coordinator/coordination_unit/coordination_unit_mana ger.h" | |
| 14 #include "services/resource_coordinator/public/cpp/coordination_unit_id.h" | |
| 15 #include "services/resource_coordinator/public/cpp/coordination_unit_types.h" | |
| 16 #include "services/resource_coordinator/public/interfaces/coordination_unit.mojo m.h" | |
| 17 #include "testing/gtest/include/gtest/gtest.h" | |
| 18 | |
| 19 namespace resource_coordinator { | |
| 20 | |
| 21 namespace { | |
| 22 | |
| 23 class CoordinationUnitGraphObserverTest : public CoordinationUnitImplTestBase { | |
| 24 }; | |
| 25 | |
| 26 class TestBasicAPICoordinationUnitGraphObserver | |
| 27 : public CoordinationUnitGraphObserver { | |
| 28 public: | |
| 29 explicit TestBasicAPICoordinationUnitGraphObserver( | |
| 30 CoordinationUnitType filter) | |
| 31 : CoordinationUnitGraphObserver(filter), | |
| 32 add_child_listener_invocations_(0u), | |
| 33 add_parent_listener_invocations_(0u), | |
| 34 coordination_unit_created_invocations_(0u), | |
| 35 property_changed_listener_invocations_(0u), | |
| 36 remove_child_listener_invocations_(0u), | |
| 37 remove_parent_listener_invocations_(0u), | |
| 38 will_be_destroyed_listener_invocations_(0u) {} | |
| 39 TestBasicAPICoordinationUnitGraphObserver() | |
| 40 : TestBasicAPICoordinationUnitGraphObserver( | |
| 41 CoordinationUnitType::kInvalidType) {} | |
| 42 | |
| 43 void CoordinationUnitCreated( | |
| 44 CoordinationUnitImpl* coordination_unit) override { | |
| 45 ++coordination_unit_created_invocations_; | |
| 46 | |
| 47 coordination_unit->on_add_child_event_listeners().AddListener(base::Bind( | |
| 48 &TestBasicAPICoordinationUnitGraphObserver::AddChildListenerInvoked, | |
| 49 base::Unretained(this))); | |
| 50 coordination_unit->on_add_parent_event_listeners().AddListener(base::Bind( | |
| 51 &TestBasicAPICoordinationUnitGraphObserver::AddParentListenerInvoked, | |
| 52 base::Unretained(this))); | |
| 53 coordination_unit->on_property_changed_event_listeners().AddListener( | |
| 54 base::Bind(&TestBasicAPICoordinationUnitGraphObserver:: | |
| 55 PropertyChangedListenerInvoked, | |
| 56 base::Unretained(this))); | |
| 57 coordination_unit->on_remove_child_event_listeners().AddListener(base::Bind( | |
| 58 &TestBasicAPICoordinationUnitGraphObserver::RemoveChildListenerInvoked, | |
| 59 base::Unretained(this))); | |
| 60 coordination_unit->on_remove_parent_event_listeners().AddListener( | |
| 61 base::Bind(&TestBasicAPICoordinationUnitGraphObserver:: | |
| 62 RemoveParentListenerInvoked, | |
| 63 base::Unretained(this))); | |
| 64 coordination_unit->on_will_be_destroyed_event_listeners().AddListener( | |
| 65 base::Bind(&TestBasicAPICoordinationUnitGraphObserver:: | |
| 66 WillBeDestroyedListenerInvoked, | |
| 67 base::Unretained(this))); | |
| 68 } | |
| 69 void AddChildListenerInvoked( | |
|
zhenw
2017/06/13 18:38:41
These callback functions should also follow the On
matthalp
2017/06/13 20:57:11
I will do that.
| |
| 70 const CoordinationUnitImpl* coordination_unit, | |
| 71 const CoordinationUnitImpl* child_coordination_unit) { | |
| 72 ++add_child_listener_invocations_; | |
| 73 } | |
| 74 void AddParentListenerInvoked( | |
| 75 const CoordinationUnitImpl* coordination_unit, | |
| 76 const CoordinationUnitImpl* parent_coordination_unit) { | |
| 77 ++add_parent_listener_invocations_; | |
| 78 } | |
| 79 void PropertyChangedListenerInvoked( | |
| 80 const CoordinationUnitImpl* coordination_unit, | |
| 81 mojom::PropertyType property) { | |
| 82 ++property_changed_listener_invocations_; | |
| 83 } | |
| 84 void RemoveChildListenerInvoked( | |
| 85 const CoordinationUnitImpl* coordination_unit, | |
| 86 const CoordinationUnitImpl* former_child_coordination_unit) { | |
| 87 ++remove_child_listener_invocations_; | |
| 88 } | |
| 89 void RemoveParentListenerInvoked( | |
| 90 const CoordinationUnitImpl* coordination_unit, | |
| 91 const CoordinationUnitImpl* former_parent_coordination_unit) { | |
| 92 ++remove_parent_listener_invocations_; | |
| 93 } | |
| 94 void WillBeDestroyedListenerInvoked( | |
| 95 const CoordinationUnitImpl* coordination_unit) { | |
| 96 ++will_be_destroyed_listener_invocations_; | |
| 97 } | |
| 98 | |
| 99 unsigned int add_child_listener_invocations() { | |
| 100 return add_child_listener_invocations_; | |
| 101 } | |
| 102 unsigned int add_parent_listener_invocations() { | |
| 103 return add_parent_listener_invocations_; | |
| 104 } | |
| 105 unsigned int coordination_unit_created_invocations() { | |
| 106 return coordination_unit_created_invocations_; | |
| 107 } | |
| 108 unsigned int property_changed_listener_invocations() { | |
| 109 return property_changed_listener_invocations_; | |
| 110 } | |
| 111 unsigned int remove_child_listener_invocations() { | |
| 112 return remove_child_listener_invocations_; | |
| 113 } | |
| 114 unsigned int remove_parent_listener_invocations() { | |
| 115 return remove_parent_listener_invocations_; | |
| 116 } | |
| 117 unsigned int will_be_destroyed_listener_invocations() { | |
| 118 return will_be_destroyed_listener_invocations_; | |
| 119 } | |
| 120 | |
| 121 protected: | |
| 122 unsigned int add_child_listener_invocations_; | |
| 123 unsigned int add_parent_listener_invocations_; | |
| 124 unsigned int coordination_unit_created_invocations_; | |
| 125 unsigned int property_changed_listener_invocations_; | |
| 126 unsigned int remove_child_listener_invocations_; | |
| 127 unsigned int remove_parent_listener_invocations_; | |
| 128 unsigned int will_be_destroyed_listener_invocations_; | |
| 129 }; | |
| 130 | |
| 131 class TestFilterAPICoordinationUnitGraphObserver | |
| 132 : public TestBasicAPICoordinationUnitGraphObserver { | |
| 133 public: | |
| 134 explicit TestFilterAPICoordinationUnitGraphObserver( | |
| 135 CoordinationUnitType filter) | |
| 136 : TestBasicAPICoordinationUnitGraphObserver(filter) {} | |
| 137 | |
| 138 void CoordinationUnitCreated( | |
| 139 CoordinationUnitImpl* coordination_unit) override { | |
| 140 ++coordination_unit_created_invocations_; | |
| 141 | |
| 142 coordination_unit->on_add_child_event_listeners().AddListener( | |
| 143 base::Bind( | |
| 144 &TestBasicAPICoordinationUnitGraphObserver::AddChildListenerInvoked, | |
| 145 base::Unretained(this)), | |
| 146 CoordinationUnitType::kFrame); | |
| 147 coordination_unit->on_add_parent_event_listeners().AddListener( | |
| 148 base::Bind(&TestBasicAPICoordinationUnitGraphObserver:: | |
| 149 AddParentListenerInvoked, | |
| 150 base::Unretained(this)), | |
| 151 CoordinationUnitType::kProcess); | |
| 152 // TODO(matthalp) Use property mojom::PropertyType enum once it is created. | |
| 153 // Currently the only enum is mojom::PropertyType::kTest which is mean to | |
| 154 // be filtered out in the test this observer class is used in. | |
| 155 coordination_unit->on_property_changed_event_listeners().AddListener( | |
| 156 base::Bind(&TestBasicAPICoordinationUnitGraphObserver:: | |
| 157 PropertyChangedListenerInvoked, | |
| 158 base::Unretained(this)), | |
| 159 static_cast<mojom::PropertyType>(1)); | |
| 160 coordination_unit->on_remove_child_event_listeners().AddListener( | |
| 161 base::Bind(&TestBasicAPICoordinationUnitGraphObserver:: | |
| 162 RemoveChildListenerInvoked, | |
| 163 base::Unretained(this)), | |
| 164 CoordinationUnitType::kNavigation); | |
| 165 coordination_unit->on_remove_parent_event_listeners().AddListener( | |
| 166 base::Bind(&TestBasicAPICoordinationUnitGraphObserver:: | |
| 167 RemoveParentListenerInvoked, | |
| 168 base::Unretained(this)), | |
| 169 CoordinationUnitType::kWebContents); | |
| 170 coordination_unit->on_will_be_destroyed_event_listeners().AddListener( | |
| 171 base::Bind(&TestBasicAPICoordinationUnitGraphObserver:: | |
| 172 WillBeDestroyedListenerInvoked, | |
| 173 base::Unretained(this))); | |
| 174 } | |
| 175 }; | |
| 176 | |
| 177 } // namespace | |
| 178 | |
| 179 TEST_F(CoordinationUnitGraphObserverTest, CallbacksInvokedNoFilters) { | |
| 180 // The observer will be deleted after this test executes when the | |
| 181 // CoordinationUnitManager object goes out of scope and destructs. | |
| 182 TestBasicAPICoordinationUnitGraphObserver* observer = | |
| 183 new TestBasicAPICoordinationUnitGraphObserver(); | |
| 184 coordination_unit_manager()->RegisterObserver(observer); | |
| 185 | |
| 186 // The CoordinationUnit types are intentionally different to make | |
| 187 // sure filtering, which is not disabled, does not occur. | |
| 188 CoordinationUnitID parent_cu_id(CoordinationUnitType::kWebContents, | |
| 189 std::string()); | |
| 190 CoordinationUnitID child_cu_id(CoordinationUnitType::kFrame, std::string()); | |
| 191 | |
| 192 std::unique_ptr<CoordinationUnitImpl> parent_coordination_unit = | |
| 193 coordination_unit_factory::CreateCoordinationUnit( | |
| 194 parent_cu_id, service_context_ref_factory()->CreateRef()); | |
| 195 std::unique_ptr<CoordinationUnitImpl> child_coordination_unit = | |
| 196 coordination_unit_factory::CreateCoordinationUnit( | |
| 197 child_cu_id, service_context_ref_factory()->CreateRef()); | |
| 198 | |
| 199 coordination_unit_manager()->NotifyObserversCoordinationUnitCreated( | |
| 200 parent_coordination_unit.get()); | |
| 201 coordination_unit_manager()->NotifyObserversCoordinationUnitCreated( | |
| 202 child_coordination_unit.get()); | |
| 203 | |
| 204 parent_coordination_unit->AddChild(child_coordination_unit->id()); | |
| 205 parent_coordination_unit->RemoveChild(child_coordination_unit->id()); | |
| 206 | |
| 207 parent_coordination_unit->SetProperty(mojom::PropertyType::kTest, | |
| 208 base::Value(42)); | |
| 209 | |
| 210 child_coordination_unit->WillBeDestroyed(); | |
| 211 parent_coordination_unit->WillBeDestroyed(); | |
| 212 | |
| 213 EXPECT_EQ(1u, observer->add_child_listener_invocations()); | |
| 214 EXPECT_EQ(1u, observer->add_parent_listener_invocations()); | |
| 215 EXPECT_EQ(2u, observer->coordination_unit_created_invocations()); | |
| 216 EXPECT_EQ(1u, observer->property_changed_listener_invocations()); | |
| 217 EXPECT_EQ(1u, observer->remove_child_listener_invocations()); | |
| 218 EXPECT_EQ(1u, observer->remove_parent_listener_invocations()); | |
| 219 EXPECT_EQ(2u, observer->will_be_destroyed_listener_invocations()); | |
| 220 } | |
| 221 | |
| 222 TEST_F(CoordinationUnitGraphObserverTest, CallbacksInvokedWithFilters) { | |
| 223 TestFilterAPICoordinationUnitGraphObserver* observer = | |
| 224 new TestFilterAPICoordinationUnitGraphObserver( | |
| 225 CoordinationUnitType::kFrame); | |
| 226 coordination_unit_manager()->RegisterObserver(observer); | |
| 227 | |
| 228 // The CoordinationUnit types are intentionally different to test | |
| 229 // that filtering is working correctly. | |
| 230 CoordinationUnitID process_cu_id(CoordinationUnitType::kProcess, | |
| 231 std::string()); | |
| 232 CoordinationUnitID tab_cu_id(CoordinationUnitType::kWebContents, | |
| 233 std::string()); | |
| 234 CoordinationUnitID root_frame_cu_id(CoordinationUnitType::kFrame, | |
| 235 std::string()); | |
| 236 CoordinationUnitID frame_cu_id(CoordinationUnitType::kFrame, std::string()); | |
| 237 CoordinationUnitID navigation_cu_id(CoordinationUnitType::kNavigation, | |
| 238 std::string()); | |
| 239 | |
| 240 std::unique_ptr<CoordinationUnitImpl> process_coordination_unit = | |
| 241 coordination_unit_factory::CreateCoordinationUnit( | |
| 242 process_cu_id, service_context_ref_factory()->CreateRef()); | |
| 243 std::unique_ptr<CoordinationUnitImpl> tab_coordination_unit = | |
| 244 coordination_unit_factory::CreateCoordinationUnit( | |
| 245 tab_cu_id, service_context_ref_factory()->CreateRef()); | |
| 246 std::unique_ptr<CoordinationUnitImpl> root_frame_coordination_unit = | |
| 247 coordination_unit_factory::CreateCoordinationUnit( | |
| 248 root_frame_cu_id, service_context_ref_factory()->CreateRef()); | |
| 249 std::unique_ptr<CoordinationUnitImpl> frame_coordination_unit = | |
| 250 coordination_unit_factory::CreateCoordinationUnit( | |
| 251 frame_cu_id, service_context_ref_factory()->CreateRef()); | |
| 252 std::unique_ptr<CoordinationUnitImpl> navigation_coordination_unit = | |
| 253 coordination_unit_factory::CreateCoordinationUnit( | |
| 254 navigation_cu_id, service_context_ref_factory()->CreateRef()); | |
| 255 | |
| 256 // Should not invoke the CoordinationUnitCreated listener | |
| 257 coordination_unit_manager()->NotifyObserversCoordinationUnitCreated( | |
| 258 process_coordination_unit.get()); | |
| 259 // Should not invoke the CoordinationUnitCreated listener | |
| 260 coordination_unit_manager()->NotifyObserversCoordinationUnitCreated( | |
| 261 tab_coordination_unit.get()); | |
| 262 // Should invoke the CoordinationUnitCreated listener | |
| 263 coordination_unit_manager()->NotifyObserversCoordinationUnitCreated( | |
| 264 root_frame_coordination_unit.get()); | |
| 265 // Should not invoke the CoordinationUnitCreated listener | |
| 266 coordination_unit_manager()->NotifyObserversCoordinationUnitCreated( | |
| 267 frame_coordination_unit.get()); | |
| 268 // Should not invoke the CoordinationUnitCreated listener | |
| 269 coordination_unit_manager()->NotifyObserversCoordinationUnitCreated( | |
| 270 navigation_coordination_unit.get()); | |
| 271 | |
| 272 // Should invoke the observer's AddChild listener. | |
| 273 root_frame_coordination_unit->AddChild(frame_coordination_unit->id()); | |
| 274 // The navigation Coordination Unit is not actually a child of a frame | |
| 275 // in practice, but is being used here to check filtering on AddChild. | |
| 276 // Should not invoke the observer's AddChild listener. | |
| 277 root_frame_coordination_unit->AddChild(navigation_coordination_unit->id()); | |
| 278 // Should invoke the observer's AddParent listener. | |
| 279 process_coordination_unit->AddChild(root_frame_coordination_unit->id()); | |
| 280 // Should not invoke the observer's AddParent listener. | |
| 281 tab_coordination_unit->AddChild(root_frame_coordination_unit->id()); | |
| 282 | |
| 283 // Should not invoke the observer's RemoveChild listener. | |
| 284 root_frame_coordination_unit->RemoveChild(frame_coordination_unit->id()); | |
| 285 // The navigation Coordination Unit is not actually a child of a frame | |
| 286 // in practice, but is being used here to check filtering on AddChild. | |
| 287 // Should invoke the observer's RemoveChild listener. | |
| 288 root_frame_coordination_unit->RemoveChild(navigation_coordination_unit->id()); | |
| 289 // Should not invoke the observer's RemoveParent listener. | |
| 290 process_coordination_unit->RemoveChild(root_frame_coordination_unit->id()); | |
| 291 // Should invoke the observer's RemoveParent listener. | |
| 292 tab_coordination_unit->RemoveChild(root_frame_coordination_unit->id()); | |
| 293 | |
| 294 // TODO(matthalp) Implement this another SetProperty once an additional | |
| 295 // mojom::PropertyType has been implemented so that the SetProperty | |
| 296 // filtering API can be tested. | |
| 297 root_frame_coordination_unit->SetProperty(mojom::PropertyType::kTest, | |
| 298 base::Value(42)); | |
| 299 | |
| 300 process_coordination_unit->WillBeDestroyed(); | |
| 301 tab_coordination_unit->WillBeDestroyed(); | |
| 302 root_frame_coordination_unit->WillBeDestroyed(); | |
| 303 frame_coordination_unit->WillBeDestroyed(); | |
| 304 navigation_coordination_unit->WillBeDestroyed(); | |
| 305 | |
| 306 EXPECT_EQ(1u, observer->add_child_listener_invocations()); | |
| 307 EXPECT_EQ(1u, observer->add_parent_listener_invocations()); | |
| 308 EXPECT_EQ(2u, observer->coordination_unit_created_invocations()); | |
| 309 EXPECT_EQ(0u, observer->property_changed_listener_invocations()); | |
| 310 EXPECT_EQ(1u, observer->remove_child_listener_invocations()); | |
| 311 EXPECT_EQ(1u, observer->remove_parent_listener_invocations()); | |
| 312 EXPECT_EQ(2u, observer->will_be_destroyed_listener_invocations()); | |
| 313 } | |
| 314 | |
| 315 } // namespace resource_coordinator | |
| OLD | NEW |