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

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

Issue 2516713002: [BlobStorage] Implementing disk. (Closed)
Patch Set: flush maybe worked? Adding it in paging spot. 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
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[] = "";
31 35
36 void SaveBlobStatusAndFiles(BlobStatus* status_ptr,
37 std::vector<FileCreationInfo>* files_ptr,
38 BlobStatus status,
39 std::vector<FileCreationInfo> files) {
40 EXPECT_FALSE(BlobStatusIsError(status));
41 *status_ptr = status;
42 for (FileCreationInfo& info : files) {
Marijn Kruisselbrink 2016/12/02 19:27:48 nit: this looks a lot like the three-argument std:
dmurph 2016/12/02 21:53:07 Done.
43 files_ptr->push_back(std::move(info));
44 }
45 }
46
32 } // namespace 47 } // namespace
33 48
34 class BlobFlattenerTest : public testing::Test { 49 class BlobFlattenerTest : public testing::Test {
35 protected: 50 protected:
36 using BlobFlattener = BlobStorageContext::BlobFlattener; 51 using BlobFlattener = BlobStorageContext::BlobFlattener;
37 52
38 BlobFlattenerTest() 53 BlobFlattenerTest()
39 : fake_file_path_(base::FilePath(FILE_PATH_LITERAL("kFakePath"))) {} 54 : fake_file_path_(base::FilePath(FILE_PATH_LITERAL("kFakePath"))) {}
40 ~BlobFlattenerTest() override {} 55 ~BlobFlattenerTest() override {}
41 56
42 void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); } 57 void SetUp() override {
58 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
59 context_ = base::MakeUnique<BlobStorageContext>();
60 }
43 61
44 void TearDown() override { 62 void TearDown() override {
45 base::RunLoop().RunUntilIdle(); 63 base::RunLoop().RunUntilIdle();
46 file_runner_->RunPendingTasks(); 64 file_runner_->RunPendingTasks();
65 base::RunLoop().RunUntilIdle();
47 ASSERT_TRUE(temp_dir_.Delete()); 66 ASSERT_TRUE(temp_dir_.Delete());
48 } 67 }
49 68
50 scoped_refptr<BlobDataItem> CreateDataDescriptionItem(size_t size) { 69 scoped_refptr<BlobDataItem> CreateDataDescriptionItem(size_t size) {
51 std::unique_ptr<DataElement> element(new DataElement()); 70 std::unique_ptr<DataElement> element(new DataElement());
52 element->SetToBytesDescription(size); 71 element->SetToBytesDescription(size);
53 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element))); 72 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element)));
54 }; 73 };
55 74
56 scoped_refptr<BlobDataItem> CreateDataItem(const char* memory, size_t size) { 75 scoped_refptr<BlobDataItem> CreateDataItem(const char* memory, size_t size) {
57 std::unique_ptr<DataElement> element(new DataElement()); 76 std::unique_ptr<DataElement> element(new DataElement());
58 element->SetToBytes(memory, size); 77 element->SetToBytes(memory, size);
59 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element))); 78 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element)));
60 }; 79 };
61 80
62 scoped_refptr<BlobDataItem> CreateFileItem(size_t offset, size_t size) { 81 scoped_refptr<BlobDataItem> CreateFileItem(size_t offset, size_t size) {
63 std::unique_ptr<DataElement> element(new DataElement()); 82 std::unique_ptr<DataElement> element(new DataElement());
64 element->SetToFilePathRange(fake_file_path_, offset, size, 83 element->SetToFilePathRange(fake_file_path_, offset, size,
65 base::Time::Max()); 84 base::Time::Max());
66 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element))); 85 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element)));
67 }; 86 };
68 87
88 scoped_refptr<BlobDataItem> CreateFutureFileItem(size_t offset, size_t size) {
89 std::unique_ptr<DataElement> element(new DataElement());
90 element->SetToFilePathRange(BlobDataBuilder::GetFutureFileItemPath(0),
91 offset, size, base::Time());
92 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element)));
93 };
94
69 std::unique_ptr<BlobDataHandle> SetupBasicBlob(const std::string& id) { 95 std::unique_ptr<BlobDataHandle> SetupBasicBlob(const std::string& id) {
70 BlobDataBuilder builder(id); 96 BlobDataBuilder builder(id);
71 builder.AppendData("1", 1); 97 builder.AppendData("1", 1);
72 builder.set_content_type("text/plain"); 98 builder.set_content_type("text/plain");
73 return context_.AddFinishedBlob(builder); 99 return context_->AddFinishedBlob(builder);
74 } 100 }
75 101
76 BlobStorageRegistry* registry() { return context_.mutable_registry(); } 102 BlobStorageRegistry* registry() { return context_->mutable_registry(); }
77 103
78 const ShareableBlobDataItem& GetItemInBlob(const std::string& uuid, 104 const ShareableBlobDataItem& GetItemInBlob(const std::string& uuid,
79 size_t index) { 105 size_t index) {
80 BlobEntry* entry = registry()->GetEntry(uuid); 106 BlobEntry* entry = registry()->GetEntry(uuid);
81 EXPECT_TRUE(entry); 107 EXPECT_TRUE(entry);
82 return *entry->items()[index]; 108 return *entry->items()[index];
83 } 109 }
84 110
85 base::FilePath fake_file_path_; 111 base::FilePath fake_file_path_;
86 base::ScopedTempDir temp_dir_; 112 base::ScopedTempDir temp_dir_;
87 scoped_refptr<TestSimpleTaskRunner> file_runner_ = new TestSimpleTaskRunner(); 113 scoped_refptr<TestSimpleTaskRunner> file_runner_ = new TestSimpleTaskRunner();
88 114
89 base::MessageLoop fake_io_message_loop; 115 base::MessageLoop fake_io_message_loop;
90 BlobStorageContext context_; 116 std::unique_ptr<BlobStorageContext> context_;
91 }; 117 };
92 118
93 TEST_F(BlobFlattenerTest, NoBlobItems) { 119 TEST_F(BlobFlattenerTest, NoBlobItems) {
94 const std::string kBlobUUID = "kId"; 120 const std::string kBlobUUID = "kId";
95 121
96 BlobDataBuilder builder(kBlobUUID); 122 BlobDataBuilder builder(kBlobUUID);
97 builder.AppendData("hi", 2u); 123 builder.AppendData("hi", 2u);
98 builder.AppendFile(fake_file_path_, 0u, 10u, base::Time::Max()); 124 builder.AppendFile(fake_file_path_, 0u, 10u, base::Time::Max());
99 BlobEntry output(kType, kDisposition); 125 BlobEntry output(kType, kDisposition);
100 BlobFlattener flattener(builder, &output, registry()); 126 BlobFlattener flattener(builder, &output, registry());
101 127
102 EXPECT_EQ(BlobStatus::PENDING_QUOTA, flattener.status); 128 EXPECT_EQ(BlobStatus::PENDING_QUOTA, flattener.status);
103 EXPECT_EQ(0u, flattener.dependent_blobs.size()); 129 EXPECT_EQ(0u, flattener.dependent_blobs.size());
104 EXPECT_EQ(0u, flattener.copies.size()); 130 EXPECT_EQ(0u, flattener.copies.size());
105 EXPECT_EQ(12u, flattener.total_size); 131 EXPECT_EQ(12u, flattener.total_size);
106 EXPECT_EQ(2u, flattener.memory_quota_needed); 132 EXPECT_EQ(2u, flattener.transport_quota_needed);
107 133
108 ASSERT_EQ(2u, output.items().size()); 134 ASSERT_EQ(2u, output.items().size());
109 EXPECT_EQ(*CreateDataItem("hi", 2u), *output.items()[0]->item()); 135 EXPECT_EQ(*CreateDataItem("hi", 2u), *output.items()[0]->item());
110 EXPECT_EQ(*CreateFileItem(0, 10u), *output.items()[1]->item()); 136 EXPECT_EQ(*CreateFileItem(0, 10u), *output.items()[1]->item());
111 } 137 }
112 138
113 TEST_F(BlobFlattenerTest, ErrorCases) { 139 TEST_F(BlobFlattenerTest, ErrorCases) {
114 const std::string kBlobUUID = "kId"; 140 const std::string kBlobUUID = "kId";
115 const std::string kBlob2UUID = "kId2"; 141 const std::string kBlob2UUID = "kId2";
116 142
(...skipping 23 matching lines...) Expand all
140 BlobEntry output(kType, kDisposition); 166 BlobEntry output(kType, kDisposition);
141 BlobFlattener flattener(builder, &output, registry()); 167 BlobFlattener flattener(builder, &output, registry());
142 EXPECT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS, flattener.status); 168 EXPECT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS, flattener.status);
143 } 169 }
144 } 170 }
145 171
146 TEST_F(BlobFlattenerTest, BlobWithSlices) { 172 TEST_F(BlobFlattenerTest, BlobWithSlices) {
147 const std::string kBlobUUID = "kId"; 173 const std::string kBlobUUID = "kId";
148 const std::string kDataBlob = "kId2"; 174 const std::string kDataBlob = "kId2";
149 const std::string kFileBlob = "kId3"; 175 const std::string kFileBlob = "kId3";
176 const std::string kPendingFileBlob = "kId4";
150 177
151 // We have the following: 178 // We have the following:
152 // * data, 179 // * data,
153 // * sliced data blob, 180 // * sliced data blob,
154 // * file 181 // * file
155 // * full data blob, 182 // * full data blob,
156 // * pending data, 183 // * pending data,
157 184
185 context_ =
186 base::MakeUnique<BlobStorageContext>(temp_dir_.GetPath(), file_runner_);
187
158 std::unique_ptr<BlobDataHandle> data_blob; 188 std::unique_ptr<BlobDataHandle> data_blob;
159 { 189 {
160 BlobDataBuilder builder(kDataBlob); 190 BlobDataBuilder builder(kDataBlob);
161 builder.AppendData("12345", 5); 191 builder.AppendData("12345", 5);
162 builder.set_content_type("text/plain"); 192 builder.set_content_type("text/plain");
163 data_blob = context_.AddFinishedBlob(builder); 193 data_blob = context_->AddFinishedBlob(builder);
164 } 194 }
165 195
166 std::unique_ptr<BlobDataHandle> file_blob; 196 std::unique_ptr<BlobDataHandle> file_blob;
167 { 197 {
168 BlobDataBuilder builder(kFileBlob); 198 BlobDataBuilder builder(kFileBlob);
169 builder.AppendFile(fake_file_path_, 1u, 10u, base::Time::Max()); 199 builder.AppendFile(fake_file_path_, 1u, 10u, base::Time::Max());
170 file_blob = context_.AddFinishedBlob(builder); 200 file_blob = context_->AddFinishedBlob(builder);
201 }
202
203 BlobStatus file_status = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS;
204 std::vector<FileCreationInfo> file_handles;
205 std::unique_ptr<BlobDataHandle> future_file_blob;
206 {
207 BlobDataBuilder builder(kPendingFileBlob);
208 builder.AppendFutureFile(0u, 2u, 0);
209 builder.AppendFutureFile(2u, 5u, 0);
210 future_file_blob = context_->BuildBlob(
211 builder,
212 base::Bind(&SaveBlobStatusAndFiles, &file_status, &file_handles));
171 } 213 }
172 214
173 BlobDataBuilder builder(kBlobUUID); 215 BlobDataBuilder builder(kBlobUUID);
174 builder.AppendData("hi", 2u); 216 builder.AppendData("hi", 2u);
175 builder.AppendBlob(kDataBlob, 1u, 2u); 217 builder.AppendBlob(kDataBlob, 1u, 2u);
176 builder.AppendFile(fake_file_path_, 3u, 5u, base::Time::Max()); 218 builder.AppendFile(fake_file_path_, 3u, 5u, base::Time::Max());
177 builder.AppendBlob(kDataBlob); 219 builder.AppendBlob(kDataBlob);
178 builder.AppendBlob(kFileBlob, 1u, 3u); 220 builder.AppendBlob(kFileBlob, 1u, 3u);
179 builder.AppendFutureData(12u); 221 builder.AppendFutureData(12u);
222 builder.AppendBlob(kPendingFileBlob, 1u, 3u);
180 223
181 BlobEntry output(kType, kDisposition); 224 BlobEntry output(kType, kDisposition);
182 BlobFlattener flattener(builder, &output, registry()); 225 BlobFlattener flattener(builder, &output, registry());
183 EXPECT_EQ(BlobStatus::PENDING_QUOTA, flattener.status); 226 EXPECT_EQ(BlobStatus::PENDING_QUOTA, flattener.status);
184 227
185 EXPECT_EQ(2u, flattener.dependent_blobs.size()); 228 EXPECT_EQ(3u, flattener.dependent_blobs.size());
186 EXPECT_EQ(29u, flattener.total_size); 229 EXPECT_EQ(32u, flattener.total_size);
187 EXPECT_EQ(16u, flattener.memory_quota_needed); 230 EXPECT_EQ(14u, flattener.transport_quota_needed);
231 EXPECT_EQ(2u, flattener.copy_quota_needed);
188 232
189 ASSERT_EQ(6u, output.items().size()); 233 ASSERT_EQ(8u, output.items().size());
190 EXPECT_EQ(*CreateDataItem("hi", 2u), *output.items()[0]->item()); 234 EXPECT_EQ(*CreateDataItem("hi", 2u), *output.items()[0]->item());
191 EXPECT_EQ(*CreateDataDescriptionItem(2u), *output.items()[1]->item()); 235 EXPECT_EQ(*CreateDataDescriptionItem(2u), *output.items()[1]->item());
192 EXPECT_EQ(*CreateFileItem(3u, 5u), *output.items()[2]->item()); 236 EXPECT_EQ(*CreateFileItem(3u, 5u), *output.items()[2]->item());
193 EXPECT_EQ(GetItemInBlob(kDataBlob, 0), *output.items()[3]); 237 EXPECT_EQ(GetItemInBlob(kDataBlob, 0), *output.items()[3]);
194 EXPECT_EQ(*CreateFileItem(2u, 3u), *output.items()[4]->item()); 238 EXPECT_EQ(*CreateFileItem(2u, 3u), *output.items()[4]->item());
195 EXPECT_EQ(*CreateDataDescriptionItem(12u), *output.items()[5]->item()); 239 EXPECT_EQ(*CreateDataDescriptionItem(12u), *output.items()[5]->item());
240 EXPECT_EQ(*CreateFutureFileItem(1u, 1u), *output.items()[6]->item());
241 EXPECT_EQ(*CreateFutureFileItem(2u, 2u), *output.items()[7]->item());
196 242
197 // We're copying item at index 1 243 // We're copying items at index 1, 6, and 7.
198 ASSERT_EQ(1u, flattener.copies.size()); 244 ASSERT_EQ(3u, flattener.copies.size());
199 EXPECT_EQ(*flattener.copies[0].dest_item, *output.items()[1]); 245 EXPECT_EQ(*flattener.copies[0].dest_item, *output.items()[1]);
200 EXPECT_EQ(GetItemInBlob(kDataBlob, 0), *flattener.copies[0].source_item); 246 EXPECT_EQ(GetItemInBlob(kDataBlob, 0), *flattener.copies[0].source_item);
201 EXPECT_EQ(1u, flattener.copies[0].source_item_offset); 247 EXPECT_EQ(1u, flattener.copies[0].source_item_offset);
248 EXPECT_EQ(*flattener.copies[1].dest_item, *output.items()[6]);
249 EXPECT_EQ(GetItemInBlob(kPendingFileBlob, 0),
250 *flattener.copies[1].source_item);
251 EXPECT_EQ(1u, flattener.copies[1].source_item_offset);
252 EXPECT_EQ(*flattener.copies[2].dest_item, *output.items()[7]);
253 EXPECT_EQ(GetItemInBlob(kPendingFileBlob, 1),
254 *flattener.copies[2].source_item);
255 EXPECT_EQ(0u, flattener.copies[2].source_item_offset);
256
257 // Clean up temp files.
258 EXPECT_TRUE(file_runner_->HasPendingTask());
259 file_runner_->RunPendingTasks();
260 base::RunLoop().RunUntilIdle();
261 EXPECT_EQ(BlobStatus::PENDING_TRANSPORT, file_status);
262 EXPECT_FALSE(file_handles.empty());
202 } 263 }
203 264
204 } // namespace storage 265 } // namespace storage
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698