setup_util_unittest.cc revision a3f7b4e666c476898878fa745f637129375cd889
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/path_service.h"
16a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "base/process/kill.h"
17a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "base/process/launch.h"
18a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "base/process/process_handle.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"
26ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "chrome/installer/util/installation_state.h"
27ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "chrome/installer/util/installer_state.h"
28ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "chrome/installer/util/util_constants.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SetupUtilTestWithDir : public testing::Test {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
35ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  virtual void SetUp() OVERRIDE {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Create a temp directory for testing.
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(test_dir_.CreateUniqueTempDir());
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  virtual void TearDown() OVERRIDE {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Clean up test directory manually so we can fail if it leaks.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(test_dir_.Delete());
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The temporary directory used to contain the test operations.
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir test_dir_;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The privilege tested in ScopeTokenPrivilege tests below.
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use SE_RESTORE_NAME as it is one of the many privileges that is available,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// but not enabled by default on processes running at high integrity.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const wchar_t kTestedPrivilege[] = SE_RESTORE_NAME;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true if the current process' token has privilege |privilege_name|
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// enabled.
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CurrentProcessHasPrivilege(const wchar_t* privilege_name) {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::ScopedHandle token;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY,
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          token.Receive())) {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ADD_FAILURE();
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First get the size of the buffer needed for |privileges| below.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD size;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(::GetTokenInformation(token, TokenPrivileges, NULL, 0, &size));
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<BYTE[]> privileges_bytes(new BYTE[size]);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TOKEN_PRIVILEGES* privileges =
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<TOKEN_PRIVILEGES*>(privileges_bytes.get());
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!::GetTokenInformation(token, TokenPrivileges, privileges, size, &size)) {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ADD_FAILURE();
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There is no point getting a buffer to store more than |privilege_name|\0 as
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // anything longer will obviously not be equal to |privilege_name|.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const DWORD desired_size = wcslen(privilege_name);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const DWORD buffer_size = desired_size + 1;
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<wchar_t[]> name_buffer(new wchar_t[buffer_size]);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = privileges->PrivilegeCount - 1; i >= 0 ; --i) {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LUID_AND_ATTRIBUTES& luid_and_att = privileges->Privileges[i];
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DWORD size = buffer_size;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ::LookupPrivilegeName(NULL, &luid_and_att.Luid, name_buffer.get(), &size);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (size == desired_size &&
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        wcscmp(name_buffer.get(), privilege_name) == 0) {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return luid_and_att.Attributes == SE_PRIVILEGE_ENABLED;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we are parsing Chrome version correctly.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SetupUtilTestWithDir, GetMaxVersionFromArchiveDirTest) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a version dir
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath chrome_dir = test_dir_.path().AppendASCII("1.0.0.0");
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_util::CreateDirectory(chrome_dir);
1017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ASSERT_TRUE(base::PathExists(chrome_dir));
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Version> version(
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      installer::GetMaxVersionFromArchiveDir(test_dir_.path()));
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(version->GetString(), "1.0.0.0");
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::DeleteFile(chrome_dir, true);
1077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ASSERT_FALSE(base::PathExists(chrome_dir));
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(installer::GetMaxVersionFromArchiveDir(test_dir_.path()) == NULL);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome_dir = test_dir_.path().AppendASCII("ABC");
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_util::CreateDirectory(chrome_dir);
1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ASSERT_TRUE(base::PathExists(chrome_dir));
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(installer::GetMaxVersionFromArchiveDir(test_dir_.path()) == NULL);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome_dir = test_dir_.path().AppendASCII("2.3.4.5");
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_util::CreateDirectory(chrome_dir);
1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ASSERT_TRUE(base::PathExists(chrome_dir));
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  version.reset(installer::GetMaxVersionFromArchiveDir(test_dir_.path()));
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(version->GetString(), "2.3.4.5");
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create multiple version dirs, ensure that we select the greatest.
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome_dir = test_dir_.path().AppendASCII("9.9.9.9");
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_util::CreateDirectory(chrome_dir);
1247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ASSERT_TRUE(base::PathExists(chrome_dir));
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome_dir = test_dir_.path().AppendASCII("1.1.1.1");
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_util::CreateDirectory(chrome_dir);
1277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ASSERT_TRUE(base::PathExists(chrome_dir));
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  version.reset(installer::GetMaxVersionFromArchiveDir(test_dir_.path()));
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(version->GetString(), "9.9.9.9");
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SetupUtilTestWithDir, DeleteFileFromTempProcess) {
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath test_file;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_util::CreateTemporaryFileInDir(test_dir_.path(), &test_file);
1367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ASSERT_TRUE(base::PathExists(test_file));
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_util::WriteFile(test_file, "foo", 3);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(installer::DeleteFileFromTempProcess(test_file, 0));
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(200));
1407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(base::PathExists(test_file));
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note: This test is only valid when run at high integrity (i.e. it will fail
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// at medium integrity).
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(SetupUtilTest, ScopedTokenPrivilegeBasic) {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(CurrentProcessHasPrivilege(kTestedPrivilege));
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    installer::ScopedTokenPrivilege test_scoped_privilege(kTestedPrivilege);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(test_scoped_privilege.is_enabled());
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(CurrentProcessHasPrivilege(kTestedPrivilege));
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(CurrentProcessHasPrivilege(kTestedPrivilege));
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note: This test is only valid when run at high integrity (i.e. it will fail
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// at medium integrity).
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(SetupUtilTest, ScopedTokenPrivilegeAlreadyEnabled) {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(CurrentProcessHasPrivilege(kTestedPrivilege));
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    installer::ScopedTokenPrivilege test_scoped_privilege(kTestedPrivilege);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(test_scoped_privilege.is_enabled());
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(CurrentProcessHasPrivilege(kTestedPrivilege));
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      installer::ScopedTokenPrivilege dup_scoped_privilege(kTestedPrivilege);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_TRUE(dup_scoped_privilege.is_enabled());
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_TRUE(CurrentProcessHasPrivilege(kTestedPrivilege));
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(CurrentProcessHasPrivilege(kTestedPrivilege));
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(CurrentProcessHasPrivilege(kTestedPrivilege));
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char kAdjustProcessPriority[] = "adjust-process-priority";
178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)PriorityClassChangeResult DoProcessPriorityAdjustment() {
180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return installer::AdjustProcessPriority() ? PCCR_CHANGED : PCCR_UNCHANGED;
181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace {
184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// A scoper that sets/resets the current process's priority class.
186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class ScopedPriorityClass {
187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public:
188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Applies |priority_class|, returning an instance if a change was made.
189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Otherwise, returns an empty scoped_ptr.
190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  static scoped_ptr<ScopedPriorityClass> Create(DWORD priority_class);
191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ~ScopedPriorityClass();
192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private:
194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  explicit ScopedPriorityClass(DWORD original_priority_class);
195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DWORD original_priority_class_;
196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ScopedPriorityClass);
197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)scoped_ptr<ScopedPriorityClass> ScopedPriorityClass::Create(
200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DWORD priority_class) {
201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HANDLE this_process = ::GetCurrentProcess();
202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DWORD original_priority_class = ::GetPriorityClass(this_process);
203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_NE(0U, original_priority_class);
204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (original_priority_class && original_priority_class != priority_class) {
205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    BOOL result = ::SetPriorityClass(this_process, priority_class);
206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_NE(FALSE, result);
207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (result) {
208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return scoped_ptr<ScopedPriorityClass>(
209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          new ScopedPriorityClass(original_priority_class));
210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return scoped_ptr<ScopedPriorityClass>();
213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ScopedPriorityClass::ScopedPriorityClass(DWORD original_priority_class)
216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : original_priority_class_(original_priority_class) {}
217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ScopedPriorityClass::~ScopedPriorityClass() {
219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  BOOL result = ::SetPriorityClass(::GetCurrentProcess(),
220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                   original_priority_class_);
221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_NE(FALSE, result);
222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)PriorityClassChangeResult RelaunchAndDoProcessPriorityAdjustment() {
225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CommandLine cmd_line(*CommandLine::ForCurrentProcess());
226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  cmd_line.AppendSwitch(kAdjustProcessPriority);
227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::ProcessHandle process_handle = NULL;
228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int exit_code = 0;
229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!base::LaunchProcess(cmd_line, base::LaunchOptions(),
230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                           &process_handle)) {
231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ADD_FAILURE() << " to launch subprocess.";
232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } else if (!base::WaitForExitCode(process_handle, &exit_code)) {
233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ADD_FAILURE() << " to wait for subprocess to exit.";
234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } else {
235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return static_cast<PriorityClassChangeResult>(exit_code);
236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return PCCR_UNKNOWN;
238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace
241868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Launching a subprocess at normal priority class is a noop.
243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST(SetupUtilTest, AdjustFromNormalPriority) {
244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(NORMAL_PRIORITY_CLASS, ::GetPriorityClass(::GetCurrentProcess()));
245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(PCCR_UNCHANGED, RelaunchAndDoProcessPriorityAdjustment());
246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Launching a subprocess below normal priority class drops it to bg mode for
249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// sufficiently recent operating systems.
250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST(SetupUtilTest, AdjustFromBelowNormalPriority) {
251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<ScopedPriorityClass> below_normal =
252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ScopedPriorityClass::Create(BELOW_NORMAL_PRIORITY_CLASS);
253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(below_normal);
254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (base::win::GetVersion() > base::win::VERSION_SERVER_2003)
255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_EQ(PCCR_CHANGED, RelaunchAndDoProcessPriorityAdjustment());
256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  else
257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_EQ(PCCR_UNCHANGED, RelaunchAndDoProcessPriorityAdjustment());
258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
259ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
260ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochnamespace {
261ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
262ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// A test fixture that configures an InstallationState and an InstallerState
263ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// with a product being updated.
264ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochclass FindArchiveToPatchTest : public SetupUtilTestWithDir {
265ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch protected:
266ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  class FakeInstallationState : public installer::InstallationState {
267ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  };
268ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
269ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  class FakeProductState : public installer::ProductState {
270ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch   public:
271ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    static FakeProductState* FromProductState(const ProductState* product) {
272ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      return static_cast<FakeProductState*>(const_cast<ProductState*>(product));
273ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    }
274ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
275ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    void set_version(const Version& version) {
276ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      if (version.IsValid())
277ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        version_.reset(new Version(version));
278ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      else
279ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        version_.reset();
280ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    }
281ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
282ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    void set_uninstall_command(const CommandLine& uninstall_command) {
283ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      uninstall_command_ = uninstall_command;
284ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    }
285ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  };
286ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
287ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  virtual void SetUp() OVERRIDE {
288ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    SetupUtilTestWithDir::SetUp();
289ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    product_version_ = Version("30.0.1559.0");
290ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    max_version_ = Version("47.0.1559.0");
291ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
292ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // Install the product according to the version.
293ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    original_state_.reset(new FakeInstallationState());
294ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    InstallProduct();
295ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
296ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // Prepare to update the product in the temp dir.
297ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    installer_state_.reset(new installer::InstallerState(
298ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        kSystemInstall_ ? installer::InstallerState::SYSTEM_LEVEL :
299ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        installer::InstallerState::USER_LEVEL));
300ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    installer_state_->AddProductFromState(
301ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        kProductType_,
302ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        *original_state_->GetProductState(kSystemInstall_, kProductType_));
303ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
304ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // Create archives in the two version dirs.
305ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    ASSERT_TRUE(
306ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        file_util::CreateDirectory(GetProductVersionArchivePath().DirName()));
307ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    ASSERT_EQ(1, file_util::WriteFile(GetProductVersionArchivePath(), "a", 1));
308ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    ASSERT_TRUE(
309ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        file_util::CreateDirectory(GetMaxVersionArchivePath().DirName()));
310ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    ASSERT_EQ(1, file_util::WriteFile(GetMaxVersionArchivePath(), "b", 1));
311ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
312ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
313ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  virtual void TearDown() OVERRIDE {
314ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    original_state_.reset();
315ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    SetupUtilTestWithDir::TearDown();
316ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
317ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
318ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::FilePath GetArchivePath(const Version& version) const {
319ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return test_dir_.path()
320ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        .AppendASCII(version.GetString())
321ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        .Append(installer::kInstallerDir)
322ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        .Append(installer::kChromeArchive);
323ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
324ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
325ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::FilePath GetMaxVersionArchivePath() const {
326ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return GetArchivePath(max_version_);
327ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
328ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
329ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::FilePath GetProductVersionArchivePath() const {
330ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return GetArchivePath(product_version_);
331ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
332ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
333ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  void InstallProduct() {
334ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    FakeProductState* product = FakeProductState::FromProductState(
335ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        original_state_->GetNonVersionedProductState(kSystemInstall_,
336ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                                     kProductType_));
337ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
338ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    product->set_version(product_version_);
339ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    CommandLine uninstall_command(
340ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        test_dir_.path().AppendASCII(product_version_.GetString())
341ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        .Append(installer::kInstallerDir)
342ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        .Append(installer::kSetupExe));
343ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    uninstall_command.AppendSwitch(installer::switches::kUninstall);
344ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    product->set_uninstall_command(uninstall_command);
345ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
346ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
347ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  void UninstallProduct() {
348ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    FakeProductState::FromProductState(
349ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        original_state_->GetNonVersionedProductState(kSystemInstall_,
350ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                                     kProductType_))
351ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        ->set_version(Version());
352ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
353ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
354ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  static const bool kSystemInstall_;
355ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  static const BrowserDistribution::Type kProductType_;
356ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  Version product_version_;
357ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  Version max_version_;
358ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  scoped_ptr<FakeInstallationState> original_state_;
359ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  scoped_ptr<installer::InstallerState> installer_state_;
360ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch};
361ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
362ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochconst bool FindArchiveToPatchTest::kSystemInstall_ = false;
363ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochconst BrowserDistribution::Type FindArchiveToPatchTest::kProductType_ =
364ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    BrowserDistribution::CHROME_BROWSER;
365ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
366ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}  // namespace
367ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
368ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Test that the path to the advertised product version is found.
369ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_F(FindArchiveToPatchTest, ProductVersionFound) {
370ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::FilePath patch_source(installer::FindArchiveToPatch(
371ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      *original_state_, *installer_state_));
372ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_EQ(GetProductVersionArchivePath().value(), patch_source.value());
373ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
374ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
375ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Test that the path to the max version is found if the advertised version is
376ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// missing.
377ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_F(FindArchiveToPatchTest, MaxVersionFound) {
378ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // The patch file is absent.
379ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  ASSERT_TRUE(base::DeleteFile(GetProductVersionArchivePath(), false));
380ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::FilePath patch_source(installer::FindArchiveToPatch(
381ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      *original_state_, *installer_state_));
382ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_EQ(GetMaxVersionArchivePath().value(), patch_source.value());
383ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
384ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // The product doesn't appear to be installed, so the max version is found.
385ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  UninstallProduct();
386ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  patch_source = installer::FindArchiveToPatch(
387ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      *original_state_, *installer_state_);
388ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_EQ(GetMaxVersionArchivePath().value(), patch_source.value());
389ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
390ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
391ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Test that an empty path is returned if no version is found.
392ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTEST_F(FindArchiveToPatchTest, NoVersionFound) {
393ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // The product doesn't appear to be installed and no archives are present.
394ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  UninstallProduct();
395ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  ASSERT_TRUE(base::DeleteFile(GetProductVersionArchivePath(), false));
396ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  ASSERT_TRUE(base::DeleteFile(GetMaxVersionArchivePath(), false));
397ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
398ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::FilePath patch_source(installer::FindArchiveToPatch(
399ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      *original_state_, *installer_state_));
400ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_EQ(base::FilePath::StringType(), patch_source.value());
401ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
402