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 "chrome/browser/chrome_elf_init_win.h" 6 7 #include "base/basictypes.h" 8 #include "base/memory/scoped_ptr.h" 9 #include "base/metrics/field_trial.h" 10 #include "base/strings/string16.h" 11 #include "base/strings/utf_string_conversions.h" 12 #include "base/test/test_reg_util_win.h" 13 #include "chrome/common/chrome_version_info.h" 14 #include "chrome_elf/chrome_elf_constants.h" 15 #include "components/variations/entropy_provider.h" 16 #include "components/variations/variations_associated_data.h" 17 #include "testing/gtest/include/gtest/gtest.h" 18 #include "version.h" // NOLINT 19 20 namespace { 21 22 const char kBrowserBlacklistTrialEnabledGroupName[] = "Enabled"; 23 24 class ChromeBlacklistTrialTest : public testing::Test { 25 protected: 26 ChromeBlacklistTrialTest() {} 27 virtual ~ChromeBlacklistTrialTest() {} 28 29 virtual void SetUp() OVERRIDE { 30 testing::Test::SetUp(); 31 32 override_manager_.OverrideRegistry(HKEY_CURRENT_USER); 33 34 blacklist_registry_key_.reset( 35 new base::win::RegKey(HKEY_CURRENT_USER, 36 blacklist::kRegistryBeaconPath, 37 KEY_QUERY_VALUE | KEY_SET_VALUE)); 38 } 39 40 DWORD GetBlacklistState() { 41 DWORD blacklist_state = blacklist::BLACKLIST_STATE_MAX; 42 blacklist_registry_key_->ReadValueDW(blacklist::kBeaconState, 43 &blacklist_state); 44 45 return blacklist_state; 46 } 47 48 base::string16 GetBlacklistVersion() { 49 base::string16 blacklist_version; 50 blacklist_registry_key_->ReadValue(blacklist::kBeaconVersion, 51 &blacklist_version); 52 53 return blacklist_version; 54 } 55 56 scoped_ptr<base::win::RegKey> blacklist_registry_key_; 57 registry_util::RegistryOverrideManager override_manager_; 58 59 private: 60 DISALLOW_COPY_AND_ASSIGN(ChromeBlacklistTrialTest); 61 }; 62 63 // Ensure that the default trial sets up the blacklist beacons. 64 TEST_F(ChromeBlacklistTrialTest, DefaultRun) { 65 // Set some dummy values as beacons. 66 blacklist_registry_key_->WriteValue(blacklist::kBeaconState, 67 blacklist::BLACKLIST_DISABLED); 68 blacklist_registry_key_->WriteValue(blacklist::kBeaconVersion, L"Data"); 69 70 // This setup code should result in the default group, which should have 71 // the blacklist set up. 72 InitializeChromeElf(); 73 74 // Ensure the beacon values are now correct, indicating the 75 // blacklist beacon was setup. 76 ASSERT_EQ(blacklist::BLACKLIST_ENABLED, GetBlacklistState()); 77 chrome::VersionInfo version_info; 78 base::string16 version(base::UTF8ToUTF16(version_info.Version())); 79 ASSERT_EQ(version, GetBlacklistVersion()); 80 } 81 82 // Ensure that the blacklist is disabled for any users in the 83 // "BlacklistDisabled" finch group. 84 TEST_F(ChromeBlacklistTrialTest, BlacklistDisabledRun) { 85 // Set the beacons to enabled values. 86 blacklist_registry_key_->WriteValue(blacklist::kBeaconState, 87 blacklist::BLACKLIST_ENABLED); 88 blacklist_registry_key_->WriteValue(blacklist::kBeaconVersion, L"Data"); 89 90 // Create the field trial with the blacklist disabled group. 91 base::FieldTrialList field_trial_list( 92 new metrics::SHA1EntropyProvider("test")); 93 94 scoped_refptr<base::FieldTrial> trial( 95 base::FieldTrialList::CreateFieldTrial( 96 kBrowserBlacklistTrialName, kBrowserBlacklistTrialDisabledGroupName)); 97 98 // This setup code should now delete any existing blacklist beacons. 99 InitializeChromeElf(); 100 101 // Ensure invalid values are returned to indicate that the beacon 102 // values are indeed gone. 103 ASSERT_EQ(blacklist::BLACKLIST_STATE_MAX, GetBlacklistState()); 104 ASSERT_EQ(base::string16(), GetBlacklistVersion()); 105 } 106 107 TEST_F(ChromeBlacklistTrialTest, VerifyFirstRun) { 108 BrowserBlacklistBeaconSetup(); 109 110 // Verify the state is properly set after the first run. 111 ASSERT_EQ(blacklist::BLACKLIST_ENABLED, GetBlacklistState()); 112 113 chrome::VersionInfo version_info; 114 base::string16 version(base::UTF8ToUTF16(version_info.Version())); 115 ASSERT_EQ(version, GetBlacklistVersion()); 116 } 117 118 TEST_F(ChromeBlacklistTrialTest, BlacklistFailed) { 119 // Ensure when the blacklist set up failed we set the state to disabled for 120 // future runs. 121 blacklist_registry_key_->WriteValue(blacklist::kBeaconVersion, 122 TEXT(CHROME_VERSION_STRING)); 123 blacklist_registry_key_->WriteValue(blacklist::kBeaconState, 124 blacklist::BLACKLIST_SETUP_FAILED); 125 126 BrowserBlacklistBeaconSetup(); 127 128 ASSERT_EQ(blacklist::BLACKLIST_DISABLED, GetBlacklistState()); 129 } 130 131 TEST_F(ChromeBlacklistTrialTest, VersionChanged) { 132 // Mark the blacklist as disabled for an older version, it should 133 // get enabled for this new version. Also record a non-zero number of 134 // setup failures, which should be reset to zero. 135 blacklist_registry_key_->WriteValue(blacklist::kBeaconVersion, 136 L"old_version"); 137 blacklist_registry_key_->WriteValue(blacklist::kBeaconState, 138 blacklist::BLACKLIST_DISABLED); 139 blacklist_registry_key_->WriteValue(blacklist::kBeaconAttemptCount, 140 blacklist::kBeaconMaxAttempts); 141 142 BrowserBlacklistBeaconSetup(); 143 144 // The beacon should now be marked as enabled for the current version. 145 ASSERT_EQ(blacklist::BLACKLIST_ENABLED, GetBlacklistState()); 146 147 chrome::VersionInfo version_info; 148 base::string16 expected_version(base::UTF8ToUTF16(version_info.Version())); 149 ASSERT_EQ(expected_version, GetBlacklistVersion()); 150 151 // The counter should be reset. 152 DWORD attempt_count = blacklist::kBeaconMaxAttempts; 153 blacklist_registry_key_->ReadValueDW(blacklist::kBeaconAttemptCount, 154 &attempt_count); 155 ASSERT_EQ(static_cast<DWORD>(0), attempt_count); 156 } 157 158 TEST_F(ChromeBlacklistTrialTest, AddFinchBlacklistToRegistry) { 159 // Create the field trial with the blacklist enabled group. 160 base::FieldTrialList field_trial_list( 161 new metrics::SHA1EntropyProvider("test")); 162 163 scoped_refptr<base::FieldTrial> trial(base::FieldTrialList::CreateFieldTrial( 164 kBrowserBlacklistTrialName, kBrowserBlacklistTrialEnabledGroupName)); 165 166 // Set up the trial with the desired parameters. 167 std::map<std::string, std::string> desired_params; 168 desired_params["TestDllName1"] = "TestDll1.dll"; 169 desired_params["TestDllName2"] = "TestDll2.dll"; 170 171 variations::AssociateVariationParams( 172 kBrowserBlacklistTrialName, 173 kBrowserBlacklistTrialEnabledGroupName, 174 desired_params); 175 176 // This should add the dlls in those parameters to the registry. 177 AddFinchBlacklistToRegistry(); 178 179 // Check that all the values in desired_params were added to the registry. 180 base::win::RegKey finch_blacklist_registry_key( 181 HKEY_CURRENT_USER, 182 blacklist::kRegistryFinchListPath, 183 KEY_QUERY_VALUE | KEY_SET_VALUE); 184 185 ASSERT_EQ(desired_params.size(), 186 finch_blacklist_registry_key.GetValueCount()); 187 188 for (std::map<std::string, std::string>::iterator it = desired_params.begin(); 189 it != desired_params.end(); 190 ++it) { 191 std::wstring name = base::UTF8ToWide(it->first); 192 ASSERT_TRUE(finch_blacklist_registry_key.HasValue(name.c_str())); 193 } 194 } 195 196 } // namespace 197