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

Side by Side Diff: chrome/install_static/product_install_details_unittest.cc

Issue 2422643002: Windows install_static refactor. (Closed)
Patch Set: sync to position 431863 Created 4 years, 1 month 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 2016 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/install_static/product_install_details.h"
6
7 #include "base/base_paths.h"
8 #include "base/files/file_path.h"
9 #include "base/i18n/case_conversion.h"
10 #include "base/macros.h"
11 #include "base/path_service.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/test/test_reg_util_win.h"
14 #include "base/win/registry.h"
15 #include "base/win/windows_version.h"
16 #include "chrome/install_static/install_constants.h"
17 #include "chrome/install_static/install_modes.h"
18 #include "chrome_elf/nt_registry/nt_registry.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 using ::testing::Eq;
23 using ::testing::StrEq;
24
25 namespace install_static {
26
27 namespace {
28
29 TEST(ProductInstallDetailsTest, IsPathParentOf) {
30 std::wstring path = L"C:\\Program Files\\Company\\Product\\Application\\foo";
31 static constexpr const wchar_t* kFalseExpectations[] = {
32 L"",
33 L"\\",
34 L"\\\\",
35 L"C:\\Program File",
36 L"C:\\Program Filesz",
37 };
38 for (const wchar_t* false_expectation : kFalseExpectations) {
39 EXPECT_FALSE(IsPathParentOf(
40 false_expectation, std::wstring::traits_type::length(false_expectation),
41 path));
42 }
43
44 static constexpr const wchar_t* kTrueExpectations[] = {
45 L"C:\\Program Files",
46 L"C:\\PROGRAM FILES",
47 L"C:\\Program Files\\",
48 L"C:\\Program Files\\\\\\",
49 };
50 for (const wchar_t* true_expectation : kTrueExpectations) {
51 EXPECT_TRUE(IsPathParentOf(
52 true_expectation, std::wstring::traits_type::length(true_expectation),
53 path));
54 }
55 }
56
57 TEST(ProductInstallDetailsTest, PathIsInProgramFiles) {
58 static constexpr const wchar_t* kInvalidPaths[] = {
59 L"",
60 L"hello",
61 L"C:\\Program File",
62 L"C:\\Program Filesz",
63 L"C:\\foo\\Program Files",
64 L"C:\\foo\\Program Files\\",
65 L"C:\\foo\\Program Files (x86)",
66 L"C:\\foo\\Program Files (x86)\\",
67 };
68 for (const wchar_t* invalid : kInvalidPaths)
69 EXPECT_FALSE(PathIsInProgramFiles(invalid)) << invalid;
70
71 // 32-bit on 32-bit: only check C:\Program Files.
72 // 32-bit and 64-bit on 64-bit: check both.
73 const bool is_x64 = base::win::OSInfo::GetInstance()->architecture() !=
74 base::win::OSInfo::X86_ARCHITECTURE;
75 std::vector<int> program_files_keys;
76 program_files_keys.push_back(base::DIR_PROGRAM_FILESX86);
77 if (is_x64)
78 program_files_keys.push_back(base::DIR_PROGRAM_FILES6432);
79 std::vector<std::wstring> program_files_paths;
80 for (int key : program_files_keys) {
81 base::FilePath path;
82 ASSERT_TRUE(base::PathService::Get(key, &path));
83 program_files_paths.push_back(path.value());
84 }
85
86 static constexpr const wchar_t* kValidFormats[] = {
87 L"%ls",
88 L"%ls\\",
89 L"%ls\\spam",
90 };
91 for (const wchar_t* valid : kValidFormats) {
92 for (const std::wstring& program_files_path : program_files_paths) {
93 std::wstring path = base::StringPrintf(valid, program_files_path.c_str());
94 EXPECT_TRUE(PathIsInProgramFiles(path)) << path;
95
96 path = base::StringPrintf(
97 valid, base::i18n::ToLower(program_files_path).c_str());
98 EXPECT_TRUE(PathIsInProgramFiles(path)) << path;
99 }
100 }
101 }
102
103 TEST(ProductInstallDetailsTest, GetInstallSuffix) {
104 std::wstring suffix;
105 const std::pair<const wchar_t*, const wchar_t*> kData[] = {
106 {L"%ls\\Application", L""},
107 {L"%ls\\Application\\", L""},
108 {L"\\%ls\\Application", L""},
109 {L"\\%ls\\Application\\", L""},
110 {L"C:\\foo\\%ls\\Application\\foo.exe", L""},
111 {L"%ls Blorf\\Application", L" Blorf"},
112 {L"%ls Blorf\\Application\\", L" Blorf"},
113 {L"\\%ls Blorf\\Application", L" Blorf"},
114 {L"\\%ls Blorf\\Application\\", L" Blorf"},
115 {L"C:\\foo\\%ls Blorf\\Application\\foo.exe", L" Blorf"},
116 };
117 for (const auto& data : kData) {
118 const std::wstring path = base::StringPrintf(data.first, kProductPathName);
119 EXPECT_EQ(std::wstring(data.second), GetInstallSuffix(path)) << path;
120 }
121 }
122
123 struct TestData {
124 const wchar_t* path;
125 InstallConstantIndex index;
126 bool system_level;
127 const wchar_t* channel;
128 };
129
130 #if defined(GOOGLE_CHROME_BUILD)
131 constexpr TestData kTestData[] = {
132 {
133 L"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe",
134 STABLE_INDEX, true, L"",
135 },
136 {
137 L"C:\\Users\\user\\AppData\\Local\\Google\\Chrome\\Application"
138 L"\\chrome.exe",
139 STABLE_INDEX, false, L"",
140 },
141 {
142 L"C:\\Users\\user\\AppData\\Local\\Google\\Chrome SxS\\Application"
143 L"\\chrome.exe",
144 CANARY_INDEX, false, L"canary",
145 },
146 {
147 L"C:\\Users\\user\\AppData\\Local\\Google\\CHROME SXS\\application"
148 L"\\chrome.exe",
149 CANARY_INDEX, false, L"canary",
150 },
151 };
152 #else // GOOGLE_CHROME_BUILD
153 constexpr TestData kTestData[] = {
154 {
155 L"C:\\Program Files (x86)\\Chromium\\Application\\chrome.exe",
156 CHROMIUM_INDEX, true, L"",
157 },
158 {
159 L"C:\\Users\\user\\AppData\\Local\\Chromium\\Application\\chrome.exe",
160 CHROMIUM_INDEX, false, L"",
161 },
162 };
163 #endif // !GOOGLE_CHROME_BUILD
164
165 } // namespace
166
167 // Test that MakeProductDetails properly sniffs out an install's details.
168 class MakeProductDetailsTest : public testing::TestWithParam<TestData> {
169 protected:
170 MakeProductDetailsTest()
171 : test_data_(GetParam()),
172 root_key_(test_data_.system_level ? HKEY_LOCAL_MACHINE
173 : HKEY_CURRENT_USER),
174 nt_root_key_(test_data_.system_level ? nt::HKLM : nt::HKCU) {
175 base::string16 path;
176 override_manager_.OverrideRegistry(root_key_, &path);
177 nt::SetTestingOverride(nt_root_key_, path);
178 }
179
180 ~MakeProductDetailsTest() {
181 nt::SetTestingOverride(nt_root_key_, base::string16());
182 }
183
184 const TestData& test_data() const { return test_data_; }
185
186 void SetUninstallArguments(const wchar_t* value) {
187 ASSERT_THAT(
188 base::win::RegKey(root_key_, GetClientStateKeyPath(false).c_str(),
189 KEY_WOW64_32KEY | KEY_SET_VALUE)
190 .WriteValue(L"UninstallArguments", value),
191 Eq(ERROR_SUCCESS));
192 }
193
194 void SetAp(const wchar_t* value, bool binaries) {
195 ASSERT_TRUE(!binaries ||
196 kInstallModes[test_data().index].supports_multi_install);
197 ASSERT_THAT(
198 base::win::RegKey(root_key_, GetClientStateKeyPath(binaries).c_str(),
199 KEY_WOW64_32KEY | KEY_SET_VALUE)
200 .WriteValue(L"ap", value),
201 Eq(ERROR_SUCCESS));
202 }
203
204 private:
205 // Returns the registry path for the product's ClientState key.
206 std::wstring GetClientStateKeyPath(bool binaries) {
207 EXPECT_TRUE(!binaries ||
208 kInstallModes[test_data().index].supports_multi_install);
209 std::wstring result(L"Software\\");
210 if (kUseGoogleUpdateIntegration) {
211 result.append(L"Google\\Update\\ClientState\\");
212 if (binaries)
213 result.append(kBinariesAppGuid);
214 else
215 result.append(kInstallModes[test_data().index].app_guid);
216 } else if (binaries) {
217 result.append(kBinariesPathName);
218 } else {
219 result.append(kProductPathName);
220 }
221 return result;
222 }
223
224 registry_util::RegistryOverrideManager override_manager_;
225 const TestData& test_data_;
226 HKEY root_key_;
227 nt::ROOT_KEY nt_root_key_;
228
229 DISALLOW_COPY_AND_ASSIGN(MakeProductDetailsTest);
230 };
231
232 // Test that the install mode is sniffed properly based on the path.
233 TEST_P(MakeProductDetailsTest, Index) {
234 std::unique_ptr<PrimaryInstallDetails> details(
235 MakeProductDetails(test_data().path));
236 EXPECT_THAT(details->install_mode_index(), Eq(test_data().index));
237 }
238
239 // Test that user/system level is sniffed properly based on the path.
240 TEST_P(MakeProductDetailsTest, SystemLevel) {
241 std::unique_ptr<PrimaryInstallDetails> details(
242 MakeProductDetails(test_data().path));
243 EXPECT_THAT(details->system_level(), Eq(test_data().system_level));
244 }
245
246 // Test that the default channel is sniffed properly based on the path.
247 TEST_P(MakeProductDetailsTest, DefaultChannel) {
248 std::unique_ptr<PrimaryInstallDetails> details(
249 MakeProductDetails(test_data().path));
250 EXPECT_THAT(details->channel(), StrEq(test_data().channel));
251 }
252
253 // Test that multi-install is properly parsed out of the registry.
254 TEST_P(MakeProductDetailsTest, MultiInstall) {
255 {
256 std::unique_ptr<PrimaryInstallDetails> details(
257 MakeProductDetails(test_data().path));
258 EXPECT_FALSE(details->multi_install());
259 }
260
261 {
262 SetUninstallArguments(L"--uninstall");
263 std::unique_ptr<PrimaryInstallDetails> details(
264 MakeProductDetails(test_data().path));
265 EXPECT_FALSE(details->multi_install());
266 }
267
268 if (!kInstallModes[test_data().index].supports_multi_install)
269 return;
270
271 {
272 SetUninstallArguments(L"--uninstall --multi-install --chrome");
273 std::unique_ptr<PrimaryInstallDetails> details(
274 MakeProductDetails(test_data().path));
275 EXPECT_TRUE(details->multi_install());
276 }
277 }
278
279 // Test that the channel name is properly parsed out of additional parameters.
280 TEST_P(MakeProductDetailsTest, AdditionalParametersChannels) {
281 const std::pair<const wchar_t*, const wchar_t*> kApChannels[] = {
282 // stable
283 {L"", L""},
284 {L"-full", L""},
285 {L"x64-stable", L""},
286 {L"x64-stable-full", L""},
287 {L"baz-x64-stable", L""},
288 {L"foo-1.1-beta", L""},
289 {L"2.0-beta", L""},
290 {L"bar-2.0-dev", L""},
291 {L"1.0-dev", L""},
292 {L"fuzzy", L""},
293 {L"foo", L""},
294 {L"-multi-chrome", L""},
295 {L"x64-stable-multi-chrome", L""},
296 {L"-stage:ensemble_patching-multi-chrome-full", L""},
297 {L"-multi-chrome-full", L""},
298 // beta
299 {L"1.1-beta", L"beta"},
300 {L"1.1-beta-full", L"beta"},
301 {L"x64-beta", L"beta"},
302 {L"x64-beta-full", L"beta"},
303 {L"1.1-bar", L"beta"},
304 {L"1n1-foobar", L"beta"},
305 {L"x64-Beta", L"beta"},
306 {L"bar-x64-beta", L"beta"},
307 // dev
308 {L"2.0-dev", L"dev"},
309 {L"2.0-dev-full", L"dev"},
310 {L"x64-dev", L"dev"},
311 {L"x64-dev-full", L"dev"},
312 {L"2.0-DEV", L"dev"},
313 {L"2.0-dev-eloper", L"dev"},
314 {L"2.0-doom", L"dev"},
315 {L"250-doom", L"dev"},
316 };
317
318 for (const auto& ap_and_channel : kApChannels) {
319 SetAp(ap_and_channel.first, false);
320 std::unique_ptr<PrimaryInstallDetails> details(
321 MakeProductDetails(test_data().path));
322 if (kInstallModes[test_data().index].channel_strategy ==
323 ChannelStrategy::ADDITIONAL_PARAMETERS) {
324 EXPECT_THAT(details->channel(), StrEq(ap_and_channel.second));
325 } else {
326 // "ap" is ignored for this mode.
327 EXPECT_THAT(details->channel(), StrEq(test_data().channel));
328 }
329 }
330
331 if (!kInstallModes[test_data().index].supports_multi_install)
332 return;
333
334 // For multi-install modes, "ap" is pulled from the binaries' key.
335 for (const auto& ap_and_channel : kApChannels) {
336 SetAp(ap_and_channel.first, true);
337 SetUninstallArguments(L"--uninstall --multi-install --chrome");
338 std::unique_ptr<PrimaryInstallDetails> details(
339 MakeProductDetails(test_data().path));
340 if (kInstallModes[test_data().index].channel_strategy ==
341 ChannelStrategy::ADDITIONAL_PARAMETERS) {
342 EXPECT_THAT(details->channel(), StrEq(ap_and_channel.second));
343 } else {
344 // "ap" is ignored for this mode.
345 EXPECT_THAT(details->channel(), StrEq(test_data().channel));
346 }
347 }
348 }
349
350 INSTANTIATE_TEST_CASE_P(All,
351 MakeProductDetailsTest,
352 testing::ValuesIn(kTestData));
353
354 } // namespace install_static
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698