| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/enhanced_bookmarks/image_store.h" | 5 #include "components/enhanced_bookmarks/image_store.h" |
| 6 | 6 |
| 7 #include "base/files/file_path.h" |
| 7 #include "base/files/scoped_temp_dir.h" | 8 #include "base/files/scoped_temp_dir.h" |
| 8 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
| 10 #include "components/enhanced_bookmarks/image_record.h" |
| 9 #include "components/enhanced_bookmarks/image_store_util.h" | 11 #include "components/enhanced_bookmarks/image_store_util.h" |
| 10 #include "components/enhanced_bookmarks/persistent_image_store.h" | 12 #include "components/enhanced_bookmarks/persistent_image_store.h" |
| 11 #include "components/enhanced_bookmarks/test_image_store.h" | 13 #include "components/enhanced_bookmarks/test_image_store.h" |
| 14 #include "sql/statement.h" |
| 12 #include "testing/platform_test.h" | 15 #include "testing/platform_test.h" |
| 13 #include "third_party/skia/include/core/SkBitmap.h" | 16 #include "third_party/skia/include/core/SkBitmap.h" |
| 17 #include "third_party/skia/include/core/SkColor.h" |
| 14 #include "url/gurl.h" | 18 #include "url/gurl.h" |
| 15 | 19 |
| 16 namespace { | 20 namespace { |
| 17 | 21 |
| 18 gfx::Image CreateImage(int width, int height, int a, int r, int g, int b) { | 22 gfx::Image CreateImage(int width, int height, int a, int r, int g, int b) { |
| 19 SkBitmap bitmap; | 23 SkBitmap bitmap; |
| 20 bitmap.allocN32Pixels(width, height); | 24 bitmap.allocN32Pixels(width, height); |
| 21 bitmap.eraseARGB(a, r, g, b); | 25 bitmap.eraseARGB(a, r, g, b); |
| 22 gfx::Image image(gfx::Image::CreateFrom1xBitmap(bitmap)); | 26 gfx::Image image(gfx::Image::CreateFrom1xBitmap(bitmap)); |
| 23 | 27 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 55 enhanced_bookmarks::BytesForImage(image_2); | 59 enhanced_bookmarks::BytesForImage(image_2); |
| 56 | 60 |
| 57 if (image_1_bytes->size() != image_2_bytes->size()) | 61 if (image_1_bytes->size() != image_2_bytes->size()) |
| 58 return false; | 62 return false; |
| 59 | 63 |
| 60 return !memcmp(image_1_bytes->front(), | 64 return !memcmp(image_1_bytes->front(), |
| 61 image_2_bytes->front(), | 65 image_2_bytes->front(), |
| 62 image_1_bytes->size()); | 66 image_1_bytes->size()); |
| 63 } | 67 } |
| 64 | 68 |
| 69 bool CreateV1PersistentImageStoreDB(const base::FilePath& path) { |
| 70 sql::Connection db; |
| 71 if (!db.Open(path)) |
| 72 return false; |
| 73 |
| 74 if (db.DoesTableExist("images_by_url")) |
| 75 return false; |
| 76 |
| 77 const char kV1TableSql[] = |
| 78 "CREATE TABLE IF NOT EXISTS images_by_url (" |
| 79 "page_url LONGVARCHAR NOT NULL," |
| 80 "image_url LONGVARCHAR NOT NULL," |
| 81 "image_data BLOB," |
| 82 "width INTEGER," |
| 83 "height INTEGER" |
| 84 ")"; |
| 85 if (!db.Execute(kV1TableSql)) |
| 86 return false; |
| 87 |
| 88 const char kV1IndexSql[] = |
| 89 "CREATE INDEX IF NOT EXISTS images_by_url_idx ON images_by_url(page_url)"; |
| 90 if (!db.Execute(kV1IndexSql)) |
| 91 return false; |
| 92 |
| 93 sql::Statement statement(db.GetUniqueStatement( |
| 94 "INSERT INTO images_by_url " |
| 95 "(page_url, image_url, image_data, width, height) " |
| 96 "VALUES (?, ?, ?, ?, ?)")); |
| 97 statement.BindString(0, "foo://bar"); |
| 98 statement.BindString(1, "http://a.jpg"); |
| 99 scoped_refptr<base::RefCountedMemory> image_bytes = |
| 100 enhanced_bookmarks::BytesForImage(GenerateWhiteImage()); |
| 101 statement.BindBlob(2, image_bytes->front(), (int)image_bytes->size()); |
| 102 statement.BindInt(3, 42); |
| 103 statement.BindInt(4, 24); |
| 104 |
| 105 return statement.Run(); |
| 106 } |
| 107 |
| 65 // Factory functions for creating instances of the implementations. | 108 // Factory functions for creating instances of the implementations. |
| 66 template <class T> | 109 template <class T> |
| 67 ImageStore* CreateStore(base::ScopedTempDir& folder); | 110 ImageStore* CreateStore(base::ScopedTempDir& folder); |
| 68 | 111 |
| 69 template <> | 112 template <> |
| 70 ImageStore* CreateStore<TestImageStore>( | 113 ImageStore* CreateStore<TestImageStore>( |
| 71 base::ScopedTempDir& folder) { | 114 base::ScopedTempDir& folder) { |
| 72 return new TestImageStore(); | 115 return new TestImageStore(); |
| 73 } | 116 } |
| 74 | 117 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 TYPED_TEST_CASE(ImageStoreUnitTest, Implementations); | 163 TYPED_TEST_CASE(ImageStoreUnitTest, Implementations); |
| 121 | 164 |
| 122 // All those tests are run on all the implementations. | 165 // All those tests are run on all the implementations. |
| 123 TYPED_TEST(ImageStoreUnitTest, StartsEmpty) { | 166 TYPED_TEST(ImageStoreUnitTest, StartsEmpty) { |
| 124 std::set<GURL> all_urls; | 167 std::set<GURL> all_urls; |
| 125 this->store_->GetAllPageUrls(&all_urls); | 168 this->store_->GetAllPageUrls(&all_urls); |
| 126 EXPECT_EQ(0u, all_urls.size()); | 169 EXPECT_EQ(0u, all_urls.size()); |
| 127 } | 170 } |
| 128 | 171 |
| 129 TYPED_TEST(ImageStoreUnitTest, StoreOne) { | 172 TYPED_TEST(ImageStoreUnitTest, StoreOne) { |
| 130 this->store_->Insert(GURL("foo://bar"), GURL("a.jpg"), GenerateBlackImage()); | 173 const enhanced_bookmarks::ImageRecord image( |
| 174 GenerateBlackImage(), GURL("http://a.jpg"), SK_ColorBLACK); |
| 175 this->store_->Insert(GURL("foo://bar"), image); |
| 131 | 176 |
| 132 std::set<GURL> all_urls; | 177 std::set<GURL> all_urls; |
| 133 this->store_->GetAllPageUrls(&all_urls); | 178 this->store_->GetAllPageUrls(&all_urls); |
| 134 EXPECT_EQ(1u, all_urls.size()); | 179 EXPECT_EQ(1u, all_urls.size()); |
| 135 EXPECT_EQ(GURL("foo://bar"), *all_urls.begin()); | 180 EXPECT_EQ(GURL("foo://bar"), *all_urls.begin()); |
| 136 EXPECT_TRUE(this->store_->HasKey(GURL("foo://bar"))); | 181 EXPECT_TRUE(this->store_->HasKey(GURL("foo://bar"))); |
| 137 } | 182 } |
| 138 | 183 |
| 139 TYPED_TEST(ImageStoreUnitTest, Retrieve) { | 184 TYPED_TEST(ImageStoreUnitTest, Retrieve) { |
| 140 gfx::Image src_image = GenerateBlackImage(42, 24); | |
| 141 const GURL url("foo://bar"); | 185 const GURL url("foo://bar"); |
| 142 const GURL image_url("a.jpg"); | 186 const enhanced_bookmarks::ImageRecord image_in( |
| 143 this->store_->Insert(url, image_url, src_image); | 187 CreateImage(42, 24, 1, 0, 0, 1), GURL("http://a.jpg"), SK_ColorBLUE); |
| 188 this->store_->Insert(url, image_in); |
| 144 | 189 |
| 145 std::pair<gfx::Image, GURL> image_info = this->store_->Get(url); | 190 const enhanced_bookmarks::ImageRecord image_out = this->store_->Get(url); |
| 146 gfx::Size size = this->store_->GetSize(url); | 191 const gfx::Size size = this->store_->GetSize(url); |
| 147 | 192 |
| 148 EXPECT_EQ(size.width(), 42); | 193 EXPECT_EQ(42, size.width()); |
| 149 EXPECT_EQ(size.height(), 24); | 194 EXPECT_EQ(24, size.height()); |
| 150 EXPECT_EQ(image_url, image_info.second); | 195 EXPECT_EQ(image_in.url, image_out.url); |
| 151 EXPECT_TRUE(CompareImages(src_image, image_info.first)); | 196 EXPECT_TRUE(CompareImages(image_in.image, image_out.image)); |
| 197 EXPECT_EQ(SK_ColorBLUE, image_out.dominant_color); |
| 152 } | 198 } |
| 153 | 199 |
| 154 TYPED_TEST(ImageStoreUnitTest, Erase) { | 200 TYPED_TEST(ImageStoreUnitTest, Erase) { |
| 155 gfx::Image src_image = GenerateBlackImage(); | |
| 156 const GURL url("foo://bar"); | 201 const GURL url("foo://bar"); |
| 157 const GURL image_url("a.jpg"); | 202 const enhanced_bookmarks::ImageRecord image( |
| 158 this->store_->Insert(url, image_url, src_image); | 203 GenerateBlackImage(), GURL("http://a.jpg"), SK_ColorBLACK); |
| 204 this->store_->Insert(url, image); |
| 159 this->store_->Erase(url); | 205 this->store_->Erase(url); |
| 160 | 206 |
| 161 EXPECT_FALSE(this->store_->HasKey(url)); | 207 EXPECT_FALSE(this->store_->HasKey(url)); |
| 162 std::set<GURL> all_urls; | 208 std::set<GURL> all_urls; |
| 163 this->store_->GetAllPageUrls(&all_urls); | 209 this->store_->GetAllPageUrls(&all_urls); |
| 164 EXPECT_EQ(0u, all_urls.size()); | 210 EXPECT_EQ(0u, all_urls.size()); |
| 165 } | 211 } |
| 166 | 212 |
| 167 TYPED_TEST(ImageStoreUnitTest, ClearAll) { | 213 TYPED_TEST(ImageStoreUnitTest, ClearAll) { |
| 168 const GURL url_foo("http://foo"); | 214 const GURL url_foo("http://foo"); |
| 169 this->store_->Insert(url_foo, GURL("foo.jpg"), GenerateBlackImage()); | 215 const enhanced_bookmarks::ImageRecord black_image( |
| 216 GenerateBlackImage(), GURL("http://a.jpg"), SK_ColorBLACK); |
| 217 this->store_->Insert(url_foo, black_image); |
| 170 const GURL url_bar("http://bar"); | 218 const GURL url_bar("http://bar"); |
| 171 this->store_->Insert(url_foo, GURL("bar.jpg"), GenerateWhiteImage()); | 219 const enhanced_bookmarks::ImageRecord white_image( |
| 220 GenerateWhiteImage(), GURL("http://a.jpg"), SK_ColorWHITE); |
| 221 this->store_->Insert(url_bar, white_image); |
| 172 | 222 |
| 173 this->store_->ClearAll(); | 223 this->store_->ClearAll(); |
| 174 | 224 |
| 175 EXPECT_FALSE(this->store_->HasKey(url_foo)); | 225 EXPECT_FALSE(this->store_->HasKey(url_foo)); |
| 176 EXPECT_FALSE(this->store_->HasKey(url_bar)); | 226 EXPECT_FALSE(this->store_->HasKey(url_bar)); |
| 177 std::set<GURL> all_urls; | 227 std::set<GURL> all_urls; |
| 178 this->store_->GetAllPageUrls(&all_urls); | 228 this->store_->GetAllPageUrls(&all_urls); |
| 179 EXPECT_EQ(0u, all_urls.size()); | 229 EXPECT_EQ(0u, all_urls.size()); |
| 180 } | 230 } |
| 181 | 231 |
| 182 TYPED_TEST(ImageStoreUnitTest, Update) { | 232 TYPED_TEST(ImageStoreUnitTest, Update) { |
| 183 gfx::Image src_image1 = GenerateWhiteImage(); | |
| 184 gfx::Image src_image2 = GenerateBlackImage(); | |
| 185 const GURL url("foo://bar"); | 233 const GURL url("foo://bar"); |
| 186 const GURL image_url1("1.jpg"); | 234 const enhanced_bookmarks::ImageRecord image1(GenerateWhiteImage(), |
| 187 this->store_->Insert(url, image_url1, src_image1); | 235 GURL("1.jpg"), SK_ColorWHITE); |
| 236 this->store_->Insert(url, image1); |
| 188 | 237 |
| 189 const GURL image_url2("2.jpg"); | 238 const enhanced_bookmarks::ImageRecord image2(GenerateBlackImage(), |
| 190 this->store_->Insert(url, image_url2, src_image2); | 239 GURL("2.jpg"), SK_ColorBLACK); |
| 240 this->store_->Insert(url, image2); |
| 191 | 241 |
| 192 std::pair<gfx::Image, GURL> image_info = this->store_->Get(url); | 242 const enhanced_bookmarks::ImageRecord image_out = this->store_->Get(url); |
| 193 | 243 |
| 194 EXPECT_TRUE(this->store_->HasKey(url)); | 244 EXPECT_TRUE(this->store_->HasKey(url)); |
| 195 std::set<GURL> all_urls; | 245 std::set<GURL> all_urls; |
| 196 this->store_->GetAllPageUrls(&all_urls); | 246 this->store_->GetAllPageUrls(&all_urls); |
| 197 EXPECT_EQ(1u, all_urls.size()); | 247 EXPECT_EQ(1u, all_urls.size()); |
| 198 EXPECT_EQ(image_url2, image_info.second); | 248 EXPECT_EQ(image2.url, image_out.url); |
| 199 EXPECT_TRUE(CompareImages(src_image2, image_info.first)); | 249 EXPECT_TRUE(CompareImages(image2.image, image_out.image)); |
| 250 EXPECT_EQ(SK_ColorBLACK, image_out.dominant_color); |
| 200 } | 251 } |
| 201 | 252 |
| 202 TYPED_TEST(ImageStoreUnitTest, Persistence) { | 253 TYPED_TEST(ImageStoreUnitTest, Persistence) { |
| 203 gfx::Image src_image = GenerateBlackImage(); | |
| 204 const GURL url("foo://bar"); | 254 const GURL url("foo://bar"); |
| 205 const GURL image_url("a.jpg"); | 255 const enhanced_bookmarks::ImageRecord image_in( |
| 206 this->store_->Insert(url, image_url, src_image); | 256 GenerateBlackImage(), GURL("http://a.jpg"), SK_ColorBLACK); |
| 257 this->store_->Insert(url, image_in); |
| 207 | 258 |
| 208 this->ResetStore(); | 259 this->ResetStore(); |
| 209 if (this->use_persistent_store()) { | 260 if (this->use_persistent_store()) { |
| 210 std::set<GURL> all_urls; | 261 std::set<GURL> all_urls; |
| 211 this->store_->GetAllPageUrls(&all_urls); | 262 this->store_->GetAllPageUrls(&all_urls); |
| 212 EXPECT_EQ(1u, all_urls.size()); | 263 EXPECT_EQ(1u, all_urls.size()); |
| 213 EXPECT_EQ(GURL("foo://bar"), *all_urls.begin()); | 264 EXPECT_EQ(url, *all_urls.begin()); |
| 214 EXPECT_TRUE(this->store_->HasKey(GURL("foo://bar"))); | 265 EXPECT_TRUE(this->store_->HasKey(url)); |
| 215 std::pair<gfx::Image, GURL> image_info = this->store_->Get(url); | 266 const enhanced_bookmarks::ImageRecord image_out = this->store_->Get(url); |
| 216 | 267 |
| 217 EXPECT_EQ(image_url, image_info.second); | 268 EXPECT_EQ(image_in.url, image_out.url); |
| 218 EXPECT_TRUE(CompareImages(src_image, image_info.first)); | 269 EXPECT_TRUE(CompareImages(image_in.image, image_out.image)); |
| 270 EXPECT_EQ(image_in.dominant_color, image_out.dominant_color); |
| 219 } else { | 271 } else { |
| 220 std::set<GURL> all_urls; | 272 std::set<GURL> all_urls; |
| 221 this->store_->GetAllPageUrls(&all_urls); | 273 this->store_->GetAllPageUrls(&all_urls); |
| 222 EXPECT_EQ(0u, all_urls.size()); | 274 EXPECT_EQ(0u, all_urls.size()); |
| 223 EXPECT_FALSE(this->store_->HasKey(GURL("foo://bar"))); | 275 EXPECT_FALSE(this->store_->HasKey(url)); |
| 224 } | 276 } |
| 225 } | 277 } |
| 226 | 278 |
| 279 TYPED_TEST(ImageStoreUnitTest, MigrationToV2) { |
| 280 // Migration is available only with persistent stores. |
| 281 if (!this->use_persistent_store()) |
| 282 return; |
| 283 |
| 284 // Set up v1 DB. |
| 285 EXPECT_TRUE(CreateV1PersistentImageStoreDB(this->tempDir_.path().Append( |
| 286 base::FilePath::FromUTF8Unsafe("BookmarkImageAndUrlStore.db")))); |
| 287 |
| 288 const enhanced_bookmarks::ImageRecord image_out = |
| 289 this->store_->Get(GURL("foo://bar")); |
| 290 EXPECT_EQ(SK_ColorWHITE, image_out.dominant_color); |
| 291 } |
| 292 |
| 227 TYPED_TEST(ImageStoreUnitTest, GetSize) { | 293 TYPED_TEST(ImageStoreUnitTest, GetSize) { |
| 228 gfx::Image src_image = GenerateBlackImage(); | |
| 229 const GURL url("foo://bar"); | 294 const GURL url("foo://bar"); |
| 230 const GURL image_url("a.jpg"); | 295 const enhanced_bookmarks::ImageRecord image_in( |
| 296 GenerateBlackImage(), GURL("http://a.jpg"), SK_ColorBLACK); |
| 231 | 297 |
| 232 int64 size = 0; | 298 int64 size = 0; |
| 233 if (this->use_persistent_store()) { | 299 if (this->use_persistent_store()) { |
| 234 // File shouldn't exist before we actually start using it since we do lazy | 300 // File shouldn't exist before we actually start using it since we do lazy |
| 235 // initialization. | 301 // initialization. |
| 236 EXPECT_EQ(this->store_->GetStoreSizeInBytes(), -1); | 302 EXPECT_EQ(this->store_->GetStoreSizeInBytes(), -1); |
| 237 } else { | 303 } else { |
| 238 EXPECT_LE(this->store_->GetStoreSizeInBytes(), 1024); | 304 EXPECT_LE(this->store_->GetStoreSizeInBytes(), 1024); |
| 239 } | 305 } |
| 240 for (int i = 0; i < 100; ++i) { | 306 for (int i = 0; i < 100; ++i) { |
| 241 this->store_->Insert( | 307 this->store_->Insert(GURL(url.spec() + '/' + base::IntToString(i)), |
| 242 GURL(url.spec() + '/' + base::IntToString(i)), image_url, src_image); | 308 image_in); |
| 243 EXPECT_GE(this->store_->GetStoreSizeInBytes(), size); | 309 EXPECT_GE(this->store_->GetStoreSizeInBytes(), size); |
| 244 size = this->store_->GetStoreSizeInBytes(); | 310 size = this->store_->GetStoreSizeInBytes(); |
| 245 } | 311 } |
| 246 | 312 |
| 247 if (this->use_persistent_store()) { | 313 if (this->use_persistent_store()) { |
| 248 EXPECT_GE(this->store_->GetStoreSizeInBytes(), 80 * 1024); // 80kb | 314 EXPECT_GE(this->store_->GetStoreSizeInBytes(), 80 * 1024); // 80kb |
| 249 EXPECT_LE(this->store_->GetStoreSizeInBytes(), 200 * 1024); // 200kb | 315 EXPECT_LE(this->store_->GetStoreSizeInBytes(), 200 * 1024); // 200kb |
| 250 } else { | 316 } else { |
| 251 EXPECT_GE(this->store_->GetStoreSizeInBytes(), 400 * 1024); // 400kb | 317 EXPECT_GE(this->store_->GetStoreSizeInBytes(), 400 * 1024); // 400kb |
| 252 EXPECT_LE(this->store_->GetStoreSizeInBytes(), 500 * 1024); // 500kb | 318 EXPECT_LE(this->store_->GetStoreSizeInBytes(), 500 * 1024); // 500kb |
| 253 } | 319 } |
| 254 } | 320 } |
| 255 | 321 |
| 256 } // namespace | 322 } // namespace |
| OLD | NEW |