diff options
author | grt@chromium.org <grt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-14 07:43:20 +0000 |
---|---|---|
committer | grt@chromium.org <grt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-14 07:43:20 +0000 |
commit | 20402235d708145f61c1fe41a4d7b8ddc35a15be (patch) | |
tree | 9acfda4ab3c09257f8515019c63a4981c49859c5 /rlz/test | |
parent | b7c04c11491d6c37c22b9ebb49696cafefb38c09 (diff) | |
download | chromium_src-20402235d708145f61c1fe41a4d7b8ddc35a15be.zip chromium_src-20402235d708145f61c1fe41a4d7b8ddc35a15be.tar.gz chromium_src-20402235d708145f61c1fe41a4d7b8ddc35a15be.tar.bz2 |
Use RegistryOverrideManager properly in RLZ tests.
Previously, rlz/test/rlz_test_helpers.cc and
chrome/browser/rlz/rlz_unittest.cc each did somewhat different things to
prepare the registry for tests. Now, rlz_test_helpers.cc does the prep
the right way using RegistryOverrideManager and rlz_unittests.cc uses
rlz_test_helpers.cc.
This unblocks the refactor in r234367 that was reverted in r234627.
BUG=314800
R=rogerta@chromium.org, tommycli@chromium.org
Review URL: https://codereview.chromium.org/63153009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@235090 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'rlz/test')
-rw-r--r-- | rlz/test/rlz_test_helpers.cc | 139 | ||||
-rw-r--r-- | rlz/test/rlz_test_helpers.h | 13 |
2 files changed, 112 insertions, 40 deletions
diff --git a/rlz/test/rlz_test_helpers.cc b/rlz/test/rlz_test_helpers.cc index db34cd9..af08836 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() { diff --git a/rlz/test/rlz_test_helpers.h b/rlz/test/rlz_test_helpers.h index a78764f..ec067fe 100644 --- a/rlz/test/rlz_test_helpers.h +++ b/rlz/test/rlz_test_helpers.h @@ -14,20 +14,27 @@ #include "base/files/scoped_temp_dir.h" #endif +#if defined(OS_WIN) +#include "base/test/test_reg_util_win.h" +#endif + class RlzLibTestNoMachineState : public ::testing::Test { protected: virtual void SetUp() OVERRIDE; virtual void TearDown() OVERRIDE; - #if defined(OS_POSIX) - base::ScopedTempDir temp_dir_; + base::ScopedTempDir temp_dir_; +#endif + +#if defined(OS_WIN) + registry_util::RegistryOverrideManager override_manager_; #endif }; class RlzLibTestBase : public RlzLibTestNoMachineState { + protected: virtual void SetUp() OVERRIDE; }; - #endif // RLZ_TEST_RLZ_TEST_HELPERS_H |