15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
95e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string16.h"
10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/memory/oom_priority_manager.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/url_constants.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef testing::Test OomPriorityManagerTest;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum TestIndicies {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kSelected,
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kPinned,
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kApp,
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  kPlayingAudio,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kRecent,
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kOld,
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kReallyOld,
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  kOldButPinned,
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  kReloadableUI,
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests the sorting comparator so that we know it's producing the
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// desired order.
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(OomPriorityManagerTest, Comparator) {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chromeos::OomPriorityManager::TabStatsList test_list;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::TimeTicks now = base::TimeTicks::Now();
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add kSelected last to verify we are sorting the array.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OomPriorityManager::TabStats stats;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    stats.is_pinned = true;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    stats.renderer_handle = kPinned;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    test_list.push_back(stats);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OomPriorityManager::TabStats stats;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    stats.is_app = true;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    stats.renderer_handle = kApp;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    test_list.push_back(stats);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OomPriorityManager::TabStats stats;
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stats.is_playing_audio = true;
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stats.renderer_handle = kPlayingAudio;
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_list.push_back(stats);
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    OomPriorityManager::TabStats stats;
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    stats.last_active = now - base::TimeDelta::FromSeconds(10);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    stats.renderer_handle = kRecent;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    test_list.push_back(stats);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OomPriorityManager::TabStats stats;
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    stats.last_active = now - base::TimeDelta::FromMinutes(15);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    stats.renderer_handle = kOld;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    test_list.push_back(stats);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OomPriorityManager::TabStats stats;
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    stats.last_active = now - base::TimeDelta::FromDays(365);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    stats.renderer_handle = kReallyOld;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    test_list.push_back(stats);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OomPriorityManager::TabStats stats;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    stats.is_pinned = true;
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    stats.last_active = now - base::TimeDelta::FromDays(365);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    stats.renderer_handle = kOldButPinned;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    test_list.push_back(stats);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    OomPriorityManager::TabStats stats;
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stats.is_reloadable_ui = true;
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stats.renderer_handle = kReloadableUI;
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_list.push_back(stats);
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This entry sorts to the front, so by adding it last we verify that
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we are actually sorting the array.
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OomPriorityManager::TabStats stats;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    stats.is_selected = true;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    stats.renderer_handle = kSelected;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    test_list.push_back(stats);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::sort(test_list.begin(),
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            test_list.end(),
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            OomPriorityManager::CompareTabStats);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int index = 0;
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kSelected, test_list[index++].renderer_handle);
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kPinned, test_list[index++].renderer_handle);
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kOldButPinned, test_list[index++].renderer_handle);
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kApp, test_list[index++].renderer_handle);
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kPlayingAudio, test_list[index++].renderer_handle);
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kRecent, test_list[index++].renderer_handle);
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kOld, test_list[index++].renderer_handle);
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kReallyOld, test_list[index++].renderer_handle);
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kReloadableUI, test_list[index++].renderer_handle);
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(OomPriorityManagerTest, IsReloadableUI) {
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(OomPriorityManager::IsReloadableUI(
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GURL(chrome::kChromeUIDownloadsURL)));
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(OomPriorityManager::IsReloadableUI(
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GURL(chrome::kChromeUIHistoryURL)));
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(OomPriorityManager::IsReloadableUI(
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GURL(chrome::kChromeUINewTabURL)));
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(OomPriorityManager::IsReloadableUI(
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GURL(chrome::kChromeUISettingsURL)));
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Debugging URLs are not included.
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(OomPriorityManager::IsReloadableUI(
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GURL(chrome::kChromeUIDiscardsURL)));
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(OomPriorityManager::IsReloadableUI(
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GURL(chrome::kChromeUINetInternalsURL)));
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Prefix matches are included.
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(OomPriorityManager::IsReloadableUI(
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GURL("chrome://settings/fakeSetting")));
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochTEST_F(OomPriorityManagerTest, GetProcessHandles) {
146e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  OomPriorityManager::TabStats stats;
147e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  std::vector<base::ProcessHandle> handles;
148e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
149e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Empty stats list gives empty handles list.
150e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  OomPriorityManager::TabStatsList empty_list;
151e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  handles = OomPriorityManager::GetProcessHandles(empty_list);
152e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(0u, handles.size());
153e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
154e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Two tabs in two different processes generates two handles out.
155e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  OomPriorityManager::TabStatsList two_list;
156e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  stats.renderer_handle = 100;
157e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  two_list.push_back(stats);
158e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  stats.renderer_handle = 101;
159e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  two_list.push_back(stats);
160e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  handles = OomPriorityManager::GetProcessHandles(two_list);
161e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(2u, handles.size());
162e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(100, handles[0]);
163e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(101, handles[1]);
164e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
165e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Zero handles are removed.
166e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  OomPriorityManager::TabStatsList zero_handle_list;
167e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  stats.renderer_handle = 0;
168e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  zero_handle_list.push_back(stats);
169e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  handles = OomPriorityManager::GetProcessHandles(zero_handle_list);
170e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(0u, handles.size());
171e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
172e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Two tabs in the same process generates one handle out. When a duplicate
173e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // occurs the later instance is dropped.
174e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  OomPriorityManager::TabStatsList same_process_list;
175e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  stats.renderer_handle = 100;
176e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  same_process_list.push_back(stats);
177e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  stats.renderer_handle = 101;
178e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  same_process_list.push_back(stats);
179e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  stats.renderer_handle = 100;  // Duplicate.
180e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  same_process_list.push_back(stats);
181e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  handles = OomPriorityManager::GetProcessHandles(same_process_list);
182e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(2u, handles.size());
183e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(100, handles[0]);
184e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(101, handles[1]);
185e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
186e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chromeos
188