15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <algorithm> 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/rand_util.h" 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/time/time.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/apps/ephemeral_app_service.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Generate a time N number of days before the reference time. 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// The generated time can be randomized. 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::Time GetPastTime(const base::Time& reference_time, 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int days_before, 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool randomize_time = false) { 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Time generated_time = 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) reference_time - base::TimeDelta::FromDays(days_before); 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Add an hour so that the time is well within the number of days before. 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) generated_time += base::TimeDelta::FromHours(1); 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Add a random number of seconds between 0 - 10 hours. 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (randomize_time) 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) generated_time += base::TimeDelta::FromSeconds(base::RandInt(0, 36000)); 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return generated_time; 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class EphemeralAppServiceTest : public testing::Test { 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected: 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) typedef EphemeralAppService::LaunchTimeAppMap LaunchTimeAppMap; 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EphemeralAppServiceTest() {} 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~EphemeralAppServiceTest() {} 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void RunTest(int ephemeral_app_count, 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const LaunchTimeAppMap& launch_times, 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::set<std::string>& expected_removed_ids) { 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::set<std::string> remove_app_ids; 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EphemeralAppService::GetAppsToRemove(ephemeral_app_count, 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) launch_times, 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &remove_app_ids); 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(expected_removed_ids, remove_app_ids); 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void RunTestCheckLRU(int ephemeral_app_count, 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LaunchTimeAppMap& launch_times, 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int expected_removed_count) { 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::set<std::string> remove_app_ids; 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EphemeralAppService::GetAppsToRemove(ephemeral_app_count, 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) launch_times, 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &remove_app_ids); 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(expected_removed_count, (int) remove_app_ids.size()); 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Move the launch times of removed apps to another map. 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LaunchTimeAppMap removed_apps; 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (LaunchTimeAppMap::iterator it = launch_times.begin(); 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) it != launch_times.end(); ) { 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (remove_app_ids.find(it->second) != remove_app_ids.end()) { 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) removed_apps.insert(*it); 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) launch_times.erase(it++); 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ++it; 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (launch_times.empty()) 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Verify that the removed apps have launch times earlier than or equal to 7746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // all retained apps. We can actually just compare with the first entry in 7846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // |launch_times| but will make no implementation assumptions. 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (LaunchTimeAppMap::const_iterator removed = removed_apps.begin(); 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) removed != removed_apps.end(); ++removed) { 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (LaunchTimeAppMap::iterator retained = launch_times.begin(); 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) retained != launch_times.end(); ++retained) { 8346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_LE(removed->first, retained->first); 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Generate X app launch times, N days before the reference time. 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If |generated_ids| is not NULL, the generated app IDs will be added 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // to the set. 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void GenerateLaunchTimes(const base::Time& reference_time, 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int days_before, 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int count, 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LaunchTimeAppMap* launch_times, 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::set<std::string>* generated_ids = NULL) { 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (int i = 0; i < count; ++i) { 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string app_id = base::IntToString(launch_times->size()); 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) launch_times->insert(std::make_pair( 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetPastTime(reference_time, days_before, true), 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) app_id)); 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (generated_ids) 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) generated_ids->insert(app_id); 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Add inactive apps that should always be removed by garbage collection. 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void AddInactiveApps(const base::Time& reference_time, 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int count, 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LaunchTimeAppMap* launch_times, 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::set<std::string>* generated_ids = NULL) { 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GenerateLaunchTimes(reference_time, 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EphemeralAppService::kAppInactiveThreshold + 1, 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) count, 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) launch_times, 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) generated_ids); 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Add recently launched apps that should NOT be removed by garbage 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // collection regardless of the number of cached ephemeral apps. 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void AddRecentlyLaunchedApps(const base::Time& reference_time, 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int count, 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LaunchTimeAppMap* launch_times, 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::set<std::string>* generated_ids = NULL) { 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GenerateLaunchTimes(reference_time, 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EphemeralAppService::kAppKeepThreshold, 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) count, 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) launch_times, 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) generated_ids); 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Add apps launched between the kAppInactiveThreshold and kAppKeepThreshold, 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // which may or may not be removed by garbage collection depending on the 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // number of ephemeral apps in the cache. 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void AddIntermediateApps(const base::Time& reference_time, 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int count, 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LaunchTimeAppMap* launch_times, 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::set<std::string>* generated_ids = NULL) { 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int days_before = base::RandInt(EphemeralAppService::kAppKeepThreshold + 1, 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EphemeralAppService::kAppInactiveThreshold); 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GenerateLaunchTimes(reference_time, 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) days_before, 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) count, 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) launch_times, 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) generated_ids); 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Verify that inactive apps are removed even if the cache has not reached 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// capacity. 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Test case: | inactive | 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Expected output: All inactive apps removed. 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(EphemeralAppServiceTest, RemoveInactiveApps) { 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Time time_now = base::Time::Now(); 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LaunchTimeAppMap launch_times; 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::set<std::string> expected_removed_ids; 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddInactiveApps( 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) time_now, 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EphemeralAppService::kMaxEphemeralAppsCount / 5, 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &launch_times, 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &expected_removed_ids); 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RunTest(launch_times.size(), launch_times, expected_removed_ids); 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Verify that inactive apps are removed even if the cache has not reached 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// capacity. 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Test case: | inactive | intermediate | recently launched | 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Expected output: All inactive apps removed, other apps retained. 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(EphemeralAppServiceTest, RemoveInactiveAppsKeepOthers) { 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Time time_now = base::Time::Now(); 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LaunchTimeAppMap launch_times; 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::set<std::string> expected_removed_ids; 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddInactiveApps( 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) time_now, 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EphemeralAppService::kMaxEphemeralAppsCount / 5, 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &launch_times, 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &expected_removed_ids); 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddIntermediateApps( 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) time_now, 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EphemeralAppService::kMaxEphemeralAppsCount / 5, 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &launch_times); 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddRecentlyLaunchedApps( 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) time_now, 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EphemeralAppService::kMaxEphemeralAppsCount / 5, 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &launch_times); 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RunTest(launch_times.size(), launch_times, expected_removed_ids); 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Verify that recently launched apps will not be removed, even when the cache 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// overflows. 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Test case: | recently launched | 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Expected output: All recently launched apps retained. 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(EphemeralAppServiceTest, KeepRecentLaunch) { 1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Time time_now = base::Time::Now(); 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LaunchTimeAppMap launch_times; 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddRecentlyLaunchedApps( 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) time_now, 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3, 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &launch_times); 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RunTest(launch_times.size(), launch_times, std::set<std::string>()); 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddRecentlyLaunchedApps( 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) time_now, 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EphemeralAppService::kMaxEphemeralAppsCount, 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &launch_times); // overflow 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RunTest(launch_times.size(), launch_times, std::set<std::string>()); 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Verify that recently launched apps will not be removed, even when the cache 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// overflows. 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Test case: | intermediate (overflow) | recently launched (overflow) | 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Expected output: All recently launched apps retained, intermediate apps 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// removed. 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(EphemeralAppServiceTest, KeepRecentLaunchRemoveOthers) { 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Time time_now = base::Time::Now(); 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LaunchTimeAppMap launch_times; 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::set<std::string> expected_removed_ids; 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddRecentlyLaunchedApps( 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) time_now, 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EphemeralAppService::kMaxEphemeralAppsCount + 3, 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &launch_times); // overflow 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddIntermediateApps( 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) time_now, 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3, 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &launch_times, 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &expected_removed_ids); // overflow 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RunTest(launch_times.size(), launch_times, expected_removed_ids); 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Verify that the LRU algorithm is implemented correctly. 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Test case: | intermediate (overflow) | 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Expected output: The least recently launched apps are removed. 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(EphemeralAppServiceTest, RemoveOverflow) { 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Time time_now = base::Time::Now(); 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LaunchTimeAppMap launch_times; 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const int kOverflow = 3; 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddIntermediateApps( 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) time_now, 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EphemeralAppService::kMaxEphemeralAppsCount + kOverflow, 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &launch_times); // overflow 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RunTestCheckLRU(launch_times.size(), launch_times, kOverflow); 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Verify that GetAppsToRemove() takes into account the number of running apps, 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// since they are not included in the launch times. 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Test case: | intermediate (overflow) | running apps | 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Expected output: The least recently launched apps are removed. 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(EphemeralAppServiceTest, RemoveOverflowWithRunningApps) { 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Time time_now = base::Time::Now(); 2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LaunchTimeAppMap launch_times; 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const int kRunningApps = 3; 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddIntermediateApps( 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) time_now, 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EphemeralAppService::kMaxEphemeralAppsCount, 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &launch_times); // overflow 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RunTestCheckLRU( 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) launch_times.size() + kRunningApps, 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) launch_times, 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kRunningApps); 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 267