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/files/file_util.h" 6#include "base/files/scoped_temp_dir.h" 7#include "base/memory/scoped_ptr.h" 8#include "base/message_loop/message_loop.h" 9#include "base/path_service.h" 10#include "content/public/test/test_browser_thread.h" 11#include "extensions/browser/value_store/value_store_frontend.h" 12#include "extensions/common/extension_paths.h" 13#include "testing/gtest/include/gtest/gtest.h" 14 15using content::BrowserThread; 16 17class ValueStoreFrontendTest : public testing::Test { 18 public: 19 ValueStoreFrontendTest() 20 : ui_thread_(BrowserThread::UI, base::MessageLoop::current()), 21 file_thread_(BrowserThread::FILE, base::MessageLoop::current()) { 22 } 23 24 virtual void SetUp() { 25 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 26 27 base::FilePath test_data_dir; 28 ASSERT_TRUE(PathService::Get(extensions::DIR_TEST_DATA, &test_data_dir)); 29 base::FilePath src_db(test_data_dir.AppendASCII("value_store_db")); 30 db_path_ = temp_dir_.path().AppendASCII("temp_db"); 31 base::CopyDirectory(src_db, db_path_, true); 32 33 ResetStorage(); 34 } 35 36 virtual void TearDown() { 37 base::MessageLoop::current()->RunUntilIdle(); // wait for storage to delete 38 storage_.reset(); 39 } 40 41 // Reset the value store, reloading the DB from disk. 42 void ResetStorage() { 43 storage_.reset(new ValueStoreFrontend(db_path_)); 44 } 45 46 bool Get(const std::string& key, scoped_ptr<base::Value>* output) { 47 storage_->Get(key, base::Bind(&ValueStoreFrontendTest::GetAndWait, 48 base::Unretained(this), output)); 49 base::MessageLoop::current()->Run(); // wait for GetAndWait 50 return !!output->get(); 51 } 52 53 protected: 54 void GetAndWait(scoped_ptr<base::Value>* output, 55 scoped_ptr<base::Value> result) { 56 *output = result.Pass(); 57 base::MessageLoop::current()->Quit(); 58 } 59 60 scoped_ptr<ValueStoreFrontend> storage_; 61 base::ScopedTempDir temp_dir_; 62 base::FilePath db_path_; 63 base::MessageLoop message_loop_; 64 content::TestBrowserThread ui_thread_; 65 content::TestBrowserThread file_thread_; 66}; 67 68TEST_F(ValueStoreFrontendTest, GetExistingData) { 69 scoped_ptr<base::Value> value; 70 ASSERT_FALSE(Get("key0", &value)); 71 72 // Test existing keys in the DB. 73 { 74 ASSERT_TRUE(Get("key1", &value)); 75 std::string result; 76 ASSERT_TRUE(value->GetAsString(&result)); 77 EXPECT_EQ("value1", result); 78 } 79 80 { 81 ASSERT_TRUE(Get("key2", &value)); 82 int result; 83 ASSERT_TRUE(value->GetAsInteger(&result)); 84 EXPECT_EQ(2, result); 85 } 86} 87 88TEST_F(ValueStoreFrontendTest, ChangesPersistAfterReload) { 89 storage_->Set("key0", scoped_ptr<base::Value>(new base::FundamentalValue(0))); 90 storage_->Set("key1", scoped_ptr<base::Value>(new base::StringValue("new1"))); 91 storage_->Remove("key2"); 92 93 // Reload the DB and test our changes. 94 ResetStorage(); 95 96 scoped_ptr<base::Value> value; 97 { 98 ASSERT_TRUE(Get("key0", &value)); 99 int result; 100 ASSERT_TRUE(value->GetAsInteger(&result)); 101 EXPECT_EQ(0, result); 102 } 103 104 { 105 ASSERT_TRUE(Get("key1", &value)); 106 std::string result; 107 ASSERT_TRUE(value->GetAsString(&result)); 108 EXPECT_EQ("new1", result); 109 } 110 111 ASSERT_FALSE(Get("key2", &value)); 112} 113