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