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"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/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_database.h"
15bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "content/browser/dom_storage/dom_storage_database_adapter.h"
16bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "content/browser/dom_storage/dom_storage_task_runner.h"
17bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "content/browser/dom_storage/local_storage_database_adapter.h"
18bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "content/common/dom_storage/dom_storage_types.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochnamespace content {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochclass DOMStorageAreaTest : public testing::Test {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
26bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  DOMStorageAreaTest()
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : kOrigin(GURL("http://dom_storage/")),
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kKey(ASCIIToUTF16("key")),
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kValue(ASCIIToUTF16("value")),
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kKey2(ASCIIToUTF16("key2")),
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kValue2(ASCIIToUTF16("value2")) {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kOrigin;
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const base::string16 kKey;
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const base::string16 kValue;
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const base::string16 kKey2;
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const base::string16 kValue2;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Method used in the CommitTasks test case.
41bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  void InjectedCommitSequencingTask(DOMStorageArea* area) {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // At this point the OnCommitTimer has run.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Verify that it put a commit in flight.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(1, area->commit_batches_in_flight_);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(area->commit_batch_.get());
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(area->HasUncommittedChanges());
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make additional change and verify that a new commit batch
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // is created for that change.
497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::NullableString16 old_value;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(area->SetItem(kKey2, kValue2, &old_value));
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(area->commit_batch_.get());
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(1, area->commit_batches_in_flight_);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(area->HasUncommittedChanges());
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Class used in the CommitChangesAtShutdown test case.
57bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  class VerifyChangesCommittedDatabase : public DOMStorageDatabase {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VerifyChangesCommittedDatabase() {}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual ~VerifyChangesCommittedDatabase() {
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const base::string16 kKey(ASCIIToUTF16("key"));
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const base::string16 kValue(ASCIIToUTF16("value"));
63bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      DOMStorageValuesMap values;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ReadAllValues(&values);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(1u, values.size());
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(kValue, values[kKey].string());
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
71b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop message_loop_;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochTEST_F(DOMStorageAreaTest, DOMStorageAreaBasics) {
75bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  scoped_refptr<DOMStorageArea> area(
76bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      new DOMStorageArea(1, std::string(), kOrigin, NULL, NULL));
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::string16 old_value;
787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::NullableString16 old_nullable_value;
79bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  scoped_refptr<DOMStorageArea> copy;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // We don't focus on the underlying DOMStorageMap functionality
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // since that's covered by seperate unit tests.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kOrigin, area->origin());
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, area->namespace_id());
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, area->Length());
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->SetItem(kKey, kValue, &old_nullable_value));
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->SetItem(kKey2, kValue2, &old_nullable_value));
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(area->HasUncommittedChanges());
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that a copy shares the same map.
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  copy = area->ShallowCopy(2, std::string());
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kOrigin, copy->origin());
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, copy->namespace_id());
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(area->Length(), copy->Length());
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(area->GetItem(kKey).string(), copy->GetItem(kKey).string());
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(area->Key(0).string(), copy->Key(0).string());
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(copy->map_.get(), area->map_.get());
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // But will deep copy-on-write as needed.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->RemoveItem(kKey, &old_value));
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(copy->map_.get(), area->map_.get());
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  copy = area->ShallowCopy(2, std::string());
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(copy->map_.get(), area->map_.get());
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->SetItem(kKey, kValue, &old_nullable_value));
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(copy->map_.get(), area->map_.get());
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  copy = area->ShallowCopy(2, std::string());
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(copy->map_.get(), area->map_.get());
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(0u, area->Length());
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->Clear());
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, area->Length());
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(copy->map_.get(), area->map_.get());
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that once Shutdown(), behaves that way.
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  area->Shutdown();
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->is_shutdown_);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(area->map_.get());
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, area->Length());
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->Key(0).is_null());
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->GetItem(kKey).is_null());
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(area->SetItem(kKey, kValue, &old_nullable_value));
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(area->RemoveItem(kKey, &old_value));
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(area->Clear());
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochTEST_F(DOMStorageAreaTest, BackingDatabaseOpened) {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int64 kSessionStorageNamespaceId = kLocalStorageNamespaceId + 1;
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir temp_dir;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::FilePath kExpectedOriginFilePath = temp_dir.path().Append(
130bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      DOMStorageArea::DatabaseFileNameFromOrigin(kOrigin));
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No directory, backing should be null.
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
134bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    scoped_refptr<DOMStorageArea> area(
135bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch        new DOMStorageArea(kOrigin, base::FilePath(), NULL));
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(NULL, area->backing_.get());
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(area->is_initial_import_done_);
1387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    EXPECT_FALSE(base::PathExists(kExpectedOriginFilePath));
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Valid directory and origin but no session storage backing. Backing should
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be null.
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
144bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    scoped_refptr<DOMStorageArea> area(
145bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch        new DOMStorageArea(kSessionStorageNamespaceId, std::string(), kOrigin,
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           NULL, NULL));
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(NULL, area->backing_.get());
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(area->is_initial_import_done_);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::NullableString16 old_value;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(area->SetItem(kKey, kValue, &old_value));
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(old_value.is_null());
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Check that saving a value has still left us without a backing database.
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(NULL, area->backing_.get());
1567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    EXPECT_FALSE(base::PathExists(kExpectedOriginFilePath));
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
159bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // This should set up a DOMStorageArea that is correctly backed to disk.
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
161bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    scoped_refptr<DOMStorageArea> area(new DOMStorageArea(
1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        kOrigin,
1637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        temp_dir.path(),
164bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch        new MockDOMStorageTaskRunner(base::MessageLoopProxy::current().get())));
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(area->backing_.get());
167bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    DOMStorageDatabase* database = static_cast<LocalStorageDatabaseAdapter*>(
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        area->backing_.get())->db_.get();
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(database->IsOpen());
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(area->is_initial_import_done_);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Inject an in-memory db to speed up the test.
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We will verify that something is written into the database but not
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // that a file is written to disk - DOMStorageDatabase unit tests cover
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // that.
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    area->backing_.reset(new LocalStorageDatabaseAdapter());
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Need to write something to ensure that the database is created.
1797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::NullableString16 old_value;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(area->SetItem(kKey, kValue, &old_value));
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(old_value.is_null());
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(area->is_initial_import_done_);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(area->commit_batch_.get());
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, area->commit_batches_in_flight_);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
186b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    base::MessageLoop::current()->RunUntilIdle();
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(area->commit_batch_.get());
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, area->commit_batches_in_flight_);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    database = static_cast<LocalStorageDatabaseAdapter*>(
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        area->backing_.get())->db_.get();
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(database->IsOpen());
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(1u, area->Length());
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kValue, area->GetItem(kKey).string());
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Verify the content made it to the in memory database.
197bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    DOMStorageValuesMap values;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    area->backing_->ReadAllValues(&values);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(1u, values.size());
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kValue, values[kKey].string());
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
204bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochTEST_F(DOMStorageAreaTest, CommitTasks) {
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir temp_dir;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
208bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  scoped_refptr<DOMStorageArea> area(new DOMStorageArea(
2097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      kOrigin,
2107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      temp_dir.path(),
211bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      new MockDOMStorageTaskRunner(base::MessageLoopProxy::current().get())));
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Inject an in-memory db to speed up the test.
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  area->backing_.reset(new LocalStorageDatabaseAdapter());
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unrelated to commits, but while we're here, see that querying Length()
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // causes the backing database to be opened and presumably read from.
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(area->is_initial_import_done_);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, area->Length());
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->is_initial_import_done_);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
221bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  DOMStorageValuesMap values;
2227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::NullableString16 old_value;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See that changes are batched up.
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(area->commit_batch_.get());
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->SetItem(kKey, kValue, &old_value));
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->HasUncommittedChanges());
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->commit_batch_.get());
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(area->commit_batch_->clear_all_first);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, area->commit_batch_->changed_values.size());
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->SetItem(kKey2, kValue2, &old_value));
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->commit_batch_.get());
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(area->commit_batch_->clear_all_first);
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2u, area->commit_batch_->changed_values.size());
235b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(area->HasUncommittedChanges());
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(area->commit_batch_.get());
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, area->commit_batches_in_flight_);
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify the changes made it to the database.
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  values.clear();
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  area->backing_->ReadAllValues(&values);
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2u, values.size());
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kValue, values[kKey].string());
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kValue2, values[kKey2].string());
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See that clear is handled properly.
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->Clear());
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->commit_batch_.get());
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->commit_batch_->clear_all_first);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->commit_batch_->changed_values.empty());
251b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(area->commit_batch_.get());
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, area->commit_batches_in_flight_);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify the changes made it to the database.
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  values.clear();
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  area->backing_->ReadAllValues(&values);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(values.empty());
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See that if changes accrue while a commit is "in flight"
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // those will also get committed.
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->SetItem(kKey, kValue, &old_value));
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->HasUncommittedChanges());
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // At this point the OnCommitTimer task has been posted. We inject
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // another task in the queue that will execute after the timer task,
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // but before the CommitChanges task. From within our injected task,
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we'll make an additional SetItem() call.
267b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
269bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      base::Bind(&DOMStorageAreaTest::InjectedCommitSequencingTask,
270b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                 base::Unretained(this),
271b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                 area));
272b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->HasOneRef());
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(area->HasUncommittedChanges());
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify the changes made it to the database.
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  values.clear();
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  area->backing_->ReadAllValues(&values);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2u, values.size());
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kValue, values[kKey].string());
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kValue2, values[kKey2].string());
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
283bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochTEST_F(DOMStorageAreaTest, CommitChangesAtShutdown) {
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir temp_dir;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
286bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  scoped_refptr<DOMStorageArea> area(new DOMStorageArea(
2877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      kOrigin,
2887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      temp_dir.path(),
289bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      new MockDOMStorageTaskRunner(base::MessageLoopProxy::current().get())));
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Inject an in-memory db to speed up the test and also to verify
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the final changes are commited in it's dtor.
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static_cast<LocalStorageDatabaseAdapter*>(area->backing_.get())->db_.reset(
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new VerifyChangesCommittedDatabase());
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
296bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  DOMStorageValuesMap values;
2977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::NullableString16 old_value;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->SetItem(kKey, kValue, &old_value));
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->HasUncommittedChanges());
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  area->backing_->ReadAllValues(&values);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(values.empty());  // not committed yet
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  area->Shutdown();
303b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->HasOneRef());
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(area->backing_.get());
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The VerifyChangesCommittedDatabase destructor verifies values
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // were committed.
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
310bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochTEST_F(DOMStorageAreaTest, DeleteOrigin) {
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir temp_dir;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
313bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  scoped_refptr<DOMStorageArea> area(new DOMStorageArea(
3147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      kOrigin,
3157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      temp_dir.path(),
316bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      new MockDOMStorageTaskRunner(base::MessageLoopProxy::current().get())));
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This test puts files on disk.
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath db_file_path = static_cast<LocalStorageDatabaseAdapter*>(
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      area->backing_.get())->db_->file_path();
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath db_journal_file_path =
322bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      DOMStorageDatabase::GetJournalFilePath(db_file_path);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Nothing bad should happen when invoked w/o any files on disk.
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  area->DeleteOrigin();
3267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(base::PathExists(db_file_path));
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Commit something in the database and then delete.
3297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::NullableString16 old_value;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  area->SetItem(kKey, kValue, &old_value);
331b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
3327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(base::PathExists(db_file_path));
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  area->DeleteOrigin();
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, area->Length());
3357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(base::PathExists(db_file_path));
3367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(base::PathExists(db_journal_file_path));
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Put some uncommitted changes to a non-existing database in
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and then delete. No file ever gets created in this case.
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  area->SetItem(kKey, kValue, &old_value);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->HasUncommittedChanges());
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, area->Length());
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  area->DeleteOrigin();
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->HasUncommittedChanges());
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, area->Length());
346b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(area->HasUncommittedChanges());
3487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(base::PathExists(db_file_path));
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Put some uncommitted changes to a an existing database in
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and then delete.
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  area->SetItem(kKey, kValue, &old_value);
353b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
3547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(base::PathExists(db_file_path));
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  area->SetItem(kKey2, kValue2, &old_value);
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->HasUncommittedChanges());
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2u, area->Length());
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  area->DeleteOrigin();
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->HasUncommittedChanges());
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, area->Length());
361b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(area->HasUncommittedChanges());
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since the area had uncommitted changes at the time delete
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // was called, the file will linger until the shutdown time.
3657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(base::PathExists(db_file_path));
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  area->Shutdown();
367b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
3687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(base::PathExists(db_file_path));
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
371bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochTEST_F(DOMStorageAreaTest, PurgeMemory) {
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir temp_dir;
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
374bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  scoped_refptr<DOMStorageArea> area(new DOMStorageArea(
3757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      kOrigin,
3767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      temp_dir.path(),
377bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      new MockDOMStorageTaskRunner(base::MessageLoopProxy::current().get())));
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Inject an in-memory db to speed up the test.
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  area->backing_.reset(new LocalStorageDatabaseAdapter());
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unowned ptrs we use to verify that 'purge' has happened.
383bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  DOMStorageDatabase* original_backing =
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<LocalStorageDatabaseAdapter*>(
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          area->backing_.get())->db_.get();
386bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  DOMStorageMap* original_map = area->map_.get();
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should do no harm when called on a newly constructed object.
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(area->is_initial_import_done_);
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  area->PurgeMemory();
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(area->is_initial_import_done_);
392bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  DOMStorageDatabase* new_backing = static_cast<LocalStorageDatabaseAdapter*>(
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      area->backing_.get())->db_.get();
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(original_backing, new_backing);
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(original_map, area->map_.get());
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should not do anything when commits are pending.
3987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::NullableString16 old_value;
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  area->SetItem(kKey, kValue, &old_value);
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->is_initial_import_done_);
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->HasUncommittedChanges());
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  area->PurgeMemory();
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->is_initial_import_done_);
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(area->HasUncommittedChanges());
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_backing = static_cast<LocalStorageDatabaseAdapter*>(
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      area->backing_.get())->db_.get();
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(original_backing, new_backing);
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(original_map, area->map_.get());
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Commit the changes from above,
411b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(area->HasUncommittedChanges());
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_backing = static_cast<LocalStorageDatabaseAdapter*>(
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      area->backing_.get())->db_.get();
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(original_backing, new_backing);
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(original_map, area->map_.get());
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should drop caches and reset database connections
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when invoked on an area that's loaded up primed.
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  area->PurgeMemory();
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(area->is_initial_import_done_);
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_backing = static_cast<LocalStorageDatabaseAdapter*>(
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      area->backing_.get())->db_.get();
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(original_backing, new_backing);
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(original_map, area->map_.get());
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
428bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochTEST_F(DOMStorageAreaTest, DatabaseFileNames) {
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct {
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* origin;
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* file_name;
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* journal_file_name;
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } kCases[] = {
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "https://www.google.com/",
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https_www.google.com_0.localstorage",
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https_www.google.com_0.localstorage-journal" },
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "http://www.google.com:8080/",
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http_www.google.com_8080.localstorage",
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http_www.google.com_8080.localstorage-journal" },
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "file:///",
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "file__0.localstorage",
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "file__0.localstorage-journal" },
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kCases); ++i) {
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL origin = GURL(kCases[i].origin).GetOrigin();
447bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    base::FilePath file_name =
448bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch        base::FilePath().AppendASCII(kCases[i].file_name);
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath journal_file_name =
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::FilePath().AppendASCII(kCases[i].journal_file_name);
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(file_name,
453bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch              DOMStorageArea::DatabaseFileNameFromOrigin(origin));
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(origin,
455bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch              DOMStorageArea::OriginFromDatabaseFileName(file_name));
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(journal_file_name,
457bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch              DOMStorageDatabase::GetJournalFilePath(file_name));
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
460bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Also test some DOMStorageDatabase::GetJournalFilePath cases here.
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath parent = base::FilePath().AppendASCII("a").AppendASCII("b");
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      parent.AppendASCII("file-journal"),
464bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      DOMStorageDatabase::GetJournalFilePath(parent.AppendASCII("file")));
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath().AppendASCII("-journal"),
467bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      DOMStorageDatabase::GetJournalFilePath(base::FilePath()));
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath().AppendASCII(".extensiononly-journal"),
470bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      DOMStorageDatabase::GetJournalFilePath(
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::FilePath().AppendASCII(".extensiononly")));
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
474bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}  // namespace content
475