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