6b40cfef5031458649120d3b13b14951e0da1e47
[platform/framework/web/crosswalk.git] / src / chrome / browser / apps / ephemeral_app_service_unittest.cc
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <algorithm>
6
7 #include "base/rand_util.h"
8 #include "base/strings/string_number_conversions.h"
9 #include "base/time/time.h"
10 #include "chrome/browser/apps/ephemeral_app_service.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12
13 namespace {
14
15 // Generate a time N number of days before the reference time.
16 // The generated time can be randomized.
17 base::Time GetPastTime(const base::Time& reference_time,
18                        int days_before,
19                        bool randomize_time = false) {
20   base::Time generated_time =
21       reference_time - base::TimeDelta::FromDays(days_before);
22
23   // Add an hour so that the time is well within the number of days before.
24   generated_time += base::TimeDelta::FromHours(1);
25
26   // Add a random number of seconds between 0 - 10 hours.
27   if (randomize_time)
28     generated_time += base::TimeDelta::FromSeconds(base::RandInt(0, 36000));
29
30   return generated_time;
31 }
32
33 }  // namespace
34
35 class EphemeralAppServiceTest : public testing::Test {
36  protected:
37   typedef EphemeralAppService::LaunchTimeAppMap LaunchTimeAppMap;
38
39   EphemeralAppServiceTest() {}
40   virtual ~EphemeralAppServiceTest() {}
41
42   void RunTest(int ephemeral_app_count,
43                const LaunchTimeAppMap& launch_times,
44                const std::set<std::string>& expected_removed_ids) {
45     std::set<std::string> remove_app_ids;
46     EphemeralAppService::GetAppsToRemove(ephemeral_app_count,
47                                          launch_times,
48                                          &remove_app_ids);
49     EXPECT_EQ(expected_removed_ids, remove_app_ids);
50   }
51
52   void RunTestCheckLRU(int ephemeral_app_count,
53                        LaunchTimeAppMap& launch_times,
54                        int expected_removed_count) {
55     std::set<std::string> remove_app_ids;
56     EphemeralAppService::GetAppsToRemove(ephemeral_app_count,
57                                          launch_times,
58                                          &remove_app_ids);
59     EXPECT_EQ(expected_removed_count, (int) remove_app_ids.size());
60
61     // Move the launch times of removed apps to another map.
62     LaunchTimeAppMap removed_apps;
63     for (LaunchTimeAppMap::iterator it = launch_times.begin();
64          it != launch_times.end(); ) {
65       if (remove_app_ids.find(it->second) != remove_app_ids.end()) {
66         removed_apps.insert(*it);
67         launch_times.erase(it++);
68       } else {
69         ++it;
70       }
71     }
72
73     if (launch_times.empty())
74       return;
75
76     // Verify that the removed apps have launch times earlier than or equal to
77     // all retained apps. We can actually just compare with the first entry in
78     // |launch_times| but will make no implementation assumptions.
79     for (LaunchTimeAppMap::const_iterator removed = removed_apps.begin();
80          removed != removed_apps.end(); ++removed) {
81       for (LaunchTimeAppMap::iterator retained = launch_times.begin();
82          retained != launch_times.end(); ++retained) {
83         EXPECT_LE(removed->first, retained->first);
84       }
85     }
86   }
87
88   // Generate X app launch times, N days before the reference time.
89   // If |generated_ids| is not NULL, the generated app IDs will be added
90   // to the set.
91   void GenerateLaunchTimes(const base::Time& reference_time,
92                            int days_before,
93                            int count,
94                            LaunchTimeAppMap* launch_times,
95                            std::set<std::string>* generated_ids = NULL) {
96     for (int i = 0; i < count; ++i) {
97       std::string app_id = base::IntToString(launch_times->size());
98       launch_times->insert(std::make_pair(
99           GetPastTime(reference_time, days_before, true),
100           app_id));
101
102       if (generated_ids)
103         generated_ids->insert(app_id);
104     }
105   }
106
107   // Add inactive apps that should always be removed by garbage collection.
108   void AddInactiveApps(const base::Time& reference_time,
109                        int count,
110                        LaunchTimeAppMap* launch_times,
111                        std::set<std::string>* generated_ids = NULL) {
112     GenerateLaunchTimes(reference_time,
113                         EphemeralAppService::kAppInactiveThreshold + 1,
114                         count,
115                         launch_times,
116                         generated_ids);
117   }
118
119   // Add recently launched apps that should NOT be removed by garbage
120   // collection regardless of the number of cached ephemeral apps.
121   void AddRecentlyLaunchedApps(const base::Time& reference_time,
122                                int count,
123                                LaunchTimeAppMap* launch_times,
124                                std::set<std::string>* generated_ids = NULL) {
125     GenerateLaunchTimes(reference_time,
126                         EphemeralAppService::kAppKeepThreshold,
127                         count,
128                         launch_times,
129                         generated_ids);
130   }
131
132   // Add apps launched between the kAppInactiveThreshold and kAppKeepThreshold,
133   // which may or may not be removed by garbage collection depending on the
134   // number of ephemeral apps in the cache.
135   void AddIntermediateApps(const base::Time& reference_time,
136                            int count,
137                            LaunchTimeAppMap* launch_times,
138                            std::set<std::string>* generated_ids = NULL) {
139     int days_before = base::RandInt(EphemeralAppService::kAppKeepThreshold + 1,
140                                     EphemeralAppService::kAppInactiveThreshold);
141     GenerateLaunchTimes(reference_time,
142                         days_before,
143                         count,
144                         launch_times,
145                         generated_ids);
146   }
147 };
148
149 // Verify that inactive apps are removed even if the cache has not reached
150 // capacity.
151 // Test case: | inactive |
152 // Expected output: All inactive apps removed.
153 TEST_F(EphemeralAppServiceTest, RemoveInactiveApps) {
154   base::Time time_now = base::Time::Now();
155   LaunchTimeAppMap launch_times;
156   std::set<std::string> expected_removed_ids;
157
158   AddInactiveApps(
159       time_now,
160       EphemeralAppService::kMaxEphemeralAppsCount / 5,
161       &launch_times,
162       &expected_removed_ids);
163   RunTest(launch_times.size(), launch_times, expected_removed_ids);
164 }
165
166 // Verify that inactive apps are removed even if the cache has not reached
167 // capacity.
168 // Test case: | inactive | intermediate | recently launched |
169 // Expected output: All inactive apps removed, other apps retained.
170 TEST_F(EphemeralAppServiceTest, RemoveInactiveAppsKeepOthers) {
171   base::Time time_now = base::Time::Now();
172   LaunchTimeAppMap launch_times;
173   std::set<std::string> expected_removed_ids;
174
175   AddInactiveApps(
176       time_now,
177       EphemeralAppService::kMaxEphemeralAppsCount / 5,
178       &launch_times,
179       &expected_removed_ids);
180   AddIntermediateApps(
181       time_now,
182       EphemeralAppService::kMaxEphemeralAppsCount / 5,
183       &launch_times);
184   AddRecentlyLaunchedApps(
185       time_now,
186       EphemeralAppService::kMaxEphemeralAppsCount / 5,
187       &launch_times);
188   RunTest(launch_times.size(), launch_times, expected_removed_ids);
189 }
190
191 // Verify that recently launched apps will not be removed, even when the cache
192 // overflows.
193 // Test case: | recently launched |
194 // Expected output: All recently launched apps retained.
195 TEST_F(EphemeralAppServiceTest, KeepRecentLaunch) {
196   base::Time time_now = base::Time::Now();
197   LaunchTimeAppMap launch_times;
198
199   AddRecentlyLaunchedApps(
200       time_now,
201       3,
202       &launch_times);
203   RunTest(launch_times.size(), launch_times, std::set<std::string>());
204
205   AddRecentlyLaunchedApps(
206       time_now,
207       EphemeralAppService::kMaxEphemeralAppsCount,
208       &launch_times); // overflow
209   RunTest(launch_times.size(), launch_times, std::set<std::string>());
210 }
211
212 // Verify that recently launched apps will not be removed, even when the cache
213 // overflows.
214 // Test case: | intermediate (overflow) | recently launched (overflow) |
215 // Expected output: All recently launched apps retained, intermediate apps
216 // removed.
217 TEST_F(EphemeralAppServiceTest, KeepRecentLaunchRemoveOthers) {
218   base::Time time_now = base::Time::Now();
219   LaunchTimeAppMap launch_times;
220   std::set<std::string> expected_removed_ids;
221
222   AddRecentlyLaunchedApps(
223       time_now,
224       EphemeralAppService::kMaxEphemeralAppsCount + 3,
225       &launch_times); // overflow
226   AddIntermediateApps(
227       time_now,
228       3,
229       &launch_times,
230       &expected_removed_ids); // overflow
231   RunTest(launch_times.size(), launch_times, expected_removed_ids);
232 }
233
234 // Verify that the LRU algorithm is implemented correctly.
235 // Test case: | intermediate (overflow) |
236 // Expected output: The least recently launched apps are removed.
237 TEST_F(EphemeralAppServiceTest, RemoveOverflow) {
238   base::Time time_now = base::Time::Now();
239   LaunchTimeAppMap launch_times;
240
241   const int kOverflow = 3;
242   AddIntermediateApps(
243       time_now,
244       EphemeralAppService::kMaxEphemeralAppsCount + kOverflow,
245       &launch_times); // overflow
246   RunTestCheckLRU(launch_times.size(), launch_times, kOverflow);
247 }
248
249 // Verify that GetAppsToRemove() takes into account the number of running apps,
250 // since they are not included in the launch times.
251 // Test case: | intermediate (overflow) | running apps |
252 // Expected output: The least recently launched apps are removed.
253 TEST_F(EphemeralAppServiceTest, RemoveOverflowWithRunningApps) {
254   base::Time time_now = base::Time::Now();
255   LaunchTimeAppMap launch_times;
256
257   const int kRunningApps = 3;
258   AddIntermediateApps(
259       time_now,
260       EphemeralAppService::kMaxEphemeralAppsCount,
261       &launch_times);  // overflow
262   RunTestCheckLRU(
263       launch_times.size() + kRunningApps,
264       launch_times,
265       kRunningApps);
266 }