| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/fileapi/quota/quota_reservation_manager.h" | 5 #include "storage/browser/fileapi/quota/quota_reservation_manager.h" |
| 6 | 6 |
| 7 #include <stdint.h> |
| 8 |
| 7 #include "base/bind.h" | 9 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| 9 #include "base/files/file.h" | 11 #include "base/files/file.h" |
| 10 #include "base/files/file_util.h" | 12 #include "base/files/file_util.h" |
| 11 #include "base/files/scoped_temp_dir.h" | 13 #include "base/files/scoped_temp_dir.h" |
| 12 #include "base/location.h" | 14 #include "base/location.h" |
| 15 #include "base/macros.h" |
| 13 #include "base/run_loop.h" | 16 #include "base/run_loop.h" |
| 14 #include "base/single_thread_task_runner.h" | 17 #include "base/single_thread_task_runner.h" |
| 15 #include "base/thread_task_runner_handle.h" | 18 #include "base/thread_task_runner_handle.h" |
| 16 #include "storage/browser/fileapi/quota/open_file_handle.h" | 19 #include "storage/browser/fileapi/quota/open_file_handle.h" |
| 17 #include "storage/browser/fileapi/quota/quota_reservation.h" | 20 #include "storage/browser/fileapi/quota/quota_reservation.h" |
| 18 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
| 19 | 22 |
| 20 using storage::kFileSystemTypeTemporary; | 23 using storage::kFileSystemTypeTemporary; |
| 21 using storage::OpenFileHandle; | 24 using storage::OpenFileHandle; |
| 22 using storage::QuotaReservation; | 25 using storage::QuotaReservation; |
| 23 using storage::QuotaReservationManager; | 26 using storage::QuotaReservationManager; |
| 24 | 27 |
| 25 namespace content { | 28 namespace content { |
| 26 | 29 |
| 27 namespace { | 30 namespace { |
| 28 | 31 |
| 29 const char kOrigin[] = "http://example.com"; | 32 const char kOrigin[] = "http://example.com"; |
| 30 const storage::FileSystemType kType = kFileSystemTypeTemporary; | 33 const storage::FileSystemType kType = kFileSystemTypeTemporary; |
| 31 const int64 kInitialFileSize = 1; | 34 const int64_t kInitialFileSize = 1; |
| 32 | 35 |
| 33 typedef QuotaReservationManager::ReserveQuotaCallback ReserveQuotaCallback; | 36 typedef QuotaReservationManager::ReserveQuotaCallback ReserveQuotaCallback; |
| 34 | 37 |
| 35 int64 GetFileSize(const base::FilePath& path) { | 38 int64_t GetFileSize(const base::FilePath& path) { |
| 36 int64 size = 0; | 39 int64_t size = 0; |
| 37 base::GetFileSize(path, &size); | 40 base::GetFileSize(path, &size); |
| 38 return size; | 41 return size; |
| 39 } | 42 } |
| 40 | 43 |
| 41 void SetFileSize(const base::FilePath& path, int64 size) { | 44 void SetFileSize(const base::FilePath& path, int64_t size) { |
| 42 base::File file(path, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_WRITE); | 45 base::File file(path, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_WRITE); |
| 43 ASSERT_TRUE(file.IsValid()); | 46 ASSERT_TRUE(file.IsValid()); |
| 44 ASSERT_TRUE(file.SetLength(size)); | 47 ASSERT_TRUE(file.SetLength(size)); |
| 45 } | 48 } |
| 46 | 49 |
| 47 class FakeBackend : public QuotaReservationManager::QuotaBackend { | 50 class FakeBackend : public QuotaReservationManager::QuotaBackend { |
| 48 public: | 51 public: |
| 49 FakeBackend() | 52 FakeBackend() |
| 50 : on_memory_usage_(kInitialFileSize), | 53 : on_memory_usage_(kInitialFileSize), |
| 51 on_disk_usage_(kInitialFileSize) {} | 54 on_disk_usage_(kInitialFileSize) {} |
| 52 ~FakeBackend() override {} | 55 ~FakeBackend() override {} |
| 53 | 56 |
| 54 void ReserveQuota(const GURL& origin, | 57 void ReserveQuota(const GURL& origin, |
| 55 storage::FileSystemType type, | 58 storage::FileSystemType type, |
| 56 int64 delta, | 59 int64_t delta, |
| 57 const ReserveQuotaCallback& callback) override { | 60 const ReserveQuotaCallback& callback) override { |
| 58 EXPECT_EQ(GURL(kOrigin), origin); | 61 EXPECT_EQ(GURL(kOrigin), origin); |
| 59 EXPECT_EQ(kType, type); | 62 EXPECT_EQ(kType, type); |
| 60 on_memory_usage_ += delta; | 63 on_memory_usage_ += delta; |
| 61 base::ThreadTaskRunnerHandle::Get()->PostTask( | 64 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 62 FROM_HERE, | 65 FROM_HERE, |
| 63 base::Bind(base::IgnoreResult(callback), base::File::FILE_OK, delta)); | 66 base::Bind(base::IgnoreResult(callback), base::File::FILE_OK, delta)); |
| 64 } | 67 } |
| 65 | 68 |
| 66 void ReleaseReservedQuota(const GURL& origin, | 69 void ReleaseReservedQuota(const GURL& origin, |
| 67 storage::FileSystemType type, | 70 storage::FileSystemType type, |
| 68 int64 size) override { | 71 int64_t size) override { |
| 69 EXPECT_LE(0, size); | 72 EXPECT_LE(0, size); |
| 70 EXPECT_EQ(GURL(kOrigin), origin); | 73 EXPECT_EQ(GURL(kOrigin), origin); |
| 71 EXPECT_EQ(kType, type); | 74 EXPECT_EQ(kType, type); |
| 72 on_memory_usage_ -= size; | 75 on_memory_usage_ -= size; |
| 73 } | 76 } |
| 74 | 77 |
| 75 void CommitQuotaUsage(const GURL& origin, | 78 void CommitQuotaUsage(const GURL& origin, |
| 76 storage::FileSystemType type, | 79 storage::FileSystemType type, |
| 77 int64 delta) override { | 80 int64_t delta) override { |
| 78 EXPECT_EQ(GURL(kOrigin), origin); | 81 EXPECT_EQ(GURL(kOrigin), origin); |
| 79 EXPECT_EQ(kType, type); | 82 EXPECT_EQ(kType, type); |
| 80 on_disk_usage_ += delta; | 83 on_disk_usage_ += delta; |
| 81 on_memory_usage_ += delta; | 84 on_memory_usage_ += delta; |
| 82 } | 85 } |
| 83 | 86 |
| 84 void IncrementDirtyCount(const GURL& origin, | 87 void IncrementDirtyCount(const GURL& origin, |
| 85 storage::FileSystemType type) override {} | 88 storage::FileSystemType type) override {} |
| 86 void DecrementDirtyCount(const GURL& origin, | 89 void DecrementDirtyCount(const GURL& origin, |
| 87 storage::FileSystemType type) override {} | 90 storage::FileSystemType type) override {} |
| 88 | 91 |
| 89 int64 on_memory_usage() { return on_memory_usage_; } | 92 int64_t on_memory_usage() { return on_memory_usage_; } |
| 90 int64 on_disk_usage() { return on_disk_usage_; } | 93 int64_t on_disk_usage() { return on_disk_usage_; } |
| 91 | 94 |
| 92 private: | 95 private: |
| 93 int64 on_memory_usage_; | 96 int64_t on_memory_usage_; |
| 94 int64 on_disk_usage_; | 97 int64_t on_disk_usage_; |
| 95 | 98 |
| 96 DISALLOW_COPY_AND_ASSIGN(FakeBackend); | 99 DISALLOW_COPY_AND_ASSIGN(FakeBackend); |
| 97 }; | 100 }; |
| 98 | 101 |
| 99 class FakeWriter { | 102 class FakeWriter { |
| 100 public: | 103 public: |
| 101 explicit FakeWriter(scoped_ptr<OpenFileHandle> handle) | 104 explicit FakeWriter(scoped_ptr<OpenFileHandle> handle) |
| 102 : handle_(handle.Pass()), | 105 : handle_(handle.Pass()), |
| 103 path_(handle_->platform_path()), | 106 path_(handle_->platform_path()), |
| 104 max_written_offset_(handle_->GetEstimatedFileSize()), | 107 max_written_offset_(handle_->GetEstimatedFileSize()), |
| 105 append_mode_write_amount_(0), | 108 append_mode_write_amount_(0), |
| 106 dirty_(false) { | 109 dirty_(false) { |
| 107 } | 110 } |
| 108 | 111 |
| 109 ~FakeWriter() { | 112 ~FakeWriter() { |
| 110 if (handle_) | 113 if (handle_) |
| 111 EXPECT_FALSE(dirty_); | 114 EXPECT_FALSE(dirty_); |
| 112 } | 115 } |
| 113 | 116 |
| 114 int64 Truncate(int64 length) { | 117 int64_t Truncate(int64_t length) { |
| 115 int64 consumed = 0; | 118 int64_t consumed = 0; |
| 116 | 119 |
| 117 if (max_written_offset_ < length) { | 120 if (max_written_offset_ < length) { |
| 118 consumed = length - max_written_offset_; | 121 consumed = length - max_written_offset_; |
| 119 max_written_offset_ = length; | 122 max_written_offset_ = length; |
| 120 } | 123 } |
| 121 SetFileSize(path_, length); | 124 SetFileSize(path_, length); |
| 122 return consumed; | 125 return consumed; |
| 123 } | 126 } |
| 124 | 127 |
| 125 int64 Write(int64 max_offset) { | 128 int64_t Write(int64_t max_offset) { |
| 126 dirty_ = true; | 129 dirty_ = true; |
| 127 | 130 |
| 128 int64 consumed = 0; | 131 int64_t consumed = 0; |
| 129 if (max_written_offset_ < max_offset) { | 132 if (max_written_offset_ < max_offset) { |
| 130 consumed = max_offset - max_written_offset_; | 133 consumed = max_offset - max_written_offset_; |
| 131 max_written_offset_ = max_offset; | 134 max_written_offset_ = max_offset; |
| 132 } | 135 } |
| 133 if (GetFileSize(path_) < max_offset) | 136 if (GetFileSize(path_) < max_offset) |
| 134 SetFileSize(path_, max_offset); | 137 SetFileSize(path_, max_offset); |
| 135 return consumed; | 138 return consumed; |
| 136 } | 139 } |
| 137 | 140 |
| 138 int64 Append(int64 amount) { | 141 int64_t Append(int64_t amount) { |
| 139 dirty_ = true; | 142 dirty_ = true; |
| 140 append_mode_write_amount_ += amount; | 143 append_mode_write_amount_ += amount; |
| 141 SetFileSize(path_, GetFileSize(path_) + amount); | 144 SetFileSize(path_, GetFileSize(path_) + amount); |
| 142 return amount; | 145 return amount; |
| 143 } | 146 } |
| 144 | 147 |
| 145 void ReportUsage() { | 148 void ReportUsage() { |
| 146 handle_->UpdateMaxWrittenOffset(max_written_offset_); | 149 handle_->UpdateMaxWrittenOffset(max_written_offset_); |
| 147 handle_->AddAppendModeWriteAmount(append_mode_write_amount_); | 150 handle_->AddAppendModeWriteAmount(append_mode_write_amount_); |
| 148 max_written_offset_ = handle_->GetEstimatedFileSize(); | 151 max_written_offset_ = handle_->GetEstimatedFileSize(); |
| 149 append_mode_write_amount_ = 0; | 152 append_mode_write_amount_ = 0; |
| 150 dirty_ = false; | 153 dirty_ = false; |
| 151 } | 154 } |
| 152 | 155 |
| 153 void ClearWithoutUsageReport() { | 156 void ClearWithoutUsageReport() { |
| 154 handle_.reset(); | 157 handle_.reset(); |
| 155 } | 158 } |
| 156 | 159 |
| 157 private: | 160 private: |
| 158 scoped_ptr<OpenFileHandle> handle_; | 161 scoped_ptr<OpenFileHandle> handle_; |
| 159 base::FilePath path_; | 162 base::FilePath path_; |
| 160 int64 max_written_offset_; | 163 int64_t max_written_offset_; |
| 161 int64 append_mode_write_amount_; | 164 int64_t append_mode_write_amount_; |
| 162 bool dirty_; | 165 bool dirty_; |
| 163 }; | 166 }; |
| 164 | 167 |
| 165 void ExpectSuccess(bool* done, base::File::Error error) { | 168 void ExpectSuccess(bool* done, base::File::Error error) { |
| 166 EXPECT_FALSE(*done); | 169 EXPECT_FALSE(*done); |
| 167 *done = true; | 170 *done = true; |
| 168 EXPECT_EQ(base::File::FILE_OK, error); | 171 EXPECT_EQ(base::File::FILE_OK, error); |
| 169 } | 172 } |
| 170 | 173 |
| 171 void RefreshReservation(QuotaReservation* reservation, int64 size) { | 174 void RefreshReservation(QuotaReservation* reservation, int64_t size) { |
| 172 DCHECK(reservation); | 175 DCHECK(reservation); |
| 173 | 176 |
| 174 bool done = false; | 177 bool done = false; |
| 175 reservation->RefreshReservation(size, base::Bind(&ExpectSuccess, &done)); | 178 reservation->RefreshReservation(size, base::Bind(&ExpectSuccess, &done)); |
| 176 base::RunLoop().RunUntilIdle(); | 179 base::RunLoop().RunUntilIdle(); |
| 177 EXPECT_TRUE(done); | 180 EXPECT_TRUE(done); |
| 178 } | 181 } |
| 179 | 182 |
| 180 } // namespace | 183 } // namespace |
| 181 | 184 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 | 218 |
| 216 DISALLOW_COPY_AND_ASSIGN(QuotaReservationManagerTest); | 219 DISALLOW_COPY_AND_ASSIGN(QuotaReservationManagerTest); |
| 217 }; | 220 }; |
| 218 | 221 |
| 219 TEST_F(QuotaReservationManagerTest, BasicTest) { | 222 TEST_F(QuotaReservationManagerTest, BasicTest) { |
| 220 scoped_refptr<QuotaReservation> reservation = | 223 scoped_refptr<QuotaReservation> reservation = |
| 221 reservation_manager()->CreateReservation(GURL(kOrigin), kType); | 224 reservation_manager()->CreateReservation(GURL(kOrigin), kType); |
| 222 | 225 |
| 223 { | 226 { |
| 224 RefreshReservation(reservation.get(), 10 + 20 + 3); | 227 RefreshReservation(reservation.get(), 10 + 20 + 3); |
| 225 int64 cached_reserved_quota = reservation->remaining_quota(); | 228 int64_t cached_reserved_quota = reservation->remaining_quota(); |
| 226 FakeWriter writer(reservation->GetOpenFileHandle(file_path())); | 229 FakeWriter writer(reservation->GetOpenFileHandle(file_path())); |
| 227 | 230 |
| 228 cached_reserved_quota -= writer.Write(kInitialFileSize + 10); | 231 cached_reserved_quota -= writer.Write(kInitialFileSize + 10); |
| 229 EXPECT_LE(0, cached_reserved_quota); | 232 EXPECT_LE(0, cached_reserved_quota); |
| 230 cached_reserved_quota -= writer.Append(20); | 233 cached_reserved_quota -= writer.Append(20); |
| 231 EXPECT_LE(0, cached_reserved_quota); | 234 EXPECT_LE(0, cached_reserved_quota); |
| 232 | 235 |
| 233 writer.ReportUsage(); | 236 writer.ReportUsage(); |
| 234 } | 237 } |
| 235 | 238 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 256 | 259 |
| 257 EXPECT_EQ(3, fake_backend()->on_memory_usage()); | 260 EXPECT_EQ(3, fake_backend()->on_memory_usage()); |
| 258 } | 261 } |
| 259 | 262 |
| 260 TEST_F(QuotaReservationManagerTest, MultipleWriter) { | 263 TEST_F(QuotaReservationManagerTest, MultipleWriter) { |
| 261 scoped_refptr<QuotaReservation> reservation = | 264 scoped_refptr<QuotaReservation> reservation = |
| 262 reservation_manager()->CreateReservation(GURL(kOrigin), kType); | 265 reservation_manager()->CreateReservation(GURL(kOrigin), kType); |
| 263 | 266 |
| 264 { | 267 { |
| 265 RefreshReservation(reservation.get(), 10 + 20 + 30 + 40 + 5); | 268 RefreshReservation(reservation.get(), 10 + 20 + 30 + 40 + 5); |
| 266 int64 cached_reserved_quota = reservation->remaining_quota(); | 269 int64_t cached_reserved_quota = reservation->remaining_quota(); |
| 267 FakeWriter writer1(reservation->GetOpenFileHandle(file_path())); | 270 FakeWriter writer1(reservation->GetOpenFileHandle(file_path())); |
| 268 FakeWriter writer2(reservation->GetOpenFileHandle(file_path())); | 271 FakeWriter writer2(reservation->GetOpenFileHandle(file_path())); |
| 269 FakeWriter writer3(reservation->GetOpenFileHandle(file_path())); | 272 FakeWriter writer3(reservation->GetOpenFileHandle(file_path())); |
| 270 | 273 |
| 271 cached_reserved_quota -= writer1.Write(kInitialFileSize + 10); | 274 cached_reserved_quota -= writer1.Write(kInitialFileSize + 10); |
| 272 EXPECT_LE(0, cached_reserved_quota); | 275 EXPECT_LE(0, cached_reserved_quota); |
| 273 cached_reserved_quota -= writer2.Write(kInitialFileSize + 20); | 276 cached_reserved_quota -= writer2.Write(kInitialFileSize + 20); |
| 274 cached_reserved_quota -= writer3.Append(30); | 277 cached_reserved_quota -= writer3.Append(30); |
| 275 EXPECT_LE(0, cached_reserved_quota); | 278 EXPECT_LE(0, cached_reserved_quota); |
| 276 cached_reserved_quota -= writer3.Append(40); | 279 cached_reserved_quota -= writer3.Append(40); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 288 | 291 |
| 289 reservation = NULL; | 292 reservation = NULL; |
| 290 | 293 |
| 291 EXPECT_EQ(kInitialFileSize + 20 + 30 + 40, fake_backend()->on_disk_usage()); | 294 EXPECT_EQ(kInitialFileSize + 20 + 30 + 40, fake_backend()->on_disk_usage()); |
| 292 } | 295 } |
| 293 | 296 |
| 294 TEST_F(QuotaReservationManagerTest, MultipleClient) { | 297 TEST_F(QuotaReservationManagerTest, MultipleClient) { |
| 295 scoped_refptr<QuotaReservation> reservation1 = | 298 scoped_refptr<QuotaReservation> reservation1 = |
| 296 reservation_manager()->CreateReservation(GURL(kOrigin), kType); | 299 reservation_manager()->CreateReservation(GURL(kOrigin), kType); |
| 297 RefreshReservation(reservation1.get(), 10); | 300 RefreshReservation(reservation1.get(), 10); |
| 298 int64 cached_reserved_quota1 = reservation1->remaining_quota(); | 301 int64_t cached_reserved_quota1 = reservation1->remaining_quota(); |
| 299 | 302 |
| 300 scoped_refptr<QuotaReservation> reservation2 = | 303 scoped_refptr<QuotaReservation> reservation2 = |
| 301 reservation_manager()->CreateReservation(GURL(kOrigin), kType); | 304 reservation_manager()->CreateReservation(GURL(kOrigin), kType); |
| 302 RefreshReservation(reservation2.get(), 20); | 305 RefreshReservation(reservation2.get(), 20); |
| 303 int64 cached_reserved_quota2 = reservation2->remaining_quota(); | 306 int64_t cached_reserved_quota2 = reservation2->remaining_quota(); |
| 304 | 307 |
| 305 scoped_ptr<FakeWriter> writer1( | 308 scoped_ptr<FakeWriter> writer1( |
| 306 new FakeWriter(reservation1->GetOpenFileHandle(file_path()))); | 309 new FakeWriter(reservation1->GetOpenFileHandle(file_path()))); |
| 307 | 310 |
| 308 scoped_ptr<FakeWriter> writer2( | 311 scoped_ptr<FakeWriter> writer2( |
| 309 new FakeWriter(reservation2->GetOpenFileHandle(file_path()))); | 312 new FakeWriter(reservation2->GetOpenFileHandle(file_path()))); |
| 310 | 313 |
| 311 cached_reserved_quota1 -= writer1->Write(kInitialFileSize + 10); | 314 cached_reserved_quota1 -= writer1->Write(kInitialFileSize + 10); |
| 312 EXPECT_LE(0, cached_reserved_quota1); | 315 EXPECT_LE(0, cached_reserved_quota1); |
| 313 | 316 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 | 361 |
| 359 EXPECT_EQ(kInitialFileSize + 10, GetFileSize(file_path())); | 362 EXPECT_EQ(kInitialFileSize + 10, GetFileSize(file_path())); |
| 360 EXPECT_EQ(kInitialFileSize + 15 + 20, fake_backend()->on_memory_usage()); | 363 EXPECT_EQ(kInitialFileSize + 15 + 20, fake_backend()->on_memory_usage()); |
| 361 EXPECT_EQ(kInitialFileSize + 10, fake_backend()->on_disk_usage()); | 364 EXPECT_EQ(kInitialFileSize + 10, fake_backend()->on_disk_usage()); |
| 362 | 365 |
| 363 reservation2 = NULL; | 366 reservation2 = NULL; |
| 364 EXPECT_EQ(kInitialFileSize + 10, fake_backend()->on_memory_usage()); | 367 EXPECT_EQ(kInitialFileSize + 10, fake_backend()->on_memory_usage()); |
| 365 } | 368 } |
| 366 | 369 |
| 367 } // namespace content | 370 } // namespace content |
| OLD | NEW |