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

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: rebase Created 4 years, 2 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_storage_context.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_registry.h"
19 #include "storage/browser/blob/internal_blob_data.h"
20 #include "storage/browser/blob/shareable_blob_data_item.h"
21 #include "storage/common/data_element.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23
24 namespace storage {
25 namespace {
26 using base::TestSimpleTaskRunner;
27
28 const char kType[] = "type";
29 const char kDisposition[] = "";
30
31 scoped_refptr<BlobDataItem> CreateDataDescriptionItem(size_t size) {
32 std::unique_ptr<DataElement> element(new DataElement());
33 element->SetToBytesDescription(size);
34 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element)));
35 };
36
37 scoped_refptr<BlobDataItem> CreateDataItem(const char* memory, size_t size) {
38 std::unique_ptr<DataElement> element(new DataElement());
39 element->SetToBytes(memory, size);
40 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element)));
41 };
42
43 scoped_refptr<BlobDataItem> CreateFileItem(size_t offset, size_t size) {
44 std::unique_ptr<DataElement> element(new DataElement());
45 element->SetToFilePathRange(base::FilePath("kFakePath"), offset, size,
46 base::Time::Max());
47 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element)));
48 };
49
50 scoped_refptr<BlobDataItem> CreateFutureFileItem(size_t offset, size_t size) {
51 std::unique_ptr<DataElement> element(new DataElement());
52 element->SetToFilePathRange(base::FilePath(BlobDataBuilder::kFutureFileName),
53 offset, size, base::Time::Max());
54 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element)));
55 };
56
57 } // namespace
58
59 class BlobFlattenerTest : public testing::Test {
60 protected:
61 using BlobFlattener = BlobStorageContext::BlobFlattener;
62
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(base::FilePath(BlobDataBuilder::kFutureFileName), 2u, 5u,
187 base::Time::Max());
188 future_file_blob = context_.AddFinishedBlob(builder);
189 }
190
191 BlobDataBuilder builder(kBlobUUID);
192 builder.AppendData("hi", 2u);
193 builder.AppendBlob(kDataBlob, 1u, 2u);
194 builder.AppendFile(base::FilePath("kFakePath"), 3u, 5u, base::Time::Max());
195 builder.AppendBlob(kDataBlob);
196 builder.AppendBlob(kFileBlob, 1u, 3u);
197 builder.AppendFutureData(12u);
198 builder.AppendBlob(kPendingFileBlob, 1u, 2u);
199
200 InternalBlobData output(kType, kDisposition);
201 BlobFlattener flattener(builder, &output, registry());
202 EXPECT_EQ(BlobStatus::PENDING, flattener.status);
203
204 EXPECT_EQ(3u, flattener.dependent_blobs.size());
205 EXPECT_EQ(31u, flattener.total_size.ValueOrDie());
206 EXPECT_EQ(14u, flattener.transport_quota_needed.ValueOrDie());
207 EXPECT_EQ(2u, flattener.copy_quota_needed.ValueOrDie());
208
209 ASSERT_EQ(7u, output.items().size());
210 EXPECT_EQ(*CreateDataItem("hi", 2u), *output.items()[0]->item());
211 EXPECT_EQ(*CreateDataDescriptionItem(2u), *output.items()[1]->item());
212 EXPECT_EQ(*CreateFileItem(3u, 5u), *output.items()[2]->item());
213 EXPECT_EQ(GetItemInBlob(kDataBlob, 0), *output.items()[3]);
214 EXPECT_EQ(*CreateFileItem(2u, 3u), *output.items()[4]->item());
215 EXPECT_EQ(*CreateDataDescriptionItem(12u), *output.items()[5]->item());
216 EXPECT_EQ(*CreateFutureFileItem(3u, 2u), *output.items()[6]->item());
217
218 // We're copying item at index 1 and 6.
219 ASSERT_EQ(2u, flattener.copies.size());
220 EXPECT_EQ(*flattener.copies[0].dest_item, *output.items()[1]);
221 EXPECT_EQ(GetItemInBlob(kDataBlob, 0), *flattener.copies[0].source_item);
222 EXPECT_EQ(1u, flattener.copies[0].source_item_offset);
223
224 EXPECT_EQ(*flattener.copies[1].dest_item, *output.items()[6]);
225 EXPECT_EQ(GetItemInBlob(kPendingFileBlob, 0),
226 *flattener.copies[1].source_item);
227 EXPECT_EQ(1u, flattener.copies[0].source_item_offset);
228 }
229
230 } // namespace storage
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698