| Index: chrome/browser/memory/tab_manager_unittest.cc
|
| diff --git a/chrome/browser/memory/tab_manager_unittest.cc b/chrome/browser/memory/tab_manager_unittest.cc
|
| deleted file mode 100644
|
| index 6cf646f66495148a0ec8e04602a15fa2008ece96..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/memory/tab_manager_unittest.cc
|
| +++ /dev/null
|
| @@ -1,497 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "chrome/browser/memory/tab_manager.h"
|
| -
|
| -#include <algorithm>
|
| -#include <map>
|
| -#include <vector>
|
| -
|
| -#include "base/logging.h"
|
| -#include "base/macros.h"
|
| -#include "base/memory/ptr_util.h"
|
| -#include "base/metrics/field_trial.h"
|
| -#include "base/strings/string16.h"
|
| -#include "base/test/mock_entropy_provider.h"
|
| -#include "base/test/simple_test_tick_clock.h"
|
| -#include "base/time/time.h"
|
| -#include "build/build_config.h"
|
| -#include "chrome/browser/memory/tab_manager_web_contents_data.h"
|
| -#include "chrome/browser/memory/tab_stats.h"
|
| -#include "chrome/browser/profiles/profile.h"
|
| -#include "chrome/browser/ui/tabs/tab_strip_model.h"
|
| -#include "chrome/browser/ui/tabs/test_tab_strip_model_delegate.h"
|
| -#include "chrome/common/chrome_features.h"
|
| -#include "chrome/common/url_constants.h"
|
| -#include "chrome/test/base/chrome_render_view_host_test_harness.h"
|
| -#include "chrome/test/base/testing_profile.h"
|
| -#include "components/variations/variations_associated_data.h"
|
| -#include "content/public/browser/render_process_host.h"
|
| -#include "content/public/browser/web_contents.h"
|
| -#include "content/public/test/mock_render_process_host.h"
|
| -#include "content/public/test/web_contents_tester.h"
|
| -#include "testing/gtest/include/gtest/gtest.h"
|
| -#include "url/gurl.h"
|
| -
|
| -using content::WebContents;
|
| -using content::WebContentsTester;
|
| -
|
| -namespace memory {
|
| -namespace {
|
| -
|
| -class TabStripDummyDelegate : public TestTabStripModelDelegate {
|
| - public:
|
| - TabStripDummyDelegate() {}
|
| -
|
| - bool RunUnloadListenerBeforeClosing(WebContents* contents) override {
|
| - return false;
|
| - }
|
| -
|
| - private:
|
| - DISALLOW_COPY_AND_ASSIGN(TabStripDummyDelegate);
|
| -};
|
| -
|
| -class MockTabStripModelObserver : public TabStripModelObserver {
|
| - public:
|
| - MockTabStripModelObserver()
|
| - : nb_events_(0), old_contents_(nullptr), new_contents_(nullptr) {}
|
| -
|
| - int NbEvents() const { return nb_events_; }
|
| - WebContents* OldContents() const { return old_contents_; }
|
| - WebContents* NewContents() const { return new_contents_; }
|
| -
|
| - void Reset() {
|
| - nb_events_ = 0;
|
| - old_contents_ = nullptr;
|
| - new_contents_ = nullptr;
|
| - }
|
| -
|
| - // TabStripModelObserver implementation:
|
| - void TabReplacedAt(TabStripModel* tab_strip_model,
|
| - WebContents* old_contents,
|
| - WebContents* new_contents,
|
| - int index) override {
|
| - nb_events_++;
|
| - old_contents_ = old_contents;
|
| - new_contents_ = new_contents;
|
| - }
|
| -
|
| - private:
|
| - int nb_events_;
|
| - WebContents* old_contents_;
|
| - WebContents* new_contents_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(MockTabStripModelObserver);
|
| -};
|
| -
|
| -enum TestIndicies {
|
| - kSelected,
|
| - kAutoDiscardable,
|
| - kPinned,
|
| - kApp,
|
| - kPlayingAudio,
|
| - kFormEntry,
|
| - kRecent,
|
| - kOld,
|
| - kReallyOld,
|
| - kOldButPinned,
|
| - kInternalPage,
|
| -};
|
| -
|
| -} // namespace
|
| -
|
| -class TabManagerTest : public ChromeRenderViewHostTestHarness {
|
| - public:
|
| - WebContents* CreateWebContents() {
|
| - return WebContents::Create(WebContents::CreateParams(profile()));
|
| - }
|
| -};
|
| -
|
| -// TODO(georgesak): Add tests for protection to tabs with form input and
|
| -// playing audio;
|
| -
|
| -// Tests the sorting comparator to make sure it's producing the desired order.
|
| -TEST_F(TabManagerTest, Comparator) {
|
| - TabStatsList test_list;
|
| - const base::TimeTicks now = base::TimeTicks::Now();
|
| -
|
| - // Add kSelected last to verify that the array is being sorted.
|
| -
|
| - {
|
| - TabStats stats;
|
| - stats.last_active = now;
|
| - stats.is_pinned = true;
|
| - stats.child_process_host_id = kPinned;
|
| - test_list.push_back(stats);
|
| - }
|
| -
|
| - {
|
| - TabStats stats;
|
| - stats.last_active = now;
|
| - stats.is_app = true;
|
| - stats.child_process_host_id = kApp;
|
| - test_list.push_back(stats);
|
| - }
|
| -
|
| - {
|
| - TabStats stats;
|
| - stats.last_active = now;
|
| - stats.is_media = true;
|
| - stats.child_process_host_id = kPlayingAudio;
|
| - test_list.push_back(stats);
|
| - }
|
| -
|
| - {
|
| - TabStats stats;
|
| - stats.last_active = now;
|
| - stats.has_form_entry = true;
|
| - stats.child_process_host_id = kFormEntry;
|
| - test_list.push_back(stats);
|
| - }
|
| -
|
| - {
|
| - TabStats stats;
|
| - stats.last_active = now - base::TimeDelta::FromSeconds(10);
|
| - stats.child_process_host_id = kRecent;
|
| - test_list.push_back(stats);
|
| - }
|
| -
|
| - {
|
| - TabStats stats;
|
| - stats.last_active = now - base::TimeDelta::FromMinutes(15);
|
| - stats.child_process_host_id = kOld;
|
| - test_list.push_back(stats);
|
| - }
|
| -
|
| - {
|
| - TabStats stats;
|
| - stats.last_active = now - base::TimeDelta::FromDays(365);
|
| - stats.child_process_host_id = kReallyOld;
|
| - test_list.push_back(stats);
|
| - }
|
| -
|
| - {
|
| - TabStats stats;
|
| - stats.is_pinned = true;
|
| - stats.last_active = now - base::TimeDelta::FromDays(365);
|
| - stats.child_process_host_id = kOldButPinned;
|
| - test_list.push_back(stats);
|
| - }
|
| -
|
| - {
|
| - TabStats stats;
|
| - stats.last_active = now;
|
| - stats.is_internal_page = true;
|
| - stats.child_process_host_id = kInternalPage;
|
| - test_list.push_back(stats);
|
| - }
|
| -
|
| - {
|
| - TabStats stats;
|
| - stats.last_active = now;
|
| - stats.is_auto_discardable = false;
|
| - stats.child_process_host_id = kAutoDiscardable;
|
| - test_list.push_back(stats);
|
| - }
|
| -
|
| - // This entry sorts to the front, so by adding it last, it verifies that the
|
| - // array is being sorted.
|
| - {
|
| - TabStats stats;
|
| - stats.last_active = now;
|
| - stats.is_selected = true;
|
| - stats.child_process_host_id = kSelected;
|
| - test_list.push_back(stats);
|
| - }
|
| -
|
| - std::sort(test_list.begin(), test_list.end(), TabManager::CompareTabStats);
|
| -
|
| - int index = 0;
|
| - EXPECT_EQ(kSelected, test_list[index++].child_process_host_id);
|
| - EXPECT_EQ(kAutoDiscardable, test_list[index++].child_process_host_id);
|
| - EXPECT_EQ(kFormEntry, test_list[index++].child_process_host_id);
|
| - EXPECT_EQ(kPlayingAudio, test_list[index++].child_process_host_id);
|
| - EXPECT_EQ(kPinned, test_list[index++].child_process_host_id);
|
| - EXPECT_EQ(kOldButPinned, test_list[index++].child_process_host_id);
|
| - EXPECT_EQ(kApp, test_list[index++].child_process_host_id);
|
| - EXPECT_EQ(kRecent, test_list[index++].child_process_host_id);
|
| - EXPECT_EQ(kOld, test_list[index++].child_process_host_id);
|
| - EXPECT_EQ(kReallyOld, test_list[index++].child_process_host_id);
|
| - EXPECT_EQ(kInternalPage, test_list[index++].child_process_host_id);
|
| -}
|
| -
|
| -TEST_F(TabManagerTest, IsInternalPage) {
|
| - EXPECT_TRUE(TabManager::IsInternalPage(GURL(chrome::kChromeUIDownloadsURL)));
|
| - EXPECT_TRUE(TabManager::IsInternalPage(GURL(chrome::kChromeUIHistoryURL)));
|
| - EXPECT_TRUE(TabManager::IsInternalPage(GURL(chrome::kChromeUINewTabURL)));
|
| - EXPECT_TRUE(TabManager::IsInternalPage(GURL(chrome::kChromeUISettingsURL)));
|
| -
|
| -// Debugging URLs are not included.
|
| -#if defined(OS_CHROMEOS)
|
| - EXPECT_FALSE(TabManager::IsInternalPage(GURL(chrome::kChromeUIDiscardsURL)));
|
| -#endif
|
| - EXPECT_FALSE(
|
| - TabManager::IsInternalPage(GURL(chrome::kChromeUINetInternalsURL)));
|
| -
|
| - // Prefix matches are included.
|
| - EXPECT_TRUE(
|
| - TabManager::IsInternalPage(GURL("chrome://settings/fakeSetting")));
|
| -}
|
| -
|
| -// Ensures discarding tabs leaves TabStripModel in a good state.
|
| -TEST_F(TabManagerTest, DiscardWebContentsAt) {
|
| - TabManager tab_manager;
|
| -
|
| - TabStripDummyDelegate delegate;
|
| - TabStripModel tabstrip(&delegate, profile());
|
| - tabstrip.AddObserver(&tab_manager);
|
| -
|
| - // Fill it with some tabs.
|
| - WebContents* contents1 = CreateWebContents();
|
| - tabstrip.AppendWebContents(contents1, true);
|
| - WebContents* contents2 = CreateWebContents();
|
| - tabstrip.AppendWebContents(contents2, true);
|
| -
|
| - // Start watching for events after the appends to avoid observing state
|
| - // transitions that aren't relevant to this test.
|
| - MockTabStripModelObserver tabstrip_observer;
|
| - tabstrip.AddObserver(&tabstrip_observer);
|
| -
|
| - // Discard one of the tabs.
|
| - WebContents* null_contents1 = tab_manager.DiscardWebContentsAt(0, &tabstrip);
|
| - ASSERT_EQ(2, tabstrip.count());
|
| - EXPECT_TRUE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(0)));
|
| - EXPECT_FALSE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(1)));
|
| - ASSERT_EQ(null_contents1, tabstrip.GetWebContentsAt(0));
|
| - ASSERT_EQ(contents2, tabstrip.GetWebContentsAt(1));
|
| - ASSERT_EQ(1, tabstrip_observer.NbEvents());
|
| - EXPECT_EQ(contents1, tabstrip_observer.OldContents());
|
| - EXPECT_EQ(null_contents1, tabstrip_observer.NewContents());
|
| - tabstrip_observer.Reset();
|
| -
|
| - // Discard the same tab again, after resetting its discard state.
|
| - tab_manager.GetWebContentsData(tabstrip.GetWebContentsAt(0))
|
| - ->SetDiscardState(false);
|
| - WebContents* null_contents2 = tab_manager.DiscardWebContentsAt(0, &tabstrip);
|
| - ASSERT_EQ(2, tabstrip.count());
|
| - EXPECT_TRUE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(0)));
|
| - EXPECT_FALSE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(1)));
|
| - ASSERT_EQ(null_contents2, tabstrip.GetWebContentsAt(0));
|
| - ASSERT_EQ(contents2, tabstrip.GetWebContentsAt(1));
|
| - ASSERT_EQ(1, tabstrip_observer.NbEvents());
|
| - EXPECT_EQ(null_contents1, tabstrip_observer.OldContents());
|
| - EXPECT_EQ(null_contents2, tabstrip_observer.NewContents());
|
| -
|
| - // Activating the tab should clear its discard state.
|
| - tabstrip.ActivateTabAt(0, true /* user_gesture */);
|
| - ASSERT_EQ(2, tabstrip.count());
|
| - EXPECT_FALSE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(0)));
|
| - EXPECT_FALSE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(1)));
|
| -
|
| - // Don't discard active tab.
|
| - tab_manager.DiscardWebContentsAt(0, &tabstrip);
|
| - ASSERT_EQ(2, tabstrip.count());
|
| - EXPECT_FALSE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(0)));
|
| - EXPECT_FALSE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(1)));
|
| -
|
| - tabstrip.CloseAllTabs();
|
| - EXPECT_TRUE(tabstrip.empty());
|
| -}
|
| -
|
| -// Makes sure that reloading a discarded tab without activating it unmarks the
|
| -// tab as discarded so it won't reload on activation.
|
| -TEST_F(TabManagerTest, ReloadDiscardedTabContextMenu) {
|
| - // Note that we do not add |tab_manager| as an observer to |tabstrip| here as
|
| - // the event we are trying to test for is not related to the tab strip, but
|
| - // the web content instead and therefore should be handled by WebContentsData
|
| - // (which observes the web content).
|
| - TabManager tab_manager;
|
| - TabStripDummyDelegate delegate;
|
| - TabStripModel tabstrip(&delegate, profile());
|
| -
|
| - // Create 2 tabs because the active tab cannot be discarded.
|
| - tabstrip.AppendWebContents(CreateWebContents(), true);
|
| - content::WebContents* test_contents =
|
| - WebContentsTester::CreateTestWebContents(browser_context(), nullptr);
|
| - tabstrip.AppendWebContents(test_contents, false); // Opened in background.
|
| -
|
| - // Navigate to a web page. This is necessary to set a current entry in memory
|
| - // so the reload can happen.
|
| - WebContentsTester::For(test_contents)
|
| - ->NavigateAndCommit(GURL("chrome://newtab"));
|
| - EXPECT_FALSE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(1)));
|
| -
|
| - tab_manager.DiscardWebContentsAt(1, &tabstrip);
|
| - EXPECT_TRUE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(1)));
|
| -
|
| - tabstrip.GetWebContentsAt(1)->GetController().Reload(
|
| - content::ReloadType::NORMAL, false);
|
| - EXPECT_FALSE(tab_manager.IsTabDiscarded(tabstrip.GetWebContentsAt(1)));
|
| - tabstrip.CloseAllTabs();
|
| - EXPECT_TRUE(tabstrip.empty());
|
| -}
|
| -
|
| -// Makes sure that the last active time property is saved even though the tab is
|
| -// discarded.
|
| -TEST_F(TabManagerTest, DiscardedTabKeepsLastActiveTime) {
|
| - TabManager tab_manager;
|
| - TabStripDummyDelegate delegate;
|
| - TabStripModel tabstrip(&delegate, profile());
|
| - tabstrip.AddObserver(&tab_manager);
|
| -
|
| - tabstrip.AppendWebContents(CreateWebContents(), true);
|
| - WebContents* test_contents = CreateWebContents();
|
| - tabstrip.AppendWebContents(test_contents, false);
|
| -
|
| - // Simulate an old inactive tab about to get discarded.
|
| - base::TimeTicks new_last_active_time =
|
| - base::TimeTicks::Now() - base::TimeDelta::FromMinutes(35);
|
| - test_contents->SetLastActiveTime(new_last_active_time);
|
| - EXPECT_EQ(new_last_active_time, test_contents->GetLastActiveTime());
|
| -
|
| - WebContents* null_contents = tab_manager.DiscardWebContentsAt(1, &tabstrip);
|
| - EXPECT_EQ(new_last_active_time, null_contents->GetLastActiveTime());
|
| -
|
| - tabstrip.CloseAllTabs();
|
| - EXPECT_TRUE(tabstrip.empty());
|
| -}
|
| -
|
| -// Test to see if a tab can only be discarded once. On Windows and Mac, this
|
| -// defaults to true unless overridden through a variation parameter. On other
|
| -// platforms, it's always false.
|
| -#if defined(OS_WIN) || defined(OS_MACOSX)
|
| -TEST_F(TabManagerTest, CanOnlyDiscardOnce) {
|
| - TabManager tab_manager;
|
| - const std::string kTrialName = features::kAutomaticTabDiscarding.name;
|
| -
|
| - // Not setting the variation parameter.
|
| - {
|
| - bool discard_once_value = tab_manager.CanOnlyDiscardOnce();
|
| - EXPECT_TRUE(discard_once_value);
|
| - }
|
| -
|
| - // Setting the variation parameter to true.
|
| - {
|
| - std::unique_ptr<base::FieldTrialList> field_trial_list_;
|
| - field_trial_list_.reset(
|
| - new base::FieldTrialList(
|
| - base::MakeUnique<base::MockEntropyProvider>()));
|
| - variations::testing::ClearAllVariationParams();
|
| -
|
| - std::map<std::string, std::string> params;
|
| - params["AllowMultipleDiscards"] = "true";
|
| - ASSERT_TRUE(variations::AssociateVariationParams(kTrialName, "A", params));
|
| - base::FieldTrialList::CreateFieldTrial(kTrialName, "A");
|
| -
|
| - bool discard_once_value = tab_manager.CanOnlyDiscardOnce();
|
| - EXPECT_FALSE(discard_once_value);
|
| - }
|
| -
|
| - // Setting the variation parameter to something else.
|
| - {
|
| - std::unique_ptr<base::FieldTrialList> field_trial_list_;
|
| - field_trial_list_.reset(
|
| - new base::FieldTrialList(
|
| - base::MakeUnique<base::MockEntropyProvider>()));
|
| - variations::testing::ClearAllVariationParams();
|
| -
|
| - std::map<std::string, std::string> params;
|
| - params["AllowMultipleDiscards"] = "somethingElse";
|
| - ASSERT_TRUE(variations::AssociateVariationParams(kTrialName, "B", params));
|
| - base::FieldTrialList::CreateFieldTrial(kTrialName, "B");
|
| -
|
| - bool discard_once_value = tab_manager.CanOnlyDiscardOnce();
|
| - EXPECT_TRUE(discard_once_value);
|
| - }
|
| -}
|
| -#else
|
| -TEST_F(TabManagerTest, CanOnlyDiscardOnce) {
|
| - TabManager tab_manager;
|
| -
|
| - bool discard_once_value = tab_manager.CanOnlyDiscardOnce();
|
| - EXPECT_FALSE(discard_once_value);
|
| -}
|
| -#endif // defined(OS_WIN) || defined(OS_MACOSX)
|
| -
|
| -TEST_F(TabManagerTest, DefaultTimeToPurgeInCorrectRange) {
|
| - TabManager tab_manager;
|
| - base::TimeDelta time_to_purge =
|
| - tab_manager.GetTimeToPurge(TabManager::kDefaultMinTimeToPurge);
|
| - EXPECT_GE(time_to_purge, base::TimeDelta::FromMinutes(30));
|
| - EXPECT_LT(time_to_purge, base::TimeDelta::FromMinutes(60));
|
| -}
|
| -
|
| -TEST_F(TabManagerTest, ShouldPurgeAtDefaultTime) {
|
| - TabManager tab_manager;
|
| - TabStripDummyDelegate delegate;
|
| - TabStripModel tabstrip(&delegate, profile());
|
| - tabstrip.AddObserver(&tab_manager);
|
| -
|
| - WebContents* test_contents = CreateWebContents();
|
| - tabstrip.AppendWebContents(test_contents, false);
|
| -
|
| - base::SimpleTestTickClock test_clock;
|
| - tab_manager.set_test_tick_clock(&test_clock);
|
| -
|
| - tab_manager.GetWebContentsData(test_contents)->set_is_purged(false);
|
| - tab_manager.GetWebContentsData(test_contents)
|
| - ->SetLastInactiveTime(test_clock.NowTicks());
|
| - tab_manager.GetWebContentsData(test_contents)
|
| - ->set_time_to_purge(base::TimeDelta::FromMinutes(1));
|
| -
|
| - // Wait 1 minute and verify that the tab is still not to be purged.
|
| - test_clock.Advance(base::TimeDelta::FromMinutes(1));
|
| - EXPECT_FALSE(tab_manager.ShouldPurgeNow(test_contents));
|
| -
|
| - // Wait another 1 second and verify that it should be purged now .
|
| - test_clock.Advance(base::TimeDelta::FromSeconds(1));
|
| - EXPECT_TRUE(tab_manager.ShouldPurgeNow(test_contents));
|
| -
|
| - tab_manager.GetWebContentsData(test_contents)->set_is_purged(true);
|
| - tab_manager.GetWebContentsData(test_contents)
|
| - ->SetLastInactiveTime(test_clock.NowTicks());
|
| -
|
| - // Wait 1 day and verify that the tab is still be purged.
|
| - test_clock.Advance(base::TimeDelta::FromHours(24));
|
| - EXPECT_FALSE(tab_manager.ShouldPurgeNow(test_contents));
|
| -}
|
| -
|
| -TEST_F(TabManagerTest, ActivateTabResetPurgeState) {
|
| - TabManager tab_manager;
|
| - TabStripDummyDelegate delegate;
|
| - TabStripModel tabstrip(&delegate, profile());
|
| - tabstrip.AddObserver(&tab_manager);
|
| - tab_manager.test_tab_strip_models_.push_back(
|
| - TabManager::TestTabStripModel(&tabstrip, false /* !is_app */));
|
| -
|
| - base::SimpleTestTickClock test_clock;
|
| - tab_manager.set_test_tick_clock(&test_clock);
|
| -
|
| - WebContents* tab1 = CreateWebContents();
|
| - WebContents* tab2 = CreateWebContents();
|
| - tabstrip.AppendWebContents(tab1, true);
|
| - tabstrip.AppendWebContents(tab2, false);
|
| -
|
| - tab_manager.GetWebContentsData(tab2)->SetLastInactiveTime(
|
| - test_clock.NowTicks());
|
| - static_cast<content::MockRenderProcessHost*>(tab2->GetRenderProcessHost())
|
| - ->set_is_process_backgrounded(true);
|
| - EXPECT_TRUE(tab2->GetRenderProcessHost()->IsProcessBackgrounded());
|
| -
|
| - // Initially PurgeAndSuspend state should be NOT_PURGED.
|
| - EXPECT_FALSE(tab_manager.GetWebContentsData(tab2)->is_purged());
|
| - tab_manager.GetWebContentsData(tab2)->set_time_to_purge(
|
| - base::TimeDelta::FromMinutes(1));
|
| - test_clock.Advance(base::TimeDelta::FromMinutes(2));
|
| - tab_manager.PurgeBackgroundedTabsIfNeeded();
|
| - // Since tab2 is kept inactive and background for more than time-to-purge,
|
| - // tab2 should be purged.
|
| - EXPECT_TRUE(tab_manager.GetWebContentsData(tab2)->is_purged());
|
| -
|
| - // Activate tab2. Tab2's PurgeAndSuspend state should be NOT_PURGED.
|
| - tabstrip.ActivateTabAt(1, true /* user_gesture */);
|
| - EXPECT_FALSE(tab_manager.GetWebContentsData(tab2)->is_purged());
|
| -}
|
| -
|
| -} // namespace memory
|
|
|