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, BlobStatus::ERR_OUT_OF_MEMORY); |
| 453 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
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, BlobStatus::ERR_OUT_OF_MEMORY); |
496 ExpectAndResetBadMessage(); | 482 ExpectAndResetBadMessage(); |
497 } | 483 } |
498 | 484 |
499 TEST_F(BlobDispatcherHostTest, BlobDataWithHostDeletion) { | 485 TEST_F(BlobDispatcherHostTest, BlobDataWithHostDeletion) { |
500 // Build up a basic blob. | 486 // Build up a basic blob. |
501 const std::string kId("id"); | 487 const std::string kId("id"); |
502 AsyncShortcutBlobTransfer(kId); | 488 AsyncShortcutBlobTransfer(kId); |
503 std::unique_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId); | 489 std::unique_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId); |
504 EXPECT_TRUE(handle); | 490 EXPECT_TRUE(handle); |
505 | 491 |
(...skipping 11 matching lines...) Expand all Loading... |
517 base::RunLoop().RunUntilIdle(); | 503 base::RunLoop().RunUntilIdle(); |
518 | 504 |
519 handle = context_->GetBlobDataFromUUID(kId); | 505 handle = context_->GetBlobDataFromUUID(kId); |
520 EXPECT_FALSE(handle); | 506 EXPECT_FALSE(handle); |
521 } | 507 } |
522 | 508 |
523 TEST_F(BlobDispatcherHostTest, BlobReferenceWhileConstructing) { | 509 TEST_F(BlobDispatcherHostTest, BlobReferenceWhileConstructing) { |
524 const std::string kId("id"); | 510 const std::string kId("id"); |
525 | 511 |
526 // Start building blob. | 512 // Start building blob. |
527 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 513 DataElement element; |
528 std::string(kContentDisposition), | 514 element.SetToBytesDescription(kDataSize); |
529 std::set<std::string>()); | 515 std::vector<DataElement> elements = {element}; |
| 516 host_->OnRegisterBlob(kId, std::string(kContentType), |
| 517 std::string(kContentDisposition), elements); |
530 | 518 |
531 // Grab the handle. | 519 // Grab the handle. |
532 std::unique_ptr<BlobDataHandle> blob_data_handle = | 520 std::unique_ptr<BlobDataHandle> blob_data_handle = |
533 context_->GetBlobDataFromUUID(kId); | 521 context_->GetBlobDataFromUUID(kId); |
534 EXPECT_TRUE(blob_data_handle); | 522 EXPECT_TRUE(blob_data_handle); |
535 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); | 523 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); |
536 bool built = false; | 524 bool built = false; |
537 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN; | 525 BlobStatus error_code = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS; |
538 blob_data_handle->RunOnConstructionComplete( | 526 blob_data_handle->RunOnConstructionComplete( |
539 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); | 527 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); |
540 | 528 |
541 // Continue building. | |
542 DataElement element; | |
543 element.SetToBytesDescription(kDataSize); | |
544 std::vector<DataElement> elements = {element}; | |
545 host_->OnStartBuildingBlob(kId, elements); | |
546 sink_.ClearMessages(); | 529 sink_.ClearMessages(); |
547 | 530 |
548 // Send data. | 531 // Send data. |
549 BlobItemBytesResponse response(0); | 532 BlobItemBytesResponse response(0); |
550 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); | 533 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); |
551 std::vector<BlobItemBytesResponse> responses = {response}; | 534 std::vector<BlobItemBytesResponse> responses = {response}; |
552 sink_.ClearMessages(); | 535 sink_.ClearMessages(); |
553 host_->OnMemoryItemResponse(kId, responses); | 536 host_->OnMemoryItemResponse(kId, responses); |
554 | 537 |
555 ExpectDone(kId); | 538 ExpectDone(kId); |
556 base::RunLoop().RunUntilIdle(); | 539 base::RunLoop().RunUntilIdle(); |
557 EXPECT_TRUE(built) << "Error code: " << static_cast<int>(error_code); | 540 EXPECT_TRUE(built) << "Error code: " << static_cast<int>(error_code); |
558 } | 541 } |
559 | 542 |
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) { | 543 TEST_F(BlobDispatcherHostTest, BlobReferenceWhileConstructingCancelled) { |
589 const std::string kId("id"); | 544 const std::string kId("id"); |
590 | 545 |
591 // Start building blob. | 546 // Start building blob. |
592 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 547 DataElement element; |
593 std::string(kContentDisposition), | 548 element.SetToBytesDescription(kDataSize); |
594 std::set<std::string>()); | 549 std::vector<DataElement> elements = {element}; |
| 550 host_->OnRegisterBlob(kId, std::string(kContentType), |
| 551 std::string(kContentDisposition), elements); |
595 | 552 |
596 // Grab the handle. | 553 // Grab the handle. |
597 std::unique_ptr<BlobDataHandle> blob_data_handle = | 554 std::unique_ptr<BlobDataHandle> blob_data_handle = |
598 context_->GetBlobDataFromUUID(kId); | 555 context_->GetBlobDataFromUUID(kId); |
599 EXPECT_TRUE(blob_data_handle); | 556 EXPECT_TRUE(blob_data_handle); |
600 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); | 557 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); |
601 bool built = true; | 558 bool built = true; |
602 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN; | 559 BlobStatus error_code = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS; |
603 blob_data_handle->RunOnConstructionComplete( | 560 blob_data_handle->RunOnConstructionComplete( |
604 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); | 561 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); |
605 | 562 |
606 // Cancel in middle of construction. | 563 // Cancel in middle of construction. |
607 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN); | 564 host_->OnCancelBuildingBlob(kId, BlobStatus::ERR_OUT_OF_MEMORY); |
608 base::RunLoop().RunUntilIdle(); | 565 base::RunLoop().RunUntilIdle(); |
609 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 566 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
610 EXPECT_TRUE(host_->IsInUseInHost(kId)); | 567 EXPECT_TRUE(host_->IsInUseInHost(kId)); |
611 EXPECT_FALSE(IsBeingBuiltInHost(kId)); | 568 EXPECT_FALSE(IsBeingBuiltInHost(kId)); |
612 EXPECT_TRUE(blob_data_handle->IsBroken()); | 569 EXPECT_TRUE(blob_data_handle->IsBroken()); |
613 EXPECT_FALSE(built); | 570 EXPECT_FALSE(built); |
614 EXPECT_EQ(IPCBlobCreationCancelCode::UNKNOWN, error_code); | 571 EXPECT_EQ(BlobStatus::ERR_OUT_OF_MEMORY, error_code); |
615 error_code = IPCBlobCreationCancelCode::UNKNOWN; | 572 error_code = BlobStatus::ERR_OUT_OF_MEMORY; |
616 built = true; | 573 built = true; |
617 blob_data_handle->RunOnConstructionComplete( | 574 blob_data_handle->RunOnConstructionComplete( |
618 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); | 575 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); |
619 EXPECT_FALSE(built); | 576 EXPECT_FALSE(built); |
620 EXPECT_EQ(IPCBlobCreationCancelCode::UNKNOWN, error_code); | 577 EXPECT_EQ(BlobStatus::ERR_OUT_OF_MEMORY, error_code); |
621 | 578 |
622 // Remove it. | 579 // Remove it. |
623 blob_data_handle.reset(); | 580 blob_data_handle.reset(); |
624 base::RunLoop().RunUntilIdle(); | 581 base::RunLoop().RunUntilIdle(); |
625 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 582 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
626 host_->OnDecrementBlobRefCount(kId); | 583 host_->OnDecrementBlobRefCount(kId); |
627 ExpectBlobNotExist(kId); | 584 ExpectBlobNotExist(kId); |
628 } | 585 } |
629 | 586 |
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) { | 587 TEST_F(BlobDispatcherHostTest, DecrementRefAfterOnStart) { |
672 const std::string kId("id"); | 588 const std::string kId("id"); |
673 | 589 |
674 // Decrement the refcount while building, after we call OnStartBuildlingBlob. | 590 // 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; | 591 DataElement element; |
680 element.SetToBytesDescription(kDataSize); | 592 element.SetToBytesDescription(kDataSize); |
681 std::vector<DataElement> elements = {element}; | 593 std::vector<DataElement> elements = {element}; |
682 host_->OnStartBuildingBlob(kId, elements); | 594 host_->OnRegisterBlob(kId, std::string(kContentType), |
| 595 std::string(kContentDisposition), elements); |
683 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 596 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
684 | 597 |
685 std::vector<BlobItemBytesRequest> expected_requests = { | 598 std::vector<BlobItemBytesRequest> expected_requests = { |
686 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; | 599 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; |
687 ExpectRequest(kId, expected_requests); | 600 ExpectRequest(kId, expected_requests); |
688 sink_.ClearMessages(); | 601 sink_.ClearMessages(); |
689 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 602 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
690 host_->OnDecrementBlobRefCount(kId); | 603 host_->OnDecrementBlobRefCount(kId); |
691 EXPECT_FALSE(context_->registry().HasEntry(kId)); | 604 EXPECT_FALSE(context_->registry().HasEntry(kId)); |
692 EXPECT_FALSE(IsBeingBuiltInHost(kId)); | 605 EXPECT_FALSE(IsBeingBuiltInHost(kId)); |
693 ExpectCancel(kId, | 606 ExpectCancel(kId, BlobStatus::ERR_BLOB_DEREFERENCED_WHILE_BUILDING); |
694 IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING); | |
695 sink_.ClearMessages(); | 607 sink_.ClearMessages(); |
696 | 608 |
697 // Do the same, but this time grab a handle to keep it alive. | 609 // Do the same, but this time grab a handle to keep it alive. |
698 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 610 host_->OnRegisterBlob(kId, std::string(kContentType), |
699 std::string(kContentDisposition), | 611 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_); | 612 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
704 ExpectRequest(kId, expected_requests); | 613 ExpectRequest(kId, expected_requests); |
705 sink_.ClearMessages(); | 614 sink_.ClearMessages(); |
706 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 615 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
707 // Grab the handle before decrementing. | 616 // Grab the handle before decrementing. |
708 std::unique_ptr<BlobDataHandle> blob_data_handle = | 617 std::unique_ptr<BlobDataHandle> blob_data_handle = |
709 context_->GetBlobDataFromUUID(kId); | 618 context_->GetBlobDataFromUUID(kId); |
710 host_->OnDecrementBlobRefCount(kId); | 619 host_->OnDecrementBlobRefCount(kId); |
711 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 620 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
712 EXPECT_TRUE(IsBeingBuiltInHost(kId)); | 621 EXPECT_TRUE(IsBeingBuiltInHost(kId)); |
| 622 EXPECT_EQ(0u, sink_.message_count()); |
713 | 623 |
714 // We finish the blob, and verify that we send 'Done' back to the renderer. | 624 // We finish the blob, and verify that we send 'Done' back to the renderer. |
715 BlobItemBytesResponse response(0); | 625 BlobItemBytesResponse response(0); |
716 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); | 626 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); |
717 std::vector<BlobItemBytesResponse> responses = {response}; | 627 std::vector<BlobItemBytesResponse> responses = {response}; |
718 host_->OnMemoryItemResponse(kId, responses); | 628 host_->OnMemoryItemResponse(kId, responses); |
719 ExpectDone(kId); | 629 ExpectDone(kId); |
720 sink_.ClearMessages(); | 630 sink_.ClearMessages(); |
721 // Check that it's still around. | 631 // Check that it's still around. |
722 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 632 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
723 EXPECT_FALSE(IsBeingBuiltInHost(kId)); | 633 EXPECT_FALSE(IsBeingBuiltInHost(kId)); |
724 | 634 |
725 // Get rid of the handle, and verify it's gone. | 635 // Get rid of the handle, and verify it's gone. |
726 blob_data_handle.reset(); | 636 blob_data_handle.reset(); |
727 base::RunLoop().RunUntilIdle(); | 637 base::RunLoop().RunUntilIdle(); |
728 // Check that it's no longer around. | 638 // Check that it's no longer around. |
729 EXPECT_FALSE(context_->registry().HasEntry(kId)); | 639 EXPECT_FALSE(context_->registry().HasEntry(kId)); |
730 EXPECT_FALSE(IsBeingBuiltInHost(kId)); | 640 EXPECT_FALSE(IsBeingBuiltInHost(kId)); |
731 } | 641 } |
732 | 642 |
733 TEST_F(BlobDispatcherHostTest, DecrementRefAfterOnStartWithHandle) { | 643 TEST_F(BlobDispatcherHostTest, DecrementRefAfterOnStartWithHandle) { |
734 const std::string kId("id"); | 644 const std::string kId("id"); |
735 // Decrement the refcount while building, after we call | 645 // Decrement the refcount while building, after we call |
736 // OnStartBuildlingBlob, except we have another handle. | 646 // OnStartBuildlingBlob, except we have another handle. |
737 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 647 DataElement element; |
738 std::string(kContentDisposition), | 648 element.SetToBytesDescription(kDataSize); |
739 std::set<std::string>()); | 649 std::vector<DataElement> elements = {element}; |
| 650 host_->OnRegisterBlob(kId, std::string(kContentType), |
| 651 std::string(kContentDisposition), elements); |
740 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 652 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
741 | 653 |
742 std::unique_ptr<BlobDataHandle> blob_data_handle = | 654 std::unique_ptr<BlobDataHandle> blob_data_handle = |
743 context_->GetBlobDataFromUUID(kId); | 655 context_->GetBlobDataFromUUID(kId); |
744 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); | 656 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); |
745 bool built = true; | 657 bool built = true; |
746 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN; | 658 BlobStatus error_code = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS; |
747 blob_data_handle->RunOnConstructionComplete( | 659 blob_data_handle->RunOnConstructionComplete( |
748 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); | 660 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); |
749 | 661 |
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. | 662 // Check that we got the expected request. |
757 std::vector<BlobItemBytesRequest> expected_requests = { | 663 std::vector<BlobItemBytesRequest> expected_requests = { |
758 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; | 664 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; |
759 ExpectRequest(kId, expected_requests); | 665 ExpectRequest(kId, expected_requests); |
760 sink_.ClearMessages(); | 666 sink_.ClearMessages(); |
761 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 667 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
762 EXPECT_TRUE(IsBeingBuiltInHost(kId)); | 668 EXPECT_TRUE(IsBeingBuiltInHost(kId)); |
763 // Decrement, simulating where the ref goes out of scope in renderer. | 669 // Decrement, simulating where the ref goes out of scope in renderer. |
764 host_->OnDecrementBlobRefCount(kId); | 670 host_->OnDecrementBlobRefCount(kId); |
765 // We still have the blob as it's not done. | 671 // We still have the blob as it's not done. |
766 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 672 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
767 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); | 673 EXPECT_TRUE(blob_data_handle->IsBeingBuilt()); |
768 EXPECT_TRUE(IsBeingBuiltInHost(kId)); | 674 EXPECT_TRUE(IsBeingBuiltInHost(kId)); |
769 // Cancel to clean up. | 675 // Cancel to clean up. |
770 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN); | 676 host_->OnCancelBuildingBlob(kId, BlobStatus::ERR_OUT_OF_MEMORY); |
771 // Run loop to propagate the handle decrement in the host. | 677 // Run loop to propagate the handle decrement in the host. |
772 base::RunLoop().RunUntilIdle(); | 678 base::RunLoop().RunUntilIdle(); |
773 // We still have the entry because of our earlier handle. | 679 // We still have the entry because of our earlier handle. |
774 EXPECT_TRUE(context_->registry().HasEntry(kId)); | 680 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
775 EXPECT_FALSE(IsBeingBuiltInHost(kId)); | 681 EXPECT_FALSE(IsBeingBuiltInHost(kId)); |
776 EXPECT_FALSE(built); | 682 EXPECT_FALSE(built); |
777 EXPECT_EQ(IPCBlobCreationCancelCode::UNKNOWN, error_code); | 683 EXPECT_EQ(BlobStatus::ERR_OUT_OF_MEMORY, error_code); |
778 sink_.ClearMessages(); | 684 sink_.ClearMessages(); |
779 | 685 |
780 // Should disappear after dropping the handle. | 686 // Should disappear after dropping the handle. |
781 EXPECT_TRUE(blob_data_handle->IsBroken()); | 687 EXPECT_TRUE(blob_data_handle->IsBroken()); |
782 blob_data_handle.reset(); | 688 blob_data_handle.reset(); |
783 base::RunLoop().RunUntilIdle(); | 689 base::RunLoop().RunUntilIdle(); |
784 EXPECT_FALSE(context_->registry().HasEntry(kId)); | 690 EXPECT_FALSE(context_->registry().HasEntry(kId)); |
785 } | 691 } |
786 | 692 |
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) { | 693 TEST_F(BlobDispatcherHostTest, HostDisconnectAfterOnStart) { |
822 const std::string kId("id"); | 694 const std::string kId("id"); |
823 | 695 |
824 // Host deleted after OnStartBuilding. | 696 // Host deleted after OnStartBuilding. |
825 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | |
826 std::string(kContentDisposition), | |
827 std::set<std::string>()); | |
828 | |
829 DataElement element; | 697 DataElement element; |
830 element.SetToBytesDescription(kDataSize); | 698 element.SetToBytesDescription(kDataSize); |
831 std::vector<DataElement> elements = {element}; | 699 std::vector<DataElement> elements = {element}; |
832 host_->OnStartBuildingBlob(kId, elements); | 700 host_->OnRegisterBlob(kId, std::string(kContentType), |
| 701 std::string(kContentDisposition), elements); |
833 | 702 |
834 std::vector<BlobItemBytesRequest> expected_requests = { | 703 std::vector<BlobItemBytesRequest> expected_requests = { |
835 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; | 704 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; |
836 ExpectRequest(kId, expected_requests); | 705 ExpectRequest(kId, expected_requests); |
837 sink_.ClearMessages(); | 706 sink_.ClearMessages(); |
838 host_ = nullptr; | 707 host_ = nullptr; |
839 // We need to run the message loop because of the handle in the async builder. | 708 // We need to run the message loop because of the handle in the async builder. |
840 base::RunLoop().RunUntilIdle(); | 709 base::RunLoop().RunUntilIdle(); |
841 EXPECT_FALSE(context_->registry().HasEntry(kId)); | 710 EXPECT_FALSE(context_->registry().HasEntry(kId)); |
842 } | 711 } |
843 | 712 |
844 TEST_F(BlobDispatcherHostTest, HostDisconnectAfterOnMemoryResponse) { | 713 TEST_F(BlobDispatcherHostTest, HostDisconnectAfterOnMemoryResponse) { |
845 const std::string kId("id"); | 714 const std::string kId("id"); |
846 | 715 |
847 // Host deleted after OnMemoryItemResponse. | 716 // 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; | 717 DataElement element; |
854 element.SetToBytesDescription(kDataSize); | 718 element.SetToBytesDescription(kDataSize); |
855 std::vector<DataElement> elements = {element, element}; | 719 std::vector<DataElement> elements = {element, element}; |
856 host_->OnStartBuildingBlob(kId, elements); | 720 host_->OnRegisterBlob(kId, std::string(kContentType), |
| 721 std::string(kContentDisposition), elements); |
| 722 |
| 723 // Create list of two items. |
857 std::vector<BlobItemBytesRequest> expected_requests = { | 724 std::vector<BlobItemBytesRequest> expected_requests = { |
858 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize), | 725 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize), |
859 BlobItemBytesRequest::CreateIPCRequest(1, 1, 0, kDataSize)}; | 726 BlobItemBytesRequest::CreateIPCRequest(1, 1, 0, kDataSize)}; |
860 ExpectRequest(kId, expected_requests); | 727 ExpectRequest(kId, expected_requests); |
861 sink_.ClearMessages(); | 728 sink_.ClearMessages(); |
862 | 729 |
863 // Send just one response so the blob isn't 'done' yet. | 730 // Send just one response so the blob isn't 'done' yet. |
864 BlobItemBytesResponse response(0); | 731 BlobItemBytesResponse response(0); |
865 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); | 732 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); |
866 std::vector<BlobItemBytesResponse> responses = {response}; | 733 std::vector<BlobItemBytesResponse> responses = {response}; |
867 host_->OnMemoryItemResponse(kId, responses); | 734 host_->OnMemoryItemResponse(kId, responses); |
868 EXPECT_EQ(0u, sink_.message_count()); | 735 EXPECT_EQ(0u, sink_.message_count()); |
869 | 736 |
870 host_ = nullptr; | 737 host_ = nullptr; |
871 base::RunLoop().RunUntilIdle(); | 738 base::RunLoop().RunUntilIdle(); |
872 EXPECT_FALSE(context_->registry().HasEntry(kId)); | 739 EXPECT_FALSE(context_->registry().HasEntry(kId)); |
873 } | 740 } |
874 | 741 |
875 TEST_F(BlobDispatcherHostTest, CreateBlobWithBrokenReference) { | 742 TEST_F(BlobDispatcherHostTest, CreateBlobWithBrokenReference) { |
876 const std::string kBrokenId("id1"); | 743 const std::string kBrokenId("id1"); |
877 const std::string kReferencingId("id2"); | 744 const std::string kReferencingId("id2"); |
878 | 745 |
879 // First, let's test a circular reference. | 746 // First, let's test a circular reference. |
880 const std::string kCircularId("id1"); | 747 const std::string kCircularId("id1"); |
881 host_->OnRegisterBlobUUID(kCircularId, std::string(kContentType), | 748 DataElement element; |
882 std::string(kContentDisposition), {kCircularId}); | 749 element.SetToBlob(kCircularId); |
| 750 std::vector<DataElement> elements = {element}; |
| 751 host_->OnRegisterBlob(kCircularId, std::string(kContentType), |
| 752 std::string(kContentDisposition), elements); |
883 ExpectAndResetBadMessage(); | 753 ExpectAndResetBadMessage(); |
| 754 // Remove the blob. |
| 755 host_->OnDecrementBlobRefCount(kCircularId); |
| 756 sink_.ClearMessages(); |
884 | 757 |
885 // Next, test a blob that references a broken blob. | 758 // Next, test a blob that references a broken blob. |
886 host_->OnRegisterBlobUUID(kBrokenId, std::string(kContentType), | 759 element.SetToBytesDescription(kDataSize); |
887 std::string(kContentDisposition), | 760 elements = {element}; |
888 std::set<std::string>()); | 761 host_->OnRegisterBlob(kBrokenId, std::string(kContentType), |
889 host_->OnCancelBuildingBlob(kBrokenId, IPCBlobCreationCancelCode::UNKNOWN); | 762 std::string(kContentDisposition), elements); |
890 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 763 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
| 764 sink_.ClearMessages(); |
| 765 host_->OnCancelBuildingBlob(kBrokenId, BlobStatus::ERR_OUT_OF_MEMORY); |
| 766 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
| 767 sink_.ClearMessages(); |
891 EXPECT_TRUE(context_->GetBlobDataFromUUID(kBrokenId)->IsBroken()); | 768 EXPECT_TRUE(context_->GetBlobDataFromUUID(kBrokenId)->IsBroken()); |
892 | 769 |
893 // Create referencing blob. We should be broken right away, but also ignore | 770 // Create referencing blob. We should be broken right away, but also ignore |
894 // the subsequent OnStart message. | 771 // the subsequent OnStart message. |
895 host_->OnRegisterBlobUUID(kReferencingId, std::string(kContentType), | 772 element.SetToBytesDescription(kDataSize); |
896 std::string(kContentDisposition), {kBrokenId}); | 773 elements = {element}; |
| 774 element.SetToBlob(kBrokenId); |
| 775 elements.push_back(element); |
| 776 host_->OnRegisterBlob(kReferencingId, std::string(kContentType), |
| 777 std::string(kContentDisposition), elements); |
897 EXPECT_TRUE(context_->GetBlobDataFromUUID(kReferencingId)->IsBroken()); | 778 EXPECT_TRUE(context_->GetBlobDataFromUUID(kReferencingId)->IsBroken()); |
898 EXPECT_FALSE(IsBeingBuiltInHost(kReferencingId)); | 779 EXPECT_FALSE(IsBeingBuiltInHost(kReferencingId)); |
899 EXPECT_TRUE(context_->registry().HasEntry(kReferencingId)); | 780 EXPECT_TRUE(context_->registry().HasEntry(kReferencingId)); |
900 ExpectCancel(kReferencingId, | 781 ExpectCancel(kReferencingId, BlobStatus::ERR_REFERENCED_BLOB_BROKEN); |
901 IPCBlobCreationCancelCode::REFERENCED_BLOB_BROKEN); | |
902 sink_.ClearMessages(); | 782 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 } | 783 } |
913 | 784 |
914 TEST_F(BlobDispatcherHostTest, DeferenceBlobOnDifferentHost) { | 785 TEST_F(BlobDispatcherHostTest, DeferenceBlobOnDifferentHost) { |
915 const std::string kId("id"); | 786 const std::string kId("id"); |
916 // Data elements for our transfer & checking messages. | 787 // Data elements for our transfer & checking messages. |
917 DataElement element; | 788 DataElement element; |
918 element.SetToBytesDescription(kDataSize); | 789 element.SetToBytesDescription(kDataSize); |
919 std::vector<DataElement> elements = {element}; | 790 std::vector<DataElement> elements = {element}; |
920 std::vector<BlobItemBytesRequest> expected_requests = { | 791 std::vector<BlobItemBytesRequest> expected_requests = { |
921 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; | 792 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; |
922 BlobItemBytesResponse response(0); | 793 BlobItemBytesResponse response(0); |
923 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); | 794 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); |
924 std::vector<BlobItemBytesResponse> responses = {response}; | 795 std::vector<BlobItemBytesResponse> responses = {response}; |
925 | 796 |
926 scoped_refptr<TestableBlobDispatcherHost> host2( | 797 scoped_refptr<TestableBlobDispatcherHost> host2( |
927 new TestableBlobDispatcherHost(chrome_blob_storage_context_, | 798 new TestableBlobDispatcherHost(chrome_blob_storage_context_, |
928 file_system_context_.get(), &sink_)); | 799 file_system_context_.get(), &sink_)); |
929 | 800 |
930 // Delete host with another host having a referencing, then dereference on | 801 // 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 | 802 // 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. | 803 // verify that a building message from the renderer will kill it. |
933 | 804 |
934 // Test OnStartBuilding after double dereference. | 805 // Test OnStartBuilding after double dereference. |
935 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 806 host_->OnRegisterBlob(kId, std::string(kContentType), |
936 std::string(kContentDisposition), | 807 std::string(kContentDisposition), elements); |
937 std::set<std::string>()); | 808 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
| 809 ExpectRequest(kId, expected_requests); |
| 810 sink_.ClearMessages(); |
938 host2->OnIncrementBlobRefCount(kId); | 811 host2->OnIncrementBlobRefCount(kId); |
939 host_->OnDecrementBlobRefCount(kId); | 812 host_->OnDecrementBlobRefCount(kId); |
940 EXPECT_FALSE(host_->IsInUseInHost(kId)); | 813 EXPECT_FALSE(host_->IsInUseInHost(kId)); |
941 host2->OnDecrementBlobRefCount(kId); | 814 host2->OnDecrementBlobRefCount(kId); |
942 // So no more blob in the context, but we're still being built in host 1. | 815 // Blob is gone as we've been decremented from both hosts. |
943 EXPECT_FALSE(context_->registry().HasEntry(kId)); | 816 EXPECT_FALSE(context_->registry().HasEntry(kId)); |
944 EXPECT_TRUE(host_->async_builder_.IsBeingBuilt(kId)); | 817 // Send the memory. When the host sees the entry doesn't exist, it should |
945 host_->OnStartBuildingBlob(kId, elements); | 818 // cancel and clean up. |
946 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 819 EXPECT_TRUE(host_->transport_host_.IsBeingBuilt(kId)); |
| 820 host_->OnMemoryItemResponse(kId, responses); |
947 // We should be cleaned up. | 821 // We should be cleaned up. |
948 EXPECT_FALSE(host_->async_builder_.IsBeingBuilt(kId)); | 822 EXPECT_FALSE(context_->registry().HasEntry(kId)); |
949 ExpectCancel(kId, | 823 EXPECT_FALSE(host_->transport_host_.IsBeingBuilt(kId)); |
950 IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING); | 824 ExpectCancel(kId, BlobStatus::ERR_BLOB_DEREFERENCED_WHILE_BUILDING); |
951 sink_.ClearMessages(); | 825 sink_.ClearMessages(); |
952 | 826 |
953 // Same as above, but test OnMemoryItemResponse after double dereference. | 827 // Same, but now for OnCancel. |
954 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 828 host_->OnRegisterBlob(kId, std::string(kContentType), |
955 std::string(kContentDisposition), | 829 std::string(kContentDisposition), elements); |
956 std::set<std::string>()); | |
957 host2->OnIncrementBlobRefCount(kId); | 830 host2->OnIncrementBlobRefCount(kId); |
958 host_->OnDecrementBlobRefCount(kId); | 831 host_->OnDecrementBlobRefCount(kId); |
959 EXPECT_FALSE(host_->IsInUseInHost(kId)); | 832 EXPECT_FALSE(host_->IsInUseInHost(kId)); |
960 host_->OnStartBuildingBlob(kId, elements); | |
961 ExpectRequest(kId, expected_requests); | 833 ExpectRequest(kId, expected_requests); |
962 sink_.ClearMessages(); | 834 sink_.ClearMessages(); |
963 | 835 |
964 host2->OnDecrementBlobRefCount(kId); | 836 host2->OnDecrementBlobRefCount(kId); |
965 // So no more blob in the context, but we're still being built in host 1. | 837 // Blob is gone as we've been decremented from both hosts. |
966 EXPECT_FALSE(context_->registry().HasEntry(kId)); | 838 EXPECT_FALSE(context_->registry().HasEntry(kId)); |
967 EXPECT_TRUE(host_->async_builder_.IsBeingBuilt(kId)); | 839 EXPECT_TRUE(host_->transport_host_.IsBeingBuilt(kId)); |
968 host_->OnMemoryItemResponse(kId, responses); | 840 host_->OnCancelBuildingBlob(kId, BlobStatus::ERR_OUT_OF_MEMORY); |
969 EXPECT_FALSE(host_->shutdown_for_bad_message_); | 841 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
| 842 EXPECT_FALSE(context_->registry().HasEntry(kId)); |
970 // We should be cleaned up. | 843 // We should be cleaned up. |
971 EXPECT_FALSE(host_->async_builder_.IsBeingBuilt(kId)); | 844 EXPECT_FALSE(host_->transport_host_.IsBeingBuilt(kId)); |
972 ExpectCancel(kId, | 845 ExpectCancel(kId, BlobStatus::ERR_BLOB_DEREFERENCED_WHILE_BUILDING); |
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 } | 846 } |
996 | 847 |
997 TEST_F(BlobDispatcherHostTest, BuildingReferenceChain) { | 848 TEST_F(BlobDispatcherHostTest, BuildingReferenceChain) { |
998 const std::string kId("id"); | 849 const std::string kId("id"); |
999 const std::string kSameHostReferencingId("id2"); | 850 const std::string kSameHostReferencingId("id2"); |
1000 const std::string kDifferentHostReferencingId("id3"); | 851 const std::string kDifferentHostReferencingId("id3"); |
1001 // Data elements for our transfer & checking messages. | 852 // Data elements for our transfer & checking messages. |
1002 DataElement element; | 853 DataElement element; |
1003 element.SetToBytes(kData, kDataSize); | 854 element.SetToBytesDescription(kDataSize); |
1004 std::vector<DataElement> elements = {element}; | |
1005 DataElement referencing_element; | 855 DataElement referencing_element; |
1006 referencing_element.SetToBlob(kId); | 856 referencing_element.SetToBlob(kId); |
| 857 std::vector<DataElement> elements = {element}; |
1007 std::vector<DataElement> referencing_elements = {referencing_element}; | 858 std::vector<DataElement> referencing_elements = {referencing_element}; |
1008 std::set<std::string> referenced_blobs_set = {kId}; | 859 std::vector<BlobItemBytesRequest> expected_requests = { |
| 860 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; |
| 861 BlobItemBytesResponse response(0); |
| 862 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); |
| 863 std::vector<BlobItemBytesResponse> responses = {response}; |
1009 | 864 |
1010 scoped_refptr<TestableBlobDispatcherHost> host2( | 865 scoped_refptr<TestableBlobDispatcherHost> host2( |
1011 new TestableBlobDispatcherHost(chrome_blob_storage_context_, | 866 new TestableBlobDispatcherHost(chrome_blob_storage_context_, |
1012 file_system_context_.get(), &sink_)); | 867 file_system_context_.get(), &sink_)); |
1013 | 868 |
1014 // We want to have a blob referencing another blob that is building, both on | 869 // 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 | 870 // the same host and a different host. We should successfully build all blobs |
1016 // after the referenced blob is finished. | 871 // after the referenced blob is finished. |
1017 | 872 |
1018 // First we start the referenced blob. | 873 // First we start the referenced blob. |
1019 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 874 host_->OnRegisterBlob(kId, std::string(kContentType), |
1020 std::string(kContentDisposition), | 875 std::string(kContentDisposition), elements); |
1021 std::set<std::string>()); | 876 ExpectRequest(kId, expected_requests); |
| 877 sink_.ClearMessages(); |
1022 EXPECT_TRUE(host_->IsInUseInHost(kId)); | 878 EXPECT_TRUE(host_->IsInUseInHost(kId)); |
| 879 EXPECT_TRUE(IsBeingBuiltInContext(kId)); |
1023 | 880 |
1024 // Next we start the referencing blobs in both the same and different host. | 881 // Next we start the referencing blobs in both the same and different host. |
1025 host_->OnRegisterBlobUUID(kSameHostReferencingId, std::string(kContentType), | 882 host_->OnRegisterBlob(kSameHostReferencingId, std::string(kContentType), |
1026 std::string(kContentDisposition), | 883 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_); | 884 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
1031 ExpectDone(kSameHostReferencingId); | 885 ExpectDone(kSameHostReferencingId); |
1032 EXPECT_TRUE(host_->async_builder_.IsBeingBuilt(kSameHostReferencingId)); | |
1033 sink_.ClearMessages(); | 886 sink_.ClearMessages(); |
| 887 EXPECT_FALSE( |
| 888 context_->GetBlobDataFromUUID(kSameHostReferencingId)->IsBroken()); |
| 889 EXPECT_FALSE(host_->transport_host_.IsBeingBuilt(kSameHostReferencingId)); |
| 890 EXPECT_TRUE(IsBeingBuiltInContext(kSameHostReferencingId)); |
| 891 |
1034 // Now the other host. | 892 // Now the other host. |
1035 host2->OnRegisterBlobUUID( | 893 host2->OnRegisterBlob(kDifferentHostReferencingId, std::string(kContentType), |
1036 kDifferentHostReferencingId, std::string(kContentType), | 894 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_); | 895 EXPECT_FALSE(host2->shutdown_for_bad_message_); |
1041 ExpectDone(kDifferentHostReferencingId); | 896 ExpectDone(kDifferentHostReferencingId); |
1042 EXPECT_TRUE(host2->async_builder_.IsBeingBuilt(kDifferentHostReferencingId)); | |
1043 sink_.ClearMessages(); | 897 sink_.ClearMessages(); |
| 898 EXPECT_FALSE( |
| 899 context_->GetBlobDataFromUUID(kDifferentHostReferencingId)->IsBroken()); |
| 900 EXPECT_FALSE( |
| 901 host2->transport_host_.IsBeingBuilt(kDifferentHostReferencingId)); |
| 902 EXPECT_TRUE(IsBeingBuiltInContext(kDifferentHostReferencingId)); |
1044 | 903 |
1045 // Now we finish the first blob, and we expect all blobs to finish. | 904 // Now we finish the first blob, and we expect all blobs to finish. |
1046 host_->OnStartBuildingBlob(kId, elements); | 905 host_->OnMemoryItemResponse(kId, responses); |
1047 ExpectDone(kId); | 906 ExpectDone(kId); |
1048 // We need to run the message loop to propagate the construction callbacks. | 907 // We need to run the message loop to propagate the construction callbacks. |
1049 base::RunLoop().RunUntilIdle(); | 908 base::RunLoop().RunUntilIdle(); |
1050 EXPECT_FALSE(host2->async_builder_.IsBeingBuilt(kDifferentHostReferencingId)); | 909 EXPECT_FALSE( |
1051 EXPECT_FALSE(host_->async_builder_.IsBeingBuilt(kSameHostReferencingId)); | 910 host2->transport_host_.IsBeingBuilt(kDifferentHostReferencingId)); |
| 911 EXPECT_FALSE(host_->transport_host_.IsBeingBuilt(kSameHostReferencingId)); |
1052 EXPECT_FALSE( | 912 EXPECT_FALSE( |
1053 context_->GetBlobDataFromUUID(kSameHostReferencingId)->IsBroken()); | 913 context_->GetBlobDataFromUUID(kSameHostReferencingId)->IsBroken()); |
1054 EXPECT_FALSE( | 914 EXPECT_FALSE( |
1055 context_->GetBlobDataFromUUID(kDifferentHostReferencingId)->IsBroken()); | 915 context_->GetBlobDataFromUUID(kDifferentHostReferencingId)->IsBroken()); |
1056 sink_.ClearMessages(); | 916 sink_.ClearMessages(); |
1057 | 917 |
1058 // Finally check that our data is correct in the child elements. | 918 // Finally check that our data is correct in the child elements. |
1059 std::unique_ptr<BlobDataHandle> handle = | 919 std::unique_ptr<BlobDataHandle> handle = |
1060 context_->GetBlobDataFromUUID(kDifferentHostReferencingId); | 920 context_->GetBlobDataFromUUID(kDifferentHostReferencingId); |
1061 ExpectHandleEqualsData(handle.get(), elements); | 921 DataElement expected; |
| 922 expected.SetToBytes(kData, kDataSize); |
| 923 std::vector<DataElement> expecteds = {expected}; |
| 924 ExpectHandleEqualsData(handle.get(), expecteds); |
1062 } | 925 } |
1063 | 926 |
1064 TEST_F(BlobDispatcherHostTest, BuildingReferenceChainWithCancel) { | 927 TEST_F(BlobDispatcherHostTest, BuildingReferenceChainWithCancel) { |
1065 const std::string kId("id"); | 928 const std::string kId("id"); |
1066 const std::string kSameHostReferencingId("id2"); | 929 const std::string kSameHostReferencingId("id2"); |
1067 const std::string kDifferentHostReferencingId("id3"); | 930 const std::string kDifferentHostReferencingId("id3"); |
1068 // Data elements for our transfer & checking messages. | 931 // Data elements for our transfer & checking messages. |
| 932 DataElement element; |
| 933 element.SetToBytesDescription(kDataSize); |
1069 DataElement referencing_element; | 934 DataElement referencing_element; |
1070 referencing_element.SetToBlob(kId); | 935 referencing_element.SetToBlob(kId); |
| 936 std::vector<DataElement> elements = {element}; |
1071 std::vector<DataElement> referencing_elements = {referencing_element}; | 937 std::vector<DataElement> referencing_elements = {referencing_element}; |
1072 std::set<std::string> referenced_blobs_set = {kId}; | 938 std::vector<BlobItemBytesRequest> expected_requests = { |
| 939 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; |
1073 | 940 |
1074 scoped_refptr<TestableBlobDispatcherHost> host2( | 941 scoped_refptr<TestableBlobDispatcherHost> host2( |
1075 new TestableBlobDispatcherHost(chrome_blob_storage_context_, | 942 new TestableBlobDispatcherHost(chrome_blob_storage_context_, |
1076 file_system_context_.get(), &sink_)); | 943 file_system_context_.get(), &sink_)); |
1077 | 944 |
1078 // We want to have a blob referencing another blob that is building, both on | 945 // 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 | 946 // the same host and a different host. We should successfully build all blobs |
1080 // others should cancel as well. | 947 // after the referenced blob is finished. |
1081 | 948 |
1082 // First we start the referenced blob. | 949 // First we start the referenced blob. |
1083 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 950 host_->OnRegisterBlob(kId, std::string(kContentType), |
1084 std::string(kContentDisposition), | 951 std::string(kContentDisposition), elements); |
1085 std::set<std::string>()); | 952 ExpectRequest(kId, expected_requests); |
| 953 sink_.ClearMessages(); |
1086 EXPECT_TRUE(host_->IsInUseInHost(kId)); | 954 EXPECT_TRUE(host_->IsInUseInHost(kId)); |
| 955 EXPECT_TRUE(IsBeingBuiltInContext(kId)); |
1087 | 956 |
1088 // Next we start the referencing blobs in both the same and different host. | 957 // Next we start the referencing blobs in both the same and different host. |
1089 host_->OnRegisterBlobUUID(kSameHostReferencingId, std::string(kContentType), | 958 host_->OnRegisterBlob(kSameHostReferencingId, std::string(kContentType), |
1090 std::string(kContentDisposition), | 959 std::string(kContentDisposition), referencing_elements); |
1091 referenced_blobs_set); | 960 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
1092 host_->OnStartBuildingBlob(kSameHostReferencingId, referencing_elements); | |
1093 ExpectDone(kSameHostReferencingId); | 961 ExpectDone(kSameHostReferencingId); |
1094 EXPECT_TRUE(host_->async_builder_.IsBeingBuilt(kSameHostReferencingId)); | |
1095 sink_.ClearMessages(); | 962 sink_.ClearMessages(); |
| 963 EXPECT_FALSE( |
| 964 context_->GetBlobDataFromUUID(kSameHostReferencingId)->IsBroken()); |
| 965 EXPECT_FALSE(host_->transport_host_.IsBeingBuilt(kSameHostReferencingId)); |
| 966 EXPECT_TRUE(IsBeingBuiltInContext(kSameHostReferencingId)); |
| 967 |
1096 // Now the other host. | 968 // Now the other host. |
1097 host2->OnRegisterBlobUUID( | 969 host2->OnRegisterBlob(kDifferentHostReferencingId, std::string(kContentType), |
1098 kDifferentHostReferencingId, std::string(kContentType), | 970 std::string(kContentDisposition), referencing_elements); |
1099 std::string(kContentDisposition), referenced_blobs_set); | 971 EXPECT_FALSE(host2->shutdown_for_bad_message_); |
1100 host2->OnStartBuildingBlob(kDifferentHostReferencingId, referencing_elements); | |
1101 ExpectDone(kDifferentHostReferencingId); | 972 ExpectDone(kDifferentHostReferencingId); |
1102 EXPECT_TRUE(host2->async_builder_.IsBeingBuilt(kDifferentHostReferencingId)); | |
1103 sink_.ClearMessages(); | 973 sink_.ClearMessages(); |
| 974 EXPECT_FALSE( |
| 975 context_->GetBlobDataFromUUID(kDifferentHostReferencingId)->IsBroken()); |
| 976 EXPECT_FALSE( |
| 977 host2->transport_host_.IsBeingBuilt(kDifferentHostReferencingId)); |
| 978 EXPECT_TRUE(IsBeingBuiltInContext(kDifferentHostReferencingId)); |
| 979 |
1104 bool built = false; | 980 bool built = false; |
1105 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN; | 981 BlobStatus error_code = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS; |
1106 context_->GetBlobDataFromUUID(kDifferentHostReferencingId) | 982 context_->GetBlobDataFromUUID(kDifferentHostReferencingId) |
1107 ->RunOnConstructionComplete( | 983 ->RunOnConstructionComplete( |
1108 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); | 984 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); |
1109 | 985 |
1110 // Now we cancel the first blob, and we expect all blobs to cancel. | 986 // Now we cancel the first blob, and we expect all blobs to cancel. |
1111 host_->OnCancelBuildingBlob(kId, IPCBlobCreationCancelCode::UNKNOWN); | 987 host_->OnCancelBuildingBlob(kId, BlobStatus::ERR_OUT_OF_MEMORY); |
1112 // We need to run the message loop to propagate the construction callbacks. | 988 // We need to run the message loop to propagate the construction callbacks. |
1113 base::RunLoop().RunUntilIdle(); | 989 base::RunLoop().RunUntilIdle(); |
1114 EXPECT_FALSE(host2->async_builder_.IsBeingBuilt(kDifferentHostReferencingId)); | 990 EXPECT_FALSE( |
1115 EXPECT_FALSE(host_->async_builder_.IsBeingBuilt(kSameHostReferencingId)); | 991 host2->transport_host_.IsBeingBuilt(kDifferentHostReferencingId)); |
| 992 EXPECT_FALSE(host_->transport_host_.IsBeingBuilt(kSameHostReferencingId)); |
1116 EXPECT_TRUE( | 993 EXPECT_TRUE( |
1117 context_->GetBlobDataFromUUID(kSameHostReferencingId)->IsBroken()); | 994 context_->GetBlobDataFromUUID(kSameHostReferencingId)->IsBroken()); |
1118 EXPECT_TRUE( | 995 EXPECT_TRUE( |
1119 context_->GetBlobDataFromUUID(kDifferentHostReferencingId)->IsBroken()); | 996 context_->GetBlobDataFromUUID(kDifferentHostReferencingId)->IsBroken()); |
1120 EXPECT_FALSE(built); | 997 EXPECT_FALSE(built); |
1121 EXPECT_EQ(IPCBlobCreationCancelCode::REFERENCED_BLOB_BROKEN, error_code); | 998 EXPECT_EQ(BlobStatus::ERR_REFERENCED_BLOB_BROKEN, error_code); |
1122 sink_.ClearMessages(); | 999 sink_.ClearMessages(); |
1123 } | 1000 } |
1124 | 1001 |
1125 TEST_F(BlobDispatcherHostTest, BuildingReferenceChainWithSourceDeath) { | 1002 TEST_F(BlobDispatcherHostTest, BuildingReferenceChainWithSourceDeath) { |
1126 const std::string kId("id"); | 1003 const std::string kId("id"); |
1127 const std::string kSameHostReferencingId("id2"); | 1004 const std::string kSameHostReferencingId("id2"); |
1128 const std::string kDifferentHostReferencingId("id3"); | 1005 const std::string kDifferentHostReferencingId("id3"); |
1129 // Data elements for our transfer & checking messages. | 1006 // Data elements for our transfer & checking messages. |
| 1007 DataElement element; |
| 1008 element.SetToBytesDescription(kDataSize); |
1130 DataElement referencing_element; | 1009 DataElement referencing_element; |
1131 referencing_element.SetToBlob(kId); | 1010 referencing_element.SetToBlob(kId); |
| 1011 std::vector<DataElement> elements = {element}; |
1132 std::vector<DataElement> referencing_elements = {referencing_element}; | 1012 std::vector<DataElement> referencing_elements = {referencing_element}; |
1133 std::set<std::string> referenced_blobs_set = {kId}; | 1013 std::vector<BlobItemBytesRequest> expected_requests = { |
| 1014 BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)}; |
| 1015 BlobItemBytesResponse response(0); |
| 1016 std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize); |
| 1017 std::vector<BlobItemBytesResponse> responses = {response}; |
1134 | 1018 |
1135 scoped_refptr<TestableBlobDispatcherHost> host2( | 1019 scoped_refptr<TestableBlobDispatcherHost> host2( |
1136 new TestableBlobDispatcherHost(chrome_blob_storage_context_, | 1020 new TestableBlobDispatcherHost(chrome_blob_storage_context_, |
1137 file_system_context_.get(), &sink_)); | 1021 file_system_context_.get(), &sink_)); |
1138 | 1022 |
1139 // We want to have a blob referencing another blob that is building, both on | 1023 // 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 | 1024 // 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. | 1025 // after the referenced blob is finished. |
1142 | 1026 |
1143 // First we start the referenced blob. | 1027 // First we start the referenced blob. |
1144 host_->OnRegisterBlobUUID(kId, std::string(kContentType), | 1028 host_->OnRegisterBlob(kId, std::string(kContentType), |
1145 std::string(kContentDisposition), | 1029 std::string(kContentDisposition), elements); |
1146 std::set<std::string>()); | 1030 ExpectRequest(kId, expected_requests); |
| 1031 sink_.ClearMessages(); |
1147 EXPECT_TRUE(host_->IsInUseInHost(kId)); | 1032 EXPECT_TRUE(host_->IsInUseInHost(kId)); |
| 1033 EXPECT_TRUE(IsBeingBuiltInContext(kId)); |
1148 | 1034 |
1149 // Next we start the referencing blobs in both the same and different host. | 1035 // Next we start the referencing blobs in both the same and different host. |
1150 host_->OnRegisterBlobUUID(kSameHostReferencingId, std::string(kContentType), | 1036 host_->OnRegisterBlob(kSameHostReferencingId, std::string(kContentType), |
1151 std::string(kContentDisposition), | 1037 std::string(kContentDisposition), referencing_elements); |
1152 referenced_blobs_set); | 1038 EXPECT_FALSE(host_->shutdown_for_bad_message_); |
1153 host_->OnStartBuildingBlob(kSameHostReferencingId, referencing_elements); | |
1154 ExpectDone(kSameHostReferencingId); | 1039 ExpectDone(kSameHostReferencingId); |
1155 EXPECT_TRUE(host_->async_builder_.IsBeingBuilt(kSameHostReferencingId)); | |
1156 sink_.ClearMessages(); | 1040 sink_.ClearMessages(); |
| 1041 |
1157 // Now the other host. | 1042 // Now the other host. |
1158 host2->OnRegisterBlobUUID( | 1043 host2->OnRegisterBlob(kDifferentHostReferencingId, std::string(kContentType), |
1159 kDifferentHostReferencingId, std::string(kContentType), | 1044 std::string(kContentDisposition), referencing_elements); |
1160 std::string(kContentDisposition), referenced_blobs_set); | 1045 EXPECT_FALSE(host2->shutdown_for_bad_message_); |
1161 host2->OnStartBuildingBlob(kDifferentHostReferencingId, referencing_elements); | |
1162 ExpectDone(kDifferentHostReferencingId); | 1046 ExpectDone(kDifferentHostReferencingId); |
1163 EXPECT_TRUE(host2->async_builder_.IsBeingBuilt(kDifferentHostReferencingId)); | |
1164 sink_.ClearMessages(); | 1047 sink_.ClearMessages(); |
1165 | 1048 |
1166 // Grab handles & add listeners. | 1049 // Grab handles & add listeners. |
1167 bool built = true; | 1050 bool built = true; |
1168 IPCBlobCreationCancelCode error_code = IPCBlobCreationCancelCode::UNKNOWN; | 1051 BlobStatus error_code = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS; |
1169 std::unique_ptr<BlobDataHandle> blob_handle = | 1052 std::unique_ptr<BlobDataHandle> blob_handle = |
1170 context_->GetBlobDataFromUUID(kId); | 1053 context_->GetBlobDataFromUUID(kId); |
1171 blob_handle->RunOnConstructionComplete( | 1054 blob_handle->RunOnConstructionComplete( |
1172 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); | 1055 base::Bind(&ConstructionCompletePopulator, &built, &error_code)); |
1173 | 1056 |
1174 bool same_host_built = true; | 1057 bool same_host_built = true; |
1175 IPCBlobCreationCancelCode same_host_error_code = | 1058 BlobStatus same_host_error_code = |
1176 IPCBlobCreationCancelCode::UNKNOWN; | 1059 BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS; |
1177 std::unique_ptr<BlobDataHandle> same_host_blob_handle = | 1060 std::unique_ptr<BlobDataHandle> same_host_blob_handle = |
1178 context_->GetBlobDataFromUUID(kSameHostReferencingId); | 1061 context_->GetBlobDataFromUUID(kSameHostReferencingId); |
1179 same_host_blob_handle->RunOnConstructionComplete(base::Bind( | 1062 same_host_blob_handle->RunOnConstructionComplete(base::Bind( |
1180 &ConstructionCompletePopulator, &same_host_built, &same_host_error_code)); | 1063 &ConstructionCompletePopulator, &same_host_built, &same_host_error_code)); |
1181 | 1064 |
1182 bool other_host_built = true; | 1065 bool other_host_built = true; |
1183 IPCBlobCreationCancelCode other_host_error_code = | 1066 BlobStatus other_host_error_code = |
1184 IPCBlobCreationCancelCode::UNKNOWN; | 1067 BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS; |
1185 std::unique_ptr<BlobDataHandle> other_host_blob_handle = | 1068 std::unique_ptr<BlobDataHandle> other_host_blob_handle = |
1186 context_->GetBlobDataFromUUID(kDifferentHostReferencingId); | 1069 context_->GetBlobDataFromUUID(kDifferentHostReferencingId); |
1187 other_host_blob_handle->RunOnConstructionComplete( | 1070 other_host_blob_handle->RunOnConstructionComplete( |
1188 base::Bind(&ConstructionCompletePopulator, &other_host_built, | 1071 base::Bind(&ConstructionCompletePopulator, &other_host_built, |
1189 &other_host_error_code)); | 1072 &other_host_error_code)); |
1190 | 1073 |
1191 // Now we kill the host. | 1074 // Now we kill the host. |
1192 host_ = nullptr; | 1075 host_ = nullptr; |
1193 // We need to run the message loop to propagate the construction callbacks. | 1076 // We need to run the message loop to propagate the construction callbacks. |
1194 base::RunLoop().RunUntilIdle(); | 1077 base::RunLoop().RunUntilIdle(); |
1195 EXPECT_FALSE(host2->async_builder_.IsBeingBuilt(kDifferentHostReferencingId)); | 1078 EXPECT_FALSE( |
| 1079 host2->transport_host_.IsBeingBuilt(kDifferentHostReferencingId)); |
1196 EXPECT_TRUE( | 1080 EXPECT_TRUE( |
1197 context_->GetBlobDataFromUUID(kSameHostReferencingId)->IsBroken()); | 1081 context_->GetBlobDataFromUUID(kSameHostReferencingId)->IsBroken()); |
1198 EXPECT_TRUE( | 1082 EXPECT_TRUE( |
1199 context_->GetBlobDataFromUUID(kDifferentHostReferencingId)->IsBroken()); | 1083 context_->GetBlobDataFromUUID(kDifferentHostReferencingId)->IsBroken()); |
1200 | 1084 |
1201 // Check our callbacks | 1085 // Check our callbacks |
1202 EXPECT_FALSE(built); | 1086 EXPECT_FALSE(built); |
1203 EXPECT_EQ(IPCBlobCreationCancelCode::SOURCE_DIED_IN_TRANSIT, error_code); | 1087 EXPECT_EQ(BlobStatus::ERR_SOURCE_DIED_IN_TRANSIT, error_code); |
1204 EXPECT_FALSE(same_host_built); | 1088 EXPECT_FALSE(same_host_built); |
1205 EXPECT_EQ(IPCBlobCreationCancelCode::SOURCE_DIED_IN_TRANSIT, | 1089 EXPECT_EQ(BlobStatus::ERR_REFERENCED_BLOB_BROKEN, same_host_error_code); |
1206 same_host_error_code); | |
1207 EXPECT_FALSE(other_host_built); | 1090 EXPECT_FALSE(other_host_built); |
1208 EXPECT_EQ(IPCBlobCreationCancelCode::SOURCE_DIED_IN_TRANSIT, | 1091 EXPECT_EQ(BlobStatus::ERR_REFERENCED_BLOB_BROKEN, other_host_error_code); |
1209 other_host_error_code); | |
1210 | 1092 |
1211 sink_.ClearMessages(); | 1093 sink_.ClearMessages(); |
1212 } | 1094 } |
1213 | 1095 |
1214 } // namespace content | 1096 } // namespace content |
OLD | NEW |