browser_persister_browsertest.cc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  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 "weblayer/browser/persistence/browser_persister.h"
  5. #include "base/callback_helpers.h"
  6. #include "base/files/file_path.h"
  7. #include "base/files/file_util.h"
  8. #include "base/guid.h"
  9. #include "base/memory/raw_ptr.h"
  10. #include "base/path_service.h"
  11. #include "base/run_loop.h"
  12. #include "base/test/bind.h"
  13. #include "base/threading/thread_restrictions.h"
  14. #include "build/build_config.h"
  15. #include "components/sessions/core/command_storage_backend.h"
  16. #include "components/sessions/core/command_storage_manager_test_helper.h"
  17. #include "components/sessions/core/session_constants.h"
  18. #include "content/public/test/browser_test_utils.h"
  19. #include "content/public/test/url_loader_interceptor.h"
  20. #include "net/base/filename_util.h"
  21. #include "net/test/embedded_test_server/embedded_test_server.h"
  22. #include "testing/gmock/include/gmock/gmock.h"
  23. #include "weblayer/browser/browser_impl.h"
  24. #include "weblayer/browser/persistence/browser_persister_file_utils.h"
  25. #include "weblayer/browser/profile_impl.h"
  26. #include "weblayer/browser/tab_impl.h"
  27. #include "weblayer/common/weblayer_paths.h"
  28. #include "weblayer/public/browser_restore_observer.h"
  29. #include "weblayer/public/navigation.h"
  30. #include "weblayer/public/navigation_controller.h"
  31. #include "weblayer/public/navigation_observer.h"
  32. #include "weblayer/public/tab.h"
  33. #include "weblayer/shell/browser/shell.h"
  34. #include "weblayer/test/interstitial_utils.h"
  35. #include "weblayer/test/test_navigation_observer.h"
  36. #include "weblayer/test/weblayer_browser_test.h"
  37. #include "weblayer/test/weblayer_browser_test_utils.h"
  38. namespace weblayer {
  39. class BrowserPersisterTestHelper {
  40. public:
  41. static sessions::CommandStorageManager* GetCommandStorageManager(
  42. BrowserPersister* persister) {
  43. return persister->command_storage_manager_.get();
  44. }
  45. };
  46. namespace {
  47. using testing::UnorderedElementsAre;
  48. class BrowserNavigationObserverImpl : public BrowserRestoreObserver,
  49. public NavigationObserver {
  50. public:
  51. static void WaitForNewTabToCompleteNavigation(Browser* browser,
  52. const GURL& url,
  53. size_t tab_to_wait_for = 0) {
  54. BrowserNavigationObserverImpl observer(browser, url, tab_to_wait_for);
  55. observer.Wait();
  56. }
  57. private:
  58. BrowserNavigationObserverImpl(Browser* browser,
  59. const GURL& url,
  60. size_t tab_to_wait_for)
  61. : browser_(browser), url_(url), tab_to_wait_for_(tab_to_wait_for) {
  62. browser_->AddBrowserRestoreObserver(this);
  63. }
  64. ~BrowserNavigationObserverImpl() override {
  65. tab_->GetNavigationController()->RemoveObserver(this);
  66. }
  67. void Wait() { run_loop_.Run(); }
  68. // NavigationObserver;
  69. void NavigationCompleted(Navigation* navigation) override {
  70. if (navigation->GetURL() == url_)
  71. run_loop_.Quit();
  72. }
  73. // BrowserRestoreObserver:
  74. void OnRestoreCompleted() override {
  75. browser_->RemoveBrowserRestoreObserver(this);
  76. ASSERT_LT(tab_to_wait_for_, browser_->GetTabs().size());
  77. ASSERT_EQ(nullptr, tab_.get());
  78. tab_ = browser_->GetTabs()[tab_to_wait_for_];
  79. tab_->GetNavigationController()->AddObserver(this);
  80. }
  81. raw_ptr<Browser> browser_;
  82. const GURL& url_;
  83. raw_ptr<Tab> tab_ = nullptr;
  84. const size_t tab_to_wait_for_;
  85. std::unique_ptr<TestNavigationObserver> navigation_observer_;
  86. base::RunLoop run_loop_;
  87. };
  88. void ShutdownBrowserPersisterAndWait(BrowserImpl* browser) {
  89. auto task_runner = sessions::CommandStorageManagerTestHelper(
  90. BrowserPersisterTestHelper::GetCommandStorageManager(
  91. browser->browser_persister()))
  92. .GetBackendTaskRunner();
  93. browser->PrepareForShutdown();
  94. base::RunLoop run_loop;
  95. task_runner->PostTaskAndReply(FROM_HERE, base::DoNothing(),
  96. run_loop.QuitClosure());
  97. run_loop.Run();
  98. }
  99. std::unique_ptr<BrowserImpl> CreateBrowser(ProfileImpl* profile,
  100. const std::string& persistence_id) {
  101. Browser::PersistenceInfo info;
  102. info.id = persistence_id;
  103. auto browser = Browser::Create(profile, &info);
  104. return std::unique_ptr<BrowserImpl>(
  105. static_cast<BrowserImpl*>(browser.release()));
  106. }
  107. } // namespace
  108. using BrowserPersisterTest = WebLayerBrowserTest;
  109. IN_PROC_BROWSER_TEST_F(BrowserPersisterTest, SingleTab) {
  110. ASSERT_TRUE(embedded_test_server()->Start());
  111. std::unique_ptr<BrowserImpl> browser = CreateBrowser(GetProfile(), "x");
  112. Tab* tab = browser->CreateTab();
  113. EXPECT_TRUE(browser->IsRestoringPreviousState());
  114. const GURL url = embedded_test_server()->GetURL("/simple_page.html");
  115. NavigateAndWaitForCompletion(url, tab);
  116. ShutdownBrowserPersisterAndWait(browser.get());
  117. tab = nullptr;
  118. browser.reset();
  119. browser = CreateBrowser(GetProfile(), "x");
  120. // Should be no tabs while waiting for restore.
  121. EXPECT_TRUE(browser->GetTabs().empty());
  122. EXPECT_TRUE(browser->IsRestoringPreviousState());
  123. // Wait for the restore and navigation to complete.
  124. BrowserNavigationObserverImpl::WaitForNewTabToCompleteNavigation(
  125. browser.get(), url);
  126. ASSERT_EQ(1u, browser->GetTabs().size());
  127. EXPECT_EQ(browser->GetTabs()[0], browser->GetActiveTab());
  128. EXPECT_EQ(1, browser->GetTabs()[0]
  129. ->GetNavigationController()
  130. ->GetNavigationListSize());
  131. EXPECT_FALSE(browser->IsRestoringPreviousState());
  132. }
  133. IN_PROC_BROWSER_TEST_F(BrowserPersisterTest, RestoresGuid) {
  134. ASSERT_TRUE(embedded_test_server()->Start());
  135. std::unique_ptr<BrowserImpl> browser = CreateBrowser(GetProfile(), "x");
  136. Tab* tab = browser->CreateTab();
  137. const std::string original_guid = tab->GetGuid();
  138. EXPECT_FALSE(original_guid.empty());
  139. EXPECT_TRUE(base::IsValidGUID(original_guid));
  140. const GURL url = embedded_test_server()->GetURL("/simple_page.html");
  141. NavigateAndWaitForCompletion(url, tab);
  142. ShutdownBrowserPersisterAndWait(browser.get());
  143. tab = nullptr;
  144. browser.reset();
  145. browser = CreateBrowser(GetProfile(), "x");
  146. // Should be no tabs while waiting for restore.
  147. EXPECT_TRUE(browser->GetTabs().empty());
  148. // Wait for the restore and navigation to complete.
  149. BrowserNavigationObserverImpl::WaitForNewTabToCompleteNavigation(
  150. browser.get(), url);
  151. ASSERT_EQ(1u, browser->GetTabs().size());
  152. EXPECT_EQ(browser->GetTabs()[0], browser->GetActiveTab());
  153. EXPECT_EQ(original_guid, browser->GetTabs()[0]->GetGuid());
  154. }
  155. IN_PROC_BROWSER_TEST_F(BrowserPersisterTest, RestoresData) {
  156. ASSERT_TRUE(embedded_test_server()->Start());
  157. std::unique_ptr<BrowserImpl> browser = CreateBrowser(GetProfile(), "x");
  158. Tab* tab = browser->CreateTab();
  159. tab->SetData({{"abc", "efg"}});
  160. const GURL url = embedded_test_server()->GetURL("/simple_page.html");
  161. NavigateAndWaitForCompletion(url, tab);
  162. ShutdownBrowserPersisterAndWait(browser.get());
  163. tab = nullptr;
  164. browser.reset();
  165. browser = CreateBrowser(GetProfile(), "x");
  166. // Should be no tabs while waiting for restore.
  167. EXPECT_TRUE(browser->GetTabs().empty());
  168. // Wait for the restore and navigation to complete.
  169. BrowserNavigationObserverImpl::WaitForNewTabToCompleteNavigation(
  170. browser.get(), url);
  171. ASSERT_EQ(1u, browser->GetTabs().size());
  172. EXPECT_EQ(browser->GetTabs()[0], browser->GetActiveTab());
  173. EXPECT_THAT(browser->GetTabs()[0]->GetData(),
  174. UnorderedElementsAre(std::make_pair("abc", "efg")));
  175. }
  176. IN_PROC_BROWSER_TEST_F(BrowserPersisterTest, RestoresMostRecentData) {
  177. ASSERT_TRUE(embedded_test_server()->Start());
  178. std::unique_ptr<BrowserImpl> browser = CreateBrowser(GetProfile(), "x");
  179. Tab* tab = browser->CreateTab();
  180. tab->SetData({{"xxx", "xxx"}});
  181. const GURL url = embedded_test_server()->GetURL("/simple_page.html");
  182. NavigateAndWaitForCompletion(url, tab);
  183. // Make sure the data has been saved, then set different data on the tab.
  184. BrowserPersisterTestHelper::GetCommandStorageManager(
  185. browser->browser_persister())
  186. ->Save();
  187. tab->SetData({{"abc", "efg"}});
  188. ShutdownBrowserPersisterAndWait(browser.get());
  189. tab = nullptr;
  190. browser.reset();
  191. browser = CreateBrowser(GetProfile(), "x");
  192. // Should be no tabs while waiting for restore.
  193. EXPECT_TRUE(browser->GetTabs().empty());
  194. // Wait for the restore and navigation to complete.
  195. BrowserNavigationObserverImpl::WaitForNewTabToCompleteNavigation(
  196. browser.get(), url);
  197. ASSERT_EQ(1u, browser->GetTabs().size());
  198. EXPECT_EQ(browser->GetTabs()[0], browser->GetActiveTab());
  199. EXPECT_THAT(browser->GetTabs()[0]->GetData(),
  200. UnorderedElementsAre(std::make_pair("abc", "efg")));
  201. }
  202. IN_PROC_BROWSER_TEST_F(BrowserPersisterTest, TwoTabs) {
  203. ASSERT_TRUE(embedded_test_server()->Start());
  204. std::unique_ptr<BrowserImpl> browser = CreateBrowser(GetProfile(), "x");
  205. Tab* tab1 = browser->CreateTab();
  206. const GURL url1 = embedded_test_server()->GetURL("/simple_page.html");
  207. NavigateAndWaitForCompletion(url1, tab1);
  208. Tab* tab2 = browser->CreateTab();
  209. const GURL url2 = embedded_test_server()->GetURL("/simple_page2.html");
  210. NavigateAndWaitForCompletion(url2, tab2);
  211. browser->SetActiveTab(tab2);
  212. // Shut down the service.
  213. ShutdownBrowserPersisterAndWait(browser.get());
  214. tab1 = tab2 = nullptr;
  215. browser.reset();
  216. // Recreate the browser and run the assertions twice to ensure we handle
  217. // correctly storing state of tabs that need to be reloaded.
  218. for (int i = 0; i < 2; ++i) {
  219. browser = CreateBrowser(GetProfile(), "x");
  220. // Should be no tabs while waiting for restore.
  221. EXPECT_TRUE(browser->GetTabs().empty()) << "iteration " << i;
  222. // Wait for the restore and navigation to complete. This waits for the
  223. // second tab as that was the active one.
  224. BrowserNavigationObserverImpl::WaitForNewTabToCompleteNavigation(
  225. browser.get(), url2, 1);
  226. ASSERT_EQ(2u, browser->GetTabs().size()) << "iteration " << i;
  227. // The first tab shouldn't have loaded yet, as it's not active.
  228. EXPECT_TRUE(static_cast<TabImpl*>(browser->GetTabs()[0])
  229. ->web_contents()
  230. ->GetController()
  231. .NeedsReload())
  232. << "iteration " << i;
  233. EXPECT_EQ(browser->GetTabs()[1], browser->GetActiveTab())
  234. << "iteration " << i;
  235. EXPECT_EQ(1, browser->GetTabs()[1]
  236. ->GetNavigationController()
  237. ->GetNavigationListSize())
  238. << "iteration " << i;
  239. ShutdownBrowserPersisterAndWait(browser.get());
  240. }
  241. }
  242. IN_PROC_BROWSER_TEST_F(BrowserPersisterTest, MoveBetweenBrowsers) {
  243. ASSERT_TRUE(embedded_test_server()->Start());
  244. // Create a browser with two tabs.
  245. std::unique_ptr<BrowserImpl> browser1 = CreateBrowser(GetProfile(), "x");
  246. Tab* tab1 = browser1->CreateTab();
  247. const GURL url1 = embedded_test_server()->GetURL("/simple_page.html");
  248. NavigateAndWaitForCompletion(url1, tab1);
  249. Tab* tab2 = browser1->CreateTab();
  250. const GURL url2 = embedded_test_server()->GetURL("/simple_page2.html");
  251. NavigateAndWaitForCompletion(url2, tab2);
  252. browser1->SetActiveTab(tab2);
  253. // Create another browser with a single tab.
  254. std::unique_ptr<BrowserImpl> browser2 = CreateBrowser(GetProfile(), "y");
  255. Tab* tab3 = browser2->CreateTab();
  256. const GURL url3 = embedded_test_server()->GetURL("/simple_page3.html");
  257. NavigateAndWaitForCompletion(url3, tab3);
  258. // Move |tab2| to |browser2|.
  259. browser2->AddTab(tab2);
  260. browser2->SetActiveTab(tab2);
  261. ShutdownBrowserPersisterAndWait(browser1.get());
  262. ShutdownBrowserPersisterAndWait(browser2.get());
  263. tab1 = nullptr;
  264. browser1.reset();
  265. tab2 = tab3 = nullptr;
  266. browser2.reset();
  267. // Restore the browsers.
  268. browser1 = CreateBrowser(GetProfile(), "x");
  269. BrowserNavigationObserverImpl::WaitForNewTabToCompleteNavigation(
  270. browser1.get(), url1);
  271. ASSERT_EQ(1u, browser1->GetTabs().size());
  272. EXPECT_EQ(1, browser1->GetTabs()[0]
  273. ->GetNavigationController()
  274. ->GetNavigationListSize());
  275. browser2 = CreateBrowser(GetProfile(), "y");
  276. BrowserNavigationObserverImpl::WaitForNewTabToCompleteNavigation(
  277. browser2.get(), url2, 1);
  278. ASSERT_EQ(2u, browser2->GetTabs().size());
  279. EXPECT_EQ(1, browser2->GetTabs()[1]
  280. ->GetNavigationController()
  281. ->GetNavigationListSize());
  282. // As |tab3| isn't active it needs to be loaded. Force that now.
  283. TabImpl* restored_tab_3 = static_cast<TabImpl*>(browser2->GetTabs()[0]);
  284. EXPECT_TRUE(restored_tab_3->web_contents()->GetController().NeedsReload());
  285. restored_tab_3->web_contents()->GetController().LoadIfNecessary();
  286. EXPECT_TRUE(content::WaitForLoadStop(restored_tab_3->web_contents()));
  287. }
  288. class BrowserPersisterTestWithTwoPersistedIds : public WebLayerBrowserTest {
  289. public:
  290. // WebLayerBrowserTest:
  291. void SetUpOnMainThread() override {
  292. WebLayerBrowserTest::SetUpOnMainThread();
  293. // Configure two browsers with ids 'x' and 'y'.
  294. ASSERT_TRUE(embedded_test_server()->Start());
  295. std::unique_ptr<BrowserImpl> browser1 = CreateBrowser(GetProfile(), "x");
  296. const GURL url1 = embedded_test_server()->GetURL("/simple_page.html");
  297. NavigateAndWaitForCompletion(url1, browser1->CreateTab());
  298. std::unique_ptr<BrowserImpl> browser2 = CreateBrowser(GetProfile(), "y");
  299. const GURL url2 = embedded_test_server()->GetURL("/simple_page3.html");
  300. NavigateAndWaitForCompletion(url2, browser2->CreateTab());
  301. // Shut down the browsers.
  302. ShutdownBrowserPersisterAndWait(browser1.get());
  303. browser1.reset();
  304. ShutdownBrowserPersisterAndWait(browser2.get());
  305. browser2.reset();
  306. }
  307. };
  308. IN_PROC_BROWSER_TEST_F(BrowserPersisterTestWithTwoPersistedIds,
  309. GetBrowserPersistenceIds) {
  310. {
  311. // Create a file that has the name of a valid persistence file, but has
  312. // invalid contents.
  313. base::ScopedAllowBlockingForTesting allow_blocking;
  314. base::WriteFile(BuildBasePathForBrowserPersister(
  315. GetProfile()->GetBrowserPersisterDataBaseDir(), "z"),
  316. "a bogus persistence file");
  317. }
  318. base::RunLoop run_loop;
  319. base::flat_set<std::string> persistence_ids;
  320. GetProfile()->GetBrowserPersistenceIds(
  321. base::BindLambdaForTesting([&](base::flat_set<std::string> ids) {
  322. persistence_ids = std::move(ids);
  323. run_loop.Quit();
  324. }));
  325. run_loop.Run();
  326. ASSERT_EQ(2u, persistence_ids.size());
  327. EXPECT_TRUE(persistence_ids.contains("x"));
  328. EXPECT_TRUE(persistence_ids.contains("y"));
  329. }
  330. bool HasSessionFileStartingWith(const base::FilePath& path) {
  331. auto paths = sessions::CommandStorageBackend::GetSessionFilePaths(
  332. path, sessions::CommandStorageManager::kOther);
  333. return paths.size() == 1;
  334. }
  335. IN_PROC_BROWSER_TEST_F(BrowserPersisterTestWithTwoPersistedIds,
  336. RemoveBrowserPersistenceStorage) {
  337. base::FilePath file_path1 = BuildBasePathForBrowserPersister(
  338. GetProfile()->GetBrowserPersisterDataBaseDir(), "x");
  339. base::FilePath file_path2 = BuildBasePathForBrowserPersister(
  340. GetProfile()->GetBrowserPersisterDataBaseDir(), "y");
  341. {
  342. base::ScopedAllowBlockingForTesting allow_blocking;
  343. ASSERT_TRUE(HasSessionFileStartingWith(file_path1));
  344. ASSERT_TRUE(HasSessionFileStartingWith(file_path2));
  345. }
  346. base::RunLoop run_loop;
  347. base::flat_set<std::string> persistence_ids;
  348. persistence_ids.insert("x");
  349. persistence_ids.insert("y");
  350. GetProfile()->RemoveBrowserPersistenceStorage(
  351. base::BindLambdaForTesting([&](bool result) {
  352. EXPECT_TRUE(result);
  353. run_loop.Quit();
  354. }),
  355. std::move(persistence_ids));
  356. run_loop.Run();
  357. {
  358. base::ScopedAllowBlockingForTesting allow_blocking;
  359. EXPECT_FALSE(base::PathExists(file_path1));
  360. EXPECT_FALSE(base::PathExists(file_path2));
  361. }
  362. }
  363. IN_PROC_BROWSER_TEST_F(BrowserPersisterTest, OnErrorWritingSessionCommands) {
  364. ASSERT_TRUE(embedded_test_server()->Start());
  365. std::unique_ptr<BrowserImpl> browser = CreateBrowser(GetProfile(), "x");
  366. Tab* tab = browser->CreateTab();
  367. EXPECT_TRUE(browser->IsRestoringPreviousState());
  368. const GURL url = embedded_test_server()->GetURL("/simple_page.html");
  369. NavigateAndWaitForCompletion(url, tab);
  370. static_cast<sessions::CommandStorageManagerDelegate*>(
  371. browser->browser_persister())
  372. ->OnErrorWritingSessionCommands();
  373. ShutdownBrowserPersisterAndWait(browser.get());
  374. tab = nullptr;
  375. browser.reset();
  376. browser = CreateBrowser(GetProfile(), "x");
  377. // Should be no tabs while waiting for restore.
  378. EXPECT_TRUE(browser->GetTabs().empty());
  379. EXPECT_TRUE(browser->IsRestoringPreviousState());
  380. // Wait for the restore and navigation to complete.
  381. BrowserNavigationObserverImpl::WaitForNewTabToCompleteNavigation(
  382. browser.get(), url);
  383. ASSERT_EQ(1u, browser->GetTabs().size());
  384. EXPECT_EQ(browser->GetTabs()[0], browser->GetActiveTab());
  385. EXPECT_EQ(1, browser->GetTabs()[0]
  386. ->GetNavigationController()
  387. ->GetNavigationListSize());
  388. EXPECT_FALSE(browser->IsRestoringPreviousState());
  389. }
  390. } // namespace weblayer