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 {
GetNoUpdateResponse__anonebf7ac180111::FakeUpdateResponse75   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 
GetUpdateResponse__anonebf7ac180111::FakeUpdateResponse91   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.
GetPayloadUrl__anonebf7ac180111::FakeUpdateResponse123   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:
SetUp()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:
OmahaRequestActionTestProcessorDelegate()241   OmahaRequestActionTestProcessorDelegate()
242       : expected_code_(ErrorCode::kSuccess) {}
~OmahaRequestActionTestProcessorDelegate()243   ~OmahaRequestActionTestProcessorDelegate() override {
244   }
ProcessingDone(const ActionProcessor * processor,ErrorCode code)245   void ProcessingDone(const ActionProcessor* processor,
246                       ErrorCode code) override {
247     brillo::MessageLoop::current()->BreakLoop();
248   }
249 
ActionCompleted(ActionProcessor * processor,AbstractAction * action,ErrorCode code)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:
OutputObjectCollectorAction()276   OutputObjectCollectorAction() : has_input_object_(false) {}
PerformAction()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
TerminateProcessing()285   void TerminateProcessing() {
286     CHECK(false);
287   }
288   // Debugging/logging
StaticType()289   static string StaticType() {
290     return "OutputObjectCollectorAction";
291   }
Type() const292   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 
TestUpdateCheck(OmahaRequestParams * request_params,const string & http_response,int fail_http_response_code,bool ping_only,ErrorCode expected_code,metrics::CheckResult expected_check_result,metrics::CheckReaction expected_check_reaction,metrics::DownloadErrorCode expected_download_error_code,OmahaResponse * out_response,brillo::Blob * out_post_data)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.
TestEvent(OmahaRequestParams params,OmahaEvent * event,const string & http_response,brillo::Blob * out_post_data)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 
TEST_F(OmahaRequestActionTest,RejectEntities)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 
TEST_F(OmahaRequestActionTest,NoUpdateTest)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.
TEST_F(OmahaRequestActionTest,ValidUpdateTest)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 
TEST_F(OmahaRequestActionTest,ExtraHeadersSentTest)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 
TEST_F(OmahaRequestActionTest,ValidUpdateBlockedByConnection)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 
TEST_F(OmahaRequestActionTest,ValidUpdateBlockedByRollback)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.
TEST_F(OmahaRequestActionTest,SkipNonCriticalUpdatesBeforeOOBE)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 
TEST_F(OmahaRequestActionTest,WallClockBasedWaitAloneCausesScattering)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 
TEST_F(OmahaRequestActionTest,NoWallClockBasedWaitCausesNoScattering)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 
TEST_F(OmahaRequestActionTest,ZeroMaxDaysToScatterCausesNoScattering)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 
TEST_F(OmahaRequestActionTest,ZeroUpdateCheckCountCausesNoScattering)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 
TEST_F(OmahaRequestActionTest,NonZeroUpdateCheckCountCausesScattering)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 
TEST_F(OmahaRequestActionTest,ExistingUpdateCheckCountCausesScattering)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 
TEST_F(OmahaRequestActionTest,CohortsArePersisted)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 
TEST_F(OmahaRequestActionTest,CohortsAreUpdated)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 
TEST_F(OmahaRequestActionTest,CohortsAreNotModifiedWhenMissing)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 
TEST_F(OmahaRequestActionTest,CohortsArePersistedWhenNoUpdate)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 
TEST_F(OmahaRequestActionTest,NoOutputPipeTest)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 
TEST_F(OmahaRequestActionTest,InvalidXmlTest)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 
TEST_F(OmahaRequestActionTest,EmptyResponseTest)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 
TEST_F(OmahaRequestActionTest,MissingStatusTest)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 
TEST_F(OmahaRequestActionTest,InvalidStatusTest)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 
TEST_F(OmahaRequestActionTest,MissingNodesetTest)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 
TEST_F(OmahaRequestActionTest,MissingFieldTest)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:
ProcessingStopped(const ActionProcessor * processor)1079   void ProcessingStopped(const ActionProcessor* processor) {
1080     brillo::MessageLoop::current()->BreakLoop();
1081   }
1082 };
1083 
TerminateTransferTestStarter(ActionProcessor * processor)1084 void TerminateTransferTestStarter(ActionProcessor* processor) {
1085   processor->StartProcessing();
1086   CHECK(processor->IsRunning());
1087   processor->StopProcessing();
1088 }
1089 }  // namespace
1090 
TEST_F(OmahaRequestActionTest,TerminateTransferTest)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 
TEST_F(OmahaRequestActionTest,XmlEncodeTest)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 
TEST_F(OmahaRequestActionTest,XmlEncodeWithDefaultTest)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 
TEST_F(OmahaRequestActionTest,XmlEncodeIsUsedForParams)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 
TEST_F(OmahaRequestActionTest,XmlDecodeTest)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 
TEST_F(OmahaRequestActionTest,ParseIntTest)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 
TEST_F(OmahaRequestActionTest,FormatUpdateCheckOutputTest)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 
TEST_F(OmahaRequestActionTest,FormatSuccessEventOutputTest)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 
TEST_F(OmahaRequestActionTest,FormatErrorEventOutputTest)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 
TEST_F(OmahaRequestActionTest,IsEventTest)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 
TEST_F(OmahaRequestActionTest,FormatDeltaOkayOutputTest)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 
TEST_F(OmahaRequestActionTest,FormatInteractiveOutputTest)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 
TEST_F(OmahaRequestActionTest,OmahaEventTest)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 
PingTest(bool ping_only)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 
TEST_F(OmahaRequestActionTest,PingTestSendOnlyAPing)1472 TEST_F(OmahaRequestActionTest, PingTestSendOnlyAPing) {
1473   PingTest(true  /* ping_only */);
1474 }
1475 
TEST_F(OmahaRequestActionTest,PingTestSendAlsoAnUpdateCheck)1476 TEST_F(OmahaRequestActionTest, PingTestSendAlsoAnUpdateCheck) {
1477   PingTest(false  /* ping_only */);
1478 }
1479 
TEST_F(OmahaRequestActionTest,ActivePingTest)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 
TEST_F(OmahaRequestActionTest,RollCallPingTest)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 
TEST_F(OmahaRequestActionTest,NoPingTest)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 
TEST_F(OmahaRequestActionTest,IgnoreEmptyPingTest)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 
TEST_F(OmahaRequestActionTest,BackInTimePingTest)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 
TEST_F(OmahaRequestActionTest,LastPingDayUpdateTest)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 
TEST_F(OmahaRequestActionTest,NoElapsedSecondsTest)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 
TEST_F(OmahaRequestActionTest,BadElapsedSecondsTest)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 
TEST_F(OmahaRequestActionTest,ParseUpdateCheckAttributesTest)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 
TEST_F(OmahaRequestActionTest,NoUniqueIDTest)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 
TEST_F(OmahaRequestActionTest,NetworkFailureTest)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 
TEST_F(OmahaRequestActionTest,NetworkFailureBadHTTPCodeTest)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 
TEST_F(OmahaRequestActionTest,TestUpdateFirstSeenAtGetsPersistedFirstTime)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 
TEST_F(OmahaRequestActionTest,TestUpdateFirstSeenAtGetsUsedIfAlreadyPresent)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 
TEST_F(OmahaRequestActionTest,TestChangingToMoreStableChannel)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 
TEST_F(OmahaRequestActionTest,TestChangingToLessStableChannel)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.
TEST_F(OmahaRequestActionTest,PingWhenPowerwashed)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.
TEST_F(OmahaRequestActionTest,RebootAfterUpdateEvent)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 
P2PTest(bool initial_allow_p2p_for_downloading,bool initial_allow_p2p_for_sharing,bool omaha_disable_p2p_for_downloading,bool omaha_disable_p2p_for_sharing,bool payload_state_allow_p2p_attempt,bool expect_p2p_client_lookup,const string & p2p_client_result_url,bool expected_allow_p2p_for_downloading,bool expected_allow_p2p_for_sharing,const string & expected_p2p_url)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 
TEST_F(OmahaRequestActionTest,P2PWithPeer)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 
TEST_F(OmahaRequestActionTest,P2PWithoutPeer)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 
TEST_F(OmahaRequestActionTest,P2PDownloadNotAllowed)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 
TEST_F(OmahaRequestActionTest,P2PWithPeerDownloadDisabledByOmaha)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 
TEST_F(OmahaRequestActionTest,P2PWithPeerSharingDisabledByOmaha)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 
TEST_F(OmahaRequestActionTest,P2PWithPeerBothDisabledByOmaha)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 
InstallDateParseHelper(const string & elapsed_days,OmahaResponse * response)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 
TEST_F(OmahaRequestActionTest,ParseInstallDateFromResponse)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.
TEST_F(OmahaRequestActionTest,GetInstallDateWhenNoPrefsNorOOBE)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.
TEST_F(OmahaRequestActionTest,GetInstallDateWhenOOBECompletedWithInvalidDate)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.
TEST_F(OmahaRequestActionTest,GetInstallDateWhenOOBECompletedWithValidDate)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.
TEST_F(OmahaRequestActionTest,GetInstallDateWhenOOBECompletedDateChanges)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