Home | History | Annotate | Download | only in simple
      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 "net/disk_cache/simple/simple_version_upgrade.h"
      6 
      7 #include "base/basictypes.h"
      8 #include "base/file_util.h"
      9 #include "base/files/file_path.h"
     10 #include "base/files/scoped_temp_dir.h"
     11 #include "base/format_macros.h"
     12 #include "base/strings/stringprintf.h"
     13 #include "net/base/net_errors.h"
     14 #include "net/disk_cache/simple/simple_backend_version.h"
     15 #include "net/disk_cache/simple/simple_entry_format_history.h"
     16 #include "testing/gtest/include/gtest/gtest.h"
     17 
     18 // The migration process relies on ability to rename newly created files, which
     19 // could be problematic on Windows XP.
     20 #if defined(OS_POSIX)
     21 
     22 namespace {
     23 
     24 // Same as |disk_cache::kSimpleInitialMagicNumber|.
     25 const uint64 kSimpleInitialMagicNumber = GG_UINT64_C(0xfcfb6d1ba7725c30);
     26 
     27 // The "fake index" file that cache backends use to distinguish whether the
     28 // cache belongs to one backend or another.
     29 const char kFakeIndexFileName[] = "index";
     30 
     31 // Same as |SimpleIndexFile::kIndexFileName|.
     32 const char kIndexFileName[] = "the-real-index";
     33 
     34 bool WriteFakeIndexFileV5(const base::FilePath& cache_path) {
     35   disk_cache::FakeIndexData data;
     36   data.version = 5;
     37   data.initial_magic_number = kSimpleInitialMagicNumber;
     38   data.unused_must_be_zero1 = 0;
     39   data.unused_must_be_zero2 = 0;
     40   const base::FilePath file_name = cache_path.AppendASCII("index");
     41   return sizeof(data) ==
     42          base::WriteFile(
     43              file_name, reinterpret_cast<const char*>(&data), sizeof(data));
     44 }
     45 
     46 TEST(SimpleVersionUpgradeTest, FailsToMigrateBackwards) {
     47   base::ScopedTempDir cache_dir;
     48   ASSERT_TRUE(cache_dir.CreateUniqueTempDir());
     49   const base::FilePath cache_path = cache_dir.path();
     50 
     51   disk_cache::FakeIndexData data;
     52   data.version = 100500;
     53   data.initial_magic_number = kSimpleInitialMagicNumber;
     54   data.unused_must_be_zero1 = 0;
     55   data.unused_must_be_zero2 = 0;
     56   const base::FilePath file_name = cache_path.AppendASCII(kFakeIndexFileName);
     57   ASSERT_EQ(implicit_cast<int>(sizeof(data)),
     58             base::WriteFile(
     59                 file_name, reinterpret_cast<const char*>(&data), sizeof(data)));
     60   EXPECT_FALSE(disk_cache::UpgradeSimpleCacheOnDisk(cache_dir.path()));
     61 }
     62 
     63 TEST(SimpleVersionUpgradeTest, FakeIndexVersionGetsUpdated) {
     64   base::ScopedTempDir cache_dir;
     65   ASSERT_TRUE(cache_dir.CreateUniqueTempDir());
     66   const base::FilePath cache_path = cache_dir.path();
     67 
     68   WriteFakeIndexFileV5(cache_path);
     69   const std::string file_contents("incorrectly serialized data");
     70   const base::FilePath index_file = cache_path.AppendASCII(kIndexFileName);
     71   ASSERT_EQ(implicit_cast<int>(file_contents.size()),
     72             base::WriteFile(
     73                 index_file, file_contents.data(), file_contents.size()));
     74 
     75   // Upgrade.
     76   ASSERT_TRUE(disk_cache::UpgradeSimpleCacheOnDisk(cache_path));
     77 
     78   // Check that the version in the fake index file is updated.
     79   std::string new_fake_index_contents;
     80   ASSERT_TRUE(base::ReadFileToString(cache_path.AppendASCII(kFakeIndexFileName),
     81                                      &new_fake_index_contents));
     82   const disk_cache::FakeIndexData* fake_index_header;
     83   EXPECT_EQ(sizeof(*fake_index_header), new_fake_index_contents.size());
     84   fake_index_header = reinterpret_cast<const disk_cache::FakeIndexData*>(
     85       new_fake_index_contents.data());
     86   EXPECT_EQ(disk_cache::kSimpleVersion, fake_index_header->version);
     87   EXPECT_EQ(kSimpleInitialMagicNumber, fake_index_header->initial_magic_number);
     88 }
     89 
     90 TEST(SimpleVersionUpgradeTest, UpgradeV5V6IndexMustDisappear) {
     91   base::ScopedTempDir cache_dir;
     92   ASSERT_TRUE(cache_dir.CreateUniqueTempDir());
     93   const base::FilePath cache_path = cache_dir.path();
     94 
     95   WriteFakeIndexFileV5(cache_path);
     96   const std::string file_contents("incorrectly serialized data");
     97   const base::FilePath index_file = cache_path.AppendASCII(kIndexFileName);
     98   ASSERT_EQ(implicit_cast<int>(file_contents.size()),
     99             base::WriteFile(
    100                 index_file, file_contents.data(), file_contents.size()));
    101 
    102   // Create a few entry-like files.
    103   const uint64 kEntries = 5;
    104   for (uint64 entry_hash = 0; entry_hash < kEntries; ++entry_hash) {
    105     for (int index = 0; index < 3; ++index) {
    106       std::string file_name =
    107           base::StringPrintf("%016" PRIx64 "_%1d", entry_hash, index);
    108       std::string entry_contents =
    109           file_contents +
    110           base::StringPrintf(" %" PRIx64, implicit_cast<uint64>(entry_hash));
    111       ASSERT_EQ(implicit_cast<int>(entry_contents.size()),
    112                 base::WriteFile(cache_path.AppendASCII(file_name),
    113                                      entry_contents.data(),
    114                                      entry_contents.size()));
    115     }
    116   }
    117 
    118   // Upgrade.
    119   ASSERT_TRUE(disk_cache::UpgradeIndexV5V6(cache_path));
    120 
    121   // Check that the old index disappeared but the files remain unchanged.
    122   EXPECT_FALSE(base::PathExists(index_file));
    123   for (uint64 entry_hash = 0; entry_hash < kEntries; ++entry_hash) {
    124     for (int index = 0; index < 3; ++index) {
    125       std::string file_name =
    126           base::StringPrintf("%016" PRIx64 "_%1d", entry_hash, index);
    127       std::string expected_contents =
    128           file_contents +
    129           base::StringPrintf(" %" PRIx64, implicit_cast<uint64>(entry_hash));
    130       std::string real_contents;
    131       EXPECT_TRUE(base::ReadFileToString(cache_path.AppendASCII(file_name),
    132                                          &real_contents));
    133       EXPECT_EQ(expected_contents, real_contents);
    134     }
    135   }
    136 }
    137 
    138 }  // namespace
    139 
    140 #endif  // defined(OS_POSIX)
    141