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