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