Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2015 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 "chrome/browser/sessions/session_restore_stats_collector.h" | |
| 6 | |
| 7 #include "base/message_loop/message_loop.h" | |
| 8 #include "base/test/simple_test_tick_clock.h" | |
| 9 #include "chrome/test/base/testing_profile.h" | |
| 10 #include "content/public/browser/notification_service.h" | |
| 11 #include "content/public/browser/notification_types.h" | |
| 12 #include "content/public/browser/render_widget_host.h" | |
| 13 #include "content/public/browser/render_widget_host_view.h" | |
| 14 #include "content/public/browser/web_contents.h" | |
| 15 #include "content/public/test/test_browser_thread.h" | |
| 16 #include "content/public/test/test_web_contents_factory.h" | |
| 17 #include "testing/gtest/include/gtest/gtest.h" | |
| 18 | |
| 19 namespace { | |
| 20 | |
| 21 using TabLoaderStats = SessionRestoreStatsCollector::TabLoaderStats; | |
| 22 using StatsReportingDelegate = | |
| 23 SessionRestoreStatsCollector::StatsReportingDelegate; | |
| 24 | |
| 25 // A mock StatsReportingDelegate. This is used by the unittests to validate the | |
| 26 // reporting and lifetime behaviour of the SessionRestoreStatsCollector under | |
| 27 // test. | |
| 28 class MockStatsReportingDelegate : public StatsReportingDelegate { | |
| 29 public: | |
| 30 MockStatsReportingDelegate() | |
| 31 : report_tab_loader_stats_call_count_(0), | |
|
sky
2015/06/17 21:12:04
0u on all of these.
chrisha
2015/06/18 12:46:23
Done.
| |
| 32 report_tab_deferred_call_count_(0), | |
| 33 report_deferred_tab_loaded_call_count_(0), | |
| 34 report_stats_collector_death_call_count_(0) {} | |
| 35 | |
| 36 ~MockStatsReportingDelegate() override { EnsureNoUnexpectedCalls(); } | |
| 37 | |
| 38 void ReportTabLoaderStats(const TabLoaderStats& stats) override { | |
| 39 report_tab_loader_stats_call_count_++; | |
| 40 tab_loader_stats_ = stats; | |
| 41 } | |
| 42 | |
| 43 void ReportTabDeferred() override { report_tab_deferred_call_count_++; } | |
| 44 | |
| 45 void ReportDeferredTabLoaded() override { | |
| 46 report_deferred_tab_loaded_call_count_++; | |
| 47 } | |
| 48 | |
| 49 // This is not part of the StatsReportingDelegate, but an added function that | |
| 50 // is invoked by the PassthroughStatsReportingDelegate when it dies. This | |
| 51 // allows the tests to be notified the moment the underlying stats collector | |
| 52 // terminates itself. | |
| 53 void ReportStatsCollectorDeath() { | |
| 54 report_stats_collector_death_call_count_++; | |
| 55 } | |
| 56 | |
| 57 void ExpectReportTabLoaderStatsCalled(size_t tab_count, | |
| 58 size_t tabs_loaded, | |
| 59 int foreground_tab_first_loaded_ms, | |
| 60 int foreground_tab_first_paint_ms, | |
| 61 int non_deferred_tabs_loaded_ms, | |
| 62 size_t parallel_tab_loads) { | |
| 63 EXPECT_LT(0u, report_tab_loader_stats_call_count_); | |
| 64 report_tab_loader_stats_call_count_--; | |
| 65 | |
| 66 EXPECT_EQ(tab_count, tab_loader_stats_.tab_count); | |
| 67 EXPECT_EQ(tabs_loaded, tab_loader_stats_.tabs_loaded); | |
| 68 EXPECT_EQ(base::TimeDelta::FromMilliseconds(foreground_tab_first_loaded_ms), | |
| 69 tab_loader_stats_.foreground_tab_first_loaded); | |
| 70 EXPECT_EQ(base::TimeDelta::FromMilliseconds(foreground_tab_first_paint_ms), | |
| 71 tab_loader_stats_.foreground_tab_first_paint); | |
| 72 EXPECT_EQ(base::TimeDelta::FromMilliseconds(non_deferred_tabs_loaded_ms), | |
| 73 tab_loader_stats_.non_deferred_tabs_loaded); | |
| 74 EXPECT_EQ(parallel_tab_loads, tab_loader_stats_.parallel_tab_loads); | |
| 75 } | |
| 76 | |
| 77 void ExpectReportTabDeferredCalled() { | |
| 78 EXPECT_LT(0u, report_tab_deferred_call_count_); | |
| 79 report_tab_deferred_call_count_--; | |
| 80 } | |
| 81 | |
| 82 void ExpectReportDeferredTabLoadedCalled() { | |
| 83 EXPECT_LT(0u, report_deferred_tab_loaded_call_count_); | |
| 84 report_deferred_tab_loaded_call_count_--; | |
| 85 } | |
| 86 | |
| 87 void ExpectReportStatsCollectorDeathCalled() { | |
| 88 EXPECT_LT(0u, report_stats_collector_death_call_count_); | |
| 89 report_stats_collector_death_call_count_--; | |
| 90 } | |
| 91 | |
| 92 void EnsureNoUnexpectedCalls() { | |
| 93 EXPECT_EQ(0u, report_tab_loader_stats_call_count_); | |
| 94 EXPECT_EQ(0u, report_tab_deferred_call_count_); | |
| 95 EXPECT_EQ(0u, report_deferred_tab_loaded_call_count_); | |
| 96 EXPECT_EQ(0u, report_stats_collector_death_call_count_); | |
| 97 | |
| 98 report_tab_loader_stats_call_count_ = 0; | |
| 99 report_tab_deferred_call_count_ = 0; | |
| 100 report_deferred_tab_loaded_call_count_ = 0; | |
| 101 report_stats_collector_death_call_count_ = 0; | |
| 102 tab_loader_stats_ = TabLoaderStats(); | |
| 103 } | |
| 104 | |
| 105 private: | |
| 106 size_t report_tab_loader_stats_call_count_; | |
| 107 size_t report_tab_deferred_call_count_; | |
| 108 size_t report_deferred_tab_loaded_call_count_; | |
| 109 size_t report_stats_collector_death_call_count_; | |
| 110 TabLoaderStats tab_loader_stats_; | |
| 111 }; | |
|
sky
2015/06/17 21:12:04
DISALLOW...
chrisha
2015/06/18 12:46:23
Done.
| |
| 112 | |
| 113 // A pass-through stats reporting delegate. This is used to decouple the | |
| 114 // lifetime of the mock reporting delegate from the SessionRestoreStatsCollector | |
| 115 // under test. The SessionRestoreStatsCollector has ownership of this delegate, | |
| 116 // which will notify the mock delegate upon its death. | |
| 117 class PassthroughStatsReportingDelegate : public StatsReportingDelegate { | |
| 118 public: | |
| 119 PassthroughStatsReportingDelegate() : reporting_delegate_(nullptr) {} | |
| 120 ~PassthroughStatsReportingDelegate() override { | |
| 121 reporting_delegate_->ReportStatsCollectorDeath(); | |
| 122 } | |
| 123 | |
| 124 void set_reporting_delegate(MockStatsReportingDelegate* reporting_delegate) { | |
| 125 reporting_delegate_ = reporting_delegate; | |
| 126 } | |
| 127 | |
| 128 void ReportTabLoaderStats(const TabLoaderStats& tab_loader_stats) override { | |
| 129 reporting_delegate_->ReportTabLoaderStats(tab_loader_stats); | |
| 130 } | |
| 131 | |
| 132 void ReportTabDeferred() override { | |
| 133 reporting_delegate_->ReportTabDeferred(); | |
| 134 } | |
| 135 | |
| 136 void ReportDeferredTabLoaded() override { | |
| 137 reporting_delegate_->ReportDeferredTabLoaded(); | |
| 138 } | |
| 139 | |
| 140 private: | |
| 141 MockStatsReportingDelegate* reporting_delegate_; | |
| 142 }; | |
|
sky
2015/06/17 21:12:04
DISALLOW... (on all the classes you have here).
chrisha
2015/06/18 12:46:23
Done.
| |
| 143 | |
| 144 } // namespace | |
| 145 | |
| 146 class TestSessionRestoreStatsCollector : public SessionRestoreStatsCollector { | |
| 147 public: | |
| 148 using SessionRestoreStatsCollector::Observe; | |
| 149 | |
| 150 TestSessionRestoreStatsCollector( | |
| 151 scoped_ptr<base::TickClock> tick_clock, | |
| 152 scoped_ptr<StatsReportingDelegate> reporting_delegate) | |
| 153 : SessionRestoreStatsCollector(tick_clock->NowTicks(), | |
| 154 reporting_delegate.Pass()) { | |
| 155 set_tick_clock(tick_clock.Pass()); | |
| 156 } | |
| 157 | |
| 158 private: | |
| 159 friend class base::RefCounted<TestSessionRestoreStatsCollector>; | |
| 160 | |
| 161 ~TestSessionRestoreStatsCollector() override {} | |
| 162 | |
| 163 base::SimpleTestTickClock* test_tick_clock_; | |
| 164 }; | |
| 165 | |
| 166 class SessionRestoreStatsCollectorTest : public testing::Test { | |
| 167 public: | |
| 168 using RestoredTab = SessionRestoreDelegate::RestoredTab; | |
| 169 | |
| 170 SessionRestoreStatsCollectorTest() | |
| 171 : ui_thread_(content::BrowserThread::UI, &message_loop_) {} | |
| 172 | |
| 173 void SetUp() override { | |
| 174 test_web_contents_factory_.reset(new content::TestWebContentsFactory); | |
| 175 | |
| 176 // Ownership of the reporting delegate is passed to the | |
| 177 // SessionRestoreStatsCollector, but a raw pointer is kept to it so it can | |
| 178 // be queried by the test. | |
| 179 passthrough_reporting_delegate_ = new PassthroughStatsReportingDelegate(); | |
| 180 | |
| 181 // Ownership of this clock is passed to the SessionRestoreStatsCollector. | |
| 182 // A raw pointer is kept to it so that it can be modified from the outside. | |
| 183 // The unittest must take not to access the clock only while the | |
|
sky
2015/06/17 21:12:04
not->care not?
chrisha
2015/06/18 12:46:23
Done.
| |
| 184 // SessionRestoreStatsCollector under test is still alive. | |
| 185 test_tick_clock_ = new base::SimpleTestTickClock(); | |
| 186 | |
| 187 // Create a stats collector, keep a raw pointer to it, and detach from it. | |
| 188 // The stats collector will stay alive as long as it has not yet completed | |
| 189 // its job, and will clean itself up when done. | |
| 190 scoped_refptr<TestSessionRestoreStatsCollector> stats_collector = | |
| 191 new TestSessionRestoreStatsCollector( | |
| 192 scoped_ptr<base::TickClock>(test_tick_clock_), | |
| 193 scoped_ptr<StatsReportingDelegate>( | |
| 194 passthrough_reporting_delegate_)); | |
| 195 stats_collector_ = stats_collector.get(); | |
| 196 stats_collector = nullptr; | |
| 197 } | |
| 198 | |
| 199 void TearDown() override { | |
| 200 passthrough_reporting_delegate_ = nullptr; | |
| 201 test_tick_clock_ = nullptr; | |
| 202 stats_collector_ = nullptr; | |
| 203 | |
| 204 // Clean up any tabs that were generated by the unittest. | |
| 205 restored_tabs_.clear(); | |
| 206 test_web_contents_factory_.reset(); | |
| 207 } | |
| 208 | |
| 209 // Advances the test clock by 1ms. | |
| 210 void Tick() { | |
| 211 test_tick_clock_->Advance(base::TimeDelta::FromMilliseconds(1)); | |
| 212 } | |
| 213 | |
| 214 void Show(size_t tab_index) { | |
| 215 restored_tabs_[tab_index].contents()->GetRenderWidgetHostView()->Show(); | |
| 216 } | |
| 217 | |
| 218 void Hide(size_t tab_index) { | |
| 219 restored_tabs_[tab_index].contents()->GetRenderWidgetHostView()->Hide(); | |
| 220 } | |
| 221 | |
| 222 // Creates a restored tab backed by dummy WebContents/NavigationController/ | |
| 223 // RenderWidgetHost/RenderWidgetHostView. Returns the index of the restored | |
| 224 // tab for future simulation of events. | |
| 225 void CreateRestoredTab(bool is_active) { | |
| 226 content::WebContents* contents = | |
| 227 test_web_contents_factory_->CreateWebContents(&testing_profile_); | |
| 228 restored_tabs_.push_back(RestoredTab(contents, is_active, false, false)); | |
| 229 if (is_active) | |
| 230 Show(restored_tabs_.size() - 1); | |
| 231 } | |
| 232 | |
| 233 // Helper function for various notification generation. | |
| 234 void GenerateControllerNotification(size_t tab_index, int type) { | |
| 235 content::WebContents* contents = restored_tabs_[tab_index].contents(); | |
| 236 content::NavigationController* controller = &contents->GetController(); | |
| 237 stats_collector_->Observe( | |
| 238 type, content::Source<content::NavigationController>(controller), | |
| 239 content::NotificationService::NoDetails()); | |
| 240 } | |
| 241 | |
| 242 // Generates a load start notification for the given tab. | |
| 243 void GenerateLoadStart(size_t tab_index) { | |
| 244 GenerateControllerNotification(tab_index, content::NOTIFICATION_LOAD_START); | |
| 245 } | |
| 246 | |
| 247 // Generates a load stop notification for the given tab. | |
| 248 void GenerateLoadStop(size_t tab_index) { | |
| 249 GenerateControllerNotification(tab_index, content::NOTIFICATION_LOAD_STOP); | |
| 250 } | |
| 251 | |
| 252 // Generates a web contents destroyed notification for the given tab. | |
| 253 void GenerateWebContentsDestroyed(size_t tab_index) { | |
| 254 content::WebContents* contents = restored_tabs_[tab_index].contents(); | |
| 255 stats_collector_->Observe(content::NOTIFICATION_WEB_CONTENTS_DESTROYED, | |
| 256 content::Source<content::WebContents>(contents), | |
| 257 content::NotificationService::NoDetails()); | |
| 258 } | |
| 259 | |
| 260 // Generates a paint notification for the given tab. | |
| 261 void GenerateRenderWidgetHostDidUpdateBackingStore(size_t tab_index) { | |
| 262 content::WebContents* contents = restored_tabs_[tab_index].contents(); | |
| 263 content::RenderWidgetHost* host = | |
| 264 contents->GetRenderWidgetHostView()->GetRenderWidgetHost(); | |
| 265 stats_collector_->Observe( | |
| 266 content::NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE, | |
| 267 content::Source<content::RenderWidgetHost>(host), | |
| 268 content::NotificationService::NoDetails()); | |
| 269 } | |
| 270 | |
| 271 // Defers a tab. | |
| 272 void DeferTab(size_t tab_index) { | |
| 273 content::WebContents* contents = restored_tabs_[tab_index].contents(); | |
| 274 content::NavigationController* controller = &contents->GetController(); | |
| 275 stats_collector_->DeferTab(controller); | |
| 276 } | |
| 277 | |
| 278 // Inputs to the stats collector. Reset prior to each test. | |
| 279 base::SimpleTestTickClock* test_tick_clock_; | |
| 280 std::vector<RestoredTab> restored_tabs_; | |
| 281 | |
| 282 // Infrastructure needed for using the TestWebContentsFactory. These are | |
| 283 // initialized once by the fixture and reused across unittests. | |
| 284 base::MessageLoop message_loop_; | |
| 285 TestingProfile testing_profile_; | |
| 286 content::TestBrowserThread ui_thread_; | |
| 287 | |
| 288 // A new web contents factory is generated per test. This automatically cleans | |
| 289 // up any tabs created by previous tests. | |
| 290 scoped_ptr<content::TestWebContentsFactory> test_web_contents_factory_; | |
| 291 | |
| 292 // These are recreated for each test. The reporting delegate allows the test | |
| 293 // to observe the behaviour of the SessionRestoreStatsCollector under test. | |
| 294 PassthroughStatsReportingDelegate* passthrough_reporting_delegate_; | |
| 295 TestSessionRestoreStatsCollector* stats_collector_; | |
| 296 }; | |
| 297 | |
| 298 TEST_F(SessionRestoreStatsCollectorTest, SingleTabPaintBeforeLoad) { | |
| 299 MockStatsReportingDelegate mock_reporting_delegate; | |
| 300 passthrough_reporting_delegate_->set_reporting_delegate( | |
| 301 &mock_reporting_delegate); | |
| 302 | |
| 303 CreateRestoredTab(true); | |
| 304 stats_collector_->TrackTabs(restored_tabs_); | |
| 305 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 306 | |
| 307 Tick(); // 1ms. | |
| 308 GenerateRenderWidgetHostDidUpdateBackingStore(0); | |
| 309 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 310 | |
| 311 Tick(); // 2ms. | |
| 312 GenerateLoadStop(0); | |
| 313 mock_reporting_delegate.ExpectReportTabLoaderStatsCalled(1, 1, 2, 1, 2, 1); | |
| 314 mock_reporting_delegate.ExpectReportStatsCollectorDeathCalled(); | |
| 315 } | |
| 316 | |
| 317 TEST_F(SessionRestoreStatsCollectorTest, SingleTabPaintAfterLoad) { | |
| 318 MockStatsReportingDelegate mock_reporting_delegate; | |
| 319 passthrough_reporting_delegate_->set_reporting_delegate( | |
| 320 &mock_reporting_delegate); | |
| 321 | |
| 322 CreateRestoredTab(true); | |
| 323 stats_collector_->TrackTabs(restored_tabs_); | |
| 324 | |
| 325 Tick(); // 1ms. | |
| 326 GenerateLoadStop(0); | |
| 327 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 328 | |
| 329 Tick(); // 2ms. | |
| 330 GenerateRenderWidgetHostDidUpdateBackingStore(0); | |
| 331 mock_reporting_delegate.ExpectReportTabLoaderStatsCalled(1, 1, 1, 2, 1, 1); | |
| 332 mock_reporting_delegate.ExpectReportStatsCollectorDeathCalled(); | |
| 333 } | |
| 334 | |
| 335 TEST_F(SessionRestoreStatsCollectorTest, MultipleTabsLoadSerially) { | |
| 336 MockStatsReportingDelegate mock_reporting_delegate; | |
| 337 passthrough_reporting_delegate_->set_reporting_delegate( | |
| 338 &mock_reporting_delegate); | |
| 339 | |
| 340 CreateRestoredTab(true); | |
| 341 CreateRestoredTab(false); | |
| 342 CreateRestoredTab(false); | |
| 343 stats_collector_->TrackTabs(restored_tabs_); | |
| 344 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 345 | |
| 346 // Foreground tab paints then finishes loading. | |
| 347 Tick(); // 1ms. | |
| 348 GenerateRenderWidgetHostDidUpdateBackingStore(0); | |
| 349 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 350 Tick(); // 2ms. | |
| 351 GenerateLoadStop(0); | |
| 352 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 353 | |
| 354 // First background tab starts loading, paints, then finishes loading. | |
| 355 Tick(); // 3ms. | |
| 356 GenerateLoadStart(1); | |
| 357 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 358 Tick(); // 4ms. | |
| 359 GenerateRenderWidgetHostDidUpdateBackingStore(1); | |
| 360 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 361 Tick(); // 5ms. | |
| 362 GenerateLoadStop(1); | |
| 363 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 364 | |
| 365 // Second background tab starts loading, finishes loading, but never paints. | |
| 366 Tick(); // 6ms. | |
| 367 GenerateLoadStart(2); | |
| 368 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 369 | |
| 370 Tick(); // 7ms. | |
| 371 GenerateLoadStop(2); | |
| 372 mock_reporting_delegate.ExpectReportTabLoaderStatsCalled(3, 3, 2, 1, 7, 1); | |
| 373 mock_reporting_delegate.ExpectReportStatsCollectorDeathCalled(); | |
| 374 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 375 } | |
| 376 | |
| 377 TEST_F(SessionRestoreStatsCollectorTest, MultipleTabsLoadSimultaneously) { | |
| 378 MockStatsReportingDelegate mock_reporting_delegate; | |
| 379 passthrough_reporting_delegate_->set_reporting_delegate( | |
| 380 &mock_reporting_delegate); | |
| 381 | |
| 382 CreateRestoredTab(true); | |
| 383 CreateRestoredTab(false); | |
| 384 CreateRestoredTab(false); | |
| 385 stats_collector_->TrackTabs(restored_tabs_); | |
| 386 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 387 | |
| 388 // Foreground tab paints then finishes loading. | |
| 389 Tick(); // 1ms. | |
| 390 GenerateRenderWidgetHostDidUpdateBackingStore(0); | |
| 391 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 392 Tick(); // 2ms. | |
| 393 GenerateLoadStop(0); | |
| 394 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 395 | |
| 396 // Both background tabs start loading at the same time. The first one paints | |
| 397 // before finishing loading, the second one paints after finishing loading | |
| 398 // (the stats collector never sees the paint event). | |
| 399 Tick(); // 3ms. | |
| 400 GenerateLoadStart(1); | |
| 401 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 402 GenerateLoadStart(2); | |
| 403 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 404 Tick(); // 4ms. | |
| 405 GenerateRenderWidgetHostDidUpdateBackingStore(1); | |
| 406 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 407 Tick(); // 5ms. | |
| 408 GenerateLoadStop(1); | |
| 409 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 410 Tick(); // 6ms. | |
| 411 GenerateLoadStop(2); | |
| 412 mock_reporting_delegate.ExpectReportTabLoaderStatsCalled(3, 3, 2, 1, 6, 2); | |
| 413 mock_reporting_delegate.ExpectReportStatsCollectorDeathCalled(); | |
| 414 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 415 } | |
| 416 | |
| 417 TEST_F(SessionRestoreStatsCollectorTest, DeferredTabs) { | |
| 418 MockStatsReportingDelegate mock_reporting_delegate; | |
| 419 passthrough_reporting_delegate_->set_reporting_delegate( | |
| 420 &mock_reporting_delegate); | |
| 421 | |
| 422 CreateRestoredTab(true); | |
| 423 CreateRestoredTab(false); | |
| 424 stats_collector_->TrackTabs(restored_tabs_); | |
| 425 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 426 | |
| 427 // Foreground tab paints, then the background tab is deferred. | |
| 428 Tick(); // 1ms. | |
| 429 GenerateRenderWidgetHostDidUpdateBackingStore(0); | |
| 430 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 431 DeferTab(1); | |
| 432 mock_reporting_delegate.ExpectReportTabDeferredCalled(); | |
| 433 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 434 | |
| 435 // Foreground tab finishes loading and stats get reported. | |
| 436 Tick(); // 2ms. | |
| 437 GenerateLoadStop(0); | |
| 438 mock_reporting_delegate.ExpectReportTabLoaderStatsCalled(2, 1, 2, 1, 2, 1); | |
| 439 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 440 | |
| 441 // Background tab starts loading, paints and stops loading. This fires off a | |
| 442 // deferred tab loaded notification. | |
| 443 Tick(); // 3ms. | |
| 444 GenerateLoadStart(1); | |
| 445 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 446 Tick(); // 4ms. | |
| 447 GenerateRenderWidgetHostDidUpdateBackingStore(1); | |
| 448 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 449 Tick(); // 5ms. | |
| 450 GenerateLoadStop(1); | |
| 451 mock_reporting_delegate.ExpectReportDeferredTabLoadedCalled(); | |
| 452 mock_reporting_delegate.ExpectReportStatsCollectorDeathCalled(); | |
| 453 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 454 } | |
| 455 | |
| 456 TEST_F(SessionRestoreStatsCollectorTest, FocusSwitchNoForegroundPaintOrLoad) { | |
| 457 MockStatsReportingDelegate mock_reporting_delegate; | |
| 458 passthrough_reporting_delegate_->set_reporting_delegate( | |
| 459 &mock_reporting_delegate); | |
| 460 | |
| 461 CreateRestoredTab(true); | |
| 462 stats_collector_->TrackTabs(restored_tabs_); | |
| 463 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 464 | |
| 465 // Create another tab and make it the foreground tab. This tab is not actually | |
| 466 // being tracked by the SessionRestoreStatsCollector, but its paint events | |
| 467 // will be observed. | |
| 468 CreateRestoredTab(false); | |
| 469 Hide(0); | |
| 470 Show(1); | |
| 471 | |
| 472 // Load and paint the restored tab (now the background tab). Don't expect | |
| 473 // any calls to the mock as a visible tab paint has not yet been observed. | |
| 474 Tick(); // 1ms. | |
| 475 GenerateRenderWidgetHostDidUpdateBackingStore(0); | |
| 476 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 477 Tick(); // 2ms. | |
| 478 GenerateLoadStop(0); | |
| 479 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 480 | |
| 481 // Mark the new foreground tab as having painted. This should cause the | |
| 482 // stats to be emitted, but with empty foreground paint and load values. | |
| 483 Tick(); // 3ms. | |
| 484 GenerateRenderWidgetHostDidUpdateBackingStore(1); | |
| 485 mock_reporting_delegate.ExpectReportTabLoaderStatsCalled(1, 1, 0, 0, 2, 1); | |
| 486 mock_reporting_delegate.ExpectReportStatsCollectorDeathCalled(); | |
| 487 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 488 } | |
| 489 | |
| 490 TEST_F(SessionRestoreStatsCollectorTest, FocusSwitchNoForegroundPaint) { | |
| 491 MockStatsReportingDelegate mock_reporting_delegate; | |
| 492 passthrough_reporting_delegate_->set_reporting_delegate( | |
| 493 &mock_reporting_delegate); | |
| 494 | |
| 495 CreateRestoredTab(true); | |
| 496 stats_collector_->TrackTabs(restored_tabs_); | |
| 497 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 498 | |
| 499 // Load the foreground tab. | |
| 500 Tick(); // 1ms. | |
| 501 GenerateLoadStop(0); | |
| 502 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 503 | |
| 504 // Create another tab and make it the foreground tab. This tab is not actually | |
| 505 // being tracked by the SessionRestoreStatsCollector, but its paint events | |
| 506 // will still be observed. | |
| 507 CreateRestoredTab(false); | |
| 508 Hide(0); | |
| 509 Show(1); | |
| 510 | |
| 511 // Load and paint the restored tab (now the background tab). Don't expect | |
| 512 // any calls to the mock as a visible tab paint has not yet been observed. | |
| 513 Tick(); // 2ms. | |
| 514 GenerateRenderWidgetHostDidUpdateBackingStore(0); | |
| 515 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 516 | |
| 517 // Mark the new foreground tab as having painted. This should cause the | |
| 518 // stats to be emitted, but with an empty foreground paint value. | |
| 519 Tick(); // 3ms. | |
| 520 GenerateRenderWidgetHostDidUpdateBackingStore(1); | |
| 521 mock_reporting_delegate.ExpectReportTabLoaderStatsCalled(1, 1, 1, 0, 1, 1); | |
| 522 mock_reporting_delegate.ExpectReportStatsCollectorDeathCalled(); | |
| 523 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 524 } | |
| 525 | |
| 526 TEST_F(SessionRestoreStatsCollectorTest, LoadingTabDestroyedBeforePaint) { | |
| 527 MockStatsReportingDelegate mock_reporting_delegate; | |
| 528 passthrough_reporting_delegate_->set_reporting_delegate( | |
| 529 &mock_reporting_delegate); | |
| 530 | |
| 531 CreateRestoredTab(true); | |
| 532 stats_collector_->TrackTabs(restored_tabs_); | |
| 533 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 534 | |
| 535 // Destroy the tab. Expect all timings to be zero. | |
| 536 GenerateWebContentsDestroyed(0); | |
| 537 mock_reporting_delegate.ExpectReportTabLoaderStatsCalled(1, 0, 0, 0, 0, 1); | |
| 538 mock_reporting_delegate.ExpectReportStatsCollectorDeathCalled(); | |
| 539 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 540 } | |
| 541 | |
| 542 TEST_F(SessionRestoreStatsCollectorTest, LoadingTabDestroyedAfterPaint) { | |
| 543 MockStatsReportingDelegate mock_reporting_delegate; | |
| 544 passthrough_reporting_delegate_->set_reporting_delegate( | |
| 545 &mock_reporting_delegate); | |
| 546 | |
| 547 CreateRestoredTab(true); | |
| 548 stats_collector_->TrackTabs(restored_tabs_); | |
| 549 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 550 | |
| 551 Tick(); // 1 ms. | |
| 552 GenerateRenderWidgetHostDidUpdateBackingStore(0); | |
| 553 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 554 | |
| 555 // Destroy the tab. Expect both load timings to be zero. | |
| 556 GenerateWebContentsDestroyed(0); | |
| 557 mock_reporting_delegate.ExpectReportTabLoaderStatsCalled(1, 0, 0, 1, 0, 1); | |
| 558 mock_reporting_delegate.ExpectReportStatsCollectorDeathCalled(); | |
| 559 mock_reporting_delegate.EnsureNoUnexpectedCalls(); | |
| 560 } | |
| OLD | NEW |