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