Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Side by Side Diff: chrome/installer/util/beacons_unittest.cc

Issue 1146843003: Beacons for tracking default browser status. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: revise active setup version Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 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/installer/util/beacons.h"
6
7 #include "base/base_paths.h"
8 #include "base/memory/scoped_vector.h"
9 #include "base/path_service.h"
10 #include "base/test/scoped_path_override.h"
11 #include "base/test/test_reg_util_win.h"
12 #include "base/win/registry.h"
13 #include "base/win/win_util.h"
14 #include "chrome/installer/util/browser_distribution.h"
15 #include "chrome/installer/util/test_app_registration_data.h"
16 #include "chrome/installer/util/util_constants.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 using ::testing::Bool;
20 using ::testing::Combine;
21 using ::testing::Values;
22
23 class TestBeacon : public Beacon {
gab 2015/05/26 18:54:35 So a TestBeacon is a Beacon with a public construc
grt (UTC plus 2) 2015/05/26 20:54:02 I've seen and used this from time to time. I find
gab 2015/05/29 13:37:36 Well at least friend puts the code owner of Beacon
grt (UTC plus 2) 2015/05/29 15:31:10 Rejiggered as discussed.
24 public:
25 using BeaconType = Beacon::BeaconType;
26 using BeaconScope = Beacon::BeaconScope;
27
28 TestBeacon(base::StringPiece16 name,
29 BeaconType type,
30 BeaconScope scope,
31 bool system_install,
32 const AppRegistrationData& registration_data)
33 : Beacon(name, type, scope, system_install, registration_data) {}
34 };
35
36 // A test fixture that exercises a test beacon.
37 class BeaconTest
38 : public ::testing::TestWithParam<::testing::tuple<TestBeacon::BeaconType,
39 TestBeacon::BeaconScope,
40 bool>> {
gab 2015/05/26 18:54:35 I think you can name the parameters here (doesn't
grt (UTC plus 2) 2015/05/26 20:54:02 Do you mean BeaconType, BeaconScope, and bool? Tho
gab 2015/05/29 13:37:37 Ah ok, I guess I was recalling something like base
41 protected:
42 static const base::char16 kBeaconName[];
43
44 BeaconTest()
45 : beacon_type_(::testing::get<0>(GetParam())),
46 beacon_scope_(::testing::get<1>(GetParam())),
47 system_install_(::testing::get<2>(GetParam())),
48 beacon_(kBeaconName,
49 beacon_type_,
50 beacon_scope_,
51 system_install_,
52 app_registration_data_) {
53 // Override the registry so that tests can freely push state to it.
54 registry_override_manager_.OverrideRegistry(HKEY_CURRENT_USER);
55 registry_override_manager_.OverrideRegistry(HKEY_LOCAL_MACHINE);
56 }
57
58 TestAppRegistrationData app_registration_data_;
59 TestBeacon::BeaconType beacon_type_;
60 TestBeacon::BeaconScope beacon_scope_;
61 bool system_install_;
62 TestBeacon beacon_;
63 registry_util::RegistryOverrideManager registry_override_manager_;
gab 2015/05/26 18:54:35 This member should be private IMO, no reason the t
grt (UTC plus 2) 2015/05/26 20:54:01 Done.
64 };
65
66 // static
67 const base::char16 BeaconTest::kBeaconName[] = L"TestBeacon";
68
69 // Nothing in the regsitry, so the becon should not exist.
gab 2015/05/26 18:54:35 s/becon/beacon
grt (UTC plus 2) 2015/05/26 20:54:02 Done.
70 TEST_P(BeaconTest, GetNonExistant) {
71 ASSERT_TRUE(beacon_.Get().is_null());
72 }
73
74 // Updating and then getting the beacon should return a value.
75 TEST_P(BeaconTest, UpdateAndGet) {
76 beacon_.Update();
77 ASSERT_FALSE(beacon_.Get().is_null());
78 }
79
80 // Tests that updating a first beacon only updates it the first time, but doing
81 // so for a last beacon always updates.
82 TEST_P(BeaconTest, UpdateTwice) {
83 beacon_.Update();
84 base::Time beacon_time(beacon_.Get());
85
86 beacon_.Update();
gab 2015/05/26 18:54:35 Should there be some kind of sleep before this Upd
grt (UTC plus 2) 2015/05/26 20:54:01 Done.
87 if (beacon_type_ == TestBeacon::BeaconType::FIRST) {
88 ASSERT_EQ(beacon_time, beacon_.Get());
89 } else {
90 ASSERT_NE(beacon_time, beacon_.Get());
91 }
92 }
93
94 // Tests that the beacon is written into the proper location in the registry.
95 TEST_P(BeaconTest, Location) {
96 beacon_.Update();
97 HKEY right_root = system_install_ ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
98 HKEY wrong_root = system_install_ ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE;
99 base::string16 right_key;
100 base::string16 wrong_key;
101 base::string16 value_name;
102
103 if (beacon_scope_ == TestBeacon::BeaconScope::PER_INSTALL ||
104 !system_install_) {
105 value_name = kBeaconName;
106 right_key = app_registration_data_.GetStateKey();
107 wrong_key = app_registration_data_.GetStateMediumKey();
108 } else {
109 ASSERT_TRUE(base::win::GetUserSidString(&value_name));
110 right_key =
111 app_registration_data_.GetStateMediumKey() + L"\\" + kBeaconName;
112 wrong_key = app_registration_data_.GetStateKey();
113 }
114
115 // Keys should not exist in the wrong root or in the right root but wrong key.
116 ASSERT_FALSE(base::win::RegKey(wrong_root, right_key.c_str(),
117 KEY_READ).Valid()) << right_key;
118 ASSERT_FALSE(base::win::RegKey(wrong_root, wrong_key.c_str(),
119 KEY_READ).Valid()) << wrong_key;
120 ASSERT_FALSE(base::win::RegKey(right_root, wrong_key.c_str(),
121 KEY_READ).Valid()) << wrong_key;
122 // The right key should exist.
123 base::win::RegKey key(right_root, right_key.c_str(), KEY_READ);
124 ASSERT_TRUE(key.Valid()) << right_key;
125 // And should have the value.
126 ASSERT_TRUE(key.HasValue(value_name.c_str())) << value_name;
gab 2015/05/26 18:54:35 Should also test that we can reconstruct a reasona
grt (UTC plus 2) 2015/05/26 20:54:01 Done in UpdateAndGet.
127 }
128
129 // Run the tests for all combinations of beacon type, scope, and install level.
130 INSTANTIATE_TEST_CASE_P(BeaconTest,
131 BeaconTest,
132 Combine(Values(TestBeacon::BeaconType::FIRST,
133 TestBeacon::BeaconType::LAST),
134 Values(TestBeacon::BeaconScope::PER_USER,
135 TestBeacon::BeaconScope::PER_INSTALL),
136 Bool()));
137
138 enum class DistributionVariant {
139 SYSTEM_LEVEL_CHROME,
140 USER_LEVEL_CHROME,
141 CHROME_SXS,
gab 2015/05/26 18:54:35 I'd remove CHROME from all of these (since enum cl
grt (UTC plus 2) 2015/05/26 20:54:01 Done.
142 };
143
144 class DefaultBrowserBeaconTest
145 : public ::testing::TestWithParam<DistributionVariant> {
146 protected:
147 using Super = ::testing::TestWithParam<DistributionVariant>;
148
149 DefaultBrowserBeaconTest()
150 : system_install_(GetParam() == DistributionVariant::SYSTEM_LEVEL_CHROME),
151 chrome_sxs_(GetParam() == DistributionVariant::CHROME_SXS),
gab 2015/05/26 18:54:35 Curious, why is Chrome SxS different than regular
grt (UTC plus 2) 2015/05/26 20:54:01 It should be the same, yes.
152 chrome_exe_(GetChromePath()),
153 distribution_(nullptr) {}
154
155 void SetUp() override {
156 Super::SetUp();
157
158 // Override FILE_EXE so that various InstallUtil functions will consider
159 // this to be a user/system Chrome or Chrome SxS.
160 path_overrides_.push_back(new base::ScopedPathOverride(
161 base::FILE_EXE, chrome_exe_, true /* is_absolute */,
162 false /* !create */));
163
164 // Override these paths with their own values so that they can be found
165 // after the registry override manager is in place. Getting them would
166 // otherwise fail since the underlying calls to the OS need to see the real
167 // contents of the registry.
168 static const int kPathKeys[] = {
169 base::DIR_PROGRAM_FILES,
170 base::DIR_PROGRAM_FILESX86,
171 base::DIR_LOCAL_APP_DATA,
172 };
173 for (int key : kPathKeys) {
174 base::FilePath temp;
175 PathService::Get(key, &temp);
176 path_overrides_.push_back(new base::ScopedPathOverride(key, temp));
177 }
178
179 // Override the registry so that tests can freely push state to it.
180 registry_override_manager_.OverrideRegistry(HKEY_CURRENT_USER);
181 registry_override_manager_.OverrideRegistry(HKEY_LOCAL_MACHINE);
182
183 distribution_ = BrowserDistribution::GetDistribution();
184 }
185
186 base::FilePath GetChromePath() const {
gab 2015/05/26 18:54:35 Move to private section. And I'd call this GetChr
grt (UTC plus 2) 2015/05/26 20:54:01 Done.
187 base::FilePath chrome_exe;
188 int dir_key = base::DIR_LOCAL_APP_DATA;
189
190 if (system_install_) {
191 #if defined(_WIN64)
192 static const int kSystemKey = base::DIR_PROGRAM_FILESX86;
193 #else
194 static const int kSystemKey = base::DIR_PROGRAM_FILES;
195 #endif
196 dir_key = kSystemKey;
197 }
198 PathService::Get(dir_key, &chrome_exe);
199 #if defined(GOOGLE_CHROME_BUILD)
200 chrome_exe = chrome_exe.Append(installer::kGoogleChromeInstallSubDir1);
201 if (chrome_sxs_) {
202 chrome_exe = chrome_exe.Append(
203 base::string16(installer::kGoogleChromeInstallSubDir2) +
204 installer::kSxSSuffix);
205 } else {
206 chrome_exe = chrome_exe.Append(installer::kGoogleChromeInstallSubDir2);
207 }
208 #else
209 chrome_exe = chrome_exe.AppendASCII("Chromium");
210 #endif
211 chrome_exe = chrome_exe.Append(installer::kInstallBinaryDir);
212 return chrome_exe.Append(installer::kChromeExe);
213 }
214
215 bool system_install_;
216 bool chrome_sxs_;
217 base::FilePath chrome_exe_;
218 ScopedVector<base::ScopedPathOverride> path_overrides_;
219 registry_util::RegistryOverrideManager registry_override_manager_;
gab 2015/05/26 18:54:35 Move these two member to private:
grt (UTC plus 2) 2015/05/26 20:54:02 Done.
220 BrowserDistribution* distribution_;
221 };
222
223 // Tests that the default browser beacons work as expected.
224 TEST_P(DefaultBrowserBeaconTest, Test) {
gab 2015/05/26 18:54:35 s/Test/All ? (feels weird to have a test named "Te
grt (UTC plus 2) 2015/05/26 20:54:02 "All" is more descriptive? Done.
gab 2015/05/29 13:37:36 I find so, i.e. it tests "everything" rather than
grt (UTC plus 2) 2015/05/29 15:31:10 I'm okay with "All".
225 scoped_ptr<Beacon> last_was_default(Beacon::LastWasDefault(
226 system_install_, distribution_->GetAppRegistrationData()));
227 scoped_ptr<Beacon> first_not_default(Beacon::FirstNotDefault(
228 system_install_, distribution_->GetAppRegistrationData()));
229
230 ASSERT_TRUE(last_was_default->Get().is_null());
231 ASSERT_TRUE(first_not_default->Get().is_null());
232
233 // Chrome is not default.
234 UpdateDefaultBrowserBeacon(chrome_exe_, distribution_,
235 ShellUtil::NOT_DEFAULT);
236 ASSERT_TRUE(last_was_default->Get().is_null());
237 ASSERT_FALSE(first_not_default->Get().is_null());
238
239 // Then it is.
240 UpdateDefaultBrowserBeacon(chrome_exe_, distribution_, ShellUtil::IS_DEFAULT);
241 ASSERT_FALSE(last_was_default->Get().is_null());
242 ASSERT_TRUE(first_not_default->Get().is_null());
243
244 // It still is.
245 UpdateDefaultBrowserBeacon(chrome_exe_, distribution_, ShellUtil::IS_DEFAULT);
246 ASSERT_FALSE(last_was_default->Get().is_null());
247 ASSERT_TRUE(first_not_default->Get().is_null());
248
249 // Now it's not again.
250 UpdateDefaultBrowserBeacon(chrome_exe_, distribution_,
251 ShellUtil::NOT_DEFAULT);
252 ASSERT_FALSE(last_was_default->Get().is_null());
253 ASSERT_FALSE(first_not_default->Get().is_null());
254
255 // And it still isn't.
256 UpdateDefaultBrowserBeacon(chrome_exe_, distribution_,
257 ShellUtil::NOT_DEFAULT);
258 ASSERT_FALSE(last_was_default->Get().is_null());
259 ASSERT_FALSE(first_not_default->Get().is_null());
gab 2015/05/26 18:54:35 Shouldn't this test also check that the timestamps
grt (UTC plus 2) 2015/05/26 20:54:01 BeaconTest::UpdateAndGet and UpdateTwice cover eve
260 }
261
262 INSTANTIATE_TEST_CASE_P(SystemLevelChrome,
263 DefaultBrowserBeaconTest,
264 Values(DistributionVariant::SYSTEM_LEVEL_CHROME));
265 INSTANTIATE_TEST_CASE_P(UserLevelChrome,
gab 2015/05/26 18:54:35 Oh cool, didn't know we could split various parame
grt (UTC plus 2) 2015/05/26 20:54:01 Acknowledged.
266 DefaultBrowserBeaconTest,
267 Values(DistributionVariant::USER_LEVEL_CHROME));
268 #if 0 && defined(GOOGLE_CHROME_BUILD)
269 // Disabled for now since InstallUtil::IsChromeSxSProcess makes this impossible.
gab 2015/05/26 18:54:35 Why? Can't we override DIR_EXE to fake this? i.e.
grt (UTC plus 2) 2015/05/26 20:54:01 That was what I hoped, except that it doesn't work
270 INSTANTIATE_TEST_CASE_P(ChromeSxS, DefaultBrowserBeaconTest,
271 Values(DistributionVariant::CHROME_SXS));
272 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698