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

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

Issue 2055053003: [BlobAsync] Disk support for blob storage (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added back transport controller test, small cleanups Created 4 years, 5 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 <memory> 7 #include <memory>
8 #include <tuple> 8 #include <tuple>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/memory/shared_memory.h" 12 #include "base/memory/shared_memory.h"
13 #include "base/run_loop.h" 13 #include "base/run_loop.h"
14 #include "base/strings/string_number_conversions.h"
14 #include "content/browser/blob_storage/chrome_blob_storage_context.h" 15 #include "content/browser/blob_storage/chrome_blob_storage_context.h"
15 #include "content/common/fileapi/webblob_messages.h" 16 #include "content/common/fileapi/webblob_messages.h"
16 #include "content/public/common/content_switches.h" 17 #include "content/public/common/content_switches.h"
17 #include "content/public/test/test_browser_context.h" 18 #include "content/public/test/test_browser_context.h"
18 #include "content/public/test/test_browser_thread_bundle.h" 19 #include "content/public/test/test_browser_thread_bundle.h"
19 #include "ipc/ipc_sender.h" 20 #include "ipc/ipc_sender.h"
20 #include "ipc/ipc_test_sink.h" 21 #include "ipc/ipc_test_sink.h"
21 #include "ipc/message_filter.h" 22 #include "ipc/message_filter.h"
22 #include "storage/browser/blob/blob_data_builder.h" 23 #include "storage/browser/blob/blob_data_builder.h"
23 #include "storage/browser/blob/blob_data_handle.h" 24 #include "storage/browser/blob/blob_data_handle.h"
(...skipping 18 matching lines...) Expand all
42 namespace content { 43 namespace content {
43 namespace { 44 namespace {
44 45
45 const char kContentType[] = "text/plain"; 46 const char kContentType[] = "text/plain";
46 const char kContentDisposition[] = "content_disposition"; 47 const char kContentDisposition[] = "content_disposition";
47 const char kData[] = "data!!"; 48 const char kData[] = "data!!";
48 const size_t kDataSize = 6; 49 const size_t kDataSize = 6;
49 50
50 const size_t kTestBlobStorageIPCThresholdBytes = 20; 51 const size_t kTestBlobStorageIPCThresholdBytes = 20;
51 const size_t kTestBlobStorageMaxSharedMemoryBytes = 50; 52 const size_t kTestBlobStorageMaxSharedMemoryBytes = 50;
53 const size_t kTestBlobStorageMaxBlobMemorySize = 400;
54 const size_t kTestBlobStorageMaxMemoryUsage = 500;
55 const uint64_t kTestBlobStorageMaxDiskSpace = 1000;
56 const size_t kTestBlobStorageInFlightMemory = 10;
57 const uint64_t kTestBlobStorageMinFileSizeBytes = 10;
52 const uint64_t kTestBlobStorageMaxFileSizeBytes = 100; 58 const uint64_t kTestBlobStorageMaxFileSizeBytes = 100;
53 59
54 void ConstructionCompletePopulator(bool* succeeded_pointer, 60 void ConstructionCompletePopulator(bool* succeeded_pointer,
55 IPCBlobCreationCancelCode* reason_pointer, 61 IPCBlobCreationCancelCode* reason_pointer,
56 bool succeeded, 62 bool succeeded,
57 IPCBlobCreationCancelCode reason) { 63 IPCBlobCreationCancelCode reason) {
58 *succeeded_pointer = succeeded; 64 *succeeded_pointer = succeeded;
59 *reason_pointer = reason; 65 *reason_pointer = reason;
60 } 66 }
61 67
62 class TestableBlobDispatcherHost : public BlobDispatcherHost { 68 class TestableBlobDispatcherHost : public BlobDispatcherHost {
63 public: 69 public:
64 TestableBlobDispatcherHost(ChromeBlobStorageContext* blob_storage_context, 70 TestableBlobDispatcherHost(ChromeBlobStorageContext* blob_storage_context,
65 IPC::TestSink* sink) 71 IPC::TestSink* sink)
66 : BlobDispatcherHost(blob_storage_context), sink_(sink) { 72 : BlobDispatcherHost(blob_storage_context), sink_(sink) {}
67 this->SetMemoryConstantsForTesting(kTestBlobStorageIPCThresholdBytes,
68 kTestBlobStorageMaxSharedMemoryBytes,
69 kTestBlobStorageMaxFileSizeBytes);
70 }
71 73
72 bool Send(IPC::Message* message) override { return sink_->Send(message); } 74 bool Send(IPC::Message* message) override { return sink_->Send(message); }
73 75
74 void ShutdownForBadMessage() override { shutdown_for_bad_message_ = true; } 76 void ShutdownForBadMessage() override { shutdown_for_bad_message_ = true; }
75 77
76 bool shutdown_for_bad_message_ = false; 78 bool shutdown_for_bad_message_ = false;
77 79
78 protected: 80 protected:
79 ~TestableBlobDispatcherHost() override {} 81 ~TestableBlobDispatcherHost() override {}
80 82
81 private: 83 private:
82 friend class base::RefCountedThreadSafe<TestableBlobDispatcherHost>; 84 friend class base::RefCountedThreadSafe<TestableBlobDispatcherHost>;
83 85
84 IPC::TestSink* sink_; 86 IPC::TestSink* sink_;
85 }; 87 };
88 //
89 // void SetElementToCharBytes(DataElement* element, char byte, size_t size) {
90 // std::vector<char> data(size);
91 // data.assign(size, byte);
92 // element->SetToBytes(data.data(), size);
93 //}
86 94
87 } // namespace 95 } // namespace
88 96
89 class BlobDispatcherHostTest : public testing::Test { 97 class BlobDispatcherHostTest : public testing::Test {
90 protected: 98 protected:
91 BlobDispatcherHostTest() 99 BlobDispatcherHostTest()
92 : chrome_blob_storage_context_( 100 : chrome_blob_storage_context_(
93 ChromeBlobStorageContext::GetFor(&browser_context_)) { 101 ChromeBlobStorageContext::GetFor(&browser_context_)) {
94 host_ = 102 host_ =
95 new TestableBlobDispatcherHost(chrome_blob_storage_context_, &sink_); 103 new TestableBlobDispatcherHost(chrome_blob_storage_context_, &sink_);
96 } 104 }
97 ~BlobDispatcherHostTest() override {} 105 ~BlobDispatcherHostTest() override {}
98 106
99 void SetUp() override { 107 void SetUp() override {
100 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); 108 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
101 if (!command_line->HasSwitch(switches::kDisableKillAfterBadIPC)) { 109 if (!command_line->HasSwitch(switches::kDisableKillAfterBadIPC)) {
102 command_line->AppendSwitch(switches::kDisableKillAfterBadIPC); 110 command_line->AppendSwitch(switches::kDisableKillAfterBadIPC);
103 } 111 }
104 // We run the run loop to initialize the chrome blob storage context. 112 // We run the run loop to initialize the chrome blob storage context.
105 base::RunLoop().RunUntilIdle(); 113 base::RunLoop().RunUntilIdle();
106 context_ = chrome_blob_storage_context_->context(); 114 context_ = chrome_blob_storage_context_->context();
115 context_->mutable_memory_controller()->SetMemoryContantsForTesting(
116 kTestBlobStorageIPCThresholdBytes, kTestBlobStorageMaxSharedMemoryBytes,
117 kTestBlobStorageMaxBlobMemorySize, kTestBlobStorageMaxMemoryUsage,
118 kTestBlobStorageMaxDiskSpace, kTestBlobStorageInFlightMemory,
119 kTestBlobStorageMinFileSizeBytes, kTestBlobStorageMaxFileSizeBytes);
107 DCHECK(context_); 120 DCHECK(context_);
108 } 121 }
109 122
110 void ExpectBlobNotExist(const std::string& id) { 123 void ExpectBlobNotExist(const std::string& id) {
111 EXPECT_FALSE(context_->registry().HasEntry(id)); 124 EXPECT_FALSE(context_->registry().HasEntry(id));
112 EXPECT_FALSE(host_->IsInUseInHost(id)); 125 EXPECT_FALSE(host_->IsInUseInHost(id));
113 EXPECT_FALSE(IsBeingBuiltInHost(id)); 126 EXPECT_FALSE(IsBeingBuiltInHost(id));
114 } 127 }
115 128
116 void AsyncShortcutBlobTransfer(const std::string& id) { 129 void AsyncShortcutBlobTransfer(const std::string& id) {
117 sink_.ClearMessages(); 130 sink_.ClearMessages();
118 ExpectBlobNotExist(id); 131 ExpectBlobNotExist(id);
119 host_->OnRegisterBlobUUID(id, std::string(kContentType),
120 std::string(kContentDisposition),
121 std::set<std::string>());
122 EXPECT_FALSE(host_->shutdown_for_bad_message_);
123 DataElement element; 132 DataElement element;
124 element.SetToBytes(kData, kDataSize); 133 element.SetToBytes(kData, kDataSize);
125 std::vector<DataElement> elements = {element}; 134 std::vector<DataElement> elements = {element};
126 host_->OnStartBuildingBlob(id, elements); 135 host_->OnRegisterBlob(id, std::string(kContentType),
136 std::string(kContentDisposition), elements);
127 EXPECT_FALSE(host_->shutdown_for_bad_message_); 137 EXPECT_FALSE(host_->shutdown_for_bad_message_);
128 ExpectDone(id); 138 ExpectDone(id);
129 sink_.ClearMessages(); 139 sink_.ClearMessages();
130 } 140 }
131 141
132 void AsyncBlobTransfer(const std::string& id) { 142 void AsyncBlobTransfer(const std::string& id) {
133 sink_.ClearMessages(); 143 sink_.ClearMessages();
134 ExpectBlobNotExist(id); 144 ExpectBlobNotExist(id);
135 host_->OnRegisterBlobUUID(id, std::string(kContentType),
136 std::string(kContentDisposition),
137 std::set<std::string>());
138 EXPECT_FALSE(host_->shutdown_for_bad_message_);
139 DataElement element; 145 DataElement element;
140 element.SetToBytesDescription(kDataSize); 146 element.SetToBytesDescription(kDataSize);
141 std::vector<DataElement> elements = {element}; 147 std::vector<DataElement> elements = {element};
142 host_->OnStartBuildingBlob(id, elements); 148 host_->OnRegisterBlob(id, std::string(kContentType),
149 std::string(kContentDisposition), elements);
143 EXPECT_FALSE(host_->shutdown_for_bad_message_); 150 EXPECT_FALSE(host_->shutdown_for_bad_message_);
144 151
145 // Expect our request. 152 // Expect our request.
146 std::vector<BlobItemBytesRequest> expected_requests = { 153 std::vector<BlobItemBytesRequest> expected_requests = {
147 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; 154 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)};
148 ExpectRequest(id, expected_requests); 155 ExpectRequest(id, expected_requests);
149 sink_.ClearMessages(); 156 sink_.ClearMessages();
150 157
151 // Send results; 158 // Send results;
152 BlobItemBytesResponse response(0); 159 BlobItemBytesResponse response(0);
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 sink_.GetUniqueMessageMatching(BlobStorageMsg_DoneBuildingBlob::ID); 254 sink_.GetUniqueMessageMatching(BlobStorageMsg_DoneBuildingBlob::ID);
248 std::tuple<std::string> args; 255 std::tuple<std::string> args;
249 BlobStorageMsg_DoneBuildingBlob::Read(message, &args); 256 BlobStorageMsg_DoneBuildingBlob::Read(message, &args);
250 EXPECT_EQ(expected_uuid, std::get<0>(args)); 257 EXPECT_EQ(expected_uuid, std::get<0>(args));
251 } 258 }
252 259
253 bool IsBeingBuiltInHost(const std::string& uuid) { 260 bool IsBeingBuiltInHost(const std::string& uuid) {
254 return host_->async_builder_.IsBeingBuilt(uuid); 261 return host_->async_builder_.IsBeingBuilt(uuid);
255 } 262 }
256 263
264 bool IsBeingBuiltInContext(const std::string& uuid) {
265 return context_->IsBeingBuilt(uuid);
266 }
267
257 IPC::TestSink sink_; 268 IPC::TestSink sink_;
258 TestBrowserThreadBundle browser_thread_bundle_; 269 TestBrowserThreadBundle browser_thread_bundle_;
259 TestBrowserContext browser_context_; 270 TestBrowserContext browser_context_;
260 ChromeBlobStorageContext* chrome_blob_storage_context_; 271 ChromeBlobStorageContext* chrome_blob_storage_context_;
261 BlobStorageContext* context_ = nullptr; 272 BlobStorageContext* context_ = nullptr;
262 scoped_refptr<TestableBlobDispatcherHost> host_; 273 scoped_refptr<TestableBlobDispatcherHost> host_;
263 }; 274 };
264 275
265 TEST_F(BlobDispatcherHostTest, EmptyUUIDs) { 276 TEST_F(BlobDispatcherHostTest, EmptyUUIDs) {
266 host_->OnRegisterBlobUUID("", "", "", std::set<std::string>()); 277 host_->OnRegisterBlob("", "", "", std::vector<DataElement>());
267 ExpectAndResetBadMessage();
268 host_->OnStartBuildingBlob("", std::vector<DataElement>());
269 ExpectAndResetBadMessage(); 278 ExpectAndResetBadMessage();
270 host_->OnMemoryItemResponse("", std::vector<BlobItemBytesResponse>()); 279 host_->OnMemoryItemResponse("", std::vector<BlobItemBytesResponse>());
271 ExpectAndResetBadMessage(); 280 ExpectAndResetBadMessage();
272 host_->OnCancelBuildingBlob("", IPCBlobCreationCancelCode::UNKNOWN); 281 host_->OnCancelBuildingBlob("", IPCBlobCreationCancelCode::UNKNOWN);
273 ExpectAndResetBadMessage(); 282 ExpectAndResetBadMessage();
274 } 283 }
275 284
276 TEST_F(BlobDispatcherHostTest, Shortcut) { 285 TEST_F(BlobDispatcherHostTest, Shortcut) {
277 const std::string kId = "uuid1"; 286 const std::string kId = "uuid1";
278 AsyncShortcutBlobTransfer(kId); 287 AsyncShortcutBlobTransfer(kId);
(...skipping 16 matching lines...) Expand all
295 304
296 DataElement expected; 305 DataElement expected;
297 expected.SetToBytes(kData, kDataSize); 306 expected.SetToBytes(kData, kDataSize);
298 std::vector<DataElement> elements = {expected}; 307 std::vector<DataElement> elements = {expected};
299 ExpectHandleEqualsData(handle.get(), elements); 308 ExpectHandleEqualsData(handle.get(), elements);
300 } 309 }
301 310
302 TEST_F(BlobDispatcherHostTest, MultipleTransfers) { 311 TEST_F(BlobDispatcherHostTest, MultipleTransfers) {
303 const std::string kId = "uuid"; 312 const std::string kId = "uuid";
304 const int kNumIters = 10; 313 const int kNumIters = 10;
314 sink_.ClearMessages();
305 for (int i = 0; i < kNumIters; i++) { 315 for (int i = 0; i < kNumIters; i++) {
306 std::string id = kId; 316 std::string id = kId;
307 id += ('0' + i); 317 id += ('0' + i);
308 ExpectBlobNotExist(id); 318 ExpectBlobNotExist(id);
309 host_->OnRegisterBlobUUID(id, std::string(kContentType),
310 std::string(kContentDisposition),
311 std::set<std::string>());
312 EXPECT_FALSE(host_->shutdown_for_bad_message_);
313 }
314 sink_.ClearMessages();
315 for (int i = 0; i < kNumIters; i++) {
316 std::string id = kId;
317 id += ('0' + i);
318 DataElement element; 319 DataElement element;
319 element.SetToBytesDescription(kDataSize); 320 element.SetToBytesDescription(kDataSize);
320 std::vector<DataElement> elements = {element}; 321 std::vector<DataElement> elements = {element};
321 host_->OnStartBuildingBlob(id, elements); 322 host_->OnRegisterBlob(id, std::string(kContentType),
323 std::string(kContentDisposition), elements);
322 EXPECT_FALSE(host_->shutdown_for_bad_message_); 324 EXPECT_FALSE(host_->shutdown_for_bad_message_);
323 // Expect our request. 325 // Expect our request.
324 std::vector<BlobItemBytesRequest> expected_requests = { 326 std::vector<BlobItemBytesRequest> expected_requests = {
325 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; 327 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)};
326 ExpectRequest(id, expected_requests); 328 ExpectRequest(id, expected_requests);
327 sink_.ClearMessages(); 329 sink_.ClearMessages();
328 } 330 }
329 for (int i = 0; i < kNumIters; i++) { 331 for (int i = 0; i < kNumIters; i++) {
330 std::string id = kId; 332 std::string id = kId;
331 id += ('0' + i); 333 id += ('0' + i);
332 // Send results; 334 // Send results;
333 BlobItemBytesResponse response(0); 335 BlobItemBytesResponse response(0);
334 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); 336 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize);
335 std::vector<BlobItemBytesResponse> responses = {response}; 337 std::vector<BlobItemBytesResponse> responses = {response};
336 host_->OnMemoryItemResponse(id, responses); 338 host_->OnMemoryItemResponse(id, responses);
337 ExpectDone(id); 339 ExpectDone(id);
338 sink_.ClearMessages(); 340 sink_.ClearMessages();
339 } 341 }
340 } 342 }
341 343
342 TEST_F(BlobDispatcherHostTest, SharedMemoryTransfer) { 344 TEST_F(BlobDispatcherHostTest, SharedMemoryTransfer) {
343 const std::string kId = "uuid1"; 345 const std::string kId = "uuid1";
344 const size_t kLargeSize = kTestBlobStorageMaxSharedMemoryBytes * 2; 346 const size_t kLargeSize = kTestBlobStorageMaxSharedMemoryBytes * 2;
345 std::vector<base::SharedMemoryHandle> shared_memory_handles; 347 std::vector<base::SharedMemoryHandle> shared_memory_handles;
346 348
347 ExpectBlobNotExist(kId); 349 ExpectBlobNotExist(kId);
348 host_->OnRegisterBlobUUID(kId, std::string(kContentType), 350 DataElement element;
349 std::string(kContentDisposition), 351 element.SetToBytesDescription(kLargeSize);
350 std::set<std::string>()); 352 std::vector<DataElement> elements = {element};
353 host_->OnRegisterBlob(kId, std::string(kContentType),
354 std::string(kContentDisposition), elements);
355 EXPECT_FALSE(host_->shutdown_for_bad_message_);
351 356
352 // Grab the handle. 357 // Grab the handle.
353 std::unique_ptr<BlobDataHandle> blob_data_handle = 358 std::unique_ptr<BlobDataHandle> blob_data_handle =
354 context_->GetBlobDataFromUUID(kId); 359 context_->GetBlobDataFromUUID(kId);
355 bool built = false; 360 bool built = false;
356 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN; 361 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN;
357 blob_data_handle->RunOnConstructionComplete( 362 blob_data_handle->RunOnConstructionComplete(
358 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); 363 base::Bind(&ConstructionCompletePopulator, &built, &error_code));
359 EXPECT_FALSE(built); 364 EXPECT_FALSE(built);
360 365
361 EXPECT_FALSE(host_->shutdown_for_bad_message_); 366 EXPECT_FALSE(host_->shutdown_for_bad_message_);
362 DataElement element;
363 element.SetToBytesDescription(kLargeSize);
364 std::vector<DataElement> elements = {element};
365 host_->OnStartBuildingBlob(kId, elements);
366 EXPECT_FALSE(host_->shutdown_for_bad_message_);
367 367
368 // Expect our first request. 368 // Expect our first request.
369 std::vector<BlobItemBytesRequest> expected_requests = { 369 std::vector<BlobItemBytesRequest> expected_requests = {
370 BlobItemBytesRequest::CreateSharedMemoryRequest( 370 BlobItemBytesRequest::CreateSharedMemoryRequest(
371 0 /* request_number */, 0 /* renderer_item_index */, 371 0 /* request_number */, 0 /* renderer_item_index */,
372 0 /* renderer_item_offset */, 372 0 /* renderer_item_offset */,
373 static_cast<uint64_t>( 373 static_cast<uint64_t>(
374 kTestBlobStorageMaxSharedMemoryBytes) /* size */, 374 kTestBlobStorageMaxSharedMemoryBytes) /* size */,
375 0 /* handle_index */, 0 /* handle_offset */)}; 375 0 /* handle_index */, 0 /* handle_offset */)};
376 ExpectRequestWithSharedMemoryHandles(kId, expected_requests, 376 ExpectRequestWithSharedMemoryHandles(kId, expected_requests,
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 } 435 }
436 436
437 TEST_F(BlobDispatcherHostTest, OnCancelBuildingBlob) { 437 TEST_F(BlobDispatcherHostTest, OnCancelBuildingBlob) {
438 const std::string kId("id"); 438 const std::string kId("id");
439 // We ignore blobs that are unknown, as it could have been cancelled earlier 439 // We ignore blobs that are unknown, as it could have been cancelled earlier
440 // and the renderer didn't know about it yet. 440 // and the renderer didn't know about it yet.
441 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN); 441 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN);
442 EXPECT_FALSE(host_->shutdown_for_bad_message_); 442 EXPECT_FALSE(host_->shutdown_for_bad_message_);
443 443
444 // Start building blob. 444 // Start building blob.
445 host_->OnRegisterBlobUUID(kId, std::string(kContentType),
446 std::string(kContentDisposition),
447 std::set<std::string>());
448 EXPECT_FALSE(host_->shutdown_for_bad_message_);
449 DataElement element; 445 DataElement element;
450 element.SetToBytesDescription(kDataSize); 446 element.SetToBytesDescription(kDataSize);
451 std::vector<DataElement> elements = {element}; 447 std::vector<DataElement> elements = {element};
452 host_->OnStartBuildingBlob(kId, elements); 448 host_->OnRegisterBlob(kId, std::string(kContentType),
449 std::string(kContentDisposition), elements);
453 // It should have requested memory here. 450 // It should have requested memory here.
454 EXPECT_FALSE(host_->shutdown_for_bad_message_); 451 EXPECT_FALSE(host_->shutdown_for_bad_message_);
455 sink_.ClearMessages(); 452 sink_.ClearMessages();
456 453
457 // Cancel in middle of construction. 454 // Cancel in middle of construction.
458 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN); 455 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN);
459 EXPECT_TRUE(context_->registry().HasEntry(kId)); 456 EXPECT_TRUE(context_->registry().HasEntry(kId));
460 EXPECT_TRUE(host_->IsInUseInHost(kId)); 457 EXPECT_TRUE(host_->IsInUseInHost(kId));
461 EXPECT_FALSE(IsBeingBuiltInHost(kId)); 458 EXPECT_FALSE(IsBeingBuiltInHost(kId));
462 // Check that's it's broken. 459 // Check that's it's broken.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 base::RunLoop().RunUntilIdle(); 505 base::RunLoop().RunUntilIdle();
509 506
510 handle = context_->GetBlobDataFromUUID(kId); 507 handle = context_->GetBlobDataFromUUID(kId);
511 EXPECT_FALSE(handle); 508 EXPECT_FALSE(handle);
512 } 509 }
513 510
514 TEST_F(BlobDispatcherHostTest, BlobReferenceWhileConstructing) { 511 TEST_F(BlobDispatcherHostTest, BlobReferenceWhileConstructing) {
515 const std::string kId("id"); 512 const std::string kId("id");
516 513
517 // Start building blob. 514 // Start building blob.
518 host_->OnRegisterBlobUUID(kId, std::string(kContentType), 515 DataElement element;
519 std::string(kContentDisposition), 516 element.SetToBytesDescription(kDataSize);
520 std::set<std::string>()); 517 std::vector<DataElement> elements = {element};
518 host_->OnRegisterBlob(kId, std::string(kContentType),
519 std::string(kContentDisposition), elements);
521 520
522 // Grab the handle. 521 // Grab the handle.
523 std::unique_ptr<BlobDataHandle> blob_data_handle = 522 std::unique_ptr<BlobDataHandle> blob_data_handle =
524 context_->GetBlobDataFromUUID(kId); 523 context_->GetBlobDataFromUUID(kId);
525 EXPECT_TRUE(blob_data_handle); 524 EXPECT_TRUE(blob_data_handle);
526 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); 525 EXPECT_TRUE(blob_data_handle->IsBeingBuilt());
527 bool built = false; 526 bool built = false;
528 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN; 527 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN;
529 blob_data_handle->RunOnConstructionComplete( 528 blob_data_handle->RunOnConstructionComplete(
530 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); 529 base::Bind(&ConstructionCompletePopulator, &built, &error_code));
531 530
532 // Continue building.
533 DataElement element;
534 element.SetToBytesDescription(kDataSize);
535 std::vector<DataElement> elements = {element};
536 host_->OnStartBuildingBlob(kId, elements);
537 sink_.ClearMessages(); 531 sink_.ClearMessages();
538 532
539 // Send data. 533 // Send data.
540 BlobItemBytesResponse response(0); 534 BlobItemBytesResponse response(0);
541 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); 535 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize);
542 std::vector<BlobItemBytesResponse> responses = {response}; 536 std::vector<BlobItemBytesResponse> responses = {response};
543 sink_.ClearMessages(); 537 sink_.ClearMessages();
544 host_->OnMemoryItemResponse(kId, responses); 538 host_->OnMemoryItemResponse(kId, responses);
545 539
546 ExpectDone(kId); 540 ExpectDone(kId);
547 base::RunLoop().RunUntilIdle(); 541 base::RunLoop().RunUntilIdle();
548 EXPECT_TRUE(built) << "Error code: " << static_cast<int>(error_code); 542 EXPECT_TRUE(built) << "Error code: " << static_cast<int>(error_code);
549 } 543 }
550 544
551 TEST_F(BlobDispatcherHostTest, BlobReferenceWhileShortcutConstructing) {
552 const std::string kId("id");
553
554 // Start building blob.
555 host_->OnRegisterBlobUUID(kId, std::string(kContentType),
556 std::string(kContentDisposition),
557 std::set<std::string>());
558
559 // Grab the handle.
560 std::unique_ptr<BlobDataHandle> blob_data_handle =
561 context_->GetBlobDataFromUUID(kId);
562 EXPECT_TRUE(blob_data_handle);
563 EXPECT_TRUE(blob_data_handle->IsBeingBuilt());
564 bool built = false;
565 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN;
566 blob_data_handle->RunOnConstructionComplete(
567 base::Bind(&ConstructionCompletePopulator, &built, &error_code));
568
569 // Continue building.
570 DataElement element;
571 element.SetToBytes(kData, kDataSize);
572 std::vector<DataElement> elements = {element};
573 host_->OnStartBuildingBlob(kId, elements);
574 ExpectDone(kId);
575 base::RunLoop().RunUntilIdle();
576 EXPECT_TRUE(built) << "Error code: " << static_cast<int>(error_code);
577 }
578
579 TEST_F(BlobDispatcherHostTest, BlobReferenceWhileConstructingCancelled) { 545 TEST_F(BlobDispatcherHostTest, BlobReferenceWhileConstructingCancelled) {
580 const std::string kId("id"); 546 const std::string kId("id");
581 547
582 // Start building blob. 548 // Start building blob.
583 host_->OnRegisterBlobUUID(kId, std::string(kContentType), 549 DataElement element;
584 std::string(kContentDisposition), 550 element.SetToBytesDescription(kDataSize);
585 std::set<std::string>()); 551 std::vector<DataElement> elements = {element};
552 host_->OnRegisterBlob(kId, std::string(kContentType),
553 std::string(kContentDisposition), elements);
586 554
587 // Grab the handle. 555 // Grab the handle.
588 std::unique_ptr<BlobDataHandle> blob_data_handle = 556 std::unique_ptr<BlobDataHandle> blob_data_handle =
589 context_->GetBlobDataFromUUID(kId); 557 context_->GetBlobDataFromUUID(kId);
590 EXPECT_TRUE(blob_data_handle); 558 EXPECT_TRUE(blob_data_handle);
591 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); 559 EXPECT_TRUE(blob_data_handle->IsBeingBuilt());
592 bool built = true; 560 bool built = true;
593 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN; 561 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN;
594 blob_data_handle->RunOnConstructionComplete( 562 blob_data_handle->RunOnConstructionComplete(
595 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); 563 base::Bind(&ConstructionCompletePopulator, &built, &error_code));
(...skipping 15 matching lines...) Expand all
611 EXPECT_EQ(IPCBlobCreationCancelCode::UNKNOWN, error_code); 579 EXPECT_EQ(IPCBlobCreationCancelCode::UNKNOWN, error_code);
612 580
613 // Remove it. 581 // Remove it.
614 blob_data_handle.reset(); 582 blob_data_handle.reset();
615 base::RunLoop().RunUntilIdle(); 583 base::RunLoop().RunUntilIdle();
616 EXPECT_TRUE(context_->registry().HasEntry(kId)); 584 EXPECT_TRUE(context_->registry().HasEntry(kId));
617 host_->OnDecrementBlobRefCount(kId); 585 host_->OnDecrementBlobRefCount(kId);
618 ExpectBlobNotExist(kId); 586 ExpectBlobNotExist(kId);
619 } 587 }
620 588
621 TEST_F(BlobDispatcherHostTest, DecrementRefAfterRegister) {
622 const std::string kId("id");
623 // Decrement the refcount while building (renderer blob gc'd before
624 // construction was completed).
625 host_->OnRegisterBlobUUID(kId, std::string(kContentType),
626 std::string(kContentDisposition),
627 std::set<std::string>());
628 EXPECT_TRUE(context_->registry().HasEntry(kId));
629 host_->OnDecrementBlobRefCount(kId);
630 EXPECT_FALSE(context_->registry().HasEntry(kId));
631 EXPECT_FALSE(IsBeingBuiltInHost(kId));
632 ExpectCancel(kId,
633 IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING);
634 sink_.ClearMessages();
635
636 // Do the same, but this time grab a handle before we decrement.
637 host_->OnRegisterBlobUUID(kId, std::string(kContentType),
638 std::string(kContentDisposition),
639 std::set<std::string>());
640 std::unique_ptr<BlobDataHandle> blob_data_handle =
641 context_->GetBlobDataFromUUID(kId);
642 host_->OnDecrementBlobRefCount(kId);
643 EXPECT_TRUE(context_->registry().HasEntry(kId));
644 EXPECT_TRUE(IsBeingBuiltInHost(kId));
645
646 // Finish up the blob, and verify we got the done message.
647 DataElement element;
648 element.SetToBytes(kData, kDataSize);
649 std::vector<DataElement> elements = {element};
650 host_->OnStartBuildingBlob(kId, elements);
651 EXPECT_FALSE(host_->shutdown_for_bad_message_);
652 ExpectDone(kId);
653 sink_.ClearMessages();
654 // Get rid of the handle, and verify it's gone.
655 blob_data_handle.reset();
656 base::RunLoop().RunUntilIdle();
657 // Check that it's no longer around.
658 EXPECT_FALSE(context_->registry().HasEntry(kId));
659 EXPECT_FALSE(IsBeingBuiltInHost(kId));
660 }
661
662 TEST_F(BlobDispatcherHostTest, DecrementRefAfterOnStart) { 589 TEST_F(BlobDispatcherHostTest, DecrementRefAfterOnStart) {
663 const std::string kId("id"); 590 const std::string kId("id");
664 591
665 // Decrement the refcount while building, after we call OnStartBuildlingBlob. 592 // Decrement the refcount while building, after we call OnStartBuildlingBlob.
666 host_->OnRegisterBlobUUID(kId, std::string(kContentType),
667 std::string(kContentDisposition),
668 std::set<std::string>());
669 EXPECT_FALSE(host_->shutdown_for_bad_message_);
670 DataElement element; 593 DataElement element;
671 element.SetToBytesDescription(kDataSize); 594 element.SetToBytesDescription(kDataSize);
672 std::vector<DataElement> elements = {element}; 595 std::vector<DataElement> elements = {element};
673 host_->OnStartBuildingBlob(kId, elements); 596 host_->OnRegisterBlob(kId, std::string(kContentType),
597 std::string(kContentDisposition), elements);
674 EXPECT_FALSE(host_->shutdown_for_bad_message_); 598 EXPECT_FALSE(host_->shutdown_for_bad_message_);
675 599
676 std::vector<BlobItemBytesRequest> expected_requests = { 600 std::vector<BlobItemBytesRequest> expected_requests = {
677 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; 601 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)};
678 ExpectRequest(kId, expected_requests); 602 ExpectRequest(kId, expected_requests);
679 sink_.ClearMessages(); 603 sink_.ClearMessages();
680 EXPECT_TRUE(context_->registry().HasEntry(kId)); 604 EXPECT_TRUE(context_->registry().HasEntry(kId));
681 host_->OnDecrementBlobRefCount(kId); 605 host_->OnDecrementBlobRefCount(kId);
682 EXPECT_FALSE(context_->registry().HasEntry(kId)); 606 EXPECT_FALSE(context_->registry().HasEntry(kId));
683 EXPECT_FALSE(IsBeingBuiltInHost(kId)); 607 EXPECT_FALSE(IsBeingBuiltInHost(kId));
684 ExpectCancel(kId, 608 ExpectCancel(kId,
685 IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING); 609 IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING);
686 sink_.ClearMessages(); 610 sink_.ClearMessages();
687 611
688 // Do the same, but this time grab a handle to keep it alive. 612 // Do the same, but this time grab a handle to keep it alive.
689 host_->OnRegisterBlobUUID(kId, std::string(kContentType), 613 host_->OnRegisterBlob(kId, std::string(kContentType),
690 std::string(kContentDisposition), 614 std::string(kContentDisposition), elements);
691 std::set<std::string>());
692 EXPECT_FALSE(host_->shutdown_for_bad_message_);
693 host_->OnStartBuildingBlob(kId, elements);
694 EXPECT_FALSE(host_->shutdown_for_bad_message_); 615 EXPECT_FALSE(host_->shutdown_for_bad_message_);
695 ExpectRequest(kId, expected_requests); 616 ExpectRequest(kId, expected_requests);
696 sink_.ClearMessages(); 617 sink_.ClearMessages();
697 EXPECT_TRUE(context_->registry().HasEntry(kId)); 618 EXPECT_TRUE(context_->registry().HasEntry(kId));
698 // Grab the handle before decrementing. 619 // Grab the handle before decrementing.
699 std::unique_ptr<BlobDataHandle> blob_data_handle = 620 std::unique_ptr<BlobDataHandle> blob_data_handle =
700 context_->GetBlobDataFromUUID(kId); 621 context_->GetBlobDataFromUUID(kId);
701 host_->OnDecrementBlobRefCount(kId); 622 host_->OnDecrementBlobRefCount(kId);
702 EXPECT_TRUE(context_->registry().HasEntry(kId)); 623 EXPECT_TRUE(context_->registry().HasEntry(kId));
703 EXPECT_TRUE(IsBeingBuiltInHost(kId)); 624 EXPECT_TRUE(IsBeingBuiltInHost(kId));
(...skipping 14 matching lines...) Expand all
718 base::RunLoop().RunUntilIdle(); 639 base::RunLoop().RunUntilIdle();
719 // Check that it's no longer around. 640 // Check that it's no longer around.
720 EXPECT_FALSE(context_->registry().HasEntry(kId)); 641 EXPECT_FALSE(context_->registry().HasEntry(kId));
721 EXPECT_FALSE(IsBeingBuiltInHost(kId)); 642 EXPECT_FALSE(IsBeingBuiltInHost(kId));
722 } 643 }
723 644
724 TEST_F(BlobDispatcherHostTest, DecrementRefAfterOnStartWithHandle) { 645 TEST_F(BlobDispatcherHostTest, DecrementRefAfterOnStartWithHandle) {
725 const std::string kId("id"); 646 const std::string kId("id");
726 // Decrement the refcount while building, after we call 647 // Decrement the refcount while building, after we call
727 // OnStartBuildlingBlob, except we have another handle. 648 // OnStartBuildlingBlob, except we have another handle.
728 host_->OnRegisterBlobUUID(kId, std::string(kContentType), 649 DataElement element;
729 std::string(kContentDisposition), 650 element.SetToBytesDescription(kDataSize);
730 std::set<std::string>()); 651 std::vector<DataElement> elements = {element};
652 host_->OnRegisterBlob(kId, std::string(kContentType),
653 std::string(kContentDisposition), elements);
731 EXPECT_FALSE(host_->shutdown_for_bad_message_); 654 EXPECT_FALSE(host_->shutdown_for_bad_message_);
732 655
733 std::unique_ptr<BlobDataHandle> blob_data_handle = 656 std::unique_ptr<BlobDataHandle> blob_data_handle =
734 context_->GetBlobDataFromUUID(kId); 657 context_->GetBlobDataFromUUID(kId);
735 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); 658 EXPECT_TRUE(blob_data_handle->IsBeingBuilt());
736 bool built = true; 659 bool built = true;
737 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN; 660 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN;
738 blob_data_handle->RunOnConstructionComplete( 661 blob_data_handle->RunOnConstructionComplete(
739 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); 662 base::Bind(&ConstructionCompletePopulator, &built, &error_code));
740 663
741 DataElement element;
742 element.SetToBytesDescription(kDataSize);
743 std::vector<DataElement> elements = {element};
744 host_->OnStartBuildingBlob(kId, elements);
745 EXPECT_FALSE(host_->shutdown_for_bad_message_);
746
747 // Check that we got the expected request. 664 // Check that we got the expected request.
748 std::vector<BlobItemBytesRequest> expected_requests = { 665 std::vector<BlobItemBytesRequest> expected_requests = {
749 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; 666 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)};
750 ExpectRequest(kId, expected_requests); 667 ExpectRequest(kId, expected_requests);
751 sink_.ClearMessages(); 668 sink_.ClearMessages();
752 EXPECT_TRUE(context_->registry().HasEntry(kId)); 669 EXPECT_TRUE(context_->registry().HasEntry(kId));
753 EXPECT_TRUE(IsBeingBuiltInHost(kId)); 670 EXPECT_TRUE(IsBeingBuiltInHost(kId));
754 // Decrement, simulating where the ref goes out of scope in renderer. 671 // Decrement, simulating where the ref goes out of scope in renderer.
755 host_->OnDecrementBlobRefCount(kId); 672 host_->OnDecrementBlobRefCount(kId);
756 // We still have the blob as it's not done. 673 // We still have the blob as it's not done.
(...skipping 11 matching lines...) Expand all
768 EXPECT_EQ(IPCBlobCreationCancelCode::UNKNOWN, error_code); 685 EXPECT_EQ(IPCBlobCreationCancelCode::UNKNOWN, error_code);
769 sink_.ClearMessages(); 686 sink_.ClearMessages();
770 687
771 // Should disappear after dropping the handle. 688 // Should disappear after dropping the handle.
772 EXPECT_TRUE(blob_data_handle->IsBroken()); 689 EXPECT_TRUE(blob_data_handle->IsBroken());
773 blob_data_handle.reset(); 690 blob_data_handle.reset();
774 base::RunLoop().RunUntilIdle(); 691 base::RunLoop().RunUntilIdle();
775 EXPECT_FALSE(context_->registry().HasEntry(kId)); 692 EXPECT_FALSE(context_->registry().HasEntry(kId));
776 } 693 }
777 694
778 TEST_F(BlobDispatcherHostTest, HostDisconnectAfterRegisterWithHandle) {
779 const std::string kId("id");
780
781 // Delete host with a handle to the blob.
782 host_->OnRegisterBlobUUID(kId, std::string(kContentType),
783 std::string(kContentDisposition),
784 std::set<std::string>());
785
786 std::unique_ptr<BlobDataHandle> blob_data_handle =
787 context_->GetBlobDataFromUUID(kId);
788 EXPECT_TRUE(blob_data_handle->IsBeingBuilt());
789 bool built = true;
790 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN;
791 blob_data_handle->RunOnConstructionComplete(
792 base::Bind(&ConstructionCompletePopulator, &built, &error_code));
793 // Get rid of host, which was doing the constructing.
794 host_ = nullptr;
795 EXPECT_FALSE(blob_data_handle->IsBeingBuilt());
796 base::RunLoop().RunUntilIdle();
797 EXPECT_FALSE(built);
798 EXPECT_EQ(IPCBlobCreationCancelCode::SOURCE_DIED_IN_TRANSIT, error_code);
799
800 // Should still be there due to the handle.
801 std::unique_ptr<BlobDataHandle> another_handle =
802 context_->GetBlobDataFromUUID(kId);
803 EXPECT_TRUE(another_handle);
804
805 // Should disappear after dropping both handles.
806 blob_data_handle.reset();
807 another_handle.reset();
808 base::RunLoop().RunUntilIdle();
809 EXPECT_FALSE(context_->registry().HasEntry(kId));
810 }
811
812 TEST_F(BlobDispatcherHostTest, HostDisconnectAfterOnStart) { 695 TEST_F(BlobDispatcherHostTest, HostDisconnectAfterOnStart) {
813 const std::string kId("id"); 696 const std::string kId("id");
814 697
815 // Host deleted after OnStartBuilding. 698 // Host deleted after OnStartBuilding.
816 host_->OnRegisterBlobUUID(kId, std::string(kContentType),
817 std::string(kContentDisposition),
818 std::set<std::string>());
819
820 DataElement element; 699 DataElement element;
821 element.SetToBytesDescription(kDataSize); 700 element.SetToBytesDescription(kDataSize);
822 std::vector<DataElement> elements = {element}; 701 std::vector<DataElement> elements = {element};
823 host_->OnStartBuildingBlob(kId, elements); 702 host_->OnRegisterBlob(kId, std::string(kContentType),
703 std::string(kContentDisposition), elements);
824 704
825 std::vector<BlobItemBytesRequest> expected_requests = { 705 std::vector<BlobItemBytesRequest> expected_requests = {
826 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; 706 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)};
827 ExpectRequest(kId, expected_requests); 707 ExpectRequest(kId, expected_requests);
828 sink_.ClearMessages(); 708 sink_.ClearMessages();
829 host_ = nullptr; 709 host_ = nullptr;
830 // We need to run the message loop because of the handle in the async builder. 710 // We need to run the message loop because of the handle in the async builder.
831 base::RunLoop().RunUntilIdle(); 711 base::RunLoop().RunUntilIdle();
832 EXPECT_FALSE(context_->registry().HasEntry(kId)); 712 EXPECT_FALSE(context_->registry().HasEntry(kId));
833 } 713 }
834 714
835 TEST_F(BlobDispatcherHostTest, HostDisconnectAfterOnMemoryResponse) { 715 TEST_F(BlobDispatcherHostTest, HostDisconnectAfterOnMemoryResponse) {
836 const std::string kId("id"); 716 const std::string kId("id");
837 717
838 // Host deleted after OnMemoryItemResponse. 718 // Host deleted after OnMemoryItemResponse.
839 host_->OnRegisterBlobUUID(kId, std::string(kContentType),
840 std::string(kContentDisposition),
841 std::set<std::string>());
842
843 // Create list of two items.
844 DataElement element; 719 DataElement element;
845 element.SetToBytesDescription(kDataSize); 720 element.SetToBytesDescription(kDataSize);
846 std::vector<DataElement> elements = {element, element}; 721 std::vector<DataElement> elements = {element, element};
847 host_->OnStartBuildingBlob(kId, elements); 722 host_->OnRegisterBlob(kId, std::string(kContentType),
723 std::string(kContentDisposition), elements);
724
725 // Create list of two items.
848 std::vector<BlobItemBytesRequest> expected_requests = { 726 std::vector<BlobItemBytesRequest> expected_requests = {
849 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize), 727 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize),
850 BlobItemBytesRequest::CreateIPCRequest(1, 1, 0, kDataSize)}; 728 BlobItemBytesRequest::CreateIPCRequest(1, 1, 0, kDataSize)};
851 ExpectRequest(kId, expected_requests); 729 ExpectRequest(kId, expected_requests);
852 sink_.ClearMessages(); 730 sink_.ClearMessages();
853 731
854 // Send just one response so the blob isn't 'done' yet. 732 // Send just one response so the blob isn't 'done' yet.
855 BlobItemBytesResponse response(0); 733 BlobItemBytesResponse response(0);
856 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); 734 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize);
857 std::vector<BlobItemBytesResponse> responses = {response}; 735 std::vector<BlobItemBytesResponse> responses = {response};
858 host_->OnMemoryItemResponse(kId, responses); 736 host_->OnMemoryItemResponse(kId, responses);
859 EXPECT_EQ(0u, sink_.message_count()); 737 EXPECT_EQ(0u, sink_.message_count());
860 738
861 host_ = nullptr; 739 host_ = nullptr;
862 base::RunLoop().RunUntilIdle(); 740 base::RunLoop().RunUntilIdle();
863 EXPECT_FALSE(context_->registry().HasEntry(kId)); 741 EXPECT_FALSE(context_->registry().HasEntry(kId));
864 } 742 }
865 743
866 TEST_F(BlobDispatcherHostTest, CreateBlobWithBrokenReference) { 744 TEST_F(BlobDispatcherHostTest, CreateBlobWithBrokenReference) {
867 const std::string kBrokenId("id1"); 745 const std::string kBrokenId("id1");
868 const std::string kReferencingId("id2"); 746 const std::string kReferencingId("id2");
869 747
870 // First, let's test a circular reference. 748 // First, let's test a circular reference.
871 const std::string kCircularId("id1"); 749 const std::string kCircularId("id1");
872 host_->OnRegisterBlobUUID(kCircularId, std::string(kContentType), 750 DataElement element;
873 std::string(kContentDisposition), {kCircularId}); 751 element.SetToBlob(kCircularId);
752 std::vector<DataElement> elements = {element};
753 host_->OnRegisterBlob(kCircularId, std::string(kContentType),
754 std::string(kContentDisposition), elements);
874 ExpectAndResetBadMessage(); 755 ExpectAndResetBadMessage();
875 756
876 // Next, test a blob that references a broken blob. 757 // Next, test a blob that references a broken blob.
877 host_->OnRegisterBlobUUID(kBrokenId, std::string(kContentType), 758 element.SetToBytesDescription(kDataSize);
878 std::string(kContentDisposition), 759 elements = {element};
879 std::set<std::string>()); 760 host_->OnRegisterBlob(kBrokenId, std::string(kContentType),
761 std::string(kContentDisposition), elements);
762 sink_.ClearMessages();
880 host_->OnCancelBuildingBlob(kBrokenId, IPCBlobCreationCancelCode::UNKNOWN); 763 host_->OnCancelBuildingBlob(kBrokenId, IPCBlobCreationCancelCode::UNKNOWN);
881 EXPECT_FALSE(host_->shutdown_for_bad_message_); 764 EXPECT_FALSE(host_->shutdown_for_bad_message_);
882 EXPECT_TRUE(context_->GetBlobDataFromUUID(kBrokenId)->IsBroken()); 765 EXPECT_TRUE(context_->GetBlobDataFromUUID(kBrokenId)->IsBroken());
883 766
884 // Create referencing blob. We should be broken right away, but also ignore 767 // Create referencing blob. We should be broken right away, but also ignore
885 // the subsequent OnStart message. 768 // the subsequent OnStart message.
886 host_->OnRegisterBlobUUID(kReferencingId, std::string(kContentType), 769 element.SetToBytesDescription(kDataSize);
887 std::string(kContentDisposition), {kBrokenId}); 770 elements = {element};
771 element.SetToBlob(kBrokenId);
772 elements.push_back(element);
773 host_->OnRegisterBlob(kReferencingId, std::string(kContentType),
774 std::string(kContentDisposition), elements);
888 EXPECT_TRUE(context_->GetBlobDataFromUUID(kReferencingId)->IsBroken()); 775 EXPECT_TRUE(context_->GetBlobDataFromUUID(kReferencingId)->IsBroken());
889 EXPECT_FALSE(IsBeingBuiltInHost(kReferencingId)); 776 EXPECT_FALSE(IsBeingBuiltInHost(kReferencingId));
890 EXPECT_TRUE(context_->registry().HasEntry(kReferencingId)); 777 EXPECT_TRUE(context_->registry().HasEntry(kReferencingId));
891 ExpectCancel(kReferencingId, 778 ExpectCancel(kReferencingId,
892 IPCBlobCreationCancelCode::REFERENCED_BLOB_BROKEN); 779 IPCBlobCreationCancelCode::REFERENCED_BLOB_BROKEN);
893 sink_.ClearMessages(); 780 sink_.ClearMessages();
894
895 DataElement element;
896 element.SetToBytesDescription(kDataSize);
897 std::vector<DataElement> elements = {element};
898 element.SetToBlob(kBrokenId);
899 elements.push_back(element);
900 host_->OnStartBuildingBlob(kReferencingId, elements);
901 EXPECT_EQ(0u, sink_.message_count());
902 base::RunLoop().RunUntilIdle();
903 } 781 }
904 782
905 TEST_F(BlobDispatcherHostTest, DeferenceBlobOnDifferentHost) { 783 TEST_F(BlobDispatcherHostTest, DeferenceBlobOnDifferentHost) {
906 const std::string kId("id"); 784 const std::string kId("id");
907 // Data elements for our transfer & checking messages. 785 // Data elements for our transfer & checking messages.
908 DataElement element; 786 DataElement element;
909 element.SetToBytesDescription(kDataSize); 787 element.SetToBytesDescription(kDataSize);
910 std::vector<DataElement> elements = {element}; 788 std::vector<DataElement> elements = {element};
911 std::vector<BlobItemBytesRequest> expected_requests = { 789 std::vector<BlobItemBytesRequest> expected_requests = {
912 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; 790 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)};
913 BlobItemBytesResponse response(0); 791 BlobItemBytesResponse response(0);
914 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); 792 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize);
915 std::vector<BlobItemBytesResponse> responses = {response}; 793 std::vector<BlobItemBytesResponse> responses = {response};
916 794
917 scoped_refptr<TestableBlobDispatcherHost> host2( 795 scoped_refptr<TestableBlobDispatcherHost> host2(
918 new TestableBlobDispatcherHost(chrome_blob_storage_context_, &sink_)); 796 new TestableBlobDispatcherHost(chrome_blob_storage_context_, &sink_));
919 797
920 // Delete host with another host having a referencing, then dereference on 798 // Delete host with another host having a referencing, then dereference on
921 // second host. Verify we're still building it on first host, and then 799 // second host. Verify we're still building it on first host, and then
922 // verify that a building message from the renderer will kill it. 800 // verify that a building message from the renderer will kill it.
923 801
924 // Test OnStartBuilding after double dereference. 802 // Test OnStartBuilding after double dereference.
925 host_->OnRegisterBlobUUID(kId, std::string(kContentType), 803 host_->OnRegisterBlob(kId, std::string(kContentType),
926 std::string(kContentDisposition), 804 std::string(kContentDisposition), elements);
927 std::set<std::string>()); 805 EXPECT_FALSE(host_->shutdown_for_bad_message_);
806 ExpectRequest(kId, expected_requests);
807 sink_.ClearMessages();
928 host2->OnIncrementBlobRefCount(kId); 808 host2->OnIncrementBlobRefCount(kId);
929 host_->OnDecrementBlobRefCount(kId); 809 host_->OnDecrementBlobRefCount(kId);
930 EXPECT_FALSE(host_->IsInUseInHost(kId)); 810 EXPECT_FALSE(host_->IsInUseInHost(kId));
931 host2->OnDecrementBlobRefCount(kId); 811 host2->OnDecrementBlobRefCount(kId);
932 // So no more blob in the context, but we're still being built in host 1. 812 // So no more blob in the context, but we're still being built in host 1.
933 EXPECT_FALSE(context_->registry().HasEntry(kId)); 813 EXPECT_FALSE(context_->registry().HasEntry(kId));
814 // Send the memory. When the host sees the entry doesn't exist, it should
815 // cancel and clean up.
934 EXPECT_TRUE(host_->async_builder_.IsBeingBuilt(kId)); 816 EXPECT_TRUE(host_->async_builder_.IsBeingBuilt(kId));
935 host_->OnStartBuildingBlob(kId, elements); 817 host_->OnMemoryItemResponse(kId, responses);
936 EXPECT_FALSE(host_->shutdown_for_bad_message_);
937 // We should be cleaned up. 818 // We should be cleaned up.
938 EXPECT_FALSE(host_->async_builder_.IsBeingBuilt(kId)); 819 EXPECT_FALSE(host_->async_builder_.IsBeingBuilt(kId));
939 ExpectCancel(kId, 820 ExpectCancel(kId,
940 IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING);
941 sink_.ClearMessages();
942
943 // Same as above, but test OnMemoryItemResponse after double dereference.
944 host_->OnRegisterBlobUUID(kId, std::string(kContentType),
945 std::string(kContentDisposition),
946 std::set<std::string>());
947 host2->OnIncrementBlobRefCount(kId);
948 host_->OnDecrementBlobRefCount(kId);
949 EXPECT_FALSE(host_->IsInUseInHost(kId));
950 host_->OnStartBuildingBlob(kId, elements);
951 ExpectRequest(kId, expected_requests);
952 sink_.ClearMessages();
953
954 host2->OnDecrementBlobRefCount(kId);
955 // So no more blob in the context, but we're still being built in host 1.
956 EXPECT_FALSE(context_->registry().HasEntry(kId));
957 EXPECT_TRUE(host_->async_builder_.IsBeingBuilt(kId));
958 host_->OnMemoryItemResponse(kId, responses);
959 EXPECT_FALSE(host_->shutdown_for_bad_message_);
960 // We should be cleaned up.
961 EXPECT_FALSE(host_->async_builder_.IsBeingBuilt(kId));
962 ExpectCancel(kId,
963 IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING); 821 IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING);
964 sink_.ClearMessages(); 822 sink_.ClearMessages();
965 823
966 // Same, but now for OnCancel. 824 // Same, but now for OnCancel.
967 host_->OnRegisterBlobUUID(kId, std::string(kContentType), 825 host_->OnRegisterBlob(kId, std::string(kContentType),
968 std::string(kContentDisposition), 826 std::string(kContentDisposition), elements);
969 std::set<std::string>());
970 host2->OnIncrementBlobRefCount(kId); 827 host2->OnIncrementBlobRefCount(kId);
971 host_->OnDecrementBlobRefCount(kId); 828 host_->OnDecrementBlobRefCount(kId);
972 EXPECT_FALSE(host_->IsInUseInHost(kId)); 829 EXPECT_FALSE(host_->IsInUseInHost(kId));
973 host_->OnStartBuildingBlob(kId, elements);
974 ExpectRequest(kId, expected_requests); 830 ExpectRequest(kId, expected_requests);
975 sink_.ClearMessages(); 831 sink_.ClearMessages();
976 832
977 host2->OnDecrementBlobRefCount(kId); 833 host2->OnDecrementBlobRefCount(kId);
978 // So no more blob in the context, but we're still being built in host 1. 834 // So no more blob in the context, but we're still being built in host 1.
979 EXPECT_FALSE(context_->registry().HasEntry(kId)); 835 EXPECT_FALSE(context_->registry().HasEntry(kId));
980 EXPECT_TRUE(host_->async_builder_.IsBeingBuilt(kId)); 836 EXPECT_TRUE(host_->async_builder_.IsBeingBuilt(kId));
981 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN); 837 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN);
982 EXPECT_FALSE(host_->shutdown_for_bad_message_); 838 EXPECT_FALSE(host_->shutdown_for_bad_message_);
983 // We should be cleaned up. 839 // We should be cleaned up.
984 EXPECT_FALSE(host_->async_builder_.IsBeingBuilt(kId)); 840 EXPECT_FALSE(host_->async_builder_.IsBeingBuilt(kId));
985 } 841 }
986 842
987 TEST_F(BlobDispatcherHostTest, BuildingReferenceChain) { 843 TEST_F(BlobDispatcherHostTest, BuildingReferenceChain) {
988 const std::string kId("id"); 844 const std::string kId("id");
989 const std::string kSameHostReferencingId("id2"); 845 const std::string kSameHostReferencingId("id2");
990 const std::string kDifferentHostReferencingId("id3"); 846 const std::string kDifferentHostReferencingId("id3");
991 // Data elements for our transfer & checking messages. 847 // Data elements for our transfer & checking messages.
992 DataElement element; 848 DataElement element;
993 element.SetToBytes(kData, kDataSize); 849 element.SetToBytesDescription(kDataSize);
994 std::vector<DataElement> elements = {element};
995 DataElement referencing_element; 850 DataElement referencing_element;
996 referencing_element.SetToBlob(kId); 851 referencing_element.SetToBlob(kId);
852 std::vector<DataElement> elements = {element};
997 std::vector<DataElement> referencing_elements = {referencing_element}; 853 std::vector<DataElement> referencing_elements = {referencing_element};
998 std::set<std::string> referenced_blobs_set = {kId}; 854 std::vector<BlobItemBytesRequest> expected_requests = {
855 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)};
856 BlobItemBytesResponse response(0);
857 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize);
858 std::vector<BlobItemBytesResponse> responses = {response};
999 859
1000 scoped_refptr<TestableBlobDispatcherHost> host2( 860 scoped_refptr<TestableBlobDispatcherHost> host2(
1001 new TestableBlobDispatcherHost(chrome_blob_storage_context_, &sink_)); 861 new TestableBlobDispatcherHost(chrome_blob_storage_context_, &sink_));
1002 862
1003 // We want to have a blob referencing another blob that is building, both on 863 // We want to have a blob referencing another blob that is building, both on
1004 // the same host and a different host. We should successfully build all blobs 864 // the same host and a different host. We should successfully build all blobs
1005 // after the referenced blob is finished. 865 // after the referenced blob is finished.
1006 866
1007 // First we start the referenced blob. 867 // First we start the referenced blob.
1008 host_->OnRegisterBlobUUID(kId, std::string(kContentType), 868 host_->OnRegisterBlob(kId, std::string(kContentType),
1009 std::string(kContentDisposition), 869 std::string(kContentDisposition), elements);
1010 std::set<std::string>()); 870 ExpectRequest(kId, expected_requests);
871 sink_.ClearMessages();
1011 EXPECT_TRUE(host_->IsInUseInHost(kId)); 872 EXPECT_TRUE(host_->IsInUseInHost(kId));
873 EXPECT_TRUE(IsBeingBuiltInContext(kId));
1012 874
1013 // Next we start the referencing blobs in both the same and different host. 875 // Next we start the referencing blobs in both the same and different host.
1014 host_->OnRegisterBlobUUID(kSameHostReferencingId, std::string(kContentType), 876 host_->OnRegisterBlob(kSameHostReferencingId, std::string(kContentType),
1015 std::string(kContentDisposition), 877 std::string(kContentDisposition), referencing_elements);
1016 referenced_blobs_set);
1017 EXPECT_FALSE(host_->shutdown_for_bad_message_);
1018 host_->OnStartBuildingBlob(kSameHostReferencingId, referencing_elements);
1019 EXPECT_FALSE(host_->shutdown_for_bad_message_); 878 EXPECT_FALSE(host_->shutdown_for_bad_message_);
1020 ExpectDone(kSameHostReferencingId); 879 ExpectDone(kSameHostReferencingId);
1021 EXPECT_TRUE(host_->async_builder_.IsBeingBuilt(kSameHostReferencingId));
1022 sink_.ClearMessages(); 880 sink_.ClearMessages();
881 EXPECT_FALSE(
882 context_->GetBlobDataFromUUID(kSameHostReferencingId)->IsBroken());
883 EXPECT_FALSE(host_->async_builder_.IsBeingBuilt(kSameHostReferencingId));
884 EXPECT_TRUE(IsBeingBuiltInContext(kSameHostReferencingId));
885
1023 // Now the other host. 886 // Now the other host.
1024 host2->OnRegisterBlobUUID( 887 host2->OnRegisterBlob(kDifferentHostReferencingId, std::string(kContentType),
1025 kDifferentHostReferencingId, std::string(kContentType), 888 std::string(kContentDisposition), referencing_elements);
1026 std::string(kContentDisposition), referenced_blobs_set);
1027 EXPECT_FALSE(host2->shutdown_for_bad_message_);
1028 host2->OnStartBuildingBlob(kDifferentHostReferencingId, referencing_elements);
1029 EXPECT_FALSE(host2->shutdown_for_bad_message_); 889 EXPECT_FALSE(host2->shutdown_for_bad_message_);
1030 ExpectDone(kDifferentHostReferencingId); 890 ExpectDone(kDifferentHostReferencingId);
1031 EXPECT_TRUE(host2->async_builder_.IsBeingBuilt(kDifferentHostReferencingId));
1032 sink_.ClearMessages(); 891 sink_.ClearMessages();
892 EXPECT_FALSE(
893 context_->GetBlobDataFromUUID(kDifferentHostReferencingId)->IsBroken());
894 EXPECT_FALSE(host2->async_builder_.IsBeingBuilt(kDifferentHostReferencingId));
895 EXPECT_TRUE(IsBeingBuiltInContext(kDifferentHostReferencingId));
1033 896
1034 // Now we finish the first blob, and we expect all blobs to finish. 897 // Now we finish the first blob, and we expect all blobs to finish.
1035 host_->OnStartBuildingBlob(kId, elements); 898 host_->OnMemoryItemResponse(kId, responses);
1036 ExpectDone(kId); 899 ExpectDone(kId);
1037 // We need to run the message loop to propagate the construction callbacks. 900 // We need to run the message loop to propagate the construction callbacks.
1038 base::RunLoop().RunUntilIdle(); 901 base::RunLoop().RunUntilIdle();
1039 EXPECT_FALSE(host2->async_builder_.IsBeingBuilt(kDifferentHostReferencingId)); 902 EXPECT_FALSE(host2->async_builder_.IsBeingBuilt(kDifferentHostReferencingId));
1040 EXPECT_FALSE(host_->async_builder_.IsBeingBuilt(kSameHostReferencingId)); 903 EXPECT_FALSE(host_->async_builder_.IsBeingBuilt(kSameHostReferencingId));
1041 EXPECT_FALSE( 904 EXPECT_FALSE(
1042 context_->GetBlobDataFromUUID(kSameHostReferencingId)->IsBroken()); 905 context_->GetBlobDataFromUUID(kSameHostReferencingId)->IsBroken());
1043 EXPECT_FALSE( 906 EXPECT_FALSE(
1044 context_->GetBlobDataFromUUID(kDifferentHostReferencingId)->IsBroken()); 907 context_->GetBlobDataFromUUID(kDifferentHostReferencingId)->IsBroken());
1045 sink_.ClearMessages(); 908 sink_.ClearMessages();
1046 909
1047 // Finally check that our data is correct in the child elements. 910 // Finally check that our data is correct in the child elements.
1048 std::unique_ptr<BlobDataHandle> handle = 911 std::unique_ptr<BlobDataHandle> handle =
1049 context_->GetBlobDataFromUUID(kDifferentHostReferencingId); 912 context_->GetBlobDataFromUUID(kDifferentHostReferencingId);
1050 ExpectHandleEqualsData(handle.get(), elements); 913 DataElement expected;
914 expected.SetToBytes(kData, kDataSize);
915 std::vector<DataElement> expecteds = {expected};
916 ExpectHandleEqualsData(handle.get(), expecteds);
1051 } 917 }
1052 918
1053 TEST_F(BlobDispatcherHostTest, BuildingReferenceChainWithCancel) { 919 TEST_F(BlobDispatcherHostTest, BuildingReferenceChainWithCancel) {
1054 const std::string kId("id"); 920 const std::string kId("id");
1055 const std::string kSameHostReferencingId("id2"); 921 const std::string kSameHostReferencingId("id2");
1056 const std::string kDifferentHostReferencingId("id3"); 922 const std::string kDifferentHostReferencingId("id3");
1057 // Data elements for our transfer & checking messages. 923 // Data elements for our transfer & checking messages.
924 DataElement element;
925 element.SetToBytesDescription(kDataSize);
1058 DataElement referencing_element; 926 DataElement referencing_element;
1059 referencing_element.SetToBlob(kId); 927 referencing_element.SetToBlob(kId);
928 std::vector<DataElement> elements = {element};
1060 std::vector<DataElement> referencing_elements = {referencing_element}; 929 std::vector<DataElement> referencing_elements = {referencing_element};
1061 std::set<std::string> referenced_blobs_set = {kId}; 930 std::vector<BlobItemBytesRequest> expected_requests = {
931 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)};
1062 932
1063 scoped_refptr<TestableBlobDispatcherHost> host2( 933 scoped_refptr<TestableBlobDispatcherHost> host2(
1064 new TestableBlobDispatcherHost(chrome_blob_storage_context_, &sink_)); 934 new TestableBlobDispatcherHost(chrome_blob_storage_context_, &sink_));
1065 935
1066 // We want to have a blob referencing another blob that is building, both on 936 // We want to have a blob referencing another blob that is building, both on
1067 // the same host and a different host. After we cancel the first blob, the 937 // the same host and a different host. We should successfully build all blobs
1068 // others should cancel as well. 938 // after the referenced blob is finished.
1069 939
1070 // First we start the referenced blob. 940 // First we start the referenced blob.
1071 host_->OnRegisterBlobUUID(kId, std::string(kContentType), 941 host_->OnRegisterBlob(kId, std::string(kContentType),
1072 std::string(kContentDisposition), 942 std::string(kContentDisposition), elements);
1073 std::set<std::string>()); 943 ExpectRequest(kId, expected_requests);
944 sink_.ClearMessages();
1074 EXPECT_TRUE(host_->IsInUseInHost(kId)); 945 EXPECT_TRUE(host_->IsInUseInHost(kId));
946 EXPECT_TRUE(IsBeingBuiltInContext(kId));
1075 947
1076 // Next we start the referencing blobs in both the same and different host. 948 // Next we start the referencing blobs in both the same and different host.
1077 host_->OnRegisterBlobUUID(kSameHostReferencingId, std::string(kContentType), 949 host_->OnRegisterBlob(kSameHostReferencingId, std::string(kContentType),
1078 std::string(kContentDisposition), 950 std::string(kContentDisposition), referencing_elements);
1079 referenced_blobs_set); 951 EXPECT_FALSE(host_->shutdown_for_bad_message_);
1080 host_->OnStartBuildingBlob(kSameHostReferencingId, referencing_elements);
1081 ExpectDone(kSameHostReferencingId); 952 ExpectDone(kSameHostReferencingId);
1082 EXPECT_TRUE(host_->async_builder_.IsBeingBuilt(kSameHostReferencingId));
1083 sink_.ClearMessages(); 953 sink_.ClearMessages();
954 EXPECT_FALSE(
955 context_->GetBlobDataFromUUID(kSameHostReferencingId)->IsBroken());
956 EXPECT_FALSE(host_->async_builder_.IsBeingBuilt(kSameHostReferencingId));
957 EXPECT_TRUE(IsBeingBuiltInContext(kSameHostReferencingId));
958
1084 // Now the other host. 959 // Now the other host.
1085 host2->OnRegisterBlobUUID( 960 host2->OnRegisterBlob(kDifferentHostReferencingId, std::string(kContentType),
1086 kDifferentHostReferencingId, std::string(kContentType), 961 std::string(kContentDisposition), referencing_elements);
1087 std::string(kContentDisposition), referenced_blobs_set); 962 EXPECT_FALSE(host2->shutdown_for_bad_message_);
1088 host2->OnStartBuildingBlob(kDifferentHostReferencingId, referencing_elements);
1089 ExpectDone(kDifferentHostReferencingId); 963 ExpectDone(kDifferentHostReferencingId);
1090 EXPECT_TRUE(host2->async_builder_.IsBeingBuilt(kDifferentHostReferencingId));
1091 sink_.ClearMessages(); 964 sink_.ClearMessages();
965 EXPECT_FALSE(
966 context_->GetBlobDataFromUUID(kDifferentHostReferencingId)->IsBroken());
967 EXPECT_FALSE(host2->async_builder_.IsBeingBuilt(kDifferentHostReferencingId));
968 EXPECT_TRUE(IsBeingBuiltInContext(kDifferentHostReferencingId));
969
1092 bool built = false; 970 bool built = false;
1093 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN; 971 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN;
1094 context_->GetBlobDataFromUUID(kDifferentHostReferencingId) 972 context_->GetBlobDataFromUUID(kDifferentHostReferencingId)
1095 ->RunOnConstructionComplete( 973 ->RunOnConstructionComplete(
1096 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); 974 base::Bind(&ConstructionCompletePopulator, &built, &error_code));
1097 975
1098 // Now we cancel the first blob, and we expect all blobs to cancel. 976 // Now we cancel the first blob, and we expect all blobs to cancel.
1099 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN); 977 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN);
1100 // We need to run the message loop to propagate the construction callbacks. 978 // We need to run the message loop to propagate the construction callbacks.
1101 base::RunLoop().RunUntilIdle(); 979 base::RunLoop().RunUntilIdle();
1102 EXPECT_FALSE(host2->async_builder_.IsBeingBuilt(kDifferentHostReferencingId)); 980 EXPECT_FALSE(host2->async_builder_.IsBeingBuilt(kDifferentHostReferencingId));
1103 EXPECT_FALSE(host_->async_builder_.IsBeingBuilt(kSameHostReferencingId)); 981 EXPECT_FALSE(host_->async_builder_.IsBeingBuilt(kSameHostReferencingId));
1104 EXPECT_TRUE( 982 EXPECT_TRUE(
1105 context_->GetBlobDataFromUUID(kSameHostReferencingId)->IsBroken()); 983 context_->GetBlobDataFromUUID(kSameHostReferencingId)->IsBroken());
1106 EXPECT_TRUE( 984 EXPECT_TRUE(
1107 context_->GetBlobDataFromUUID(kDifferentHostReferencingId)->IsBroken()); 985 context_->GetBlobDataFromUUID(kDifferentHostReferencingId)->IsBroken());
1108 EXPECT_FALSE(built); 986 EXPECT_FALSE(built);
1109 EXPECT_EQ(IPCBlobCreationCancelCode::REFERENCED_BLOB_BROKEN, error_code); 987 EXPECT_EQ(IPCBlobCreationCancelCode::REFERENCED_BLOB_BROKEN, error_code);
1110 sink_.ClearMessages(); 988 sink_.ClearMessages();
1111 } 989 }
1112 990
1113 TEST_F(BlobDispatcherHostTest, BuildingReferenceChainWithSourceDeath) { 991 TEST_F(BlobDispatcherHostTest, BuildingReferenceChainWithSourceDeath) {
1114 const std::string kId("id"); 992 const std::string kId("id");
1115 const std::string kSameHostReferencingId("id2"); 993 const std::string kSameHostReferencingId("id2");
1116 const std::string kDifferentHostReferencingId("id3"); 994 const std::string kDifferentHostReferencingId("id3");
1117 // Data elements for our transfer & checking messages. 995 // Data elements for our transfer & checking messages.
996 DataElement element;
997 element.SetToBytesDescription(kDataSize);
1118 DataElement referencing_element; 998 DataElement referencing_element;
1119 referencing_element.SetToBlob(kId); 999 referencing_element.SetToBlob(kId);
1000 std::vector<DataElement> elements = {element};
1120 std::vector<DataElement> referencing_elements = {referencing_element}; 1001 std::vector<DataElement> referencing_elements = {referencing_element};
1121 std::set<std::string> referenced_blobs_set = {kId}; 1002 std::vector<BlobItemBytesRequest> expected_requests = {
1003 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)};
1004 BlobItemBytesResponse response(0);
1005 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize);
1006 std::vector<BlobItemBytesResponse> responses = {response};
1122 1007
1123 scoped_refptr<TestableBlobDispatcherHost> host2( 1008 scoped_refptr<TestableBlobDispatcherHost> host2(
1124 new TestableBlobDispatcherHost(chrome_blob_storage_context_, &sink_)); 1009 new TestableBlobDispatcherHost(chrome_blob_storage_context_, &sink_));
1125 1010
1126 // We want to have a blob referencing another blob that is building, both on 1011 // We want to have a blob referencing another blob that is building, both on
1127 // the same host and a different host. When we destroy the host, the other 1012 // the same host and a different host. We should successfully build all blobs
1128 // blob should cancel, as well as the blob on the other host. 1013 // after the referenced blob is finished.
1129 1014
1130 // First we start the referenced blob. 1015 // First we start the referenced blob.
1131 host_->OnRegisterBlobUUID(kId, std::string(kContentType), 1016 host_->OnRegisterBlob(kId, std::string(kContentType),
1132 std::string(kContentDisposition), 1017 std::string(kContentDisposition), elements);
1133 std::set<std::string>()); 1018 ExpectRequest(kId, expected_requests);
1019 sink_.ClearMessages();
1134 EXPECT_TRUE(host_->IsInUseInHost(kId)); 1020 EXPECT_TRUE(host_->IsInUseInHost(kId));
1021 EXPECT_TRUE(IsBeingBuiltInContext(kId));
1135 1022
1136 // Next we start the referencing blobs in both the same and different host. 1023 // Next we start the referencing blobs in both the same and different host.
1137 host_->OnRegisterBlobUUID(kSameHostReferencingId, std::string(kContentType), 1024 host_->OnRegisterBlob(kSameHostReferencingId, std::string(kContentType),
1138 std::string(kContentDisposition), 1025 std::string(kContentDisposition), referencing_elements);
1139 referenced_blobs_set); 1026 EXPECT_FALSE(host_->shutdown_for_bad_message_);
1140 host_->OnStartBuildingBlob(kSameHostReferencingId, referencing_elements);
1141 ExpectDone(kSameHostReferencingId); 1027 ExpectDone(kSameHostReferencingId);
1142 EXPECT_TRUE(host_->async_builder_.IsBeingBuilt(kSameHostReferencingId));
1143 sink_.ClearMessages(); 1028 sink_.ClearMessages();
1029
1144 // Now the other host. 1030 // Now the other host.
1145 host2->OnRegisterBlobUUID( 1031 host2->OnRegisterBlob(kDifferentHostReferencingId, std::string(kContentType),
1146 kDifferentHostReferencingId, std::string(kContentType), 1032 std::string(kContentDisposition), referencing_elements);
1147 std::string(kContentDisposition), referenced_blobs_set); 1033 EXPECT_FALSE(host2->shutdown_for_bad_message_);
1148 host2->OnStartBuildingBlob(kDifferentHostReferencingId, referencing_elements);
1149 ExpectDone(kDifferentHostReferencingId); 1034 ExpectDone(kDifferentHostReferencingId);
1150 EXPECT_TRUE(host2->async_builder_.IsBeingBuilt(kDifferentHostReferencingId));
1151 sink_.ClearMessages(); 1035 sink_.ClearMessages();
1152 1036
1153 // Grab handles & add listeners. 1037 // Grab handles & add listeners.
1154 bool built = true; 1038 bool built = true;
1155 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN; 1039 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN;
1156 std::unique_ptr<BlobDataHandle> blob_handle = 1040 std::unique_ptr<BlobDataHandle> blob_handle =
1157 context_->GetBlobDataFromUUID(kId); 1041 context_->GetBlobDataFromUUID(kId);
1158 blob_handle->RunOnConstructionComplete( 1042 blob_handle->RunOnConstructionComplete(
1159 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); 1043 base::Bind(&ConstructionCompletePopulator, &built, &error_code));
1160 1044
(...skipping 29 matching lines...) Expand all
1190 EXPECT_EQ(IPCBlobCreationCancelCode::SOURCE_DIED_IN_TRANSIT, error_code); 1074 EXPECT_EQ(IPCBlobCreationCancelCode::SOURCE_DIED_IN_TRANSIT, error_code);
1191 EXPECT_FALSE(same_host_built); 1075 EXPECT_FALSE(same_host_built);
1192 EXPECT_EQ(IPCBlobCreationCancelCode::SOURCE_DIED_IN_TRANSIT, 1076 EXPECT_EQ(IPCBlobCreationCancelCode::SOURCE_DIED_IN_TRANSIT,
1193 same_host_error_code); 1077 same_host_error_code);
1194 EXPECT_FALSE(other_host_built); 1078 EXPECT_FALSE(other_host_built);
1195 EXPECT_EQ(IPCBlobCreationCancelCode::SOURCE_DIED_IN_TRANSIT, 1079 EXPECT_EQ(IPCBlobCreationCancelCode::SOURCE_DIED_IN_TRANSIT,
1196 other_host_error_code); 1080 other_host_error_code);
1197 1081
1198 sink_.ClearMessages(); 1082 sink_.ClearMessages();
1199 } 1083 }
1084 //
1085 // TEST_F(BlobDispatcherHostTest, BlobChaos) {
1086 // DataElement element;
1087 // element.SetToBytesDescription(kTestBlobStorageMaxMemoryUsage / 3 + 1);
1088 // std::vector<DataElement> elements = {element};
1089 //
1090 // int memory_left = kTestBlobStorageMaxDiskSpace
1091 // + kTestBlobStorageMaxDiskSpace;
1092 //
1093 // // Option 1:
1094 // // * shortcut
1095 // // * shared mem
1096 // // * multiple shared mem
1097 //
1098 // for (int i = 0; i < 1000; i++) {
1099 // std::string id = base::IntToString(i);
1100 // int option1 = i % 3;
1101 // size_t size;
1102 // switch(option1) {
1103 // case 0:
1104 // size = kTestBlobStorageIPCThresholdBytes;
1105 // break;
1106 // case 1:
1107 // size = kTestBlobStorageMaxSharedMemoryBytes;
1108 // break;
1109 // case 2:
1110 // size = kTestBlobStorageMaxSharedMemoryBytes * 3 + 1;
1111 // break;
1112 // }
1113 // if (memory_left - size <= 0) {
1114 // break;
1115 // }
1116 // DataElement element;
1117 // std::vector<DataElement> elements;
1118 // if (option1 == 0) {
1119 // SetElementToCharBytes(&element, 'z', size);
1120 // } else {
1121 // element.SetToBytesDescription(size);
1122 // }
1123 // elements.push_back(element);
1124 //
1125 // host_->OnRegisterBlob(id, std::string(kContentType),
1126 // std::string(kContentDisposition), elements);
1127 // }
1128 //
1129 // for (int i = 0; i < sink_.message_count(); i++) {
1130 //
1131 // }
1132 //}
1200 1133
1201 } // namespace content 1134 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698