Commit 83d1d823 authored by Joshua Pawlicki's avatar Joshua Pawlicki Committed by Commit Bot

Updater: Respond to RPC even in the qualification and uninstall paths.

Unfortunately, deferring uninstallation until after the RPC server
starts up means the test must pay the 10s between task handling and
server shutdown (& uninstall).

This CL also adds some basic functionality to print the updater log in
the case of a failed test, and speeds up Windows integration tests by
moving the sleep to only happen for --uninstall launches.

Bug: 1141659
Fixed: 1141659
Change-Id: Iba90261c402966fe1ddb814d01b5521c94da0a2b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2493043
Commit-Queue: Joshua Pawlicki <waffles@chromium.org>
Reviewed-by: default avatarSorin Jianu <sorin@chromium.org>
Auto-Submit: Joshua Pawlicki <waffles@chromium.org>
Cr-Commit-Position: refs/heads/master@{#820393}
parent 0f23e6b9
...@@ -96,6 +96,8 @@ if (is_win || is_mac) { ...@@ -96,6 +96,8 @@ if (is_win || is_mac) {
"configurator.h", "configurator.h",
"control_service_impl.cc", "control_service_impl.cc",
"control_service_impl.h", "control_service_impl.h",
"control_service_impl_inactive.cc",
"control_service_impl_inactive.h",
"crx_downloader_factory.h", "crx_downloader_factory.h",
"external_constants.cc", "external_constants.cc",
"external_constants.h", "external_constants.h",
...@@ -113,6 +115,8 @@ if (is_win || is_mac) { ...@@ -113,6 +115,8 @@ if (is_win || is_mac) {
"tag.h", "tag.h",
"update_service_impl.cc", "update_service_impl.cc",
"update_service_impl.h", "update_service_impl.h",
"update_service_impl_inactive.cc",
"update_service_impl_inactive.h",
"updater.cc", "updater.cc",
"updater.h", "updater.h",
] ]
......
...@@ -8,11 +8,18 @@ ...@@ -8,11 +8,18 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/memory/scoped_refptr.h"
#include "base/version.h" #include "base/version.h"
#include "chrome/updater/configurator.h" #include "chrome/updater/configurator.h"
#include "chrome/updater/constants.h" #include "chrome/updater/constants.h"
#include "chrome/updater/control_service.h"
#include "chrome/updater/control_service_impl.h"
#include "chrome/updater/control_service_impl_inactive.h"
#include "chrome/updater/persisted_data.h" #include "chrome/updater/persisted_data.h"
#include "chrome/updater/prefs.h" #include "chrome/updater/prefs.h"
#include "chrome/updater/update_service.h"
#include "chrome/updater/update_service_impl.h"
#include "chrome/updater/update_service_impl_inactive.h"
#include "chrome/updater/updater_version.h" #include "chrome/updater/updater_version.h"
#include "components/prefs/pref_service.h" #include "components/prefs/pref_service.h"
...@@ -41,7 +48,10 @@ base::OnceClosure AppServer::ModeCheck() { ...@@ -41,7 +48,10 @@ base::OnceClosure AppServer::ModeCheck() {
if (this_version < active_version) { if (this_version < active_version) {
global_prefs = nullptr; global_prefs = nullptr;
return base::BindOnce(&AppServer::UninstallSelf, this); uninstall_ = true;
return base::BindOnce(&AppServer::ActiveDuty, this,
MakeInactiveUpdateService(),
MakeInactiveControlService());
} }
if (active_version != base::Version("0") && active_version != this_version) { if (active_version != base::Version("0") && active_version != this_version) {
...@@ -58,12 +68,18 @@ base::OnceClosure AppServer::ModeCheck() { ...@@ -58,12 +68,18 @@ base::OnceClosure AppServer::ModeCheck() {
} }
config_ = base::MakeRefCounted<Configurator>(std::move(global_prefs)); config_ = base::MakeRefCounted<Configurator>(std::move(global_prefs));
return base::BindOnce(&AppServer::ActiveDuty, this); return base::BindOnce(&AppServer::ActiveDuty, this,
base::MakeRefCounted<UpdateServiceImpl>(config_),
base::MakeRefCounted<ControlServiceImpl>(config_));
} }
void AppServer::Uninitialize() { void AppServer::Uninitialize() {
if (config_) if (config_)
PrefsCommitPendingWrites(config_->GetPrefService()); PrefsCommitPendingWrites(config_->GetPrefService());
if (uninstall_) {
VLOG(1) << "Uninstalling version " << UPDATER_VERSION_STRING;
UninstallSelf();
}
} }
void AppServer::FirstTaskRun() { void AppServer::FirstTaskRun() {
...@@ -75,7 +91,10 @@ void AppServer::Qualify(std::unique_ptr<LocalPrefs> local_prefs) { ...@@ -75,7 +91,10 @@ void AppServer::Qualify(std::unique_ptr<LocalPrefs> local_prefs) {
DVLOG(2) << __func__; DVLOG(2) << __func__;
local_prefs->SetQualified(true); local_prefs->SetQualified(true);
PrefsCommitPendingWrites(local_prefs->GetPrefService()); PrefsCommitPendingWrites(local_prefs->GetPrefService());
Shutdown(kErrorQualificationExit);
// Start ActiveDuty with inactive service implementations. To use active
// implementations, the server would have to ModeCheck again.
ActiveDuty(MakeInactiveUpdateService(), MakeInactiveControlService());
} }
bool AppServer::SwapVersions(GlobalPrefs* global_prefs) { bool AppServer::SwapVersions(GlobalPrefs* global_prefs) {
......
...@@ -14,8 +14,10 @@ ...@@ -14,8 +14,10 @@
namespace updater { namespace updater {
class Configurator; class Configurator;
class ControlService;
class GlobalPrefs; class GlobalPrefs;
class LocalPrefs; class LocalPrefs;
class UpdateService;
// AppServer runs as the updater server process. Multiple servers of different // AppServer runs as the updater server process. Multiple servers of different
// application versions can be run side-by-side. Each such server is called a // application versions can be run side-by-side. Each such server is called a
...@@ -32,15 +34,15 @@ class AppServer : public App { ...@@ -32,15 +34,15 @@ class AppServer : public App {
// Overrides of App. // Overrides of App.
void Uninitialize() override; void Uninitialize() override;
scoped_refptr<Configurator> config_;
private: private:
// Overrides of App. // Overrides of App.
void Initialize() final; void Initialize() final;
void FirstTaskRun() final; void FirstTaskRun() final;
// Set up the server for normal active-candidate functions. // Set up the server for normal active version functions using the provided
virtual void ActiveDuty() = 0; // services.
virtual void ActiveDuty(scoped_refptr<UpdateService> update_service,
scoped_refptr<ControlService> control_service) = 0;
// Set up all non-side-by-side RPC interfaces to point to this candidate // Set up all non-side-by-side RPC interfaces to point to this candidate
// server. // server.
...@@ -63,6 +65,11 @@ class AppServer : public App { ...@@ -63,6 +65,11 @@ class AppServer : public App {
bool SwapVersions(GlobalPrefs* global_prefs); bool SwapVersions(GlobalPrefs* global_prefs);
base::OnceClosure first_task_; base::OnceClosure first_task_;
scoped_refptr<Configurator> config_;
// If true, this version of the updater should uninstall itself during
// shutdown.
bool uninstall_ = false;
}; };
scoped_refptr<App> AppServerInstance(); scoped_refptr<App> AppServerInstance();
......
...@@ -8,11 +8,14 @@ ...@@ -8,11 +8,14 @@
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/files/file_util.h" #include "base/files/file_util.h"
#include "base/memory/scoped_refptr.h"
#include "base/message_loop/message_pump_type.h" #include "base/message_loop/message_pump_type.h"
#include "base/task/single_thread_task_executor.h" #include "base/task/single_thread_task_executor.h"
#include "base/task/thread_pool/thread_pool_instance.h" #include "base/task/thread_pool/thread_pool_instance.h"
#include "chrome/updater/constants.h" #include "chrome/updater/constants.h"
#include "chrome/updater/control_service.h"
#include "chrome/updater/prefs.h" #include "chrome/updater/prefs.h"
#include "chrome/updater/update_service.h"
#include "chrome/updater/updater_version.h" #include "chrome/updater/updater_version.h"
#include "chrome/updater/util.h" #include "chrome/updater/util.h"
#include "components/prefs/pref_service.h" #include "components/prefs/pref_service.h"
...@@ -31,11 +34,12 @@ class AppServerTest : public AppServer { ...@@ -31,11 +34,12 @@ class AppServerTest : public AppServer {
AppServerTest() { AppServerTest() {
ON_CALL(*this, ActiveDuty) ON_CALL(*this, ActiveDuty)
.WillByDefault(Invoke(this, &AppServerTest::Shutdown0)); .WillByDefault(Invoke(this, &AppServerTest::Shutdown0));
ON_CALL(*this, UninstallSelf)
.WillByDefault(Invoke(this, &AppServerTest::Shutdown0));
} }
MOCK_METHOD(void, ActiveDuty, (), (override)); MOCK_METHOD(void,
ActiveDuty,
(scoped_refptr<UpdateService>, scoped_refptr<ControlService>),
(override));
MOCK_METHOD(bool, SwapRPCInterfaces, (), (override)); MOCK_METHOD(bool, SwapRPCInterfaces, (), (override));
MOCK_METHOD(void, UninstallSelf, (), (override)); MOCK_METHOD(void, UninstallSelf, (), (override));
...@@ -89,11 +93,11 @@ TEST_F(AppServerTestCase, SimpleQualify) { ...@@ -89,11 +93,11 @@ TEST_F(AppServerTestCase, SimpleQualify) {
} }
auto app = base::MakeRefCounted<AppServerTest>(); auto app = base::MakeRefCounted<AppServerTest>();
// Expect the app to qualify and then shutdown. // Expect the app to qualify and then ActiveDuty.
EXPECT_CALL(*app, ActiveDuty).Times(0); EXPECT_CALL(*app, ActiveDuty).Times(1);
EXPECT_CALL(*app, SwapRPCInterfaces).Times(0); EXPECT_CALL(*app, SwapRPCInterfaces).Times(0);
EXPECT_CALL(*app, UninstallSelf).Times(0); EXPECT_CALL(*app, UninstallSelf).Times(0);
EXPECT_EQ(app->Run(), kErrorQualificationExit); EXPECT_EQ(app->Run(), 0);
EXPECT_TRUE(CreateLocalPrefs()->GetQualified()); EXPECT_TRUE(CreateLocalPrefs()->GetQualified());
} }
...@@ -108,8 +112,8 @@ TEST_F(AppServerTestCase, SelfUninstall) { ...@@ -108,8 +112,8 @@ TEST_F(AppServerTestCase, SelfUninstall) {
} }
auto app = base::MakeRefCounted<AppServerTest>(); auto app = base::MakeRefCounted<AppServerTest>();
// Expect the app to SelfUninstall and then Shutdown(0). // Expect the app to ActiveDuty then SelfUninstall.
EXPECT_CALL(*app, ActiveDuty).Times(0); EXPECT_CALL(*app, ActiveDuty).Times(1);
EXPECT_CALL(*app, SwapRPCInterfaces).Times(0); EXPECT_CALL(*app, SwapRPCInterfaces).Times(0);
EXPECT_CALL(*app, UninstallSelf).Times(1); EXPECT_CALL(*app, UninstallSelf).Times(1);
EXPECT_EQ(app->Run(), 0); EXPECT_EQ(app->Run(), 0);
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "base/atomic_ref_count.h" #include "base/atomic_ref_count.h"
#include "base/mac/scoped_nsobject.h" #include "base/mac/scoped_nsobject.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/memory/scoped_refptr.h"
#include "base/sequence_checker.h" #include "base/sequence_checker.h"
#include "chrome/updater/app/app_server.h" #include "chrome/updater/app/app_server.h"
#include "chrome/updater/app/server/mac/service_delegate.h" #include "chrome/updater/app/server/mac/service_delegate.h"
...@@ -26,6 +27,9 @@ class SequencedTaskRunner; ...@@ -26,6 +27,9 @@ class SequencedTaskRunner;
namespace updater { namespace updater {
class ControlService;
class UpdateService;
class AppServerMac : public AppServer { class AppServerMac : public AppServer {
public: public:
AppServerMac(); AppServerMac();
...@@ -40,7 +44,8 @@ class AppServerMac : public AppServer { ...@@ -40,7 +44,8 @@ class AppServerMac : public AppServer {
~AppServerMac() override; ~AppServerMac() override;
// Overrides of AppServer. // Overrides of AppServer.
void ActiveDuty() override; void ActiveDuty(scoped_refptr<UpdateService> update_service,
scoped_refptr<ControlService> control_service) override;
bool SwapRPCInterfaces() override; bool SwapRPCInterfaces() override;
void UninstallSelf() override; void UninstallSelf() override;
......
...@@ -21,11 +21,11 @@ ...@@ -21,11 +21,11 @@
#include "chrome/updater/app/server/mac/service_delegate.h" #include "chrome/updater/app/server/mac/service_delegate.h"
#include "chrome/updater/configurator.h" #include "chrome/updater/configurator.h"
#include "chrome/updater/constants.h" #include "chrome/updater/constants.h"
#include "chrome/updater/control_service_impl.h" #include "chrome/updater/control_service.h"
#include "chrome/updater/mac/setup/setup.h" #include "chrome/updater/mac/setup/setup.h"
#import "chrome/updater/mac/xpc_service_names.h" #import "chrome/updater/mac/xpc_service_names.h"
#include "chrome/updater/prefs.h" #include "chrome/updater/prefs.h"
#include "chrome/updater/update_service_impl.h" #include "chrome/updater/update_service.h"
namespace updater { namespace updater {
...@@ -43,7 +43,8 @@ void AppServerMac::Uninitialize() { ...@@ -43,7 +43,8 @@ void AppServerMac::Uninitialize() {
AppServer::Uninitialize(); AppServer::Uninitialize();
} }
void AppServerMac::ActiveDuty() { void AppServerMac::ActiveDuty(scoped_refptr<UpdateService> update_service,
scoped_refptr<ControlService> control_service) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
const base::CommandLine& command_line = const base::CommandLine& command_line =
*base::CommandLine::ForCurrentProcess(); *base::CommandLine::ForCurrentProcess();
...@@ -58,8 +59,7 @@ void AppServerMac::ActiveDuty() { ...@@ -58,8 +59,7 @@ void AppServerMac::ActiveDuty() {
@autoreleasepool { @autoreleasepool {
// Sets up a listener and delegate for the CRUControlling XPC connection. // Sets up a listener and delegate for the CRUControlling XPC connection.
control_service_delegate_.reset([[CRUControlServiceXPCDelegate alloc] control_service_delegate_.reset([[CRUControlServiceXPCDelegate alloc]
initWithControlService:base::MakeRefCounted<ControlServiceImpl>( initWithControlService:control_service
config_)
appServer:scoped_refptr<AppServerMac>(this)]); appServer:scoped_refptr<AppServerMac>(this)]);
control_service_listener_.reset([[NSXPCListener alloc] control_service_listener_.reset([[NSXPCListener alloc]
...@@ -74,7 +74,7 @@ void AppServerMac::ActiveDuty() { ...@@ -74,7 +74,7 @@ void AppServerMac::ActiveDuty() {
// Sets up a listener and delegate for the CRUUpdateChecking XPC // Sets up a listener and delegate for the CRUUpdateChecking XPC
// connection. // connection.
update_check_delegate_.reset([[CRUUpdateCheckServiceXPCDelegate alloc] update_check_delegate_.reset([[CRUUpdateCheckServiceXPCDelegate alloc]
initWithUpdateService:base::MakeRefCounted<UpdateServiceImpl>(config_) initWithUpdateService:update_service
appServer:scoped_refptr<AppServerMac>(this)]); appServer:scoped_refptr<AppServerMac>(this)]);
update_check_listener_.reset([[NSXPCListener alloc] update_check_listener_.reset([[NSXPCListener alloc]
...@@ -91,9 +91,7 @@ void AppServerMac::ActiveDuty() { ...@@ -91,9 +91,7 @@ void AppServerMac::ActiveDuty() {
} }
void AppServerMac::UninstallSelf() { void AppServerMac::UninstallSelf() {
base::ThreadPool::PostTaskAndReplyWithResult( UninstallCandidate();
FROM_HERE, {base::MayBlock()}, base::BindOnce(&UninstallCandidate),
base::BindOnce(&AppServerMac::Shutdown, this));
} }
bool AppServerMac::SwapRPCInterfaces() { bool AppServerMac::SwapRPCInterfaces() {
......
...@@ -20,9 +20,9 @@ ...@@ -20,9 +20,9 @@
#include "chrome/updater/app/server/win/com_classes.h" #include "chrome/updater/app/server/win/com_classes.h"
#include "chrome/updater/app/server/win/com_classes_legacy.h" #include "chrome/updater/app/server/win/com_classes_legacy.h"
#include "chrome/updater/configurator.h" #include "chrome/updater/configurator.h"
#include "chrome/updater/control_service_impl.h" #include "chrome/updater/control_service.h"
#include "chrome/updater/prefs.h" #include "chrome/updater/prefs.h"
#include "chrome/updater/update_service_impl.h" #include "chrome/updater/update_service.h"
#include "chrome/updater/win/constants.h" #include "chrome/updater/win/constants.h"
#include "chrome/updater/win/wrl_module.h" #include "chrome/updater/win/wrl_module.h"
#include "components/prefs/pref_service.h" #include "components/prefs/pref_service.h"
...@@ -147,23 +147,22 @@ void ComServerApp::Stop() { ...@@ -147,23 +147,22 @@ void ComServerApp::Stop() {
main_task_runner_->PostTask( main_task_runner_->PostTask(
FROM_HERE, base::BindOnce([]() { FROM_HERE, base::BindOnce([]() {
scoped_refptr<ComServerApp> this_server = AppServerSingletonInstance(); scoped_refptr<ComServerApp> this_server = AppServerSingletonInstance();
this_server->config_->GetPrefService()->CommitPendingWrite();
this_server->update_service_ = nullptr; this_server->update_service_ = nullptr;
this_server->control_service_ = nullptr; this_server->control_service_ = nullptr;
this_server->config_ = nullptr;
this_server->Shutdown(0); this_server->Shutdown(0);
})); }));
} }
void ComServerApp::ActiveDuty() { void ComServerApp::ActiveDuty(scoped_refptr<UpdateService> update_service,
scoped_refptr<ControlService> control_service) {
if (!com_initializer_.Succeeded()) { if (!com_initializer_.Succeeded()) {
PLOG(ERROR) << "Failed to initialize COM"; PLOG(ERROR) << "Failed to initialize COM";
Shutdown(-1); Shutdown(-1);
return; return;
} }
main_task_runner_ = base::SequencedTaskRunnerHandle::Get(); main_task_runner_ = base::SequencedTaskRunnerHandle::Get();
update_service_ = base::MakeRefCounted<UpdateServiceImpl>(config_); update_service_ = update_service;
control_service_ = base::MakeRefCounted<ControlServiceImpl>(config_); control_service_ = control_service;
CreateWRLModule(); CreateWRLModule();
HRESULT hr = RegisterClassObjects(); HRESULT hr = RegisterClassObjects();
if (FAILED(hr)) if (FAILED(hr))
......
...@@ -55,7 +55,8 @@ class ComServerApp : public AppServer { ...@@ -55,7 +55,8 @@ class ComServerApp : public AppServer {
void InitializeThreadPool() override; void InitializeThreadPool() override;
// Overrides for AppServer // Overrides for AppServer
void ActiveDuty() override; void ActiveDuty(scoped_refptr<UpdateService> update_service,
scoped_refptr<ControlService> control_service) override;
bool SwapRPCInterfaces() override; bool SwapRPCInterfaces() override;
void UninstallSelf() override; void UninstallSelf() override;
......
...@@ -185,9 +185,6 @@ constexpr int kErrorFailedToLockPrefsMutex = 1; ...@@ -185,9 +185,6 @@ constexpr int kErrorFailedToLockPrefsMutex = 1;
// The server candidate failed to promote itself to active. // The server candidate failed to promote itself to active.
constexpr int kErrorFailedToSwap = 2; constexpr int kErrorFailedToSwap = 2;
// The server has finished qualification and will not do further operations.
constexpr int kErrorQualificationExit = 3;
// Policy Management constants. // Policy Management constants.
extern const char kProxyModeDirect[]; extern const char kProxyModeDirect[];
extern const char kProxyModeAutoDetect[]; extern const char kProxyModeAutoDetect[];
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/updater/control_service_impl_inactive.h"
#include "base/callback.h"
#include "base/memory/scoped_refptr.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "chrome/updater/control_service.h"
namespace updater {
namespace {
class ControlServiceImplInactive : public ControlService {
public:
ControlServiceImplInactive() = default;
// Overrides for updater::ControlService.
void Run(base::OnceClosure callback) override {
base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE,
std::move(callback));
}
void InitializeUpdateService(base::OnceClosure callback) override {
base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE,
std::move(callback));
}
void Uninitialize() override {}
private:
~ControlServiceImplInactive() override = default;
};
} // namespace
scoped_refptr<ControlService> MakeInactiveControlService() {
return base::MakeRefCounted<ControlServiceImplInactive>();
}
} // namespace updater
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_UPDATER_CONTROL_SERVICE_IMPL_INACTIVE_H_
#define CHROME_UPDATER_CONTROL_SERVICE_IMPL_INACTIVE_H_
#include "base/memory/scoped_refptr.h"
namespace updater {
class ControlService;
scoped_refptr<ControlService> MakeInactiveControlService();
} // namespace updater
#endif // CHROME_UPDATER_CONTROL_SERVICE_IMPL_INACTIVE_H_
...@@ -9,6 +9,9 @@ ...@@ -9,6 +9,9 @@
#include "base/command_line.h" #include "base/command_line.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/files/file_util.h" #include "base/files/file_util.h"
#include "base/logging.h"
#include "base/process/launch.h"
#include "base/process/process.h"
#include "base/test/task_environment.h" #include "base/test/task_environment.h"
#include "base/version.h" #include "base/version.h"
#include "build/build_config.h" #include "build/build_config.h"
...@@ -37,6 +40,18 @@ void ExpectActiveVersion(std::string expected) { ...@@ -37,6 +40,18 @@ void ExpectActiveVersion(std::string expected) {
EXPECT_EQ(CreateGlobalPrefs()->GetActiveVersion(), expected); EXPECT_EQ(CreateGlobalPrefs()->GetActiveVersion(), expected);
} }
void PrintLog() {
std::string contents;
VLOG(0) << GetDataDirPath().AppendASCII("updater.log");
if (base::ReadFileToString(GetDataDirPath().AppendASCII("updater.log"),
&contents)) {
VLOG(0) << "Contents of updater.log:";
VLOG(0) << contents;
} else {
VLOG(0) << "Failed to read updater.log file.";
}
}
} // namespace } // namespace
#if defined(OS_MAC) #if defined(OS_MAC)
...@@ -90,6 +105,28 @@ void SetupFakeUpdaterHigherVersion() { ...@@ -90,6 +105,28 @@ void SetupFakeUpdaterHigherVersion() {
} }
#endif // OS_MAC #endif // OS_MAC
bool Run(base::CommandLine command_line, int* exit_code) {
command_line.AppendSwitch("enable-logging");
command_line.AppendSwitchASCII("vmodule", "*/updater/*=2");
base::Process process = base::LaunchProcess(command_line, {});
if (!process.IsValid())
return false;
return process.WaitForExitWithTimeout(base::TimeDelta::FromSeconds(60),
exit_code);
}
void SleepFor(int seconds) {
VLOG(2) << "Sleeping " << seconds << " seconds...";
base::WaitableEvent sleep(base::WaitableEvent::ResetPolicy::MANUAL,
base::WaitableEvent::InitialState::NOT_SIGNALED);
base::ThreadPool::PostDelayedTask(
FROM_HERE, {base::MayBlock()},
base::BindOnce(&base::WaitableEvent::Signal, base::Unretained(&sleep)),
base::TimeDelta::FromSeconds(seconds));
sleep.Wait();
VLOG(2) << "Sleep complete.";
}
class IntegrationTest : public ::testing::Test { class IntegrationTest : public ::testing::Test {
protected: protected:
void SetUp() override { void SetUp() override {
...@@ -99,7 +136,11 @@ class IntegrationTest : public ::testing::Test { ...@@ -99,7 +136,11 @@ class IntegrationTest : public ::testing::Test {
} }
void TearDown() override { void TearDown() override {
if (::testing::Test::HasFailure())
PrintLog();
ExpectClean(); ExpectClean();
if (::testing::Test::HasFailure())
PrintLog();
Clean(); Clean();
} }
...@@ -123,6 +164,12 @@ TEST_F(IntegrationTest, SelfUninstallOutdatedUpdater) { ...@@ -123,6 +164,12 @@ TEST_F(IntegrationTest, SelfUninstallOutdatedUpdater) {
EXPECT_NE(CreateGlobalPrefs()->GetActiveVersion(), UPDATER_VERSION_STRING); EXPECT_NE(CreateGlobalPrefs()->GetActiveVersion(), UPDATER_VERSION_STRING);
RunWake(0); RunWake(0);
// The mac server will remain active for 10 seconds after it replies to the
// wake client, then shut down and uninstall itself. Sleep to wait for this
// to happen.
SleepFor(11);
ExpectCandidateUninstalled(); ExpectCandidateUninstalled();
Uninstall(); Uninstall();
} }
......
...@@ -28,6 +28,14 @@ void ExpectClean(); ...@@ -28,6 +28,14 @@ void ExpectClean();
// Places the updater into test mode (use local servers and disable CUP). // Places the updater into test mode (use local servers and disable CUP).
void EnterTestMode(); void EnterTestMode();
// Sleeps for the given number of seconds. This should be avoided, but in some
// cases surrounding uninstall it is necessary since the processes can exit
// prior to completing the actual uninstallation.
void SleepFor(int seconds);
// Returns the path to the updater data dir.
base::FilePath GetDataDirPath();
// Expects that the updater is installed on the system. // Expects that the updater is installed on the system.
void ExpectInstalled(); void ExpectInstalled();
......
...@@ -9,14 +9,13 @@ ...@@ -9,14 +9,13 @@
#include "base/files/file_util.h" #include "base/files/file_util.h"
#include "base/mac/foundation_util.h" #include "base/mac/foundation_util.h"
#include "base/path_service.h" #include "base/path_service.h"
#include "base/process/launch.h"
#include "base/process/process.h"
#include "base/version.h" #include "base/version.h"
#include "chrome/common/mac/launchd.h" #include "chrome/common/mac/launchd.h"
#include "chrome/updater/constants.h" #include "chrome/updater/constants.h"
#import "chrome/updater/mac/util.h" #import "chrome/updater/mac/util.h"
#include "chrome/updater/mac/xpc_service_names.h" #include "chrome/updater/mac/xpc_service_names.h"
#include "chrome/updater/prefs.h" #include "chrome/updater/prefs.h"
#include "chrome/updater/test/integration_tests.h"
#include "chrome/updater/test/test_app/constants.h" #include "chrome/updater/test/test_app/constants.h"
#include "chrome/updater/test/test_app/test_app_version.h" #include "chrome/updater/test/test_app/test_app_version.h"
#include "chrome/updater/updater_version.h" #include "chrome/updater/updater_version.h"
...@@ -27,6 +26,9 @@ namespace updater { ...@@ -27,6 +26,9 @@ namespace updater {
namespace test { namespace test {
// crbug.com/1112527: These tests are not compatible with component build.
#if !defined(COMPONENT_BUILD)
namespace { namespace {
base::FilePath GetExecutablePath() { base::FilePath GetExecutablePath() {
...@@ -57,6 +59,8 @@ base::FilePath GetProductPath() { ...@@ -57,6 +59,8 @@ base::FilePath GetProductPath() {
.AppendASCII(PRODUCT_FULLNAME_STRING); .AppendASCII(PRODUCT_FULLNAME_STRING);
} }
} // namespace
base::FilePath GetDataDirPath() { base::FilePath GetDataDirPath() {
return base::mac::GetUserLibraryPath() return base::mac::GetUserLibraryPath()
.AppendASCII("Application Support") .AppendASCII("Application Support")
...@@ -64,18 +68,6 @@ base::FilePath GetDataDirPath() { ...@@ -64,18 +68,6 @@ base::FilePath GetDataDirPath() {
.AppendASCII(PRODUCT_FULLNAME_STRING); .AppendASCII(PRODUCT_FULLNAME_STRING);
} }
} // namespace
bool Run(base::CommandLine command_line, int* exit_code) {
auto process = base::LaunchProcess(command_line, {});
if (!process.IsValid())
return false;
if (!process.WaitForExitWithTimeout(base::TimeDelta::FromSeconds(60),
exit_code))
return false;
return true;
}
void Clean() { void Clean() {
EXPECT_TRUE(base::DeletePathRecursively(GetProductPath())); EXPECT_TRUE(base::DeletePathRecursively(GetProductPath()));
EXPECT_TRUE(Launchd::GetInstance()->DeletePlist( EXPECT_TRUE(Launchd::GetInstance()->DeletePlist(
...@@ -183,6 +175,8 @@ base::FilePath GetFakeUpdaterInstallFolderPath(const base::Version& version) { ...@@ -183,6 +175,8 @@ base::FilePath GetFakeUpdaterInstallFolderPath(const base::Version& version) {
return GetExecutableFolderPathForVersion(version); return GetExecutableFolderPathForVersion(version);
} }
#endif // !defined(COMPONENT_BUILD)
} // namespace test } // namespace test
} // namespace updater } // namespace updater
...@@ -6,14 +6,13 @@ ...@@ -6,14 +6,13 @@
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/files/file_util.h" #include "base/files/file_util.h"
#include "base/path_service.h" #include "base/path_service.h"
#include "base/process/launch.h"
#include "base/process/process.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/synchronization/waitable_event.h" #include "base/synchronization/waitable_event.h"
#include "base/task/task_traits.h" #include "base/task/task_traits.h"
#include "base/task/thread_pool.h" #include "base/task/thread_pool.h"
#include "base/win/registry.h" #include "base/win/registry.h"
#include "chrome/updater/constants.h" #include "chrome/updater/constants.h"
#include "chrome/updater/test/integration_tests.h"
#include "chrome/updater/updater_version.h" #include "chrome/updater/updater_version.h"
#include "chrome/updater/util.h" #include "chrome/updater/util.h"
#include "chrome/updater/win/constants.h" #include "chrome/updater/win/constants.h"
...@@ -30,25 +29,6 @@ base::FilePath GetInstallerPath() { ...@@ -30,25 +29,6 @@ base::FilePath GetInstallerPath() {
return test_executable.DirName().AppendASCII("UpdaterSetup.exe"); return test_executable.DirName().AppendASCII("UpdaterSetup.exe");
} }
bool Run(base::CommandLine command_line, int* exit_code) {
auto process = base::LaunchProcess(command_line, {});
if (!process.IsValid())
return false;
if (!process.WaitForExitWithTimeout(base::TimeDelta::FromSeconds(60),
exit_code))
return false;
base::WaitableEvent sleep(base::WaitableEvent::ResetPolicy::MANUAL,
base::WaitableEvent::InitialState::NOT_SIGNALED);
// The process will exit before it is done uninstalling: sleep for five
// seconds to allow uninstall to complete.
base::ThreadPool::PostDelayedTask(
FROM_HERE, {base::MayBlock()},
base::BindOnce(&base::WaitableEvent::Signal, base::Unretained(&sleep)),
base::TimeDelta::FromSeconds(5));
sleep.Wait();
return true;
}
base::FilePath GetProductPath() { base::FilePath GetProductPath() {
base::FilePath app_data_dir; base::FilePath app_data_dir;
if (!base::PathService::Get(base::DIR_LOCAL_APP_DATA, &app_data_dir)) if (!base::PathService::Get(base::DIR_LOCAL_APP_DATA, &app_data_dir))
...@@ -62,6 +42,8 @@ base::FilePath GetExecutablePath() { ...@@ -62,6 +42,8 @@ base::FilePath GetExecutablePath() {
return GetProductPath().AppendASCII("updater.exe"); return GetProductPath().AppendASCII("updater.exe");
} }
} // namespace
base::FilePath GetDataDirPath() { base::FilePath GetDataDirPath() {
base::FilePath app_data_dir; base::FilePath app_data_dir;
if (!base::PathService::Get(base::DIR_LOCAL_APP_DATA, &app_data_dir)) if (!base::PathService::Get(base::DIR_LOCAL_APP_DATA, &app_data_dir))
...@@ -70,8 +52,6 @@ base::FilePath GetDataDirPath() { ...@@ -70,8 +52,6 @@ base::FilePath GetDataDirPath() {
.AppendASCII(PRODUCT_FULLNAME_STRING); .AppendASCII(PRODUCT_FULLNAME_STRING);
} }
} // namespace
void Clean() { void Clean() {
// TODO(crbug.com/1062288): Delete the Client / ClientState registry keys. // TODO(crbug.com/1062288): Delete the Client / ClientState registry keys.
base::win::RegKey(HKEY_CURRENT_USER, L"", KEY_SET_VALUE) base::win::RegKey(HKEY_CURRENT_USER, L"", KEY_SET_VALUE)
...@@ -158,6 +138,10 @@ void Uninstall() { ...@@ -158,6 +138,10 @@ void Uninstall() {
int exit_code = -1; int exit_code = -1;
ASSERT_TRUE(Run(command_line, &exit_code)); ASSERT_TRUE(Run(command_line, &exit_code));
EXPECT_EQ(0, exit_code); EXPECT_EQ(0, exit_code);
// Uninstallation involves a race with the uninstall.cmd script and the
// process exit. Sleep to allow the script to complete its work.
SleepFor(5);
} }
} // namespace test } // namespace test
......
...@@ -56,7 +56,10 @@ class UpdateService : public base::RefCountedThreadSafe<UpdateService> { ...@@ -56,7 +56,10 @@ class UpdateService : public base::RefCountedThreadSafe<UpdateService> {
// A function argument was invalid. // A function argument was invalid.
kInvalidArgument = 7, kInvalidArgument = 7,
// Change the traits class in this file when adding new values. // This server is not the active server.
kInactive = 8,
// Change the EnumTraits class in this file when adding new values.
}; };
// Run time errors are organized in specific categories to indicate the // Run time errors are organized in specific categories to indicate the
...@@ -215,7 +218,7 @@ template <> ...@@ -215,7 +218,7 @@ template <>
struct EnumTraits<UpdateService::Result> { struct EnumTraits<UpdateService::Result> {
using Result = UpdateService::Result; using Result = UpdateService::Result;
static constexpr Result first_elem = Result::kSuccess; static constexpr Result first_elem = Result::kSuccess;
static constexpr Result last_elem = Result::kInvalidArgument; static constexpr Result last_elem = Result::kInactive;
}; };
template <> template <>
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/updater/update_service_impl_inactive.h"
#include <string>
#include "base/bind.h"
#include "base/callback.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/version.h"
#include "chrome/updater/registration_data.h"
#include "chrome/updater/update_service.h"
namespace updater {
namespace {
class UpdateServiceImplInactive : public UpdateService {
public:
UpdateServiceImplInactive() = default;
// Overrides for updater::UpdateService.
void GetVersion(
base::OnceCallback<void(const base::Version&)> callback) const override {
base::SequencedTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback), base::Version()));
}
void RegisterApp(
const RegistrationRequest& request,
base::OnceCallback<void(const RegistrationResponse&)> callback) override {
base::SequencedTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(std::move(callback), RegistrationResponse(-1)));
}
void UpdateAll(StateChangeCallback state_update, Callback callback) override {
base::SequencedTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(std::move(callback), UpdateService::Result::kInactive));
}
void Update(const std::string& app_id,
Priority priority,
StateChangeCallback state_update,
Callback callback) override {
base::SequencedTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(std::move(callback), UpdateService::Result::kInactive));
}
void Uninitialize() override {}
private:
~UpdateServiceImplInactive() override = default;
};
} // namespace
scoped_refptr<UpdateService> MakeInactiveUpdateService() {
return base::MakeRefCounted<UpdateServiceImplInactive>();
}
} // namespace updater
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_UPDATER_UPDATE_SERVICE_IMPL_INACTIVE_H_
#define CHROME_UPDATER_UPDATE_SERVICE_IMPL_INACTIVE_H_
#include "base/memory/scoped_refptr.h"
namespace updater {
class UpdateService;
scoped_refptr<UpdateService> MakeInactiveUpdateService();
} // namespace updater
#endif // CHROME_UPDATER_UPDATE_SERVICE_IMPL_INACTIVE_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment