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 "storage/browser/blob/blob_storage_context.h" | 5 #include "storage/browser/blob/blob_storage_context.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
11 #include "base/memory/ref_counted.h" | 11 #include "base/memory/ref_counted.h" |
12 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
13 #include "base/message_loop/message_loop.h" | 13 #include "base/message_loop/message_loop.h" |
14 #include "base/run_loop.h" | 14 #include "base/run_loop.h" |
15 #include "base/time/time.h" | 15 #include "base/time/time.h" |
16 #include "content/browser/fileapi/blob_storage_host.h" | 16 #include "content/browser/fileapi/blob_storage_host.h" |
| 17 #include "net/base/io_buffer.h" |
| 18 #include "net/base/test_completion_callback.h" |
| 19 #include "net/disk_cache/disk_cache.h" |
17 #include "storage/browser/blob/blob_data_builder.h" | 20 #include "storage/browser/blob/blob_data_builder.h" |
18 #include "storage/browser/blob/blob_data_handle.h" | 21 #include "storage/browser/blob/blob_data_handle.h" |
19 #include "storage/browser/blob/blob_data_item.h" | 22 #include "storage/browser/blob/blob_data_item.h" |
20 #include "storage/browser/blob/blob_data_snapshot.h" | 23 #include "storage/browser/blob/blob_data_snapshot.h" |
21 #include "testing/gtest/include/gtest/gtest.h" | 24 #include "testing/gtest/include/gtest/gtest.h" |
22 | 25 |
23 using storage::BlobDataBuilder; | 26 using storage::BlobDataBuilder; |
24 using storage::BlobDataHandle; | 27 using storage::BlobDataHandle; |
25 using storage::BlobDataItem; | 28 using storage::BlobDataItem; |
26 using storage::BlobDataSnapshot; | 29 using storage::BlobDataSnapshot; |
27 using storage::BlobStorageContext; | 30 using storage::BlobStorageContext; |
28 using storage::DataElement; | 31 using storage::DataElement; |
29 | 32 |
30 namespace content { | 33 namespace content { |
31 namespace { | 34 namespace { |
32 | 35 |
| 36 const int kTestDiskCacheStreamIndex = 0; |
| 37 |
| 38 // Our disk cache tests don't need a real data handle since the tests themselves |
| 39 // scope the disk cache and entries. |
| 40 class EmptyDataHandle : public storage::BlobDataBuilder::DataHandle { |
| 41 private: |
| 42 ~EmptyDataHandle() override {} |
| 43 }; |
| 44 |
| 45 scoped_ptr<disk_cache::Backend> CreateInMemoryDiskCache() { |
| 46 scoped_ptr<disk_cache::Backend> cache; |
| 47 net::TestCompletionCallback cb; |
| 48 int rv = disk_cache::CreateCacheBackend(net::MEMORY_CACHE, |
| 49 net::CACHE_BACKEND_DEFAULT, |
| 50 base::FilePath(), 0, |
| 51 false, NULL, NULL, &cache, |
| 52 cb.callback()); |
| 53 EXPECT_EQ(net::OK, cb.GetResult(rv)); |
| 54 |
| 55 return cache.Pass(); |
| 56 } |
| 57 |
| 58 disk_cache::ScopedEntryPtr CreateDiskCacheEntry(disk_cache::Backend* cache, |
| 59 const char* key, |
| 60 const std::string& data) { |
| 61 disk_cache::Entry* tmp_entry = nullptr; |
| 62 net::TestCompletionCallback cb; |
| 63 int rv = cache->CreateEntry(key, &tmp_entry, cb.callback()); |
| 64 if (cb.GetResult(rv) != net::OK) |
| 65 return nullptr; |
| 66 disk_cache::ScopedEntryPtr entry(tmp_entry); |
| 67 |
| 68 scoped_refptr<net::StringIOBuffer> iobuffer = new net::StringIOBuffer(data); |
| 69 rv = entry->WriteData(kTestDiskCacheStreamIndex, 0, iobuffer.get(), |
| 70 iobuffer->size(), cb.callback(), false); |
| 71 EXPECT_EQ(static_cast<int>(data.size()), cb.GetResult(rv)); |
| 72 return entry.Pass(); |
| 73 } |
| 74 |
33 void SetupBasicBlob(BlobStorageHost* host, const std::string& id) { | 75 void SetupBasicBlob(BlobStorageHost* host, const std::string& id) { |
34 EXPECT_TRUE(host->StartBuildingBlob(id)); | 76 EXPECT_TRUE(host->StartBuildingBlob(id)); |
35 DataElement item; | 77 DataElement item; |
36 item.SetToBytes("1", 1); | 78 item.SetToBytes("1", 1); |
37 EXPECT_TRUE(host->AppendBlobDataItem(id, item)); | 79 EXPECT_TRUE(host->AppendBlobDataItem(id, item)); |
38 EXPECT_TRUE(host->FinishBuildingBlob(id, "text/plain")); | 80 EXPECT_TRUE(host->FinishBuildingBlob(id, "text/plain")); |
39 EXPECT_FALSE(host->StartBuildingBlob(id)); | 81 EXPECT_FALSE(host->StartBuildingBlob(id)); |
40 } | 82 } |
41 | 83 |
42 } // namespace | 84 } // namespace |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 ASSERT_EQ(1u, data->items().size()); | 297 ASSERT_EQ(1u, data->items().size()); |
256 const scoped_refptr<BlobDataItem> item = data->items()[0]; | 298 const scoped_refptr<BlobDataItem> item = data->items()[0]; |
257 EXPECT_EQ(kLargeSize - kBlobLength, item->offset()); | 299 EXPECT_EQ(kLargeSize - kBlobLength, item->offset()); |
258 EXPECT_EQ(kBlobLength, item->length()); | 300 EXPECT_EQ(kBlobLength, item->length()); |
259 | 301 |
260 blob_data_handle1.reset(); | 302 blob_data_handle1.reset(); |
261 blob_data_handle2.reset(); | 303 blob_data_handle2.reset(); |
262 base::RunLoop().RunUntilIdle(); | 304 base::RunLoop().RunUntilIdle(); |
263 } | 305 } |
264 | 306 |
| 307 TEST(BlobStorageContextTest, BuildDiskCacheBlob) { |
| 308 base::MessageLoop fake_io_message_loop; |
| 309 scoped_refptr<BlobDataBuilder::DataHandle> |
| 310 data_handle = new EmptyDataHandle(); |
| 311 |
| 312 { |
| 313 scoped_ptr<BlobStorageContext> context(new BlobStorageContext); |
| 314 BlobStorageHost host(context.get()); |
| 315 |
| 316 scoped_ptr<disk_cache::Backend> cache = CreateInMemoryDiskCache(); |
| 317 ASSERT_TRUE(cache); |
| 318 |
| 319 const std::string kTestBlobData = "Test Blob Data"; |
| 320 disk_cache::ScopedEntryPtr entry = |
| 321 CreateDiskCacheEntry(cache.get(), "test entry", kTestBlobData); |
| 322 |
| 323 const std::string kId1Prime("id1.prime"); |
| 324 BlobDataBuilder canonicalized_blob_data(kId1Prime); |
| 325 canonicalized_blob_data.AppendData(kTestBlobData.c_str()); |
| 326 |
| 327 const std::string kId1("id1"); |
| 328 BlobDataBuilder builder(kId1); |
| 329 |
| 330 builder.AppendDiskCacheEntry( |
| 331 data_handle, entry.get(), kTestDiskCacheStreamIndex); |
| 332 |
| 333 scoped_ptr<BlobDataHandle> blob_data_handle = |
| 334 context->AddFinishedBlob(&builder); |
| 335 scoped_ptr<BlobDataSnapshot> data = blob_data_handle->CreateSnapshot(); |
| 336 EXPECT_EQ(*data, builder); |
| 337 EXPECT_FALSE(data_handle->HasOneRef()) |
| 338 << "Data handle was destructed while context and builder still exist."; |
| 339 } |
| 340 EXPECT_TRUE(data_handle->HasOneRef()) |
| 341 << "Data handle was not destructed along with blob storage context."; |
| 342 base::RunLoop().RunUntilIdle(); |
| 343 } |
| 344 |
265 TEST(BlobStorageContextTest, CompoundBlobs) { | 345 TEST(BlobStorageContextTest, CompoundBlobs) { |
266 const std::string kId1("id1"); | 346 const std::string kId1("id1"); |
267 const std::string kId2("id2"); | 347 const std::string kId2("id2"); |
| 348 const std::string kId3("id3"); |
268 const std::string kId2Prime("id2.prime"); | 349 const std::string kId2Prime("id2.prime"); |
269 | 350 |
270 base::MessageLoop fake_io_message_loop; | 351 base::MessageLoop fake_io_message_loop; |
271 | 352 |
272 // Setup a set of blob data for testing. | 353 // Setup a set of blob data for testing. |
273 base::Time time1, time2; | 354 base::Time time1, time2; |
274 base::Time::FromString("Tue, 15 Nov 1994, 12:45:26 GMT", &time1); | 355 base::Time::FromString("Tue, 15 Nov 1994, 12:45:26 GMT", &time1); |
275 base::Time::FromString("Mon, 14 Nov 1994, 11:30:49 GMT", &time2); | 356 base::Time::FromString("Mon, 14 Nov 1994, 11:30:49 GMT", &time2); |
276 | 357 |
277 BlobDataBuilder blob_data1(kId1); | 358 BlobDataBuilder blob_data1(kId1); |
278 blob_data1.AppendData("Data1"); | 359 blob_data1.AppendData("Data1"); |
279 blob_data1.AppendData("Data2"); | 360 blob_data1.AppendData("Data2"); |
280 blob_data1.AppendFile(base::FilePath(FILE_PATH_LITERAL("File1.txt")), 10, | 361 blob_data1.AppendFile(base::FilePath(FILE_PATH_LITERAL("File1.txt")), 10, |
281 1024, time1); | 362 1024, time1); |
282 | 363 |
283 BlobDataBuilder blob_data2(kId2); | 364 BlobDataBuilder blob_data2(kId2); |
284 blob_data2.AppendData("Data3"); | 365 blob_data2.AppendData("Data3"); |
285 blob_data2.AppendBlob(kId1, 8, 100); | 366 blob_data2.AppendBlob(kId1, 8, 100); |
286 blob_data2.AppendFile(base::FilePath(FILE_PATH_LITERAL("File2.txt")), 0, 20, | 367 blob_data2.AppendFile(base::FilePath(FILE_PATH_LITERAL("File2.txt")), 0, 20, |
287 time2); | 368 time2); |
288 | 369 |
| 370 BlobDataBuilder blob_data3(kId3); |
| 371 blob_data3.AppendData("Data4"); |
| 372 scoped_ptr<disk_cache::Backend> cache = CreateInMemoryDiskCache(); |
| 373 ASSERT_TRUE(cache); |
| 374 disk_cache::ScopedEntryPtr disk_cache_entry = |
| 375 CreateDiskCacheEntry(cache.get(), "another key", "Data5"); |
| 376 blob_data3.AppendDiskCacheEntry(new EmptyDataHandle(), disk_cache_entry.get(), |
| 377 kTestDiskCacheStreamIndex); |
| 378 |
289 BlobDataBuilder canonicalized_blob_data2(kId2Prime); | 379 BlobDataBuilder canonicalized_blob_data2(kId2Prime); |
290 canonicalized_blob_data2.AppendData("Data3"); | 380 canonicalized_blob_data2.AppendData("Data3"); |
291 canonicalized_blob_data2.AppendData("a2___", 2); | 381 canonicalized_blob_data2.AppendData("a2___", 2); |
292 canonicalized_blob_data2.AppendFile( | 382 canonicalized_blob_data2.AppendFile( |
293 base::FilePath(FILE_PATH_LITERAL("File1.txt")), 10, 98, time1); | 383 base::FilePath(FILE_PATH_LITERAL("File1.txt")), 10, 98, time1); |
294 canonicalized_blob_data2.AppendFile( | 384 canonicalized_blob_data2.AppendFile( |
295 base::FilePath(FILE_PATH_LITERAL("File2.txt")), 0, 20, time2); | 385 base::FilePath(FILE_PATH_LITERAL("File2.txt")), 0, 20, time2); |
296 | 386 |
297 BlobStorageContext context; | 387 BlobStorageContext context; |
298 scoped_ptr<BlobDataHandle> blob_data_handle; | 388 scoped_ptr<BlobDataHandle> blob_data_handle; |
299 | 389 |
300 // Test a blob referring to only data and a file. | 390 // Test a blob referring to only data and a file. |
301 blob_data_handle = context.AddFinishedBlob(&blob_data1); | 391 blob_data_handle = context.AddFinishedBlob(&blob_data1); |
302 | 392 |
303 ASSERT_TRUE(blob_data_handle); | 393 ASSERT_TRUE(blob_data_handle); |
304 scoped_ptr<BlobDataSnapshot> data = blob_data_handle->CreateSnapshot(); | 394 scoped_ptr<BlobDataSnapshot> data = blob_data_handle->CreateSnapshot(); |
305 ASSERT_TRUE(blob_data_handle); | 395 ASSERT_TRUE(blob_data_handle); |
306 EXPECT_EQ(*data, blob_data1); | 396 EXPECT_EQ(*data, blob_data1); |
307 | 397 |
308 // Test a blob composed in part with another blob. | 398 // Test a blob composed in part with another blob. |
309 blob_data_handle = context.AddFinishedBlob(&blob_data2); | 399 blob_data_handle = context.AddFinishedBlob(&blob_data2); |
310 data = blob_data_handle->CreateSnapshot(); | 400 data = blob_data_handle->CreateSnapshot(); |
311 ASSERT_TRUE(blob_data_handle); | 401 ASSERT_TRUE(blob_data_handle); |
312 ASSERT_TRUE(data); | 402 ASSERT_TRUE(data); |
313 EXPECT_EQ(*data, canonicalized_blob_data2); | 403 EXPECT_EQ(*data, canonicalized_blob_data2); |
314 | 404 |
| 405 // Test a blob referring to only data and a disk cache entry. |
| 406 blob_data_handle = context.AddFinishedBlob(&blob_data3); |
| 407 data = blob_data_handle->CreateSnapshot(); |
| 408 ASSERT_TRUE(blob_data_handle); |
| 409 EXPECT_EQ(*data, blob_data3); |
| 410 |
315 blob_data_handle.reset(); | 411 blob_data_handle.reset(); |
316 base::RunLoop().RunUntilIdle(); | 412 base::RunLoop().RunUntilIdle(); |
317 } | 413 } |
318 | 414 |
319 TEST(BlobStorageContextTest, PublicBlobUrls) { | 415 TEST(BlobStorageContextTest, PublicBlobUrls) { |
320 BlobStorageContext context; | 416 BlobStorageContext context; |
321 BlobStorageHost host(&context); | 417 BlobStorageHost host(&context); |
322 base::MessageLoop fake_io_message_loop; | 418 base::MessageLoop fake_io_message_loop; |
323 | 419 |
324 // Build up a basic blob. | 420 // Build up a basic blob. |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 EXPECT_FALSE(host.FinishBuildingBlob(kId, "text/plain")); | 483 EXPECT_FALSE(host.FinishBuildingBlob(kId, "text/plain")); |
388 EXPECT_FALSE(host.RegisterPublicBlobURL(kUrl, kId)); | 484 EXPECT_FALSE(host.RegisterPublicBlobURL(kUrl, kId)); |
389 EXPECT_FALSE(host.IncrementBlobRefCount(kId)); | 485 EXPECT_FALSE(host.IncrementBlobRefCount(kId)); |
390 EXPECT_FALSE(host.DecrementBlobRefCount(kId)); | 486 EXPECT_FALSE(host.DecrementBlobRefCount(kId)); |
391 EXPECT_FALSE(host.RevokePublicBlobURL(kUrl)); | 487 EXPECT_FALSE(host.RevokePublicBlobURL(kUrl)); |
392 } | 488 } |
393 | 489 |
394 // TODO(michaeln): tests for the depcrecated url stuff | 490 // TODO(michaeln): tests for the depcrecated url stuff |
395 | 491 |
396 } // namespace content | 492 } // namespace content |
OLD | NEW |