OLD | NEW |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |