blob: 79e997496d9dc4cacb69aa945e59f95203d49ce4 [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));
Jay Srinivasan08fce042012-06-07 16:31:01 -070043
Gilad Arnold5bb4c902014-04-10 12:32:13 -070044 FakeSystemState* fake_system_state_;
Darin Petkov1023a602010-08-30 13:47:51 -070045};
46
47class UpdateCheckSchedulerTest : public ::testing::Test {
Darin Petkovf42cc1c2010-09-01 09:03:02 -070048 public:
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080049 UpdateCheckSchedulerTest()
Gilad Arnold5bb4c902014-04-10 12:32:13 -070050 : attempter_(&fake_system_state_, &dbus_),
51 scheduler_(&attempter_, &fake_system_state_) {}
Darin Petkovf42cc1c2010-09-01 09:03:02 -070052
Darin Petkov1023a602010-08-30 13:47:51 -070053 protected:
54 virtual void SetUp() {
55 test_ = this;
56 loop_ = NULL;
Darin Petkovf42cc1c2010-09-01 09:03:02 -070057 EXPECT_EQ(&attempter_, scheduler_.update_attempter_);
58 EXPECT_FALSE(scheduler_.enabled_);
59 EXPECT_FALSE(scheduler_.scheduled_);
60 EXPECT_EQ(0, scheduler_.last_interval_);
Darin Petkov85ced132010-09-01 10:20:56 -070061 EXPECT_EQ(0, scheduler_.poll_interval_);
Han Shen07428b52012-12-18 10:29:20 -080062 // Make sure singleton CertificateChecker has its members properly setup.
Gilad Arnold5bb4c902014-04-10 12:32:13 -070063 CertificateChecker::set_system_state(&fake_system_state_);
Han Shen07428b52012-12-18 10:29:20 -080064 CertificateChecker::set_openssl_wrapper(&openssl_wrapper_);
Darin Petkov1023a602010-08-30 13:47:51 -070065 }
66
67 virtual void TearDown() {
68 test_ = NULL;
69 loop_ = NULL;
Darin Petkov1023a602010-08-30 13:47:51 -070070 }
71
72 static gboolean SourceCallback(gpointer data) {
73 g_main_loop_quit(test_->loop_);
74 // Forwards the call to the function mock so that expectations can be set.
75 return test_->source_callback_.Call(data);
76 }
77
Gilad Arnold5bb4c902014-04-10 12:32:13 -070078 FakeSystemState fake_system_state_;
Gilad Arnold1b9d6ae2014-03-03 13:46:07 -080079 MockDBusWrapper dbus_;
Han Shen07428b52012-12-18 10:29:20 -080080 OpenSSLWrapperMock openssl_wrapper_;
Darin Petkov1023a602010-08-30 13:47:51 -070081 UpdateAttempterMock attempter_;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080082 UpdateCheckSchedulerUnderTest scheduler_;
Darin Petkov1023a602010-08-30 13:47:51 -070083 MockFunction<gboolean(gpointer data)> source_callback_;
84 GMainLoop* loop_;
85 static UpdateCheckSchedulerTest* test_;
86};
87
88UpdateCheckSchedulerTest* UpdateCheckSchedulerTest::test_ = NULL;
89
90TEST_F(UpdateCheckSchedulerTest, CanScheduleTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -070091 EXPECT_FALSE(scheduler_.CanSchedule());
92 scheduler_.enabled_ = true;
93 EXPECT_TRUE(scheduler_.CanSchedule());
94 scheduler_.scheduled_ = true;
95 EXPECT_FALSE(scheduler_.CanSchedule());
96 scheduler_.enabled_ = false;
97 EXPECT_FALSE(scheduler_.CanSchedule());
Darin Petkov1023a602010-08-30 13:47:51 -070098}
99
100TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzBackoffTest) {
101 int interval, fuzz;
102 attempter_.set_http_response_code(500);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800103 int last_interval = UpdateCheckScheduler::kTimeoutPeriodicInterval + 50;
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700104 scheduler_.last_interval_ = last_interval;
Nam T. Nguyen7d623eb2014-05-13 16:06:28 -0700105 scheduler_.ComputeNextIntervalAndFuzz(&interval, &fuzz);
Darin Petkov1023a602010-08-30 13:47:51 -0700106 EXPECT_EQ(2 * last_interval, interval);
107 EXPECT_EQ(2 * last_interval, fuzz);
108
109 attempter_.set_http_response_code(503);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800110 scheduler_.last_interval_ =
111 UpdateCheckScheduler::kTimeoutMaxBackoffInterval / 2 + 1;
Nam T. Nguyen7d623eb2014-05-13 16:06:28 -0700112 scheduler_.ComputeNextIntervalAndFuzz(&interval, &fuzz);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800113 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoffInterval, interval);
114 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoffInterval, fuzz);
Darin Petkov1023a602010-08-30 13:47:51 -0700115}
116
Darin Petkov85ced132010-09-01 10:20:56 -0700117TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzPollTest) {
118 int interval, fuzz;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800119 int poll_interval = UpdateCheckScheduler::kTimeoutPeriodicInterval + 50;
Darin Petkov85ced132010-09-01 10:20:56 -0700120 scheduler_.set_poll_interval(poll_interval);
Nam T. Nguyen7d623eb2014-05-13 16:06:28 -0700121 scheduler_.ComputeNextIntervalAndFuzz(&interval, &fuzz);
Darin Petkov85ced132010-09-01 10:20:56 -0700122 EXPECT_EQ(poll_interval, interval);
123 EXPECT_EQ(poll_interval, fuzz);
124
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800125 scheduler_.set_poll_interval(
126 UpdateCheckScheduler::kTimeoutMaxBackoffInterval + 1);
Nam T. Nguyen7d623eb2014-05-13 16:06:28 -0700127 scheduler_.ComputeNextIntervalAndFuzz(&interval, &fuzz);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800128 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoffInterval, interval);
129 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoffInterval, fuzz);
Darin Petkov85ced132010-09-01 10:20:56 -0700130
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800131 scheduler_.set_poll_interval(
132 UpdateCheckScheduler::kTimeoutPeriodicInterval - 1);
Nam T. Nguyen7d623eb2014-05-13 16:06:28 -0700133 scheduler_.ComputeNextIntervalAndFuzz(&interval, &fuzz);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800134 EXPECT_EQ(UpdateCheckScheduler::kTimeoutPeriodicInterval, interval);
Darin Petkov85ced132010-09-01 10:20:56 -0700135 EXPECT_EQ(UpdateCheckScheduler::kTimeoutRegularFuzz, fuzz);
136}
137
138TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzPriorityTest) {
139 int interval, fuzz;
140 attempter_.set_http_response_code(500);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800141 scheduler_.last_interval_ =
142 UpdateCheckScheduler::kTimeoutPeriodicInterval + 50;
143 int poll_interval = UpdateCheckScheduler::kTimeoutPeriodicInterval + 100;
Darin Petkov85ced132010-09-01 10:20:56 -0700144 scheduler_.set_poll_interval(poll_interval);
Nam T. Nguyen7d623eb2014-05-13 16:06:28 -0700145 scheduler_.ComputeNextIntervalAndFuzz(&interval, &fuzz);
Darin Petkov85ced132010-09-01 10:20:56 -0700146 EXPECT_EQ(poll_interval, interval);
147 EXPECT_EQ(poll_interval, fuzz);
148}
149
Darin Petkov1023a602010-08-30 13:47:51 -0700150TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzTest) {
151 int interval, fuzz;
Nam T. Nguyen7d623eb2014-05-13 16:06:28 -0700152 scheduler_.ComputeNextIntervalAndFuzz(&interval, &fuzz);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800153 EXPECT_EQ(UpdateCheckScheduler::kTimeoutPeriodicInterval, interval);
Darin Petkov1023a602010-08-30 13:47:51 -0700154 EXPECT_EQ(UpdateCheckScheduler::kTimeoutRegularFuzz, fuzz);
155}
156
157TEST_F(UpdateCheckSchedulerTest, GTimeoutAddSecondsTest) {
158 loop_ = g_main_loop_new(g_main_context_default(), FALSE);
159 // Invokes the actual GLib wrapper method rather than the subclass mock.
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700160 scheduler_.UpdateCheckScheduler::GTimeoutAddSeconds(0, SourceCallback);
161 EXPECT_CALL(source_callback_, Call(&scheduler_)).Times(1);
Darin Petkov1023a602010-08-30 13:47:51 -0700162 g_main_loop_run(loop_);
163 g_main_loop_unref(loop_);
164}
165
Darin Petkov1023a602010-08-30 13:47:51 -0700166TEST_F(UpdateCheckSchedulerTest, RunBootDeviceRemovableTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700167 scheduler_.enabled_ = true;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700168 fake_system_state_.fake_hardware()->SetIsOfficialBuild(true);
Alex Deymo5708ecd2014-04-29 19:44:50 -0700169 fake_system_state_.fake_hardware()->SetIsBootDeviceRemovable(true);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700170 scheduler_.Run();
171 EXPECT_FALSE(scheduler_.enabled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700172 EXPECT_EQ(NULL, attempter_.update_check_scheduler());
173}
174
175TEST_F(UpdateCheckSchedulerTest, RunNonOfficialBuildTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700176 scheduler_.enabled_ = true;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700177 fake_system_state_.fake_hardware()->SetIsOfficialBuild(false);
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, RunTest) {
184 int interval_min, interval_max;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800185 FuzzRange(UpdateCheckScheduler::kTimeoutInitialInterval,
Darin Petkov1023a602010-08-30 13:47:51 -0700186 UpdateCheckScheduler::kTimeoutRegularFuzz,
187 &interval_min,
188 &interval_max);
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700189 fake_system_state_.fake_hardware()->SetIsOfficialBuild(true);
Alex Deymo5708ecd2014-04-29 19:44:50 -0700190 fake_system_state_.fake_hardware()->SetIsBootDeviceRemovable(false);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700191 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700192 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700193 scheduler_.StaticCheck)).Times(1);
194 scheduler_.Run();
195 EXPECT_TRUE(scheduler_.enabled_);
196 EXPECT_EQ(&scheduler_, attempter_.update_check_scheduler());
Darin Petkov1023a602010-08-30 13:47:51 -0700197}
198
199TEST_F(UpdateCheckSchedulerTest, ScheduleCheckDisabledTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700200 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
201 scheduler_.ScheduleCheck(250, 30);
202 EXPECT_EQ(0, scheduler_.last_interval_);
203 EXPECT_FALSE(scheduler_.scheduled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700204}
205
206TEST_F(UpdateCheckSchedulerTest, ScheduleCheckEnabledTest) {
207 int interval_min, interval_max;
208 FuzzRange(100, 10, &interval_min,&interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700209 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700210 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700211 scheduler_.StaticCheck)).Times(1);
212 scheduler_.enabled_ = true;
213 scheduler_.ScheduleCheck(100, 10);
214 EXPECT_EQ(100, scheduler_.last_interval_);
215 EXPECT_TRUE(scheduler_.scheduled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700216}
217
218TEST_F(UpdateCheckSchedulerTest, ScheduleCheckNegativeIntervalTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700219 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(0, scheduler_.StaticCheck))
Darin Petkov1023a602010-08-30 13:47:51 -0700220 .Times(1);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700221 scheduler_.enabled_ = true;
222 scheduler_.ScheduleCheck(-50, 20);
223 EXPECT_TRUE(scheduler_.scheduled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700224}
225
226TEST_F(UpdateCheckSchedulerTest, ScheduleNextCheckDisabledTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700227 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
Nam T. Nguyen7d623eb2014-05-13 16:06:28 -0700228 scheduler_.ScheduleNextCheck();
Darin Petkov1023a602010-08-30 13:47:51 -0700229}
230
231TEST_F(UpdateCheckSchedulerTest, ScheduleNextCheckEnabledTest) {
232 int interval_min, interval_max;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800233 FuzzRange(UpdateCheckScheduler::kTimeoutPeriodicInterval,
Darin Petkov1023a602010-08-30 13:47:51 -0700234 UpdateCheckScheduler::kTimeoutRegularFuzz,
235 &interval_min,
236 &interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700237 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700238 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700239 scheduler_.StaticCheck)).Times(1);
240 scheduler_.enabled_ = true;
Nam T. Nguyen7d623eb2014-05-13 16:06:28 -0700241 scheduler_.ScheduleNextCheck();
Darin Petkov1023a602010-08-30 13:47:51 -0700242}
243
244TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusIdleDisabledTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700245 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
Nam T. Nguyen7d623eb2014-05-13 16:06:28 -0700246 scheduler_.SetUpdateStatus(UPDATE_STATUS_IDLE);
Darin Petkov1023a602010-08-30 13:47:51 -0700247}
248
249TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusIdleEnabledTest) {
250 int interval_min, interval_max;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800251 FuzzRange(UpdateCheckScheduler::kTimeoutPeriodicInterval,
Darin Petkov1023a602010-08-30 13:47:51 -0700252 UpdateCheckScheduler::kTimeoutRegularFuzz,
253 &interval_min,
254 &interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700255 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700256 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700257 scheduler_.StaticCheck)).Times(1);
258 scheduler_.enabled_ = true;
Nam T. Nguyen7d623eb2014-05-13 16:06:28 -0700259 scheduler_.SetUpdateStatus(UPDATE_STATUS_IDLE);
Darin Petkov1023a602010-08-30 13:47:51 -0700260}
261
262TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusNonIdleTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700263 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
Nam T. Nguyen7d623eb2014-05-13 16:06:28 -0700264 scheduler_.SetUpdateStatus(UPDATE_STATUS_DOWNLOADING);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700265 scheduler_.enabled_ = true;
Nam T. Nguyen7d623eb2014-05-13 16:06:28 -0700266 scheduler_.SetUpdateStatus(UPDATE_STATUS_DOWNLOADING);
Darin Petkov1023a602010-08-30 13:47:51 -0700267}
268
Darin Petkov2a0e6332010-09-24 14:43:41 -0700269TEST_F(UpdateCheckSchedulerTest, StaticCheckOOBECompleteTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700270 scheduler_.scheduled_ = true;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700271 EXPECT_TRUE(scheduler_.fake_system_state_ != NULL);
272 scheduler_.fake_system_state_->fake_hardware()->SetIsOOBEComplete(
Alex Deymobccbc382014-04-03 13:38:55 -0700273 Time::UnixEpoch());
Nam T. Nguyen7d623eb2014-05-13 16:06:28 -0700274 EXPECT_CALL(attempter_, Update("", "", false, false))
Darin Petkov2a0e6332010-09-24 14:43:41 -0700275 .Times(1)
276 .WillOnce(Assign(&scheduler_.scheduled_, true));
277 scheduler_.enabled_ = true;
278 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
279 UpdateCheckSchedulerUnderTest::StaticCheck(&scheduler_);
280}
281
282TEST_F(UpdateCheckSchedulerTest, StaticCheckOOBENotCompleteTest) {
283 scheduler_.scheduled_ = true;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700284 scheduler_.fake_system_state_->fake_hardware()->UnsetIsOOBEComplete();
Nam T. Nguyen7d623eb2014-05-13 16:06:28 -0700285 EXPECT_CALL(attempter_, Update("", "", _, _)).Times(0);
Darin Petkov2a0e6332010-09-24 14:43:41 -0700286 int interval_min, interval_max;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800287 FuzzRange(UpdateCheckScheduler::kTimeoutInitialInterval,
Darin Petkov2a0e6332010-09-24 14:43:41 -0700288 UpdateCheckScheduler::kTimeoutRegularFuzz,
289 &interval_min,
290 &interval_max);
291 scheduler_.enabled_ = true;
292 EXPECT_CALL(scheduler_,
293 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
294 scheduler_.StaticCheck)).Times(1);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700295 UpdateCheckSchedulerUnderTest::StaticCheck(&scheduler_);
Darin Petkov1023a602010-08-30 13:47:51 -0700296}
297
298} // namespace chromeos_update_engine