Handle app status errors such as error-unknownApplication in update_client.
This change introduces new error codes for these responses.
Bug: 850720
Change-Id: I85462e964a573bf310b7b0ae5e9180e2e87eafdc
Reviewed-on: https://chromium-review.googlesource.com/1091876
Reviewed-by: Joshua Pawlicki <[email protected]>
Commit-Queue: Sorin Jianu <[email protected]>
Cr-Commit-Position: refs/heads/master@{#565719}
diff --git a/components/update_client/update_client_unittest.cc b/components/update_client/update_client_unittest.cc
index 75abb181..4e99005 100644
--- a/components/update_client/update_client_unittest.cc
+++ b/components/update_client/update_client_unittest.cc
@@ -269,10 +269,8 @@
results.list.push_back(result);
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(std::move(update_check_callback),
- base::make_optional<ProtocolParser::Results>(results),
- ErrorCategory::kNone, 0, 0));
+ FROM_HERE, base::BindOnce(std::move(update_check_callback), results,
+ ErrorCategory::kNone, 0, 0));
}
};
@@ -436,10 +434,8 @@
}
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(std::move(update_check_callback),
- base::make_optional<ProtocolParser::Results>(results),
- ErrorCategory::kNone, 0, 0));
+ FROM_HERE, base::BindOnce(std::move(update_check_callback), results,
+ ErrorCategory::kNone, 0, 0));
}
};
@@ -641,10 +637,8 @@
}
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(std::move(update_check_callback),
- base::make_optional<ProtocolParser::Results>(results),
- ErrorCategory::kNone, 0, 0));
+ FROM_HERE, base::BindOnce(std::move(update_check_callback), results,
+ ErrorCategory::kNone, 0, 0));
}
};
@@ -855,10 +849,8 @@
}
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(std::move(update_check_callback),
- base::make_optional<ProtocolParser::Results>(results),
- ErrorCategory::kNone, 0, 0));
+ FROM_HERE, base::BindOnce(std::move(update_check_callback), results,
+ ErrorCategory::kNone, 0, 0));
}
};
@@ -1190,10 +1182,8 @@
}
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(std::move(update_check_callback),
- base::make_optional<ProtocolParser::Results>(results),
- ErrorCategory::kNone, 0, 0));
+ FROM_HERE, base::BindOnce(std::move(update_check_callback), results,
+ ErrorCategory::kNone, 0, 0));
}
};
@@ -1487,10 +1477,8 @@
}
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(std::move(update_check_callback),
- base::make_optional<ProtocolParser::Results>(results),
- ErrorCategory::kNone, 0, 0));
+ FROM_HERE, base::BindOnce(std::move(update_check_callback), results,
+ ErrorCategory::kNone, 0, 0));
}
};
@@ -1767,10 +1755,8 @@
ProtocolParser::Results results;
results.list.push_back(result);
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(std::move(update_check_callback),
- base::make_optional<ProtocolParser::Results>(results),
- ErrorCategory::kNone, 0, 0));
+ FROM_HERE, base::BindOnce(std::move(update_check_callback), results,
+ ErrorCategory::kNone, 0, 0));
}
};
@@ -2020,10 +2006,8 @@
}
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(std::move(update_check_callback),
- base::make_optional<ProtocolParser::Results>(results),
- ErrorCategory::kNone, 0, 0));
+ FROM_HERE, base::BindOnce(std::move(update_check_callback), results,
+ ErrorCategory::kNone, 0, 0));
}
};
@@ -2247,10 +2231,8 @@
results.list.push_back(result);
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(std::move(update_check_callback),
- base::make_optional<ProtocolParser::Results>(results),
- ErrorCategory::kNone, 0, 0));
+ FROM_HERE, base::BindOnce(std::move(update_check_callback), results,
+ ErrorCategory::kNone, 0, 0));
}
};
@@ -2397,10 +2379,8 @@
EXPECT_TRUE(components.at(id)->is_foreground());
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(std::move(update_check_callback),
- base::make_optional<ProtocolParser::Results>(results),
- ErrorCategory::kNone, 0, 0));
+ FROM_HERE, base::BindOnce(std::move(update_check_callback), results,
+ ErrorCategory::kNone, 0, 0));
}
};
@@ -2652,10 +2632,8 @@
EXPECT_TRUE(components.at(id)->is_foreground());
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(std::move(update_check_callback),
- base::make_optional<ProtocolParser::Results>(results),
- ErrorCategory::kNone, 0, 0));
+ FROM_HERE, base::BindOnce(std::move(update_check_callback), results,
+ ErrorCategory::kNone, 0, 0));
}
};
@@ -2937,10 +2915,8 @@
results.list.push_back(result);
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(std::move(update_check_callback),
- base::make_optional<ProtocolParser::Results>(results),
- ErrorCategory::kNone, 0, retry_after_sec));
+ FROM_HERE, base::BindOnce(std::move(update_check_callback), results,
+ ErrorCategory::kNone, 0, retry_after_sec));
}
};
@@ -3182,10 +3158,8 @@
}
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(std::move(update_check_callback),
- base::make_optional<ProtocolParser::Results>(results),
- ErrorCategory::kNone, 0, 0));
+ FROM_HERE, base::BindOnce(std::move(update_check_callback), results,
+ ErrorCategory::kNone, 0, 0));
}
};
@@ -3417,6 +3391,208 @@
update_client->RemoveObserver(&observer);
}
+// Tests the scenario where the server responds with different values for
+// application status.
+TEST_F(UpdateClientTest, OneCrxErrorUnknownApp) {
+ class DataCallbackMock {
+ public:
+ static std::vector<std::unique_ptr<CrxComponent>> Callback(
+ const std::vector<std::string>& ids) {
+ std::vector<std::unique_ptr<CrxComponent>> component;
+
+ std::unique_ptr<CrxComponent> crx = std::make_unique<CrxComponent>();
+ crx->name = "test_jebg";
+ crx->pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
+ crx->version = base::Version("0.9");
+ crx->installer = base::MakeRefCounted<TestInstaller>();
+ component.push_back(std::move(crx));
+
+ crx = std::make_unique<CrxComponent>();
+ crx->name = "test_abag";
+ crx->pk_hash.assign(abag_hash, abag_hash + base::size(abag_hash));
+ crx->version = base::Version("0.1");
+ crx->installer = base::MakeRefCounted<TestInstaller>();
+ component.push_back(std::move(crx));
+
+ crx = std::make_unique<CrxComponent>();
+ crx->name = "test_ihfo";
+ crx->pk_hash.assign(ihfo_hash, ihfo_hash + base::size(ihfo_hash));
+ crx->version = base::Version("0.2");
+ crx->installer = base::MakeRefCounted<TestInstaller>();
+ component.push_back(std::move(crx));
+
+ crx = std::make_unique<CrxComponent>();
+ crx->name = "test_gjpm";
+ crx->pk_hash.assign(gjpm_hash, gjpm_hash + base::size(gjpm_hash));
+ crx->version = base::Version("0.3");
+ crx->installer = base::MakeRefCounted<TestInstaller>();
+ component.push_back(std::move(crx));
+
+ return component;
+ }
+ };
+
+ class CompletionCallbackMock {
+ public:
+ static void Callback(base::OnceClosure quit_closure, Error error) {
+ EXPECT_EQ(Error::NONE, error);
+ std::move(quit_closure).Run();
+ }
+ };
+
+ class MockUpdateChecker : public UpdateChecker {
+ public:
+ static std::unique_ptr<UpdateChecker> Create(
+ scoped_refptr<Configurator> config,
+ PersistedData* metadata) {
+ return std::make_unique<MockUpdateChecker>();
+ }
+
+ void CheckForUpdates(const std::string& session_id,
+ const std::vector<std::string>& ids_to_check,
+ const IdToComponentPtrMap& components,
+ const std::string& additional_attributes,
+ bool enabled_component_updates,
+ UpdateCheckCallback update_check_callback) override {
+ EXPECT_FALSE(session_id.empty());
+ EXPECT_TRUE(enabled_component_updates);
+ EXPECT_EQ(4u, ids_to_check.size());
+
+ const std::string update_response =
+ R"(<?xml version="1.0" encoding="UTF-8"?>)"
+ R"(<response protocol="3.1">)"
+ R"(<app appid="jebgalgnebhfojomionfpkfelancnnkf")"
+ R"( status="error-unknownApplication"/>)"
+ R"(<app appid="abagagagagagagagagagagagagagagag")"
+ R"( status="restricted"/>)"
+ R"(<app appid="ihfokbkgjpifnbbojhneepfflplebdkc")"
+ R"( status="error-invalidAppId"/>)"
+ R"(<app appid="gjpmebpgbhcamgdgjcmnjfhggjpgcimm")"
+ R"( status="error-foobarApp"/>)"
+ R"(</response>)";
+
+ ProtocolParser parser;
+ EXPECT_TRUE(parser.Parse(update_response));
+
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce(std::move(update_check_callback), parser.results(),
+ ErrorCategory::kNone, 0, 0));
+ }
+ };
+
+ class MockCrxDownloader : public CrxDownloader {
+ public:
+ static std::unique_ptr<CrxDownloader> Create(
+ bool is_background_download,
+ scoped_refptr<net::URLRequestContextGetter> context_getter) {
+ return std::make_unique<MockCrxDownloader>();
+ }
+
+ MockCrxDownloader() : CrxDownloader(nullptr) {}
+
+ private:
+ void DoStartDownload(const GURL& url) override { EXPECT_TRUE(false); }
+ };
+
+ class MockPingManager : public MockPingManagerImpl {
+ public:
+ explicit MockPingManager(scoped_refptr<Configurator> config)
+ : MockPingManagerImpl(config) {}
+
+ protected:
+ ~MockPingManager() override { EXPECT_TRUE(ping_data().empty()); }
+ };
+
+ scoped_refptr<UpdateClient> update_client =
+ base::MakeRefCounted<UpdateClientImpl>(
+ config(), base::MakeRefCounted<MockPingManager>(config()),
+ &MockUpdateChecker::Create, &MockCrxDownloader::Create);
+
+ MockObserver observer;
+ {
+ InSequence seq;
+ EXPECT_CALL(observer, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES,
+ "jebgalgnebhfojomionfpkfelancnnkf"))
+ .Times(1);
+ EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_ERROR,
+ "jebgalgnebhfojomionfpkfelancnnkf"))
+ .Times(1)
+ .WillOnce(Invoke([&update_client](Events event, const std::string& id) {
+ CrxUpdateItem item;
+ update_client->GetCrxUpdateState(id, &item);
+ EXPECT_EQ(ComponentState::kUpdateError, item.state);
+ EXPECT_EQ(5, static_cast<int>(item.error_category));
+ EXPECT_EQ(-10006, item.error_code); // UNKNOWN_APPPLICATION.
+ EXPECT_EQ(0, item.extra_code1);
+ }));
+ }
+ {
+ InSequence seq;
+ EXPECT_CALL(observer, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES,
+ "abagagagagagagagagagagagagagagag"))
+ .Times(1);
+ EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_ERROR,
+ "abagagagagagagagagagagagagagagag"))
+ .Times(1)
+ .WillOnce(Invoke([&update_client](Events event, const std::string& id) {
+ CrxUpdateItem item;
+ update_client->GetCrxUpdateState(id, &item);
+ EXPECT_EQ(ComponentState::kUpdateError, item.state);
+ EXPECT_EQ(5, static_cast<int>(item.error_category));
+ EXPECT_EQ(-10007, item.error_code); // RESTRICTED_APPLICATION.
+ EXPECT_EQ(0, item.extra_code1);
+ }));
+ }
+ {
+ InSequence seq;
+ EXPECT_CALL(observer, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES,
+ "ihfokbkgjpifnbbojhneepfflplebdkc"))
+ .Times(1);
+ EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_ERROR,
+ "ihfokbkgjpifnbbojhneepfflplebdkc"))
+ .Times(1)
+ .WillOnce(Invoke([&update_client](Events event, const std::string& id) {
+ CrxUpdateItem item;
+ update_client->GetCrxUpdateState(id, &item);
+ EXPECT_EQ(ComponentState::kUpdateError, item.state);
+ EXPECT_EQ(5, static_cast<int>(item.error_category));
+ EXPECT_EQ(-10008, item.error_code); // INVALID_APPID.
+ EXPECT_EQ(0, item.extra_code1);
+ }));
+ }
+ {
+ InSequence seq;
+ EXPECT_CALL(observer, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES,
+ "gjpmebpgbhcamgdgjcmnjfhggjpgcimm"))
+ .Times(1);
+ EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_ERROR,
+ "gjpmebpgbhcamgdgjcmnjfhggjpgcimm"))
+ .Times(1)
+ .WillOnce(Invoke([&update_client](Events event, const std::string& id) {
+ CrxUpdateItem item;
+ update_client->GetCrxUpdateState(id, &item);
+ EXPECT_EQ(ComponentState::kUpdateError, item.state);
+ EXPECT_EQ(5, static_cast<int>(item.error_category));
+ EXPECT_EQ(-10004, item.error_code); // UPDATE_RESPONSE_NOT_FOUND.
+ EXPECT_EQ(0, item.extra_code1);
+ }));
+ }
+
+ update_client->AddObserver(&observer);
+
+ const std::vector<std::string> ids = {
+ "jebgalgnebhfojomionfpkfelancnnkf", "abagagagagagagagagagagagagagagag",
+ "ihfokbkgjpifnbbojhneepfflplebdkc", "gjpmebpgbhcamgdgjcmnjfhggjpgcimm"};
+ update_client->Update(
+ ids, base::BindOnce(&DataCallbackMock::Callback), true,
+ base::BindOnce(&CompletionCallbackMock::Callback, quit_closure()));
+
+ RunThreads();
+
+ update_client->RemoveObserver(&observer);
+}
+
#if defined(OS_WIN) // ActionRun is only implemented on Windows.
// Tests that a run action in invoked in the CRX install scenario.
@@ -3484,10 +3660,8 @@
results.list.push_back(result);
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(std::move(update_check_callback),
- base::make_optional<ProtocolParser::Results>(results),
- ErrorCategory::kNone, 0, 0));
+ FROM_HERE, base::BindOnce(std::move(update_check_callback), results,
+ ErrorCategory::kNone, 0, 0));
}
};
@@ -3633,10 +3807,8 @@
results.list.push_back(result);
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(std::move(update_check_callback),
- base::make_optional<ProtocolParser::Results>(results),
- ErrorCategory::kNone, 0, 0));
+ FROM_HERE, base::BindOnce(std::move(update_check_callback), results,
+ ErrorCategory::kNone, 0, 0));
}
};