Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(582)

Side by Side Diff: content/browser/blob_storage/blob_dispatcher_host_unittest.cc

Issue 2448353002: [BlobAsync] Moving async handling into BlobStorageContext & quota out. (Closed)
Patch Set: comments Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « content/browser/blob_storage/blob_dispatcher_host.cc ('k') | content/browser/blob_storage/blob_flattener_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698