| 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 <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 "content/public/test/test_file_system_context.h" | 20 #include "content/public/test/test_file_system_context.h" |
| 20 #include "ipc/ipc_sender.h" | 21 #include "ipc/ipc_sender.h" |
| 21 #include "ipc/ipc_test_sink.h" | 22 #include "ipc/ipc_test_sink.h" |
| 22 #include "ipc/message_filter.h" | 23 #include "ipc/message_filter.h" |
| 23 #include "storage/browser/blob/blob_data_builder.h" | 24 #include "storage/browser/blob/blob_data_builder.h" |
| 24 #include "storage/browser/blob/blob_data_handle.h" | 25 #include "storage/browser/blob/blob_data_handle.h" |
| 25 #include "storage/browser/blob/blob_storage_context.h" | 26 #include "storage/browser/blob/blob_storage_context.h" |
| 26 #include "storage/common/blob_storage/blob_item_bytes_request.h" | 27 #include "storage/common/blob_storage/blob_item_bytes_request.h" |
| 27 #include "storage/common/blob_storage/blob_item_bytes_response.h" | 28 #include "storage/common/blob_storage/blob_item_bytes_response.h" |
| 28 #include "storage/common/data_element.h" | 29 #include "storage/common/data_element.h" |
| 29 #include "testing/gmock/include/gmock/gmock.h" | 30 #include "testing/gmock/include/gmock/gmock.h" |
| 30 #include "testing/gtest/include/gtest/gtest.h" | 31 #include "testing/gtest/include/gtest/gtest.h" |
| 31 | 32 |
| 32 using storage::BlobDataBuilder; | 33 using storage::BlobDataBuilder; |
| 33 using storage::BlobDataHandle; | 34 using storage::BlobDataHandle; |
| 34 using storage::BlobItemBytesRequest; | 35 using storage::BlobItemBytesRequest; |
| 35 using storage::BlobItemBytesResponse; | 36 using storage::BlobItemBytesResponse; |
| 37 using storage::BlobStatus; |
| 36 using storage::BlobStorageContext; | 38 using storage::BlobStorageContext; |
| 37 using storage::BlobTransportResult; | |
| 38 using storage::DataElement; | 39 using storage::DataElement; |
| 39 using storage::IPCBlobCreationCancelCode; | 40 using RequestMemoryCallback = storage::BlobTransportHost::RequestMemoryCallback; |
| 40 using RequestMemoryCallback = | |
| 41 storage::BlobAsyncBuilderHost::RequestMemoryCallback; | |
| 42 | 41 |
| 43 namespace content { | 42 namespace content { |
| 44 namespace { | 43 namespace { |
| 45 | 44 |
| 46 const char kContentType[] = "text/plain"; | 45 const char kContentType[] = "text/plain"; |
| 47 const char kContentDisposition[] = "content_disposition"; | 46 const char kContentDisposition[] = "content_disposition"; |
| 48 const char kData[] = "data!!"; | 47 const char kData[] = "data!!"; |
| 49 const size_t kDataSize = 6; | 48 const size_t kDataSize = 6; |
| 50 | 49 |
| 51 const size_t kTestBlobStorageIPCThresholdBytes = 20; | 50 const size_t kTestBlobStorageIPCThresholdBytes = 20; |
| 52 const size_t kTestBlobStorageMaxSharedMemoryBytes = 50; | 51 const size_t kTestBlobStorageMaxSharedMemoryBytes = 50; |
| 52 const size_t kTestBlobStorageMaxBlobMemorySize = 400; |
| 53 const uint64_t kTestBlobStorageMaxDiskSpace = 1000; |
| 54 const uint64_t kTestBlobStorageMinFileSizeBytes = 10; |
| 53 const uint64_t kTestBlobStorageMaxFileSizeBytes = 100; | 55 const uint64_t kTestBlobStorageMaxFileSizeBytes = 100; |
| 54 | 56 |
| 55 void ConstructionCompletePopulator(bool* succeeded_pointer, | 57 void ConstructionCompletePopulator(bool* success_pointer, |
| 56 IPCBlobCreationCancelCode* reason_pointer, | 58 BlobStatus* reason_pointer, |
| 57 bool succeeded, | 59 BlobStatus reason) { |
| 58 IPCBlobCreationCancelCode reason) { | |
| 59 *succeeded_pointer = succeeded; | |
| 60 *reason_pointer = reason; | 60 *reason_pointer = reason; |
| 61 *success_pointer = reason == BlobStatus::DONE; |
| 61 } | 62 } |
| 62 | 63 |
| 63 // TODO(dmurph): Create file test that verifies security policy. | 64 // TODO(dmurph): Create file test that verifies security policy. |
| 64 class TestableBlobDispatcherHost : public BlobDispatcherHost { | 65 class TestableBlobDispatcherHost : public BlobDispatcherHost { |
| 65 public: | 66 public: |
| 66 TestableBlobDispatcherHost(ChromeBlobStorageContext* blob_storage_context, | 67 TestableBlobDispatcherHost(ChromeBlobStorageContext* blob_storage_context, |
| 67 storage::FileSystemContext* file_system_context, | 68 storage::FileSystemContext* file_system_context, |
| 68 IPC::TestSink* sink) | 69 IPC::TestSink* sink) |
| 69 : BlobDispatcherHost(0 /* process_id */, | 70 : BlobDispatcherHost(0 /* process_id */, |
| 70 make_scoped_refptr(blob_storage_context), | 71 make_scoped_refptr(blob_storage_context), |
| 71 make_scoped_refptr(file_system_context)), | 72 make_scoped_refptr(file_system_context)), |
| 72 sink_(sink) { | 73 sink_(sink) {} |
| 73 this->SetMemoryConstantsForTesting(kTestBlobStorageIPCThresholdBytes, | |
| 74 kTestBlobStorageMaxSharedMemoryBytes, | |
| 75 kTestBlobStorageMaxFileSizeBytes); | |
| 76 } | |
| 77 | 74 |
| 78 bool Send(IPC::Message* message) override { return sink_->Send(message); } | 75 bool Send(IPC::Message* message) override { return sink_->Send(message); } |
| 79 | 76 |
| 80 void ShutdownForBadMessage() override { shutdown_for_bad_message_ = true; } | 77 void ShutdownForBadMessage() override { shutdown_for_bad_message_ = true; } |
| 81 | 78 |
| 82 bool shutdown_for_bad_message_ = false; | 79 bool shutdown_for_bad_message_ = false; |
| 83 | 80 |
| 84 protected: | 81 protected: |
| 85 ~TestableBlobDispatcherHost() override {} | 82 ~TestableBlobDispatcherHost() override {} |
| 86 | 83 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 105 ~BlobDispatcherHostTest() override {} | 102 ~BlobDispatcherHostTest() override {} |
| 106 | 103 |
| 107 void SetUp() override { | 104 void SetUp() override { |
| 108 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | 105 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
| 109 if (!command_line->HasSwitch(switches::kDisableKillAfterBadIPC)) { | 106 if (!command_line->HasSwitch(switches::kDisableKillAfterBadIPC)) { |
| 110 command_line->AppendSwitch(switches::kDisableKillAfterBadIPC); | 107 command_line->AppendSwitch(switches::kDisableKillAfterBadIPC); |
| 111 } | 108 } |
| 112 // We run the run loop to initialize the chrome blob storage context. | 109 // We run the run loop to initialize the chrome blob storage context. |
| 113 base::RunLoop().RunUntilIdle(); | 110 base::RunLoop().RunUntilIdle(); |
| 114 context_ = chrome_blob_storage_context_->context(); | 111 context_ = chrome_blob_storage_context_->context(); |
| 115 DCHECK(context_); | 112 ASSERT_TRUE(context_); |
| 113 |
| 114 storage::BlobStorageLimits limits; |
| 115 limits.max_ipc_memory_size = kTestBlobStorageIPCThresholdBytes; |
| 116 limits.max_shared_memory_size = kTestBlobStorageMaxSharedMemoryBytes; |
| 117 limits.max_blob_in_memory_space = kTestBlobStorageMaxBlobMemorySize; |
| 118 limits.max_blob_disk_space = kTestBlobStorageMaxDiskSpace; |
| 119 limits.min_page_file_size = kTestBlobStorageMinFileSizeBytes; |
| 120 limits.max_file_size = kTestBlobStorageMaxFileSizeBytes; |
| 121 context_->mutable_memory_controller()->set_limits_for_testing(limits); |
| 116 } | 122 } |
| 117 | 123 |
| 118 void ExpectBlobNotExist(const std::string& id) { | 124 void ExpectBlobNotExist(const std::string& id) { |
| 119 EXPECT_FALSE(context_->registry().HasEntry(id)); | 125 EXPECT_FALSE(context_->registry().HasEntry(id)); |
| 120 EXPECT_FALSE(host_->IsInUseInHost(id)); | 126 EXPECT_FALSE(host_->IsInUseInHost(id)); |
| 121 EXPECT_FALSE(IsBeingBuiltInHost(id)); | 127 EXPECT_FALSE(IsBeingBuiltInHost(id)); |
| 122 } | 128 } |
| 123 | 129 |
| 124 void AsyncShortcutBlobTransfer(const std::string& id) { | 130 void AsyncShortcutBlobTransfer(const std::string& id) { |
| 125 sink_.ClearMessages(); | 131 sink_.ClearMessages(); |
| 126 ExpectBlobNotExist(id); | 132 ExpectBlobNotExist(id); |
| 127 host_->OnRegisterBlobUUID(id, std::string(kContentType), | |
| 128 std::string(kContentDisposition), | |
| 129 std::set<std::string>()); | |
| 130 EXPECT_FALSE(host_->shutdown_for_bad_message_); | |
| 131 DataElement element; | 133 DataElement element; |
| 132 element.SetToBytes(kData, kDataSize); | 134 element.SetToBytes(kData, kDataSize); |
| 133 std::vector<DataElement> elements = {element}; | 135 std::vector<DataElement> elements = {element}; |
| 134 host_->OnStartBuildingBlob(id, elements); | 136 host_->OnRegisterBlob(id, std::string(kContentType), |
| 137 std::string(kContentDisposition), elements); |
| 135 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 138 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
| 136 ExpectDone(id); | 139 ExpectDone(id); |
| 137 sink_.ClearMessages(); | 140 sink_.ClearMessages(); |
| 138 } | 141 } |
| 139 | 142 |
| 140 void AsyncBlobTransfer(const std::string& id) { | 143 void AsyncBlobTransfer(const std::string& id) { |
| 141 sink_.ClearMessages(); | 144 sink_.ClearMessages(); |
| 142 ExpectBlobNotExist(id); | 145 ExpectBlobNotExist(id); |
| 143 host_->OnRegisterBlobUUID(id, std::string(kContentType), | |
| 144 std::string(kContentDisposition), | |
| 145 std::set<std::string>()); | |
| 146 EXPECT_FALSE(host_->shutdown_for_bad_message_); | |
| 147 DataElement element; | 146 DataElement element; |
| 148 element.SetToBytesDescription(kDataSize); | 147 element.SetToBytesDescription(kDataSize); |
| 149 std::vector<DataElement> elements = {element}; | 148 std::vector<DataElement> elements = {element}; |
| 150 host_->OnStartBuildingBlob(id, elements); | 149 host_->OnRegisterBlob(id, std::string(kContentType), |
| 150 std::string(kContentDisposition), elements); |
| 151 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 151 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
| 152 | 152 |
| 153 // Expect our request. | 153 // Expect our request. |
| 154 std::vector<BlobItemBytesRequest> expected_requests = { | 154 std::vector<BlobItemBytesRequest> expected_requests = { |
| 155 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; | 155 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; |
| 156 ExpectRequest(id, expected_requests); | 156 ExpectRequest(id, expected_requests); |
| 157 sink_.ClearMessages(); | 157 sink_.ClearMessages(); |
| 158 | 158 |
| 159 // Send results; | 159 // Send results; |
| 160 BlobItemBytesResponse response(0); | 160 BlobItemBytesResponse response(0); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 180 const DataElement& actual = snapshot->items()[i]->data_element(); | 180 const DataElement& actual = snapshot->items()[i]->data_element(); |
| 181 EXPECT_EQ(expected, actual); | 181 EXPECT_EQ(expected, actual); |
| 182 } | 182 } |
| 183 EXPECT_EQ(data.size(), snapshot->items().size()); | 183 EXPECT_EQ(data.size(), snapshot->items().size()); |
| 184 } | 184 } |
| 185 | 185 |
| 186 void ExpectRequest( | 186 void ExpectRequest( |
| 187 const std::string& expected_uuid, | 187 const std::string& expected_uuid, |
| 188 const std::vector<BlobItemBytesRequest>& expected_requests) { | 188 const std::vector<BlobItemBytesRequest>& expected_requests) { |
| 189 EXPECT_FALSE( | 189 EXPECT_FALSE( |
| 190 sink_.GetFirstMessageMatching(BlobStorageMsg_DoneBuildingBlob::ID)); | 190 sink_.GetFirstMessageMatching(BlobStorageMsg_SendBlobStatus::ID)); |
| 191 EXPECT_FALSE( | |
| 192 sink_.GetFirstMessageMatching(BlobStorageMsg_CancelBuildingBlob::ID)); | |
| 193 const IPC::Message* message = | 191 const IPC::Message* message = |
| 194 sink_.GetUniqueMessageMatching(BlobStorageMsg_RequestMemoryItem::ID); | 192 sink_.GetUniqueMessageMatching(BlobStorageMsg_RequestMemoryItem::ID); |
| 195 ASSERT_TRUE(message); | 193 ASSERT_TRUE(message); |
| 196 std::tuple<std::string, std::vector<storage::BlobItemBytesRequest>, | 194 std::tuple<std::string, std::vector<storage::BlobItemBytesRequest>, |
| 197 std::vector<base::SharedMemoryHandle>, | 195 std::vector<base::SharedMemoryHandle>, |
| 198 std::vector<IPC::PlatformFileForTransit>> | 196 std::vector<IPC::PlatformFileForTransit>> |
| 199 args; | 197 args; |
| 200 BlobStorageMsg_RequestMemoryItem::Read(message, &args); | 198 BlobStorageMsg_RequestMemoryItem::Read(message, &args); |
| 201 EXPECT_EQ(expected_uuid, std::get<0>(args)); | 199 EXPECT_EQ(expected_uuid, std::get<0>(args)); |
| 202 std::vector<BlobItemBytesRequest> requests = std::get<1>(args); | 200 std::vector<BlobItemBytesRequest> requests = std::get<1>(args); |
| 203 ASSERT_EQ(requests.size(), expected_requests.size()); | 201 ASSERT_EQ(requests.size(), expected_requests.size()); |
| 204 for (size_t i = 0; i < expected_requests.size(); ++i) { | 202 for (size_t i = 0; i < expected_requests.size(); ++i) { |
| 205 EXPECT_EQ(expected_requests[i], requests[i]); | 203 EXPECT_EQ(expected_requests[i], requests[i]); |
| 206 } | 204 } |
| 207 } | 205 } |
| 208 | 206 |
| 209 void ExpectRequestWithSharedMemoryHandles( | 207 void ExpectRequestWithSharedMemoryHandles( |
| 210 const std::string& expected_uuid, | 208 const std::string& expected_uuid, |
| 211 const std::vector<BlobItemBytesRequest>& expected_requests, | 209 const std::vector<BlobItemBytesRequest>& expected_requests, |
| 212 std::vector<base::SharedMemoryHandle>* shared_memory_handles) { | 210 std::vector<base::SharedMemoryHandle>* shared_memory_handles) { |
| 213 EXPECT_FALSE( | 211 EXPECT_FALSE( |
| 214 sink_.GetFirstMessageMatching(BlobStorageMsg_DoneBuildingBlob::ID)); | 212 sink_.GetFirstMessageMatching(BlobStorageMsg_SendBlobStatus::ID)); |
| 215 EXPECT_FALSE( | |
| 216 sink_.GetFirstMessageMatching(BlobStorageMsg_CancelBuildingBlob::ID)); | |
| 217 const IPC::Message* message = | 213 const IPC::Message* message = |
| 218 sink_.GetUniqueMessageMatching(BlobStorageMsg_RequestMemoryItem::ID); | 214 sink_.GetUniqueMessageMatching(BlobStorageMsg_RequestMemoryItem::ID); |
| 219 ASSERT_TRUE(message); | 215 ASSERT_TRUE(message); |
| 220 std::tuple<std::string, std::vector<storage::BlobItemBytesRequest>, | 216 std::tuple<std::string, std::vector<storage::BlobItemBytesRequest>, |
| 221 std::vector<base::SharedMemoryHandle>, | 217 std::vector<base::SharedMemoryHandle>, |
| 222 std::vector<IPC::PlatformFileForTransit>> | 218 std::vector<IPC::PlatformFileForTransit>> |
| 223 args; | 219 args; |
| 224 BlobStorageMsg_RequestMemoryItem::Read(message, &args); | 220 BlobStorageMsg_RequestMemoryItem::Read(message, &args); |
| 225 EXPECT_EQ(expected_uuid, std::get<0>(args)); | 221 EXPECT_EQ(expected_uuid, std::get<0>(args)); |
| 226 std::vector<BlobItemBytesRequest> requests = std::get<1>(args); | 222 std::vector<BlobItemBytesRequest> requests = std::get<1>(args); |
| 227 ASSERT_EQ(requests.size(), expected_requests.size()); | 223 ASSERT_EQ(requests.size(), expected_requests.size()); |
| 228 for (size_t i = 0; i < expected_requests.size(); ++i) { | 224 for (size_t i = 0; i < expected_requests.size(); ++i) { |
| 229 EXPECT_EQ(expected_requests[i], requests[i]); | 225 EXPECT_EQ(expected_requests[i], requests[i]); |
| 230 } | 226 } |
| 231 *shared_memory_handles = std::move(std::get<2>(args)); | 227 *shared_memory_handles = std::move(std::get<2>(args)); |
| 232 } | 228 } |
| 233 | 229 |
| 234 void ExpectCancel(const std::string& expected_uuid, | 230 void ExpectCancel(const std::string& expected_uuid, BlobStatus code) { |
| 235 IPCBlobCreationCancelCode code) { | |
| 236 EXPECT_FALSE( | 231 EXPECT_FALSE( |
| 237 sink_.GetFirstMessageMatching(BlobStorageMsg_RequestMemoryItem::ID)); | 232 sink_.GetFirstMessageMatching(BlobStorageMsg_RequestMemoryItem::ID)); |
| 238 EXPECT_FALSE( | |
| 239 sink_.GetFirstMessageMatching(BlobStorageMsg_DoneBuildingBlob::ID)); | |
| 240 const IPC::Message* message = | 233 const IPC::Message* message = |
| 241 sink_.GetUniqueMessageMatching(BlobStorageMsg_CancelBuildingBlob::ID); | 234 sink_.GetUniqueMessageMatching(BlobStorageMsg_SendBlobStatus::ID); |
| 242 ASSERT_TRUE(message); | 235 ASSERT_TRUE(message); |
| 243 std::tuple<std::string, IPCBlobCreationCancelCode> args; | 236 std::tuple<std::string, BlobStatus> args; |
| 244 BlobStorageMsg_CancelBuildingBlob::Read(message, &args); | 237 BlobStorageMsg_SendBlobStatus::Read(message, &args); |
| 245 EXPECT_EQ(expected_uuid, std::get<0>(args)); | 238 EXPECT_EQ(expected_uuid, std::get<0>(args)); |
| 246 EXPECT_EQ(code, std::get<1>(args)); | 239 EXPECT_EQ(code, std::get<1>(args)); |
| 247 } | 240 } |
| 248 | 241 |
| 249 void ExpectDone(const std::string& expected_uuid) { | 242 void ExpectDone(const std::string& expected_uuid) { |
| 250 EXPECT_FALSE( | 243 EXPECT_FALSE( |
| 251 sink_.GetFirstMessageMatching(BlobStorageMsg_RequestMemoryItem::ID)); | 244 sink_.GetFirstMessageMatching(BlobStorageMsg_RequestMemoryItem::ID)); |
| 252 EXPECT_FALSE( | |
| 253 sink_.GetFirstMessageMatching(BlobStorageMsg_CancelBuildingBlob::ID)); | |
| 254 const IPC::Message* message = | 245 const IPC::Message* message = |
| 255 sink_.GetUniqueMessageMatching(BlobStorageMsg_DoneBuildingBlob::ID); | 246 sink_.GetUniqueMessageMatching(BlobStorageMsg_SendBlobStatus::ID); |
| 256 std::tuple<std::string> args; | 247 ASSERT_TRUE(message); |
| 257 BlobStorageMsg_DoneBuildingBlob::Read(message, &args); | 248 std::tuple<std::string, BlobStatus> args; |
| 249 BlobStorageMsg_SendBlobStatus::Read(message, &args); |
| 258 EXPECT_EQ(expected_uuid, std::get<0>(args)); | 250 EXPECT_EQ(expected_uuid, std::get<0>(args)); |
| 251 EXPECT_EQ(BlobStatus::DONE, std::get<1>(args)); |
| 259 } | 252 } |
| 260 | 253 |
| 261 bool IsBeingBuiltInHost(const std::string& uuid) { | 254 bool IsBeingBuiltInHost(const std::string& uuid) { |
| 262 return host_->async_builder_.IsBeingBuilt(uuid); | 255 return host_->transport_host_.IsBeingBuilt(uuid); |
| 256 } |
| 257 |
| 258 bool IsBeingBuiltInContext(const std::string& uuid) { |
| 259 return BlobStatusIsPending(context_->GetBlobStatus(uuid)); |
| 263 } | 260 } |
| 264 | 261 |
| 265 IPC::TestSink sink_; | 262 IPC::TestSink sink_; |
| 266 TestBrowserThreadBundle browser_thread_bundle_; | 263 TestBrowserThreadBundle browser_thread_bundle_; |
| 267 TestBrowserContext browser_context_; | 264 TestBrowserContext browser_context_; |
| 268 ChromeBlobStorageContext* chrome_blob_storage_context_; | 265 ChromeBlobStorageContext* chrome_blob_storage_context_; |
| 269 BlobStorageContext* context_ = nullptr; | 266 BlobStorageContext* context_ = nullptr; |
| 270 scoped_refptr<storage::FileSystemContext> file_system_context_; | 267 scoped_refptr<storage::FileSystemContext> file_system_context_; |
| 271 scoped_refptr<TestableBlobDispatcherHost> host_; | 268 scoped_refptr<TestableBlobDispatcherHost> host_; |
| 272 }; | 269 }; |
| 273 | 270 |
| 274 TEST_F(BlobDispatcherHostTest, EmptyUUIDs) { | 271 TEST_F(BlobDispatcherHostTest, EmptyUUIDs) { |
| 275 host_->OnRegisterBlobUUID("", "", "", std::set<std::string>()); | 272 host_->OnRegisterBlob("", "", "", std::vector<DataElement>()); |
| 276 ExpectAndResetBadMessage(); | |
| 277 host_->OnStartBuildingBlob("", std::vector<DataElement>()); | |
| 278 ExpectAndResetBadMessage(); | 273 ExpectAndResetBadMessage(); |
| 279 host_->OnMemoryItemResponse("", std::vector<BlobItemBytesResponse>()); | 274 host_->OnMemoryItemResponse("", std::vector<BlobItemBytesResponse>()); |
| 280 ExpectAndResetBadMessage(); | 275 ExpectAndResetBadMessage(); |
| 281 host_->OnCancelBuildingBlob("", IPCBlobCreationCancelCode::UNKNOWN); | 276 host_->OnCancelBuildingBlob("", |
| 277 BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS); |
| 282 ExpectAndResetBadMessage(); | 278 ExpectAndResetBadMessage(); |
| 283 } | 279 } |
| 284 | 280 |
| 285 TEST_F(BlobDispatcherHostTest, Shortcut) { | 281 TEST_F(BlobDispatcherHostTest, Shortcut) { |
| 286 const std::string kId = "uuid1"; | 282 const std::string kId = "uuid1"; |
| 287 AsyncShortcutBlobTransfer(kId); | 283 AsyncShortcutBlobTransfer(kId); |
| 288 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 284 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
| 289 std::unique_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId); | 285 std::unique_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId); |
| 290 EXPECT_TRUE(handle); | 286 EXPECT_TRUE(handle); |
| 291 | 287 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 304 | 300 |
| 305 DataElement expected; | 301 DataElement expected; |
| 306 expected.SetToBytes(kData, kDataSize); | 302 expected.SetToBytes(kData, kDataSize); |
| 307 std::vector<DataElement> elements = {expected}; | 303 std::vector<DataElement> elements = {expected}; |
| 308 ExpectHandleEqualsData(handle.get(), elements); | 304 ExpectHandleEqualsData(handle.get(), elements); |
| 309 } | 305 } |
| 310 | 306 |
| 311 TEST_F(BlobDispatcherHostTest, MultipleTransfers) { | 307 TEST_F(BlobDispatcherHostTest, MultipleTransfers) { |
| 312 const std::string kId = "uuid"; | 308 const std::string kId = "uuid"; |
| 313 const int kNumIters = 10; | 309 const int kNumIters = 10; |
| 310 sink_.ClearMessages(); |
| 314 for (int i = 0; i < kNumIters; i++) { | 311 for (int i = 0; i < kNumIters; i++) { |
| 315 std::string id = kId; | 312 std::string id = kId; |
| 316 id += ('0' + i); | 313 id += ('0' + i); |
| 317 ExpectBlobNotExist(id); | 314 ExpectBlobNotExist(id); |
| 318 host_->OnRegisterBlobUUID(id, std::string(kContentType), | |
| 319 std::string(kContentDisposition), | |
| 320 std::set<std::string>()); | |
| 321 EXPECT_FALSE(host_->shutdown_for_bad_message_); | |
| 322 } | |
| 323 sink_.ClearMessages(); | |
| 324 for (int i = 0; i < kNumIters; i++) { | |
| 325 std::string id = kId; | |
| 326 id += ('0' + i); | |
| 327 DataElement element; | 315 DataElement element; |
| 328 element.SetToBytesDescription(kDataSize); | 316 element.SetToBytesDescription(kDataSize); |
| 329 std::vector<DataElement> elements = {element}; | 317 std::vector<DataElement> elements = {element}; |
| 330 host_->OnStartBuildingBlob(id, elements); | 318 host_->OnRegisterBlob(id, std::string(kContentType), |
| 319 std::string(kContentDisposition), elements); |
| 331 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 320 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
| 332 // Expect our request. | 321 // Expect our request. |
| 333 std::vector<BlobItemBytesRequest> expected_requests = { | 322 std::vector<BlobItemBytesRequest> expected_requests = { |
| 334 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; | 323 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; |
| 335 ExpectRequest(id, expected_requests); | 324 ExpectRequest(id, expected_requests); |
| 336 sink_.ClearMessages(); | 325 sink_.ClearMessages(); |
| 337 } | 326 } |
| 338 for (int i = 0; i < kNumIters; i++) { | 327 for (int i = 0; i < kNumIters; i++) { |
| 339 std::string id = kId; | 328 std::string id = kId; |
| 340 id += ('0' + i); | 329 id += ('0' + i); |
| 341 // Send results; | 330 // Send results; |
| 342 BlobItemBytesResponse response(0); | 331 BlobItemBytesResponse response(0); |
| 343 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); | 332 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); |
| 344 std::vector<BlobItemBytesResponse> responses = {response}; | 333 std::vector<BlobItemBytesResponse> responses = {response}; |
| 345 host_->OnMemoryItemResponse(id, responses); | 334 host_->OnMemoryItemResponse(id, responses); |
| 346 ExpectDone(id); | 335 ExpectDone(id); |
| 347 sink_.ClearMessages(); | 336 sink_.ClearMessages(); |
| 348 } | 337 } |
| 349 } | 338 } |
| 350 | 339 |
| 351 TEST_F(BlobDispatcherHostTest, SharedMemoryTransfer) { | 340 TEST_F(BlobDispatcherHostTest, SharedMemoryTransfer) { |
| 352 const std::string kId = "uuid1"; | 341 const std::string kId = "uuid1"; |
| 353 const size_t kLargeSize = kTestBlobStorageMaxSharedMemoryBytes * 2; | 342 const size_t kLargeSize = kTestBlobStorageMaxSharedMemoryBytes * 2; |
| 354 std::vector<base::SharedMemoryHandle> shared_memory_handles; | 343 std::vector<base::SharedMemoryHandle> shared_memory_handles; |
| 355 | 344 |
| 356 ExpectBlobNotExist(kId); | 345 ExpectBlobNotExist(kId); |
| 357 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 346 DataElement element; |
| 358 std::string(kContentDisposition), | 347 element.SetToBytesDescription(kLargeSize); |
| 359 std::set<std::string>()); | 348 std::vector<DataElement> elements = {element}; |
| 349 host_->OnRegisterBlob(kId, std::string(kContentType), |
| 350 std::string(kContentDisposition), elements); |
| 351 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
| 360 | 352 |
| 361 // Grab the handle. | 353 // Grab the handle. |
| 362 std::unique_ptr<BlobDataHandle> blob_data_handle = | 354 std::unique_ptr<BlobDataHandle> blob_data_handle = |
| 363 context_->GetBlobDataFromUUID(kId); | 355 context_->GetBlobDataFromUUID(kId); |
| 364 bool built = false; | 356 bool built = false; |
| 365 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN; | 357 BlobStatus error_code = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS; |
| 366 blob_data_handle->RunOnConstructionComplete( | 358 blob_data_handle->RunOnConstructionComplete( |
| 367 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); | 359 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); |
| 368 EXPECT_FALSE(built); | 360 EXPECT_FALSE(built); |
| 369 | 361 |
| 370 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 362 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
| 371 DataElement element; | |
| 372 element.SetToBytesDescription(kLargeSize); | |
| 373 std::vector<DataElement> elements = {element}; | |
| 374 host_->OnStartBuildingBlob(kId, elements); | |
| 375 EXPECT_FALSE(host_->shutdown_for_bad_message_); | |
| 376 | 363 |
| 377 // Expect our first request. | 364 // Expect our first request. |
| 378 std::vector<BlobItemBytesRequest> expected_requests = { | 365 std::vector<BlobItemBytesRequest> expected_requests = { |
| 379 BlobItemBytesRequest::CreateSharedMemoryRequest( | 366 BlobItemBytesRequest::CreateSharedMemoryRequest( |
| 380 0 /* request_number */, 0 /* renderer_item_index */, | 367 0 /* request_number */, 0 /* renderer_item_index */, |
| 381 0 /* renderer_item_offset */, | 368 0 /* renderer_item_offset */, |
| 382 static_cast<uint64_t>( | 369 static_cast<uint64_t>( |
| 383 kTestBlobStorageMaxSharedMemoryBytes) /* size */, | 370 kTestBlobStorageMaxSharedMemoryBytes) /* size */, |
| 384 0 /* handle_index */, 0 /* handle_offset */)}; | 371 0 /* handle_index */, 0 /* handle_offset */)}; |
| 385 ExpectRequestWithSharedMemoryHandles(kId, expected_requests, | 372 ExpectRequestWithSharedMemoryHandles(kId, expected_requests, |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 elements = {expected}; | 427 elements = {expected}; |
| 441 std::memset(expected.mutable_bytes(), 'Z', kLargeSize / 2); | 428 std::memset(expected.mutable_bytes(), 'Z', kLargeSize / 2); |
| 442 elements.push_back(expected); | 429 elements.push_back(expected); |
| 443 ExpectHandleEqualsData(handle.get(), elements); | 430 ExpectHandleEqualsData(handle.get(), elements); |
| 444 } | 431 } |
| 445 | 432 |
| 446 TEST_F(BlobDispatcherHostTest, OnCancelBuildingBlob) { | 433 TEST_F(BlobDispatcherHostTest, OnCancelBuildingBlob) { |
| 447 const std::string kId("id"); | 434 const std::string kId("id"); |
| 448 // We ignore blobs that are unknown, as it could have been cancelled earlier | 435 // We ignore blobs that are unknown, as it could have been cancelled earlier |
| 449 // and the renderer didn't know about it yet. | 436 // and the renderer didn't know about it yet. |
| 450 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN); | 437 host_->OnCancelBuildingBlob(kId, |
| 438 BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS); |
| 451 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 439 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
| 452 | 440 |
| 453 // Start building blob. | 441 // Start building blob. |
| 454 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | |
| 455 std::string(kContentDisposition), | |
| 456 std::set<std::string>()); | |
| 457 EXPECT_FALSE(host_->shutdown_for_bad_message_); | |
| 458 DataElement element; | 442 DataElement element; |
| 459 element.SetToBytesDescription(kDataSize); | 443 element.SetToBytesDescription(kDataSize); |
| 460 std::vector<DataElement> elements = {element}; | 444 std::vector<DataElement> elements = {element}; |
| 461 host_->OnStartBuildingBlob(kId, elements); | 445 host_->OnRegisterBlob(kId, std::string(kContentType), |
| 446 std::string(kContentDisposition), elements); |
| 462 // It should have requested memory here. | 447 // It should have requested memory here. |
| 463 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 448 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
| 464 sink_.ClearMessages(); | 449 sink_.ClearMessages(); |
| 465 | 450 |
| 466 // Cancel in middle of construction. | 451 // Cancel in middle of construction. |
| 467 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN); | 452 host_->OnCancelBuildingBlob(kId, |
| 453 BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS); |
| 468 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 454 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
| 469 EXPECT_TRUE(host_->IsInUseInHost(kId)); | 455 EXPECT_TRUE(host_->IsInUseInHost(kId)); |
| 470 EXPECT_FALSE(IsBeingBuiltInHost(kId)); | 456 EXPECT_FALSE(IsBeingBuiltInHost(kId)); |
| 471 // Check that's it's broken. | 457 // Check that's it's broken. |
| 472 std::unique_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId); | 458 std::unique_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId); |
| 473 EXPECT_TRUE(handle->IsBroken()); | 459 EXPECT_TRUE(handle->IsBroken()); |
| 474 handle.reset(); | 460 handle.reset(); |
| 475 base::RunLoop().RunUntilIdle(); | 461 base::RunLoop().RunUntilIdle(); |
| 476 | 462 |
| 477 // Get rid of it in the host. | 463 // Get rid of it in the host. |
| 478 host_->OnDecrementBlobRefCount(kId); | 464 host_->OnDecrementBlobRefCount(kId); |
| 479 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 465 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
| 480 ExpectBlobNotExist(kId); | 466 ExpectBlobNotExist(kId); |
| 481 | 467 |
| 482 // Create blob again to verify we don't have any old construction state lying | 468 // Create blob again to verify we don't have any old construction state lying |
| 483 // around. | 469 // around. |
| 484 AsyncBlobTransfer(kId); | 470 AsyncBlobTransfer(kId); |
| 485 | 471 |
| 486 // Check data. | 472 // Check data. |
| 487 handle = context_->GetBlobDataFromUUID(kId); | 473 handle = context_->GetBlobDataFromUUID(kId); |
| 488 EXPECT_TRUE(handle); | 474 EXPECT_TRUE(handle); |
| 489 DataElement expected; | 475 DataElement expected; |
| 490 expected.SetToBytes(kData, kDataSize); | 476 expected.SetToBytes(kData, kDataSize); |
| 491 std::vector<DataElement> expecteds = {expected}; | 477 std::vector<DataElement> expecteds = {expected}; |
| 492 ExpectHandleEqualsData(handle.get(), expecteds); | 478 ExpectHandleEqualsData(handle.get(), expecteds); |
| 493 | 479 |
| 494 // Verify we can't cancel after the fact. | 480 // Verify we can't cancel after the fact. |
| 495 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN); | 481 host_->OnCancelBuildingBlob(kId, |
| 482 BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS); |
| 496 ExpectAndResetBadMessage(); | 483 ExpectAndResetBadMessage(); |
| 497 } | 484 } |
| 498 | 485 |
| 499 TEST_F(BlobDispatcherHostTest, BlobDataWithHostDeletion) { | 486 TEST_F(BlobDispatcherHostTest, BlobDataWithHostDeletion) { |
| 500 // Build up a basic blob. | 487 // Build up a basic blob. |
| 501 const std::string kId("id"); | 488 const std::string kId("id"); |
| 502 AsyncShortcutBlobTransfer(kId); | 489 AsyncShortcutBlobTransfer(kId); |
| 503 std::unique_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId); | 490 std::unique_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId); |
| 504 EXPECT_TRUE(handle); | 491 EXPECT_TRUE(handle); |
| 505 | 492 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 517 base::RunLoop().RunUntilIdle(); | 504 base::RunLoop().RunUntilIdle(); |
| 518 | 505 |
| 519 handle = context_->GetBlobDataFromUUID(kId); | 506 handle = context_->GetBlobDataFromUUID(kId); |
| 520 EXPECT_FALSE(handle); | 507 EXPECT_FALSE(handle); |
| 521 } | 508 } |
| 522 | 509 |
| 523 TEST_F(BlobDispatcherHostTest, BlobReferenceWhileConstructing) { | 510 TEST_F(BlobDispatcherHostTest, BlobReferenceWhileConstructing) { |
| 524 const std::string kId("id"); | 511 const std::string kId("id"); |
| 525 | 512 |
| 526 // Start building blob. | 513 // Start building blob. |
| 527 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 514 DataElement element; |
| 528 std::string(kContentDisposition), | 515 element.SetToBytesDescription(kDataSize); |
| 529 std::set<std::string>()); | 516 std::vector<DataElement> elements = {element}; |
| 517 host_->OnRegisterBlob(kId, std::string(kContentType), |
| 518 std::string(kContentDisposition), elements); |
| 530 | 519 |
| 531 // Grab the handle. | 520 // Grab the handle. |
| 532 std::unique_ptr<BlobDataHandle> blob_data_handle = | 521 std::unique_ptr<BlobDataHandle> blob_data_handle = |
| 533 context_->GetBlobDataFromUUID(kId); | 522 context_->GetBlobDataFromUUID(kId); |
| 534 EXPECT_TRUE(blob_data_handle); | 523 EXPECT_TRUE(blob_data_handle); |
| 535 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); | 524 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); |
| 536 bool built = false; | 525 bool built = false; |
| 537 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN; | 526 BlobStatus error_code = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS; |
| 538 blob_data_handle->RunOnConstructionComplete( | 527 blob_data_handle->RunOnConstructionComplete( |
| 539 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); | 528 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); |
| 540 | 529 |
| 541 // Continue building. | |
| 542 DataElement element; | |
| 543 element.SetToBytesDescription(kDataSize); | |
| 544 std::vector<DataElement> elements = {element}; | |
| 545 host_->OnStartBuildingBlob(kId, elements); | |
| 546 sink_.ClearMessages(); | 530 sink_.ClearMessages(); |
| 547 | 531 |
| 548 // Send data. | 532 // Send data. |
| 549 BlobItemBytesResponse response(0); | 533 BlobItemBytesResponse response(0); |
| 550 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); | 534 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); |
| 551 std::vector<BlobItemBytesResponse> responses = {response}; | 535 std::vector<BlobItemBytesResponse> responses = {response}; |
| 552 sink_.ClearMessages(); | 536 sink_.ClearMessages(); |
| 553 host_->OnMemoryItemResponse(kId, responses); | 537 host_->OnMemoryItemResponse(kId, responses); |
| 554 | 538 |
| 555 ExpectDone(kId); | 539 ExpectDone(kId); |
| 556 base::RunLoop().RunUntilIdle(); | 540 base::RunLoop().RunUntilIdle(); |
| 557 EXPECT_TRUE(built) << "Error code: " << static_cast<int>(error_code); | 541 EXPECT_TRUE(built) << "Error code: " << static_cast<int>(error_code); |
| 558 } | 542 } |
| 559 | 543 |
| 560 TEST_F(BlobDispatcherHostTest, BlobReferenceWhileShortcutConstructing) { | |
| 561 const std::string kId("id"); | |
| 562 | |
| 563 // Start building blob. | |
| 564 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | |
| 565 std::string(kContentDisposition), | |
| 566 std::set<std::string>()); | |
| 567 | |
| 568 // Grab the handle. | |
| 569 std::unique_ptr<BlobDataHandle> blob_data_handle = | |
| 570 context_->GetBlobDataFromUUID(kId); | |
| 571 EXPECT_TRUE(blob_data_handle); | |
| 572 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); | |
| 573 bool built = false; | |
| 574 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN; | |
| 575 blob_data_handle->RunOnConstructionComplete( | |
| 576 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); | |
| 577 | |
| 578 // Continue building. | |
| 579 DataElement element; | |
| 580 element.SetToBytes(kData, kDataSize); | |
| 581 std::vector<DataElement> elements = {element}; | |
| 582 host_->OnStartBuildingBlob(kId, elements); | |
| 583 ExpectDone(kId); | |
| 584 base::RunLoop().RunUntilIdle(); | |
| 585 EXPECT_TRUE(built) << "Error code: " << static_cast<int>(error_code); | |
| 586 } | |
| 587 | |
| 588 TEST_F(BlobDispatcherHostTest, BlobReferenceWhileConstructingCancelled) { | 544 TEST_F(BlobDispatcherHostTest, BlobReferenceWhileConstructingCancelled) { |
| 589 const std::string kId("id"); | 545 const std::string kId("id"); |
| 590 | 546 |
| 591 // Start building blob. | 547 // Start building blob. |
| 592 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 548 DataElement element; |
| 593 std::string(kContentDisposition), | 549 element.SetToBytesDescription(kDataSize); |
| 594 std::set<std::string>()); | 550 std::vector<DataElement> elements = {element}; |
| 551 host_->OnRegisterBlob(kId, std::string(kContentType), |
| 552 std::string(kContentDisposition), elements); |
| 595 | 553 |
| 596 // Grab the handle. | 554 // Grab the handle. |
| 597 std::unique_ptr<BlobDataHandle> blob_data_handle = | 555 std::unique_ptr<BlobDataHandle> blob_data_handle = |
| 598 context_->GetBlobDataFromUUID(kId); | 556 context_->GetBlobDataFromUUID(kId); |
| 599 EXPECT_TRUE(blob_data_handle); | 557 EXPECT_TRUE(blob_data_handle); |
| 600 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); | 558 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); |
| 601 bool built = true; | 559 bool built = true; |
| 602 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN; | 560 BlobStatus error_code = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS; |
| 603 blob_data_handle->RunOnConstructionComplete( | 561 blob_data_handle->RunOnConstructionComplete( |
| 604 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); | 562 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); |
| 605 | 563 |
| 606 // Cancel in middle of construction. | 564 // Cancel in middle of construction. |
| 607 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN); | 565 host_->OnCancelBuildingBlob(kId, |
| 566 BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS); |
| 608 base::RunLoop().RunUntilIdle(); | 567 base::RunLoop().RunUntilIdle(); |
| 609 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 568 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
| 610 EXPECT_TRUE(host_->IsInUseInHost(kId)); | 569 EXPECT_TRUE(host_->IsInUseInHost(kId)); |
| 611 EXPECT_FALSE(IsBeingBuiltInHost(kId)); | 570 EXPECT_FALSE(IsBeingBuiltInHost(kId)); |
| 612 EXPECT_TRUE(blob_data_handle->IsBroken()); | 571 EXPECT_TRUE(blob_data_handle->IsBroken()); |
| 613 EXPECT_FALSE(built); | 572 EXPECT_FALSE(built); |
| 614 EXPECT_EQ(IPCBlobCreationCancelCode::UNKNOWN, error_code); | 573 EXPECT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS, error_code); |
| 615 error_code = IPCBlobCreationCancelCode::UNKNOWN; | 574 error_code = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS; |
| 616 built = true; | 575 built = true; |
| 617 blob_data_handle->RunOnConstructionComplete( | 576 blob_data_handle->RunOnConstructionComplete( |
| 618 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); | 577 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); |
| 619 EXPECT_FALSE(built); | 578 EXPECT_FALSE(built); |
| 620 EXPECT_EQ(IPCBlobCreationCancelCode::UNKNOWN, error_code); | 579 EXPECT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS, error_code); |
| 621 | 580 |
| 622 // Remove it. | 581 // Remove it. |
| 623 blob_data_handle.reset(); | 582 blob_data_handle.reset(); |
| 624 base::RunLoop().RunUntilIdle(); | 583 base::RunLoop().RunUntilIdle(); |
| 625 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 584 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
| 626 host_->OnDecrementBlobRefCount(kId); | 585 host_->OnDecrementBlobRefCount(kId); |
| 627 ExpectBlobNotExist(kId); | 586 ExpectBlobNotExist(kId); |
| 628 } | 587 } |
| 629 | 588 |
| 630 TEST_F(BlobDispatcherHostTest, DecrementRefAfterRegister) { | |
| 631 const std::string kId("id"); | |
| 632 // Decrement the refcount while building (renderer blob gc'd before | |
| 633 // construction was completed). | |
| 634 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | |
| 635 std::string(kContentDisposition), | |
| 636 std::set<std::string>()); | |
| 637 EXPECT_TRUE(context_->registry().HasEntry(kId)); | |
| 638 host_->OnDecrementBlobRefCount(kId); | |
| 639 EXPECT_FALSE(context_->registry().HasEntry(kId)); | |
| 640 EXPECT_FALSE(IsBeingBuiltInHost(kId)); | |
| 641 ExpectCancel(kId, | |
| 642 IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING); | |
| 643 sink_.ClearMessages(); | |
| 644 | |
| 645 // Do the same, but this time grab a handle before we decrement. | |
| 646 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | |
| 647 std::string(kContentDisposition), | |
| 648 std::set<std::string>()); | |
| 649 std::unique_ptr<BlobDataHandle> blob_data_handle = | |
| 650 context_->GetBlobDataFromUUID(kId); | |
| 651 host_->OnDecrementBlobRefCount(kId); | |
| 652 EXPECT_TRUE(context_->registry().HasEntry(kId)); | |
| 653 EXPECT_TRUE(IsBeingBuiltInHost(kId)); | |
| 654 | |
| 655 // Finish up the blob, and verify we got the done message. | |
| 656 DataElement element; | |
| 657 element.SetToBytes(kData, kDataSize); | |
| 658 std::vector<DataElement> elements = {element}; | |
| 659 host_->OnStartBuildingBlob(kId, elements); | |
| 660 EXPECT_FALSE(host_->shutdown_for_bad_message_); | |
| 661 ExpectDone(kId); | |
| 662 sink_.ClearMessages(); | |
| 663 // Get rid of the handle, and verify it's gone. | |
| 664 blob_data_handle.reset(); | |
| 665 base::RunLoop().RunUntilIdle(); | |
| 666 // Check that it's no longer around. | |
| 667 EXPECT_FALSE(context_->registry().HasEntry(kId)); | |
| 668 EXPECT_FALSE(IsBeingBuiltInHost(kId)); | |
| 669 } | |
| 670 | |
| 671 TEST_F(BlobDispatcherHostTest, DecrementRefAfterOnStart) { | 589 TEST_F(BlobDispatcherHostTest, DecrementRefAfterOnStart) { |
| 672 const std::string kId("id"); | 590 const std::string kId("id"); |
| 673 | 591 |
| 674 // Decrement the refcount while building, after we call OnStartBuildlingBlob. | 592 // Decrement the refcount while building, after we call OnStartBuildlingBlob. |
| 675 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | |
| 676 std::string(kContentDisposition), | |
| 677 std::set<std::string>()); | |
| 678 EXPECT_FALSE(host_->shutdown_for_bad_message_); | |
| 679 DataElement element; | 593 DataElement element; |
| 680 element.SetToBytesDescription(kDataSize); | 594 element.SetToBytesDescription(kDataSize); |
| 681 std::vector<DataElement> elements = {element}; | 595 std::vector<DataElement> elements = {element}; |
| 682 host_->OnStartBuildingBlob(kId, elements); | 596 host_->OnRegisterBlob(kId, std::string(kContentType), |
| 597 std::string(kContentDisposition), elements); |
| 683 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 598 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
| 684 | 599 |
| 685 std::vector<BlobItemBytesRequest> expected_requests = { | 600 std::vector<BlobItemBytesRequest> expected_requests = { |
| 686 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; | 601 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; |
| 687 ExpectRequest(kId, expected_requests); | 602 ExpectRequest(kId, expected_requests); |
| 688 sink_.ClearMessages(); | 603 sink_.ClearMessages(); |
| 689 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 604 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
| 690 host_->OnDecrementBlobRefCount(kId); | 605 host_->OnDecrementBlobRefCount(kId); |
| 691 EXPECT_FALSE(context_->registry().HasEntry(kId)); | 606 EXPECT_FALSE(context_->registry().HasEntry(kId)); |
| 692 EXPECT_FALSE(IsBeingBuiltInHost(kId)); | 607 EXPECT_FALSE(IsBeingBuiltInHost(kId)); |
| 693 ExpectCancel(kId, | 608 ExpectCancel(kId, BlobStatus::ERR_BLOB_DEREFERENCED_WHILE_BUILDING); |
| 694 IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING); | |
| 695 sink_.ClearMessages(); | 609 sink_.ClearMessages(); |
| 696 | 610 |
| 697 // 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. |
| 698 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 612 host_->OnRegisterBlob(kId, std::string(kContentType), |
| 699 std::string(kContentDisposition), | 613 std::string(kContentDisposition), elements); |
| 700 std::set<std::string>()); | |
| 701 EXPECT_FALSE(host_->shutdown_for_bad_message_); | |
| 702 host_->OnStartBuildingBlob(kId, elements); | |
| 703 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 614 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
| 704 ExpectRequest(kId, expected_requests); | 615 ExpectRequest(kId, expected_requests); |
| 705 sink_.ClearMessages(); | 616 sink_.ClearMessages(); |
| 706 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 617 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
| 707 // Grab the handle before decrementing. | 618 // Grab the handle before decrementing. |
| 708 std::unique_ptr<BlobDataHandle> blob_data_handle = | 619 std::unique_ptr<BlobDataHandle> blob_data_handle = |
| 709 context_->GetBlobDataFromUUID(kId); | 620 context_->GetBlobDataFromUUID(kId); |
| 710 host_->OnDecrementBlobRefCount(kId); | 621 host_->OnDecrementBlobRefCount(kId); |
| 711 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 622 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
| 712 EXPECT_TRUE(IsBeingBuiltInHost(kId)); | 623 EXPECT_TRUE(IsBeingBuiltInHost(kId)); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 727 base::RunLoop().RunUntilIdle(); | 638 base::RunLoop().RunUntilIdle(); |
| 728 // Check that it's no longer around. | 639 // Check that it's no longer around. |
| 729 EXPECT_FALSE(context_->registry().HasEntry(kId)); | 640 EXPECT_FALSE(context_->registry().HasEntry(kId)); |
| 730 EXPECT_FALSE(IsBeingBuiltInHost(kId)); | 641 EXPECT_FALSE(IsBeingBuiltInHost(kId)); |
| 731 } | 642 } |
| 732 | 643 |
| 733 TEST_F(BlobDispatcherHostTest, DecrementRefAfterOnStartWithHandle) { | 644 TEST_F(BlobDispatcherHostTest, DecrementRefAfterOnStartWithHandle) { |
| 734 const std::string kId("id"); | 645 const std::string kId("id"); |
| 735 // Decrement the refcount while building, after we call | 646 // Decrement the refcount while building, after we call |
| 736 // OnStartBuildlingBlob, except we have another handle. | 647 // OnStartBuildlingBlob, except we have another handle. |
| 737 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 648 DataElement element; |
| 738 std::string(kContentDisposition), | 649 element.SetToBytesDescription(kDataSize); |
| 739 std::set<std::string>()); | 650 std::vector<DataElement> elements = {element}; |
| 651 host_->OnRegisterBlob(kId, std::string(kContentType), |
| 652 std::string(kContentDisposition), elements); |
| 740 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 653 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
| 741 | 654 |
| 742 std::unique_ptr<BlobDataHandle> blob_data_handle = | 655 std::unique_ptr<BlobDataHandle> blob_data_handle = |
| 743 context_->GetBlobDataFromUUID(kId); | 656 context_->GetBlobDataFromUUID(kId); |
| 744 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); | 657 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); |
| 745 bool built = true; | 658 bool built = true; |
| 746 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN; | 659 BlobStatus error_code = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS; |
| 747 blob_data_handle->RunOnConstructionComplete( | 660 blob_data_handle->RunOnConstructionComplete( |
| 748 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); | 661 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); |
| 749 | 662 |
| 750 DataElement element; | |
| 751 element.SetToBytesDescription(kDataSize); | |
| 752 std::vector<DataElement> elements = {element}; | |
| 753 host_->OnStartBuildingBlob(kId, elements); | |
| 754 EXPECT_FALSE(host_->shutdown_for_bad_message_); | |
| 755 | |
| 756 // Check that we got the expected request. | 663 // Check that we got the expected request. |
| 757 std::vector<BlobItemBytesRequest> expected_requests = { | 664 std::vector<BlobItemBytesRequest> expected_requests = { |
| 758 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; | 665 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; |
| 759 ExpectRequest(kId, expected_requests); | 666 ExpectRequest(kId, expected_requests); |
| 760 sink_.ClearMessages(); | 667 sink_.ClearMessages(); |
| 761 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 668 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
| 762 EXPECT_TRUE(IsBeingBuiltInHost(kId)); | 669 EXPECT_TRUE(IsBeingBuiltInHost(kId)); |
| 763 // Decrement, simulating where the ref goes out of scope in renderer. | 670 // Decrement, simulating where the ref goes out of scope in renderer. |
| 764 host_->OnDecrementBlobRefCount(kId); | 671 host_->OnDecrementBlobRefCount(kId); |
| 765 // We still have the blob as it's not done. | 672 // We still have the blob as it's not done. |
| 766 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 673 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
| 767 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); | 674 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); |
| 768 EXPECT_TRUE(IsBeingBuiltInHost(kId)); | 675 EXPECT_TRUE(IsBeingBuiltInHost(kId)); |
| 769 // Cancel to clean up. | 676 // Cancel to clean up. |
| 770 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN); | 677 host_->OnCancelBuildingBlob(kId, |
| 678 BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS); |
| 771 // Run loop to propagate the handle decrement in the host. | 679 // Run loop to propagate the handle decrement in the host. |
| 772 base::RunLoop().RunUntilIdle(); | 680 base::RunLoop().RunUntilIdle(); |
| 773 // We still have the entry because of our earlier handle. | 681 // We still have the entry because of our earlier handle. |
| 774 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 682 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
| 775 EXPECT_FALSE(IsBeingBuiltInHost(kId)); | 683 EXPECT_FALSE(IsBeingBuiltInHost(kId)); |
| 776 EXPECT_FALSE(built); | 684 EXPECT_FALSE(built); |
| 777 EXPECT_EQ(IPCBlobCreationCancelCode::UNKNOWN, error_code); | 685 EXPECT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS, error_code); |
| 778 sink_.ClearMessages(); | 686 sink_.ClearMessages(); |
| 779 | 687 |
| 780 // Should disappear after dropping the handle. | 688 // Should disappear after dropping the handle. |
| 781 EXPECT_TRUE(blob_data_handle->IsBroken()); | 689 EXPECT_TRUE(blob_data_handle->IsBroken()); |
| 782 blob_data_handle.reset(); | 690 blob_data_handle.reset(); |
| 783 base::RunLoop().RunUntilIdle(); | 691 base::RunLoop().RunUntilIdle(); |
| 784 EXPECT_FALSE(context_->registry().HasEntry(kId)); | 692 EXPECT_FALSE(context_->registry().HasEntry(kId)); |
| 785 } | 693 } |
| 786 | 694 |
| 787 TEST_F(BlobDispatcherHostTest, HostDisconnectAfterRegisterWithHandle) { | |
| 788 const std::string kId("id"); | |
| 789 | |
| 790 // Delete host with a handle to the blob. | |
| 791 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | |
| 792 std::string(kContentDisposition), | |
| 793 std::set<std::string>()); | |
| 794 | |
| 795 std::unique_ptr<BlobDataHandle> blob_data_handle = | |
| 796 context_->GetBlobDataFromUUID(kId); | |
| 797 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); | |
| 798 bool built = true; | |
| 799 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN; | |
| 800 blob_data_handle->RunOnConstructionComplete( | |
| 801 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); | |
| 802 // Get rid of host, which was doing the constructing. | |
| 803 host_ = nullptr; | |
| 804 EXPECT_FALSE(blob_data_handle->IsBeingBuilt()); | |
| 805 base::RunLoop().RunUntilIdle(); | |
| 806 EXPECT_FALSE(built); | |
| 807 EXPECT_EQ(IPCBlobCreationCancelCode::SOURCE_DIED_IN_TRANSIT, error_code); | |
| 808 | |
| 809 // Should still be there due to the handle. | |
| 810 std::unique_ptr<BlobDataHandle> another_handle = | |
| 811 context_->GetBlobDataFromUUID(kId); | |
| 812 EXPECT_TRUE(another_handle); | |
| 813 | |
| 814 // Should disappear after dropping both handles. | |
| 815 blob_data_handle.reset(); | |
| 816 another_handle.reset(); | |
| 817 base::RunLoop().RunUntilIdle(); | |
| 818 EXPECT_FALSE(context_->registry().HasEntry(kId)); | |
| 819 } | |
| 820 | |
| 821 TEST_F(BlobDispatcherHostTest, HostDisconnectAfterOnStart) { | 695 TEST_F(BlobDispatcherHostTest, HostDisconnectAfterOnStart) { |
| 822 const std::string kId("id"); | 696 const std::string kId("id"); |
| 823 | 697 |
| 824 // Host deleted after OnStartBuilding. | 698 // Host deleted after OnStartBuilding. |
| 825 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | |
| 826 std::string(kContentDisposition), | |
| 827 std::set<std::string>()); | |
| 828 | |
| 829 DataElement element; | 699 DataElement element; |
| 830 element.SetToBytesDescription(kDataSize); | 700 element.SetToBytesDescription(kDataSize); |
| 831 std::vector<DataElement> elements = {element}; | 701 std::vector<DataElement> elements = {element}; |
| 832 host_->OnStartBuildingBlob(kId, elements); | 702 host_->OnRegisterBlob(kId, std::string(kContentType), |
| 703 std::string(kContentDisposition), elements); |
| 833 | 704 |
| 834 std::vector<BlobItemBytesRequest> expected_requests = { | 705 std::vector<BlobItemBytesRequest> expected_requests = { |
| 835 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; | 706 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; |
| 836 ExpectRequest(kId, expected_requests); | 707 ExpectRequest(kId, expected_requests); |
| 837 sink_.ClearMessages(); | 708 sink_.ClearMessages(); |
| 838 host_ = nullptr; | 709 host_ = nullptr; |
| 839 // We need to run the message loop because of the handle in the async builder. | 710 // We need to run the message loop because of the handle in the async builder. |
| 840 base::RunLoop().RunUntilIdle(); | 711 base::RunLoop().RunUntilIdle(); |
| 841 EXPECT_FALSE(context_->registry().HasEntry(kId)); | 712 EXPECT_FALSE(context_->registry().HasEntry(kId)); |
| 842 } | 713 } |
| 843 | 714 |
| 844 TEST_F(BlobDispatcherHostTest, HostDisconnectAfterOnMemoryResponse) { | 715 TEST_F(BlobDispatcherHostTest, HostDisconnectAfterOnMemoryResponse) { |
| 845 const std::string kId("id"); | 716 const std::string kId("id"); |
| 846 | 717 |
| 847 // Host deleted after OnMemoryItemResponse. | 718 // Host deleted after OnMemoryItemResponse. |
| 848 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | |
| 849 std::string(kContentDisposition), | |
| 850 std::set<std::string>()); | |
| 851 | |
| 852 // Create list of two items. | |
| 853 DataElement element; | 719 DataElement element; |
| 854 element.SetToBytesDescription(kDataSize); | 720 element.SetToBytesDescription(kDataSize); |
| 855 std::vector<DataElement> elements = {element, element}; | 721 std::vector<DataElement> elements = {element, element}; |
| 856 host_->OnStartBuildingBlob(kId, elements); | 722 host_->OnRegisterBlob(kId, std::string(kContentType), |
| 723 std::string(kContentDisposition), elements); |
| 724 |
| 725 // Create list of two items. |
| 857 std::vector<BlobItemBytesRequest> expected_requests = { | 726 std::vector<BlobItemBytesRequest> expected_requests = { |
| 858 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize), | 727 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize), |
| 859 BlobItemBytesRequest::CreateIPCRequest(1, 1, 0, kDataSize)}; | 728 BlobItemBytesRequest::CreateIPCRequest(1, 1, 0, kDataSize)}; |
| 860 ExpectRequest(kId, expected_requests); | 729 ExpectRequest(kId, expected_requests); |
| 861 sink_.ClearMessages(); | 730 sink_.ClearMessages(); |
| 862 | 731 |
| 863 // Send just one response so the blob isn't 'done' yet. | 732 // Send just one response so the blob isn't 'done' yet. |
| 864 BlobItemBytesResponse response(0); | 733 BlobItemBytesResponse response(0); |
| 865 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); | 734 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); |
| 866 std::vector<BlobItemBytesResponse> responses = {response}; | 735 std::vector<BlobItemBytesResponse> responses = {response}; |
| 867 host_->OnMemoryItemResponse(kId, responses); | 736 host_->OnMemoryItemResponse(kId, responses); |
| 868 EXPECT_EQ(0u, sink_.message_count()); | 737 EXPECT_EQ(0u, sink_.message_count()); |
| 869 | 738 |
| 870 host_ = nullptr; | 739 host_ = nullptr; |
| 871 base::RunLoop().RunUntilIdle(); | 740 base::RunLoop().RunUntilIdle(); |
| 872 EXPECT_FALSE(context_->registry().HasEntry(kId)); | 741 EXPECT_FALSE(context_->registry().HasEntry(kId)); |
| 873 } | 742 } |
| 874 | 743 |
| 875 TEST_F(BlobDispatcherHostTest, CreateBlobWithBrokenReference) { | 744 TEST_F(BlobDispatcherHostTest, CreateBlobWithBrokenReference) { |
| 876 const std::string kBrokenId("id1"); | 745 const std::string kBrokenId("id1"); |
| 877 const std::string kReferencingId("id2"); | 746 const std::string kReferencingId("id2"); |
| 878 | 747 |
| 879 // First, let's test a circular reference. | 748 // First, let's test a circular reference. |
| 880 const std::string kCircularId("id1"); | 749 const std::string kCircularId("id1"); |
| 881 host_->OnRegisterBlobUUID(kCircularId, std::string(kContentType), | 750 DataElement element; |
| 882 std::string(kContentDisposition), {kCircularId}); | 751 element.SetToBlob(kCircularId); |
| 752 std::vector<DataElement> elements = {element}; |
| 753 host_->OnRegisterBlob(kCircularId, std::string(kContentType), |
| 754 std::string(kContentDisposition), elements); |
| 883 ExpectAndResetBadMessage(); | 755 ExpectAndResetBadMessage(); |
| 884 | 756 |
| 885 // Next, test a blob that references a broken blob. | 757 // Next, test a blob that references a broken blob. |
| 886 host_->OnRegisterBlobUUID(kBrokenId, std::string(kContentType), | 758 element.SetToBytesDescription(kDataSize); |
| 887 std::string(kContentDisposition), | 759 elements = {element}; |
| 888 std::set<std::string>()); | 760 host_->OnRegisterBlob(kBrokenId, std::string(kContentType), |
| 889 host_->OnCancelBuildingBlob(kBrokenId, IPCBlobCreationCancelCode::UNKNOWN); | 761 std::string(kContentDisposition), elements); |
| 762 sink_.ClearMessages(); |
| 763 host_->OnCancelBuildingBlob(kBrokenId, |
| 764 BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS); |
| 890 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 765 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
| 891 EXPECT_TRUE(context_->GetBlobDataFromUUID(kBrokenId)->IsBroken()); | 766 EXPECT_TRUE(context_->GetBlobDataFromUUID(kBrokenId)->IsBroken()); |
| 892 | 767 |
| 893 // Create referencing blob. We should be broken right away, but also ignore | 768 // Create referencing blob. We should be broken right away, but also ignore |
| 894 // the subsequent OnStart message. | 769 // the subsequent OnStart message. |
| 895 host_->OnRegisterBlobUUID(kReferencingId, std::string(kContentType), | 770 element.SetToBytesDescription(kDataSize); |
| 896 std::string(kContentDisposition), {kBrokenId}); | 771 elements = {element}; |
| 772 element.SetToBlob(kBrokenId); |
| 773 elements.push_back(element); |
| 774 host_->OnRegisterBlob(kReferencingId, std::string(kContentType), |
| 775 std::string(kContentDisposition), elements); |
| 897 EXPECT_TRUE(context_->GetBlobDataFromUUID(kReferencingId)->IsBroken()); | 776 EXPECT_TRUE(context_->GetBlobDataFromUUID(kReferencingId)->IsBroken()); |
| 898 EXPECT_FALSE(IsBeingBuiltInHost(kReferencingId)); | 777 EXPECT_FALSE(IsBeingBuiltInHost(kReferencingId)); |
| 899 EXPECT_TRUE(context_->registry().HasEntry(kReferencingId)); | 778 EXPECT_TRUE(context_->registry().HasEntry(kReferencingId)); |
| 900 ExpectCancel(kReferencingId, | 779 ExpectCancel(kReferencingId, BlobStatus::ERR_REFERENCED_BLOB_BROKEN); |
| 901 IPCBlobCreationCancelCode::REFERENCED_BLOB_BROKEN); | |
| 902 sink_.ClearMessages(); | 780 sink_.ClearMessages(); |
| 903 | |
| 904 DataElement element; | |
| 905 element.SetToBytesDescription(kDataSize); | |
| 906 std::vector<DataElement> elements = {element}; | |
| 907 element.SetToBlob(kBrokenId); | |
| 908 elements.push_back(element); | |
| 909 host_->OnStartBuildingBlob(kReferencingId, elements); | |
| 910 EXPECT_EQ(0u, sink_.message_count()); | |
| 911 base::RunLoop().RunUntilIdle(); | |
| 912 } | 781 } |
| 913 | 782 |
| 914 TEST_F(BlobDispatcherHostTest, DeferenceBlobOnDifferentHost) { | 783 TEST_F(BlobDispatcherHostTest, DeferenceBlobOnDifferentHost) { |
| 915 const std::string kId("id"); | 784 const std::string kId("id"); |
| 916 // Data elements for our transfer & checking messages. | 785 // Data elements for our transfer & checking messages. |
| 917 DataElement element; | 786 DataElement element; |
| 918 element.SetToBytesDescription(kDataSize); | 787 element.SetToBytesDescription(kDataSize); |
| 919 std::vector<DataElement> elements = {element}; | 788 std::vector<DataElement> elements = {element}; |
| 920 std::vector<BlobItemBytesRequest> expected_requests = { | 789 std::vector<BlobItemBytesRequest> expected_requests = { |
| 921 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; | 790 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; |
| 922 BlobItemBytesResponse response(0); | 791 BlobItemBytesResponse response(0); |
| 923 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); | 792 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); |
| 924 std::vector<BlobItemBytesResponse> responses = {response}; | 793 std::vector<BlobItemBytesResponse> responses = {response}; |
| 925 | 794 |
| 926 scoped_refptr<TestableBlobDispatcherHost> host2( | 795 scoped_refptr<TestableBlobDispatcherHost> host2( |
| 927 new TestableBlobDispatcherHost(chrome_blob_storage_context_, | 796 new TestableBlobDispatcherHost(chrome_blob_storage_context_, |
| 928 file_system_context_.get(), &sink_)); | 797 file_system_context_.get(), &sink_)); |
| 929 | 798 |
| 930 // Delete host with another host having a referencing, then dereference on | 799 // Delete host with another host having a referencing, then dereference on |
| 931 // second host. Verify we're still building it on first host, and then | 800 // second host. Verify we're still building it on first host, and then |
| 932 // verify that a building message from the renderer will kill it. | 801 // verify that a building message from the renderer will kill it. |
| 933 | 802 |
| 934 // Test OnStartBuilding after double dereference. | 803 // Test OnStartBuilding after double dereference. |
| 935 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 804 host_->OnRegisterBlob(kId, std::string(kContentType), |
| 936 std::string(kContentDisposition), | 805 std::string(kContentDisposition), elements); |
| 937 std::set<std::string>()); | 806 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
| 807 ExpectRequest(kId, expected_requests); |
| 808 sink_.ClearMessages(); |
| 938 host2->OnIncrementBlobRefCount(kId); | 809 host2->OnIncrementBlobRefCount(kId); |
| 939 host_->OnDecrementBlobRefCount(kId); | 810 host_->OnDecrementBlobRefCount(kId); |
| 940 EXPECT_FALSE(host_->IsInUseInHost(kId)); | 811 EXPECT_FALSE(host_->IsInUseInHost(kId)); |
| 941 host2->OnDecrementBlobRefCount(kId); | 812 host2->OnDecrementBlobRefCount(kId); |
| 942 // So no more blob in the context, but we're still being built in host 1. | 813 // So no more blob in the context, but we're still being built in host 1. |
| 943 EXPECT_FALSE(context_->registry().HasEntry(kId)); | 814 EXPECT_FALSE(context_->registry().HasEntry(kId)); |
| 944 EXPECT_TRUE(host_->async_builder_.IsBeingBuilt(kId)); | 815 // Send the memory. When the host sees the entry doesn't exist, it should |
| 945 host_->OnStartBuildingBlob(kId, elements); | 816 // cancel and clean up. |
| 946 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 817 EXPECT_TRUE(host_->transport_host_.IsBeingBuilt(kId)); |
| 818 host_->OnMemoryItemResponse(kId, responses); |
| 947 // We should be cleaned up. | 819 // We should be cleaned up. |
| 948 EXPECT_FALSE(host_->async_builder_.IsBeingBuilt(kId)); | 820 EXPECT_FALSE(host_->transport_host_.IsBeingBuilt(kId)); |
| 949 ExpectCancel(kId, | 821 ExpectCancel(kId, BlobStatus::ERR_BLOB_DEREFERENCED_WHILE_BUILDING); |
| 950 IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING); | |
| 951 sink_.ClearMessages(); | 822 sink_.ClearMessages(); |
| 952 | 823 |
| 953 // Same as above, but test OnMemoryItemResponse after double dereference. | 824 // Same, but now for OnCancel. |
| 954 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 825 host_->OnRegisterBlob(kId, std::string(kContentType), |
| 955 std::string(kContentDisposition), | 826 std::string(kContentDisposition), elements); |
| 956 std::set<std::string>()); | |
| 957 host2->OnIncrementBlobRefCount(kId); | 827 host2->OnIncrementBlobRefCount(kId); |
| 958 host_->OnDecrementBlobRefCount(kId); | 828 host_->OnDecrementBlobRefCount(kId); |
| 959 EXPECT_FALSE(host_->IsInUseInHost(kId)); | 829 EXPECT_FALSE(host_->IsInUseInHost(kId)); |
| 960 host_->OnStartBuildingBlob(kId, elements); | |
| 961 ExpectRequest(kId, expected_requests); | 830 ExpectRequest(kId, expected_requests); |
| 962 sink_.ClearMessages(); | 831 sink_.ClearMessages(); |
| 963 | 832 |
| 964 host2->OnDecrementBlobRefCount(kId); | 833 host2->OnDecrementBlobRefCount(kId); |
| 965 // So no more blob in the context, but we're still being built in host 1. | 834 // So no more blob in the context, but we're still being built in host 1. |
| 966 EXPECT_FALSE(context_->registry().HasEntry(kId)); | 835 EXPECT_FALSE(context_->registry().HasEntry(kId)); |
| 967 EXPECT_TRUE(host_->async_builder_.IsBeingBuilt(kId)); | 836 EXPECT_TRUE(host_->transport_host_.IsBeingBuilt(kId)); |
| 968 host_->OnMemoryItemResponse(kId, responses); | 837 host_->OnCancelBuildingBlob(kId, |
| 838 BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS); |
| 969 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 839 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
| 970 // We should be cleaned up. | 840 // We should be cleaned up. |
| 971 EXPECT_FALSE(host_->async_builder_.IsBeingBuilt(kId)); | 841 EXPECT_FALSE(host_->transport_host_.IsBeingBuilt(kId)); |
| 972 ExpectCancel(kId, | |
| 973 IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING); | |
| 974 sink_.ClearMessages(); | |
| 975 | |
| 976 // Same, but now for OnCancel. | |
| 977 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | |
| 978 std::string(kContentDisposition), | |
| 979 std::set<std::string>()); | |
| 980 host2->OnIncrementBlobRefCount(kId); | |
| 981 host_->OnDecrementBlobRefCount(kId); | |
| 982 EXPECT_FALSE(host_->IsInUseInHost(kId)); | |
| 983 host_->OnStartBuildingBlob(kId, elements); | |
| 984 ExpectRequest(kId, expected_requests); | |
| 985 sink_.ClearMessages(); | |
| 986 | |
| 987 host2->OnDecrementBlobRefCount(kId); | |
| 988 // So no more blob in the context, but we're still being built in host 1. | |
| 989 EXPECT_FALSE(context_->registry().HasEntry(kId)); | |
| 990 EXPECT_TRUE(host_->async_builder_.IsBeingBuilt(kId)); | |
| 991 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN); | |
| 992 EXPECT_FALSE(host_->shutdown_for_bad_message_); | |
| 993 // We should be cleaned up. | |
| 994 EXPECT_FALSE(host_->async_builder_.IsBeingBuilt(kId)); | |
| 995 } | 842 } |
| 996 | 843 |
| 997 TEST_F(BlobDispatcherHostTest, BuildingReferenceChain) { | 844 TEST_F(BlobDispatcherHostTest, BuildingReferenceChain) { |
| 998 const std::string kId("id"); | 845 const std::string kId("id"); |
| 999 const std::string kSameHostReferencingId("id2"); | 846 const std::string kSameHostReferencingId("id2"); |
| 1000 const std::string kDifferentHostReferencingId("id3"); | 847 const std::string kDifferentHostReferencingId("id3"); |
| 1001 // Data elements for our transfer & checking messages. | 848 // Data elements for our transfer & checking messages. |
| 1002 DataElement element; | 849 DataElement element; |
| 1003 element.SetToBytes(kData, kDataSize); | 850 element.SetToBytesDescription(kDataSize); |
| 1004 std::vector<DataElement> elements = {element}; | |
| 1005 DataElement referencing_element; | 851 DataElement referencing_element; |
| 1006 referencing_element.SetToBlob(kId); | 852 referencing_element.SetToBlob(kId); |
| 853 std::vector<DataElement> elements = {element}; |
| 1007 std::vector<DataElement> referencing_elements = {referencing_element}; | 854 std::vector<DataElement> referencing_elements = {referencing_element}; |
| 1008 std::set<std::string> referenced_blobs_set = {kId}; | 855 std::vector<BlobItemBytesRequest> expected_requests = { |
| 856 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; |
| 857 BlobItemBytesResponse response(0); |
| 858 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); |
| 859 std::vector<BlobItemBytesResponse> responses = {response}; |
| 1009 | 860 |
| 1010 scoped_refptr<TestableBlobDispatcherHost> host2( | 861 scoped_refptr<TestableBlobDispatcherHost> host2( |
| 1011 new TestableBlobDispatcherHost(chrome_blob_storage_context_, | 862 new TestableBlobDispatcherHost(chrome_blob_storage_context_, |
| 1012 file_system_context_.get(), &sink_)); | 863 file_system_context_.get(), &sink_)); |
| 1013 | 864 |
| 1014 // We want to have a blob referencing another blob that is building, both on | 865 // We want to have a blob referencing another blob that is building, both on |
| 1015 // the same host and a different host. We should successfully build all blobs | 866 // the same host and a different host. We should successfully build all blobs |
| 1016 // after the referenced blob is finished. | 867 // after the referenced blob is finished. |
| 1017 | 868 |
| 1018 // First we start the referenced blob. | 869 // First we start the referenced blob. |
| 1019 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 870 host_->OnRegisterBlob(kId, std::string(kContentType), |
| 1020 std::string(kContentDisposition), | 871 std::string(kContentDisposition), elements); |
| 1021 std::set<std::string>()); | 872 ExpectRequest(kId, expected_requests); |
| 873 sink_.ClearMessages(); |
| 1022 EXPECT_TRUE(host_->IsInUseInHost(kId)); | 874 EXPECT_TRUE(host_->IsInUseInHost(kId)); |
| 875 EXPECT_TRUE(IsBeingBuiltInContext(kId)); |
| 1023 | 876 |
| 1024 // Next we start the referencing blobs in both the same and different host. | 877 // Next we start the referencing blobs in both the same and different host. |
| 1025 host_->OnRegisterBlobUUID(kSameHostReferencingId, std::string(kContentType), | 878 host_->OnRegisterBlob(kSameHostReferencingId, std::string(kContentType), |
| 1026 std::string(kContentDisposition), | 879 std::string(kContentDisposition), referencing_elements); |
| 1027 referenced_blobs_set); | |
| 1028 EXPECT_FALSE(host_->shutdown_for_bad_message_); | |
| 1029 host_->OnStartBuildingBlob(kSameHostReferencingId, referencing_elements); | |
| 1030 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 880 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
| 1031 ExpectDone(kSameHostReferencingId); | 881 ExpectDone(kSameHostReferencingId); |
| 1032 EXPECT_TRUE(host_->async_builder_.IsBeingBuilt(kSameHostReferencingId)); | |
| 1033 sink_.ClearMessages(); | 882 sink_.ClearMessages(); |
| 883 EXPECT_FALSE( |
| 884 context_->GetBlobDataFromUUID(kSameHostReferencingId)->IsBroken()); |
| 885 EXPECT_FALSE(host_->transport_host_.IsBeingBuilt(kSameHostReferencingId)); |
| 886 EXPECT_TRUE(IsBeingBuiltInContext(kSameHostReferencingId)); |
| 887 |
| 1034 // Now the other host. | 888 // Now the other host. |
| 1035 host2->OnRegisterBlobUUID( | 889 host2->OnRegisterBlob(kDifferentHostReferencingId, std::string(kContentType), |
| 1036 kDifferentHostReferencingId, std::string(kContentType), | 890 std::string(kContentDisposition), referencing_elements); |
| 1037 std::string(kContentDisposition), referenced_blobs_set); | |
| 1038 EXPECT_FALSE(host2->shutdown_for_bad_message_); | |
| 1039 host2->OnStartBuildingBlob(kDifferentHostReferencingId, referencing_elements); | |
| 1040 EXPECT_FALSE(host2->shutdown_for_bad_message_); | 891 EXPECT_FALSE(host2->shutdown_for_bad_message_); |
| 1041 ExpectDone(kDifferentHostReferencingId); | 892 ExpectDone(kDifferentHostReferencingId); |
| 1042 EXPECT_TRUE(host2->async_builder_.IsBeingBuilt(kDifferentHostReferencingId)); | |
| 1043 sink_.ClearMessages(); | 893 sink_.ClearMessages(); |
| 894 EXPECT_FALSE( |
| 895 context_->GetBlobDataFromUUID(kDifferentHostReferencingId)->IsBroken()); |
| 896 EXPECT_FALSE( |
| 897 host2->transport_host_.IsBeingBuilt(kDifferentHostReferencingId)); |
| 898 EXPECT_TRUE(IsBeingBuiltInContext(kDifferentHostReferencingId)); |
| 1044 | 899 |
| 1045 // Now we finish the first blob, and we expect all blobs to finish. | 900 // Now we finish the first blob, and we expect all blobs to finish. |
| 1046 host_->OnStartBuildingBlob(kId, elements); | 901 host_->OnMemoryItemResponse(kId, responses); |
| 1047 ExpectDone(kId); | 902 ExpectDone(kId); |
| 1048 // We need to run the message loop to propagate the construction callbacks. | 903 // We need to run the message loop to propagate the construction callbacks. |
| 1049 base::RunLoop().RunUntilIdle(); | 904 base::RunLoop().RunUntilIdle(); |
| 1050 EXPECT_FALSE(host2->async_builder_.IsBeingBuilt(kDifferentHostReferencingId)); | 905 EXPECT_FALSE( |
| 1051 EXPECT_FALSE(host_->async_builder_.IsBeingBuilt(kSameHostReferencingId)); | 906 host2->transport_host_.IsBeingBuilt(kDifferentHostReferencingId)); |
| 907 EXPECT_FALSE(host_->transport_host_.IsBeingBuilt(kSameHostReferencingId)); |
| 1052 EXPECT_FALSE( | 908 EXPECT_FALSE( |
| 1053 context_->GetBlobDataFromUUID(kSameHostReferencingId)->IsBroken()); | 909 context_->GetBlobDataFromUUID(kSameHostReferencingId)->IsBroken()); |
| 1054 EXPECT_FALSE( | 910 EXPECT_FALSE( |
| 1055 context_->GetBlobDataFromUUID(kDifferentHostReferencingId)->IsBroken()); | 911 context_->GetBlobDataFromUUID(kDifferentHostReferencingId)->IsBroken()); |
| 1056 sink_.ClearMessages(); | 912 sink_.ClearMessages(); |
| 1057 | 913 |
| 1058 // Finally check that our data is correct in the child elements. | 914 // Finally check that our data is correct in the child elements. |
| 1059 std::unique_ptr<BlobDataHandle> handle = | 915 std::unique_ptr<BlobDataHandle> handle = |
| 1060 context_->GetBlobDataFromUUID(kDifferentHostReferencingId); | 916 context_->GetBlobDataFromUUID(kDifferentHostReferencingId); |
| 1061 ExpectHandleEqualsData(handle.get(), elements); | 917 DataElement expected; |
| 918 expected.SetToBytes(kData, kDataSize); |
| 919 std::vector<DataElement> expecteds = {expected}; |
| 920 ExpectHandleEqualsData(handle.get(), expecteds); |
| 1062 } | 921 } |
| 1063 | 922 |
| 1064 TEST_F(BlobDispatcherHostTest, BuildingReferenceChainWithCancel) { | 923 TEST_F(BlobDispatcherHostTest, BuildingReferenceChainWithCancel) { |
| 1065 const std::string kId("id"); | 924 const std::string kId("id"); |
| 1066 const std::string kSameHostReferencingId("id2"); | 925 const std::string kSameHostReferencingId("id2"); |
| 1067 const std::string kDifferentHostReferencingId("id3"); | 926 const std::string kDifferentHostReferencingId("id3"); |
| 1068 // Data elements for our transfer & checking messages. | 927 // Data elements for our transfer & checking messages. |
| 928 DataElement element; |
| 929 element.SetToBytesDescription(kDataSize); |
| 1069 DataElement referencing_element; | 930 DataElement referencing_element; |
| 1070 referencing_element.SetToBlob(kId); | 931 referencing_element.SetToBlob(kId); |
| 932 std::vector<DataElement> elements = {element}; |
| 1071 std::vector<DataElement> referencing_elements = {referencing_element}; | 933 std::vector<DataElement> referencing_elements = {referencing_element}; |
| 1072 std::set<std::string> referenced_blobs_set = {kId}; | 934 std::vector<BlobItemBytesRequest> expected_requests = { |
| 935 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; |
| 1073 | 936 |
| 1074 scoped_refptr<TestableBlobDispatcherHost> host2( | 937 scoped_refptr<TestableBlobDispatcherHost> host2( |
| 1075 new TestableBlobDispatcherHost(chrome_blob_storage_context_, | 938 new TestableBlobDispatcherHost(chrome_blob_storage_context_, |
| 1076 file_system_context_.get(), &sink_)); | 939 file_system_context_.get(), &sink_)); |
| 1077 | 940 |
| 1078 // We want to have a blob referencing another blob that is building, both on | 941 // We want to have a blob referencing another blob that is building, both on |
| 1079 // the same host and a different host. After we cancel the first blob, the | 942 // the same host and a different host. We should successfully build all blobs |
| 1080 // others should cancel as well. | 943 // after the referenced blob is finished. |
| 1081 | 944 |
| 1082 // First we start the referenced blob. | 945 // First we start the referenced blob. |
| 1083 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 946 host_->OnRegisterBlob(kId, std::string(kContentType), |
| 1084 std::string(kContentDisposition), | 947 std::string(kContentDisposition), elements); |
| 1085 std::set<std::string>()); | 948 ExpectRequest(kId, expected_requests); |
| 949 sink_.ClearMessages(); |
| 1086 EXPECT_TRUE(host_->IsInUseInHost(kId)); | 950 EXPECT_TRUE(host_->IsInUseInHost(kId)); |
| 951 EXPECT_TRUE(IsBeingBuiltInContext(kId)); |
| 1087 | 952 |
| 1088 // Next we start the referencing blobs in both the same and different host. | 953 // Next we start the referencing blobs in both the same and different host. |
| 1089 host_->OnRegisterBlobUUID(kSameHostReferencingId, std::string(kContentType), | 954 host_->OnRegisterBlob(kSameHostReferencingId, std::string(kContentType), |
| 1090 std::string(kContentDisposition), | 955 std::string(kContentDisposition), referencing_elements); |
| 1091 referenced_blobs_set); | 956 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
| 1092 host_->OnStartBuildingBlob(kSameHostReferencingId, referencing_elements); | |
| 1093 ExpectDone(kSameHostReferencingId); | 957 ExpectDone(kSameHostReferencingId); |
| 1094 EXPECT_TRUE(host_->async_builder_.IsBeingBuilt(kSameHostReferencingId)); | |
| 1095 sink_.ClearMessages(); | 958 sink_.ClearMessages(); |
| 959 EXPECT_FALSE( |
| 960 context_->GetBlobDataFromUUID(kSameHostReferencingId)->IsBroken()); |
| 961 EXPECT_FALSE(host_->transport_host_.IsBeingBuilt(kSameHostReferencingId)); |
| 962 EXPECT_TRUE(IsBeingBuiltInContext(kSameHostReferencingId)); |
| 963 |
| 1096 // Now the other host. | 964 // Now the other host. |
| 1097 host2->OnRegisterBlobUUID( | 965 host2->OnRegisterBlob(kDifferentHostReferencingId, std::string(kContentType), |
| 1098 kDifferentHostReferencingId, std::string(kContentType), | 966 std::string(kContentDisposition), referencing_elements); |
| 1099 std::string(kContentDisposition), referenced_blobs_set); | 967 EXPECT_FALSE(host2->shutdown_for_bad_message_); |
| 1100 host2->OnStartBuildingBlob(kDifferentHostReferencingId, referencing_elements); | |
| 1101 ExpectDone(kDifferentHostReferencingId); | 968 ExpectDone(kDifferentHostReferencingId); |
| 1102 EXPECT_TRUE(host2->async_builder_.IsBeingBuilt(kDifferentHostReferencingId)); | |
| 1103 sink_.ClearMessages(); | 969 sink_.ClearMessages(); |
| 970 EXPECT_FALSE( |
| 971 context_->GetBlobDataFromUUID(kDifferentHostReferencingId)->IsBroken()); |
| 972 EXPECT_FALSE( |
| 973 host2->transport_host_.IsBeingBuilt(kDifferentHostReferencingId)); |
| 974 EXPECT_TRUE(IsBeingBuiltInContext(kDifferentHostReferencingId)); |
| 975 |
| 1104 bool built = false; | 976 bool built = false; |
| 1105 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN; | 977 BlobStatus error_code = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS; |
| 1106 context_->GetBlobDataFromUUID(kDifferentHostReferencingId) | 978 context_->GetBlobDataFromUUID(kDifferentHostReferencingId) |
| 1107 ->RunOnConstructionComplete( | 979 ->RunOnConstructionComplete( |
| 1108 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); | 980 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); |
| 1109 | 981 |
| 1110 // Now we cancel the first blob, and we expect all blobs to cancel. | 982 // Now we cancel the first blob, and we expect all blobs to cancel. |
| 1111 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN); | 983 host_->OnCancelBuildingBlob(kId, |
| 984 BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS); |
| 1112 // We need to run the message loop to propagate the construction callbacks. | 985 // We need to run the message loop to propagate the construction callbacks. |
| 1113 base::RunLoop().RunUntilIdle(); | 986 base::RunLoop().RunUntilIdle(); |
| 1114 EXPECT_FALSE(host2->async_builder_.IsBeingBuilt(kDifferentHostReferencingId)); | 987 EXPECT_FALSE( |
| 1115 EXPECT_FALSE(host_->async_builder_.IsBeingBuilt(kSameHostReferencingId)); | 988 host2->transport_host_.IsBeingBuilt(kDifferentHostReferencingId)); |
| 989 EXPECT_FALSE(host_->transport_host_.IsBeingBuilt(kSameHostReferencingId)); |
| 1116 EXPECT_TRUE( | 990 EXPECT_TRUE( |
| 1117 context_->GetBlobDataFromUUID(kSameHostReferencingId)->IsBroken()); | 991 context_->GetBlobDataFromUUID(kSameHostReferencingId)->IsBroken()); |
| 1118 EXPECT_TRUE( | 992 EXPECT_TRUE( |
| 1119 context_->GetBlobDataFromUUID(kDifferentHostReferencingId)->IsBroken()); | 993 context_->GetBlobDataFromUUID(kDifferentHostReferencingId)->IsBroken()); |
| 1120 EXPECT_FALSE(built); | 994 EXPECT_FALSE(built); |
| 1121 EXPECT_EQ(IPCBlobCreationCancelCode::REFERENCED_BLOB_BROKEN, error_code); | 995 EXPECT_EQ(BlobStatus::ERR_REFERENCED_BLOB_BROKEN, error_code); |
| 1122 sink_.ClearMessages(); | 996 sink_.ClearMessages(); |
| 1123 } | 997 } |
| 1124 | 998 |
| 1125 TEST_F(BlobDispatcherHostTest, BuildingReferenceChainWithSourceDeath) { | 999 TEST_F(BlobDispatcherHostTest, BuildingReferenceChainWithSourceDeath) { |
| 1126 const std::string kId("id"); | 1000 const std::string kId("id"); |
| 1127 const std::string kSameHostReferencingId("id2"); | 1001 const std::string kSameHostReferencingId("id2"); |
| 1128 const std::string kDifferentHostReferencingId("id3"); | 1002 const std::string kDifferentHostReferencingId("id3"); |
| 1129 // Data elements for our transfer & checking messages. | 1003 // Data elements for our transfer & checking messages. |
| 1004 DataElement element; |
| 1005 element.SetToBytesDescription(kDataSize); |
| 1130 DataElement referencing_element; | 1006 DataElement referencing_element; |
| 1131 referencing_element.SetToBlob(kId); | 1007 referencing_element.SetToBlob(kId); |
| 1008 std::vector<DataElement> elements = {element}; |
| 1132 std::vector<DataElement> referencing_elements = {referencing_element}; | 1009 std::vector<DataElement> referencing_elements = {referencing_element}; |
| 1133 std::set<std::string> referenced_blobs_set = {kId}; | 1010 std::vector<BlobItemBytesRequest> expected_requests = { |
| 1011 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; |
| 1012 BlobItemBytesResponse response(0); |
| 1013 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); |
| 1014 std::vector<BlobItemBytesResponse> responses = {response}; |
| 1134 | 1015 |
| 1135 scoped_refptr<TestableBlobDispatcherHost> host2( | 1016 scoped_refptr<TestableBlobDispatcherHost> host2( |
| 1136 new TestableBlobDispatcherHost(chrome_blob_storage_context_, | 1017 new TestableBlobDispatcherHost(chrome_blob_storage_context_, |
| 1137 file_system_context_.get(), &sink_)); | 1018 file_system_context_.get(), &sink_)); |
| 1138 | 1019 |
| 1139 // We want to have a blob referencing another blob that is building, both on | 1020 // We want to have a blob referencing another blob that is building, both on |
| 1140 // the same host and a different host. When we destroy the host, the other | 1021 // the same host and a different host. We should successfully build all blobs |
| 1141 // blob should cancel, as well as the blob on the other host. | 1022 // after the referenced blob is finished. |
| 1142 | 1023 |
| 1143 // First we start the referenced blob. | 1024 // First we start the referenced blob. |
| 1144 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 1025 host_->OnRegisterBlob(kId, std::string(kContentType), |
| 1145 std::string(kContentDisposition), | 1026 std::string(kContentDisposition), elements); |
| 1146 std::set<std::string>()); | 1027 ExpectRequest(kId, expected_requests); |
| 1028 sink_.ClearMessages(); |
| 1147 EXPECT_TRUE(host_->IsInUseInHost(kId)); | 1029 EXPECT_TRUE(host_->IsInUseInHost(kId)); |
| 1030 EXPECT_TRUE(IsBeingBuiltInContext(kId)); |
| 1148 | 1031 |
| 1149 // Next we start the referencing blobs in both the same and different host. | 1032 // Next we start the referencing blobs in both the same and different host. |
| 1150 host_->OnRegisterBlobUUID(kSameHostReferencingId, std::string(kContentType), | 1033 host_->OnRegisterBlob(kSameHostReferencingId, std::string(kContentType), |
| 1151 std::string(kContentDisposition), | 1034 std::string(kContentDisposition), referencing_elements); |
| 1152 referenced_blobs_set); | 1035 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
| 1153 host_->OnStartBuildingBlob(kSameHostReferencingId, referencing_elements); | |
| 1154 ExpectDone(kSameHostReferencingId); | 1036 ExpectDone(kSameHostReferencingId); |
| 1155 EXPECT_TRUE(host_->async_builder_.IsBeingBuilt(kSameHostReferencingId)); | |
| 1156 sink_.ClearMessages(); | 1037 sink_.ClearMessages(); |
| 1038 |
| 1157 // Now the other host. | 1039 // Now the other host. |
| 1158 host2->OnRegisterBlobUUID( | 1040 host2->OnRegisterBlob(kDifferentHostReferencingId, std::string(kContentType), |
| 1159 kDifferentHostReferencingId, std::string(kContentType), | 1041 std::string(kContentDisposition), referencing_elements); |
| 1160 std::string(kContentDisposition), referenced_blobs_set); | 1042 EXPECT_FALSE(host2->shutdown_for_bad_message_); |
| 1161 host2->OnStartBuildingBlob(kDifferentHostReferencingId, referencing_elements); | |
| 1162 ExpectDone(kDifferentHostReferencingId); | 1043 ExpectDone(kDifferentHostReferencingId); |
| 1163 EXPECT_TRUE(host2->async_builder_.IsBeingBuilt(kDifferentHostReferencingId)); | |
| 1164 sink_.ClearMessages(); | 1044 sink_.ClearMessages(); |
| 1165 | 1045 |
| 1166 // Grab handles & add listeners. | 1046 // Grab handles & add listeners. |
| 1167 bool built = true; | 1047 bool built = true; |
| 1168 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN; | 1048 BlobStatus error_code = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS; |
| 1169 std::unique_ptr<BlobDataHandle> blob_handle = | 1049 std::unique_ptr<BlobDataHandle> blob_handle = |
| 1170 context_->GetBlobDataFromUUID(kId); | 1050 context_->GetBlobDataFromUUID(kId); |
| 1171 blob_handle->RunOnConstructionComplete( | 1051 blob_handle->RunOnConstructionComplete( |
| 1172 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); | 1052 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); |
| 1173 | 1053 |
| 1174 bool same_host_built = true; | 1054 bool same_host_built = true; |
| 1175 IPCBlobCreationCancelCode same_host_error_code = | 1055 BlobStatus same_host_error_code = |
| 1176 IPCBlobCreationCancelCode::UNKNOWN; | 1056 BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS; |
| 1177 std::unique_ptr<BlobDataHandle> same_host_blob_handle = | 1057 std::unique_ptr<BlobDataHandle> same_host_blob_handle = |
| 1178 context_->GetBlobDataFromUUID(kSameHostReferencingId); | 1058 context_->GetBlobDataFromUUID(kSameHostReferencingId); |
| 1179 same_host_blob_handle->RunOnConstructionComplete(base::Bind( | 1059 same_host_blob_handle->RunOnConstructionComplete(base::Bind( |
| 1180 &ConstructionCompletePopulator, &same_host_built, &same_host_error_code)); | 1060 &ConstructionCompletePopulator, &same_host_built, &same_host_error_code)); |
| 1181 | 1061 |
| 1182 bool other_host_built = true; | 1062 bool other_host_built = true; |
| 1183 IPCBlobCreationCancelCode other_host_error_code = | 1063 BlobStatus other_host_error_code = |
| 1184 IPCBlobCreationCancelCode::UNKNOWN; | 1064 BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS; |
| 1185 std::unique_ptr<BlobDataHandle> other_host_blob_handle = | 1065 std::unique_ptr<BlobDataHandle> other_host_blob_handle = |
| 1186 context_->GetBlobDataFromUUID(kDifferentHostReferencingId); | 1066 context_->GetBlobDataFromUUID(kDifferentHostReferencingId); |
| 1187 other_host_blob_handle->RunOnConstructionComplete( | 1067 other_host_blob_handle->RunOnConstructionComplete( |
| 1188 base::Bind(&ConstructionCompletePopulator, &other_host_built, | 1068 base::Bind(&ConstructionCompletePopulator, &other_host_built, |
| 1189 &other_host_error_code)); | 1069 &other_host_error_code)); |
| 1190 | 1070 |
| 1191 // Now we kill the host. | 1071 // Now we kill the host. |
| 1192 host_ = nullptr; | 1072 host_ = nullptr; |
| 1193 // We need to run the message loop to propagate the construction callbacks. | 1073 // We need to run the message loop to propagate the construction callbacks. |
| 1194 base::RunLoop().RunUntilIdle(); | 1074 base::RunLoop().RunUntilIdle(); |
| 1195 EXPECT_FALSE(host2->async_builder_.IsBeingBuilt(kDifferentHostReferencingId)); | 1075 EXPECT_FALSE( |
| 1076 host2->transport_host_.IsBeingBuilt(kDifferentHostReferencingId)); |
| 1196 EXPECT_TRUE( | 1077 EXPECT_TRUE( |
| 1197 context_->GetBlobDataFromUUID(kSameHostReferencingId)->IsBroken()); | 1078 context_->GetBlobDataFromUUID(kSameHostReferencingId)->IsBroken()); |
| 1198 EXPECT_TRUE( | 1079 EXPECT_TRUE( |
| 1199 context_->GetBlobDataFromUUID(kDifferentHostReferencingId)->IsBroken()); | 1080 context_->GetBlobDataFromUUID(kDifferentHostReferencingId)->IsBroken()); |
| 1200 | 1081 |
| 1201 // Check our callbacks | 1082 // Check our callbacks |
| 1202 EXPECT_FALSE(built); | 1083 EXPECT_FALSE(built); |
| 1203 EXPECT_EQ(IPCBlobCreationCancelCode::SOURCE_DIED_IN_TRANSIT, error_code); | 1084 EXPECT_EQ(BlobStatus::ERR_SOURCE_DIED_IN_TRANSIT, error_code); |
| 1204 EXPECT_FALSE(same_host_built); | 1085 EXPECT_FALSE(same_host_built); |
| 1205 EXPECT_EQ(IPCBlobCreationCancelCode::SOURCE_DIED_IN_TRANSIT, | 1086 EXPECT_EQ(BlobStatus::ERR_REFERENCED_BLOB_BROKEN, same_host_error_code); |
| 1206 same_host_error_code); | |
| 1207 EXPECT_FALSE(other_host_built); | 1087 EXPECT_FALSE(other_host_built); |
| 1208 EXPECT_EQ(IPCBlobCreationCancelCode::SOURCE_DIED_IN_TRANSIT, | 1088 EXPECT_EQ(BlobStatus::ERR_REFERENCED_BLOB_BROKEN, other_host_error_code); |
| 1209 other_host_error_code); | |
| 1210 | 1089 |
| 1211 sink_.ClearMessages(); | 1090 sink_.ClearMessages(); |
| 1212 } | 1091 } |
| 1213 | 1092 |
| 1214 } // namespace content | 1093 } // namespace content |
| OLD | NEW |