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

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

Issue 2448353002: [BlobAsync] Moving async handling into BlobStorageContext & quota out. (Closed)
Patch Set: comments Created 4 years, 1 month 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/files/scoped_temp_dir.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/run_loop.h"
14 #include "base/test/test_simple_task_runner.h"
15 #include "base/time/time.h"
16 #include "storage/browser/blob/blob_data_builder.h"
17 #include "storage/browser/blob/blob_data_handle.h"
18 #include "storage/browser/blob/blob_data_item.h"
19 #include "storage/browser/blob/blob_entry.h"
20 #include "storage/browser/blob/blob_storage_registry.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 } // namespace
33
34 class BlobFlattenerTest : public testing::Test {
35 protected:
36 using BlobFlattener = BlobStorageContext::BlobFlattener;
37
38 BlobFlattenerTest()
39 : fake_file_path_(base::FilePath(FILE_PATH_LITERAL("kFakePath"))) {}
40 ~BlobFlattenerTest() override {}
41
42 void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); }
43
44 void TearDown() override {
45 base::RunLoop().RunUntilIdle();
46 file_runner_->RunPendingTasks();
47 ASSERT_TRUE(temp_dir_.Delete());
48 }
49
50 scoped_refptr<BlobDataItem> CreateDataDescriptionItem(size_t size) {
51 std::unique_ptr<DataElement> element(new DataElement());
52 element->SetToBytesDescription(size);
53 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element)));
54 };
55
56 scoped_refptr<BlobDataItem> CreateDataItem(const char* memory, size_t size) {
57 std::unique_ptr<DataElement> element(new DataElement());
58 element->SetToBytes(memory, size);
59 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element)));
60 };
61
62 scoped_refptr<BlobDataItem> CreateFileItem(size_t offset, size_t size) {
63 std::unique_ptr<DataElement> element(new DataElement());
64 element->SetToFilePathRange(fake_file_path_, offset, size,
65 base::Time::Max());
66 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element)));
67 };
68
69 std::unique_ptr<BlobDataHandle> SetupBasicBlob(const std::string& id) {
70 BlobDataBuilder builder(id);
71 builder.AppendData("1", 1);
72 builder.set_content_type("text/plain");
73 return context_.AddFinishedBlob(builder);
74 }
75
76 BlobStorageRegistry* registry() { return context_.mutable_registry(); }
77
78 const ShareableBlobDataItem& GetItemInBlob(const std::string& uuid,
79 size_t index) {
80 BlobEntry* entry = registry()->GetEntry(uuid);
81 EXPECT_TRUE(entry);
82 return *entry->items()[index];
83 }
84
85 base::FilePath fake_file_path_;
86 base::ScopedTempDir temp_dir_;
87 scoped_refptr<TestSimpleTaskRunner> file_runner_ = new TestSimpleTaskRunner();
88
89 base::MessageLoop fake_io_message_loop;
90 BlobStorageContext context_;
91 };
92
93 TEST_F(BlobFlattenerTest, NoBlobItems) {
94 const std::string kBlobUUID = "kId";
95
96 BlobDataBuilder builder(kBlobUUID);
97 builder.AppendData("hi", 2u);
98 builder.AppendFile(fake_file_path_, 0u, 10u, base::Time::Max());
99 BlobEntry output(kType, kDisposition);
100 BlobFlattener flattener(builder, &output, registry());
101
102 EXPECT_EQ(BlobStatus::PENDING_QUOTA, flattener.status);
103 EXPECT_EQ(0u, flattener.dependent_blobs.size());
104 EXPECT_EQ(0u, flattener.copies.size());
105 EXPECT_EQ(12u, flattener.total_size);
106 EXPECT_EQ(2u, flattener.memory_quota_needed);
107
108 ASSERT_EQ(2u, output.items().size());
109 EXPECT_EQ(*CreateDataItem("hi", 2u), *output.items()[0]->item());
110 EXPECT_EQ(*CreateFileItem(0, 10u), *output.items()[1]->item());
111 }
112
113 TEST_F(BlobFlattenerTest, ErrorCases) {
114 const std::string kBlobUUID = "kId";
115 const std::string kBlob2UUID = "kId2";
116
117 // Invalid blob reference.
118 {
119 BlobDataBuilder builder(kBlobUUID);
120 builder.AppendBlob("doesnotexist");
121 BlobEntry output(kType, kDisposition);
122 BlobFlattener flattener(builder, &output, registry());
123 EXPECT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS, flattener.status);
124 }
125
126 // Circular reference.
127 {
128 BlobDataBuilder builder(kBlobUUID);
129 builder.AppendBlob(kBlobUUID);
130 BlobEntry output(kType, kDisposition);
131 BlobFlattener flattener(builder, &output, registry());
132 EXPECT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS, flattener.status);
133 }
134
135 // Bad slice.
136 {
137 std::unique_ptr<BlobDataHandle> handle = SetupBasicBlob(kBlob2UUID);
138 BlobDataBuilder builder(kBlobUUID);
139 builder.AppendBlob(kBlob2UUID, 1, 2);
140 BlobEntry output(kType, kDisposition);
141 BlobFlattener flattener(builder, &output, registry());
142 EXPECT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS, flattener.status);
143 }
144 }
145
146 TEST_F(BlobFlattenerTest, BlobWithSlices) {
147 const std::string kBlobUUID = "kId";
148 const std::string kDataBlob = "kId2";
149 const std::string kFileBlob = "kId3";
150
151 // We have the following:
152 // * data,
153 // * sliced data blob,
154 // * file
155 // * full data blob,
156 // * pending data,
157
158 std::unique_ptr<BlobDataHandle> data_blob;
159 {
160 BlobDataBuilder builder(kDataBlob);
161 builder.AppendData("12345", 5);
162 builder.set_content_type("text/plain");
163 data_blob = context_.AddFinishedBlob(builder);
164 }
165
166 std::unique_ptr<BlobDataHandle> file_blob;
167 {
168 BlobDataBuilder builder(kFileBlob);
169 builder.AppendFile(fake_file_path_, 1u, 10u, base::Time::Max());
170 file_blob = context_.AddFinishedBlob(builder);
171 }
172
173 BlobDataBuilder builder(kBlobUUID);
174 builder.AppendData("hi", 2u);
175 builder.AppendBlob(kDataBlob, 1u, 2u);
176 builder.AppendFile(fake_file_path_, 3u, 5u, base::Time::Max());
177 builder.AppendBlob(kDataBlob);
178 builder.AppendBlob(kFileBlob, 1u, 3u);
179 builder.AppendFutureData(12u);
180
181 BlobEntry output(kType, kDisposition);
182 BlobFlattener flattener(builder, &output, registry());
183 EXPECT_EQ(BlobStatus::PENDING_QUOTA, flattener.status);
184
185 EXPECT_EQ(2u, flattener.dependent_blobs.size());
186 EXPECT_EQ(29u, flattener.total_size);
187 EXPECT_EQ(16u, flattener.memory_quota_needed);
188
189 ASSERT_EQ(6u, output.items().size());
190 EXPECT_EQ(*CreateDataItem("hi", 2u), *output.items()[0]->item());
191 EXPECT_EQ(*CreateDataDescriptionItem(2u), *output.items()[1]->item());
192 EXPECT_EQ(*CreateFileItem(3u, 5u), *output.items()[2]->item());
193 EXPECT_EQ(GetItemInBlob(kDataBlob, 0), *output.items()[3]);
194 EXPECT_EQ(*CreateFileItem(2u, 3u), *output.items()[4]->item());
195 EXPECT_EQ(*CreateDataDescriptionItem(12u), *output.items()[5]->item());
196
197 // We're copying item at index 1
198 ASSERT_EQ(1u, flattener.copies.size());
199 EXPECT_EQ(*flattener.copies[0].dest_item, *output.items()[1]);
200 EXPECT_EQ(GetItemInBlob(kDataBlob, 0), *flattener.copies[0].source_item);
201 EXPECT_EQ(1u, flattener.copies[0].source_item_offset);
202 }
203
204 } // namespace storage
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698