Home | History | Annotate | Download | only in update_manager
      1 //
      2 // Copyright (C) 2017 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/update_manager/next_update_check_policy_impl.h"
     18 
     19 #include <memory>
     20 
     21 #include "update_engine/update_manager/policy_test_utils.h"
     22 
     23 using base::Time;
     24 using base::TimeDelta;
     25 using std::string;
     26 
     27 namespace chromeos_update_manager {
     28 
     29 const NextUpdateCheckPolicyConstants policy_test_constants = {
     30     // these are specifically NOT the values used by real Policy
     31     // implementations.
     32     .timeout_initial_interval = 3 * 60,
     33     .timeout_periodic_interval = 2 * 60 * 60,
     34     .timeout_max_backoff_interval = 8 * 60 * 60,
     35     .timeout_regular_fuzz = 5 * 60,
     36     .attempt_backoff_max_interval_in_days = 12,
     37     .attempt_backoff_fuzz_in_hours = 10,
     38 };
     39 
     40 class UmNextUpdateCheckTimePolicyImplTest : public UmPolicyTestBase {
     41  protected:
     42   UmNextUpdateCheckTimePolicyImplTest() {
     43     policy_ =
     44         std::make_unique<NextUpdateCheckTimePolicyImpl>(policy_test_constants);
     45   }
     46 };
     47 
     48 TEST_F(UmNextUpdateCheckTimePolicyImplTest,
     49        FirstCheckIsAtMostInitialIntervalAfterStart) {
     50   Time next_update_check;
     51 
     52   // Set the last update time so it'll appear as if this is a first update check
     53   // in the lifetime of the current updater.
     54   fake_state_.updater_provider()->var_last_checked_time()->reset(
     55       new Time(fake_clock_.GetWallclockTime() - TimeDelta::FromMinutes(10)));
     56 
     57   CallMethodWithContext(&NextUpdateCheckTimePolicyImpl::NextUpdateCheckTime,
     58                         &next_update_check,
     59                         policy_test_constants);
     60 
     61   EXPECT_LE(fake_clock_.GetWallclockTime(), next_update_check);
     62   EXPECT_GE(fake_clock_.GetWallclockTime() +
     63                 TimeDelta::FromSeconds(
     64                     policy_test_constants.timeout_initial_interval +
     65                     policy_test_constants.timeout_regular_fuzz / 2),
     66             next_update_check);
     67 }
     68 
     69 TEST_F(UmNextUpdateCheckTimePolicyImplTest, RecurringCheckBaseIntervalAndFuzz) {
     70   // Ensure that we're using the correct interval (kPeriodicInterval) and fuzz
     71   // (ktimeout_regular_fuzz) as base values for period updates.
     72   Time next_update_check;
     73 
     74   CallMethodWithContext(&NextUpdateCheckTimePolicyImpl::NextUpdateCheckTime,
     75                         &next_update_check,
     76                         policy_test_constants);
     77 
     78   EXPECT_LE(fake_clock_.GetWallclockTime() +
     79                 TimeDelta::FromSeconds(
     80                     policy_test_constants.timeout_periodic_interval -
     81                     policy_test_constants.timeout_regular_fuzz / 2),
     82             next_update_check);
     83   EXPECT_GE(fake_clock_.GetWallclockTime() +
     84                 TimeDelta::FromSeconds(
     85                     policy_test_constants.timeout_periodic_interval +
     86                     policy_test_constants.timeout_regular_fuzz / 2),
     87             next_update_check);
     88 }
     89 
     90 TEST_F(UmNextUpdateCheckTimePolicyImplTest,
     91        RecurringCheckBackoffIntervalAndFuzz) {
     92   // Ensure that we're properly backing off and fuzzing in the presence of
     93   // failed updates attempts.
     94   Time next_update_check;
     95 
     96   fake_state_.updater_provider()->var_consecutive_failed_update_checks()->reset(
     97       new unsigned int{2});
     98 
     99   ExpectStatus(EvalStatus::kSucceeded,
    100                NextUpdateCheckTimePolicyImpl::NextUpdateCheckTime,
    101                &next_update_check,
    102                policy_test_constants);
    103 
    104   int expected_interval = policy_test_constants.timeout_periodic_interval * 4;
    105   EXPECT_LE(
    106       fake_clock_.GetWallclockTime() +
    107           TimeDelta::FromSeconds(expected_interval - expected_interval / 2),
    108       next_update_check);
    109   EXPECT_GE(
    110       fake_clock_.GetWallclockTime() +
    111           TimeDelta::FromSeconds(expected_interval + expected_interval / 2),
    112       next_update_check);
    113 }
    114 
    115 TEST_F(UmNextUpdateCheckTimePolicyImplTest,
    116        RecurringCheckServerDictatedPollInterval) {
    117   // Policy honors the server provided check poll interval.
    118   Time next_update_check;
    119 
    120   const auto kInterval = policy_test_constants.timeout_periodic_interval * 4;
    121   fake_state_.updater_provider()->var_server_dictated_poll_interval()->reset(
    122       new unsigned int(kInterval));  // NOLINT(readability/casting)
    123   // We should not be backing off in this case.
    124   fake_state_.updater_provider()->var_consecutive_failed_update_checks()->reset(
    125       new unsigned int(2));  // NOLINT(readability/casting)
    126 
    127   ExpectStatus(EvalStatus::kSucceeded,
    128                &NextUpdateCheckTimePolicyImpl::NextUpdateCheckTime,
    129                &next_update_check,
    130                policy_test_constants);
    131 
    132   EXPECT_LE(fake_clock_.GetWallclockTime() +
    133                 TimeDelta::FromSeconds(kInterval - kInterval / 2),
    134             next_update_check);
    135   EXPECT_GE(fake_clock_.GetWallclockTime() +
    136                 TimeDelta::FromSeconds(kInterval + kInterval / 2),
    137             next_update_check);
    138 }
    139 
    140 TEST_F(UmNextUpdateCheckTimePolicyImplTest, ExponentialBackoffIsCapped) {
    141   Time next_update_check;
    142 
    143   fake_state_.updater_provider()->var_consecutive_failed_update_checks()->reset(
    144       new unsigned int(100));  // NOLINT(readability/casting)
    145 
    146   ExpectStatus(EvalStatus::kSucceeded,
    147                &NextUpdateCheckTimePolicyImpl::NextUpdateCheckTime,
    148                &next_update_check,
    149                policy_test_constants);
    150 
    151   EXPECT_LE(fake_clock_.GetWallclockTime() +
    152                 TimeDelta::FromSeconds(
    153                     policy_test_constants.timeout_max_backoff_interval -
    154                     policy_test_constants.timeout_max_backoff_interval / 2),
    155             next_update_check);
    156   EXPECT_GE(fake_clock_.GetWallclockTime() +
    157                 TimeDelta::FromSeconds(
    158                     policy_test_constants.timeout_max_backoff_interval +
    159                     policy_test_constants.timeout_max_backoff_interval / 2),
    160             next_update_check);
    161 }
    162 
    163 }  // namespace chromeos_update_manager
    164