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

Side by Side Diff: content/browser/fileapi/blob_storage_context_unittest.cc

Issue 895933007: [Storage] Blob items are now shared between blobs. Ready for disk swap. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Cleanup and added one more histogram Created 5 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
« no previous file with comments | « no previous file | content/browser/fileapi/blob_url_request_job_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "base/files/file_path.h" 5 #include "base/files/file_path.h"
6 #include "base/memory/ref_counted.h" 6 #include "base/memory/ref_counted.h"
7 #include "base/memory/scoped_ptr.h" 7 #include "base/memory/scoped_ptr.h"
8 #include "base/message_loop/message_loop.h" 8 #include "base/message_loop/message_loop.h"
9 #include "base/run_loop.h" 9 #include "base/run_loop.h"
10 #include "base/time/time.h" 10 #include "base/time/time.h"
11 #include "content/browser/fileapi/blob_storage_host.h" 11 #include "content/browser/fileapi/blob_storage_host.h"
12 #include "storage/browser/blob/blob_data_builder.h" 12 #include "storage/browser/blob/blob_data_builder.h"
13 #include "storage/browser/blob/blob_data_handle.h" 13 #include "storage/browser/blob/blob_data_handle.h"
14 #include "storage/browser/blob/blob_data_snapshot.h" 14 #include "storage/browser/blob/blob_data_snapshot.h"
15 #include "storage/browser/blob/blob_storage_context.h" 15 #include "storage/browser/blob/blob_storage_context.h"
16 #include "testing/gtest/include/gtest/gtest.h" 16 #include "testing/gtest/include/gtest/gtest.h"
17 17
18 using storage::BlobDataBuilder; 18 using storage::BlobDataBuilder;
19 using storage::BlobDataHandle; 19 using storage::BlobDataHandle;
20 using storage::BlobDataSnapshot; 20 using storage::BlobDataSnapshot;
21 using storage::BlobStorageContext; 21 using storage::BlobStorageContext;
22 using storage::DataElement; 22 using storage::DataElement;
23 23
24 namespace content { 24 namespace content {
25 25
26 namespace { 26 namespace {
27 // This is necessary to clean up the blobs after the handles are released.
28 void RunEventLoopTillIdle() {
29 base::RunLoop run_loop;
30 run_loop.RunUntilIdle();
31 }
32
27 void SetupBasicBlob(BlobStorageHost* host, const std::string& id) { 33 void SetupBasicBlob(BlobStorageHost* host, const std::string& id) {
28 EXPECT_TRUE(host->StartBuildingBlob(id)); 34 EXPECT_TRUE(host->StartBuildingBlob(id));
29 DataElement item; 35 DataElement item;
30 item.SetToBytes("1", 1); 36 item.SetToBytes("1", 1);
31 EXPECT_TRUE(host->AppendBlobDataItem(id, item)); 37 EXPECT_TRUE(host->AppendBlobDataItem(id, item));
32 EXPECT_TRUE(host->FinishBuildingBlob(id, "text/plain")); 38 EXPECT_TRUE(host->FinishBuildingBlob(id, "text/plain"));
33 EXPECT_FALSE(host->StartBuildingBlob(id)); 39 EXPECT_FALSE(host->StartBuildingBlob(id));
34 } 40 }
35 } // namespace 41 } // namespace
36 42
37 TEST(BlobStorageContextTest, IncrementDecrementRef) { 43 TEST(BlobStorageContextTest, IncrementDecrementRef) {
38 BlobStorageContext context; 44 BlobStorageContext context;
39 BlobStorageHost host(&context); 45 BlobStorageHost host(&context);
40 base::MessageLoop fake_io_message_loop; 46 base::MessageLoop fake_io_message_loop;
41 47
42 // Build up a basic blob. 48 // Build up a basic blob.
43 const std::string kId("id"); 49 const std::string kId("id");
44 SetupBasicBlob(&host, kId); 50 SetupBasicBlob(&host, kId);
45 51
46 // Make sure it's there, finish building implies a ref of one. 52 // Make sure it's there, finish building implies a ref of one.
47 scoped_ptr<BlobDataHandle> blob_data_handle; 53 scoped_ptr<BlobDataHandle> blob_data_handle;
48 blob_data_handle = context.GetBlobDataFromUUID(kId); 54 blob_data_handle = context.GetBlobDataFromUUID(kId);
49 EXPECT_TRUE(blob_data_handle); 55 EXPECT_TRUE(blob_data_handle);
50 blob_data_handle.reset(); 56 blob_data_handle.reset();
51 { // Clean up for ASAN 57 RunEventLoopTillIdle();
52 base::RunLoop run_loop;
53 run_loop.RunUntilIdle();
54 }
55 58
56 // Make sure its still there after inc/dec. 59 // Make sure its still there after inc/dec.
57 EXPECT_TRUE(host.IncrementBlobRefCount(kId)); 60 EXPECT_TRUE(host.IncrementBlobRefCount(kId));
58 EXPECT_TRUE(host.DecrementBlobRefCount(kId)); 61 EXPECT_TRUE(host.DecrementBlobRefCount(kId));
59 blob_data_handle = context.GetBlobDataFromUUID(kId); 62 blob_data_handle = context.GetBlobDataFromUUID(kId);
60 EXPECT_TRUE(blob_data_handle); 63 EXPECT_TRUE(blob_data_handle);
61 blob_data_handle.reset(); 64 blob_data_handle.reset();
62 { // Clean up for ASAN 65 RunEventLoopTillIdle();
63 base::RunLoop run_loop;
64 run_loop.RunUntilIdle();
65 }
66 66
67 // Make sure it goes away in the end. 67 // Make sure it goes away in the end.
68 EXPECT_TRUE(host.DecrementBlobRefCount(kId)); 68 EXPECT_TRUE(host.DecrementBlobRefCount(kId));
69 blob_data_handle = context.GetBlobDataFromUUID(kId); 69 blob_data_handle = context.GetBlobDataFromUUID(kId);
70 EXPECT_FALSE(blob_data_handle); 70 EXPECT_FALSE(blob_data_handle);
71 EXPECT_FALSE(host.DecrementBlobRefCount(kId)); 71 EXPECT_FALSE(host.DecrementBlobRefCount(kId));
72 EXPECT_FALSE(host.IncrementBlobRefCount(kId)); 72 EXPECT_FALSE(host.IncrementBlobRefCount(kId));
73 } 73 }
74 74
75 TEST(BlobStorageContextTest, CancelBuildingBlob) { 75 TEST(BlobStorageContextTest, CancelBuildingBlob) {
(...skipping 30 matching lines...) Expand all
106 EXPECT_TRUE(host.DecrementBlobRefCount(kId)); 106 EXPECT_TRUE(host.DecrementBlobRefCount(kId));
107 107
108 // Should still be there due to the handle. 108 // Should still be there due to the handle.
109 scoped_ptr<BlobDataHandle> another_handle = 109 scoped_ptr<BlobDataHandle> another_handle =
110 context.GetBlobDataFromUUID(kId); 110 context.GetBlobDataFromUUID(kId);
111 EXPECT_TRUE(another_handle); 111 EXPECT_TRUE(another_handle);
112 112
113 // Should disappear after dropping both handles. 113 // Should disappear after dropping both handles.
114 blob_data_handle.reset(); 114 blob_data_handle.reset();
115 another_handle.reset(); 115 another_handle.reset();
116 { // Clean up for ASAN 116 RunEventLoopTillIdle();
117 base::RunLoop run_loop; 117
118 run_loop.RunUntilIdle();
119 }
120 blob_data_handle = context.GetBlobDataFromUUID(kId); 118 blob_data_handle = context.GetBlobDataFromUUID(kId);
121 EXPECT_FALSE(blob_data_handle); 119 EXPECT_FALSE(blob_data_handle);
122 } 120 }
123 121
122 TEST(BlobStorageContextTest, MemoryUsage) {
123 const std::string kId1("id1");
124 const std::string kId2("id2");
125
126 base::MessageLoop fake_io_message_loop;
127
128 BlobDataBuilder builder1(kId1);
129 BlobDataBuilder builder2(kId2);
130 builder1.AppendData("Data1Data2");
131 builder2.AppendBlob(kId1);
132 builder2.AppendBlob(kId1);
133 builder2.AppendBlob(kId1);
134 builder2.AppendBlob(kId1);
135 builder2.AppendBlob(kId1);
136 builder2.AppendBlob(kId1);
137 builder2.AppendBlob(kId1);
138
139 BlobStorageContext context;
140 EXPECT_EQ(0lu, context.memory_usage());
141
142 scoped_ptr<BlobDataHandle> blob_data_handle =
143 context.AddFinishedBlob(&builder1);
144 EXPECT_EQ(10lu, context.memory_usage());
145 scoped_ptr<BlobDataHandle> blob_data_handle2 =
146 context.AddFinishedBlob(&builder2);
147 EXPECT_EQ(10lu, context.memory_usage());
148
149 blob_data_handle.reset();
150 RunEventLoopTillIdle();
151
152 EXPECT_EQ(10lu, context.memory_usage());
153 blob_data_handle2.reset();
154 RunEventLoopTillIdle();
155
156 EXPECT_EQ(0lu, context.memory_usage());
157 }
158
159 TEST(BlobStorageContextTest, AddFinishedBlob) {
160 const std::string kId1("id1");
161 const std::string kId2("id12");
162 const std::string kId2Prime("id2.prime");
163 const std::string kId3("id3");
164 const std::string kId3Prime("id3.prime");
165
166 base::MessageLoop fake_io_message_loop;
167
168 BlobDataBuilder builder1(kId1);
169 BlobDataBuilder builder2(kId2);
170 BlobDataBuilder canonicalized_blob_data2(kId2Prime);
171 builder1.AppendData("Data1Data2");
172 builder2.AppendBlob(kId1, 5, 5);
173 builder2.AppendData(" is the best");
174 canonicalized_blob_data2.AppendData("Data2");
175 canonicalized_blob_data2.AppendData(" is the best");
176
177 BlobStorageContext context;
178
179 scoped_ptr<BlobDataHandle> blob_data_handle =
180 context.AddFinishedBlob(&builder1);
181 scoped_ptr<BlobDataHandle> blob_data_handle2 =
182 context.AddFinishedBlob(&builder2);
183
184 ASSERT_TRUE(blob_data_handle);
185 ASSERT_TRUE(blob_data_handle2);
186 scoped_ptr<BlobDataSnapshot> data1 = blob_data_handle->CreateSnapshot();
187 scoped_ptr<BlobDataSnapshot> data2 = blob_data_handle2->CreateSnapshot();
188 EXPECT_EQ(*data1, builder1);
189 EXPECT_EQ(*data2, canonicalized_blob_data2);
190 blob_data_handle.reset();
191 data2.reset();
192
193 RunEventLoopTillIdle();
194
195 blob_data_handle = context.GetBlobDataFromUUID(kId1);
196 EXPECT_FALSE(blob_data_handle);
197 EXPECT_TRUE(blob_data_handle2);
198 data2 = blob_data_handle2->CreateSnapshot();
199 EXPECT_EQ(*data2, canonicalized_blob_data2);
200
201 // Test shared elements stick around.
202 BlobDataBuilder builder3(kId3);
203 builder3.AppendBlob(kId2);
204 builder3.AppendBlob(kId2);
205 scoped_ptr<BlobDataHandle> blob_data_handle3 =
206 context.AddFinishedBlob(&builder3);
207 blob_data_handle2.reset();
208 RunEventLoopTillIdle();
209
210 blob_data_handle2 = context.GetBlobDataFromUUID(kId2);
211 EXPECT_FALSE(blob_data_handle2);
212 EXPECT_TRUE(blob_data_handle3);
213 scoped_ptr<BlobDataSnapshot> data3 = blob_data_handle3->CreateSnapshot();
214
215 BlobDataBuilder canonicalized_blob_data3(kId3Prime);
216 canonicalized_blob_data3.AppendData("Data2");
217 canonicalized_blob_data3.AppendData(" is the best");
218 canonicalized_blob_data3.AppendData("Data2");
219 canonicalized_blob_data3.AppendData(" is the best");
220 EXPECT_EQ(*data3, canonicalized_blob_data3);
221
222 blob_data_handle.reset();
223 blob_data_handle2.reset();
224 blob_data_handle3.reset();
225 RunEventLoopTillIdle();
226 }
227
124 TEST(BlobStorageContextTest, CompoundBlobs) { 228 TEST(BlobStorageContextTest, CompoundBlobs) {
125 const std::string kId1("id1"); 229 const std::string kId1("id1");
126 const std::string kId2("id2"); 230 const std::string kId2("id2");
127 const std::string kId2Prime("id2.prime"); 231 const std::string kId2Prime("id2.prime");
128 232
129 base::MessageLoop fake_io_message_loop; 233 base::MessageLoop fake_io_message_loop;
130 234
131 // Setup a set of blob data for testing. 235 // Setup a set of blob data for testing.
132 base::Time time1, time2; 236 base::Time time1, time2;
133 base::Time::FromString("Tue, 15 Nov 1994, 12:45:26 GMT", &time1); 237 base::Time::FromString("Tue, 15 Nov 1994, 12:45:26 GMT", &time1);
134 base::Time::FromString("Mon, 14 Nov 1994, 11:30:49 GMT", &time2); 238 base::Time::FromString("Mon, 14 Nov 1994, 11:30:49 GMT", &time2);
135 239
136 scoped_ptr<BlobDataBuilder> blob_data1(new BlobDataBuilder(kId1)); 240 BlobDataBuilder blob_data1(kId1);
137 blob_data1->AppendData("Data1"); 241 blob_data1.AppendData("Data1");
138 blob_data1->AppendData("Data2"); 242 blob_data1.AppendData("Data2");
139 blob_data1->AppendFile(base::FilePath(FILE_PATH_LITERAL("File1.txt")), 243 blob_data1.AppendFile(base::FilePath(FILE_PATH_LITERAL("File1.txt")), 10,
140 10, 1024, time1); 244 1024, time1);
141 245
142 scoped_ptr<BlobDataBuilder> blob_data2(new BlobDataBuilder(kId2)); 246 BlobDataBuilder blob_data2(kId2);
143 blob_data2->AppendData("Data3"); 247 blob_data2.AppendData("Data3");
144 blob_data2->AppendBlob(kId1, 8, 100); 248 blob_data2.AppendBlob(kId1, 8, 100);
145 blob_data2->AppendFile(base::FilePath(FILE_PATH_LITERAL("File2.txt")), 249 blob_data2.AppendFile(base::FilePath(FILE_PATH_LITERAL("File2.txt")), 0, 20,
146 0, 20, time2); 250 time2);
147 251
148 scoped_ptr<BlobDataBuilder> canonicalized_blob_data2( 252 BlobDataBuilder canonicalized_blob_data2(kId2Prime);
149 new BlobDataBuilder(kId2Prime)); 253 canonicalized_blob_data2.AppendData("Data3");
150 canonicalized_blob_data2->AppendData("Data3"); 254 canonicalized_blob_data2.AppendData("a2___", 2);
151 canonicalized_blob_data2->AppendData("a2___", 2); 255 canonicalized_blob_data2.AppendFile(
152 canonicalized_blob_data2->AppendFile( 256 base::FilePath(FILE_PATH_LITERAL("File1.txt")), 10, 98, time1);
153 base::FilePath(FILE_PATH_LITERAL("File1.txt")), 257 canonicalized_blob_data2.AppendFile(
154 10, 98, time1);
155 canonicalized_blob_data2->AppendFile(
156 base::FilePath(FILE_PATH_LITERAL("File2.txt")), 0, 20, time2); 258 base::FilePath(FILE_PATH_LITERAL("File2.txt")), 0, 20, time2);
157 259
158 BlobStorageContext context; 260 BlobStorageContext context;
159 scoped_ptr<BlobDataHandle> blob_data_handle; 261 scoped_ptr<BlobDataHandle> blob_data_handle;
160 262
161 // Test a blob referring to only data and a file. 263 // Test a blob referring to only data and a file.
162 blob_data_handle = context.AddFinishedBlob(*blob_data1.get()); 264 blob_data_handle = context.AddFinishedBlob(&blob_data1);
265
163 ASSERT_TRUE(blob_data_handle); 266 ASSERT_TRUE(blob_data_handle);
164 scoped_ptr<BlobDataSnapshot> data = blob_data_handle->CreateSnapshot(); 267 scoped_ptr<BlobDataSnapshot> data = blob_data_handle->CreateSnapshot();
165 ASSERT_TRUE(blob_data_handle); 268 ASSERT_TRUE(blob_data_handle);
166 EXPECT_EQ(*data, *blob_data1); 269 EXPECT_EQ(*data, blob_data1);
167 270
168 // Test a blob composed in part with another blob. 271 // Test a blob composed in part with another blob.
169 blob_data_handle = context.AddFinishedBlob(*blob_data2.get()); 272 blob_data_handle = context.AddFinishedBlob(&blob_data2);
170 data = blob_data_handle->CreateSnapshot(); 273 data = blob_data_handle->CreateSnapshot();
171 ASSERT_TRUE(blob_data_handle); 274 ASSERT_TRUE(blob_data_handle);
172 ASSERT_TRUE(data); 275 ASSERT_TRUE(data);
173 EXPECT_EQ(*data, *canonicalized_blob_data2); 276 EXPECT_EQ(*data, canonicalized_blob_data2);
174 277
175 blob_data_handle.reset(); 278 blob_data_handle.reset();
176 { // Clean up for ASAN 279 RunEventLoopTillIdle();
177 base::RunLoop run_loop;
178 run_loop.RunUntilIdle();
179 }
180 } 280 }
181 281
182 TEST(BlobStorageContextTest, PublicBlobUrls) { 282 TEST(BlobStorageContextTest, PublicBlobUrls) {
183 BlobStorageContext context; 283 BlobStorageContext context;
184 BlobStorageHost host(&context); 284 BlobStorageHost host(&context);
185 base::MessageLoop fake_io_message_loop; 285 base::MessageLoop fake_io_message_loop;
186 286
187 // Build up a basic blob. 287 // Build up a basic blob.
188 const std::string kId("id"); 288 const std::string kId("id");
189 SetupBasicBlob(&host, kId); 289 SetupBasicBlob(&host, kId);
190 290
191 // Now register a url for that blob. 291 // Now register a url for that blob.
192 GURL kUrl("blob:id"); 292 GURL kUrl("blob:id");
193 EXPECT_TRUE(host.RegisterPublicBlobURL(kUrl, kId)); 293 EXPECT_TRUE(host.RegisterPublicBlobURL(kUrl, kId));
194 scoped_ptr<BlobDataHandle> blob_data_handle = 294 scoped_ptr<BlobDataHandle> blob_data_handle =
195 context.GetBlobDataFromPublicURL(kUrl); 295 context.GetBlobDataFromPublicURL(kUrl);
196 ASSERT_TRUE(blob_data_handle.get()); 296 ASSERT_TRUE(blob_data_handle.get());
197 EXPECT_EQ(kId, blob_data_handle->uuid()); 297 EXPECT_EQ(kId, blob_data_handle->uuid());
198 scoped_ptr<BlobDataSnapshot> data = blob_data_handle->CreateSnapshot(); 298 scoped_ptr<BlobDataSnapshot> data = blob_data_handle->CreateSnapshot();
199 blob_data_handle.reset(); 299 blob_data_handle.reset();
200 { // Clean up for ASAN 300 RunEventLoopTillIdle();
201 base::RunLoop run_loop;
202 run_loop.RunUntilIdle();
203 }
204 301
205 // The url registration should keep the blob alive even after 302 // The url registration should keep the blob alive even after
206 // explicit references are dropped. 303 // explicit references are dropped.
207 EXPECT_TRUE(host.DecrementBlobRefCount(kId)); 304 EXPECT_TRUE(host.DecrementBlobRefCount(kId));
208 blob_data_handle = context.GetBlobDataFromPublicURL(kUrl); 305 blob_data_handle = context.GetBlobDataFromPublicURL(kUrl);
209 EXPECT_TRUE(blob_data_handle); 306 EXPECT_TRUE(blob_data_handle);
210 blob_data_handle.reset(); 307 blob_data_handle.reset();
211 { // Clean up for ASAN 308 RunEventLoopTillIdle();
212 base::RunLoop run_loop;
213 run_loop.RunUntilIdle();
214 }
215 309
216 // Finally get rid of the url registration and the blob. 310 // Finally get rid of the url registration and the blob.
217 EXPECT_TRUE(host.RevokePublicBlobURL(kUrl)); 311 EXPECT_TRUE(host.RevokePublicBlobURL(kUrl));
218 blob_data_handle = context.GetBlobDataFromPublicURL(kUrl); 312 blob_data_handle = context.GetBlobDataFromPublicURL(kUrl);
219 EXPECT_TRUE(!blob_data_handle.get()); 313 EXPECT_TRUE(!blob_data_handle.get());
220 EXPECT_FALSE(host.RevokePublicBlobURL(kUrl)); 314 EXPECT_FALSE(host.RevokePublicBlobURL(kUrl));
221 } 315 }
222 316
223 TEST(BlobStorageContextTest, HostCleanup) { 317 TEST(BlobStorageContextTest, HostCleanup) {
224 BlobStorageContext context; 318 BlobStorageContext context;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 EXPECT_FALSE(host.FinishBuildingBlob(kId, "text/plain")); 350 EXPECT_FALSE(host.FinishBuildingBlob(kId, "text/plain"));
257 EXPECT_FALSE(host.RegisterPublicBlobURL(kUrl, kId)); 351 EXPECT_FALSE(host.RegisterPublicBlobURL(kUrl, kId));
258 EXPECT_FALSE(host.IncrementBlobRefCount(kId)); 352 EXPECT_FALSE(host.IncrementBlobRefCount(kId));
259 EXPECT_FALSE(host.DecrementBlobRefCount(kId)); 353 EXPECT_FALSE(host.DecrementBlobRefCount(kId));
260 EXPECT_FALSE(host.RevokePublicBlobURL(kUrl)); 354 EXPECT_FALSE(host.RevokePublicBlobURL(kUrl));
261 } 355 }
262 356
263 // TODO(michaeln): tests for the depcrecated url stuff 357 // TODO(michaeln): tests for the depcrecated url stuff
264 358
265 } // namespace content 359 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | content/browser/fileapi/blob_url_request_job_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698