| 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
|
| index a3621c1664b72299ee49daa1673b18d42ca76f31..6cf646f66495148a0ec8e04602a15fa2008ece96 100644
|
| --- a/chrome/browser/memory/tab_manager_unittest.cc
|
| +++ b/chrome/browser/memory/tab_manager_unittest.cc
|
| @@ -31,7 +31,6 @@
|
| #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/gmock/include/gmock/gmock.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| #include "url/gurl.h"
|
|
|
| @@ -86,95 +85,6 @@ class MockTabStripModelObserver : public TabStripModelObserver {
|
| DISALLOW_COPY_AND_ASSIGN(MockTabStripModelObserver);
|
| };
|
|
|
| -// A mock task runner. This isn't directly a TaskRunner as the reference
|
| -// counting confuses gmock.
|
| -class LenientMockTaskRunner {
|
| - public:
|
| - LenientMockTaskRunner() {}
|
| - MOCK_METHOD2(PostDelayedTask,
|
| - bool(const tracked_objects::Location&, base::TimeDelta));
|
| -
|
| - private:
|
| - DISALLOW_COPY_AND_ASSIGN(LenientMockTaskRunner);
|
| -};
|
| -using MockTaskRunner = testing::StrictMock<LenientMockTaskRunner>;
|
| -
|
| -// Represents a pending task.
|
| -using Task = std::pair<base::TimeTicks, base::OnceClosure>;
|
| -
|
| -// Comparator used for sorting Task objects. Can't use std::pair's default
|
| -// comparison operators because Closure's are comparable.
|
| -struct TaskComparator {
|
| - bool operator()(const Task& t1, const Task& t2) const {
|
| - // Reverse the sort order so this can be used with a min-heap.
|
| - return t1.first > t2.first;
|
| - }
|
| -};
|
| -
|
| -// A TaskRunner implementation that delegates to a MockTaskRunner for asserting
|
| -// on task insertion order, and which stores tasks for actual later execution.
|
| -class TaskRunnerProxy : public base::TaskRunner {
|
| - public:
|
| - TaskRunnerProxy(MockTaskRunner* mock,
|
| - base::SimpleTestTickClock* clock)
|
| - : mock_(mock), clock_(clock) {}
|
| - bool RunsTasksInCurrentSequence() const override { return true; }
|
| - bool PostDelayedTask(const tracked_objects::Location& location,
|
| - base::OnceClosure closure,
|
| - base::TimeDelta delta) override {
|
| - mock_->PostDelayedTask(location, delta);
|
| - base::TimeTicks when = clock_->NowTicks() + delta;
|
| - tasks_.push_back(Task(when, std::move(closure)));
|
| - // Use 'greater' comparator to make this a min heap.
|
| - std::push_heap(tasks_.begin(), tasks_.end(), TaskComparator());
|
| - return true;
|
| - }
|
| -
|
| - // Runs tasks up to the current time. Returns the number of tasks executed.
|
| - size_t RunTasks() {
|
| - base::TimeTicks now = clock_->NowTicks();
|
| - size_t count = 0;
|
| - while (!tasks_.empty() && tasks_.front().first <= now) {
|
| - std::move(tasks_.front().second).Run();
|
| - std::pop_heap(tasks_.begin(), tasks_.end(), TaskComparator());
|
| - tasks_.pop_back();
|
| - ++count;
|
| - }
|
| - return count;
|
| - }
|
| -
|
| - // Advances the clock and runs the next task in the queue. Can run more than
|
| - // one task if multiple tasks have the same scheduled time.
|
| - size_t RunNextTask() {
|
| - // Get the time of the next task that can possibly run.
|
| - base::TimeTicks when = tasks_.front().first;
|
| -
|
| - // Advance the clock to exactly that time.
|
| - base::TimeTicks now = clock_->NowTicks();
|
| - if (now < when) {
|
| - base::TimeDelta delta = when - now;
|
| - clock_->Advance(delta);
|
| - }
|
| -
|
| - // Run whatever tasks are now eligible to run.
|
| - return RunTasks();
|
| - }
|
| -
|
| - size_t size() const { return tasks_.size(); }
|
| -
|
| - private:
|
| - ~TaskRunnerProxy() override {}
|
| -
|
| - MockTaskRunner* mock_;
|
| - base::SimpleTestTickClock* clock_;
|
| -
|
| - // A min-heap of outstanding tasks.
|
| - using Task = std::pair<base::TimeTicks, base::OnceClosure>;
|
| - std::vector<Task> tasks_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(TaskRunnerProxy);
|
| -};
|
| -
|
| enum TestIndicies {
|
| kSelected,
|
| kAutoDiscardable,
|
| @@ -188,19 +98,15 @@ enum TestIndicies {
|
| kOldButPinned,
|
| kInternalPage,
|
| };
|
| +
|
| } // namespace
|
|
|
| -class LenientTabManagerTest : public ChromeRenderViewHostTestHarness {
|
| +class TabManagerTest : public ChromeRenderViewHostTestHarness {
|
| public:
|
| WebContents* CreateWebContents() {
|
| return WebContents::Create(WebContents::CreateParams(profile()));
|
| }
|
| -
|
| - MOCK_METHOD2(NotifyRendererProcess,
|
| - void(const content::RenderProcessHost*,
|
| - base::MemoryPressureListener::MemoryPressureLevel));
|
| };
|
| -using TabManagerTest = testing::StrictMock<LenientTabManagerTest>;
|
|
|
| // TODO(georgesak): Add tests for protection to tabs with form input and
|
| // playing audio;
|
| @@ -508,168 +414,6 @@ TEST_F(TabManagerTest, CanOnlyDiscardOnce) {
|
| }
|
| #endif // defined(OS_WIN) || defined(OS_MACOSX)
|
|
|
| -namespace {
|
| -
|
| -using MemoryPressureLevel = base::MemoryPressureListener::MemoryPressureLevel;
|
| -
|
| -// Function that always indicates the absence of memory pressure.
|
| -MemoryPressureLevel ReturnNoPressure() {
|
| - return base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
|
| -}
|
| -
|
| -// Function that simply parrots back an externally specified memory pressure
|
| -// level.
|
| -MemoryPressureLevel ReturnSpecifiedPressure(
|
| - const MemoryPressureLevel* level) {
|
| - return *level;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -// ChildProcessNotification is disabled on Chrome OS. crbug.com/588172.
|
| -#if defined(OS_CHROMEOS)
|
| -#define MAYBE_ChildProcessNotifications DISABLED_ChildProcessNotifications
|
| -#else
|
| -#define MAYBE_ChildProcessNotifications ChildProcessNotifications
|
| -#endif
|
| -
|
| -// Ensure that memory pressure notifications are forwarded to child processes.
|
| -TEST_F(TabManagerTest, MAYBE_ChildProcessNotifications) {
|
| - TabManager tm;
|
| -
|
| - // Set up the tab strip.
|
| - TabStripDummyDelegate delegate;
|
| - TabStripModel tabstrip(&delegate, profile());
|
| -
|
| - // Create test clock, task runner.
|
| - base::SimpleTestTickClock test_clock;
|
| - MockTaskRunner mock_task_runner;
|
| - scoped_refptr<TaskRunnerProxy> task_runner(
|
| - new TaskRunnerProxy(&mock_task_runner, &test_clock));
|
| -
|
| - // Configure the TabManager for testing.
|
| - tabstrip.AddObserver(&tm);
|
| - tm.test_tab_strip_models_.push_back(
|
| - TabManager::TestTabStripModel(&tabstrip, false /* !is_app */));
|
| - tm.test_tick_clock_ = &test_clock;
|
| - tm.task_runner_ = task_runner;
|
| - tm.notify_renderer_process_ = base::Bind(
|
| - &TabManagerTest::NotifyRendererProcess, base::Unretained(this));
|
| -
|
| - // Create two dummy tabs.
|
| - auto* tab0 = CreateWebContents();
|
| - auto* tab1 = CreateWebContents();
|
| - auto* tab2 = CreateWebContents();
|
| - tabstrip.AppendWebContents(tab0, true); // Foreground tab.
|
| - tabstrip.AppendWebContents(tab1, false); // Background tab.
|
| - tabstrip.AppendWebContents(tab2, false); // Background tab.
|
| - const content::RenderProcessHost* renderer1 = tab1->GetRenderProcessHost();
|
| - const content::RenderProcessHost* renderer2 = tab2->GetRenderProcessHost();
|
| -
|
| - // Make sure that tab2 has a lower priority than tab1 by its access time.
|
| - test_clock.Advance(base::TimeDelta::FromMilliseconds(1));
|
| - tab2->SetLastActiveTime(test_clock.NowTicks());
|
| - test_clock.Advance(base::TimeDelta::FromMilliseconds(1));
|
| - tab1->SetLastActiveTime(test_clock.NowTicks());
|
| -
|
| - // Expect that the tab manager has not yet encountered memory pressure.
|
| - EXPECT_FALSE(tm.under_memory_pressure_);
|
| - EXPECT_EQ(0u, tm.notified_renderers_.size());
|
| -
|
| - // Simulate a memory pressure situation that will immediately end. This should
|
| - // cause no notifications or scheduled tasks.
|
| - auto level = base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE;
|
| - tm.get_current_pressure_level_ = base::Bind(&ReturnNoPressure);
|
| - tm.OnMemoryPressure(level);
|
| - testing::Mock::VerifyAndClearExpectations(&mock_task_runner);
|
| - EXPECT_FALSE(tm.under_memory_pressure_);
|
| - EXPECT_EQ(0u, task_runner->size());
|
| - EXPECT_EQ(0u, tm.notified_renderers_.size());
|
| -
|
| - // START OF MEMORY PRESSURE
|
| -
|
| - // Simulate a memory pressure situation that persists. This should cause a
|
| - // task to be scheduled, and a background renderer to be notified.
|
| - tm.get_current_pressure_level_ = base::Bind(
|
| - &ReturnSpecifiedPressure, base::Unretained(&level));
|
| - EXPECT_CALL(mock_task_runner, PostDelayedTask(
|
| - testing::_,
|
| - base::TimeDelta::FromSeconds(tm.kRendererNotificationDelayInSeconds)));
|
| - EXPECT_CALL(*this, NotifyRendererProcess(renderer2, level));
|
| - tm.OnMemoryPressure(level);
|
| - testing::Mock::VerifyAndClearExpectations(&mock_task_runner);
|
| - testing::Mock::VerifyAndClearExpectations(this);
|
| - EXPECT_TRUE(tm.under_memory_pressure_);
|
| - EXPECT_EQ(1u, task_runner->size());
|
| - EXPECT_EQ(1u, tm.notified_renderers_.size());
|
| - EXPECT_EQ(1u, tm.notified_renderers_.count(renderer2));
|
| -
|
| - // REPEATED MEMORY PRESSURE SIGNAL
|
| -
|
| - // Simulate another memory pressure event. This should not cause any
|
| - // additional tasks to be scheduled, nor any further renderer notifications.
|
| - tm.OnMemoryPressure(level);
|
| - testing::Mock::VerifyAndClearExpectations(&mock_task_runner);
|
| - testing::Mock::VerifyAndClearExpectations(this);
|
| - EXPECT_TRUE(tm.under_memory_pressure_);
|
| - EXPECT_EQ(1u, task_runner->size());
|
| - EXPECT_EQ(1u, tm.notified_renderers_.size());
|
| -
|
| - // FIRST SCHEDULED NOTIFICATION
|
| -
|
| - // Run the scheduled task. This should cause another notification, but this
|
| - // time to the foreground tab. It should also cause another scheduled event.
|
| - EXPECT_CALL(mock_task_runner, PostDelayedTask(
|
| - testing::_,
|
| - base::TimeDelta::FromSeconds(tm.kRendererNotificationDelayInSeconds)));
|
| - EXPECT_CALL(*this, NotifyRendererProcess(renderer1, level));
|
| - EXPECT_EQ(1u, task_runner->RunNextTask());
|
| - testing::Mock::VerifyAndClearExpectations(&mock_task_runner);
|
| - testing::Mock::VerifyAndClearExpectations(this);
|
| - EXPECT_TRUE(tm.under_memory_pressure_);
|
| - EXPECT_EQ(1u, task_runner->size());
|
| - EXPECT_EQ(2u, tm.notified_renderers_.size());
|
| - EXPECT_EQ(1u, tm.notified_renderers_.count(renderer1));
|
| -
|
| - // SECOND SCHEDULED NOTIFICATION
|
| -
|
| - // Run the scheduled task. This should cause another notification, to the
|
| - // background tab. It should also cause another scheduled event.
|
| - EXPECT_CALL(mock_task_runner, PostDelayedTask(
|
| - testing::_,
|
| - base::TimeDelta::FromSeconds(tm.kRendererNotificationDelayInSeconds)));
|
| - EXPECT_CALL(*this, NotifyRendererProcess(renderer2, level));
|
| - EXPECT_EQ(1u, task_runner->RunNextTask());
|
| - testing::Mock::VerifyAndClearExpectations(&mock_task_runner);
|
| - testing::Mock::VerifyAndClearExpectations(this);
|
| - EXPECT_TRUE(tm.under_memory_pressure_);
|
| - EXPECT_EQ(1u, task_runner->size());
|
| - EXPECT_EQ(1u, tm.notified_renderers_.size());
|
| -
|
| - // Expect that the background tab has been notified. The list of notified
|
| - // renderers maintained by the TabManager should also have been reset because
|
| - // the notification logic restarts after all renderers are notified.
|
| - EXPECT_EQ(1u, tm.notified_renderers_.count(renderer2));
|
| -
|
| - // END OF MEMORY PRESSURE
|
| -
|
| - // End the memory pressure condition and run the scheduled event. This should
|
| - // clean up the various state data. It should not schedule another event nor
|
| - // fire any notifications.
|
| - level = base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
|
| - EXPECT_EQ(1u, task_runner->RunNextTask());
|
| - testing::Mock::VerifyAndClearExpectations(&mock_task_runner);
|
| - testing::Mock::VerifyAndClearExpectations(this);
|
| - EXPECT_FALSE(tm.under_memory_pressure_);
|
| - EXPECT_EQ(0u, task_runner->size());
|
| - EXPECT_EQ(0u, tm.notified_renderers_.size());
|
| -
|
| -
|
| - // Clean up the tabstrip.
|
| - tabstrip.CloseAllTabs();
|
| - ASSERT_TRUE(tabstrip.empty());
|
| -}
|
| -
|
| TEST_F(TabManagerTest, DefaultTimeToPurgeInCorrectRange) {
|
| TabManager tab_manager;
|
| base::TimeDelta time_to_purge =
|
|
|