Home | History | Annotate | Download | only in update_engine
      1 //
      2 // Copyright (C) 2012 The Android Open Source Project
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 //
     16 
     17 #include "update_engine/omaha_request_action.h"
     18 
     19 #include <stdint.h>
     20 
     21 #include <memory>
     22 #include <string>
     23 #include <vector>
     24 
     25 #include <base/bind.h>
     26 #include <base/files/file_util.h>
     27 #include <base/files/scoped_temp_dir.h>
     28 #include <base/memory/ptr_util.h>
     29 #include <base/strings/string_number_conversions.h>
     30 #include <base/strings/string_util.h>
     31 #include <base/strings/stringprintf.h>
     32 #include <base/time/time.h>
     33 #include <brillo/bind_lambda.h>
     34 #include <brillo/message_loops/fake_message_loop.h>
     35 #include <brillo/message_loops/message_loop.h>
     36 #include <brillo/message_loops/message_loop_utils.h>
     37 #include <gtest/gtest.h>
     38 
     39 #include "update_engine/common/action_pipe.h"
     40 #include "update_engine/common/constants.h"
     41 #include "update_engine/common/fake_prefs.h"
     42 #include "update_engine/common/hash_calculator.h"
     43 #include "update_engine/common/mock_http_fetcher.h"
     44 #include "update_engine/common/platform_constants.h"
     45 #include "update_engine/common/prefs.h"
     46 #include "update_engine/common/test_utils.h"
     47 #include "update_engine/fake_system_state.h"
     48 #include "update_engine/metrics_reporter_interface.h"
     49 #include "update_engine/mock_connection_manager.h"
     50 #include "update_engine/mock_payload_state.h"
     51 #include "update_engine/omaha_request_params.h"
     52 
     53 using base::Time;
     54 using base::TimeDelta;
     55 using std::string;
     56 using std::vector;
     57 using testing::AllOf;
     58 using testing::AnyNumber;
     59 using testing::DoAll;
     60 using testing::Ge;
     61 using testing::Le;
     62 using testing::NiceMock;
     63 using testing::Return;
     64 using testing::ReturnPointee;
     65 using testing::SaveArg;
     66 using testing::SetArgPointee;
     67 using testing::_;
     68 
     69 namespace {
     70 
     71 const char kTestAppId[] = "test-app-id";
     72 const char kTestAppId2[] = "test-app2-id";
     73 
     74 // This is a helper struct to allow unit tests build an update response with the
     75 // values they care about.
     76 struct FakeUpdateResponse {
     77   string GetNoUpdateResponse() const {
     78     string entity_str;
     79     if (include_entity)
     80       entity_str = "<!DOCTYPE response [<!ENTITY CrOS \"ChromeOS\">]>";
     81     return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + entity_str +
     82            "<response protocol=\"3.0\">"
     83            "<daystart elapsed_seconds=\"100\"/>"
     84            "<app appid=\"" +
     85            app_id + "\" " +
     86            (include_cohorts
     87                 ? "cohort=\"" + cohort + "\" cohorthint=\"" + cohorthint +
     88                       "\" cohortname=\"" + cohortname + "\" "
     89                 : "") +
     90            " status=\"ok\">"
     91            "<ping status=\"ok\"/>"
     92            "<updatecheck status=\"noupdate\"/></app>" +
     93            (multi_app_no_update
     94                 ? "<app appid=\"" + app_id2 +
     95                       "\"><updatecheck status=\"noupdate\"/></app>"
     96                 : "") +
     97            "</response>";
     98   }
     99 
    100   string GetUpdateResponse() const {
    101     return "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response "
    102            "protocol=\"3.0\">"
    103            "<daystart elapsed_seconds=\"100\"" +
    104            (elapsed_days.empty() ? ""
    105                                  : (" elapsed_days=\"" + elapsed_days + "\"")) +
    106            "/>"
    107            "<app appid=\"" +
    108            app_id + "\" " +
    109            (include_cohorts
    110                 ? "cohort=\"" + cohort + "\" cohorthint=\"" + cohorthint +
    111                       "\" cohortname=\"" + cohortname + "\" "
    112                 : "") +
    113            " status=\"ok\">"
    114            "<ping status=\"ok\"/><updatecheck status=\"ok\">"
    115            "<urls><url codebase=\"" +
    116            codebase +
    117            "\"/></urls>"
    118            "<manifest version=\"" +
    119            version +
    120            "\">"
    121            "<packages><package hash=\"not-used\" name=\"" +
    122            filename + "\" size=\"" + base::Int64ToString(size) +
    123            "\" hash_sha256=\"" + hash + "\"/>" +
    124            (multi_package ? "<package name=\"package2\" size=\"222\" "
    125                             "hash_sha256=\"hash2\"/>"
    126                           : "") +
    127            "</packages>"
    128            "<actions><action event=\"postinstall\" MetadataSize=\"11" +
    129            (multi_package ? ":22" : "") + "\" ChromeOSVersion=\"" + version +
    130            "\" MoreInfo=\"" + more_info_url + "\" Prompt=\"" + prompt +
    131            "\" "
    132            "IsDelta=\"true\" "
    133            "IsDeltaPayload=\"true" +
    134            (multi_package ? ":false" : "") +
    135            "\" "
    136            "MaxDaysToScatter=\"" +
    137            max_days_to_scatter +
    138            "\" "
    139            "sha256=\"not-used\" "
    140            "needsadmin=\"" +
    141            needsadmin + "\" " +
    142            (deadline.empty() ? "" : ("deadline=\"" + deadline + "\" ")) +
    143            (disable_p2p_for_downloading ? "DisableP2PForDownloading=\"true\" "
    144                                         : "") +
    145            (disable_p2p_for_sharing ? "DisableP2PForSharing=\"true\" " : "") +
    146            "/></actions></manifest></updatecheck></app>" +
    147            (multi_app
    148                 ? "<app appid=\"" + app_id2 + "\"" +
    149                       (include_cohorts ? " cohort=\"cohort2\"" : "") +
    150                       "><updatecheck status=\"ok\"><urls><url codebase=\"" +
    151                       codebase2 + "\"/></urls><manifest version=\"" + version2 +
    152                       "\"><packages>"
    153                       "<package name=\"package3\" size=\"333\" "
    154                       "hash_sha256=\"hash3\"/></packages>"
    155                       "<actions><action event=\"postinstall\" " +
    156                       (multi_app_self_update
    157                            ? "noupdate=\"true\" IsDeltaPayload=\"true\" "
    158                            : "IsDeltaPayload=\"false\" ") +
    159                       "MetadataSize=\"33\"/></actions>"
    160                       "</manifest></updatecheck></app>"
    161                 : "") +
    162            (multi_app_no_update
    163                 ? "<app><updatecheck status=\"noupdate\"/></app>"
    164                 : "") +
    165            "</response>";
    166   }
    167 
    168   // Return the payload URL, which is split in two fields in the XML response.
    169   string GetPayloadUrl() {
    170     return codebase + filename;
    171   }
    172 
    173   string app_id = kTestAppId;
    174   string app_id2 = kTestAppId2;
    175   string version = "1.2.3.4";
    176   string version2 = "2.3.4.5";
    177   string more_info_url = "http://more/info";
    178   string prompt = "true";
    179   string codebase = "http://code/base/";
    180   string codebase2 = "http://code/base/2/";
    181   string filename = "file.signed";
    182   string hash = "4841534831323334";
    183   string needsadmin = "false";
    184   uint64_t size = 123;
    185   string deadline = "";
    186   string max_days_to_scatter = "7";
    187   string elapsed_days = "42";
    188 
    189   // P2P setting defaults to allowed.
    190   bool disable_p2p_for_downloading = false;
    191   bool disable_p2p_for_sharing = false;
    192 
    193   // Omaha cohorts settings.
    194   bool include_cohorts = false;
    195   string cohort = "";
    196   string cohorthint = "";
    197   string cohortname = "";
    198 
    199   // Whether to include the CrOS <!ENTITY> in the XML response.
    200   bool include_entity = false;
    201 
    202   // Whether to include more than one app.
    203   bool multi_app = false;
    204   // Whether to include an app with noupdate="true".
    205   bool multi_app_self_update = false;
    206   // Whether to include an additional app with status="noupdate".
    207   bool multi_app_no_update = false;
    208   // Whether to include more than one package in an app.
    209   bool multi_package = false;
    210 };
    211 
    212 }  // namespace
    213 
    214 namespace chromeos_update_engine {
    215 
    216 class OmahaRequestActionTest : public ::testing::Test {
    217  protected:
    218   void SetUp() override {
    219     fake_system_state_.set_request_params(&request_params_);
    220     fake_system_state_.set_prefs(&fake_prefs_);
    221   }
    222 
    223   // Returns true iff an output response was obtained from the
    224   // OmahaRequestAction. |prefs| may be null, in which case a local MockPrefs
    225   // is used. |payload_state| may be null, in which case a local mock is used.
    226   // |p2p_manager| may be null, in which case a local mock is used.
    227   // |connection_manager| may be null, in which case a local mock is used.
    228   // out_response may be null. If |fail_http_response_code| is non-negative,
    229   // the transfer will fail with that code. |ping_only| is passed through to the
    230   // OmahaRequestAction constructor. out_post_data may be null; if non-null, the
    231   // post-data received by the mock HttpFetcher is returned.
    232   //
    233   // The |expected_check_result|, |expected_check_reaction| and
    234   // |expected_error_code| parameters are for checking expectations
    235   // about reporting UpdateEngine.Check.{Result,Reaction,DownloadError}
    236   // UMA statistics. Use the appropriate ::kUnset value to specify that
    237   // the given metric should not be reported.
    238   bool TestUpdateCheck(OmahaRequestParams* request_params,
    239                        const string& http_response,
    240                        int fail_http_response_code,
    241                        bool ping_only,
    242                        ErrorCode expected_code,
    243                        metrics::CheckResult expected_check_result,
    244                        metrics::CheckReaction expected_check_reaction,
    245                        metrics::DownloadErrorCode expected_download_error_code,
    246                        OmahaResponse* out_response,
    247                        brillo::Blob* out_post_data);
    248 
    249   // Runs and checks a ping test. |ping_only| indicates whether it should send
    250   // only a ping or also an updatecheck.
    251   void PingTest(bool ping_only);
    252 
    253   // InstallDate test helper function.
    254   bool InstallDateParseHelper(const string &elapsed_days,
    255                               OmahaResponse *response);
    256 
    257   // P2P test helper function.
    258   void P2PTest(
    259       bool initial_allow_p2p_for_downloading,
    260       bool initial_allow_p2p_for_sharing,
    261       bool omaha_disable_p2p_for_downloading,
    262       bool omaha_disable_p2p_for_sharing,
    263       bool payload_state_allow_p2p_attempt,
    264       bool expect_p2p_client_lookup,
    265       const string& p2p_client_result_url,
    266       bool expected_allow_p2p_for_downloading,
    267       bool expected_allow_p2p_for_sharing,
    268       const string& expected_p2p_url);
    269 
    270   FakeSystemState fake_system_state_;
    271   FakeUpdateResponse fake_update_response_;
    272 
    273   // By default, all tests use these objects unless they replace them in the
    274   // fake_system_state_.
    275   OmahaRequestParams request_params_ = OmahaRequestParams{
    276       &fake_system_state_,
    277       constants::kOmahaPlatformName,
    278       OmahaRequestParams::kOsVersion,
    279       "service_pack",
    280       "x86-generic",
    281       kTestAppId,
    282       "0.1.0.0",
    283       "en-US",
    284       "unittest",
    285       "OEM MODEL 09235 7471",
    286       "ChromeOSFirmware.1.0",
    287       "0X0A1",
    288       false,   // delta okay
    289       false,   // interactive
    290       "http://url",
    291       ""};     // target_version_prefix
    292 
    293   FakePrefs fake_prefs_;
    294 };
    295 
    296 namespace {
    297 class OmahaRequestActionTestProcessorDelegate : public ActionProcessorDelegate {
    298  public:
    299   OmahaRequestActionTestProcessorDelegate()
    300       : expected_code_(ErrorCode::kSuccess) {}
    301   ~OmahaRequestActionTestProcessorDelegate() override {
    302   }
    303   void ProcessingDone(const ActionProcessor* processor,
    304                       ErrorCode code) override {
    305     brillo::MessageLoop::current()->BreakLoop();
    306   }
    307 
    308   void ActionCompleted(ActionProcessor* processor,
    309                        AbstractAction* action,
    310                        ErrorCode code) override {
    311     // make sure actions always succeed
    312     if (action->Type() == OmahaRequestAction::StaticType())
    313       EXPECT_EQ(expected_code_, code);
    314     else
    315       EXPECT_EQ(ErrorCode::kSuccess, code);
    316   }
    317   ErrorCode expected_code_;
    318 };
    319 }  // namespace
    320 
    321 class OutputObjectCollectorAction;
    322 
    323 template<>
    324 class ActionTraits<OutputObjectCollectorAction> {
    325  public:
    326   // Does not take an object for input
    327   typedef OmahaResponse InputObjectType;
    328   // On success, puts the output path on output
    329   typedef NoneType OutputObjectType;
    330 };
    331 
    332 class OutputObjectCollectorAction : public Action<OutputObjectCollectorAction> {
    333  public:
    334   OutputObjectCollectorAction() : has_input_object_(false) {}
    335   void PerformAction() {
    336     // copy input object
    337     has_input_object_ = HasInputObject();
    338     if (has_input_object_)
    339       omaha_response_ = GetInputObject();
    340     processor_->ActionComplete(this, ErrorCode::kSuccess);
    341   }
    342   // Should never be called
    343   void TerminateProcessing() {
    344     CHECK(false);
    345   }
    346   // Debugging/logging
    347   static string StaticType() {
    348     return "OutputObjectCollectorAction";
    349   }
    350   string Type() const { return StaticType(); }
    351   using InputObjectType =
    352       ActionTraits<OutputObjectCollectorAction>::InputObjectType;
    353   using OutputObjectType =
    354       ActionTraits<OutputObjectCollectorAction>::OutputObjectType;
    355   bool has_input_object_;
    356   OmahaResponse omaha_response_;
    357 };
    358 
    359 bool OmahaRequestActionTest::TestUpdateCheck(
    360     OmahaRequestParams* request_params,
    361     const string& http_response,
    362     int fail_http_response_code,
    363     bool ping_only,
    364     ErrorCode expected_code,
    365     metrics::CheckResult expected_check_result,
    366     metrics::CheckReaction expected_check_reaction,
    367     metrics::DownloadErrorCode expected_download_error_code,
    368     OmahaResponse* out_response,
    369     brillo::Blob* out_post_data) {
    370   brillo::FakeMessageLoop loop(nullptr);
    371   loop.SetAsCurrent();
    372   MockHttpFetcher* fetcher = new MockHttpFetcher(http_response.data(),
    373                                                  http_response.size(),
    374                                                  nullptr);
    375   if (fail_http_response_code >= 0) {
    376     fetcher->FailTransfer(fail_http_response_code);
    377   }
    378   if (request_params)
    379     fake_system_state_.set_request_params(request_params);
    380   OmahaRequestAction action(&fake_system_state_,
    381                             nullptr,
    382                             base::WrapUnique(fetcher),
    383                             ping_only);
    384   OmahaRequestActionTestProcessorDelegate delegate;
    385   delegate.expected_code_ = expected_code;
    386 
    387   ActionProcessor processor;
    388   processor.set_delegate(&delegate);
    389   processor.EnqueueAction(&action);
    390 
    391   OutputObjectCollectorAction collector_action;
    392   BondActions(&action, &collector_action);
    393   processor.EnqueueAction(&collector_action);
    394 
    395   EXPECT_CALL(*fake_system_state_.mock_metrics_reporter(),
    396               ReportUpdateCheckMetrics(_, _, _, _))
    397       .Times(AnyNumber());
    398 
    399   EXPECT_CALL(*fake_system_state_.mock_metrics_reporter(),
    400               ReportUpdateCheckMetrics(_,
    401                                        expected_check_result,
    402                                        expected_check_reaction,
    403                                        expected_download_error_code))
    404       .Times(ping_only ? 0 : 1);
    405 
    406   loop.PostTask(base::Bind(
    407       [](ActionProcessor* processor) { processor->StartProcessing(); },
    408       base::Unretained(&processor)));
    409   loop.Run();
    410   EXPECT_FALSE(loop.PendingTasks());
    411   if (collector_action.has_input_object_ && out_response)
    412     *out_response = collector_action.omaha_response_;
    413   if (out_post_data)
    414     *out_post_data = fetcher->post_data();
    415   return collector_action.has_input_object_;
    416 }
    417 
    418 // Tests Event requests -- they should always succeed. |out_post_data|
    419 // may be null; if non-null, the post-data received by the mock
    420 // HttpFetcher is returned.
    421 void TestEvent(OmahaRequestParams params,
    422                OmahaEvent* event,
    423                const string& http_response,
    424                brillo::Blob* out_post_data) {
    425   brillo::FakeMessageLoop loop(nullptr);
    426   loop.SetAsCurrent();
    427   MockHttpFetcher* fetcher = new MockHttpFetcher(http_response.data(),
    428                                                  http_response.size(),
    429                                                  nullptr);
    430   FakeSystemState fake_system_state;
    431   fake_system_state.set_request_params(&params);
    432   OmahaRequestAction action(&fake_system_state,
    433                             event,
    434                             base::WrapUnique(fetcher),
    435                             false);
    436   OmahaRequestActionTestProcessorDelegate delegate;
    437   ActionProcessor processor;
    438   processor.set_delegate(&delegate);
    439   processor.EnqueueAction(&action);
    440 
    441   loop.PostTask(base::Bind(
    442       [](ActionProcessor* processor) { processor->StartProcessing(); },
    443       base::Unretained(&processor)));
    444   loop.Run();
    445   EXPECT_FALSE(loop.PendingTasks());
    446 
    447   if (out_post_data)
    448     *out_post_data = fetcher->post_data();
    449 }
    450 
    451 TEST_F(OmahaRequestActionTest, RejectEntities) {
    452   OmahaResponse response;
    453   fake_update_response_.include_entity = true;
    454   ASSERT_FALSE(
    455       TestUpdateCheck(nullptr,  // request_params
    456                       fake_update_response_.GetNoUpdateResponse(),
    457                       -1,
    458                       false,  // ping_only
    459                       ErrorCode::kOmahaRequestXMLHasEntityDecl,
    460                       metrics::CheckResult::kParsingError,
    461                       metrics::CheckReaction::kUnset,
    462                       metrics::DownloadErrorCode::kUnset,
    463                       &response,
    464                       nullptr));
    465   EXPECT_FALSE(response.update_exists);
    466 }
    467 
    468 TEST_F(OmahaRequestActionTest, NoUpdateTest) {
    469   OmahaResponse response;
    470   ASSERT_TRUE(
    471       TestUpdateCheck(nullptr,  // request_params
    472                       fake_update_response_.GetNoUpdateResponse(),
    473                       -1,
    474                       false,  // ping_only
    475                       ErrorCode::kSuccess,
    476                       metrics::CheckResult::kNoUpdateAvailable,
    477                       metrics::CheckReaction::kUnset,
    478                       metrics::DownloadErrorCode::kUnset,
    479                       &response,
    480                       nullptr));
    481   EXPECT_FALSE(response.update_exists);
    482 }
    483 
    484 TEST_F(OmahaRequestActionTest, MultiAppNoUpdateTest) {
    485   OmahaResponse response;
    486   fake_update_response_.multi_app_no_update = true;
    487   ASSERT_TRUE(TestUpdateCheck(nullptr,  // request_params
    488                               fake_update_response_.GetNoUpdateResponse(),
    489                               -1,
    490                               false,  // ping_only
    491                               ErrorCode::kSuccess,
    492                               metrics::CheckResult::kNoUpdateAvailable,
    493                               metrics::CheckReaction::kUnset,
    494                               metrics::DownloadErrorCode::kUnset,
    495                               &response,
    496                               nullptr));
    497   EXPECT_FALSE(response.update_exists);
    498 }
    499 
    500 TEST_F(OmahaRequestActionTest, MultiAppNoPartialUpdateTest) {
    501   OmahaResponse response;
    502   fake_update_response_.multi_app_no_update = true;
    503   ASSERT_TRUE(TestUpdateCheck(nullptr,  // request_params
    504                               fake_update_response_.GetUpdateResponse(),
    505                               -1,
    506                               false,  // ping_only
    507                               ErrorCode::kSuccess,
    508                               metrics::CheckResult::kNoUpdateAvailable,
    509                               metrics::CheckReaction::kUnset,
    510                               metrics::DownloadErrorCode::kUnset,
    511                               &response,
    512                               nullptr));
    513   EXPECT_FALSE(response.update_exists);
    514 }
    515 
    516 TEST_F(OmahaRequestActionTest, NoSelfUpdateTest) {
    517   OmahaResponse response;
    518   ASSERT_TRUE(TestUpdateCheck(
    519       nullptr,  // request_params
    520       "<response><app><updatecheck status=\"ok\"><manifest><actions><action "
    521       "event=\"postinstall\" noupdate=\"true\"/></actions>"
    522       "</manifest></updatecheck></app></response>",
    523       -1,
    524       false,  // ping_only
    525       ErrorCode::kSuccess,
    526       metrics::CheckResult::kNoUpdateAvailable,
    527       metrics::CheckReaction::kUnset,
    528       metrics::DownloadErrorCode::kUnset,
    529       &response,
    530       nullptr));
    531   EXPECT_FALSE(response.update_exists);
    532 }
    533 
    534 // Test that all the values in the response are parsed in a normal update
    535 // response.
    536 TEST_F(OmahaRequestActionTest, ValidUpdateTest) {
    537   OmahaResponse response;
    538   fake_update_response_.deadline = "20101020";
    539   ASSERT_TRUE(
    540       TestUpdateCheck(nullptr,  // request_params
    541                       fake_update_response_.GetUpdateResponse(),
    542                       -1,
    543                       false,  // ping_only
    544                       ErrorCode::kSuccess,
    545                       metrics::CheckResult::kUpdateAvailable,
    546                       metrics::CheckReaction::kUpdating,
    547                       metrics::DownloadErrorCode::kUnset,
    548                       &response,
    549                       nullptr));
    550   EXPECT_TRUE(response.update_exists);
    551   EXPECT_EQ(fake_update_response_.version, response.version);
    552   EXPECT_EQ("", response.system_version);
    553   EXPECT_EQ(fake_update_response_.GetPayloadUrl(),
    554             response.packages[0].payload_urls[0]);
    555   EXPECT_EQ(fake_update_response_.more_info_url, response.more_info_url);
    556   EXPECT_EQ(fake_update_response_.hash, response.packages[0].hash);
    557   EXPECT_EQ(fake_update_response_.size, response.packages[0].size);
    558   EXPECT_EQ(true, response.packages[0].is_delta);
    559   EXPECT_EQ(fake_update_response_.prompt == "true", response.prompt);
    560   EXPECT_EQ(fake_update_response_.deadline, response.deadline);
    561   // Omaha cohort attributes are not set in the response, so they should not be
    562   // persisted.
    563   EXPECT_FALSE(fake_prefs_.Exists(kPrefsOmahaCohort));
    564   EXPECT_FALSE(fake_prefs_.Exists(kPrefsOmahaCohortHint));
    565   EXPECT_FALSE(fake_prefs_.Exists(kPrefsOmahaCohortName));
    566 }
    567 
    568 TEST_F(OmahaRequestActionTest, MultiPackageUpdateTest) {
    569   OmahaResponse response;
    570   fake_update_response_.multi_package = true;
    571   ASSERT_TRUE(TestUpdateCheck(nullptr,  // request_params
    572                               fake_update_response_.GetUpdateResponse(),
    573                               -1,
    574                               false,  // ping_only
    575                               ErrorCode::kSuccess,
    576                               metrics::CheckResult::kUpdateAvailable,
    577                               metrics::CheckReaction::kUpdating,
    578                               metrics::DownloadErrorCode::kUnset,
    579                               &response,
    580                               nullptr));
    581   EXPECT_TRUE(response.update_exists);
    582   EXPECT_EQ(fake_update_response_.version, response.version);
    583   EXPECT_EQ(fake_update_response_.GetPayloadUrl(),
    584             response.packages[0].payload_urls[0]);
    585   EXPECT_EQ(fake_update_response_.codebase + "package2",
    586             response.packages[1].payload_urls[0]);
    587   EXPECT_EQ(fake_update_response_.hash, response.packages[0].hash);
    588   EXPECT_EQ(fake_update_response_.size, response.packages[0].size);
    589   EXPECT_EQ(true, response.packages[0].is_delta);
    590   EXPECT_EQ(11u, response.packages[0].metadata_size);
    591   ASSERT_EQ(2u, response.packages.size());
    592   EXPECT_EQ(string("hash2"), response.packages[1].hash);
    593   EXPECT_EQ(222u, response.packages[1].size);
    594   EXPECT_EQ(22u, response.packages[1].metadata_size);
    595   EXPECT_EQ(false, response.packages[1].is_delta);
    596 }
    597 
    598 TEST_F(OmahaRequestActionTest, MultiAppUpdateTest) {
    599   OmahaResponse response;
    600   fake_update_response_.multi_app = true;
    601   ASSERT_TRUE(TestUpdateCheck(nullptr,  // request_params
    602                               fake_update_response_.GetUpdateResponse(),
    603                               -1,
    604                               false,  // ping_only
    605                               ErrorCode::kSuccess,
    606                               metrics::CheckResult::kUpdateAvailable,
    607                               metrics::CheckReaction::kUpdating,
    608                               metrics::DownloadErrorCode::kUnset,
    609                               &response,
    610                               nullptr));
    611   EXPECT_TRUE(response.update_exists);
    612   EXPECT_EQ(fake_update_response_.version, response.version);
    613   EXPECT_EQ(fake_update_response_.GetPayloadUrl(),
    614             response.packages[0].payload_urls[0]);
    615   EXPECT_EQ(fake_update_response_.codebase2 + "package3",
    616             response.packages[1].payload_urls[0]);
    617   EXPECT_EQ(fake_update_response_.hash, response.packages[0].hash);
    618   EXPECT_EQ(fake_update_response_.size, response.packages[0].size);
    619   EXPECT_EQ(11u, response.packages[0].metadata_size);
    620   EXPECT_EQ(true, response.packages[0].is_delta);
    621   ASSERT_EQ(2u, response.packages.size());
    622   EXPECT_EQ(string("hash3"), response.packages[1].hash);
    623   EXPECT_EQ(333u, response.packages[1].size);
    624   EXPECT_EQ(33u, response.packages[1].metadata_size);
    625   EXPECT_EQ(false, response.packages[1].is_delta);
    626 }
    627 
    628 TEST_F(OmahaRequestActionTest, MultiAppAndSystemUpdateTest) {
    629   OmahaResponse response;
    630   fake_update_response_.multi_app = true;
    631   // trigger the lining up of the app and system versions
    632   request_params_.set_system_app_id(fake_update_response_.app_id2);
    633 
    634   ASSERT_TRUE(TestUpdateCheck(nullptr,  // request_params
    635                               fake_update_response_.GetUpdateResponse(),
    636                               -1,
    637                               false,  // ping_only
    638                               ErrorCode::kSuccess,
    639                               metrics::CheckResult::kUpdateAvailable,
    640                               metrics::CheckReaction::kUpdating,
    641                               metrics::DownloadErrorCode::kUnset,
    642                               &response,
    643                               nullptr));
    644   EXPECT_TRUE(response.update_exists);
    645   EXPECT_EQ(fake_update_response_.version, response.version);
    646   EXPECT_EQ(fake_update_response_.version2, response.system_version);
    647   EXPECT_EQ(fake_update_response_.GetPayloadUrl(),
    648             response.packages[0].payload_urls[0]);
    649   EXPECT_EQ(fake_update_response_.codebase2 + "package3",
    650             response.packages[1].payload_urls[0]);
    651   EXPECT_EQ(fake_update_response_.hash, response.packages[0].hash);
    652   EXPECT_EQ(fake_update_response_.size, response.packages[0].size);
    653   EXPECT_EQ(11u, response.packages[0].metadata_size);
    654   EXPECT_EQ(true, response.packages[0].is_delta);
    655   ASSERT_EQ(2u, response.packages.size());
    656   EXPECT_EQ(string("hash3"), response.packages[1].hash);
    657   EXPECT_EQ(333u, response.packages[1].size);
    658   EXPECT_EQ(33u, response.packages[1].metadata_size);
    659   EXPECT_EQ(false, response.packages[1].is_delta);
    660 }
    661 
    662 TEST_F(OmahaRequestActionTest, MultiAppPartialUpdateTest) {
    663   OmahaResponse response;
    664   fake_update_response_.multi_app = true;
    665   fake_update_response_.multi_app_self_update = true;
    666   ASSERT_TRUE(TestUpdateCheck(nullptr,  // request_params
    667                               fake_update_response_.GetUpdateResponse(),
    668                               -1,
    669                               false,  // ping_only
    670                               ErrorCode::kSuccess,
    671                               metrics::CheckResult::kUpdateAvailable,
    672                               metrics::CheckReaction::kUpdating,
    673                               metrics::DownloadErrorCode::kUnset,
    674                               &response,
    675                               nullptr));
    676   EXPECT_TRUE(response.update_exists);
    677   EXPECT_EQ(fake_update_response_.version, response.version);
    678   EXPECT_EQ("", response.system_version);
    679   EXPECT_EQ(fake_update_response_.GetPayloadUrl(),
    680             response.packages[0].payload_urls[0]);
    681   EXPECT_EQ(fake_update_response_.hash, response.packages[0].hash);
    682   EXPECT_EQ(fake_update_response_.size, response.packages[0].size);
    683   EXPECT_EQ(11u, response.packages[0].metadata_size);
    684   ASSERT_EQ(2u, response.packages.size());
    685   EXPECT_EQ(string("hash3"), response.packages[1].hash);
    686   EXPECT_EQ(333u, response.packages[1].size);
    687   EXPECT_EQ(33u, response.packages[1].metadata_size);
    688   EXPECT_EQ(true, response.packages[1].is_delta);
    689 }
    690 
    691 TEST_F(OmahaRequestActionTest, MultiAppMultiPackageUpdateTest) {
    692   OmahaResponse response;
    693   fake_update_response_.multi_app = true;
    694   fake_update_response_.multi_package = true;
    695   ASSERT_TRUE(TestUpdateCheck(nullptr,  // request_params
    696                               fake_update_response_.GetUpdateResponse(),
    697                               -1,
    698                               false,  // ping_only
    699                               ErrorCode::kSuccess,
    700                               metrics::CheckResult::kUpdateAvailable,
    701                               metrics::CheckReaction::kUpdating,
    702                               metrics::DownloadErrorCode::kUnset,
    703                               &response,
    704                               nullptr));
    705   EXPECT_TRUE(response.update_exists);
    706   EXPECT_EQ(fake_update_response_.version, response.version);
    707   EXPECT_EQ("", response.system_version);
    708   EXPECT_EQ(fake_update_response_.GetPayloadUrl(),
    709             response.packages[0].payload_urls[0]);
    710   EXPECT_EQ(fake_update_response_.codebase + "package2",
    711             response.packages[1].payload_urls[0]);
    712   EXPECT_EQ(fake_update_response_.codebase2 + "package3",
    713             response.packages[2].payload_urls[0]);
    714   EXPECT_EQ(fake_update_response_.hash, response.packages[0].hash);
    715   EXPECT_EQ(fake_update_response_.size, response.packages[0].size);
    716   EXPECT_EQ(11u, response.packages[0].metadata_size);
    717   EXPECT_EQ(true, response.packages[0].is_delta);
    718   ASSERT_EQ(3u, response.packages.size());
    719   EXPECT_EQ(string("hash2"), response.packages[1].hash);
    720   EXPECT_EQ(222u, response.packages[1].size);
    721   EXPECT_EQ(22u, response.packages[1].metadata_size);
    722   EXPECT_EQ(false, response.packages[1].is_delta);
    723   EXPECT_EQ(string("hash3"), response.packages[2].hash);
    724   EXPECT_EQ(333u, response.packages[2].size);
    725   EXPECT_EQ(33u, response.packages[2].metadata_size);
    726   EXPECT_EQ(false, response.packages[2].is_delta);
    727 }
    728 
    729 TEST_F(OmahaRequestActionTest, ExtraHeadersSentTest) {
    730   const string http_response = "<?xml invalid response";
    731   request_params_.set_interactive(true);
    732 
    733   brillo::FakeMessageLoop loop(nullptr);
    734   loop.SetAsCurrent();
    735 
    736   MockHttpFetcher* fetcher =
    737       new MockHttpFetcher(http_response.data(), http_response.size(), nullptr);
    738   OmahaRequestAction action(&fake_system_state_, nullptr,
    739                             base::WrapUnique(fetcher), false);
    740   ActionProcessor processor;
    741   processor.EnqueueAction(&action);
    742 
    743   loop.PostTask(base::Bind(
    744       [](ActionProcessor* processor) { processor->StartProcessing(); },
    745       base::Unretained(&processor)));
    746   loop.Run();
    747   EXPECT_FALSE(loop.PendingTasks());
    748 
    749   // Check that the headers were set in the fetcher during the action. Note that
    750   // we set this request as "interactive".
    751   EXPECT_EQ("fg", fetcher->GetHeader("X-GoogleUpdate-Interactivity"));
    752   EXPECT_EQ(kTestAppId, fetcher->GetHeader("X-GoogleUpdate-AppId"));
    753   EXPECT_NE("", fetcher->GetHeader("X-GoogleUpdate-Updater"));
    754 }
    755 
    756 TEST_F(OmahaRequestActionTest, ValidUpdateBlockedByConnection) {
    757   OmahaResponse response;
    758   // Set up a connection manager that doesn't allow a valid update over
    759   // the current ethernet connection.
    760   MockConnectionManager mock_cm;
    761   fake_system_state_.set_connection_manager(&mock_cm);
    762 
    763   EXPECT_CALL(mock_cm, GetConnectionProperties(_, _))
    764       .WillRepeatedly(
    765           DoAll(SetArgPointee<0>(ConnectionType::kEthernet),
    766                 SetArgPointee<1>(ConnectionTethering::kUnknown),
    767                 Return(true)));
    768   EXPECT_CALL(mock_cm, IsUpdateAllowedOver(ConnectionType::kEthernet, _))
    769       .WillRepeatedly(Return(false));
    770 
    771   ASSERT_FALSE(
    772       TestUpdateCheck(nullptr,  // request_params
    773                       fake_update_response_.GetUpdateResponse(),
    774                       -1,
    775                       false,  // ping_only
    776                       ErrorCode::kOmahaUpdateIgnoredPerPolicy,
    777                       metrics::CheckResult::kUpdateAvailable,
    778                       metrics::CheckReaction::kIgnored,
    779                       metrics::DownloadErrorCode::kUnset,
    780                       &response,
    781                       nullptr));
    782   EXPECT_FALSE(response.update_exists);
    783 }
    784 
    785 TEST_F(OmahaRequestActionTest, ValidUpdateBlockedByRollback) {
    786   string rollback_version = "1234.0.0";
    787   OmahaResponse response;
    788 
    789   MockPayloadState mock_payload_state;
    790   fake_system_state_.set_payload_state(&mock_payload_state);
    791 
    792   EXPECT_CALL(mock_payload_state, GetRollbackVersion())
    793     .WillRepeatedly(Return(rollback_version));
    794 
    795   fake_update_response_.version = rollback_version;
    796   ASSERT_FALSE(
    797       TestUpdateCheck(nullptr,  // request_params
    798                       fake_update_response_.GetUpdateResponse(),
    799                       -1,
    800                       false,  // ping_only
    801                       ErrorCode::kOmahaUpdateIgnoredPerPolicy,
    802                       metrics::CheckResult::kUpdateAvailable,
    803                       metrics::CheckReaction::kIgnored,
    804                       metrics::DownloadErrorCode::kUnset,
    805                       &response,
    806                       nullptr));
    807   EXPECT_FALSE(response.update_exists);
    808 }
    809 
    810 // Verify that update checks called during OOBE will only try to download
    811 // an update if the response includes a non-empty deadline field.
    812 TEST_F(OmahaRequestActionTest, SkipNonCriticalUpdatesBeforeOOBE) {
    813   OmahaResponse response;
    814 
    815   // TODO(senj): set better default value for metrics::checkresult in
    816   // OmahaRequestAction::ActionCompleted.
    817   fake_system_state_.fake_hardware()->UnsetIsOOBEComplete();
    818   ASSERT_FALSE(TestUpdateCheck(nullptr,  // request_params
    819                                fake_update_response_.GetUpdateResponse(),
    820                                -1,
    821                                false,  // ping_only
    822                                ErrorCode::kNonCriticalUpdateInOOBE,
    823                                metrics::CheckResult::kParsingError,
    824                                metrics::CheckReaction::kUnset,
    825                                metrics::DownloadErrorCode::kUnset,
    826                                &response,
    827                                nullptr));
    828   EXPECT_FALSE(response.update_exists);
    829 
    830   // The IsOOBEComplete() value is ignored when the OOBE flow is not enabled.
    831   fake_system_state_.fake_hardware()->SetIsOOBEEnabled(false);
    832   ASSERT_TRUE(TestUpdateCheck(nullptr,  // request_params
    833                               fake_update_response_.GetUpdateResponse(),
    834                               -1,
    835                               false,  // ping_only
    836                               ErrorCode::kSuccess,
    837                               metrics::CheckResult::kUpdateAvailable,
    838                               metrics::CheckReaction::kUpdating,
    839                               metrics::DownloadErrorCode::kUnset,
    840                               &response,
    841                               nullptr));
    842   EXPECT_TRUE(response.update_exists);
    843   fake_system_state_.fake_hardware()->SetIsOOBEEnabled(true);
    844 
    845   // The payload is applied when a deadline was set in the response.
    846   fake_update_response_.deadline = "20101020";
    847   ASSERT_TRUE(
    848       TestUpdateCheck(nullptr,  // request_params
    849                       fake_update_response_.GetUpdateResponse(),
    850                       -1,
    851                       false,  // ping_only
    852                       ErrorCode::kSuccess,
    853                       metrics::CheckResult::kUpdateAvailable,
    854                       metrics::CheckReaction::kUpdating,
    855                       metrics::DownloadErrorCode::kUnset,
    856                       &response,
    857                       nullptr));
    858   EXPECT_TRUE(response.update_exists);
    859 }
    860 
    861 TEST_F(OmahaRequestActionTest, WallClockBasedWaitAloneCausesScattering) {
    862   OmahaResponse response;
    863   OmahaRequestParams params = request_params_;
    864   params.set_wall_clock_based_wait_enabled(true);
    865   params.set_update_check_count_wait_enabled(false);
    866   params.set_waiting_period(TimeDelta::FromDays(2));
    867 
    868   ASSERT_FALSE(
    869       TestUpdateCheck(&params,
    870                       fake_update_response_.GetUpdateResponse(),
    871                       -1,
    872                       false,  // ping_only
    873                       ErrorCode::kOmahaUpdateDeferredPerPolicy,
    874                       metrics::CheckResult::kUpdateAvailable,
    875                       metrics::CheckReaction::kDeferring,
    876                       metrics::DownloadErrorCode::kUnset,
    877                       &response,
    878                       nullptr));
    879   EXPECT_FALSE(response.update_exists);
    880 
    881   // Verify if we are interactive check we don't defer.
    882   params.set_interactive(true);
    883   ASSERT_TRUE(
    884       TestUpdateCheck(&params,
    885                       fake_update_response_.GetUpdateResponse(),
    886                       -1,
    887                       false,  // ping_only
    888                       ErrorCode::kSuccess,
    889                       metrics::CheckResult::kUpdateAvailable,
    890                       metrics::CheckReaction::kUpdating,
    891                       metrics::DownloadErrorCode::kUnset,
    892                       &response,
    893                       nullptr));
    894   EXPECT_TRUE(response.update_exists);
    895 }
    896 
    897 TEST_F(OmahaRequestActionTest, NoWallClockBasedWaitCausesNoScattering) {
    898   OmahaResponse response;
    899   OmahaRequestParams params = request_params_;
    900   params.set_wall_clock_based_wait_enabled(false);
    901   params.set_waiting_period(TimeDelta::FromDays(2));
    902 
    903   params.set_update_check_count_wait_enabled(true);
    904   params.set_min_update_checks_needed(1);
    905   params.set_max_update_checks_allowed(8);
    906 
    907   ASSERT_TRUE(
    908       TestUpdateCheck(&params,
    909                       fake_update_response_.GetUpdateResponse(),
    910                       -1,
    911                       false,  // ping_only
    912                       ErrorCode::kSuccess,
    913                       metrics::CheckResult::kUpdateAvailable,
    914                       metrics::CheckReaction::kUpdating,
    915                       metrics::DownloadErrorCode::kUnset,
    916                       &response,
    917                       nullptr));
    918   EXPECT_TRUE(response.update_exists);
    919 }
    920 
    921 TEST_F(OmahaRequestActionTest, ZeroMaxDaysToScatterCausesNoScattering) {
    922   OmahaResponse response;
    923   OmahaRequestParams params = request_params_;
    924   params.set_wall_clock_based_wait_enabled(true);
    925   params.set_waiting_period(TimeDelta::FromDays(2));
    926 
    927   params.set_update_check_count_wait_enabled(true);
    928   params.set_min_update_checks_needed(1);
    929   params.set_max_update_checks_allowed(8);
    930 
    931   fake_update_response_.max_days_to_scatter = "0";
    932   ASSERT_TRUE(
    933       TestUpdateCheck(&params,
    934                       fake_update_response_.GetUpdateResponse(),
    935                       -1,
    936                       false,  // ping_only
    937                       ErrorCode::kSuccess,
    938                       metrics::CheckResult::kUpdateAvailable,
    939                       metrics::CheckReaction::kUpdating,
    940                       metrics::DownloadErrorCode::kUnset,
    941                       &response,
    942                       nullptr));
    943   EXPECT_TRUE(response.update_exists);
    944 }
    945 
    946 
    947 TEST_F(OmahaRequestActionTest, ZeroUpdateCheckCountCausesNoScattering) {
    948   OmahaResponse response;
    949   OmahaRequestParams params = request_params_;
    950   params.set_wall_clock_based_wait_enabled(true);
    951   params.set_waiting_period(TimeDelta());
    952 
    953   params.set_update_check_count_wait_enabled(true);
    954   params.set_min_update_checks_needed(0);
    955   params.set_max_update_checks_allowed(0);
    956 
    957   ASSERT_TRUE(TestUpdateCheck(
    958                       &params,
    959                       fake_update_response_.GetUpdateResponse(),
    960                       -1,
    961                       false,  // ping_only
    962                       ErrorCode::kSuccess,
    963                       metrics::CheckResult::kUpdateAvailable,
    964                       metrics::CheckReaction::kUpdating,
    965                       metrics::DownloadErrorCode::kUnset,
    966                       &response,
    967                       nullptr));
    968 
    969   int64_t count;
    970   ASSERT_TRUE(fake_prefs_.GetInt64(kPrefsUpdateCheckCount, &count));
    971   ASSERT_EQ(count, 0);
    972   EXPECT_TRUE(response.update_exists);
    973 }
    974 
    975 TEST_F(OmahaRequestActionTest, NonZeroUpdateCheckCountCausesScattering) {
    976   OmahaResponse response;
    977   OmahaRequestParams params = request_params_;
    978   params.set_wall_clock_based_wait_enabled(true);
    979   params.set_waiting_period(TimeDelta());
    980 
    981   params.set_update_check_count_wait_enabled(true);
    982   params.set_min_update_checks_needed(1);
    983   params.set_max_update_checks_allowed(8);
    984 
    985   ASSERT_FALSE(TestUpdateCheck(
    986                       &params,
    987                       fake_update_response_.GetUpdateResponse(),
    988                       -1,
    989                       false,  // ping_only
    990                       ErrorCode::kOmahaUpdateDeferredPerPolicy,
    991                       metrics::CheckResult::kUpdateAvailable,
    992                       metrics::CheckReaction::kDeferring,
    993                       metrics::DownloadErrorCode::kUnset,
    994                       &response,
    995                       nullptr));
    996 
    997   int64_t count;
    998   ASSERT_TRUE(fake_prefs_.GetInt64(kPrefsUpdateCheckCount, &count));
    999   ASSERT_GT(count, 0);
   1000   EXPECT_FALSE(response.update_exists);
   1001 
   1002   // Verify if we are interactive check we don't defer.
   1003   params.set_interactive(true);
   1004   ASSERT_TRUE(
   1005       TestUpdateCheck(&params,
   1006                       fake_update_response_.GetUpdateResponse(),
   1007                       -1,
   1008                       false,  // ping_only
   1009                       ErrorCode::kSuccess,
   1010                       metrics::CheckResult::kUpdateAvailable,
   1011                       metrics::CheckReaction::kUpdating,
   1012                       metrics::DownloadErrorCode::kUnset,
   1013                       &response,
   1014                       nullptr));
   1015   EXPECT_TRUE(response.update_exists);
   1016 }
   1017 
   1018 TEST_F(OmahaRequestActionTest, ExistingUpdateCheckCountCausesScattering) {
   1019   OmahaResponse response;
   1020   OmahaRequestParams params = request_params_;
   1021   params.set_wall_clock_based_wait_enabled(true);
   1022   params.set_waiting_period(TimeDelta());
   1023 
   1024   params.set_update_check_count_wait_enabled(true);
   1025   params.set_min_update_checks_needed(1);
   1026   params.set_max_update_checks_allowed(8);
   1027 
   1028   ASSERT_TRUE(fake_prefs_.SetInt64(kPrefsUpdateCheckCount, 5));
   1029 
   1030   ASSERT_FALSE(TestUpdateCheck(
   1031                       &params,
   1032                       fake_update_response_.GetUpdateResponse(),
   1033                       -1,
   1034                       false,  // ping_only
   1035                       ErrorCode::kOmahaUpdateDeferredPerPolicy,
   1036                       metrics::CheckResult::kUpdateAvailable,
   1037                       metrics::CheckReaction::kDeferring,
   1038                       metrics::DownloadErrorCode::kUnset,
   1039                       &response,
   1040                       nullptr));
   1041 
   1042   int64_t count;
   1043   ASSERT_TRUE(fake_prefs_.GetInt64(kPrefsUpdateCheckCount, &count));
   1044   // count remains the same, as the decrementing happens in update_attempter
   1045   // which this test doesn't exercise.
   1046   ASSERT_EQ(count, 5);
   1047   EXPECT_FALSE(response.update_exists);
   1048 
   1049   // Verify if we are interactive check we don't defer.
   1050   params.set_interactive(true);
   1051   ASSERT_TRUE(
   1052       TestUpdateCheck(&params,
   1053                       fake_update_response_.GetUpdateResponse(),
   1054                       -1,
   1055                       false,  // ping_only
   1056                       ErrorCode::kSuccess,
   1057                       metrics::CheckResult::kUpdateAvailable,
   1058                       metrics::CheckReaction::kUpdating,
   1059                       metrics::DownloadErrorCode::kUnset,
   1060                       &response,
   1061                       nullptr));
   1062   EXPECT_TRUE(response.update_exists);
   1063 }
   1064 
   1065 TEST_F(OmahaRequestActionTest, CohortsArePersisted) {
   1066   OmahaResponse response;
   1067   OmahaRequestParams params = request_params_;
   1068   fake_update_response_.include_cohorts = true;
   1069   fake_update_response_.cohort = "s/154454/8479665";
   1070   fake_update_response_.cohorthint = "please-put-me-on-beta";
   1071   fake_update_response_.cohortname = "stable";
   1072 
   1073   ASSERT_TRUE(TestUpdateCheck(&params,
   1074                               fake_update_response_.GetUpdateResponse(),
   1075                               -1,
   1076                               false,  // ping_only
   1077                               ErrorCode::kSuccess,
   1078                               metrics::CheckResult::kUpdateAvailable,
   1079                               metrics::CheckReaction::kUpdating,
   1080                               metrics::DownloadErrorCode::kUnset,
   1081                               &response,
   1082                               nullptr));
   1083 
   1084   string value;
   1085   EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohort, &value));
   1086   EXPECT_EQ(fake_update_response_.cohort, value);
   1087 
   1088   EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohortHint, &value));
   1089   EXPECT_EQ(fake_update_response_.cohorthint, value);
   1090 
   1091   EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohortName, &value));
   1092   EXPECT_EQ(fake_update_response_.cohortname, value);
   1093 }
   1094 
   1095 TEST_F(OmahaRequestActionTest, CohortsAreUpdated) {
   1096   OmahaResponse response;
   1097   OmahaRequestParams params = request_params_;
   1098   EXPECT_TRUE(fake_prefs_.SetString(kPrefsOmahaCohort, "old_value"));
   1099   EXPECT_TRUE(fake_prefs_.SetString(kPrefsOmahaCohortHint, "old_hint"));
   1100   EXPECT_TRUE(fake_prefs_.SetString(kPrefsOmahaCohortName, "old_name"));
   1101   fake_update_response_.include_cohorts = true;
   1102   fake_update_response_.cohort = "s/154454/8479665";
   1103   fake_update_response_.cohorthint = "please-put-me-on-beta";
   1104   fake_update_response_.cohortname = "";
   1105 
   1106   ASSERT_TRUE(TestUpdateCheck(&params,
   1107                               fake_update_response_.GetUpdateResponse(),
   1108                               -1,
   1109                               false,  // ping_only
   1110                               ErrorCode::kSuccess,
   1111                               metrics::CheckResult::kUpdateAvailable,
   1112                               metrics::CheckReaction::kUpdating,
   1113                               metrics::DownloadErrorCode::kUnset,
   1114                               &response,
   1115                               nullptr));
   1116 
   1117   string value;
   1118   EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohort, &value));
   1119   EXPECT_EQ(fake_update_response_.cohort, value);
   1120 
   1121   EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohortHint, &value));
   1122   EXPECT_EQ(fake_update_response_.cohorthint, value);
   1123 
   1124   EXPECT_FALSE(fake_prefs_.GetString(kPrefsOmahaCohortName, &value));
   1125 }
   1126 
   1127 TEST_F(OmahaRequestActionTest, CohortsAreNotModifiedWhenMissing) {
   1128   OmahaResponse response;
   1129   OmahaRequestParams params = request_params_;
   1130   EXPECT_TRUE(fake_prefs_.SetString(kPrefsOmahaCohort, "old_value"));
   1131 
   1132   ASSERT_TRUE(TestUpdateCheck(&params,
   1133                               fake_update_response_.GetUpdateResponse(),
   1134                               -1,
   1135                               false,  // ping_only
   1136                               ErrorCode::kSuccess,
   1137                               metrics::CheckResult::kUpdateAvailable,
   1138                               metrics::CheckReaction::kUpdating,
   1139                               metrics::DownloadErrorCode::kUnset,
   1140                               &response,
   1141                               nullptr));
   1142 
   1143   string value;
   1144   EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohort, &value));
   1145   EXPECT_EQ("old_value", value);
   1146 
   1147   EXPECT_FALSE(fake_prefs_.GetString(kPrefsOmahaCohortHint, &value));
   1148   EXPECT_FALSE(fake_prefs_.GetString(kPrefsOmahaCohortName, &value));
   1149 }
   1150 
   1151 TEST_F(OmahaRequestActionTest, CohortsArePersistedWhenNoUpdate) {
   1152   OmahaResponse response;
   1153   OmahaRequestParams params = request_params_;
   1154   fake_update_response_.include_cohorts = true;
   1155   fake_update_response_.cohort = "s/154454/8479665";
   1156   fake_update_response_.cohorthint = "please-put-me-on-beta";
   1157   fake_update_response_.cohortname = "stable";
   1158 
   1159   ASSERT_TRUE(TestUpdateCheck(&params,
   1160                               fake_update_response_.GetNoUpdateResponse(),
   1161                               -1,
   1162                               false,  // ping_only
   1163                               ErrorCode::kSuccess,
   1164                               metrics::CheckResult::kNoUpdateAvailable,
   1165                               metrics::CheckReaction::kUnset,
   1166                               metrics::DownloadErrorCode::kUnset,
   1167                               &response,
   1168                               nullptr));
   1169 
   1170   string value;
   1171   EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohort, &value));
   1172   EXPECT_EQ(fake_update_response_.cohort, value);
   1173 
   1174   EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohortHint, &value));
   1175   EXPECT_EQ(fake_update_response_.cohorthint, value);
   1176 
   1177   EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohortName, &value));
   1178   EXPECT_EQ(fake_update_response_.cohortname, value);
   1179 }
   1180 
   1181 TEST_F(OmahaRequestActionTest, MultiAppCohortTest) {
   1182   OmahaResponse response;
   1183   OmahaRequestParams params = request_params_;
   1184   fake_update_response_.multi_app = true;
   1185   fake_update_response_.include_cohorts = true;
   1186   fake_update_response_.cohort = "s/154454/8479665";
   1187   fake_update_response_.cohorthint = "please-put-me-on-beta";
   1188   fake_update_response_.cohortname = "stable";
   1189 
   1190   ASSERT_TRUE(TestUpdateCheck(&params,
   1191                               fake_update_response_.GetUpdateResponse(),
   1192                               -1,
   1193                               false,  // ping_only
   1194                               ErrorCode::kSuccess,
   1195                               metrics::CheckResult::kUpdateAvailable,
   1196                               metrics::CheckReaction::kUpdating,
   1197                               metrics::DownloadErrorCode::kUnset,
   1198                               &response,
   1199                               nullptr));
   1200 
   1201   string value;
   1202   EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohort, &value));
   1203   EXPECT_EQ(fake_update_response_.cohort, value);
   1204 
   1205   EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohortHint, &value));
   1206   EXPECT_EQ(fake_update_response_.cohorthint, value);
   1207 
   1208   EXPECT_TRUE(fake_prefs_.GetString(kPrefsOmahaCohortName, &value));
   1209   EXPECT_EQ(fake_update_response_.cohortname, value);
   1210 }
   1211 
   1212 TEST_F(OmahaRequestActionTest, NoOutputPipeTest) {
   1213   const string http_response(fake_update_response_.GetNoUpdateResponse());
   1214 
   1215   brillo::FakeMessageLoop loop(nullptr);
   1216   loop.SetAsCurrent();
   1217 
   1218   OmahaRequestParams params = request_params_;
   1219   fake_system_state_.set_request_params(&params);
   1220   OmahaRequestAction action(
   1221       &fake_system_state_,
   1222       nullptr,
   1223       std::make_unique<MockHttpFetcher>(http_response.data(),
   1224                                         http_response.size(),
   1225                                         nullptr),
   1226       false);
   1227   OmahaRequestActionTestProcessorDelegate delegate;
   1228   ActionProcessor processor;
   1229   processor.set_delegate(&delegate);
   1230   processor.EnqueueAction(&action);
   1231 
   1232   loop.PostTask(base::Bind(
   1233       [](ActionProcessor* processor) { processor->StartProcessing(); },
   1234       base::Unretained(&processor)));
   1235   loop.Run();
   1236   EXPECT_FALSE(loop.PendingTasks());
   1237   EXPECT_FALSE(processor.IsRunning());
   1238 }
   1239 
   1240 TEST_F(OmahaRequestActionTest, InvalidXmlTest) {
   1241   OmahaResponse response;
   1242   ASSERT_FALSE(
   1243       TestUpdateCheck(nullptr,  // request_params
   1244                       "invalid xml>",
   1245                       -1,
   1246                       false,  // ping_only
   1247                       ErrorCode::kOmahaRequestXMLParseError,
   1248                       metrics::CheckResult::kParsingError,
   1249                       metrics::CheckReaction::kUnset,
   1250                       metrics::DownloadErrorCode::kUnset,
   1251                       &response,
   1252                       nullptr));
   1253   EXPECT_FALSE(response.update_exists);
   1254 }
   1255 
   1256 TEST_F(OmahaRequestActionTest, EmptyResponseTest) {
   1257   OmahaResponse response;
   1258   ASSERT_FALSE(
   1259       TestUpdateCheck(nullptr,  // request_params
   1260                       "",
   1261                       -1,
   1262                       false,  // ping_only
   1263                       ErrorCode::kOmahaRequestEmptyResponseError,
   1264                       metrics::CheckResult::kParsingError,
   1265                       metrics::CheckReaction::kUnset,
   1266                       metrics::DownloadErrorCode::kUnset,
   1267                       &response,
   1268                       nullptr));
   1269   EXPECT_FALSE(response.update_exists);
   1270 }
   1271 
   1272 TEST_F(OmahaRequestActionTest, MissingStatusTest) {
   1273   OmahaResponse response;
   1274   ASSERT_FALSE(TestUpdateCheck(
   1275       nullptr,  // request_params
   1276       "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response protocol=\"3.0\">"
   1277       "<daystart elapsed_seconds=\"100\"/>"
   1278       "<app appid=\"foo\" status=\"ok\">"
   1279       "<ping status=\"ok\"/>"
   1280       "<updatecheck/></app></response>",
   1281       -1,
   1282       false,  // ping_only
   1283       ErrorCode::kOmahaResponseInvalid,
   1284       metrics::CheckResult::kParsingError,
   1285       metrics::CheckReaction::kUnset,
   1286       metrics::DownloadErrorCode::kUnset,
   1287       &response,
   1288       nullptr));
   1289   EXPECT_FALSE(response.update_exists);
   1290 }
   1291 
   1292 TEST_F(OmahaRequestActionTest, InvalidStatusTest) {
   1293   OmahaResponse response;
   1294   ASSERT_FALSE(TestUpdateCheck(
   1295       nullptr,  // request_params
   1296       "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response protocol=\"3.0\">"
   1297       "<daystart elapsed_seconds=\"100\"/>"
   1298       "<app appid=\"foo\" status=\"ok\">"
   1299       "<ping status=\"ok\"/>"
   1300       "<updatecheck status=\"InvalidStatusTest\"/></app></response>",
   1301       -1,
   1302       false,  // ping_only
   1303       ErrorCode::kOmahaResponseInvalid,
   1304       metrics::CheckResult::kParsingError,
   1305       metrics::CheckReaction::kUnset,
   1306       metrics::DownloadErrorCode::kUnset,
   1307       &response,
   1308       nullptr));
   1309   EXPECT_FALSE(response.update_exists);
   1310 }
   1311 
   1312 TEST_F(OmahaRequestActionTest, MissingNodesetTest) {
   1313   OmahaResponse response;
   1314   ASSERT_FALSE(TestUpdateCheck(
   1315       nullptr,  // request_params
   1316       "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response protocol=\"3.0\">"
   1317       "<daystart elapsed_seconds=\"100\"/>"
   1318       "<app appid=\"foo\" status=\"ok\">"
   1319       "<ping status=\"ok\"/>"
   1320       "</app></response>",
   1321       -1,
   1322       false,  // ping_only
   1323       ErrorCode::kOmahaResponseInvalid,
   1324       metrics::CheckResult::kParsingError,
   1325       metrics::CheckReaction::kUnset,
   1326       metrics::DownloadErrorCode::kUnset,
   1327       &response,
   1328       nullptr));
   1329   EXPECT_FALSE(response.update_exists);
   1330 }
   1331 
   1332 TEST_F(OmahaRequestActionTest, MissingFieldTest) {
   1333   string input_response =
   1334       "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response protocol=\"3.0\">"
   1335       "<daystart elapsed_seconds=\"100\"/>"
   1336       // the appid needs to match that in the request params
   1337       "<app appid=\"" +
   1338       fake_update_response_.app_id +
   1339       "\" status=\"ok\">"
   1340       "<updatecheck status=\"ok\">"
   1341       "<urls><url codebase=\"http://missing/field/test/\"/></urls>"
   1342       "<manifest version=\"10.2.3.4\">"
   1343       "<packages><package hash=\"not-used\" name=\"f\" "
   1344       "size=\"587\" hash_sha256=\"lkq34j5345\"/></packages>"
   1345       "<actions><action event=\"postinstall\" "
   1346       "ChromeOSVersion=\"10.2.3.4\" "
   1347       "Prompt=\"false\" "
   1348       "IsDelta=\"true\" "
   1349       "IsDeltaPayload=\"false\" "
   1350       "sha256=\"not-used\" "
   1351       "needsadmin=\"true\" "
   1352       "/></actions></manifest></updatecheck></app></response>";
   1353   LOG(INFO) << "Input Response = " << input_response;
   1354 
   1355   OmahaResponse response;
   1356   ASSERT_TRUE(TestUpdateCheck(nullptr,  // request_params
   1357                               input_response,
   1358                               -1,
   1359                               false,  // ping_only
   1360                               ErrorCode::kSuccess,
   1361                               metrics::CheckResult::kUpdateAvailable,
   1362                               metrics::CheckReaction::kUpdating,
   1363                               metrics::DownloadErrorCode::kUnset,
   1364                               &response,
   1365                               nullptr));
   1366   EXPECT_TRUE(response.update_exists);
   1367   EXPECT_EQ("10.2.3.4", response.version);
   1368   EXPECT_EQ("http://missing/field/test/f",
   1369             response.packages[0].payload_urls[0]);
   1370   EXPECT_EQ("", response.more_info_url);
   1371   EXPECT_EQ("lkq34j5345", response.packages[0].hash);
   1372   EXPECT_EQ(587u, response.packages[0].size);
   1373   EXPECT_FALSE(response.prompt);
   1374   EXPECT_TRUE(response.deadline.empty());
   1375 }
   1376 
   1377 namespace {
   1378 class TerminateEarlyTestProcessorDelegate : public ActionProcessorDelegate {
   1379  public:
   1380   void ProcessingStopped(const ActionProcessor* processor) {
   1381     brillo::MessageLoop::current()->BreakLoop();
   1382   }
   1383 };
   1384 
   1385 void TerminateTransferTestStarter(ActionProcessor* processor) {
   1386   processor->StartProcessing();
   1387   CHECK(processor->IsRunning());
   1388   processor->StopProcessing();
   1389 }
   1390 }  // namespace
   1391 
   1392 TEST_F(OmahaRequestActionTest, TerminateTransferTest) {
   1393   brillo::FakeMessageLoop loop(nullptr);
   1394   loop.SetAsCurrent();
   1395 
   1396   string http_response("doesn't matter");
   1397   OmahaRequestAction action(
   1398       &fake_system_state_,
   1399       nullptr,
   1400       std::make_unique<MockHttpFetcher>(http_response.data(),
   1401                                         http_response.size(),
   1402                                         nullptr),
   1403       false);
   1404   TerminateEarlyTestProcessorDelegate delegate;
   1405   ActionProcessor processor;
   1406   processor.set_delegate(&delegate);
   1407   processor.EnqueueAction(&action);
   1408 
   1409   loop.PostTask(base::Bind(&TerminateTransferTestStarter, &processor));
   1410   loop.Run();
   1411   EXPECT_FALSE(loop.PendingTasks());
   1412 }
   1413 
   1414 TEST_F(OmahaRequestActionTest, XmlEncodeTest) {
   1415   string output;
   1416   EXPECT_TRUE(XmlEncode("ab", &output));
   1417   EXPECT_EQ("ab", output);
   1418   EXPECT_TRUE(XmlEncode("a<b", &output));
   1419   EXPECT_EQ("a&lt;b", output);
   1420   EXPECT_TRUE(XmlEncode("<&>\"\'\\", &output));
   1421   EXPECT_EQ("&lt;&amp;&gt;&quot;&apos;\\", output);
   1422   EXPECT_TRUE(XmlEncode("&lt;&amp;&gt;", &output));
   1423   EXPECT_EQ("&amp;lt;&amp;amp;&amp;gt;", output);
   1424   // Check that unterminated UTF-8 strings are handled properly.
   1425   EXPECT_FALSE(XmlEncode("\xc2", &output));
   1426   // Fail with invalid ASCII-7 chars.
   1427   EXPECT_FALSE(XmlEncode("This is an 'n' with a tilde: \xc3\xb1", &output));
   1428 }
   1429 
   1430 TEST_F(OmahaRequestActionTest, XmlEncodeWithDefaultTest) {
   1431   EXPECT_EQ("&lt;&amp;&gt;", XmlEncodeWithDefault("<&>", "something else"));
   1432   EXPECT_EQ("<not escaped>", XmlEncodeWithDefault("\xc2", "<not escaped>"));
   1433 }
   1434 
   1435 TEST_F(OmahaRequestActionTest, XmlEncodeIsUsedForParams) {
   1436   brillo::Blob post_data;
   1437 
   1438   // Make sure XML Encode is being called on the params
   1439   OmahaRequestParams params(&fake_system_state_,
   1440                             constants::kOmahaPlatformName,
   1441                             OmahaRequestParams::kOsVersion,
   1442                             "testtheservice_pack>",
   1443                             "x86 generic<id",
   1444                             kTestAppId,
   1445                             "0.1.0.0",
   1446                             "en-US",
   1447                             "unittest_track&lt;",
   1448                             "<OEM MODEL>",
   1449                             "ChromeOSFirmware.1.0",
   1450                             "EC100",
   1451                             false,   // delta okay
   1452                             false,   // interactive
   1453                             "http://url",
   1454                             "");     // target_version_prefix
   1455   fake_prefs_.SetString(kPrefsOmahaCohort, "evil\nstring");
   1456   fake_prefs_.SetString(kPrefsOmahaCohortHint, "evil&string\\");
   1457   fake_prefs_.SetString(kPrefsOmahaCohortName,
   1458                         base::JoinString(
   1459                             vector<string>(100, "My spoon is too big."), " "));
   1460   OmahaResponse response;
   1461   ASSERT_FALSE(
   1462       TestUpdateCheck(&params,
   1463                       "invalid xml>",
   1464                       -1,
   1465                       false,  // ping_only
   1466                       ErrorCode::kOmahaRequestXMLParseError,
   1467                       metrics::CheckResult::kParsingError,
   1468                       metrics::CheckReaction::kUnset,
   1469                       metrics::DownloadErrorCode::kUnset,
   1470                       &response,
   1471                       &post_data));
   1472   // convert post_data to string
   1473   string post_str(post_data.begin(), post_data.end());
   1474   EXPECT_NE(string::npos, post_str.find("testtheservice_pack&gt;"));
   1475   EXPECT_EQ(string::npos, post_str.find("testtheservice_pack>"));
   1476   EXPECT_NE(string::npos, post_str.find("x86 generic&lt;id"));
   1477   EXPECT_EQ(string::npos, post_str.find("x86 generic<id"));
   1478   EXPECT_NE(string::npos, post_str.find("unittest_track&amp;lt;"));
   1479   EXPECT_EQ(string::npos, post_str.find("unittest_track&lt;"));
   1480   EXPECT_NE(string::npos, post_str.find("&lt;OEM MODEL&gt;"));
   1481   EXPECT_EQ(string::npos, post_str.find("<OEM MODEL>"));
   1482   EXPECT_NE(string::npos, post_str.find("cohort=\"evil\nstring\""));
   1483   EXPECT_EQ(string::npos, post_str.find("cohorthint=\"evil&string\\\""));
   1484   EXPECT_NE(string::npos, post_str.find("cohorthint=\"evil&amp;string\\\""));
   1485   // Values from Prefs that are too big are removed from the XML instead of
   1486   // encoded.
   1487   EXPECT_EQ(string::npos, post_str.find("cohortname="));
   1488 }
   1489 
   1490 TEST_F(OmahaRequestActionTest, XmlDecodeTest) {
   1491   OmahaResponse response;
   1492   fake_update_response_.deadline = "&lt;20110101";
   1493   fake_update_response_.more_info_url = "testthe&lt;url";
   1494   fake_update_response_.codebase = "testthe&amp;codebase/";
   1495   ASSERT_TRUE(
   1496       TestUpdateCheck(nullptr,  // request_params
   1497                       fake_update_response_.GetUpdateResponse(),
   1498                       -1,
   1499                       false,  // ping_only
   1500                       ErrorCode::kSuccess,
   1501                       metrics::CheckResult::kUpdateAvailable,
   1502                       metrics::CheckReaction::kUpdating,
   1503                       metrics::DownloadErrorCode::kUnset,
   1504                       &response,
   1505                       nullptr));
   1506 
   1507   EXPECT_EQ("testthe<url", response.more_info_url);
   1508   EXPECT_EQ("testthe&codebase/file.signed",
   1509             response.packages[0].payload_urls[0]);
   1510   EXPECT_EQ("<20110101", response.deadline);
   1511 }
   1512 
   1513 TEST_F(OmahaRequestActionTest, ParseIntTest) {
   1514   OmahaResponse response;
   1515   // overflows int32_t:
   1516   fake_update_response_.size = 123123123123123ull;
   1517   ASSERT_TRUE(
   1518       TestUpdateCheck(nullptr,  // request_params
   1519                       fake_update_response_.GetUpdateResponse(),
   1520                       -1,
   1521                       false,  // ping_only
   1522                       ErrorCode::kSuccess,
   1523                       metrics::CheckResult::kUpdateAvailable,
   1524                       metrics::CheckReaction::kUpdating,
   1525                       metrics::DownloadErrorCode::kUnset,
   1526                       &response,
   1527                       nullptr));
   1528 
   1529   EXPECT_EQ(fake_update_response_.size, response.packages[0].size);
   1530 }
   1531 
   1532 TEST_F(OmahaRequestActionTest, FormatUpdateCheckOutputTest) {
   1533   brillo::Blob post_data;
   1534   NiceMock<MockPrefs> prefs;
   1535   fake_system_state_.set_prefs(&prefs);
   1536 
   1537   EXPECT_CALL(prefs, GetString(kPrefsPreviousVersion, _))
   1538       .WillOnce(DoAll(SetArgPointee<1>(string("")), Return(true)));
   1539   // An existing but empty previous version means that we didn't reboot to a new
   1540   // update, therefore, no need to update the previous version.
   1541   EXPECT_CALL(prefs, SetString(kPrefsPreviousVersion, _)).Times(0);
   1542   ASSERT_FALSE(TestUpdateCheck(nullptr,  // request_params
   1543                                "invalid xml>",
   1544                                -1,
   1545                                false,  // ping_only
   1546                                ErrorCode::kOmahaRequestXMLParseError,
   1547                                metrics::CheckResult::kParsingError,
   1548                                metrics::CheckReaction::kUnset,
   1549                                metrics::DownloadErrorCode::kUnset,
   1550                                nullptr,  // response
   1551                                &post_data));
   1552   // convert post_data to string
   1553   string post_str(post_data.begin(), post_data.end());
   1554   EXPECT_NE(post_str.find(
   1555       "        <ping active=\"1\" a=\"-1\" r=\"-1\"></ping>\n"
   1556       "        <updatecheck targetversionprefix=\"\"></updatecheck>\n"),
   1557       string::npos);
   1558   EXPECT_NE(post_str.find("hardware_class=\"OEM MODEL 09235 7471\""),
   1559             string::npos);
   1560   EXPECT_NE(post_str.find("fw_version=\"ChromeOSFirmware.1.0\""),
   1561             string::npos);
   1562   EXPECT_NE(post_str.find("ec_version=\"0X0A1\""),
   1563             string::npos);
   1564   // No <event> tag should be sent if we didn't reboot to an update.
   1565   EXPECT_EQ(post_str.find("<event"), string::npos);
   1566 }
   1567 
   1568 
   1569 TEST_F(OmahaRequestActionTest, FormatSuccessEventOutputTest) {
   1570   brillo::Blob post_data;
   1571   TestEvent(request_params_,
   1572             new OmahaEvent(OmahaEvent::kTypeUpdateDownloadStarted),
   1573             "invalid xml>",
   1574             &post_data);
   1575   // convert post_data to string
   1576   string post_str(post_data.begin(), post_data.end());
   1577   string expected_event = base::StringPrintf(
   1578       "        <event eventtype=\"%d\" eventresult=\"%d\"></event>\n",
   1579       OmahaEvent::kTypeUpdateDownloadStarted,
   1580       OmahaEvent::kResultSuccess);
   1581   EXPECT_NE(post_str.find(expected_event), string::npos);
   1582   EXPECT_EQ(post_str.find("ping"), string::npos);
   1583   EXPECT_EQ(post_str.find("updatecheck"), string::npos);
   1584 }
   1585 
   1586 TEST_F(OmahaRequestActionTest, FormatErrorEventOutputTest) {
   1587   brillo::Blob post_data;
   1588   TestEvent(request_params_,
   1589             new OmahaEvent(OmahaEvent::kTypeDownloadComplete,
   1590                            OmahaEvent::kResultError,
   1591                            ErrorCode::kError),
   1592             "invalid xml>",
   1593             &post_data);
   1594   // convert post_data to string
   1595   string post_str(post_data.begin(), post_data.end());
   1596   string expected_event = base::StringPrintf(
   1597       "        <event eventtype=\"%d\" eventresult=\"%d\" "
   1598       "errorcode=\"%d\"></event>\n",
   1599       OmahaEvent::kTypeDownloadComplete,
   1600       OmahaEvent::kResultError,
   1601       static_cast<int>(ErrorCode::kError));
   1602   EXPECT_NE(post_str.find(expected_event), string::npos);
   1603   EXPECT_EQ(post_str.find("updatecheck"), string::npos);
   1604 }
   1605 
   1606 TEST_F(OmahaRequestActionTest, IsEventTest) {
   1607   string http_response("doesn't matter");
   1608   // Create a copy of the OmahaRequestParams to reuse it later.
   1609   OmahaRequestParams params = request_params_;
   1610   fake_system_state_.set_request_params(&params);
   1611   OmahaRequestAction update_check_action(
   1612       &fake_system_state_,
   1613       nullptr,
   1614       std::make_unique<MockHttpFetcher>(http_response.data(),
   1615                                         http_response.size(),
   1616                                         nullptr),
   1617       false);
   1618   EXPECT_FALSE(update_check_action.IsEvent());
   1619 
   1620   params = request_params_;
   1621   fake_system_state_.set_request_params(&params);
   1622   OmahaRequestAction event_action(
   1623       &fake_system_state_,
   1624       new OmahaEvent(OmahaEvent::kTypeUpdateComplete),
   1625       std::make_unique<MockHttpFetcher>(http_response.data(),
   1626                                         http_response.size(),
   1627                                         nullptr),
   1628       false);
   1629   EXPECT_TRUE(event_action.IsEvent());
   1630 }
   1631 
   1632 TEST_F(OmahaRequestActionTest, FormatDeltaOkayOutputTest) {
   1633   for (int i = 0; i < 2; i++) {
   1634     bool delta_okay = i == 1;
   1635     const char* delta_okay_str = delta_okay ? "true" : "false";
   1636     brillo::Blob post_data;
   1637     OmahaRequestParams params(&fake_system_state_,
   1638                               constants::kOmahaPlatformName,
   1639                               OmahaRequestParams::kOsVersion,
   1640                               "service_pack",
   1641                               "x86-generic",
   1642                               kTestAppId,
   1643                               "0.1.0.0",
   1644                               "en-US",
   1645                               "unittest_track",
   1646                               "OEM MODEL REV 1234",
   1647                               "ChromeOSFirmware.1.0",
   1648                               "EC100",
   1649                               delta_okay,
   1650                               false,  // interactive
   1651                               "http://url",
   1652                               "");    // target_version_prefix
   1653     ASSERT_FALSE(TestUpdateCheck(&params,
   1654                                  "invalid xml>",
   1655                                  -1,
   1656                                  false,  // ping_only
   1657                                  ErrorCode::kOmahaRequestXMLParseError,
   1658                                  metrics::CheckResult::kParsingError,
   1659                                  metrics::CheckReaction::kUnset,
   1660                                  metrics::DownloadErrorCode::kUnset,
   1661                                  nullptr,
   1662                                  &post_data));
   1663     // convert post_data to string
   1664     string post_str(post_data.begin(), post_data.end());
   1665     EXPECT_NE(post_str.find(base::StringPrintf(" delta_okay=\"%s\"",
   1666                                                delta_okay_str)),
   1667               string::npos)
   1668         << "i = " << i;
   1669   }
   1670 }
   1671 
   1672 TEST_F(OmahaRequestActionTest, FormatInteractiveOutputTest) {
   1673   for (int i = 0; i < 2; i++) {
   1674     bool interactive = i == 1;
   1675     const char* interactive_str = interactive ? "ondemandupdate" : "scheduler";
   1676     brillo::Blob post_data;
   1677     FakeSystemState fake_system_state;
   1678     OmahaRequestParams params(&fake_system_state_,
   1679                               constants::kOmahaPlatformName,
   1680                               OmahaRequestParams::kOsVersion,
   1681                               "service_pack",
   1682                               "x86-generic",
   1683                               kTestAppId,
   1684                               "0.1.0.0",
   1685                               "en-US",
   1686                               "unittest_track",
   1687                               "OEM MODEL REV 1234",
   1688                               "ChromeOSFirmware.1.0",
   1689                               "EC100",
   1690                               true,   // delta_okay
   1691                               interactive,
   1692                               "http://url",
   1693                               "");    // target_version_prefix
   1694     ASSERT_FALSE(TestUpdateCheck(&params,
   1695                                  "invalid xml>",
   1696                                  -1,
   1697                                  false,  // ping_only
   1698                                  ErrorCode::kOmahaRequestXMLParseError,
   1699                                  metrics::CheckResult::kParsingError,
   1700                                  metrics::CheckReaction::kUnset,
   1701                                  metrics::DownloadErrorCode::kUnset,
   1702                                  nullptr,
   1703                                  &post_data));
   1704     // convert post_data to string
   1705     string post_str(post_data.begin(), post_data.end());
   1706     EXPECT_NE(post_str.find(base::StringPrintf("installsource=\"%s\"",
   1707                                                interactive_str)),
   1708               string::npos)
   1709         << "i = " << i;
   1710   }
   1711 }
   1712 
   1713 TEST_F(OmahaRequestActionTest, OmahaEventTest) {
   1714   OmahaEvent default_event;
   1715   EXPECT_EQ(OmahaEvent::kTypeUnknown, default_event.type);
   1716   EXPECT_EQ(OmahaEvent::kResultError, default_event.result);
   1717   EXPECT_EQ(ErrorCode::kError, default_event.error_code);
   1718 
   1719   OmahaEvent success_event(OmahaEvent::kTypeUpdateDownloadStarted);
   1720   EXPECT_EQ(OmahaEvent::kTypeUpdateDownloadStarted, success_event.type);
   1721   EXPECT_EQ(OmahaEvent::kResultSuccess, success_event.result);
   1722   EXPECT_EQ(ErrorCode::kSuccess, success_event.error_code);
   1723 
   1724   OmahaEvent error_event(OmahaEvent::kTypeUpdateDownloadFinished,
   1725                          OmahaEvent::kResultError,
   1726                          ErrorCode::kError);
   1727   EXPECT_EQ(OmahaEvent::kTypeUpdateDownloadFinished, error_event.type);
   1728   EXPECT_EQ(OmahaEvent::kResultError, error_event.result);
   1729   EXPECT_EQ(ErrorCode::kError, error_event.error_code);
   1730 }
   1731 
   1732 void OmahaRequestActionTest::PingTest(bool ping_only) {
   1733   NiceMock<MockPrefs> prefs;
   1734   fake_system_state_.set_prefs(&prefs);
   1735   EXPECT_CALL(prefs, GetInt64(kPrefsMetricsCheckLastReportingTime, _))
   1736     .Times(AnyNumber());
   1737   EXPECT_CALL(prefs, SetInt64(_, _)).Times(AnyNumber());
   1738   // Add a few hours to the day difference to test no rounding, etc.
   1739   int64_t five_days_ago =
   1740       (Time::Now() - TimeDelta::FromHours(5 * 24 + 13)).ToInternalValue();
   1741   int64_t six_days_ago =
   1742       (Time::Now() - TimeDelta::FromHours(6 * 24 + 11)).ToInternalValue();
   1743   EXPECT_CALL(prefs, GetInt64(kPrefsInstallDateDays, _))
   1744       .WillOnce(DoAll(SetArgPointee<1>(0), Return(true)));
   1745   EXPECT_CALL(prefs, GetInt64(kPrefsLastActivePingDay, _))
   1746       .WillOnce(DoAll(SetArgPointee<1>(six_days_ago), Return(true)));
   1747   EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _))
   1748       .WillOnce(DoAll(SetArgPointee<1>(five_days_ago), Return(true)));
   1749   brillo::Blob post_data;
   1750   ASSERT_TRUE(TestUpdateCheck(nullptr,  // request_params
   1751                               fake_update_response_.GetNoUpdateResponse(),
   1752                               -1,
   1753                               ping_only,
   1754                               ErrorCode::kSuccess,
   1755                               metrics::CheckResult::kNoUpdateAvailable,
   1756                               metrics::CheckReaction::kUnset,
   1757                               metrics::DownloadErrorCode::kUnset,
   1758                               nullptr,
   1759                               &post_data));
   1760   string post_str(post_data.begin(), post_data.end());
   1761   EXPECT_NE(post_str.find("<ping active=\"1\" a=\"6\" r=\"5\"></ping>"),
   1762             string::npos);
   1763   if (ping_only) {
   1764     EXPECT_EQ(post_str.find("updatecheck"), string::npos);
   1765     EXPECT_EQ(post_str.find("previousversion"), string::npos);
   1766   } else {
   1767     EXPECT_NE(post_str.find("updatecheck"), string::npos);
   1768     EXPECT_NE(post_str.find("previousversion"), string::npos);
   1769   }
   1770 }
   1771 
   1772 TEST_F(OmahaRequestActionTest, PingTestSendOnlyAPing) {
   1773   PingTest(true  /* ping_only */);
   1774 }
   1775 
   1776 TEST_F(OmahaRequestActionTest, PingTestSendAlsoAnUpdateCheck) {
   1777   PingTest(false  /* ping_only */);
   1778 }
   1779 
   1780 TEST_F(OmahaRequestActionTest, ActivePingTest) {
   1781   NiceMock<MockPrefs> prefs;
   1782   fake_system_state_.set_prefs(&prefs);
   1783   EXPECT_CALL(prefs, GetInt64(kPrefsMetricsCheckLastReportingTime, _))
   1784     .Times(AnyNumber());
   1785   EXPECT_CALL(prefs, SetInt64(_, _)).Times(AnyNumber());
   1786   int64_t three_days_ago =
   1787       (Time::Now() - TimeDelta::FromHours(3 * 24 + 12)).ToInternalValue();
   1788   int64_t now = Time::Now().ToInternalValue();
   1789   EXPECT_CALL(prefs, GetInt64(kPrefsInstallDateDays, _))
   1790       .WillOnce(DoAll(SetArgPointee<1>(0), Return(true)));
   1791   EXPECT_CALL(prefs, GetInt64(kPrefsLastActivePingDay, _))
   1792       .WillOnce(DoAll(SetArgPointee<1>(three_days_ago), Return(true)));
   1793   EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _))
   1794       .WillOnce(DoAll(SetArgPointee<1>(now), Return(true)));
   1795   brillo::Blob post_data;
   1796   ASSERT_TRUE(
   1797       TestUpdateCheck(nullptr,  // request_params
   1798                       fake_update_response_.GetNoUpdateResponse(),
   1799                       -1,
   1800                       false,  // ping_only
   1801                       ErrorCode::kSuccess,
   1802                       metrics::CheckResult::kNoUpdateAvailable,
   1803                       metrics::CheckReaction::kUnset,
   1804                       metrics::DownloadErrorCode::kUnset,
   1805                       nullptr,
   1806                       &post_data));
   1807   string post_str(post_data.begin(), post_data.end());
   1808   EXPECT_NE(post_str.find("<ping active=\"1\" a=\"3\"></ping>"),
   1809             string::npos);
   1810 }
   1811 
   1812 TEST_F(OmahaRequestActionTest, RollCallPingTest) {
   1813   NiceMock<MockPrefs> prefs;
   1814   fake_system_state_.set_prefs(&prefs);
   1815   EXPECT_CALL(prefs, GetInt64(kPrefsMetricsCheckLastReportingTime, _))
   1816     .Times(AnyNumber());
   1817   EXPECT_CALL(prefs, SetInt64(_, _)).Times(AnyNumber());
   1818   int64_t four_days_ago =
   1819       (Time::Now() - TimeDelta::FromHours(4 * 24)).ToInternalValue();
   1820   int64_t now = Time::Now().ToInternalValue();
   1821   EXPECT_CALL(prefs, GetInt64(kPrefsInstallDateDays, _))
   1822       .WillOnce(DoAll(SetArgPointee<1>(0), Return(true)));
   1823   EXPECT_CALL(prefs, GetInt64(kPrefsLastActivePingDay, _))
   1824       .WillOnce(DoAll(SetArgPointee<1>(now), Return(true)));
   1825   EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _))
   1826       .WillOnce(DoAll(SetArgPointee<1>(four_days_ago), Return(true)));
   1827   brillo::Blob post_data;
   1828   ASSERT_TRUE(
   1829       TestUpdateCheck(nullptr,  // request_params
   1830                       fake_update_response_.GetNoUpdateResponse(),
   1831                       -1,
   1832                       false,  // ping_only
   1833                       ErrorCode::kSuccess,
   1834                       metrics::CheckResult::kNoUpdateAvailable,
   1835                       metrics::CheckReaction::kUnset,
   1836                       metrics::DownloadErrorCode::kUnset,
   1837                       nullptr,
   1838                       &post_data));
   1839   string post_str(post_data.begin(), post_data.end());
   1840   EXPECT_NE(post_str.find("<ping active=\"1\" r=\"4\"></ping>\n"),
   1841             string::npos);
   1842 }
   1843 
   1844 TEST_F(OmahaRequestActionTest, NoPingTest) {
   1845   NiceMock<MockPrefs> prefs;
   1846   fake_system_state_.set_prefs(&prefs);
   1847   EXPECT_CALL(prefs, GetInt64(kPrefsMetricsCheckLastReportingTime, _))
   1848     .Times(AnyNumber());
   1849   EXPECT_CALL(prefs, SetInt64(_, _)).Times(AnyNumber());
   1850   int64_t one_hour_ago =
   1851       (Time::Now() - TimeDelta::FromHours(1)).ToInternalValue();
   1852   EXPECT_CALL(prefs, GetInt64(kPrefsInstallDateDays, _))
   1853       .WillOnce(DoAll(SetArgPointee<1>(0), Return(true)));
   1854   EXPECT_CALL(prefs, GetInt64(kPrefsLastActivePingDay, _))
   1855       .WillOnce(DoAll(SetArgPointee<1>(one_hour_ago), Return(true)));
   1856   EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _))
   1857       .WillOnce(DoAll(SetArgPointee<1>(one_hour_ago), Return(true)));
   1858   // LastActivePingDay and PrefsLastRollCallPingDay are set even if we didn't
   1859   // send a ping.
   1860   EXPECT_CALL(prefs, SetInt64(kPrefsLastActivePingDay, _))
   1861       .WillOnce(Return(true));
   1862   EXPECT_CALL(prefs, SetInt64(kPrefsLastRollCallPingDay, _))
   1863       .WillOnce(Return(true));
   1864   brillo::Blob post_data;
   1865   ASSERT_TRUE(
   1866       TestUpdateCheck(nullptr,  // request_params
   1867                       fake_update_response_.GetNoUpdateResponse(),
   1868                       -1,
   1869                       false,  // ping_only
   1870                       ErrorCode::kSuccess,
   1871                       metrics::CheckResult::kNoUpdateAvailable,
   1872                       metrics::CheckReaction::kUnset,
   1873                       metrics::DownloadErrorCode::kUnset,
   1874                       nullptr,
   1875                       &post_data));
   1876   string post_str(post_data.begin(), post_data.end());
   1877   EXPECT_EQ(post_str.find("ping"), string::npos);
   1878 }
   1879 
   1880 TEST_F(OmahaRequestActionTest, IgnoreEmptyPingTest) {
   1881   // This test ensures that we ignore empty ping only requests.
   1882   NiceMock<MockPrefs> prefs;
   1883   fake_system_state_.set_prefs(&prefs);
   1884   int64_t now = Time::Now().ToInternalValue();
   1885   EXPECT_CALL(prefs, GetInt64(kPrefsLastActivePingDay, _))
   1886       .WillOnce(DoAll(SetArgPointee<1>(now), Return(true)));
   1887   EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _))
   1888       .WillOnce(DoAll(SetArgPointee<1>(now), Return(true)));
   1889   EXPECT_CALL(prefs, SetInt64(kPrefsLastActivePingDay, _)).Times(0);
   1890   EXPECT_CALL(prefs, SetInt64(kPrefsLastRollCallPingDay, _)).Times(0);
   1891   brillo::Blob post_data;
   1892   EXPECT_TRUE(
   1893       TestUpdateCheck(nullptr,  // request_params
   1894                       fake_update_response_.GetNoUpdateResponse(),
   1895                       -1,
   1896                       true,  // ping_only
   1897                       ErrorCode::kSuccess,
   1898                       metrics::CheckResult::kUnset,
   1899                       metrics::CheckReaction::kUnset,
   1900                       metrics::DownloadErrorCode::kUnset,
   1901                       nullptr,
   1902                       &post_data));
   1903   EXPECT_EQ(0U, post_data.size());
   1904 }
   1905 
   1906 TEST_F(OmahaRequestActionTest, BackInTimePingTest) {
   1907   NiceMock<MockPrefs> prefs;
   1908   fake_system_state_.set_prefs(&prefs);
   1909   EXPECT_CALL(prefs, GetInt64(kPrefsMetricsCheckLastReportingTime, _))
   1910     .Times(AnyNumber());
   1911   EXPECT_CALL(prefs, SetInt64(_, _)).Times(AnyNumber());
   1912   int64_t future =
   1913       (Time::Now() + TimeDelta::FromHours(3 * 24 + 4)).ToInternalValue();
   1914   EXPECT_CALL(prefs, GetInt64(kPrefsInstallDateDays, _))
   1915       .WillOnce(DoAll(SetArgPointee<1>(0), Return(true)));
   1916   EXPECT_CALL(prefs, GetInt64(kPrefsLastActivePingDay, _))
   1917       .WillOnce(DoAll(SetArgPointee<1>(future), Return(true)));
   1918   EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _))
   1919       .WillOnce(DoAll(SetArgPointee<1>(future), Return(true)));
   1920   EXPECT_CALL(prefs, SetInt64(kPrefsLastActivePingDay, _))
   1921       .WillOnce(Return(true));
   1922   EXPECT_CALL(prefs, SetInt64(kPrefsLastRollCallPingDay, _))
   1923       .WillOnce(Return(true));
   1924   brillo::Blob post_data;
   1925   ASSERT_TRUE(
   1926       TestUpdateCheck(nullptr,  // request_params
   1927                       "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response "
   1928                       "protocol=\"3.0\"><daystart elapsed_seconds=\"100\"/>"
   1929                       "<app appid=\"foo\" status=\"ok\"><ping status=\"ok\"/>"
   1930                       "<updatecheck status=\"noupdate\"/></app></response>",
   1931                       -1,
   1932                       false,  // ping_only
   1933                       ErrorCode::kSuccess,
   1934                       metrics::CheckResult::kNoUpdateAvailable,
   1935                       metrics::CheckReaction::kUnset,
   1936                       metrics::DownloadErrorCode::kUnset,
   1937                       nullptr,
   1938                       &post_data));
   1939   string post_str(post_data.begin(), post_data.end());
   1940   EXPECT_EQ(post_str.find("ping"), string::npos);
   1941 }
   1942 
   1943 TEST_F(OmahaRequestActionTest, LastPingDayUpdateTest) {
   1944   // This test checks that the action updates the last ping day to now
   1945   // minus 200 seconds with a slack of 5 seconds. Therefore, the test
   1946   // may fail if it runs for longer than 5 seconds. It shouldn't run
   1947   // that long though.
   1948   int64_t midnight =
   1949       (Time::Now() - TimeDelta::FromSeconds(200)).ToInternalValue();
   1950   int64_t midnight_slack =
   1951       (Time::Now() - TimeDelta::FromSeconds(195)).ToInternalValue();
   1952   NiceMock<MockPrefs> prefs;
   1953   fake_system_state_.set_prefs(&prefs);
   1954   EXPECT_CALL(prefs, GetInt64(_, _)).Times(AnyNumber());
   1955   EXPECT_CALL(prefs, SetInt64(_, _)).Times(AnyNumber());
   1956   EXPECT_CALL(prefs, SetInt64(kPrefsLastActivePingDay,
   1957                               AllOf(Ge(midnight), Le(midnight_slack))))
   1958       .WillOnce(Return(true));
   1959   EXPECT_CALL(prefs, SetInt64(kPrefsLastRollCallPingDay,
   1960                               AllOf(Ge(midnight), Le(midnight_slack))))
   1961       .WillOnce(Return(true));
   1962   ASSERT_TRUE(
   1963       TestUpdateCheck(nullptr,  // request_params
   1964                       "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response "
   1965                       "protocol=\"3.0\"><daystart elapsed_seconds=\"200\"/>"
   1966                       "<app appid=\"foo\" status=\"ok\"><ping status=\"ok\"/>"
   1967                       "<updatecheck status=\"noupdate\"/></app></response>",
   1968                       -1,
   1969                       false,  // ping_only
   1970                       ErrorCode::kSuccess,
   1971                       metrics::CheckResult::kNoUpdateAvailable,
   1972                       metrics::CheckReaction::kUnset,
   1973                       metrics::DownloadErrorCode::kUnset,
   1974                       nullptr,
   1975                       nullptr));
   1976 }
   1977 
   1978 TEST_F(OmahaRequestActionTest, NoElapsedSecondsTest) {
   1979   NiceMock<MockPrefs> prefs;
   1980   fake_system_state_.set_prefs(&prefs);
   1981   EXPECT_CALL(prefs, GetInt64(_, _)).Times(AnyNumber());
   1982   EXPECT_CALL(prefs, SetInt64(_, _)).Times(AnyNumber());
   1983   EXPECT_CALL(prefs, SetInt64(kPrefsLastActivePingDay, _)).Times(0);
   1984   EXPECT_CALL(prefs, SetInt64(kPrefsLastRollCallPingDay, _)).Times(0);
   1985   ASSERT_TRUE(
   1986       TestUpdateCheck(nullptr,  // request_params
   1987                       "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response "
   1988                       "protocol=\"3.0\"><daystart blah=\"200\"/>"
   1989                       "<app appid=\"foo\" status=\"ok\"><ping status=\"ok\"/>"
   1990                       "<updatecheck status=\"noupdate\"/></app></response>",
   1991                       -1,
   1992                       false,  // ping_only
   1993                       ErrorCode::kSuccess,
   1994                       metrics::CheckResult::kNoUpdateAvailable,
   1995                       metrics::CheckReaction::kUnset,
   1996                       metrics::DownloadErrorCode::kUnset,
   1997                       nullptr,
   1998                       nullptr));
   1999 }
   2000 
   2001 TEST_F(OmahaRequestActionTest, BadElapsedSecondsTest) {
   2002   NiceMock<MockPrefs> prefs;
   2003   fake_system_state_.set_prefs(&prefs);
   2004   EXPECT_CALL(prefs, GetInt64(_, _)).Times(AnyNumber());
   2005   EXPECT_CALL(prefs, SetInt64(_, _)).Times(AnyNumber());
   2006   EXPECT_CALL(prefs, SetInt64(kPrefsLastActivePingDay, _)).Times(0);
   2007   EXPECT_CALL(prefs, SetInt64(kPrefsLastRollCallPingDay, _)).Times(0);
   2008   ASSERT_TRUE(
   2009       TestUpdateCheck(nullptr,  // request_params
   2010                       "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response "
   2011                       "protocol=\"3.0\"><daystart elapsed_seconds=\"x\"/>"
   2012                       "<app appid=\"foo\" status=\"ok\"><ping status=\"ok\"/>"
   2013                       "<updatecheck status=\"noupdate\"/></app></response>",
   2014                       -1,
   2015                       false,  // ping_only
   2016                       ErrorCode::kSuccess,
   2017                       metrics::CheckResult::kNoUpdateAvailable,
   2018                       metrics::CheckReaction::kUnset,
   2019                       metrics::DownloadErrorCode::kUnset,
   2020                       nullptr,
   2021                       nullptr));
   2022 }
   2023 
   2024 TEST_F(OmahaRequestActionTest, ParseUpdateCheckAttributesTest) {
   2025   // Test that the "eol" flags is only parsed from the "_eol" attribute and not
   2026   // the "eol" attribute.
   2027   ASSERT_TRUE(
   2028       TestUpdateCheck(nullptr,  // request_params
   2029                       "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response "
   2030                       "protocol=\"3.0\"><app appid=\"foo\" status=\"ok\">"
   2031                       "<ping status=\"ok\"/><updatecheck status=\"noupdate\" "
   2032                       "_eol=\"security-only\" eol=\"eol\" _foo=\"bar\"/>"
   2033                       "</app></response>",
   2034                       -1,
   2035                       false,  // ping_only
   2036                       ErrorCode::kSuccess,
   2037                       metrics::CheckResult::kNoUpdateAvailable,
   2038                       metrics::CheckReaction::kUnset,
   2039                       metrics::DownloadErrorCode::kUnset,
   2040                       nullptr,
   2041                       nullptr));
   2042   string eol_pref;
   2043   EXPECT_TRUE(
   2044       fake_system_state_.prefs()->GetString(kPrefsOmahaEolStatus, &eol_pref));
   2045   // Note that the eol="eol" attribute should be ignored and the _eol should be
   2046   // used instead.
   2047   EXPECT_EQ("security-only", eol_pref);
   2048 }
   2049 
   2050 TEST_F(OmahaRequestActionTest, NoUniqueIDTest) {
   2051   brillo::Blob post_data;
   2052   ASSERT_FALSE(TestUpdateCheck(nullptr,  // request_params
   2053                                "invalid xml>",
   2054                                -1,
   2055                                false,  // ping_only
   2056                                ErrorCode::kOmahaRequestXMLParseError,
   2057                                metrics::CheckResult::kParsingError,
   2058                                metrics::CheckReaction::kUnset,
   2059                                metrics::DownloadErrorCode::kUnset,
   2060                                nullptr,  // response
   2061                                &post_data));
   2062   // convert post_data to string
   2063   string post_str(post_data.begin(), post_data.end());
   2064   EXPECT_EQ(post_str.find("machineid="), string::npos);
   2065   EXPECT_EQ(post_str.find("userid="), string::npos);
   2066 }
   2067 
   2068 TEST_F(OmahaRequestActionTest, NetworkFailureTest) {
   2069   OmahaResponse response;
   2070   const int http_error_code =
   2071       static_cast<int>(ErrorCode::kOmahaRequestHTTPResponseBase) + 501;
   2072   ASSERT_FALSE(
   2073       TestUpdateCheck(nullptr,  // request_params
   2074                       "",
   2075                       501,
   2076                       false,  // ping_only
   2077                       static_cast<ErrorCode>(http_error_code),
   2078                       metrics::CheckResult::kDownloadError,
   2079                       metrics::CheckReaction::kUnset,
   2080                       static_cast<metrics::DownloadErrorCode>(501),
   2081                       &response,
   2082                       nullptr));
   2083   EXPECT_FALSE(response.update_exists);
   2084 }
   2085 
   2086 TEST_F(OmahaRequestActionTest, NetworkFailureBadHTTPCodeTest) {
   2087   OmahaResponse response;
   2088   const int http_error_code =
   2089       static_cast<int>(ErrorCode::kOmahaRequestHTTPResponseBase) + 999;
   2090   ASSERT_FALSE(
   2091       TestUpdateCheck(nullptr,  // request_params
   2092                       "",
   2093                       1500,
   2094                       false,  // ping_only
   2095                       static_cast<ErrorCode>(http_error_code),
   2096                       metrics::CheckResult::kDownloadError,
   2097                       metrics::CheckReaction::kUnset,
   2098                       metrics::DownloadErrorCode::kHttpStatusOther,
   2099                       &response,
   2100                       nullptr));
   2101   EXPECT_FALSE(response.update_exists);
   2102 }
   2103 
   2104 TEST_F(OmahaRequestActionTest, TestUpdateFirstSeenAtGetsPersistedFirstTime) {
   2105   OmahaResponse response;
   2106   OmahaRequestParams params = request_params_;
   2107   params.set_wall_clock_based_wait_enabled(true);
   2108   params.set_waiting_period(TimeDelta().FromDays(1));
   2109   params.set_update_check_count_wait_enabled(false);
   2110 
   2111   Time arbitrary_date;
   2112   ASSERT_TRUE(Time::FromString("6/4/1989", &arbitrary_date));
   2113   fake_system_state_.fake_clock()->SetWallclockTime(arbitrary_date);
   2114   ASSERT_FALSE(TestUpdateCheck(&params,
   2115                                fake_update_response_.GetUpdateResponse(),
   2116                                -1,
   2117                                false,  // ping_only
   2118                                ErrorCode::kOmahaUpdateDeferredPerPolicy,
   2119                                metrics::CheckResult::kUpdateAvailable,
   2120                                metrics::CheckReaction::kDeferring,
   2121                                metrics::DownloadErrorCode::kUnset,
   2122                                &response,
   2123                                nullptr));
   2124 
   2125   int64_t timestamp = 0;
   2126   ASSERT_TRUE(fake_prefs_.GetInt64(kPrefsUpdateFirstSeenAt, &timestamp));
   2127   EXPECT_EQ(arbitrary_date.ToInternalValue(), timestamp);
   2128   EXPECT_FALSE(response.update_exists);
   2129 
   2130   // Verify if we are interactive check we don't defer.
   2131   params.set_interactive(true);
   2132   ASSERT_TRUE(TestUpdateCheck(&params,
   2133                               fake_update_response_.GetUpdateResponse(),
   2134                               -1,
   2135                               false,  // ping_only
   2136                               ErrorCode::kSuccess,
   2137                               metrics::CheckResult::kUpdateAvailable,
   2138                               metrics::CheckReaction::kUpdating,
   2139                               metrics::DownloadErrorCode::kUnset,
   2140                               &response,
   2141                               nullptr));
   2142   EXPECT_TRUE(response.update_exists);
   2143 }
   2144 
   2145 TEST_F(OmahaRequestActionTest, TestUpdateFirstSeenAtGetsUsedIfAlreadyPresent) {
   2146   OmahaResponse response;
   2147   OmahaRequestParams params = request_params_;
   2148   params.set_wall_clock_based_wait_enabled(true);
   2149   params.set_waiting_period(TimeDelta().FromDays(1));
   2150   params.set_update_check_count_wait_enabled(false);
   2151 
   2152   Time t1, t2;
   2153   ASSERT_TRUE(Time::FromString("1/1/2012", &t1));
   2154   ASSERT_TRUE(Time::FromString("1/3/2012", &t2));
   2155   ASSERT_TRUE(
   2156       fake_prefs_.SetInt64(kPrefsUpdateFirstSeenAt, t1.ToInternalValue()));
   2157   fake_system_state_.fake_clock()->SetWallclockTime(t2);
   2158   ASSERT_TRUE(TestUpdateCheck(&params,
   2159                               fake_update_response_.GetUpdateResponse(),
   2160                               -1,
   2161                               false,  // ping_only
   2162                               ErrorCode::kSuccess,
   2163                               metrics::CheckResult::kUpdateAvailable,
   2164                               metrics::CheckReaction::kUpdating,
   2165                               metrics::DownloadErrorCode::kUnset,
   2166                               &response,
   2167                               nullptr));
   2168 
   2169   EXPECT_TRUE(response.update_exists);
   2170 
   2171   // Make sure the timestamp t1 is unchanged showing that it was reused.
   2172   int64_t timestamp = 0;
   2173   ASSERT_TRUE(fake_prefs_.GetInt64(kPrefsUpdateFirstSeenAt, &timestamp));
   2174   ASSERT_TRUE(timestamp == t1.ToInternalValue());
   2175 }
   2176 
   2177 TEST_F(OmahaRequestActionTest, TestChangingToMoreStableChannel) {
   2178   // Create a uniquely named test directory.
   2179   base::ScopedTempDir tempdir;
   2180   ASSERT_TRUE(tempdir.CreateUniqueTempDir());
   2181 
   2182   brillo::Blob post_data;
   2183   OmahaRequestParams params(&fake_system_state_);
   2184   params.set_root(tempdir.GetPath().value());
   2185   params.set_app_id("{22222222-2222-2222-2222-222222222222}");
   2186   params.set_app_version("1.2.3.4");
   2187   params.set_product_components("o.bundle=1");
   2188   params.set_current_channel("canary-channel");
   2189   EXPECT_TRUE(params.SetTargetChannel("stable-channel", true, nullptr));
   2190   params.UpdateDownloadChannel();
   2191   EXPECT_TRUE(params.ShouldPowerwash());
   2192   ASSERT_FALSE(TestUpdateCheck(&params,
   2193                                "invalid xml>",
   2194                                -1,
   2195                                false,  // ping_only
   2196                                ErrorCode::kOmahaRequestXMLParseError,
   2197                                metrics::CheckResult::kParsingError,
   2198                                metrics::CheckReaction::kUnset,
   2199                                metrics::DownloadErrorCode::kUnset,
   2200                                nullptr,  // response
   2201                                &post_data));
   2202   // convert post_data to string
   2203   string post_str(post_data.begin(), post_data.end());
   2204   EXPECT_NE(string::npos, post_str.find(
   2205       "appid=\"{22222222-2222-2222-2222-222222222222}\" "
   2206       "version=\"0.0.0.0\" from_version=\"1.2.3.4\" "
   2207       "track=\"stable-channel\" from_track=\"canary-channel\" "));
   2208   EXPECT_EQ(string::npos, post_str.find("o.bundle"));
   2209 }
   2210 
   2211 TEST_F(OmahaRequestActionTest, TestChangingToLessStableChannel) {
   2212   // Create a uniquely named test directory.
   2213   base::ScopedTempDir tempdir;
   2214   ASSERT_TRUE(tempdir.CreateUniqueTempDir());
   2215 
   2216   brillo::Blob post_data;
   2217   OmahaRequestParams params(&fake_system_state_);
   2218   params.set_root(tempdir.GetPath().value());
   2219   params.set_app_id("{11111111-1111-1111-1111-111111111111}");
   2220   params.set_app_version("5.6.7.8");
   2221   params.set_product_components("o.bundle=1");
   2222   params.set_current_channel("stable-channel");
   2223   EXPECT_TRUE(params.SetTargetChannel("canary-channel", false, nullptr));
   2224   params.UpdateDownloadChannel();
   2225   EXPECT_FALSE(params.ShouldPowerwash());
   2226   ASSERT_FALSE(TestUpdateCheck(&params,
   2227                                "invalid xml>",
   2228                                -1,
   2229                                false,  // ping_only
   2230                                ErrorCode::kOmahaRequestXMLParseError,
   2231                                metrics::CheckResult::kParsingError,
   2232                                metrics::CheckReaction::kUnset,
   2233                                metrics::DownloadErrorCode::kUnset,
   2234                                nullptr,  // response
   2235                                &post_data));
   2236   // convert post_data to string
   2237   string post_str(post_data.begin(), post_data.end());
   2238   EXPECT_NE(string::npos, post_str.find(
   2239       "appid=\"{11111111-1111-1111-1111-111111111111}\" "
   2240       "version=\"5.6.7.8\" "
   2241       "track=\"canary-channel\" from_track=\"stable-channel\""));
   2242   EXPECT_EQ(string::npos, post_str.find("from_version"));
   2243   EXPECT_NE(string::npos, post_str.find("o.bundle.version=\"1\""));
   2244 }
   2245 
   2246 // Checks that the initial ping with a=-1 r=-1 is not send when the device
   2247 // was powerwashed.
   2248 TEST_F(OmahaRequestActionTest, PingWhenPowerwashed) {
   2249   fake_prefs_.SetString(kPrefsPreviousVersion, "");
   2250 
   2251   // Flag that the device was powerwashed in the past.
   2252   fake_system_state_.fake_hardware()->SetPowerwashCount(1);
   2253 
   2254   brillo::Blob post_data;
   2255   ASSERT_TRUE(
   2256       TestUpdateCheck(nullptr,  // request_params
   2257                       fake_update_response_.GetNoUpdateResponse(),
   2258                       -1,
   2259                       false,  // ping_only
   2260                       ErrorCode::kSuccess,
   2261                       metrics::CheckResult::kNoUpdateAvailable,
   2262                       metrics::CheckReaction::kUnset,
   2263                       metrics::DownloadErrorCode::kUnset,
   2264                       nullptr,
   2265                       &post_data));
   2266   // We shouldn't send a ping in this case since powerwash > 0.
   2267   string post_str(post_data.begin(), post_data.end());
   2268   EXPECT_EQ(string::npos, post_str.find("<ping"));
   2269 }
   2270 
   2271 // Checks that the initial ping with a=-1 r=-1 is not send when the device
   2272 // first_active_omaha_ping_sent is set.
   2273 TEST_F(OmahaRequestActionTest, PingWhenFirstActiveOmahaPingIsSent) {
   2274   fake_prefs_.SetString(kPrefsPreviousVersion, "");
   2275 
   2276   // Flag that the device was not powerwashed in the past.
   2277   fake_system_state_.fake_hardware()->SetPowerwashCount(0);
   2278 
   2279   // Flag that the device has sent first active ping in the past.
   2280   fake_system_state_.fake_hardware()->SetFirstActiveOmahaPingSent();
   2281 
   2282   brillo::Blob post_data;
   2283   ASSERT_TRUE(
   2284       TestUpdateCheck(nullptr,  // request_params
   2285                       fake_update_response_.GetNoUpdateResponse(),
   2286                       -1,
   2287                       false,  // ping_only
   2288                       ErrorCode::kSuccess,
   2289                       metrics::CheckResult::kNoUpdateAvailable,
   2290                       metrics::CheckReaction::kUnset,
   2291                       metrics::DownloadErrorCode::kUnset,
   2292                       nullptr,
   2293                       &post_data));
   2294   // We shouldn't send a ping in this case since
   2295   // first_active_omaha_ping_sent=true
   2296   string post_str(post_data.begin(), post_data.end());
   2297   EXPECT_EQ(string::npos, post_str.find("<ping"));
   2298 }
   2299 
   2300 // Checks that the event 54 is sent on a reboot to a new update.
   2301 TEST_F(OmahaRequestActionTest, RebootAfterUpdateEvent) {
   2302   // Flag that the device was updated in a previous boot.
   2303   fake_prefs_.SetString(kPrefsPreviousVersion, "1.2.3.4");
   2304 
   2305   brillo::Blob post_data;
   2306   ASSERT_TRUE(
   2307       TestUpdateCheck(nullptr,  // request_params
   2308                       fake_update_response_.GetNoUpdateResponse(),
   2309                       -1,
   2310                       false,  // ping_only
   2311                       ErrorCode::kSuccess,
   2312                       metrics::CheckResult::kNoUpdateAvailable,
   2313                       metrics::CheckReaction::kUnset,
   2314                       metrics::DownloadErrorCode::kUnset,
   2315                       nullptr,
   2316                       &post_data));
   2317   string post_str(post_data.begin(), post_data.end());
   2318 
   2319   // An event 54 is included and has the right version.
   2320   EXPECT_NE(string::npos,
   2321             post_str.find(base::StringPrintf(
   2322                               "<event eventtype=\"%d\"",
   2323                               OmahaEvent::kTypeRebootedAfterUpdate)));
   2324   EXPECT_NE(string::npos,
   2325             post_str.find("previousversion=\"1.2.3.4\"></event>"));
   2326 
   2327   // The previous version flag should have been removed.
   2328   EXPECT_TRUE(fake_prefs_.Exists(kPrefsPreviousVersion));
   2329   string prev_version;
   2330   EXPECT_TRUE(fake_prefs_.GetString(kPrefsPreviousVersion, &prev_version));
   2331   EXPECT_TRUE(prev_version.empty());
   2332 }
   2333 
   2334 void OmahaRequestActionTest::P2PTest(
   2335     bool initial_allow_p2p_for_downloading,
   2336     bool initial_allow_p2p_for_sharing,
   2337     bool omaha_disable_p2p_for_downloading,
   2338     bool omaha_disable_p2p_for_sharing,
   2339     bool payload_state_allow_p2p_attempt,
   2340     bool expect_p2p_client_lookup,
   2341     const string& p2p_client_result_url,
   2342     bool expected_allow_p2p_for_downloading,
   2343     bool expected_allow_p2p_for_sharing,
   2344     const string& expected_p2p_url) {
   2345   OmahaResponse response;
   2346   OmahaRequestParams request_params = request_params_;
   2347   bool actual_allow_p2p_for_downloading = initial_allow_p2p_for_downloading;
   2348   bool actual_allow_p2p_for_sharing = initial_allow_p2p_for_sharing;
   2349   string actual_p2p_url;
   2350 
   2351   MockPayloadState mock_payload_state;
   2352   fake_system_state_.set_payload_state(&mock_payload_state);
   2353   EXPECT_CALL(mock_payload_state, P2PAttemptAllowed())
   2354       .WillRepeatedly(Return(payload_state_allow_p2p_attempt));
   2355   EXPECT_CALL(mock_payload_state, GetUsingP2PForDownloading())
   2356       .WillRepeatedly(ReturnPointee(&actual_allow_p2p_for_downloading));
   2357   EXPECT_CALL(mock_payload_state, GetUsingP2PForSharing())
   2358       .WillRepeatedly(ReturnPointee(&actual_allow_p2p_for_sharing));
   2359   EXPECT_CALL(mock_payload_state, SetUsingP2PForDownloading(_))
   2360       .WillRepeatedly(SaveArg<0>(&actual_allow_p2p_for_downloading));
   2361   EXPECT_CALL(mock_payload_state, SetUsingP2PForSharing(_))
   2362       .WillRepeatedly(SaveArg<0>(&actual_allow_p2p_for_sharing));
   2363   EXPECT_CALL(mock_payload_state, SetP2PUrl(_))
   2364       .WillRepeatedly(SaveArg<0>(&actual_p2p_url));
   2365 
   2366   MockP2PManager mock_p2p_manager;
   2367   fake_system_state_.set_p2p_manager(&mock_p2p_manager);
   2368   mock_p2p_manager.fake().SetLookupUrlForFileResult(p2p_client_result_url);
   2369 
   2370   TimeDelta timeout = TimeDelta::FromSeconds(kMaxP2PNetworkWaitTimeSeconds);
   2371   EXPECT_CALL(mock_p2p_manager, LookupUrlForFile(_, _, timeout, _))
   2372       .Times(expect_p2p_client_lookup ? 1 : 0);
   2373 
   2374   fake_update_response_.disable_p2p_for_downloading =
   2375       omaha_disable_p2p_for_downloading;
   2376   fake_update_response_.disable_p2p_for_sharing = omaha_disable_p2p_for_sharing;
   2377   ASSERT_TRUE(
   2378       TestUpdateCheck(&request_params,
   2379                       fake_update_response_.GetUpdateResponse(),
   2380                       -1,
   2381                       false,  // ping_only
   2382                       ErrorCode::kSuccess,
   2383                       metrics::CheckResult::kUpdateAvailable,
   2384                       metrics::CheckReaction::kUpdating,
   2385                       metrics::DownloadErrorCode::kUnset,
   2386                       &response,
   2387                       nullptr));
   2388   EXPECT_TRUE(response.update_exists);
   2389 
   2390   EXPECT_EQ(omaha_disable_p2p_for_downloading,
   2391             response.disable_p2p_for_downloading);
   2392   EXPECT_EQ(omaha_disable_p2p_for_sharing,
   2393             response.disable_p2p_for_sharing);
   2394 
   2395   EXPECT_EQ(expected_allow_p2p_for_downloading,
   2396             actual_allow_p2p_for_downloading);
   2397   EXPECT_EQ(expected_allow_p2p_for_sharing, actual_allow_p2p_for_sharing);
   2398   EXPECT_EQ(expected_p2p_url, actual_p2p_url);
   2399 }
   2400 
   2401 TEST_F(OmahaRequestActionTest, P2PWithPeer) {
   2402   P2PTest(true,                   // initial_allow_p2p_for_downloading
   2403           true,                   // initial_allow_p2p_for_sharing
   2404           false,                  // omaha_disable_p2p_for_downloading
   2405           false,                  // omaha_disable_p2p_for_sharing
   2406           true,                   // payload_state_allow_p2p_attempt
   2407           true,                   // expect_p2p_client_lookup
   2408           "http://1.3.5.7/p2p",   // p2p_client_result_url
   2409           true,                   // expected_allow_p2p_for_downloading
   2410           true,                   // expected_allow_p2p_for_sharing
   2411           "http://1.3.5.7/p2p");  // expected_p2p_url
   2412 }
   2413 
   2414 TEST_F(OmahaRequestActionTest, P2PWithoutPeer) {
   2415   P2PTest(true,                   // initial_allow_p2p_for_downloading
   2416           true,                   // initial_allow_p2p_for_sharing
   2417           false,                  // omaha_disable_p2p_for_downloading
   2418           false,                  // omaha_disable_p2p_for_sharing
   2419           true,                   // payload_state_allow_p2p_attempt
   2420           true,                   // expect_p2p_client_lookup
   2421           "",                     // p2p_client_result_url
   2422           false,                  // expected_allow_p2p_for_downloading
   2423           true,                   // expected_allow_p2p_for_sharing
   2424           "");                    // expected_p2p_url
   2425 }
   2426 
   2427 TEST_F(OmahaRequestActionTest, P2PDownloadNotAllowed) {
   2428   P2PTest(false,                  // initial_allow_p2p_for_downloading
   2429           true,                   // initial_allow_p2p_for_sharing
   2430           false,                  // omaha_disable_p2p_for_downloading
   2431           false,                  // omaha_disable_p2p_for_sharing
   2432           true,                   // payload_state_allow_p2p_attempt
   2433           false,                  // expect_p2p_client_lookup
   2434           "unset",                // p2p_client_result_url
   2435           false,                  // expected_allow_p2p_for_downloading
   2436           true,                   // expected_allow_p2p_for_sharing
   2437           "");                    // expected_p2p_url
   2438 }
   2439 
   2440 TEST_F(OmahaRequestActionTest, P2PWithPeerDownloadDisabledByOmaha) {
   2441   P2PTest(true,                   // initial_allow_p2p_for_downloading
   2442           true,                   // initial_allow_p2p_for_sharing
   2443           true,                   // omaha_disable_p2p_for_downloading
   2444           false,                  // omaha_disable_p2p_for_sharing
   2445           true,                   // payload_state_allow_p2p_attempt
   2446           false,                  // expect_p2p_client_lookup
   2447           "unset",                // p2p_client_result_url
   2448           false,                  // expected_allow_p2p_for_downloading
   2449           true,                   // expected_allow_p2p_for_sharing
   2450           "");                    // expected_p2p_url
   2451 }
   2452 
   2453 TEST_F(OmahaRequestActionTest, P2PWithPeerSharingDisabledByOmaha) {
   2454   P2PTest(true,                   // initial_allow_p2p_for_downloading
   2455           true,                   // initial_allow_p2p_for_sharing
   2456           false,                  // omaha_disable_p2p_for_downloading
   2457           true,                   // omaha_disable_p2p_for_sharing
   2458           true,                   // payload_state_allow_p2p_attempt
   2459           true,                   // expect_p2p_client_lookup
   2460           "http://1.3.5.7/p2p",   // p2p_client_result_url
   2461           true,                   // expected_allow_p2p_for_downloading
   2462           false,                  // expected_allow_p2p_for_sharing
   2463           "http://1.3.5.7/p2p");  // expected_p2p_url
   2464 }
   2465 
   2466 TEST_F(OmahaRequestActionTest, P2PWithPeerBothDisabledByOmaha) {
   2467   P2PTest(true,                   // initial_allow_p2p_for_downloading
   2468           true,                   // initial_allow_p2p_for_sharing
   2469           true,                   // omaha_disable_p2p_for_downloading
   2470           true,                   // omaha_disable_p2p_for_sharing
   2471           true,                   // payload_state_allow_p2p_attempt
   2472           false,                  // expect_p2p_client_lookup
   2473           "unset",                // p2p_client_result_url
   2474           false,                  // expected_allow_p2p_for_downloading
   2475           false,                  // expected_allow_p2p_for_sharing
   2476           "");                    // expected_p2p_url
   2477 }
   2478 
   2479 bool OmahaRequestActionTest::InstallDateParseHelper(const string &elapsed_days,
   2480                                                     OmahaResponse *response) {
   2481   fake_update_response_.elapsed_days = elapsed_days;
   2482   return
   2483       TestUpdateCheck(nullptr,  // request_params
   2484                       fake_update_response_.GetUpdateResponse(),
   2485                       -1,
   2486                       false,  // ping_only
   2487                       ErrorCode::kSuccess,
   2488                       metrics::CheckResult::kUpdateAvailable,
   2489                       metrics::CheckReaction::kUpdating,
   2490                       metrics::DownloadErrorCode::kUnset,
   2491                       response,
   2492                       nullptr);
   2493 }
   2494 
   2495 TEST_F(OmahaRequestActionTest, ParseInstallDateFromResponse) {
   2496   OmahaResponse response;
   2497 
   2498   // Simulate a successful update check that happens during OOBE.  The
   2499   // deadline in the response is needed to force the update attempt to
   2500   // occur; responses without a deadline seen during OOBE will normally
   2501   // return ErrorCode::kNonCriticalUpdateInOOBE.
   2502   fake_system_state_.fake_hardware()->UnsetIsOOBEComplete();
   2503   fake_update_response_.deadline = "20101020";
   2504 
   2505   // Check that we parse elapsed_days in the Omaha Response correctly.
   2506   // and that the kPrefsInstallDateDays value is written to.
   2507   EXPECT_FALSE(fake_prefs_.Exists(kPrefsInstallDateDays));
   2508   EXPECT_TRUE(InstallDateParseHelper("42", &response));
   2509   EXPECT_TRUE(response.update_exists);
   2510   EXPECT_EQ(42, response.install_date_days);
   2511   EXPECT_TRUE(fake_prefs_.Exists(kPrefsInstallDateDays));
   2512   int64_t prefs_days;
   2513   EXPECT_TRUE(fake_prefs_.GetInt64(kPrefsInstallDateDays, &prefs_days));
   2514   EXPECT_EQ(prefs_days, 42);
   2515 
   2516   // If there already is a value set, we shouldn't do anything.
   2517   EXPECT_TRUE(InstallDateParseHelper("7", &response));
   2518   EXPECT_TRUE(response.update_exists);
   2519   EXPECT_EQ(7, response.install_date_days);
   2520   EXPECT_TRUE(fake_prefs_.GetInt64(kPrefsInstallDateDays, &prefs_days));
   2521   EXPECT_EQ(prefs_days, 42);
   2522 
   2523   // Note that elapsed_days is not necessarily divisible by 7 so check
   2524   // that we round down correctly when populating kPrefsInstallDateDays.
   2525   EXPECT_TRUE(fake_prefs_.Delete(kPrefsInstallDateDays));
   2526   EXPECT_TRUE(InstallDateParseHelper("23", &response));
   2527   EXPECT_TRUE(response.update_exists);
   2528   EXPECT_EQ(23, response.install_date_days);
   2529   EXPECT_TRUE(fake_prefs_.GetInt64(kPrefsInstallDateDays, &prefs_days));
   2530   EXPECT_EQ(prefs_days, 21);
   2531 
   2532   // Check that we correctly handle elapsed_days not being included in
   2533   // the Omaha Response.
   2534   EXPECT_TRUE(InstallDateParseHelper("", &response));
   2535   EXPECT_TRUE(response.update_exists);
   2536   EXPECT_EQ(-1, response.install_date_days);
   2537 }
   2538 
   2539 // If there is no prefs and OOBE is not complete, we should not
   2540 // report anything to Omaha.
   2541 TEST_F(OmahaRequestActionTest, GetInstallDateWhenNoPrefsNorOOBE) {
   2542   fake_system_state_.fake_hardware()->UnsetIsOOBEComplete();
   2543   EXPECT_EQ(OmahaRequestAction::GetInstallDate(&fake_system_state_), -1);
   2544   EXPECT_FALSE(fake_prefs_.Exists(kPrefsInstallDateDays));
   2545 }
   2546 
   2547 // If OOBE is complete and happened on a valid date (e.g. after Jan
   2548 // 1 2007 0:00 PST), that date should be used and written to
   2549 // prefs. However, first try with an invalid date and check we do
   2550 // nothing.
   2551 TEST_F(OmahaRequestActionTest, GetInstallDateWhenOOBECompletedWithInvalidDate) {
   2552   Time oobe_date = Time::FromTimeT(42);  // Dec 31, 1969 16:00:42 PST.
   2553   fake_system_state_.fake_hardware()->SetIsOOBEComplete(oobe_date);
   2554   EXPECT_EQ(OmahaRequestAction::GetInstallDate(&fake_system_state_), -1);
   2555   EXPECT_FALSE(fake_prefs_.Exists(kPrefsInstallDateDays));
   2556 }
   2557 
   2558 // Then check with a valid date. The date Jan 20, 2007 0:00 PST
   2559 // should yield an InstallDate of 14.
   2560 TEST_F(OmahaRequestActionTest, GetInstallDateWhenOOBECompletedWithValidDate) {
   2561   Time oobe_date = Time::FromTimeT(1169280000);  // Jan 20, 2007 0:00 PST.
   2562   fake_system_state_.fake_hardware()->SetIsOOBEComplete(oobe_date);
   2563   EXPECT_EQ(OmahaRequestAction::GetInstallDate(&fake_system_state_), 14);
   2564   EXPECT_TRUE(fake_prefs_.Exists(kPrefsInstallDateDays));
   2565 
   2566   int64_t prefs_days;
   2567   EXPECT_TRUE(fake_prefs_.GetInt64(kPrefsInstallDateDays, &prefs_days));
   2568   EXPECT_EQ(prefs_days, 14);
   2569 }
   2570 
   2571 // Now that we have a valid date in prefs, check that we keep using
   2572 // that even if OOBE date reports something else. The date Jan 30,
   2573 // 2007 0:00 PST should yield an InstallDate of 28... but since
   2574 // there's a prefs file, we should still get 14.
   2575 TEST_F(OmahaRequestActionTest, GetInstallDateWhenOOBECompletedDateChanges) {
   2576   // Set a valid date in the prefs first.
   2577   EXPECT_TRUE(fake_prefs_.SetInt64(kPrefsInstallDateDays, 14));
   2578 
   2579   Time oobe_date = Time::FromTimeT(1170144000);  // Jan 30, 2007 0:00 PST.
   2580   fake_system_state_.fake_hardware()->SetIsOOBEComplete(oobe_date);
   2581   EXPECT_EQ(OmahaRequestAction::GetInstallDate(&fake_system_state_), 14);
   2582 
   2583   int64_t prefs_days;
   2584   EXPECT_TRUE(fake_prefs_.GetInt64(kPrefsInstallDateDays, &prefs_days));
   2585   EXPECT_EQ(prefs_days, 14);
   2586 
   2587   // If we delete the prefs file, we should get 28 days.
   2588   EXPECT_TRUE(fake_prefs_.Delete(kPrefsInstallDateDays));
   2589   EXPECT_EQ(OmahaRequestAction::GetInstallDate(&fake_system_state_), 28);
   2590   EXPECT_TRUE(fake_prefs_.GetInt64(kPrefsInstallDateDays, &prefs_days));
   2591   EXPECT_EQ(prefs_days, 28);
   2592 }
   2593 
   2594 }  // namespace chromeos_update_engine
   2595