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

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

Issue 2448353002: [BlobAsync] Moving async handling into BlobStorageContext & quota out. (Closed)
Patch Set: hopefully fixed android/windows compile, and 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "storage/browser/blob/blob_async_builder_host.h"
6
7 #include <stddef.h> 5 #include <stddef.h>
8 #include <stdint.h> 6 #include <stdint.h>
9 #include <string.h> 7 #include <string.h>
10 8
11 #include "base/bind.h" 9 #include "base/bind.h"
12 #include "base/logging.h" 10 #include "base/logging.h"
13 #include "base/memory/shared_memory.h" 11 #include "base/memory/shared_memory.h"
14 #include "base/run_loop.h" 12 #include "base/run_loop.h"
15 #include "content/public/test/test_browser_thread_bundle.h" 13 #include "content/public/test/test_browser_thread_bundle.h"
16 #include "storage/browser/blob/blob_data_builder.h" 14 #include "storage/browser/blob/blob_data_builder.h"
17 #include "storage/browser/blob/blob_data_handle.h" 15 #include "storage/browser/blob/blob_data_handle.h"
18 #include "storage/browser/blob/blob_storage_context.h" 16 #include "storage/browser/blob/blob_storage_context.h"
17 #include "storage/browser/blob/blob_transport_host.h"
19 #include "storage/common/blob_storage/blob_storage_constants.h" 18 #include "storage/common/blob_storage/blob_storage_constants.h"
20 #include "testing/gtest/include/gtest/gtest.h" 19 #include "testing/gtest/include/gtest/gtest.h"
21 20
22 namespace storage { 21 namespace storage {
23 namespace { 22 namespace {
24 const std::string kBlobUUID = "blobUUIDYAY"; 23 const std::string kBlobUUID = "blobUUIDYAY";
25 const std::string kContentType = "content_type"; 24 const std::string kContentType = "content_type";
26 const std::string kContentDisposition = "content_disposition"; 25 const std::string kContentDisposition = "content_disposition";
27 const std::string kCompletedBlobUUID = "completedBlob"; 26 const std::string kCompletedBlobUUID = "completedBlob";
28 const std::string kCompletedBlobData = "completedBlobData"; 27 const std::string kCompletedBlobData = "completedBlobData";
29 28
30 const size_t kTestBlobStorageIPCThresholdBytes = 5; 29 const size_t kTestBlobStorageIPCThresholdBytes = 5;
31 const size_t kTestBlobStorageMaxSharedMemoryBytes = 20; 30 const size_t kTestBlobStorageMaxSharedMemoryBytes = 20;
31
32 const size_t kTestBlobStorageMaxBlobMemorySize = 400;
33 const uint64_t kTestBlobStorageMaxDiskSpace = 4000;
34 const uint64_t kTestBlobStorageMinFileSizeBytes = 10;
32 const uint64_t kTestBlobStorageMaxFileSizeBytes = 100; 35 const uint64_t kTestBlobStorageMaxFileSizeBytes = 100;
33 36
34 void PopulateBytes(char* bytes, size_t length) { 37 void PopulateBytes(char* bytes, size_t length) {
35 for (size_t i = 0; i < length; i++) { 38 for (size_t i = 0; i < length; i++) {
36 bytes[i] = static_cast<char>(i); 39 bytes[i] = static_cast<char>(i);
37 } 40 }
38 } 41 }
39 42
40 void AddMemoryItem(size_t length, std::vector<DataElement>* out) { 43 void AddMemoryItem(size_t length, std::vector<DataElement>* out) {
41 DataElement bytes; 44 DataElement bytes;
(...skipping 15 matching lines...) Expand all
57 out->AppendData(bytes.bytes(), length); 60 out->AppendData(bytes.bytes(), length);
58 } 61 }
59 62
60 void AddBlobItem(std::vector<DataElement>* out) { 63 void AddBlobItem(std::vector<DataElement>* out) {
61 DataElement blob; 64 DataElement blob;
62 blob.SetToBlob(kCompletedBlobUUID); 65 blob.SetToBlob(kCompletedBlobUUID);
63 out->push_back(blob); 66 out->push_back(blob);
64 } 67 }
65 } // namespace 68 } // namespace
66 69
67 class BlobAsyncBuilderHostTest : public testing::Test { 70 class BlobTransportHostTest : public testing::Test {
68 public: 71 public:
69 BlobAsyncBuilderHostTest() 72 BlobTransportHostTest()
70 : cancel_code_(IPCBlobCreationCancelCode::UNKNOWN), 73 : status_code_(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS),
71 request_called_(false) {} 74 request_called_(false) {}
72 ~BlobAsyncBuilderHostTest() override {} 75 ~BlobTransportHostTest() override {}
73 76
74 void SetUp() override { 77 void SetUp() override {
75 cancel_code_ = IPCBlobCreationCancelCode::UNKNOWN; 78 status_code_ = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS;
76 request_called_ = false; 79 request_called_ = false;
77 requests_.clear(); 80 requests_.clear();
78 memory_handles_.clear(); 81 memory_handles_.clear();
79 host_.SetMemoryConstantsForTesting(kTestBlobStorageIPCThresholdBytes, 82 storage::BlobStorageLimits limits;
80 kTestBlobStorageMaxSharedMemoryBytes, 83 limits.max_ipc_memory_size = kTestBlobStorageIPCThresholdBytes;
81 kTestBlobStorageMaxFileSizeBytes); 84 limits.max_shared_memory_size = kTestBlobStorageMaxSharedMemoryBytes;
85 limits.max_blob_in_memory_space = kTestBlobStorageMaxBlobMemorySize;
86 limits.max_blob_disk_space = kTestBlobStorageMaxDiskSpace;
87 limits.min_page_file_size = kTestBlobStorageMinFileSizeBytes;
88 limits.max_file_size = kTestBlobStorageMaxFileSizeBytes;
89 context_.mutable_memory_controller()->set_limits_for_testing(limits);
82 BlobDataBuilder builder(kCompletedBlobUUID); 90 BlobDataBuilder builder(kCompletedBlobUUID);
83 builder.AppendData(kCompletedBlobData); 91 builder.AppendData(kCompletedBlobData);
84 completed_blob_handle_ = context_.AddFinishedBlob(builder); 92 completed_blob_handle_ = context_.AddFinishedBlob(builder);
85 completed_blob_uuid_set_ = {kCompletedBlobUUID}; 93 EXPECT_EQ(BlobStatus::DONE, completed_blob_handle_->GetBlobStatus());
94 }
95
96 void StatusCallback(BlobStatus status) {
97 status_called_ = true;
98 status_code_ = status;
86 } 99 }
87 100
88 void RequestMemoryCallback( 101 void RequestMemoryCallback(
89 std::unique_ptr<std::vector<storage::BlobItemBytesRequest>> requests, 102 std::vector<storage::BlobItemBytesRequest> requests,
90 std::unique_ptr<std::vector<base::SharedMemoryHandle>> 103 std::vector<base::SharedMemoryHandle> shared_memory_handles,
91 shared_memory_handles, 104 std::vector<base::File> files) {
92 std::unique_ptr<std::vector<base::File>> files) { 105 requests_ = std::move(requests);
93 requests_ = std::move(*requests); 106 memory_handles_ = std::move(shared_memory_handles);
94 memory_handles_ = std::move(*shared_memory_handles);
95 request_called_ = true; 107 request_called_ = true;
96 } 108 }
97 109
98 BlobTransportResult BuildBlobAsync( 110 BlobStatus BuildBlobAsync(const std::string& uuid,
99 const std::vector<DataElement>& descriptions, 111 const std::vector<DataElement>& descriptions) {
100 const std::set<std::string>& referenced_blob_uuids,
101 size_t memory_available) {
102 request_called_ = false; 112 request_called_ = false;
103 BlobTransportResult register_result = 113 status_called_ = false;
104 host_.RegisterBlobUUID(kBlobUUID, kContentType, kContentDisposition, 114 host_.StartBuildingBlob(
105 referenced_blob_uuids, &context_); 115 uuid, kContentType, kContentDisposition, descriptions, &context_,
106 if (register_result != BlobTransportResult::DONE) { 116 base::Bind(&BlobTransportHostTest::RequestMemoryCallback,
107 return register_result; 117 base::Unretained(this)),
108 } 118 base::Bind(&BlobTransportHostTest::StatusCallback,
109 return host_.StartBuildingBlob(
110 kBlobUUID, descriptions, memory_available, &context_,
111 base::Bind(&BlobAsyncBuilderHostTest::RequestMemoryCallback,
112 base::Unretained(this))); 119 base::Unretained(this)));
120 if (status_called_)
121 return status_code_;
122 else
123 return context_.GetBlobStatus(uuid);
113 } 124 }
114 125
115 void DecrementBlobRefCount(const std::string& uuid) { 126 void DecrementBlobRefCount(const std::string& uuid) {
116 context_.DecrementBlobRefCount(uuid); 127 context_.DecrementBlobRefCount(uuid);
117 } 128 }
118 129
119 bool IsBeingBuiltInContext(const std::string& uuid) { 130 bool IsBeingBuiltInContext(const std::string& uuid) {
120 return context_.IsBeingBuilt(uuid); 131 return BlobStatusIsPending(context_.GetBlobStatus(uuid));
121 } 132 }
122 133
123 content::TestBrowserThreadBundle browser_thread_bundle_; 134 content::TestBrowserThreadBundle browser_thread_bundle_;
124 BlobStorageContext context_; 135 BlobStorageContext context_;
125 BlobAsyncBuilderHost host_; 136 BlobTransportHost host_;
126 IPCBlobCreationCancelCode cancel_code_; 137 bool status_called_;
138 BlobStatus status_code_;
127 139
128 bool request_called_; 140 bool request_called_;
129 std::vector<storage::BlobItemBytesRequest> requests_; 141 std::vector<storage::BlobItemBytesRequest> requests_;
130 std::vector<base::SharedMemoryHandle> memory_handles_; 142 std::vector<base::SharedMemoryHandle> memory_handles_;
131 std::set<std::string> completed_blob_uuid_set_;
132
133 std::unique_ptr<BlobDataHandle> completed_blob_handle_; 143 std::unique_ptr<BlobDataHandle> completed_blob_handle_;
134 }; 144 };
135 145
136 // The 'shortcut' method is when the data is included in the initial IPCs and 146 // The 'shortcut' method is when the data is included in the initial IPCs and
137 // the browser uses that instead of requesting the memory. 147 // the browser uses that instead of requesting the memory.
138 TEST_F(BlobAsyncBuilderHostTest, TestShortcut) { 148 TEST_F(BlobTransportHostTest, TestShortcut) {
139 std::vector<DataElement> descriptions; 149 std::vector<DataElement> descriptions;
140 150
141 AddShortcutMemoryItem(10, &descriptions); 151 AddShortcutMemoryItem(10, &descriptions);
142 AddBlobItem(&descriptions); 152 AddBlobItem(&descriptions);
143 AddShortcutMemoryItem(5000, &descriptions); 153 AddShortcutMemoryItem(300, &descriptions);
144 154
145 BlobDataBuilder expected(kBlobUUID); 155 BlobDataBuilder expected(kBlobUUID);
146 expected.set_content_type(kContentType); 156 expected.set_content_type(kContentType);
147 expected.set_content_disposition(kContentDisposition); 157 expected.set_content_disposition(kContentDisposition);
148 AddShortcutMemoryItem(10, &expected); 158 AddShortcutMemoryItem(10, &expected);
149 expected.AppendData(kCompletedBlobData); 159 expected.AppendData(kCompletedBlobData);
150 AddShortcutMemoryItem(5000, &expected); 160 AddShortcutMemoryItem(300, &expected);
151 161
152 EXPECT_EQ(BlobTransportResult::DONE, 162 EXPECT_EQ(BlobStatus::DONE, BuildBlobAsync(kBlobUUID, descriptions));
153 BuildBlobAsync(descriptions, completed_blob_uuid_set_, 5010));
154 163
155 EXPECT_FALSE(request_called_); 164 EXPECT_FALSE(request_called_);
156 EXPECT_EQ(0u, host_.blob_building_count()); 165 EXPECT_EQ(0u, host_.blob_building_count());
157 std::unique_ptr<BlobDataHandle> handle = 166 std::unique_ptr<BlobDataHandle> handle =
158 context_.GetBlobDataFromUUID(kBlobUUID); 167 context_.GetBlobDataFromUUID(kBlobUUID);
159 EXPECT_FALSE(handle->IsBeingBuilt()); 168 EXPECT_FALSE(handle->IsBeingBuilt());
160 EXPECT_FALSE(handle->IsBroken()); 169 ASSERT_FALSE(handle->IsBroken());
161 std::unique_ptr<BlobDataSnapshot> data = handle->CreateSnapshot(); 170 std::unique_ptr<BlobDataSnapshot> data = handle->CreateSnapshot();
162 EXPECT_EQ(expected, *data); 171 EXPECT_EQ(expected, *data);
163 data.reset(); 172 data.reset();
164 handle.reset(); 173 handle.reset();
165 base::RunLoop().RunUntilIdle(); 174 base::RunLoop().RunUntilIdle();
166 }; 175 };
167 176
168 TEST_F(BlobAsyncBuilderHostTest, TestShortcutNoRoom) { 177 TEST_F(BlobTransportHostTest, TestShortcutNoRoom) {
169 std::vector<DataElement> descriptions; 178 std::vector<DataElement> descriptions;
170 179
171 AddShortcutMemoryItem(10, &descriptions); 180 AddShortcutMemoryItem(10, &descriptions);
172 AddBlobItem(&descriptions); 181 AddBlobItem(&descriptions);
173 AddShortcutMemoryItem(5000, &descriptions); 182 AddShortcutMemoryItem(5000, &descriptions);
174 183
175 EXPECT_EQ(BlobTransportResult::CANCEL_MEMORY_FULL, 184 EXPECT_EQ(BlobStatus::ERR_OUT_OF_MEMORY,
176 BuildBlobAsync(descriptions, completed_blob_uuid_set_, 5000)); 185 BuildBlobAsync(kBlobUUID, descriptions));
177 186
178 EXPECT_FALSE(request_called_); 187 EXPECT_FALSE(request_called_);
179 EXPECT_EQ(0u, host_.blob_building_count()); 188 EXPECT_EQ(0u, host_.blob_building_count());
180 }; 189 };
181 190
182 TEST_F(BlobAsyncBuilderHostTest, TestSingleSharedMemRequest) { 191 TEST_F(BlobTransportHostTest, TestSingleSharedMemRequest) {
183 std::vector<DataElement> descriptions; 192 std::vector<DataElement> descriptions;
184 const size_t kSize = kTestBlobStorageIPCThresholdBytes + 1; 193 const size_t kSize = kTestBlobStorageIPCThresholdBytes + 1;
185 AddMemoryItem(kSize, &descriptions); 194 AddMemoryItem(kSize, &descriptions);
186 195
187 EXPECT_EQ(BlobTransportResult::PENDING_RESPONSES, 196 EXPECT_EQ(BlobStatus::PENDING_TRANSPORT,
188 BuildBlobAsync(descriptions, std::set<std::string>(), 197 BuildBlobAsync(kBlobUUID, descriptions));
189 kTestBlobStorageIPCThresholdBytes + 1));
190 198
191 EXPECT_TRUE(request_called_); 199 EXPECT_TRUE(request_called_);
192 EXPECT_EQ(1u, host_.blob_building_count()); 200 EXPECT_EQ(1u, host_.blob_building_count());
193 ASSERT_EQ(1u, requests_.size()); 201 ASSERT_EQ(1u, requests_.size());
194 request_called_ = false; 202 request_called_ = false;
195 203
196 EXPECT_EQ( 204 EXPECT_EQ(
197 BlobItemBytesRequest::CreateSharedMemoryRequest(0, 0, 0, kSize, 0, 0), 205 BlobItemBytesRequest::CreateSharedMemoryRequest(0, 0, 0, kSize, 0, 0),
198 requests_.at(0)); 206 requests_.at(0));
199 }; 207 };
200 208
201 TEST_F(BlobAsyncBuilderHostTest, TestMultipleSharedMemRequests) { 209 TEST_F(BlobTransportHostTest, TestMultipleSharedMemRequests) {
202 std::vector<DataElement> descriptions; 210 std::vector<DataElement> descriptions;
203 const size_t kSize = kTestBlobStorageMaxSharedMemoryBytes + 1; 211 const size_t kSize = kTestBlobStorageMaxSharedMemoryBytes + 1;
204 const char kFirstBlockByte = 7; 212 const char kFirstBlockByte = 7;
205 const char kSecondBlockByte = 19; 213 const char kSecondBlockByte = 19;
206 AddMemoryItem(kSize, &descriptions); 214 AddMemoryItem(kSize, &descriptions);
207 215
208 BlobDataBuilder expected(kBlobUUID); 216 BlobDataBuilder expected(kBlobUUID);
209 expected.set_content_type(kContentType); 217 expected.set_content_type(kContentType);
210 expected.set_content_disposition(kContentDisposition); 218 expected.set_content_disposition(kContentDisposition);
211 char data[kSize]; 219 char data[kSize];
212 memset(data, kFirstBlockByte, kTestBlobStorageMaxSharedMemoryBytes); 220 memset(data, kFirstBlockByte, kTestBlobStorageMaxSharedMemoryBytes);
213 expected.AppendData(data, kTestBlobStorageMaxSharedMemoryBytes); 221 expected.AppendData(data, kTestBlobStorageMaxSharedMemoryBytes);
214 expected.AppendData(&kSecondBlockByte, 1); 222 expected.AppendData(&kSecondBlockByte, 1);
215 223
216 EXPECT_EQ(BlobTransportResult::PENDING_RESPONSES, 224 EXPECT_EQ(BlobStatus::PENDING_TRANSPORT,
217 BuildBlobAsync(descriptions, std::set<std::string>(), 225 BuildBlobAsync(kBlobUUID, descriptions));
218 kTestBlobStorageMaxSharedMemoryBytes + 1));
219 226
220 EXPECT_TRUE(request_called_); 227 EXPECT_TRUE(request_called_);
221 EXPECT_EQ(1u, host_.blob_building_count()); 228 EXPECT_EQ(1u, host_.blob_building_count());
222 ASSERT_EQ(1u, requests_.size()); 229 ASSERT_EQ(1u, requests_.size());
223 request_called_ = false; 230 request_called_ = false;
224 231
225 // We need to grab a duplicate handle so we can have two blocks open at the 232 // We need to grab a duplicate handle so we can have two blocks open at the
226 // same time. 233 // same time.
227 base::SharedMemoryHandle handle = 234 base::SharedMemoryHandle handle =
228 base::SharedMemory::DuplicateHandle(memory_handles_.at(0)); 235 base::SharedMemory::DuplicateHandle(memory_handles_.at(0));
229 EXPECT_TRUE(base::SharedMemory::IsHandleValid(handle)); 236 EXPECT_TRUE(base::SharedMemory::IsHandleValid(handle));
230 base::SharedMemory shared_memory(handle, false); 237 base::SharedMemory shared_memory(handle, false);
231 EXPECT_TRUE(shared_memory.Map(kTestBlobStorageMaxSharedMemoryBytes)); 238 EXPECT_TRUE(shared_memory.Map(kTestBlobStorageMaxSharedMemoryBytes));
232 239
233 EXPECT_EQ(BlobItemBytesRequest::CreateSharedMemoryRequest( 240 EXPECT_EQ(BlobItemBytesRequest::CreateSharedMemoryRequest(
234 0, 0, 0, kTestBlobStorageMaxSharedMemoryBytes, 0, 0), 241 0, 0, 0, kTestBlobStorageMaxSharedMemoryBytes, 0, 0),
235 requests_.at(0)); 242 requests_.at(0));
236 243
237 memset(shared_memory.memory(), kFirstBlockByte, 244 memset(shared_memory.memory(), kFirstBlockByte,
238 kTestBlobStorageMaxSharedMemoryBytes); 245 kTestBlobStorageMaxSharedMemoryBytes);
239 246
240 BlobItemBytesResponse response(0); 247 BlobItemBytesResponse response(0);
241 std::vector<BlobItemBytesResponse> responses = {response}; 248 std::vector<BlobItemBytesResponse> responses = {response};
242 EXPECT_EQ(BlobTransportResult::PENDING_RESPONSES, 249 EXPECT_EQ(BlobStatus::PENDING_TRANSPORT,
243 host_.OnMemoryResponses(kBlobUUID, responses, &context_)); 250 host_.OnMemoryResponses(kBlobUUID, responses, &context_));
244 251
245 EXPECT_TRUE(request_called_); 252 EXPECT_TRUE(request_called_);
246 EXPECT_EQ(1u, host_.blob_building_count()); 253 EXPECT_EQ(1u, host_.blob_building_count());
247 ASSERT_EQ(1u, requests_.size()); 254 ASSERT_EQ(1u, requests_.size());
248 request_called_ = false; 255 request_called_ = false;
249 256
250 EXPECT_EQ(BlobItemBytesRequest::CreateSharedMemoryRequest( 257 EXPECT_EQ(BlobItemBytesRequest::CreateSharedMemoryRequest(
251 1, 0, kTestBlobStorageMaxSharedMemoryBytes, 1, 0, 0), 258 1, 0, kTestBlobStorageMaxSharedMemoryBytes, 1, 0, 0),
252 requests_.at(0)); 259 requests_.at(0));
253 260
254 memset(shared_memory.memory(), kSecondBlockByte, 1); 261 memset(shared_memory.memory(), kSecondBlockByte, 1);
255 262
256 response.request_number = 1; 263 response.request_number = 1;
257 responses[0] = response; 264 responses[0] = response;
258 EXPECT_EQ(BlobTransportResult::DONE, 265 EXPECT_EQ(BlobStatus::DONE,
259 host_.OnMemoryResponses(kBlobUUID, responses, &context_)); 266 host_.OnMemoryResponses(kBlobUUID, responses, &context_));
260 EXPECT_FALSE(request_called_); 267 EXPECT_FALSE(request_called_);
261 EXPECT_EQ(0u, host_.blob_building_count()); 268 EXPECT_EQ(0u, host_.blob_building_count());
262 std::unique_ptr<BlobDataHandle> blob_handle = 269 std::unique_ptr<BlobDataHandle> blob_handle =
263 context_.GetBlobDataFromUUID(kBlobUUID); 270 context_.GetBlobDataFromUUID(kBlobUUID);
264 EXPECT_FALSE(blob_handle->IsBeingBuilt()); 271 EXPECT_FALSE(blob_handle->IsBeingBuilt());
265 EXPECT_FALSE(blob_handle->IsBroken()); 272 EXPECT_FALSE(blob_handle->IsBroken());
266 std::unique_ptr<BlobDataSnapshot> blob_data = blob_handle->CreateSnapshot(); 273 std::unique_ptr<BlobDataSnapshot> blob_data = blob_handle->CreateSnapshot();
267 EXPECT_EQ(expected, *blob_data); 274 EXPECT_EQ(expected, *blob_data);
268 }; 275 };
269 276
270 TEST_F(BlobAsyncBuilderHostTest, TestBasicIPCAndStopBuilding) { 277 TEST_F(BlobTransportHostTest, TestBasicIPCAndStopBuilding) {
271 std::vector<DataElement> descriptions; 278 std::vector<DataElement> descriptions;
272 279
273 AddMemoryItem(2, &descriptions); 280 AddMemoryItem(2, &descriptions);
274 AddBlobItem(&descriptions); 281 AddBlobItem(&descriptions);
275 AddMemoryItem(2, &descriptions); 282 AddMemoryItem(2, &descriptions);
276 283
277 BlobDataBuilder expected(kBlobUUID); 284 BlobDataBuilder expected(kBlobUUID);
278 expected.set_content_type(kContentType); 285 expected.set_content_type(kContentType);
279 expected.set_content_disposition(kContentDisposition); 286 expected.set_content_disposition(kContentDisposition);
280 AddShortcutMemoryItem(2, &expected); 287 AddShortcutMemoryItem(2, &expected);
281 expected.AppendData(kCompletedBlobData); 288 expected.AppendData(kCompletedBlobData);
282 AddShortcutMemoryItem(2, &expected); 289 AddShortcutMemoryItem(2, &expected);
283 290
284 EXPECT_EQ(BlobTransportResult::PENDING_RESPONSES, 291 EXPECT_EQ(BlobStatus::PENDING_TRANSPORT,
285 BuildBlobAsync(descriptions, completed_blob_uuid_set_, 5010)); 292 BuildBlobAsync(kBlobUUID, descriptions));
286 host_.CancelBuildingBlob(kBlobUUID, IPCBlobCreationCancelCode::UNKNOWN, 293 host_.CancelBuildingBlob(kBlobUUID, BlobStatus::ERR_OUT_OF_MEMORY, &context_);
287 &context_);
288 294
289 // Check that we're broken, and then remove the blob. 295 // Check that we're broken, and then remove the blob.
290 std::unique_ptr<BlobDataHandle> blob_handle = 296 std::unique_ptr<BlobDataHandle> blob_handle =
291 context_.GetBlobDataFromUUID(kBlobUUID); 297 context_.GetBlobDataFromUUID(kBlobUUID);
292 EXPECT_FALSE(blob_handle->IsBeingBuilt()); 298 EXPECT_FALSE(blob_handle->IsBeingBuilt());
293 EXPECT_TRUE(blob_handle->IsBroken()); 299 EXPECT_TRUE(blob_handle->IsBroken());
294 blob_handle.reset(); 300 blob_handle.reset();
295 DecrementBlobRefCount(kBlobUUID); 301 DecrementBlobRefCount(kBlobUUID);
296 base::RunLoop().RunUntilIdle(); 302 base::RunLoop().RunUntilIdle();
297 blob_handle = context_.GetBlobDataFromUUID(kBlobUUID); 303 blob_handle = context_.GetBlobDataFromUUID(kBlobUUID);
298 EXPECT_FALSE(blob_handle.get()); 304 EXPECT_FALSE(blob_handle.get());
299 305
300 // This should succeed because we've removed all references to the blob. 306 // This should succeed because we've removed all references to the blob.
301 EXPECT_EQ(BlobTransportResult::PENDING_RESPONSES, 307 EXPECT_EQ(BlobStatus::PENDING_TRANSPORT,
302 BuildBlobAsync(descriptions, completed_blob_uuid_set_, 5010)); 308 BuildBlobAsync(kBlobUUID, descriptions));
303 309
304 EXPECT_TRUE(request_called_); 310 EXPECT_TRUE(request_called_);
305 EXPECT_EQ(1u, host_.blob_building_count()); 311 EXPECT_EQ(1u, host_.blob_building_count());
306 request_called_ = false; 312 request_called_ = false;
307 313
308 BlobItemBytesResponse response1(0); 314 BlobItemBytesResponse response1(0);
309 PopulateBytes(response1.allocate_mutable_data(2), 2); 315 PopulateBytes(response1.allocate_mutable_data(2), 2);
310 BlobItemBytesResponse response2(1); 316 BlobItemBytesResponse response2(1);
311 PopulateBytes(response2.allocate_mutable_data(2), 2); 317 PopulateBytes(response2.allocate_mutable_data(2), 2);
312 std::vector<BlobItemBytesResponse> responses = {response1, response2}; 318 std::vector<BlobItemBytesResponse> responses = {response1, response2};
313 319
314 EXPECT_EQ(BlobTransportResult::DONE, 320 EXPECT_EQ(BlobStatus::DONE,
315 host_.OnMemoryResponses(kBlobUUID, responses, &context_)); 321 host_.OnMemoryResponses(kBlobUUID, responses, &context_));
316 EXPECT_FALSE(request_called_); 322 EXPECT_FALSE(request_called_);
317 EXPECT_EQ(0u, host_.blob_building_count()); 323 EXPECT_EQ(0u, host_.blob_building_count());
318 blob_handle = context_.GetBlobDataFromUUID(kBlobUUID); 324 blob_handle = context_.GetBlobDataFromUUID(kBlobUUID);
319 EXPECT_FALSE(blob_handle->IsBeingBuilt()); 325 EXPECT_FALSE(blob_handle->IsBeingBuilt());
320 EXPECT_FALSE(blob_handle->IsBroken()); 326 EXPECT_FALSE(blob_handle->IsBroken());
321 std::unique_ptr<BlobDataSnapshot> blob_data = blob_handle->CreateSnapshot(); 327 std::unique_ptr<BlobDataSnapshot> blob_data = blob_handle->CreateSnapshot();
322 EXPECT_EQ(expected, *blob_data); 328 EXPECT_EQ(expected, *blob_data);
323 }; 329 };
324 330
325 TEST_F(BlobAsyncBuilderHostTest, TestBreakingAllBuilding) { 331 TEST_F(BlobTransportHostTest, TestBreakingAllBuilding) {
326 const std::string& kBlob1 = "blob1"; 332 const std::string& kBlob1 = "blob1";
327 const std::string& kBlob2 = "blob2"; 333 const std::string& kBlob2 = "blob2";
328 const std::string& kBlob3 = "blob3"; 334 const std::string& kBlob3 = "blob3";
329 335
330 // Register blobs.
331 EXPECT_EQ(BlobTransportResult::DONE,
332 host_.RegisterBlobUUID(kBlob1, kContentType, kContentDisposition,
333 std::set<std::string>(), &context_));
334 EXPECT_EQ(BlobTransportResult::DONE,
335 host_.RegisterBlobUUID(kBlob2, kContentType, kContentDisposition,
336 std::set<std::string>(), &context_));
337 EXPECT_EQ(BlobTransportResult::DONE,
338 host_.RegisterBlobUUID(kBlob3, kContentType, kContentDisposition,
339 std::set<std::string>(), &context_));
340
341 // Start building one of them.
342 std::vector<DataElement> descriptions; 336 std::vector<DataElement> descriptions;
343 AddMemoryItem(2, &descriptions); 337 AddMemoryItem(2, &descriptions);
344 EXPECT_EQ(BlobTransportResult::PENDING_RESPONSES, 338
345 host_.StartBuildingBlob( 339 // Register blobs.
346 kBlob1, descriptions, 2, &context_, 340 EXPECT_EQ(BlobStatus::PENDING_TRANSPORT,
347 base::Bind(&BlobAsyncBuilderHostTest::RequestMemoryCallback, 341 BuildBlobAsync(kBlob1, descriptions));
348 base::Unretained(this)))); 342 EXPECT_EQ(BlobStatus::PENDING_TRANSPORT,
343 BuildBlobAsync(kBlob2, descriptions));
344 EXPECT_EQ(BlobStatus::PENDING_TRANSPORT,
345 BuildBlobAsync(kBlob3, descriptions));
346
349 EXPECT_TRUE(request_called_); 347 EXPECT_TRUE(request_called_);
350 348
351 std::unique_ptr<BlobDataHandle> blob_handle1 = 349 std::unique_ptr<BlobDataHandle> blob_handle1 =
352 context_.GetBlobDataFromUUID(kBlob1); 350 context_.GetBlobDataFromUUID(kBlob1);
353 std::unique_ptr<BlobDataHandle> blob_handle2 = 351 std::unique_ptr<BlobDataHandle> blob_handle2 =
354 context_.GetBlobDataFromUUID(kBlob2); 352 context_.GetBlobDataFromUUID(kBlob2);
355 std::unique_ptr<BlobDataHandle> blob_handle3 = 353 std::unique_ptr<BlobDataHandle> blob_handle3 =
356 context_.GetBlobDataFromUUID(kBlob2); 354 context_.GetBlobDataFromUUID(kBlob2);
357 EXPECT_TRUE(blob_handle1->IsBeingBuilt() && blob_handle2->IsBeingBuilt() && 355 EXPECT_TRUE(blob_handle1->IsBeingBuilt() && blob_handle2->IsBeingBuilt() &&
358 blob_handle3->IsBeingBuilt()); 356 blob_handle3->IsBeingBuilt());
359 EXPECT_FALSE(blob_handle1->IsBroken() || blob_handle2->IsBroken() || 357 EXPECT_FALSE(blob_handle1->IsBroken() || blob_handle2->IsBroken() ||
360 blob_handle3->IsBroken()); 358 blob_handle3->IsBroken());
361 359
362 host_.CancelAll(&context_); 360 host_.CancelAll(&context_);
363 361
364 EXPECT_FALSE(blob_handle1->IsBeingBuilt() || blob_handle2->IsBeingBuilt() || 362 EXPECT_FALSE(blob_handle1->IsBeingBuilt() || blob_handle2->IsBeingBuilt() ||
365 blob_handle3->IsBeingBuilt()); 363 blob_handle3->IsBeingBuilt());
366 EXPECT_TRUE(blob_handle1->IsBroken() && blob_handle2->IsBroken() && 364 EXPECT_TRUE(blob_handle1->IsBroken() && blob_handle2->IsBroken() &&
367 blob_handle3->IsBroken()); 365 blob_handle3->IsBroken());
368 blob_handle1.reset(); 366 blob_handle1.reset();
369 blob_handle2.reset(); 367 blob_handle2.reset();
370 blob_handle3.reset(); 368 blob_handle3.reset();
371 base::RunLoop().RunUntilIdle(); 369 base::RunLoop().RunUntilIdle();
372 }; 370 };
373 371
374 TEST_F(BlobAsyncBuilderHostTest, TestBadIPCs) { 372 TEST_F(BlobTransportHostTest, TestBadIPCs) {
375 std::vector<DataElement> descriptions; 373 std::vector<DataElement> descriptions;
376 374
377 // Test reusing same blob uuid. 375 // Test reusing same blob uuid.
378 AddMemoryItem(10, &descriptions); 376 AddMemoryItem(10, &descriptions);
379 AddBlobItem(&descriptions); 377 AddBlobItem(&descriptions);
380 AddMemoryItem(5000, &descriptions); 378 AddMemoryItem(300, &descriptions);
381 EXPECT_EQ(BlobTransportResult::PENDING_RESPONSES, 379 EXPECT_EQ(BlobStatus::PENDING_TRANSPORT,
382 BuildBlobAsync(descriptions, completed_blob_uuid_set_, 5010)); 380 BuildBlobAsync(kBlobUUID, descriptions));
383 EXPECT_EQ(BlobTransportResult::BAD_IPC, 381 EXPECT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS,
384 BuildBlobAsync(descriptions, completed_blob_uuid_set_, 5010)); 382 BuildBlobAsync(kBlobUUID, descriptions));
385 EXPECT_FALSE(request_called_); 383 EXPECT_FALSE(request_called_);
386 host_.CancelBuildingBlob(kBlobUUID, IPCBlobCreationCancelCode::UNKNOWN, 384 host_.CancelBuildingBlob(kBlobUUID, BlobStatus::ERR_REFERENCED_BLOB_BROKEN,
387 &context_); 385 &context_);
388 base::RunLoop().RunUntilIdle(); 386 base::RunLoop().RunUntilIdle();
389 DecrementBlobRefCount(kBlobUUID); 387 DecrementBlobRefCount(kBlobUUID);
390 EXPECT_FALSE(context_.GetBlobDataFromUUID(kBlobUUID).get()); 388 EXPECT_FALSE(context_.GetBlobDataFromUUID(kBlobUUID).get());
391 389
392 // Test we're an error if we get a bad uuid for responses. 390 // Test we're an error if we get a bad uuid for responses.
393 BlobItemBytesResponse response(0); 391 BlobItemBytesResponse response(0);
394 std::vector<BlobItemBytesResponse> responses = {response}; 392 std::vector<BlobItemBytesResponse> responses = {response};
395 EXPECT_EQ(BlobTransportResult::BAD_IPC, 393 EXPECT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS,
396 host_.OnMemoryResponses(kBlobUUID, responses, &context_)); 394 host_.OnMemoryResponses(kBlobUUID, responses, &context_));
397 395
398 // Test empty responses. 396 // Test empty responses.
399 responses.clear(); 397 responses.clear();
400 EXPECT_EQ(BlobTransportResult::BAD_IPC, 398 EXPECT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS,
401 host_.OnMemoryResponses(kBlobUUID, responses, &context_)); 399 host_.OnMemoryResponses(kBlobUUID, responses, &context_));
402 400
403 // Test response problems below here. 401 // Test response problems below here.
404 descriptions.clear(); 402 descriptions.clear();
405 AddMemoryItem(2, &descriptions); 403 AddMemoryItem(2, &descriptions);
406 AddBlobItem(&descriptions); 404 AddBlobItem(&descriptions);
407 AddMemoryItem(2, &descriptions); 405 AddMemoryItem(2, &descriptions);
408 EXPECT_EQ(BlobTransportResult::PENDING_RESPONSES, 406 EXPECT_EQ(BlobStatus::PENDING_TRANSPORT,
409 BuildBlobAsync(descriptions, completed_blob_uuid_set_, 5010)); 407 BuildBlobAsync(kBlobUUID, descriptions));
410 408
411 // Invalid request number. 409 // Invalid request number.
412 BlobItemBytesResponse response1(3); 410 BlobItemBytesResponse response1(3);
413 PopulateBytes(response1.allocate_mutable_data(2), 2); 411 PopulateBytes(response1.allocate_mutable_data(2), 2);
414 responses = {response1}; 412 responses = {response1};
415 EXPECT_EQ(BlobTransportResult::BAD_IPC, 413 EXPECT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS,
416 host_.OnMemoryResponses(kBlobUUID, responses, &context_)); 414 host_.OnMemoryResponses(kBlobUUID, responses, &context_));
417 EXPECT_TRUE(context_.GetBlobDataFromUUID(kBlobUUID)->IsBroken()); 415 EXPECT_TRUE(context_.GetBlobDataFromUUID(kBlobUUID)->IsBroken());
418 DecrementBlobRefCount(kBlobUUID); 416 DecrementBlobRefCount(kBlobUUID);
419 base::RunLoop().RunUntilIdle(); 417 base::RunLoop().RunUntilIdle();
420 418
421 // Duplicate request number responses. 419 // Duplicate request number responses.
422 EXPECT_EQ(BlobTransportResult::PENDING_RESPONSES, 420 EXPECT_EQ(BlobStatus::PENDING_TRANSPORT,
423 BuildBlobAsync(descriptions, completed_blob_uuid_set_, 5010)); 421 BuildBlobAsync(kBlobUUID, descriptions));
424 response1.request_number = 0; 422 response1.request_number = 0;
425 BlobItemBytesResponse response2(0); 423 BlobItemBytesResponse response2(0);
426 PopulateBytes(response2.allocate_mutable_data(2), 2); 424 PopulateBytes(response2.allocate_mutable_data(2), 2);
427 responses = {response1, response2}; 425 responses = {response1, response2};
428 EXPECT_EQ(BlobTransportResult::BAD_IPC, 426 EXPECT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS,
429 host_.OnMemoryResponses(kBlobUUID, responses, &context_)); 427 host_.OnMemoryResponses(kBlobUUID, responses, &context_));
430 EXPECT_TRUE(context_.GetBlobDataFromUUID(kBlobUUID)->IsBroken()); 428 EXPECT_TRUE(context_.GetBlobDataFromUUID(kBlobUUID)->IsBroken());
431 DecrementBlobRefCount(kBlobUUID); 429 DecrementBlobRefCount(kBlobUUID);
432 base::RunLoop().RunUntilIdle(); 430 base::RunLoop().RunUntilIdle();
433 }; 431 };
434 432
435 TEST_F(BlobAsyncBuilderHostTest, WaitOnReferencedBlob) { 433 TEST_F(BlobTransportHostTest, WaitOnReferencedBlob) {
436 const std::string& kBlob1 = "blob1"; 434 const std::string& kBlob1 = "blob1";
437 const std::string& kBlob2 = "blob2"; 435 const std::string& kBlob2 = "blob2";
438 const std::string& kBlob3 = "blob3"; 436 const std::string& kBlob3 = "blob3";
439 437
438 std::vector<DataElement> descriptions;
439 AddMemoryItem(2, &descriptions);
440
440 // Register blobs. 441 // Register blobs.
441 EXPECT_EQ(BlobTransportResult::DONE, 442 EXPECT_EQ(BlobStatus::PENDING_TRANSPORT,
442 host_.RegisterBlobUUID(kBlob1, kContentType, kContentDisposition, 443 BuildBlobAsync(kBlob1, descriptions));
443 std::set<std::string>(), &context_)); 444 EXPECT_EQ(BlobStatus::PENDING_TRANSPORT,
444 EXPECT_EQ(BlobTransportResult::DONE, 445 BuildBlobAsync(kBlob2, descriptions));
445 host_.RegisterBlobUUID(kBlob2, kContentType, kContentDisposition, 446 EXPECT_TRUE(request_called_);
446 std::set<std::string>(), &context_)); 447 request_called_ = false;
447 EXPECT_EQ(BlobTransportResult::DONE,
448 host_.RegisterBlobUUID(kBlob3, kContentType, kContentDisposition,
449 {kBlob1, kBlob2}, &context_));
450 448
451 // Finish the third one, with a reference to the first and second blob. 449 // Finish the third one, with a reference to the first and second blob.
452 std::vector<DataElement> descriptions;
453 AddShortcutMemoryItem(2, &descriptions);
454 DataElement element; 450 DataElement element;
455 element.SetToBlob(kBlob1); 451 element.SetToBlob(kBlob1);
456 descriptions.push_back(element); 452 descriptions.push_back(element);
457 element.SetToBlob(kBlob2); 453 element.SetToBlob(kBlob2);
458 descriptions.push_back(element); 454 descriptions.push_back(element);
459 455
456 EXPECT_EQ(BlobStatus::PENDING_TRANSPORT,
457 BuildBlobAsync(kBlob3, descriptions));
458 EXPECT_TRUE(request_called_);
459 request_called_ = false;
460
460 // Finish the third, but we should still be 'building' it. 461 // Finish the third, but we should still be 'building' it.
461 EXPECT_EQ(BlobTransportResult::DONE, 462 BlobItemBytesResponse response1(0);
462 host_.StartBuildingBlob( 463 PopulateBytes(response1.allocate_mutable_data(2), 2);
463 kBlob3, descriptions, 2, &context_, 464 std::vector<BlobItemBytesResponse> responses = {response1};
464 base::Bind(&BlobAsyncBuilderHostTest::RequestMemoryCallback, 465 EXPECT_EQ(BlobStatus::DONE,
465 base::Unretained(this)))); 466 host_.OnMemoryResponses(kBlob3, responses, &context_));
466 EXPECT_FALSE(request_called_); 467 EXPECT_FALSE(request_called_);
467 EXPECT_TRUE(host_.IsBeingBuilt(kBlob3)); 468 EXPECT_FALSE(host_.IsBeingBuilt(kBlob3));
468 EXPECT_TRUE(IsBeingBuiltInContext(kBlob3)); 469 EXPECT_TRUE(IsBeingBuiltInContext(kBlob3));
469 470
470 // Finish the first. 471 // Finish the first.
471 descriptions.clear(); 472 descriptions.clear();
472 AddShortcutMemoryItem(2, &descriptions); 473 AddShortcutMemoryItem(2, &descriptions);
473 EXPECT_EQ(BlobTransportResult::DONE, 474 EXPECT_EQ(BlobStatus::DONE,
474 host_.StartBuildingBlob( 475 host_.OnMemoryResponses(kBlob1, responses, &context_));
475 kBlob1, descriptions, 2, &context_,
476 base::Bind(&BlobAsyncBuilderHostTest::RequestMemoryCallback,
477 base::Unretained(this))));
478 EXPECT_FALSE(request_called_); 476 EXPECT_FALSE(request_called_);
479 EXPECT_FALSE(host_.IsBeingBuilt(kBlob1)); 477 EXPECT_FALSE(host_.IsBeingBuilt(kBlob1));
480 EXPECT_FALSE(IsBeingBuiltInContext(kBlob1)); 478 EXPECT_FALSE(IsBeingBuiltInContext(kBlob1));
481 EXPECT_TRUE(context_.GetBlobDataFromUUID(kBlob1)); 479 EXPECT_TRUE(context_.GetBlobDataFromUUID(kBlob1));
482 480
483 // Run the message loop so we propogate the construction complete callbacks. 481 // Run the message loop so we propogate the construction complete callbacks.
484 base::RunLoop().RunUntilIdle(); 482 base::RunLoop().RunUntilIdle();
485 // Verify we're not done. 483 // Verify we're not done.
486 EXPECT_TRUE(host_.IsBeingBuilt(kBlob3));
487 EXPECT_TRUE(IsBeingBuiltInContext(kBlob3)); 484 EXPECT_TRUE(IsBeingBuiltInContext(kBlob3));
488 485
489 // Finish the second. 486 // Finish the second.
490 EXPECT_EQ(BlobTransportResult::DONE, 487 EXPECT_EQ(BlobStatus::DONE,
491 host_.StartBuildingBlob( 488 host_.OnMemoryResponses(kBlob2, responses, &context_));
492 kBlob2, descriptions, 2, &context_,
493 base::Bind(&BlobAsyncBuilderHostTest::RequestMemoryCallback,
494 base::Unretained(this))));
495 EXPECT_FALSE(request_called_); 489 EXPECT_FALSE(request_called_);
496 EXPECT_FALSE(host_.IsBeingBuilt(kBlob2)); 490 EXPECT_FALSE(host_.IsBeingBuilt(kBlob2));
497 EXPECT_FALSE(IsBeingBuiltInContext(kBlob2)); 491 EXPECT_FALSE(IsBeingBuiltInContext(kBlob2));
498 EXPECT_TRUE(context_.GetBlobDataFromUUID(kBlob2)); 492 EXPECT_TRUE(context_.GetBlobDataFromUUID(kBlob2));
499 493
500 // Run the message loop so we propogate the construction complete callbacks. 494 // Run the message loop so we propogate the construction complete callbacks.
501 base::RunLoop().RunUntilIdle(); 495 base::RunLoop().RunUntilIdle();
502 // Finally, we should be finished with third blob. 496 // Finally, we should be finished with third blob.
503 EXPECT_FALSE(host_.IsBeingBuilt(kBlob3)); 497 EXPECT_FALSE(host_.IsBeingBuilt(kBlob3));
504 EXPECT_FALSE(IsBeingBuiltInContext(kBlob3)); 498 EXPECT_FALSE(IsBeingBuiltInContext(kBlob3));
505 EXPECT_TRUE(context_.GetBlobDataFromUUID(kBlob3)); 499 EXPECT_TRUE(context_.GetBlobDataFromUUID(kBlob3));
506 }; 500 };
507 501
508 TEST_F(BlobAsyncBuilderHostTest, IncorrectBlobDependencies) {
509 const std::string& kGoodBlob = "goodBlob";
510 const std::string& kBlob1 = "blob1";
511 const std::string& kBlob2 = "blob2";
512 const std::string& kBlob3 = "blob3";
513
514 // Register blobs. Blob 1 has a reference to itself, Blob 2 has a reference
515 // but doesn't use it, and blob 3 doesn't list it's reference.
516 EXPECT_EQ(BlobTransportResult::DONE,
517 host_.RegisterBlobUUID(kGoodBlob, kContentType, kContentDisposition,
518 std::set<std::string>(), &context_));
519 EXPECT_EQ(BlobTransportResult::BAD_IPC,
520 host_.RegisterBlobUUID(kBlob1, kContentType, kContentDisposition,
521 {kBlob1}, &context_));
522 EXPECT_EQ(BlobTransportResult::DONE,
523 host_.RegisterBlobUUID(kBlob2, kContentType, kContentDisposition,
524 {kGoodBlob}, &context_));
525 EXPECT_EQ(BlobTransportResult::DONE,
526 host_.RegisterBlobUUID(kBlob3, kContentType, kContentDisposition,
527 std::set<std::string>(), &context_));
528
529 // The first blob shouldn't be building anymore.
530 EXPECT_FALSE(host_.IsBeingBuilt(kBlob1));
531
532 // Try to finish the second one, without a reference to the first.
533 std::vector<DataElement> descriptions;
534 AddShortcutMemoryItem(2, &descriptions);
535 EXPECT_EQ(BlobTransportResult::BAD_IPC,
536 host_.StartBuildingBlob(
537 kBlob2, descriptions, 2, &context_,
538 base::Bind(&BlobAsyncBuilderHostTest::RequestMemoryCallback,
539 base::Unretained(this))));
540 EXPECT_FALSE(host_.IsBeingBuilt(kBlob2));
541
542 // Try to finish the third one with the reference we didn't declare earlier.
543 descriptions.clear();
544 AddShortcutMemoryItem(2, &descriptions);
545 DataElement element;
546 element.SetToBlob(kGoodBlob);
547 descriptions.push_back(element);
548 EXPECT_EQ(BlobTransportResult::BAD_IPC,
549 host_.StartBuildingBlob(
550 kBlob3, descriptions, 2, &context_,
551 base::Bind(&BlobAsyncBuilderHostTest::RequestMemoryCallback,
552 base::Unretained(this))));
553 EXPECT_FALSE(host_.IsBeingBuilt(kBlob3));
554 };
555
556 TEST_F(BlobAsyncBuilderHostTest, BlobBreaksWhenReferenceBreaks) {
557 const std::string& kBlob1 = "blob1";
558 const std::string& kBlob2 = "blob2";
559
560 // Register blobs.
561 EXPECT_EQ(BlobTransportResult::DONE,
562 host_.RegisterBlobUUID(kBlob1, kContentType, kContentDisposition,
563 std::set<std::string>(), &context_));
564 EXPECT_EQ(BlobTransportResult::DONE,
565 host_.RegisterBlobUUID(kBlob2, kContentType, kContentDisposition,
566 {kBlob1}, &context_));
567
568 // Finish the second one, with a reference to the first.
569 std::vector<DataElement> descriptions;
570 AddShortcutMemoryItem(2, &descriptions);
571 DataElement element;
572 element.SetToBlob(kBlob1);
573 descriptions.push_back(element);
574 EXPECT_EQ(BlobTransportResult::DONE,
575 host_.StartBuildingBlob(
576 kBlob2, descriptions, 2, &context_,
577 base::Bind(&BlobAsyncBuilderHostTest::RequestMemoryCallback,
578 base::Unretained(this))));
579 EXPECT_FALSE(request_called_);
580 EXPECT_TRUE(host_.IsBeingBuilt(kBlob2));
581 EXPECT_TRUE(IsBeingBuiltInContext(kBlob2));
582
583 // Break the first.
584 descriptions.clear();
585 host_.CancelBuildingBlob(kBlob1, IPCBlobCreationCancelCode::UNKNOWN,
586 &context_);
587 EXPECT_FALSE(host_.IsBeingBuilt(kBlob1));
588 EXPECT_FALSE(IsBeingBuiltInContext(kBlob1));
589 EXPECT_TRUE(context_.GetBlobDataFromUUID(kBlob1)->IsBroken());
590
591 // Run the message loop so we propogate the construction complete callbacks.
592 base::RunLoop().RunUntilIdle();
593 // We should be finished with third blob, and it should be broken.
594 EXPECT_FALSE(host_.IsBeingBuilt(kBlob2));
595 EXPECT_FALSE(IsBeingBuiltInContext(kBlob2));
596 EXPECT_TRUE(context_.GetBlobDataFromUUID(kBlob2)->IsBroken());
597 };
598
599 TEST_F(BlobAsyncBuilderHostTest, BlobBreaksWhenReferenceBroken) {
600 const std::string& kBlob1 = "blob1";
601 const std::string& kBlob2 = "blob2";
602
603 // Register blobs.
604 EXPECT_EQ(BlobTransportResult::DONE,
605 host_.RegisterBlobUUID(kBlob1, kContentType, kContentDisposition,
606 std::set<std::string>(), &context_));
607 host_.CancelBuildingBlob(kBlob1, IPCBlobCreationCancelCode::UNKNOWN,
608 &context_);
609 EXPECT_EQ(BlobTransportResult::CANCEL_REFERENCED_BLOB_BROKEN,
610 host_.RegisterBlobUUID(kBlob2, kContentType, kContentDisposition,
611 {kBlob1}, &context_));
612 EXPECT_FALSE(host_.IsBeingBuilt(kBlob2));
613 EXPECT_FALSE(IsBeingBuiltInContext(kBlob2));
614 EXPECT_TRUE(context_.GetBlobDataFromUUID(kBlob2)->IsBroken());
615 };
616
617 } // namespace storage 502 } // namespace storage
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698