Home | History | Annotate | Download | only in util
      1 // Copyright (c) 2011 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 <windows.h>
      6 
      7 #include "base/files/file_path.h"
      8 #include "base/memory/scoped_ptr.h"
      9 #include "base/strings/string_util.h"
     10 #include "base/win/registry.h"
     11 #include "chrome/installer/util/create_reg_key_work_item.h"
     12 #include "chrome/installer/util/work_item.h"
     13 #include "testing/gtest/include/gtest/gtest.h"
     14 
     15 using base::win::RegKey;
     16 
     17 namespace {
     18 
     19 wchar_t test_root[] = L"TmpTmp";
     20 
     21 class CreateRegKeyWorkItemTest : public testing::Test {
     22  protected:
     23   virtual void SetUp() {
     24     // Create a temporary key for testing
     25     RegKey key(HKEY_CURRENT_USER, L"", KEY_ALL_ACCESS);
     26     key.DeleteKey(test_root);
     27     ASSERT_NE(ERROR_SUCCESS, key.Open(HKEY_CURRENT_USER, test_root, KEY_READ));
     28     ASSERT_EQ(ERROR_SUCCESS, key.Create(HKEY_CURRENT_USER, test_root,
     29                                         KEY_READ));
     30   }
     31   virtual void TearDown() {
     32     logging::CloseLogFile();
     33     // Clean up the temporary key
     34     RegKey key(HKEY_CURRENT_USER, L"", KEY_ALL_ACCESS);
     35     ASSERT_EQ(ERROR_SUCCESS, key.DeleteKey(test_root));
     36   }
     37 };
     38 
     39 }  // namespace
     40 
     41 TEST_F(CreateRegKeyWorkItemTest, CreateKey) {
     42   RegKey key;
     43 
     44   base::FilePath parent_key(test_root);
     45   parent_key = parent_key.AppendASCII("a");
     46   ASSERT_EQ(ERROR_SUCCESS,
     47       key.Create(HKEY_CURRENT_USER, parent_key.value().c_str(), KEY_READ));
     48 
     49   base::FilePath top_key_to_create(parent_key);
     50   top_key_to_create = top_key_to_create.AppendASCII("b");
     51 
     52   base::FilePath key_to_create(top_key_to_create);
     53   key_to_create = key_to_create.AppendASCII("c");
     54   key_to_create = key_to_create.AppendASCII("d");
     55 
     56   scoped_ptr<CreateRegKeyWorkItem> work_item(
     57       WorkItem::CreateCreateRegKeyWorkItem(
     58           HKEY_CURRENT_USER, key_to_create.value(), WorkItem::kWow64Default));
     59 
     60   EXPECT_TRUE(work_item->Do());
     61 
     62   EXPECT_EQ(ERROR_SUCCESS,
     63       key.Open(HKEY_CURRENT_USER, key_to_create.value().c_str(), KEY_READ));
     64 
     65   work_item->Rollback();
     66 
     67   // Rollback should delete all the keys up to top_key_to_create.
     68   EXPECT_NE(ERROR_SUCCESS,
     69       key.Open(HKEY_CURRENT_USER, top_key_to_create.value().c_str(), KEY_READ));
     70   EXPECT_EQ(ERROR_SUCCESS,
     71       key.Open(HKEY_CURRENT_USER, parent_key.value().c_str(), KEY_READ));
     72 }
     73 
     74 TEST_F(CreateRegKeyWorkItemTest, CreateExistingKey) {
     75   RegKey key;
     76 
     77   base::FilePath key_to_create(test_root);
     78   key_to_create = key_to_create.AppendASCII("aa");
     79   ASSERT_EQ(ERROR_SUCCESS,
     80       key.Create(HKEY_CURRENT_USER, key_to_create.value().c_str(), KEY_READ));
     81 
     82   scoped_ptr<CreateRegKeyWorkItem> work_item(
     83       WorkItem::CreateCreateRegKeyWorkItem(
     84           HKEY_CURRENT_USER, key_to_create.value(), WorkItem::kWow64Default));
     85 
     86   EXPECT_TRUE(work_item->Do());
     87 
     88   EXPECT_EQ(ERROR_SUCCESS,
     89       key.Open(HKEY_CURRENT_USER, key_to_create.value().c_str(), KEY_READ));
     90 
     91   work_item->Rollback();
     92 
     93   // Rollback should not remove the key since it exists before
     94   // the CreateRegKeyWorkItem is called.
     95   EXPECT_EQ(ERROR_SUCCESS,
     96       key.Open(HKEY_CURRENT_USER, key_to_create.value().c_str(), KEY_READ));
     97 }
     98 
     99 TEST_F(CreateRegKeyWorkItemTest, CreateSharedKey) {
    100   RegKey key;
    101   base::FilePath key_to_create_1(test_root);
    102   key_to_create_1 = key_to_create_1.AppendASCII("aaa");
    103 
    104   base::FilePath key_to_create_2(key_to_create_1);
    105   key_to_create_2 = key_to_create_2.AppendASCII("bbb");
    106 
    107   base::FilePath key_to_create_3(key_to_create_2);
    108   key_to_create_3 = key_to_create_3.AppendASCII("ccc");
    109 
    110   scoped_ptr<CreateRegKeyWorkItem> work_item(
    111       WorkItem::CreateCreateRegKeyWorkItem(
    112           HKEY_CURRENT_USER, key_to_create_3.value(), WorkItem::kWow64Default));
    113 
    114   EXPECT_TRUE(work_item->Do());
    115 
    116   EXPECT_EQ(ERROR_SUCCESS,
    117       key.Open(HKEY_CURRENT_USER, key_to_create_3.value().c_str(), KEY_READ));
    118 
    119   // Create another key under key_to_create_2
    120   base::FilePath key_to_create_4(key_to_create_2);
    121   key_to_create_4 = key_to_create_4.AppendASCII("ddd");
    122   ASSERT_EQ(ERROR_SUCCESS,
    123       key.Create(HKEY_CURRENT_USER, key_to_create_4.value().c_str(), KEY_READ));
    124 
    125   work_item->Rollback();
    126 
    127   // Rollback should delete key_to_create_3.
    128   EXPECT_NE(ERROR_SUCCESS,
    129       key.Open(HKEY_CURRENT_USER, key_to_create_3.value().c_str(), KEY_READ));
    130 
    131   // Rollback should not delete key_to_create_2 as it is shared.
    132   EXPECT_EQ(ERROR_SUCCESS,
    133       key.Open(HKEY_CURRENT_USER, key_to_create_2.value().c_str(), KEY_READ));
    134   EXPECT_EQ(ERROR_SUCCESS,
    135       key.Open(HKEY_CURRENT_USER, key_to_create_4.value().c_str(), KEY_READ));
    136 }
    137 
    138 TEST_F(CreateRegKeyWorkItemTest, RollbackWithMissingKey) {
    139   RegKey key;
    140   base::FilePath key_to_create_1(test_root);
    141   key_to_create_1 = key_to_create_1.AppendASCII("aaaa");
    142 
    143   base::FilePath key_to_create_2(key_to_create_1);
    144   key_to_create_2 = key_to_create_2.AppendASCII("bbbb");
    145 
    146   base::FilePath key_to_create_3(key_to_create_2);
    147   key_to_create_3 = key_to_create_3.AppendASCII("cccc");
    148 
    149   scoped_ptr<CreateRegKeyWorkItem> work_item(
    150       WorkItem::CreateCreateRegKeyWorkItem(
    151           HKEY_CURRENT_USER, key_to_create_3.value(), WorkItem::kWow64Default));
    152 
    153   EXPECT_TRUE(work_item->Do());
    154 
    155   EXPECT_EQ(ERROR_SUCCESS,
    156       key.Open(HKEY_CURRENT_USER, key_to_create_3.value().c_str(), KEY_READ));
    157   key.Close();
    158 
    159   // now delete key_to_create_3
    160   ASSERT_EQ(ERROR_SUCCESS,
    161       RegDeleteKey(HKEY_CURRENT_USER, key_to_create_3.value().c_str()));
    162   ASSERT_NE(ERROR_SUCCESS,
    163       key.Open(HKEY_CURRENT_USER, key_to_create_3.value().c_str(), KEY_READ));
    164 
    165   work_item->Rollback();
    166 
    167   // key_to_create_3 has already been deleted, Rollback should delete
    168   // the rest.
    169   ASSERT_NE(ERROR_SUCCESS,
    170       key.Open(HKEY_CURRENT_USER, key_to_create_1.value().c_str(), KEY_READ));
    171 }
    172 
    173 TEST_F(CreateRegKeyWorkItemTest, RollbackWithSetValue) {
    174   RegKey key;
    175 
    176   base::FilePath key_to_create(test_root);
    177   key_to_create = key_to_create.AppendASCII("aaaaa");
    178 
    179   scoped_ptr<CreateRegKeyWorkItem> work_item(
    180       WorkItem::CreateCreateRegKeyWorkItem(
    181           HKEY_CURRENT_USER, key_to_create.value(), WorkItem::kWow64Default));
    182 
    183   EXPECT_TRUE(work_item->Do());
    184 
    185   // Write a value under the key we just created.
    186   EXPECT_EQ(ERROR_SUCCESS, key.Open(HKEY_CURRENT_USER,
    187       key_to_create.value().c_str(), KEY_READ | KEY_SET_VALUE));
    188   EXPECT_EQ(ERROR_SUCCESS, key.WriteValue(L"name", L"value"));
    189   key.Close();
    190 
    191   work_item->Rollback();
    192 
    193   // Rollback should not remove the key.
    194   EXPECT_EQ(ERROR_SUCCESS,
    195       key.Open(HKEY_CURRENT_USER, key_to_create.value().c_str(), KEY_READ));
    196 }
    197