- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / installer / util / product_state_unittest.cc
1 // Copyright (c) 2011 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 <windows.h>
6
7 #include "base/strings/utf_string_conversions.h"
8 #include "base/test/test_reg_util_win.h"
9 #include "base/version.h"
10 #include "base/win/registry.h"
11 #include "chrome/installer/util/browser_distribution.h"
12 #include "chrome/installer/util/google_update_constants.h"
13 #include "chrome/installer/util/installation_state.h"
14 #include "chrome/installer/util/product_unittest.h"
15 #include "chrome/installer/util/util_constants.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 using base::win::RegKey;
19 using installer::ProductState;
20 using registry_util::RegistryOverrideManager;
21
22 class ProductStateTest : public testing::Test {
23  protected:
24   static void SetUpTestCase();
25   static void TearDownTestCase();
26
27   virtual void SetUp();
28   virtual void TearDown();
29
30   void ApplyUninstallCommand(const wchar_t* exe_path, const wchar_t* args);
31   void MinimallyInstallProduct(const wchar_t* version);
32
33   static BrowserDistribution* dist_;
34   static std::wstring temp_key_path_;
35   bool system_install_;
36   HKEY overridden_;
37   RegKey clients_;
38   RegKey client_state_;
39 };
40
41 BrowserDistribution* ProductStateTest::dist_;
42 std::wstring ProductStateTest::temp_key_path_;
43
44 // static
45 void ProductStateTest::SetUpTestCase() {
46   testing::Test::SetUpTestCase();
47
48   // We'll use Chrome as our test subject.
49   dist_ = BrowserDistribution::GetSpecificDistribution(
50       BrowserDistribution::CHROME_BROWSER);
51
52   // And we'll play in HKCU here:
53   temp_key_path_.assign(RegistryOverrideManager::kTempTestKeyPath)
54       .append(1, L'\\')
55       .append(L"ProductStateTest");
56 }
57
58 // static
59 void ProductStateTest::TearDownTestCase() {
60   temp_key_path_.clear();
61   dist_ = NULL;
62
63   testing::Test::TearDownTestCase();
64 }
65
66 void ProductStateTest::SetUp() {
67   testing::Test::SetUp();
68
69   // Create/open the keys for the product we'll test.
70   system_install_ = true;
71   overridden_ = (system_install_ ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER);
72
73   // Override for test purposes.  We don't use ScopedRegistryKeyOverride
74   // directly because it doesn't suit itself to our use here.
75   RegKey temp_key;
76   EXPECT_EQ(ERROR_SUCCESS,
77             temp_key.Create(HKEY_CURRENT_USER, temp_key_path_.c_str(),
78                             KEY_ALL_ACCESS));
79   EXPECT_EQ(ERROR_SUCCESS,
80             ::RegOverridePredefKey(overridden_, temp_key.Handle()));
81
82   EXPECT_EQ(ERROR_SUCCESS,
83             clients_.Create(overridden_, dist_->GetVersionKey().c_str(),
84                             KEY_ALL_ACCESS));
85   EXPECT_EQ(ERROR_SUCCESS,
86             client_state_.Create(overridden_, dist_->GetStateKey().c_str(),
87                                  KEY_ALL_ACCESS));
88 }
89
90 void ProductStateTest::TearDown() {
91   // Done with the keys.
92   client_state_.Close();
93   clients_.Close();
94   EXPECT_EQ(ERROR_SUCCESS, ::RegOverridePredefKey(overridden_, NULL));
95   overridden_ = NULL;
96   system_install_ = false;
97
98   // Shotgun approach to clearing out data we may have written.
99   RegistryOverrideManager::DeleteAllTempKeys();
100
101   testing::Test::TearDown();
102 }
103
104 void ProductStateTest::MinimallyInstallProduct(const wchar_t* version) {
105   EXPECT_EQ(ERROR_SUCCESS,
106             clients_.WriteValue(google_update::kRegVersionField, version));
107 }
108
109 void ProductStateTest::ApplyUninstallCommand(const wchar_t* exe_path,
110                                              const wchar_t* args) {
111   if (exe_path == NULL) {
112     LONG result = client_state_.DeleteValue(installer::kUninstallStringField);
113     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
114   } else {
115     EXPECT_EQ(ERROR_SUCCESS,
116               client_state_.WriteValue(installer::kUninstallStringField,
117                                        exe_path));
118   }
119
120   if (args == NULL) {
121     LONG result =
122         client_state_.DeleteValue(installer::kUninstallArgumentsField);
123     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
124   } else {
125     EXPECT_EQ(ERROR_SUCCESS,
126               client_state_.WriteValue(installer::kUninstallArgumentsField,
127                                        args));
128   }
129 }
130
131 TEST_F(ProductStateTest, InitializeInstalled) {
132   // Not installed.
133   {
134     ProductState state;
135     LONG result = clients_.DeleteValue(google_update::kRegVersionField);
136     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
137     EXPECT_FALSE(state.Initialize(system_install_, dist_));
138   }
139
140   // Empty version.
141   {
142     ProductState state;
143     LONG result = clients_.WriteValue(google_update::kRegVersionField, L"");
144     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
145     EXPECT_FALSE(state.Initialize(system_install_, dist_));
146   }
147
148   // Bogus version.
149   {
150     ProductState state;
151     LONG result = clients_.WriteValue(google_update::kRegVersionField,
152                                       L"goofy");
153     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
154     EXPECT_FALSE(state.Initialize(system_install_, dist_));
155   }
156
157   // Valid "pv" value.
158   {
159     ProductState state;
160     LONG result = clients_.WriteValue(google_update::kRegVersionField,
161                                       L"10.0.47.0");
162     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
163     EXPECT_TRUE(state.Initialize(system_install_, dist_));
164     EXPECT_EQ("10.0.47.0", state.version().GetString());
165   }
166 }
167
168 // Test extraction of the "opv" value from the Clients key.
169 TEST_F(ProductStateTest, InitializeOldVersion) {
170   MinimallyInstallProduct(L"10.0.1.1");
171
172   // No "opv" value.
173   {
174     ProductState state;
175     LONG result = clients_.DeleteValue(google_update::kRegOldVersionField);
176     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
177     EXPECT_TRUE(state.Initialize(system_install_, dist_));
178     EXPECT_TRUE(state.old_version() == NULL);
179   }
180
181   // Empty "opv" value.
182   {
183     ProductState state;
184     LONG result = clients_.WriteValue(google_update::kRegOldVersionField, L"");
185     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
186     EXPECT_TRUE(state.Initialize(system_install_, dist_));
187     EXPECT_TRUE(state.old_version() == NULL);
188   }
189
190   // Bogus "opv" value.
191   {
192     ProductState state;
193     LONG result = clients_.WriteValue(google_update::kRegOldVersionField,
194                                       L"coming home");
195     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
196     EXPECT_TRUE(state.Initialize(system_install_, dist_));
197     EXPECT_TRUE(state.old_version() == NULL);
198   }
199
200   // Valid "opv" value.
201   {
202     ProductState state;
203     LONG result = clients_.WriteValue(google_update::kRegOldVersionField,
204                                       L"10.0.47.0");
205     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
206     EXPECT_TRUE(state.Initialize(system_install_, dist_));
207     EXPECT_TRUE(state.old_version() != NULL);
208     EXPECT_EQ("10.0.47.0", state.old_version()->GetString());
209   }
210 }
211
212 // Test extraction of the "cmd" value from the Clients key.
213 TEST_F(ProductStateTest, InitializeRenameCmd) {
214   MinimallyInstallProduct(L"10.0.1.1");
215
216   // No "cmd" value.
217   {
218     ProductState state;
219     LONG result = clients_.DeleteValue(google_update::kRegRenameCmdField);
220     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
221     EXPECT_TRUE(state.Initialize(system_install_, dist_));
222     EXPECT_TRUE(state.rename_cmd().empty());
223   }
224
225   // Empty "cmd" value.
226   {
227     ProductState state;
228     LONG result = clients_.WriteValue(google_update::kRegRenameCmdField, L"");
229     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
230     EXPECT_TRUE(state.Initialize(system_install_, dist_));
231     EXPECT_TRUE(state.rename_cmd().empty());
232   }
233
234   // Valid "cmd" value.
235   {
236     ProductState state;
237     LONG result = clients_.WriteValue(google_update::kRegRenameCmdField,
238                                       L"spam.exe --spamalot");
239     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
240     EXPECT_TRUE(state.Initialize(system_install_, dist_));
241     EXPECT_EQ(L"spam.exe --spamalot", state.rename_cmd());
242   }
243 }
244
245 // Test extraction of the "ap" value from the ClientState key.
246 TEST_F(ProductStateTest, InitializeChannelInfo) {
247   MinimallyInstallProduct(L"10.0.1.1");
248
249   // No "ap" value.
250   {
251     ProductState state;
252     LONG result = client_state_.DeleteValue(google_update::kRegApField);
253     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
254     EXPECT_TRUE(state.Initialize(system_install_, dist_));
255     EXPECT_TRUE(state.channel().value().empty());
256   }
257
258   // Empty "ap" value.
259   {
260     ProductState state;
261     LONG result = client_state_.WriteValue(google_update::kRegApField, L"");
262     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
263     EXPECT_TRUE(state.Initialize(system_install_, dist_));
264     EXPECT_TRUE(state.channel().value().empty());
265   }
266
267   // Valid "ap" value.
268   {
269     ProductState state;
270     LONG result = client_state_.WriteValue(google_update::kRegApField, L"spam");
271     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
272     EXPECT_TRUE(state.Initialize(system_install_, dist_));
273     EXPECT_EQ(L"spam", state.channel().value());
274   }
275 }
276
277 // Test extraction of the uninstall command and arguments from the ClientState
278 // key.
279 TEST_F(ProductStateTest, InitializeUninstallCommand) {
280   MinimallyInstallProduct(L"10.0.1.1");
281
282   // No uninstall command.
283   {
284     ProductState state;
285     ApplyUninstallCommand(NULL, NULL);
286     EXPECT_TRUE(state.Initialize(system_install_, dist_));
287     EXPECT_TRUE(state.GetSetupPath().empty());
288     EXPECT_TRUE(state.uninstall_command().GetCommandLineString().empty());
289     EXPECT_TRUE(state.uninstall_command().GetSwitches().empty());
290   }
291
292   // Empty values.
293   {
294     ProductState state;
295     ApplyUninstallCommand(L"", L"");
296     EXPECT_TRUE(state.Initialize(system_install_, dist_));
297     EXPECT_TRUE(state.GetSetupPath().empty());
298     EXPECT_TRUE(state.uninstall_command().GetCommandLineString().empty());
299     EXPECT_TRUE(state.uninstall_command().GetSwitches().empty());
300   }
301
302   // Uninstall command without exe.
303   {
304     ProductState state;
305     ApplyUninstallCommand(NULL, L"--uninstall");
306     EXPECT_TRUE(state.Initialize(system_install_, dist_));
307     EXPECT_TRUE(state.GetSetupPath().empty());
308     EXPECT_EQ(L" --uninstall",
309               state.uninstall_command().GetCommandLineString());
310     EXPECT_EQ(1U, state.uninstall_command().GetSwitches().size());
311   }
312
313   // Uninstall command without args.
314   {
315     ProductState state;
316     ApplyUninstallCommand(L"setup.exe", NULL);
317     EXPECT_TRUE(state.Initialize(system_install_, dist_));
318     EXPECT_EQ(L"setup.exe", state.GetSetupPath().value());
319     EXPECT_EQ(L"setup.exe", state.uninstall_command().GetCommandLineString());
320     EXPECT_TRUE(state.uninstall_command().GetSwitches().empty());
321   }
322
323   // Uninstall command with exe that requires quoting.
324   {
325     ProductState state;
326     ApplyUninstallCommand(L"set up.exe", NULL);
327     EXPECT_TRUE(state.Initialize(system_install_, dist_));
328     EXPECT_EQ(L"set up.exe", state.GetSetupPath().value());
329     EXPECT_EQ(L"\"set up.exe\"",
330               state.uninstall_command().GetCommandLineString());
331     EXPECT_TRUE(state.uninstall_command().GetSwitches().empty());
332   }
333
334   // Uninstall command with both exe and args.
335   {
336     ProductState state;
337     ApplyUninstallCommand(L"setup.exe", L"--uninstall");
338     EXPECT_TRUE(state.Initialize(system_install_, dist_));
339     EXPECT_EQ(L"setup.exe", state.GetSetupPath().value());
340     EXPECT_EQ(L"setup.exe --uninstall",
341               state.uninstall_command().GetCommandLineString());
342     EXPECT_EQ(1U, state.uninstall_command().GetSwitches().size());
343   }
344 }
345
346 // Test extraction of the msi marker from the ClientState key.
347 TEST_F(ProductStateTest, InitializeMsi) {
348   MinimallyInstallProduct(L"10.0.1.1");
349
350   // No msi marker.
351   {
352     ProductState state;
353     LONG result = client_state_.DeleteValue(google_update::kRegMSIField);
354     EXPECT_TRUE(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
355     EXPECT_TRUE(state.Initialize(system_install_, dist_));
356     EXPECT_FALSE(state.is_msi());
357   }
358
359   // Msi marker set to zero.
360   {
361     ProductState state;
362     EXPECT_EQ(ERROR_SUCCESS,
363               client_state_.WriteValue(google_update::kRegMSIField,
364                                        static_cast<DWORD>(0)));
365     EXPECT_TRUE(state.Initialize(system_install_, dist_));
366     EXPECT_FALSE(state.is_msi());
367   }
368
369   // Msi marker set to one.
370   {
371     ProductState state;
372     EXPECT_EQ(ERROR_SUCCESS,
373               client_state_.WriteValue(google_update::kRegMSIField,
374                                        static_cast<DWORD>(1)));
375     EXPECT_TRUE(state.Initialize(system_install_, dist_));
376     EXPECT_TRUE(state.is_msi());
377   }
378
379   // Msi marker set to a bogus DWORD.
380   {
381     ProductState state;
382     EXPECT_EQ(ERROR_SUCCESS,
383               client_state_.WriteValue(google_update::kRegMSIField,
384                                        static_cast<DWORD>(47)));
385     EXPECT_TRUE(state.Initialize(system_install_, dist_));
386     EXPECT_TRUE(state.is_msi());
387   }
388
389   // Msi marker set to a bogus string.
390   {
391     ProductState state;
392     EXPECT_EQ(ERROR_SUCCESS,
393               client_state_.WriteValue(google_update::kRegMSIField,
394                                        L"bogus!"));
395     EXPECT_TRUE(state.Initialize(system_install_, dist_));
396     EXPECT_FALSE(state.is_msi());
397   }
398 }
399
400 // Test detection of multi-install.
401 TEST_F(ProductStateTest, InitializeMultiInstall) {
402   MinimallyInstallProduct(L"10.0.1.1");
403
404   // No uninstall command means single install.
405   {
406     ProductState state;
407     ApplyUninstallCommand(NULL, NULL);
408     EXPECT_TRUE(state.Initialize(system_install_, dist_));
409     EXPECT_FALSE(state.is_multi_install());
410   }
411
412   // Uninstall command without --multi-install is single install.
413   {
414     ProductState state;
415     ApplyUninstallCommand(L"setup.exe", L"--uninstall");
416     EXPECT_TRUE(state.Initialize(system_install_, dist_));
417     EXPECT_FALSE(state.is_multi_install());
418   }
419
420   // Uninstall command with --multi-install is multi install.
421   {
422     ProductState state;
423     ApplyUninstallCommand(L"setup.exe",
424                           L"--uninstall --chrome --multi-install");
425     EXPECT_TRUE(state.Initialize(system_install_, dist_));
426     EXPECT_TRUE(state.is_multi_install());
427   }
428 }