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