OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2014 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 <set> |
| 6 |
| 7 #include "base/test/test_simple_task_runner.h" |
| 8 #include "content/browser/indexed_db/indexed_db_active_blob_registry.h" |
| 9 #include "content/browser/indexed_db/indexed_db_backing_store.h" |
| 10 #include "content/browser/indexed_db/indexed_db_factory.h" |
| 11 #include "content/browser/indexed_db/indexed_db_fake_backing_store.h" |
| 12 #include "testing/gtest/include/gtest/gtest.h" |
| 13 |
| 14 namespace content { |
| 15 |
| 16 namespace { |
| 17 |
| 18 class MockIDBFactory : public IndexedDBFactory { |
| 19 public: |
| 20 MockIDBFactory() : IndexedDBFactory(NULL), duplicate_calls_(false) {} |
| 21 |
| 22 virtual void ReportOutstandingBlobs(const GURL& origin_url, |
| 23 bool blobs_outstanding) OVERRIDE { |
| 24 if (blobs_outstanding) { |
| 25 if (origins_.count(origin_url)) { |
| 26 duplicate_calls_ = true; |
| 27 } else { |
| 28 origins_.insert(origin_url); |
| 29 } |
| 30 } else { |
| 31 if (!origins_.count(origin_url)) { |
| 32 duplicate_calls_ = true; |
| 33 } else { |
| 34 origins_.erase(origin_url); |
| 35 } |
| 36 } |
| 37 } |
| 38 |
| 39 bool CheckNoOriginsInUse() const { |
| 40 return !duplicate_calls_ && !origins_.size(); |
| 41 } |
| 42 bool CheckSingleOriginInUse(const GURL& origin) const { |
| 43 return !duplicate_calls_ && origins_.size() == 1 && origins_.count(origin); |
| 44 } |
| 45 |
| 46 protected: |
| 47 virtual ~MockIDBFactory() {} |
| 48 |
| 49 private: |
| 50 std::set<GURL> origins_; |
| 51 bool duplicate_calls_; |
| 52 }; |
| 53 |
| 54 class MockIDBBackingStore : public IndexedDBFakeBackingStore { |
| 55 public: |
| 56 MockIDBBackingStore(IndexedDBFactory* factory, base::TaskRunner* task_runner) |
| 57 : IndexedDBFakeBackingStore(factory, task_runner), |
| 58 duplicate_calls_(false) {} |
| 59 |
| 60 virtual void ReportBlobUnused(int64 database_id, int64 blob_key) OVERRIDE { |
| 61 unused_blobs_.insert(std::make_pair(database_id, blob_key)); |
| 62 } |
| 63 |
| 64 typedef std::pair<int64, int64> KeyPair; |
| 65 typedef std::set<KeyPair> KeyPairSet; |
| 66 bool CheckUnusedBlobsEmpty() const { |
| 67 return !duplicate_calls_ && !unused_blobs_.size(); |
| 68 } |
| 69 bool CheckSingleUnusedBlob(int64 database_id, int64 blob_key) const { |
| 70 return !duplicate_calls_ && unused_blobs_.size() == 1 && |
| 71 unused_blobs_.count(std::make_pair(database_id, blob_key)); |
| 72 } |
| 73 |
| 74 const KeyPairSet& unused_blobs() const { return unused_blobs_; } |
| 75 |
| 76 protected: |
| 77 virtual ~MockIDBBackingStore() {} |
| 78 |
| 79 private: |
| 80 KeyPairSet unused_blobs_; |
| 81 bool duplicate_calls_; |
| 82 }; |
| 83 |
| 84 // Base class for our test fixtures. |
| 85 class IndexedDBActiveBlobRegistryTest : public testing::Test { |
| 86 public: |
| 87 IndexedDBActiveBlobRegistryTest() |
| 88 : task_runner_(new base::TestSimpleTaskRunner), |
| 89 factory_(new MockIDBFactory), |
| 90 backing_store_(new MockIDBBackingStore(factory_, task_runner_)), |
| 91 registry_(new IndexedDBActiveBlobRegistry(backing_store_.get())) {} |
| 92 |
| 93 void RunUntilIdle() { task_runner_->RunUntilIdle(); } |
| 94 MockIDBFactory* factory() const { return factory_.get(); } |
| 95 MockIDBBackingStore* backing_store() const { return backing_store_.get(); } |
| 96 IndexedDBActiveBlobRegistry* registry() const { return registry_.get(); } |
| 97 |
| 98 static const int64 kDatabaseId0 = 7; |
| 99 static const int64 kDatabaseId1 = 12; |
| 100 static const int64 kBlobKey0 = 77; |
| 101 static const int64 kBlobKey1 = 14; |
| 102 |
| 103 typedef webkit_blob::ShareableFileReference::FinalReleaseCallback |
| 104 ReleaseCallback; |
| 105 |
| 106 private: |
| 107 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; |
| 108 scoped_refptr<MockIDBFactory> factory_; |
| 109 scoped_refptr<MockIDBBackingStore> backing_store_; |
| 110 scoped_ptr<IndexedDBActiveBlobRegistry> registry_; |
| 111 |
| 112 DISALLOW_COPY_AND_ASSIGN(IndexedDBActiveBlobRegistryTest); |
| 113 }; |
| 114 |
| 115 TEST_F(IndexedDBActiveBlobRegistryTest, DeleteUnused) { |
| 116 EXPECT_TRUE(factory()->CheckNoOriginsInUse()); |
| 117 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); |
| 118 |
| 119 EXPECT_FALSE(registry()->MarkDeletedCheckIfUsed(kDatabaseId0, kBlobKey0)); |
| 120 RunUntilIdle(); |
| 121 |
| 122 EXPECT_TRUE(factory()->CheckNoOriginsInUse()); |
| 123 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); |
| 124 } |
| 125 |
| 126 TEST_F(IndexedDBActiveBlobRegistryTest, SimpleUse) { |
| 127 EXPECT_TRUE(factory()->CheckNoOriginsInUse()); |
| 128 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); |
| 129 |
| 130 base::Closure add_ref = |
| 131 registry()->GetAddBlobRefCallback(kDatabaseId0, kBlobKey0); |
| 132 ReleaseCallback release = |
| 133 registry()->GetFinalReleaseCallback(kDatabaseId0, kBlobKey0); |
| 134 add_ref.Run(); |
| 135 RunUntilIdle(); |
| 136 |
| 137 EXPECT_TRUE(factory()->CheckSingleOriginInUse(backing_store()->origin_url())); |
| 138 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); |
| 139 |
| 140 release.Run(base::FilePath()); |
| 141 RunUntilIdle(); |
| 142 |
| 143 EXPECT_TRUE(factory()->CheckNoOriginsInUse()); |
| 144 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); |
| 145 } |
| 146 |
| 147 TEST_F(IndexedDBActiveBlobRegistryTest, DeleteWhileInUse) { |
| 148 EXPECT_TRUE(factory()->CheckNoOriginsInUse()); |
| 149 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); |
| 150 |
| 151 base::Closure add_ref = |
| 152 registry()->GetAddBlobRefCallback(kDatabaseId0, kBlobKey0); |
| 153 ReleaseCallback release = |
| 154 registry()->GetFinalReleaseCallback(kDatabaseId0, kBlobKey0); |
| 155 |
| 156 add_ref.Run(); |
| 157 RunUntilIdle(); |
| 158 |
| 159 EXPECT_TRUE(factory()->CheckSingleOriginInUse(backing_store()->origin_url())); |
| 160 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); |
| 161 |
| 162 EXPECT_TRUE(registry()->MarkDeletedCheckIfUsed(kDatabaseId0, kBlobKey0)); |
| 163 RunUntilIdle(); |
| 164 |
| 165 EXPECT_TRUE(factory()->CheckSingleOriginInUse(backing_store()->origin_url())); |
| 166 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); |
| 167 |
| 168 release.Run(base::FilePath()); |
| 169 RunUntilIdle(); |
| 170 |
| 171 EXPECT_TRUE(factory()->CheckNoOriginsInUse()); |
| 172 EXPECT_TRUE(backing_store()->CheckSingleUnusedBlob(kDatabaseId0, kBlobKey0)); |
| 173 } |
| 174 |
| 175 TEST_F(IndexedDBActiveBlobRegistryTest, MultipleBlobs) { |
| 176 EXPECT_TRUE(factory()->CheckNoOriginsInUse()); |
| 177 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); |
| 178 |
| 179 base::Closure add_ref_00 = |
| 180 registry()->GetAddBlobRefCallback(kDatabaseId0, kBlobKey0); |
| 181 ReleaseCallback release_00 = |
| 182 registry()->GetFinalReleaseCallback(kDatabaseId0, kBlobKey0); |
| 183 base::Closure add_ref_01 = |
| 184 registry()->GetAddBlobRefCallback(kDatabaseId0, kBlobKey1); |
| 185 ReleaseCallback release_01 = |
| 186 registry()->GetFinalReleaseCallback(kDatabaseId0, kBlobKey1); |
| 187 base::Closure add_ref_10 = |
| 188 registry()->GetAddBlobRefCallback(kDatabaseId1, kBlobKey0); |
| 189 ReleaseCallback release_10 = |
| 190 registry()->GetFinalReleaseCallback(kDatabaseId1, kBlobKey0); |
| 191 base::Closure add_ref_11 = |
| 192 registry()->GetAddBlobRefCallback(kDatabaseId1, kBlobKey1); |
| 193 ReleaseCallback release_11 = |
| 194 registry()->GetFinalReleaseCallback(kDatabaseId1, kBlobKey1); |
| 195 |
| 196 add_ref_00.Run(); |
| 197 add_ref_01.Run(); |
| 198 RunUntilIdle(); |
| 199 |
| 200 EXPECT_TRUE(factory()->CheckSingleOriginInUse(backing_store()->origin_url())); |
| 201 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); |
| 202 |
| 203 release_00.Run(base::FilePath()); |
| 204 add_ref_10.Run(); |
| 205 add_ref_11.Run(); |
| 206 RunUntilIdle(); |
| 207 |
| 208 EXPECT_TRUE(factory()->CheckSingleOriginInUse(backing_store()->origin_url())); |
| 209 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); |
| 210 |
| 211 EXPECT_TRUE(registry()->MarkDeletedCheckIfUsed(kDatabaseId0, kBlobKey1)); |
| 212 RunUntilIdle(); |
| 213 |
| 214 EXPECT_TRUE(factory()->CheckSingleOriginInUse(backing_store()->origin_url())); |
| 215 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); |
| 216 |
| 217 release_01.Run(base::FilePath()); |
| 218 release_11.Run(base::FilePath()); |
| 219 RunUntilIdle(); |
| 220 |
| 221 EXPECT_TRUE(factory()->CheckSingleOriginInUse(backing_store()->origin_url())); |
| 222 EXPECT_TRUE(backing_store()->CheckSingleUnusedBlob(kDatabaseId0, kBlobKey1)); |
| 223 |
| 224 release_10.Run(base::FilePath()); |
| 225 RunUntilIdle(); |
| 226 |
| 227 EXPECT_TRUE(factory()->CheckNoOriginsInUse()); |
| 228 EXPECT_TRUE(backing_store()->CheckSingleUnusedBlob(kDatabaseId0, kBlobKey1)); |
| 229 } |
| 230 |
| 231 TEST_F(IndexedDBActiveBlobRegistryTest, ForceShutdown) { |
| 232 EXPECT_TRUE(factory()->CheckNoOriginsInUse()); |
| 233 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); |
| 234 |
| 235 base::Closure add_ref_0 = |
| 236 registry()->GetAddBlobRefCallback(kDatabaseId0, kBlobKey0); |
| 237 ReleaseCallback release_0 = |
| 238 registry()->GetFinalReleaseCallback(kDatabaseId0, kBlobKey0); |
| 239 base::Closure add_ref_1 = |
| 240 registry()->GetAddBlobRefCallback(kDatabaseId0, kBlobKey1); |
| 241 ReleaseCallback release_1 = |
| 242 registry()->GetFinalReleaseCallback(kDatabaseId0, kBlobKey1); |
| 243 |
| 244 add_ref_0.Run(); |
| 245 RunUntilIdle(); |
| 246 |
| 247 EXPECT_TRUE(factory()->CheckSingleOriginInUse(backing_store()->origin_url())); |
| 248 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); |
| 249 |
| 250 registry()->ForceShutdown(); |
| 251 |
| 252 add_ref_1.Run(); |
| 253 RunUntilIdle(); |
| 254 |
| 255 // Nothing changes. |
| 256 EXPECT_TRUE(factory()->CheckSingleOriginInUse(backing_store()->origin_url())); |
| 257 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); |
| 258 |
| 259 release_0.Run(base::FilePath()); |
| 260 release_1.Run(base::FilePath()); |
| 261 RunUntilIdle(); |
| 262 |
| 263 // Nothing changes. |
| 264 EXPECT_TRUE(factory()->CheckSingleOriginInUse(backing_store()->origin_url())); |
| 265 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); |
| 266 } |
| 267 |
| 268 } // namespace |
| 269 |
| 270 } // namespace content |
OLD | NEW |