15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/installer/setup/setup_util_unittest.h"
6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/command_line.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/scoped_temp_dir.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
15a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "base/process/kill.h"
16a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "base/process/launch.h"
17a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "base/process/process_handle.h"
18558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "base/test/test_reg_util_win.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/platform_thread.h"
20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
21ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/version.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_handle.h"
23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/win/windows_version.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/setup/setup_util.h"
25ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "chrome/installer/setup/setup_constants.h"
26558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "chrome/installer/util/google_update_constants.h"
27ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "chrome/installer/util/installation_state.h"
28ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "chrome/installer/util/installer_state.h"
29ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "chrome/installer/util/util_constants.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SetupUtilTestWithDir : public testing::Test {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
36ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  virtual void SetUp() OVERRIDE {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Create a temp directory for testing.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(test_dir_.CreateUniqueTempDir());
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  virtual void TearDown() OVERRIDE {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Clean up test directory manually so we can fail if it leaks.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(test_dir_.Delete());
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The temporary directory used to contain the test operations.
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir test_dir_;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The privilege tested in ScopeTokenPrivilege tests below.
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use SE_RESTORE_NAME as it is one of the many privileges that is available,
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// but not enabled by default on processes running at high integrity.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const wchar_t kTestedPrivilege[] = SE_RESTORE_NAME;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true if the current process' token has privilege |privilege_name|
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// enabled.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CurrentProcessHasPrivilege(const wchar_t* privilege_name) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::ScopedHandle token;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          token.Receive())) {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ADD_FAILURE();
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First get the size of the buffer needed for |privileges| below.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD size;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(::GetTokenInformation(token, TokenPrivileges, NULL, 0, &size));
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<BYTE[]> privileges_bytes(new BYTE[size]);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TOKEN_PRIVILEGES* privileges =
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<TOKEN_PRIVILEGES*>(privileges_bytes.get());
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!::GetTokenInformation(token, TokenPrivileges, privileges, size, &size)) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ADD_FAILURE();
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There is no point getting a buffer to store more than |privilege_name|\0 as
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // anything longer will obviously not be equal to |privilege_name|.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const DWORD desired_size = wcslen(privilege_name);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const DWORD buffer_size = desired_size + 1;
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<wchar_t[]> name_buffer(new wchar_t[buffer_size]);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = privileges->PrivilegeCount - 1; i >= 0 ; --i) {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LUID_AND_ATTRIBUTES& luid_and_att = privileges->Privileges[i];
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DWORD size = buffer_size;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ::LookupPrivilegeName(NULL, &luid_and_att.Luid, name_buffer.get(), &size);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (size == desired_size &&
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        wcscmp(name_buffer.get(), privilege_name) == 0) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return luid_and_att.Attributes == SE_PRIVILEGE_ENABLED;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we are parsing Chrome version correctly.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SetupUtilTestWithDir, GetMaxVersionFromArchiveDirTest) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a version dir
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath chrome_dir = test_dir_.path().AppendASCII("1.0.0.0");
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_util::CreateDirectory(chrome_dir);
1027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ASSERT_TRUE(base::PathExists(chrome_dir));
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Version> version(
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      installer::GetMaxVersionFromArchiveDir(test_dir_.path()));
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(version->GetString(), "1.0.0.0");
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::DeleteFile(chrome_dir, true);
1087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ASSERT_FALSE(base::PathExists(chrome_dir));
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(installer::GetMaxVersionFromArchiveDir(test_dir_.path()) == NULL);
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome_dir = test_dir_.path().AppendASCII("ABC");
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_util::CreateDirectory(chrome_dir);
1137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ASSERT_TRUE(base::PathExists(chrome_dir));
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(installer::GetMaxVersionFromArchiveDir(test_dir_.path()) == NULL);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome_dir = test_dir_.path().AppendASCII("2.3.4.5");
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_util::CreateDirectory(chrome_dir);
1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ASSERT_TRUE(base::PathExists(chrome_dir));
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  version.reset(installer::GetMaxVersionFromArchiveDir(test_dir_.path()));
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(version->GetString(), "2.3.4.5");
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create multiple version dirs, ensure that we select the greatest.
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome_dir = test_dir_.path().AppendASCII("9.9.9.9");
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_util::CreateDirectory(chrome_dir);
1257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ASSERT_TRUE(base::PathExists(chrome_dir));
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome_dir = test_dir_.path().AppendASCII("1.1.1.1");
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_util::CreateDirectory(chrome_dir);
1287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ASSERT_TRUE(base::PathExists(chrome_dir));
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  version.reset(installer::GetMaxVersionFromArchiveDir(test_dir_.path()));
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(version->GetString(), "9.9.9.9");
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SetupUtilTestWithDir, DeleteFileFromTempProcess) {
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath test_file;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_util::CreateTemporaryFileInDir(test_dir_.path(), &test_file);
1377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ASSERT_TRUE(base::PathExists(test_file));
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_util::WriteFile(test_file, "foo", 3);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(installer::DeleteFileFromTempProcess(test_file, 0));
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(200));
1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(base::PathExists(test_file));
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note: This test is only valid when run at high integrity (i.e. it will fail
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// at medium integrity).
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(SetupUtilTest, ScopedTokenPrivilegeBasic) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(CurrentProcessHasPrivilege(kTestedPrivilege));
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    installer::ScopedTokenPrivilege test_scoped_privilege(kTestedPrivilege);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(test_scoped_privilege.is_enabled());
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(CurrentProcessHasPrivilege(kTestedPrivilege));
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(CurrentProcessHasPrivilege(kTestedPrivilege));
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note: This test is only valid when run at high integrity (i.e. it will fail
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// at medium integrity).
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(SetupUtilTest, ScopedTokenPrivilegeAlreadyEnabled) {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(CurrentProcessHasPrivilege(kTestedPrivilege));
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    installer::ScopedTokenPrivilege test_scoped_privilege(kTestedPrivilege);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(test_scoped_privilege.is_enabled());
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(CurrentProcessHasPrivilege(kTestedPrivilege));
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      installer::ScopedTokenPrivilege dup_scoped_privilege(kTestedPrivilege);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_TRUE(dup_scoped_privilege.is_enabled());
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_TRUE(CurrentProcessHasPrivilege(kTestedPrivilege));
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(CurrentProcessHasPrivilege(kTestedPrivilege));
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(CurrentProcessHasPrivilege(kTestedPrivilege));
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char kAdjustProcessPriority[] = "adjust-process-priority";
179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)PriorityClassChangeResult DoProcessPriorityAdjustment() {
181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return installer::AdjustProcessPriority() ? PCCR_CHANGED : PCCR_UNCHANGED;
182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace {
185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// A scoper that sets/resets the current process's priority class.
187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class ScopedPriorityClass {
188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public:
189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Applies |priority_class|, returning an instance if a change was made.
190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Otherwise, returns an empty scoped_ptr.
191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  static scoped_ptr<ScopedPriorityClass> Create(DWORD priority_class);
192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ~ScopedPriorityClass();
193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private:
195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  explicit ScopedPriorityClass(DWORD original_priority_class);
196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DWORD original_priority_class_;
197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ScopedPriorityClass);
198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)scoped_ptr<ScopedPriorityClass> ScopedPriorityClass::Create(
201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DWORD priority_class) {
202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HANDLE this_process = ::GetCurrentProcess();
203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DWORD original_priority_class = ::GetPriorityClass(this_process);
204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_NE(0U, original_priority_class);
205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (original_priority_class && original_priority_class != priority_class) {
206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    BOOL result = ::SetPriorityClass(this_process, priority_class);
207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_NE(FALSE, result);
208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (result) {
209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return scoped_ptr<ScopedPriorityClass>(
210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          new ScopedPriorityClass(original_priority_class));
211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return scoped_ptr<ScopedPriorityClass>();
214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ScopedPriorityClass::ScopedPriorityClass(DWORD original_priority_class)
217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : original_priority_class_(original_priority_class) {}
218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ScopedPriorityClass::~ScopedPriorityClass() {
220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  BOOL result = ::SetPriorityClass(::GetCurrentProcess(),
221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                   original_priority_class_);
222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_NE(FALSE, result);
223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)PriorityClassChangeResult RelaunchAndDoProcessPriorityAdjustment() {
226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CommandLine cmd_line(*CommandLine::ForCurrentProcess());
227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  cmd_line.AppendSwitch(kAdjustProcessPriority);
228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::ProcessHandle process_handle = NULL;
229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int exit_code = 0;
230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!base::LaunchProcess(cmd_line, base::LaunchOptions(),
231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           &process_handle)) {
232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ADD_FAILURE() << " to launch subprocess.";
233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } else if (!base::WaitForExitCode(process_handle, &exit_code)) {
234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ADD_FAILURE() << " to wait for subprocess to exit.";
235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } else {
236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return static_cast<PriorityClassChangeResult>(exit_code);
237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return PCCR_UNKNOWN;
239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
241868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace
242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Launching a subprocess at normal priority class is a noop.
244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST(SetupUtilTest, AdjustFromNormalPriority) {
245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(NORMAL_PRIORITY_CLASS, ::GetPriorityClass(::GetCurrentProcess()));
246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(PCCR_UNCHANGED, RelaunchAndDoProcessPriorityAdjustment());
247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Launching a subprocess below normal priority class drops it to bg mode for
250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// sufficiently recent operating systems.
251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST(SetupUtilTest, AdjustFromBelowNormalPriority) {
252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<ScopedPriorityClass> below_normal =
253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ScopedPriorityClass::Create(BELOW_NORMAL_PRIORITY_CLASS);
254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(below_normal);
255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (base::win::GetVersion() > base::win::VERSION_SERVER_2003)
256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_EQ(PCCR_CHANGED, RelaunchAndDoProcessPriorityAdjustment());
257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  else
258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_EQ(PCCR_UNCHANGED, RelaunchAndDoProcessPriorityAdjustment());
259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
260ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
261ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochnamespace {
262ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
263ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// A test fixture that configures an InstallationState and an InstallerState
264ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// with a product being updated.
265ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochclass FindArchiveToPatchTest : public SetupUtilTestWithDir {
266ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch protected:
267ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  class FakeInstallationState : public installer::InstallationState {
268ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  };
269ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
270ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  class FakeProductState : public installer::ProductState {
271ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch   public:
272ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    static FakeProductState* FromProductState(const ProductState* product) {
273ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      return static_cast<FakeProductState*>(const_cast<ProductState*>(product));
274ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    }
275ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
276ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    void set_version(const Version& version) {
277ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      if (version.IsValid())
278ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        version_.reset(new Version(version));
279ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      else
280ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        version_.reset();
281ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    }
282ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
283ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    void set_uninstall_command(const CommandLine& uninstall_command) {
284ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      uninstall_command_ = uninstall_command;
285ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    }
286ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  };
287ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
288ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  virtual void SetUp() OVERRIDE {
289ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    SetupUtilTestWithDir::SetUp();
290ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    product_version_ = Version("30.0.1559.0");
291ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    max_version_ = Version("47.0.1559.0");
292ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
293ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // Install the product according to the version.
294ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    original_state_.reset(new FakeInstallationState());
295ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    InstallProduct();
296ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
297ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // Prepare to update the product in the temp dir.
298ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    installer_state_.reset(new installer::InstallerState(
299ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        kSystemInstall_ ? installer::InstallerState::SYSTEM_LEVEL :
300ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        installer::InstallerState::USER_LEVEL));
301ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    installer_state_->AddProductFromState(
302ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        kProductType_,
303ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        *original_state_->GetProductState(kSystemInstall_, kProductType_));
304ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
305ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // Create archives in the two version dirs.
306ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    ASSERT_TRUE(
307ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        file_util::CreateDirectory(GetProductVersionArchivePath().DirName()));
308ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    ASSERT_EQ(1, file_util::WriteFile(GetProductVersionArchivePath(), "a", 1));
309ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    ASSERT_TRUE(
310ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        file_util::CreateDirectory(GetMaxVersionArchivePath().DirName()));
311ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    ASSERT_EQ(1, file_util::WriteFile(GetMaxVersionArchivePath(), "b", 1));
312ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
313ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
314ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  virtual void TearDown() OVERRIDE {
315ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    original_state_.reset();
316ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    SetupUtilTestWithDir::TearDown();
317ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
318ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
319ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::FilePath GetArchivePath(const Version& version) const {
320ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return test_dir_.path()
321ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        .AppendASCII(version.GetString())
322ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        .Append(installer::kInstallerDir)
323ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        .Append(installer::kChromeArchive);
324ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
325ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
326ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::FilePath GetMaxVersionArchivePath() const {
327ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return GetArchivePath(max_version_);
328ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
329ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
330ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::FilePath GetProductVersionArchivePath() const {
331ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return GetArchivePath(product_version_);
332ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
333ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
334ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  void InstallProduct() {
335ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    FakeProductState* product = FakeProductState::FromProductState(
336ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        original_state_->GetNonVersionedProductState(kSystemInstall_,
337ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                                     kProductType_));
338ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
339ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    product->set_version(product_version_);
340ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    CommandLine uninstall_command(
341ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        test_dir_.path().AppendASCII(product_version_.GetString())
342ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        .Append(installer::kInstallerDir)
343ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        .Append(installer::kSetupExe));
344ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    uninstall_command.AppendSwitch(installer::switches::kUninstall);
345ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    product->set_uninstall_command(uninstall_command);
346ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
347ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
348ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  void UninstallProduct() {
349ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    FakeProductState::FromProductState(
350ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        original_state_->GetNonVersionedProductState(kSystemInstall_,
351ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                                     kProductType_))
352ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        ->set_version(Version());
353ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
354ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
355ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  static const bool kSystemInstall_;
356ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  static const BrowserDistribution::Type kProductType_;
357ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  Version product_version_;
358ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  Version max_version_;
359ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  scoped_ptr<FakeInstallationState> original_state_;
360ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  scoped_ptr<installer::InstallerState> installer_state_;
361ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch};
362ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
363ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochconst bool FindArchiveToPatchTest::kSystemInstall_ = false;
364ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochconst BrowserDistribution::Type FindArchiveToPatchTest::kProductType_ =
365ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    BrowserDistribution::CHROME_BROWSER;
366ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
367ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}  // namespace
368ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
369ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Test that the path to the advertised product version is found.
370ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_F(FindArchiveToPatchTest, ProductVersionFound) {
371ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::FilePath patch_source(installer::FindArchiveToPatch(
372ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      *original_state_, *installer_state_));
373ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_EQ(GetProductVersionArchivePath().value(), patch_source.value());
374ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
375ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
376ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Test that the path to the max version is found if the advertised version is
377ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// missing.
378ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_F(FindArchiveToPatchTest, MaxVersionFound) {
379ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // The patch file is absent.
380ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  ASSERT_TRUE(base::DeleteFile(GetProductVersionArchivePath(), false));
381ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::FilePath patch_source(installer::FindArchiveToPatch(
382ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      *original_state_, *installer_state_));
383ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_EQ(GetMaxVersionArchivePath().value(), patch_source.value());
384ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
385ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // The product doesn't appear to be installed, so the max version is found.
386ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  UninstallProduct();
387ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  patch_source = installer::FindArchiveToPatch(
388ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      *original_state_, *installer_state_);
389ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_EQ(GetMaxVersionArchivePath().value(), patch_source.value());
390ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
391ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
392ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Test that an empty path is returned if no version is found.
393ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_F(FindArchiveToPatchTest, NoVersionFound) {
394ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // The product doesn't appear to be installed and no archives are present.
395ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  UninstallProduct();
396ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  ASSERT_TRUE(base::DeleteFile(GetProductVersionArchivePath(), false));
397ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  ASSERT_TRUE(base::DeleteFile(GetMaxVersionArchivePath(), false));
398ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
399ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::FilePath patch_source(installer::FindArchiveToPatch(
400ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      *original_state_, *installer_state_));
401ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_EQ(base::FilePath::StringType(), patch_source.value());
402ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
403558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
404558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochnamespace {
405558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
406558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochclass MigrateMultiToSingleTest : public testing::Test {
407558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch protected:
408558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  virtual void SetUp() OVERRIDE {
409558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    registry_override_manager_.OverrideRegistry(kRootKey,
410558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                                L"MigrateMultiToSingleTest");
411558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
412558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
413558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  virtual void TearDown() OVERRIDE {
414558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    registry_override_manager_.RemoveAllOverrides();
415558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
416558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
417558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  static const bool kSystemLevel = false;
418558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  static const HKEY kRootKey;
419558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  static const wchar_t kVersionString[];
420558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  static const wchar_t kMultiChannel[];
421558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  registry_util::RegistryOverrideManager registry_override_manager_;
422558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch};
423558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
424558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochconst bool MigrateMultiToSingleTest::kSystemLevel;
425558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochconst HKEY MigrateMultiToSingleTest::kRootKey =
426558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    kSystemLevel ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
427558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochconst wchar_t MigrateMultiToSingleTest::kVersionString[] = L"30.0.1574.0";
428558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochconst wchar_t MigrateMultiToSingleTest::kMultiChannel[] =
429558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    L"2.0-dev-multi-chromeframe";
430558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
431558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}  // namespace
432558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
433558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// Test migrating Chrome Frame from multi to single.
434558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_F(MigrateMultiToSingleTest, ChromeFrame) {
435558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  installer::ProductState chrome_frame;
436558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  installer::ProductState binaries;
437558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  DWORD usagestats = 0;
438558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
439558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Set up a config with dev-channel multi-install GCF.
440558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  base::win::RegKey key;
441558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
442558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  BrowserDistribution* dist = BrowserDistribution::GetSpecificDistribution(
443558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      BrowserDistribution::CHROME_BINARIES);
444558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  ASSERT_EQ(ERROR_SUCCESS,
445558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch            base::win::RegKey(kRootKey, dist->GetVersionKey().c_str(),
446558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                              KEY_SET_VALUE)
447558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                .WriteValue(google_update::kRegVersionField, kVersionString));
448558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  ASSERT_EQ(ERROR_SUCCESS,
449558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch            base::win::RegKey(kRootKey, dist->GetStateKey().c_str(),
450558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                              KEY_SET_VALUE)
451558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                .WriteValue(google_update::kRegApField, kMultiChannel));
452558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  ASSERT_EQ(ERROR_SUCCESS,
453558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch            base::win::RegKey(kRootKey, dist->GetStateKey().c_str(),
454558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                              KEY_SET_VALUE)
455558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                .WriteValue(google_update::kRegUsageStatsField, 1U));
456558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
457558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  dist = BrowserDistribution::GetSpecificDistribution(
458558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      BrowserDistribution::CHROME_FRAME);
459558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  ASSERT_EQ(ERROR_SUCCESS,
460558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch            base::win::RegKey(kRootKey, dist->GetVersionKey().c_str(),
461558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                              KEY_SET_VALUE)
462558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                .WriteValue(google_update::kRegVersionField, kVersionString));
463558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  ASSERT_EQ(ERROR_SUCCESS,
464558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch            base::win::RegKey(kRootKey, dist->GetStateKey().c_str(),
465558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                              KEY_SET_VALUE)
466558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                .WriteValue(google_update::kRegApField, kMultiChannel));
467558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
468558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Do the registry migration.
469558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  installer::InstallationState machine_state;
470558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  machine_state.Initialize();
471558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
472558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  installer::MigrateGoogleUpdateStateMultiToSingle(
473558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      kSystemLevel,
474558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      BrowserDistribution::CHROME_FRAME,
475558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      machine_state);
476558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
477558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Confirm that usagestats were copied to CF and that its channel was
478558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // stripped.
479558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  ASSERT_TRUE(chrome_frame.Initialize(kSystemLevel,
480558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                      BrowserDistribution::CHROME_FRAME));
481558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  EXPECT_TRUE(chrome_frame.GetUsageStats(&usagestats));
482558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  EXPECT_EQ(1U, usagestats);
483558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  EXPECT_EQ(L"2.0-dev", chrome_frame.channel().value());
484558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
485558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Confirm that the binaries' channel no longer contains GCF.
486558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  ASSERT_TRUE(binaries.Initialize(kSystemLevel,
487558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                  BrowserDistribution::CHROME_BINARIES));
488558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  EXPECT_EQ(L"2.0-dev-multi", binaries.channel().value());
489558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
490