blob: 2d2e81d52f94c7ac9e0ab634ea71c679f37ac457 [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:
43 UpdateCheckSchedulerTest() : scheduler_(&attempter_) {}
44
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_;
Darin Petkov1023a602010-08-30 13:47:51 -070068 UpdateAttempterMock attempter_;
69 MockFunction<gboolean(gpointer data)> source_callback_;
70 GMainLoop* loop_;
71 static UpdateCheckSchedulerTest* test_;
72};
73
74UpdateCheckSchedulerTest* UpdateCheckSchedulerTest::test_ = NULL;
75
76TEST_F(UpdateCheckSchedulerTest, CanScheduleTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -070077 EXPECT_FALSE(scheduler_.CanSchedule());
78 scheduler_.enabled_ = true;
79 EXPECT_TRUE(scheduler_.CanSchedule());
80 scheduler_.scheduled_ = true;
81 EXPECT_FALSE(scheduler_.CanSchedule());
82 scheduler_.enabled_ = false;
83 EXPECT_FALSE(scheduler_.CanSchedule());
Darin Petkov1023a602010-08-30 13:47:51 -070084}
85
86TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzBackoffTest) {
87 int interval, fuzz;
88 attempter_.set_http_response_code(500);
89 int last_interval = UpdateCheckScheduler::kTimeoutPeriodic + 50;
Darin Petkovf42cc1c2010-09-01 09:03:02 -070090 scheduler_.last_interval_ = last_interval;
91 scheduler_.ComputeNextIntervalAndFuzz(&interval, &fuzz);
Darin Petkov1023a602010-08-30 13:47:51 -070092 EXPECT_EQ(2 * last_interval, interval);
93 EXPECT_EQ(2 * last_interval, fuzz);
94
95 attempter_.set_http_response_code(503);
Darin Petkov85ced132010-09-01 10:20:56 -070096 scheduler_.last_interval_ = UpdateCheckScheduler::kTimeoutMaxBackoff / 2 + 1;
Darin Petkovf42cc1c2010-09-01 09:03:02 -070097 scheduler_.ComputeNextIntervalAndFuzz(&interval, &fuzz);
Darin Petkov1023a602010-08-30 13:47:51 -070098 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoff, interval);
99 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoff, fuzz);
100}
101
Darin Petkov85ced132010-09-01 10:20:56 -0700102TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzPollTest) {
103 int interval, fuzz;
104 int poll_interval = UpdateCheckScheduler::kTimeoutPeriodic + 50;
105 scheduler_.set_poll_interval(poll_interval);
106 scheduler_.ComputeNextIntervalAndFuzz(&interval, &fuzz);
107 EXPECT_EQ(poll_interval, interval);
108 EXPECT_EQ(poll_interval, fuzz);
109
110 scheduler_.set_poll_interval(UpdateCheckScheduler::kTimeoutMaxBackoff + 1);
111 scheduler_.ComputeNextIntervalAndFuzz(&interval, &fuzz);
112 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoff, interval);
113 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoff, fuzz);
114
115 scheduler_.set_poll_interval(UpdateCheckScheduler::kTimeoutPeriodic - 1);
116 scheduler_.ComputeNextIntervalAndFuzz(&interval, &fuzz);
117 EXPECT_EQ(UpdateCheckScheduler::kTimeoutPeriodic, interval);
118 EXPECT_EQ(UpdateCheckScheduler::kTimeoutRegularFuzz, fuzz);
119}
120
121TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzPriorityTest) {
122 int interval, fuzz;
123 attempter_.set_http_response_code(500);
124 scheduler_.last_interval_ = UpdateCheckScheduler::kTimeoutPeriodic + 50;
125 int poll_interval = UpdateCheckScheduler::kTimeoutPeriodic + 100;
126 scheduler_.set_poll_interval(poll_interval);
127 scheduler_.ComputeNextIntervalAndFuzz(&interval, &fuzz);
128 EXPECT_EQ(poll_interval, interval);
129 EXPECT_EQ(poll_interval, fuzz);
130}
131
Darin Petkov1023a602010-08-30 13:47:51 -0700132TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzTest) {
133 int interval, fuzz;
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700134 scheduler_.ComputeNextIntervalAndFuzz(&interval, &fuzz);
Darin Petkov1023a602010-08-30 13:47:51 -0700135 EXPECT_EQ(UpdateCheckScheduler::kTimeoutPeriodic, interval);
136 EXPECT_EQ(UpdateCheckScheduler::kTimeoutRegularFuzz, fuzz);
137}
138
139TEST_F(UpdateCheckSchedulerTest, GTimeoutAddSecondsTest) {
140 loop_ = g_main_loop_new(g_main_context_default(), FALSE);
141 // Invokes the actual GLib wrapper method rather than the subclass mock.
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700142 scheduler_.UpdateCheckScheduler::GTimeoutAddSeconds(0, SourceCallback);
143 EXPECT_CALL(source_callback_, Call(&scheduler_)).Times(1);
Darin Petkov1023a602010-08-30 13:47:51 -0700144 g_main_loop_run(loop_);
145 g_main_loop_unref(loop_);
146}
147
148TEST_F(UpdateCheckSchedulerTest, IsBootDeviceRemovableTest) {
149 // Invokes the actual utils wrapper method rather than the subclass mock.
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700150 EXPECT_FALSE(scheduler_.UpdateCheckScheduler::IsBootDeviceRemovable());
Darin Petkov1023a602010-08-30 13:47:51 -0700151}
152
Darin Petkov2a0e6332010-09-24 14:43:41 -0700153TEST_F(UpdateCheckSchedulerTest, IsOOBECompleteTest) {
154 // Invokes the actual utils wrapper method rather than the subclass mock.
155 EXPECT_FALSE(scheduler_.UpdateCheckScheduler::IsOOBEComplete());
156}
157
Darin Petkov1023a602010-08-30 13:47:51 -0700158TEST_F(UpdateCheckSchedulerTest, IsOfficialBuildTest) {
159 // Invokes the actual utils wrapper method rather than the subclass mock.
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700160 EXPECT_TRUE(scheduler_.UpdateCheckScheduler::IsOfficialBuild());
Darin Petkov1023a602010-08-30 13:47:51 -0700161}
162
163TEST_F(UpdateCheckSchedulerTest, RunBootDeviceRemovableTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700164 scheduler_.enabled_ = true;
165 EXPECT_CALL(scheduler_, IsOfficialBuild()).Times(1).WillOnce(Return(true));
166 EXPECT_CALL(scheduler_, IsBootDeviceRemovable())
Darin Petkov1023a602010-08-30 13:47:51 -0700167 .Times(1)
168 .WillOnce(Return(true));
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700169 scheduler_.Run();
170 EXPECT_FALSE(scheduler_.enabled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700171 EXPECT_EQ(NULL, attempter_.update_check_scheduler());
172}
173
174TEST_F(UpdateCheckSchedulerTest, RunNonOfficialBuildTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700175 scheduler_.enabled_ = true;
176 EXPECT_CALL(scheduler_, IsOfficialBuild()).Times(1).WillOnce(Return(false));
177 scheduler_.Run();
178 EXPECT_FALSE(scheduler_.enabled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700179 EXPECT_EQ(NULL, attempter_.update_check_scheduler());
180}
181
182TEST_F(UpdateCheckSchedulerTest, RunTest) {
183 int interval_min, interval_max;
184 FuzzRange(UpdateCheckScheduler::kTimeoutOnce,
185 UpdateCheckScheduler::kTimeoutRegularFuzz,
186 &interval_min,
187 &interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700188 EXPECT_CALL(scheduler_, IsOfficialBuild()).Times(1).WillOnce(Return(true));
189 EXPECT_CALL(scheduler_, IsBootDeviceRemovable())
Darin Petkov1023a602010-08-30 13:47:51 -0700190 .Times(1)
191 .WillOnce(Return(false));
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700192 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700193 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700194 scheduler_.StaticCheck)).Times(1);
195 scheduler_.Run();
196 EXPECT_TRUE(scheduler_.enabled_);
197 EXPECT_EQ(&scheduler_, attempter_.update_check_scheduler());
Darin Petkov1023a602010-08-30 13:47:51 -0700198}
199
200TEST_F(UpdateCheckSchedulerTest, ScheduleCheckDisabledTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700201 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
202 scheduler_.ScheduleCheck(250, 30);
203 EXPECT_EQ(0, scheduler_.last_interval_);
204 EXPECT_FALSE(scheduler_.scheduled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700205}
206
207TEST_F(UpdateCheckSchedulerTest, ScheduleCheckEnabledTest) {
208 int interval_min, interval_max;
209 FuzzRange(100, 10, &interval_min,&interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700210 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700211 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700212 scheduler_.StaticCheck)).Times(1);
213 scheduler_.enabled_ = true;
214 scheduler_.ScheduleCheck(100, 10);
215 EXPECT_EQ(100, scheduler_.last_interval_);
216 EXPECT_TRUE(scheduler_.scheduled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700217}
218
219TEST_F(UpdateCheckSchedulerTest, ScheduleCheckNegativeIntervalTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700220 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(0, scheduler_.StaticCheck))
Darin Petkov1023a602010-08-30 13:47:51 -0700221 .Times(1);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700222 scheduler_.enabled_ = true;
223 scheduler_.ScheduleCheck(-50, 20);
224 EXPECT_TRUE(scheduler_.scheduled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700225}
226
227TEST_F(UpdateCheckSchedulerTest, ScheduleNextCheckDisabledTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700228 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
229 scheduler_.ScheduleNextCheck();
Darin Petkov1023a602010-08-30 13:47:51 -0700230}
231
232TEST_F(UpdateCheckSchedulerTest, ScheduleNextCheckEnabledTest) {
233 int interval_min, interval_max;
234 FuzzRange(UpdateCheckScheduler::kTimeoutPeriodic,
235 UpdateCheckScheduler::kTimeoutRegularFuzz,
236 &interval_min,
237 &interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700238 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700239 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700240 scheduler_.StaticCheck)).Times(1);
241 scheduler_.enabled_ = true;
242 scheduler_.ScheduleNextCheck();
Darin Petkov1023a602010-08-30 13:47:51 -0700243}
244
245TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusIdleDisabledTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700246 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
247 scheduler_.SetUpdateStatus(UPDATE_STATUS_IDLE);
Darin Petkov1023a602010-08-30 13:47:51 -0700248}
249
250TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusIdleEnabledTest) {
251 int interval_min, interval_max;
252 FuzzRange(UpdateCheckScheduler::kTimeoutPeriodic,
253 UpdateCheckScheduler::kTimeoutRegularFuzz,
254 &interval_min,
255 &interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700256 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700257 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700258 scheduler_.StaticCheck)).Times(1);
259 scheduler_.enabled_ = true;
260 scheduler_.SetUpdateStatus(UPDATE_STATUS_IDLE);
Darin Petkov1023a602010-08-30 13:47:51 -0700261}
262
263TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusNonIdleTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700264 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
265 scheduler_.SetUpdateStatus(UPDATE_STATUS_DOWNLOADING);
266 scheduler_.enabled_ = true;
267 scheduler_.SetUpdateStatus(UPDATE_STATUS_DOWNLOADING);
Darin Petkov1023a602010-08-30 13:47:51 -0700268}
269
Darin Petkov2a0e6332010-09-24 14:43:41 -0700270TEST_F(UpdateCheckSchedulerTest, StaticCheckOOBECompleteTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700271 scheduler_.scheduled_ = true;
Darin Petkov2a0e6332010-09-24 14:43:41 -0700272 EXPECT_CALL(scheduler_, IsOOBEComplete()).Times(1).WillOnce(Return(true));
273 EXPECT_CALL(attempter_, Update("", ""))
274 .Times(1)
275 .WillOnce(Assign(&scheduler_.scheduled_, true));
276 scheduler_.enabled_ = true;
277 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
278 UpdateCheckSchedulerUnderTest::StaticCheck(&scheduler_);
279}
280
281TEST_F(UpdateCheckSchedulerTest, StaticCheckOOBENotCompleteTest) {
282 scheduler_.scheduled_ = true;
283 EXPECT_CALL(scheduler_, IsOOBEComplete()).Times(1).WillOnce(Return(false));
284 EXPECT_CALL(attempter_, Update("", "")).Times(0);
285 int interval_min, interval_max;
286 FuzzRange(UpdateCheckScheduler::kTimeoutOnce,
287 UpdateCheckScheduler::kTimeoutRegularFuzz,
288 &interval_min,
289 &interval_max);
290 scheduler_.enabled_ = true;
291 EXPECT_CALL(scheduler_,
292 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
293 scheduler_.StaticCheck)).Times(1);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700294 UpdateCheckSchedulerUnderTest::StaticCheck(&scheduler_);
Darin Petkov1023a602010-08-30 13:47:51 -0700295}
296
297} // namespace chromeos_update_engine