blob: bc1a560554f4f8973234f2e5195e743321bf36e8 [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:
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080033 UpdateCheckSchedulerUnderTest(UpdateAttempter* update_attempter,
34 MockSystemState* mock_system_state)
35 : UpdateCheckScheduler(update_attempter, NULL, mock_system_state),
36 mock_system_state_(mock_system_state) {}
Darin Petkov1023a602010-08-30 13:47:51 -070037
38 MOCK_METHOD2(GTimeoutAddSeconds, guint(guint seconds, GSourceFunc function));
39 MOCK_METHOD0(IsBootDeviceRemovable, bool());
40 MOCK_METHOD0(IsOfficialBuild, bool());
Jay Srinivasan08fce042012-06-07 16:31:01 -070041
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080042 MockSystemState* mock_system_state_;
Darin Petkov1023a602010-08-30 13:47:51 -070043};
44
45class UpdateCheckSchedulerTest : public ::testing::Test {
Darin Petkovf42cc1c2010-09-01 09:03:02 -070046 public:
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080047 UpdateCheckSchedulerTest()
48 : attempter_(&mock_system_state_, &dbus_),
49 scheduler_(&attempter_, &mock_system_state_) {}
Darin Petkovf42cc1c2010-09-01 09:03:02 -070050
Darin Petkov1023a602010-08-30 13:47:51 -070051 protected:
52 virtual void SetUp() {
53 test_ = this;
54 loop_ = NULL;
Darin Petkovf42cc1c2010-09-01 09:03:02 -070055 EXPECT_EQ(&attempter_, scheduler_.update_attempter_);
56 EXPECT_FALSE(scheduler_.enabled_);
57 EXPECT_FALSE(scheduler_.scheduled_);
58 EXPECT_EQ(0, scheduler_.last_interval_);
Darin Petkov85ced132010-09-01 10:20:56 -070059 EXPECT_EQ(0, scheduler_.poll_interval_);
Darin Petkov1023a602010-08-30 13:47:51 -070060 }
61
62 virtual void TearDown() {
63 test_ = NULL;
64 loop_ = NULL;
Darin Petkov1023a602010-08-30 13:47:51 -070065 }
66
67 static gboolean SourceCallback(gpointer data) {
68 g_main_loop_quit(test_->loop_);
69 // Forwards the call to the function mock so that expectations can be set.
70 return test_->source_callback_.Call(data);
71 }
72
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080073 MockSystemState mock_system_state_;
Andrew de los Reyes000d8952011-03-02 15:21:14 -080074 MockDbusGlib dbus_;
Darin Petkov1023a602010-08-30 13:47:51 -070075 UpdateAttempterMock attempter_;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080076 UpdateCheckSchedulerUnderTest scheduler_;
Darin Petkov1023a602010-08-30 13:47:51 -070077 MockFunction<gboolean(gpointer data)> source_callback_;
78 GMainLoop* loop_;
79 static UpdateCheckSchedulerTest* test_;
80};
81
82UpdateCheckSchedulerTest* UpdateCheckSchedulerTest::test_ = NULL;
83
84TEST_F(UpdateCheckSchedulerTest, CanScheduleTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -070085 EXPECT_FALSE(scheduler_.CanSchedule());
86 scheduler_.enabled_ = true;
87 EXPECT_TRUE(scheduler_.CanSchedule());
88 scheduler_.scheduled_ = true;
89 EXPECT_FALSE(scheduler_.CanSchedule());
90 scheduler_.enabled_ = false;
91 EXPECT_FALSE(scheduler_.CanSchedule());
Darin Petkov1023a602010-08-30 13:47:51 -070092}
93
94TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzBackoffTest) {
95 int interval, fuzz;
96 attempter_.set_http_response_code(500);
Gilad Arnold1ebd8132012-03-05 10:19:29 -080097 int last_interval = UpdateCheckScheduler::kTimeoutPeriodicInterval + 50;
Darin Petkovf42cc1c2010-09-01 09:03:02 -070098 scheduler_.last_interval_ = last_interval;
Gilad Arnold1ebd8132012-03-05 10:19:29 -080099 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
Darin Petkov1023a602010-08-30 13:47:51 -0700100 EXPECT_EQ(2 * last_interval, interval);
101 EXPECT_EQ(2 * last_interval, fuzz);
102
103 attempter_.set_http_response_code(503);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800104 scheduler_.last_interval_ =
105 UpdateCheckScheduler::kTimeoutMaxBackoffInterval / 2 + 1;
106 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
107 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoffInterval, interval);
108 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoffInterval, fuzz);
Darin Petkov1023a602010-08-30 13:47:51 -0700109}
110
Darin Petkov85ced132010-09-01 10:20:56 -0700111TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzPollTest) {
112 int interval, fuzz;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800113 int poll_interval = UpdateCheckScheduler::kTimeoutPeriodicInterval + 50;
Darin Petkov85ced132010-09-01 10:20:56 -0700114 scheduler_.set_poll_interval(poll_interval);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800115 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
Darin Petkov85ced132010-09-01 10:20:56 -0700116 EXPECT_EQ(poll_interval, interval);
117 EXPECT_EQ(poll_interval, fuzz);
118
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800119 scheduler_.set_poll_interval(
120 UpdateCheckScheduler::kTimeoutMaxBackoffInterval + 1);
121 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
122 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoffInterval, interval);
123 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoffInterval, fuzz);
Darin Petkov85ced132010-09-01 10:20:56 -0700124
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800125 scheduler_.set_poll_interval(
126 UpdateCheckScheduler::kTimeoutPeriodicInterval - 1);
127 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
128 EXPECT_EQ(UpdateCheckScheduler::kTimeoutPeriodicInterval, interval);
Darin Petkov85ced132010-09-01 10:20:56 -0700129 EXPECT_EQ(UpdateCheckScheduler::kTimeoutRegularFuzz, fuzz);
130}
131
132TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzPriorityTest) {
133 int interval, fuzz;
134 attempter_.set_http_response_code(500);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800135 scheduler_.last_interval_ =
136 UpdateCheckScheduler::kTimeoutPeriodicInterval + 50;
137 int poll_interval = UpdateCheckScheduler::kTimeoutPeriodicInterval + 100;
Darin Petkov85ced132010-09-01 10:20:56 -0700138 scheduler_.set_poll_interval(poll_interval);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800139 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
Darin Petkov85ced132010-09-01 10:20:56 -0700140 EXPECT_EQ(poll_interval, interval);
141 EXPECT_EQ(poll_interval, fuzz);
142}
143
Darin Petkov1023a602010-08-30 13:47:51 -0700144TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzTest) {
145 int interval, fuzz;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800146 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
147 EXPECT_EQ(UpdateCheckScheduler::kTimeoutPeriodicInterval, interval);
Darin Petkov1023a602010-08-30 13:47:51 -0700148 EXPECT_EQ(UpdateCheckScheduler::kTimeoutRegularFuzz, fuzz);
149}
150
151TEST_F(UpdateCheckSchedulerTest, GTimeoutAddSecondsTest) {
152 loop_ = g_main_loop_new(g_main_context_default(), FALSE);
153 // Invokes the actual GLib wrapper method rather than the subclass mock.
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700154 scheduler_.UpdateCheckScheduler::GTimeoutAddSeconds(0, SourceCallback);
155 EXPECT_CALL(source_callback_, Call(&scheduler_)).Times(1);
Darin Petkov1023a602010-08-30 13:47:51 -0700156 g_main_loop_run(loop_);
157 g_main_loop_unref(loop_);
158}
159
160TEST_F(UpdateCheckSchedulerTest, IsBootDeviceRemovableTest) {
161 // Invokes the actual utils wrapper method rather than the subclass mock.
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700162 EXPECT_FALSE(scheduler_.UpdateCheckScheduler::IsBootDeviceRemovable());
Darin Petkov1023a602010-08-30 13:47:51 -0700163}
164
165TEST_F(UpdateCheckSchedulerTest, IsOfficialBuildTest) {
166 // Invokes the actual utils wrapper method rather than the subclass mock.
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700167 EXPECT_TRUE(scheduler_.UpdateCheckScheduler::IsOfficialBuild());
Darin Petkov1023a602010-08-30 13:47:51 -0700168}
169
170TEST_F(UpdateCheckSchedulerTest, RunBootDeviceRemovableTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700171 scheduler_.enabled_ = true;
172 EXPECT_CALL(scheduler_, IsOfficialBuild()).Times(1).WillOnce(Return(true));
173 EXPECT_CALL(scheduler_, IsBootDeviceRemovable())
Darin Petkov1023a602010-08-30 13:47:51 -0700174 .Times(1)
175 .WillOnce(Return(true));
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700176 scheduler_.Run();
177 EXPECT_FALSE(scheduler_.enabled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700178 EXPECT_EQ(NULL, attempter_.update_check_scheduler());
179}
180
181TEST_F(UpdateCheckSchedulerTest, RunNonOfficialBuildTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700182 scheduler_.enabled_ = true;
183 EXPECT_CALL(scheduler_, IsOfficialBuild()).Times(1).WillOnce(Return(false));
184 scheduler_.Run();
185 EXPECT_FALSE(scheduler_.enabled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700186 EXPECT_EQ(NULL, attempter_.update_check_scheduler());
187}
188
189TEST_F(UpdateCheckSchedulerTest, RunTest) {
190 int interval_min, interval_max;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800191 FuzzRange(UpdateCheckScheduler::kTimeoutInitialInterval,
Darin Petkov1023a602010-08-30 13:47:51 -0700192 UpdateCheckScheduler::kTimeoutRegularFuzz,
193 &interval_min,
194 &interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700195 EXPECT_CALL(scheduler_, IsOfficialBuild()).Times(1).WillOnce(Return(true));
196 EXPECT_CALL(scheduler_, IsBootDeviceRemovable())
Darin Petkov1023a602010-08-30 13:47:51 -0700197 .Times(1)
198 .WillOnce(Return(false));
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700199 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700200 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700201 scheduler_.StaticCheck)).Times(1);
202 scheduler_.Run();
203 EXPECT_TRUE(scheduler_.enabled_);
204 EXPECT_EQ(&scheduler_, attempter_.update_check_scheduler());
Darin Petkov1023a602010-08-30 13:47:51 -0700205}
206
207TEST_F(UpdateCheckSchedulerTest, ScheduleCheckDisabledTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700208 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
209 scheduler_.ScheduleCheck(250, 30);
210 EXPECT_EQ(0, scheduler_.last_interval_);
211 EXPECT_FALSE(scheduler_.scheduled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700212}
213
214TEST_F(UpdateCheckSchedulerTest, ScheduleCheckEnabledTest) {
215 int interval_min, interval_max;
216 FuzzRange(100, 10, &interval_min,&interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700217 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700218 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700219 scheduler_.StaticCheck)).Times(1);
220 scheduler_.enabled_ = true;
221 scheduler_.ScheduleCheck(100, 10);
222 EXPECT_EQ(100, scheduler_.last_interval_);
223 EXPECT_TRUE(scheduler_.scheduled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700224}
225
226TEST_F(UpdateCheckSchedulerTest, ScheduleCheckNegativeIntervalTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700227 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(0, scheduler_.StaticCheck))
Darin Petkov1023a602010-08-30 13:47:51 -0700228 .Times(1);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700229 scheduler_.enabled_ = true;
230 scheduler_.ScheduleCheck(-50, 20);
231 EXPECT_TRUE(scheduler_.scheduled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700232}
233
234TEST_F(UpdateCheckSchedulerTest, ScheduleNextCheckDisabledTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700235 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800236 scheduler_.ScheduleNextCheck(false);
Darin Petkov1023a602010-08-30 13:47:51 -0700237}
238
239TEST_F(UpdateCheckSchedulerTest, ScheduleNextCheckEnabledTest) {
240 int interval_min, interval_max;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800241 FuzzRange(UpdateCheckScheduler::kTimeoutPeriodicInterval,
Darin Petkov1023a602010-08-30 13:47:51 -0700242 UpdateCheckScheduler::kTimeoutRegularFuzz,
243 &interval_min,
244 &interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700245 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700246 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700247 scheduler_.StaticCheck)).Times(1);
248 scheduler_.enabled_ = true;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800249 scheduler_.ScheduleNextCheck(false);
Darin Petkov1023a602010-08-30 13:47:51 -0700250}
251
252TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusIdleDisabledTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700253 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800254 scheduler_.SetUpdateStatus(UPDATE_STATUS_IDLE, kUpdateNoticeUnspecified);
Darin Petkov1023a602010-08-30 13:47:51 -0700255}
256
257TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusIdleEnabledTest) {
258 int interval_min, interval_max;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800259 FuzzRange(UpdateCheckScheduler::kTimeoutPeriodicInterval,
Darin Petkov1023a602010-08-30 13:47:51 -0700260 UpdateCheckScheduler::kTimeoutRegularFuzz,
261 &interval_min,
262 &interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700263 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700264 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700265 scheduler_.StaticCheck)).Times(1);
266 scheduler_.enabled_ = true;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800267 scheduler_.SetUpdateStatus(UPDATE_STATUS_IDLE, kUpdateNoticeUnspecified);
Darin Petkov1023a602010-08-30 13:47:51 -0700268}
269
270TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusNonIdleTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700271 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800272 scheduler_.SetUpdateStatus(UPDATE_STATUS_DOWNLOADING,
273 kUpdateNoticeUnspecified);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700274 scheduler_.enabled_ = true;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800275 scheduler_.SetUpdateStatus(UPDATE_STATUS_DOWNLOADING,
276 kUpdateNoticeUnspecified);
Darin Petkov1023a602010-08-30 13:47:51 -0700277}
278
Darin Petkov2a0e6332010-09-24 14:43:41 -0700279TEST_F(UpdateCheckSchedulerTest, StaticCheckOOBECompleteTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700280 scheduler_.scheduled_ = true;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800281 EXPECT_TRUE(scheduler_.mock_system_state_ != NULL);
282 EXPECT_CALL(*scheduler_.mock_system_state_,
Jay Srinivasan08fce042012-06-07 16:31:01 -0700283 IsOOBEComplete()).Times(1).WillOnce(Return(true));
284 EXPECT_CALL(attempter_, Update("", "", false, false, false, false))
Darin Petkov2a0e6332010-09-24 14:43:41 -0700285 .Times(1)
286 .WillOnce(Assign(&scheduler_.scheduled_, true));
287 scheduler_.enabled_ = true;
288 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
289 UpdateCheckSchedulerUnderTest::StaticCheck(&scheduler_);
290}
291
292TEST_F(UpdateCheckSchedulerTest, StaticCheckOOBENotCompleteTest) {
293 scheduler_.scheduled_ = true;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800294 EXPECT_CALL(*scheduler_.mock_system_state_,
Jay Srinivasan08fce042012-06-07 16:31:01 -0700295 IsOOBEComplete()).Times(1).WillOnce(Return(false));
296 EXPECT_CALL(attempter_, Update("", "", _, _, _,_)).Times(0);
Darin Petkov2a0e6332010-09-24 14:43:41 -0700297 int interval_min, interval_max;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800298 FuzzRange(UpdateCheckScheduler::kTimeoutInitialInterval,
Darin Petkov2a0e6332010-09-24 14:43:41 -0700299 UpdateCheckScheduler::kTimeoutRegularFuzz,
300 &interval_min,
301 &interval_max);
302 scheduler_.enabled_ = true;
303 EXPECT_CALL(scheduler_,
304 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
305 scheduler_.StaticCheck)).Times(1);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700306 UpdateCheckSchedulerUnderTest::StaticCheck(&scheduler_);
Darin Petkov1023a602010-08-30 13:47:51 -0700307}
308
309} // namespace chromeos_update_engine