| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 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/command_line.h" | 
|  | 6 #include "base/files/file_path.h" | 
|  | 7 #include "base/memory/ref_counted.h" | 
|  | 8 #include "base/strings/stringprintf.h" | 
|  | 9 #include "chrome/browser/extensions/api/storage/settings_storage_quota_enforcer.
     h" | 
|  | 10 #include "chrome/browser/extensions/api/storage/settings_test_util.h" | 
|  | 11 #include "chrome/browser/extensions/api/storage/storage_api.h" | 
|  | 12 #include "chrome/browser/extensions/extension_api_unittest.h" | 
|  | 13 #include "chrome/browser/extensions/extension_service.h" | 
|  | 14 #include "chrome/browser/extensions/test_extension_system.h" | 
|  | 15 #include "chrome/browser/value_store/leveldb_value_store.h" | 
|  | 16 #include "chrome/browser/value_store/value_store.h" | 
|  | 17 #include "extensions/browser/event_router.h" | 
|  | 18 #include "extensions/browser/extension_prefs.h" | 
|  | 19 #include "extensions/browser/extension_system.h" | 
|  | 20 #include "extensions/common/id_util.h" | 
|  | 21 #include "extensions/common/manifest.h" | 
|  | 22 #include "extensions/common/test_util.h" | 
|  | 23 #include "third_party/leveldatabase/src/include/leveldb/db.h" | 
|  | 24 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" | 
|  | 25 | 
|  | 26 namespace extensions { | 
|  | 27 | 
|  | 28 class StorageApiUnittest : public ExtensionApiUnittest { | 
|  | 29  public: | 
|  | 30   virtual void SetUp() OVERRIDE { | 
|  | 31     ExtensionApiUnittest::SetUp(); | 
|  | 32     TestExtensionSystem* extension_system = | 
|  | 33         static_cast<TestExtensionSystem*>(ExtensionSystem::Get(profile())); | 
|  | 34     ExtensionService* extension_service = extension_system->extension_service(); | 
|  | 35     if (!extension_service) { | 
|  | 36       extension_service = extension_system->CreateExtensionService( | 
|  | 37           CommandLine::ForCurrentProcess(), base::FilePath(), false); | 
|  | 38       ASSERT_TRUE(extension_service); | 
|  | 39     } | 
|  | 40 | 
|  | 41     if (!extension_system->event_router()) { | 
|  | 42       extension_system->SetEventRouter(scoped_ptr<EventRouter>( | 
|  | 43           new EventRouter(profile(), ExtensionPrefs::Get(profile())))); | 
|  | 44     } | 
|  | 45 | 
|  | 46     scoped_refptr<Extension> extension = | 
|  | 47         test_util::CreateExtensionWithID(id_util::GenerateId("ext")); | 
|  | 48     set_extension(extension); | 
|  | 49     extension_service->AddExtension(extension.get()); | 
|  | 50   } | 
|  | 51 | 
|  | 52  protected: | 
|  | 53   // Runs the storage.set() API function with local storage. | 
|  | 54   void RunSetFunction(const std::string& key, const std::string& value) { | 
|  | 55     RunFunction( | 
|  | 56         new StorageStorageAreaSetFunction(), | 
|  | 57         base::StringPrintf( | 
|  | 58             "[\"local\", {\"%s\": \"%s\"}]", key.c_str(), value.c_str())); | 
|  | 59   } | 
|  | 60 | 
|  | 61   // Runs the storage.get() API function with the local storage, and populates | 
|  | 62   // |value| with the string result. | 
|  | 63   testing::AssertionResult RunGetFunction(const std::string& key, | 
|  | 64                                           std::string* value) { | 
|  | 65     scoped_ptr<base::Value> result = RunFunctionAndReturnValue( | 
|  | 66         new StorageStorageAreaGetFunction(), | 
|  | 67         base::StringPrintf("[\"local\", \"%s\"]", key.c_str())); | 
|  | 68     base::DictionaryValue* dict = NULL; | 
|  | 69     if (!result->GetAsDictionary(&dict)) | 
|  | 70       return testing::AssertionFailure() << result << " was not a dictionary."; | 
|  | 71     if (!dict->GetString(key, value)) { | 
|  | 72       return testing::AssertionFailure() << " could not retrieve a string from" | 
|  | 73           << dict << " at " << key; | 
|  | 74     } | 
|  | 75     return testing::AssertionSuccess(); | 
|  | 76   } | 
|  | 77 }; | 
|  | 78 | 
|  | 79 TEST_F(StorageApiUnittest, RestoreCorruptedStorage) { | 
|  | 80   const char kKey[] = "key"; | 
|  | 81   const char kValue[] = "value"; | 
|  | 82   std::string result; | 
|  | 83 | 
|  | 84   // Do a simple set/get combo to make sure the API works. | 
|  | 85   RunSetFunction(kKey, kValue); | 
|  | 86   EXPECT_TRUE(RunGetFunction(kKey, &result)); | 
|  | 87   EXPECT_EQ(kValue, result); | 
|  | 88 | 
|  | 89   // Corrupt the store. This is not as pretty as ideal, because we use knowledge | 
|  | 90   // of the underlying structure, but there's no real good way to corrupt a | 
|  | 91   // store other than directly modifying the files. | 
|  | 92   ValueStore* store = | 
|  | 93       settings_test_util::GetStorage(extension()->id(), | 
|  | 94                                      settings_namespace::LOCAL, | 
|  | 95                                      ExtensionSystem::Get(profile()) | 
|  | 96                                          ->extension_service() | 
|  | 97                                          ->settings_frontend()); | 
|  | 98   ASSERT_TRUE(store); | 
|  | 99   SettingsStorageQuotaEnforcer* quota_store = | 
|  | 100       static_cast<SettingsStorageQuotaEnforcer*>(store); | 
|  | 101   LeveldbValueStore* leveldb_store = | 
|  | 102       static_cast<LeveldbValueStore*>(quota_store->get_delegate_for_test()); | 
|  | 103   leveldb::WriteBatch batch; | 
|  | 104   batch.Put(kKey, "[{(.*+\"\'\\"); | 
|  | 105   EXPECT_TRUE(leveldb_store->WriteToDbForTest(&batch)); | 
|  | 106   EXPECT_TRUE(leveldb_store->Get(kKey)->IsCorrupted()); | 
|  | 107 | 
|  | 108   // Running another set should end up working (even though it will restore the | 
|  | 109   // store behind the scenes). | 
|  | 110   RunSetFunction(kKey, kValue); | 
|  | 111   EXPECT_TRUE(RunGetFunction(kKey, &result)); | 
|  | 112   EXPECT_EQ(kValue, result); | 
|  | 113 } | 
|  | 114 | 
|  | 115 }  // namespace extensions | 
| OLD | NEW | 
|---|