blob: c9e04474bd992c7cf433ed1affcc5f5e2e900d6b [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
Han Shen07428b52012-12-18 10:29:20 -08007#include "update_engine/certificate_checker.h"
8#include "update_engine/certificate_checker_mock.h"
Jay Srinivasan08fce042012-06-07 16:31:01 -07009#include "update_engine/mock_system_state.h"
Darin Petkov1023a602010-08-30 13:47:51 -070010#include "update_engine/update_attempter_mock.h"
11#include "update_engine/update_check_scheduler.h"
12
13using std::string;
14using testing::_;
15using testing::AllOf;
Darin Petkov2a0e6332010-09-24 14:43:41 -070016using testing::Assign;
Darin Petkov1023a602010-08-30 13:47:51 -070017using testing::Ge;
18using testing::Le;
19using testing::MockFunction;
20using testing::Return;
21
22namespace chromeos_update_engine {
23
24namespace {
25void FuzzRange(int interval, int fuzz, int* interval_min, int* interval_max) {
26 *interval_min = interval - fuzz / 2;
27 *interval_max = interval + fuzz - fuzz / 2;
28}
29} // namespace {}
30
31// Test a subclass rather than the main class directly so that we can mock out
32// GLib and utils in tests. There're explicit unit test for the wrapper methods.
33class UpdateCheckSchedulerUnderTest : public UpdateCheckScheduler {
34 public:
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080035 UpdateCheckSchedulerUnderTest(UpdateAttempter* update_attempter,
36 MockSystemState* mock_system_state)
Gilad Arnoldbf7919b2013-01-08 13:07:37 -080037 : UpdateCheckScheduler(update_attempter, mock_system_state),
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080038 mock_system_state_(mock_system_state) {}
Darin Petkov1023a602010-08-30 13:47:51 -070039
40 MOCK_METHOD2(GTimeoutAddSeconds, guint(guint seconds, GSourceFunc function));
41 MOCK_METHOD0(IsBootDeviceRemovable, bool());
42 MOCK_METHOD0(IsOfficialBuild, bool());
Jay Srinivasan08fce042012-06-07 16:31:01 -070043
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080044 MockSystemState* mock_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()
50 : attempter_(&mock_system_state_, &dbus_),
51 scheduler_(&attempter_, &mock_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.
63 CertificateChecker::set_system_state(&mock_system_state_);
64 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
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080078 MockSystemState mock_system_state_;
Andrew de los Reyes000d8952011-03-02 15:21:14 -080079 MockDbusGlib 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;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800105 scheduler_.ComputeNextIntervalAndFuzz(0, &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;
112 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
113 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);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800121 scheduler_.ComputeNextIntervalAndFuzz(0, &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);
127 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
128 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);
133 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
134 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);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800145 scheduler_.ComputeNextIntervalAndFuzz(0, &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;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800152 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
153 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
166TEST_F(UpdateCheckSchedulerTest, IsBootDeviceRemovableTest) {
167 // Invokes the actual utils wrapper method rather than the subclass mock.
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700168 EXPECT_FALSE(scheduler_.UpdateCheckScheduler::IsBootDeviceRemovable());
Darin Petkov1023a602010-08-30 13:47:51 -0700169}
170
171TEST_F(UpdateCheckSchedulerTest, IsOfficialBuildTest) {
172 // Invokes the actual utils wrapper method rather than the subclass mock.
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700173 EXPECT_TRUE(scheduler_.UpdateCheckScheduler::IsOfficialBuild());
Darin Petkov1023a602010-08-30 13:47:51 -0700174}
175
176TEST_F(UpdateCheckSchedulerTest, RunBootDeviceRemovableTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700177 scheduler_.enabled_ = true;
178 EXPECT_CALL(scheduler_, IsOfficialBuild()).Times(1).WillOnce(Return(true));
179 EXPECT_CALL(scheduler_, IsBootDeviceRemovable())
Darin Petkov1023a602010-08-30 13:47:51 -0700180 .Times(1)
181 .WillOnce(Return(true));
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700182 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, RunNonOfficialBuildTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700188 scheduler_.enabled_ = true;
189 EXPECT_CALL(scheduler_, IsOfficialBuild()).Times(1).WillOnce(Return(false));
190 scheduler_.Run();
191 EXPECT_FALSE(scheduler_.enabled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700192 EXPECT_EQ(NULL, attempter_.update_check_scheduler());
193}
194
195TEST_F(UpdateCheckSchedulerTest, RunTest) {
196 int interval_min, interval_max;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800197 FuzzRange(UpdateCheckScheduler::kTimeoutInitialInterval,
Darin Petkov1023a602010-08-30 13:47:51 -0700198 UpdateCheckScheduler::kTimeoutRegularFuzz,
199 &interval_min,
200 &interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700201 EXPECT_CALL(scheduler_, IsOfficialBuild()).Times(1).WillOnce(Return(true));
202 EXPECT_CALL(scheduler_, IsBootDeviceRemovable())
Darin Petkov1023a602010-08-30 13:47:51 -0700203 .Times(1)
204 .WillOnce(Return(false));
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700205 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700206 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700207 scheduler_.StaticCheck)).Times(1);
208 scheduler_.Run();
209 EXPECT_TRUE(scheduler_.enabled_);
210 EXPECT_EQ(&scheduler_, attempter_.update_check_scheduler());
Darin Petkov1023a602010-08-30 13:47:51 -0700211}
212
213TEST_F(UpdateCheckSchedulerTest, ScheduleCheckDisabledTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700214 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
215 scheduler_.ScheduleCheck(250, 30);
216 EXPECT_EQ(0, scheduler_.last_interval_);
217 EXPECT_FALSE(scheduler_.scheduled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700218}
219
220TEST_F(UpdateCheckSchedulerTest, ScheduleCheckEnabledTest) {
221 int interval_min, interval_max;
222 FuzzRange(100, 10, &interval_min,&interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700223 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700224 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700225 scheduler_.StaticCheck)).Times(1);
226 scheduler_.enabled_ = true;
227 scheduler_.ScheduleCheck(100, 10);
228 EXPECT_EQ(100, scheduler_.last_interval_);
229 EXPECT_TRUE(scheduler_.scheduled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700230}
231
232TEST_F(UpdateCheckSchedulerTest, ScheduleCheckNegativeIntervalTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700233 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(0, scheduler_.StaticCheck))
Darin Petkov1023a602010-08-30 13:47:51 -0700234 .Times(1);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700235 scheduler_.enabled_ = true;
236 scheduler_.ScheduleCheck(-50, 20);
237 EXPECT_TRUE(scheduler_.scheduled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700238}
239
240TEST_F(UpdateCheckSchedulerTest, ScheduleNextCheckDisabledTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700241 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800242 scheduler_.ScheduleNextCheck(false);
Darin Petkov1023a602010-08-30 13:47:51 -0700243}
244
245TEST_F(UpdateCheckSchedulerTest, ScheduleNextCheckEnabledTest) {
246 int interval_min, interval_max;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800247 FuzzRange(UpdateCheckScheduler::kTimeoutPeriodicInterval,
Darin Petkov1023a602010-08-30 13:47:51 -0700248 UpdateCheckScheduler::kTimeoutRegularFuzz,
249 &interval_min,
250 &interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700251 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700252 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700253 scheduler_.StaticCheck)).Times(1);
254 scheduler_.enabled_ = true;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800255 scheduler_.ScheduleNextCheck(false);
Darin Petkov1023a602010-08-30 13:47:51 -0700256}
257
258TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusIdleDisabledTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700259 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800260 scheduler_.SetUpdateStatus(UPDATE_STATUS_IDLE, kUpdateNoticeUnspecified);
Darin Petkov1023a602010-08-30 13:47:51 -0700261}
262
263TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusIdleEnabledTest) {
264 int interval_min, interval_max;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800265 FuzzRange(UpdateCheckScheduler::kTimeoutPeriodicInterval,
Darin Petkov1023a602010-08-30 13:47:51 -0700266 UpdateCheckScheduler::kTimeoutRegularFuzz,
267 &interval_min,
268 &interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700269 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700270 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700271 scheduler_.StaticCheck)).Times(1);
272 scheduler_.enabled_ = true;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800273 scheduler_.SetUpdateStatus(UPDATE_STATUS_IDLE, kUpdateNoticeUnspecified);
Darin Petkov1023a602010-08-30 13:47:51 -0700274}
275
276TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusNonIdleTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700277 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800278 scheduler_.SetUpdateStatus(UPDATE_STATUS_DOWNLOADING,
279 kUpdateNoticeUnspecified);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700280 scheduler_.enabled_ = true;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800281 scheduler_.SetUpdateStatus(UPDATE_STATUS_DOWNLOADING,
282 kUpdateNoticeUnspecified);
Darin Petkov1023a602010-08-30 13:47:51 -0700283}
284
Darin Petkov2a0e6332010-09-24 14:43:41 -0700285TEST_F(UpdateCheckSchedulerTest, StaticCheckOOBECompleteTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700286 scheduler_.scheduled_ = true;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800287 EXPECT_TRUE(scheduler_.mock_system_state_ != NULL);
288 EXPECT_CALL(*scheduler_.mock_system_state_,
Jay Srinivasan08fce042012-06-07 16:31:01 -0700289 IsOOBEComplete()).Times(1).WillOnce(Return(true));
Gilad Arnoldb92f0df2013-01-10 16:32:45 -0800290 EXPECT_CALL(attempter_, Update("", "", false, false, false))
Darin Petkov2a0e6332010-09-24 14:43:41 -0700291 .Times(1)
292 .WillOnce(Assign(&scheduler_.scheduled_, true));
293 scheduler_.enabled_ = true;
294 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
295 UpdateCheckSchedulerUnderTest::StaticCheck(&scheduler_);
296}
297
298TEST_F(UpdateCheckSchedulerTest, StaticCheckOOBENotCompleteTest) {
299 scheduler_.scheduled_ = true;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800300 EXPECT_CALL(*scheduler_.mock_system_state_,
Jay Srinivasan08fce042012-06-07 16:31:01 -0700301 IsOOBEComplete()).Times(1).WillOnce(Return(false));
Gilad Arnoldb92f0df2013-01-10 16:32:45 -0800302 EXPECT_CALL(attempter_, Update("", "", _, _, _)).Times(0);
Darin Petkov2a0e6332010-09-24 14:43:41 -0700303 int interval_min, interval_max;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800304 FuzzRange(UpdateCheckScheduler::kTimeoutInitialInterval,
Darin Petkov2a0e6332010-09-24 14:43:41 -0700305 UpdateCheckScheduler::kTimeoutRegularFuzz,
306 &interval_min,
307 &interval_max);
308 scheduler_.enabled_ = true;
309 EXPECT_CALL(scheduler_,
310 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
311 scheduler_.StaticCheck)).Times(1);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700312 UpdateCheckSchedulerUnderTest::StaticCheck(&scheduler_);
Darin Petkov1023a602010-08-30 13:47:51 -0700313}
314
315} // namespace chromeos_update_engine