Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3456)

Unified Diff: chrome/browser/memory/tab_manager_unittest.cc

Issue 2882513004: Remove renderer notifications of memory pressure. (Closed)
Patch Set: Merge Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/memory/tab_manager.cc ('k') | chrome/browser/memory/tab_stats.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 =
« no previous file with comments | « chrome/browser/memory/tab_manager.cc ('k') | chrome/browser/memory/tab_stats.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698