Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / content / browser / fileapi / blob_storage_context_unittest.cc
blob81d873aacfd67e6141c638851dd5d5fc03444729
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
3 // found in the LICENSE file.
5 #include "base/files/file_path.h"
6 #include "base/memory/ref_counted.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/run_loop.h"
10 #include "base/time/time.h"
11 #include "content/browser/fileapi/blob_storage_host.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "webkit/browser/blob/blob_data_handle.h"
14 #include "webkit/browser/blob/blob_storage_context.h"
16 using storage::BlobDataHandle;
18 namespace content {
20 namespace {
21 void SetupBasicBlob(BlobStorageHost* host, const std::string& id) {
22 EXPECT_TRUE(host->StartBuildingBlob(id));
23 BlobData::Item item;
24 item.SetToBytes("1", 1);
25 EXPECT_TRUE(host->AppendBlobDataItem(id, item));
26 EXPECT_TRUE(host->FinishBuildingBlob(id, "text/plain"));
27 EXPECT_FALSE(host->StartBuildingBlob(id));
29 } // namespace
31 TEST(BlobStorageContextTest, IncrementDecrementRef) {
32 BlobStorageContext context;
33 BlobStorageHost host(&context);
34 base::MessageLoop fake_io_message_loop;
36 // Build up a basic blob.
37 const std::string kId("id");
38 SetupBasicBlob(&host, kId);
40 // Make sure it's there, finish building implies a ref of one.
41 scoped_ptr<BlobDataHandle> blob_data_handle;
42 blob_data_handle = context.GetBlobDataFromUUID(kId);
43 EXPECT_TRUE(blob_data_handle);
44 blob_data_handle.reset();
45 { // Clean up for ASAN
46 base::RunLoop run_loop;
47 run_loop.RunUntilIdle();
50 // Make sure its still there after inc/dec.
51 EXPECT_TRUE(host.IncrementBlobRefCount(kId));
52 EXPECT_TRUE(host.DecrementBlobRefCount(kId));
53 blob_data_handle = context.GetBlobDataFromUUID(kId);
54 EXPECT_TRUE(blob_data_handle);
55 blob_data_handle.reset();
56 { // Clean up for ASAN
57 base::RunLoop run_loop;
58 run_loop.RunUntilIdle();
61 // Make sure it goes away in the end.
62 EXPECT_TRUE(host.DecrementBlobRefCount(kId));
63 blob_data_handle = context.GetBlobDataFromUUID(kId);
64 EXPECT_FALSE(blob_data_handle);
65 EXPECT_FALSE(host.DecrementBlobRefCount(kId));
66 EXPECT_FALSE(host.IncrementBlobRefCount(kId));
69 TEST(BlobStorageContextTest, BlobDataHandle) {
70 BlobStorageContext context;
71 BlobStorageHost host(&context);
72 base::MessageLoop fake_io_message_loop;
74 // Build up a basic blob.
75 const std::string kId("id");
76 SetupBasicBlob(&host, kId);
78 // Get a handle to it.
79 scoped_ptr<BlobDataHandle> blob_data_handle =
80 context.GetBlobDataFromUUID(kId);
81 EXPECT_TRUE(blob_data_handle);
83 // Drop the host's ref to it.
84 EXPECT_TRUE(host.DecrementBlobRefCount(kId));
86 // Should still be there due to the handle.
87 scoped_ptr<BlobDataHandle> another_handle =
88 context.GetBlobDataFromUUID(kId);
89 EXPECT_TRUE(another_handle);
91 // Should disappear after dropping both handles.
92 blob_data_handle.reset();
93 another_handle.reset();
94 { // Clean up for ASAN
95 base::RunLoop run_loop;
96 run_loop.RunUntilIdle();
98 blob_data_handle = context.GetBlobDataFromUUID(kId);
99 EXPECT_FALSE(blob_data_handle);
102 TEST(BlobStorageContextTest, CompoundBlobs) {
103 const std::string kId1("id1");
104 const std::string kId2("id2");
105 const std::string kId2Prime("id2.prime");
107 base::MessageLoop fake_io_message_loop;
109 // Setup a set of blob data for testing.
110 base::Time time1, time2;
111 base::Time::FromString("Tue, 15 Nov 1994, 12:45:26 GMT", &time1);
112 base::Time::FromString("Mon, 14 Nov 1994, 11:30:49 GMT", &time2);
114 scoped_refptr<BlobData> blob_data1(new BlobData(kId1));
115 blob_data1->AppendData("Data1");
116 blob_data1->AppendData("Data2");
117 blob_data1->AppendFile(base::FilePath(FILE_PATH_LITERAL("File1.txt")),
118 10, 1024, time1);
120 scoped_refptr<BlobData> blob_data2(new BlobData(kId2));
121 blob_data2->AppendData("Data3");
122 blob_data2->AppendBlob(kId1, 8, 100);
123 blob_data2->AppendFile(base::FilePath(FILE_PATH_LITERAL("File2.txt")),
124 0, 20, time2);
126 scoped_refptr<BlobData> canonicalized_blob_data2(new BlobData(kId2Prime));
127 canonicalized_blob_data2->AppendData("Data3");
128 canonicalized_blob_data2->AppendData("a2___", 2);
129 canonicalized_blob_data2->AppendFile(
130 base::FilePath(FILE_PATH_LITERAL("File1.txt")),
131 10, 98, time1);
132 canonicalized_blob_data2->AppendFile(
133 base::FilePath(FILE_PATH_LITERAL("File2.txt")), 0, 20, time2);
135 BlobStorageContext context;
136 scoped_ptr<BlobDataHandle> blob_data_handle;
138 // Test a blob referring to only data and a file.
139 blob_data_handle = context.AddFinishedBlob(blob_data1.get());
140 ASSERT_TRUE(blob_data_handle.get());
141 EXPECT_TRUE(*(blob_data_handle->data()) == *blob_data1.get());
143 // Test a blob composed in part with another blob.
144 blob_data_handle = context.AddFinishedBlob(blob_data2.get());
145 ASSERT_TRUE(blob_data_handle.get());
146 EXPECT_TRUE(*(blob_data_handle->data()) == *canonicalized_blob_data2.get());
148 blob_data_handle.reset();
149 { // Clean up for ASAN
150 base::RunLoop run_loop;
151 run_loop.RunUntilIdle();
155 TEST(BlobStorageContextTest, PublicBlobUrls) {
156 BlobStorageContext context;
157 BlobStorageHost host(&context);
158 base::MessageLoop fake_io_message_loop;
160 // Build up a basic blob.
161 const std::string kId("id");
162 SetupBasicBlob(&host, kId);
164 // Now register a url for that blob.
165 GURL kUrl("blob:id");
166 EXPECT_TRUE(host.RegisterPublicBlobURL(kUrl, kId));
167 scoped_ptr<BlobDataHandle> blob_data_handle =
168 context.GetBlobDataFromPublicURL(kUrl);
169 ASSERT_TRUE(blob_data_handle.get());
170 EXPECT_EQ(kId, blob_data_handle->data()->uuid());
171 blob_data_handle.reset();
172 { // Clean up for ASAN
173 base::RunLoop run_loop;
174 run_loop.RunUntilIdle();
177 // The url registration should keep the blob alive even after
178 // explicit references are dropped.
179 EXPECT_TRUE(host.DecrementBlobRefCount(kId));
180 blob_data_handle = context.GetBlobDataFromPublicURL(kUrl);
181 EXPECT_TRUE(blob_data_handle);
182 blob_data_handle.reset();
183 { // Clean up for ASAN
184 base::RunLoop run_loop;
185 run_loop.RunUntilIdle();
188 // Finally get rid of the url registration and the blob.
189 EXPECT_TRUE(host.RevokePublicBlobURL(kUrl));
190 blob_data_handle = context.GetBlobDataFromPublicURL(kUrl);
191 EXPECT_TRUE(!blob_data_handle.get());
192 EXPECT_FALSE(host.RevokePublicBlobURL(kUrl));
195 TEST(BlobStorageContextTest, HostCleanup) {
196 BlobStorageContext context;
197 scoped_ptr<BlobStorageHost> host(new BlobStorageHost(&context));
198 base::MessageLoop fake_io_message_loop;
200 // Build up a basic blob and register a url
201 const std::string kId("id");
202 GURL kUrl("blob:id");
203 SetupBasicBlob(host.get(), kId);
204 EXPECT_TRUE(host->RegisterPublicBlobURL(kUrl, kId));
206 // All should disappear upon host deletion.
207 host.reset();
208 scoped_ptr<BlobDataHandle> handle = context.GetBlobDataFromPublicURL(kUrl);
209 EXPECT_TRUE(!handle.get());
210 handle = context.GetBlobDataFromUUID(kId);
211 EXPECT_TRUE(!handle.get());
214 TEST(BlobStorageContextTest, EarlyContextDeletion) {
215 scoped_ptr<BlobStorageContext> context(new BlobStorageContext);
216 BlobStorageHost host(context.get());
217 base::MessageLoop fake_io_message_loop;
219 // Deleting the context should not induce crashes.
220 context.reset();
222 const std::string kId("id");
223 GURL kUrl("blob:id");
224 EXPECT_FALSE(host.StartBuildingBlob(kId));
225 BlobData::Item item;
226 item.SetToBytes("1", 1);
227 EXPECT_FALSE(host.AppendBlobDataItem(kId, item));
228 EXPECT_FALSE(host.FinishBuildingBlob(kId, "text/plain"));
229 EXPECT_FALSE(host.RegisterPublicBlobURL(kUrl, kId));
230 EXPECT_FALSE(host.IncrementBlobRefCount(kId));
231 EXPECT_FALSE(host.DecrementBlobRefCount(kId));
232 EXPECT_FALSE(host.RevokePublicBlobURL(kUrl));
235 // TODO(michaeln): tests for the depcrecated url stuff
237 } // namespace content