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

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

Powered by Google App Engine
This is Rietveld 408576698