update_engine: Support milestones to EOL from Omaha

Initiative to show EOL message on Chrome OS devices require that
update_engine parses the fields within Omaha response that pertain to the
new milestones to EOL field. The Omaha response will include a new
field called "milestones_to_eol" which will be an integer value
string.

The job of update_engine when it comes to milestones to EOL from Omaha
is to merely forward. No checks and no modifications of fields are
done within update_engine besides being able to convert the milestones
to EOL from a string to integer.

BUG=chromium:994999
TEST=FEATURES="test" emerge-$BOARD update_engine update_engine-client
TEST=cros deploy $IP update_engine update_engine-client
TEST=test_that -b $BOARD $IP autoupdate_EOL # from Cq-Depend
TEST=test_that -b $BOARD $IP autoupdate_EOL.milestones # from Cq-Depend

Cq-Depend:chromium:1761371
Change-Id: I268e4c8e641b17d6a727a50f53285cc97c76eb22
Reviewed-on: https://chromium-review.googlesource.com/1759285
Tested-by: Jae Hoon Kim <kimjae@chromium.org>
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Legacy-Commit-Queue: Commit Bot <commit-bot@chromium.org>
Reviewed-by: Nicolas Norvez <norvez@chromium.org>
Reviewed-by: Amin Hassani <ahassani@chromium.org>
diff --git a/common_service_unittest.cc b/common_service_unittest.cc
index 65202a0..68b2468 100644
--- a/common_service_unittest.cc
+++ b/common_service_unittest.cc
@@ -169,19 +169,90 @@
                                UpdateEngineService::kErrorFailed));
 }
 
-TEST_F(UpdateEngineServiceTest, GetEolStatusTest) {
+TEST_F(UpdateEngineServiceTest, GetEolStatusTestWithMilestonesDefault) {
   FakePrefs fake_prefs;
   fake_system_state_.set_prefs(&fake_prefs);
-  // The default value should be "supported".
+  // The default value for EOL be |kSupported| and milestone
+  // |kMilestonesToEolNone|.
   int32_t eol_status = static_cast<int32_t>(EolStatus::kEol);
-  EXPECT_TRUE(common_service_.GetEolStatus(&error_, &eol_status));
+  MilestonesToEol milestones_to_eol = kMilestonesToEolNone;
+  EXPECT_TRUE(
+      common_service_.GetEolStatus(&error_, &eol_status, &milestones_to_eol));
   EXPECT_EQ(nullptr, error_);
   EXPECT_EQ(EolStatus::kSupported, static_cast<EolStatus>(eol_status));
+  EXPECT_EQ(kMilestonesToEolNone, milestones_to_eol);
+}
 
-  fake_prefs.SetString(kPrefsOmahaEolStatus, "security-only");
-  EXPECT_TRUE(common_service_.GetEolStatus(&error_, &eol_status));
+TEST_F(UpdateEngineServiceTest, GetEolStatusMilestonesToEolNone) {
+  FakePrefs fake_prefs;
+  fake_system_state_.set_prefs(&fake_prefs);
+  int32_t eol_status = static_cast<int32_t>(EolStatus::kEol);
+  MilestonesToEol milestones_to_eol = kMilestonesToEolNone;
+
+  // Device is supported and no milestones to EOL set.
+  fake_prefs.SetString(kPrefsOmahaEolStatus, kEolStatusSupported);
+  EXPECT_TRUE(
+      common_service_.GetEolStatus(&error_, &eol_status, &milestones_to_eol));
+  EXPECT_EQ(nullptr, error_);
+  EXPECT_EQ(EolStatus::kSupported, static_cast<EolStatus>(eol_status));
+  EXPECT_EQ(kMilestonesToEolNone, milestones_to_eol);
+
+  // Device is security only and no milestones to EOL set.
+  fake_prefs.SetString(kPrefsOmahaEolStatus, kEolStatusSecurityOnly);
+  EXPECT_TRUE(
+      common_service_.GetEolStatus(&error_, &eol_status, &milestones_to_eol));
   EXPECT_EQ(nullptr, error_);
   EXPECT_EQ(EolStatus::kSecurityOnly, static_cast<EolStatus>(eol_status));
+  EXPECT_EQ(kMilestonesToEolNone, milestones_to_eol);
+
+  // Device is EOL and no milestones to EOL set.
+  fake_prefs.SetString(kPrefsOmahaEolStatus, kEolStatusEol);
+  EXPECT_TRUE(
+      common_service_.GetEolStatus(&error_, &eol_status, &milestones_to_eol));
+  EXPECT_EQ(nullptr, error_);
+  EXPECT_EQ(EolStatus::kEol, static_cast<EolStatus>(eol_status));
+  EXPECT_EQ(kMilestonesToEolNone, milestones_to_eol);
+}
+
+TEST_F(UpdateEngineServiceTest, GetEolStatusMilestonesToEolTwo) {
+  FakePrefs fake_prefs;
+  fake_system_state_.set_prefs(&fake_prefs);
+  int32_t eol_status = static_cast<int32_t>(EolStatus::kEol);
+  MilestonesToEol milestones_to_eol = kMilestonesToEolNone;
+
+  // Device is supported and milestones to EOL is n-2.
+  fake_prefs.SetString(kPrefsOmahaEolStatus, kEolStatusSupported);
+  fake_prefs.SetString(kPrefsOmahaMilestonesToEol, "2");
+  EXPECT_TRUE(
+      common_service_.GetEolStatus(&error_, &eol_status, &milestones_to_eol));
+  EXPECT_EQ(nullptr, error_);
+  EXPECT_EQ(EolStatus::kSupported, static_cast<EolStatus>(eol_status));
+  EXPECT_EQ(2, milestones_to_eol);
+
+  // Device is security only and milestones to EOL is n-2.
+  fake_prefs.SetString(kPrefsOmahaEolStatus, kEolStatusSecurityOnly);
+  fake_prefs.SetString(kPrefsOmahaMilestonesToEol, "2");
+  EXPECT_TRUE(
+      common_service_.GetEolStatus(&error_, &eol_status, &milestones_to_eol));
+  EXPECT_EQ(nullptr, error_);
+  EXPECT_EQ(EolStatus::kSecurityOnly, static_cast<EolStatus>(eol_status));
+  EXPECT_EQ(2, milestones_to_eol);
+}
+
+TEST_F(UpdateEngineServiceTest, GetEolStatusMilestonesToEolZero) {
+  FakePrefs fake_prefs;
+  fake_system_state_.set_prefs(&fake_prefs);
+  int32_t eol_status = static_cast<int32_t>(EolStatus::kEol);
+  MilestonesToEol milestones_to_eol = kMilestonesToEolNone;
+
+  // Device is EOL and milestones to EOL is n.
+  fake_prefs.SetString(kPrefsOmahaEolStatus, kEolStatusEol);
+  fake_prefs.SetString(kPrefsOmahaMilestonesToEol, "0");
+  EXPECT_TRUE(
+      common_service_.GetEolStatus(&error_, &eol_status, &milestones_to_eol));
+  EXPECT_EQ(nullptr, error_);
+  EXPECT_EQ(EolStatus::kEol, static_cast<EolStatus>(eol_status));
+  EXPECT_EQ(0, milestones_to_eol);
 }
 
 }  // namespace chromeos_update_engine