google_update_settings_unittest.cc revision 868fa2fe829687343ffae624259930155e16dbd8
1// Copyright (c) 2012 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#include <shlwapi.h>  // For SHDeleteKey.
7
8#include "base/memory/scoped_ptr.h"
9#include "base/strings/utf_string_conversions.h"
10#include "base/test/test_reg_util_win.h"
11#include "base/win/registry.h"
12#include "chrome/common/chrome_constants.h"
13#include "chrome/installer/util/browser_distribution.h"
14#include "chrome/installer/util/channel_info.h"
15#include "chrome/installer/util/fake_installation_state.h"
16#include "chrome/installer/util/google_update_constants.h"
17#include "chrome/installer/util/google_update_settings.h"
18#include "chrome/installer/util/util_constants.h"
19#include "chrome/installer/util/work_item_list.h"
20#include "testing/gtest/include/gtest/gtest.h"
21
22using base::win::RegKey;
23using installer::ChannelInfo;
24
25namespace {
26
27const wchar_t kGoogleUpdatePoliciesKey[] =
28    L"SOFTWARE\\Policies\\Google\\Update";
29const wchar_t kGoogleUpdateUpdateDefault[] = L"UpdateDefault";
30const wchar_t kGoogleUpdateUpdatePrefix[] = L"Update";
31const GoogleUpdateSettings::UpdatePolicy kDefaultUpdatePolicy =
32#if defined(GOOGLE_CHROME_BUILD)
33    GoogleUpdateSettings::AUTOMATIC_UPDATES;
34#else
35    GoogleUpdateSettings::UPDATES_DISABLED;
36#endif
37
38const wchar_t kTestProductGuid[] = L"{89F1B351-B15D-48D4-8F10-1298721CF13D}";
39const wchar_t kTestExperimentLabel[] = L"test_label_value";
40
41// This test fixture redirects the HKLM and HKCU registry hives for
42// the duration of the test to make it independent of the machine
43// and user settings.
44class GoogleUpdateSettingsTest : public testing::Test {
45 protected:
46  virtual void SetUp() OVERRIDE {
47    registry_overrides_.OverrideRegistry(HKEY_LOCAL_MACHINE, L"HKLM_pit");
48    registry_overrides_.OverrideRegistry(HKEY_CURRENT_USER, L"HKCU_pit");
49  }
50
51  enum SystemUserInstall {
52    SYSTEM_INSTALL,
53    USER_INSTALL,
54  };
55
56  void SetApField(SystemUserInstall is_system, const wchar_t* value) {
57    HKEY root = is_system == SYSTEM_INSTALL ?
58        HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
59
60    RegKey update_key;
61    BrowserDistribution* dist = BrowserDistribution::GetDistribution();
62    std::wstring path = dist->GetStateKey();
63    ASSERT_EQ(ERROR_SUCCESS, update_key.Create(root, path.c_str(), KEY_WRITE));
64    ASSERT_EQ(ERROR_SUCCESS, update_key.WriteValue(L"ap", value));
65  }
66
67  // Tests setting the ap= value to various combinations of values with
68  // prefixes and suffixes, while asserting on the correct channel value.
69  // Note that any non-empty ap= value that doesn't match ".*-{dev|beta}.*"
70  // will return the "unknown" channel.
71  void TestCurrentChromeChannelWithVariousApValues(SystemUserInstall install) {
72    static struct Expectations {
73      const wchar_t* ap_value;
74      const wchar_t* channel;
75    } expectations[] = {
76      { L"dev", installer::kChromeChannelDev },
77      { L"-dev", installer::kChromeChannelDev },
78      { L"-developer", installer::kChromeChannelDev },
79      { L"beta", installer::kChromeChannelBeta },
80      { L"-beta", installer::kChromeChannelBeta },
81      { L"-betamax", installer::kChromeChannelBeta },
82    };
83    bool is_system = install == SYSTEM_INSTALL;
84    const wchar_t* prefixes[] = {
85      L"",
86      L"prefix",
87      L"prefix-with-dash",
88    };
89    const wchar_t* suffixes[] = {
90      L"",
91      L"suffix",
92      L"suffix-with-dash",
93    };
94
95    for (size_t i = 0; i < arraysize(prefixes); ++i) {
96      for (size_t j = 0; j < arraysize(expectations); ++j) {
97        for (size_t k = 0; k < arraysize(suffixes); ++k) {
98          std::wstring ap = prefixes[i];
99          ap += expectations[j].ap_value;
100          ap += suffixes[k];
101          const wchar_t* channel = expectations[j].channel;
102
103          SetApField(install, ap.c_str());
104          string16 ret_channel;
105
106          EXPECT_TRUE(GoogleUpdateSettings::GetChromeChannelAndModifiers(
107              is_system, &ret_channel));
108          EXPECT_STREQ(channel, ret_channel.c_str())
109              << "Expecting channel \"" << channel
110              << "\" for ap=\"" << ap << "\"";
111        }
112      }
113    }
114  }
115
116  // Test the writing and deleting functionality of the experiments label
117  // helper.
118  void TestExperimentsLabelHelper(SystemUserInstall install) {
119    BrowserDistribution* chrome =
120        BrowserDistribution::GetSpecificDistribution(
121            BrowserDistribution::CHROME_BROWSER);
122    std::wstring value;
123#if defined(GOOGLE_CHROME_BUILD)
124    EXPECT_TRUE(chrome->ShouldSetExperimentLabels());
125
126    // Before anything is set, ReadExperimentLabels should succeed but return
127    // an empty string.
128    EXPECT_TRUE(GoogleUpdateSettings::ReadExperimentLabels(
129        install == SYSTEM_INSTALL, &value));
130    EXPECT_EQ(string16(), value);
131
132    EXPECT_TRUE(GoogleUpdateSettings::SetExperimentLabels(
133        install == SYSTEM_INSTALL, kTestExperimentLabel));
134
135    // Validate that something is written. Only worry about the label itself.
136    RegKey key;
137    HKEY root = install == SYSTEM_INSTALL ?
138        HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
139    string16 state_key = install == SYSTEM_INSTALL ?
140        chrome->GetStateMediumKey() : chrome->GetStateKey();
141
142    EXPECT_EQ(ERROR_SUCCESS,
143              key.Open(root, state_key.c_str(), KEY_QUERY_VALUE));
144    EXPECT_EQ(ERROR_SUCCESS,
145        key.ReadValue(google_update::kExperimentLabels, &value));
146    EXPECT_EQ(kTestExperimentLabel, value);
147    EXPECT_TRUE(GoogleUpdateSettings::ReadExperimentLabels(
148        install == SYSTEM_INSTALL, &value));
149    EXPECT_EQ(kTestExperimentLabel, value);
150    key.Close();
151
152    // Now that the label is set, test the delete functionality. An empty label
153    // should result in deleting the value.
154    EXPECT_TRUE(GoogleUpdateSettings::SetExperimentLabels(
155        install == SYSTEM_INSTALL, string16()));
156    EXPECT_EQ(ERROR_SUCCESS,
157              key.Open(root, state_key.c_str(), KEY_QUERY_VALUE));
158    EXPECT_EQ(ERROR_FILE_NOT_FOUND,
159        key.ReadValue(google_update::kExperimentLabels, &value));
160    EXPECT_TRUE(GoogleUpdateSettings::ReadExperimentLabels(
161        install == SYSTEM_INSTALL, &value));
162    EXPECT_EQ(string16(), value);
163    key.Close();
164#else
165    EXPECT_FALSE(chrome->ShouldSetExperimentLabels());
166    EXPECT_FALSE(GoogleUpdateSettings::ReadExperimentLabels(
167        install == SYSTEM_INSTALL, &value));
168#endif  // GOOGLE_CHROME_BUILD
169  }
170
171  // Creates "ap" key with the value given as parameter. Also adds work
172  // items to work_item_list given so that they can be rolled back later.
173  bool CreateApKey(WorkItemList* work_item_list, const std::wstring& value) {
174    HKEY reg_root = HKEY_CURRENT_USER;
175    std::wstring reg_key = GetApKeyPath();
176    work_item_list->AddCreateRegKeyWorkItem(reg_root, reg_key);
177    work_item_list->AddSetRegValueWorkItem(reg_root, reg_key,
178        google_update::kRegApField, value.c_str(), true);
179    if (!work_item_list->Do()) {
180      work_item_list->Rollback();
181      return false;
182    }
183    return true;
184  }
185
186  // Returns the key path of "ap" key, e.g.:
187  // Google\Update\ClientState\<kTestProductGuid>
188  std::wstring GetApKeyPath() {
189    std::wstring reg_key(google_update::kRegPathClientState);
190    reg_key.append(L"\\");
191    reg_key.append(kTestProductGuid);
192    return reg_key;
193  }
194
195  // Utility method to read "ap" key value
196  std::wstring ReadApKeyValue() {
197    RegKey key;
198    std::wstring ap_key_value;
199    std::wstring reg_key = GetApKeyPath();
200    if (key.Open(HKEY_CURRENT_USER, reg_key.c_str(), KEY_ALL_ACCESS) ==
201        ERROR_SUCCESS) {
202      key.ReadValue(google_update::kRegApField, &ap_key_value);
203    }
204
205    return ap_key_value;
206  }
207
208  registry_util::RegistryOverrideManager registry_overrides_;
209};
210
211}  // namespace
212
213// Verify that we return success on no registration (which means stable),
214// whether per-system or per-user install.
215TEST_F(GoogleUpdateSettingsTest, CurrentChromeChannelAbsent) {
216  // Per-system first.
217  string16 channel;
218  EXPECT_TRUE(GoogleUpdateSettings::GetChromeChannelAndModifiers(true,
219                                                                 &channel));
220  EXPECT_STREQ(L"", channel.c_str());
221
222  // Then per-user.
223  EXPECT_TRUE(GoogleUpdateSettings::GetChromeChannelAndModifiers(false,
224                                                                 &channel));
225  EXPECT_STREQ(L"", channel.c_str());
226}
227
228// Test an empty Ap key for system and user.
229TEST_F(GoogleUpdateSettingsTest, CurrentChromeChannelEmptySystem) {
230  SetApField(SYSTEM_INSTALL, L"");
231  string16 channel;
232  EXPECT_TRUE(GoogleUpdateSettings::GetChromeChannelAndModifiers(true,
233                                                                 &channel));
234  EXPECT_STREQ(L"", channel.c_str());
235
236  // Per-user lookups still succeed and return empty string.
237  EXPECT_TRUE(GoogleUpdateSettings::GetChromeChannelAndModifiers(false,
238                                                                 &channel));
239  EXPECT_STREQ(L"", channel.c_str());
240}
241
242TEST_F(GoogleUpdateSettingsTest, CurrentChromeChannelEmptyUser) {
243  SetApField(USER_INSTALL, L"");
244  // Per-system lookups still succeed and return empty string.
245  string16 channel;
246  EXPECT_TRUE(GoogleUpdateSettings::GetChromeChannelAndModifiers(true,
247                                                                 &channel));
248  EXPECT_STREQ(L"", channel.c_str());
249
250  // Per-user lookup should succeed.
251  EXPECT_TRUE(GoogleUpdateSettings::GetChromeChannelAndModifiers(false,
252                                                                 &channel));
253  EXPECT_STREQ(L"", channel.c_str());
254}
255
256TEST_F(GoogleUpdateSettingsTest, CurrentChromeChannelVariousApValuesSystem) {
257  TestCurrentChromeChannelWithVariousApValues(SYSTEM_INSTALL);
258}
259
260TEST_F(GoogleUpdateSettingsTest, CurrentChromeChannelVariousApValuesUser) {
261  TestCurrentChromeChannelWithVariousApValues(USER_INSTALL);
262}
263
264// Run through all combinations of diff vs. full install, single vs. multi
265// install, success and failure results, and a fistful of initial "ap" values
266// checking that the expected final "ap" value is generated by
267// GoogleUpdateSettings::UpdateGoogleUpdateApKey.
268TEST_F(GoogleUpdateSettingsTest, UpdateGoogleUpdateApKey) {
269  const installer::ArchiveType archive_types[] = {
270    installer::UNKNOWN_ARCHIVE_TYPE,
271    installer::FULL_ARCHIVE_TYPE,
272    installer::INCREMENTAL_ARCHIVE_TYPE
273  };
274  const int results[] = {
275    installer::FIRST_INSTALL_SUCCESS,
276    installer::INSTALL_FAILED
277  };
278  const wchar_t* const plain[] = {
279    L"",
280    L"1.1",
281    L"1.1-dev"
282  };
283  const wchar_t* const full[] = {
284    L"-full",
285    L"1.1-full",
286    L"1.1-dev-full"
287  };
288  COMPILE_ASSERT(arraysize(full) == arraysize(plain), bad_full_array_size);
289  const wchar_t* const multifail[] = {
290    L"-multifail",
291    L"1.1-multifail",
292    L"1.1-dev-multifail"
293  };
294  COMPILE_ASSERT(arraysize(multifail) == arraysize(plain),
295                 bad_multifail_array_size);
296  const wchar_t* const multifail_full[] = {
297    L"-multifail-full",
298    L"1.1-multifail-full",
299    L"1.1-dev-multifail-full"
300  };
301  COMPILE_ASSERT(arraysize(multifail_full) == arraysize(plain),
302                 bad_multifail_full_array_size);
303  const wchar_t* const* input_arrays[] = {
304    plain,
305    full,
306    multifail,
307    multifail_full
308  };
309  ChannelInfo v;
310  for (int type_idx = 0; type_idx < arraysize(archive_types); ++type_idx) {
311    const installer::ArchiveType archive_type = archive_types[type_idx];
312    for (int result_idx = 0; result_idx < arraysize(results); ++result_idx) {
313      const int result = results[result_idx];
314      // The archive type will/must always be known on install success.
315      if (archive_type == installer::UNKNOWN_ARCHIVE_TYPE &&
316          result == installer::FIRST_INSTALL_SUCCESS) {
317        continue;
318      }
319      const wchar_t* const* outputs = NULL;
320      if (result == installer::FIRST_INSTALL_SUCCESS ||
321          archive_type == installer::FULL_ARCHIVE_TYPE) {
322        outputs = plain;
323      } else if (archive_type == installer::INCREMENTAL_ARCHIVE_TYPE) {
324        outputs = full;
325      }  // else if (archive_type == UNKNOWN) see below
326
327      for (int inputs_idx = 0; inputs_idx < arraysize(input_arrays);
328           ++inputs_idx) {
329        const wchar_t* const* inputs = input_arrays[inputs_idx];
330        if (archive_type == installer::UNKNOWN_ARCHIVE_TYPE) {
331          // "-full" is untouched if the archive type is unknown.
332          // "-multifail" is unconditionally removed.
333          if (inputs == full || inputs == multifail_full)
334            outputs = full;
335          else
336            outputs = plain;
337        }
338        for (int input_idx = 0; input_idx < arraysize(plain); ++input_idx) {
339          const wchar_t* input = inputs[input_idx];
340          const wchar_t* output = outputs[input_idx];
341
342          v.set_value(input);
343          if (output == v.value()) {
344            EXPECT_FALSE(GoogleUpdateSettings::UpdateGoogleUpdateApKey(
345                archive_type, result, &v))
346                << "archive_type: " << archive_type
347                << ", result: " << result
348                << ", input ap value: " << input;
349          } else {
350            EXPECT_TRUE(GoogleUpdateSettings::UpdateGoogleUpdateApKey(
351                archive_type, result, &v))
352                << "archive_type: " << archive_type
353                << ", result: " << result
354                << ", input ap value: " << input;
355          }
356          EXPECT_EQ(output, v.value())
357              << "archive_type: " << archive_type
358              << ", result: " << result
359              << ", input ap value: " << input;
360        }
361      }
362    }
363  }
364}
365
366TEST_F(GoogleUpdateSettingsTest, UpdateInstallStatusTest) {
367  scoped_ptr<WorkItemList> work_item_list(WorkItem::CreateWorkItemList());
368  // Test incremental install failure
369  ASSERT_TRUE(CreateApKey(work_item_list.get(), L""))
370      << "Failed to create ap key.";
371  GoogleUpdateSettings::UpdateInstallStatus(false,
372                                            installer::INCREMENTAL_ARCHIVE_TYPE,
373                                            installer::INSTALL_FAILED,
374                                            kTestProductGuid);
375  EXPECT_STREQ(ReadApKeyValue().c_str(), L"-full");
376  work_item_list->Rollback();
377
378  work_item_list.reset(WorkItem::CreateWorkItemList());
379  // Test incremental install success
380  ASSERT_TRUE(CreateApKey(work_item_list.get(), L""))
381      << "Failed to create ap key.";
382  GoogleUpdateSettings::UpdateInstallStatus(false,
383                                            installer::INCREMENTAL_ARCHIVE_TYPE,
384                                            installer::FIRST_INSTALL_SUCCESS,
385                                            kTestProductGuid);
386  EXPECT_STREQ(ReadApKeyValue().c_str(), L"");
387  work_item_list->Rollback();
388
389  work_item_list.reset(WorkItem::CreateWorkItemList());
390  // Test full install failure
391  ASSERT_TRUE(CreateApKey(work_item_list.get(), L"-full"))
392      << "Failed to create ap key.";
393  GoogleUpdateSettings::UpdateInstallStatus(false, installer::FULL_ARCHIVE_TYPE,
394                                            installer::INSTALL_FAILED,
395                                            kTestProductGuid);
396  EXPECT_STREQ(ReadApKeyValue().c_str(), L"");
397  work_item_list->Rollback();
398
399  work_item_list.reset(WorkItem::CreateWorkItemList());
400  // Test full install success
401  ASSERT_TRUE(CreateApKey(work_item_list.get(), L"-full"))
402      << "Failed to create ap key.";
403  GoogleUpdateSettings::UpdateInstallStatus(false, installer::FULL_ARCHIVE_TYPE,
404                                            installer::FIRST_INSTALL_SUCCESS,
405                                            kTestProductGuid);
406  EXPECT_STREQ(ReadApKeyValue().c_str(), L"");
407  work_item_list->Rollback();
408
409  work_item_list.reset(WorkItem::CreateWorkItemList());
410  // Test the case of when "ap" key doesnt exist at all
411  std::wstring ap_key_value = ReadApKeyValue();
412  std::wstring reg_key = GetApKeyPath();
413  HKEY reg_root = HKEY_CURRENT_USER;
414  bool ap_key_deleted = false;
415  RegKey key;
416  if (key.Open(HKEY_CURRENT_USER, reg_key.c_str(), KEY_ALL_ACCESS) !=
417      ERROR_SUCCESS) {
418    work_item_list->AddCreateRegKeyWorkItem(reg_root, reg_key);
419    ASSERT_TRUE(work_item_list->Do()) << "Failed to create ClientState key.";
420  } else if (key.DeleteValue(google_update::kRegApField) == ERROR_SUCCESS) {
421    ap_key_deleted = true;
422  }
423  // try differential installer
424  GoogleUpdateSettings::UpdateInstallStatus(false,
425                                            installer::INCREMENTAL_ARCHIVE_TYPE,
426                                            installer::INSTALL_FAILED,
427                                            kTestProductGuid);
428  EXPECT_STREQ(ReadApKeyValue().c_str(), L"-full");
429  // try full installer now
430  GoogleUpdateSettings::UpdateInstallStatus(false, installer::FULL_ARCHIVE_TYPE,
431                                            installer::INSTALL_FAILED,
432                                            kTestProductGuid);
433  EXPECT_STREQ(ReadApKeyValue().c_str(), L"");
434  // Now cleanup to leave the system in unchanged state.
435  // - Diff installer creates an ap key if it didnt exist, so delete this ap key
436  // - If we created any reg key path for ap, roll it back
437  // - Finally restore the original value of ap key.
438  key.Open(HKEY_CURRENT_USER, reg_key.c_str(), KEY_ALL_ACCESS);
439  key.DeleteValue(google_update::kRegApField);
440  work_item_list->Rollback();
441  if (ap_key_deleted) {
442    work_item_list.reset(WorkItem::CreateWorkItemList());
443    ASSERT_TRUE(CreateApKey(work_item_list.get(), ap_key_value))
444        << "Failed to restore ap key.";
445  }
446}
447
448TEST_F(GoogleUpdateSettingsTest, SetEULAConsent) {
449  using installer::FakeInstallationState;
450
451  const bool multi_install = true;
452  const bool system_level = true;
453  FakeInstallationState machine_state;
454
455  // Chrome is installed.
456  machine_state.AddChrome(system_level, multi_install,
457      new Version(chrome::kChromeVersion));
458
459  RegKey key;
460  DWORD value;
461  BrowserDistribution* binaries =
462      BrowserDistribution::GetSpecificDistribution(
463          BrowserDistribution::CHROME_BINARIES);
464  BrowserDistribution* chrome =
465      BrowserDistribution::GetSpecificDistribution(
466          BrowserDistribution::CHROME_BROWSER);
467
468  // eulaconsent is set on both the product and the binaries.
469  EXPECT_TRUE(GoogleUpdateSettings::SetEULAConsent(machine_state, chrome,
470                                                   true));
471  EXPECT_EQ(ERROR_SUCCESS,
472      key.Open(HKEY_LOCAL_MACHINE, binaries->GetStateMediumKey().c_str(),
473               KEY_QUERY_VALUE));
474  EXPECT_EQ(ERROR_SUCCESS,
475      key.ReadValueDW(google_update::kRegEULAAceptedField, &value));
476  EXPECT_EQ(1U, value);
477  EXPECT_EQ(ERROR_SUCCESS,
478      key.Open(HKEY_LOCAL_MACHINE, chrome->GetStateMediumKey().c_str(),
479               KEY_QUERY_VALUE));
480  EXPECT_EQ(ERROR_SUCCESS,
481      key.ReadValueDW(google_update::kRegEULAAceptedField, &value));
482  EXPECT_EQ(1U, value);
483}
484
485// Test that the appropriate default is returned if no update override is
486// present.
487TEST_F(GoogleUpdateSettingsTest, GetAppUpdatePolicyNoOverride) {
488  // There are no policies at all.
489  EXPECT_EQ(ERROR_FILE_NOT_FOUND,
490            RegKey().Open(HKEY_LOCAL_MACHINE, kGoogleUpdatePoliciesKey,
491                          KEY_QUERY_VALUE));
492  bool is_overridden = true;
493  EXPECT_EQ(kDefaultUpdatePolicy,
494            GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid,
495                                                     &is_overridden));
496  EXPECT_FALSE(is_overridden);
497
498  // The policy key exists, but there are no values of interest present.
499  EXPECT_EQ(ERROR_SUCCESS,
500            RegKey().Create(HKEY_LOCAL_MACHINE, kGoogleUpdatePoliciesKey,
501                            KEY_SET_VALUE));
502  EXPECT_EQ(ERROR_SUCCESS,
503            RegKey().Open(HKEY_LOCAL_MACHINE, kGoogleUpdatePoliciesKey,
504                          KEY_QUERY_VALUE));
505  is_overridden = true;
506  EXPECT_EQ(kDefaultUpdatePolicy,
507            GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid,
508                                                     &is_overridden));
509  EXPECT_FALSE(is_overridden);
510}
511
512#if defined(GOOGLE_CHROME_BUILD)
513
514// Test that the default override is returned if no app-specific override is
515// present.
516TEST_F(GoogleUpdateSettingsTest, GetAppUpdatePolicyDefaultOverride) {
517  EXPECT_EQ(ERROR_SUCCESS,
518            RegKey(HKEY_LOCAL_MACHINE, kGoogleUpdatePoliciesKey,
519                   KEY_SET_VALUE).WriteValue(kGoogleUpdateUpdateDefault,
520                                             static_cast<DWORD>(0)));
521  bool is_overridden = true;
522  EXPECT_EQ(GoogleUpdateSettings::UPDATES_DISABLED,
523            GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid,
524                                                     &is_overridden));
525  EXPECT_FALSE(is_overridden);
526
527  EXPECT_EQ(ERROR_SUCCESS,
528            RegKey(HKEY_LOCAL_MACHINE, kGoogleUpdatePoliciesKey,
529                   KEY_SET_VALUE).WriteValue(kGoogleUpdateUpdateDefault,
530                                             static_cast<DWORD>(1)));
531  is_overridden = true;
532  EXPECT_EQ(GoogleUpdateSettings::AUTOMATIC_UPDATES,
533            GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid,
534                                                     &is_overridden));
535  EXPECT_FALSE(is_overridden);
536
537  EXPECT_EQ(ERROR_SUCCESS,
538            RegKey(HKEY_LOCAL_MACHINE, kGoogleUpdatePoliciesKey,
539                   KEY_SET_VALUE).WriteValue(kGoogleUpdateUpdateDefault,
540                                             static_cast<DWORD>(2)));
541  is_overridden = true;
542  EXPECT_EQ(GoogleUpdateSettings::MANUAL_UPDATES_ONLY,
543            GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid,
544                                                     &is_overridden));
545  EXPECT_FALSE(is_overridden);
546
547  // The default policy should be in force for bogus values.
548  EXPECT_EQ(ERROR_SUCCESS,
549            RegKey(HKEY_LOCAL_MACHINE, kGoogleUpdatePoliciesKey,
550                   KEY_SET_VALUE).WriteValue(kGoogleUpdateUpdateDefault,
551                                             static_cast<DWORD>(3)));
552  is_overridden = true;
553  EXPECT_EQ(kDefaultUpdatePolicy,
554            GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid,
555                                                     &is_overridden));
556  EXPECT_FALSE(is_overridden);
557}
558
559// Test that an app-specific override is used if present.
560TEST_F(GoogleUpdateSettingsTest, GetAppUpdatePolicyAppOverride) {
561  std::wstring app_policy_value(kGoogleUpdateUpdatePrefix);
562  app_policy_value.append(kTestProductGuid);
563
564  EXPECT_EQ(ERROR_SUCCESS,
565            RegKey(HKEY_LOCAL_MACHINE, kGoogleUpdatePoliciesKey,
566                   KEY_SET_VALUE).WriteValue(kGoogleUpdateUpdateDefault,
567                                             static_cast<DWORD>(1)));
568  EXPECT_EQ(ERROR_SUCCESS,
569            RegKey(HKEY_LOCAL_MACHINE, kGoogleUpdatePoliciesKey,
570                   KEY_SET_VALUE).WriteValue(app_policy_value.c_str(),
571                                             static_cast<DWORD>(0)));
572  bool is_overridden = false;
573  EXPECT_EQ(GoogleUpdateSettings::UPDATES_DISABLED,
574            GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid,
575                                                     &is_overridden));
576  EXPECT_TRUE(is_overridden);
577
578  EXPECT_EQ(ERROR_SUCCESS,
579            RegKey(HKEY_LOCAL_MACHINE, kGoogleUpdatePoliciesKey,
580                   KEY_SET_VALUE).WriteValue(kGoogleUpdateUpdateDefault,
581                                             static_cast<DWORD>(0)));
582  EXPECT_EQ(ERROR_SUCCESS,
583            RegKey(HKEY_LOCAL_MACHINE, kGoogleUpdatePoliciesKey,
584                   KEY_SET_VALUE).WriteValue(app_policy_value.c_str(),
585                                             static_cast<DWORD>(1)));
586  is_overridden = false;
587  EXPECT_EQ(GoogleUpdateSettings::AUTOMATIC_UPDATES,
588            GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid,
589                                                     &is_overridden));
590  EXPECT_TRUE(is_overridden);
591
592  EXPECT_EQ(ERROR_SUCCESS,
593            RegKey(HKEY_LOCAL_MACHINE, kGoogleUpdatePoliciesKey,
594                   KEY_SET_VALUE).WriteValue(app_policy_value.c_str(),
595                                             static_cast<DWORD>(2)));
596  is_overridden = false;
597  EXPECT_EQ(GoogleUpdateSettings::MANUAL_UPDATES_ONLY,
598            GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid,
599                                                     &is_overridden));
600  EXPECT_TRUE(is_overridden);
601
602  // The default policy should be in force for bogus values.
603  EXPECT_EQ(ERROR_SUCCESS,
604            RegKey(HKEY_LOCAL_MACHINE, kGoogleUpdatePoliciesKey,
605                   KEY_SET_VALUE).WriteValue(app_policy_value.c_str(),
606                                             static_cast<DWORD>(3)));
607  is_overridden = true;
608  EXPECT_EQ(GoogleUpdateSettings::UPDATES_DISABLED,
609            GoogleUpdateSettings::GetAppUpdatePolicy(kTestProductGuid,
610                                                     &is_overridden));
611  EXPECT_FALSE(is_overridden);
612}
613
614TEST_F(GoogleUpdateSettingsTest, ExperimentsLabelHelperSystem) {
615  TestExperimentsLabelHelper(SYSTEM_INSTALL);
616}
617
618TEST_F(GoogleUpdateSettingsTest, ExperimentsLabelHelperUser) {
619  TestExperimentsLabelHelper(USER_INSTALL);
620}
621
622#endif  // defined(GOOGLE_CHROME_BUILD)
623
624// Test GoogleUpdateSettings::GetUninstallCommandLine at system- or user-level,
625// according to the param.
626class GetUninstallCommandLine : public GoogleUpdateSettingsTest,
627                                public testing::WithParamInterface<bool> {
628 protected:
629  static const wchar_t kDummyCommand[];
630
631  virtual void SetUp() OVERRIDE {
632    GoogleUpdateSettingsTest::SetUp();
633    system_install_ = GetParam();
634    root_key_ = system_install_ ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
635  }
636
637  HKEY root_key_;
638  bool system_install_;
639};
640
641const wchar_t GetUninstallCommandLine::kDummyCommand[] =
642    L"\"goopdate.exe\" /spam";
643
644// Tests that GetUninstallCommandLine returns an empty string if there's no
645// Software\Google\Update key.
646TEST_P(GetUninstallCommandLine, TestNoKey) {
647  EXPECT_EQ(string16(),
648            GoogleUpdateSettings::GetUninstallCommandLine(system_install_));
649}
650
651// Tests that GetUninstallCommandLine returns an empty string if there's no
652// UninstallCmdLine value in the Software\Google\Update key.
653TEST_P(GetUninstallCommandLine, TestNoValue) {
654  RegKey(root_key_, google_update::kRegPathGoogleUpdate, KEY_SET_VALUE);
655  EXPECT_EQ(string16(),
656            GoogleUpdateSettings::GetUninstallCommandLine(system_install_));
657}
658
659// Tests that GetUninstallCommandLine returns an empty string if there's an
660// empty UninstallCmdLine value in the Software\Google\Update key.
661TEST_P(GetUninstallCommandLine, TestEmptyValue) {
662  RegKey(root_key_, google_update::kRegPathGoogleUpdate, KEY_SET_VALUE)
663    .WriteValue(google_update::kRegUninstallCmdLine, L"");
664  EXPECT_EQ(string16(),
665            GoogleUpdateSettings::GetUninstallCommandLine(system_install_));
666}
667
668// Tests that GetUninstallCommandLine returns the correct string if there's an
669// UninstallCmdLine value in the Software\Google\Update key.
670TEST_P(GetUninstallCommandLine, TestRealValue) {
671  RegKey(root_key_, google_update::kRegPathGoogleUpdate, KEY_SET_VALUE)
672      .WriteValue(google_update::kRegUninstallCmdLine, kDummyCommand);
673  EXPECT_EQ(string16(kDummyCommand),
674            GoogleUpdateSettings::GetUninstallCommandLine(system_install_));
675  // Make sure that there's no value in the other level (user or system).
676  EXPECT_EQ(string16(),
677            GoogleUpdateSettings::GetUninstallCommandLine(!system_install_));
678}
679
680INSTANTIATE_TEST_CASE_P(GetUninstallCommandLineAtLevel, GetUninstallCommandLine,
681                        testing::Bool());
682
683// Test GoogleUpdateSettings::GetGoogleUpdateVersion at system- or user-level,
684// according to the param.
685class GetGoogleUpdateVersion : public GoogleUpdateSettingsTest,
686                               public testing::WithParamInterface<bool> {
687 protected:
688  static const wchar_t kDummyVersion[];
689
690  virtual void SetUp() OVERRIDE {
691    GoogleUpdateSettingsTest::SetUp();
692    system_install_ = GetParam();
693    root_key_ = system_install_ ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
694  }
695
696  HKEY root_key_;
697  bool system_install_;
698};
699
700const wchar_t GetGoogleUpdateVersion::kDummyVersion[] = L"1.2.3.4";
701
702// Tests that GetGoogleUpdateVersion returns an empty string if there's no
703// Software\Google\Update key.
704TEST_P(GetGoogleUpdateVersion, TestNoKey) {
705  EXPECT_FALSE(
706      GoogleUpdateSettings::GetGoogleUpdateVersion(system_install_).IsValid());
707}
708
709// Tests that GetGoogleUpdateVersion returns an empty string if there's no
710// version value in the Software\Google\Update key.
711TEST_P(GetGoogleUpdateVersion, TestNoValue) {
712  RegKey(root_key_, google_update::kRegPathGoogleUpdate, KEY_SET_VALUE);
713  EXPECT_FALSE(
714      GoogleUpdateSettings::GetGoogleUpdateVersion(system_install_).IsValid());
715}
716
717// Tests that GetGoogleUpdateVersion returns an empty string if there's an
718// empty version value in the Software\Google\Update key.
719TEST_P(GetGoogleUpdateVersion, TestEmptyValue) {
720  RegKey(root_key_, google_update::kRegPathGoogleUpdate, KEY_SET_VALUE)
721      .WriteValue(google_update::kRegGoogleUpdateVersion, L"");
722  EXPECT_FALSE(
723      GoogleUpdateSettings::GetGoogleUpdateVersion(system_install_).IsValid());
724}
725
726// Tests that GetGoogleUpdateVersion returns the correct string if there's a
727// version value in the Software\Google\Update key.
728TEST_P(GetGoogleUpdateVersion, TestRealValue) {
729  RegKey(root_key_, google_update::kRegPathGoogleUpdate, KEY_SET_VALUE)
730      .WriteValue(google_update::kRegGoogleUpdateVersion, kDummyVersion);
731  Version expected(UTF16ToUTF8(kDummyVersion));
732  EXPECT_TRUE(expected.Equals(
733      GoogleUpdateSettings::GetGoogleUpdateVersion(system_install_)));
734  // Make sure that there's no value in the other level (user or system).
735  EXPECT_FALSE(
736      GoogleUpdateSettings::GetGoogleUpdateVersion(!system_install_)
737          .IsValid());
738}
739
740INSTANTIATE_TEST_CASE_P(GetGoogleUpdateVersionAtLevel, GetGoogleUpdateVersion,
741                        testing::Bool());
742
743// Test values for use by the CollectStatsConsent test fixture.
744class StatsState {
745 public:
746  enum InstallType {
747    SINGLE_INSTALL,
748    MULTI_INSTALL,
749  };
750  enum StateSetting {
751    NO_SETTING,
752    FALSE_SETTING,
753    TRUE_SETTING,
754  };
755  struct UserLevelState {};
756  struct SystemLevelState {};
757  static const UserLevelState kUserLevel;
758  static const SystemLevelState kSystemLevel;
759
760  StatsState(const UserLevelState&,
761             InstallType install_type,
762             StateSetting state_value)
763      : system_level_(false),
764        multi_install_(install_type == MULTI_INSTALL),
765        state_value_(state_value),
766        state_medium_value_(NO_SETTING) {
767  }
768  StatsState(const SystemLevelState&,
769             InstallType install_type,
770             StateSetting state_value,
771             StateSetting state_medium_value)
772      : system_level_(true),
773        multi_install_(install_type == MULTI_INSTALL),
774        state_value_(state_value),
775        state_medium_value_(state_medium_value) {
776  }
777  bool system_level() const { return system_level_; }
778  bool multi_install() const { return multi_install_; }
779  HKEY root_key() const {
780    return system_level_ ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
781  }
782  StateSetting state_value() const { return state_value_; }
783  StateSetting state_medium_value() const {
784    return state_medium_value_;
785  }
786  bool is_consent_granted() const {
787    return (system_level_ && state_medium_value_ != NO_SETTING) ?
788        (state_medium_value_ == TRUE_SETTING) :
789        (state_value_ == TRUE_SETTING);
790  }
791 private:
792  bool system_level_;
793  bool multi_install_;
794  StateSetting state_value_;
795  StateSetting state_medium_value_;
796};
797
798const StatsState::UserLevelState StatsState::kUserLevel;
799const StatsState::SystemLevelState StatsState::kSystemLevel;
800
801// A value parameterized test for testing the stats collection consent setting.
802class CollectStatsConsent : public ::testing::TestWithParam<StatsState> {
803 public:
804  static void SetUpTestCase();
805  static void TearDownTestCase();
806 protected:
807  virtual void SetUp() OVERRIDE;
808  static void MakeChromeMultiInstall(HKEY root_key);
809  static void ApplySetting(StatsState::StateSetting setting,
810                           HKEY root_key,
811                           const std::wstring& reg_key);
812
813  static std::wstring* chrome_version_key_;
814  static std::wstring* chrome_state_key_;
815  static std::wstring* chrome_state_medium_key_;
816  static std::wstring* binaries_state_key_;
817  static std::wstring* binaries_state_medium_key_;
818  registry_util::RegistryOverrideManager override_manager_;
819};
820
821std::wstring* CollectStatsConsent::chrome_version_key_;
822std::wstring* CollectStatsConsent::chrome_state_key_;
823std::wstring* CollectStatsConsent::chrome_state_medium_key_;
824std::wstring* CollectStatsConsent::binaries_state_key_;
825std::wstring* CollectStatsConsent::binaries_state_medium_key_;
826
827void CollectStatsConsent::SetUpTestCase() {
828  BrowserDistribution* dist =
829      BrowserDistribution::GetSpecificDistribution(
830          BrowserDistribution::CHROME_BROWSER);
831  chrome_version_key_ = new std::wstring(dist->GetVersionKey());
832  chrome_state_key_ = new std::wstring(dist->GetStateKey());
833  chrome_state_medium_key_ = new std::wstring(dist->GetStateMediumKey());
834
835  dist = BrowserDistribution::GetSpecificDistribution(
836      BrowserDistribution::CHROME_BINARIES);
837  binaries_state_key_ = new std::wstring(dist->GetStateKey());
838  binaries_state_medium_key_ = new std::wstring(dist->GetStateMediumKey());
839}
840
841void CollectStatsConsent::TearDownTestCase() {
842  delete chrome_version_key_;
843  delete chrome_state_key_;
844  delete chrome_state_medium_key_;
845  delete binaries_state_key_;
846  delete binaries_state_medium_key_;
847}
848
849// Install the registry override and apply the settings to the registry.
850void CollectStatsConsent::SetUp() {
851  const StatsState& stats_state = GetParam();
852  const HKEY root_key = stats_state.root_key();
853  std::wstring reg_temp_name(stats_state.system_level() ? L"HKLM_" : L"HKCU_");
854  reg_temp_name += L"CollectStatsConsent";
855  override_manager_.OverrideRegistry(root_key, reg_temp_name);
856
857  if (stats_state.multi_install()) {
858    MakeChromeMultiInstall(root_key);
859    ApplySetting(stats_state.state_value(), root_key, *binaries_state_key_);
860    ApplySetting(stats_state.state_medium_value(), root_key,
861                 *binaries_state_medium_key_);
862  } else {
863    ApplySetting(stats_state.state_value(), root_key, *chrome_state_key_);
864    ApplySetting(stats_state.state_medium_value(), root_key,
865                 *chrome_state_medium_key_);
866  }
867}
868
869// Write values into the registry so that Chrome is considered to be installed
870// as multi-install.
871void CollectStatsConsent::MakeChromeMultiInstall(HKEY root_key) {
872  ASSERT_EQ(
873      ERROR_SUCCESS,
874      RegKey(root_key, chrome_version_key_->c_str(),
875             KEY_SET_VALUE).WriteValue(google_update::kRegVersionField,
876                                       L"1.2.3.4"));
877  ASSERT_EQ(
878      ERROR_SUCCESS,
879      RegKey(root_key, chrome_state_key_->c_str(),
880             KEY_SET_VALUE).WriteValue(installer::kUninstallArgumentsField,
881                                       L"--multi-install"));
882}
883
884// Write the correct value to represent |setting| in the registry.
885void CollectStatsConsent::ApplySetting(StatsState::StateSetting setting,
886                                       HKEY root_key,
887                                       const std::wstring& reg_key) {
888  if (setting != StatsState::NO_SETTING) {
889    DWORD value = setting != StatsState::FALSE_SETTING ? 1 : 0;
890    ASSERT_EQ(
891        ERROR_SUCCESS,
892        RegKey(root_key, reg_key.c_str(),
893               KEY_SET_VALUE).WriteValue(google_update::kRegUsageStatsField,
894                                         value));
895  }
896}
897
898// Test that stats consent can be read.
899TEST_P(CollectStatsConsent, GetCollectStatsConsentAtLevel) {
900  if (GetParam().is_consent_granted()) {
901    EXPECT_TRUE(GoogleUpdateSettings::GetCollectStatsConsentAtLevel(
902                    GetParam().system_level()));
903  } else {
904    EXPECT_FALSE(GoogleUpdateSettings::GetCollectStatsConsentAtLevel(
905                     GetParam().system_level()));
906  }
907}
908
909// Test that stats consent can be flipped to the opposite setting, that the new
910// setting takes affect, and that the correct registry location is modified.
911TEST_P(CollectStatsConsent, SetCollectStatsConsentAtLevel) {
912  EXPECT_TRUE(GoogleUpdateSettings::SetCollectStatsConsentAtLevel(
913                  GetParam().system_level(),
914                  !GetParam().is_consent_granted()));
915  const std::wstring* const reg_keys[] = {
916    chrome_state_key_,
917    chrome_state_medium_key_,
918    binaries_state_key_,
919    binaries_state_medium_key_,
920  };
921  int key_index = ((GetParam().system_level() ? 1 : 0) +
922                   (GetParam().multi_install() ? 2 : 0));
923  const std::wstring& reg_key = *reg_keys[key_index];
924  DWORD value = 0;
925  EXPECT_EQ(
926      ERROR_SUCCESS,
927      RegKey(GetParam().root_key(), reg_key.c_str(),
928             KEY_QUERY_VALUE).ReadValueDW(google_update::kRegUsageStatsField,
929                                          &value));
930  if (GetParam().is_consent_granted()) {
931    EXPECT_FALSE(GoogleUpdateSettings::GetCollectStatsConsentAtLevel(
932                     GetParam().system_level()));
933    EXPECT_EQ(0UL, value);
934  } else {
935    EXPECT_TRUE(GoogleUpdateSettings::GetCollectStatsConsentAtLevel(
936                    GetParam().system_level()));
937    EXPECT_EQ(1UL, value);
938  }
939}
940
941INSTANTIATE_TEST_CASE_P(
942    UserLevelSingleInstall,
943    CollectStatsConsent,
944    ::testing::Values(
945        StatsState(StatsState::kUserLevel, StatsState::SINGLE_INSTALL,
946                   StatsState::NO_SETTING),
947        StatsState(StatsState::kUserLevel, StatsState::SINGLE_INSTALL,
948                   StatsState::FALSE_SETTING),
949        StatsState(StatsState::kUserLevel, StatsState::SINGLE_INSTALL,
950                   StatsState::TRUE_SETTING)));
951INSTANTIATE_TEST_CASE_P(
952    UserLevelMultiInstall,
953    CollectStatsConsent,
954    ::testing::Values(
955        StatsState(StatsState::kUserLevel, StatsState::MULTI_INSTALL,
956                   StatsState::NO_SETTING),
957        StatsState(StatsState::kUserLevel, StatsState::MULTI_INSTALL,
958                   StatsState::FALSE_SETTING),
959        StatsState(StatsState::kUserLevel, StatsState::MULTI_INSTALL,
960                   StatsState::TRUE_SETTING)));
961INSTANTIATE_TEST_CASE_P(
962    SystemLevelSingleInstall,
963    CollectStatsConsent,
964    ::testing::Values(
965        StatsState(StatsState::kSystemLevel, StatsState::SINGLE_INSTALL,
966                   StatsState::NO_SETTING, StatsState::NO_SETTING),
967        StatsState(StatsState::kSystemLevel, StatsState::SINGLE_INSTALL,
968                   StatsState::NO_SETTING, StatsState::FALSE_SETTING),
969        StatsState(StatsState::kSystemLevel, StatsState::SINGLE_INSTALL,
970                   StatsState::NO_SETTING, StatsState::TRUE_SETTING),
971        StatsState(StatsState::kSystemLevel, StatsState::SINGLE_INSTALL,
972                   StatsState::FALSE_SETTING, StatsState::NO_SETTING),
973        StatsState(StatsState::kSystemLevel, StatsState::SINGLE_INSTALL,
974                   StatsState::FALSE_SETTING, StatsState::FALSE_SETTING),
975        StatsState(StatsState::kSystemLevel, StatsState::SINGLE_INSTALL,
976                   StatsState::FALSE_SETTING, StatsState::TRUE_SETTING),
977        StatsState(StatsState::kSystemLevel, StatsState::SINGLE_INSTALL,
978                   StatsState::TRUE_SETTING, StatsState::NO_SETTING),
979        StatsState(StatsState::kSystemLevel, StatsState::SINGLE_INSTALL,
980                   StatsState::TRUE_SETTING, StatsState::FALSE_SETTING),
981        StatsState(StatsState::kSystemLevel, StatsState::SINGLE_INSTALL,
982                   StatsState::TRUE_SETTING, StatsState::TRUE_SETTING)));
983INSTANTIATE_TEST_CASE_P(
984    SystemLevelMultiInstall,
985    CollectStatsConsent,
986    ::testing::Values(
987        StatsState(StatsState::kSystemLevel, StatsState::MULTI_INSTALL,
988                   StatsState::NO_SETTING, StatsState::NO_SETTING),
989        StatsState(StatsState::kSystemLevel, StatsState::MULTI_INSTALL,
990                   StatsState::NO_SETTING, StatsState::FALSE_SETTING),
991        StatsState(StatsState::kSystemLevel, StatsState::MULTI_INSTALL,
992                   StatsState::NO_SETTING, StatsState::TRUE_SETTING),
993        StatsState(StatsState::kSystemLevel, StatsState::MULTI_INSTALL,
994                   StatsState::FALSE_SETTING, StatsState::NO_SETTING),
995        StatsState(StatsState::kSystemLevel, StatsState::MULTI_INSTALL,
996                   StatsState::FALSE_SETTING, StatsState::FALSE_SETTING),
997        StatsState(StatsState::kSystemLevel, StatsState::MULTI_INSTALL,
998                   StatsState::FALSE_SETTING, StatsState::TRUE_SETTING),
999        StatsState(StatsState::kSystemLevel, StatsState::MULTI_INSTALL,
1000                   StatsState::TRUE_SETTING, StatsState::NO_SETTING),
1001        StatsState(StatsState::kSystemLevel, StatsState::MULTI_INSTALL,
1002                   StatsState::TRUE_SETTING, StatsState::FALSE_SETTING),
1003        StatsState(StatsState::kSystemLevel, StatsState::MULTI_INSTALL,
1004                   StatsState::TRUE_SETTING, StatsState::TRUE_SETTING)));
1005