1 // Copyright 2013 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.
5 #include "content/browser/renderer_host/pepper/quota_reservation.h"
8 #include "base/bind_helpers.h"
9 #include "base/file_util.h"
10 #include "base/files/scoped_temp_dir.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/run_loop.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "webkit/browser/fileapi/quota/quota_reservation.h"
16 using fileapi::FileSystemType
;
17 using fileapi::QuotaReservationManager
;
23 const char kOrigin
[] = "http://example.com";
24 const FileSystemType kType
= fileapi::kFileSystemTypeTemporary
;
26 const base::FilePath::StringType file1_name
= FILE_PATH_LITERAL("file1");
27 const base::FilePath::StringType file2_name
= FILE_PATH_LITERAL("file2");
28 const base::FilePath::StringType file3_name
= FILE_PATH_LITERAL("file3");
29 const int kFile1ID
= 1;
30 const int kFile2ID
= 2;
31 const int kFile3ID
= 3;
33 class FakeBackend
: public QuotaReservationManager::QuotaBackend
{
36 virtual ~FakeBackend() {}
38 virtual void ReserveQuota(
42 const QuotaReservationManager::ReserveQuotaCallback
& callback
) OVERRIDE
{
43 base::MessageLoopProxy::current()->PostTask(
45 base::Bind(base::IgnoreResult(callback
), base::PLATFORM_FILE_OK
));
48 virtual void ReleaseReservedQuota(const GURL
& origin
,
50 int64 size
) OVERRIDE
{
53 virtual void CommitQuotaUsage(const GURL
& origin
,
55 int64 delta
) OVERRIDE
{
58 virtual void IncrementDirtyCount(const GURL
& origin
,
59 FileSystemType type
) OVERRIDE
{}
60 virtual void DecrementDirtyCount(const GURL
& origin
,
61 FileSystemType type
) OVERRIDE
{}
64 DISALLOW_COPY_AND_ASSIGN(FakeBackend
);
69 class QuotaReservationTest
: public testing::Test
{
71 QuotaReservationTest() {}
72 virtual ~QuotaReservationTest() {}
74 virtual void SetUp() OVERRIDE
{
75 ASSERT_TRUE(work_dir_
.CreateUniqueTempDir());
77 reservation_manager_
.reset(new QuotaReservationManager(
78 scoped_ptr
<QuotaReservationManager::QuotaBackend
>(new FakeBackend
)));
81 virtual void TearDown() OVERRIDE
{
82 reservation_manager_
.reset();
85 base::FilePath
MakeFilePath(base::FilePath::StringType file_name
) {
86 return work_dir_
.path().Append(file_name
);
89 scoped_refptr
<QuotaReservation
> CreateQuotaReservation(
90 scoped_refptr
<fileapi::QuotaReservation
> reservation
,
92 FileSystemType type
) {
93 // Sets reservation_ as a side effect.
94 return scoped_refptr
<QuotaReservation
>(
95 new QuotaReservation(reservation
, origin
, type
));
98 void SetFileSize(const base::FilePath::StringType
& file_name
, int64 size
) {
100 base::PlatformFileError error
= base::PLATFORM_FILE_ERROR_FAILED
;
101 base::PlatformFile file
= CreatePlatformFile(
102 MakeFilePath(file_name
),
103 base::PLATFORM_FILE_OPEN_ALWAYS
| base::PLATFORM_FILE_WRITE
,
105 ASSERT_EQ(base::PLATFORM_FILE_OK
, error
);
106 ASSERT_TRUE(base::TruncatePlatformFile(file
, size
));
107 ASSERT_TRUE(base::ClosePlatformFile(file
));
110 QuotaReservationManager
* reservation_manager() {
111 return reservation_manager_
.get();
115 base::MessageLoop message_loop_
;
116 base::ScopedTempDir work_dir_
;
117 scoped_ptr
<fileapi::QuotaReservationManager
> reservation_manager_
;
119 DISALLOW_COPY_AND_ASSIGN(QuotaReservationTest
);
122 void GotReservedQuota(
123 int64
* reserved_quota_ptr
,
124 QuotaReservation::OffsetMap
* maximum_written_offsets_ptr
,
125 int64 reserved_quota
,
126 const QuotaReservation::OffsetMap
& maximum_written_offsets
) {
127 *reserved_quota_ptr
= reserved_quota
;
128 *maximum_written_offsets_ptr
= maximum_written_offsets
;
132 scoped_refptr
<QuotaReservation
> quota_reservation
,
134 int64
* reserved_quota
,
135 QuotaReservation::OffsetMap
* max_written_offsets
) {
136 quota_reservation
->ReserveQuota(amount
,
137 *max_written_offsets
,
138 base::Bind(&GotReservedQuota
,
140 max_written_offsets
));
141 base::RunLoop().RunUntilIdle();
145 // 1) We can reserve quota with no files open.
146 // 2) Open a file, grow it, close it, and reserve quota with correct sizes.
147 TEST_F(QuotaReservationTest
, DISABLED_ReserveQuota
) {
148 GURL
origin(kOrigin
);
149 FileSystemType type
= kType
;
151 scoped_refptr
<fileapi::QuotaReservation
> reservation(
152 reservation_manager()->CreateReservation(origin
, type
));
153 scoped_refptr
<QuotaReservation
> test
=
154 CreateQuotaReservation(reservation
, origin
, type
);
156 // Reserve quota with no files open.
158 int64 reserved_quota
;
159 QuotaReservation::OffsetMap max_written_offsets
;
160 ReserveQuota(test
, amount
, &reserved_quota
, &max_written_offsets
);
161 EXPECT_EQ(amount
, reserved_quota
);
162 EXPECT_EQ(0U, max_written_offsets
.size());
164 // Open a file, refresh the reservation, extend the file, and close it.
165 int64 file_size
= 10;
166 SetFileSize(file1_name
, file_size
);
167 int64 open_file_size
= test
->OpenFile(kFile1ID
, MakeFilePath(file1_name
));
168 EXPECT_EQ(file_size
, open_file_size
);
170 max_written_offsets
[kFile1ID
] = file_size
; // 1 file open.
171 ReserveQuota(test
, amount
, &reserved_quota
, &max_written_offsets
);
172 EXPECT_EQ(amount
, reserved_quota
);
173 EXPECT_EQ(1U, max_written_offsets
.size());
174 EXPECT_EQ(file_size
, max_written_offsets
[kFile1ID
]);
176 int64 new_file_size
= 30;
177 SetFileSize(file1_name
, new_file_size
);
179 EXPECT_EQ(amount
, reservation
->remaining_quota());
180 test
->CloseFile(kFile1ID
, new_file_size
);
181 EXPECT_EQ(amount
- (new_file_size
- file_size
),
182 reservation
->remaining_quota());
186 // 1) We can open and close multiple files.
187 TEST_F(QuotaReservationTest
, DISABLED_MultipleFiles
) {
188 GURL
origin(kOrigin
);
189 FileSystemType type
= kType
;
191 scoped_refptr
<fileapi::QuotaReservation
> reservation(
192 reservation_manager()->CreateReservation(origin
, type
));
193 scoped_refptr
<QuotaReservation
> test
=
194 CreateQuotaReservation(reservation
, origin
, type
);
196 // Open some files of different sizes.
197 int64 file1_size
= 10;
198 SetFileSize(file1_name
, file1_size
);
199 int64 open_file1_size
= test
->OpenFile(kFile1ID
, MakeFilePath(file1_name
));
200 EXPECT_EQ(file1_size
, open_file1_size
);
201 int64 file2_size
= 20;
202 SetFileSize(file2_name
, file2_size
);
203 int64 open_file2_size
= test
->OpenFile(kFile2ID
, MakeFilePath(file2_name
));
204 EXPECT_EQ(file2_size
, open_file2_size
);
205 int64 file3_size
= 30;
206 SetFileSize(file3_name
, file3_size
);
207 int64 open_file3_size
= test
->OpenFile(kFile3ID
, MakeFilePath(file3_name
));
208 EXPECT_EQ(file3_size
, open_file3_size
);
212 int64 reserved_quota
;
213 QuotaReservation::OffsetMap max_written_offsets
;
214 max_written_offsets
[kFile1ID
] = file1_size
; // 3 files open.
215 max_written_offsets
[kFile2ID
] = file2_size
;
216 max_written_offsets
[kFile3ID
] = file3_size
;
218 ReserveQuota(test
, amount
, &reserved_quota
, &max_written_offsets
);
219 EXPECT_EQ(amount
, reserved_quota
);
220 EXPECT_EQ(3U, max_written_offsets
.size());
221 EXPECT_EQ(file1_size
, max_written_offsets
[kFile1ID
]);
222 EXPECT_EQ(file2_size
, max_written_offsets
[kFile2ID
]);
223 EXPECT_EQ(file3_size
, max_written_offsets
[kFile3ID
]);
225 test
->CloseFile(kFile2ID
, file2_size
);
227 max_written_offsets
.erase(max_written_offsets
.find(kFile2ID
));
228 ReserveQuota(test
, amount
, &reserved_quota
, &max_written_offsets
);
229 EXPECT_EQ(amount
, reserved_quota
);
230 EXPECT_EQ(2U, max_written_offsets
.size());
231 EXPECT_EQ(file1_size
, max_written_offsets
[kFile1ID
]);
232 EXPECT_EQ(file3_size
, max_written_offsets
[kFile3ID
]);
234 test
->CloseFile(kFile1ID
, file1_size
);
235 test
->CloseFile(kFile3ID
, file3_size
);
238 } // namespace content