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 "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 <memory> | 10 #include <memory> |
11 #include <string> | 11 #include <string> |
12 | 12 |
| 13 #include "base/bind.h" |
13 #include "base/files/file.h" | 14 #include "base/files/file.h" |
14 #include "base/files/file_path.h" | 15 #include "base/files/file_path.h" |
| 16 #include "base/files/file_util.h" |
15 #include "base/memory/ref_counted.h" | 17 #include "base/memory/ref_counted.h" |
16 #include "base/message_loop/message_loop.h" | 18 #include "base/message_loop/message_loop.h" |
17 #include "base/run_loop.h" | 19 #include "base/run_loop.h" |
| 20 #include "base/strings/string_number_conversions.h" |
| 21 #include "base/test/test_simple_task_runner.h" |
| 22 #include "base/threading/thread_task_runner_handle.h" |
18 #include "base/time/time.h" | 23 #include "base/time/time.h" |
19 #include "content/browser/blob_storage/blob_dispatcher_host.h" | 24 #include "content/browser/blob_storage/blob_dispatcher_host.h" |
20 #include "content/browser/blob_storage/chrome_blob_storage_context.h" | 25 #include "content/browser/blob_storage/chrome_blob_storage_context.h" |
21 #include "content/public/test/test_browser_context.h" | 26 #include "content/public/test/test_browser_context.h" |
22 #include "net/base/io_buffer.h" | 27 #include "net/base/io_buffer.h" |
23 #include "net/base/test_completion_callback.h" | 28 #include "net/base/test_completion_callback.h" |
24 #include "net/disk_cache/disk_cache.h" | 29 #include "net/disk_cache/disk_cache.h" |
25 #include "storage/browser/blob/blob_async_builder_host.h" | |
26 #include "storage/browser/blob/blob_data_builder.h" | 30 #include "storage/browser/blob/blob_data_builder.h" |
27 #include "storage/browser/blob/blob_data_handle.h" | 31 #include "storage/browser/blob/blob_data_handle.h" |
28 #include "storage/browser/blob/blob_data_item.h" | 32 #include "storage/browser/blob/blob_data_item.h" |
29 #include "storage/browser/blob/blob_data_snapshot.h" | 33 #include "storage/browser/blob/blob_data_snapshot.h" |
30 #include "storage/browser/blob/blob_transport_result.h" | 34 #include "storage/browser/blob/blob_transport_host.h" |
31 #include "storage/common/blob_storage/blob_item_bytes_request.h" | 35 #include "storage/common/blob_storage/blob_item_bytes_request.h" |
32 #include "storage/common/blob_storage/blob_item_bytes_response.h" | 36 #include "storage/common/blob_storage/blob_item_bytes_response.h" |
33 #include "testing/gtest/include/gtest/gtest.h" | 37 #include "testing/gtest/include/gtest/gtest.h" |
34 | 38 |
35 using RequestMemoryCallback = | 39 using RequestMemoryCallback = storage::BlobTransportHost::RequestMemoryCallback; |
36 storage::BlobAsyncBuilderHost::RequestMemoryCallback; | 40 using FileCreationInfo = storage::BlobMemoryController::FileCreationInfo; |
37 | 41 |
38 namespace storage { | 42 namespace storage { |
39 namespace { | 43 namespace { |
| 44 using base::TestSimpleTaskRunner; |
40 | 45 |
41 const char kContentType[] = "text/plain"; | |
42 const char kContentDisposition[] = "content_disposition"; | |
43 const int kTestDiskCacheStreamIndex = 0; | 46 const int kTestDiskCacheStreamIndex = 0; |
44 | 47 |
| 48 const std::string kBlobStorageDirectory = "blob_storage"; |
| 49 const size_t kTestBlobStorageIPCThresholdBytes = 20; |
| 50 const size_t kTestBlobStorageMaxSharedMemoryBytes = 50; |
| 51 |
| 52 const size_t kTestBlobStorageMaxBlobMemorySize = 400; |
| 53 const uint64_t kTestBlobStorageMaxDiskSpace = 4000; |
| 54 const uint64_t kTestBlobStorageMinFileSizeBytes = 10; |
| 55 const uint64_t kTestBlobStorageMaxFileSizeBytes = 100; |
| 56 |
45 // Our disk cache tests don't need a real data handle since the tests themselves | 57 // Our disk cache tests don't need a real data handle since the tests themselves |
46 // scope the disk cache and entries. | 58 // scope the disk cache and entries. |
47 class EmptyDataHandle : public storage::BlobDataBuilder::DataHandle { | 59 class EmptyDataHandle : public storage::BlobDataBuilder::DataHandle { |
48 private: | 60 private: |
49 ~EmptyDataHandle() override {} | 61 ~EmptyDataHandle() override {} |
50 }; | 62 }; |
51 | 63 |
52 std::unique_ptr<disk_cache::Backend> CreateInMemoryDiskCache() { | 64 std::unique_ptr<disk_cache::Backend> CreateInMemoryDiskCache() { |
53 std::unique_ptr<disk_cache::Backend> cache; | 65 std::unique_ptr<disk_cache::Backend> cache; |
54 net::TestCompletionCallback callback; | 66 net::TestCompletionCallback callback; |
(...skipping 17 matching lines...) Expand all Loading... |
72 return nullptr; | 84 return nullptr; |
73 disk_cache::ScopedEntryPtr entry(temp_entry); | 85 disk_cache::ScopedEntryPtr entry(temp_entry); |
74 | 86 |
75 scoped_refptr<net::StringIOBuffer> iobuffer = new net::StringIOBuffer(data); | 87 scoped_refptr<net::StringIOBuffer> iobuffer = new net::StringIOBuffer(data); |
76 rv = entry->WriteData(kTestDiskCacheStreamIndex, 0, iobuffer.get(), | 88 rv = entry->WriteData(kTestDiskCacheStreamIndex, 0, iobuffer.get(), |
77 iobuffer->size(), callback.callback(), false); | 89 iobuffer->size(), callback.callback(), false); |
78 EXPECT_EQ(static_cast<int>(data.size()), callback.GetResult(rv)); | 90 EXPECT_EQ(static_cast<int>(data.size()), callback.GetResult(rv)); |
79 return entry; | 91 return entry; |
80 } | 92 } |
81 | 93 |
| 94 void SaveBlobStatus(BlobStatus* status_ptr, BlobStatus status) { |
| 95 *status_ptr = status; |
| 96 } |
| 97 |
| 98 void SaveBlobStatusAndFiles(BlobStatus* status_ptr, |
| 99 std::vector<FileCreationInfo>* files_ptr, |
| 100 BlobStatus status, |
| 101 std::vector<FileCreationInfo> files) { |
| 102 *status_ptr = status; |
| 103 for (FileCreationInfo& info : files) { |
| 104 files_ptr->push_back(std::move(info)); |
| 105 } |
| 106 } |
82 | 107 |
83 } // namespace | 108 } // namespace |
84 | 109 |
85 class BlobStorageContextTest : public testing::Test { | 110 class BlobStorageContextTest : public testing::Test { |
86 protected: | 111 protected: |
87 BlobStorageContextTest() {} | 112 BlobStorageContextTest() {} |
88 ~BlobStorageContextTest() override {} | 113 ~BlobStorageContextTest() override {} |
89 | 114 |
| 115 void SetUp() override { context_ = base::MakeUnique<BlobStorageContext>(); } |
| 116 |
90 std::unique_ptr<BlobDataHandle> SetupBasicBlob(const std::string& id) { | 117 std::unique_ptr<BlobDataHandle> SetupBasicBlob(const std::string& id) { |
91 BlobDataBuilder builder(id); | 118 BlobDataBuilder builder(id); |
92 builder.AppendData("1", 1); | 119 builder.AppendData("1", 1); |
93 builder.set_content_type("text/plain"); | 120 builder.set_content_type("text/plain"); |
94 return context_.AddFinishedBlob(builder); | 121 return context_->AddFinishedBlob(builder); |
95 } | 122 } |
96 | 123 |
97 BlobStorageContext context_; | 124 void SetTestMemoryLimits() { |
| 125 BlobStorageLimits limits; |
| 126 limits.max_ipc_memory_size = kTestBlobStorageIPCThresholdBytes; |
| 127 limits.max_shared_memory_size = kTestBlobStorageMaxSharedMemoryBytes; |
| 128 limits.max_blob_in_memory_space = kTestBlobStorageMaxBlobMemorySize; |
| 129 limits.max_blob_disk_space = kTestBlobStorageMaxDiskSpace; |
| 130 limits.min_page_file_size = kTestBlobStorageMinFileSizeBytes; |
| 131 limits.max_file_size = kTestBlobStorageMaxFileSizeBytes; |
| 132 context_->mutable_memory_controller()->set_limits_for_testing(limits); |
| 133 } |
| 134 |
| 135 void IncrementRefCount(const std::string& uuid) { |
| 136 context_->IncrementBlobRefCount(uuid); |
| 137 } |
| 138 |
| 139 void DecrementRefCount(const std::string& uuid) { |
| 140 context_->DecrementBlobRefCount(uuid); |
| 141 } |
| 142 |
| 143 std::vector<FileCreationInfo> files_; |
| 144 |
| 145 base::MessageLoop fake_io_message_loop_; |
| 146 std::unique_ptr<BlobStorageContext> context_; |
98 }; | 147 }; |
99 | 148 |
| 149 TEST_F(BlobStorageContextTest, BuildBlobAsync) { |
| 150 const std::string kId("id"); |
| 151 const size_t kSize = 10u; |
| 152 BlobStatus status = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS; |
| 153 |
| 154 BlobDataBuilder builder(kId); |
| 155 builder.AppendFutureData(kSize); |
| 156 builder.set_content_type("text/plain"); |
| 157 EXPECT_EQ(0lu, context_->memory_controller().memory_usage()); |
| 158 std::unique_ptr<BlobDataHandle> handle = context_->BuildBlob( |
| 159 builder, base::Bind(&SaveBlobStatusAndFiles, &status, &files_)); |
| 160 EXPECT_EQ(10lu, context_->memory_controller().memory_usage()); |
| 161 EXPECT_TRUE(handle->IsBeingBuilt()) |
| 162 << static_cast<int>(handle->GetBlobStatus()); |
| 163 EXPECT_EQ(BlobStatus::PENDING_TRANSPORT, status); |
| 164 |
| 165 BlobStatus construction_done = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS; |
| 166 handle->RunOnConstructionComplete( |
| 167 base::Bind(&SaveBlobStatus, &construction_done)); |
| 168 |
| 169 EXPECT_EQ(10u, context_->memory_controller().memory_usage()); |
| 170 |
| 171 builder.PopulateFutureData(0, "abcdefghij", 0, 10u); |
| 172 context_->NotifyTransportComplete(kId); |
| 173 |
| 174 // Check we're done. |
| 175 EXPECT_EQ(BlobStatus::DONE, handle->GetBlobStatus()); |
| 176 base::RunLoop().RunUntilIdle(); |
| 177 EXPECT_EQ(BlobStatus::DONE, construction_done); |
| 178 |
| 179 EXPECT_EQ(builder, *handle->CreateSnapshot()); |
| 180 |
| 181 handle.reset(); |
| 182 base::RunLoop().RunUntilIdle(); |
| 183 EXPECT_EQ(0lu, context_->memory_controller().memory_usage()); |
| 184 } |
| 185 |
| 186 TEST_F(BlobStorageContextTest, BuildBlobAndCancel) { |
| 187 const std::string kId("id"); |
| 188 const size_t kSize = 10u; |
| 189 BlobStatus status = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS; |
| 190 |
| 191 BlobDataBuilder builder(kId); |
| 192 builder.AppendFutureData(kSize); |
| 193 builder.set_content_type("text/plain"); |
| 194 EXPECT_EQ(0lu, context_->memory_controller().memory_usage()); |
| 195 std::unique_ptr<BlobDataHandle> handle = context_->BuildBlob( |
| 196 builder, base::Bind(&SaveBlobStatusAndFiles, &status, &files_)); |
| 197 EXPECT_EQ(10lu, context_->memory_controller().memory_usage()); |
| 198 EXPECT_TRUE(handle->IsBeingBuilt()); |
| 199 EXPECT_EQ(BlobStatus::PENDING_TRANSPORT, status); |
| 200 EXPECT_EQ(10u, context_->memory_controller().memory_usage()); |
| 201 |
| 202 BlobStatus construction_done = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS; |
| 203 handle->RunOnConstructionComplete( |
| 204 base::Bind(&SaveBlobStatus, &construction_done)); |
| 205 |
| 206 context_->CancelBuildingBlob(kId, BlobStatus::ERR_SOURCE_DIED_IN_TRANSIT); |
| 207 EXPECT_TRUE(handle->IsBroken()); |
| 208 EXPECT_EQ(0lu, context_->memory_controller().memory_usage()); |
| 209 |
| 210 // Check we're broken. |
| 211 EXPECT_EQ(BlobStatus::ERR_SOURCE_DIED_IN_TRANSIT, handle->GetBlobStatus()); |
| 212 base::RunLoop().RunUntilIdle(); |
| 213 EXPECT_EQ(BlobStatus::ERR_SOURCE_DIED_IN_TRANSIT, construction_done); |
| 214 } |
| 215 |
| 216 TEST_F(BlobStorageContextTest, CancelledReference) { |
| 217 const std::string kId1("id1"); |
| 218 const std::string kId2("id2"); |
| 219 const size_t kSize = 10u; |
| 220 BlobStatus status = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS; |
| 221 |
| 222 // Start our first blob. |
| 223 BlobDataBuilder builder(kId1); |
| 224 builder.AppendFutureData(kSize); |
| 225 builder.set_content_type("text/plain"); |
| 226 EXPECT_EQ(0lu, context_->memory_controller().memory_usage()); |
| 227 std::unique_ptr<BlobDataHandle> handle = context_->BuildBlob( |
| 228 builder, base::Bind(&SaveBlobStatusAndFiles, &status, &files_)); |
| 229 EXPECT_EQ(10lu, context_->memory_controller().memory_usage()); |
| 230 EXPECT_TRUE(handle->IsBeingBuilt()); |
| 231 EXPECT_EQ(BlobStatus::PENDING_TRANSPORT, status); |
| 232 |
| 233 BlobStatus construction_done = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS; |
| 234 handle->RunOnConstructionComplete( |
| 235 base::Bind(&SaveBlobStatus, &construction_done)); |
| 236 |
| 237 EXPECT_EQ(10u, context_->memory_controller().memory_usage()); |
| 238 |
| 239 // Create our second blob, which depends on the first. |
| 240 BlobDataBuilder builder2(kId2); |
| 241 builder2.AppendBlob(kId1); |
| 242 builder2.set_content_type("text/plain"); |
| 243 std::unique_ptr<BlobDataHandle> handle2 = context_->BuildBlob( |
| 244 builder2, BlobStorageContext::TransportAllowedCallback()); |
| 245 BlobStatus construction_done2 = |
| 246 BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS; |
| 247 handle->RunOnConstructionComplete( |
| 248 base::Bind(&SaveBlobStatus, &construction_done2)); |
| 249 EXPECT_TRUE(handle2->IsBeingBuilt()); |
| 250 |
| 251 EXPECT_EQ(10lu, context_->memory_controller().memory_usage()); |
| 252 |
| 253 // Cancel the first blob. |
| 254 context_->CancelBuildingBlob(kId1, BlobStatus::ERR_SOURCE_DIED_IN_TRANSIT); |
| 255 |
| 256 base::RunLoop().RunUntilIdle(); |
| 257 // Check we broke successfully. |
| 258 EXPECT_EQ(BlobStatus::ERR_SOURCE_DIED_IN_TRANSIT, construction_done); |
| 259 EXPECT_EQ(BlobStatus::ERR_SOURCE_DIED_IN_TRANSIT, handle->GetBlobStatus()); |
| 260 EXPECT_EQ(0lu, context_->memory_controller().memory_usage()); |
| 261 EXPECT_TRUE(handle->IsBroken()); |
| 262 |
| 263 // Check that it propagated. |
| 264 EXPECT_TRUE(handle2->IsBroken()); |
| 265 EXPECT_EQ(BlobStatus::ERR_SOURCE_DIED_IN_TRANSIT, construction_done2); |
| 266 EXPECT_EQ(BlobStatus::ERR_SOURCE_DIED_IN_TRANSIT, handle->GetBlobStatus()); |
| 267 } |
| 268 |
| 269 TEST_F(BlobStorageContextTest, IncorrectSlice) { |
| 270 const std::string kId1("id1"); |
| 271 const std::string kId2("id2"); |
| 272 |
| 273 std::unique_ptr<BlobDataHandle> handle = SetupBasicBlob(kId1); |
| 274 |
| 275 EXPECT_EQ(1lu, context_->memory_controller().memory_usage()); |
| 276 |
| 277 BlobDataBuilder builder(kId2); |
| 278 builder.AppendBlob(kId1, 1, 10); |
| 279 std::unique_ptr<BlobDataHandle> handle2 = context_->BuildBlob( |
| 280 builder, BlobStorageContext::TransportAllowedCallback()); |
| 281 |
| 282 EXPECT_TRUE(handle2->IsBroken()); |
| 283 EXPECT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS, |
| 284 handle2->GetBlobStatus()); |
| 285 } |
| 286 |
100 TEST_F(BlobStorageContextTest, IncrementDecrementRef) { | 287 TEST_F(BlobStorageContextTest, IncrementDecrementRef) { |
101 base::MessageLoop fake_io_message_loop; | |
102 | |
103 // Build up a basic blob. | 288 // Build up a basic blob. |
104 const std::string kId("id"); | 289 const std::string kId("id"); |
105 std::unique_ptr<BlobDataHandle> blob_data_handle = SetupBasicBlob(kId); | 290 std::unique_ptr<BlobDataHandle> blob_data_handle = SetupBasicBlob(kId); |
106 | 291 |
107 // Do an extra increment to keep it around after we kill the handle. | 292 // Do an extra increment to keep it around after we kill the handle. |
108 context_.IncrementBlobRefCount(kId); | 293 IncrementRefCount(kId); |
109 context_.IncrementBlobRefCount(kId); | 294 IncrementRefCount(kId); |
110 context_.DecrementBlobRefCount(kId); | 295 DecrementRefCount(kId); |
111 blob_data_handle = context_.GetBlobDataFromUUID(kId); | 296 blob_data_handle = context_->GetBlobDataFromUUID(kId); |
112 EXPECT_TRUE(blob_data_handle); | 297 EXPECT_TRUE(blob_data_handle); |
113 blob_data_handle.reset(); | 298 blob_data_handle.reset(); |
114 base::RunLoop().RunUntilIdle(); | 299 base::RunLoop().RunUntilIdle(); |
115 | 300 |
116 EXPECT_TRUE(context_.registry().HasEntry(kId)); | 301 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
117 context_.DecrementBlobRefCount(kId); | 302 DecrementRefCount(kId); |
118 EXPECT_FALSE(context_.registry().HasEntry(kId)); | 303 EXPECT_FALSE(context_->registry().HasEntry(kId)); |
119 | 304 |
120 // Make sure it goes away in the end. | 305 // Make sure it goes away in the end. |
121 blob_data_handle = context_.GetBlobDataFromUUID(kId); | 306 blob_data_handle = context_->GetBlobDataFromUUID(kId); |
122 EXPECT_FALSE(blob_data_handle); | 307 EXPECT_FALSE(blob_data_handle); |
123 } | 308 } |
124 | 309 |
125 TEST_F(BlobStorageContextTest, OnCancelBuildingBlob) { | 310 TEST_F(BlobStorageContextTest, BlobDataHandle) { |
126 base::MessageLoop fake_io_message_loop; | |
127 | |
128 // Build up a basic blob. | 311 // Build up a basic blob. |
129 const std::string kId("id"); | 312 const std::string kId("id"); |
130 context_.CreatePendingBlob(kId, std::string(kContentType), | |
131 std::string(kContentDisposition)); | |
132 EXPECT_TRUE(context_.IsBeingBuilt(kId)); | |
133 context_.CancelPendingBlob(kId, IPCBlobCreationCancelCode::OUT_OF_MEMORY); | |
134 EXPECT_TRUE(context_.registry().HasEntry(kId)); | |
135 EXPECT_FALSE(context_.IsBeingBuilt(kId)); | |
136 EXPECT_TRUE(context_.IsBroken(kId)); | |
137 } | |
138 | |
139 TEST_F(BlobStorageContextTest, BlobDataHandle) { | |
140 base::MessageLoop fake_io_message_loop; | |
141 | |
142 // Build up a basic blob. | |
143 const std::string kId("id"); | |
144 std::unique_ptr<BlobDataHandle> blob_data_handle = SetupBasicBlob(kId); | 313 std::unique_ptr<BlobDataHandle> blob_data_handle = SetupBasicBlob(kId); |
145 EXPECT_TRUE(blob_data_handle); | 314 EXPECT_TRUE(blob_data_handle); |
146 | 315 |
147 // Get another handle | 316 // Get another handle |
148 std::unique_ptr<BlobDataHandle> another_handle = | 317 std::unique_ptr<BlobDataHandle> another_handle = |
149 context_.GetBlobDataFromUUID(kId); | 318 context_->GetBlobDataFromUUID(kId); |
150 EXPECT_TRUE(another_handle); | 319 EXPECT_TRUE(another_handle); |
151 | 320 |
152 // Should disappear after dropping both handles. | 321 // Should disappear after dropping both handles. |
153 blob_data_handle.reset(); | 322 blob_data_handle.reset(); |
154 base::RunLoop().RunUntilIdle(); | 323 base::RunLoop().RunUntilIdle(); |
155 | 324 |
156 EXPECT_TRUE(context_.registry().HasEntry(kId)); | 325 EXPECT_TRUE(context_->registry().HasEntry(kId)); |
157 | 326 |
158 another_handle.reset(); | 327 another_handle.reset(); |
159 base::RunLoop().RunUntilIdle(); | 328 base::RunLoop().RunUntilIdle(); |
160 | 329 |
161 blob_data_handle = context_.GetBlobDataFromUUID(kId); | 330 blob_data_handle = context_->GetBlobDataFromUUID(kId); |
162 EXPECT_FALSE(blob_data_handle); | 331 EXPECT_FALSE(blob_data_handle); |
163 } | 332 } |
164 | 333 |
165 TEST_F(BlobStorageContextTest, MemoryUsage) { | 334 TEST_F(BlobStorageContextTest, MemoryUsage) { |
166 const std::string kId1("id1"); | 335 const std::string kId1("id1"); |
167 const std::string kId2("id2"); | 336 const std::string kId2("id2"); |
168 | 337 |
169 base::MessageLoop fake_io_message_loop; | |
170 | |
171 BlobDataBuilder builder1(kId1); | 338 BlobDataBuilder builder1(kId1); |
172 BlobDataBuilder builder2(kId2); | 339 BlobDataBuilder builder2(kId2); |
173 builder1.AppendData("Data1Data2"); | 340 builder1.AppendData("Data1Data2"); |
174 builder2.AppendBlob(kId1); | 341 builder2.AppendBlob(kId1); |
175 builder2.AppendBlob(kId1); | 342 builder2.AppendBlob(kId1); |
176 builder2.AppendBlob(kId1); | 343 builder2.AppendBlob(kId1); |
177 builder2.AppendBlob(kId1); | 344 builder2.AppendBlob(kId1); |
178 builder2.AppendBlob(kId1); | 345 builder2.AppendBlob(kId1); |
179 builder2.AppendBlob(kId1); | 346 builder2.AppendBlob(kId1); |
180 builder2.AppendBlob(kId1); | 347 builder2.AppendBlob(kId1); |
181 | 348 |
182 EXPECT_EQ(0lu, context_.memory_usage()); | 349 EXPECT_EQ(0lu, context_->memory_controller().memory_usage()); |
183 | 350 |
184 std::unique_ptr<BlobDataHandle> blob_data_handle = | 351 std::unique_ptr<BlobDataHandle> blob_data_handle = |
185 context_.AddFinishedBlob(&builder1); | 352 context_->AddFinishedBlob(&builder1); |
186 EXPECT_EQ(10lu, context_.memory_usage()); | 353 EXPECT_EQ(10lu, context_->memory_controller().memory_usage()); |
187 std::unique_ptr<BlobDataHandle> blob_data_handle2 = | 354 std::unique_ptr<BlobDataHandle> blob_data_handle2 = |
188 context_.AddFinishedBlob(&builder2); | 355 context_->AddFinishedBlob(&builder2); |
189 EXPECT_EQ(10lu, context_.memory_usage()); | 356 EXPECT_EQ(10lu, context_->memory_controller().memory_usage()); |
190 | 357 |
191 EXPECT_EQ(2u, context_.registry().blob_count()); | 358 EXPECT_EQ(2u, context_->registry().blob_count()); |
192 | 359 |
193 blob_data_handle.reset(); | 360 blob_data_handle.reset(); |
194 base::RunLoop().RunUntilIdle(); | 361 base::RunLoop().RunUntilIdle(); |
195 | 362 |
196 EXPECT_EQ(10lu, context_.memory_usage()); | 363 EXPECT_EQ(10lu, context_->memory_controller().memory_usage()); |
197 EXPECT_EQ(1u, context_.registry().blob_count()); | 364 EXPECT_EQ(1u, context_->registry().blob_count()); |
198 blob_data_handle2.reset(); | 365 blob_data_handle2.reset(); |
199 base::RunLoop().RunUntilIdle(); | 366 base::RunLoop().RunUntilIdle(); |
200 | 367 |
201 EXPECT_EQ(0lu, context_.memory_usage()); | 368 EXPECT_EQ(0lu, context_->memory_controller().memory_usage()); |
202 EXPECT_EQ(0u, context_.registry().blob_count()); | 369 EXPECT_EQ(0u, context_->registry().blob_count()); |
203 } | 370 } |
204 | 371 |
205 TEST_F(BlobStorageContextTest, AddFinishedBlob) { | 372 TEST_F(BlobStorageContextTest, AddFinishedBlob) { |
206 const std::string kId1("id1"); | 373 const std::string kId1("id1"); |
207 const std::string kId2("id12"); | 374 const std::string kId2("id12"); |
208 const std::string kId2Prime("id2.prime"); | |
209 const std::string kId3("id3"); | 375 const std::string kId3("id3"); |
210 const std::string kId3Prime("id3.prime"); | |
211 | |
212 base::MessageLoop fake_io_message_loop; | |
213 | 376 |
214 BlobDataBuilder builder1(kId1); | 377 BlobDataBuilder builder1(kId1); |
215 BlobDataBuilder builder2(kId2); | 378 BlobDataBuilder builder2(kId2); |
216 BlobDataBuilder canonicalized_blob_data2(kId2Prime); | 379 BlobDataBuilder canonicalized_blob_data2(kId2); |
217 builder1.AppendData("Data1Data2"); | 380 builder1.AppendData("Data1Data2"); |
218 builder2.AppendBlob(kId1, 5, 5); | 381 builder2.AppendBlob(kId1, 5, 5); |
219 builder2.AppendData(" is the best"); | 382 builder2.AppendData(" is the best"); |
220 canonicalized_blob_data2.AppendData("Data2"); | 383 canonicalized_blob_data2.AppendData("Data2"); |
221 canonicalized_blob_data2.AppendData(" is the best"); | 384 canonicalized_blob_data2.AppendData(" is the best"); |
222 | 385 |
223 BlobStorageContext context; | 386 BlobStorageContext context; |
224 | 387 |
225 std::unique_ptr<BlobDataHandle> blob_data_handle = | 388 std::unique_ptr<BlobDataHandle> blob_data_handle = |
226 context_.AddFinishedBlob(&builder1); | 389 context_->AddFinishedBlob(&builder1); |
227 std::unique_ptr<BlobDataHandle> blob_data_handle2 = | 390 std::unique_ptr<BlobDataHandle> blob_data_handle2 = |
228 context_.AddFinishedBlob(&builder2); | 391 context_->AddFinishedBlob(&builder2); |
| 392 |
| 393 EXPECT_EQ(10u + 12u + 5u, context_->memory_controller().memory_usage()); |
229 | 394 |
230 ASSERT_TRUE(blob_data_handle); | 395 ASSERT_TRUE(blob_data_handle); |
231 ASSERT_TRUE(blob_data_handle2); | 396 ASSERT_TRUE(blob_data_handle2); |
232 std::unique_ptr<BlobDataSnapshot> data1 = blob_data_handle->CreateSnapshot(); | 397 std::unique_ptr<BlobDataSnapshot> data1 = blob_data_handle->CreateSnapshot(); |
233 std::unique_ptr<BlobDataSnapshot> data2 = blob_data_handle2->CreateSnapshot(); | 398 std::unique_ptr<BlobDataSnapshot> data2 = blob_data_handle2->CreateSnapshot(); |
234 EXPECT_EQ(*data1, builder1); | 399 EXPECT_EQ(*data1, builder1); |
235 EXPECT_EQ(*data2, canonicalized_blob_data2); | 400 EXPECT_EQ(*data2, canonicalized_blob_data2); |
236 blob_data_handle.reset(); | 401 blob_data_handle.reset(); |
237 data2.reset(); | 402 data2.reset(); |
238 | 403 |
239 base::RunLoop().RunUntilIdle(); | 404 base::RunLoop().RunUntilIdle(); |
240 | 405 |
241 blob_data_handle = context_.GetBlobDataFromUUID(kId1); | 406 EXPECT_EQ(12u + 5u, context_->memory_controller().memory_usage()); |
| 407 |
| 408 blob_data_handle = context_->GetBlobDataFromUUID(kId1); |
242 EXPECT_FALSE(blob_data_handle); | 409 EXPECT_FALSE(blob_data_handle); |
243 EXPECT_TRUE(blob_data_handle2); | 410 EXPECT_TRUE(blob_data_handle2); |
244 data2 = blob_data_handle2->CreateSnapshot(); | 411 data2 = blob_data_handle2->CreateSnapshot(); |
245 EXPECT_EQ(*data2, canonicalized_blob_data2); | 412 EXPECT_EQ(*data2, canonicalized_blob_data2); |
246 | 413 |
247 // Test shared elements stick around. | 414 // Test shared elements stick around. |
248 BlobDataBuilder builder3(kId3); | 415 BlobDataBuilder builder3(kId3); |
249 builder3.AppendBlob(kId2); | 416 builder3.AppendBlob(kId2); |
250 builder3.AppendBlob(kId2); | 417 builder3.AppendBlob(kId2); |
251 std::unique_ptr<BlobDataHandle> blob_data_handle3 = | 418 std::unique_ptr<BlobDataHandle> blob_data_handle3 = |
252 context_.AddFinishedBlob(&builder3); | 419 context_->AddFinishedBlob(&builder3); |
| 420 EXPECT_FALSE(blob_data_handle3->IsBeingBuilt()); |
253 blob_data_handle2.reset(); | 421 blob_data_handle2.reset(); |
254 base::RunLoop().RunUntilIdle(); | 422 base::RunLoop().RunUntilIdle(); |
255 | 423 |
256 blob_data_handle2 = context_.GetBlobDataFromUUID(kId2); | 424 EXPECT_EQ(12u + 5u, context_->memory_controller().memory_usage()); |
| 425 |
| 426 blob_data_handle2 = context_->GetBlobDataFromUUID(kId2); |
257 EXPECT_FALSE(blob_data_handle2); | 427 EXPECT_FALSE(blob_data_handle2); |
258 EXPECT_TRUE(blob_data_handle3); | 428 EXPECT_TRUE(blob_data_handle3); |
259 std::unique_ptr<BlobDataSnapshot> data3 = blob_data_handle3->CreateSnapshot(); | 429 std::unique_ptr<BlobDataSnapshot> data3 = blob_data_handle3->CreateSnapshot(); |
260 | 430 |
261 BlobDataBuilder canonicalized_blob_data3(kId3Prime); | 431 BlobDataBuilder canonicalized_blob_data3(kId3); |
262 canonicalized_blob_data3.AppendData("Data2"); | 432 canonicalized_blob_data3.AppendData("Data2"); |
263 canonicalized_blob_data3.AppendData(" is the best"); | 433 canonicalized_blob_data3.AppendData(" is the best"); |
264 canonicalized_blob_data3.AppendData("Data2"); | 434 canonicalized_blob_data3.AppendData("Data2"); |
265 canonicalized_blob_data3.AppendData(" is the best"); | 435 canonicalized_blob_data3.AppendData(" is the best"); |
266 EXPECT_EQ(*data3, canonicalized_blob_data3); | 436 EXPECT_EQ(*data3, canonicalized_blob_data3); |
267 | 437 |
268 blob_data_handle.reset(); | 438 blob_data_handle.reset(); |
269 blob_data_handle2.reset(); | 439 blob_data_handle2.reset(); |
270 blob_data_handle3.reset(); | 440 blob_data_handle3.reset(); |
271 base::RunLoop().RunUntilIdle(); | 441 base::RunLoop().RunUntilIdle(); |
272 } | 442 } |
273 | 443 |
274 TEST_F(BlobStorageContextTest, AddFinishedBlob_LargeOffset) { | 444 TEST_F(BlobStorageContextTest, AddFinishedBlob_LargeOffset) { |
275 // A value which does not fit in a 4-byte data type. Used to confirm that | 445 // A value which does not fit in a 4-byte data type. Used to confirm that |
276 // large values are supported on 32-bit Chromium builds. Regression test for: | 446 // large values are supported on 32-bit Chromium builds. Regression test for: |
277 // crbug.com/458122. | 447 // crbug.com/458122. |
278 const uint64_t kLargeSize = std::numeric_limits<uint64_t>::max(); | 448 const uint64_t kLargeSize = std::numeric_limits<uint64_t>::max() - 1; |
279 | 449 |
280 const uint64_t kBlobLength = 5; | 450 const uint64_t kBlobLength = 5; |
281 const std::string kId1("id1"); | 451 const std::string kId1("id1"); |
282 const std::string kId2("id2"); | 452 const std::string kId2("id2"); |
283 base::MessageLoop fake_io_message_loop; | |
284 | 453 |
285 BlobDataBuilder builder1(kId1); | 454 BlobDataBuilder builder1(kId1); |
286 builder1.AppendFileSystemFile(GURL(), 0, kLargeSize, base::Time::Now()); | 455 builder1.AppendFileSystemFile(GURL(), 0, kLargeSize, base::Time::Now()); |
287 | 456 |
288 BlobDataBuilder builder2(kId2); | 457 BlobDataBuilder builder2(kId2); |
289 builder2.AppendBlob(kId1, kLargeSize - kBlobLength, kBlobLength); | 458 builder2.AppendBlob(kId1, kLargeSize - kBlobLength, kBlobLength); |
290 | 459 |
291 std::unique_ptr<BlobDataHandle> blob_data_handle1 = | 460 std::unique_ptr<BlobDataHandle> blob_data_handle1 = |
292 context_.AddFinishedBlob(&builder1); | 461 context_->AddFinishedBlob(&builder1); |
293 std::unique_ptr<BlobDataHandle> blob_data_handle2 = | 462 std::unique_ptr<BlobDataHandle> blob_data_handle2 = |
294 context_.AddFinishedBlob(&builder2); | 463 context_->AddFinishedBlob(&builder2); |
295 | 464 |
296 ASSERT_TRUE(blob_data_handle1); | 465 ASSERT_TRUE(blob_data_handle1); |
297 ASSERT_TRUE(blob_data_handle2); | 466 ASSERT_TRUE(blob_data_handle2); |
298 std::unique_ptr<BlobDataSnapshot> data = blob_data_handle2->CreateSnapshot(); | 467 std::unique_ptr<BlobDataSnapshot> data = blob_data_handle2->CreateSnapshot(); |
299 ASSERT_EQ(1u, data->items().size()); | 468 ASSERT_EQ(1u, data->items().size()); |
300 const scoped_refptr<BlobDataItem> item = data->items()[0]; | 469 const scoped_refptr<BlobDataItem> item = data->items()[0]; |
301 EXPECT_EQ(kLargeSize - kBlobLength, item->offset()); | 470 EXPECT_EQ(kLargeSize - kBlobLength, item->offset()); |
302 EXPECT_EQ(kBlobLength, item->length()); | 471 EXPECT_EQ(kBlobLength, item->length()); |
303 | 472 |
304 blob_data_handle1.reset(); | 473 blob_data_handle1.reset(); |
305 blob_data_handle2.reset(); | 474 blob_data_handle2.reset(); |
306 base::RunLoop().RunUntilIdle(); | 475 base::RunLoop().RunUntilIdle(); |
307 } | 476 } |
308 | 477 |
309 TEST_F(BlobStorageContextTest, BuildDiskCacheBlob) { | 478 TEST_F(BlobStorageContextTest, BuildDiskCacheBlob) { |
310 base::MessageLoop fake_io_message_loop; | |
311 scoped_refptr<BlobDataBuilder::DataHandle> | 479 scoped_refptr<BlobDataBuilder::DataHandle> |
312 data_handle = new EmptyDataHandle(); | 480 data_handle = new EmptyDataHandle(); |
313 | 481 |
314 { | 482 { |
315 BlobStorageContext context; | 483 BlobStorageContext context; |
316 | 484 |
317 std::unique_ptr<disk_cache::Backend> cache = CreateInMemoryDiskCache(); | 485 std::unique_ptr<disk_cache::Backend> cache = CreateInMemoryDiskCache(); |
318 ASSERT_TRUE(cache); | 486 ASSERT_TRUE(cache); |
319 | 487 |
320 const std::string kTestBlobData = "Test Blob Data"; | 488 const std::string kTestBlobData = "Test Blob Data"; |
(...skipping 19 matching lines...) Expand all Loading... |
340 } | 508 } |
341 EXPECT_TRUE(data_handle->HasOneRef()) | 509 EXPECT_TRUE(data_handle->HasOneRef()) |
342 << "Data handle was not destructed along with blob storage context."; | 510 << "Data handle was not destructed along with blob storage context."; |
343 base::RunLoop().RunUntilIdle(); | 511 base::RunLoop().RunUntilIdle(); |
344 } | 512 } |
345 | 513 |
346 TEST_F(BlobStorageContextTest, CompoundBlobs) { | 514 TEST_F(BlobStorageContextTest, CompoundBlobs) { |
347 const std::string kId1("id1"); | 515 const std::string kId1("id1"); |
348 const std::string kId2("id2"); | 516 const std::string kId2("id2"); |
349 const std::string kId3("id3"); | 517 const std::string kId3("id3"); |
350 const std::string kId2Prime("id2.prime"); | |
351 | |
352 base::MessageLoop fake_io_message_loop; | |
353 | 518 |
354 // Setup a set of blob data for testing. | 519 // Setup a set of blob data for testing. |
355 base::Time time1, time2; | 520 base::Time time1, time2; |
356 base::Time::FromString("Tue, 15 Nov 1994, 12:45:26 GMT", &time1); | 521 base::Time::FromString("Tue, 15 Nov 1994, 12:45:26 GMT", &time1); |
357 base::Time::FromString("Mon, 14 Nov 1994, 11:30:49 GMT", &time2); | 522 base::Time::FromString("Mon, 14 Nov 1994, 11:30:49 GMT", &time2); |
358 | 523 |
359 BlobDataBuilder blob_data1(kId1); | 524 BlobDataBuilder blob_data1(kId1); |
360 blob_data1.AppendData("Data1"); | 525 blob_data1.AppendData("Data1"); |
361 blob_data1.AppendData("Data2"); | 526 blob_data1.AppendData("Data2"); |
362 blob_data1.AppendFile(base::FilePath(FILE_PATH_LITERAL("File1.txt")), 10, | 527 blob_data1.AppendFile(base::FilePath(FILE_PATH_LITERAL("File1.txt")), 10, |
363 1024, time1); | 528 1024, time1); |
364 | 529 |
365 BlobDataBuilder blob_data2(kId2); | 530 BlobDataBuilder blob_data2(kId2); |
366 blob_data2.AppendData("Data3"); | 531 blob_data2.AppendData("Data3"); |
367 blob_data2.AppendBlob(kId1, 8, 100); | 532 blob_data2.AppendBlob(kId1, 8, 100); |
368 blob_data2.AppendFile(base::FilePath(FILE_PATH_LITERAL("File2.txt")), 0, 20, | 533 blob_data2.AppendFile(base::FilePath(FILE_PATH_LITERAL("File2.txt")), 0, 20, |
369 time2); | 534 time2); |
370 | 535 |
371 BlobDataBuilder blob_data3(kId3); | 536 BlobDataBuilder blob_data3(kId3); |
372 blob_data3.AppendData("Data4"); | 537 blob_data3.AppendData("Data4"); |
373 std::unique_ptr<disk_cache::Backend> cache = CreateInMemoryDiskCache(); | 538 std::unique_ptr<disk_cache::Backend> cache = CreateInMemoryDiskCache(); |
374 ASSERT_TRUE(cache); | 539 ASSERT_TRUE(cache); |
375 disk_cache::ScopedEntryPtr disk_cache_entry = | 540 disk_cache::ScopedEntryPtr disk_cache_entry = |
376 CreateDiskCacheEntry(cache.get(), "another key", "Data5"); | 541 CreateDiskCacheEntry(cache.get(), "another key", "Data5"); |
377 blob_data3.AppendDiskCacheEntry(new EmptyDataHandle(), disk_cache_entry.get(), | 542 blob_data3.AppendDiskCacheEntry(new EmptyDataHandle(), disk_cache_entry.get(), |
378 kTestDiskCacheStreamIndex); | 543 kTestDiskCacheStreamIndex); |
379 | 544 |
380 BlobDataBuilder canonicalized_blob_data2(kId2Prime); | 545 BlobDataBuilder canonicalized_blob_data2(kId2); |
381 canonicalized_blob_data2.AppendData("Data3"); | 546 canonicalized_blob_data2.AppendData("Data3"); |
382 canonicalized_blob_data2.AppendData("a2___", 2); | 547 canonicalized_blob_data2.AppendData("a2___", 2); |
383 canonicalized_blob_data2.AppendFile( | 548 canonicalized_blob_data2.AppendFile( |
384 base::FilePath(FILE_PATH_LITERAL("File1.txt")), 10, 98, time1); | 549 base::FilePath(FILE_PATH_LITERAL("File1.txt")), 10, 98, time1); |
385 canonicalized_blob_data2.AppendFile( | 550 canonicalized_blob_data2.AppendFile( |
386 base::FilePath(FILE_PATH_LITERAL("File2.txt")), 0, 20, time2); | 551 base::FilePath(FILE_PATH_LITERAL("File2.txt")), 0, 20, time2); |
387 | 552 |
388 BlobStorageContext context; | 553 BlobStorageContext context; |
389 std::unique_ptr<BlobDataHandle> blob_data_handle; | 554 std::unique_ptr<BlobDataHandle> blob_data_handle; |
390 | 555 |
391 // Test a blob referring to only data and a file. | 556 // Test a blob referring to only data and a file. |
392 blob_data_handle = context_.AddFinishedBlob(&blob_data1); | 557 blob_data_handle = context_->AddFinishedBlob(&blob_data1); |
393 | 558 |
394 ASSERT_TRUE(blob_data_handle); | 559 ASSERT_TRUE(blob_data_handle); |
395 std::unique_ptr<BlobDataSnapshot> data = blob_data_handle->CreateSnapshot(); | 560 std::unique_ptr<BlobDataSnapshot> data = blob_data_handle->CreateSnapshot(); |
396 ASSERT_TRUE(blob_data_handle); | 561 ASSERT_TRUE(blob_data_handle); |
397 EXPECT_EQ(*data, blob_data1); | 562 EXPECT_EQ(*data, blob_data1); |
398 | 563 |
399 // Test a blob composed in part with another blob. | 564 // Test a blob composed in part with another blob. |
400 blob_data_handle = context_.AddFinishedBlob(&blob_data2); | 565 blob_data_handle = context_->AddFinishedBlob(&blob_data2); |
401 data = blob_data_handle->CreateSnapshot(); | 566 data = blob_data_handle->CreateSnapshot(); |
402 ASSERT_TRUE(blob_data_handle); | 567 ASSERT_TRUE(blob_data_handle); |
403 ASSERT_TRUE(data); | 568 ASSERT_TRUE(data); |
404 EXPECT_EQ(*data, canonicalized_blob_data2); | 569 EXPECT_EQ(*data, canonicalized_blob_data2); |
405 | 570 |
406 // Test a blob referring to only data and a disk cache entry. | 571 // Test a blob referring to only data and a disk cache entry. |
407 blob_data_handle = context_.AddFinishedBlob(&blob_data3); | 572 blob_data_handle = context_->AddFinishedBlob(&blob_data3); |
408 data = blob_data_handle->CreateSnapshot(); | 573 data = blob_data_handle->CreateSnapshot(); |
409 ASSERT_TRUE(blob_data_handle); | 574 ASSERT_TRUE(blob_data_handle); |
410 EXPECT_EQ(*data, blob_data3); | 575 EXPECT_EQ(*data, blob_data3); |
411 | 576 |
412 blob_data_handle.reset(); | 577 blob_data_handle.reset(); |
413 base::RunLoop().RunUntilIdle(); | 578 base::RunLoop().RunUntilIdle(); |
414 } | 579 } |
415 | 580 |
416 TEST_F(BlobStorageContextTest, PublicBlobUrls) { | 581 TEST_F(BlobStorageContextTest, PublicBlobUrls) { |
417 base::MessageLoop fake_io_message_loop; | |
418 | |
419 // Build up a basic blob. | 582 // Build up a basic blob. |
420 const std::string kId("id"); | 583 const std::string kId("id"); |
421 std::unique_ptr<BlobDataHandle> first_handle = SetupBasicBlob(kId); | 584 std::unique_ptr<BlobDataHandle> first_handle = SetupBasicBlob(kId); |
422 | 585 |
423 // Now register a url for that blob. | 586 // Now register a url for that blob. |
424 GURL kUrl("blob:id"); | 587 GURL kUrl("blob:id"); |
425 context_.RegisterPublicBlobURL(kUrl, kId); | 588 context_->RegisterPublicBlobURL(kUrl, kId); |
426 std::unique_ptr<BlobDataHandle> blob_data_handle = | 589 std::unique_ptr<BlobDataHandle> blob_data_handle = |
427 context_.GetBlobDataFromPublicURL(kUrl); | 590 context_->GetBlobDataFromPublicURL(kUrl); |
428 ASSERT_TRUE(blob_data_handle.get()); | 591 ASSERT_TRUE(blob_data_handle.get()); |
429 EXPECT_EQ(kId, blob_data_handle->uuid()); | 592 EXPECT_EQ(kId, blob_data_handle->uuid()); |
430 std::unique_ptr<BlobDataSnapshot> data = blob_data_handle->CreateSnapshot(); | 593 std::unique_ptr<BlobDataSnapshot> data = blob_data_handle->CreateSnapshot(); |
431 blob_data_handle.reset(); | 594 blob_data_handle.reset(); |
432 first_handle.reset(); | 595 first_handle.reset(); |
433 base::RunLoop().RunUntilIdle(); | 596 base::RunLoop().RunUntilIdle(); |
434 | 597 |
435 // The url registration should keep the blob alive even after | 598 // The url registration should keep the blob alive even after |
436 // explicit references are dropped. | 599 // explicit references are dropped. |
437 blob_data_handle = context_.GetBlobDataFromPublicURL(kUrl); | 600 blob_data_handle = context_->GetBlobDataFromPublicURL(kUrl); |
438 EXPECT_TRUE(blob_data_handle); | 601 EXPECT_TRUE(blob_data_handle); |
439 blob_data_handle.reset(); | 602 blob_data_handle.reset(); |
| 603 |
440 base::RunLoop().RunUntilIdle(); | 604 base::RunLoop().RunUntilIdle(); |
441 | |
442 // Finally get rid of the url registration and the blob. | 605 // Finally get rid of the url registration and the blob. |
443 context_.RevokePublicBlobURL(kUrl); | 606 context_->RevokePublicBlobURL(kUrl); |
444 blob_data_handle = context_.GetBlobDataFromPublicURL(kUrl); | 607 blob_data_handle = context_->GetBlobDataFromPublicURL(kUrl); |
445 EXPECT_FALSE(blob_data_handle.get()); | 608 EXPECT_FALSE(blob_data_handle.get()); |
446 EXPECT_FALSE(context_.registry().HasEntry(kId)); | 609 EXPECT_FALSE(context_->registry().HasEntry(kId)); |
447 } | 610 } |
448 | 611 |
449 TEST_F(BlobStorageContextTest, TestUnknownBrokenAndBuildingBlobReference) { | 612 TEST_F(BlobStorageContextTest, TestUnknownBrokenAndBuildingBlobReference) { |
450 base::MessageLoop fake_io_message_loop; | |
451 const std::string kBrokenId("broken_id"); | 613 const std::string kBrokenId("broken_id"); |
452 const std::string kBuildingId("building_id"); | 614 const std::string kBuildingId("building_id"); |
453 const std::string kReferencingId("referencing_id"); | 615 const std::string kReferencingId("referencing_id"); |
454 const std::string kUnknownId("unknown_id"); | 616 const std::string kUnknownId("unknown_id"); |
455 | 617 |
456 // Create a broken blob and a building blob. | 618 // Create a broken blob. |
457 context_.CreatePendingBlob(kBuildingId, "", ""); | 619 std::unique_ptr<BlobDataHandle> broken_handle = |
458 context_.CreatePendingBlob(kBrokenId, "", ""); | 620 context_->AddBrokenBlob(kBrokenId, "", "", BlobStatus::ERR_OUT_OF_MEMORY); |
459 context_.CancelPendingBlob(kBrokenId, IPCBlobCreationCancelCode::UNKNOWN); | 621 EXPECT_TRUE(broken_handle->GetBlobStatus() == BlobStatus::ERR_OUT_OF_MEMORY); |
460 EXPECT_TRUE(context_.IsBroken(kBrokenId)); | 622 EXPECT_TRUE(context_->registry().HasEntry(kBrokenId)); |
461 EXPECT_TRUE(context_.registry().HasEntry(kBrokenId)); | |
462 | 623 |
463 // Try to create a blob with a reference to an unknown blob. | 624 // Try to create a blob with a reference to an unknown blob. |
464 BlobDataBuilder builder(kReferencingId); | 625 BlobDataBuilder builder(kReferencingId); |
465 builder.AppendData("data"); | 626 builder.AppendData("data"); |
466 builder.AppendBlob(kUnknownId); | 627 builder.AppendBlob(kUnknownId); |
467 std::unique_ptr<BlobDataHandle> handle = context_.AddFinishedBlob(builder); | 628 std::unique_ptr<BlobDataHandle> handle = context_->AddFinishedBlob(builder); |
468 EXPECT_TRUE(handle->IsBroken()); | 629 EXPECT_TRUE(handle->IsBroken()); |
469 EXPECT_TRUE(context_.registry().HasEntry(kReferencingId)); | 630 EXPECT_TRUE(context_->registry().HasEntry(kReferencingId)); |
470 handle.reset(); | 631 handle.reset(); |
471 base::RunLoop().RunUntilIdle(); | 632 base::RunLoop().RunUntilIdle(); |
472 EXPECT_FALSE(context_.registry().HasEntry(kReferencingId)); | 633 EXPECT_FALSE(context_->registry().HasEntry(kReferencingId)); |
473 | 634 |
474 // Try to create a blob with a reference to the broken blob. | 635 // Try to create a blob with a reference to the broken blob. |
475 BlobDataBuilder builder2(kReferencingId); | 636 BlobDataBuilder builder2(kReferencingId); |
476 builder2.AppendData("data"); | 637 builder2.AppendData("data"); |
477 builder2.AppendBlob(kBrokenId); | 638 builder2.AppendBlob(kBrokenId); |
478 handle = context_.AddFinishedBlob(builder2); | 639 handle = context_->AddFinishedBlob(builder2); |
479 EXPECT_TRUE(handle->IsBroken()); | 640 EXPECT_TRUE(handle->IsBroken()); |
480 EXPECT_TRUE(context_.registry().HasEntry(kReferencingId)); | 641 EXPECT_TRUE(context_->registry().HasEntry(kReferencingId)); |
481 handle.reset(); | 642 handle.reset(); |
482 base::RunLoop().RunUntilIdle(); | 643 base::RunLoop().RunUntilIdle(); |
483 EXPECT_FALSE(context_.registry().HasEntry(kReferencingId)); | 644 EXPECT_FALSE(context_->registry().HasEntry(kReferencingId)); |
484 | 645 |
485 // Try to create a blob with a reference to the building blob. | 646 // Try to create a blob with a reference to the building blob. |
486 BlobDataBuilder builder3(kReferencingId); | 647 BlobDataBuilder builder3(kReferencingId); |
487 builder3.AppendData("data"); | 648 builder3.AppendData("data"); |
488 builder3.AppendBlob(kBuildingId); | 649 builder3.AppendBlob(kBuildingId); |
489 handle = context_.AddFinishedBlob(builder3); | 650 handle = context_->AddFinishedBlob(builder3); |
490 EXPECT_TRUE(handle->IsBroken()); | 651 EXPECT_TRUE(handle->IsBroken()); |
491 EXPECT_TRUE(context_.registry().HasEntry(kReferencingId)); | 652 EXPECT_TRUE(context_->registry().HasEntry(kReferencingId)); |
492 handle.reset(); | 653 handle.reset(); |
493 base::RunLoop().RunUntilIdle(); | 654 base::RunLoop().RunUntilIdle(); |
494 EXPECT_FALSE(context_.registry().HasEntry(kReferencingId)); | 655 EXPECT_FALSE(context_->registry().HasEntry(kReferencingId)); |
495 } | 656 } |
496 | 657 |
497 // TODO(michaeln): tests for the depcrecated url stuff | 658 // TODO(michaeln): tests for the depcrecated url stuff |
498 | 659 |
499 } // namespace content | 660 } // namespace content |
OLD | NEW |