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

Side by Side Diff: content/browser/fileapi/blob_storage_context_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 Created 4 years, 9 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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_storage_context.h" 5 #include "storage/browser/blob/blob_storage_context.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <limits> 9 #include <limits>
10 #include <string> 10 #include <string>
11 11
12 #include "base/files/file.h"
12 #include "base/files/file_path.h" 13 #include "base/files/file_path.h"
13 #include "base/memory/ref_counted.h" 14 #include "base/memory/ref_counted.h"
14 #include "base/memory/scoped_ptr.h" 15 #include "base/memory/scoped_ptr.h"
15 #include "base/message_loop/message_loop.h" 16 #include "base/message_loop/message_loop.h"
16 #include "base/run_loop.h" 17 #include "base/run_loop.h"
17 #include "base/time/time.h" 18 #include "base/time/time.h"
18 #include "content/browser/fileapi/blob_storage_host.h" 19 #include "content/browser/blob_storage/blob_dispatcher_host.h"
20 #include "content/browser/fileapi/chrome_blob_storage_context.h"
21 #include "content/public/test/test_browser_context.h"
19 #include "net/base/io_buffer.h" 22 #include "net/base/io_buffer.h"
20 #include "net/base/test_completion_callback.h" 23 #include "net/base/test_completion_callback.h"
21 #include "net/disk_cache/disk_cache.h" 24 #include "net/disk_cache/disk_cache.h"
25 #include "storage/browser/blob/blob_async_builder_host.h"
22 #include "storage/browser/blob/blob_data_builder.h" 26 #include "storage/browser/blob/blob_data_builder.h"
23 #include "storage/browser/blob/blob_data_handle.h" 27 #include "storage/browser/blob/blob_data_handle.h"
24 #include "storage/browser/blob/blob_data_item.h" 28 #include "storage/browser/blob/blob_data_item.h"
25 #include "storage/browser/blob/blob_data_snapshot.h" 29 #include "storage/browser/blob/blob_data_snapshot.h"
30 #include "storage/browser/blob/blob_transport_result.h"
31 #include "storage/common/blob_storage/blob_item_bytes_request.h"
32 #include "storage/common/blob_storage/blob_item_bytes_response.h"
26 #include "testing/gtest/include/gtest/gtest.h" 33 #include "testing/gtest/include/gtest/gtest.h"
27 34
28 using storage::BlobDataBuilder; 35 using RequestMemoryCallback =
29 using storage::BlobDataHandle; 36 storage::BlobAsyncBuilderHost::RequestMemoryCallback;
30 using storage::BlobDataItem;
31 using storage::BlobDataSnapshot;
32 using storage::BlobStorageContext;
33 using storage::DataElement;
34 37
35 namespace content { 38 namespace storage {
36 namespace { 39 namespace {
37 40
41 const char kContentType[] = "text/plain";
42 const char kContentDisposition[] = "content_disposition";
38 const int kTestDiskCacheStreamIndex = 0; 43 const int kTestDiskCacheStreamIndex = 0;
39 44
40 // Our disk cache tests don't need a real data handle since the tests themselves 45 // Our disk cache tests don't need a real data handle since the tests themselves
41 // scope the disk cache and entries. 46 // scope the disk cache and entries.
42 class EmptyDataHandle : public storage::BlobDataBuilder::DataHandle { 47 class EmptyDataHandle : public storage::BlobDataBuilder::DataHandle {
43 private: 48 private:
44 ~EmptyDataHandle() override {} 49 ~EmptyDataHandle() override {}
45 }; 50 };
46 51
47 scoped_ptr<disk_cache::Backend> CreateInMemoryDiskCache() { 52 scoped_ptr<disk_cache::Backend> CreateInMemoryDiskCache() {
(...skipping 19 matching lines...) Expand all
67 return nullptr; 72 return nullptr;
68 disk_cache::ScopedEntryPtr entry(temp_entry); 73 disk_cache::ScopedEntryPtr entry(temp_entry);
69 74
70 scoped_refptr<net::StringIOBuffer> iobuffer = new net::StringIOBuffer(data); 75 scoped_refptr<net::StringIOBuffer> iobuffer = new net::StringIOBuffer(data);
71 rv = entry->WriteData(kTestDiskCacheStreamIndex, 0, iobuffer.get(), 76 rv = entry->WriteData(kTestDiskCacheStreamIndex, 0, iobuffer.get(),
72 iobuffer->size(), callback.callback(), false); 77 iobuffer->size(), callback.callback(), false);
73 EXPECT_EQ(static_cast<int>(data.size()), callback.GetResult(rv)); 78 EXPECT_EQ(static_cast<int>(data.size()), callback.GetResult(rv));
74 return entry; 79 return entry;
75 } 80 }
76 81
77 void SetupBasicBlob(BlobStorageHost* host, const std::string& id) {
78 EXPECT_TRUE(host->StartBuildingBlob(id));
79 DataElement item;
80 item.SetToBytes("1", 1);
81 EXPECT_TRUE(host->AppendBlobDataItem(id, item));
82 EXPECT_TRUE(host->FinishBuildingBlob(id, "text/plain"));
83 EXPECT_FALSE(host->StartBuildingBlob(id));
84 }
85 82
86 } // namespace 83 } // namespace
87 84
88 TEST(BlobStorageContextTest, IncrementDecrementRef) { 85 class BlobStorageContextTest : public testing::Test {
89 BlobStorageContext context; 86 protected:
90 BlobStorageHost host(&context); 87 BlobStorageContextTest() {}
88 ~BlobStorageContextTest() override {}
89
90 scoped_ptr<BlobDataHandle> SetupBasicBlob(const std::string& id) {
91 BlobDataBuilder builder(id);
92 builder.AppendData("1", 1);
93 builder.set_content_type("text/plain");
94 return context_.AddFinishedBlob(builder);
95 }
96
97 BlobStorageContext context_;
98 };
99
100 TEST_F(BlobStorageContextTest, IncrementDecrementRef) {
91 base::MessageLoop fake_io_message_loop; 101 base::MessageLoop fake_io_message_loop;
92 102
93 // Build up a basic blob. 103 // Build up a basic blob.
94 const std::string kId("id"); 104 const std::string kId("id");
95 SetupBasicBlob(&host, kId); 105 scoped_ptr<BlobDataHandle> blob_data_handle = SetupBasicBlob(kId);
96 106
97 // Make sure it's there, finish building implies a ref of one. 107 // Do an extra increment to keep it around after we kill the handle.
98 scoped_ptr<BlobDataHandle> blob_data_handle; 108 context_.IncrementBlobRefCount(kId);
99 blob_data_handle = context.GetBlobDataFromUUID(kId); 109 context_.IncrementBlobRefCount(kId);
110 context_.DecrementBlobRefCount(kId);
111 blob_data_handle = context_.GetBlobDataFromUUID(kId);
100 EXPECT_TRUE(blob_data_handle); 112 EXPECT_TRUE(blob_data_handle);
101 blob_data_handle.reset(); 113 blob_data_handle.reset();
102 base::RunLoop().RunUntilIdle(); 114 base::RunLoop().RunUntilIdle();
103 115
104 // Make sure its still there after inc/dec. 116 EXPECT_TRUE(context_.registry().HasEntry(kId));
105 EXPECT_TRUE(host.IncrementBlobRefCount(kId)); 117 context_.DecrementBlobRefCount(kId);
106 EXPECT_TRUE(host.DecrementBlobRefCount(kId)); 118 EXPECT_FALSE(context_.registry().HasEntry(kId));
107 blob_data_handle = context.GetBlobDataFromUUID(kId);
108 EXPECT_TRUE(blob_data_handle);
109 blob_data_handle.reset();
110 base::RunLoop().RunUntilIdle();
111 119
112 // Make sure it goes away in the end. 120 // Make sure it goes away in the end.
113 EXPECT_TRUE(host.DecrementBlobRefCount(kId)); 121 blob_data_handle = context_.GetBlobDataFromUUID(kId);
114 blob_data_handle = context.GetBlobDataFromUUID(kId);
115 EXPECT_FALSE(blob_data_handle); 122 EXPECT_FALSE(blob_data_handle);
116 EXPECT_FALSE(host.DecrementBlobRefCount(kId));
117 EXPECT_FALSE(host.IncrementBlobRefCount(kId));
118 } 123 }
119 124
120 TEST(BlobStorageContextTest, CancelBuildingBlob) { 125 TEST_F(BlobStorageContextTest, OnCancelBuildingBlob) {
121 BlobStorageContext context;
122 BlobStorageHost host(&context);
123 base::MessageLoop fake_io_message_loop; 126 base::MessageLoop fake_io_message_loop;
124 127
125 // Build up a basic blob. 128 // Build up a basic blob.
126 const std::string kId("id"); 129 const std::string kId("id");
127 EXPECT_TRUE(host.StartBuildingBlob(kId)); 130 context_.CreatePendingBlob(kId, std::string(kContentType),
128 DataElement item; 131 std::string(kContentDisposition));
129 item.SetToBytes("1", 1); 132 EXPECT_TRUE(context_.IsBeingBuilt(kId));
130 EXPECT_TRUE(host.AppendBlobDataItem(kId, item)); 133 context_.CancelPendingBlob(kId, IPCBlobCreationCancelCode::OUT_OF_MEMORY);
131 EXPECT_TRUE(host.CancelBuildingBlob(kId)); 134 EXPECT_TRUE(context_.registry().HasEntry(kId));
132 EXPECT_FALSE(host.FinishBuildingBlob(kId, "text/plain")); 135 EXPECT_FALSE(context_.IsBeingBuilt(kId));
133 EXPECT_TRUE(host.StartBuildingBlob(kId)); 136 EXPECT_TRUE(context_.IsBroken(kId));
134 } 137 }
135 138
136 TEST(BlobStorageContextTest, BlobDataHandle) { 139 TEST_F(BlobStorageContextTest, BlobDataHandle) {
137 BlobStorageContext context;
138 BlobStorageHost host(&context);
139 base::MessageLoop fake_io_message_loop; 140 base::MessageLoop fake_io_message_loop;
140 141
141 // Build up a basic blob. 142 // Build up a basic blob.
142 const std::string kId("id"); 143 const std::string kId("id");
143 SetupBasicBlob(&host, kId); 144 scoped_ptr<BlobDataHandle> blob_data_handle = SetupBasicBlob(kId);
144
145 // Get a handle to it.
146 scoped_ptr<BlobDataHandle> blob_data_handle =
147 context.GetBlobDataFromUUID(kId);
148 EXPECT_TRUE(blob_data_handle); 145 EXPECT_TRUE(blob_data_handle);
149 146
150 // Drop the host's ref to it. 147 // Get another handle
151 EXPECT_TRUE(host.DecrementBlobRefCount(kId)); 148 scoped_ptr<BlobDataHandle> another_handle = context_.GetBlobDataFromUUID(kId);
152
153 // Should still be there due to the handle.
154 scoped_ptr<BlobDataHandle> another_handle =
155 context.GetBlobDataFromUUID(kId);
156 EXPECT_TRUE(another_handle); 149 EXPECT_TRUE(another_handle);
157 150
158 // Should disappear after dropping both handles. 151 // Should disappear after dropping both handles.
159 blob_data_handle.reset(); 152 blob_data_handle.reset();
153 base::RunLoop().RunUntilIdle();
154
155 EXPECT_TRUE(context_.registry().HasEntry(kId));
156
160 another_handle.reset(); 157 another_handle.reset();
161 base::RunLoop().RunUntilIdle(); 158 base::RunLoop().RunUntilIdle();
162 159
163 blob_data_handle = context.GetBlobDataFromUUID(kId); 160 blob_data_handle = context_.GetBlobDataFromUUID(kId);
164 EXPECT_FALSE(blob_data_handle); 161 EXPECT_FALSE(blob_data_handle);
165 } 162 }
166 163
167 TEST(BlobStorageContextTest, MemoryUsage) { 164 TEST_F(BlobStorageContextTest, MemoryUsage) {
168 const std::string kId1("id1"); 165 const std::string kId1("id1");
169 const std::string kId2("id2"); 166 const std::string kId2("id2");
170 167
171 base::MessageLoop fake_io_message_loop; 168 base::MessageLoop fake_io_message_loop;
172 169
173 BlobDataBuilder builder1(kId1); 170 BlobDataBuilder builder1(kId1);
174 BlobDataBuilder builder2(kId2); 171 BlobDataBuilder builder2(kId2);
175 builder1.AppendData("Data1Data2"); 172 builder1.AppendData("Data1Data2");
176 builder2.AppendBlob(kId1); 173 builder2.AppendBlob(kId1);
177 builder2.AppendBlob(kId1); 174 builder2.AppendBlob(kId1);
178 builder2.AppendBlob(kId1); 175 builder2.AppendBlob(kId1);
179 builder2.AppendBlob(kId1); 176 builder2.AppendBlob(kId1);
180 builder2.AppendBlob(kId1); 177 builder2.AppendBlob(kId1);
181 builder2.AppendBlob(kId1); 178 builder2.AppendBlob(kId1);
182 builder2.AppendBlob(kId1); 179 builder2.AppendBlob(kId1);
183 180
184 BlobStorageContext context; 181 EXPECT_EQ(0lu, context_.memory_usage());
185 EXPECT_EQ(0lu, context.memory_usage());
186 182
187 scoped_ptr<BlobDataHandle> blob_data_handle = 183 scoped_ptr<BlobDataHandle> blob_data_handle =
188 context.AddFinishedBlob(&builder1); 184 context_.AddFinishedBlob(&builder1);
189 EXPECT_EQ(10lu, context.memory_usage()); 185 EXPECT_EQ(10lu, context_.memory_usage());
190 scoped_ptr<BlobDataHandle> blob_data_handle2 = 186 scoped_ptr<BlobDataHandle> blob_data_handle2 =
191 context.AddFinishedBlob(&builder2); 187 context_.AddFinishedBlob(&builder2);
192 EXPECT_EQ(10lu, context.memory_usage()); 188 EXPECT_EQ(10lu, context_.memory_usage());
189
190 EXPECT_EQ(2u, context_.registry().blob_count());
193 191
194 blob_data_handle.reset(); 192 blob_data_handle.reset();
195 base::RunLoop().RunUntilIdle(); 193 base::RunLoop().RunUntilIdle();
196 194
197 EXPECT_EQ(10lu, context.memory_usage()); 195 EXPECT_EQ(10lu, context_.memory_usage());
196 EXPECT_EQ(1u, context_.registry().blob_count());
198 blob_data_handle2.reset(); 197 blob_data_handle2.reset();
199 base::RunLoop().RunUntilIdle(); 198 base::RunLoop().RunUntilIdle();
200 199
201 EXPECT_EQ(0lu, context.memory_usage()); 200 EXPECT_EQ(0lu, context_.memory_usage());
201 EXPECT_EQ(0u, context_.registry().blob_count());
202 } 202 }
203 203
204 TEST(BlobStorageContextTest, AddFinishedBlob) { 204 TEST_F(BlobStorageContextTest, AddFinishedBlob) {
205 const std::string kId1("id1"); 205 const std::string kId1("id1");
206 const std::string kId2("id12"); 206 const std::string kId2("id12");
207 const std::string kId2Prime("id2.prime"); 207 const std::string kId2Prime("id2.prime");
208 const std::string kId3("id3"); 208 const std::string kId3("id3");
209 const std::string kId3Prime("id3.prime"); 209 const std::string kId3Prime("id3.prime");
210 210
211 base::MessageLoop fake_io_message_loop; 211 base::MessageLoop fake_io_message_loop;
212 212
213 BlobDataBuilder builder1(kId1); 213 BlobDataBuilder builder1(kId1);
214 BlobDataBuilder builder2(kId2); 214 BlobDataBuilder builder2(kId2);
215 BlobDataBuilder canonicalized_blob_data2(kId2Prime); 215 BlobDataBuilder canonicalized_blob_data2(kId2Prime);
216 builder1.AppendData("Data1Data2"); 216 builder1.AppendData("Data1Data2");
217 builder2.AppendBlob(kId1, 5, 5); 217 builder2.AppendBlob(kId1, 5, 5);
218 builder2.AppendData(" is the best"); 218 builder2.AppendData(" is the best");
219 canonicalized_blob_data2.AppendData("Data2"); 219 canonicalized_blob_data2.AppendData("Data2");
220 canonicalized_blob_data2.AppendData(" is the best"); 220 canonicalized_blob_data2.AppendData(" is the best");
221 221
222 BlobStorageContext context; 222 BlobStorageContext context;
223 223
224 scoped_ptr<BlobDataHandle> blob_data_handle = 224 scoped_ptr<BlobDataHandle> blob_data_handle =
225 context.AddFinishedBlob(&builder1); 225 context_.AddFinishedBlob(&builder1);
226 scoped_ptr<BlobDataHandle> blob_data_handle2 = 226 scoped_ptr<BlobDataHandle> blob_data_handle2 =
227 context.AddFinishedBlob(&builder2); 227 context_.AddFinishedBlob(&builder2);
228 228
229 ASSERT_TRUE(blob_data_handle); 229 ASSERT_TRUE(blob_data_handle);
230 ASSERT_TRUE(blob_data_handle2); 230 ASSERT_TRUE(blob_data_handle2);
231 scoped_ptr<BlobDataSnapshot> data1 = blob_data_handle->CreateSnapshot(); 231 scoped_ptr<BlobDataSnapshot> data1 = blob_data_handle->CreateSnapshot();
232 scoped_ptr<BlobDataSnapshot> data2 = blob_data_handle2->CreateSnapshot(); 232 scoped_ptr<BlobDataSnapshot> data2 = blob_data_handle2->CreateSnapshot();
233 EXPECT_EQ(*data1, builder1); 233 EXPECT_EQ(*data1, builder1);
234 EXPECT_EQ(*data2, canonicalized_blob_data2); 234 EXPECT_EQ(*data2, canonicalized_blob_data2);
235 blob_data_handle.reset(); 235 blob_data_handle.reset();
236 data2.reset(); 236 data2.reset();
237 237
238 base::RunLoop().RunUntilIdle(); 238 base::RunLoop().RunUntilIdle();
239 239
240 blob_data_handle = context.GetBlobDataFromUUID(kId1); 240 blob_data_handle = context_.GetBlobDataFromUUID(kId1);
241 EXPECT_FALSE(blob_data_handle); 241 EXPECT_FALSE(blob_data_handle);
242 EXPECT_TRUE(blob_data_handle2); 242 EXPECT_TRUE(blob_data_handle2);
243 data2 = blob_data_handle2->CreateSnapshot(); 243 data2 = blob_data_handle2->CreateSnapshot();
244 EXPECT_EQ(*data2, canonicalized_blob_data2); 244 EXPECT_EQ(*data2, canonicalized_blob_data2);
245 245
246 // Test shared elements stick around. 246 // Test shared elements stick around.
247 BlobDataBuilder builder3(kId3); 247 BlobDataBuilder builder3(kId3);
248 builder3.AppendBlob(kId2); 248 builder3.AppendBlob(kId2);
249 builder3.AppendBlob(kId2); 249 builder3.AppendBlob(kId2);
250 scoped_ptr<BlobDataHandle> blob_data_handle3 = 250 scoped_ptr<BlobDataHandle> blob_data_handle3 =
251 context.AddFinishedBlob(&builder3); 251 context_.AddFinishedBlob(&builder3);
252 blob_data_handle2.reset(); 252 blob_data_handle2.reset();
253 base::RunLoop().RunUntilIdle(); 253 base::RunLoop().RunUntilIdle();
254 254
255 blob_data_handle2 = context.GetBlobDataFromUUID(kId2); 255 blob_data_handle2 = context_.GetBlobDataFromUUID(kId2);
256 EXPECT_FALSE(blob_data_handle2); 256 EXPECT_FALSE(blob_data_handle2);
257 EXPECT_TRUE(blob_data_handle3); 257 EXPECT_TRUE(blob_data_handle3);
258 scoped_ptr<BlobDataSnapshot> data3 = blob_data_handle3->CreateSnapshot(); 258 scoped_ptr<BlobDataSnapshot> data3 = blob_data_handle3->CreateSnapshot();
259 259
260 BlobDataBuilder canonicalized_blob_data3(kId3Prime); 260 BlobDataBuilder canonicalized_blob_data3(kId3Prime);
261 canonicalized_blob_data3.AppendData("Data2"); 261 canonicalized_blob_data3.AppendData("Data2");
262 canonicalized_blob_data3.AppendData(" is the best"); 262 canonicalized_blob_data3.AppendData(" is the best");
263 canonicalized_blob_data3.AppendData("Data2"); 263 canonicalized_blob_data3.AppendData("Data2");
264 canonicalized_blob_data3.AppendData(" is the best"); 264 canonicalized_blob_data3.AppendData(" is the best");
265 EXPECT_EQ(*data3, canonicalized_blob_data3); 265 EXPECT_EQ(*data3, canonicalized_blob_data3);
266 266
267 blob_data_handle.reset(); 267 blob_data_handle.reset();
268 blob_data_handle2.reset(); 268 blob_data_handle2.reset();
269 blob_data_handle3.reset(); 269 blob_data_handle3.reset();
270 base::RunLoop().RunUntilIdle(); 270 base::RunLoop().RunUntilIdle();
271 } 271 }
272 272
273 TEST(BlobStorageContextTest, AddFinishedBlob_LargeOffset) { 273 TEST_F(BlobStorageContextTest, AddFinishedBlob_LargeOffset) {
274 // A value which does not fit in a 4-byte data type. Used to confirm that 274 // A value which does not fit in a 4-byte data type. Used to confirm that
275 // large values are supported on 32-bit Chromium builds. Regression test for: 275 // large values are supported on 32-bit Chromium builds. Regression test for:
276 // crbug.com/458122. 276 // crbug.com/458122.
277 const uint64_t kLargeSize = std::numeric_limits<uint64_t>::max(); 277 const uint64_t kLargeSize = std::numeric_limits<uint64_t>::max();
278 278
279 const uint64_t kBlobLength = 5; 279 const uint64_t kBlobLength = 5;
280 const std::string kId1("id1"); 280 const std::string kId1("id1");
281 const std::string kId2("id2"); 281 const std::string kId2("id2");
282 base::MessageLoop fake_io_message_loop; 282 base::MessageLoop fake_io_message_loop;
283 283
284 BlobDataBuilder builder1(kId1); 284 BlobDataBuilder builder1(kId1);
285 builder1.AppendFileSystemFile(GURL(), 0, kLargeSize, base::Time::Now()); 285 builder1.AppendFileSystemFile(GURL(), 0, kLargeSize, base::Time::Now());
286 286
287 BlobDataBuilder builder2(kId2); 287 BlobDataBuilder builder2(kId2);
288 builder2.AppendBlob(kId1, kLargeSize - kBlobLength, kBlobLength); 288 builder2.AppendBlob(kId1, kLargeSize - kBlobLength, kBlobLength);
289 289
290 BlobStorageContext context;
291 scoped_ptr<BlobDataHandle> blob_data_handle1 = 290 scoped_ptr<BlobDataHandle> blob_data_handle1 =
292 context.AddFinishedBlob(&builder1); 291 context_.AddFinishedBlob(&builder1);
293 scoped_ptr<BlobDataHandle> blob_data_handle2 = 292 scoped_ptr<BlobDataHandle> blob_data_handle2 =
294 context.AddFinishedBlob(&builder2); 293 context_.AddFinishedBlob(&builder2);
295 294
296 ASSERT_TRUE(blob_data_handle1); 295 ASSERT_TRUE(blob_data_handle1);
297 ASSERT_TRUE(blob_data_handle2); 296 ASSERT_TRUE(blob_data_handle2);
298 scoped_ptr<BlobDataSnapshot> data = blob_data_handle2->CreateSnapshot(); 297 scoped_ptr<BlobDataSnapshot> data = blob_data_handle2->CreateSnapshot();
299 ASSERT_EQ(1u, data->items().size()); 298 ASSERT_EQ(1u, data->items().size());
300 const scoped_refptr<BlobDataItem> item = data->items()[0]; 299 const scoped_refptr<BlobDataItem> item = data->items()[0];
301 EXPECT_EQ(kLargeSize - kBlobLength, item->offset()); 300 EXPECT_EQ(kLargeSize - kBlobLength, item->offset());
302 EXPECT_EQ(kBlobLength, item->length()); 301 EXPECT_EQ(kBlobLength, item->length());
303 302
304 blob_data_handle1.reset(); 303 blob_data_handle1.reset();
305 blob_data_handle2.reset(); 304 blob_data_handle2.reset();
306 base::RunLoop().RunUntilIdle(); 305 base::RunLoop().RunUntilIdle();
307 } 306 }
308 307
309 TEST(BlobStorageContextTest, BuildDiskCacheBlob) { 308 TEST_F(BlobStorageContextTest, BuildDiskCacheBlob) {
310 base::MessageLoop fake_io_message_loop; 309 base::MessageLoop fake_io_message_loop;
311 scoped_refptr<BlobDataBuilder::DataHandle> 310 scoped_refptr<BlobDataBuilder::DataHandle>
312 data_handle = new EmptyDataHandle(); 311 data_handle = new EmptyDataHandle();
313 312
314 { 313 {
315 scoped_ptr<BlobStorageContext> context(new BlobStorageContext); 314 BlobStorageContext context;
316 BlobStorageHost host(context.get());
317 315
318 scoped_ptr<disk_cache::Backend> cache = CreateInMemoryDiskCache(); 316 scoped_ptr<disk_cache::Backend> cache = CreateInMemoryDiskCache();
319 ASSERT_TRUE(cache); 317 ASSERT_TRUE(cache);
320 318
321 const std::string kTestBlobData = "Test Blob Data"; 319 const std::string kTestBlobData = "Test Blob Data";
322 disk_cache::ScopedEntryPtr entry = 320 disk_cache::ScopedEntryPtr entry =
323 CreateDiskCacheEntry(cache.get(), "test entry", kTestBlobData); 321 CreateDiskCacheEntry(cache.get(), "test entry", kTestBlobData);
324 322
325 const std::string kId1Prime("id1.prime"); 323 const std::string kId1Prime("id1.prime");
326 BlobDataBuilder canonicalized_blob_data(kId1Prime); 324 BlobDataBuilder canonicalized_blob_data(kId1Prime);
327 canonicalized_blob_data.AppendData(kTestBlobData.c_str()); 325 canonicalized_blob_data.AppendData(kTestBlobData.c_str());
328 326
329 const std::string kId1("id1"); 327 const std::string kId1("id1");
330 BlobDataBuilder builder(kId1); 328 BlobDataBuilder builder(kId1);
331 329
332 builder.AppendDiskCacheEntry( 330 builder.AppendDiskCacheEntry(
333 data_handle, entry.get(), kTestDiskCacheStreamIndex); 331 data_handle, entry.get(), kTestDiskCacheStreamIndex);
334 332
335 scoped_ptr<BlobDataHandle> blob_data_handle = 333 scoped_ptr<BlobDataHandle> blob_data_handle =
336 context->AddFinishedBlob(&builder); 334 context.AddFinishedBlob(&builder);
337 scoped_ptr<BlobDataSnapshot> data = blob_data_handle->CreateSnapshot(); 335 scoped_ptr<BlobDataSnapshot> data = blob_data_handle->CreateSnapshot();
338 EXPECT_EQ(*data, builder); 336 EXPECT_EQ(*data, builder);
339 EXPECT_FALSE(data_handle->HasOneRef()) 337 EXPECT_FALSE(data_handle->HasOneRef())
340 << "Data handle was destructed while context and builder still exist."; 338 << "Data handle was destructed while context and builder still exist.";
341 } 339 }
342 EXPECT_TRUE(data_handle->HasOneRef()) 340 EXPECT_TRUE(data_handle->HasOneRef())
343 << "Data handle was not destructed along with blob storage context."; 341 << "Data handle was not destructed along with blob storage context.";
344 base::RunLoop().RunUntilIdle(); 342 base::RunLoop().RunUntilIdle();
345 } 343 }
346 344
347 TEST(BlobStorageContextTest, CompoundBlobs) { 345 TEST_F(BlobStorageContextTest, CompoundBlobs) {
348 const std::string kId1("id1"); 346 const std::string kId1("id1");
349 const std::string kId2("id2"); 347 const std::string kId2("id2");
350 const std::string kId3("id3"); 348 const std::string kId3("id3");
351 const std::string kId2Prime("id2.prime"); 349 const std::string kId2Prime("id2.prime");
352 350
353 base::MessageLoop fake_io_message_loop; 351 base::MessageLoop fake_io_message_loop;
354 352
355 // Setup a set of blob data for testing. 353 // Setup a set of blob data for testing.
356 base::Time time1, time2; 354 base::Time time1, time2;
357 base::Time::FromString("Tue, 15 Nov 1994, 12:45:26 GMT", &time1); 355 base::Time::FromString("Tue, 15 Nov 1994, 12:45:26 GMT", &time1);
(...skipping 25 matching lines...) Expand all
383 canonicalized_blob_data2.AppendData("a2___", 2); 381 canonicalized_blob_data2.AppendData("a2___", 2);
384 canonicalized_blob_data2.AppendFile( 382 canonicalized_blob_data2.AppendFile(
385 base::FilePath(FILE_PATH_LITERAL("File1.txt")), 10, 98, time1); 383 base::FilePath(FILE_PATH_LITERAL("File1.txt")), 10, 98, time1);
386 canonicalized_blob_data2.AppendFile( 384 canonicalized_blob_data2.AppendFile(
387 base::FilePath(FILE_PATH_LITERAL("File2.txt")), 0, 20, time2); 385 base::FilePath(FILE_PATH_LITERAL("File2.txt")), 0, 20, time2);
388 386
389 BlobStorageContext context; 387 BlobStorageContext context;
390 scoped_ptr<BlobDataHandle> blob_data_handle; 388 scoped_ptr<BlobDataHandle> blob_data_handle;
391 389
392 // Test a blob referring to only data and a file. 390 // Test a blob referring to only data and a file.
393 blob_data_handle = context.AddFinishedBlob(&blob_data1); 391 blob_data_handle = context_.AddFinishedBlob(&blob_data1);
394 392
395 ASSERT_TRUE(blob_data_handle); 393 ASSERT_TRUE(blob_data_handle);
396 scoped_ptr<BlobDataSnapshot> data = blob_data_handle->CreateSnapshot(); 394 scoped_ptr<BlobDataSnapshot> data = blob_data_handle->CreateSnapshot();
397 ASSERT_TRUE(blob_data_handle); 395 ASSERT_TRUE(blob_data_handle);
398 EXPECT_EQ(*data, blob_data1); 396 EXPECT_EQ(*data, blob_data1);
399 397
400 // Test a blob composed in part with another blob. 398 // Test a blob composed in part with another blob.
401 blob_data_handle = context.AddFinishedBlob(&blob_data2); 399 blob_data_handle = context_.AddFinishedBlob(&blob_data2);
402 data = blob_data_handle->CreateSnapshot(); 400 data = blob_data_handle->CreateSnapshot();
403 ASSERT_TRUE(blob_data_handle); 401 ASSERT_TRUE(blob_data_handle);
404 ASSERT_TRUE(data); 402 ASSERT_TRUE(data);
405 EXPECT_EQ(*data, canonicalized_blob_data2); 403 EXPECT_EQ(*data, canonicalized_blob_data2);
406 404
407 // Test a blob referring to only data and a disk cache entry. 405 // Test a blob referring to only data and a disk cache entry.
408 blob_data_handle = context.AddFinishedBlob(&blob_data3); 406 blob_data_handle = context_.AddFinishedBlob(&blob_data3);
409 data = blob_data_handle->CreateSnapshot(); 407 data = blob_data_handle->CreateSnapshot();
410 ASSERT_TRUE(blob_data_handle); 408 ASSERT_TRUE(blob_data_handle);
411 EXPECT_EQ(*data, blob_data3); 409 EXPECT_EQ(*data, blob_data3);
412 410
413 blob_data_handle.reset(); 411 blob_data_handle.reset();
414 base::RunLoop().RunUntilIdle(); 412 base::RunLoop().RunUntilIdle();
415 } 413 }
416 414
417 TEST(BlobStorageContextTest, PublicBlobUrls) { 415 TEST_F(BlobStorageContextTest, PublicBlobUrls) {
418 BlobStorageContext context;
419 BlobStorageHost host(&context);
420 base::MessageLoop fake_io_message_loop; 416 base::MessageLoop fake_io_message_loop;
421 417
422 // Build up a basic blob. 418 // Build up a basic blob.
423 const std::string kId("id"); 419 const std::string kId("id");
424 SetupBasicBlob(&host, kId); 420 scoped_ptr<BlobDataHandle> first_handle = SetupBasicBlob(kId);
425 421
426 // Now register a url for that blob. 422 // Now register a url for that blob.
427 GURL kUrl("blob:id"); 423 GURL kUrl("blob:id");
428 EXPECT_TRUE(host.RegisterPublicBlobURL(kUrl, kId)); 424 context_.RegisterPublicBlobURL(kUrl, kId);
429 scoped_ptr<BlobDataHandle> blob_data_handle = 425 scoped_ptr<BlobDataHandle> blob_data_handle =
430 context.GetBlobDataFromPublicURL(kUrl); 426 context_.GetBlobDataFromPublicURL(kUrl);
431 ASSERT_TRUE(blob_data_handle.get()); 427 ASSERT_TRUE(blob_data_handle.get());
432 EXPECT_EQ(kId, blob_data_handle->uuid()); 428 EXPECT_EQ(kId, blob_data_handle->uuid());
433 scoped_ptr<BlobDataSnapshot> data = blob_data_handle->CreateSnapshot(); 429 scoped_ptr<BlobDataSnapshot> data = blob_data_handle->CreateSnapshot();
434 blob_data_handle.reset(); 430 blob_data_handle.reset();
431 first_handle.reset();
435 base::RunLoop().RunUntilIdle(); 432 base::RunLoop().RunUntilIdle();
436 433
437 // The url registration should keep the blob alive even after 434 // The url registration should keep the blob alive even after
438 // explicit references are dropped. 435 // explicit references are dropped.
439 EXPECT_TRUE(host.DecrementBlobRefCount(kId)); 436 blob_data_handle = context_.GetBlobDataFromPublicURL(kUrl);
440 blob_data_handle = context.GetBlobDataFromPublicURL(kUrl);
441 EXPECT_TRUE(blob_data_handle); 437 EXPECT_TRUE(blob_data_handle);
442 blob_data_handle.reset(); 438 blob_data_handle.reset();
443 base::RunLoop().RunUntilIdle(); 439 base::RunLoop().RunUntilIdle();
444 440
445 // Finally get rid of the url registration and the blob. 441 // Finally get rid of the url registration and the blob.
446 EXPECT_TRUE(host.RevokePublicBlobURL(kUrl)); 442 context_.RevokePublicBlobURL(kUrl);
447 blob_data_handle = context.GetBlobDataFromPublicURL(kUrl); 443 blob_data_handle = context_.GetBlobDataFromPublicURL(kUrl);
448 EXPECT_TRUE(!blob_data_handle.get()); 444 EXPECT_FALSE(blob_data_handle.get());
449 EXPECT_FALSE(host.RevokePublicBlobURL(kUrl)); 445 EXPECT_FALSE(context_.registry().HasEntry(kId));
450 } 446 }
451 447
452 TEST(BlobStorageContextTest, HostCleanup) { 448 TEST_F(BlobStorageContextTest, TestUnknownBrokenAndBuildingBlobReference) {
453 BlobStorageContext context;
454 scoped_ptr<BlobStorageHost> host(new BlobStorageHost(&context));
455 base::MessageLoop fake_io_message_loop; 449 base::MessageLoop fake_io_message_loop;
450 const std::string kBrokenId("broken_id");
451 const std::string kBuildingId("building_id");
452 const std::string kReferencingId("referencing_id");
453 const std::string kUnknownId("unknown_id");
456 454
457 // Build up a basic blob and register a url 455 // Create a broken blob and a building blob.
458 const std::string kId("id"); 456 context_.CreatePendingBlob(kBuildingId, "", "");
459 GURL kUrl("blob:id"); 457 context_.CreatePendingBlob(kBrokenId, "", "");
460 SetupBasicBlob(host.get(), kId); 458 context_.CancelPendingBlob(kBrokenId, IPCBlobCreationCancelCode::UNKNOWN);
461 EXPECT_TRUE(host->RegisterPublicBlobURL(kUrl, kId)); 459 EXPECT_TRUE(context_.IsBroken(kBrokenId));
460 EXPECT_TRUE(context_.registry().HasEntry(kBrokenId));
462 461
463 // All should disappear upon host deletion. 462 // Try to create a blob with a reference to an unknown blob.
464 host.reset(); 463 BlobDataBuilder builder(kReferencingId);
465 scoped_ptr<BlobDataHandle> handle = context.GetBlobDataFromPublicURL(kUrl); 464 builder.AppendData("data");
466 EXPECT_TRUE(!handle.get()); 465 builder.AppendBlob(kUnknownId);
467 handle = context.GetBlobDataFromUUID(kId); 466 scoped_ptr<BlobDataHandle> handle = context_.AddFinishedBlob(builder);
468 EXPECT_TRUE(!handle.get()); 467 EXPECT_TRUE(handle->IsBroken());
469 } 468 EXPECT_TRUE(context_.registry().HasEntry(kReferencingId));
469 handle.reset();
470 base::RunLoop().RunUntilIdle();
471 EXPECT_FALSE(context_.registry().HasEntry(kReferencingId));
470 472
471 TEST(BlobStorageContextTest, EarlyContextDeletion) { 473 // Try to create a blob with a reference to the broken blob.
472 scoped_ptr<BlobStorageContext> context(new BlobStorageContext); 474 BlobDataBuilder builder2(kReferencingId);
473 BlobStorageHost host(context.get()); 475 builder2.AppendData("data");
474 base::MessageLoop fake_io_message_loop; 476 builder2.AppendBlob(kBrokenId);
477 handle = context_.AddFinishedBlob(builder2);
478 EXPECT_TRUE(handle->IsBroken());
479 EXPECT_TRUE(context_.registry().HasEntry(kReferencingId));
480 handle.reset();
481 base::RunLoop().RunUntilIdle();
482 EXPECT_FALSE(context_.registry().HasEntry(kReferencingId));
475 483
476 // Deleting the context should not induce crashes. 484 // Try to create a blob with a reference to the building blob.
477 context.reset(); 485 BlobDataBuilder builder3(kReferencingId);
478 486 builder3.AppendData("data");
479 const std::string kId("id"); 487 builder3.AppendBlob(kBuildingId);
480 GURL kUrl("blob:id"); 488 handle = context_.AddFinishedBlob(builder3);
481 EXPECT_FALSE(host.StartBuildingBlob(kId)); 489 EXPECT_TRUE(handle->IsBroken());
482 DataElement item; 490 EXPECT_TRUE(context_.registry().HasEntry(kReferencingId));
483 item.SetToBytes("1", 1); 491 handle.reset();
484 EXPECT_FALSE(host.AppendBlobDataItem(kId, item)); 492 base::RunLoop().RunUntilIdle();
485 EXPECT_FALSE(host.FinishBuildingBlob(kId, "text/plain")); 493 EXPECT_FALSE(context_.registry().HasEntry(kReferencingId));
486 EXPECT_FALSE(host.RegisterPublicBlobURL(kUrl, kId));
487 EXPECT_FALSE(host.IncrementBlobRefCount(kId));
488 EXPECT_FALSE(host.DecrementBlobRefCount(kId));
489 EXPECT_FALSE(host.RevokePublicBlobURL(kUrl));
490 } 494 }
491 495
492 // TODO(michaeln): tests for the depcrecated url stuff 496 // TODO(michaeln): tests for the depcrecated url stuff
493 497
494 } // namespace content 498 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698