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