| Index: rlz/test/rlz_test_helpers.cc
|
| diff --git a/rlz/test/rlz_test_helpers.cc b/rlz/test/rlz_test_helpers.cc
|
| index db34cd93697ddb47d6747a7a9da3884eed55c6b4..af08836f9bba3b1a1e55dbd83792fc7c73c566d0 100644
|
| --- a/rlz/test/rlz_test_helpers.cc
|
| +++ b/rlz/test/rlz_test_helpers.cc
|
| @@ -6,62 +6,129 @@
|
|
|
| #include "rlz_test_helpers.h"
|
|
|
| +#include <map>
|
| +#include <vector>
|
| +
|
| +#include "base/strings/string16.h"
|
| #include "rlz/lib/rlz_lib.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| #if defined(OS_WIN)
|
| #include <shlwapi.h>
|
| #include "base/win/registry.h"
|
| -#include "rlz/win/lib/rlz_lib.h"
|
| +#include "base/win/windows_version.h"
|
| #elif defined(OS_POSIX)
|
| #include "base/files/file_path.h"
|
| #include "rlz/lib/rlz_value_store.h"
|
| #endif
|
|
|
| #if defined(OS_WIN)
|
| +
|
| namespace {
|
|
|
| -const wchar_t* kHKCUReplacement = L"Software\\Google\\RlzUtilUnittest\\HKCU";
|
| -const wchar_t* kHKLMReplacement = L"Software\\Google\\RlzUtilUnittest\\HKLM";
|
| -
|
| -void OverrideRegistryHives() {
|
| - // Wipe the keys we redirect to.
|
| - // This gives us a stable run, even in the presence of previous
|
| - // crashes or failures.
|
| - LSTATUS err = SHDeleteKey(HKEY_CURRENT_USER, kHKCUReplacement);
|
| - EXPECT_TRUE(err == ERROR_SUCCESS || err == ERROR_FILE_NOT_FOUND);
|
| - err = SHDeleteKey(HKEY_CURRENT_USER, kHKLMReplacement);
|
| - EXPECT_TRUE(err == ERROR_SUCCESS || err == ERROR_FILE_NOT_FOUND);
|
| -
|
| - // Create the keys we're redirecting HKCU and HKLM to.
|
| - base::win::RegKey hkcu;
|
| - base::win::RegKey hklm;
|
| - ASSERT_EQ(ERROR_SUCCESS,
|
| - hkcu.Create(HKEY_CURRENT_USER, kHKCUReplacement, KEY_READ));
|
| - ASSERT_EQ(ERROR_SUCCESS,
|
| - hklm.Create(HKEY_CURRENT_USER, kHKLMReplacement, KEY_READ));
|
| -
|
| - rlz_lib::InitializeTempHivesForTesting(hklm, hkcu);
|
| -
|
| - // And do the switcharoo.
|
| - ASSERT_EQ(ERROR_SUCCESS,
|
| - ::RegOverridePredefKey(HKEY_CURRENT_USER, hkcu.Handle()));
|
| - ASSERT_EQ(ERROR_SUCCESS,
|
| - ::RegOverridePredefKey(HKEY_LOCAL_MACHINE, hklm.Handle()));
|
| +// Path to recursively copy into the replacemment hives. These are needed
|
| +// to make sure certain win32 APIs continue to run correctly once the real
|
| +// hives are replaced.
|
| +const wchar_t kHKLMAccessProviders[] =
|
| + L"System\\CurrentControlSet\\Control\\Lsa\\AccessProviders";
|
| +
|
| +struct RegistryValue {
|
| + string16 name;
|
| + DWORD type;
|
| + std::vector<uint8> data;
|
| +};
|
| +
|
| +struct RegistryKeyData {
|
| + std::vector<RegistryValue> values;
|
| + std::map<string16, RegistryKeyData> keys;
|
| +};
|
| +
|
| +void ReadRegistryTree(const base::win::RegKey& src, RegistryKeyData* data) {
|
| + // First read values.
|
| + {
|
| + base::win::RegistryValueIterator i(src.Handle(), L"");
|
| + data->values.clear();
|
| + data->values.reserve(i.ValueCount());
|
| + for (; i.Valid(); ++i) {
|
| + RegistryValue& value = *data->values.insert(data->values.end(),
|
| + RegistryValue());
|
| + const uint8* data = reinterpret_cast<const uint8*>(i.Value());
|
| + value.name.assign(i.Name());
|
| + value.type = i.Type();
|
| + value.data.assign(data, data + i.ValueSize());
|
| + }
|
| + }
|
| +
|
| + // Next read subkeys recursively.
|
| + for (base::win::RegistryKeyIterator i(src.Handle(), L"");
|
| + i.Valid(); ++i) {
|
| + ReadRegistryTree(base::win::RegKey(src.Handle(), i.Name(), KEY_READ),
|
| + &data->keys[string16(i.Name())]);
|
| + }
|
| +}
|
| +
|
| +void WriteRegistryTree(const RegistryKeyData& data, base::win::RegKey* dest) {
|
| + // First write values.
|
| + for (size_t i = 0; i < data.values.size(); ++i) {
|
| + const RegistryValue& value = data.values[i];
|
| + dest->WriteValue(value.name.c_str(),
|
| + value.data.size() ? &value.data[0] : NULL,
|
| + static_cast<DWORD>(value.data.size()),
|
| + value.type);
|
| + }
|
| +
|
| + // Next write values recursively.
|
| + for (std::map<string16, RegistryKeyData>::const_iterator iter =
|
| + data.keys.begin();
|
| + iter != data.keys.end(); ++iter) {
|
| + WriteRegistryTree(iter->second,
|
| + &base::win::RegKey(dest->Handle(), iter->first.c_str(),
|
| + KEY_ALL_ACCESS));
|
| + }
|
| }
|
|
|
| -void UndoOverrideRegistryHives() {
|
| - // Undo the redirection.
|
| - EXPECT_EQ(ERROR_SUCCESS, ::RegOverridePredefKey(HKEY_CURRENT_USER, NULL));
|
| - EXPECT_EQ(ERROR_SUCCESS, ::RegOverridePredefKey(HKEY_LOCAL_MACHINE, NULL));
|
| +// Initialize temporary HKLM/HKCU registry hives used for testing.
|
| +// Testing RLZ requires reading and writing to the Windows registry. To keep
|
| +// the tests isolated from the machine's state, as well as to prevent the tests
|
| +// from causing side effects in the registry, HKCU and HKLM are overridden for
|
| +// the duration of the tests. RLZ tests don't expect the HKCU and KHLM hives to
|
| +// be empty though, and this function initializes the minimum value needed so
|
| +// that the test will run successfully.
|
| +void InitializeRegistryOverridesForTesting(
|
| + registry_util::RegistryOverrideManager* override_manager) {
|
| + // For the moment, the HKCU hive requires no initialization.
|
| + const bool do_copy = (base::win::GetVersion() >= base::win::VERSION_WIN7);
|
| + RegistryKeyData data;
|
| +
|
| + if (do_copy) {
|
| + // Copy the following HKLM subtrees to the temporary location so that the
|
| + // win32 APIs used by the tests continue to work:
|
| + //
|
| + // HKLM\System\CurrentControlSet\Control\Lsa\AccessProviders
|
| + //
|
| + // This seems to be required since Win7.
|
| + ReadRegistryTree(base::win::RegKey(HKEY_LOCAL_MACHINE,
|
| + kHKLMAccessProviders,
|
| + KEY_READ), &data);
|
| + }
|
| +
|
| + override_manager->OverrideRegistry(HKEY_LOCAL_MACHINE, L"rlz_temp_hklm");
|
| + override_manager->OverrideRegistry(HKEY_CURRENT_USER, L"rlz_temp_hkcu");
|
| +
|
| + if (do_copy) {
|
| + WriteRegistryTree(data, &base::win::RegKey(HKEY_LOCAL_MACHINE,
|
| + kHKLMAccessProviders,
|
| + KEY_ALL_ACCESS));
|
| + }
|
| }
|
|
|
| } // namespace
|
| +
|
| #endif // defined(OS_WIN)
|
|
|
| void RlzLibTestNoMachineState::SetUp() {
|
| #if defined(OS_WIN)
|
| - OverrideRegistryHives();
|
| + InitializeRegistryOverridesForTesting(&override_manager_);
|
| #elif defined(OS_MACOSX)
|
| base::mac::ScopedNSAutoreleasePool pool;
|
| #endif // defined(OS_WIN)
|
| @@ -72,11 +139,9 @@ void RlzLibTestNoMachineState::SetUp() {
|
| }
|
|
|
| void RlzLibTestNoMachineState::TearDown() {
|
| -#if defined(OS_WIN)
|
| - UndoOverrideRegistryHives();
|
| -#elif defined(OS_POSIX)
|
| +#if defined(OS_POSIX)
|
| rlz_lib::testing::SetRlzStoreDirectory(base::FilePath());
|
| -#endif // defined(OS_WIN)
|
| +#endif // defined(OS_POSIX)
|
| }
|
|
|
| void RlzLibTestBase::SetUp() {
|
|
|