blob: 098651b4b36f07eb7a13d94b71143e726271f1e2 [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
5#include <gtest/gtest.h>
6
7#include "update_engine/update_attempter_mock.h"
8#include "update_engine/update_check_scheduler.h"
9
10using std::string;
11using testing::_;
12using testing::AllOf;
Darin Petkov2a0e6332010-09-24 14:43:41 -070013using testing::Assign;
Darin Petkov1023a602010-08-30 13:47:51 -070014using testing::Ge;
15using testing::Le;
16using testing::MockFunction;
17using testing::Return;
18
19namespace chromeos_update_engine {
20
21namespace {
22void FuzzRange(int interval, int fuzz, int* interval_min, int* interval_max) {
23 *interval_min = interval - fuzz / 2;
24 *interval_max = interval + fuzz - fuzz / 2;
25}
26} // namespace {}
27
28// Test a subclass rather than the main class directly so that we can mock out
29// GLib and utils in tests. There're explicit unit test for the wrapper methods.
30class UpdateCheckSchedulerUnderTest : public UpdateCheckScheduler {
31 public:
32 UpdateCheckSchedulerUnderTest(UpdateAttempter* update_attempter)
33 : UpdateCheckScheduler(update_attempter) {}
34
35 MOCK_METHOD2(GTimeoutAddSeconds, guint(guint seconds, GSourceFunc function));
36 MOCK_METHOD0(IsBootDeviceRemovable, bool());
37 MOCK_METHOD0(IsOfficialBuild, bool());
Darin Petkov2a0e6332010-09-24 14:43:41 -070038 MOCK_METHOD0(IsOOBEComplete, bool());
Darin Petkov1023a602010-08-30 13:47:51 -070039};
40
41class UpdateCheckSchedulerTest : public ::testing::Test {
Darin Petkovf42cc1c2010-09-01 09:03:02 -070042 public:
Andrew de los Reyes000d8952011-03-02 15:21:14 -080043 UpdateCheckSchedulerTest() : scheduler_(&attempter_), attempter_(&dbus_) {}
Darin Petkovf42cc1c2010-09-01 09:03:02 -070044
Darin Petkov1023a602010-08-30 13:47:51 -070045 protected:
46 virtual void SetUp() {
47 test_ = this;
48 loop_ = NULL;
Darin Petkovf42cc1c2010-09-01 09:03:02 -070049 EXPECT_EQ(&attempter_, scheduler_.update_attempter_);
50 EXPECT_FALSE(scheduler_.enabled_);
51 EXPECT_FALSE(scheduler_.scheduled_);
52 EXPECT_EQ(0, scheduler_.last_interval_);
Darin Petkov85ced132010-09-01 10:20:56 -070053 EXPECT_EQ(0, scheduler_.poll_interval_);
Darin Petkov1023a602010-08-30 13:47:51 -070054 }
55
56 virtual void TearDown() {
57 test_ = NULL;
58 loop_ = NULL;
Darin Petkov1023a602010-08-30 13:47:51 -070059 }
60
61 static gboolean SourceCallback(gpointer data) {
62 g_main_loop_quit(test_->loop_);
63 // Forwards the call to the function mock so that expectations can be set.
64 return test_->source_callback_.Call(data);
65 }
66
Darin Petkovf42cc1c2010-09-01 09:03:02 -070067 UpdateCheckSchedulerUnderTest scheduler_;
Andrew de los Reyes000d8952011-03-02 15:21:14 -080068 MockDbusGlib dbus_;
Darin Petkov1023a602010-08-30 13:47:51 -070069 UpdateAttempterMock attempter_;
70 MockFunction<gboolean(gpointer data)> source_callback_;
71 GMainLoop* loop_;
72 static UpdateCheckSchedulerTest* test_;
73};
74
75UpdateCheckSchedulerTest* UpdateCheckSchedulerTest::test_ = NULL;
76
77TEST_F(UpdateCheckSchedulerTest, CanScheduleTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -070078 EXPECT_FALSE(scheduler_.CanSchedule());
79 scheduler_.enabled_ = true;
80 EXPECT_TRUE(scheduler_.CanSchedule());
81 scheduler_.scheduled_ = true;
82 EXPECT_FALSE(scheduler_.CanSchedule());
83 scheduler_.enabled_ = false;
84 EXPECT_FALSE(scheduler_.CanSchedule());
Darin Petkov1023a602010-08-30 13:47:51 -070085}
86
87TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzBackoffTest) {
88 int interval, fuzz;
89 attempter_.set_http_response_code(500);
Gilad Arnold1ebd8132012-03-05 10:19:29 -080090 int last_interval = UpdateCheckScheduler::kTimeoutPeriodicInterval + 50;
Darin Petkovf42cc1c2010-09-01 09:03:02 -070091 scheduler_.last_interval_ = last_interval;
Gilad Arnold1ebd8132012-03-05 10:19:29 -080092 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
Darin Petkov1023a602010-08-30 13:47:51 -070093 EXPECT_EQ(2 * last_interval, interval);
94 EXPECT_EQ(2 * last_interval, fuzz);
95
96 attempter_.set_http_response_code(503);
Gilad Arnold1ebd8132012-03-05 10:19:29 -080097 scheduler_.last_interval_ =
98 UpdateCheckScheduler::kTimeoutMaxBackoffInterval / 2 + 1;
99 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
100 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoffInterval, interval);
101 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoffInterval, fuzz);
Darin Petkov1023a602010-08-30 13:47:51 -0700102}
103
Darin Petkov85ced132010-09-01 10:20:56 -0700104TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzPollTest) {
105 int interval, fuzz;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800106 int poll_interval = UpdateCheckScheduler::kTimeoutPeriodicInterval + 50;
Darin Petkov85ced132010-09-01 10:20:56 -0700107 scheduler_.set_poll_interval(poll_interval);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800108 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
Darin Petkov85ced132010-09-01 10:20:56 -0700109 EXPECT_EQ(poll_interval, interval);
110 EXPECT_EQ(poll_interval, fuzz);
111
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800112 scheduler_.set_poll_interval(
113 UpdateCheckScheduler::kTimeoutMaxBackoffInterval + 1);
114 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
115 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoffInterval, interval);
116 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoffInterval, fuzz);
Darin Petkov85ced132010-09-01 10:20:56 -0700117
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800118 scheduler_.set_poll_interval(
119 UpdateCheckScheduler::kTimeoutPeriodicInterval - 1);
120 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
121 EXPECT_EQ(UpdateCheckScheduler::kTimeoutPeriodicInterval, interval);
Darin Petkov85ced132010-09-01 10:20:56 -0700122 EXPECT_EQ(UpdateCheckScheduler::kTimeoutRegularFuzz, fuzz);
123}
124
125TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzPriorityTest) {
126 int interval, fuzz;
127 attempter_.set_http_response_code(500);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800128 scheduler_.last_interval_ =
129 UpdateCheckScheduler::kTimeoutPeriodicInterval + 50;
130 int poll_interval = UpdateCheckScheduler::kTimeoutPeriodicInterval + 100;
Darin Petkov85ced132010-09-01 10:20:56 -0700131 scheduler_.set_poll_interval(poll_interval);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800132 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
Darin Petkov85ced132010-09-01 10:20:56 -0700133 EXPECT_EQ(poll_interval, interval);
134 EXPECT_EQ(poll_interval, fuzz);
135}
136
Darin Petkov1023a602010-08-30 13:47:51 -0700137TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzTest) {
138 int interval, fuzz;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800139 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
140 EXPECT_EQ(UpdateCheckScheduler::kTimeoutPeriodicInterval, interval);
Darin Petkov1023a602010-08-30 13:47:51 -0700141 EXPECT_EQ(UpdateCheckScheduler::kTimeoutRegularFuzz, fuzz);
142}
143
144TEST_F(UpdateCheckSchedulerTest, GTimeoutAddSecondsTest) {
145 loop_ = g_main_loop_new(g_main_context_default(), FALSE);
146 // Invokes the actual GLib wrapper method rather than the subclass mock.
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700147 scheduler_.UpdateCheckScheduler::GTimeoutAddSeconds(0, SourceCallback);
148 EXPECT_CALL(source_callback_, Call(&scheduler_)).Times(1);
Darin Petkov1023a602010-08-30 13:47:51 -0700149 g_main_loop_run(loop_);
150 g_main_loop_unref(loop_);
151}
152
153TEST_F(UpdateCheckSchedulerTest, IsBootDeviceRemovableTest) {
154 // Invokes the actual utils wrapper method rather than the subclass mock.
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700155 EXPECT_FALSE(scheduler_.UpdateCheckScheduler::IsBootDeviceRemovable());
Darin Petkov1023a602010-08-30 13:47:51 -0700156}
157
Darin Petkov2a0e6332010-09-24 14:43:41 -0700158TEST_F(UpdateCheckSchedulerTest, IsOOBECompleteTest) {
159 // Invokes the actual utils wrapper method rather than the subclass mock.
160 EXPECT_FALSE(scheduler_.UpdateCheckScheduler::IsOOBEComplete());
161}
162
Darin Petkov1023a602010-08-30 13:47:51 -0700163TEST_F(UpdateCheckSchedulerTest, IsOfficialBuildTest) {
164 // Invokes the actual utils wrapper method rather than the subclass mock.
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700165 EXPECT_TRUE(scheduler_.UpdateCheckScheduler::IsOfficialBuild());
Darin Petkov1023a602010-08-30 13:47:51 -0700166}
167
168TEST_F(UpdateCheckSchedulerTest, RunBootDeviceRemovableTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700169 scheduler_.enabled_ = true;
170 EXPECT_CALL(scheduler_, IsOfficialBuild()).Times(1).WillOnce(Return(true));
171 EXPECT_CALL(scheduler_, IsBootDeviceRemovable())
Darin Petkov1023a602010-08-30 13:47:51 -0700172 .Times(1)
173 .WillOnce(Return(true));
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700174 scheduler_.Run();
175 EXPECT_FALSE(scheduler_.enabled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700176 EXPECT_EQ(NULL, attempter_.update_check_scheduler());
177}
178
179TEST_F(UpdateCheckSchedulerTest, RunNonOfficialBuildTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700180 scheduler_.enabled_ = true;
181 EXPECT_CALL(scheduler_, IsOfficialBuild()).Times(1).WillOnce(Return(false));
182 scheduler_.Run();
183 EXPECT_FALSE(scheduler_.enabled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700184 EXPECT_EQ(NULL, attempter_.update_check_scheduler());
185}
186
187TEST_F(UpdateCheckSchedulerTest, RunTest) {
188 int interval_min, interval_max;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800189 FuzzRange(UpdateCheckScheduler::kTimeoutInitialInterval,
Darin Petkov1023a602010-08-30 13:47:51 -0700190 UpdateCheckScheduler::kTimeoutRegularFuzz,
191 &interval_min,
192 &interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700193 EXPECT_CALL(scheduler_, IsOfficialBuild()).Times(1).WillOnce(Return(true));
194 EXPECT_CALL(scheduler_, IsBootDeviceRemovable())
Darin Petkov1023a602010-08-30 13:47:51 -0700195 .Times(1)
196 .WillOnce(Return(false));
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700197 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700198 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700199 scheduler_.StaticCheck)).Times(1);
200 scheduler_.Run();
201 EXPECT_TRUE(scheduler_.enabled_);
202 EXPECT_EQ(&scheduler_, attempter_.update_check_scheduler());
Darin Petkov1023a602010-08-30 13:47:51 -0700203}
204
205TEST_F(UpdateCheckSchedulerTest, ScheduleCheckDisabledTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700206 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
207 scheduler_.ScheduleCheck(250, 30);
208 EXPECT_EQ(0, scheduler_.last_interval_);
209 EXPECT_FALSE(scheduler_.scheduled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700210}
211
212TEST_F(UpdateCheckSchedulerTest, ScheduleCheckEnabledTest) {
213 int interval_min, interval_max;
214 FuzzRange(100, 10, &interval_min,&interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700215 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700216 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700217 scheduler_.StaticCheck)).Times(1);
218 scheduler_.enabled_ = true;
219 scheduler_.ScheduleCheck(100, 10);
220 EXPECT_EQ(100, scheduler_.last_interval_);
221 EXPECT_TRUE(scheduler_.scheduled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700222}
223
224TEST_F(UpdateCheckSchedulerTest, ScheduleCheckNegativeIntervalTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700225 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(0, scheduler_.StaticCheck))
Darin Petkov1023a602010-08-30 13:47:51 -0700226 .Times(1);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700227 scheduler_.enabled_ = true;
228 scheduler_.ScheduleCheck(-50, 20);
229 EXPECT_TRUE(scheduler_.scheduled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700230}
231
232TEST_F(UpdateCheckSchedulerTest, ScheduleNextCheckDisabledTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700233 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800234 scheduler_.ScheduleNextCheck(false);
Darin Petkov1023a602010-08-30 13:47:51 -0700235}
236
237TEST_F(UpdateCheckSchedulerTest, ScheduleNextCheckEnabledTest) {
238 int interval_min, interval_max;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800239 FuzzRange(UpdateCheckScheduler::kTimeoutPeriodicInterval,
Darin Petkov1023a602010-08-30 13:47:51 -0700240 UpdateCheckScheduler::kTimeoutRegularFuzz,
241 &interval_min,
242 &interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700243 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700244 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700245 scheduler_.StaticCheck)).Times(1);
246 scheduler_.enabled_ = true;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800247 scheduler_.ScheduleNextCheck(false);
Darin Petkov1023a602010-08-30 13:47:51 -0700248}
249
250TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusIdleDisabledTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700251 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800252 scheduler_.SetUpdateStatus(UPDATE_STATUS_IDLE, kUpdateNoticeUnspecified);
Darin Petkov1023a602010-08-30 13:47:51 -0700253}
254
255TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusIdleEnabledTest) {
256 int interval_min, interval_max;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800257 FuzzRange(UpdateCheckScheduler::kTimeoutPeriodicInterval,
Darin Petkov1023a602010-08-30 13:47:51 -0700258 UpdateCheckScheduler::kTimeoutRegularFuzz,
259 &interval_min,
260 &interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700261 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700262 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700263 scheduler_.StaticCheck)).Times(1);
264 scheduler_.enabled_ = true;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800265 scheduler_.SetUpdateStatus(UPDATE_STATUS_IDLE, kUpdateNoticeUnspecified);
Darin Petkov1023a602010-08-30 13:47:51 -0700266}
267
268TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusNonIdleTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700269 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800270 scheduler_.SetUpdateStatus(UPDATE_STATUS_DOWNLOADING,
271 kUpdateNoticeUnspecified);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700272 scheduler_.enabled_ = true;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800273 scheduler_.SetUpdateStatus(UPDATE_STATUS_DOWNLOADING,
274 kUpdateNoticeUnspecified);
Darin Petkov1023a602010-08-30 13:47:51 -0700275}
276
Darin Petkov2a0e6332010-09-24 14:43:41 -0700277TEST_F(UpdateCheckSchedulerTest, StaticCheckOOBECompleteTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700278 scheduler_.scheduled_ = true;
Darin Petkov2a0e6332010-09-24 14:43:41 -0700279 EXPECT_CALL(scheduler_, IsOOBEComplete()).Times(1).WillOnce(Return(true));
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800280 EXPECT_CALL(attempter_, Update("", "", false, false, false))
Darin Petkov2a0e6332010-09-24 14:43:41 -0700281 .Times(1)
282 .WillOnce(Assign(&scheduler_.scheduled_, true));
283 scheduler_.enabled_ = true;
284 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
285 UpdateCheckSchedulerUnderTest::StaticCheck(&scheduler_);
286}
287
288TEST_F(UpdateCheckSchedulerTest, StaticCheckOOBENotCompleteTest) {
289 scheduler_.scheduled_ = true;
290 EXPECT_CALL(scheduler_, IsOOBEComplete()).Times(1).WillOnce(Return(false));
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800291 EXPECT_CALL(attempter_, Update("", "", _, _, _)).Times(0);
Darin Petkov2a0e6332010-09-24 14:43:41 -0700292 int interval_min, interval_max;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800293 FuzzRange(UpdateCheckScheduler::kTimeoutInitialInterval,
Darin Petkov2a0e6332010-09-24 14:43:41 -0700294 UpdateCheckScheduler::kTimeoutRegularFuzz,
295 &interval_min,
296 &interval_max);
297 scheduler_.enabled_ = true;
298 EXPECT_CALL(scheduler_,
299 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
300 scheduler_.StaticCheck)).Times(1);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700301 UpdateCheckSchedulerUnderTest::StaticCheck(&scheduler_);
Darin Petkov1023a602010-08-30 13:47:51 -0700302}
303
304} // namespace chromeos_update_engine