Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(503)

Side by Side Diff: content/browser/blob_storage/blob_dispatcher_host_unittest.cc

Issue 1846363002: [BlobAsync] Adding better error reporting and some new tests. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: comments Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "content/browser/blob_storage/blob_dispatcher_host.h" 5 #include "content/browser/blob_storage/blob_dispatcher_host.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 44
45 const char kContentType[] = "text/plain"; 45 const char kContentType[] = "text/plain";
46 const char kContentDisposition[] = "content_disposition"; 46 const char kContentDisposition[] = "content_disposition";
47 const char kData[] = "data!!"; 47 const char kData[] = "data!!";
48 const size_t kDataSize = 6; 48 const size_t kDataSize = 6;
49 49
50 const size_t kTestBlobStorageIPCThresholdBytes = 20; 50 const size_t kTestBlobStorageIPCThresholdBytes = 20;
51 const size_t kTestBlobStorageMaxSharedMemoryBytes = 50; 51 const size_t kTestBlobStorageMaxSharedMemoryBytes = 50;
52 const uint64_t kTestBlobStorageMaxFileSizeBytes = 100; 52 const uint64_t kTestBlobStorageMaxFileSizeBytes = 100;
53 53
54 template <typename T> 54 void ConstructionCompletePopulator(bool* succeeded_pointer,
55 void SetPointerValue(T* pointer, T value) { 55 IPCBlobCreationCancelCode* reason_pointer,
56 *pointer = value; 56 bool succeeded,
57 IPCBlobCreationCancelCode reason) {
58 *succeeded_pointer = succeeded;
59 *reason_pointer = reason;
57 } 60 }
58 61
59 class TestableBlobDispatcherHost : public BlobDispatcherHost { 62 class TestableBlobDispatcherHost : public BlobDispatcherHost {
60 public: 63 public:
61 TestableBlobDispatcherHost(ChromeBlobStorageContext* blob_storage_context, 64 TestableBlobDispatcherHost(ChromeBlobStorageContext* blob_storage_context,
62 IPC::TestSink* sink) 65 IPC::TestSink* sink)
63 : BlobDispatcherHost(blob_storage_context), sink_(sink) { 66 : BlobDispatcherHost(blob_storage_context), sink_(sink) {
64 this->SetMemoryConstantsForTesting(kTestBlobStorageIPCThresholdBytes, 67 this->SetMemoryConstantsForTesting(kTestBlobStorageIPCThresholdBytes,
65 kTestBlobStorageMaxSharedMemoryBytes, 68 kTestBlobStorageMaxSharedMemoryBytes,
66 kTestBlobStorageMaxFileSizeBytes); 69 kTestBlobStorageMaxFileSizeBytes);
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 std::vector<base::SharedMemoryHandle> shared_memory_handles; 304 std::vector<base::SharedMemoryHandle> shared_memory_handles;
302 305
303 ExpectBlobNotExist(kId); 306 ExpectBlobNotExist(kId);
304 host_->OnRegisterBlobUUID(kId, std::string(kContentType), 307 host_->OnRegisterBlobUUID(kId, std::string(kContentType),
305 std::string(kContentDisposition), 308 std::string(kContentDisposition),
306 std::set<std::string>()); 309 std::set<std::string>());
307 // Grab the handle. 310 // Grab the handle.
308 scoped_ptr<BlobDataHandle> blob_data_handle = 311 scoped_ptr<BlobDataHandle> blob_data_handle =
309 context_->GetBlobDataFromUUID(kId); 312 context_->GetBlobDataFromUUID(kId);
310 bool built = false; 313 bool built = false;
314 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN;
311 blob_data_handle->RunOnConstructionComplete( 315 blob_data_handle->RunOnConstructionComplete(
312 base::Bind(&SetPointerValue<bool>, &built)); 316 base::Bind(&ConstructionCompletePopulator, &built, &error_code));
313 EXPECT_FALSE(built); 317 EXPECT_FALSE(built);
314 318
315 EXPECT_FALSE(host_->shutdown_for_bad_message_); 319 EXPECT_FALSE(host_->shutdown_for_bad_message_);
316 DataElement element; 320 DataElement element;
317 element.SetToBytesDescription(kLargeSize); 321 element.SetToBytesDescription(kLargeSize);
318 std::vector<DataElement> elements = {element}; 322 std::vector<DataElement> elements = {element};
319 host_->OnStartBuildingBlob(kId, elements); 323 host_->OnStartBuildingBlob(kId, elements);
320 EXPECT_FALSE(host_->shutdown_for_bad_message_); 324 EXPECT_FALSE(host_->shutdown_for_bad_message_);
321 325
322 // Expect our first request. 326 // Expect our first request.
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 std::memset(memory.memory(), 'Z', kTestBlobStorageMaxSharedMemoryBytes); 371 std::memset(memory.memory(), 'Z', kTestBlobStorageMaxSharedMemoryBytes);
368 memory.Close(); 372 memory.Close();
369 } 373 }
370 // Send the confirmation. 374 // Send the confirmation.
371 responses = {BlobItemBytesResponse(1)}; 375 responses = {BlobItemBytesResponse(1)};
372 host_->OnMemoryItemResponse(kId, responses); 376 host_->OnMemoryItemResponse(kId, responses);
373 377
374 ExpectDone(kId); 378 ExpectDone(kId);
375 sink_.ClearMessages(); 379 sink_.ClearMessages();
376 base::RunLoop().RunUntilIdle(); 380 base::RunLoop().RunUntilIdle();
377 EXPECT_TRUE(built); 381 EXPECT_TRUE(built) << "Error code: " << static_cast<int>(error_code);
378 EXPECT_TRUE(context_->registry().HasEntry(kId)); 382 EXPECT_TRUE(context_->registry().HasEntry(kId));
379 scoped_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId); 383 scoped_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId);
380 EXPECT_TRUE(handle); 384 EXPECT_TRUE(handle);
381 385
382 DataElement expected; 386 DataElement expected;
383 expected.SetToAllocatedBytes(kLargeSize / 2); 387 expected.SetToAllocatedBytes(kLargeSize / 2);
384 std::memset(expected.mutable_bytes(), 'X', kLargeSize / 2); 388 std::memset(expected.mutable_bytes(), 'X', kLargeSize / 2);
385 elements = {expected}; 389 elements = {expected};
386 std::memset(expected.mutable_bytes(), 'Z', kLargeSize / 2); 390 std::memset(expected.mutable_bytes(), 'Z', kLargeSize / 2);
387 elements.push_back(expected); 391 elements.push_back(expected);
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 host_->OnRegisterBlobUUID(kId, std::string(kContentType), 475 host_->OnRegisterBlobUUID(kId, std::string(kContentType),
472 std::string(kContentDisposition), 476 std::string(kContentDisposition),
473 std::set<std::string>()); 477 std::set<std::string>());
474 478
475 // Grab the handle. 479 // Grab the handle.
476 scoped_ptr<BlobDataHandle> blob_data_handle = 480 scoped_ptr<BlobDataHandle> blob_data_handle =
477 context_->GetBlobDataFromUUID(kId); 481 context_->GetBlobDataFromUUID(kId);
478 EXPECT_TRUE(blob_data_handle); 482 EXPECT_TRUE(blob_data_handle);
479 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); 483 EXPECT_TRUE(blob_data_handle->IsBeingBuilt());
480 bool built = false; 484 bool built = false;
485 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN;
481 blob_data_handle->RunOnConstructionComplete( 486 blob_data_handle->RunOnConstructionComplete(
482 base::Bind(&SetPointerValue<bool>, &built)); 487 base::Bind(&ConstructionCompletePopulator, &built, &error_code));
483 488
484 // Continue building. 489 // Continue building.
485 DataElement element; 490 DataElement element;
486 element.SetToBytesDescription(kDataSize); 491 element.SetToBytesDescription(kDataSize);
487 std::vector<DataElement> elements = {element}; 492 std::vector<DataElement> elements = {element};
488 host_->OnStartBuildingBlob(kId, elements); 493 host_->OnStartBuildingBlob(kId, elements);
489 sink_.ClearMessages(); 494 sink_.ClearMessages();
490 495
491 // Send data. 496 // Send data.
492 BlobItemBytesResponse response(0); 497 BlobItemBytesResponse response(0);
493 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); 498 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize);
494 std::vector<BlobItemBytesResponse> responses = {response}; 499 std::vector<BlobItemBytesResponse> responses = {response};
495 sink_.ClearMessages(); 500 sink_.ClearMessages();
496 host_->OnMemoryItemResponse(kId, responses); 501 host_->OnMemoryItemResponse(kId, responses);
497 502
498 ExpectDone(kId); 503 ExpectDone(kId);
499 base::RunLoop().RunUntilIdle(); 504 base::RunLoop().RunUntilIdle();
500 EXPECT_TRUE(built); 505 EXPECT_TRUE(built) << "Error code: " << static_cast<int>(error_code);
501 } 506 }
502 507
503 TEST_F(BlobDispatcherHostTest, BlobReferenceWhileShortcutConstructing) { 508 TEST_F(BlobDispatcherHostTest, BlobReferenceWhileShortcutConstructing) {
504 const std::string kId("id"); 509 const std::string kId("id");
505 510
506 // Start building blob. 511 // Start building blob.
507 host_->OnRegisterBlobUUID(kId, std::string(kContentType), 512 host_->OnRegisterBlobUUID(kId, std::string(kContentType),
508 std::string(kContentDisposition), 513 std::string(kContentDisposition),
509 std::set<std::string>()); 514 std::set<std::string>());
510 515
511 // Grab the handle. 516 // Grab the handle.
512 scoped_ptr<BlobDataHandle> blob_data_handle = 517 scoped_ptr<BlobDataHandle> blob_data_handle =
513 context_->GetBlobDataFromUUID(kId); 518 context_->GetBlobDataFromUUID(kId);
514 EXPECT_TRUE(blob_data_handle); 519 EXPECT_TRUE(blob_data_handle);
515 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); 520 EXPECT_TRUE(blob_data_handle->IsBeingBuilt());
516 bool built = false; 521 bool built = false;
522 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN;
517 blob_data_handle->RunOnConstructionComplete( 523 blob_data_handle->RunOnConstructionComplete(
518 base::Bind(&SetPointerValue<bool>, &built)); 524 base::Bind(&ConstructionCompletePopulator, &built, &error_code));
519 525
520 // Continue building. 526 // Continue building.
521 DataElement element; 527 DataElement element;
522 element.SetToBytes(kData, kDataSize); 528 element.SetToBytes(kData, kDataSize);
523 std::vector<DataElement> elements = {element}; 529 std::vector<DataElement> elements = {element};
524 host_->OnStartBuildingBlob(kId, elements); 530 host_->OnStartBuildingBlob(kId, elements);
525 ExpectDone(kId); 531 ExpectDone(kId);
526 base::RunLoop().RunUntilIdle(); 532 base::RunLoop().RunUntilIdle();
527 EXPECT_TRUE(built); 533 EXPECT_TRUE(built) << "Error code: " << static_cast<int>(error_code);
528 } 534 }
529 535
530 TEST_F(BlobDispatcherHostTest, BlobReferenceWhileConstructingCancelled) { 536 TEST_F(BlobDispatcherHostTest, BlobReferenceWhileConstructingCancelled) {
531 const std::string kId("id"); 537 const std::string kId("id");
532 538
533 // Start building blob. 539 // Start building blob.
534 host_->OnRegisterBlobUUID(kId, std::string(kContentType), 540 host_->OnRegisterBlobUUID(kId, std::string(kContentType),
535 std::string(kContentDisposition), 541 std::string(kContentDisposition),
536 std::set<std::string>()); 542 std::set<std::string>());
537 543
538 // Grab the handle. 544 // Grab the handle.
539 scoped_ptr<BlobDataHandle> blob_data_handle = 545 scoped_ptr<BlobDataHandle> blob_data_handle =
540 context_->GetBlobDataFromUUID(kId); 546 context_->GetBlobDataFromUUID(kId);
541 EXPECT_TRUE(blob_data_handle); 547 EXPECT_TRUE(blob_data_handle);
542 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); 548 EXPECT_TRUE(blob_data_handle->IsBeingBuilt());
543 bool built = true; 549 bool built = true;
550 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN;
544 blob_data_handle->RunOnConstructionComplete( 551 blob_data_handle->RunOnConstructionComplete(
545 base::Bind(&SetPointerValue<bool>, &built)); 552 base::Bind(&ConstructionCompletePopulator, &built, &error_code));
546 553
547 // Cancel in middle of construction. 554 // Cancel in middle of construction.
548 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN); 555 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN);
549 base::RunLoop().RunUntilIdle(); 556 base::RunLoop().RunUntilIdle();
550 EXPECT_TRUE(context_->registry().HasEntry(kId)); 557 EXPECT_TRUE(context_->registry().HasEntry(kId));
551 EXPECT_TRUE(host_->IsInUseInHost(kId)); 558 EXPECT_TRUE(host_->IsInUseInHost(kId));
552 EXPECT_FALSE(IsBeingBuiltInHost(kId)); 559 EXPECT_FALSE(IsBeingBuiltInHost(kId));
553 EXPECT_TRUE(blob_data_handle->IsBroken()); 560 EXPECT_TRUE(blob_data_handle->IsBroken());
554 EXPECT_FALSE(built); 561 EXPECT_FALSE(built);
562 EXPECT_EQ(IPCBlobCreationCancelCode::UNKNOWN, error_code);
563 error_code = IPCBlobCreationCancelCode::UNKNOWN;
555 built = true; 564 built = true;
556 blob_data_handle->RunOnConstructionComplete( 565 blob_data_handle->RunOnConstructionComplete(
557 base::Bind(&SetPointerValue<bool>, &built)); 566 base::Bind(&ConstructionCompletePopulator, &built, &error_code));
558 EXPECT_FALSE(built); 567 EXPECT_FALSE(built);
568 EXPECT_EQ(IPCBlobCreationCancelCode::UNKNOWN, error_code);
559 569
560 // Remove it. 570 // Remove it.
561 blob_data_handle.reset(); 571 blob_data_handle.reset();
562 base::RunLoop().RunUntilIdle(); 572 base::RunLoop().RunUntilIdle();
563 EXPECT_TRUE(context_->registry().HasEntry(kId)); 573 EXPECT_TRUE(context_->registry().HasEntry(kId));
564 host_->OnDecrementBlobRefCount(kId); 574 host_->OnDecrementBlobRefCount(kId);
565 ExpectBlobNotExist(kId); 575 ExpectBlobNotExist(kId);
566 } 576 }
567 577
568 TEST_F(BlobDispatcherHostTest, DecrementRefAfterRegister) { 578 TEST_F(BlobDispatcherHostTest, DecrementRefAfterRegister) {
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 // OnStartBuildlingBlob, except we have another handle. 684 // OnStartBuildlingBlob, except we have another handle.
675 host_->OnRegisterBlobUUID(kId, std::string(kContentType), 685 host_->OnRegisterBlobUUID(kId, std::string(kContentType),
676 std::string(kContentDisposition), 686 std::string(kContentDisposition),
677 std::set<std::string>()); 687 std::set<std::string>());
678 EXPECT_FALSE(host_->shutdown_for_bad_message_); 688 EXPECT_FALSE(host_->shutdown_for_bad_message_);
679 689
680 scoped_ptr<BlobDataHandle> blob_data_handle = 690 scoped_ptr<BlobDataHandle> blob_data_handle =
681 context_->GetBlobDataFromUUID(kId); 691 context_->GetBlobDataFromUUID(kId);
682 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); 692 EXPECT_TRUE(blob_data_handle->IsBeingBuilt());
683 bool built = true; 693 bool built = true;
694 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN;
684 blob_data_handle->RunOnConstructionComplete( 695 blob_data_handle->RunOnConstructionComplete(
685 base::Bind(&SetPointerValue<bool>, &built)); 696 base::Bind(&ConstructionCompletePopulator, &built, &error_code));
686 697
687 DataElement element; 698 DataElement element;
688 element.SetToBytesDescription(kDataSize); 699 element.SetToBytesDescription(kDataSize);
689 std::vector<DataElement> elements = {element}; 700 std::vector<DataElement> elements = {element};
690 host_->OnStartBuildingBlob(kId, elements); 701 host_->OnStartBuildingBlob(kId, elements);
691 EXPECT_FALSE(host_->shutdown_for_bad_message_); 702 EXPECT_FALSE(host_->shutdown_for_bad_message_);
692 703
693 // Check that we got the expected request. 704 // Check that we got the expected request.
694 std::vector<BlobItemBytesRequest> expected_requests = { 705 std::vector<BlobItemBytesRequest> expected_requests = {
695 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; 706 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)};
696 ExpectRequest(kId, expected_requests); 707 ExpectRequest(kId, expected_requests);
697 sink_.ClearMessages(); 708 sink_.ClearMessages();
698 EXPECT_TRUE(context_->registry().HasEntry(kId)); 709 EXPECT_TRUE(context_->registry().HasEntry(kId));
699 EXPECT_TRUE(IsBeingBuiltInHost(kId)); 710 EXPECT_TRUE(IsBeingBuiltInHost(kId));
700 // Decrement, simulating where the ref goes out of scope in renderer. 711 // Decrement, simulating where the ref goes out of scope in renderer.
701 host_->OnDecrementBlobRefCount(kId); 712 host_->OnDecrementBlobRefCount(kId);
702 // We still have the blob as it's not done. 713 // We still have the blob as it's not done.
703 EXPECT_TRUE(context_->registry().HasEntry(kId)); 714 EXPECT_TRUE(context_->registry().HasEntry(kId));
704 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); 715 EXPECT_TRUE(blob_data_handle->IsBeingBuilt());
705 EXPECT_TRUE(IsBeingBuiltInHost(kId)); 716 EXPECT_TRUE(IsBeingBuiltInHost(kId));
706 // Cancel to clean up. 717 // Cancel to clean up.
707 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN); 718 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN);
708 // Run loop to propagate the handle decrement in the host. 719 // Run loop to propagate the handle decrement in the host.
709 base::RunLoop().RunUntilIdle(); 720 base::RunLoop().RunUntilIdle();
710 // We still have the entry because of our earlier handle. 721 // We still have the entry because of our earlier handle.
711 EXPECT_TRUE(context_->registry().HasEntry(kId)); 722 EXPECT_TRUE(context_->registry().HasEntry(kId));
712 EXPECT_FALSE(IsBeingBuiltInHost(kId)); 723 EXPECT_FALSE(IsBeingBuiltInHost(kId));
724 EXPECT_FALSE(built);
725 EXPECT_EQ(IPCBlobCreationCancelCode::UNKNOWN, error_code);
713 sink_.ClearMessages(); 726 sink_.ClearMessages();
714 727
715 // Should disappear after dropping the handle. 728 // Should disappear after dropping the handle.
716 EXPECT_TRUE(blob_data_handle->IsBroken()); 729 EXPECT_TRUE(blob_data_handle->IsBroken());
717 blob_data_handle.reset(); 730 blob_data_handle.reset();
718 base::RunLoop().RunUntilIdle(); 731 base::RunLoop().RunUntilIdle();
719 EXPECT_FALSE(context_->registry().HasEntry(kId)); 732 EXPECT_FALSE(context_->registry().HasEntry(kId));
720 } 733 }
721 734
722 TEST_F(BlobDispatcherHostTest, HostDisconnectAfterRegisterWithHandle) { 735 TEST_F(BlobDispatcherHostTest, HostDisconnectAfterRegisterWithHandle) {
723 const std::string kId("id"); 736 const std::string kId("id");
724 737
725 // Delete host with a handle to the blob. 738 // Delete host with a handle to the blob.
726 host_->OnRegisterBlobUUID(kId, std::string(kContentType), 739 host_->OnRegisterBlobUUID(kId, std::string(kContentType),
727 std::string(kContentDisposition), 740 std::string(kContentDisposition),
728 std::set<std::string>()); 741 std::set<std::string>());
729 742
730 scoped_ptr<BlobDataHandle> blob_data_handle = 743 scoped_ptr<BlobDataHandle> blob_data_handle =
731 context_->GetBlobDataFromUUID(kId); 744 context_->GetBlobDataFromUUID(kId);
732 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); 745 EXPECT_TRUE(blob_data_handle->IsBeingBuilt());
733 bool built = true; 746 bool built = true;
747 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN;
734 blob_data_handle->RunOnConstructionComplete( 748 blob_data_handle->RunOnConstructionComplete(
735 base::Bind(&SetPointerValue<bool>, &built)); 749 base::Bind(&ConstructionCompletePopulator, &built, &error_code));
736 // Get rid of host, which was doing the constructing. 750 // Get rid of host, which was doing the constructing.
737 host_ = nullptr; 751 host_ = nullptr;
738 EXPECT_FALSE(blob_data_handle->IsBeingBuilt()); 752 EXPECT_FALSE(blob_data_handle->IsBeingBuilt());
739 base::RunLoop().RunUntilIdle(); 753 base::RunLoop().RunUntilIdle();
740 EXPECT_FALSE(built); 754 EXPECT_FALSE(built);
755 EXPECT_EQ(IPCBlobCreationCancelCode::SOURCE_DIED_IN_TRANSIT, error_code);
741 756
742 // Should still be there due to the handle. 757 // Should still be there due to the handle.
743 scoped_ptr<BlobDataHandle> another_handle = 758 scoped_ptr<BlobDataHandle> another_handle =
744 context_->GetBlobDataFromUUID(kId); 759 context_->GetBlobDataFromUUID(kId);
745 EXPECT_TRUE(another_handle); 760 EXPECT_TRUE(another_handle);
746 761
747 // Should disappear after dropping both handles. 762 // Should disappear after dropping both handles.
748 blob_data_handle.reset(); 763 blob_data_handle.reset();
749 another_handle.reset(); 764 another_handle.reset();
750 base::RunLoop().RunUntilIdle(); 765 base::RunLoop().RunUntilIdle();
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
919 host2->OnDecrementBlobRefCount(kId); 934 host2->OnDecrementBlobRefCount(kId);
920 // So no more blob in the context, but we're still being built in host 1. 935 // So no more blob in the context, but we're still being built in host 1.
921 EXPECT_FALSE(context_->registry().HasEntry(kId)); 936 EXPECT_FALSE(context_->registry().HasEntry(kId));
922 EXPECT_TRUE(host_->async_builder_.IsBeingBuilt(kId)); 937 EXPECT_TRUE(host_->async_builder_.IsBeingBuilt(kId));
923 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN); 938 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN);
924 EXPECT_FALSE(host_->shutdown_for_bad_message_); 939 EXPECT_FALSE(host_->shutdown_for_bad_message_);
925 // We should be cleaned up. 940 // We should be cleaned up.
926 EXPECT_FALSE(host_->async_builder_.IsBeingBuilt(kId)); 941 EXPECT_FALSE(host_->async_builder_.IsBeingBuilt(kId));
927 } 942 }
928 943
944 TEST_F(BlobDispatcherHostTest, BuildingReferenceChain) {
945 const std::string kId("id");
946 const std::string kSameHostReferencingId("id2");
947 const std::string kDifferentHostReferencingId("id3");
948 // Data elements for our transfer & checking messages.
949 DataElement element;
950 element.SetToBytes(kData, kDataSize);
951 std::vector<DataElement> elements = {element};
952 DataElement referencing_element;
953 referencing_element.SetToBlob(kId);
954 std::vector<DataElement> referencing_elements = {referencing_element};
955 std::set<std::string> referenced_blobs_set = {kId};
956
957 scoped_refptr<TestableBlobDispatcherHost> host2(
958 new TestableBlobDispatcherHost(chrome_blob_storage_context_, &sink_));
959
960 // We want to have a blob referencing another blob that is building, both on
961 // the same host and a different host. We should successfully build all blobs
962 // after the referenced blob is finished.
963
964 // First we start the referenced blob.
965 host_->OnRegisterBlobUUID(kId, std::string(kContentType),
966 std::string(kContentDisposition),
967 std::set<std::string>());
968 EXPECT_TRUE(host_->IsInUseInHost(kId));
969
970 // Next we start the referencing blobs in both the same and different host.
971 host_->OnRegisterBlobUUID(kSameHostReferencingId, std::string(kContentType),
972 std::string(kContentDisposition),
973 referenced_blobs_set);
974 EXPECT_FALSE(host_->shutdown_for_bad_message_);
975 host_->OnStartBuildingBlob(kSameHostReferencingId, referencing_elements);
976 EXPECT_FALSE(host_->shutdown_for_bad_message_);
977 ExpectDone(kSameHostReferencingId);
978 EXPECT_TRUE(host_->async_builder_.IsBeingBuilt(kSameHostReferencingId));
979 sink_.ClearMessages();
980 // Now the other host.
981 host2->OnRegisterBlobUUID(
982 kDifferentHostReferencingId, std::string(kContentType),
983 std::string(kContentDisposition), referenced_blobs_set);
984 EXPECT_FALSE(host2->shutdown_for_bad_message_);
985 host2->OnStartBuildingBlob(kDifferentHostReferencingId, referencing_elements);
986 EXPECT_FALSE(host2->shutdown_for_bad_message_);
987 ExpectDone(kDifferentHostReferencingId);
988 EXPECT_TRUE(host2->async_builder_.IsBeingBuilt(kDifferentHostReferencingId));
989 sink_.ClearMessages();
990
991 // Now we finish the first blob, and we expect all blobs to finish.
992 host_->OnStartBuildingBlob(kId, elements);
993 ExpectDone(kId);
994 // We need to run the message loop to propagate the construction callbacks.
995 base::RunLoop().RunUntilIdle();
996 EXPECT_FALSE(host2->async_builder_.IsBeingBuilt(kDifferentHostReferencingId));
997 EXPECT_FALSE(host_->async_builder_.IsBeingBuilt(kSameHostReferencingId));
998 EXPECT_FALSE(
999 context_->GetBlobDataFromUUID(kSameHostReferencingId)->IsBroken());
1000 EXPECT_FALSE(
1001 context_->GetBlobDataFromUUID(kDifferentHostReferencingId)->IsBroken());
1002 sink_.ClearMessages();
1003
1004 // Finally check that our data is correct in the child elements.
1005 scoped_ptr<BlobDataHandle> handle =
1006 context_->GetBlobDataFromUUID(kDifferentHostReferencingId);
1007 ExpectHandleEqualsData(handle.get(), elements);
1008 }
1009
1010 TEST_F(BlobDispatcherHostTest, BuildingReferenceChainWithCancel) {
1011 const std::string kId("id");
1012 const std::string kSameHostReferencingId("id2");
1013 const std::string kDifferentHostReferencingId("id3");
1014 // Data elements for our transfer & checking messages.
1015 DataElement referencing_element;
1016 referencing_element.SetToBlob(kId);
1017 std::vector<DataElement> referencing_elements = {referencing_element};
1018 std::set<std::string> referenced_blobs_set = {kId};
1019
1020 scoped_refptr<TestableBlobDispatcherHost> host2(
1021 new TestableBlobDispatcherHost(chrome_blob_storage_context_, &sink_));
1022
1023 // We want to have a blob referencing another blob that is building, both on
1024 // the same host and a different host. After we cancel the first blob, the
1025 // others should cancel as well.
1026
1027 // First we start the referenced blob.
1028 host_->OnRegisterBlobUUID(kId, std::string(kContentType),
1029 std::string(kContentDisposition),
1030 std::set<std::string>());
1031 EXPECT_TRUE(host_->IsInUseInHost(kId));
1032
1033 // Next we start the referencing blobs in both the same and different host.
1034 host_->OnRegisterBlobUUID(kSameHostReferencingId, std::string(kContentType),
1035 std::string(kContentDisposition),
1036 referenced_blobs_set);
1037 host_->OnStartBuildingBlob(kSameHostReferencingId, referencing_elements);
1038 ExpectDone(kSameHostReferencingId);
1039 EXPECT_TRUE(host_->async_builder_.IsBeingBuilt(kSameHostReferencingId));
1040 sink_.ClearMessages();
1041 // Now the other host.
1042 host2->OnRegisterBlobUUID(
1043 kDifferentHostReferencingId, std::string(kContentType),
1044 std::string(kContentDisposition), referenced_blobs_set);
1045 host2->OnStartBuildingBlob(kDifferentHostReferencingId, referencing_elements);
1046 ExpectDone(kDifferentHostReferencingId);
1047 EXPECT_TRUE(host2->async_builder_.IsBeingBuilt(kDifferentHostReferencingId));
1048 sink_.ClearMessages();
1049 bool built = false;
1050 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN;
1051 context_->GetBlobDataFromUUID(kDifferentHostReferencingId)
1052 ->RunOnConstructionComplete(
1053 base::Bind(&ConstructionCompletePopulator, &built, &error_code));
1054
1055 // Now we cancel the first blob, and we expect all blobs to cancel.
1056 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN);
1057 // We need to run the message loop to propagate the construction callbacks.
1058 base::RunLoop().RunUntilIdle();
1059 EXPECT_FALSE(host2->async_builder_.IsBeingBuilt(kDifferentHostReferencingId));
1060 EXPECT_FALSE(host_->async_builder_.IsBeingBuilt(kSameHostReferencingId));
1061 EXPECT_TRUE(
1062 context_->GetBlobDataFromUUID(kSameHostReferencingId)->IsBroken());
1063 EXPECT_TRUE(
1064 context_->GetBlobDataFromUUID(kDifferentHostReferencingId)->IsBroken());
1065 EXPECT_FALSE(built);
1066 EXPECT_EQ(IPCBlobCreationCancelCode::REFERENCED_BLOB_BROKEN, error_code);
1067 sink_.ClearMessages();
1068 }
1069
1070 TEST_F(BlobDispatcherHostTest, BuildingReferenceChainWithSourceDeath) {
1071 const std::string kId("id");
1072 const std::string kSameHostReferencingId("id2");
1073 const std::string kDifferentHostReferencingId("id3");
1074 // Data elements for our transfer & checking messages.
1075 DataElement referencing_element;
1076 referencing_element.SetToBlob(kId);
1077 std::vector<DataElement> referencing_elements = {referencing_element};
1078 std::set<std::string> referenced_blobs_set = {kId};
1079
1080 scoped_refptr<TestableBlobDispatcherHost> host2(
1081 new TestableBlobDispatcherHost(chrome_blob_storage_context_, &sink_));
1082
1083 // We want to have a blob referencing another blob that is building, both on
1084 // the same host and a different host. When we destroy the host, the other
1085 // blob should cancel, as well as the blob on the other host.
1086
1087 // First we start the referenced blob.
1088 host_->OnRegisterBlobUUID(kId, std::string(kContentType),
1089 std::string(kContentDisposition),
1090 std::set<std::string>());
1091 EXPECT_TRUE(host_->IsInUseInHost(kId));
1092
1093 // Next we start the referencing blobs in both the same and different host.
1094 host_->OnRegisterBlobUUID(kSameHostReferencingId, std::string(kContentType),
1095 std::string(kContentDisposition),
1096 referenced_blobs_set);
1097 host_->OnStartBuildingBlob(kSameHostReferencingId, referencing_elements);
1098 ExpectDone(kSameHostReferencingId);
1099 EXPECT_TRUE(host_->async_builder_.IsBeingBuilt(kSameHostReferencingId));
1100 sink_.ClearMessages();
1101 // Now the other host.
1102 host2->OnRegisterBlobUUID(
1103 kDifferentHostReferencingId, std::string(kContentType),
1104 std::string(kContentDisposition), referenced_blobs_set);
1105 host2->OnStartBuildingBlob(kDifferentHostReferencingId, referencing_elements);
1106 ExpectDone(kDifferentHostReferencingId);
1107 EXPECT_TRUE(host2->async_builder_.IsBeingBuilt(kDifferentHostReferencingId));
1108 sink_.ClearMessages();
1109
1110 // Grab handles & add listeners.
1111 bool built = true;
1112 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN;
1113 scoped_ptr<BlobDataHandle> blob_handle = context_->GetBlobDataFromUUID(kId);
1114 blob_handle->RunOnConstructionComplete(
1115 base::Bind(&ConstructionCompletePopulator, &built, &error_code));
1116
1117 bool same_host_built = true;
1118 IPCBlobCreationCancelCode same_host_error_code =
1119 IPCBlobCreationCancelCode::UNKNOWN;
1120 scoped_ptr<BlobDataHandle> same_host_blob_handle =
1121 context_->GetBlobDataFromUUID(kSameHostReferencingId);
1122 same_host_blob_handle->RunOnConstructionComplete(base::Bind(
1123 &ConstructionCompletePopulator, &same_host_built, &same_host_error_code));
1124
1125 bool other_host_built = true;
1126 IPCBlobCreationCancelCode other_host_error_code =
1127 IPCBlobCreationCancelCode::UNKNOWN;
1128 scoped_ptr<BlobDataHandle> other_host_blob_handle =
1129 context_->GetBlobDataFromUUID(kDifferentHostReferencingId);
1130 other_host_blob_handle->RunOnConstructionComplete(
1131 base::Bind(&ConstructionCompletePopulator, &other_host_built,
1132 &other_host_error_code));
1133
1134 // Now we kill the host.
1135 host_ = nullptr;
1136 // We need to run the message loop to propagate the construction callbacks.
1137 base::RunLoop().RunUntilIdle();
1138 EXPECT_FALSE(host2->async_builder_.IsBeingBuilt(kDifferentHostReferencingId));
1139 EXPECT_TRUE(
1140 context_->GetBlobDataFromUUID(kSameHostReferencingId)->IsBroken());
1141 EXPECT_TRUE(
1142 context_->GetBlobDataFromUUID(kDifferentHostReferencingId)->IsBroken());
1143
1144 // Check our callbacks
1145 EXPECT_FALSE(built);
1146 EXPECT_EQ(IPCBlobCreationCancelCode::SOURCE_DIED_IN_TRANSIT, error_code);
1147 EXPECT_FALSE(same_host_built);
1148 EXPECT_EQ(IPCBlobCreationCancelCode::SOURCE_DIED_IN_TRANSIT,
1149 same_host_error_code);
1150 EXPECT_FALSE(other_host_built);
1151 EXPECT_EQ(IPCBlobCreationCancelCode::SOURCE_DIED_IN_TRANSIT,
1152 other_host_error_code);
1153
1154 sink_.ClearMessages();
1155 }
1156
929 } // namespace content 1157 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/blob_storage/blob_dispatcher_host.h ('k') | storage/browser/blob/blob_async_builder_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698