blob: d3aeb9e8896b2d4ba4069c43d1f723c99c05fefe [file] [log] [blame]
Joshua Pawlickibae1c6d2352020-03-19 19:21:441// Copyright 2020 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Mila Greena3991ae2020-10-16 00:10:555#include <stdint.h>
Joshua Pawlicki6867d7c2021-01-06 15:51:096#include <string>
Adam Norberg14b66a12021-01-20 21:54:037#include <vector>
Mila Greena3991ae2020-10-16 00:10:558
Joshua Pawlickibae1c6d2352020-03-19 19:21:449#include "base/command_line.h"
10#include "base/files/file_path.h"
11#include "base/files/file_util.h"
Mila Greenf6d82f82021-03-05 22:14:2912#include "base/logging.h"
Joshua Pawlickibae1c6d2352020-03-19 19:21:4413#include "base/mac/foundation_util.h"
Mila Greenf6d82f82021-03-05 22:14:2914#include "base/optional.h"
Joshua Pawlickibae1c6d2352020-03-19 19:21:4415#include "base/path_service.h"
Joshua Pawlickicd6925c92020-12-15 15:07:5016#include "base/run_loop.h"
17#include "base/strings/sys_string_conversions.h"
18#include "base/test/bind.h"
Mila Greena3991ae2020-10-16 00:10:5519#include "base/version.h"
Joshua Pawlicki8f755d382020-03-20 19:51:1020#include "chrome/common/mac/launchd.h"
Mila Green8ddc4e02020-05-01 00:15:0221#include "chrome/updater/constants.h"
Adam Norberg14b66a12021-01-20 21:54:0322#include "chrome/updater/external_constants_builder.h"
Joshua Pawlickicd6925c92020-12-15 15:07:5023#include "chrome/updater/launchd_util.h"
Mila Greenf6d82f82021-03-05 22:14:2924#import "chrome/updater/mac/mac_util.h"
Joshua Pawlicki8f755d382020-03-20 19:51:1025#include "chrome/updater/mac/xpc_service_names.h"
Mila Greena3991ae2020-10-16 00:10:5526#include "chrome/updater/prefs.h"
Joshua Pawlicki83d1d8232020-10-23 20:13:3127#include "chrome/updater/test/integration_tests.h"
Mila Green3e3058a2020-08-27 16:59:2728#include "chrome/updater/test/test_app/constants.h"
29#include "chrome/updater/test/test_app/test_app_version.h"
Mila Greenaff086902021-01-07 22:00:5230#include "chrome/updater/updater_branding.h"
Mila Greenf6d82f82021-03-05 22:14:2931#include "chrome/updater/updater_scope.h"
Joshua Pawlicki4abd1322020-08-19 22:05:5732#include "chrome/updater/util.h"
Joshua Pawlickibae1c6d2352020-03-19 19:21:4433#include "testing/gtest/include/gtest/gtest.h"
Joshua Pawlicki6867d7c2021-01-06 15:51:0934#include "url/gurl.h"
Joshua Pawlickibae1c6d2352020-03-19 19:21:4435
36namespace updater {
Joshua Pawlickibae1c6d2352020-03-19 19:21:4437namespace test {
38
Joshua Pawlickibae1c6d2352020-03-19 19:21:4439namespace {
40
Mila Greenf6d82f82021-03-05 22:14:2941Launchd::Domain LaunchdDomain(UpdaterScope scope) {
42 switch (scope) {
43 case UpdaterScope::kSystem:
44 return Launchd::Domain::Local;
45 case UpdaterScope::kUser:
46 return Launchd::Domain::User;
47 }
48}
Joshua Pawlickicd6925c92020-12-15 15:07:5049
Mila Greenf6d82f82021-03-05 22:14:2950Launchd::Type LaunchdType(UpdaterScope scope) {
51 switch (scope) {
52 case UpdaterScope::kSystem:
53 return Launchd::Type::Daemon;
54 case UpdaterScope::kUser:
55 return Launchd::Type::Agent;
56 }
Joshua Pawlickicd6925c92020-12-15 15:07:5057}
58
Joshua Pawlickibae1c6d2352020-03-19 19:21:4459base::FilePath GetExecutablePath() {
60 base::FilePath test_executable;
61 if (!base::PathService::Get(base::FILE_EXE, &test_executable))
62 return base::FilePath();
63 return test_executable.DirName()
Mila Greena3991ae2020-10-16 00:10:5564 .Append(FILE_PATH_LITERAL(PRODUCT_FULLNAME_STRING ".app"))
Joshua Pawlickibae1c6d2352020-03-19 19:21:4465 .Append(FILE_PATH_LITERAL("Contents"))
66 .Append(FILE_PATH_LITERAL("MacOS"))
67 .Append(FILE_PATH_LITERAL(PRODUCT_FULLNAME_STRING));
68}
69
Mila Green3e3058a2020-08-27 16:59:2770base::FilePath GetTestAppExecutablePath() {
71 base::FilePath test_executable;
72 if (!base::PathService::Get(base::FILE_EXE, &test_executable))
73 return base::FilePath();
74 return test_executable.DirName()
Mila Greena3991ae2020-10-16 00:10:5575 .Append(FILE_PATH_LITERAL(TEST_APP_FULLNAME_STRING ".app"))
Mila Green3e3058a2020-08-27 16:59:2776 .Append(FILE_PATH_LITERAL("Contents"))
77 .Append(FILE_PATH_LITERAL("MacOS"))
78 .Append(FILE_PATH_LITERAL(TEST_APP_FULLNAME_STRING));
79}
80
Mila Greenf6d82f82021-03-05 22:14:2981base::Optional<base::FilePath> GetProductPath(UpdaterScope scope) {
82 base::Optional<base::FilePath> path = GetLibraryFolderPath(scope);
83 if (!path)
84 return base::nullopt;
85
86 return path->AppendASCII(COMPANY_SHORTNAME_STRING)
Joshua Pawlicki8f755d382020-03-20 19:51:1087 .AppendASCII(PRODUCT_FULLNAME_STRING);
88}
89
Mila Greenf6d82f82021-03-05 22:14:2990base::Optional<base::FilePath> GetActiveFile(UpdaterScope scope,
91 const std::string& id) {
92 base::Optional<base::FilePath> path = GetLibraryFolderPath(scope);
93 if (!path)
94 return base::nullopt;
95
96 return path->AppendASCII(COMPANY_SHORTNAME_STRING)
Joshua Pawlicki6867d7c2021-01-06 15:51:0997 .AppendASCII(COMPANY_SHORTNAME_STRING "SoftwareUpdate")
98 .AppendASCII("Actives")
99 .AppendASCII(id);
100}
101
Mila Greenf6d82f82021-03-05 22:14:29102void ExpectServiceAbsent(UpdaterScope scope, const std::string& service) {
103 VLOG(0) << __func__ << " - scope: " << scope << ". service: " << service;
Joshua Pawlickicd6925c92020-12-15 15:07:50104 bool success = false;
105 base::RunLoop loop;
Mila Greenf6d82f82021-03-05 22:14:29106 PollLaunchctlList(scope, service, LaunchctlPresence::kAbsent,
Joshua Pawlickicd6925c92020-12-15 15:07:50107 base::TimeDelta::FromSeconds(7),
108 base::BindLambdaForTesting([&](bool result) {
109 success = result;
110 loop.QuitClosure().Run();
111 }));
112 loop.Run();
113 EXPECT_TRUE(success) << service << " is unexpectedly present.";
114}
115
Joshua Pawlicki83d1d8232020-10-23 20:13:31116} // namespace
117
Joshua Pawlicki6867d7c2021-01-06 15:51:09118void EnterTestMode(const GURL& url) {
Adam Norberg14b66a12021-01-20 21:54:03119 ASSERT_TRUE(ExternalConstantsBuilder()
120 .SetUpdateURL(std::vector<std::string>{url.spec()})
121 .SetUseCUP(false)
Mila Green1cb26962021-01-21 01:00:00122 .SetInitialDelay(0.1)
Mila Green59389f12021-02-03 20:52:32123 .SetServerKeepAliveSeconds(1)
Adam Norberg14b66a12021-01-20 21:54:03124 .Overwrite());
Joshua Pawlicki6867d7c2021-01-06 15:51:09125}
126
Mila Greenf6d82f82021-03-05 22:14:29127base::Optional<base::FilePath> GetDataDirPath(UpdaterScope scope) {
128 base::Optional<base::FilePath> app_path =
129 GetApplicationSupportDirectory(scope);
130 if (!app_path) {
131 VLOG(1) << "Failed to get Application support path.";
132 return base::nullopt;
133 }
Joshua Pawlicki6867d7c2021-01-06 15:51:09134
Mila Greenf6d82f82021-03-05 22:14:29135 return app_path->AppendASCII(COMPANY_SHORTNAME_STRING)
Joshua Pawlicki9d1340fc2020-08-14 20:59:35136 .AppendASCII(PRODUCT_FULLNAME_STRING);
137}
138
Mila Greenf6d82f82021-03-05 22:14:29139void Clean(UpdaterScope scope) {
140 Launchd::Domain launchd_domain = LaunchdDomain(scope);
141 Launchd::Type launchd_type = LaunchdType(scope);
142
143 base::Optional<base::FilePath> path = GetProductPath(scope);
144 EXPECT_TRUE(path);
145 if (path)
146 EXPECT_TRUE(base::DeletePathRecursively(*path));
Joshua Pawlicki8f755d382020-03-20 19:51:10147 EXPECT_TRUE(Launchd::GetInstance()->DeletePlist(
Mila Greenf6d82f82021-03-05 22:14:29148 launchd_domain, launchd_type, updater::CopyWakeLaunchdName()));
Joshua Pawlicki8f755d382020-03-20 19:51:10149 EXPECT_TRUE(Launchd::GetInstance()->DeletePlist(
Mila Greenf6d82f82021-03-05 22:14:29150 launchd_domain, launchd_type,
Mila Green80845642020-12-10 03:44:51151 updater::CopyUpdateServiceInternalLaunchdName()));
Mila Green7414a0ed2020-07-21 21:30:42152 EXPECT_TRUE(Launchd::GetInstance()->DeletePlist(
Mila Greenf6d82f82021-03-05 22:14:29153 launchd_domain, launchd_type, updater::CopyUpdateServiceLaunchdName()));
154
155 path = GetDataDirPath(scope);
156 EXPECT_TRUE(path);
157 if (path)
158 EXPECT_TRUE(base::DeletePathRecursively(*path));
Joshua Pawlicki3f645882020-08-21 20:36:17159
160 @autoreleasepool {
Mila Greenf6d82f82021-03-05 22:14:29161 RemoveJobFromLaunchd(scope, launchd_domain, launchd_type,
Joshua Pawlickicd6925c92020-12-15 15:07:50162 CopyUpdateServiceLaunchdName());
Mila Greenf6d82f82021-03-05 22:14:29163 RemoveJobFromLaunchd(scope, launchd_domain, launchd_type,
Joshua Pawlickicd6925c92020-12-15 15:07:50164 CopyUpdateServiceInternalLaunchdName());
Joshua Pawlicki3f645882020-08-21 20:36:17165 }
Joshua Pawlickibae1c6d2352020-03-19 19:21:44166}
167
Mila Greenf6d82f82021-03-05 22:14:29168void ExpectClean(UpdaterScope scope) {
169 Launchd::Domain launchd_domain = LaunchdDomain(scope);
170 Launchd::Type launchd_type = LaunchdType(scope);
171
Joshua Pawlickibae1c6d2352020-03-19 19:21:44172 // Files must not exist on the file system.
Mila Greenf6d82f82021-03-05 22:14:29173 base::Optional<base::FilePath> path = GetProductPath(scope);
174 EXPECT_TRUE(path);
175 if (path)
176 EXPECT_FALSE(base::PathExists(*path));
Joshua Pawlicki8f755d382020-03-20 19:51:10177 EXPECT_FALSE(Launchd::GetInstance()->PlistExists(
Mila Greenf6d82f82021-03-05 22:14:29178 launchd_domain, launchd_type, updater::CopyWakeLaunchdName()));
Mila Green8ddc4e02020-05-01 00:15:02179 EXPECT_FALSE(Launchd::GetInstance()->PlistExists(
Mila Greenf6d82f82021-03-05 22:14:29180 launchd_domain, launchd_type,
Mila Green80845642020-12-10 03:44:51181 updater::CopyUpdateServiceInternalLaunchdName()));
Mila Green7414a0ed2020-07-21 21:30:42182 EXPECT_FALSE(Launchd::GetInstance()->PlistExists(
Mila Greenf6d82f82021-03-05 22:14:29183 launchd_domain, launchd_type, updater::CopyUpdateServiceLaunchdName()));
184
185 path = GetDataDirPath(scope);
186 EXPECT_TRUE(path);
187 if (path)
188 EXPECT_FALSE(base::PathExists(*path));
189
190 ExpectServiceAbsent(scope, kUpdateServiceLaunchdName);
191 ExpectServiceAbsent(scope, kUpdateServiceInternalLaunchdName);
Joshua Pawlickibae1c6d2352020-03-19 19:21:44192}
193
Mila Greenf6d82f82021-03-05 22:14:29194void ExpectInstalled(UpdaterScope scope) {
195 Launchd::Domain launchd_domain = LaunchdDomain(scope);
196 Launchd::Type launchd_type = LaunchdType(scope);
197
198 VLOG(0) << "Scope :" << scope
199 << "; GetProductPath(scope): " << GetProductPath(scope);
Joshua Pawlickibae1c6d2352020-03-19 19:21:44200 // Files must exist on the file system.
Mila Greenf6d82f82021-03-05 22:14:29201 base::Optional<base::FilePath> path = GetProductPath(scope);
202 EXPECT_TRUE(path);
203 if (path)
204 EXPECT_TRUE(base::PathExists(*path));
205
206 EXPECT_TRUE(Launchd::GetInstance()->PlistExists(launchd_domain, launchd_type,
Mila Green7414a0ed2020-07-21 21:30:42207 CopyWakeLaunchdName()));
Mila Green80845642020-12-10 03:44:51208 EXPECT_TRUE(Launchd::GetInstance()->PlistExists(
Mila Greenf6d82f82021-03-05 22:14:29209 launchd_domain, launchd_type, CopyUpdateServiceInternalLaunchdName()));
Joshua Pawlickibae1c6d2352020-03-19 19:21:44210}
211
Mila Greenf6d82f82021-03-05 22:14:29212void Install(UpdaterScope scope) {
Mila Green8ddc4e02020-05-01 00:15:02213 const base::FilePath path = GetExecutablePath();
Joshua Pawlickibae1c6d2352020-03-19 19:21:44214 ASSERT_FALSE(path.empty());
Michael Change4785a822020-03-26 20:55:01215 base::CommandLine command_line(path);
Joshua Pawlicki91ce318b2020-09-15 14:35:38216 command_line.AppendSwitch(kInstallSwitch);
Mila Green8ddc4e02020-05-01 00:15:02217 int exit_code = -1;
Mila Greenf6d82f82021-03-05 22:14:29218 ASSERT_TRUE(Run(scope, command_line, &exit_code));
219 EXPECT_EQ(exit_code, 0);
Mila Green8ddc4e02020-05-01 00:15:02220}
221
Mila Greenf6d82f82021-03-05 22:14:29222void ExpectActiveUpdater(UpdaterScope scope) {
223 Launchd::Domain launchd_domain = LaunchdDomain(scope);
224 Launchd::Type launchd_type = LaunchdType(scope);
225
Mila Green8ddc4e02020-05-01 00:15:02226 // Files must exist on the file system.
Mila Greenf6d82f82021-03-05 22:14:29227 base::Optional<base::FilePath> path = GetProductPath(scope);
228 EXPECT_TRUE(path);
229 if (path)
230 EXPECT_TRUE(base::PathExists(*path));
231
Mila Green80845642020-12-10 03:44:51232 EXPECT_TRUE(Launchd::GetInstance()->PlistExists(
Mila Greenf6d82f82021-03-05 22:14:29233 launchd_domain, launchd_type, CopyUpdateServiceLaunchdName()));
Mila Green8ddc4e02020-05-01 00:15:02234}
235
Mila Greenf6d82f82021-03-05 22:14:29236void RegisterTestApp(UpdaterScope scope) {
Mila Green3e3058a2020-08-27 16:59:27237 const base::FilePath path = GetTestAppExecutablePath();
238 ASSERT_FALSE(path.empty());
239 base::CommandLine command_line(path);
240 command_line.AppendSwitch(kRegisterUpdaterSwitch);
241 int exit_code = -1;
Mila Greenf6d82f82021-03-05 22:14:29242 ASSERT_TRUE(Run(scope, command_line, &exit_code));
243 EXPECT_EQ(exit_code, 0);
Mila Green3e3058a2020-08-27 16:59:27244}
245
Mila Greenf6d82f82021-03-05 22:14:29246base::Optional<base::FilePath> GetInstalledExecutablePath(UpdaterScope scope) {
247 return GetUpdaterExecutablePath(scope);
Mila Greena3991ae2020-10-16 00:10:55248}
249
Mila Greenf6d82f82021-03-05 22:14:29250void ExpectCandidateUninstalled(UpdaterScope scope) {
251 Launchd::Domain launchd_domain = LaunchdDomain(scope);
252 Launchd::Type launchd_type = LaunchdType(scope);
253
254 base::Optional<base::FilePath> versioned_folder_path =
255 GetVersionedUpdaterFolderPath(scope);
256 EXPECT_TRUE(versioned_folder_path);
257 if (versioned_folder_path)
258 EXPECT_FALSE(base::PathExists(*versioned_folder_path));
259
260 EXPECT_FALSE(Launchd::GetInstance()->PlistExists(launchd_domain, launchd_type,
261 CopyWakeLaunchdName()));
Mila Greena3991ae2020-10-16 00:10:55262 EXPECT_FALSE(Launchd::GetInstance()->PlistExists(
Mila Greenf6d82f82021-03-05 22:14:29263 launchd_domain, launchd_type, CopyUpdateServiceInternalLaunchdName()));
Joshua Pawlicki4abd1322020-08-19 22:05:57264}
265
Mila Greenf6d82f82021-03-05 22:14:29266void Uninstall(UpdaterScope scope) {
Joshua Pawlicki6867d7c2021-01-06 15:51:09267 if (::testing::Test::HasFailure())
Mila Greenf6d82f82021-03-05 22:14:29268 PrintLog(scope);
adoneria1762dd72020-12-17 17:33:08269 // Copy logs from GetDataDirPath() before updater uninstalls itself
270 // and deletes the path.
Mila Greenf6d82f82021-03-05 22:14:29271 base::Optional<base::FilePath> path = GetDataDirPath(scope);
272 EXPECT_TRUE(path);
273 if (path)
274 CopyLog(*path);
adoneria1762dd72020-12-17 17:33:08275
276 // Uninstall the updater.
Mila Greenf6d82f82021-03-05 22:14:29277 path = GetExecutablePath();
278 ASSERT_TRUE(path);
279 base::CommandLine command_line(*path);
Mila Green8ddc4e02020-05-01 00:15:02280 command_line.AppendSwitch(kUninstallSwitch);
Joshua Pawlickibae1c6d2352020-03-19 19:21:44281 int exit_code = -1;
Mila Greenf6d82f82021-03-05 22:14:29282 ASSERT_TRUE(Run(scope, command_line, &exit_code));
283 EXPECT_EQ(exit_code, 0);
Joshua Pawlickibae1c6d2352020-03-19 19:21:44284}
285
Mila Greenf6d82f82021-03-05 22:14:29286base::Optional<base::FilePath> GetFakeUpdaterInstallFolderPath(
287 UpdaterScope scope,
288 const base::Version& version) {
289 return GetExecutableFolderPathForVersion(scope, version);
Mila Greena3991ae2020-10-16 00:10:55290}
291
Mila Greenf6d82f82021-03-05 22:14:29292void SetActive(UpdaterScope scope, const std::string& app_id) {
Joshua Pawlicki6867d7c2021-01-06 15:51:09293 base::File::Error err = base::File::FILE_OK;
Mila Greenf6d82f82021-03-05 22:14:29294 base::Optional<base::FilePath> actives_file = GetActiveFile(scope, app_id);
295 ASSERT_TRUE(actives_file);
296 VLOG(0) << "Actives file: " << *actives_file;
297 VLOG(0) << "Actives file dir name: " << actives_file->DirName();
298 EXPECT_TRUE(base::CreateDirectoryAndGetError(actives_file->DirName(), &err))
Joshua Pawlicki6867d7c2021-01-06 15:51:09299 << "Error: " << err;
Mila Greenf6d82f82021-03-05 22:14:29300 EXPECT_TRUE(base::WriteFile(*actives_file, ""));
Joshua Pawlicki6867d7c2021-01-06 15:51:09301}
302
Mila Greenf6d82f82021-03-05 22:14:29303void ExpectActive(UpdaterScope scope, const std::string& app_id) {
304 base::Optional<base::FilePath> path = GetActiveFile(scope, app_id);
305 ASSERT_TRUE(path);
306 EXPECT_TRUE(base::PathExists(*path));
307 EXPECT_TRUE(base::PathIsWritable(*path));
Joshua Pawlicki6867d7c2021-01-06 15:51:09308}
309
Mila Greenf6d82f82021-03-05 22:14:29310void ExpectNotActive(UpdaterScope scope, const std::string& app_id) {
311 base::Optional<base::FilePath> path = GetActiveFile(scope, app_id);
312 ASSERT_TRUE(path);
313 EXPECT_FALSE(base::PathExists(*path));
314 EXPECT_FALSE(base::PathIsWritable(*path));
Joshua Pawlicki6867d7c2021-01-06 15:51:09315}
316
Joshua Pawlickibae1c6d2352020-03-19 19:21:44317} // namespace test
Joshua Pawlickibae1c6d2352020-03-19 19:21:44318} // namespace updater