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.
5 #include "net/disk_cache/simple/simple_version_upgrade.h"
7 #include "base/basictypes.h"
8 #include "base/files/file_path.h"
9 #include "base/files/file_util.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"
18 // The migration process relies on ability to rename newly created files, which
19 // could be problematic on Windows XP.
24 // Same as |disk_cache::kSimpleInitialMagicNumber|.
25 const uint64 kSimpleInitialMagicNumber
= GG_UINT64_C(0xfcfb6d1ba7725c30);
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";
31 // Same as |SimpleIndexFile::kIndexFileName|.
32 const char kIndexFileName
[] = "the-real-index";
34 bool WriteFakeIndexFileV5(const base::FilePath
& cache_path
) {
35 disk_cache::FakeIndexData data
;
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
) ==
43 file_name
, reinterpret_cast<const char*>(&data
), sizeof(data
));
46 TEST(SimpleVersionUpgradeTest
, FailsToMigrateBackwards
) {
47 base::ScopedTempDir cache_dir
;
48 ASSERT_TRUE(cache_dir
.CreateUniqueTempDir());
49 const base::FilePath cache_path
= cache_dir
.path();
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
)),
59 file_name
, reinterpret_cast<const char*>(&data
), sizeof(data
)));
60 EXPECT_FALSE(disk_cache::UpgradeSimpleCacheOnDisk(cache_dir
.path()));
63 TEST(SimpleVersionUpgradeTest
, FakeIndexVersionGetsUpdated
) {
64 base::ScopedTempDir cache_dir
;
65 ASSERT_TRUE(cache_dir
.CreateUniqueTempDir());
66 const base::FilePath cache_path
= cache_dir
.path();
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()),
73 index_file
, file_contents
.data(), file_contents
.size()));
76 ASSERT_TRUE(disk_cache::UpgradeSimpleCacheOnDisk(cache_path
));
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
);
90 TEST(SimpleVersionUpgradeTest
, UpgradeV5V6IndexMustDisappear
) {
91 base::ScopedTempDir cache_dir
;
92 ASSERT_TRUE(cache_dir
.CreateUniqueTempDir());
93 const base::FilePath cache_path
= cache_dir
.path();
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()),
100 index_file
, file_contents
.data(), file_contents
.size()));
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
=
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()));
119 ASSERT_TRUE(disk_cache::UpgradeIndexV5V6(cache_path
));
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
=
129 base::StringPrintf(" %" PRIx64
, implicit_cast
<uint64
>(entry_hash
));
130 std::string real_contents
;
131 EXPECT_TRUE(base::ReadFileToString(cache_path
.AppendASCII(file_name
),
133 EXPECT_EQ(expected_contents
, real_contents
);
140 #endif // defined(OS_POSIX)