blob: 2e7e62da049f0c629ba9bb969b484f8f6a62a07b [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
Jay Srinivasan08fce042012-06-07 16:31:01 -07007#include "update_engine/mock_system_state.h"
Darin Petkov1023a602010-08-30 13:47:51 -07008#include "update_engine/update_attempter_mock.h"
9#include "update_engine/update_check_scheduler.h"
10
11using std::string;
12using testing::_;
13using testing::AllOf;
Darin Petkov2a0e6332010-09-24 14:43:41 -070014using testing::Assign;
Darin Petkov1023a602010-08-30 13:47:51 -070015using testing::Ge;
16using testing::Le;
17using testing::MockFunction;
18using testing::Return;
19
20namespace chromeos_update_engine {
21
22namespace {
23void FuzzRange(int interval, int fuzz, int* interval_min, int* interval_max) {
24 *interval_min = interval - fuzz / 2;
25 *interval_max = interval + fuzz - fuzz / 2;
26}
27} // namespace {}
28
29// Test a subclass rather than the main class directly so that we can mock out
30// GLib and utils in tests. There're explicit unit test for the wrapper methods.
31class UpdateCheckSchedulerUnderTest : public UpdateCheckScheduler {
32 public:
33 UpdateCheckSchedulerUnderTest(UpdateAttempter* update_attempter)
Jay Srinivasan08fce042012-06-07 16:31:01 -070034 : UpdateCheckScheduler(update_attempter, NULL, &mock_system_state_) {}
Darin Petkov1023a602010-08-30 13:47:51 -070035
36 MOCK_METHOD2(GTimeoutAddSeconds, guint(guint seconds, GSourceFunc function));
37 MOCK_METHOD0(IsBootDeviceRemovable, bool());
38 MOCK_METHOD0(IsOfficialBuild, bool());
Jay Srinivasan08fce042012-06-07 16:31:01 -070039
40 MockSystemState mock_system_state_;
Darin Petkov1023a602010-08-30 13:47:51 -070041};
42
43class UpdateCheckSchedulerTest : public ::testing::Test {
Darin Petkovf42cc1c2010-09-01 09:03:02 -070044 public:
Andrew de los Reyes000d8952011-03-02 15:21:14 -080045 UpdateCheckSchedulerTest() : scheduler_(&attempter_), attempter_(&dbus_) {}
Darin Petkovf42cc1c2010-09-01 09:03:02 -070046
Darin Petkov1023a602010-08-30 13:47:51 -070047 protected:
48 virtual void SetUp() {
49 test_ = this;
50 loop_ = NULL;
Darin Petkovf42cc1c2010-09-01 09:03:02 -070051 EXPECT_EQ(&attempter_, scheduler_.update_attempter_);
52 EXPECT_FALSE(scheduler_.enabled_);
53 EXPECT_FALSE(scheduler_.scheduled_);
54 EXPECT_EQ(0, scheduler_.last_interval_);
Darin Petkov85ced132010-09-01 10:20:56 -070055 EXPECT_EQ(0, scheduler_.poll_interval_);
Darin Petkov1023a602010-08-30 13:47:51 -070056 }
57
58 virtual void TearDown() {
59 test_ = NULL;
60 loop_ = NULL;
Darin Petkov1023a602010-08-30 13:47:51 -070061 }
62
63 static gboolean SourceCallback(gpointer data) {
64 g_main_loop_quit(test_->loop_);
65 // Forwards the call to the function mock so that expectations can be set.
66 return test_->source_callback_.Call(data);
67 }
68
Darin Petkovf42cc1c2010-09-01 09:03:02 -070069 UpdateCheckSchedulerUnderTest scheduler_;
Andrew de los Reyes000d8952011-03-02 15:21:14 -080070 MockDbusGlib dbus_;
Darin Petkov1023a602010-08-30 13:47:51 -070071 UpdateAttempterMock attempter_;
72 MockFunction<gboolean(gpointer data)> source_callback_;
73 GMainLoop* loop_;
74 static UpdateCheckSchedulerTest* test_;
75};
76
77UpdateCheckSchedulerTest* UpdateCheckSchedulerTest::test_ = NULL;
78
79TEST_F(UpdateCheckSchedulerTest, CanScheduleTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -070080 EXPECT_FALSE(scheduler_.CanSchedule());
81 scheduler_.enabled_ = true;
82 EXPECT_TRUE(scheduler_.CanSchedule());
83 scheduler_.scheduled_ = true;
84 EXPECT_FALSE(scheduler_.CanSchedule());
85 scheduler_.enabled_ = false;
86 EXPECT_FALSE(scheduler_.CanSchedule());
Darin Petkov1023a602010-08-30 13:47:51 -070087}
88
89TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzBackoffTest) {
90 int interval, fuzz;
91 attempter_.set_http_response_code(500);
Gilad Arnold1ebd8132012-03-05 10:19:29 -080092 int last_interval = UpdateCheckScheduler::kTimeoutPeriodicInterval + 50;
Darin Petkovf42cc1c2010-09-01 09:03:02 -070093 scheduler_.last_interval_ = last_interval;
Gilad Arnold1ebd8132012-03-05 10:19:29 -080094 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
Darin Petkov1023a602010-08-30 13:47:51 -070095 EXPECT_EQ(2 * last_interval, interval);
96 EXPECT_EQ(2 * last_interval, fuzz);
97
98 attempter_.set_http_response_code(503);
Gilad Arnold1ebd8132012-03-05 10:19:29 -080099 scheduler_.last_interval_ =
100 UpdateCheckScheduler::kTimeoutMaxBackoffInterval / 2 + 1;
101 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
102 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoffInterval, interval);
103 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoffInterval, fuzz);
Darin Petkov1023a602010-08-30 13:47:51 -0700104}
105
Darin Petkov85ced132010-09-01 10:20:56 -0700106TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzPollTest) {
107 int interval, fuzz;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800108 int poll_interval = UpdateCheckScheduler::kTimeoutPeriodicInterval + 50;
Darin Petkov85ced132010-09-01 10:20:56 -0700109 scheduler_.set_poll_interval(poll_interval);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800110 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
Darin Petkov85ced132010-09-01 10:20:56 -0700111 EXPECT_EQ(poll_interval, interval);
112 EXPECT_EQ(poll_interval, fuzz);
113
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800114 scheduler_.set_poll_interval(
115 UpdateCheckScheduler::kTimeoutMaxBackoffInterval + 1);
116 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
117 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoffInterval, interval);
118 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoffInterval, fuzz);
Darin Petkov85ced132010-09-01 10:20:56 -0700119
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800120 scheduler_.set_poll_interval(
121 UpdateCheckScheduler::kTimeoutPeriodicInterval - 1);
122 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
123 EXPECT_EQ(UpdateCheckScheduler::kTimeoutPeriodicInterval, interval);
Darin Petkov85ced132010-09-01 10:20:56 -0700124 EXPECT_EQ(UpdateCheckScheduler::kTimeoutRegularFuzz, fuzz);
125}
126
127TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzPriorityTest) {
128 int interval, fuzz;
129 attempter_.set_http_response_code(500);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800130 scheduler_.last_interval_ =
131 UpdateCheckScheduler::kTimeoutPeriodicInterval + 50;
132 int poll_interval = UpdateCheckScheduler::kTimeoutPeriodicInterval + 100;
Darin Petkov85ced132010-09-01 10:20:56 -0700133 scheduler_.set_poll_interval(poll_interval);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800134 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
Darin Petkov85ced132010-09-01 10:20:56 -0700135 EXPECT_EQ(poll_interval, interval);
136 EXPECT_EQ(poll_interval, fuzz);
137}
138
Darin Petkov1023a602010-08-30 13:47:51 -0700139TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzTest) {
140 int interval, fuzz;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800141 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
142 EXPECT_EQ(UpdateCheckScheduler::kTimeoutPeriodicInterval, interval);
Darin Petkov1023a602010-08-30 13:47:51 -0700143 EXPECT_EQ(UpdateCheckScheduler::kTimeoutRegularFuzz, fuzz);
144}
145
146TEST_F(UpdateCheckSchedulerTest, GTimeoutAddSecondsTest) {
147 loop_ = g_main_loop_new(g_main_context_default(), FALSE);
148 // Invokes the actual GLib wrapper method rather than the subclass mock.
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700149 scheduler_.UpdateCheckScheduler::GTimeoutAddSeconds(0, SourceCallback);
150 EXPECT_CALL(source_callback_, Call(&scheduler_)).Times(1);
Darin Petkov1023a602010-08-30 13:47:51 -0700151 g_main_loop_run(loop_);
152 g_main_loop_unref(loop_);
153}
154
155TEST_F(UpdateCheckSchedulerTest, IsBootDeviceRemovableTest) {
156 // Invokes the actual utils wrapper method rather than the subclass mock.
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700157 EXPECT_FALSE(scheduler_.UpdateCheckScheduler::IsBootDeviceRemovable());
Darin Petkov1023a602010-08-30 13:47:51 -0700158}
159
160TEST_F(UpdateCheckSchedulerTest, IsOfficialBuildTest) {
161 // Invokes the actual utils wrapper method rather than the subclass mock.
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700162 EXPECT_TRUE(scheduler_.UpdateCheckScheduler::IsOfficialBuild());
Darin Petkov1023a602010-08-30 13:47:51 -0700163}
164
165TEST_F(UpdateCheckSchedulerTest, RunBootDeviceRemovableTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700166 scheduler_.enabled_ = true;
167 EXPECT_CALL(scheduler_, IsOfficialBuild()).Times(1).WillOnce(Return(true));
168 EXPECT_CALL(scheduler_, IsBootDeviceRemovable())
Darin Petkov1023a602010-08-30 13:47:51 -0700169 .Times(1)
170 .WillOnce(Return(true));
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700171 scheduler_.Run();
172 EXPECT_FALSE(scheduler_.enabled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700173 EXPECT_EQ(NULL, attempter_.update_check_scheduler());
174}
175
176TEST_F(UpdateCheckSchedulerTest, RunNonOfficialBuildTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700177 scheduler_.enabled_ = true;
178 EXPECT_CALL(scheduler_, IsOfficialBuild()).Times(1).WillOnce(Return(false));
179 scheduler_.Run();
180 EXPECT_FALSE(scheduler_.enabled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700181 EXPECT_EQ(NULL, attempter_.update_check_scheduler());
182}
183
184TEST_F(UpdateCheckSchedulerTest, RunTest) {
185 int interval_min, interval_max;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800186 FuzzRange(UpdateCheckScheduler::kTimeoutInitialInterval,
Darin Petkov1023a602010-08-30 13:47:51 -0700187 UpdateCheckScheduler::kTimeoutRegularFuzz,
188 &interval_min,
189 &interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700190 EXPECT_CALL(scheduler_, IsOfficialBuild()).Times(1).WillOnce(Return(true));
191 EXPECT_CALL(scheduler_, IsBootDeviceRemovable())
Darin Petkov1023a602010-08-30 13:47:51 -0700192 .Times(1)
193 .WillOnce(Return(false));
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700194 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700195 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700196 scheduler_.StaticCheck)).Times(1);
197 scheduler_.Run();
198 EXPECT_TRUE(scheduler_.enabled_);
199 EXPECT_EQ(&scheduler_, attempter_.update_check_scheduler());
Darin Petkov1023a602010-08-30 13:47:51 -0700200}
201
202TEST_F(UpdateCheckSchedulerTest, ScheduleCheckDisabledTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700203 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
204 scheduler_.ScheduleCheck(250, 30);
205 EXPECT_EQ(0, scheduler_.last_interval_);
206 EXPECT_FALSE(scheduler_.scheduled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700207}
208
209TEST_F(UpdateCheckSchedulerTest, ScheduleCheckEnabledTest) {
210 int interval_min, interval_max;
211 FuzzRange(100, 10, &interval_min,&interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700212 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700213 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700214 scheduler_.StaticCheck)).Times(1);
215 scheduler_.enabled_ = true;
216 scheduler_.ScheduleCheck(100, 10);
217 EXPECT_EQ(100, scheduler_.last_interval_);
218 EXPECT_TRUE(scheduler_.scheduled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700219}
220
221TEST_F(UpdateCheckSchedulerTest, ScheduleCheckNegativeIntervalTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700222 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(0, scheduler_.StaticCheck))
Darin Petkov1023a602010-08-30 13:47:51 -0700223 .Times(1);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700224 scheduler_.enabled_ = true;
225 scheduler_.ScheduleCheck(-50, 20);
226 EXPECT_TRUE(scheduler_.scheduled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700227}
228
229TEST_F(UpdateCheckSchedulerTest, ScheduleNextCheckDisabledTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700230 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800231 scheduler_.ScheduleNextCheck(false);
Darin Petkov1023a602010-08-30 13:47:51 -0700232}
233
234TEST_F(UpdateCheckSchedulerTest, ScheduleNextCheckEnabledTest) {
235 int interval_min, interval_max;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800236 FuzzRange(UpdateCheckScheduler::kTimeoutPeriodicInterval,
Darin Petkov1023a602010-08-30 13:47:51 -0700237 UpdateCheckScheduler::kTimeoutRegularFuzz,
238 &interval_min,
239 &interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700240 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700241 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700242 scheduler_.StaticCheck)).Times(1);
243 scheduler_.enabled_ = true;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800244 scheduler_.ScheduleNextCheck(false);
Darin Petkov1023a602010-08-30 13:47:51 -0700245}
246
247TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusIdleDisabledTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700248 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800249 scheduler_.SetUpdateStatus(UPDATE_STATUS_IDLE, kUpdateNoticeUnspecified);
Darin Petkov1023a602010-08-30 13:47:51 -0700250}
251
252TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusIdleEnabledTest) {
253 int interval_min, interval_max;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800254 FuzzRange(UpdateCheckScheduler::kTimeoutPeriodicInterval,
Darin Petkov1023a602010-08-30 13:47:51 -0700255 UpdateCheckScheduler::kTimeoutRegularFuzz,
256 &interval_min,
257 &interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700258 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700259 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700260 scheduler_.StaticCheck)).Times(1);
261 scheduler_.enabled_ = true;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800262 scheduler_.SetUpdateStatus(UPDATE_STATUS_IDLE, kUpdateNoticeUnspecified);
Darin Petkov1023a602010-08-30 13:47:51 -0700263}
264
265TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusNonIdleTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700266 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800267 scheduler_.SetUpdateStatus(UPDATE_STATUS_DOWNLOADING,
268 kUpdateNoticeUnspecified);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700269 scheduler_.enabled_ = true;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800270 scheduler_.SetUpdateStatus(UPDATE_STATUS_DOWNLOADING,
271 kUpdateNoticeUnspecified);
Darin Petkov1023a602010-08-30 13:47:51 -0700272}
273
Darin Petkov2a0e6332010-09-24 14:43:41 -0700274TEST_F(UpdateCheckSchedulerTest, StaticCheckOOBECompleteTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700275 scheduler_.scheduled_ = true;
Jay Srinivasan08fce042012-06-07 16:31:01 -0700276 EXPECT_CALL(scheduler_.mock_system_state_,
277 IsOOBEComplete()).Times(1).WillOnce(Return(true));
278 EXPECT_CALL(attempter_, Update("", "", false, false, false, false))
Darin Petkov2a0e6332010-09-24 14:43:41 -0700279 .Times(1)
280 .WillOnce(Assign(&scheduler_.scheduled_, true));
281 scheduler_.enabled_ = true;
282 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
283 UpdateCheckSchedulerUnderTest::StaticCheck(&scheduler_);
284}
285
286TEST_F(UpdateCheckSchedulerTest, StaticCheckOOBENotCompleteTest) {
287 scheduler_.scheduled_ = true;
Jay Srinivasan08fce042012-06-07 16:31:01 -0700288 EXPECT_CALL(scheduler_.mock_system_state_,
289 IsOOBEComplete()).Times(1).WillOnce(Return(false));
290 EXPECT_CALL(attempter_, Update("", "", _, _, _,_)).Times(0);
Darin Petkov2a0e6332010-09-24 14:43:41 -0700291 int interval_min, interval_max;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800292 FuzzRange(UpdateCheckScheduler::kTimeoutInitialInterval,
Darin Petkov2a0e6332010-09-24 14:43:41 -0700293 UpdateCheckScheduler::kTimeoutRegularFuzz,
294 &interval_min,
295 &interval_max);
296 scheduler_.enabled_ = true;
297 EXPECT_CALL(scheduler_,
298 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
299 scheduler_.StaticCheck)).Times(1);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700300 UpdateCheckSchedulerUnderTest::StaticCheck(&scheduler_);
Darin Petkov1023a602010-08-30 13:47:51 -0700301}
302
303} // namespace chromeos_update_engine