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

Side by Side Diff: content/browser/blob_storage/blob_flattener_unittest.cc

Issue 2516713002: [BlobStorage] Implementing disk. (Closed)
Patch Set: removed cleanup check, as mac doesn't run out event loops Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | content/browser/blob_storage/blob_memory_controller_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 <memory> 7 #include <memory>
8 8
9 #include "base/bind.h"
9 #include "base/files/file_path.h" 10 #include "base/files/file_path.h"
10 #include "base/files/file_util.h" 11 #include "base/files/file_util.h"
11 #include "base/files/scoped_temp_dir.h" 12 #include "base/files/scoped_temp_dir.h"
13 #include "base/memory/ptr_util.h"
12 #include "base/message_loop/message_loop.h" 14 #include "base/message_loop/message_loop.h"
13 #include "base/run_loop.h" 15 #include "base/run_loop.h"
14 #include "base/test/test_simple_task_runner.h" 16 #include "base/test/test_simple_task_runner.h"
15 #include "base/time/time.h" 17 #include "base/time/time.h"
16 #include "storage/browser/blob/blob_data_builder.h" 18 #include "storage/browser/blob/blob_data_builder.h"
17 #include "storage/browser/blob/blob_data_handle.h" 19 #include "storage/browser/blob/blob_data_handle.h"
18 #include "storage/browser/blob/blob_data_item.h" 20 #include "storage/browser/blob/blob_data_item.h"
19 #include "storage/browser/blob/blob_entry.h" 21 #include "storage/browser/blob/blob_entry.h"
22 #include "storage/browser/blob/blob_memory_controller.h"
20 #include "storage/browser/blob/blob_storage_registry.h" 23 #include "storage/browser/blob/blob_storage_registry.h"
21 #include "storage/browser/blob/shareable_blob_data_item.h" 24 #include "storage/browser/blob/shareable_blob_data_item.h"
22 #include "storage/common/data_element.h" 25 #include "storage/common/data_element.h"
23 #include "testing/gtest/include/gtest/gtest.h" 26 #include "testing/gtest/include/gtest/gtest.h"
24 27
25 namespace storage { 28 namespace storage {
26 namespace { 29 namespace {
27 using base::TestSimpleTaskRunner; 30 using base::TestSimpleTaskRunner;
31 using FileCreationInfo = BlobMemoryController::FileCreationInfo;
28 32
29 const char kType[] = "type"; 33 const char kType[] = "type";
30 const char kDisposition[] = ""; 34 const char kDisposition[] = "";
35 const size_t kTestBlobStorageIPCThresholdBytes = 20;
36 const size_t kTestBlobStorageMaxSharedMemoryBytes = 50;
37
38 const size_t kTestBlobStorageMaxBlobMemorySize = 400;
39 const uint64_t kTestBlobStorageMaxDiskSpace = 4000;
40 const uint64_t kTestBlobStorageMinFileSizeBytes = 10;
41 const uint64_t kTestBlobStorageMaxFileSizeBytes = 100;
42
43 void SaveBlobStatusAndFiles(BlobStatus* status_ptr,
44 std::vector<FileCreationInfo>* files_ptr,
45 BlobStatus status,
46 std::vector<FileCreationInfo> files) {
47 EXPECT_FALSE(BlobStatusIsError(status));
48 *status_ptr = status;
49 std::move(files.begin(), files.end(), std::back_inserter(*files_ptr));
50 }
31 51
32 } // namespace 52 } // namespace
33 53
34 class BlobFlattenerTest : public testing::Test { 54 class BlobFlattenerTest : public testing::Test {
35 protected: 55 protected:
36 using BlobFlattener = BlobStorageContext::BlobFlattener; 56 using BlobFlattener = BlobStorageContext::BlobFlattener;
37 57
38 BlobFlattenerTest() 58 BlobFlattenerTest()
39 : fake_file_path_(base::FilePath(FILE_PATH_LITERAL("kFakePath"))) {} 59 : fake_file_path_(base::FilePath(FILE_PATH_LITERAL("kFakePath"))) {}
40 ~BlobFlattenerTest() override {} 60 ~BlobFlattenerTest() override {}
41 61
42 void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); } 62 void SetUp() override {
63 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
64 context_ = base::MakeUnique<BlobStorageContext>();
65 }
43 66
44 void TearDown() override { 67 void TearDown() override {
45 base::RunLoop().RunUntilIdle(); 68 base::RunLoop().RunUntilIdle();
46 file_runner_->RunPendingTasks(); 69 file_runner_->RunPendingTasks();
70 base::RunLoop().RunUntilIdle();
47 ASSERT_TRUE(temp_dir_.Delete()); 71 ASSERT_TRUE(temp_dir_.Delete());
48 } 72 }
49 73
50 scoped_refptr<BlobDataItem> CreateDataDescriptionItem(size_t size) { 74 scoped_refptr<BlobDataItem> CreateDataDescriptionItem(size_t size) {
51 std::unique_ptr<DataElement> element(new DataElement()); 75 std::unique_ptr<DataElement> element(new DataElement());
52 element->SetToBytesDescription(size); 76 element->SetToBytesDescription(size);
53 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element))); 77 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element)));
54 }; 78 };
55 79
56 scoped_refptr<BlobDataItem> CreateDataItem(const char* memory, size_t size) { 80 scoped_refptr<BlobDataItem> CreateDataItem(const char* memory, size_t size) {
57 std::unique_ptr<DataElement> element(new DataElement()); 81 std::unique_ptr<DataElement> element(new DataElement());
58 element->SetToBytes(memory, size); 82 element->SetToBytes(memory, size);
59 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element))); 83 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element)));
60 }; 84 };
61 85
62 scoped_refptr<BlobDataItem> CreateFileItem(size_t offset, size_t size) { 86 scoped_refptr<BlobDataItem> CreateFileItem(size_t offset, size_t size) {
63 std::unique_ptr<DataElement> element(new DataElement()); 87 std::unique_ptr<DataElement> element(new DataElement());
64 element->SetToFilePathRange(fake_file_path_, offset, size, 88 element->SetToFilePathRange(fake_file_path_, offset, size,
65 base::Time::Max()); 89 base::Time::Max());
66 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element))); 90 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element)));
67 }; 91 };
68 92
93 scoped_refptr<BlobDataItem> CreateFutureFileItem(size_t offset, size_t size) {
94 std::unique_ptr<DataElement> element(new DataElement());
95 element->SetToFilePathRange(BlobDataBuilder::GetFutureFileItemPath(0),
96 offset, size, base::Time());
97 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element)));
98 };
99
69 std::unique_ptr<BlobDataHandle> SetupBasicBlob(const std::string& id) { 100 std::unique_ptr<BlobDataHandle> SetupBasicBlob(const std::string& id) {
70 BlobDataBuilder builder(id); 101 BlobDataBuilder builder(id);
71 builder.AppendData("1", 1); 102 builder.AppendData("1", 1);
72 builder.set_content_type("text/plain"); 103 builder.set_content_type("text/plain");
73 return context_.AddFinishedBlob(builder); 104 return context_->AddFinishedBlob(builder);
74 } 105 }
75 106
76 BlobStorageRegistry* registry() { return context_.mutable_registry(); } 107 BlobStorageRegistry* registry() { return context_->mutable_registry(); }
77 108
78 const ShareableBlobDataItem& GetItemInBlob(const std::string& uuid, 109 const ShareableBlobDataItem& GetItemInBlob(const std::string& uuid,
79 size_t index) { 110 size_t index) {
80 BlobEntry* entry = registry()->GetEntry(uuid); 111 BlobEntry* entry = registry()->GetEntry(uuid);
81 EXPECT_TRUE(entry); 112 EXPECT_TRUE(entry);
82 return *entry->items()[index]; 113 return *entry->items()[index];
83 } 114 }
84 115
116 void SetTestMemoryLimits() {
117 BlobStorageLimits limits;
118 limits.max_ipc_memory_size = kTestBlobStorageIPCThresholdBytes;
119 limits.max_shared_memory_size = kTestBlobStorageMaxSharedMemoryBytes;
120 limits.max_blob_in_memory_space = kTestBlobStorageMaxBlobMemorySize;
121 limits.max_blob_disk_space = kTestBlobStorageMaxDiskSpace;
122 limits.min_page_file_size = kTestBlobStorageMinFileSizeBytes;
123 limits.max_file_size = kTestBlobStorageMaxFileSizeBytes;
124 context_->mutable_memory_controller()->set_limits_for_testing(limits);
125 }
126
85 base::FilePath fake_file_path_; 127 base::FilePath fake_file_path_;
86 base::ScopedTempDir temp_dir_; 128 base::ScopedTempDir temp_dir_;
87 scoped_refptr<TestSimpleTaskRunner> file_runner_ = new TestSimpleTaskRunner(); 129 scoped_refptr<TestSimpleTaskRunner> file_runner_ = new TestSimpleTaskRunner();
88 130
89 base::MessageLoop fake_io_message_loop; 131 base::MessageLoop fake_io_message_loop;
90 BlobStorageContext context_; 132 std::unique_ptr<BlobStorageContext> context_;
91 }; 133 };
92 134
93 TEST_F(BlobFlattenerTest, NoBlobItems) { 135 TEST_F(BlobFlattenerTest, NoBlobItems) {
94 const std::string kBlobUUID = "kId"; 136 const std::string kBlobUUID = "kId";
95 137
96 BlobDataBuilder builder(kBlobUUID); 138 BlobDataBuilder builder(kBlobUUID);
97 builder.AppendData("hi", 2u); 139 builder.AppendData("hi", 2u);
98 builder.AppendFile(fake_file_path_, 0u, 10u, base::Time::Max()); 140 builder.AppendFile(fake_file_path_, 0u, 10u, base::Time::Max());
99 BlobEntry output(kType, kDisposition); 141 BlobEntry output(kType, kDisposition);
100 BlobFlattener flattener(builder, &output, registry()); 142 BlobFlattener flattener(builder, &output, registry());
101 143
102 EXPECT_EQ(BlobStatus::PENDING_QUOTA, flattener.status); 144 EXPECT_EQ(BlobStatus::PENDING_QUOTA, flattener.status);
103 EXPECT_EQ(0u, flattener.dependent_blobs.size()); 145 EXPECT_EQ(0u, flattener.dependent_blobs.size());
104 EXPECT_EQ(0u, flattener.copies.size()); 146 EXPECT_EQ(0u, flattener.copies.size());
105 EXPECT_EQ(12u, flattener.total_size); 147 EXPECT_EQ(12u, flattener.total_size);
106 EXPECT_EQ(2u, flattener.memory_quota_needed); 148 EXPECT_EQ(2u, flattener.transport_quota_needed);
107 149
108 ASSERT_EQ(2u, output.items().size()); 150 ASSERT_EQ(2u, output.items().size());
109 EXPECT_EQ(*CreateDataItem("hi", 2u), *output.items()[0]->item()); 151 EXPECT_EQ(*CreateDataItem("hi", 2u), *output.items()[0]->item());
110 EXPECT_EQ(*CreateFileItem(0, 10u), *output.items()[1]->item()); 152 EXPECT_EQ(*CreateFileItem(0, 10u), *output.items()[1]->item());
111 } 153 }
112 154
113 TEST_F(BlobFlattenerTest, ErrorCases) { 155 TEST_F(BlobFlattenerTest, ErrorCases) {
114 const std::string kBlobUUID = "kId"; 156 const std::string kBlobUUID = "kId";
115 const std::string kBlob2UUID = "kId2"; 157 const std::string kBlob2UUID = "kId2";
116 158
(...skipping 23 matching lines...) Expand all
140 BlobEntry output(kType, kDisposition); 182 BlobEntry output(kType, kDisposition);
141 BlobFlattener flattener(builder, &output, registry()); 183 BlobFlattener flattener(builder, &output, registry());
142 EXPECT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS, flattener.status); 184 EXPECT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS, flattener.status);
143 } 185 }
144 } 186 }
145 187
146 TEST_F(BlobFlattenerTest, BlobWithSlices) { 188 TEST_F(BlobFlattenerTest, BlobWithSlices) {
147 const std::string kBlobUUID = "kId"; 189 const std::string kBlobUUID = "kId";
148 const std::string kDataBlob = "kId2"; 190 const std::string kDataBlob = "kId2";
149 const std::string kFileBlob = "kId3"; 191 const std::string kFileBlob = "kId3";
192 const std::string kPendingFileBlob = "kId4";
150 193
151 // We have the following: 194 // We have the following:
152 // * data, 195 // * data,
153 // * sliced data blob, 196 // * sliced data blob,
154 // * file 197 // * file
155 // * full data blob, 198 // * full data blob,
156 // * pending data, 199 // * pending data,
157 200
201 context_ =
202 base::MakeUnique<BlobStorageContext>(temp_dir_.GetPath(), file_runner_);
203 SetTestMemoryLimits();
204
158 std::unique_ptr<BlobDataHandle> data_blob; 205 std::unique_ptr<BlobDataHandle> data_blob;
159 { 206 {
160 BlobDataBuilder builder(kDataBlob); 207 BlobDataBuilder builder(kDataBlob);
161 builder.AppendData("12345", 5); 208 builder.AppendData("12345", 5);
162 builder.set_content_type("text/plain"); 209 builder.set_content_type("text/plain");
163 data_blob = context_.AddFinishedBlob(builder); 210 data_blob = context_->AddFinishedBlob(builder);
164 } 211 }
165 212
166 std::unique_ptr<BlobDataHandle> file_blob; 213 std::unique_ptr<BlobDataHandle> file_blob;
167 { 214 {
168 BlobDataBuilder builder(kFileBlob); 215 BlobDataBuilder builder(kFileBlob);
169 builder.AppendFile(fake_file_path_, 1u, 10u, base::Time::Max()); 216 builder.AppendFile(fake_file_path_, 1u, 10u, base::Time::Max());
170 file_blob = context_.AddFinishedBlob(builder); 217 file_blob = context_->AddFinishedBlob(builder);
218 }
219
220 BlobStatus file_status = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS;
221 std::vector<FileCreationInfo> file_handles;
222 std::unique_ptr<BlobDataHandle> future_file_blob;
223 {
224 BlobDataBuilder builder(kPendingFileBlob);
225 builder.AppendFutureFile(0u, 2u, 0);
226 builder.AppendFutureFile(2u, 5u, 0);
227 future_file_blob = context_->BuildBlob(
228 builder,
229 base::Bind(&SaveBlobStatusAndFiles, &file_status, &file_handles));
171 } 230 }
172 231
173 BlobDataBuilder builder(kBlobUUID); 232 BlobDataBuilder builder(kBlobUUID);
174 builder.AppendData("hi", 2u); 233 builder.AppendData("hi", 2u);
175 builder.AppendBlob(kDataBlob, 1u, 2u); 234 builder.AppendBlob(kDataBlob, 1u, 2u);
176 builder.AppendFile(fake_file_path_, 3u, 5u, base::Time::Max()); 235 builder.AppendFile(fake_file_path_, 3u, 5u, base::Time::Max());
177 builder.AppendBlob(kDataBlob); 236 builder.AppendBlob(kDataBlob);
178 builder.AppendBlob(kFileBlob, 1u, 3u); 237 builder.AppendBlob(kFileBlob, 1u, 3u);
179 builder.AppendFutureData(12u); 238 builder.AppendFutureData(12u);
239 builder.AppendBlob(kPendingFileBlob, 1u, 3u);
180 240
181 BlobEntry output(kType, kDisposition); 241 BlobEntry output(kType, kDisposition);
182 BlobFlattener flattener(builder, &output, registry()); 242 BlobFlattener flattener(builder, &output, registry());
183 EXPECT_EQ(BlobStatus::PENDING_QUOTA, flattener.status); 243 EXPECT_EQ(BlobStatus::PENDING_QUOTA, flattener.status);
184 244
185 EXPECT_EQ(2u, flattener.dependent_blobs.size()); 245 EXPECT_EQ(3u, flattener.dependent_blobs.size());
186 EXPECT_EQ(29u, flattener.total_size); 246 EXPECT_EQ(32u, flattener.total_size);
187 EXPECT_EQ(16u, flattener.memory_quota_needed); 247 EXPECT_EQ(14u, flattener.transport_quota_needed);
248 EXPECT_EQ(2u, flattener.copy_quota_needed);
188 249
189 ASSERT_EQ(6u, output.items().size()); 250 ASSERT_EQ(8u, output.items().size());
190 EXPECT_EQ(*CreateDataItem("hi", 2u), *output.items()[0]->item()); 251 EXPECT_EQ(*CreateDataItem("hi", 2u), *output.items()[0]->item());
191 EXPECT_EQ(*CreateDataDescriptionItem(2u), *output.items()[1]->item()); 252 EXPECT_EQ(*CreateDataDescriptionItem(2u), *output.items()[1]->item());
192 EXPECT_EQ(*CreateFileItem(3u, 5u), *output.items()[2]->item()); 253 EXPECT_EQ(*CreateFileItem(3u, 5u), *output.items()[2]->item());
193 EXPECT_EQ(GetItemInBlob(kDataBlob, 0), *output.items()[3]); 254 EXPECT_EQ(GetItemInBlob(kDataBlob, 0), *output.items()[3]);
194 EXPECT_EQ(*CreateFileItem(2u, 3u), *output.items()[4]->item()); 255 EXPECT_EQ(*CreateFileItem(2u, 3u), *output.items()[4]->item());
195 EXPECT_EQ(*CreateDataDescriptionItem(12u), *output.items()[5]->item()); 256 EXPECT_EQ(*CreateDataDescriptionItem(12u), *output.items()[5]->item());
257 EXPECT_EQ(*CreateFutureFileItem(1u, 1u), *output.items()[6]->item());
258 EXPECT_EQ(*CreateFutureFileItem(2u, 2u), *output.items()[7]->item());
196 259
197 // We're copying item at index 1 260 // We're copying items at index 1, 6, and 7.
198 ASSERT_EQ(1u, flattener.copies.size()); 261 ASSERT_EQ(3u, flattener.copies.size());
199 EXPECT_EQ(*flattener.copies[0].dest_item, *output.items()[1]); 262 EXPECT_EQ(*flattener.copies[0].dest_item, *output.items()[1]);
200 EXPECT_EQ(GetItemInBlob(kDataBlob, 0), *flattener.copies[0].source_item); 263 EXPECT_EQ(GetItemInBlob(kDataBlob, 0), *flattener.copies[0].source_item);
201 EXPECT_EQ(1u, flattener.copies[0].source_item_offset); 264 EXPECT_EQ(1u, flattener.copies[0].source_item_offset);
265 EXPECT_EQ(*flattener.copies[1].dest_item, *output.items()[6]);
266 EXPECT_EQ(GetItemInBlob(kPendingFileBlob, 0),
267 *flattener.copies[1].source_item);
268 EXPECT_EQ(1u, flattener.copies[1].source_item_offset);
269 EXPECT_EQ(*flattener.copies[2].dest_item, *output.items()[7]);
270 EXPECT_EQ(GetItemInBlob(kPendingFileBlob, 1),
271 *flattener.copies[2].source_item);
272 EXPECT_EQ(0u, flattener.copies[2].source_item_offset);
273
274 // Clean up temp files.
275 EXPECT_TRUE(file_runner_->HasPendingTask());
276 file_runner_->RunPendingTasks();
277 base::RunLoop().RunUntilIdle();
278 EXPECT_EQ(BlobStatus::PENDING_TRANSPORT, file_status);
279 EXPECT_FALSE(file_handles.empty());
202 } 280 }
203 281
204 } // namespace storage 282 } // namespace storage
OLDNEW
« no previous file with comments | « no previous file | content/browser/blob_storage/blob_memory_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698