| Index: components/precache/core/precache_database_unittest.cc | 
| diff --git a/components/precache/core/precache_database_unittest.cc b/components/precache/core/precache_database_unittest.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..4e23a201c3704619450ace5b927500a7c098374c | 
| --- /dev/null | 
| +++ b/components/precache/core/precache_database_unittest.cc | 
| @@ -0,0 +1,454 @@ | 
| +// Copyright 2013 The Chromium Authors. All rights reserved. | 
| +// Use of this source code is governed by a BSD-style license that can be | 
| +// found in the LICENSE file. | 
| + | 
| +#include "components/precache/core/precache_database.h" | 
| + | 
| +#include <map> | 
| +#include <string> | 
| + | 
| +#include "base/basictypes.h" | 
| +#include "base/bind.h" | 
| +#include "base/bind_helpers.h" | 
| +#include "base/callback.h" | 
| +#include "base/logging.h" | 
| +#include "base/metrics/histogram.h" | 
| +#include "base/metrics/histogram_samples.h" | 
| +#include "base/metrics/statistics_recorder.h" | 
| +#include "base/time/time.h" | 
| +#include "components/precache/core/precache_statistics_table.h" | 
| +#include "components/precache/core/precache_url_table.h" | 
| +#include "sql/connection.h" | 
| +#include "testing/gtest/include/gtest/gtest.h" | 
| +#include "url/gurl.h" | 
| + | 
| +namespace { | 
| + | 
| +typedef precache::PrecacheStatisticsTable::PrecacheStatistics | 
| +    PrecacheStatistics; | 
| + | 
| +std::map<GURL, base::Time> BuildURLTableMap(const GURL& url, | 
| +                                            const base::Time& precache_time) { | 
| +  std::map<GURL, base::Time> url_table_map; | 
| +  url_table_map[url] = precache_time; | 
| +  return url_table_map; | 
| +} | 
| + | 
| +std::map<base::Time, PrecacheStatistics> BuildStatsMap( | 
| +    const base::Time& day, const PrecacheStatistics& stats) { | 
| +  std::map<base::Time, PrecacheStatistics> stats_map; | 
| +  stats_map[day] = stats; | 
| +  return stats_map; | 
| +} | 
| + | 
| +std::map<base::Time, PrecacheStatistics> BuildStatsMap( | 
| +    const base::Time& day, int64 precached_bytes, int64 downloaded_bytes, | 
| +    int64 downloaded_bytes_cellular, int64 saved_bytes, | 
| +    int64 saved_bytes_cellular) { | 
| +  return BuildStatsMap( | 
| +      day, PrecacheStatistics(precached_bytes, downloaded_bytes, | 
| +                              downloaded_bytes_cellular, saved_bytes, | 
| +                              saved_bytes_cellular)); | 
| +} | 
| + | 
| +scoped_ptr<base::HistogramSamples> GetHistogramSamples( | 
| +    const std::string& histogram_name) { | 
| +  base::HistogramBase* histogram = | 
| +      base::StatisticsRecorder::FindHistogram(histogram_name); | 
| + | 
| +  EXPECT_NE(static_cast<base::HistogramBase*>(NULL), histogram); | 
| + | 
| +  return histogram->SnapshotSamples().Pass(); | 
| +} | 
| + | 
| +void ExpectHistogramSamples(const std::string& histogram_name, int64 sample1, | 
| +                            int64 sample2) { | 
| +  scoped_ptr<base::HistogramSamples> samples( | 
| +      GetHistogramSamples(histogram_name)); | 
| + | 
| +  EXPECT_EQ(2, samples->TotalCount()); | 
| + | 
| +  if (sample1 == sample2) { | 
| +    EXPECT_EQ(2, samples->GetCount(sample1)); | 
| +    return; | 
| +  } | 
| + | 
| +  EXPECT_EQ(1, samples->GetCount(sample1)); | 
| +  EXPECT_EQ(1, samples->GetCount(sample2)); | 
| +} | 
| + | 
| +const GURL kURL("http://url.com"); | 
| +const base::Time kFetchTime = | 
| +    base::Time::UnixEpoch() + base::TimeDelta::FromHours(100); | 
| +const base::Time kFetchDay = kFetchTime.LocalMidnight(); | 
| +const int64 kSize = 5000; | 
| + | 
| +}  // namespace | 
| + | 
| +namespace precache { | 
| + | 
| +class PrecacheDatabaseTest : public testing::Test { | 
| + public: | 
| +  PrecacheDatabaseTest() {} | 
| +  virtual ~PrecacheDatabaseTest() {} | 
| + | 
| + protected: | 
| +  virtual void SetUp() { | 
| +    precache_database_ = new PrecacheDatabase(); | 
| +    sql::Connection* db = new sql::Connection(); | 
| +    ASSERT_TRUE(db->OpenInMemory()); | 
| +    precache_database_->Init(db); | 
| +  } | 
| + | 
| +  std::map<GURL, base::Time> GetActualURLTableMap() { | 
| +    std::map<GURL, base::Time> url_table_map; | 
| +    precache_database_->precache_url_table_->GetAllDataForTesting( | 
| +        &url_table_map); | 
| +    return url_table_map; | 
| +  } | 
| + | 
| +  std::map<base::Time, PrecacheStatistics> GetActualStatsMap() { | 
| +    std::map<base::Time, PrecacheStatistics> stats_map; | 
| +    precache_database_->precache_statistics_table_->GetAllStatsBetween( | 
| +        base::Time::FromInternalValue(0), base::Time::Max(), &stats_map); | 
| +    return stats_map; | 
| +  } | 
| + | 
| +  PrecacheURLTable* precache_url_table() { | 
| +    return precache_database_->precache_url_table_.get(); | 
| +  } | 
| + | 
| +  PrecacheStatisticsTable* precache_statistics_table() { | 
| +    return precache_database_->precache_statistics_table_.get(); | 
| +  } | 
| + | 
| +  // Convenience methods for recording different types of URL fetches. These | 
| +  // exist to improve the readability of the sample interaction test. | 
| +  void RecordPrecacheFromNetwork(const GURL& url, const base::Time& fetch_time, | 
| +                                 int64 size); | 
| +  void RecordPrecacheFromCache(const GURL& url, const base::Time& fetch_time, | 
| +                               int64 size); | 
| +  void RecordFetchFromNetwork(const GURL& url, const base::Time& fetch_time, | 
| +                              int64 size); | 
| +  void RecordFetchFromNetworkCellular(const GURL& url, | 
| +                                      const base::Time& fetch_time, int64 size); | 
| +  void RecordFetchFromCache(const GURL& url, const base::Time& fetch_time, | 
| +                            int64 size); | 
| +  void RecordFetchFromCacheCellular(const GURL& url, | 
| +                                    const base::Time& fetch_time, int64 size); | 
| + | 
| +  scoped_refptr<PrecacheDatabase> precache_database_; | 
| +}; | 
| + | 
| +void PrecacheDatabaseTest::RecordPrecacheFromNetwork( | 
| +    const GURL& url, const base::Time& fetch_time, int64 size) { | 
| +  precache_database_->RecordURLFetched( | 
| +      url, fetch_time, size, false /* was_cached */, true /* is_precaching */, | 
| +      false /* is_cellular */); | 
| +} | 
| + | 
| +void PrecacheDatabaseTest::RecordPrecacheFromCache(const GURL& url, | 
| +                                                   const base::Time& fetch_time, | 
| +                                                   int64 size) { | 
| +  precache_database_->RecordURLFetched( | 
| +      url, fetch_time, size, true /* was_cached */, true /* is_precaching */, | 
| +      false /* is_cellular */); | 
| +} | 
| + | 
| +void PrecacheDatabaseTest::RecordFetchFromNetwork(const GURL& url, | 
| +                                                  const base::Time& fetch_time, | 
| +                                                  int64 size) { | 
| +  precache_database_->RecordURLFetched( | 
| +      url, fetch_time, size, false /* was_cached */, false /* is_precaching */, | 
| +      false /* is_cellular */); | 
| +} | 
| + | 
| +void PrecacheDatabaseTest::RecordFetchFromNetworkCellular( | 
| +    const GURL& url, const base::Time& fetch_time, int64 size) { | 
| +  precache_database_->RecordURLFetched( | 
| +      url, fetch_time, size, false /* was_cached */, false /* is_precaching */, | 
| +      true /* is_cellular */); | 
| +} | 
| + | 
| +void PrecacheDatabaseTest::RecordFetchFromCache(const GURL& url, | 
| +                                                const base::Time& fetch_time, | 
| +                                                int64 size) { | 
| +  precache_database_->RecordURLFetched( | 
| +      url, fetch_time, size, true /* was_cached */, false /* is_precaching */, | 
| +      false /* is_cellular */); | 
| +} | 
| + | 
| +void PrecacheDatabaseTest::RecordFetchFromCacheCellular( | 
| +    const GURL& url, const base::Time& fetch_time, int64 size) { | 
| +  precache_database_->RecordURLFetched( | 
| +      url, fetch_time, size, true /* was_cached */, false /* is_precaching */, | 
| +      true /* is_cellular */); | 
| +} | 
| + | 
| +namespace { | 
| + | 
| +TEST_F(PrecacheDatabaseTest, PrecacheOverNetwork) { | 
| +  precache_database_->RecordURLFetched( | 
| +      kURL, kFetchTime, kSize, false /* was_cached */, true /* is_precaching */, | 
| +      false /* is_cellular */); | 
| + | 
| +  EXPECT_EQ(BuildURLTableMap(kURL, kFetchTime), GetActualURLTableMap()); | 
| +  EXPECT_EQ(BuildStatsMap(kFetchDay, kSize /* precached_bytes */, 0, 0, 0, 0), | 
| +            GetActualStatsMap()); | 
| +} | 
| + | 
| +TEST_F(PrecacheDatabaseTest, PrecacheFromCacheWithURLTableEntry) { | 
| +  precache_url_table()->AddURL(kURL, kFetchTime - base::TimeDelta::FromDays(1)); | 
| + | 
| +  precache_database_->RecordURLFetched( | 
| +      kURL, kFetchTime, kSize, true /* was_cached */, true /* is_precaching */, | 
| +      false /* is_cellular */); | 
| + | 
| +  // The URL table entry should have been updated to have |kFetchTime| as the | 
| +  // timestamp. | 
| +  EXPECT_EQ(BuildURLTableMap(kURL, kFetchTime), GetActualURLTableMap()); | 
| +  EXPECT_TRUE(GetActualStatsMap().empty()); | 
| +} | 
| + | 
| +TEST_F(PrecacheDatabaseTest, PrecacheFromCacheWithoutURLTableEntry) { | 
| +  precache_database_->RecordURLFetched( | 
| +      kURL, kFetchTime, kSize, true /* was_cached */, true /* is_precaching */, | 
| +      false /* is_cellular */); | 
| + | 
| +  EXPECT_TRUE(GetActualURLTableMap().empty()); | 
| +  EXPECT_TRUE(GetActualStatsMap().empty()); | 
| +} | 
| + | 
| +TEST_F(PrecacheDatabaseTest, FetchOverNetwork_NonCellular) { | 
| +  precache_database_->RecordURLFetched( | 
| +      kURL, kFetchTime, kSize, false /* was_cached */, | 
| +      false /* is_precaching */, false /* is_cellular */); | 
| + | 
| +  EXPECT_TRUE(GetActualURLTableMap().empty()); | 
| +  EXPECT_EQ(BuildStatsMap(kFetchDay, 0, kSize /* downloaded_bytes */, 0, 0, 0), | 
| +            GetActualStatsMap()); | 
| +} | 
| + | 
| +TEST_F(PrecacheDatabaseTest, FetchOverNetwork_Cellular) { | 
| +  precache_database_->RecordURLFetched( | 
| +      kURL, kFetchTime, kSize, false /* was_cached */, | 
| +      false /* is_precaching */, true /* is_cellular */); | 
| + | 
| +  EXPECT_TRUE(GetActualURLTableMap().empty()); | 
| +  EXPECT_EQ(BuildStatsMap(kFetchDay, 0, kSize /* downloaded_bytes */, | 
| +                          kSize /* downloaded_bytes_cellular */, 0, 0), | 
| +            GetActualStatsMap()); | 
| +} | 
| + | 
| +TEST_F(PrecacheDatabaseTest, FetchOverNetworkWithURLTableEntry) { | 
| +  precache_url_table()->AddURL(kURL, kFetchTime - base::TimeDelta::FromDays(1)); | 
| + | 
| +  precache_database_->RecordURLFetched( | 
| +      kURL, kFetchTime, kSize, false /* was_cached */, | 
| +      false /* is_precaching */, false /* is_cellular */); | 
| + | 
| +  // The URL table entry should have been deleted. | 
| +  EXPECT_TRUE(GetActualURLTableMap().empty()); | 
| +  EXPECT_EQ(BuildStatsMap(kFetchDay, 0, kSize /* downloaded_bytes */, 0, 0, 0), | 
| +            GetActualStatsMap()); | 
| +} | 
| + | 
| +TEST_F(PrecacheDatabaseTest, FetchFromCacheWithURLTableEntry_NonCellular) { | 
| +  precache_url_table()->AddURL(kURL, kFetchTime - base::TimeDelta::FromDays(1)); | 
| + | 
| +  precache_database_->RecordURLFetched( | 
| +      kURL, kFetchTime, kSize, true /* was_cached */, false /* is_precaching */, | 
| +      false /* is_cellular */); | 
| + | 
| +  // The URL table entry should have been deleted. | 
| +  EXPECT_TRUE(GetActualURLTableMap().empty()); | 
| +  EXPECT_EQ(BuildStatsMap(kFetchDay, 0, 0, 0, kSize /* saved_bytes */, 0), | 
| +            GetActualStatsMap()); | 
| +} | 
| + | 
| +TEST_F(PrecacheDatabaseTest, FetchFromCacheWithURLTableEntry_Cellular) { | 
| +  precache_url_table()->AddURL(kURL, kFetchTime - base::TimeDelta::FromDays(1)); | 
| + | 
| +  precache_database_->RecordURLFetched( | 
| +      kURL, kFetchTime, kSize, true /* was_cached */, false /* is_precaching */, | 
| +      true /* is_cellular */); | 
| + | 
| +  // The URL table entry should have been deleted. | 
| +  EXPECT_TRUE(GetActualURLTableMap().empty()); | 
| +  EXPECT_EQ(BuildStatsMap(kFetchDay, 0, 0, 0, kSize /* saved_bytes */, | 
| +                          kSize /* saved_bytes_cellular */), | 
| +            GetActualStatsMap()); | 
| +} | 
| + | 
| +TEST_F(PrecacheDatabaseTest, FetchFromCacheWithoutURLTableEntry) { | 
| +  precache_database_->RecordURLFetched( | 
| +      kURL, kFetchTime, kSize, true /* was_cached */, false /* is_precaching */, | 
| +      false /* is_cellular */); | 
| + | 
| +  EXPECT_TRUE(GetActualURLTableMap().empty()); | 
| +  EXPECT_TRUE(GetActualStatsMap().empty()); | 
| +} | 
| + | 
| +TEST_F(PrecacheDatabaseTest, ReportAndDeleteOldStats) { | 
| +  base::StatisticsRecorder::Initialize(); | 
| + | 
| +  const base::Time kEndDate = | 
| +      base::Time::UnixEpoch() + base::TimeDelta::FromDays(1000); | 
| + | 
| +  precache_url_table()->AddURL(GURL("http://expired-precache.com"), | 
| +                               kEndDate - base::TimeDelta::FromDays(61)); | 
| +  precache_url_table()->AddURL(GURL("http://old-precache.com"), | 
| +                               kEndDate - base::TimeDelta::FromDays(59)); | 
| + | 
| +  const PrecacheStatistics kWeekOldStats(5000, 4000, 3000, 2000, 1000); | 
| +  const PrecacheStatistics kDayOldStats(50000, 40000, 30000, 20000, 10000); | 
| +  const PrecacheStatistics kCurrentStats(500000, 400000, 300000, 200000, | 
| +                                         100000); | 
| + | 
| +  precache_statistics_table()->IncreaseStatsForFetch( | 
| +      kEndDate - base::TimeDelta::FromDays(6), kWeekOldStats); | 
| +  precache_statistics_table()->IncreaseStatsForFetch(kEndDate, kDayOldStats); | 
| +  precache_statistics_table()->IncreaseStatsForFetch( | 
| +      kEndDate + base::TimeDelta::FromDays(1), kCurrentStats); | 
| + | 
| +  precache_database_->ReportAndDeleteOldStats(kEndDate); | 
| + | 
| +  EXPECT_EQ(BuildURLTableMap(GURL("http://old-precache.com"), | 
| +                             kEndDate - base::TimeDelta::FromDays(59)), | 
| +            GetActualURLTableMap()); | 
| + | 
| +  EXPECT_EQ( | 
| +      BuildStatsMap((kEndDate + base::TimeDelta::FromDays(1)).LocalMidnight(), | 
| +                    kCurrentStats), | 
| +      GetActualStatsMap()); | 
| + | 
| +  ExpectHistogramSamples("Precache.DailyPrecachedBytes", | 
| +                         kWeekOldStats.precached_bytes, | 
| +                         kDayOldStats.precached_bytes); | 
| +  ExpectHistogramSamples("Precache.DailyDownloadedBytes", | 
| +                         kWeekOldStats.downloaded_bytes, | 
| +                         kDayOldStats.downloaded_bytes); | 
| +  ExpectHistogramSamples("Precache.DailyDownloadedBytes.Cellular", | 
| +                         kWeekOldStats.downloaded_bytes_cellular, | 
| +                         kDayOldStats.downloaded_bytes_cellular); | 
| +  ExpectHistogramSamples("Precache.DailySavedBytes", kWeekOldStats.saved_bytes, | 
| +                         kDayOldStats.saved_bytes); | 
| +  ExpectHistogramSamples("Precache.DailySavedBytes.Cellular", | 
| +                         kWeekOldStats.saved_bytes_cellular, | 
| +                         kDayOldStats.saved_bytes_cellular); | 
| +  ExpectHistogramSamples("Precache.DailySavingsPercentage", 33, 33); | 
| +  ExpectHistogramSamples("Precache.DailySavingsPercentage.Cellular", 25, 25); | 
| +} | 
| + | 
| +TEST_F(PrecacheDatabaseTest, SampleInteraction) { | 
| +  const GURL kURL1("http://url1.com"); | 
| +  const int64 kSize1 = 1000; | 
| +  const GURL kURL2("http://url2.com"); | 
| +  const int64 kSize2 = 2000; | 
| +  const GURL kURL3("http://url3.com"); | 
| +  const int64 kSize3 = 3000; | 
| +  const GURL kURL4("http://url4.com"); | 
| +  const int64 kSize4 = 4000; | 
| +  const GURL kURL5("http://url5.com"); | 
| +  const int64 kSize5 = 5000; | 
| + | 
| +  const base::Time kFetchDay1 = | 
| +      (base::Time::UnixEpoch() + base::TimeDelta::FromHours(1000)) | 
| +          .LocalMidnight(); | 
| +  const base::Time kFetchDay2 = | 
| +      (kFetchDay1 + base::TimeDelta::FromHours(30)).LocalMidnight(); | 
| +  const base::TimeDelta kFetchPeriod = base::TimeDelta::FromMilliseconds(100); | 
| + | 
| +  std::map<base::Time, PrecacheStatistics> expected_stats_map; | 
| + | 
| +  // Start of day 1. | 
| +  base::Time fetch_time = kFetchDay1; | 
| + | 
| +  // Precache URL 1 from network. | 
| +  RecordPrecacheFromNetwork(kURL1, fetch_time += kFetchPeriod, kSize1); | 
| +  expected_stats_map[kFetchDay1].precached_bytes += kSize1; | 
| +  EXPECT_EQ(expected_stats_map, GetActualStatsMap()); | 
| + | 
| +  // Precache URL 2 from network. | 
| +  RecordPrecacheFromNetwork(kURL2, fetch_time += kFetchPeriod, kSize2); | 
| +  expected_stats_map[kFetchDay1].precached_bytes += kSize2; | 
| +  EXPECT_EQ(expected_stats_map, GetActualStatsMap()); | 
| + | 
| +  // Precache URL 3 from network. | 
| +  RecordPrecacheFromNetwork(kURL3, fetch_time += kFetchPeriod, kSize3); | 
| +  expected_stats_map[kFetchDay1].precached_bytes += kSize3; | 
| +  EXPECT_EQ(expected_stats_map, GetActualStatsMap()); | 
| + | 
| +  // Precache URL 4 from network. | 
| +  RecordPrecacheFromNetwork(kURL4, fetch_time += kFetchPeriod, kSize4); | 
| +  expected_stats_map[kFetchDay1].precached_bytes += kSize4; | 
| +  EXPECT_EQ(expected_stats_map, GetActualStatsMap()); | 
| + | 
| +  // Fetch URL 1 from cache when on a cellular network. | 
| +  RecordFetchFromCacheCellular(kURL1, fetch_time += kFetchPeriod, kSize1); | 
| +  expected_stats_map[kFetchDay1].saved_bytes += kSize1; | 
| +  expected_stats_map[kFetchDay1].saved_bytes_cellular += kSize1; | 
| +  EXPECT_EQ(expected_stats_map, GetActualStatsMap()); | 
| + | 
| +  // Fetch URL 1 from cache when on a cellular network. | 
| +  RecordFetchFromCacheCellular(kURL1, fetch_time += kFetchPeriod, kSize1); | 
| +  EXPECT_EQ(expected_stats_map, GetActualStatsMap()); | 
| + | 
| +  // Fetch URL 2 from network when on a cellular network. | 
| +  RecordFetchFromNetworkCellular(kURL2, fetch_time += kFetchPeriod, kSize2); | 
| +  expected_stats_map[kFetchDay1].downloaded_bytes += kSize2; | 
| +  expected_stats_map[kFetchDay1].downloaded_bytes_cellular += kSize2; | 
| +  EXPECT_EQ(expected_stats_map, GetActualStatsMap()); | 
| + | 
| +  // Fetch URL 5 from network when on a cellular network. | 
| +  RecordFetchFromNetworkCellular(kURL5, fetch_time += kFetchPeriod, kSize5); | 
| +  expected_stats_map[kFetchDay1].downloaded_bytes += kSize5; | 
| +  expected_stats_map[kFetchDay1].downloaded_bytes_cellular += kSize5; | 
| +  EXPECT_EQ(expected_stats_map, GetActualStatsMap()); | 
| + | 
| +  // Fetch URL 5 from cache when on a cellular network. | 
| +  RecordFetchFromCacheCellular(kURL5, fetch_time += kFetchPeriod, kSize5); | 
| +  EXPECT_EQ(expected_stats_map, GetActualStatsMap()); | 
| + | 
| +  // Day 1 ends, day 2 begins. | 
| +  fetch_time = kFetchDay2; | 
| + | 
| +  // Precache URL 1 from cache. | 
| +  RecordPrecacheFromCache(kURL1, fetch_time += kFetchPeriod, kSize1); | 
| +  EXPECT_EQ(expected_stats_map, GetActualStatsMap()); | 
| + | 
| +  // Precache URL 2 from network. | 
| +  RecordPrecacheFromNetwork(kURL2, fetch_time += kFetchPeriod, kSize2); | 
| +  expected_stats_map[kFetchDay2].precached_bytes += kSize2; | 
| +  EXPECT_EQ(expected_stats_map, GetActualStatsMap()); | 
| + | 
| +  // Precache URL 3 from cache. | 
| +  RecordPrecacheFromCache(kURL3, fetch_time += kFetchPeriod, kSize3); | 
| +  EXPECT_EQ(expected_stats_map, GetActualStatsMap()); | 
| + | 
| +  // Precache URL 4 from cache. | 
| +  RecordPrecacheFromCache(kURL4, fetch_time += kFetchPeriod, kSize4); | 
| +  EXPECT_EQ(expected_stats_map, GetActualStatsMap()); | 
| + | 
| +  // Fetch URL 1 from cache. | 
| +  RecordFetchFromCache(kURL1, fetch_time += kFetchPeriod, kSize1); | 
| +  EXPECT_EQ(expected_stats_map, GetActualStatsMap()); | 
| + | 
| +  // Fetch URL 2 from network. | 
| +  RecordFetchFromNetwork(kURL2, fetch_time += kFetchPeriod, kSize2); | 
| +  expected_stats_map[kFetchDay2].downloaded_bytes += kSize2; | 
| +  EXPECT_EQ(expected_stats_map, GetActualStatsMap()); | 
| + | 
| +  // Fetch URL 3 from cache. | 
| +  RecordFetchFromCache(kURL3, fetch_time += kFetchPeriod, kSize3); | 
| +  expected_stats_map[kFetchDay2].saved_bytes += kSize3; | 
| +  EXPECT_EQ(expected_stats_map, GetActualStatsMap()); | 
| + | 
| +  // Fetch URL 5 from cache. | 
| +  RecordFetchFromCache(kURL5, fetch_time += kFetchPeriod, kSize5); | 
| +  EXPECT_EQ(expected_stats_map, GetActualStatsMap()); | 
| +} | 
| + | 
| +}  // namespace | 
| + | 
| +}  // namespace precache | 
|  |