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
3 // found in the LICENSE file.
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_fake_backing_store.h"
11 #include "content/browser/indexed_db/mock_indexed_db_factory.h"
12 #include "testing/gtest/include/gtest/gtest.h"
18 class RegistryTestMockFactory
: public MockIndexedDBFactory
{
20 RegistryTestMockFactory() : duplicate_calls_(false) {}
22 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;
28 origins_
.insert(origin_url
);
31 if (!origins_
.count(origin_url
)) {
32 duplicate_calls_
= true;
34 origins_
.erase(origin_url
);
39 bool CheckNoOriginsInUse() const {
40 return !duplicate_calls_
&& !origins_
.size();
43 bool CheckSingleOriginInUse(const GURL
& origin
) const {
44 return !duplicate_calls_
&& origins_
.size() == 1 && origins_
.count(origin
);
48 ~RegistryTestMockFactory() override
{}
50 std::set
<GURL
> origins_
;
51 bool duplicate_calls_
;
53 DISALLOW_COPY_AND_ASSIGN(RegistryTestMockFactory
);
56 class MockIDBBackingStore
: public IndexedDBFakeBackingStore
{
58 typedef std::pair
<int64
, int64
> KeyPair
;
59 typedef std::set
<KeyPair
> KeyPairSet
;
61 MockIDBBackingStore(IndexedDBFactory
* factory
,
62 base::SequencedTaskRunner
* task_runner
)
63 : IndexedDBFakeBackingStore(factory
, task_runner
),
64 duplicate_calls_(false) {}
66 void ReportBlobUnused(int64 database_id
, int64 blob_key
) override
{
67 unused_blobs_
.insert(std::make_pair(database_id
, blob_key
));
70 bool CheckUnusedBlobsEmpty() const {
71 return !duplicate_calls_
&& !unused_blobs_
.size();
73 bool CheckSingleUnusedBlob(int64 database_id
, int64 blob_key
) const {
74 return !duplicate_calls_
&& unused_blobs_
.size() == 1 &&
75 unused_blobs_
.count(std::make_pair(database_id
, blob_key
));
78 const KeyPairSet
& unused_blobs() const { return unused_blobs_
; }
81 ~MockIDBBackingStore() override
{}
84 KeyPairSet unused_blobs_
;
85 bool duplicate_calls_
;
87 DISALLOW_COPY_AND_ASSIGN(MockIDBBackingStore
);
90 // Base class for our test fixtures.
91 class IndexedDBActiveBlobRegistryTest
: public testing::Test
{
93 typedef storage::ShareableFileReference::FinalReleaseCallback
96 static const int64 kDatabaseId0
= 7;
97 static const int64 kDatabaseId1
= 12;
98 static const int64 kBlobKey0
= 77;
99 static const int64 kBlobKey1
= 14;
101 IndexedDBActiveBlobRegistryTest()
102 : task_runner_(new base::TestSimpleTaskRunner
),
103 factory_(new RegistryTestMockFactory
),
105 new MockIDBBackingStore(factory_
.get(), task_runner_
.get())),
106 registry_(new IndexedDBActiveBlobRegistry(backing_store_
.get())) {}
108 void RunUntilIdle() { task_runner_
->RunUntilIdle(); }
109 RegistryTestMockFactory
* factory() const { return factory_
.get(); }
110 MockIDBBackingStore
* backing_store() const { return backing_store_
.get(); }
111 IndexedDBActiveBlobRegistry
* registry() const { return registry_
.get(); }
114 scoped_refptr
<base::TestSimpleTaskRunner
> task_runner_
;
115 scoped_refptr
<RegistryTestMockFactory
> factory_
;
116 scoped_refptr
<MockIDBBackingStore
> backing_store_
;
117 scoped_ptr
<IndexedDBActiveBlobRegistry
> registry_
;
119 DISALLOW_COPY_AND_ASSIGN(IndexedDBActiveBlobRegistryTest
);
122 TEST_F(IndexedDBActiveBlobRegistryTest
, DeleteUnused
) {
123 EXPECT_TRUE(factory()->CheckNoOriginsInUse());
124 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty());
126 EXPECT_FALSE(registry()->MarkDeletedCheckIfUsed(kDatabaseId0
, kBlobKey0
));
129 EXPECT_TRUE(factory()->CheckNoOriginsInUse());
130 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty());
133 TEST_F(IndexedDBActiveBlobRegistryTest
, SimpleUse
) {
134 EXPECT_TRUE(factory()->CheckNoOriginsInUse());
135 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty());
137 base::Closure add_ref
=
138 registry()->GetAddBlobRefCallback(kDatabaseId0
, kBlobKey0
);
139 ReleaseCallback release
=
140 registry()->GetFinalReleaseCallback(kDatabaseId0
, kBlobKey0
);
144 EXPECT_TRUE(factory()->CheckSingleOriginInUse(backing_store()->origin_url()));
145 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty());
147 release
.Run(base::FilePath());
150 EXPECT_TRUE(factory()->CheckNoOriginsInUse());
151 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty());
154 TEST_F(IndexedDBActiveBlobRegistryTest
, DeleteWhileInUse
) {
155 EXPECT_TRUE(factory()->CheckNoOriginsInUse());
156 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty());
158 base::Closure add_ref
=
159 registry()->GetAddBlobRefCallback(kDatabaseId0
, kBlobKey0
);
160 ReleaseCallback release
=
161 registry()->GetFinalReleaseCallback(kDatabaseId0
, kBlobKey0
);
166 EXPECT_TRUE(factory()->CheckSingleOriginInUse(backing_store()->origin_url()));
167 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty());
169 EXPECT_TRUE(registry()->MarkDeletedCheckIfUsed(kDatabaseId0
, kBlobKey0
));
172 EXPECT_TRUE(factory()->CheckSingleOriginInUse(backing_store()->origin_url()));
173 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty());
175 release
.Run(base::FilePath());
178 EXPECT_TRUE(factory()->CheckNoOriginsInUse());
179 EXPECT_TRUE(backing_store()->CheckSingleUnusedBlob(kDatabaseId0
, kBlobKey0
));
182 TEST_F(IndexedDBActiveBlobRegistryTest
, MultipleBlobs
) {
183 EXPECT_TRUE(factory()->CheckNoOriginsInUse());
184 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty());
186 base::Closure add_ref_00
=
187 registry()->GetAddBlobRefCallback(kDatabaseId0
, kBlobKey0
);
188 ReleaseCallback release_00
=
189 registry()->GetFinalReleaseCallback(kDatabaseId0
, kBlobKey0
);
190 base::Closure add_ref_01
=
191 registry()->GetAddBlobRefCallback(kDatabaseId0
, kBlobKey1
);
192 ReleaseCallback release_01
=
193 registry()->GetFinalReleaseCallback(kDatabaseId0
, kBlobKey1
);
194 base::Closure add_ref_10
=
195 registry()->GetAddBlobRefCallback(kDatabaseId1
, kBlobKey0
);
196 ReleaseCallback release_10
=
197 registry()->GetFinalReleaseCallback(kDatabaseId1
, kBlobKey0
);
198 base::Closure add_ref_11
=
199 registry()->GetAddBlobRefCallback(kDatabaseId1
, kBlobKey1
);
200 ReleaseCallback release_11
=
201 registry()->GetFinalReleaseCallback(kDatabaseId1
, kBlobKey1
);
207 EXPECT_TRUE(factory()->CheckSingleOriginInUse(backing_store()->origin_url()));
208 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty());
210 release_00
.Run(base::FilePath());
215 EXPECT_TRUE(factory()->CheckSingleOriginInUse(backing_store()->origin_url()));
216 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty());
218 EXPECT_TRUE(registry()->MarkDeletedCheckIfUsed(kDatabaseId0
, kBlobKey1
));
221 EXPECT_TRUE(factory()->CheckSingleOriginInUse(backing_store()->origin_url()));
222 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty());
224 release_01
.Run(base::FilePath());
225 release_11
.Run(base::FilePath());
228 EXPECT_TRUE(factory()->CheckSingleOriginInUse(backing_store()->origin_url()));
229 EXPECT_TRUE(backing_store()->CheckSingleUnusedBlob(kDatabaseId0
, kBlobKey1
));
231 release_10
.Run(base::FilePath());
234 EXPECT_TRUE(factory()->CheckNoOriginsInUse());
235 EXPECT_TRUE(backing_store()->CheckSingleUnusedBlob(kDatabaseId0
, kBlobKey1
));
238 TEST_F(IndexedDBActiveBlobRegistryTest
, ForceShutdown
) {
239 EXPECT_TRUE(factory()->CheckNoOriginsInUse());
240 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty());
242 base::Closure add_ref_0
=
243 registry()->GetAddBlobRefCallback(kDatabaseId0
, kBlobKey0
);
244 ReleaseCallback release_0
=
245 registry()->GetFinalReleaseCallback(kDatabaseId0
, kBlobKey0
);
246 base::Closure add_ref_1
=
247 registry()->GetAddBlobRefCallback(kDatabaseId0
, kBlobKey1
);
248 ReleaseCallback release_1
=
249 registry()->GetFinalReleaseCallback(kDatabaseId0
, kBlobKey1
);
254 EXPECT_TRUE(factory()->CheckSingleOriginInUse(backing_store()->origin_url()));
255 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty());
257 registry()->ForceShutdown();
263 EXPECT_TRUE(factory()->CheckSingleOriginInUse(backing_store()->origin_url()));
264 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty());
266 release_0
.Run(base::FilePath());
267 release_1
.Run(base::FilePath());
271 EXPECT_TRUE(factory()->CheckSingleOriginInUse(backing_store()->origin_url()));
272 EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty());
277 } // namespace content