OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/blob_storage/blob_dispatcher_host.h" | 5 #include "content/browser/blob_storage/blob_dispatcher_host.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 | 49 |
50 const size_t kTestBlobStorageIPCThresholdBytes = 20; | 50 const size_t kTestBlobStorageIPCThresholdBytes = 20; |
51 const size_t kTestBlobStorageMaxSharedMemoryBytes = 50; | 51 const size_t kTestBlobStorageMaxSharedMemoryBytes = 50; |
52 const uint64_t kTestBlobStorageMaxFileSizeBytes = 100; | 52 const uint64_t kTestBlobStorageMaxFileSizeBytes = 100; |
53 | 53 |
54 template <typename T> | 54 template <typename T> |
55 void SetPointerValue(T* pointer, T value) { | 55 void SetPointerValue(T* pointer, T value) { |
56 *pointer = value; | 56 *pointer = value; |
57 } | 57 } |
58 | 58 |
| 59 void SetAndCheckBlobsBuilding(bool* blobs_building, bool set_can_terminate) { |
| 60 EXPECT_NE(*blobs_building, !set_can_terminate) |
| 61 << "We shouldn't set sudden termination the same way twice"; |
| 62 *blobs_building = !set_can_terminate; |
| 63 } |
| 64 |
59 class TestableBlobDispatcherHost : public BlobDispatcherHost { | 65 class TestableBlobDispatcherHost : public BlobDispatcherHost { |
60 public: | 66 public: |
61 TestableBlobDispatcherHost(ChromeBlobStorageContext* blob_storage_context, | 67 TestableBlobDispatcherHost(ChromeBlobStorageContext* blob_storage_context, |
62 IPC::TestSink* sink) | 68 IPC::TestSink* sink, |
63 : BlobDispatcherHost(blob_storage_context), sink_(sink) { | 69 bool* blobs_building) |
| 70 : BlobDispatcherHost( |
| 71 blob_storage_context, |
| 72 base::Bind(&SetAndCheckBlobsBuilding, blobs_building)), |
| 73 sink_(sink) { |
64 this->SetMemoryConstantsForTesting(kTestBlobStorageIPCThresholdBytes, | 74 this->SetMemoryConstantsForTesting(kTestBlobStorageIPCThresholdBytes, |
65 kTestBlobStorageMaxSharedMemoryBytes, | 75 kTestBlobStorageMaxSharedMemoryBytes, |
66 kTestBlobStorageMaxFileSizeBytes); | 76 kTestBlobStorageMaxFileSizeBytes); |
67 } | 77 } |
68 | 78 |
69 bool Send(IPC::Message* message) override { return sink_->Send(message); } | 79 bool Send(IPC::Message* message) override { return sink_->Send(message); } |
70 | 80 |
71 void ShutdownForBadMessage() override { shutdown_for_bad_message_ = true; } | 81 void ShutdownForBadMessage() override { shutdown_for_bad_message_ = true; } |
72 | 82 |
73 bool shutdown_for_bad_message_ = false; | 83 bool shutdown_for_bad_message_ = false; |
74 | 84 |
75 protected: | 85 protected: |
76 ~TestableBlobDispatcherHost() override {} | 86 ~TestableBlobDispatcherHost() override {} |
77 | 87 |
78 private: | 88 private: |
79 friend class base::RefCountedThreadSafe<TestableBlobDispatcherHost>; | 89 friend class base::RefCountedThreadSafe<TestableBlobDispatcherHost>; |
80 | 90 |
81 IPC::TestSink* sink_; | 91 IPC::TestSink* sink_; |
82 }; | 92 }; |
83 | 93 |
84 } // namespace | 94 } // namespace |
85 | 95 |
86 class BlobDispatcherHostTest : public testing::Test { | 96 class BlobDispatcherHostTest : public testing::Test { |
87 protected: | 97 protected: |
88 BlobDispatcherHostTest() | 98 BlobDispatcherHostTest() |
89 : chrome_blob_storage_context_( | 99 : chrome_blob_storage_context_( |
90 ChromeBlobStorageContext::GetFor(&browser_context_)) { | 100 ChromeBlobStorageContext::GetFor(&browser_context_)) { |
91 host_ = | 101 host_ = new TestableBlobDispatcherHost(chrome_blob_storage_context_, &sink_, |
92 new TestableBlobDispatcherHost(chrome_blob_storage_context_, &sink_); | 102 &blobs_building_); |
93 } | 103 } |
94 ~BlobDispatcherHostTest() override {} | 104 ~BlobDispatcherHostTest() override {} |
95 | 105 |
96 void SetUp() override { | 106 void SetUp() override { |
97 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | 107 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
98 if (!command_line->HasSwitch(switches::kDisableKillAfterBadIPC)) { | 108 if (!command_line->HasSwitch(switches::kDisableKillAfterBadIPC)) { |
99 command_line->AppendSwitch(switches::kDisableKillAfterBadIPC); | 109 command_line->AppendSwitch(switches::kDisableKillAfterBadIPC); |
100 } | 110 } |
101 // 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. |
102 base::RunLoop().RunUntilIdle(); | 112 base::RunLoop().RunUntilIdle(); |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 sink_.GetUniqueMessageMatching(BlobStorageMsg_DoneBuildingBlob::ID); | 253 sink_.GetUniqueMessageMatching(BlobStorageMsg_DoneBuildingBlob::ID); |
244 base::Tuple<std::string> args; | 254 base::Tuple<std::string> args; |
245 BlobStorageMsg_DoneBuildingBlob::Read(message, &args); | 255 BlobStorageMsg_DoneBuildingBlob::Read(message, &args); |
246 EXPECT_EQ(expected_uuid, base::get<0>(args)); | 256 EXPECT_EQ(expected_uuid, base::get<0>(args)); |
247 } | 257 } |
248 | 258 |
249 bool IsBeingBuiltInHost(const std::string& uuid) { | 259 bool IsBeingBuiltInHost(const std::string& uuid) { |
250 return host_->async_builder_.IsBeingBuilt(uuid); | 260 return host_->async_builder_.IsBeingBuilt(uuid); |
251 } | 261 } |
252 | 262 |
| 263 bool blobs_building_ = false; |
253 IPC::TestSink sink_; | 264 IPC::TestSink sink_; |
254 TestBrowserThreadBundle browser_thread_bundle_; | 265 TestBrowserThreadBundle browser_thread_bundle_; |
255 TestBrowserContext browser_context_; | 266 TestBrowserContext browser_context_; |
256 ChromeBlobStorageContext* chrome_blob_storage_context_; | 267 ChromeBlobStorageContext* chrome_blob_storage_context_; |
257 BlobStorageContext* context_ = nullptr; | 268 BlobStorageContext* context_ = nullptr; |
258 scoped_refptr<TestableBlobDispatcherHost> host_; | 269 scoped_refptr<TestableBlobDispatcherHost> host_; |
259 }; | 270 }; |
260 | 271 |
261 TEST_F(BlobDispatcherHostTest, EmptyUUIDs) { | 272 TEST_F(BlobDispatcherHostTest, EmptyUUIDs) { |
262 host_->OnRegisterBlobUUID("", "", "", std::set<std::string>()); | 273 host_->OnRegisterBlobUUID("", "", "", std::set<std::string>()); |
263 ExpectAndResetBadMessage(); | 274 ExpectAndResetBadMessage(); |
| 275 EXPECT_FALSE(blobs_building_); |
264 host_->OnStartBuildingBlob("", std::vector<DataElement>()); | 276 host_->OnStartBuildingBlob("", std::vector<DataElement>()); |
265 ExpectAndResetBadMessage(); | 277 ExpectAndResetBadMessage(); |
| 278 EXPECT_FALSE(blobs_building_); |
266 host_->OnMemoryItemResponse("", std::vector<BlobItemBytesResponse>()); | 279 host_->OnMemoryItemResponse("", std::vector<BlobItemBytesResponse>()); |
267 ExpectAndResetBadMessage(); | 280 ExpectAndResetBadMessage(); |
| 281 EXPECT_FALSE(blobs_building_); |
268 host_->OnCancelBuildingBlob("", IPCBlobCreationCancelCode::UNKNOWN); | 282 host_->OnCancelBuildingBlob("", IPCBlobCreationCancelCode::UNKNOWN); |
269 ExpectAndResetBadMessage(); | 283 ExpectAndResetBadMessage(); |
| 284 EXPECT_FALSE(blobs_building_); |
270 } | 285 } |
271 | 286 |
272 TEST_F(BlobDispatcherHostTest, Shortcut) { | 287 TEST_F(BlobDispatcherHostTest, Shortcut) { |
273 const std::string kId = "uuid1"; | 288 const std::string kId = "uuid1"; |
| 289 EXPECT_FALSE(blobs_building_); |
274 AsyncShortcutBlobTransfer(kId); | 290 AsyncShortcutBlobTransfer(kId); |
| 291 EXPECT_FALSE(blobs_building_); |
275 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 292 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
276 scoped_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId); | 293 scoped_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId); |
277 EXPECT_TRUE(handle); | 294 EXPECT_TRUE(handle); |
278 | 295 |
279 DataElement expected; | 296 DataElement expected; |
280 expected.SetToBytes(kData, kDataSize); | 297 expected.SetToBytes(kData, kDataSize); |
281 std::vector<DataElement> elements = {expected}; | 298 std::vector<DataElement> elements = {expected}; |
282 ExpectHandleEqualsData(handle.get(), elements); | 299 ExpectHandleEqualsData(handle.get(), elements); |
283 } | 300 } |
284 | 301 |
285 TEST_F(BlobDispatcherHostTest, RegularTransfer) { | 302 TEST_F(BlobDispatcherHostTest, RegularTransfer) { |
286 const std::string kId = "uuid1"; | 303 const std::string kId = "uuid1"; |
287 AsyncBlobTransfer(kId); | 304 AsyncBlobTransfer(kId); |
| 305 EXPECT_FALSE(blobs_building_); |
288 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 306 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
289 scoped_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId); | 307 scoped_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId); |
290 EXPECT_TRUE(handle); | 308 EXPECT_TRUE(handle); |
291 | 309 |
292 DataElement expected; | 310 DataElement expected; |
293 expected.SetToBytes(kData, kDataSize); | 311 expected.SetToBytes(kData, kDataSize); |
294 std::vector<DataElement> elements = {expected}; | 312 std::vector<DataElement> elements = {expected}; |
295 ExpectHandleEqualsData(handle.get(), elements); | 313 ExpectHandleEqualsData(handle.get(), elements); |
296 } | 314 } |
297 | 315 |
| 316 TEST_F(BlobDispatcherHostTest, MultipleTransfers) { |
| 317 const std::string kId = "uuid"; |
| 318 const int kNumIters = 10; |
| 319 EXPECT_FALSE(blobs_building_); |
| 320 for (int i = 0; i < kNumIters; i++) { |
| 321 std::string id = kId; |
| 322 id += ('0' + i); |
| 323 ExpectBlobNotExist(id); |
| 324 host_->OnRegisterBlobUUID(id, std::string(kContentType), |
| 325 std::string(kContentDisposition), |
| 326 std::set<std::string>()); |
| 327 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
| 328 EXPECT_TRUE(blobs_building_); |
| 329 } |
| 330 sink_.ClearMessages(); |
| 331 |
| 332 for (int i = 0; i < kNumIters; i++) { |
| 333 std::string id = kId; |
| 334 id += ('0' + i); |
| 335 DataElement element; |
| 336 element.SetToBytesDescription(kDataSize); |
| 337 std::vector<DataElement> elements = {element}; |
| 338 host_->OnStartBuildingBlob(id, elements); |
| 339 EXPECT_TRUE(blobs_building_); |
| 340 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
| 341 // Expect our request. |
| 342 std::vector<BlobItemBytesRequest> expected_requests = { |
| 343 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; |
| 344 ExpectRequest(id, expected_requests); |
| 345 sink_.ClearMessages(); |
| 346 } |
| 347 |
| 348 for (int i = 0; i < kNumIters; i++) { |
| 349 std::string id = kId; |
| 350 id += ('0' + i); |
| 351 // Send results; |
| 352 BlobItemBytesResponse response(0); |
| 353 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); |
| 354 std::vector<BlobItemBytesResponse> responses = {response}; |
| 355 host_->OnMemoryItemResponse(id, responses); |
| 356 ExpectDone(id); |
| 357 sink_.ClearMessages(); |
| 358 } |
| 359 EXPECT_FALSE(blobs_building_); |
| 360 } |
| 361 |
298 TEST_F(BlobDispatcherHostTest, SharedMemoryTransfer) { | 362 TEST_F(BlobDispatcherHostTest, SharedMemoryTransfer) { |
299 const std::string kId = "uuid1"; | 363 const std::string kId = "uuid1"; |
300 const size_t kLargeSize = kTestBlobStorageMaxSharedMemoryBytes * 2; | 364 const size_t kLargeSize = kTestBlobStorageMaxSharedMemoryBytes * 2; |
301 std::vector<base::SharedMemoryHandle> shared_memory_handles; | 365 std::vector<base::SharedMemoryHandle> shared_memory_handles; |
302 | 366 |
303 ExpectBlobNotExist(kId); | 367 ExpectBlobNotExist(kId); |
| 368 EXPECT_FALSE(blobs_building_); |
304 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 369 host_->OnRegisterBlobUUID(kId, std::string(kContentType), |
305 std::string(kContentDisposition), | 370 std::string(kContentDisposition), |
306 std::set<std::string>()); | 371 std::set<std::string>()); |
| 372 EXPECT_TRUE(blobs_building_); |
| 373 |
307 // Grab the handle. | 374 // Grab the handle. |
308 scoped_ptr<BlobDataHandle> blob_data_handle = | 375 scoped_ptr<BlobDataHandle> blob_data_handle = |
309 context_->GetBlobDataFromUUID(kId); | 376 context_->GetBlobDataFromUUID(kId); |
310 bool built = false; | 377 bool built = false; |
311 blob_data_handle->RunOnConstructionComplete( | 378 blob_data_handle->RunOnConstructionComplete( |
312 base::Bind(&SetPointerValue<bool>, &built)); | 379 base::Bind(&SetPointerValue<bool>, &built)); |
313 EXPECT_FALSE(built); | 380 EXPECT_FALSE(built); |
314 | 381 |
315 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 382 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
316 DataElement element; | 383 DataElement element; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
362 EXPECT_TRUE(base::SharedMemory::IsHandleValid(shared_memory_handles[0])); | 429 EXPECT_TRUE(base::SharedMemory::IsHandleValid(shared_memory_handles[0])); |
363 { | 430 { |
364 base::SharedMemory memory( | 431 base::SharedMemory memory( |
365 base::SharedMemory::DuplicateHandle(shared_memory_handles[0]), false); | 432 base::SharedMemory::DuplicateHandle(shared_memory_handles[0]), false); |
366 memory.Map(kTestBlobStorageMaxSharedMemoryBytes); | 433 memory.Map(kTestBlobStorageMaxSharedMemoryBytes); |
367 std::memset(memory.memory(), 'Z', kTestBlobStorageMaxSharedMemoryBytes); | 434 std::memset(memory.memory(), 'Z', kTestBlobStorageMaxSharedMemoryBytes); |
368 memory.Close(); | 435 memory.Close(); |
369 } | 436 } |
370 // Send the confirmation. | 437 // Send the confirmation. |
371 responses = {BlobItemBytesResponse(1)}; | 438 responses = {BlobItemBytesResponse(1)}; |
| 439 EXPECT_TRUE(blobs_building_); |
372 host_->OnMemoryItemResponse(kId, responses); | 440 host_->OnMemoryItemResponse(kId, responses); |
| 441 EXPECT_FALSE(blobs_building_); |
373 | 442 |
374 ExpectDone(kId); | 443 ExpectDone(kId); |
375 sink_.ClearMessages(); | 444 sink_.ClearMessages(); |
376 base::RunLoop().RunUntilIdle(); | 445 base::RunLoop().RunUntilIdle(); |
377 EXPECT_TRUE(built); | 446 EXPECT_TRUE(built); |
378 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 447 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
379 scoped_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId); | 448 scoped_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId); |
380 EXPECT_TRUE(handle); | 449 EXPECT_TRUE(handle); |
381 | 450 |
382 DataElement expected; | 451 DataElement expected; |
383 expected.SetToAllocatedBytes(kLargeSize / 2); | 452 expected.SetToAllocatedBytes(kLargeSize / 2); |
384 std::memset(expected.mutable_bytes(), 'X', kLargeSize / 2); | 453 std::memset(expected.mutable_bytes(), 'X', kLargeSize / 2); |
385 elements = {expected}; | 454 elements = {expected}; |
386 std::memset(expected.mutable_bytes(), 'Z', kLargeSize / 2); | 455 std::memset(expected.mutable_bytes(), 'Z', kLargeSize / 2); |
387 elements.push_back(expected); | 456 elements.push_back(expected); |
388 ExpectHandleEqualsData(handle.get(), elements); | 457 ExpectHandleEqualsData(handle.get(), elements); |
389 } | 458 } |
390 | 459 |
391 TEST_F(BlobDispatcherHostTest, OnCancelBuildingBlob) { | 460 TEST_F(BlobDispatcherHostTest, OnCancelBuildingBlob) { |
392 const std::string kId("id"); | 461 const std::string kId("id"); |
393 // We ignore blobs that are unknown, as it could have been cancelled earlier | 462 // We ignore blobs that are unknown, as it could have been cancelled earlier |
394 // and the renderer didn't know about it yet. | 463 // and the renderer didn't know about it yet. |
395 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN); | 464 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN); |
396 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 465 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
397 | 466 |
398 // Start building blob. | 467 // Start building blob. |
| 468 EXPECT_FALSE(blobs_building_); |
399 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 469 host_->OnRegisterBlobUUID(kId, std::string(kContentType), |
400 std::string(kContentDisposition), | 470 std::string(kContentDisposition), |
401 std::set<std::string>()); | 471 std::set<std::string>()); |
| 472 EXPECT_TRUE(blobs_building_); |
402 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 473 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
403 DataElement element; | 474 DataElement element; |
404 element.SetToBytesDescription(kDataSize); | 475 element.SetToBytesDescription(kDataSize); |
405 std::vector<DataElement> elements = {element}; | 476 std::vector<DataElement> elements = {element}; |
406 host_->OnStartBuildingBlob(kId, elements); | 477 host_->OnStartBuildingBlob(kId, elements); |
407 // It should have requested memory here. | 478 // It should have requested memory here. |
408 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 479 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
409 sink_.ClearMessages(); | 480 sink_.ClearMessages(); |
410 | 481 |
411 // Cancel in middle of construction. | 482 // Cancel in middle of construction. |
412 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN); | 483 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN); |
| 484 EXPECT_FALSE(blobs_building_); |
413 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 485 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
414 EXPECT_TRUE(host_->IsInUseInHost(kId)); | 486 EXPECT_TRUE(host_->IsInUseInHost(kId)); |
415 EXPECT_FALSE(IsBeingBuiltInHost(kId)); | 487 EXPECT_FALSE(IsBeingBuiltInHost(kId)); |
416 // Check that's it's broken. | 488 // Check that's it's broken. |
417 scoped_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId); | 489 scoped_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId); |
418 EXPECT_TRUE(handle->IsBroken()); | 490 EXPECT_TRUE(handle->IsBroken()); |
419 handle.reset(); | 491 handle.reset(); |
420 base::RunLoop().RunUntilIdle(); | 492 base::RunLoop().RunUntilIdle(); |
421 | 493 |
422 // Get rid of it in the host. | 494 // Get rid of it in the host. |
423 host_->OnDecrementBlobRefCount(kId); | 495 host_->OnDecrementBlobRefCount(kId); |
| 496 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
424 ExpectBlobNotExist(kId); | 497 ExpectBlobNotExist(kId); |
425 | 498 |
426 // Create blob again to verify we don't have any old construction state lying | 499 // Create blob again to verify we don't have any old construction state lying |
427 // around. | 500 // around. |
428 AsyncBlobTransfer(kId); | 501 AsyncBlobTransfer(kId); |
| 502 EXPECT_FALSE(blobs_building_); |
429 | 503 |
430 // Check data. | 504 // Check data. |
431 handle = context_->GetBlobDataFromUUID(kId); | 505 handle = context_->GetBlobDataFromUUID(kId); |
432 EXPECT_TRUE(handle); | 506 EXPECT_TRUE(handle); |
433 DataElement expected; | 507 DataElement expected; |
434 expected.SetToBytes(kData, kDataSize); | 508 expected.SetToBytes(kData, kDataSize); |
435 std::vector<DataElement> expecteds = {expected}; | 509 std::vector<DataElement> expecteds = {expected}; |
436 ExpectHandleEqualsData(handle.get(), expecteds); | 510 ExpectHandleEqualsData(handle.get(), expecteds); |
437 | 511 |
438 // Verify we can't cancel after the fact. | 512 // Verify we can't cancel after the fact. |
439 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN); | 513 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN); |
440 ExpectAndResetBadMessage(); | 514 ExpectAndResetBadMessage(); |
| 515 EXPECT_FALSE(blobs_building_); |
441 } | 516 } |
442 | 517 |
443 TEST_F(BlobDispatcherHostTest, BlobDataWithHostDeletion) { | 518 TEST_F(BlobDispatcherHostTest, BlobDataWithHostDeletion) { |
444 // Build up a basic blob. | 519 // Build up a basic blob. |
445 const std::string kId("id"); | 520 const std::string kId("id"); |
446 AsyncShortcutBlobTransfer(kId); | 521 AsyncShortcutBlobTransfer(kId); |
447 scoped_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId); | 522 scoped_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId); |
448 EXPECT_TRUE(handle); | 523 EXPECT_TRUE(handle); |
449 | 524 |
450 // Kill the host. | 525 // Kill the host. |
(...skipping 10 matching lines...) Expand all Loading... |
461 base::RunLoop().RunUntilIdle(); | 536 base::RunLoop().RunUntilIdle(); |
462 | 537 |
463 handle = context_->GetBlobDataFromUUID(kId); | 538 handle = context_->GetBlobDataFromUUID(kId); |
464 EXPECT_FALSE(handle); | 539 EXPECT_FALSE(handle); |
465 } | 540 } |
466 | 541 |
467 TEST_F(BlobDispatcherHostTest, BlobReferenceWhileConstructing) { | 542 TEST_F(BlobDispatcherHostTest, BlobReferenceWhileConstructing) { |
468 const std::string kId("id"); | 543 const std::string kId("id"); |
469 | 544 |
470 // Start building blob. | 545 // Start building blob. |
| 546 EXPECT_FALSE(blobs_building_); |
471 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 547 host_->OnRegisterBlobUUID(kId, std::string(kContentType), |
472 std::string(kContentDisposition), | 548 std::string(kContentDisposition), |
473 std::set<std::string>()); | 549 std::set<std::string>()); |
| 550 EXPECT_TRUE(blobs_building_); |
474 | 551 |
475 // Grab the handle. | 552 // Grab the handle. |
476 scoped_ptr<BlobDataHandle> blob_data_handle = | 553 scoped_ptr<BlobDataHandle> blob_data_handle = |
477 context_->GetBlobDataFromUUID(kId); | 554 context_->GetBlobDataFromUUID(kId); |
478 EXPECT_TRUE(blob_data_handle); | 555 EXPECT_TRUE(blob_data_handle); |
479 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); | 556 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); |
480 bool built = false; | 557 bool built = false; |
481 blob_data_handle->RunOnConstructionComplete( | 558 blob_data_handle->RunOnConstructionComplete( |
482 base::Bind(&SetPointerValue<bool>, &built)); | 559 base::Bind(&SetPointerValue<bool>, &built)); |
483 | 560 |
484 // Continue building. | 561 // Continue building. |
485 DataElement element; | 562 DataElement element; |
486 element.SetToBytesDescription(kDataSize); | 563 element.SetToBytesDescription(kDataSize); |
487 std::vector<DataElement> elements = {element}; | 564 std::vector<DataElement> elements = {element}; |
488 host_->OnStartBuildingBlob(kId, elements); | 565 host_->OnStartBuildingBlob(kId, elements); |
| 566 EXPECT_TRUE(blobs_building_); |
489 sink_.ClearMessages(); | 567 sink_.ClearMessages(); |
490 | 568 |
491 // Send data. | 569 // Send data. |
492 BlobItemBytesResponse response(0); | 570 BlobItemBytesResponse response(0); |
493 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); | 571 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); |
494 std::vector<BlobItemBytesResponse> responses = {response}; | 572 std::vector<BlobItemBytesResponse> responses = {response}; |
495 sink_.ClearMessages(); | 573 sink_.ClearMessages(); |
496 host_->OnMemoryItemResponse(kId, responses); | 574 host_->OnMemoryItemResponse(kId, responses); |
| 575 EXPECT_FALSE(blobs_building_); |
497 | 576 |
498 ExpectDone(kId); | 577 ExpectDone(kId); |
499 base::RunLoop().RunUntilIdle(); | 578 base::RunLoop().RunUntilIdle(); |
500 EXPECT_TRUE(built); | 579 EXPECT_TRUE(built); |
501 } | 580 } |
502 | 581 |
503 TEST_F(BlobDispatcherHostTest, BlobReferenceWhileShortcutConstructing) { | 582 TEST_F(BlobDispatcherHostTest, BlobReferenceWhileShortcutConstructing) { |
504 const std::string kId("id"); | 583 const std::string kId("id"); |
505 | 584 |
506 // Start building blob. | 585 // Start building blob. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
539 scoped_ptr<BlobDataHandle> blob_data_handle = | 618 scoped_ptr<BlobDataHandle> blob_data_handle = |
540 context_->GetBlobDataFromUUID(kId); | 619 context_->GetBlobDataFromUUID(kId); |
541 EXPECT_TRUE(blob_data_handle); | 620 EXPECT_TRUE(blob_data_handle); |
542 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); | 621 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); |
543 bool built = true; | 622 bool built = true; |
544 blob_data_handle->RunOnConstructionComplete( | 623 blob_data_handle->RunOnConstructionComplete( |
545 base::Bind(&SetPointerValue<bool>, &built)); | 624 base::Bind(&SetPointerValue<bool>, &built)); |
546 | 625 |
547 // Cancel in middle of construction. | 626 // Cancel in middle of construction. |
548 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN); | 627 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN); |
| 628 EXPECT_FALSE(blobs_building_); |
549 base::RunLoop().RunUntilIdle(); | 629 base::RunLoop().RunUntilIdle(); |
550 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 630 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
551 EXPECT_TRUE(host_->IsInUseInHost(kId)); | 631 EXPECT_TRUE(host_->IsInUseInHost(kId)); |
552 EXPECT_FALSE(IsBeingBuiltInHost(kId)); | 632 EXPECT_FALSE(IsBeingBuiltInHost(kId)); |
553 EXPECT_TRUE(blob_data_handle->IsBroken()); | 633 EXPECT_TRUE(blob_data_handle->IsBroken()); |
554 EXPECT_FALSE(built); | 634 EXPECT_FALSE(built); |
555 built = true; | 635 built = true; |
556 blob_data_handle->RunOnConstructionComplete( | 636 blob_data_handle->RunOnConstructionComplete( |
557 base::Bind(&SetPointerValue<bool>, &built)); | 637 base::Bind(&SetPointerValue<bool>, &built)); |
558 EXPECT_FALSE(built); | 638 EXPECT_FALSE(built); |
559 | 639 |
560 // Remove it. | 640 // Remove it. |
561 blob_data_handle.reset(); | 641 blob_data_handle.reset(); |
562 base::RunLoop().RunUntilIdle(); | 642 base::RunLoop().RunUntilIdle(); |
563 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 643 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
564 host_->OnDecrementBlobRefCount(kId); | 644 host_->OnDecrementBlobRefCount(kId); |
565 ExpectBlobNotExist(kId); | 645 ExpectBlobNotExist(kId); |
566 } | 646 } |
567 | 647 |
568 TEST_F(BlobDispatcherHostTest, DecrementRefAfterRegister) { | 648 TEST_F(BlobDispatcherHostTest, DecrementRefAfterRegister) { |
569 const std::string kId("id"); | 649 const std::string kId("id"); |
570 // Decrement the refcount while building (renderer blob gc'd before | 650 // Decrement the refcount while building (renderer blob gc'd before |
571 // construction was completed). | 651 // construction was completed). |
572 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 652 host_->OnRegisterBlobUUID(kId, std::string(kContentType), |
573 std::string(kContentDisposition), | 653 std::string(kContentDisposition), |
574 std::set<std::string>()); | 654 std::set<std::string>()); |
575 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 655 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
576 host_->OnDecrementBlobRefCount(kId); | 656 host_->OnDecrementBlobRefCount(kId); |
| 657 EXPECT_FALSE(blobs_building_); |
577 EXPECT_FALSE(context_->registry().HasEntry(kId)); | 658 EXPECT_FALSE(context_->registry().HasEntry(kId)); |
578 EXPECT_FALSE(IsBeingBuiltInHost(kId)); | 659 EXPECT_FALSE(IsBeingBuiltInHost(kId)); |
579 ExpectCancel(kId, | 660 ExpectCancel(kId, |
580 IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING); | 661 IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING); |
581 sink_.ClearMessages(); | 662 sink_.ClearMessages(); |
582 | 663 |
583 // Do the same, but this time grab a handle before we decrement. | 664 // Do the same, but this time grab a handle before we decrement. |
584 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 665 host_->OnRegisterBlobUUID(kId, std::string(kContentType), |
585 std::string(kContentDisposition), | 666 std::string(kContentDisposition), |
586 std::set<std::string>()); | 667 std::set<std::string>()); |
587 scoped_ptr<BlobDataHandle> blob_data_handle = | 668 scoped_ptr<BlobDataHandle> blob_data_handle = |
588 context_->GetBlobDataFromUUID(kId); | 669 context_->GetBlobDataFromUUID(kId); |
589 host_->OnDecrementBlobRefCount(kId); | 670 host_->OnDecrementBlobRefCount(kId); |
| 671 EXPECT_TRUE(blobs_building_); |
590 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 672 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
591 EXPECT_TRUE(IsBeingBuiltInHost(kId)); | 673 EXPECT_TRUE(IsBeingBuiltInHost(kId)); |
592 | 674 |
593 // Finish up the blob, and verify we got the done message. | 675 // Finish up the blob, and verify we got the done message. |
594 DataElement element; | 676 DataElement element; |
595 element.SetToBytes(kData, kDataSize); | 677 element.SetToBytes(kData, kDataSize); |
596 std::vector<DataElement> elements = {element}; | 678 std::vector<DataElement> elements = {element}; |
597 host_->OnStartBuildingBlob(kId, elements); | 679 host_->OnStartBuildingBlob(kId, elements); |
| 680 EXPECT_FALSE(blobs_building_); |
598 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 681 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
599 ExpectDone(kId); | 682 ExpectDone(kId); |
600 sink_.ClearMessages(); | 683 sink_.ClearMessages(); |
601 // Get rid of the handle, and verify it's gone. | 684 // Get rid of the handle, and verify it's gone. |
602 blob_data_handle.reset(); | 685 blob_data_handle.reset(); |
603 base::RunLoop().RunUntilIdle(); | 686 base::RunLoop().RunUntilIdle(); |
604 // Check that it's no longer around. | 687 // Check that it's no longer around. |
605 EXPECT_FALSE(context_->registry().HasEntry(kId)); | 688 EXPECT_FALSE(context_->registry().HasEntry(kId)); |
606 EXPECT_FALSE(IsBeingBuiltInHost(kId)); | 689 EXPECT_FALSE(IsBeingBuiltInHost(kId)); |
607 } | 690 } |
608 | 691 |
609 TEST_F(BlobDispatcherHostTest, DecrementRefAfterOnStart) { | 692 TEST_F(BlobDispatcherHostTest, DecrementRefAfterOnStart) { |
610 const std::string kId("id"); | 693 const std::string kId("id"); |
611 | 694 |
612 // Decrement the refcount while building, after we call OnStartBuildlingBlob. | 695 // Decrement the refcount while building, after we call OnStartBuildlingBlob. |
613 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 696 host_->OnRegisterBlobUUID(kId, std::string(kContentType), |
614 std::string(kContentDisposition), | 697 std::string(kContentDisposition), |
615 std::set<std::string>()); | 698 std::set<std::string>()); |
616 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 699 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
617 DataElement element; | 700 DataElement element; |
618 element.SetToBytesDescription(kDataSize); | 701 element.SetToBytesDescription(kDataSize); |
619 std::vector<DataElement> elements = {element}; | 702 std::vector<DataElement> elements = {element}; |
620 host_->OnStartBuildingBlob(kId, elements); | 703 host_->OnStartBuildingBlob(kId, elements); |
| 704 EXPECT_TRUE(blobs_building_); |
621 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 705 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
622 | 706 |
623 std::vector<BlobItemBytesRequest> expected_requests = { | 707 std::vector<BlobItemBytesRequest> expected_requests = { |
624 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; | 708 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; |
625 ExpectRequest(kId, expected_requests); | 709 ExpectRequest(kId, expected_requests); |
626 sink_.ClearMessages(); | 710 sink_.ClearMessages(); |
627 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 711 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
628 host_->OnDecrementBlobRefCount(kId); | 712 host_->OnDecrementBlobRefCount(kId); |
| 713 EXPECT_FALSE(blobs_building_); |
629 EXPECT_FALSE(context_->registry().HasEntry(kId)); | 714 EXPECT_FALSE(context_->registry().HasEntry(kId)); |
630 EXPECT_FALSE(IsBeingBuiltInHost(kId)); | 715 EXPECT_FALSE(IsBeingBuiltInHost(kId)); |
631 ExpectCancel(kId, | 716 ExpectCancel(kId, |
632 IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING); | 717 IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING); |
633 sink_.ClearMessages(); | 718 sink_.ClearMessages(); |
634 | 719 |
635 // Do the same, but this time grab a handle to keep it alive. | 720 // Do the same, but this time grab a handle to keep it alive. |
636 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 721 host_->OnRegisterBlobUUID(kId, std::string(kContentType), |
637 std::string(kContentDisposition), | 722 std::string(kContentDisposition), |
638 std::set<std::string>()); | 723 std::set<std::string>()); |
639 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 724 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
640 host_->OnStartBuildingBlob(kId, elements); | 725 host_->OnStartBuildingBlob(kId, elements); |
641 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 726 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
642 ExpectRequest(kId, expected_requests); | 727 ExpectRequest(kId, expected_requests); |
643 sink_.ClearMessages(); | 728 sink_.ClearMessages(); |
644 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 729 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
645 // Grab the handle before decrementing. | 730 // Grab the handle before decrementing. |
646 scoped_ptr<BlobDataHandle> blob_data_handle = | 731 scoped_ptr<BlobDataHandle> blob_data_handle = |
647 context_->GetBlobDataFromUUID(kId); | 732 context_->GetBlobDataFromUUID(kId); |
648 host_->OnDecrementBlobRefCount(kId); | 733 host_->OnDecrementBlobRefCount(kId); |
| 734 EXPECT_TRUE(blobs_building_); |
649 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 735 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
650 EXPECT_TRUE(IsBeingBuiltInHost(kId)); | 736 EXPECT_TRUE(IsBeingBuiltInHost(kId)); |
651 | 737 |
652 // We finish the blob, and verify that we send 'Done' back to the renderer. | 738 // We finish the blob, and verify that we send 'Done' back to the renderer. |
653 BlobItemBytesResponse response(0); | 739 BlobItemBytesResponse response(0); |
654 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); | 740 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); |
655 std::vector<BlobItemBytesResponse> responses = {response}; | 741 std::vector<BlobItemBytesResponse> responses = {response}; |
656 host_->OnMemoryItemResponse(kId, responses); | 742 host_->OnMemoryItemResponse(kId, responses); |
| 743 EXPECT_FALSE(blobs_building_); |
657 ExpectDone(kId); | 744 ExpectDone(kId); |
658 sink_.ClearMessages(); | 745 sink_.ClearMessages(); |
659 // Check that it's still around. | 746 // Check that it's still around. |
660 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 747 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
661 EXPECT_FALSE(IsBeingBuiltInHost(kId)); | 748 EXPECT_FALSE(IsBeingBuiltInHost(kId)); |
662 | 749 |
663 // Get rid of the handle, and verify it's gone. | 750 // Get rid of the handle, and verify it's gone. |
664 blob_data_handle.reset(); | 751 blob_data_handle.reset(); |
665 base::RunLoop().RunUntilIdle(); | 752 base::RunLoop().RunUntilIdle(); |
666 // Check that it's no longer around. | 753 // Check that it's no longer around. |
(...skipping 25 matching lines...) Expand all Loading... |
692 | 779 |
693 // Check that we got the expected request. | 780 // Check that we got the expected request. |
694 std::vector<BlobItemBytesRequest> expected_requests = { | 781 std::vector<BlobItemBytesRequest> expected_requests = { |
695 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; | 782 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; |
696 ExpectRequest(kId, expected_requests); | 783 ExpectRequest(kId, expected_requests); |
697 sink_.ClearMessages(); | 784 sink_.ClearMessages(); |
698 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 785 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
699 EXPECT_TRUE(IsBeingBuiltInHost(kId)); | 786 EXPECT_TRUE(IsBeingBuiltInHost(kId)); |
700 // Decrement, simulating where the ref goes out of scope in renderer. | 787 // Decrement, simulating where the ref goes out of scope in renderer. |
701 host_->OnDecrementBlobRefCount(kId); | 788 host_->OnDecrementBlobRefCount(kId); |
| 789 EXPECT_TRUE(blobs_building_); |
702 // We still have the blob as it's not done. | 790 // We still have the blob as it's not done. |
703 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 791 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
704 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); | 792 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); |
705 EXPECT_TRUE(IsBeingBuiltInHost(kId)); | 793 EXPECT_TRUE(IsBeingBuiltInHost(kId)); |
706 // Cancel to clean up. | 794 // Cancel to clean up. |
707 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN); | 795 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN); |
| 796 EXPECT_FALSE(blobs_building_); |
708 // Run loop to propagate the handle decrement in the host. | 797 // Run loop to propagate the handle decrement in the host. |
709 base::RunLoop().RunUntilIdle(); | 798 base::RunLoop().RunUntilIdle(); |
710 // We still have the entry because of our earlier handle. | 799 // We still have the entry because of our earlier handle. |
711 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 800 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
712 EXPECT_FALSE(IsBeingBuiltInHost(kId)); | 801 EXPECT_FALSE(IsBeingBuiltInHost(kId)); |
713 sink_.ClearMessages(); | 802 sink_.ClearMessages(); |
714 | 803 |
715 // Should disappear after dropping the handle. | 804 // Should disappear after dropping the handle. |
716 EXPECT_TRUE(blob_data_handle->IsBroken()); | 805 EXPECT_TRUE(blob_data_handle->IsBroken()); |
717 blob_data_handle.reset(); | 806 blob_data_handle.reset(); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
761 | 850 |
762 DataElement element; | 851 DataElement element; |
763 element.SetToBytesDescription(kDataSize); | 852 element.SetToBytesDescription(kDataSize); |
764 std::vector<DataElement> elements = {element}; | 853 std::vector<DataElement> elements = {element}; |
765 host_->OnStartBuildingBlob(kId, elements); | 854 host_->OnStartBuildingBlob(kId, elements); |
766 | 855 |
767 std::vector<BlobItemBytesRequest> expected_requests = { | 856 std::vector<BlobItemBytesRequest> expected_requests = { |
768 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; | 857 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; |
769 ExpectRequest(kId, expected_requests); | 858 ExpectRequest(kId, expected_requests); |
770 sink_.ClearMessages(); | 859 sink_.ClearMessages(); |
| 860 EXPECT_TRUE(blobs_building_); |
771 host_ = nullptr; | 861 host_ = nullptr; |
| 862 EXPECT_FALSE(blobs_building_); |
772 // We need to run the message loop because of the handle in the async builder. | 863 // We need to run the message loop because of the handle in the async builder. |
773 base::RunLoop().RunUntilIdle(); | 864 base::RunLoop().RunUntilIdle(); |
774 EXPECT_FALSE(context_->registry().HasEntry(kId)); | 865 EXPECT_FALSE(context_->registry().HasEntry(kId)); |
775 } | 866 } |
776 | 867 |
777 TEST_F(BlobDispatcherHostTest, HostDisconnectAfterOnMemoryResponse) { | 868 TEST_F(BlobDispatcherHostTest, HostDisconnectAfterOnMemoryResponse) { |
778 const std::string kId("id"); | 869 const std::string kId("id"); |
779 | 870 |
780 // Host deleted after OnMemoryItemResponse. | 871 // Host deleted after OnMemoryItemResponse. |
781 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 872 host_->OnRegisterBlobUUID(kId, std::string(kContentType), |
(...skipping 11 matching lines...) Expand all Loading... |
793 ExpectRequest(kId, expected_requests); | 884 ExpectRequest(kId, expected_requests); |
794 sink_.ClearMessages(); | 885 sink_.ClearMessages(); |
795 | 886 |
796 // Send just one response so the blob isn't 'done' yet. | 887 // Send just one response so the blob isn't 'done' yet. |
797 BlobItemBytesResponse response(0); | 888 BlobItemBytesResponse response(0); |
798 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); | 889 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); |
799 std::vector<BlobItemBytesResponse> responses = {response}; | 890 std::vector<BlobItemBytesResponse> responses = {response}; |
800 host_->OnMemoryItemResponse(kId, responses); | 891 host_->OnMemoryItemResponse(kId, responses); |
801 EXPECT_EQ(0u, sink_.message_count()); | 892 EXPECT_EQ(0u, sink_.message_count()); |
802 | 893 |
| 894 EXPECT_TRUE(blobs_building_); |
803 host_ = nullptr; | 895 host_ = nullptr; |
| 896 EXPECT_FALSE(blobs_building_); |
804 base::RunLoop().RunUntilIdle(); | 897 base::RunLoop().RunUntilIdle(); |
805 EXPECT_FALSE(context_->registry().HasEntry(kId)); | 898 EXPECT_FALSE(context_->registry().HasEntry(kId)); |
806 } | 899 } |
807 | 900 |
808 TEST_F(BlobDispatcherHostTest, CreateBlobWithBrokenReference) { | 901 TEST_F(BlobDispatcherHostTest, CreateBlobWithBrokenReference) { |
809 const std::string kBrokenId("id1"); | 902 const std::string kBrokenId("id1"); |
810 const std::string kReferencingId("id2"); | 903 const std::string kReferencingId("id2"); |
811 | 904 |
812 // First, let's test a circular reference. | 905 // First, let's test a circular reference. |
813 const std::string kCircularId("id1"); | 906 const std::string kCircularId("id1"); |
814 host_->OnRegisterBlobUUID(kCircularId, std::string(kContentType), | 907 host_->OnRegisterBlobUUID(kCircularId, std::string(kContentType), |
815 std::string(kContentDisposition), {kCircularId}); | 908 std::string(kContentDisposition), {kCircularId}); |
816 ExpectAndResetBadMessage(); | 909 ExpectAndResetBadMessage(); |
817 | 910 |
818 // Next, test a blob that references a broken blob. | 911 // Next, test a blob that references a broken blob. |
819 host_->OnRegisterBlobUUID(kBrokenId, std::string(kContentType), | 912 host_->OnRegisterBlobUUID(kBrokenId, std::string(kContentType), |
820 std::string(kContentDisposition), | 913 std::string(kContentDisposition), |
821 std::set<std::string>()); | 914 std::set<std::string>()); |
822 host_->OnCancelBuildingBlob(kBrokenId, IPCBlobCreationCancelCode::UNKNOWN); | 915 host_->OnCancelBuildingBlob(kBrokenId, IPCBlobCreationCancelCode::UNKNOWN); |
| 916 EXPECT_FALSE(blobs_building_); |
823 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 917 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
824 EXPECT_TRUE(context_->GetBlobDataFromUUID(kBrokenId)->IsBroken()); | 918 EXPECT_TRUE(context_->GetBlobDataFromUUID(kBrokenId)->IsBroken()); |
825 | 919 |
826 // Create referencing blob. We should be broken right away, but also ignore | 920 // Create referencing blob. We should be broken right away, but also ignore |
827 // the subsequent OnStart message. | 921 // the subsequent OnStart message. |
828 host_->OnRegisterBlobUUID(kReferencingId, std::string(kContentType), | 922 host_->OnRegisterBlobUUID(kReferencingId, std::string(kContentType), |
829 std::string(kContentDisposition), {kBrokenId}); | 923 std::string(kContentDisposition), {kBrokenId}); |
| 924 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
| 925 EXPECT_FALSE(blobs_building_); |
830 EXPECT_TRUE(context_->GetBlobDataFromUUID(kReferencingId)->IsBroken()); | 926 EXPECT_TRUE(context_->GetBlobDataFromUUID(kReferencingId)->IsBroken()); |
831 EXPECT_FALSE(IsBeingBuiltInHost(kReferencingId)); | 927 EXPECT_FALSE(IsBeingBuiltInHost(kReferencingId)); |
832 EXPECT_TRUE(context_->registry().HasEntry(kReferencingId)); | 928 EXPECT_TRUE(context_->registry().HasEntry(kReferencingId)); |
833 ExpectCancel(kReferencingId, | 929 ExpectCancel(kReferencingId, |
834 IPCBlobCreationCancelCode::REFERENCED_BLOB_BROKEN); | 930 IPCBlobCreationCancelCode::REFERENCED_BLOB_BROKEN); |
835 sink_.ClearMessages(); | 931 sink_.ClearMessages(); |
836 | 932 |
837 DataElement element; | 933 DataElement element; |
838 element.SetToBytesDescription(kDataSize); | 934 element.SetToBytesDescription(kDataSize); |
839 std::vector<DataElement> elements = {element}; | 935 std::vector<DataElement> elements = {element}; |
840 element.SetToBlob(kBrokenId); | 936 element.SetToBlob(kBrokenId); |
841 elements.push_back(element); | 937 elements.push_back(element); |
842 host_->OnStartBuildingBlob(kReferencingId, elements); | 938 host_->OnStartBuildingBlob(kReferencingId, elements); |
843 EXPECT_EQ(0u, sink_.message_count()); | 939 EXPECT_EQ(0u, sink_.message_count()); |
844 base::RunLoop().RunUntilIdle(); | 940 base::RunLoop().RunUntilIdle(); |
845 } | 941 } |
846 | 942 |
847 TEST_F(BlobDispatcherHostTest, DeferenceBlobOnDifferentHost) { | 943 TEST_F(BlobDispatcherHostTest, DeferenceBlobOnDifferentHost) { |
848 const std::string kId("id"); | 944 const std::string kId("id"); |
849 // Data elements for our transfer & checking messages. | 945 // Data elements for our transfer & checking messages. |
850 DataElement element; | 946 DataElement element; |
851 element.SetToBytesDescription(kDataSize); | 947 element.SetToBytesDescription(kDataSize); |
852 std::vector<DataElement> elements = {element}; | 948 std::vector<DataElement> elements = {element}; |
853 std::vector<BlobItemBytesRequest> expected_requests = { | 949 std::vector<BlobItemBytesRequest> expected_requests = { |
854 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; | 950 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; |
855 BlobItemBytesResponse response(0); | 951 BlobItemBytesResponse response(0); |
856 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); | 952 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); |
857 std::vector<BlobItemBytesResponse> responses = {response}; | 953 std::vector<BlobItemBytesResponse> responses = {response}; |
858 | 954 |
| 955 bool host2_blobs_building = false; |
859 scoped_refptr<TestableBlobDispatcherHost> host2( | 956 scoped_refptr<TestableBlobDispatcherHost> host2( |
860 new TestableBlobDispatcherHost(chrome_blob_storage_context_, &sink_)); | 957 new TestableBlobDispatcherHost(chrome_blob_storage_context_, &sink_, |
| 958 &host2_blobs_building)); |
861 | 959 |
862 // Delete host with another host having a referencing, then dereference on | 960 // Delete host with another host having a referencing, then dereference on |
863 // second host. Verify we're still building it on first host, and then | 961 // second host. Verify we're still building it on first host, and then |
864 // verify that a building message from the renderer will kill it. | 962 // verify that a building message from the renderer will kill it. |
865 | 963 |
866 // Test OnStartBuilding after double dereference. | 964 // Test OnStartBuilding after double dereference. |
867 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 965 host_->OnRegisterBlobUUID(kId, std::string(kContentType), |
868 std::string(kContentDisposition), | 966 std::string(kContentDisposition), |
869 std::set<std::string>()); | 967 std::set<std::string>()); |
| 968 EXPECT_TRUE(blobs_building_); |
870 host2->OnIncrementBlobRefCount(kId); | 969 host2->OnIncrementBlobRefCount(kId); |
871 host_->OnDecrementBlobRefCount(kId); | 970 host_->OnDecrementBlobRefCount(kId); |
872 EXPECT_FALSE(host_->IsInUseInHost(kId)); | 971 EXPECT_FALSE(host_->IsInUseInHost(kId)); |
873 host2->OnDecrementBlobRefCount(kId); | 972 host2->OnDecrementBlobRefCount(kId); |
| 973 EXPECT_TRUE(blobs_building_); |
874 // So no more blob in the context, but we're still being built in host 1. | 974 // So no more blob in the context, but we're still being built in host 1. |
875 EXPECT_FALSE(context_->registry().HasEntry(kId)); | 975 EXPECT_FALSE(context_->registry().HasEntry(kId)); |
876 EXPECT_TRUE(host_->async_builder_.IsBeingBuilt(kId)); | 976 EXPECT_TRUE(host_->async_builder_.IsBeingBuilt(kId)); |
877 host_->OnStartBuildingBlob(kId, elements); | 977 host_->OnStartBuildingBlob(kId, elements); |
| 978 EXPECT_FALSE(blobs_building_); |
878 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 979 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
879 // We should be cleaned up. | 980 // We should be cleaned up. |
880 EXPECT_FALSE(host_->async_builder_.IsBeingBuilt(kId)); | 981 EXPECT_FALSE(host_->async_builder_.IsBeingBuilt(kId)); |
881 ExpectCancel(kId, | 982 ExpectCancel(kId, |
882 IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING); | 983 IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING); |
883 sink_.ClearMessages(); | 984 sink_.ClearMessages(); |
884 | 985 |
885 // Same as above, but test OnMemoryItemResponse after double dereference. | 986 // Same as above, but test OnMemoryItemResponse after double dereference. |
886 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 987 host_->OnRegisterBlobUUID(kId, std::string(kContentType), |
887 std::string(kContentDisposition), | 988 std::string(kContentDisposition), |
888 std::set<std::string>()); | 989 std::set<std::string>()); |
| 990 EXPECT_TRUE(blobs_building_); |
889 host2->OnIncrementBlobRefCount(kId); | 991 host2->OnIncrementBlobRefCount(kId); |
890 host_->OnDecrementBlobRefCount(kId); | 992 host_->OnDecrementBlobRefCount(kId); |
891 EXPECT_FALSE(host_->IsInUseInHost(kId)); | 993 EXPECT_FALSE(host_->IsInUseInHost(kId)); |
892 host_->OnStartBuildingBlob(kId, elements); | 994 host_->OnStartBuildingBlob(kId, elements); |
893 ExpectRequest(kId, expected_requests); | 995 ExpectRequest(kId, expected_requests); |
894 sink_.ClearMessages(); | 996 sink_.ClearMessages(); |
895 | 997 |
896 host2->OnDecrementBlobRefCount(kId); | 998 host2->OnDecrementBlobRefCount(kId); |
897 // So no more blob in the context, but we're still being built in host 1. | 999 // So no more blob in the context, but we're still being built in host 1. |
898 EXPECT_FALSE(context_->registry().HasEntry(kId)); | 1000 EXPECT_FALSE(context_->registry().HasEntry(kId)); |
899 EXPECT_TRUE(host_->async_builder_.IsBeingBuilt(kId)); | 1001 EXPECT_TRUE(host_->async_builder_.IsBeingBuilt(kId)); |
| 1002 EXPECT_TRUE(blobs_building_); |
900 host_->OnMemoryItemResponse(kId, responses); | 1003 host_->OnMemoryItemResponse(kId, responses); |
| 1004 EXPECT_FALSE(blobs_building_); |
901 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 1005 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
902 // We should be cleaned up. | 1006 // We should be cleaned up. |
903 EXPECT_FALSE(host_->async_builder_.IsBeingBuilt(kId)); | 1007 EXPECT_FALSE(host_->async_builder_.IsBeingBuilt(kId)); |
904 ExpectCancel(kId, | 1008 ExpectCancel(kId, |
905 IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING); | 1009 IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING); |
906 sink_.ClearMessages(); | 1010 sink_.ClearMessages(); |
907 | 1011 |
908 // Same, but now for OnCancel. | 1012 // Same, but now for OnCancel. |
909 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 1013 host_->OnRegisterBlobUUID(kId, std::string(kContentType), |
910 std::string(kContentDisposition), | 1014 std::string(kContentDisposition), |
911 std::set<std::string>()); | 1015 std::set<std::string>()); |
912 host2->OnIncrementBlobRefCount(kId); | 1016 host2->OnIncrementBlobRefCount(kId); |
913 host_->OnDecrementBlobRefCount(kId); | 1017 host_->OnDecrementBlobRefCount(kId); |
914 EXPECT_FALSE(host_->IsInUseInHost(kId)); | 1018 EXPECT_FALSE(host_->IsInUseInHost(kId)); |
915 host_->OnStartBuildingBlob(kId, elements); | 1019 host_->OnStartBuildingBlob(kId, elements); |
916 ExpectRequest(kId, expected_requests); | 1020 ExpectRequest(kId, expected_requests); |
917 sink_.ClearMessages(); | 1021 sink_.ClearMessages(); |
918 | 1022 |
919 host2->OnDecrementBlobRefCount(kId); | 1023 host2->OnDecrementBlobRefCount(kId); |
920 // So no more blob in the context, but we're still being built in host 1. | 1024 // So no more blob in the context, but we're still being built in host 1. |
921 EXPECT_FALSE(context_->registry().HasEntry(kId)); | 1025 EXPECT_FALSE(context_->registry().HasEntry(kId)); |
922 EXPECT_TRUE(host_->async_builder_.IsBeingBuilt(kId)); | 1026 EXPECT_TRUE(host_->async_builder_.IsBeingBuilt(kId)); |
| 1027 EXPECT_TRUE(blobs_building_); |
923 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN); | 1028 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN); |
| 1029 EXPECT_FALSE(blobs_building_); |
924 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 1030 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
925 // We should be cleaned up. | 1031 // We should be cleaned up. |
926 EXPECT_FALSE(host_->async_builder_.IsBeingBuilt(kId)); | 1032 EXPECT_FALSE(host_->async_builder_.IsBeingBuilt(kId)); |
927 } | 1033 } |
928 | 1034 |
929 } // namespace content | 1035 } // namespace content |
OLD | NEW |