blob: dfb79cdb43991903c5b89922652fa12d43dd51fb [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"
Mila Green3c9375d2021-03-17 16:33:5927#include "chrome/updater/test/integration_tests_impl.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
39namespace {
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) {
Mila Green708bf0d92021-03-23 17:33:1592 const base::Optional<base::FilePath> path =
93 GetLibraryFolderPath(UpdaterScope::kUser);
Mila Greenf6d82f82021-03-05 22:14:2994 if (!path)
95 return base::nullopt;
96
97 return path->AppendASCII(COMPANY_SHORTNAME_STRING)
Joshua Pawlicki6867d7c2021-01-06 15:51:0998 .AppendASCII(COMPANY_SHORTNAME_STRING "SoftwareUpdate")
99 .AppendASCII("Actives")
100 .AppendASCII(id);
101}
102
Mila Greenf6d82f82021-03-05 22:14:29103void ExpectServiceAbsent(UpdaterScope scope, const std::string& service) {
104 VLOG(0) << __func__ << " - scope: " << scope << ". service: " << service;
Joshua Pawlickicd6925c92020-12-15 15:07:50105 bool success = false;
106 base::RunLoop loop;
Mila Greenf6d82f82021-03-05 22:14:29107 PollLaunchctlList(scope, service, LaunchctlPresence::kAbsent,
Joshua Pawlickicd6925c92020-12-15 15:07:50108 base::TimeDelta::FromSeconds(7),
109 base::BindLambdaForTesting([&](bool result) {
110 success = result;
111 loop.QuitClosure().Run();
112 }));
113 loop.Run();
114 EXPECT_TRUE(success) << service << " is unexpectedly present.";
115}
116
Joshua Pawlicki83d1d8232020-10-23 20:13:31117} // namespace
118
Joshua Pawlicki6867d7c2021-01-06 15:51:09119void EnterTestMode(const GURL& url) {
Adam Norberg14b66a12021-01-20 21:54:03120 ASSERT_TRUE(ExternalConstantsBuilder()
121 .SetUpdateURL(std::vector<std::string>{url.spec()})
122 .SetUseCUP(false)
Mila Green1cb26962021-01-21 01:00:00123 .SetInitialDelay(0.1)
Mila Green59389f12021-02-03 20:52:32124 .SetServerKeepAliveSeconds(1)
Adam Norberg14b66a12021-01-20 21:54:03125 .Overwrite());
Joshua Pawlicki6867d7c2021-01-06 15:51:09126}
127
Mila Greenf6d82f82021-03-05 22:14:29128base::Optional<base::FilePath> GetDataDirPath(UpdaterScope scope) {
129 base::Optional<base::FilePath> app_path =
130 GetApplicationSupportDirectory(scope);
131 if (!app_path) {
132 VLOG(1) << "Failed to get Application support path.";
133 return base::nullopt;
134 }
Joshua Pawlicki6867d7c2021-01-06 15:51:09135
Mila Greenf6d82f82021-03-05 22:14:29136 return app_path->AppendASCII(COMPANY_SHORTNAME_STRING)
Joshua Pawlicki9d1340fc2020-08-14 20:59:35137 .AppendASCII(PRODUCT_FULLNAME_STRING);
138}
139
Mila Greenf6d82f82021-03-05 22:14:29140void Clean(UpdaterScope scope) {
141 Launchd::Domain launchd_domain = LaunchdDomain(scope);
142 Launchd::Type launchd_type = LaunchdType(scope);
143
144 base::Optional<base::FilePath> path = GetProductPath(scope);
145 EXPECT_TRUE(path);
146 if (path)
147 EXPECT_TRUE(base::DeletePathRecursively(*path));
Joshua Pawlicki8f755d382020-03-20 19:51:10148 EXPECT_TRUE(Launchd::GetInstance()->DeletePlist(
Mila Greenf6d82f82021-03-05 22:14:29149 launchd_domain, launchd_type, updater::CopyWakeLaunchdName()));
Joshua Pawlicki8f755d382020-03-20 19:51:10150 EXPECT_TRUE(Launchd::GetInstance()->DeletePlist(
Mila Greenf6d82f82021-03-05 22:14:29151 launchd_domain, launchd_type,
Mila Green80845642020-12-10 03:44:51152 updater::CopyUpdateServiceInternalLaunchdName()));
Mila Green7414a0ed2020-07-21 21:30:42153 EXPECT_TRUE(Launchd::GetInstance()->DeletePlist(
Mila Greenf6d82f82021-03-05 22:14:29154 launchd_domain, launchd_type, updater::CopyUpdateServiceLaunchdName()));
155
156 path = GetDataDirPath(scope);
157 EXPECT_TRUE(path);
158 if (path)
159 EXPECT_TRUE(base::DeletePathRecursively(*path));
Joshua Pawlicki3f645882020-08-21 20:36:17160
161 @autoreleasepool {
Mila Greenf6d82f82021-03-05 22:14:29162 RemoveJobFromLaunchd(scope, launchd_domain, launchd_type,
Mila Green3c9375d2021-03-17 16:33:59163 CopyWakeLaunchdName());
164 RemoveJobFromLaunchd(scope, launchd_domain, launchd_type,
Joshua Pawlickicd6925c92020-12-15 15:07:50165 CopyUpdateServiceLaunchdName());
Mila Greenf6d82f82021-03-05 22:14:29166 RemoveJobFromLaunchd(scope, launchd_domain, launchd_type,
Joshua Pawlickicd6925c92020-12-15 15:07:50167 CopyUpdateServiceInternalLaunchdName());
Joshua Pawlicki3f645882020-08-21 20:36:17168 }
Joshua Pawlickibae1c6d2352020-03-19 19:21:44169}
170
Mila Greenf6d82f82021-03-05 22:14:29171void ExpectClean(UpdaterScope scope) {
172 Launchd::Domain launchd_domain = LaunchdDomain(scope);
173 Launchd::Type launchd_type = LaunchdType(scope);
174
Joshua Pawlickibae1c6d2352020-03-19 19:21:44175 // Files must not exist on the file system.
Mila Greenf6d82f82021-03-05 22:14:29176 base::Optional<base::FilePath> path = GetProductPath(scope);
177 EXPECT_TRUE(path);
178 if (path)
179 EXPECT_FALSE(base::PathExists(*path));
Joshua Pawlicki8f755d382020-03-20 19:51:10180 EXPECT_FALSE(Launchd::GetInstance()->PlistExists(
Mila Greenf6d82f82021-03-05 22:14:29181 launchd_domain, launchd_type, updater::CopyWakeLaunchdName()));
Mila Green8ddc4e02020-05-01 00:15:02182 EXPECT_FALSE(Launchd::GetInstance()->PlistExists(
Mila Greenf6d82f82021-03-05 22:14:29183 launchd_domain, launchd_type,
Mila Green80845642020-12-10 03:44:51184 updater::CopyUpdateServiceInternalLaunchdName()));
Mila Green7414a0ed2020-07-21 21:30:42185 EXPECT_FALSE(Launchd::GetInstance()->PlistExists(
Mila Greenf6d82f82021-03-05 22:14:29186 launchd_domain, launchd_type, updater::CopyUpdateServiceLaunchdName()));
187
188 path = GetDataDirPath(scope);
189 EXPECT_TRUE(path);
190 if (path)
191 EXPECT_FALSE(base::PathExists(*path));
192
193 ExpectServiceAbsent(scope, kUpdateServiceLaunchdName);
194 ExpectServiceAbsent(scope, kUpdateServiceInternalLaunchdName);
Joshua Pawlickibae1c6d2352020-03-19 19:21:44195}
196
Mila Greenf6d82f82021-03-05 22:14:29197void ExpectInstalled(UpdaterScope scope) {
198 Launchd::Domain launchd_domain = LaunchdDomain(scope);
199 Launchd::Type launchd_type = LaunchdType(scope);
200
Joshua Pawlickibae1c6d2352020-03-19 19:21:44201 // Files must exist on the file system.
Mila Greenf6d82f82021-03-05 22:14:29202 base::Optional<base::FilePath> path = GetProductPath(scope);
203 EXPECT_TRUE(path);
204 if (path)
205 EXPECT_TRUE(base::PathExists(*path));
206
207 EXPECT_TRUE(Launchd::GetInstance()->PlistExists(launchd_domain, launchd_type,
Mila Green7414a0ed2020-07-21 21:30:42208 CopyWakeLaunchdName()));
Mila Green80845642020-12-10 03:44:51209 EXPECT_TRUE(Launchd::GetInstance()->PlistExists(
Mila Greenf6d82f82021-03-05 22:14:29210 launchd_domain, launchd_type, CopyUpdateServiceInternalLaunchdName()));
Joshua Pawlickibae1c6d2352020-03-19 19:21:44211}
212
Mila Greenf6d82f82021-03-05 22:14:29213void Install(UpdaterScope scope) {
Mila Green8ddc4e02020-05-01 00:15:02214 const base::FilePath path = GetExecutablePath();
Joshua Pawlickibae1c6d2352020-03-19 19:21:44215 ASSERT_FALSE(path.empty());
Michael Change4785a822020-03-26 20:55:01216 base::CommandLine command_line(path);
Joshua Pawlicki91ce318b2020-09-15 14:35:38217 command_line.AppendSwitch(kInstallSwitch);
Mila Green8ddc4e02020-05-01 00:15:02218 int exit_code = -1;
Mila Greenf6d82f82021-03-05 22:14:29219 ASSERT_TRUE(Run(scope, command_line, &exit_code));
220 EXPECT_EQ(exit_code, 0);
Mila Green8ddc4e02020-05-01 00:15:02221}
222
Mila Greenf6d82f82021-03-05 22:14:29223void ExpectActiveUpdater(UpdaterScope scope) {
224 Launchd::Domain launchd_domain = LaunchdDomain(scope);
225 Launchd::Type launchd_type = LaunchdType(scope);
226
Mila Green8ddc4e02020-05-01 00:15:02227 // Files must exist on the file system.
Mila Greenf6d82f82021-03-05 22:14:29228 base::Optional<base::FilePath> path = GetProductPath(scope);
229 EXPECT_TRUE(path);
230 if (path)
231 EXPECT_TRUE(base::PathExists(*path));
232
Mila Green80845642020-12-10 03:44:51233 EXPECT_TRUE(Launchd::GetInstance()->PlistExists(
Mila Greenf6d82f82021-03-05 22:14:29234 launchd_domain, launchd_type, CopyUpdateServiceLaunchdName()));
Mila Green8ddc4e02020-05-01 00:15:02235}
236
Mila Greenf6d82f82021-03-05 22:14:29237void RegisterTestApp(UpdaterScope scope) {
Mila Green3e3058a2020-08-27 16:59:27238 const base::FilePath path = GetTestAppExecutablePath();
239 ASSERT_FALSE(path.empty());
240 base::CommandLine command_line(path);
241 command_line.AppendSwitch(kRegisterUpdaterSwitch);
242 int exit_code = -1;
Mila Greenf6d82f82021-03-05 22:14:29243 ASSERT_TRUE(Run(scope, command_line, &exit_code));
244 EXPECT_EQ(exit_code, 0);
Mila Green3e3058a2020-08-27 16:59:27245}
246
Mila Greenf6d82f82021-03-05 22:14:29247base::Optional<base::FilePath> GetInstalledExecutablePath(UpdaterScope scope) {
248 return GetUpdaterExecutablePath(scope);
Mila Greena3991ae2020-10-16 00:10:55249}
250
Mila Greenf6d82f82021-03-05 22:14:29251void ExpectCandidateUninstalled(UpdaterScope scope) {
252 Launchd::Domain launchd_domain = LaunchdDomain(scope);
253 Launchd::Type launchd_type = LaunchdType(scope);
254
255 base::Optional<base::FilePath> versioned_folder_path =
256 GetVersionedUpdaterFolderPath(scope);
257 EXPECT_TRUE(versioned_folder_path);
258 if (versioned_folder_path)
259 EXPECT_FALSE(base::PathExists(*versioned_folder_path));
260
261 EXPECT_FALSE(Launchd::GetInstance()->PlistExists(launchd_domain, launchd_type,
262 CopyWakeLaunchdName()));
Mila Greena3991ae2020-10-16 00:10:55263 EXPECT_FALSE(Launchd::GetInstance()->PlistExists(
Mila Greenf6d82f82021-03-05 22:14:29264 launchd_domain, launchd_type, CopyUpdateServiceInternalLaunchdName()));
Joshua Pawlicki4abd1322020-08-19 22:05:57265}
266
Mila Greenf6d82f82021-03-05 22:14:29267void Uninstall(UpdaterScope scope) {
Joshua Pawlicki6867d7c2021-01-06 15:51:09268 if (::testing::Test::HasFailure())
Mila Greenf6d82f82021-03-05 22:14:29269 PrintLog(scope);
adoneria1762dd72020-12-17 17:33:08270 // Copy logs from GetDataDirPath() before updater uninstalls itself
271 // and deletes the path.
Mila Greenf6d82f82021-03-05 22:14:29272 base::Optional<base::FilePath> path = GetDataDirPath(scope);
273 EXPECT_TRUE(path);
274 if (path)
275 CopyLog(*path);
adoneria1762dd72020-12-17 17:33:08276
277 // Uninstall the updater.
Mila Greenf6d82f82021-03-05 22:14:29278 path = GetExecutablePath();
279 ASSERT_TRUE(path);
280 base::CommandLine command_line(*path);
Mila Green8ddc4e02020-05-01 00:15:02281 command_line.AppendSwitch(kUninstallSwitch);
Joshua Pawlickibae1c6d2352020-03-19 19:21:44282 int exit_code = -1;
Mila Greenf6d82f82021-03-05 22:14:29283 ASSERT_TRUE(Run(scope, command_line, &exit_code));
284 EXPECT_EQ(exit_code, 0);
Joshua Pawlickibae1c6d2352020-03-19 19:21:44285}
286
Mila Greenf6d82f82021-03-05 22:14:29287base::Optional<base::FilePath> GetFakeUpdaterInstallFolderPath(
288 UpdaterScope scope,
289 const base::Version& version) {
290 return GetExecutableFolderPathForVersion(scope, version);
Mila Greena3991ae2020-10-16 00:10:55291}
292
Mila Greenf6d82f82021-03-05 22:14:29293void SetActive(UpdaterScope scope, const std::string& app_id) {
Mila Green708bf0d92021-03-23 17:33:15294 const base::Optional<base::FilePath> path = GetActiveFile(scope, app_id);
295 ASSERT_TRUE(path);
296 VLOG(0) << "Actives file: " << *path;
Joshua Pawlicki6867d7c2021-01-06 15:51:09297 base::File::Error err = base::File::FILE_OK;
Mila Green708bf0d92021-03-23 17:33:15298 EXPECT_TRUE(base::CreateDirectoryAndGetError(path->DirName(), &err))
Joshua Pawlicki6867d7c2021-01-06 15:51:09299 << "Error: " << err;
Mila Green708bf0d92021-03-23 17:33:15300 EXPECT_TRUE(base::WriteFile(*path, ""));
Joshua Pawlicki6867d7c2021-01-06 15:51:09301}
302
Mila Greenf6d82f82021-03-05 22:14:29303void ExpectActive(UpdaterScope scope, const std::string& app_id) {
Mila Green708bf0d92021-03-23 17:33:15304 const base::Optional<base::FilePath> path = GetActiveFile(scope, app_id);
Mila Greenf6d82f82021-03-05 22:14:29305 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) {
Mila Green708bf0d92021-03-23 17:33:15311 const base::Optional<base::FilePath> path = GetActiveFile(scope, app_id);
Mila Greenf6d82f82021-03-05 22:14:29312 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