blob: 608b6a6fc1835b6df789c8a93c3c815e1348c31a [file] [log] [blame]
Darin Petkov1023a602010-08-30 13:47:51 -07001// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Alex Deymo7984bf02014-04-02 20:41:57 -07005#include "update_engine/update_check_scheduler.h"
6
Darin Petkov1023a602010-08-30 13:47:51 -07007#include <gtest/gtest.h>
8
Han Shen07428b52012-12-18 10:29:20 -08009#include "update_engine/certificate_checker.h"
10#include "update_engine/certificate_checker_mock.h"
Gilad Arnold5bb4c902014-04-10 12:32:13 -070011#include "update_engine/fake_system_state.h"
Darin Petkov1023a602010-08-30 13:47:51 -070012#include "update_engine/update_attempter_mock.h"
Darin Petkov1023a602010-08-30 13:47:51 -070013
David Zeuthen639aa362014-02-03 16:23:44 -080014using base::Time;
Darin Petkov1023a602010-08-30 13:47:51 -070015using testing::_;
16using testing::AllOf;
Darin Petkov2a0e6332010-09-24 14:43:41 -070017using testing::Assign;
Darin Petkov1023a602010-08-30 13:47:51 -070018using testing::Ge;
19using testing::Le;
20using testing::MockFunction;
21using testing::Return;
David Zeuthen639aa362014-02-03 16:23:44 -080022using testing::SetArgumentPointee;
Darin Petkov1023a602010-08-30 13:47:51 -070023
24namespace chromeos_update_engine {
25
26namespace {
27void FuzzRange(int interval, int fuzz, int* interval_min, int* interval_max) {
28 *interval_min = interval - fuzz / 2;
29 *interval_max = interval + fuzz - fuzz / 2;
30}
Alex Deymo7984bf02014-04-02 20:41:57 -070031} // namespace
Darin Petkov1023a602010-08-30 13:47:51 -070032
33// Test a subclass rather than the main class directly so that we can mock out
34// GLib and utils in tests. There're explicit unit test for the wrapper methods.
35class UpdateCheckSchedulerUnderTest : public UpdateCheckScheduler {
36 public:
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080037 UpdateCheckSchedulerUnderTest(UpdateAttempter* update_attempter,
Gilad Arnold5bb4c902014-04-10 12:32:13 -070038 FakeSystemState* fake_system_state)
39 : UpdateCheckScheduler(update_attempter, fake_system_state),
40 fake_system_state_(fake_system_state) {}
Darin Petkov1023a602010-08-30 13:47:51 -070041
42 MOCK_METHOD2(GTimeoutAddSeconds, guint(guint seconds, GSourceFunc function));
43 MOCK_METHOD0(IsBootDeviceRemovable, bool());
Jay Srinivasan08fce042012-06-07 16:31:01 -070044
Gilad Arnold5bb4c902014-04-10 12:32:13 -070045 FakeSystemState* fake_system_state_;
Darin Petkov1023a602010-08-30 13:47:51 -070046};
47
48class UpdateCheckSchedulerTest : public ::testing::Test {
Darin Petkovf42cc1c2010-09-01 09:03:02 -070049 public:
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080050 UpdateCheckSchedulerTest()
Gilad Arnold5bb4c902014-04-10 12:32:13 -070051 : attempter_(&fake_system_state_, &dbus_),
52 scheduler_(&attempter_, &fake_system_state_) {}
Darin Petkovf42cc1c2010-09-01 09:03:02 -070053
Darin Petkov1023a602010-08-30 13:47:51 -070054 protected:
55 virtual void SetUp() {
56 test_ = this;
57 loop_ = NULL;
Darin Petkovf42cc1c2010-09-01 09:03:02 -070058 EXPECT_EQ(&attempter_, scheduler_.update_attempter_);
59 EXPECT_FALSE(scheduler_.enabled_);
60 EXPECT_FALSE(scheduler_.scheduled_);
61 EXPECT_EQ(0, scheduler_.last_interval_);
Darin Petkov85ced132010-09-01 10:20:56 -070062 EXPECT_EQ(0, scheduler_.poll_interval_);
Han Shen07428b52012-12-18 10:29:20 -080063 // Make sure singleton CertificateChecker has its members properly setup.
Gilad Arnold5bb4c902014-04-10 12:32:13 -070064 CertificateChecker::set_system_state(&fake_system_state_);
Han Shen07428b52012-12-18 10:29:20 -080065 CertificateChecker::set_openssl_wrapper(&openssl_wrapper_);
Darin Petkov1023a602010-08-30 13:47:51 -070066 }
67
68 virtual void TearDown() {
69 test_ = NULL;
70 loop_ = NULL;
Darin Petkov1023a602010-08-30 13:47:51 -070071 }
72
73 static gboolean SourceCallback(gpointer data) {
74 g_main_loop_quit(test_->loop_);
75 // Forwards the call to the function mock so that expectations can be set.
76 return test_->source_callback_.Call(data);
77 }
78
Gilad Arnold5bb4c902014-04-10 12:32:13 -070079 FakeSystemState fake_system_state_;
Gilad Arnold1b9d6ae2014-03-03 13:46:07 -080080 MockDBusWrapper dbus_;
Han Shen07428b52012-12-18 10:29:20 -080081 OpenSSLWrapperMock openssl_wrapper_;
Darin Petkov1023a602010-08-30 13:47:51 -070082 UpdateAttempterMock attempter_;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080083 UpdateCheckSchedulerUnderTest scheduler_;
Darin Petkov1023a602010-08-30 13:47:51 -070084 MockFunction<gboolean(gpointer data)> source_callback_;
85 GMainLoop* loop_;
86 static UpdateCheckSchedulerTest* test_;
87};
88
89UpdateCheckSchedulerTest* UpdateCheckSchedulerTest::test_ = NULL;
90
91TEST_F(UpdateCheckSchedulerTest, CanScheduleTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -070092 EXPECT_FALSE(scheduler_.CanSchedule());
93 scheduler_.enabled_ = true;
94 EXPECT_TRUE(scheduler_.CanSchedule());
95 scheduler_.scheduled_ = true;
96 EXPECT_FALSE(scheduler_.CanSchedule());
97 scheduler_.enabled_ = false;
98 EXPECT_FALSE(scheduler_.CanSchedule());
Darin Petkov1023a602010-08-30 13:47:51 -070099}
100
101TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzBackoffTest) {
102 int interval, fuzz;
103 attempter_.set_http_response_code(500);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800104 int last_interval = UpdateCheckScheduler::kTimeoutPeriodicInterval + 50;
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700105 scheduler_.last_interval_ = last_interval;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800106 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
Darin Petkov1023a602010-08-30 13:47:51 -0700107 EXPECT_EQ(2 * last_interval, interval);
108 EXPECT_EQ(2 * last_interval, fuzz);
109
110 attempter_.set_http_response_code(503);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800111 scheduler_.last_interval_ =
112 UpdateCheckScheduler::kTimeoutMaxBackoffInterval / 2 + 1;
113 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
114 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoffInterval, interval);
115 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoffInterval, fuzz);
Darin Petkov1023a602010-08-30 13:47:51 -0700116}
117
Darin Petkov85ced132010-09-01 10:20:56 -0700118TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzPollTest) {
119 int interval, fuzz;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800120 int poll_interval = UpdateCheckScheduler::kTimeoutPeriodicInterval + 50;
Darin Petkov85ced132010-09-01 10:20:56 -0700121 scheduler_.set_poll_interval(poll_interval);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800122 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
Darin Petkov85ced132010-09-01 10:20:56 -0700123 EXPECT_EQ(poll_interval, interval);
124 EXPECT_EQ(poll_interval, fuzz);
125
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800126 scheduler_.set_poll_interval(
127 UpdateCheckScheduler::kTimeoutMaxBackoffInterval + 1);
128 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
129 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoffInterval, interval);
130 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoffInterval, fuzz);
Darin Petkov85ced132010-09-01 10:20:56 -0700131
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800132 scheduler_.set_poll_interval(
133 UpdateCheckScheduler::kTimeoutPeriodicInterval - 1);
134 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
135 EXPECT_EQ(UpdateCheckScheduler::kTimeoutPeriodicInterval, interval);
Darin Petkov85ced132010-09-01 10:20:56 -0700136 EXPECT_EQ(UpdateCheckScheduler::kTimeoutRegularFuzz, fuzz);
137}
138
139TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzPriorityTest) {
140 int interval, fuzz;
141 attempter_.set_http_response_code(500);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800142 scheduler_.last_interval_ =
143 UpdateCheckScheduler::kTimeoutPeriodicInterval + 50;
144 int poll_interval = UpdateCheckScheduler::kTimeoutPeriodicInterval + 100;
Darin Petkov85ced132010-09-01 10:20:56 -0700145 scheduler_.set_poll_interval(poll_interval);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800146 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
Darin Petkov85ced132010-09-01 10:20:56 -0700147 EXPECT_EQ(poll_interval, interval);
148 EXPECT_EQ(poll_interval, fuzz);
149}
150
Darin Petkov1023a602010-08-30 13:47:51 -0700151TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzTest) {
152 int interval, fuzz;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800153 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
154 EXPECT_EQ(UpdateCheckScheduler::kTimeoutPeriodicInterval, interval);
Darin Petkov1023a602010-08-30 13:47:51 -0700155 EXPECT_EQ(UpdateCheckScheduler::kTimeoutRegularFuzz, fuzz);
156}
157
158TEST_F(UpdateCheckSchedulerTest, GTimeoutAddSecondsTest) {
159 loop_ = g_main_loop_new(g_main_context_default(), FALSE);
160 // Invokes the actual GLib wrapper method rather than the subclass mock.
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700161 scheduler_.UpdateCheckScheduler::GTimeoutAddSeconds(0, SourceCallback);
162 EXPECT_CALL(source_callback_, Call(&scheduler_)).Times(1);
Darin Petkov1023a602010-08-30 13:47:51 -0700163 g_main_loop_run(loop_);
164 g_main_loop_unref(loop_);
165}
166
167TEST_F(UpdateCheckSchedulerTest, IsBootDeviceRemovableTest) {
168 // Invokes the actual utils wrapper method rather than the subclass mock.
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700169 EXPECT_FALSE(scheduler_.UpdateCheckScheduler::IsBootDeviceRemovable());
Darin Petkov1023a602010-08-30 13:47:51 -0700170}
171
Darin Petkov1023a602010-08-30 13:47:51 -0700172TEST_F(UpdateCheckSchedulerTest, RunBootDeviceRemovableTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700173 scheduler_.enabled_ = true;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700174 fake_system_state_.fake_hardware()->SetIsOfficialBuild(true);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700175 EXPECT_CALL(scheduler_, IsBootDeviceRemovable())
Darin Petkov1023a602010-08-30 13:47:51 -0700176 .Times(1)
177 .WillOnce(Return(true));
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700178 scheduler_.Run();
179 EXPECT_FALSE(scheduler_.enabled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700180 EXPECT_EQ(NULL, attempter_.update_check_scheduler());
181}
182
183TEST_F(UpdateCheckSchedulerTest, RunNonOfficialBuildTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700184 scheduler_.enabled_ = true;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700185 fake_system_state_.fake_hardware()->SetIsOfficialBuild(false);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700186 scheduler_.Run();
187 EXPECT_FALSE(scheduler_.enabled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700188 EXPECT_EQ(NULL, attempter_.update_check_scheduler());
189}
190
191TEST_F(UpdateCheckSchedulerTest, RunTest) {
192 int interval_min, interval_max;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800193 FuzzRange(UpdateCheckScheduler::kTimeoutInitialInterval,
Darin Petkov1023a602010-08-30 13:47:51 -0700194 UpdateCheckScheduler::kTimeoutRegularFuzz,
195 &interval_min,
196 &interval_max);
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700197 fake_system_state_.fake_hardware()->SetIsOfficialBuild(true);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700198 EXPECT_CALL(scheduler_, IsBootDeviceRemovable())
Darin Petkov1023a602010-08-30 13:47:51 -0700199 .Times(1)
200 .WillOnce(Return(false));
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700201 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700202 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700203 scheduler_.StaticCheck)).Times(1);
204 scheduler_.Run();
205 EXPECT_TRUE(scheduler_.enabled_);
206 EXPECT_EQ(&scheduler_, attempter_.update_check_scheduler());
Darin Petkov1023a602010-08-30 13:47:51 -0700207}
208
209TEST_F(UpdateCheckSchedulerTest, ScheduleCheckDisabledTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700210 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
211 scheduler_.ScheduleCheck(250, 30);
212 EXPECT_EQ(0, scheduler_.last_interval_);
213 EXPECT_FALSE(scheduler_.scheduled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700214}
215
216TEST_F(UpdateCheckSchedulerTest, ScheduleCheckEnabledTest) {
217 int interval_min, interval_max;
218 FuzzRange(100, 10, &interval_min,&interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700219 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700220 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700221 scheduler_.StaticCheck)).Times(1);
222 scheduler_.enabled_ = true;
223 scheduler_.ScheduleCheck(100, 10);
224 EXPECT_EQ(100, scheduler_.last_interval_);
225 EXPECT_TRUE(scheduler_.scheduled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700226}
227
228TEST_F(UpdateCheckSchedulerTest, ScheduleCheckNegativeIntervalTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700229 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(0, scheduler_.StaticCheck))
Darin Petkov1023a602010-08-30 13:47:51 -0700230 .Times(1);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700231 scheduler_.enabled_ = true;
232 scheduler_.ScheduleCheck(-50, 20);
233 EXPECT_TRUE(scheduler_.scheduled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700234}
235
236TEST_F(UpdateCheckSchedulerTest, ScheduleNextCheckDisabledTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700237 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800238 scheduler_.ScheduleNextCheck(false);
Darin Petkov1023a602010-08-30 13:47:51 -0700239}
240
241TEST_F(UpdateCheckSchedulerTest, ScheduleNextCheckEnabledTest) {
242 int interval_min, interval_max;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800243 FuzzRange(UpdateCheckScheduler::kTimeoutPeriodicInterval,
Darin Petkov1023a602010-08-30 13:47:51 -0700244 UpdateCheckScheduler::kTimeoutRegularFuzz,
245 &interval_min,
246 &interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700247 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700248 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700249 scheduler_.StaticCheck)).Times(1);
250 scheduler_.enabled_ = true;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800251 scheduler_.ScheduleNextCheck(false);
Darin Petkov1023a602010-08-30 13:47:51 -0700252}
253
254TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusIdleDisabledTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700255 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800256 scheduler_.SetUpdateStatus(UPDATE_STATUS_IDLE, kUpdateNoticeUnspecified);
Darin Petkov1023a602010-08-30 13:47:51 -0700257}
258
259TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusIdleEnabledTest) {
260 int interval_min, interval_max;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800261 FuzzRange(UpdateCheckScheduler::kTimeoutPeriodicInterval,
Darin Petkov1023a602010-08-30 13:47:51 -0700262 UpdateCheckScheduler::kTimeoutRegularFuzz,
263 &interval_min,
264 &interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700265 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700266 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700267 scheduler_.StaticCheck)).Times(1);
268 scheduler_.enabled_ = true;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800269 scheduler_.SetUpdateStatus(UPDATE_STATUS_IDLE, kUpdateNoticeUnspecified);
Darin Petkov1023a602010-08-30 13:47:51 -0700270}
271
272TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusNonIdleTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700273 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800274 scheduler_.SetUpdateStatus(UPDATE_STATUS_DOWNLOADING,
275 kUpdateNoticeUnspecified);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700276 scheduler_.enabled_ = true;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800277 scheduler_.SetUpdateStatus(UPDATE_STATUS_DOWNLOADING,
278 kUpdateNoticeUnspecified);
Darin Petkov1023a602010-08-30 13:47:51 -0700279}
280
Darin Petkov2a0e6332010-09-24 14:43:41 -0700281TEST_F(UpdateCheckSchedulerTest, StaticCheckOOBECompleteTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700282 scheduler_.scheduled_ = true;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700283 EXPECT_TRUE(scheduler_.fake_system_state_ != NULL);
284 scheduler_.fake_system_state_->fake_hardware()->SetIsOOBEComplete(
Alex Deymobccbc382014-04-03 13:38:55 -0700285 Time::UnixEpoch());
Gilad Arnoldb92f0df2013-01-10 16:32:45 -0800286 EXPECT_CALL(attempter_, Update("", "", false, false, false))
Darin Petkov2a0e6332010-09-24 14:43:41 -0700287 .Times(1)
288 .WillOnce(Assign(&scheduler_.scheduled_, true));
289 scheduler_.enabled_ = true;
290 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
291 UpdateCheckSchedulerUnderTest::StaticCheck(&scheduler_);
292}
293
294TEST_F(UpdateCheckSchedulerTest, StaticCheckOOBENotCompleteTest) {
295 scheduler_.scheduled_ = true;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700296 scheduler_.fake_system_state_->fake_hardware()->UnsetIsOOBEComplete();
Gilad Arnoldb92f0df2013-01-10 16:32:45 -0800297 EXPECT_CALL(attempter_, Update("", "", _, _, _)).Times(0);
Darin Petkov2a0e6332010-09-24 14:43:41 -0700298 int interval_min, interval_max;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800299 FuzzRange(UpdateCheckScheduler::kTimeoutInitialInterval,
Darin Petkov2a0e6332010-09-24 14:43:41 -0700300 UpdateCheckScheduler::kTimeoutRegularFuzz,
301 &interval_min,
302 &interval_max);
303 scheduler_.enabled_ = true;
304 EXPECT_CALL(scheduler_,
305 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
306 scheduler_.StaticCheck)).Times(1);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700307 UpdateCheckSchedulerUnderTest::StaticCheck(&scheduler_);
Darin Petkov1023a602010-08-30 13:47:51 -0700308}
309
310} // namespace chromeos_update_engine