Add ICU message format support
[chromium-blink-merge.git] / extensions / browser / api / storage / storage_frontend_unittest.cc
blob64515d08922953a1cdf7a64cd5e2f8c97b308e2e
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.
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/string_number_conversions.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"
23 using content::BrowserThread;
25 namespace extensions {
27 namespace settings = settings_namespace;
28 namespace util = settings_test_util;
30 namespace {
32 // To save typing ValueStore::DEFAULTS everywhere.
33 const ValueStore::WriteOptions DEFAULTS = ValueStore::DEFAULTS;
35 } // namespace
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()) {}
47 void SetUp() override {
48 ExtensionsTest::SetUp();
49 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
50 ResetFrontend();
53 void TearDown() override {
54 frontend_.reset();
55 // Execute any pending deletion tasks.
56 message_loop_.RunUntilIdle();
57 ExtensionsTest::TearDown();
60 protected:
61 void ResetFrontend() {
62 storage_factory_->Reset(new LeveldbSettingsStorageFactory());
63 frontend_ = StorageFrontend::CreateForTesting(storage_factory_,
64 browser_context()).Pass();
67 base::ScopedTempDir temp_dir_;
68 scoped_ptr<StorageFrontend> frontend_;
69 scoped_refptr<util::ScopedSettingsStorageFactory> storage_factory_;
71 private:
72 base::MessageLoop message_loop_;
73 content::TestBrowserThread ui_thread_;
74 content::TestBrowserThread file_thread_;
75 ExtensionsAPIClient extensions_api_client_;
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.
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));
88 // Invalid storage areas are not available.
89 EXPECT_FALSE(frontend_->IsStorageEnabled(settings::INVALID));
90 EXPECT_FALSE(frontend_->GetValueStoreCache(settings::INVALID));
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);
98 ValueStore* storage =
99 util::GetStorage(extension, settings::LOCAL, frontend_.get());
101 // The correctness of Get/Set/Remove/Clear is tested elsewhere so no need to
102 // be too rigorous.
104 base::StringValue bar("bar");
105 ValueStore::WriteResult result = storage->Set(DEFAULTS, "foo", bar);
106 ASSERT_FALSE(result->HasError());
110 ValueStore::ReadResult result = storage->Get();
111 ASSERT_FALSE(result->HasError());
112 EXPECT_FALSE(result->settings().empty());
115 ResetFrontend();
116 storage = util::GetStorage(extension, settings::LOCAL, frontend_.get());
119 ValueStore::ReadResult result = storage->Get();
120 ASSERT_FALSE(result->HasError());
121 EXPECT_FALSE(result->settings().empty());
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);
130 ValueStore* storage =
131 util::GetStorage(extension, settings::LOCAL, frontend_.get());
134 base::StringValue bar("bar");
135 ValueStore::WriteResult result = storage->Set(DEFAULTS, "foo", bar);
136 ASSERT_FALSE(result->HasError());
139 // This would be triggered by extension uninstall via a DataDeleter.
140 frontend_->DeleteStorageSoon(id);
141 base::MessageLoop::current()->RunUntilIdle();
143 // The storage area may no longer be valid post-uninstall, so re-request.
144 storage = util::GetStorage(extension, settings::LOCAL, frontend_.get());
146 ValueStore::ReadResult result = storage->Get();
147 ASSERT_FALSE(result->HasError());
148 EXPECT_TRUE(result->settings().empty());
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);
157 ValueStore* storage =
158 util::GetStorage(extension, settings::LOCAL, frontend_.get());
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()));
167 // Should need to both clear the database and delete the frontend for the
168 // leveldb database to be deleted from disk.
170 ValueStore::WriteResult result = storage->Clear();
171 ASSERT_FALSE(result->HasError());
172 EXPECT_TRUE(base::PathExists(temp_dir_.path()));
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()));
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);
190 ValueStore* sync_storage =
191 util::GetStorage(extension, settings::SYNC, frontend_.get());
192 ValueStore* local_storage =
193 util::GetStorage(extension, settings::LOCAL, frontend_.get());
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::IntToString(i), *kilobyte);
201 EXPECT_TRUE(sync_storage->Set(DEFAULTS, "WillError", *kilobyte)->HasError());
203 // Local storage shouldn't run out after ~100K.
204 for (int i = 0; i < 100; ++i) {
205 local_storage->Set(DEFAULTS, base::IntToString(i), *kilobyte);
208 EXPECT_FALSE(
209 local_storage->Set(DEFAULTS, "WontError", *kilobyte)->HasError());
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::IntToString(i), *megabyte);
217 EXPECT_TRUE(local_storage->Set(DEFAULTS, "WillError", *megabyte)->HasError());
220 } // namespace extensions