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

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

Issue 2055053003: [BlobAsync] Disk support for blob storage (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Combined BlobSlice & BlobFlattener files, more comments, a little cleanup. Created 4 years, 4 months 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "storage/browser/blob/blob_flattener.h"
6
7 #include <memory>
8
9 #include "base/files/file_path.h"
10 #include "base/files/file_util.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/run_loop.h"
13 #include "base/test/test_simple_task_runner.h"
14 #include "base/time/time.h"
15 #include "storage/browser/blob/blob_data_builder.h"
16 #include "storage/browser/blob/blob_data_handle.h"
17 #include "storage/browser/blob/blob_data_item.h"
18 #include "storage/browser/blob/blob_storage_context.h"
19 #include "storage/browser/blob/blob_storage_registry.h"
20 #include "storage/browser/blob/internal_blob_data.h"
21 #include "storage/browser/blob/shareable_blob_data_item.h"
22 #include "storage/common/data_element.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24
25 namespace storage {
26 namespace {
27 using base::TestSimpleTaskRunner;
28
29 const char kType[] = "type";
30 const char kDisposition[] = "";
31
32 scoped_refptr<BlobDataItem> CreateDataDescriptionItem(size_t size) {
33 std::unique_ptr<DataElement> element(new DataElement());
34 element->SetToBytesDescription(size);
35 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element)));
36 };
37
38 scoped_refptr<BlobDataItem> CreateDataItem(const char* memory, size_t size) {
39 std::unique_ptr<DataElement> element(new DataElement());
40 element->SetToBytes(memory, size);
41 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element)));
42 };
43
44 scoped_refptr<BlobDataItem> CreateFileItem(size_t offset, size_t size) {
45 std::unique_ptr<DataElement> element(new DataElement());
46 element->SetToFilePathRange(base::FilePath("kFakePath"), offset, size,
47 base::Time::Max());
48 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element)));
49 };
50
51 scoped_refptr<BlobDataItem> CreateFutureFileItem(size_t offset, size_t size) {
52 std::unique_ptr<DataElement> element(new DataElement());
53 element->SetToFilePathRange(
54 base::FilePath(BlobDataBuilder::kAppendFutureFileTemporaryFileName),
55 offset, size, base::Time::Max());
56 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element)));
57 };
58
59 } // namespace
60
61 class BlobFlattenerTest : public testing::Test {
62 protected:
63 BlobFlattenerTest() {}
64 ~BlobFlattenerTest() override {}
65
66 void SetUp() override {
67 ASSERT_TRUE(base::CreateNewTempDirectory("BlobFlattenerTest", &temp_dir_));
68 }
69
70 void TearDown() override {
71 base::RunLoop().RunUntilIdle();
72 file_runner_->RunPendingTasks();
73 ASSERT_EQ(true, base::DeleteFile(temp_dir_, true));
74 }
75
76 std::unique_ptr<BlobDataHandle> SetupBasicBlob(const std::string& id) {
77 BlobDataBuilder builder(id);
78 builder.AppendData("1", 1);
79 builder.set_content_type("text/plain");
80 return context_.AddFinishedBlob(builder);
81 }
82
83 BlobStorageRegistry* registry() { return context_.mutable_registry(); }
84
85 const ShareableBlobDataItem& GetItemInBlob(const std::string& uuid,
86 size_t index) {
87 InternalBlobData* entry = registry()->GetEntry(uuid);
88 EXPECT_TRUE(entry);
89 return *entry->items()[index];
90 }
91
92 base::FilePath temp_dir_;
93 scoped_refptr<TestSimpleTaskRunner> file_runner_ = new TestSimpleTaskRunner();
94
95 base::MessageLoop fake_io_message_loop;
96 BlobStorageContext context_;
97 };
98
99 TEST_F(BlobFlattenerTest, NoBlobItems) {
100 const std::string kBlobUUID = "kId";
101
102 BlobDataBuilder builder(kBlobUUID);
103 builder.AppendData("hi", 2u);
104 builder.AppendFile(base::FilePath("kFakePath"), 0u, 10u, base::Time::Max());
105 InternalBlobData output(kType, kDisposition);
106 BlobFlattener flattener(builder, &output, registry());
107
108 EXPECT_EQ(BlobStatus::DONE, flattener.status);
109 EXPECT_EQ(0u, flattener.dependent_blobs.size());
110 EXPECT_EQ(0u, flattener.copies.size());
111 EXPECT_EQ(12u, flattener.total_size.ValueOrDie());
112 EXPECT_EQ(2u, flattener.transport_quota_needed.ValueOrDie());
113
114 ASSERT_EQ(2u, output.items().size());
115 EXPECT_EQ(*CreateDataItem("hi", 2u), *output.items()[0]->item());
116 EXPECT_EQ(*CreateFileItem(0, 10u), *output.items()[1]->item());
117 }
118
119 TEST_F(BlobFlattenerTest, ErrorCases) {
120 const std::string kBlobUUID = "kId";
121 const std::string kBlob2UUID = "kId2";
122
123 // Invalid blob reference.
124 {
125 BlobDataBuilder builder(kBlobUUID);
126 builder.AppendBlob("doesnotexist");
127 InternalBlobData output(kType, kDisposition);
128 BlobFlattener flattener(builder, &output, registry());
129 EXPECT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS, flattener.status);
130 }
131
132 // Circular reference.
133 {
134 BlobDataBuilder builder(kBlobUUID);
135 builder.AppendBlob(kBlobUUID);
136 InternalBlobData output(kType, kDisposition);
137 BlobFlattener flattener(builder, &output, registry());
138 EXPECT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS, flattener.status);
139 }
140
141 // Bad slice.
142 {
143 std::unique_ptr<BlobDataHandle> handle = SetupBasicBlob(kBlob2UUID);
144 BlobDataBuilder builder(kBlobUUID);
145 builder.AppendBlob(kBlob2UUID, 1, 2);
146 InternalBlobData output(kType, kDisposition);
147 BlobFlattener flattener(builder, &output, registry());
148 EXPECT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS, flattener.status);
149 }
150 }
151
152 TEST_F(BlobFlattenerTest, BlobWithSlices) {
153 const std::string kBlobUUID = "kId";
154 const std::string kDataBlob = "kId2";
155 const std::string kFileBlob = "kId3";
156 const std::string kPendingFileBlob = "kId4";
157
158 // We have the following:
159 // * data,
160 // * sliced data blob,
161 // * file
162 // * full data blob,
163 // * pending data,
164 // * sliced pending file.
165
166 context_.EnableDisk(temp_dir_, file_runner_);
167
168 std::unique_ptr<BlobDataHandle> data_blob;
169 {
170 BlobDataBuilder builder(kDataBlob);
171 builder.AppendData("12345", 5);
172 builder.set_content_type("text/plain");
173 data_blob = context_.AddFinishedBlob(builder);
174 }
175
176 std::unique_ptr<BlobDataHandle> file_blob;
177 {
178 BlobDataBuilder builder(kFileBlob);
179 builder.AppendFile(base::FilePath("kFakePath"), 1u, 10u, base::Time::Max());
180 file_blob = context_.AddFinishedBlob(builder);
181 }
182
183 std::unique_ptr<BlobDataHandle> future_file_blob;
184 {
185 BlobDataBuilder builder(kPendingFileBlob);
186 builder.AppendFile(
187 base::FilePath(BlobDataBuilder::kAppendFutureFileTemporaryFileName), 2u,
188 5u, base::Time::Max());
189 future_file_blob = context_.AddFinishedBlob(builder);
190 }
191
192 BlobDataBuilder builder(kBlobUUID);
193 builder.AppendData("hi", 2u);
194 builder.AppendBlob(kDataBlob, 1u, 2u);
195 builder.AppendFile(base::FilePath("kFakePath"), 3u, 5u, base::Time::Max());
196 builder.AppendBlob(kDataBlob);
197 builder.AppendBlob(kFileBlob, 1u, 3u);
198 builder.AppendFutureData(12u);
199 builder.AppendBlob(kPendingFileBlob, 1u, 2u);
200
201 InternalBlobData output(kType, kDisposition);
202 BlobFlattener flattener(builder, &output, registry());
203 EXPECT_EQ(BlobStatus::PENDING, flattener.status);
204
205 EXPECT_EQ(3u, flattener.dependent_blobs.size());
206 EXPECT_EQ(31u, flattener.total_size.ValueOrDie());
207 EXPECT_EQ(14u, flattener.transport_quota_needed.ValueOrDie());
208 EXPECT_EQ(2u, flattener.copy_quota_needed.ValueOrDie());
209
210 ASSERT_EQ(7u, output.items().size());
211 EXPECT_EQ(*CreateDataItem("hi", 2u), *output.items()[0]->item());
212 EXPECT_EQ(*CreateDataDescriptionItem(2u), *output.items()[1]->item());
213 EXPECT_EQ(*CreateFileItem(3u, 5u), *output.items()[2]->item());
214 EXPECT_EQ(GetItemInBlob(kDataBlob, 0), *output.items()[3]);
215 EXPECT_EQ(*CreateFileItem(2u, 3u), *output.items()[4]->item());
216 EXPECT_EQ(*CreateDataDescriptionItem(12u), *output.items()[5]->item());
217 EXPECT_EQ(*CreateFutureFileItem(3u, 2u), *output.items()[6]->item());
218
219 // We're copying item at index 1 and 6.
220 ASSERT_EQ(2u, flattener.copies.size());
221 EXPECT_EQ(*flattener.copies[0].dest_item, *output.items()[1]);
222 EXPECT_EQ(GetItemInBlob(kDataBlob, 0), *flattener.copies[0].source_item);
223 EXPECT_EQ(1u, flattener.copies[0].source_item_offset);
224
225 EXPECT_EQ(*flattener.copies[1].dest_item, *output.items()[6]);
226 EXPECT_EQ(GetItemInBlob(kPendingFileBlob, 0),
227 *flattener.copies[1].source_item);
228 EXPECT_EQ(1u, flattener.copies[0].source_item_offset);
229 }
230
231 } // namespace storage
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698