| // Copyright 2020 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <cstdlib> |
| #include <memory> |
| #include <string> |
| |
| #include "base/bind.h" |
| #include "base/command_line.h" |
| #include "base/files/file_path.h" |
| #include "base/logging.h" |
| #include "base/memory/scoped_refptr.h" |
| #include "base/numerics/checked_math.h" |
| #include "base/process/launch.h" |
| #include "base/process/process.h" |
| #include "base/strings/strcat.h" |
| #include "base/strings/stringprintf.h" |
| #include "base/test/scoped_run_loop_timeout.h" |
| #include "base/test/task_environment.h" |
| #include "base/test/test_timeouts.h" |
| #include "base/time/time.h" |
| #include "base/values.h" |
| #include "base/version.h" |
| #include "build/branding_buildflags.h" |
| #include "build/build_config.h" |
| #include "build/buildflag.h" |
| #include "chrome/updater/constants.h" |
| #include "chrome/updater/persisted_data.h" |
| #include "chrome/updater/prefs.h" |
| #include "chrome/updater/registration_data.h" |
| #include "chrome/updater/test/integration_test_commands.h" |
| #include "chrome/updater/test/integration_tests_impl.h" |
| #include "chrome/updater/test/server.h" |
| #include "chrome/updater/test_scope.h" |
| #include "chrome/updater/unittest_util.h" |
| #include "chrome/updater/update_service.h" |
| #include "chrome/updater/updater_scope.h" |
| #include "chrome/updater/updater_version.h" |
| #include "chrome/updater/util.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "url/gurl.h" |
| |
| #if BUILDFLAG(IS_WIN) |
| #include <shlobj.h> |
| |
| #include "base/strings/utf_string_conversions.h" |
| #include "base/win/registry.h" |
| #include "chrome/updater/app/server/win/updater_legacy_idl.h" |
| #include "chrome/updater/win/win_constants.h" |
| #include "chrome/updater/win/win_util.h" |
| #endif // BUILDFLAG(IS_WIN) |
| |
| // TODO(noahrose): Enable tests once updater is implemented for Linux |
| #if !BUILDFLAG(IS_LINUX) |
| |
| namespace updater::test { |
| namespace { |
| |
| #if BUILDFLAG(IS_WIN) || !defined(COMPONENT_BUILD) |
| |
| void ExpectNoUpdateSequence(ScopedServer* test_server, |
| const std::string& app_id) { |
| test_server->ExpectOnce( |
| {base::BindRepeating( |
| RequestMatcherRegex, |
| base::StringPrintf(R"(.*"appid":"%s".*)", app_id.c_str()))}, |
| base::StringPrintf(")]}'\n" |
| R"({"response":{)" |
| R"( "protocol":"3.1",)" |
| R"( "app":[)" |
| R"( {)" |
| R"( "appid":"%s",)" |
| R"( "status":"ok",)" |
| R"( "updatecheck":{)" |
| R"( "status":"noupdate")" |
| R"( })" |
| R"( })" |
| R"( ])" |
| R"(}})", |
| app_id.c_str())); |
| } |
| |
| #endif // BUILDFLAG(IS_WIN) || !defined(COMPONENT_BUILD) |
| |
| } // namespace |
| |
| class IntegrationTest : public ::testing::Test { |
| public: |
| IntegrationTest() : test_commands_(CreateIntegrationTestCommands()) {} |
| ~IntegrationTest() override = default; |
| |
| protected: |
| void SetUp() override { |
| logging::SetLogItems(true, // enable_process_id |
| true, // enable_thread_id |
| true, // enable_timestamp |
| false); // enable_tickcount |
| #if BUILDFLAG(IS_WIN) |
| ASSERT_TRUE(base::PathExists(updater_path_)) << updater_path_; |
| #endif |
| Clean(); |
| ExpectClean(); |
| // TODO(crbug.com/1233612) - reenable the code when system tests pass. |
| // SetUpTestService(); |
| EnterTestMode(GURL("http://localhost:1234")); |
| } |
| |
| void TearDown() override { |
| ExitTestMode(); |
| ExpectClean(); |
| PrintLog(); |
| // TODO(crbug.com/1159189): Use a specific test output directory |
| // because Uninstall() deletes the files under GetDataDirPath(). |
| CopyLog(); |
| // TODO(crbug.com/1233612) - reenable the code when system tests pass. |
| // TearDownTestService(); |
| Clean(); |
| #if BUILDFLAG(IS_WIN) |
| ASSERT_TRUE(base::PathExists(updater_path_)) << updater_path_; |
| #endif |
| } |
| |
| void CopyLog() { test_commands_->CopyLog(); } |
| |
| void PrintLog() { test_commands_->PrintLog(); } |
| |
| void Install() { test_commands_->Install(); } |
| |
| void ExpectInstalled() { test_commands_->ExpectInstalled(); } |
| |
| void Uninstall() { |
| PrintLog(); |
| CopyLog(); |
| test_commands_->Uninstall(); |
| EXPECT_TRUE(WaitForUpdaterExit()); |
| } |
| |
| void ExpectCandidateUninstalled() { |
| test_commands_->ExpectCandidateUninstalled(); |
| } |
| |
| void Clean() { test_commands_->Clean(); } |
| |
| void ExpectClean() { test_commands_->ExpectClean(); } |
| |
| void EnterTestMode(const GURL& url) { test_commands_->EnterTestMode(url); } |
| |
| void ExitTestMode() { test_commands_->ExitTestMode(); } |
| |
| void SetGroupPolicies(const base::Value::Dict& values) { |
| test_commands_->SetGroupPolicies(values); |
| } |
| |
| void ExpectVersionActive(const std::string& version) { |
| test_commands_->ExpectVersionActive(version); |
| } |
| |
| void ExpectVersionNotActive(const std::string& version) { |
| test_commands_->ExpectVersionNotActive(version); |
| } |
| |
| void ExpectActiveUpdater() { test_commands_->ExpectActiveUpdater(); } |
| |
| #if BUILDFLAG(IS_WIN) |
| void ExpectInterfacesRegistered() { |
| test_commands_->ExpectInterfacesRegistered(); |
| } |
| |
| void ExpectMarshalInterfaceSucceeds() { |
| test_commands_->ExpectMarshalInterfaceSucceeds(); |
| } |
| |
| void ExpectLegacyUpdate3WebSucceeds(const std::string& app_id, |
| int expected_final_state, |
| int expected_error_code) { |
| test_commands_->ExpectLegacyUpdate3WebSucceeds(app_id, expected_final_state, |
| expected_error_code); |
| } |
| |
| void ExpectLegacyProcessLauncherSucceeds() { |
| test_commands_->ExpectLegacyProcessLauncherSucceeds(); |
| } |
| |
| void ExpectLegacyAppCommandWebSucceeds(const std::string& app_id, |
| const std::string& command_id, |
| const base::Value::List& parameters, |
| int expected_exit_code) { |
| test_commands_->ExpectLegacyAppCommandWebSucceeds( |
| app_id, command_id, parameters, expected_exit_code); |
| } |
| |
| void ExpectLegacyPolicyStatusSucceeds() { |
| test_commands_->ExpectLegacyPolicyStatusSucceeds(); |
| } |
| |
| void RunUninstallCmdLine() { test_commands_->RunUninstallCmdLine(); } |
| #endif // BUILDFLAG(IS_WIN) |
| |
| void SetupFakeUpdaterHigherVersion() { |
| test_commands_->SetupFakeUpdaterHigherVersion(); |
| } |
| |
| void SetupFakeUpdaterLowerVersion() { |
| test_commands_->SetupFakeUpdaterLowerVersion(); |
| } |
| |
| void SetupRealUpdaterLowerVersion() { |
| test_commands_->SetupRealUpdaterLowerVersion(); |
| } |
| |
| void SetActive(const std::string& app_id) { |
| test_commands_->SetActive(app_id); |
| } |
| |
| void ExpectActive(const std::string& app_id) { |
| test_commands_->ExpectActive(app_id); |
| } |
| |
| void ExpectNotActive(const std::string& app_id) { |
| test_commands_->ExpectNotActive(app_id); |
| } |
| |
| void SetExistenceCheckerPath(const std::string& app_id, |
| const base::FilePath& path) { |
| test_commands_->SetExistenceCheckerPath(app_id, path); |
| } |
| |
| void SetServerStarts(int value) { test_commands_->SetServerStarts(value); } |
| |
| void ExpectRegistered(const std::string& app_id) { |
| test_commands_->ExpectRegistered(app_id); |
| } |
| |
| void ExpectNotRegistered(const std::string& app_id) { |
| test_commands_->ExpectNotRegistered(app_id); |
| } |
| |
| void ExpectAppVersion(const std::string& app_id, |
| const base::Version& version) { |
| test_commands_->ExpectAppVersion(app_id, version); |
| } |
| |
| void InstallApp(const std::string& app_id) { |
| test_commands_->InstallApp(app_id); |
| } |
| |
| void UninstallApp(const std::string& app_id) { |
| test_commands_->UninstallApp(app_id); |
| } |
| |
| void RunWake(int exit_code) { test_commands_->RunWake(exit_code); } |
| |
| void RunWakeActive(int exit_code) { |
| test_commands_->RunWakeActive(exit_code); |
| } |
| |
| void Update(const std::string& app_id, |
| const std::string& install_data_index) { |
| test_commands_->Update(app_id, install_data_index); |
| } |
| |
| void UpdateAll() { test_commands_->UpdateAll(); } |
| |
| void DeleteUpdaterDirectory() { test_commands_->DeleteUpdaterDirectory(); } |
| |
| base::FilePath GetDifferentUserPath() { |
| return test_commands_->GetDifferentUserPath(); |
| } |
| |
| [[nodiscard]] bool WaitForUpdaterExit() { |
| return test_commands_->WaitForUpdaterExit(); |
| } |
| |
| void SetUpTestService() { |
| #if BUILDFLAG(IS_WIN) |
| test_commands_->SetUpTestService(); |
| #endif // BUILDFLAG(IS_WIN) |
| } |
| |
| void TearDownTestService() { |
| #if BUILDFLAG(IS_WIN) |
| test_commands_->TearDownTestService(); |
| #endif // BUILDFLAG(IS_WIN) |
| } |
| |
| void ExpectUpdateSequence(ScopedServer* test_server, |
| const std::string& app_id, |
| const std::string& install_data_index, |
| const base::Version& from_version, |
| const base::Version& to_version) { |
| test_commands_->ExpectUpdateSequence( |
| test_server, app_id, install_data_index, from_version, to_version); |
| } |
| |
| void ExpectSelfUpdateSequence(ScopedServer* test_server) { |
| test_commands_->ExpectSelfUpdateSequence(test_server); |
| } |
| |
| void ExpectInstallEvent(ScopedServer* test_server, |
| const std::string& app_id) { |
| test_server->ExpectOnce( |
| {base::BindRepeating( |
| RequestMatcherRegex, |
| base::StrCat({R"(.*"appid":")", app_id, R"(","enabled":true,")", |
| R"(event":\[{"eventresult":1,"eventtype":2,.*)"}))}, |
| ""); |
| } |
| |
| void StressUpdateService() { test_commands_->StressUpdateService(); } |
| |
| void CallServiceUpdate( |
| const std::string& app_id, |
| const std::string& install_data_index, |
| UpdateService::PolicySameVersionUpdate policy_same_version_update) { |
| test_commands_->CallServiceUpdate(app_id, install_data_index, |
| policy_same_version_update); |
| } |
| |
| void SetupFakeLegacyUpdaterData() { |
| test_commands_->SetupFakeLegacyUpdaterData(); |
| } |
| |
| void ExpectLegacyUpdaterDataMigrated() { |
| test_commands_->ExpectLegacyUpdaterDataMigrated(); |
| } |
| |
| void RunRecoveryComponent(const std::string& app_id, |
| const base::Version& version) { |
| test_commands_->RunRecoveryComponent(app_id, version); |
| } |
| |
| void ExpectLastChecked() { test_commands_->ExpectLastChecked(); } |
| |
| void ExpectLastStarted() { test_commands_->ExpectLastStarted(); } |
| |
| void RunOfflineInstall(bool is_legacy_install, bool is_silent_install) { |
| test_commands_->RunOfflineInstall(is_legacy_install, is_silent_install); |
| } |
| |
| scoped_refptr<IntegrationTestCommands> test_commands_; |
| |
| private: |
| base::test::TaskEnvironment environment_; |
| const base::FilePath updater_path_ = GetUpdaterTestPath(); |
| }; |
| |
| // The project's position is that component builds are not portable outside of |
| // the build directory. Therefore, installation of component builds is not |
| // expected to work and these tests do not run on component builders. |
| // See crbug.com/1112527. |
| #if BUILDFLAG(IS_WIN) || !defined(COMPONENT_BUILD) |
| |
| // Tests the setup and teardown of the fixture. |
| TEST_F(IntegrationTest, DoNothing) {} |
| |
| TEST_F(IntegrationTest, InstallUninstall) { |
| Install(); |
| EXPECT_TRUE(WaitForUpdaterExit()); |
| ExpectInstalled(); |
| ExpectVersionActive(kUpdaterVersion); |
| ExpectActiveUpdater(); |
| #if BUILDFLAG(IS_WIN) |
| // Tests the COM registration after the install. For now, tests that the |
| // COM interfaces are registered, which is indirectly testing the type |
| // library separation for the public, private, and legacy interfaces. |
| ExpectInterfacesRegistered(); |
| #endif // BUILDFLAG(IS_WIN) |
| Uninstall(); |
| } |
| |
| // TODO(crbug.com/1345407): this test is disabled temporarily. Reenable after |
| // the build that adds `IUpdater::FetchPolicies` is published to CIPD. |
| TEST_F(IntegrationTest, DISABLED_OverinstallWorking) { |
| SetupRealUpdaterLowerVersion(); |
| EXPECT_TRUE(WaitForUpdaterExit()); |
| ExpectVersionNotActive(kUpdaterVersion); |
| |
| // A new version hands off installation to the old version, and doesn't |
| // change the active version of the updater. |
| Install(); |
| EXPECT_TRUE(WaitForUpdaterExit()); |
| ExpectVersionNotActive(kUpdaterVersion); |
| |
| Uninstall(); |
| } |
| |
| // TODO(crbug.com/1359334): Flaky on Win10. |
| #if BUILDFLAG(IS_WIN) |
| #define MAYBE_OverinstallBroken DISABLED_OverinstallBroken |
| #else |
| #define MAYBE_OverinstallBroken OverinstallBroken |
| #endif |
| TEST_F(IntegrationTest, MAYBE_OverinstallBroken) { |
| SetupRealUpdaterLowerVersion(); |
| EXPECT_TRUE(WaitForUpdaterExit()); |
| DeleteUpdaterDirectory(); |
| |
| // Since the old version is not working, the new version should install and |
| // become active. |
| Install(); |
| EXPECT_TRUE(WaitForUpdaterExit()); |
| ExpectVersionActive(kUpdaterVersion); |
| |
| Uninstall(); |
| } |
| |
| TEST_F(IntegrationTest, SelfUninstallOutdatedUpdater) { |
| Install(); |
| ExpectInstalled(); |
| EXPECT_TRUE(WaitForUpdaterExit()); |
| SetupFakeUpdaterHigherVersion(); |
| ExpectVersionNotActive(kUpdaterVersion); |
| |
| RunWake(0); |
| EXPECT_TRUE(WaitForUpdaterExit()); |
| |
| ExpectCandidateUninstalled(); |
| // The candidate uninstall should not have altered global prefs. |
| ExpectVersionNotActive(kUpdaterVersion); |
| ExpectVersionNotActive("0.0.0.0"); |
| |
| Uninstall(); |
| Clean(); |
| } |
| |
| TEST_F(IntegrationTest, QualifyUpdater) { |
| ScopedServer test_server(test_commands_); |
| Install(); |
| ExpectInstalled(); |
| EXPECT_TRUE(WaitForUpdaterExit()); |
| SetupFakeUpdaterLowerVersion(); |
| ExpectVersionNotActive(kUpdaterVersion); |
| |
| ExpectUpdateSequence(&test_server, kQualificationAppId, "", |
| base::Version("0.1"), base::Version("0.2")); |
| |
| RunWake(0); |
| EXPECT_TRUE(WaitForUpdaterExit()); |
| |
| // This instance is now qualified and should activate itself and check itself |
| // for updates on the next check. |
| test_server.ExpectOnce( |
| {base::BindRepeating(RequestMatcherRegex, |
| base::StringPrintf(".*%s.*", kUpdaterAppId))}, |
| ")]}'\n"); |
| RunWake(0); |
| EXPECT_TRUE(WaitForUpdaterExit()); |
| ExpectVersionActive(kUpdaterVersion); |
| |
| Uninstall(); |
| Clean(); |
| } |
| |
| TEST_F(IntegrationTest, SelfUpdate) { |
| ScopedServer test_server(test_commands_); |
| Install(); |
| |
| base::Version next_version(base::StringPrintf("%s1", kUpdaterVersion)); |
| ExpectUpdateSequence(&test_server, kUpdaterAppId, "", |
| base::Version(kUpdaterVersion), next_version); |
| |
| RunWake(0); |
| EXPECT_TRUE(WaitForUpdaterExit()); |
| ExpectAppVersion(kUpdaterAppId, next_version); |
| |
| Uninstall(); |
| Clean(); |
| } |
| |
| TEST_F(IntegrationTest, ReportsActive) { |
| // A longer than usual timeout is needed for this test because the macOS |
| // UpdateServiceInternal server takes at least 10 seconds to shut down after |
| // Install, and InstallApp cannot make progress until it shut downs and |
| // releases the global prefs lock. |
| EXPECT_GE(TestTimeouts::action_timeout(), base::Seconds(18)); |
| base::test::ScopedRunLoopTimeout timeout(FROM_HERE, |
| TestTimeouts::action_timeout()); |
| |
| ScopedServer test_server(test_commands_); |
| Install(); |
| ExpectInstalled(); |
| |
| // Register apps test1 and test2. Expect pings for each. |
| InstallApp("test1"); |
| InstallApp("test2"); |
| |
| // Set test1 to be active and do a background updatecheck. |
| SetActive("test1"); |
| ExpectActive("test1"); |
| ExpectNotActive("test2"); |
| test_server.ExpectOnce( |
| {base::BindRepeating( |
| RequestMatcherRegex, |
| R"(.*"appid":"test1","enabled":true,"ping":{"a":-2,.*)")}, |
| R"()]}')" |
| "\n" |
| R"({"response":{"protocol":"3.1","daystart":{"elapsed_)" |
| R"(days":5098}},"app":[{"appid":"test1","status":"ok",)" |
| R"("updatecheck":{"status":"noupdate"}},{"appid":"test2",)" |
| R"("status":"ok","updatecheck":{"status":"noupdate"}}]})"); |
| RunWake(0); |
| |
| // The updater has cleared the active bits. |
| ExpectNotActive("test1"); |
| ExpectNotActive("test2"); |
| |
| Uninstall(); |
| } |
| |
| TEST_F(IntegrationTest, UpdateApp) { |
| ScopedServer test_server(test_commands_); |
| Install(); |
| |
| const std::string kAppId("test"); |
| InstallApp(kAppId); |
| base::Version v1("1"); |
| ExpectUpdateSequence(&test_server, kAppId, "", base::Version("0.1"), v1); |
| RunWake(0); |
| |
| base::Version v2("2"); |
| const std::string kInstallDataIndex("test_install_data_index"); |
| ExpectUpdateSequence(&test_server, kAppId, kInstallDataIndex, v1, v2); |
| Update(kAppId, kInstallDataIndex); |
| EXPECT_TRUE(WaitForUpdaterExit()); |
| ExpectAppVersion(kAppId, v2); |
| ExpectLastChecked(); |
| ExpectLastStarted(); |
| |
| Uninstall(); |
| Clean(); |
| } |
| |
| #if BUILDFLAG(IS_WIN) |
| TEST_F(IntegrationTest, ForceInstallApp) { |
| ScopedServer test_server(test_commands_); |
| Install(); |
| |
| base::Value::Dict group_policies; |
| group_policies.Set("Installtest1", GetTestScope() == UpdaterScope::kSystem |
| ? kPolicyForceInstallMachine |
| : kPolicyForceInstallUser); |
| SetGroupPolicies(group_policies); |
| |
| const std::string kAppId("test1"); |
| base::Version v0point1("0.1"); |
| base::Version v1("1"); |
| ExpectUpdateSequence(&test_server, kAppId, "", base::Version("0.0.0.0"), |
| v0point1); |
| ExpectUpdateSequence(&test_server, kAppId, "", v0point1, v1); |
| RunWake(0); |
| |
| EXPECT_TRUE(WaitForUpdaterExit()); |
| ExpectAppVersion(kAppId, v1); |
| |
| Uninstall(); |
| Clean(); |
| } |
| #endif // BUILDFLAG(IS_WIN) |
| |
| TEST_F(IntegrationTest, MultipleWakesOneNetRequest) { |
| ScopedServer test_server(test_commands_); |
| Install(); |
| |
| // Only one sequence visible to the server despite multiple wakes. |
| ExpectNoUpdateSequence(&test_server, kUpdaterAppId); |
| RunWake(0); |
| RunWake(0); |
| |
| Uninstall(); |
| Clean(); |
| } |
| |
| TEST_F(IntegrationTest, MultipleUpdateAllsMultipleNetRequests) { |
| ScopedServer test_server(test_commands_); |
| Install(); |
| |
| ExpectNoUpdateSequence(&test_server, kUpdaterAppId); |
| UpdateAll(); |
| ExpectNoUpdateSequence(&test_server, kUpdaterAppId); |
| UpdateAll(); |
| |
| Uninstall(); |
| Clean(); |
| } |
| |
| #if BUILDFLAG(IS_WIN) |
| TEST_F(IntegrationTest, MarshalInterface) { |
| Install(); |
| ExpectMarshalInterfaceSucceeds(); |
| Uninstall(); |
| } |
| |
| TEST_F(IntegrationTest, LegacyUpdate3Web) { |
| ScopedServer test_server(test_commands_); |
| Install(); |
| |
| const char kAppId[] = "test1"; |
| InstallApp(kAppId); |
| |
| ExpectNoUpdateSequence(&test_server, kAppId); |
| ExpectLegacyUpdate3WebSucceeds(kAppId, STATE_NO_UPDATE, S_OK); |
| |
| base::Value::Dict group_policies; |
| group_policies.Set("Updatetest1", kPolicyAutomaticUpdatesOnly); |
| SetGroupPolicies(group_policies); |
| ExpectLegacyUpdate3WebSucceeds( |
| kAppId, STATE_ERROR, GOOPDATE_E_APP_UPDATE_DISABLED_BY_POLICY_MANUAL); |
| |
| group_policies.Set("Updatetest1", kPolicyDisabled); |
| SetGroupPolicies(group_policies); |
| ExpectLegacyUpdate3WebSucceeds(kAppId, STATE_ERROR, |
| GOOPDATE_E_APP_UPDATE_DISABLED_BY_POLICY); |
| |
| group_policies.clear(); |
| SetGroupPolicies(group_policies); |
| ExpectUpdateSequence(&test_server, kAppId, "", base::Version("0.1"), |
| base::Version("0.2")); |
| ExpectLegacyUpdate3WebSucceeds(kAppId, STATE_INSTALL_COMPLETE, S_OK); |
| |
| Uninstall(); |
| } |
| |
| TEST_F(IntegrationTest, LegacyProcessLauncher) { |
| Install(); |
| ExpectLegacyProcessLauncherSucceeds(); |
| Uninstall(); |
| } |
| |
| TEST_F(IntegrationTest, LegacyAppCommandWeb) { |
| Install(); |
| |
| const char kAppId[] = "test1"; |
| InstallApp(kAppId); |
| |
| base::Value::List parameters; |
| parameters.Append("5432"); |
| ExpectLegacyAppCommandWebSucceeds(kAppId, "command1", parameters, 5432); |
| |
| Uninstall(); |
| } |
| |
| TEST_F(IntegrationTest, LegacyPolicyStatus) { |
| ScopedServer test_server(test_commands_); |
| Install(); |
| |
| const std::string kAppId("test"); |
| InstallApp(kAppId); |
| base::Version v1("1"); |
| ExpectUpdateSequence(&test_server, kAppId, "", base::Version("0.1"), v1); |
| RunWake(0); |
| ExpectAppVersion(kAppId, v1); |
| |
| ExpectLegacyPolicyStatusSucceeds(); |
| |
| Uninstall(); |
| } |
| |
| TEST_F(IntegrationTest, UninstallCmdLine) { |
| Install(); |
| ExpectInstalled(); |
| ExpectVersionActive(kUpdaterVersion); |
| ExpectActiveUpdater(); |
| |
| // Running the uninstall command does not uninstall this instance of the |
| // updater right after installing it (not enough server starts). |
| RunUninstallCmdLine(); |
| EXPECT_TRUE(WaitForUpdaterExit()); |
| ExpectInstalled(); |
| |
| SetServerStarts(24); |
| |
| // Uninstall the idle updater. |
| RunUninstallCmdLine(); |
| EXPECT_TRUE(WaitForUpdaterExit()); |
| } |
| #endif // BUILDFLAG(IS_WIN) |
| |
| TEST_F(IntegrationTest, UnregisterUninstalledApp) { |
| Install(); |
| ExpectInstalled(); |
| InstallApp("test1"); |
| InstallApp("test2"); |
| |
| EXPECT_TRUE(WaitForUpdaterExit()); |
| ExpectVersionActive(kUpdaterVersion); |
| ExpectActiveUpdater(); |
| UninstallApp("test1"); |
| |
| RunWake(0); |
| |
| EXPECT_TRUE(WaitForUpdaterExit()); |
| ExpectInstalled(); |
| ExpectNotRegistered("test1"); |
| ExpectRegistered("test2"); |
| |
| Uninstall(); |
| } |
| |
| TEST_F(IntegrationTest, UninstallIfMaxServerWakesBeforeRegistrationExceeded) { |
| Install(); |
| EXPECT_TRUE(WaitForUpdaterExit()); |
| ExpectInstalled(); |
| SetServerStarts(24); |
| RunWake(0); |
| EXPECT_TRUE(WaitForUpdaterExit()); |
| } |
| |
| TEST_F(IntegrationTest, UninstallUpdaterWhenAllAppsUninstalled) { |
| Install(); |
| InstallApp("test1"); |
| ExpectInstalled(); |
| EXPECT_TRUE(WaitForUpdaterExit()); |
| // TODO(crbug.com/1287235): The test is flaky without the following line. |
| SetServerStarts(24); |
| RunWake(0); |
| EXPECT_TRUE(WaitForUpdaterExit()); |
| ExpectInstalled(); |
| ExpectVersionActive(kUpdaterVersion); |
| ExpectActiveUpdater(); |
| UninstallApp("test1"); |
| RunWake(0); |
| EXPECT_TRUE(WaitForUpdaterExit()); |
| } |
| |
| // Windows does not currently have a concept of app ownership, so this |
| // test need not run on Windows. |
| #if BUILDFLAG(IS_MAC) |
| TEST_F(IntegrationTest, UnregisterUnownedApp) { |
| Install(); |
| ExpectInstalled(); |
| ExpectVersionActive(kUpdaterVersion); |
| ExpectActiveUpdater(); |
| |
| InstallApp("test1"); |
| InstallApp("test2"); |
| EXPECT_TRUE(WaitForUpdaterExit()); |
| |
| SetExistenceCheckerPath("test1", GetDifferentUserPath()); |
| |
| RunWake(0); |
| EXPECT_TRUE(WaitForUpdaterExit()); |
| |
| ExpectNotRegistered("test1"); |
| ExpectRegistered("test2"); |
| |
| Uninstall(); |
| } |
| #endif // BUILDFLAG(IS_MAC) |
| |
| #if BUILDFLAG(CHROMIUM_BRANDING) || BUILDFLAG(GOOGLE_CHROME_BRANDING) |
| #if !defined(COMPONENT_BUILD) |
| TEST_F(IntegrationTest, SelfUpdateFromOldReal) { |
| ScopedServer test_server(test_commands_); |
| |
| SetupRealUpdaterLowerVersion(); |
| ExpectVersionNotActive(kUpdaterVersion); |
| |
| // Trigger an old instance update check. |
| ExpectSelfUpdateSequence(&test_server); |
| RunWakeActive(0); |
| |
| // Qualify the new instance. |
| ExpectUpdateSequence(&test_server, kQualificationAppId, "", |
| base::Version("0.1"), base::Version("0.2")); |
| RunWake(0); |
| EXPECT_TRUE(WaitForUpdaterExit()); |
| |
| // Activate the new instance. (It should not check itself for updates.) |
| RunWake(0); |
| EXPECT_TRUE(WaitForUpdaterExit()); |
| |
| ExpectVersionActive(kUpdaterVersion); |
| Uninstall(); |
| } |
| |
| // Tests that installing and uninstalling an old version of the updater from |
| // CIPD is possible. |
| TEST_F(IntegrationTest, InstallUninstallLowerVersion) { |
| SetupRealUpdaterLowerVersion(); |
| ExpectVersionNotActive(kUpdaterVersion); |
| Uninstall(); |
| |
| #if BUILDFLAG(IS_WIN) |
| // This deletes a tree of empty subdirectories corresponding to the crash |
| // handler of the lower version updater installed above. `Uninstall` runs |
| // `updater --uninstall` from the out directory of the build, which attempts |
| // to launch the `uninstall.cmd` script corresponding to this version of the |
| // updater from the install directory. However, there is no such script |
| // because this version was never installed, and the script is not found |
| // there. |
| DeleteUpdaterDirectory(); |
| #endif // IS_WIN |
| } |
| |
| #endif |
| #endif |
| |
| TEST_F(IntegrationTest, UpdateServiceStress) { |
| Install(); |
| ExpectInstalled(); |
| StressUpdateService(); |
| Uninstall(); |
| } |
| |
| TEST_F(IntegrationTest, SameVersionUpdate) { |
| ScopedServer test_server(test_commands_); |
| Install(); |
| ExpectInstalled(); |
| |
| const std::string app_id = "test-appid"; |
| InstallApp(app_id); |
| |
| const std::string response = base::StringPrintf( |
| ")]}'\n" |
| R"({"response":{)" |
| R"( "protocol":"3.1",)" |
| R"( "app":[)" |
| R"( {)" |
| R"( "appid":"%s",)" |
| R"( "status":"ok",)" |
| R"( "updatecheck":{)" |
| R"( "status":"noupdate")" |
| R"( })" |
| R"( })" |
| R"( ])" |
| R"(}})", |
| app_id.c_str()); |
| test_server.ExpectOnce( |
| {base::BindRepeating( |
| RequestMatcherRegex, |
| R"(.*"updatecheck":{"sameversionupdate":true},"version":"0.1"}.*)")}, |
| response); |
| CallServiceUpdate(app_id, "", |
| UpdateService::PolicySameVersionUpdate::kAllowed); |
| |
| test_server.ExpectOnce( |
| {base::BindRepeating(RequestMatcherRegex, |
| R"(.*"updatecheck":{},"version":"0.1"}.*)")}, |
| response); |
| CallServiceUpdate(app_id, "", |
| UpdateService::PolicySameVersionUpdate::kNotAllowed); |
| Uninstall(); |
| } |
| |
| TEST_F(IntegrationTest, InstallDataIndex) { |
| ScopedServer test_server(test_commands_); |
| Install(); |
| ExpectInstalled(); |
| |
| const std::string app_id = "test-appid"; |
| const std::string install_data_index = "test-install-data-index"; |
| |
| InstallApp(app_id); |
| |
| const std::string response = base::StringPrintf( |
| ")]}'\n" |
| R"({"response":{)" |
| R"( "protocol":"3.1",)" |
| R"( "app":[)" |
| R"( {)" |
| R"( "appid":"%s",)" |
| R"( "status":"ok",)" |
| R"( "updatecheck":{)" |
| R"( "status":"noupdate")" |
| R"( })" |
| R"( })" |
| R"( ])" |
| R"(}})", |
| app_id.c_str()); |
| |
| test_server.ExpectOnce( |
| {base::BindRepeating( |
| RequestMatcherRegex, |
| base::StringPrintf( |
| R"(.*"data":\[{"index":"%s","name":"install"}],.*)", |
| install_data_index.c_str()))}, |
| response); |
| |
| CallServiceUpdate(app_id, install_data_index, |
| UpdateService::PolicySameVersionUpdate::kAllowed); |
| |
| Uninstall(); |
| } |
| |
| TEST_F(IntegrationTest, MigrateLegacyUpdater) { |
| SetupFakeLegacyUpdaterData(); |
| Install(); |
| ExpectInstalled(); |
| ExpectLegacyUpdaterDataMigrated(); |
| Uninstall(); |
| } |
| |
| TEST_F(IntegrationTest, RecoveryNoUpdater) { |
| const std::string appid = "test1"; |
| const base::Version version("0.1"); |
| RunRecoveryComponent(appid, version); |
| EXPECT_TRUE(WaitForUpdaterExit()); |
| ExpectInstalled(); |
| ExpectActiveUpdater(); |
| ExpectAppVersion(appid, version); |
| Uninstall(); |
| } |
| |
| TEST_F(IntegrationTest, OfflineInstall) { |
| Install(); |
| ExpectInstalled(); |
| RunOfflineInstall(/*is_legacy_install=*/false, /*is_silent_install=*/false); |
| Uninstall(); |
| } |
| |
| TEST_F(IntegrationTest, SilentOfflineInstall) { |
| Install(); |
| ExpectInstalled(); |
| RunOfflineInstall(/*is_legacy_install=*/false, /*is_silent_install=*/true); |
| Uninstall(); |
| } |
| |
| TEST_F(IntegrationTest, LegacySilentOfflineInstall) { |
| Install(); |
| ExpectInstalled(); |
| RunOfflineInstall(/*is_legacy_install=*/true, /*is_silent_install=*/true); |
| Uninstall(); |
| } |
| |
| #endif // BUILDFLAG(IS_WIN) || !defined(COMPONENT_BUILD) |
| |
| } // namespace updater::test |
| |
| #endif // !BUILDFLAG(IS_LINUX) |