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(¶ms);
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(¶ms,
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(¶ms,
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(¶ms,
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(¶ms,
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 ¶ms,
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 ¶ms,
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(¶ms,
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 ¶ms,
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(¶ms,
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(¶ms,
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(¶ms,
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(¶ms,
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(¶ms,
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(¶ms,
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(¶ms);
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<b", output);
1420 EXPECT_TRUE(XmlEncode("<&>\"\'\\", &output));
1421 EXPECT_EQ("<&>"'\\", output);
1422 EXPECT_TRUE(XmlEncode("<&>", &output));
1423 EXPECT_EQ("&lt;&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("<&>", 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<",
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(¶ms,
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>"));
1475 EXPECT_EQ(string::npos, post_str.find("testtheservice_pack>"));
1476 EXPECT_NE(string::npos, post_str.find("x86 generic<id"));
1477 EXPECT_EQ(string::npos, post_str.find("x86 generic<id"));
1478 EXPECT_NE(string::npos, post_str.find("unittest_track&lt;"));
1479 EXPECT_EQ(string::npos, post_str.find("unittest_track<"));
1480 EXPECT_NE(string::npos, post_str.find("<OEM MODEL>"));
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&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 = "<20110101";
1493 fake_update_response_.more_info_url = "testthe<url";
1494 fake_update_response_.codebase = "testthe&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(¶ms);
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(¶ms);
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(¶ms,
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(¶ms,
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(¶ms,
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, ×tamp));
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(¶ms,
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(¶ms,
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, ×tamp));
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(¶ms,
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(¶ms,
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