1// Copyright (c) 2012 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 "base/files/file.h" 6#include "base/files/file_path.h" 7#include "base/files/file_util.h" 8#include "base/files/scoped_temp_dir.h" 9#include "base/path_service.h" 10#include "base/strings/string_piece.h" 11#include "testing/gtest/include/gtest/gtest.h" 12#include "ui/base/resource/data_pack.h" 13#include "ui/base/ui_base_paths.h" 14 15namespace ui { 16 17class DataPackTest 18 : public testing::TestWithParam<DataPack::TextEncodingType> { 19 public: 20 DataPackTest() {} 21}; 22 23extern const char kSamplePakContents[]; 24extern const char kSampleCorruptPakContents[]; 25extern const size_t kSamplePakSize; 26extern const size_t kSampleCorruptPakSize; 27 28TEST(DataPackTest, LoadFromPath) { 29 base::ScopedTempDir dir; 30 ASSERT_TRUE(dir.CreateUniqueTempDir()); 31 base::FilePath data_path = dir.path().Append(FILE_PATH_LITERAL("sample.pak")); 32 33 // Dump contents into the pak file. 34 ASSERT_EQ(base::WriteFile(data_path, kSamplePakContents, kSamplePakSize), 35 static_cast<int>(kSamplePakSize)); 36 37 // Load the file through the data pack API. 38 DataPack pack(SCALE_FACTOR_100P); 39 ASSERT_TRUE(pack.LoadFromPath(data_path)); 40 41 base::StringPiece data; 42 ASSERT_TRUE(pack.HasResource(4)); 43 ASSERT_TRUE(pack.GetStringPiece(4, &data)); 44 EXPECT_EQ("this is id 4", data); 45 ASSERT_TRUE(pack.HasResource(6)); 46 ASSERT_TRUE(pack.GetStringPiece(6, &data)); 47 EXPECT_EQ("this is id 6", data); 48 49 // Try reading zero-length data blobs, just in case. 50 ASSERT_TRUE(pack.GetStringPiece(1, &data)); 51 EXPECT_EQ(0U, data.length()); 52 ASSERT_TRUE(pack.GetStringPiece(10, &data)); 53 EXPECT_EQ(0U, data.length()); 54 55 // Try looking up an invalid key. 56 ASSERT_FALSE(pack.HasResource(140)); 57 ASSERT_FALSE(pack.GetStringPiece(140, &data)); 58} 59 60TEST(DataPackTest, LoadFromFile) { 61 base::ScopedTempDir dir; 62 ASSERT_TRUE(dir.CreateUniqueTempDir()); 63 base::FilePath data_path = dir.path().Append(FILE_PATH_LITERAL("sample.pak")); 64 65 // Dump contents into the pak file. 66 ASSERT_EQ(base::WriteFile(data_path, kSamplePakContents, kSamplePakSize), 67 static_cast<int>(kSamplePakSize)); 68 69 base::File file(data_path, base::File::FLAG_OPEN | base::File::FLAG_READ); 70 ASSERT_TRUE(file.IsValid()); 71 72 // Load the file through the data pack API. 73 DataPack pack(SCALE_FACTOR_100P); 74 ASSERT_TRUE(pack.LoadFromFile(file.Pass())); 75 76 base::StringPiece data; 77 ASSERT_TRUE(pack.HasResource(4)); 78 ASSERT_TRUE(pack.GetStringPiece(4, &data)); 79 EXPECT_EQ("this is id 4", data); 80 ASSERT_TRUE(pack.HasResource(6)); 81 ASSERT_TRUE(pack.GetStringPiece(6, &data)); 82 EXPECT_EQ("this is id 6", data); 83 84 // Try reading zero-length data blobs, just in case. 85 ASSERT_TRUE(pack.GetStringPiece(1, &data)); 86 EXPECT_EQ(0U, data.length()); 87 ASSERT_TRUE(pack.GetStringPiece(10, &data)); 88 EXPECT_EQ(0U, data.length()); 89 90 // Try looking up an invalid key. 91 ASSERT_FALSE(pack.HasResource(140)); 92 ASSERT_FALSE(pack.GetStringPiece(140, &data)); 93} 94 95TEST(DataPackTest, LoadFromFileRegion) { 96 base::ScopedTempDir dir; 97 ASSERT_TRUE(dir.CreateUniqueTempDir()); 98 base::FilePath data_path = dir.path().Append(FILE_PATH_LITERAL("sample.pak")); 99 100 // Construct a file which has a non page-aligned zero-filled header followed 101 // by the actual pak file content. 102 const char kPadding[5678] = {0}; 103 ASSERT_EQ(static_cast<int>(sizeof(kPadding)), 104 base::WriteFile(data_path, kPadding, sizeof(kPadding))); 105 ASSERT_EQ(static_cast<int>(kSamplePakSize), 106 base::AppendToFile(data_path, kSamplePakContents, kSamplePakSize)); 107 108 base::File file(data_path, base::File::FLAG_OPEN | base::File::FLAG_READ); 109 ASSERT_TRUE(file.IsValid()); 110 111 // Load the file through the data pack API. 112 DataPack pack(SCALE_FACTOR_100P); 113 base::MemoryMappedFile::Region region(sizeof(kPadding), kSamplePakSize); 114 ASSERT_TRUE(pack.LoadFromFileRegion(file.Pass(), region)); 115 116 base::StringPiece data; 117 ASSERT_TRUE(pack.HasResource(4)); 118 ASSERT_TRUE(pack.GetStringPiece(4, &data)); 119 EXPECT_EQ("this is id 4", data); 120 ASSERT_TRUE(pack.HasResource(6)); 121 ASSERT_TRUE(pack.GetStringPiece(6, &data)); 122 EXPECT_EQ("this is id 6", data); 123 124 // Try reading zero-length data blobs, just in case. 125 ASSERT_TRUE(pack.GetStringPiece(1, &data)); 126 EXPECT_EQ(0U, data.length()); 127 ASSERT_TRUE(pack.GetStringPiece(10, &data)); 128 EXPECT_EQ(0U, data.length()); 129 130 // Try looking up an invalid key. 131 ASSERT_FALSE(pack.HasResource(140)); 132 ASSERT_FALSE(pack.GetStringPiece(140, &data)); 133} 134 135INSTANTIATE_TEST_CASE_P(WriteBINARY, DataPackTest, ::testing::Values( 136 DataPack::BINARY)); 137INSTANTIATE_TEST_CASE_P(WriteUTF8, DataPackTest, ::testing::Values( 138 DataPack::UTF8)); 139INSTANTIATE_TEST_CASE_P(WriteUTF16, DataPackTest, ::testing::Values( 140 DataPack::UTF16)); 141 142TEST(DataPackTest, LoadFileWithTruncatedHeader) { 143 base::FilePath data_path; 144 ASSERT_TRUE(PathService::Get(UI_DIR_TEST_DATA, &data_path)); 145 data_path = data_path.AppendASCII("data_pack_unittest/truncated-header.pak"); 146 147 DataPack pack(SCALE_FACTOR_100P); 148 ASSERT_FALSE(pack.LoadFromPath(data_path)); 149} 150 151TEST_P(DataPackTest, Write) { 152 base::ScopedTempDir dir; 153 ASSERT_TRUE(dir.CreateUniqueTempDir()); 154 base::FilePath file = dir.path().Append(FILE_PATH_LITERAL("data.pak")); 155 156 std::string one("one"); 157 std::string two("two"); 158 std::string three("three"); 159 std::string four("four"); 160 std::string fifteen("fifteen"); 161 162 std::map<uint16, base::StringPiece> resources; 163 resources.insert(std::make_pair(1, base::StringPiece(one))); 164 resources.insert(std::make_pair(2, base::StringPiece(two))); 165 resources.insert(std::make_pair(15, base::StringPiece(fifteen))); 166 resources.insert(std::make_pair(3, base::StringPiece(three))); 167 resources.insert(std::make_pair(4, base::StringPiece(four))); 168 ASSERT_TRUE(DataPack::WritePack(file, resources, GetParam())); 169 170 // Now try to read the data back in. 171 DataPack pack(SCALE_FACTOR_100P); 172 ASSERT_TRUE(pack.LoadFromPath(file)); 173 EXPECT_EQ(pack.GetTextEncodingType(), GetParam()); 174 175 base::StringPiece data; 176 ASSERT_TRUE(pack.GetStringPiece(1, &data)); 177 EXPECT_EQ(one, data); 178 ASSERT_TRUE(pack.GetStringPiece(2, &data)); 179 EXPECT_EQ(two, data); 180 ASSERT_TRUE(pack.GetStringPiece(3, &data)); 181 EXPECT_EQ(three, data); 182 ASSERT_TRUE(pack.GetStringPiece(4, &data)); 183 EXPECT_EQ(four, data); 184 ASSERT_TRUE(pack.GetStringPiece(15, &data)); 185 EXPECT_EQ(fifteen, data); 186} 187 188#if defined(OS_POSIX) 189TEST(DataPackTest, ModifiedWhileUsed) { 190 base::ScopedTempDir dir; 191 ASSERT_TRUE(dir.CreateUniqueTempDir()); 192 base::FilePath data_path = dir.path().Append(FILE_PATH_LITERAL("sample.pak")); 193 194 // Dump contents into the pak file. 195 ASSERT_EQ(base::WriteFile(data_path, kSamplePakContents, kSamplePakSize), 196 static_cast<int>(kSamplePakSize)); 197 198 base::File file(data_path, base::File::FLAG_OPEN | base::File::FLAG_READ); 199 ASSERT_TRUE(file.IsValid()); 200 201 // Load the file through the data pack API. 202 DataPack pack(SCALE_FACTOR_100P); 203 ASSERT_TRUE(pack.LoadFromFile(file.Pass())); 204 205 base::StringPiece data; 206 ASSERT_TRUE(pack.HasResource(10)); 207 ASSERT_TRUE(pack.GetStringPiece(10, &data)); 208 209 ASSERT_EQ(base::WriteFile(data_path, kSampleCorruptPakContents, 210 kSampleCorruptPakSize), 211 static_cast<int>(kSampleCorruptPakSize)); 212 213 // Reading asset #10 should now fail as it extends past the end of the file. 214 ASSERT_TRUE(pack.HasResource(10)); 215 ASSERT_FALSE(pack.GetStringPiece(10, &data)); 216} 217#endif 218 219} // namespace ui 220