1 // Copyright (c) 2012 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 // Main entry point for all unit tests. 6 7 #include "rlz_test_helpers.h" 8 9 #include <map> 10 #include <vector> 11 12 #include "base/strings/string16.h" 13 #include "rlz/lib/rlz_lib.h" 14 #include "testing/gtest/include/gtest/gtest.h" 15 16 #if defined(OS_WIN) 17 #include <shlwapi.h> 18 #include "base/win/registry.h" 19 #include "base/win/windows_version.h" 20 #elif defined(OS_POSIX) 21 #include "base/files/file_path.h" 22 #include "rlz/lib/rlz_value_store.h" 23 #endif 24 25 #if defined(OS_WIN) 26 27 namespace { 28 29 // Path to recursively copy into the replacemment hives. These are needed 30 // to make sure certain win32 APIs continue to run correctly once the real 31 // hives are replaced. 32 const wchar_t kHKLMAccessProviders[] = 33 L"System\\CurrentControlSet\\Control\\Lsa\\AccessProviders"; 34 35 struct RegistryValue { 36 base::string16 name; 37 DWORD type; 38 std::vector<uint8> data; 39 }; 40 41 struct RegistryKeyData { 42 std::vector<RegistryValue> values; 43 std::map<base::string16, RegistryKeyData> keys; 44 }; 45 46 void ReadRegistryTree(const base::win::RegKey& src, RegistryKeyData* data) { 47 // First read values. 48 { 49 base::win::RegistryValueIterator i(src.Handle(), L""); 50 data->values.clear(); 51 data->values.reserve(i.ValueCount()); 52 for (; i.Valid(); ++i) { 53 RegistryValue& value = *data->values.insert(data->values.end(), 54 RegistryValue()); 55 const uint8* data = reinterpret_cast<const uint8*>(i.Value()); 56 value.name.assign(i.Name()); 57 value.type = i.Type(); 58 value.data.assign(data, data + i.ValueSize()); 59 } 60 } 61 62 // Next read subkeys recursively. 63 for (base::win::RegistryKeyIterator i(src.Handle(), L""); 64 i.Valid(); ++i) { 65 ReadRegistryTree(base::win::RegKey(src.Handle(), i.Name(), KEY_READ), 66 &data->keys[base::string16(i.Name())]); 67 } 68 } 69 70 void WriteRegistryTree(const RegistryKeyData& data, base::win::RegKey* dest) { 71 // First write values. 72 for (size_t i = 0; i < data.values.size(); ++i) { 73 const RegistryValue& value = data.values[i]; 74 dest->WriteValue(value.name.c_str(), 75 value.data.size() ? &value.data[0] : NULL, 76 static_cast<DWORD>(value.data.size()), 77 value.type); 78 } 79 80 // Next write values recursively. 81 for (std::map<base::string16, RegistryKeyData>::const_iterator iter = 82 data.keys.begin(); 83 iter != data.keys.end(); ++iter) { 84 WriteRegistryTree(iter->second, 85 &base::win::RegKey(dest->Handle(), iter->first.c_str(), 86 KEY_ALL_ACCESS)); 87 } 88 } 89 90 // Initialize temporary HKLM/HKCU registry hives used for testing. 91 // Testing RLZ requires reading and writing to the Windows registry. To keep 92 // the tests isolated from the machine's state, as well as to prevent the tests 93 // from causing side effects in the registry, HKCU and HKLM are overridden for 94 // the duration of the tests. RLZ tests don't expect the HKCU and KHLM hives to 95 // be empty though, and this function initializes the minimum value needed so 96 // that the test will run successfully. 97 void InitializeRegistryOverridesForTesting( 98 registry_util::RegistryOverrideManager* override_manager) { 99 // For the moment, the HKCU hive requires no initialization. 100 const bool do_copy = (base::win::GetVersion() >= base::win::VERSION_WIN7); 101 RegistryKeyData data; 102 103 if (do_copy) { 104 // Copy the following HKLM subtrees to the temporary location so that the 105 // win32 APIs used by the tests continue to work: 106 // 107 // HKLM\System\CurrentControlSet\Control\Lsa\AccessProviders 108 // 109 // This seems to be required since Win7. 110 ReadRegistryTree(base::win::RegKey(HKEY_LOCAL_MACHINE, 111 kHKLMAccessProviders, 112 KEY_READ), &data); 113 } 114 115 override_manager->OverrideRegistry(HKEY_LOCAL_MACHINE, L"rlz_temp_hklm"); 116 override_manager->OverrideRegistry(HKEY_CURRENT_USER, L"rlz_temp_hkcu"); 117 118 if (do_copy) { 119 WriteRegistryTree(data, &base::win::RegKey(HKEY_LOCAL_MACHINE, 120 kHKLMAccessProviders, 121 KEY_ALL_ACCESS)); 122 } 123 } 124 125 } // namespace 126 127 #endif // defined(OS_WIN) 128 129 void RlzLibTestNoMachineState::SetUp() { 130 #if defined(OS_WIN) 131 InitializeRegistryOverridesForTesting(&override_manager_); 132 #elif defined(OS_MACOSX) 133 base::mac::ScopedNSAutoreleasePool pool; 134 #endif // defined(OS_WIN) 135 #if defined(OS_POSIX) 136 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 137 rlz_lib::testing::SetRlzStoreDirectory(temp_dir_.path()); 138 #endif // defined(OS_POSIX) 139 } 140 141 void RlzLibTestNoMachineState::TearDown() { 142 #if defined(OS_POSIX) 143 rlz_lib::testing::SetRlzStoreDirectory(base::FilePath()); 144 #endif // defined(OS_POSIX) 145 } 146 147 void RlzLibTestBase::SetUp() { 148 RlzLibTestNoMachineState::SetUp(); 149 #if defined(OS_WIN) 150 rlz_lib::CreateMachineState(); 151 #endif // defined(OS_WIN) 152 } 153