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

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

Issue 1234813004: [BlobAsync] Asynchronous Blob Construction Final Patch (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@blob-protocol-change
Patch Set: comments/fixes Created 4 years, 10 months 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" 5 #include "storage/browser/blob/blob_async_builder_host.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 #include <string.h> 9 #include <string.h>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/memory/shared_memory.h" 13 #include "base/memory/shared_memory.h"
14 #include "base/run_loop.h"
15 #include "content/public/test/test_browser_thread_bundle.h"
16 #include "storage/browser/blob/blob_data_builder.h"
17 #include "storage/browser/blob/blob_data_handle.h"
18 #include "storage/browser/blob/blob_storage_context.h"
14 #include "storage/common/blob_storage/blob_storage_constants.h" 19 #include "storage/common/blob_storage/blob_storage_constants.h"
15 #include "testing/gtest/include/gtest/gtest.h" 20 #include "testing/gtest/include/gtest/gtest.h"
16 21
17 namespace storage { 22 namespace storage {
18 namespace { 23 namespace {
19 const std::string kBlobUUID = "blobUUIDYAY"; 24 const std::string kBlobUUID = "blobUUIDYAY";
20 const std::string kFakeBlobUUID = "fakeBlob"; 25 const std::string kContentType = "content_type";
21 const std::string kBlobType = "blobtypeYAY"; 26 const std::string kContentDisposition = "content_disposition";
27 const std::string kCompletedBlobUUID = "completedBlob";
28 const std::string kCompletedBlobData = "completedBlobData";
22 29
23 const size_t kTestBlobStorageIPCThresholdBytes = 5; 30 const size_t kTestBlobStorageIPCThresholdBytes = 5;
24 const size_t kTestBlobStorageMaxSharedMemoryBytes = 20; 31 const size_t kTestBlobStorageMaxSharedMemoryBytes = 20;
25 const uint64_t kTestBlobStorageMaxFileSizeBytes = 100; 32 const uint64_t kTestBlobStorageMaxFileSizeBytes = 100;
26 33
27 void PopulateBytes(char* bytes, size_t length) { 34 void PopulateBytes(char* bytes, size_t length) {
28 for (size_t i = 0; i < length; i++) { 35 for (size_t i = 0; i < length; i++) {
29 bytes[i] = static_cast<char>(i); 36 bytes[i] = static_cast<char>(i);
30 } 37 }
31 } 38 }
(...skipping 13 matching lines...) Expand all
45 52
46 void AddShortcutMemoryItem(size_t length, BlobDataBuilder* out) { 53 void AddShortcutMemoryItem(size_t length, BlobDataBuilder* out) {
47 DataElement bytes; 54 DataElement bytes;
48 bytes.SetToAllocatedBytes(length); 55 bytes.SetToAllocatedBytes(length);
49 PopulateBytes(bytes.mutable_bytes(), length); 56 PopulateBytes(bytes.mutable_bytes(), length);
50 out->AppendData(bytes.bytes(), length); 57 out->AppendData(bytes.bytes(), length);
51 } 58 }
52 59
53 void AddBlobItem(std::vector<DataElement>* out) { 60 void AddBlobItem(std::vector<DataElement>* out) {
54 DataElement blob; 61 DataElement blob;
55 blob.SetToBlob(kFakeBlobUUID); 62 blob.SetToBlob(kCompletedBlobUUID);
56 out->push_back(blob); 63 out->push_back(blob);
57 } 64 }
65 } // namespace
58 66
59 class BlobAsyncBuilderHostTest : public testing::Test { 67 class BlobAsyncBuilderHostTest : public testing::Test {
60 protected: 68 public:
61 BlobAsyncBuilderHostTest() 69 BlobAsyncBuilderHostTest()
62 : matching_builder_(nullptr), 70 : cancel_code_(IPCBlobCreationCancelCode::UNKNOWN),
63 done_called_(false),
64 cancel_called_(false),
65 cancel_code_(IPCBlobCreationCancelCode::UNKNOWN),
66 request_called_(false) {} 71 request_called_(false) {}
67 ~BlobAsyncBuilderHostTest() override {} 72 ~BlobAsyncBuilderHostTest() override {}
68 73
69 void SetUp() override { 74 void SetUp() override {
70 matching_builder_ = nullptr;
71 done_called_ = false;
72 cancel_called_ = false;
73 cancel_code_ = IPCBlobCreationCancelCode::UNKNOWN; 75 cancel_code_ = IPCBlobCreationCancelCode::UNKNOWN;
74 request_called_ = false; 76 request_called_ = false;
75 requests_.clear(); 77 requests_.clear();
76 memory_handles_.clear(); 78 memory_handles_.clear();
77 file_handles_.clear();
78 host_.SetMemoryConstantsForTesting(kTestBlobStorageIPCThresholdBytes, 79 host_.SetMemoryConstantsForTesting(kTestBlobStorageIPCThresholdBytes,
79 kTestBlobStorageMaxSharedMemoryBytes, 80 kTestBlobStorageMaxSharedMemoryBytes,
80 kTestBlobStorageMaxFileSizeBytes); 81 kTestBlobStorageMaxFileSizeBytes);
81 } 82 BlobDataBuilder builder(kCompletedBlobUUID);
82 83 builder.AppendData(kCompletedBlobData);
83 void SetMatchingBuilder(BlobDataBuilder* builder) { 84 completed_blob_handle_ = context_.AddFinishedBlob(builder);
84 matching_builder_ = builder;
85 }
86
87 void CancelCallback(IPCBlobCreationCancelCode code) {
88 cancel_called_ = true;
89 cancel_code_ = code;
90 }
91
92 void DoneCallback(const BlobDataBuilder& builder) {
93 // This does a deep comparison, including internal data items.
94 if (matching_builder_)
95 EXPECT_EQ(*matching_builder_, builder);
96 done_called_ = true;
97 } 85 }
98 86
99 void RequestMemoryCallback( 87 void RequestMemoryCallback(
100 const std::vector<storage::BlobItemBytesRequest>& requests, 88 const std::vector<storage::BlobItemBytesRequest>& requests,
101 const std::vector<base::SharedMemoryHandle>& shared_memory_handles, 89 const std::vector<base::SharedMemoryHandle>& shared_memory_handles,
102 const std::vector<uint64_t>& file_sizes) { 90 std::vector<base::File>* files) {
103 this->requests_ = requests; 91 this->requests_ = requests;
104 memory_handles_ = shared_memory_handles; 92 memory_handles_ = shared_memory_handles;
105 file_handles_ = file_sizes;
106 request_called_ = true; 93 request_called_ = true;
107 } 94 }
108 95
109 bool BuildBlobAsync(const std::vector<DataElement>& descriptions, 96 BlobTransportResult BuildBlobAsync(
110 size_t memory_available) { 97 const std::vector<DataElement>& descriptions,
111 done_called_ = false; 98 size_t memory_available) {
112 cancel_called_ = false;
113 request_called_ = false; 99 request_called_ = false;
100 if (!host_.RegisterBlobUUID(kBlobUUID, kContentType, kContentDisposition,
101 &context_)) {
102 return BlobTransportResult::BAD_IPC;
103 }
114 return host_.StartBuildingBlob( 104 return host_.StartBuildingBlob(
115 kBlobUUID, kBlobType, descriptions, memory_available, 105 kBlobUUID, descriptions, memory_available, &context_,
116 base::Bind(&BlobAsyncBuilderHostTest::RequestMemoryCallback, 106 base::Bind(&BlobAsyncBuilderHostTest::RequestMemoryCallback,
117 base::Unretained(this)),
118 base::Bind(&BlobAsyncBuilderHostTest::DoneCallback,
119 base::Unretained(this)),
120 base::Bind(&BlobAsyncBuilderHostTest::CancelCallback,
121 base::Unretained(this))); 107 base::Unretained(this)));
122 } 108 }
123 109
124 BlobDataBuilder* matching_builder_; 110 void DecrementBlobRefCount(const std::string& uuid) {
111 context_.DecrementBlobRefCount(uuid);
112 }
113
114 content::TestBrowserThreadBundle browser_thread_bundle_;
115 BlobStorageContext context_;
125 BlobAsyncBuilderHost host_; 116 BlobAsyncBuilderHost host_;
126 bool done_called_;
127 bool cancel_called_;
128 IPCBlobCreationCancelCode cancel_code_; 117 IPCBlobCreationCancelCode cancel_code_;
129 118
130 bool request_called_; 119 bool request_called_;
131 std::vector<storage::BlobItemBytesRequest> requests_; 120 std::vector<storage::BlobItemBytesRequest> requests_;
132 std::vector<base::SharedMemoryHandle> memory_handles_; 121 std::vector<base::SharedMemoryHandle> memory_handles_;
133 std::vector<uint64_t> file_handles_; 122
123 scoped_ptr<BlobDataHandle> completed_blob_handle_;
134 }; 124 };
135 125
136 TEST_F(BlobAsyncBuilderHostTest, TestShortcut) { 126 TEST_F(BlobAsyncBuilderHostTest, TestShortcut) {
137 std::vector<DataElement> descriptions; 127 std::vector<DataElement> descriptions;
138 128
139 AddShortcutMemoryItem(10, &descriptions); 129 AddShortcutMemoryItem(10, &descriptions);
140 AddBlobItem(&descriptions); 130 AddBlobItem(&descriptions);
141 AddShortcutMemoryItem(5000, &descriptions); 131 AddShortcutMemoryItem(5000, &descriptions);
142 132
143 BlobDataBuilder expected(kBlobUUID); 133 BlobDataBuilder expected(kBlobUUID);
144 expected.set_content_type(kBlobType); 134 expected.set_content_type(kContentType);
135 expected.set_content_disposition(kContentDisposition);
145 AddShortcutMemoryItem(10, &expected); 136 AddShortcutMemoryItem(10, &expected);
146 expected.AppendBlob(kFakeBlobUUID); 137 expected.AppendData(kCompletedBlobData);
147 AddShortcutMemoryItem(5000, &expected); 138 AddShortcutMemoryItem(5000, &expected);
148 SetMatchingBuilder(&expected);
149 139
150 EXPECT_TRUE(BuildBlobAsync(descriptions, 5010)); 140 EXPECT_EQ(BlobTransportResult::DONE, BuildBlobAsync(descriptions, 5010));
151 141
152 EXPECT_TRUE(done_called_); 142 EXPECT_FALSE(request_called_);
153 EXPECT_FALSE(cancel_called_); 143 EXPECT_EQ(0u, host_.blob_building_count());
144 scoped_ptr<BlobDataHandle> handle = context_.GetBlobDataFromUUID(kBlobUUID);
145 EXPECT_FALSE(handle->IsBeingBuilt());
146 EXPECT_FALSE(handle->IsBroken());
147 scoped_ptr<BlobDataSnapshot> data = handle->CreateSnapshot();
148 EXPECT_EQ(expected, *data);
149 data.reset();
150 handle.reset();
151 base::RunLoop().RunUntilIdle();
152 };
153
154 TEST_F(BlobAsyncBuilderHostTest, TestShortcutNoRoom) {
155 std::vector<DataElement> descriptions;
156
157 AddShortcutMemoryItem(10, &descriptions);
158 AddBlobItem(&descriptions);
159 AddShortcutMemoryItem(5000, &descriptions);
160
161 EXPECT_EQ(BlobTransportResult::CANCEL_MEMORY_FULL,
162 BuildBlobAsync(descriptions, 5000));
163
154 EXPECT_FALSE(request_called_); 164 EXPECT_FALSE(request_called_);
155 EXPECT_EQ(0u, host_.blob_building_count()); 165 EXPECT_EQ(0u, host_.blob_building_count());
156 }; 166 };
157 167
158 TEST_F(BlobAsyncBuilderHostTest, TestSingleSharedMemRequest) { 168 TEST_F(BlobAsyncBuilderHostTest, TestSingleSharedMemRequest) {
159 std::vector<DataElement> descriptions; 169 std::vector<DataElement> descriptions;
160 const size_t kSize = kTestBlobStorageIPCThresholdBytes + 1; 170 const size_t kSize = kTestBlobStorageIPCThresholdBytes + 1;
161 AddMemoryItem(kSize, &descriptions); 171 AddMemoryItem(kSize, &descriptions);
162 172
163 EXPECT_TRUE( 173 EXPECT_EQ(
174 BlobTransportResult::PENDING_RESPONSES,
164 BuildBlobAsync(descriptions, kTestBlobStorageIPCThresholdBytes + 1)); 175 BuildBlobAsync(descriptions, kTestBlobStorageIPCThresholdBytes + 1));
165 176
166 EXPECT_FALSE(done_called_);
167 EXPECT_FALSE(cancel_called_);
168 EXPECT_TRUE(request_called_); 177 EXPECT_TRUE(request_called_);
169 EXPECT_EQ(1u, host_.blob_building_count()); 178 EXPECT_EQ(1u, host_.blob_building_count());
170 ASSERT_EQ(1u, requests_.size()); 179 ASSERT_EQ(1u, requests_.size());
171 request_called_ = false; 180 request_called_ = false;
172 181
173 EXPECT_EQ( 182 EXPECT_EQ(
174 BlobItemBytesRequest::CreateSharedMemoryRequest(0, 0, 0, kSize, 0, 0), 183 BlobItemBytesRequest::CreateSharedMemoryRequest(0, 0, 0, kSize, 0, 0),
175 requests_.at(0)); 184 requests_.at(0));
176 }; 185 };
177 186
178 TEST_F(BlobAsyncBuilderHostTest, TestMultipleSharedMemRequests) { 187 TEST_F(BlobAsyncBuilderHostTest, TestMultipleSharedMemRequests) {
179 std::vector<DataElement> descriptions; 188 std::vector<DataElement> descriptions;
180 const size_t kSize = kTestBlobStorageMaxSharedMemoryBytes + 1; 189 const size_t kSize = kTestBlobStorageMaxSharedMemoryBytes + 1;
181 const char kFirstBlockByte = 7; 190 const char kFirstBlockByte = 7;
182 const char kSecondBlockByte = 19; 191 const char kSecondBlockByte = 19;
183 AddMemoryItem(kSize, &descriptions); 192 AddMemoryItem(kSize, &descriptions);
184 193
185 BlobDataBuilder expected(kBlobUUID); 194 BlobDataBuilder expected(kBlobUUID);
186 expected.set_content_type(kBlobType); 195 expected.set_content_type(kContentType);
196 expected.set_content_disposition(kContentDisposition);
187 char data[kSize]; 197 char data[kSize];
188 memset(data, kFirstBlockByte, kTestBlobStorageMaxSharedMemoryBytes); 198 memset(data, kFirstBlockByte, kTestBlobStorageMaxSharedMemoryBytes);
189 expected.AppendData(data, kTestBlobStorageMaxSharedMemoryBytes); 199 expected.AppendData(data, kTestBlobStorageMaxSharedMemoryBytes);
190 expected.AppendData(&kSecondBlockByte, 1); 200 expected.AppendData(&kSecondBlockByte, 1);
191 SetMatchingBuilder(&expected);
192 201
193 EXPECT_TRUE( 202 EXPECT_EQ(
203 BlobTransportResult::PENDING_RESPONSES,
194 BuildBlobAsync(descriptions, kTestBlobStorageMaxSharedMemoryBytes + 1)); 204 BuildBlobAsync(descriptions, kTestBlobStorageMaxSharedMemoryBytes + 1));
195 205
196 EXPECT_FALSE(done_called_);
197 EXPECT_FALSE(cancel_called_);
198 EXPECT_TRUE(request_called_); 206 EXPECT_TRUE(request_called_);
199 EXPECT_EQ(1u, host_.blob_building_count()); 207 EXPECT_EQ(1u, host_.blob_building_count());
200 ASSERT_EQ(1u, requests_.size()); 208 ASSERT_EQ(1u, requests_.size());
201 request_called_ = false; 209 request_called_ = false;
202 210
203 // We need to grab a duplicate handle so we can have two blocks open at the 211 // We need to grab a duplicate handle so we can have two blocks open at the
204 // same time. 212 // same time.
205 base::SharedMemoryHandle handle = 213 base::SharedMemoryHandle handle =
206 base::SharedMemory::DuplicateHandle(memory_handles_.at(0)); 214 base::SharedMemory::DuplicateHandle(memory_handles_.at(0));
207 EXPECT_TRUE(base::SharedMemory::IsHandleValid(handle)); 215 EXPECT_TRUE(base::SharedMemory::IsHandleValid(handle));
208 base::SharedMemory shared_memory(handle, false); 216 base::SharedMemory shared_memory(handle, false);
209 EXPECT_TRUE(shared_memory.Map(kTestBlobStorageMaxSharedMemoryBytes)); 217 EXPECT_TRUE(shared_memory.Map(kTestBlobStorageMaxSharedMemoryBytes));
210 218
211 EXPECT_EQ(BlobItemBytesRequest::CreateSharedMemoryRequest( 219 EXPECT_EQ(BlobItemBytesRequest::CreateSharedMemoryRequest(
212 0, 0, 0, kTestBlobStorageMaxSharedMemoryBytes, 0, 0), 220 0, 0, 0, kTestBlobStorageMaxSharedMemoryBytes, 0, 0),
213 requests_.at(0)); 221 requests_.at(0));
214 222
215 memset(shared_memory.memory(), kFirstBlockByte, 223 memset(shared_memory.memory(), kFirstBlockByte,
216 kTestBlobStorageMaxSharedMemoryBytes); 224 kTestBlobStorageMaxSharedMemoryBytes);
217 225
218 BlobItemBytesResponse response(0); 226 BlobItemBytesResponse response(0);
219 std::vector<BlobItemBytesResponse> responses = {response}; 227 std::vector<BlobItemBytesResponse> responses = {response};
220 EXPECT_TRUE(host_.OnMemoryResponses(kBlobUUID, responses)); 228 EXPECT_EQ(BlobTransportResult::PENDING_RESPONSES,
229 host_.OnMemoryResponses(kBlobUUID, responses, &context_));
221 230
222 EXPECT_FALSE(done_called_);
223 EXPECT_FALSE(cancel_called_);
224 EXPECT_TRUE(request_called_); 231 EXPECT_TRUE(request_called_);
225 EXPECT_EQ(1u, host_.blob_building_count()); 232 EXPECT_EQ(1u, host_.blob_building_count());
226 ASSERT_EQ(1u, requests_.size()); 233 ASSERT_EQ(1u, requests_.size());
227 request_called_ = false; 234 request_called_ = false;
228 235
229 EXPECT_EQ(BlobItemBytesRequest::CreateSharedMemoryRequest( 236 EXPECT_EQ(BlobItemBytesRequest::CreateSharedMemoryRequest(
230 1, 0, kTestBlobStorageMaxSharedMemoryBytes, 1, 0, 0), 237 1, 0, kTestBlobStorageMaxSharedMemoryBytes, 1, 0, 0),
231 requests_.at(0)); 238 requests_.at(0));
232 239
233 memset(shared_memory.memory(), kSecondBlockByte, 1); 240 memset(shared_memory.memory(), kSecondBlockByte, 1);
234 241
235 response.request_number = 1; 242 response.request_number = 1;
236 responses[0] = response; 243 responses[0] = response;
237 EXPECT_TRUE(host_.OnMemoryResponses(kBlobUUID, responses)); 244 EXPECT_EQ(BlobTransportResult::DONE,
238 EXPECT_TRUE(done_called_); 245 host_.OnMemoryResponses(kBlobUUID, responses, &context_));
239 EXPECT_FALSE(cancel_called_);
240 EXPECT_FALSE(request_called_); 246 EXPECT_FALSE(request_called_);
241 EXPECT_EQ(0u, host_.blob_building_count()); 247 EXPECT_EQ(0u, host_.blob_building_count());
248 scoped_ptr<BlobDataHandle> blob_handle =
249 context_.GetBlobDataFromUUID(kBlobUUID);
250 EXPECT_FALSE(blob_handle->IsBeingBuilt());
251 EXPECT_FALSE(blob_handle->IsBroken());
252 scoped_ptr<BlobDataSnapshot> blob_data = blob_handle->CreateSnapshot();
253 EXPECT_EQ(expected, *blob_data);
242 }; 254 };
243 255
244 TEST_F(BlobAsyncBuilderHostTest, TestBasicIPCAndStopBuilding) { 256 TEST_F(BlobAsyncBuilderHostTest, TestBasicIPCAndStopBuilding) {
245 std::vector<DataElement> descriptions; 257 std::vector<DataElement> descriptions;
246 258
247 AddMemoryItem(2, &descriptions); 259 AddMemoryItem(2, &descriptions);
248 AddBlobItem(&descriptions); 260 AddBlobItem(&descriptions);
249 AddMemoryItem(2, &descriptions); 261 AddMemoryItem(2, &descriptions);
250 262
251 BlobDataBuilder expected(kBlobUUID); 263 BlobDataBuilder expected(kBlobUUID);
252 expected.set_content_type(kBlobType); 264 expected.set_content_type(kContentType);
265 expected.set_content_disposition(kContentDisposition);
253 AddShortcutMemoryItem(2, &expected); 266 AddShortcutMemoryItem(2, &expected);
254 expected.AppendBlob(kFakeBlobUUID); 267 expected.AppendData(kCompletedBlobData);
255 AddShortcutMemoryItem(2, &expected); 268 AddShortcutMemoryItem(2, &expected);
256 SetMatchingBuilder(&expected);
257 269
258 EXPECT_TRUE(BuildBlobAsync(descriptions, 5010)); 270 EXPECT_EQ(BlobTransportResult::PENDING_RESPONSES,
259 host_.StopBuildingBlob(kBlobUUID); 271 BuildBlobAsync(descriptions, 5010));
260 EXPECT_TRUE(BuildBlobAsync(descriptions, 5010)); 272 host_.MaybeCancelBuildingBlob(kBlobUUID, IPCBlobCreationCancelCode::UNKNOWN,
273 &context_);
261 274
262 EXPECT_FALSE(done_called_); 275 // Check that we're broken, and then remove the blob.
263 EXPECT_FALSE(cancel_called_); 276 scoped_ptr<BlobDataHandle> blob_handle =
277 context_.GetBlobDataFromUUID(kBlobUUID);
278 EXPECT_FALSE(blob_handle->IsBeingBuilt());
279 EXPECT_TRUE(blob_handle->IsBroken());
280 blob_handle.reset();
281 DecrementBlobRefCount(kBlobUUID);
282 base::RunLoop().RunUntilIdle();
283 blob_handle = context_.GetBlobDataFromUUID(kBlobUUID);
284 EXPECT_FALSE(blob_handle.get());
285
286 // This should succeed because we've removed all references to the blob.
287 EXPECT_EQ(BlobTransportResult::PENDING_RESPONSES,
288 BuildBlobAsync(descriptions, 5010));
289
264 EXPECT_TRUE(request_called_); 290 EXPECT_TRUE(request_called_);
265 EXPECT_EQ(1u, host_.blob_building_count()); 291 EXPECT_EQ(1u, host_.blob_building_count());
266 request_called_ = false; 292 request_called_ = false;
267 293
268 BlobItemBytesResponse response1(0); 294 BlobItemBytesResponse response1(0);
269 PopulateBytes(response1.allocate_mutable_data(2), 2); 295 PopulateBytes(response1.allocate_mutable_data(2), 2);
270 BlobItemBytesResponse response2(1); 296 BlobItemBytesResponse response2(1);
271 PopulateBytes(response2.allocate_mutable_data(2), 2); 297 PopulateBytes(response2.allocate_mutable_data(2), 2);
272 std::vector<BlobItemBytesResponse> responses = {response1, response2}; 298 std::vector<BlobItemBytesResponse> responses = {response1, response2};
273 EXPECT_TRUE(host_.OnMemoryResponses(kBlobUUID, responses)); 299
274 EXPECT_TRUE(done_called_); 300 EXPECT_EQ(BlobTransportResult::DONE,
275 EXPECT_FALSE(cancel_called_); 301 host_.OnMemoryResponses(kBlobUUID, responses, &context_));
276 EXPECT_FALSE(request_called_); 302 EXPECT_FALSE(request_called_);
277 EXPECT_EQ(0u, host_.blob_building_count()); 303 EXPECT_EQ(0u, host_.blob_building_count());
304 blob_handle = context_.GetBlobDataFromUUID(kBlobUUID);
305 EXPECT_FALSE(blob_handle->IsBeingBuilt());
306 EXPECT_FALSE(blob_handle->IsBroken());
307 scoped_ptr<BlobDataSnapshot> blob_data = blob_handle->CreateSnapshot();
308 EXPECT_EQ(expected, *blob_data);
309 };
310
311 TEST_F(BlobAsyncBuilderHostTest, TestBreakingAllBuilding) {
312 const std::string& kBlob1 = "blob1";
313 const std::string& kBlob2 = "blob2";
314 const std::string& kBlob3 = "blob3";
315
316 // Register blobs.
317 EXPECT_TRUE(host_.RegisterBlobUUID(kBlob1, kContentType, kContentDisposition,
318 &context_));
319 EXPECT_TRUE(host_.RegisterBlobUUID(kBlob2, kContentType, kContentDisposition,
320 &context_));
321 EXPECT_TRUE(host_.RegisterBlobUUID(kBlob3, kContentType, kContentDisposition,
322 &context_));
323
324 // Start building one of them.
325 std::vector<DataElement> descriptions;
326 AddMemoryItem(2, &descriptions);
327 EXPECT_EQ(BlobTransportResult::PENDING_RESPONSES,
328 host_.StartBuildingBlob(
329 kBlob1, descriptions, 2, &context_,
330 base::Bind(&BlobAsyncBuilderHostTest::RequestMemoryCallback,
331 base::Unretained(this))));
332 EXPECT_TRUE(request_called_);
333
334 scoped_ptr<BlobDataHandle> blob_handle1 =
335 context_.GetBlobDataFromUUID(kBlob1);
336 scoped_ptr<BlobDataHandle> blob_handle2 =
337 context_.GetBlobDataFromUUID(kBlob2);
338 scoped_ptr<BlobDataHandle> blob_handle3 =
339 context_.GetBlobDataFromUUID(kBlob2);
340 EXPECT_TRUE(blob_handle1->IsBeingBuilt() && blob_handle2->IsBeingBuilt() &&
341 blob_handle3->IsBeingBuilt());
342 EXPECT_FALSE(blob_handle1->IsBroken() || blob_handle2->IsBroken() ||
343 blob_handle3->IsBroken());
344
345 host_.ClearAndBreakPendingBlobConstruction(&context_);
346
347 EXPECT_FALSE(blob_handle1->IsBeingBuilt() || blob_handle2->IsBeingBuilt() ||
348 blob_handle3->IsBeingBuilt());
349 EXPECT_TRUE(blob_handle1->IsBroken() && blob_handle2->IsBroken() &&
350 blob_handle3->IsBroken());
351 blob_handle1.reset();
352 blob_handle2.reset();
353 blob_handle3.reset();
354 base::RunLoop().RunUntilIdle();
278 }; 355 };
279 356
280 TEST_F(BlobAsyncBuilderHostTest, TestBadIPCs) { 357 TEST_F(BlobAsyncBuilderHostTest, TestBadIPCs) {
281 std::vector<DataElement> descriptions; 358 std::vector<DataElement> descriptions;
282 359
283 // Test reusing same blob uuid. 360 // Test reusing same blob uuid.
284 SetMatchingBuilder(nullptr);
285 AddMemoryItem(10, &descriptions); 361 AddMemoryItem(10, &descriptions);
286 AddBlobItem(&descriptions); 362 AddBlobItem(&descriptions);
287 AddMemoryItem(5000, &descriptions); 363 AddMemoryItem(5000, &descriptions);
288 EXPECT_TRUE(BuildBlobAsync(descriptions, 5010)); 364 EXPECT_EQ(BlobTransportResult::PENDING_RESPONSES,
289 EXPECT_FALSE(BuildBlobAsync(descriptions, 5010)); 365 BuildBlobAsync(descriptions, 5010));
290 EXPECT_FALSE(done_called_); 366 EXPECT_EQ(BlobTransportResult::BAD_IPC, BuildBlobAsync(descriptions, 5010));
291 EXPECT_FALSE(cancel_called_);
292 EXPECT_FALSE(request_called_); 367 EXPECT_FALSE(request_called_);
293 host_.StopBuildingBlob(kBlobUUID); 368 host_.MaybeCancelBuildingBlob(kBlobUUID, IPCBlobCreationCancelCode::UNKNOWN,
369 &context_);
370 DecrementBlobRefCount(kBlobUUID);
371 EXPECT_FALSE(context_.GetBlobDataFromUUID(kBlobUUID).get());
294 372
295 // Test we're _not_ an error if we get a bad uuid for responses. 373 // Test we're an error if we get a bad uuid for responses.
296 BlobItemBytesResponse response(0); 374 BlobItemBytesResponse response(0);
297 std::vector<BlobItemBytesResponse> responses = {response}; 375 std::vector<BlobItemBytesResponse> responses = {response};
298 EXPECT_TRUE(host_.OnMemoryResponses(kBlobUUID, responses)); 376 EXPECT_EQ(BlobTransportResult::BAD_IPC,
377 host_.OnMemoryResponses(kBlobUUID, responses, &context_));
299 378
300 // Test empty responses. 379 // Test empty responses.
301 responses.clear(); 380 responses.clear();
302 EXPECT_FALSE(host_.OnMemoryResponses(kBlobUUID, responses)); 381 EXPECT_EQ(BlobTransportResult::BAD_IPC,
382 host_.OnMemoryResponses(kBlobUUID, responses, &context_));
303 383
304 // Test response problems below here. 384 // Test response problems below here.
305 descriptions.clear(); 385 descriptions.clear();
306 AddMemoryItem(2, &descriptions); 386 AddMemoryItem(2, &descriptions);
307 AddBlobItem(&descriptions); 387 AddBlobItem(&descriptions);
308 AddMemoryItem(2, &descriptions); 388 AddMemoryItem(2, &descriptions);
309 EXPECT_TRUE(BuildBlobAsync(descriptions, 5010)); 389 EXPECT_EQ(BlobTransportResult::PENDING_RESPONSES,
390 BuildBlobAsync(descriptions, 5010));
310 391
311 // Invalid request number. 392 // Invalid request number.
312 BlobItemBytesResponse response1(3); 393 BlobItemBytesResponse response1(3);
313 PopulateBytes(response1.allocate_mutable_data(2), 2); 394 PopulateBytes(response1.allocate_mutable_data(2), 2);
314 responses = {response1}; 395 responses = {response1};
315 EXPECT_FALSE(host_.OnMemoryResponses(kBlobUUID, responses)); 396 EXPECT_EQ(BlobTransportResult::BAD_IPC,
397 host_.OnMemoryResponses(kBlobUUID, responses, &context_));
398 EXPECT_TRUE(context_.GetBlobDataFromUUID(kBlobUUID)->IsBroken());
399 DecrementBlobRefCount(kBlobUUID);
400 base::RunLoop().RunUntilIdle();
316 401
317 // Duplicate request number responses. 402 // Duplicate request number responses.
318 EXPECT_TRUE(BuildBlobAsync(descriptions, 5010)); 403 EXPECT_EQ(BlobTransportResult::PENDING_RESPONSES,
404 BuildBlobAsync(descriptions, 5010));
319 response1.request_number = 0; 405 response1.request_number = 0;
320 BlobItemBytesResponse response2(0); 406 BlobItemBytesResponse response2(0);
321 PopulateBytes(response2.allocate_mutable_data(2), 2); 407 PopulateBytes(response2.allocate_mutable_data(2), 2);
322 responses = {response1, response2}; 408 responses = {response1, response2};
323 EXPECT_FALSE(host_.OnMemoryResponses(kBlobUUID, responses)); 409 EXPECT_EQ(BlobTransportResult::BAD_IPC,
410 host_.OnMemoryResponses(kBlobUUID, responses, &context_));
411 EXPECT_TRUE(context_.GetBlobDataFromUUID(kBlobUUID)->IsBroken());
412 DecrementBlobRefCount(kBlobUUID);
413 base::RunLoop().RunUntilIdle();
324 }; 414 };
325 415
326 } // namespace
327 } // namespace storage 416 } // namespace storage
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698