| Index: omaha_request_action_unittest.cc
|
| diff --git a/omaha_request_action_unittest.cc b/omaha_request_action_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..778f408e268f2a7e46ca6e01e1c4539eca3f13c4
|
| --- /dev/null
|
| +++ b/omaha_request_action_unittest.cc
|
| @@ -0,0 +1,538 @@
|
| +// Copyright (c) 2009 The Chromium OS 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 <string>
|
| +#include <vector>
|
| +#include <glib.h>
|
| +#include <gtest/gtest.h>
|
| +#include "update_engine/action_pipe.h"
|
| +#include "update_engine/mock_http_fetcher.h"
|
| +#include "update_engine/omaha_hash_calculator.h"
|
| +#include "update_engine/omaha_request_action.h"
|
| +#include "update_engine/test_utils.h"
|
| +
|
| +using std::string;
|
| +using std::vector;
|
| +
|
| +namespace chromeos_update_engine {
|
| +
|
| +class OmahaRequestActionTest : public ::testing::Test { };
|
| +
|
| +namespace {
|
| +string GetNoUpdateResponse(const string& app_id) {
|
| + return string(
|
| + "<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
|
| + "xmlns=\"http://www.google.com/update2/response\" protocol=\"2.0\"><app "
|
| + "appid=\"") + app_id + "\" status=\"ok\"><ping "
|
| + "status=\"ok\"/><updatecheck status=\"noupdate\"/></app></gupdate>";
|
| +}
|
| +
|
| +string GetUpdateResponse(const string& app_id,
|
| + const string& display_version,
|
| + const string& more_info_url,
|
| + const string& prompt,
|
| + const string& codebase,
|
| + const string& hash,
|
| + const string& needsadmin,
|
| + const string& size) {
|
| + return string("<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
|
| + "xmlns=\"http://www.google.com/update2/response\" "
|
| + "protocol=\"2.0\"><app "
|
| + "appid=\"") + app_id + "\" status=\"ok\"><ping "
|
| + "status=\"ok\"/><updatecheck DisplayVersion=\"" + display_version + "\" "
|
| + "MoreInfo=\"" + more_info_url + "\" Prompt=\"" + prompt + "\" "
|
| + "codebase=\"" + codebase + "\" "
|
| + "hash=\"" + hash + "\" needsadmin=\"" + needsadmin + "\" "
|
| + "size=\"" + size + "\" status=\"ok\"/></app></gupdate>";
|
| +}
|
| +
|
| +class OmahaRequestActionTestProcessorDelegate : public ActionProcessorDelegate {
|
| + public:
|
| + OmahaRequestActionTestProcessorDelegate()
|
| + : loop_(NULL),
|
| + expected_success_(true) {}
|
| + virtual ~OmahaRequestActionTestProcessorDelegate() {
|
| + }
|
| + virtual void ProcessingDone(const ActionProcessor* processor, bool success) {
|
| + ASSERT_TRUE(loop_);
|
| + g_main_loop_quit(loop_);
|
| + }
|
| +
|
| + virtual void ActionCompleted(ActionProcessor* processor,
|
| + AbstractAction* action,
|
| + bool success) {
|
| + // make sure actions always succeed
|
| + if (action->Type() == OmahaRequestAction::StaticType())
|
| + EXPECT_EQ(expected_success_, success);
|
| + else
|
| + EXPECT_TRUE(success);
|
| + }
|
| + GMainLoop *loop_;
|
| + bool expected_success_;
|
| +};
|
| +
|
| +gboolean StartProcessorInRunLoop(gpointer data) {
|
| + ActionProcessor *processor = reinterpret_cast<ActionProcessor*>(data);
|
| + processor->StartProcessing();
|
| + return FALSE;
|
| +}
|
| +
|
| +} // namespace {}
|
| +
|
| +class OutputObjectCollectorAction;
|
| +
|
| +template<>
|
| +class ActionTraits<OutputObjectCollectorAction> {
|
| + public:
|
| + // Does not take an object for input
|
| + typedef OmahaResponse InputObjectType;
|
| + // On success, puts the output path on output
|
| + typedef NoneType OutputObjectType;
|
| +};
|
| +
|
| +class OutputObjectCollectorAction : public Action<OutputObjectCollectorAction> {
|
| + public:
|
| + OutputObjectCollectorAction() : has_input_object_(false) {}
|
| + void PerformAction() {
|
| + // copy input object
|
| + has_input_object_ = HasInputObject();
|
| + if (has_input_object_)
|
| + omaha_response_ = GetInputObject();
|
| + processor_->ActionComplete(this, true);
|
| + }
|
| + // Should never be called
|
| + void TerminateProcessing() {
|
| + CHECK(false);
|
| + }
|
| + // Debugging/logging
|
| + static std::string StaticType() {
|
| + return "OutputObjectCollectorAction";
|
| + }
|
| + std::string Type() const { return StaticType(); }
|
| + bool has_input_object_;
|
| + OmahaResponse omaha_response_;
|
| +};
|
| +
|
| +// returns true iff an output response was obtained from the
|
| +// OmahaRequestAction. out_response may be NULL.
|
| +// out_post_data may be null; if non-null, the post-data received by the
|
| +// mock HttpFetcher is returned.
|
| +bool TestOmahaRequestAction(const OmahaRequestParams& params,
|
| + const string& http_response,
|
| + bool expected_success,
|
| + OmahaResponse* out_response,
|
| + vector<char> *out_post_data) {
|
| + GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
|
| + MockHttpFetcher *fetcher = new MockHttpFetcher(http_response.data(),
|
| + http_response.size());
|
| + ObjectFeederAction<OmahaRequestParams> feeder_action;
|
| + OmahaRequestAction action(fetcher); // takes ownership of fetcher
|
| + OmahaRequestActionTestProcessorDelegate delegate;
|
| + delegate.loop_ = loop;
|
| + delegate.expected_success_ = expected_success;
|
| + ActionProcessor processor;
|
| + feeder_action.set_obj(params);
|
| + processor.set_delegate(&delegate);
|
| + processor.EnqueueAction(&feeder_action);
|
| + processor.EnqueueAction(&action);
|
| +
|
| + OutputObjectCollectorAction collector_action;
|
| +
|
| + BondActions(&feeder_action, &action);
|
| + BondActions(&action, &collector_action);
|
| + processor.EnqueueAction(&collector_action);
|
| +
|
| + g_timeout_add(0, &StartProcessorInRunLoop, &processor);
|
| + g_main_loop_run(loop);
|
| + g_main_loop_unref(loop);
|
| + if (collector_action.has_input_object_ && out_response)
|
| + *out_response = collector_action.omaha_response_;
|
| + if (out_post_data)
|
| + *out_post_data = fetcher->post_data();
|
| + return collector_action.has_input_object_;
|
| +}
|
| +
|
| +TEST(OmahaRequestActionTest, NoUpdateTest) {
|
| + OmahaRequestParams params("", // machine_id
|
| + "", // user_id
|
| + OmahaRequestParams::kOsPlatform,
|
| + OmahaRequestParams::kOsVersion,
|
| + "", // os_sp
|
| + "x86-generic",
|
| + OmahaRequestParams::kAppId,
|
| + "0.1.0.0",
|
| + "en-US",
|
| + "unittest",
|
| + ""); // url
|
| + OmahaResponse response;
|
| + ASSERT_TRUE(
|
| + TestOmahaRequestAction(params,
|
| + GetNoUpdateResponse(OmahaRequestParams::kAppId),
|
| + true,
|
| + &response,
|
| + NULL));
|
| + EXPECT_FALSE(response.update_exists);
|
| +}
|
| +
|
| +TEST(OmahaRequestActionTest, ValidUpdateTest) {
|
| + OmahaRequestParams params("machine_id",
|
| + "user_id",
|
| + OmahaRequestParams::kOsPlatform,
|
| + OmahaRequestParams::kOsVersion,
|
| + "service_pack",
|
| + "arm-generic",
|
| + OmahaRequestParams::kAppId,
|
| + "0.1.0.0",
|
| + "en-US",
|
| + "unittest_track",
|
| + ""); // url
|
| + OmahaResponse response;
|
| + ASSERT_TRUE(
|
| + TestOmahaRequestAction(params,
|
| + GetUpdateResponse(OmahaRequestParams::kAppId,
|
| + "1.2.3.4", // version
|
| + "http://more/info",
|
| + "true", // prompt
|
| + "http://code/base", // dl url
|
| + "HASH1234=", // checksum
|
| + "false", // needs admin
|
| + "123"), // size
|
| + true,
|
| + &response,
|
| + NULL));
|
| + EXPECT_TRUE(response.update_exists);
|
| + EXPECT_EQ("1.2.3.4", response.display_version);
|
| + EXPECT_EQ("http://code/base", response.codebase);
|
| + EXPECT_EQ("http://more/info", response.more_info_url);
|
| + EXPECT_EQ("HASH1234=", response.hash);
|
| + EXPECT_EQ(123, response.size);
|
| + EXPECT_FALSE(response.needs_admin);
|
| + EXPECT_TRUE(response.prompt);
|
| +}
|
| +
|
| +TEST(OmahaRequestActionTest, NoOutputPipeTest) {
|
| + OmahaRequestParams params("", // machine_id
|
| + "", // usr_id
|
| + OmahaRequestParams::kOsPlatform,
|
| + OmahaRequestParams::kOsVersion,
|
| + "", // os_sp
|
| + "", // os_board
|
| + OmahaRequestParams::kAppId,
|
| + "0.1.0.0",
|
| + "en-US",
|
| + "unittest",
|
| + ""); // url
|
| + const string http_response(GetNoUpdateResponse(OmahaRequestParams::kAppId));
|
| +
|
| + GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
|
| +
|
| + ObjectFeederAction<OmahaRequestParams> feeder_action;
|
| + feeder_action.set_obj(params);
|
| + OmahaRequestAction action(new MockHttpFetcher(http_response.data(),
|
| + http_response.size()));
|
| + OmahaRequestActionTestProcessorDelegate delegate;
|
| + delegate.loop_ = loop;
|
| + ActionProcessor processor;
|
| + processor.set_delegate(&delegate);
|
| + processor.EnqueueAction(&feeder_action);
|
| + processor.EnqueueAction(&action);
|
| + BondActions(&feeder_action, &action);
|
| +
|
| + g_timeout_add(0, &StartProcessorInRunLoop, &processor);
|
| + g_main_loop_run(loop);
|
| + g_main_loop_unref(loop);
|
| + EXPECT_FALSE(processor.IsRunning());
|
| +}
|
| +
|
| +TEST(OmahaRequestActionTest, InvalidXmlTest) {
|
| + OmahaRequestParams params("machine_id",
|
| + "user_id",
|
| + OmahaRequestParams::kOsPlatform,
|
| + OmahaRequestParams::kOsVersion,
|
| + "service_pack",
|
| + "x86-generic",
|
| + OmahaRequestParams::kAppId,
|
| + "0.1.0.0",
|
| + "en-US",
|
| + "unittest_track",
|
| + "http://url");
|
| + OmahaResponse response;
|
| + ASSERT_FALSE(
|
| + TestOmahaRequestAction(params,
|
| + "invalid xml>",
|
| + false,
|
| + &response,
|
| + NULL));
|
| + EXPECT_FALSE(response.update_exists);
|
| +}
|
| +
|
| +TEST(OmahaRequestActionTest, MissingStatusTest) {
|
| + OmahaRequestParams params("machine_id",
|
| + "user_id",
|
| + OmahaRequestParams::kOsPlatform,
|
| + OmahaRequestParams::kOsVersion,
|
| + "service_pack",
|
| + "x86-generic",
|
| + OmahaRequestParams::kAppId,
|
| + "0.1.0.0",
|
| + "en-US",
|
| + "unittest_track",
|
| + "http://url");
|
| + OmahaResponse response;
|
| + ASSERT_FALSE(TestOmahaRequestAction(
|
| + params,
|
| + "<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
|
| + "xmlns=\"http://www.google.com/update2/response\" protocol=\"2.0\"><app "
|
| + "appid=\"foo\" status=\"ok\"><ping "
|
| + "status=\"ok\"/><updatecheck/></app></gupdate>",
|
| + false,
|
| + &response,
|
| + NULL));
|
| + EXPECT_FALSE(response.update_exists);
|
| +}
|
| +
|
| +TEST(OmahaRequestActionTest, InvalidStatusTest) {
|
| + OmahaRequestParams params("machine_id",
|
| + "user_id",
|
| + OmahaRequestParams::kOsPlatform,
|
| + OmahaRequestParams::kOsVersion,
|
| + "service_pack",
|
| + "x86-generic",
|
| + OmahaRequestParams::kAppId,
|
| + "0.1.0.0",
|
| + "en-US",
|
| + "unittest_track",
|
| + "http://url");
|
| + OmahaResponse response;
|
| + ASSERT_FALSE(TestOmahaRequestAction(
|
| + params,
|
| + "<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
|
| + "xmlns=\"http://www.google.com/update2/response\" protocol=\"2.0\"><app "
|
| + "appid=\"foo\" status=\"ok\"><ping "
|
| + "status=\"ok\"/><updatecheck status=\"foo\"/></app></gupdate>",
|
| + false,
|
| + &response,
|
| + NULL));
|
| + EXPECT_FALSE(response.update_exists);
|
| +}
|
| +
|
| +TEST(OmahaRequestActionTest, MissingNodesetTest) {
|
| + OmahaRequestParams params("machine_id",
|
| + "user_id",
|
| + OmahaRequestParams::kOsPlatform,
|
| + OmahaRequestParams::kOsVersion,
|
| + "service_pack",
|
| + "x86-generic",
|
| + OmahaRequestParams::kAppId,
|
| + "0.1.0.0",
|
| + "en-US",
|
| + "unittest_track",
|
| + "http://url");
|
| + OmahaResponse response;
|
| + ASSERT_FALSE(TestOmahaRequestAction(
|
| + params,
|
| + "<?xml version=\"1.0\" encoding=\"UTF-8\"?><gupdate "
|
| + "xmlns=\"http://www.google.com/update2/response\" protocol=\"2.0\"><app "
|
| + "appid=\"foo\" status=\"ok\"><ping "
|
| + "status=\"ok\"/></app></gupdate>",
|
| + false,
|
| + &response,
|
| + NULL));
|
| + EXPECT_FALSE(response.update_exists);
|
| +}
|
| +
|
| +TEST(OmahaRequestActionTest, MissingFieldTest) {
|
| + OmahaRequestParams params("machine_id",
|
| + "user_id",
|
| + OmahaRequestParams::kOsPlatform,
|
| + OmahaRequestParams::kOsVersion,
|
| + "service_pack",
|
| + "x86-generic",
|
| + OmahaRequestParams::kAppId,
|
| + "0.1.0.0",
|
| + "en-US",
|
| + "unittest_track",
|
| + "http://url");
|
| + OmahaResponse response;
|
| + ASSERT_TRUE(TestOmahaRequestAction(params,
|
| + string("<?xml version=\"1.0\" "
|
| + "encoding=\"UTF-8\"?><gupdate "
|
| + "xmlns=\"http://www.google.com/"
|
| + "update2/response\" "
|
| + "protocol=\"2.0\"><app appid=\"") +
|
| + OmahaRequestParams::kAppId
|
| + + "\" status=\"ok\"><ping "
|
| + "status=\"ok\"/><updatecheck "
|
| + "DisplayVersion=\"1.2.3.4\" "
|
| + "Prompt=\"false\" "
|
| + "codebase=\"http://code/base\" "
|
| + "hash=\"HASH1234=\" needsadmin=\"true\" "
|
| + "size=\"123\" "
|
| + "status=\"ok\"/></app></gupdate>",
|
| + true,
|
| + &response,
|
| + NULL));
|
| + EXPECT_TRUE(response.update_exists);
|
| + EXPECT_EQ("1.2.3.4", response.display_version);
|
| + EXPECT_EQ("http://code/base", response.codebase);
|
| + EXPECT_EQ("", response.more_info_url);
|
| + EXPECT_EQ("HASH1234=", response.hash);
|
| + EXPECT_EQ(123, response.size);
|
| + EXPECT_TRUE(response.needs_admin);
|
| + EXPECT_FALSE(response.prompt);
|
| +}
|
| +
|
| +namespace {
|
| +class TerminateEarlyTestProcessorDelegate : public ActionProcessorDelegate {
|
| + public:
|
| + void ProcessingStopped(const ActionProcessor* processor) {
|
| + ASSERT_TRUE(loop_);
|
| + g_main_loop_quit(loop_);
|
| + }
|
| + GMainLoop *loop_;
|
| +};
|
| +
|
| +gboolean TerminateTransferTestStarter(gpointer data) {
|
| + ActionProcessor *processor = reinterpret_cast<ActionProcessor*>(data);
|
| + processor->StartProcessing();
|
| + CHECK(processor->IsRunning());
|
| + processor->StopProcessing();
|
| + return FALSE;
|
| +}
|
| +} // namespace {}
|
| +
|
| +TEST(OmahaRequestActionTest, TerminateTransferTest) {
|
| + OmahaRequestParams params("", // machine_id
|
| + "", // usr_id
|
| + OmahaRequestParams::kOsPlatform,
|
| + OmahaRequestParams::kOsVersion,
|
| + "", // os_sp
|
| + "", // os_board
|
| + OmahaRequestParams::kAppId,
|
| + "0.1.0.0",
|
| + "en-US",
|
| + "unittest",
|
| + "http://url");
|
| + string http_response("doesn't matter");
|
| + GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
|
| +
|
| + ObjectFeederAction<OmahaRequestParams> feeder_action;
|
| + feeder_action.set_obj(params);
|
| + OmahaRequestAction action(new MockHttpFetcher(http_response.data(),
|
| + http_response.size()));
|
| + TerminateEarlyTestProcessorDelegate delegate;
|
| + delegate.loop_ = loop;
|
| + ActionProcessor processor;
|
| + processor.set_delegate(&delegate);
|
| + processor.EnqueueAction(&feeder_action);
|
| + processor.EnqueueAction(&action);
|
| + BondActions(&feeder_action, &action);
|
| +
|
| + g_timeout_add(0, &TerminateTransferTestStarter, &processor);
|
| + g_main_loop_run(loop);
|
| + g_main_loop_unref(loop);
|
| +}
|
| +
|
| +TEST(OmahaRequestActionTest, XmlEncodeTest) {
|
| + EXPECT_EQ("ab", XmlEncode("ab"));
|
| + EXPECT_EQ("a<b", XmlEncode("a<b"));
|
| + EXPECT_EQ("foo-Ω", XmlEncode("foo-\xce\xa9"));
|
| + EXPECT_EQ("<&>", XmlEncode("<&>"));
|
| + EXPECT_EQ("&lt;&amp;&gt;", XmlEncode("<&>"));
|
| +
|
| + vector<char> post_data;
|
| +
|
| + // Make sure XML Encode is being called on the params
|
| + OmahaRequestParams params("testthemachine<id",
|
| + "testtheuser_id<",
|
| + OmahaRequestParams::kOsPlatform,
|
| + OmahaRequestParams::kOsVersion,
|
| + "testtheservice_pack>",
|
| + "x86 generic",
|
| + OmahaRequestParams::kAppId,
|
| + "0.1.0.0",
|
| + "en-US",
|
| + "unittest_track",
|
| + "http://url");
|
| + OmahaResponse response;
|
| + ASSERT_FALSE(
|
| + TestOmahaRequestAction(params,
|
| + "invalid xml>",
|
| + false,
|
| + &response,
|
| + &post_data));
|
| + // convert post_data to string
|
| + string post_str(&post_data[0], post_data.size());
|
| + EXPECT_NE(post_str.find("testthemachine<id"), string::npos);
|
| + EXPECT_EQ(post_str.find("testthemachine<id"), string::npos);
|
| + EXPECT_NE(post_str.find("testtheuser_id&lt;"), string::npos);
|
| + EXPECT_EQ(post_str.find("testtheuser_id<"), string::npos);
|
| + EXPECT_NE(post_str.find("testtheservice_pack>"), string::npos);
|
| + EXPECT_EQ(post_str.find("testtheservice_pack>"), string::npos);
|
| + EXPECT_NE(post_str.find("x86 generic"), string::npos);
|
| +}
|
| +
|
| +TEST(OmahaRequestActionTest, XmlDecodeTest) {
|
| + OmahaRequestParams params("machine_id",
|
| + "user_id",
|
| + OmahaRequestParams::kOsPlatform,
|
| + OmahaRequestParams::kOsVersion,
|
| + "service_pack",
|
| + "x86-generic",
|
| + OmahaRequestParams::kAppId,
|
| + "0.1.0.0",
|
| + "en-US",
|
| + "unittest_track",
|
| + "http://url");
|
| + OmahaResponse response;
|
| + ASSERT_TRUE(
|
| + TestOmahaRequestAction(params,
|
| + GetUpdateResponse(OmahaRequestParams::kAppId,
|
| + "1.2.3.4", // version
|
| + "testthe<url", // more info
|
| + "true", // prompt
|
| + "testthe&code", // dl url
|
| + "HASH1234=", // checksum
|
| + "false", // needs admin
|
| + "123"), // size
|
| + true,
|
| + &response,
|
| + NULL));
|
| +
|
| + EXPECT_EQ(response.more_info_url, "testthe<url");
|
| + EXPECT_EQ(response.codebase, "testthe&code");
|
| +}
|
| +
|
| +TEST(OmahaRequestActionTest, ParseIntTest) {
|
| + OmahaRequestParams params("machine_id",
|
| + "user_id",
|
| + OmahaRequestParams::kOsPlatform,
|
| + OmahaRequestParams::kOsVersion,
|
| + "service_pack",
|
| + "the_board",
|
| + OmahaRequestParams::kAppId,
|
| + "0.1.0.0",
|
| + "en-US",
|
| + "unittest_track",
|
| + "http://url");
|
| + OmahaResponse response;
|
| + ASSERT_TRUE(
|
| + TestOmahaRequestAction(params,
|
| + GetUpdateResponse(OmahaRequestParams::kAppId,
|
| + "1.2.3.4", // version
|
| + "theurl", // more info
|
| + "true", // prompt
|
| + "thecodebase", // dl url
|
| + "HASH1234=", // checksum
|
| + "false", // needs admin
|
| + // overflows int32:
|
| + "123123123123123"), // size
|
| + true,
|
| + &response,
|
| + NULL));
|
| +
|
| + EXPECT_EQ(response.size, 123123123123123ll);
|
| +}
|
| +
|
| +} // namespace chromeos_update_engine
|
|
|