1bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/scoped_temp_dir.h"
8ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/sequenced_worker_pool.h"
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
13bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "content/browser/dom_storage/dom_storage_area.h"
14bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "content/browser/dom_storage/dom_storage_context_impl.h"
15bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "content/browser/dom_storage/dom_storage_namespace.h"
16bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "content/browser/dom_storage/dom_storage_task_runner.h"
17bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "content/public/browser/local_storage_usage_info.h"
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/browser/session_storage_namespace.h"
19bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "content/public/browser/session_storage_usage_info.h"
205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "content/public/test/mock_special_storage_policy.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::ASCIIToUTF16;
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
25bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochnamespace content {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochclass DOMStorageContextImplTest : public testing::Test {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
29bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  DOMStorageContextImplTest()
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : kOrigin(GURL("http://dom_storage/")),
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kKey(ASCIIToUTF16("key")),
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kValue(ASCIIToUTF16("value")),
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kDontIncludeFileInfo(false),
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kDoIncludeFileInfo(true) {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kOrigin;
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const base::string16 kKey;
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const base::string16 kValue;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool kDontIncludeFileInfo;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool kDoIncludeFileInfo;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    storage_policy_ = new MockSpecialStoragePolicy;
467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    task_runner_ =
47bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch        new MockDOMStorageTaskRunner(base::MessageLoopProxy::current().get());
48bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    context_ = new DOMStorageContextImpl(temp_dir_.path(),
49bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                         base::FilePath(),
50bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                         storage_policy_.get(),
51bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                         task_runner_.get());
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() {
55b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    base::MessageLoop::current()->RunUntilIdle();
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void VerifySingleOriginRemains(const GURL& origin) {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Use a new instance to examine the contexts of temp_dir_.
60bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    scoped_refptr<DOMStorageContextImpl> context =
61bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch        new DOMStorageContextImpl(temp_dir_.path(), base::FilePath(),
62bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                  NULL, NULL);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<LocalStorageUsageInfo> infos;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    context->GetLocalStorageUsage(&infos, kDontIncludeFileInfo);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(1u, infos.size());
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(origin, infos[0].origin);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
70b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop message_loop_;
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir temp_dir_;
725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_refptr<MockSpecialStoragePolicy> storage_policy_;
73bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  scoped_refptr<MockDOMStorageTaskRunner> task_runner_;
74bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  scoped_refptr<DOMStorageContextImpl> context_;
75bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(DOMStorageContextImplTest);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochTEST_F(DOMStorageContextImplTest, Basics) {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This test doesn't do much, checks that the constructor
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // initializes members properly and that invoking methods
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on a newly created object w/o any data on disk do no harm.
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(temp_dir_.path(), context_->localstorage_directory());
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(base::FilePath(), context_->sessionstorage_directory());
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(storage_policy_.get(), context_->special_storage_policy_.get());
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->DeleteLocalStorage(GURL("http://chromium.org/"));
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kFirstSessionStorageNamespaceId = 1;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(context_->GetStorageNamespace(kLocalStorageNamespaceId));
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(context_->GetStorageNamespace(kFirstSessionStorageNamespaceId));
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kFirstSessionStorageNamespaceId, context_->AllocateSessionId());
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<LocalStorageUsageInfo> infos;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->GetLocalStorageUsage(&infos, kDontIncludeFileInfo);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(infos.empty());
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->Shutdown();
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochTEST_F(DOMStorageContextImplTest, UsageInfo) {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should be empty initially
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<LocalStorageUsageInfo> infos;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->GetLocalStorageUsage(&infos, kDontIncludeFileInfo);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(infos.empty());
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->GetLocalStorageUsage(&infos, kDoIncludeFileInfo);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(infos.empty());
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Put some data into local storage and shutdown the context
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to ensure data is written to disk.
1067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::NullableString16 old_value;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(context_->GetStorageNamespace(kLocalStorageNamespaceId)->
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OpenStorageArea(kOrigin)->SetItem(kKey, kValue, &old_value));
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->Shutdown();
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_ = NULL;
111b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a new context that points to the same directory, see that
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it knows about the origin that we stored data for.
115bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  context_ = new DOMStorageContextImpl(temp_dir_.path(), base::FilePath(),
116bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                       NULL, NULL);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->GetLocalStorageUsage(&infos, kDontIncludeFileInfo);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, infos.size());
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kOrigin, infos[0].origin);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, infos[0].data_size);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::Time(), infos[0].last_modified);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  infos.clear();
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->GetLocalStorageUsage(&infos, kDoIncludeFileInfo);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, infos.size());
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kOrigin, infos[0].origin);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(0u, infos[0].data_size);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(base::Time(), infos[0].last_modified);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
130bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochTEST_F(DOMStorageContextImplTest, SessionOnly) {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kSessionOnlyOrigin("http://www.sessiononly.com/");
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  storage_policy_->AddSessionOnly(kSessionOnlyOrigin);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Store data for a normal and a session-only origin and then
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // invoke Shutdown() which should delete data for session-only
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // origins.
1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::NullableString16 old_value;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(context_->GetStorageNamespace(kLocalStorageNamespaceId)->
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OpenStorageArea(kOrigin)->SetItem(kKey, kValue, &old_value));
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(context_->GetStorageNamespace(kLocalStorageNamespaceId)->
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OpenStorageArea(kSessionOnlyOrigin)->SetItem(kKey, kValue, &old_value));
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->Shutdown();
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_ = NULL;
144b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that the session-only origin data is gone.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifySingleOriginRemains(kOrigin);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
150bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochTEST_F(DOMStorageContextImplTest, SetForceKeepSessionState) {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kSessionOnlyOrigin("http://www.sessiononly.com/");
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  storage_policy_->AddSessionOnly(kSessionOnlyOrigin);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Store data for a session-only origin, setup to save session data, then
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // shutdown.
1567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::NullableString16 old_value;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(context_->GetStorageNamespace(kLocalStorageNamespaceId)->
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OpenStorageArea(kSessionOnlyOrigin)->SetItem(kKey, kValue, &old_value));
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->SetForceKeepSessionState();  // Should override clear behavior.
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->Shutdown();
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_ = NULL;
162b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifySingleOriginRemains(kSessionOnlyOrigin);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
167bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochTEST_F(DOMStorageContextImplTest, PersistentIds) {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kFirstSessionStorageNamespaceId = 1;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string kPersistentId = "persistent";
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->CreateSessionNamespace(kFirstSessionStorageNamespaceId,
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   kPersistentId);
172bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  DOMStorageNamespace* dom_namespace =
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      context_->GetStorageNamespace(kFirstSessionStorageNamespaceId);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(dom_namespace);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kPersistentId, dom_namespace->persistent_namespace_id());
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that the areas inherit the persistent ID.
177bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  DOMStorageArea* area = dom_namespace->OpenStorageArea(kOrigin);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kPersistentId, area->persistent_namespace_id_);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that the persistent IDs are handled correctly when cloning.
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kClonedSessionStorageNamespaceId = 2;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string kClonedPersistentId = "cloned";
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->CloneSessionNamespace(kFirstSessionStorageNamespaceId,
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  kClonedSessionStorageNamespaceId,
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  kClonedPersistentId);
186bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  DOMStorageNamespace* cloned_dom_namespace =
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      context_->GetStorageNamespace(kClonedSessionStorageNamespaceId);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(dom_namespace);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kClonedPersistentId,
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            cloned_dom_namespace->persistent_namespace_id());
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that the areas inherit the persistent ID.
192bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  DOMStorageArea* cloned_area = cloned_dom_namespace->OpenStorageArea(kOrigin);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kClonedPersistentId, cloned_area->persistent_namespace_id_);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
196bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochTEST_F(DOMStorageContextImplTest, DeleteSessionStorage) {
197bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Create a DOMStorageContextImpl which will save sessionStorage on disk.
198bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  context_ = new DOMStorageContextImpl(temp_dir_.path(),
199bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                       temp_dir_.path(),
200bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                       storage_policy_.get(),
201bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                       task_runner_.get());
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->SetSaveSessionStorageOnDisk();
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(temp_dir_.path(), context_->sessionstorage_directory());
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Write data.
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kSessionStorageNamespaceId = 1;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string kPersistentId = "persistent";
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->CreateSessionNamespace(kSessionStorageNamespaceId,
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   kPersistentId);
210bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  DOMStorageNamespace* dom_namespace =
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      context_->GetStorageNamespace(kSessionStorageNamespaceId);
212bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  DOMStorageArea* area = dom_namespace->OpenStorageArea(kOrigin);
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const base::string16 kKey(ASCIIToUTF16("foo"));
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const base::string16 kValue(ASCIIToUTF16("bar"));
2157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::NullableString16 old_nullable_value;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  area->SetItem(kKey, kValue, &old_nullable_value);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dom_namespace->CloseStorageArea(area);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
219bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Destroy and recreate the DOMStorageContextImpl.
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->Shutdown();
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_ = NULL;
222b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
223bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  context_ = new DOMStorageContextImpl(
224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      temp_dir_.path(), temp_dir_.path(),
225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      storage_policy_.get(), task_runner_.get());
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->SetSaveSessionStorageOnDisk();
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read the data back.
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->CreateSessionNamespace(kSessionStorageNamespaceId,
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   kPersistentId);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dom_namespace = context_->GetStorageNamespace(kSessionStorageNamespaceId);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  area = dom_namespace->OpenStorageArea(kOrigin);
2337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::NullableString16 read_value;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  read_value = area->GetItem(kKey);
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kValue, read_value.string());
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dom_namespace->CloseStorageArea(area);
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SessionStorageUsageInfo info;
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.origin = kOrigin;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.persistent_namespace_id = kPersistentId;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->DeleteSessionStorage(info);
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Destroy and recreate again.
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->Shutdown();
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_ = NULL;
246b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
247bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  context_ = new DOMStorageContextImpl(
248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      temp_dir_.path(), temp_dir_.path(),
249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      storage_policy_.get(), task_runner_.get());
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->SetSaveSessionStorageOnDisk();
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now there should be no data.
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->CreateSessionNamespace(kSessionStorageNamespaceId,
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   kPersistentId);
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dom_namespace = context_->GetStorageNamespace(kSessionStorageNamespaceId);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  area = dom_namespace->OpenStorageArea(kOrigin);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  read_value = area->GetItem(kKey);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(read_value.is_null());
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dom_namespace->CloseStorageArea(area);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->Shutdown();
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_ = NULL;
262b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(DOMStorageContextImplTest, SessionStorageAlias) {
266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const int kFirstSessionStorageNamespaceId = 1;
267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string kPersistentId = "persistent";
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  context_->CreateSessionNamespace(kFirstSessionStorageNamespaceId,
269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                   kPersistentId);
270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DOMStorageNamespace* dom_namespace1 =
271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      context_->GetStorageNamespace(kFirstSessionStorageNamespaceId);
272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(dom_namespace1);
273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DOMStorageArea* area1 = dom_namespace1->OpenStorageArea(kOrigin);
274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::NullableString16 old_value;
275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  area1->SetItem(kKey, kValue, &old_value);
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(old_value.is_null());
277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::NullableString16 read_value = area1->GetItem(kKey);
278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(!read_value.is_null() && read_value.string() == kValue);
279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Create an alias.
281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const int kAliasSessionStorageNamespaceId = 2;
282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  context_->CreateAliasSessionNamespace(kFirstSessionStorageNamespaceId,
283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                        kAliasSessionStorageNamespaceId,
284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                        kPersistentId);
285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DOMStorageNamespace* dom_namespace2 =
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      context_->GetStorageNamespace(kAliasSessionStorageNamespaceId);
287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(dom_namespace2);
288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(dom_namespace2->alias_master_namespace() == dom_namespace1);
289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Verify that read values are identical.
291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DOMStorageArea* area2 = dom_namespace2->OpenStorageArea(kOrigin);
292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  read_value = area2->GetItem(kKey);
293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(!read_value.is_null() && read_value.string() == kValue);
294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Verify that writes are reflected in both namespaces.
296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const base::string16 kValue2(ASCIIToUTF16("value2"));
297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  area2->SetItem(kKey, kValue2, &old_value);
298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  read_value = area1->GetItem(kKey);
299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(!read_value.is_null() && read_value.string() == kValue2);
300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  dom_namespace1->CloseStorageArea(area1);
301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  dom_namespace2->CloseStorageArea(area2);
302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // When creating an alias of an alias, ensure that the master relationship
304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // is collapsed.
305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const int kAlias2SessionStorageNamespaceId = 3;
306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  context_->CreateAliasSessionNamespace(kAliasSessionStorageNamespaceId,
307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                        kAlias2SessionStorageNamespaceId,
308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                        kPersistentId);
309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DOMStorageNamespace* dom_namespace3 =
310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      context_->GetStorageNamespace(kAlias2SessionStorageNamespaceId);
311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(dom_namespace3);
312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(dom_namespace3->alias_master_namespace() == dom_namespace1);
313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
314f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(DOMStorageContextImplTest, SessionStorageMerge) {
316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Create a target namespace that we will merge into.
317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const int kTargetSessionStorageNamespaceId = 1;
318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string kTargetPersistentId = "persistent";
319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  context_->CreateSessionNamespace(kTargetSessionStorageNamespaceId,
320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                   kTargetPersistentId);
321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DOMStorageNamespace* target_ns =
322f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      context_->GetStorageNamespace(kTargetSessionStorageNamespaceId);
323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(target_ns);
324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DOMStorageArea* target_ns_area = target_ns->OpenStorageArea(kOrigin);
325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::NullableString16 old_value;
326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const base::string16 kKey2(ASCIIToUTF16("key2"));
327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const base::string16 kKey2Value(ASCIIToUTF16("key2value"));
328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  target_ns_area->SetItem(kKey, kValue, &old_value);
329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  target_ns_area->SetItem(kKey2, kKey2Value, &old_value);
330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Create a source namespace & its alias.
332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const int kSourceSessionStorageNamespaceId = 2;
333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const int kAliasSessionStorageNamespaceId = 3;
334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string kSourcePersistentId = "persistent_source";
335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  context_->CreateSessionNamespace(kSourceSessionStorageNamespaceId,
336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                   kSourcePersistentId);
337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  context_->CreateAliasSessionNamespace(kSourceSessionStorageNamespaceId,
338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                        kAliasSessionStorageNamespaceId,
339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                        kSourcePersistentId);
340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DOMStorageNamespace* alias_ns =
341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      context_->GetStorageNamespace(kAliasSessionStorageNamespaceId);
342f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(alias_ns);
343f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Create a transaction log that can't be merged.
345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const int kPid1 = 10;
346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_FALSE(alias_ns->IsLoggingRenderer(kPid1));
347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  alias_ns->AddTransactionLogProcessId(kPid1);
348f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(alias_ns->IsLoggingRenderer(kPid1));
349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const base::string16 kValue2(ASCIIToUTF16("value2"));
350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DOMStorageNamespace::TransactionRecord txn;
351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  txn.origin = kOrigin;
352f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  txn.key = kKey;
353f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  txn.value = base::NullableString16(kValue2, false);
354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  txn.transaction_type = DOMStorageNamespace::TRANSACTION_READ;
355f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  alias_ns->AddTransaction(kPid1, txn);
356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(alias_ns->Merge(false, kPid1, target_ns, NULL) ==
357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              SessionStorageNamespace::MERGE_RESULT_NOT_MERGEABLE);
358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
359f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Create a transaction log that can be merged.
360f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const int kPid2 = 20;
361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  alias_ns->AddTransactionLogProcessId(kPid2);
362f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  txn.transaction_type = DOMStorageNamespace::TRANSACTION_WRITE;
363f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  alias_ns->AddTransaction(kPid2, txn);
364f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(alias_ns->Merge(true, kPid2, target_ns, NULL) ==
365f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              SessionStorageNamespace::MERGE_RESULT_MERGEABLE);
366f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
367f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Verify that the merge was successful.
368f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(alias_ns->alias_master_namespace() == target_ns);
369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::NullableString16 read_value = target_ns_area->GetItem(kKey);
370f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(!read_value.is_null() && read_value.string() == kValue2);
371f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DOMStorageArea* alias_ns_area = alias_ns->OpenStorageArea(kOrigin);
372f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  read_value = alias_ns_area->GetItem(kKey2);
373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(!read_value.is_null() && read_value.string() == kKey2Value);
374f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
376bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}  // namespace content
377