Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / components / precache / core / precache_database_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 "components/precache/core/precache_database.h"
6
7 #include <map>
8
9 #include "base/files/file_path.h"
10 #include "base/files/scoped_temp_dir.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/metrics/histogram.h"
13 #include "base/metrics/histogram_samples.h"
14 #include "base/metrics/statistics_recorder.h"
15 #include "base/time/time.h"
16 #include "sql/connection.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "url/gurl.h"
19
20 namespace {
21
22 const GURL kURL("http://url.com");
23 const base::Time kFetchTime = base::Time() + base::TimeDelta::FromHours(1000);
24 const base::Time kOldFetchTime = kFetchTime - base::TimeDelta::FromDays(1);
25 const int64 kSize = 5000;
26
27 const char* kHistogramNames[] = {"Precache.DownloadedPrecacheMotivated",
28                                  "Precache.DownloadedNonPrecache",
29                                  "Precache.DownloadedNonPrecache.Cellular",
30                                  "Precache.Saved",
31                                  "Precache.Saved.Cellular"};
32
33 scoped_ptr<base::HistogramSamples> GetHistogramSamples(
34     const char* histogram_name) {
35   base::HistogramBase* histogram =
36       base::StatisticsRecorder::FindHistogram(histogram_name);
37
38   EXPECT_NE(static_cast<base::HistogramBase*>(NULL), histogram);
39
40   return histogram->SnapshotSamples().Pass();
41 }
42
43 std::map<GURL, base::Time> BuildURLTableMap(const GURL& url,
44                                             const base::Time& precache_time) {
45   std::map<GURL, base::Time> url_table_map;
46   url_table_map[url] = precache_time;
47   return url_table_map;
48 }
49
50 }  // namespace
51
52 namespace precache {
53
54 class PrecacheDatabaseTest : public testing::Test {
55  public:
56   PrecacheDatabaseTest() {}
57   ~PrecacheDatabaseTest() override {}
58
59  protected:
60   void SetUp() override {
61     base::StatisticsRecorder::Initialize();
62     precache_database_ = new PrecacheDatabase();
63
64     ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());
65     base::FilePath db_path = scoped_temp_dir_.path().Append(
66         base::FilePath(FILE_PATH_LITERAL("precache_database")));
67     precache_database_->Init(db_path);
68
69     // Log a sample for each histogram, to ensure that they are all created.
70     // This has to be done here, and not in the for loop below, because of the
71     // way that UMA_HISTOGRAM_COUNTS uses static variables.
72     UMA_HISTOGRAM_COUNTS("Precache.DownloadedPrecacheMotivated", 0);
73     UMA_HISTOGRAM_COUNTS("Precache.DownloadedNonPrecache", 0);
74     UMA_HISTOGRAM_COUNTS("Precache.DownloadedNonPrecache.Cellular", 0);
75     UMA_HISTOGRAM_COUNTS("Precache.Saved", 0);
76     UMA_HISTOGRAM_COUNTS("Precache.Saved.Cellular", 0);
77
78     for (size_t i = 0; i < arraysize(kHistogramNames); i++) {
79       initial_histogram_samples_[i] =
80           GetHistogramSamples(kHistogramNames[i]).Pass();
81       initial_histogram_samples_map_[kHistogramNames[i]] =
82           initial_histogram_samples_[i].get();
83     }
84   }
85
86   std::map<GURL, base::Time> GetActualURLTableMap() {
87     // Flush any buffered writes so that the URL table will be up to date.
88     precache_database_->Flush();
89
90     std::map<GURL, base::Time> url_table_map;
91     precache_url_table()->GetAllDataForTesting(&url_table_map);
92     return url_table_map;
93   }
94
95   PrecacheURLTable* precache_url_table() {
96     return &precache_database_->precache_url_table_;
97   }
98
99   scoped_ptr<base::HistogramSamples> GetHistogramSamplesDelta(
100       const char* histogram_name) {
101     scoped_ptr<base::HistogramSamples> delta_samples(
102         GetHistogramSamples(histogram_name));
103     delta_samples->Subtract(*initial_histogram_samples_map_[histogram_name]);
104
105     return delta_samples.Pass();
106   }
107
108   void ExpectNewSample(const char* histogram_name,
109                        base::HistogramBase::Sample sample) {
110     scoped_ptr<base::HistogramSamples> delta_samples(
111         GetHistogramSamplesDelta(histogram_name));
112     EXPECT_EQ(1, delta_samples->TotalCount());
113     EXPECT_EQ(1, delta_samples->GetCount(sample));
114   }
115
116   void ExpectNoNewSamples(const char* histogram_name) {
117     scoped_ptr<base::HistogramSamples> delta_samples(
118         GetHistogramSamplesDelta(histogram_name));
119     EXPECT_EQ(0, delta_samples->TotalCount());
120   }
121
122   // Convenience methods for recording different types of URL fetches. These
123   // exist to improve the readability of the tests.
124   void RecordPrecacheFromNetwork(const GURL& url, const base::Time& fetch_time,
125                                  int64 size);
126   void RecordPrecacheFromCache(const GURL& url, const base::Time& fetch_time,
127                                int64 size);
128   void RecordFetchFromNetwork(const GURL& url, const base::Time& fetch_time,
129                               int64 size);
130   void RecordFetchFromNetworkCellular(const GURL& url,
131                                       const base::Time& fetch_time, int64 size);
132   void RecordFetchFromCache(const GURL& url, const base::Time& fetch_time,
133                             int64 size);
134   void RecordFetchFromCacheCellular(const GURL& url,
135                                     const base::Time& fetch_time, int64 size);
136
137   // Having this MessageLoop member variable causes base::MessageLoop::current()
138   // to be set properly.
139   base::MessageLoopForUI loop_;
140
141   scoped_refptr<PrecacheDatabase> precache_database_;
142   base::ScopedTempDir scoped_temp_dir_;
143   scoped_ptr<base::HistogramSamples> initial_histogram_samples_
144       [arraysize(kHistogramNames)];
145   std::map<std::string, base::HistogramSamples*> initial_histogram_samples_map_;
146 };
147
148 void PrecacheDatabaseTest::RecordPrecacheFromNetwork(
149     const GURL& url, const base::Time& fetch_time, int64 size) {
150   precache_database_->RecordURLPrecached(url, fetch_time, size,
151                                          false /* was_cached */);
152 }
153
154 void PrecacheDatabaseTest::RecordPrecacheFromCache(const GURL& url,
155                                                    const base::Time& fetch_time,
156                                                    int64 size) {
157   precache_database_->RecordURLPrecached(url, fetch_time, size,
158                                          true /* was_cached */);
159 }
160
161 void PrecacheDatabaseTest::RecordFetchFromNetwork(const GURL& url,
162                                                   const base::Time& fetch_time,
163                                                   int64 size) {
164   precache_database_->RecordURLFetched(url, fetch_time, size,
165                                        false /* was_cached */,
166                                        false /* is_connection_cellular */);
167 }
168
169 void PrecacheDatabaseTest::RecordFetchFromNetworkCellular(
170     const GURL& url, const base::Time& fetch_time, int64 size) {
171   precache_database_->RecordURLFetched(url, fetch_time, size,
172                                        false /* was_cached */,
173                                        true /* is_connection_cellular */);
174 }
175
176 void PrecacheDatabaseTest::RecordFetchFromCache(const GURL& url,
177                                                 const base::Time& fetch_time,
178                                                 int64 size) {
179   precache_database_->RecordURLFetched(url, fetch_time, size,
180                                        true /* was_cached */,
181                                        false /* is_connection_cellular */);
182 }
183
184 void PrecacheDatabaseTest::RecordFetchFromCacheCellular(
185     const GURL& url, const base::Time& fetch_time, int64 size) {
186   precache_database_->RecordURLFetched(url, fetch_time, size,
187                                        true /* was_cached */,
188                                        true /* is_connection_cellular */);
189 }
190
191 namespace {
192
193 TEST_F(PrecacheDatabaseTest, PrecacheOverNetwork) {
194   RecordPrecacheFromNetwork(kURL, kFetchTime, kSize);
195
196   EXPECT_EQ(BuildURLTableMap(kURL, kFetchTime), GetActualURLTableMap());
197
198   ExpectNewSample("Precache.DownloadedPrecacheMotivated", kSize);
199   ExpectNoNewSamples("Precache.DownloadedNonPrecache");
200   ExpectNoNewSamples("Precache.DownloadedNonPrecache.Cellular");
201   ExpectNoNewSamples("Precache.Saved");
202   ExpectNoNewSamples("Precache.Saved.Cellular");
203 }
204
205 TEST_F(PrecacheDatabaseTest, PrecacheFromCacheWithURLTableEntry) {
206   precache_url_table()->AddURL(kURL, kOldFetchTime);
207   RecordPrecacheFromCache(kURL, kFetchTime, kSize);
208
209   // The URL table entry should have been updated to have |kFetchTime| as the
210   // timestamp.
211   EXPECT_EQ(BuildURLTableMap(kURL, kFetchTime), GetActualURLTableMap());
212
213   ExpectNoNewSamples("Precache.DownloadedPrecacheMotivated");
214   ExpectNoNewSamples("Precache.DownloadedNonPrecache");
215   ExpectNoNewSamples("Precache.DownloadedNonPrecache.Cellular");
216   ExpectNoNewSamples("Precache.Saved");
217   ExpectNoNewSamples("Precache.Saved.Cellular");
218 }
219
220 TEST_F(PrecacheDatabaseTest, PrecacheFromCacheWithoutURLTableEntry) {
221   RecordPrecacheFromCache(kURL, kFetchTime, kSize);
222
223   EXPECT_TRUE(GetActualURLTableMap().empty());
224
225   ExpectNoNewSamples("Precache.DownloadedPrecacheMotivated");
226   ExpectNoNewSamples("Precache.DownloadedNonPrecache");
227   ExpectNoNewSamples("Precache.DownloadedNonPrecache.Cellular");
228   ExpectNoNewSamples("Precache.Saved");
229   ExpectNoNewSamples("Precache.Saved.Cellular");
230 }
231
232 TEST_F(PrecacheDatabaseTest, FetchOverNetwork_NonCellular) {
233   RecordFetchFromNetwork(kURL, kFetchTime, kSize);
234
235   EXPECT_TRUE(GetActualURLTableMap().empty());
236
237   ExpectNoNewSamples("Precache.DownloadedPrecacheMotivated");
238   ExpectNewSample("Precache.DownloadedNonPrecache", kSize);
239   ExpectNoNewSamples("Precache.DownloadedNonPrecache.Cellular");
240   ExpectNoNewSamples("Precache.Saved");
241   ExpectNoNewSamples("Precache.Saved.Cellular");
242 }
243
244 TEST_F(PrecacheDatabaseTest, FetchOverNetwork_Cellular) {
245   RecordFetchFromNetworkCellular(kURL, kFetchTime, kSize);
246
247   EXPECT_TRUE(GetActualURLTableMap().empty());
248
249   ExpectNoNewSamples("Precache.DownloadedPrecacheMotivated");
250   ExpectNewSample("Precache.DownloadedNonPrecache", kSize);
251   ExpectNewSample("Precache.DownloadedNonPrecache.Cellular", kSize);
252   ExpectNoNewSamples("Precache.Saved");
253   ExpectNoNewSamples("Precache.Saved.Cellular");
254 }
255
256 TEST_F(PrecacheDatabaseTest, FetchOverNetworkWithURLTableEntry) {
257   precache_url_table()->AddURL(kURL, kOldFetchTime);
258   RecordFetchFromNetwork(kURL, kFetchTime, kSize);
259
260   // The URL table entry should have been deleted.
261   EXPECT_TRUE(GetActualURLTableMap().empty());
262
263   ExpectNoNewSamples("Precache.DownloadedPrecacheMotivated");
264   ExpectNewSample("Precache.DownloadedNonPrecache", kSize);
265   ExpectNoNewSamples("Precache.DownloadedNonPrecache.Cellular");
266   ExpectNoNewSamples("Precache.Saved");
267   ExpectNoNewSamples("Precache.Saved.Cellular");
268 }
269
270 TEST_F(PrecacheDatabaseTest, FetchFromCacheWithURLTableEntry_NonCellular) {
271   precache_url_table()->AddURL(kURL, kOldFetchTime);
272   RecordFetchFromCache(kURL, kFetchTime, kSize);
273
274   // The URL table entry should have been deleted.
275   EXPECT_TRUE(GetActualURLTableMap().empty());
276
277   ExpectNoNewSamples("Precache.DownloadedPrecacheMotivated");
278   ExpectNoNewSamples("Precache.DownloadedNonPrecache");
279   ExpectNoNewSamples("Precache.DownloadedNonPrecache.Cellular");
280   ExpectNewSample("Precache.Saved", kSize);
281   ExpectNoNewSamples("Precache.Saved.Cellular");
282 }
283
284 TEST_F(PrecacheDatabaseTest, FetchFromCacheWithURLTableEntry_Cellular) {
285   precache_url_table()->AddURL(kURL, kOldFetchTime);
286   RecordFetchFromCacheCellular(kURL, kFetchTime, kSize);
287
288   // The URL table entry should have been deleted.
289   EXPECT_TRUE(GetActualURLTableMap().empty());
290
291   ExpectNoNewSamples("Precache.DownloadedPrecacheMotivated");
292   ExpectNoNewSamples("Precache.DownloadedNonPrecache");
293   ExpectNoNewSamples("Precache.DownloadedNonPrecache.Cellular");
294   ExpectNewSample("Precache.Saved", kSize);
295   ExpectNewSample("Precache.Saved.Cellular", kSize);
296 }
297
298 TEST_F(PrecacheDatabaseTest, FetchFromCacheWithoutURLTableEntry) {
299   RecordFetchFromCache(kURL, kFetchTime, kSize);
300
301   EXPECT_TRUE(GetActualURLTableMap().empty());
302
303   ExpectNoNewSamples("Precache.DownloadedPrecacheMotivated");
304   ExpectNoNewSamples("Precache.DownloadedNonPrecache");
305   ExpectNoNewSamples("Precache.DownloadedNonPrecache.Cellular");
306   ExpectNoNewSamples("Precache.Saved");
307   ExpectNoNewSamples("Precache.Saved.Cellular");
308 }
309
310 TEST_F(PrecacheDatabaseTest, DeleteExpiredPrecacheHistory) {
311   const base::Time kToday = base::Time() + base::TimeDelta::FromDays(1000);
312   const base::Time k59DaysAgo = kToday - base::TimeDelta::FromDays(59);
313   const base::Time k61DaysAgo = kToday - base::TimeDelta::FromDays(61);
314
315   precache_url_table()->AddURL(GURL("http://expired-precache.com"), k61DaysAgo);
316   precache_url_table()->AddURL(GURL("http://old-precache.com"), k59DaysAgo);
317
318   precache_database_->DeleteExpiredPrecacheHistory(kToday);
319
320   EXPECT_EQ(BuildURLTableMap(GURL("http://old-precache.com"), k59DaysAgo),
321             GetActualURLTableMap());
322 }
323
324 TEST_F(PrecacheDatabaseTest, SampleInteraction) {
325   const GURL kURL1("http://url1.com");
326   const int64 kSize1 = 1000;
327   const GURL kURL2("http://url2.com");
328   const int64 kSize2 = 2000;
329   const GURL kURL3("http://url3.com");
330   const int64 kSize3 = 3000;
331   const GURL kURL4("http://url4.com");
332   const int64 kSize4 = 4000;
333   const GURL kURL5("http://url5.com");
334   const int64 kSize5 = 5000;
335
336   RecordPrecacheFromNetwork(kURL1, kFetchTime, kSize1);
337   RecordPrecacheFromNetwork(kURL2, kFetchTime, kSize2);
338   RecordPrecacheFromNetwork(kURL3, kFetchTime, kSize3);
339   RecordPrecacheFromNetwork(kURL4, kFetchTime, kSize4);
340
341   RecordFetchFromCacheCellular(kURL1, kFetchTime, kSize1);
342   RecordFetchFromCacheCellular(kURL1, kFetchTime, kSize1);
343   RecordFetchFromNetworkCellular(kURL2, kFetchTime, kSize2);
344   RecordFetchFromNetworkCellular(kURL5, kFetchTime, kSize5);
345   RecordFetchFromCacheCellular(kURL5, kFetchTime, kSize5);
346
347   RecordPrecacheFromCache(kURL1, kFetchTime, kSize1);
348   RecordPrecacheFromNetwork(kURL2, kFetchTime, kSize2);
349   RecordPrecacheFromCache(kURL3, kFetchTime, kSize3);
350   RecordPrecacheFromCache(kURL4, kFetchTime, kSize4);
351
352   RecordFetchFromCache(kURL1, kFetchTime, kSize1);
353   RecordFetchFromNetwork(kURL2, kFetchTime, kSize2);
354   RecordFetchFromCache(kURL3, kFetchTime, kSize3);
355   RecordFetchFromCache(kURL5, kFetchTime, kSize5);
356
357   scoped_ptr<base::HistogramSamples> downloaded_precache_motivated_bytes(
358       GetHistogramSamplesDelta("Precache.DownloadedPrecacheMotivated"));
359   EXPECT_EQ(5, downloaded_precache_motivated_bytes->TotalCount());
360   EXPECT_EQ(1, downloaded_precache_motivated_bytes->GetCount(kSize1));
361   EXPECT_EQ(2, downloaded_precache_motivated_bytes->GetCount(kSize2));
362   EXPECT_EQ(1, downloaded_precache_motivated_bytes->GetCount(kSize3));
363   EXPECT_EQ(1, downloaded_precache_motivated_bytes->GetCount(kSize4));
364
365   scoped_ptr<base::HistogramSamples> downloaded_non_precache_bytes(
366       GetHistogramSamplesDelta("Precache.DownloadedNonPrecache"));
367   EXPECT_EQ(3, downloaded_non_precache_bytes->TotalCount());
368   EXPECT_EQ(2, downloaded_non_precache_bytes->GetCount(kSize2));
369   EXPECT_EQ(1, downloaded_non_precache_bytes->GetCount(kSize5));
370
371   scoped_ptr<base::HistogramSamples> downloaded_non_precache_bytes_cellular(
372       GetHistogramSamplesDelta("Precache.DownloadedNonPrecache.Cellular"));
373   EXPECT_EQ(2, downloaded_non_precache_bytes_cellular->TotalCount());
374   EXPECT_EQ(1, downloaded_non_precache_bytes_cellular->GetCount(kSize2));
375   EXPECT_EQ(1, downloaded_non_precache_bytes_cellular->GetCount(kSize5));
376
377   scoped_ptr<base::HistogramSamples> saved_bytes(
378       GetHistogramSamplesDelta("Precache.Saved"));
379   EXPECT_EQ(2, saved_bytes->TotalCount());
380   EXPECT_EQ(1, saved_bytes->GetCount(kSize1));
381   EXPECT_EQ(1, saved_bytes->GetCount(kSize3));
382
383   scoped_ptr<base::HistogramSamples> saved_bytes_cellular(
384       GetHistogramSamplesDelta("Precache.Saved.Cellular"));
385   EXPECT_EQ(1, saved_bytes_cellular->TotalCount());
386   EXPECT_EQ(1, saved_bytes_cellular->GetCount(kSize1));
387 }
388
389 }  // namespace
390
391 }  // namespace precache