minimal_browser_persister_browsertest.cc 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  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 "base/memory/raw_ptr.h"
  5. #include "build/build_config.h"
  6. #include "content/public/browser/navigation_controller.h"
  7. #include "content/public/browser/navigation_entry.h"
  8. #include "content/public/browser/web_contents.h"
  9. #include "content/public/test/browser_test_utils.h"
  10. #include "net/base/filename_util.h"
  11. #include "net/test/embedded_test_server/embedded_test_server.h"
  12. #include "third_party/blink/public/common/features.h"
  13. #include "weblayer/browser/browser_impl.h"
  14. #include "weblayer/browser/persistence/minimal_browser_persister.h"
  15. #include "weblayer/browser/profile_impl.h"
  16. #include "weblayer/browser/tab_impl.h"
  17. #include "weblayer/public/browser_observer.h"
  18. #include "weblayer/public/navigation.h"
  19. #include "weblayer/public/navigation_controller.h"
  20. #include "weblayer/public/tab.h"
  21. #include "weblayer/shell/browser/shell.h"
  22. #include "weblayer/test/test_navigation_observer.h"
  23. #include "weblayer/test/weblayer_browser_test.h"
  24. #include "weblayer/test/weblayer_browser_test_utils.h"
  25. namespace weblayer {
  26. class MinimalBrowserPersisterTest : public WebLayerBrowserTest,
  27. public BrowserObserver {
  28. public:
  29. MinimalBrowserPersisterTest() = default;
  30. ~MinimalBrowserPersisterTest() override = default;
  31. // WebLayerBrowserTest:
  32. void SetUpOnMainThread() override {
  33. WebLayerBrowserTest::SetUpOnMainThread();
  34. ASSERT_TRUE(embedded_test_server()->Start());
  35. browser_ = Browser::Create(GetProfile(), nullptr);
  36. tab_ = static_cast<TabImpl*>(browser_->CreateTab());
  37. browser_->SetActiveTab(tab_);
  38. }
  39. void PostRunTestOnMainThread() override {
  40. tab_ = nullptr;
  41. browser_.reset();
  42. WebLayerBrowserTest::PostRunTestOnMainThread();
  43. }
  44. GURL url1() { return embedded_test_server()->GetURL("/simple_page.html"); }
  45. GURL url2() { return embedded_test_server()->GetURL("/simple_page2.html"); }
  46. // Persists the current state, then recreates the browser. See
  47. // BrowserImpl::GetMinimalPersistenceState() for details on
  48. // |max_size_in_bytes|, 0 means use the default value.
  49. void RecreateBrowserUsingMinimalState(
  50. int max_number_of_navigations_per_tab = 0,
  51. int max_size_in_bytes = 0) {
  52. std::vector<uint8_t> minimal_state =
  53. browser_impl()->GetMinimalPersistenceState(
  54. max_number_of_navigations_per_tab, max_size_in_bytes);
  55. tab_ = nullptr;
  56. got_on_tab_added_ = false;
  57. browser_ = Browser::Create(GetProfile(), nullptr);
  58. browser_->AddObserver(this);
  59. RestoreMinimalStateForBrowser(browser_impl(), minimal_state);
  60. EXPECT_TRUE(got_on_tab_added_);
  61. browser_->RemoveObserver(this);
  62. // There is always at least one tab created (even if restore fails).
  63. ASSERT_GE(browser_->GetTabs().size(), 1u);
  64. tab_ = static_cast<TabImpl*>(browser_->GetTabs()[0]);
  65. }
  66. // BrowserObserver:
  67. void OnTabAdded(Tab* tab) override {
  68. got_on_tab_added_ = true;
  69. EXPECT_TRUE(browser_->IsRestoringPreviousState());
  70. }
  71. protected:
  72. BrowserImpl* browser_impl() {
  73. return static_cast<BrowserImpl*>(browser_.get());
  74. }
  75. bool got_on_tab_added_ = false;
  76. std::unique_ptr<Browser> browser_;
  77. raw_ptr<TabImpl> tab_ = nullptr;
  78. };
  79. IN_PROC_BROWSER_TEST_F(MinimalBrowserPersisterTest, SingleTab) {
  80. NavigateAndWaitForCompletion(url1(), tab_);
  81. ASSERT_NO_FATAL_FAILURE(RecreateBrowserUsingMinimalState());
  82. EXPECT_EQ(tab_, browser_->GetActiveTab());
  83. TestNavigationObserver observer(
  84. url1(), TestNavigationObserver::NavigationEvent::kCompletion,
  85. browser_->GetActiveTab());
  86. observer.Wait();
  87. EXPECT_EQ(1, tab_->GetNavigationController()->GetNavigationListSize());
  88. }
  89. IN_PROC_BROWSER_TEST_F(MinimalBrowserPersisterTest, TwoTabs) {
  90. NavigateAndWaitForCompletion(url1(), tab_);
  91. Tab* tab2 = browser_->CreateTab();
  92. NavigateAndWaitForCompletion(url2(), tab2);
  93. browser_->SetActiveTab(tab2);
  94. // Shutdown the service and run the assertions twice to ensure we handle
  95. // correctly storing state of tabs that need to be reloaded.
  96. for (int i = 0; i < 2; ++i) {
  97. ASSERT_NO_FATAL_FAILURE(RecreateBrowserUsingMinimalState());
  98. tab2 = nullptr;
  99. ASSERT_EQ(2u, browser_->GetTabs().size()) << "iteration " << i;
  100. tab2 = browser_->GetTabs()[1];
  101. EXPECT_EQ(tab2, browser_->GetActiveTab()) << "iteration " << i;
  102. // The first tab shouldn't have loaded yet, as it's not active.
  103. EXPECT_TRUE(tab_->web_contents()->GetController().NeedsReload())
  104. << "iteration " << i;
  105. EXPECT_EQ(1, tab2->GetNavigationController()->GetNavigationListSize())
  106. << "iteration " << i;
  107. TestNavigationObserver observer(
  108. url2(), TestNavigationObserver::NavigationEvent::kCompletion, tab2);
  109. }
  110. }
  111. IN_PROC_BROWSER_TEST_F(MinimalBrowserPersisterTest, PendingSkipped) {
  112. NavigateAndWaitForCompletion(url1(), tab_);
  113. tab_->GetNavigationController()->Navigate(url2());
  114. ASSERT_NO_FATAL_FAILURE(RecreateBrowserUsingMinimalState());
  115. EXPECT_EQ(tab_, browser_->GetActiveTab());
  116. TestNavigationObserver observer(
  117. url1(), TestNavigationObserver::NavigationEvent::kCompletion,
  118. browser_->GetActiveTab());
  119. observer.Wait();
  120. ASSERT_EQ(1, tab_->GetNavigationController()->GetNavigationListSize());
  121. }
  122. IN_PROC_BROWSER_TEST_F(MinimalBrowserPersisterTest, TwoNavs) {
  123. NavigateAndWaitForCompletion(url1(), tab_);
  124. NavigateAndWaitForCompletion(url2(), tab_);
  125. ASSERT_NO_FATAL_FAILURE(RecreateBrowserUsingMinimalState());
  126. TabImpl* restored_tab = tab_;
  127. EXPECT_EQ(restored_tab, browser_->GetActiveTab());
  128. TestNavigationObserver observer(
  129. url2(), TestNavigationObserver::NavigationEvent::kCompletion,
  130. restored_tab);
  131. observer.Wait();
  132. ASSERT_EQ(2,
  133. restored_tab->GetNavigationController()->GetNavigationListSize());
  134. content::NavigationController& nav_controller =
  135. restored_tab->web_contents()->GetController();
  136. EXPECT_EQ(1, nav_controller.GetCurrentEntryIndex());
  137. EXPECT_EQ(url1(), nav_controller.GetEntryAtIndex(0)->GetURL());
  138. EXPECT_EQ(url2(), nav_controller.GetEntryAtIndex(1)->GetURL());
  139. }
  140. IN_PROC_BROWSER_TEST_F(MinimalBrowserPersisterTest, NavigationOverflow) {
  141. NavigateAndWaitForCompletion(url1(), tab_);
  142. NavigateAndWaitForCompletion(url2(), tab_);
  143. const GURL url3 = embedded_test_server()->GetURL("/simple_page3.html");
  144. NavigateAndWaitForCompletion(url3, tab_);
  145. const GURL url4 = embedded_test_server()->GetURL("/simple_page4.html");
  146. NavigateAndWaitForCompletion(url4, tab_);
  147. ASSERT_NO_FATAL_FAILURE(RecreateBrowserUsingMinimalState(3));
  148. // As a max of 3 navigations was specified, only the last three navigations
  149. // should be restored.
  150. TabImpl* restored_tab = tab_;
  151. EXPECT_EQ(restored_tab, browser_->GetActiveTab());
  152. TestNavigationObserver observer(
  153. url4, TestNavigationObserver::NavigationEvent::kCompletion, restored_tab);
  154. observer.Wait();
  155. ASSERT_EQ(3,
  156. restored_tab->GetNavigationController()->GetNavigationListSize());
  157. content::NavigationController& nav_controller =
  158. restored_tab->web_contents()->GetController();
  159. EXPECT_EQ(2, nav_controller.GetCurrentEntryIndex());
  160. EXPECT_EQ(url2(), nav_controller.GetEntryAtIndex(0)->GetURL());
  161. EXPECT_EQ(url3, nav_controller.GetEntryAtIndex(1)->GetURL());
  162. EXPECT_EQ(url4, nav_controller.GetEntryAtIndex(2)->GetURL());
  163. }
  164. // crbug.com/1240904: test is flaky on linux and win.
  165. #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN)
  166. #define MAYBE_Overflow DISABLED_Overflow
  167. #else
  168. #define MAYBE_Overflow Overflow
  169. #endif
  170. IN_PROC_BROWSER_TEST_F(MinimalBrowserPersisterTest, MAYBE_Overflow) {
  171. std::string url_string(2048, 'a');
  172. const std::string data = "data:,";
  173. url_string.replace(0, data.size(), data);
  174. NavigateAndWaitForCompletion(GURL(url_string), tab_);
  175. ASSERT_NO_FATAL_FAILURE(RecreateBrowserUsingMinimalState(0, 2048));
  176. TabImpl* restored_tab = tab_;
  177. EXPECT_EQ(restored_tab, browser_->GetActiveTab());
  178. if (blink::features::IsInitialNavigationEntryEnabled()) {
  179. EXPECT_EQ(1, restored_tab->web_contents()->GetController().GetEntryCount());
  180. } else {
  181. EXPECT_EQ(0, restored_tab->web_contents()->GetController().GetEntryCount());
  182. }
  183. EXPECT_TRUE(restored_tab->web_contents()->GetController().GetPendingEntry() ==
  184. nullptr);
  185. }
  186. // Tests that a tab with no committed navigation won't be persisted/restored.
  187. IN_PROC_BROWSER_TEST_F(MinimalBrowserPersisterTest, TabWithNoNavigation) {
  188. std::vector<uint8_t> minimal_state =
  189. browser_impl()->GetMinimalPersistenceState();
  190. got_on_tab_added_ = false;
  191. RestoreMinimalStateForBrowser(browser_impl(), minimal_state);
  192. EXPECT_FALSE(got_on_tab_added_);
  193. }
  194. } // namespace weblayer