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