OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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 "base/bind.h" | |
6 #include "base/file_util.h" | |
7 #include "base/files/scoped_temp_dir.h" | |
8 #include "base/message_loop/message_loop.h" | |
9 #include "base/message_loop/message_loop_proxy.h" | |
10 #include "base/strings/utf_string_conversions.h" | |
11 #include "base/threading/sequenced_worker_pool.h" | |
12 #include "base/time/time.h" | |
13 #include "testing/gtest/include/gtest/gtest.h" | |
14 #include "webkit/browser/dom_storage/dom_storage_area.h" | |
15 #include "webkit/browser/dom_storage/dom_storage_context.h" | |
16 #include "webkit/browser/dom_storage/dom_storage_namespace.h" | |
17 #include "webkit/browser/dom_storage/dom_storage_task_runner.h" | |
18 #include "webkit/browser/quota/mock_special_storage_policy.h" | |
19 #include "webkit/common/dom_storage/dom_storage_types.h" | |
20 | |
21 namespace dom_storage { | |
22 | |
23 class DomStorageContextTest : public testing::Test { | |
24 public: | |
25 DomStorageContextTest() | |
26 : kOrigin(GURL("http://dom_storage/")), | |
27 kKey(ASCIIToUTF16("key")), | |
28 kValue(ASCIIToUTF16("value")), | |
29 kDontIncludeFileInfo(false), | |
30 kDoIncludeFileInfo(true) { | |
31 } | |
32 | |
33 const GURL kOrigin; | |
34 const base::string16 kKey; | |
35 const base::string16 kValue; | |
36 const bool kDontIncludeFileInfo; | |
37 const bool kDoIncludeFileInfo; | |
38 | |
39 virtual void SetUp() { | |
40 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | |
41 storage_policy_ = new quota::MockSpecialStoragePolicy; | |
42 task_runner_ = | |
43 new MockDomStorageTaskRunner(base::MessageLoopProxy::current().get()); | |
44 context_ = new DomStorageContext(temp_dir_.path(), | |
45 base::FilePath(), | |
46 storage_policy_.get(), | |
47 task_runner_.get()); | |
48 } | |
49 | |
50 virtual void TearDown() { | |
51 base::MessageLoop::current()->RunUntilIdle(); | |
52 } | |
53 | |
54 void VerifySingleOriginRemains(const GURL& origin) { | |
55 // Use a new instance to examine the contexts of temp_dir_. | |
56 scoped_refptr<DomStorageContext> context = | |
57 new DomStorageContext(temp_dir_.path(), base::FilePath(), NULL, NULL); | |
58 std::vector<LocalStorageUsageInfo> infos; | |
59 context->GetLocalStorageUsage(&infos, kDontIncludeFileInfo); | |
60 ASSERT_EQ(1u, infos.size()); | |
61 EXPECT_EQ(origin, infos[0].origin); | |
62 } | |
63 | |
64 protected: | |
65 base::MessageLoop message_loop_; | |
66 base::ScopedTempDir temp_dir_; | |
67 scoped_refptr<quota::MockSpecialStoragePolicy> storage_policy_; | |
68 scoped_refptr<MockDomStorageTaskRunner> task_runner_; | |
69 scoped_refptr<DomStorageContext> context_; | |
70 DISALLOW_COPY_AND_ASSIGN(DomStorageContextTest); | |
71 }; | |
72 | |
73 TEST_F(DomStorageContextTest, Basics) { | |
74 // This test doesn't do much, checks that the constructor | |
75 // initializes members properly and that invoking methods | |
76 // on a newly created object w/o any data on disk do no harm. | |
77 EXPECT_EQ(temp_dir_.path(), context_->localstorage_directory()); | |
78 EXPECT_EQ(base::FilePath(), context_->sessionstorage_directory()); | |
79 EXPECT_EQ(storage_policy_.get(), context_->special_storage_policy_.get()); | |
80 context_->PurgeMemory(); | |
81 context_->DeleteLocalStorage(GURL("http://chromium.org/")); | |
82 const int kFirstSessionStorageNamespaceId = 1; | |
83 EXPECT_TRUE(context_->GetStorageNamespace(kLocalStorageNamespaceId)); | |
84 EXPECT_FALSE(context_->GetStorageNamespace(kFirstSessionStorageNamespaceId)); | |
85 EXPECT_EQ(kFirstSessionStorageNamespaceId, context_->AllocateSessionId()); | |
86 std::vector<LocalStorageUsageInfo> infos; | |
87 context_->GetLocalStorageUsage(&infos, kDontIncludeFileInfo); | |
88 EXPECT_TRUE(infos.empty()); | |
89 context_->Shutdown(); | |
90 } | |
91 | |
92 TEST_F(DomStorageContextTest, UsageInfo) { | |
93 // Should be empty initially | |
94 std::vector<LocalStorageUsageInfo> infos; | |
95 context_->GetLocalStorageUsage(&infos, kDontIncludeFileInfo); | |
96 EXPECT_TRUE(infos.empty()); | |
97 context_->GetLocalStorageUsage(&infos, kDoIncludeFileInfo); | |
98 EXPECT_TRUE(infos.empty()); | |
99 | |
100 // Put some data into local storage and shutdown the context | |
101 // to ensure data is written to disk. | |
102 base::NullableString16 old_value; | |
103 EXPECT_TRUE(context_->GetStorageNamespace(kLocalStorageNamespaceId)-> | |
104 OpenStorageArea(kOrigin)->SetItem(kKey, kValue, &old_value)); | |
105 context_->Shutdown(); | |
106 context_ = NULL; | |
107 base::MessageLoop::current()->RunUntilIdle(); | |
108 | |
109 // Create a new context that points to the same directory, see that | |
110 // it knows about the origin that we stored data for. | |
111 context_ = new DomStorageContext(temp_dir_.path(), base::FilePath(), NULL, NUL
L); | |
112 context_->GetLocalStorageUsage(&infos, kDontIncludeFileInfo); | |
113 EXPECT_EQ(1u, infos.size()); | |
114 EXPECT_EQ(kOrigin, infos[0].origin); | |
115 EXPECT_EQ(0u, infos[0].data_size); | |
116 EXPECT_EQ(base::Time(), infos[0].last_modified); | |
117 infos.clear(); | |
118 context_->GetLocalStorageUsage(&infos, kDoIncludeFileInfo); | |
119 EXPECT_EQ(1u, infos.size()); | |
120 EXPECT_EQ(kOrigin, infos[0].origin); | |
121 EXPECT_NE(0u, infos[0].data_size); | |
122 EXPECT_NE(base::Time(), infos[0].last_modified); | |
123 } | |
124 | |
125 TEST_F(DomStorageContextTest, SessionOnly) { | |
126 const GURL kSessionOnlyOrigin("http://www.sessiononly.com/"); | |
127 storage_policy_->AddSessionOnly(kSessionOnlyOrigin); | |
128 | |
129 // Store data for a normal and a session-only origin and then | |
130 // invoke Shutdown() which should delete data for session-only | |
131 // origins. | |
132 base::NullableString16 old_value; | |
133 EXPECT_TRUE(context_->GetStorageNamespace(kLocalStorageNamespaceId)-> | |
134 OpenStorageArea(kOrigin)->SetItem(kKey, kValue, &old_value)); | |
135 EXPECT_TRUE(context_->GetStorageNamespace(kLocalStorageNamespaceId)-> | |
136 OpenStorageArea(kSessionOnlyOrigin)->SetItem(kKey, kValue, &old_value)); | |
137 context_->Shutdown(); | |
138 context_ = NULL; | |
139 base::MessageLoop::current()->RunUntilIdle(); | |
140 | |
141 // Verify that the session-only origin data is gone. | |
142 VerifySingleOriginRemains(kOrigin); | |
143 } | |
144 | |
145 TEST_F(DomStorageContextTest, SetForceKeepSessionState) { | |
146 const GURL kSessionOnlyOrigin("http://www.sessiononly.com/"); | |
147 storage_policy_->AddSessionOnly(kSessionOnlyOrigin); | |
148 | |
149 // Store data for a session-only origin, setup to save session data, then | |
150 // shutdown. | |
151 base::NullableString16 old_value; | |
152 EXPECT_TRUE(context_->GetStorageNamespace(kLocalStorageNamespaceId)-> | |
153 OpenStorageArea(kSessionOnlyOrigin)->SetItem(kKey, kValue, &old_value)); | |
154 context_->SetForceKeepSessionState(); // Should override clear behavior. | |
155 context_->Shutdown(); | |
156 context_ = NULL; | |
157 base::MessageLoop::current()->RunUntilIdle(); | |
158 | |
159 VerifySingleOriginRemains(kSessionOnlyOrigin); | |
160 } | |
161 | |
162 TEST_F(DomStorageContextTest, PersistentIds) { | |
163 const int kFirstSessionStorageNamespaceId = 1; | |
164 const std::string kPersistentId = "persistent"; | |
165 context_->CreateSessionNamespace(kFirstSessionStorageNamespaceId, | |
166 kPersistentId); | |
167 DomStorageNamespace* dom_namespace = | |
168 context_->GetStorageNamespace(kFirstSessionStorageNamespaceId); | |
169 ASSERT_TRUE(dom_namespace); | |
170 EXPECT_EQ(kPersistentId, dom_namespace->persistent_namespace_id()); | |
171 // Verify that the areas inherit the persistent ID. | |
172 DomStorageArea* area = dom_namespace->OpenStorageArea(kOrigin); | |
173 EXPECT_EQ(kPersistentId, area->persistent_namespace_id_); | |
174 | |
175 // Verify that the persistent IDs are handled correctly when cloning. | |
176 const int kClonedSessionStorageNamespaceId = 2; | |
177 const std::string kClonedPersistentId = "cloned"; | |
178 context_->CloneSessionNamespace(kFirstSessionStorageNamespaceId, | |
179 kClonedSessionStorageNamespaceId, | |
180 kClonedPersistentId); | |
181 DomStorageNamespace* cloned_dom_namespace = | |
182 context_->GetStorageNamespace(kClonedSessionStorageNamespaceId); | |
183 ASSERT_TRUE(dom_namespace); | |
184 EXPECT_EQ(kClonedPersistentId, | |
185 cloned_dom_namespace->persistent_namespace_id()); | |
186 // Verify that the areas inherit the persistent ID. | |
187 DomStorageArea* cloned_area = cloned_dom_namespace->OpenStorageArea(kOrigin); | |
188 EXPECT_EQ(kClonedPersistentId, cloned_area->persistent_namespace_id_); | |
189 } | |
190 | |
191 TEST_F(DomStorageContextTest, DeleteSessionStorage) { | |
192 // Create a DomStorageContext which will save sessionStorage on disk. | |
193 context_ = new DomStorageContext(temp_dir_.path(), | |
194 temp_dir_.path(), | |
195 storage_policy_.get(), | |
196 task_runner_.get()); | |
197 context_->SetSaveSessionStorageOnDisk(); | |
198 ASSERT_EQ(temp_dir_.path(), context_->sessionstorage_directory()); | |
199 | |
200 // Write data. | |
201 const int kSessionStorageNamespaceId = 1; | |
202 const std::string kPersistentId = "persistent"; | |
203 context_->CreateSessionNamespace(kSessionStorageNamespaceId, | |
204 kPersistentId); | |
205 DomStorageNamespace* dom_namespace = | |
206 context_->GetStorageNamespace(kSessionStorageNamespaceId); | |
207 DomStorageArea* area = dom_namespace->OpenStorageArea(kOrigin); | |
208 const base::string16 kKey(ASCIIToUTF16("foo")); | |
209 const base::string16 kValue(ASCIIToUTF16("bar")); | |
210 base::NullableString16 old_nullable_value; | |
211 area->SetItem(kKey, kValue, &old_nullable_value); | |
212 dom_namespace->CloseStorageArea(area); | |
213 | |
214 // Destroy and recreate the DomStorageContext. | |
215 context_->Shutdown(); | |
216 context_ = NULL; | |
217 base::MessageLoop::current()->RunUntilIdle(); | |
218 context_ = new DomStorageContext( | |
219 temp_dir_.path(), temp_dir_.path(), | |
220 storage_policy_.get(), task_runner_.get()); | |
221 context_->SetSaveSessionStorageOnDisk(); | |
222 | |
223 // Read the data back. | |
224 context_->CreateSessionNamespace(kSessionStorageNamespaceId, | |
225 kPersistentId); | |
226 dom_namespace = context_->GetStorageNamespace(kSessionStorageNamespaceId); | |
227 area = dom_namespace->OpenStorageArea(kOrigin); | |
228 base::NullableString16 read_value; | |
229 read_value = area->GetItem(kKey); | |
230 EXPECT_EQ(kValue, read_value.string()); | |
231 dom_namespace->CloseStorageArea(area); | |
232 | |
233 SessionStorageUsageInfo info; | |
234 info.origin = kOrigin; | |
235 info.persistent_namespace_id = kPersistentId; | |
236 context_->DeleteSessionStorage(info); | |
237 | |
238 // Destroy and recreate again. | |
239 context_->Shutdown(); | |
240 context_ = NULL; | |
241 base::MessageLoop::current()->RunUntilIdle(); | |
242 context_ = new DomStorageContext( | |
243 temp_dir_.path(), temp_dir_.path(), | |
244 storage_policy_.get(), task_runner_.get()); | |
245 context_->SetSaveSessionStorageOnDisk(); | |
246 | |
247 // Now there should be no data. | |
248 context_->CreateSessionNamespace(kSessionStorageNamespaceId, | |
249 kPersistentId); | |
250 dom_namespace = context_->GetStorageNamespace(kSessionStorageNamespaceId); | |
251 area = dom_namespace->OpenStorageArea(kOrigin); | |
252 read_value = area->GetItem(kKey); | |
253 EXPECT_TRUE(read_value.is_null()); | |
254 dom_namespace->CloseStorageArea(area); | |
255 context_->Shutdown(); | |
256 context_ = NULL; | |
257 base::MessageLoop::current()->RunUntilIdle(); | |
258 } | |
259 | |
260 } // namespace dom_storage | |
OLD | NEW |