installer_state_unittest.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// Use of this source code is governed by a BSD-style license that can be
3f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// found in the LICENSE file.
4f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
5f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include <windows.h>
6f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
7f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include <fstream>
8f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
9f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "base/base_paths.h"
10f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "base/command_line.h"
11f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "base/file_util.h"
12f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "base/files/file_path.h"
13f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "base/files/scoped_temp_dir.h"
14f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "base/path_service.h"
15b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek#include "base/process_util.h"
16f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "base/string_util.h"
17f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "base/test/test_reg_util_win.h"
18f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "base/utf_string_conversions.h"
19f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "base/version.h"
20f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "base/win/registry.h"
21f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "base/win/scoped_handle.h"
22f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "chrome/common/chrome_constants.h"
23f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "chrome/installer/test/alternate_version_generator.h"
24f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "chrome/installer/util/fake_installation_state.h"
25f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "chrome/installer/util/fake_product_state.h"
26f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "chrome/installer/util/google_update_constants.h"
27f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "chrome/installer/util/helper.h"
28f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "chrome/installer/util/installation_state.h"
29f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "chrome/installer/util/installer_state.h"
30f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "chrome/installer/util/master_preferences.h"
31f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "chrome/installer/util/product_unittest.h"
3234d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek#include "chrome/installer/util/util_constants.h"
33f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "chrome/installer/util/work_item.h"
34f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "testing/gtest/include/gtest/gtest.h"
35f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
36f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek#include "installer_util_strings.h"  // NOLINT
37f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
38f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenekusing base::win::RegKey;
39f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenekusing installer::InstallationState;
40f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenekusing installer::InstallerState;
41f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenekusing installer::MasterPreferences;
42f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenekusing registry_util::RegistryOverrideManager;
43f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
44f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenekclass InstallerStateTest : public TestWithTempDirAndDeleteTempOverrideKeys {
45f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek protected:
46f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek};
47f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
48f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// An installer state on which we can access otherwise protected members.
49f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenekclass MockInstallerState : public InstallerState {
50f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek public:
51f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  MockInstallerState() : InstallerState() { }
52f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  void set_target_path(const base::FilePath& target_path) {
53f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek    target_path_ = target_path;
54f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  }
55f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  static bool IsFileInUse(const base::FilePath& file) {
56f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek    return InstallerState::IsFileInUse(file);
57f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  }
58f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  const Version& critical_update_version() const {
59f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek    return critical_update_version_;
60f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  }
61f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  void GetExistingExeVersions(std::set<std::string>* existing_version_strings) {
62f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek    return InstallerState::GetExistingExeVersions(existing_version_strings);
63f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  }
64f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek};
65f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
66f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// Simple function to dump some text into a new file.
67f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenekvoid CreateTextFile(const std::wstring& filename,
68f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek                    const std::wstring& contents) {
69f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  std::ofstream file;
70f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  file.open(filename.c_str());
71f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  ASSERT_TRUE(file.is_open());
72f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  file << contents;
73f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  file.close();
74f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek}
75f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
76f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenekvoid BuildSingleChromeState(const base::FilePath& target_dir,
77f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek                            MockInstallerState* installer_state) {
78f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  CommandLine cmd_line = CommandLine::FromString(L"setup.exe");
79f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  MasterPreferences prefs(cmd_line);
80f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  InstallationState machine_state;
81f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  machine_state.Initialize();
82f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  installer_state->Initialize(cmd_line, prefs, machine_state);
83f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  installer_state->set_target_path(target_dir);
84f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  EXPECT_TRUE(installer_state->FindProduct(BrowserDistribution::CHROME_BROWSER)
85f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek      != NULL);
86f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  EXPECT_TRUE(installer_state->FindProduct(BrowserDistribution::CHROME_FRAME)
87f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek      == NULL);
88f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek}
89f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
90f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenekwchar_t text_content_1[] = L"delete me";
91f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenekwchar_t text_content_2[] = L"delete me as well";
92f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
93f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// Delete version directories. Everything lower than the given version
94f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// should be deleted.
95f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted KremenekTEST_F(InstallerStateTest, Delete) {
96f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  // TODO(grt): move common stuff into the test fixture.
97f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  // Create a Chrome dir
98f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  base::FilePath chrome_dir(test_dir_.path());
99f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  chrome_dir = chrome_dir.AppendASCII("chrome");
100f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  file_util::CreateDirectory(chrome_dir);
101f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  ASSERT_TRUE(file_util::PathExists(chrome_dir));
102f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
103f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  base::FilePath chrome_dir_1(chrome_dir);
104f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  chrome_dir_1 = chrome_dir_1.AppendASCII("1.0.1.0");
10534d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  file_util::CreateDirectory(chrome_dir_1);
106f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  ASSERT_TRUE(file_util::PathExists(chrome_dir_1));
107f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
108f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  base::FilePath chrome_dir_2(chrome_dir);
109f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  chrome_dir_2 = chrome_dir_2.AppendASCII("1.0.2.0");
110b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  file_util::CreateDirectory(chrome_dir_2);
111f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  ASSERT_TRUE(file_util::PathExists(chrome_dir_2));
112f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
113f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  base::FilePath chrome_dir_3(chrome_dir);
11434d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  chrome_dir_3 = chrome_dir_3.AppendASCII("1.0.3.0");
115f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  file_util::CreateDirectory(chrome_dir_3);
116f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  ASSERT_TRUE(file_util::PathExists(chrome_dir_3));
117f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
118f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  base::FilePath chrome_dir_4(chrome_dir);
119f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  chrome_dir_4 = chrome_dir_4.AppendASCII("1.0.4.0");
120f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  file_util::CreateDirectory(chrome_dir_4);
121f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  ASSERT_TRUE(file_util::PathExists(chrome_dir_4));
122f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
123f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  base::FilePath chrome_dll_1(chrome_dir_1);
124f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  chrome_dll_1 = chrome_dll_1.AppendASCII("chrome.dll");
125f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  CreateTextFile(chrome_dll_1.value(), text_content_1);
126f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  ASSERT_TRUE(file_util::PathExists(chrome_dll_1));
127f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
128f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  base::FilePath chrome_dll_2(chrome_dir_2);
129f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  chrome_dll_2 = chrome_dll_2.AppendASCII("chrome.dll");
130f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  CreateTextFile(chrome_dll_2.value(), text_content_1);
131f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  ASSERT_TRUE(file_util::PathExists(chrome_dll_2));
132f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
133f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  base::FilePath chrome_dll_3(chrome_dir_3);
134f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  chrome_dll_3 = chrome_dll_3.AppendASCII("chrome.dll");
135f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  CreateTextFile(chrome_dll_3.value(), text_content_1);
136f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  ASSERT_TRUE(file_util::PathExists(chrome_dll_3));
137b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek
138b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  base::FilePath chrome_dll_4(chrome_dir_4);
139b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  chrome_dll_4 = chrome_dll_4.AppendASCII("chrome.dll");
140b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  CreateTextFile(chrome_dll_4.value(), text_content_1);
141b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  ASSERT_TRUE(file_util::PathExists(chrome_dll_4));
142b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek
143b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  MockInstallerState installer_state;
144b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  BuildSingleChromeState(chrome_dir, &installer_state);
145b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  Version latest_version("1.0.4.0");
146b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  {
147b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek    base::ScopedTempDir temp_dir;
148f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek    ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
149f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek    installer_state.RemoveOldVersionDirectories(latest_version, NULL,
150f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek                                                temp_dir.path());
151f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  }
152f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
15334d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  // old versions should be gone
15434d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  EXPECT_FALSE(file_util::PathExists(chrome_dir_1));
15534d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  EXPECT_FALSE(file_util::PathExists(chrome_dir_2));
15634d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  EXPECT_FALSE(file_util::PathExists(chrome_dir_3));
15734d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  // the latest version should stay
15834d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  EXPECT_TRUE(file_util::PathExists(chrome_dll_4));
15934d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek}
16034d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek
16134d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek// Delete older version directories, keeping the one in used intact.
16234d7734b6ed1d9c0f647405e065251eb67f42badTed KremenekTEST_F(InstallerStateTest, DeleteInUsed) {
16334d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  // Create a Chrome dir
16434d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  base::FilePath chrome_dir(test_dir_.path());
16534d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  chrome_dir = chrome_dir.AppendASCII("chrome");
16634d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  file_util::CreateDirectory(chrome_dir);
16734d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  ASSERT_TRUE(file_util::PathExists(chrome_dir));
16834d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek
16934d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  base::FilePath chrome_dir_1(chrome_dir);
17034d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  chrome_dir_1 = chrome_dir_1.AppendASCII("1.0.1.0");
17134d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  file_util::CreateDirectory(chrome_dir_1);
17234d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  ASSERT_TRUE(file_util::PathExists(chrome_dir_1));
17334d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek
17434d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  base::FilePath chrome_dir_2(chrome_dir);
17534d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  chrome_dir_2 = chrome_dir_2.AppendASCII("1.0.2.0");
17634d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  file_util::CreateDirectory(chrome_dir_2);
17734d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  ASSERT_TRUE(file_util::PathExists(chrome_dir_2));
17834d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek
17934d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  base::FilePath chrome_dir_3(chrome_dir);
18034d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  chrome_dir_3 = chrome_dir_3.AppendASCII("1.0.3.0");
18134d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  file_util::CreateDirectory(chrome_dir_3);
18234d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  ASSERT_TRUE(file_util::PathExists(chrome_dir_3));
183f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
184f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  base::FilePath chrome_dir_4(chrome_dir);
185f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  chrome_dir_4 = chrome_dir_4.AppendASCII("1.0.4.0");
186f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  file_util::CreateDirectory(chrome_dir_4);
187f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  ASSERT_TRUE(file_util::PathExists(chrome_dir_4));
188f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
189f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  base::FilePath chrome_dll_1(chrome_dir_1);
190f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  chrome_dll_1 = chrome_dll_1.AppendASCII("chrome.dll");
191f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  CreateTextFile(chrome_dll_1.value(), text_content_1);
192f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  ASSERT_TRUE(file_util::PathExists(chrome_dll_1));
193f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
194f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  base::FilePath chrome_dll_2(chrome_dir_2);
195f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  chrome_dll_2 = chrome_dll_2.AppendASCII("chrome.dll");
196f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  CreateTextFile(chrome_dll_2.value(), text_content_1);
197f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  ASSERT_TRUE(file_util::PathExists(chrome_dll_2));
198f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
199f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  // Open the file to make it in use.
200f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  std::ofstream file;
201f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  file.open(chrome_dll_2.value().c_str());
202f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
203f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  base::FilePath chrome_othera_2(chrome_dir_2);
204f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  chrome_othera_2 = chrome_othera_2.AppendASCII("othera.dll");
205f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  CreateTextFile(chrome_othera_2.value(), text_content_2);
206f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  ASSERT_TRUE(file_util::PathExists(chrome_othera_2));
207f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
208f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  base::FilePath chrome_otherb_2(chrome_dir_2);
209f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  chrome_otherb_2 = chrome_otherb_2.AppendASCII("otherb.dll");
210f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  CreateTextFile(chrome_otherb_2.value(), text_content_2);
211f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  ASSERT_TRUE(file_util::PathExists(chrome_otherb_2));
212f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
213f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  base::FilePath chrome_dll_3(chrome_dir_3);
214f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  chrome_dll_3 = chrome_dll_3.AppendASCII("chrome.dll");
215f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  CreateTextFile(chrome_dll_3.value(), text_content_1);
216f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  ASSERT_TRUE(file_util::PathExists(chrome_dll_3));
217f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
218f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  base::FilePath chrome_dll_4(chrome_dir_4);
219f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  chrome_dll_4 = chrome_dll_4.AppendASCII("chrome.dll");
220f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  CreateTextFile(chrome_dll_4.value(), text_content_1);
221f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  ASSERT_TRUE(file_util::PathExists(chrome_dll_4));
222f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
223f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  MockInstallerState installer_state;
224f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  BuildSingleChromeState(chrome_dir, &installer_state);
225f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  Version latest_version("1.0.4.0");
226f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  Version existing_version("1.0.1.0");
227f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  {
228f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek    base::ScopedTempDir temp_dir;
229f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek    ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
230f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek    installer_state.RemoveOldVersionDirectories(latest_version,
231f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek                                                &existing_version,
232f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek                                                temp_dir.path());
233f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  }
234f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
235f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  // the version defined as the existing version should stay
236f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  EXPECT_TRUE(file_util::PathExists(chrome_dir_1));
237f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  // old versions not in used should be gone
238f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  EXPECT_FALSE(file_util::PathExists(chrome_dir_3));
239f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  // every thing under in used version should stay
240f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  EXPECT_TRUE(file_util::PathExists(chrome_dir_2));
241f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  EXPECT_TRUE(file_util::PathExists(chrome_dll_2));
242f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  EXPECT_TRUE(file_util::PathExists(chrome_othera_2));
243f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  EXPECT_TRUE(file_util::PathExists(chrome_otherb_2));
244f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  // the latest version should stay
245f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  EXPECT_TRUE(file_util::PathExists(chrome_dll_4));
246f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek}
247f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
248f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// Tests a few basic things of the Package class.  Makes sure that the path
249f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek// operations are correct
250f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted KremenekTEST_F(InstallerStateTest, Basic) {
251f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  const bool multi_install = false;
252f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  const bool system_level = true;
253f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  CommandLine cmd_line = CommandLine::FromString(
254f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek      std::wstring(L"setup.exe") +
255f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek      (multi_install ? L" --multi-install --chrome" : L"") +
256f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek      (system_level ? L" --system-level" : L""));
257f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  MasterPreferences prefs(cmd_line);
258f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  InstallationState machine_state;
259f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  machine_state.Initialize();
260f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  MockInstallerState installer_state;
261b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  installer_state.Initialize(cmd_line, prefs, machine_state);
262bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek  installer_state.set_target_path(test_dir_.path());
263bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek  EXPECT_EQ(test_dir_.path().value(), installer_state.target_path().value());
264bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek  EXPECT_EQ(1U, installer_state.products().size());
265bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek
26634d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  const char kOldVersion[] = "1.2.3.4";
26734d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  const char kNewVersion[] = "2.3.4.5";
26834d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek
26934d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  Version new_version(kNewVersion);
270b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  Version old_version(kOldVersion);
271bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek  ASSERT_TRUE(new_version.IsValid());
272bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek  ASSERT_TRUE(old_version.IsValid());
273b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek
274b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  base::FilePath installer_dir(
275b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek      installer_state.GetInstallerDirectory(new_version));
276bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek  EXPECT_FALSE(installer_dir.empty());
277b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek
27834d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  base::FilePath new_version_dir(installer_state.target_path().Append(
27934d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek      UTF8ToWide(new_version.GetString())));
28034d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek  base::FilePath old_version_dir(installer_state.target_path().Append(
28134d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek      UTF8ToWide(old_version.GetString())));
28234d7734b6ed1d9c0f647405e065251eb67f42badTed Kremenek
283bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek  EXPECT_FALSE(file_util::PathExists(new_version_dir));
284bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek  EXPECT_FALSE(file_util::PathExists(old_version_dir));
285bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek
286bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek  EXPECT_FALSE(file_util::PathExists(installer_dir));
287bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek  file_util::CreateDirectory(installer_dir);
288bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek  EXPECT_TRUE(file_util::PathExists(new_version_dir));
289bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek
290bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek  file_util::CreateDirectory(old_version_dir);
291bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek  EXPECT_TRUE(file_util::PathExists(old_version_dir));
292bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek
293bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek  // Create a fake chrome.dll key file in the old version directory.  This
294b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  // should prevent the old version directory from getting deleted.
295b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  base::FilePath old_chrome_dll(old_version_dir.Append(installer::kChromeDll));
296b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  EXPECT_FALSE(file_util::PathExists(old_chrome_dll));
297b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek
298b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  // Hold on to the file exclusively to prevent the directory from
299b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  // being deleted.
300b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  base::win::ScopedHandle file(
301b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek    ::CreateFile(old_chrome_dll.value().c_str(), GENERIC_READ,
302b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek                 0, NULL, OPEN_ALWAYS, 0, NULL));
303b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  EXPECT_TRUE(file.IsValid());
304b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  EXPECT_TRUE(file_util::PathExists(old_chrome_dll));
305b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek
306b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  base::ScopedTempDir temp_dir;
307b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
308b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek
309b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  // Don't explicitly tell the directory cleanup logic not to delete the
310b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  // old version, rely on the key files to keep it around.
311b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  installer_state.RemoveOldVersionDirectories(new_version,
312b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek                                              NULL,
313b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek                                              temp_dir.path());
314b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek
315b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  // The old directory should still exist.
316bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek  EXPECT_TRUE(file_util::PathExists(old_version_dir));
317bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek  EXPECT_TRUE(file_util::PathExists(new_version_dir));
318bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek
319bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek  // Now close the file handle to make it possible to delete our key file.
320f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  file.Close();
321f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
322f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  installer_state.RemoveOldVersionDirectories(new_version,
323f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek                                              NULL,
324f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek                                              temp_dir.path());
325f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  // The new directory should still exist.
326f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  EXPECT_TRUE(file_util::PathExists(new_version_dir));
327f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
328f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  // Now, the old directory and key file should be gone.
329f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  EXPECT_FALSE(file_util::PathExists(old_chrome_dll));
330f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  EXPECT_FALSE(file_util::PathExists(old_version_dir));
331f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek}
332f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek
333f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted KremenekTEST_F(InstallerStateTest, WithProduct) {
334f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  const bool multi_install = false;
335f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  const bool system_level = true;
336f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  CommandLine cmd_line = CommandLine::FromString(
337f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek      std::wstring(L"setup.exe") +
338f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek      (multi_install ? L" --multi-install --chrome" : L"") +
339f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek      (system_level ? L" --system-level" : L""));
340f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  MasterPreferences prefs(cmd_line);
341f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  InstallationState machine_state;
342f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  machine_state.Initialize();
343f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  MockInstallerState installer_state;
344f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  installer_state.Initialize(cmd_line, prefs, machine_state);
345f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  installer_state.set_target_path(test_dir_.path());
346f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  EXPECT_EQ(1U, installer_state.products().size());
347b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  EXPECT_EQ(system_level, installer_state.system_install());
348b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek
349b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  const char kCurrentVersion[] = "1.2.3.4";
350b35a74a40c1d2656a25e560e773ed48bdf49f9c0Ted Kremenek  Version current_version(kCurrentVersion);
351bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek
352bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek  HKEY root = system_level ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
353bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek  EXPECT_EQ(root, installer_state.root_key());
354bc46f345838b1c0d420dbd3655c94f5f360fb5b8Ted Kremenek
355f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek  {
356f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek    RegistryOverrideManager override_manager;
357f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek    override_manager.OverrideRegistry(root, L"root_pit");
358f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek    BrowserDistribution* dist = BrowserDistribution::GetSpecificDistribution(
359f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek        BrowserDistribution::CHROME_BROWSER);
360f4381fddf152a63e1ac97185293c47ec0ac2f1a6Ted Kremenek    RegKey chrome_key(root, dist->GetVersionKey().c_str(), KEY_ALL_ACCESS);
361    EXPECT_TRUE(chrome_key.Valid());
362    if (chrome_key.Valid()) {
363      chrome_key.WriteValue(google_update::kRegVersionField,
364                            UTF8ToWide(current_version.GetString()).c_str());
365      machine_state.Initialize();
366      // TODO(tommi): Also test for when there exists a new_chrome.exe.
367      Version found_version(*installer_state.GetCurrentVersion(machine_state));
368      EXPECT_TRUE(found_version.IsValid());
369      if (found_version.IsValid())
370        EXPECT_TRUE(current_version.Equals(found_version));
371    }
372  }
373}
374
375TEST_F(InstallerStateTest, InstallerResult) {
376  const bool system_level = true;
377  bool multi_install = false;
378  HKEY root = system_level ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
379
380  RegKey key;
381  std::wstring launch_cmd = L"hey diddle diddle";
382  std::wstring value;
383  DWORD dw_value;
384
385  // check results for a fresh install of single Chrome
386  {
387    RegistryOverrideManager override_manager;
388    override_manager.OverrideRegistry(root, L"root_inst_res");
389    CommandLine cmd_line = CommandLine::FromString(L"setup.exe --system-level");
390    const MasterPreferences prefs(cmd_line);
391    InstallationState machine_state;
392    machine_state.Initialize();
393    InstallerState state;
394    state.Initialize(cmd_line, prefs, machine_state);
395    state.WriteInstallerResult(installer::FIRST_INSTALL_SUCCESS,
396                               IDS_INSTALL_OS_ERROR_BASE, &launch_cmd);
397    BrowserDistribution* distribution =
398        BrowserDistribution::GetSpecificDistribution(
399            BrowserDistribution::CHROME_BROWSER);
400    EXPECT_EQ(ERROR_SUCCESS,
401        key.Open(root, distribution->GetStateKey().c_str(), KEY_READ));
402    EXPECT_EQ(ERROR_SUCCESS,
403        key.ReadValueDW(installer::kInstallerResult, &dw_value));
404    EXPECT_EQ(static_cast<DWORD>(0), dw_value);
405    EXPECT_EQ(ERROR_SUCCESS,
406        key.ReadValueDW(installer::kInstallerError, &dw_value));
407    EXPECT_EQ(static_cast<DWORD>(installer::FIRST_INSTALL_SUCCESS), dw_value);
408    EXPECT_EQ(ERROR_SUCCESS,
409        key.ReadValue(installer::kInstallerResultUIString, &value));
410    EXPECT_FALSE(value.empty());
411    EXPECT_EQ(ERROR_SUCCESS,
412        key.ReadValue(installer::kInstallerSuccessLaunchCmdLine, &value));
413    EXPECT_EQ(launch_cmd, value);
414  }
415
416  // check results for a fresh install of multi Chrome
417  {
418    RegistryOverrideManager override_manager;
419    override_manager.OverrideRegistry(root, L"root_inst_res");
420    CommandLine cmd_line = CommandLine::FromString(
421        L"setup.exe --system-level --multi-install --chrome");
422    const MasterPreferences prefs(cmd_line);
423    InstallationState machine_state;
424    machine_state.Initialize();
425    InstallerState state;
426    state.Initialize(cmd_line, prefs, machine_state);
427    state.WriteInstallerResult(installer::FIRST_INSTALL_SUCCESS, 0,
428                               &launch_cmd);
429    BrowserDistribution* distribution =
430        BrowserDistribution::GetSpecificDistribution(
431            BrowserDistribution::CHROME_BROWSER);
432    BrowserDistribution* binaries =
433        BrowserDistribution::GetSpecificDistribution(
434            BrowserDistribution::CHROME_BINARIES);
435    EXPECT_EQ(ERROR_SUCCESS,
436        key.Open(root, distribution->GetStateKey().c_str(), KEY_READ));
437    EXPECT_EQ(ERROR_SUCCESS,
438        key.ReadValue(installer::kInstallerSuccessLaunchCmdLine, &value));
439    EXPECT_EQ(launch_cmd, value);
440    EXPECT_EQ(ERROR_SUCCESS,
441        key.Open(root, binaries->GetStateKey().c_str(), KEY_READ));
442    EXPECT_EQ(ERROR_SUCCESS,
443        key.ReadValue(installer::kInstallerSuccessLaunchCmdLine, &value));
444    EXPECT_EQ(launch_cmd, value);
445    key.Close();
446  }
447}
448
449// Test GetCurrentVersion when migrating single Chrome to multi
450TEST_F(InstallerStateTest, GetCurrentVersionMigrateChrome) {
451  using installer::FakeInstallationState;
452
453  const bool system_install = false;
454  FakeInstallationState machine_state;
455
456  // Pretend that this version of single-install Chrome is already installed.
457  machine_state.AddChrome(system_install, false,
458                          new Version(chrome::kChromeVersion));
459
460  // Now we're invoked to install multi Chrome.
461  CommandLine cmd_line(
462      CommandLine::FromString(L"setup.exe --multi-install --chrome"));
463  MasterPreferences prefs(cmd_line);
464  InstallerState installer_state;
465  installer_state.Initialize(cmd_line, prefs, machine_state);
466
467  // Is the Chrome version picked up?
468  scoped_ptr<Version> version(installer_state.GetCurrentVersion(machine_state));
469  EXPECT_TRUE(version.get() != NULL);
470}
471
472TEST_F(InstallerStateTest, IsFileInUse) {
473  base::ScopedTempDir temp_dir;
474  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
475
476  base::FilePath temp_file;
477  ASSERT_TRUE(file_util::CreateTemporaryFileInDir(temp_dir.path(), &temp_file));
478
479  EXPECT_FALSE(MockInstallerState::IsFileInUse(temp_file));
480
481  {
482    // Open a handle to the file with the same access mode and sharing options
483    // as the loader.
484    base::win::ScopedHandle temp_handle(
485        CreateFile(temp_file.value().c_str(),
486                   SYNCHRONIZE | FILE_EXECUTE,
487                   FILE_SHARE_DELETE | FILE_SHARE_READ,
488                   NULL, OPEN_EXISTING, 0, 0));
489    ASSERT_TRUE(temp_handle != NULL);
490
491    // The file should now be in use.
492    EXPECT_TRUE(MockInstallerState::IsFileInUse(temp_file));
493  }
494
495  // And once the handle is gone, it should no longer be in use.
496  EXPECT_FALSE(MockInstallerState::IsFileInUse(temp_file));
497}
498
499// TODO(jschuh): crbug.com/167707 need to fix Win64 pe_image issues due to
500// calling upgrade_test::GenerateSpecificPEFileVersion
501#if defined(OS_WIN) && defined(ARCH_CPU_X86_64)
502#define MAYBE_RemoveOldVersionDirs DISABLED_RemoveOldVersionDirs
503#else
504#define MAYBE_RemoveOldVersionDirs RemoveOldVersionDirs
505#endif
506
507TEST_F(InstallerStateTest, MAYBE_RemoveOldVersionDirs) {
508  MockInstallerState installer_state;
509  installer_state.set_target_path(test_dir_.path());
510  EXPECT_EQ(test_dir_.path().value(), installer_state.target_path().value());
511
512  const char kOldVersion[] = "2.0.0.0";
513  const char kNewVersion[] = "3.0.0.0";
514  const char kOldChromeExeVersion[] = "2.1.0.0";
515  const char kChromeExeVersion[] = "2.1.1.1";
516  const char kNewChromeExeVersion[] = "3.0.0.0";
517
518  Version new_version(kNewVersion);
519  Version old_version(kOldVersion);
520  Version old_chrome_exe_version(kOldChromeExeVersion);
521  Version chrome_exe_version(kChromeExeVersion);
522  Version new_chrome_exe_version(kNewChromeExeVersion);
523
524  ASSERT_TRUE(new_version.IsValid());
525  ASSERT_TRUE(old_version.IsValid());
526  ASSERT_TRUE(old_chrome_exe_version.IsValid());
527  ASSERT_TRUE(chrome_exe_version.IsValid());
528  ASSERT_TRUE(new_chrome_exe_version.IsValid());
529
530  // Set up a bunch of version dir paths.
531  base::FilePath version_dirs[] = {
532    installer_state.target_path().Append(L"1.2.3.4"),
533    installer_state.target_path().Append(L"1.2.3.5"),
534    installer_state.target_path().Append(L"1.2.3.6"),
535    installer_state.target_path().Append(ASCIIToWide(kOldVersion)),
536    installer_state.target_path().Append(ASCIIToWide(kOldChromeExeVersion)),
537    installer_state.target_path().Append(L"2.1.1.0"),
538    installer_state.target_path().Append(ASCIIToWide(kChromeExeVersion)),
539    installer_state.target_path().Append(ASCIIToWide(kNewVersion)),
540    installer_state.target_path().Append(L"3.9.1.1"),
541  };
542
543  // Create the version directories.
544  for (int i = 0; i < arraysize(version_dirs); i++) {
545    file_util::CreateDirectory(version_dirs[i]);
546    EXPECT_TRUE(file_util::PathExists(version_dirs[i]));
547  }
548
549  // Create exes with the appropriate version resource.
550  // Use the current test exe as a baseline.
551  base::FilePath exe_path;
552  ASSERT_TRUE(PathService::Get(base::FILE_EXE, &exe_path));
553
554  struct target_info {
555    base::FilePath target_file;
556    const Version& target_version;
557  } targets[] = {
558    { installer_state.target_path().Append(installer::kChromeOldExe),
559      old_chrome_exe_version },
560    { installer_state.target_path().Append(installer::kChromeExe),
561      chrome_exe_version },
562    { installer_state.target_path().Append(installer::kChromeNewExe),
563      new_chrome_exe_version },
564  };
565  for (int i = 0; i < arraysize(targets); ++i) {
566    ASSERT_TRUE(upgrade_test::GenerateSpecificPEFileVersion(
567        exe_path, targets[i].target_file, targets[i].target_version));
568  }
569
570  // Call GetExistingExeVersions, validate that picks up the
571  // exe resources.
572  std::set<std::string> expected_exe_versions;
573  expected_exe_versions.insert(kOldChromeExeVersion);
574  expected_exe_versions.insert(kChromeExeVersion);
575  expected_exe_versions.insert(kNewChromeExeVersion);
576
577  std::set<std::string> actual_exe_versions;
578  installer_state.GetExistingExeVersions(&actual_exe_versions);
579  EXPECT_EQ(expected_exe_versions, actual_exe_versions);
580
581  // Call RemoveOldVersionDirectories
582  installer_state.RemoveOldVersionDirectories(new_version,
583                                              &old_version,
584                                              installer_state.target_path());
585
586  // What we expect to have left.
587  std::set<std::string> expected_remaining_dirs;
588  expected_remaining_dirs.insert(kOldVersion);
589  expected_remaining_dirs.insert(kNewVersion);
590  expected_remaining_dirs.insert(kOldChromeExeVersion);
591  expected_remaining_dirs.insert(kChromeExeVersion);
592  expected_remaining_dirs.insert(kNewChromeExeVersion);
593
594  // Enumerate dirs in target_path(), ensure only desired remain.
595  file_util::FileEnumerator version_enum(installer_state.target_path(), false,
596      file_util::FileEnumerator::DIRECTORIES);
597  for (base::FilePath next_version = version_enum.Next(); !next_version.empty();
598       next_version = version_enum.Next()) {
599    base::FilePath dir_name(next_version.BaseName());
600    Version version(WideToASCII(dir_name.value()));
601    if (version.IsValid()) {
602      EXPECT_TRUE(expected_remaining_dirs.erase(version.GetString()))
603          << "Unexpected version dir found: " << version.GetString();
604    }
605  }
606
607  std::set<std::string>::const_iterator iter(
608      expected_remaining_dirs.begin());
609  for (; iter != expected_remaining_dirs.end(); ++iter)
610    ADD_FAILURE() << "Expected to find version dir for " << *iter;
611}
612
613
614// A fixture for testing InstallerState::DetermineCriticalVersion.  Individual
615// tests must invoke Initialize() with a critical version.
616class InstallerStateCriticalVersionTest : public ::testing::Test {
617 protected:
618  InstallerStateCriticalVersionTest() : cmd_line_(CommandLine::NO_PROGRAM) {}
619
620  // Creates a set of versions for use by all test runs.
621  static void SetUpTestCase() {
622    low_version_    = new Version("15.0.874.106");
623    opv_version_    = new Version("15.0.874.255");
624    middle_version_ = new Version("16.0.912.32");
625    pv_version_     = new Version("16.0.912.255");
626    high_version_   = new Version("17.0.932.0");
627  }
628
629  // Cleans up versions used by all test runs.
630  static void TearDownTestCase() {
631    delete low_version_;
632    delete opv_version_;
633    delete middle_version_;
634    delete pv_version_;
635    delete high_version_;
636  }
637
638  // Initializes the InstallerState to use for a test run.  The returned
639  // instance's critical update version is set to |version|.  |version| may be
640  // NULL, in which case the critical update version is unset.
641  MockInstallerState& Initialize(const Version* version) {
642    cmd_line_ = version == NULL ?
643        CommandLine::FromString(L"setup.exe") :
644        CommandLine::FromString(
645            L"setup.exe --critical-update-version=" +
646            ASCIIToWide(version->GetString()));
647    prefs_.reset(new MasterPreferences(cmd_line_));
648    machine_state_.Initialize();
649    installer_state_.Initialize(cmd_line_, *prefs_, machine_state_);
650    return installer_state_;
651  }
652
653  static Version* low_version_;
654  static Version* opv_version_;
655  static Version* middle_version_;
656  static Version* pv_version_;
657  static Version* high_version_;
658
659  CommandLine cmd_line_;
660  scoped_ptr<MasterPreferences> prefs_;
661  InstallationState machine_state_;
662  MockInstallerState installer_state_;
663};
664
665Version* InstallerStateCriticalVersionTest::low_version_ = NULL;
666Version* InstallerStateCriticalVersionTest::opv_version_ = NULL;
667Version* InstallerStateCriticalVersionTest::middle_version_ = NULL;
668Version* InstallerStateCriticalVersionTest::pv_version_ = NULL;
669Version* InstallerStateCriticalVersionTest::high_version_ = NULL;
670
671// Test the case where the critical version is less than the currently-running
672// Chrome.  The critical version is ignored since it doesn't apply.
673TEST_F(InstallerStateCriticalVersionTest, CriticalBeforeOpv) {
674  MockInstallerState& installer_state(Initialize(low_version_));
675
676  EXPECT_TRUE(installer_state.critical_update_version().Equals(*low_version_));
677  // Unable to determine the installed version, so assume critical update.
678  EXPECT_TRUE(
679      installer_state.DetermineCriticalVersion(NULL, *pv_version_).IsValid());
680  // Installed version is past the critical update.
681  EXPECT_FALSE(
682      installer_state.DetermineCriticalVersion(opv_version_, *pv_version_)
683          .IsValid());
684  // Installed version is past the critical update.
685  EXPECT_FALSE(
686      installer_state.DetermineCriticalVersion(pv_version_, *pv_version_)
687          .IsValid());
688}
689
690// Test the case where the critical version is equal to the currently-running
691// Chrome.  The critical version is ignored since it doesn't apply.
692TEST_F(InstallerStateCriticalVersionTest, CriticalEqualsOpv) {
693  MockInstallerState& installer_state(Initialize(opv_version_));
694
695  EXPECT_TRUE(installer_state.critical_update_version().Equals(*opv_version_));
696  // Unable to determine the installed version, so assume critical update.
697  EXPECT_TRUE(
698      installer_state.DetermineCriticalVersion(NULL, *pv_version_).IsValid());
699  // Installed version equals the critical update.
700  EXPECT_FALSE(
701      installer_state.DetermineCriticalVersion(opv_version_, *pv_version_)
702          .IsValid());
703  // Installed version equals the critical update.
704  EXPECT_FALSE(
705      installer_state.DetermineCriticalVersion(pv_version_, *pv_version_)
706          .IsValid());
707}
708
709// Test the case where the critical version is between the currently-running
710// Chrome and the to-be-installed Chrome.
711TEST_F(InstallerStateCriticalVersionTest, CriticalBetweenOpvAndPv) {
712  MockInstallerState& installer_state(Initialize(middle_version_));
713
714  EXPECT_TRUE(installer_state.critical_update_version().Equals(
715      *middle_version_));
716  // Unable to determine the installed version, so assume critical update.
717  EXPECT_TRUE(
718      installer_state.DetermineCriticalVersion(NULL, *pv_version_).IsValid());
719  // Installed version before the critical update.
720  EXPECT_TRUE(
721      installer_state.DetermineCriticalVersion(opv_version_, *pv_version_)
722          .IsValid());
723  // Installed version is past the critical update.
724  EXPECT_FALSE(
725      installer_state.DetermineCriticalVersion(pv_version_, *pv_version_)
726          .IsValid());
727}
728
729// Test the case where the critical version is the same as the to-be-installed
730// Chrome.
731TEST_F(InstallerStateCriticalVersionTest, CriticalEqualsPv) {
732  MockInstallerState& installer_state(Initialize(pv_version_));
733
734  EXPECT_TRUE(installer_state.critical_update_version().Equals(
735      *pv_version_));
736  // Unable to determine the installed version, so assume critical update.
737  EXPECT_TRUE(
738      installer_state.DetermineCriticalVersion(NULL, *pv_version_).IsValid());
739  // Installed version before the critical update.
740  EXPECT_TRUE(
741      installer_state.DetermineCriticalVersion(opv_version_, *pv_version_)
742          .IsValid());
743  // Installed version equals the critical update.
744  EXPECT_FALSE(
745      installer_state.DetermineCriticalVersion(pv_version_, *pv_version_)
746          .IsValid());
747}
748
749// Test the case where the critical version is greater than the to-be-installed
750// Chrome.
751TEST_F(InstallerStateCriticalVersionTest, CriticalAfterPv) {
752  MockInstallerState& installer_state(Initialize(high_version_));
753
754  EXPECT_TRUE(installer_state.critical_update_version().Equals(
755      *high_version_));
756  // Critical update newer than the new version.
757  EXPECT_FALSE(
758      installer_state.DetermineCriticalVersion(NULL, *pv_version_).IsValid());
759  EXPECT_FALSE(
760      installer_state.DetermineCriticalVersion(opv_version_, *pv_version_)
761          .IsValid());
762  EXPECT_FALSE(
763      installer_state.DetermineCriticalVersion(pv_version_, *pv_version_)
764          .IsValid());
765}
766