Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / extensions / browser / api / storage / storage_frontend_unittest.cc
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/bind.h"
6 #include "base/files/file_util.h"
7 #include "base/files/scoped_temp_dir.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/stringprintf.h"
11 #include "content/public/browser/browser_context.h"
12 #include "content/public/test/test_browser_context.h"
13 #include "content/public/test/test_browser_thread.h"
14 #include "extensions/browser/api/extensions_api_client.h"
15 #include "extensions/browser/api/storage/leveldb_settings_storage_factory.h"
16 #include "extensions/browser/api/storage/settings_namespace.h"
17 #include "extensions/browser/api/storage/settings_test_util.h"
18 #include "extensions/browser/api/storage/storage_frontend.h"
19 #include "extensions/browser/extensions_test.h"
20 #include "extensions/browser/value_store/value_store.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22
23 using content::BrowserThread;
24
25 namespace extensions {
26
27 namespace settings = settings_namespace;
28 namespace util = settings_test_util;
29
30 namespace {
31
32 // To save typing ValueStore::DEFAULTS everywhere.
33 const ValueStore::WriteOptions DEFAULTS = ValueStore::DEFAULTS;
34
35 }  // namespace
36
37 // A better name for this would be StorageFrontendTest, but the historical name
38 // has been ExtensionSettingsFrontendTest. In order to preserve crash/failure
39 // history, the test names are unchanged.
40 class ExtensionSettingsFrontendTest : public ExtensionsTest {
41  public:
42   ExtensionSettingsFrontendTest()
43       : storage_factory_(new util::ScopedSettingsStorageFactory()),
44         ui_thread_(BrowserThread::UI, base::MessageLoop::current()),
45         file_thread_(BrowserThread::FILE, base::MessageLoop::current()) {}
46
47   void SetUp() override {
48     ExtensionsTest::SetUp();
49     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
50     ResetFrontend();
51   }
52
53   void TearDown() override {
54     frontend_.reset();
55     // Execute any pending deletion tasks.
56     message_loop_.RunUntilIdle();
57     ExtensionsTest::TearDown();
58   }
59
60  protected:
61   void ResetFrontend() {
62     storage_factory_->Reset(new LeveldbSettingsStorageFactory());
63     frontend_.reset(
64         StorageFrontend::CreateForTesting(storage_factory_, browser_context()));
65   }
66
67   base::ScopedTempDir temp_dir_;
68   scoped_ptr<StorageFrontend> frontend_;
69   scoped_refptr<util::ScopedSettingsStorageFactory> storage_factory_;
70
71  private:
72   base::MessageLoop message_loop_;
73   content::TestBrowserThread ui_thread_;
74   content::TestBrowserThread file_thread_;
75   ExtensionsAPIClient extensions_api_client_;
76 };
77
78 // Get a semblance of coverage for both extension and app settings by
79 // alternating in each test.
80 // TODO(kalman): explicitly test the two interact correctly.
81
82 // Tests that the frontend is set up correctly.
83 TEST_F(ExtensionSettingsFrontendTest, Basics) {
84   // Local storage is always enabled.
85   EXPECT_TRUE(frontend_->IsStorageEnabled(settings::LOCAL));
86   EXPECT_TRUE(frontend_->GetValueStoreCache(settings::LOCAL));
87
88   // Invalid storage areas are not available.
89   EXPECT_FALSE(frontend_->IsStorageEnabled(settings::INVALID));
90   EXPECT_FALSE(frontend_->GetValueStoreCache(settings::INVALID));
91 }
92
93 TEST_F(ExtensionSettingsFrontendTest, SettingsPreservedAcrossReconstruction) {
94   const std::string id = "ext";
95   scoped_refptr<const Extension> extension =
96       util::AddExtensionWithId(browser_context(), id, Manifest::TYPE_EXTENSION);
97
98   ValueStore* storage =
99       util::GetStorage(extension, settings::LOCAL, frontend_.get());
100
101   // The correctness of Get/Set/Remove/Clear is tested elsewhere so no need to
102   // be too rigorous.
103   {
104     base::StringValue bar("bar");
105     ValueStore::WriteResult result = storage->Set(DEFAULTS, "foo", bar);
106     ASSERT_FALSE(result->HasError());
107   }
108
109   {
110     ValueStore::ReadResult result = storage->Get();
111     ASSERT_FALSE(result->HasError());
112     EXPECT_FALSE(result->settings().empty());
113   }
114
115   ResetFrontend();
116   storage = util::GetStorage(extension, settings::LOCAL, frontend_.get());
117
118   {
119     ValueStore::ReadResult result = storage->Get();
120     ASSERT_FALSE(result->HasError());
121     EXPECT_FALSE(result->settings().empty());
122   }
123 }
124
125 TEST_F(ExtensionSettingsFrontendTest, SettingsClearedOnUninstall) {
126   const std::string id = "ext";
127   scoped_refptr<const Extension> extension = util::AddExtensionWithId(
128       browser_context(), id, Manifest::TYPE_LEGACY_PACKAGED_APP);
129
130   ValueStore* storage =
131       util::GetStorage(extension, settings::LOCAL, frontend_.get());
132
133   {
134     base::StringValue bar("bar");
135     ValueStore::WriteResult result = storage->Set(DEFAULTS, "foo", bar);
136     ASSERT_FALSE(result->HasError());
137   }
138
139   // This would be triggered by extension uninstall via a DataDeleter.
140   frontend_->DeleteStorageSoon(id);
141   base::MessageLoop::current()->RunUntilIdle();
142
143   // The storage area may no longer be valid post-uninstall, so re-request.
144   storage = util::GetStorage(extension, settings::LOCAL, frontend_.get());
145   {
146     ValueStore::ReadResult result = storage->Get();
147     ASSERT_FALSE(result->HasError());
148     EXPECT_TRUE(result->settings().empty());
149   }
150 }
151
152 TEST_F(ExtensionSettingsFrontendTest, LeveldbDatabaseDeletedFromDiskOnClear) {
153   const std::string id = "ext";
154   scoped_refptr<const Extension> extension =
155       util::AddExtensionWithId(browser_context(), id, Manifest::TYPE_EXTENSION);
156
157   ValueStore* storage =
158       util::GetStorage(extension, settings::LOCAL, frontend_.get());
159
160   {
161     base::StringValue bar("bar");
162     ValueStore::WriteResult result = storage->Set(DEFAULTS, "foo", bar);
163     ASSERT_FALSE(result->HasError());
164     EXPECT_TRUE(base::PathExists(temp_dir_.path()));
165   }
166
167   // Should need to both clear the database and delete the frontend for the
168   // leveldb database to be deleted from disk.
169   {
170     ValueStore::WriteResult result = storage->Clear();
171     ASSERT_FALSE(result->HasError());
172     EXPECT_TRUE(base::PathExists(temp_dir_.path()));
173   }
174
175   frontend_.reset();
176   base::MessageLoop::current()->RunUntilIdle();
177   // TODO(kalman): Figure out why this fails, despite appearing to work.
178   // Leaving this commented out rather than disabling the whole test so that the
179   // deletion code paths are at least exercised.
180   //EXPECT_FALSE(base::PathExists(temp_dir_.path()));
181 }
182
183 // Disabled (slow), http://crbug.com/322751 .
184 TEST_F(ExtensionSettingsFrontendTest,
185        DISABLED_QuotaLimitsEnforcedCorrectlyForSyncAndLocal) {
186   const std::string id = "ext";
187   scoped_refptr<const Extension> extension =
188       util::AddExtensionWithId(browser_context(), id, Manifest::TYPE_EXTENSION);
189
190   ValueStore* sync_storage =
191       util::GetStorage(extension, settings::SYNC, frontend_.get());
192   ValueStore* local_storage =
193       util::GetStorage(extension, settings::LOCAL, frontend_.get());
194
195   // Sync storage should run out after ~100K.
196   scoped_ptr<base::Value> kilobyte = util::CreateKilobyte();
197   for (int i = 0; i < 100; ++i) {
198     sync_storage->Set(DEFAULTS, base::StringPrintf("%d", i), *kilobyte);
199   }
200
201   EXPECT_TRUE(sync_storage->Set(DEFAULTS, "WillError", *kilobyte)->HasError());
202
203   // Local storage shouldn't run out after ~100K.
204   for (int i = 0; i < 100; ++i) {
205     local_storage->Set(DEFAULTS, base::StringPrintf("%d", i), *kilobyte);
206   }
207
208   EXPECT_FALSE(
209       local_storage->Set(DEFAULTS, "WontError", *kilobyte)->HasError());
210
211   // Local storage should run out after ~5MB.
212   scoped_ptr<base::Value> megabyte = util::CreateMegabyte();
213   for (int i = 0; i < 5; ++i) {
214     local_storage->Set(DEFAULTS, base::StringPrintf("%d", i), *megabyte);
215   }
216
217   EXPECT_TRUE(local_storage->Set(DEFAULTS, "WillError", *megabyte)->HasError());
218 }
219
220 }  // namespace extensions