blob: b3497c47dc0aa727928e4c9b456a2607ef2139b7 [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
David Zeuthen639aa362014-02-03 16:23:44 -080013using base::Time;
Darin Petkov1023a602010-08-30 13:47:51 -070014using std::string;
15using testing::_;
16using testing::AllOf;
Darin Petkov2a0e6332010-09-24 14:43:41 -070017using testing::Assign;
Darin Petkov1023a602010-08-30 13:47:51 -070018using testing::Ge;
19using testing::Le;
20using testing::MockFunction;
21using testing::Return;
David Zeuthen639aa362014-02-03 16:23:44 -080022using testing::SetArgumentPointee;
Darin Petkov1023a602010-08-30 13:47:51 -070023
24namespace chromeos_update_engine {
25
26namespace {
27void FuzzRange(int interval, int fuzz, int* interval_min, int* interval_max) {
28 *interval_min = interval - fuzz / 2;
29 *interval_max = interval + fuzz - fuzz / 2;
30}
31} // namespace {}
32
33// Test a subclass rather than the main class directly so that we can mock out
34// GLib and utils in tests. There're explicit unit test for the wrapper methods.
35class UpdateCheckSchedulerUnderTest : public UpdateCheckScheduler {
36 public:
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080037 UpdateCheckSchedulerUnderTest(UpdateAttempter* update_attempter,
38 MockSystemState* mock_system_state)
Gilad Arnoldbf7919b2013-01-08 13:07:37 -080039 : UpdateCheckScheduler(update_attempter, mock_system_state),
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080040 mock_system_state_(mock_system_state) {}
Darin Petkov1023a602010-08-30 13:47:51 -070041
42 MOCK_METHOD2(GTimeoutAddSeconds, guint(guint seconds, GSourceFunc function));
43 MOCK_METHOD0(IsBootDeviceRemovable, bool());
44 MOCK_METHOD0(IsOfficialBuild, bool());
Jay Srinivasan08fce042012-06-07 16:31:01 -070045
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080046 MockSystemState* mock_system_state_;
Darin Petkov1023a602010-08-30 13:47:51 -070047};
48
49class UpdateCheckSchedulerTest : public ::testing::Test {
Darin Petkovf42cc1c2010-09-01 09:03:02 -070050 public:
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080051 UpdateCheckSchedulerTest()
52 : attempter_(&mock_system_state_, &dbus_),
53 scheduler_(&attempter_, &mock_system_state_) {}
Darin Petkovf42cc1c2010-09-01 09:03:02 -070054
Darin Petkov1023a602010-08-30 13:47:51 -070055 protected:
56 virtual void SetUp() {
57 test_ = this;
58 loop_ = NULL;
Darin Petkovf42cc1c2010-09-01 09:03:02 -070059 EXPECT_EQ(&attempter_, scheduler_.update_attempter_);
60 EXPECT_FALSE(scheduler_.enabled_);
61 EXPECT_FALSE(scheduler_.scheduled_);
62 EXPECT_EQ(0, scheduler_.last_interval_);
Darin Petkov85ced132010-09-01 10:20:56 -070063 EXPECT_EQ(0, scheduler_.poll_interval_);
Han Shen07428b52012-12-18 10:29:20 -080064 // Make sure singleton CertificateChecker has its members properly setup.
65 CertificateChecker::set_system_state(&mock_system_state_);
66 CertificateChecker::set_openssl_wrapper(&openssl_wrapper_);
Darin Petkov1023a602010-08-30 13:47:51 -070067 }
68
69 virtual void TearDown() {
70 test_ = NULL;
71 loop_ = NULL;
Darin Petkov1023a602010-08-30 13:47:51 -070072 }
73
74 static gboolean SourceCallback(gpointer data) {
75 g_main_loop_quit(test_->loop_);
76 // Forwards the call to the function mock so that expectations can be set.
77 return test_->source_callback_.Call(data);
78 }
79
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080080 MockSystemState mock_system_state_;
Gilad Arnold1b9d6ae2014-03-03 13:46:07 -080081 MockDBusWrapper dbus_;
Han Shen07428b52012-12-18 10:29:20 -080082 OpenSSLWrapperMock openssl_wrapper_;
Darin Petkov1023a602010-08-30 13:47:51 -070083 UpdateAttempterMock attempter_;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080084 UpdateCheckSchedulerUnderTest scheduler_;
Darin Petkov1023a602010-08-30 13:47:51 -070085 MockFunction<gboolean(gpointer data)> source_callback_;
86 GMainLoop* loop_;
87 static UpdateCheckSchedulerTest* test_;
88};
89
90UpdateCheckSchedulerTest* UpdateCheckSchedulerTest::test_ = NULL;
91
92TEST_F(UpdateCheckSchedulerTest, CanScheduleTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -070093 EXPECT_FALSE(scheduler_.CanSchedule());
94 scheduler_.enabled_ = true;
95 EXPECT_TRUE(scheduler_.CanSchedule());
96 scheduler_.scheduled_ = true;
97 EXPECT_FALSE(scheduler_.CanSchedule());
98 scheduler_.enabled_ = false;
99 EXPECT_FALSE(scheduler_.CanSchedule());
Darin Petkov1023a602010-08-30 13:47:51 -0700100}
101
102TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzBackoffTest) {
103 int interval, fuzz;
104 attempter_.set_http_response_code(500);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800105 int last_interval = UpdateCheckScheduler::kTimeoutPeriodicInterval + 50;
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700106 scheduler_.last_interval_ = last_interval;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800107 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
Darin Petkov1023a602010-08-30 13:47:51 -0700108 EXPECT_EQ(2 * last_interval, interval);
109 EXPECT_EQ(2 * last_interval, fuzz);
110
111 attempter_.set_http_response_code(503);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800112 scheduler_.last_interval_ =
113 UpdateCheckScheduler::kTimeoutMaxBackoffInterval / 2 + 1;
114 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
115 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoffInterval, interval);
116 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoffInterval, fuzz);
Darin Petkov1023a602010-08-30 13:47:51 -0700117}
118
Darin Petkov85ced132010-09-01 10:20:56 -0700119TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzPollTest) {
120 int interval, fuzz;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800121 int poll_interval = UpdateCheckScheduler::kTimeoutPeriodicInterval + 50;
Darin Petkov85ced132010-09-01 10:20:56 -0700122 scheduler_.set_poll_interval(poll_interval);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800123 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
Darin Petkov85ced132010-09-01 10:20:56 -0700124 EXPECT_EQ(poll_interval, interval);
125 EXPECT_EQ(poll_interval, fuzz);
126
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800127 scheduler_.set_poll_interval(
128 UpdateCheckScheduler::kTimeoutMaxBackoffInterval + 1);
129 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
130 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoffInterval, interval);
131 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoffInterval, fuzz);
Darin Petkov85ced132010-09-01 10:20:56 -0700132
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800133 scheduler_.set_poll_interval(
134 UpdateCheckScheduler::kTimeoutPeriodicInterval - 1);
135 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
136 EXPECT_EQ(UpdateCheckScheduler::kTimeoutPeriodicInterval, interval);
Darin Petkov85ced132010-09-01 10:20:56 -0700137 EXPECT_EQ(UpdateCheckScheduler::kTimeoutRegularFuzz, fuzz);
138}
139
140TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzPriorityTest) {
141 int interval, fuzz;
142 attempter_.set_http_response_code(500);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800143 scheduler_.last_interval_ =
144 UpdateCheckScheduler::kTimeoutPeriodicInterval + 50;
145 int poll_interval = UpdateCheckScheduler::kTimeoutPeriodicInterval + 100;
Darin Petkov85ced132010-09-01 10:20:56 -0700146 scheduler_.set_poll_interval(poll_interval);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800147 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
Darin Petkov85ced132010-09-01 10:20:56 -0700148 EXPECT_EQ(poll_interval, interval);
149 EXPECT_EQ(poll_interval, fuzz);
150}
151
Darin Petkov1023a602010-08-30 13:47:51 -0700152TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzTest) {
153 int interval, fuzz;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800154 scheduler_.ComputeNextIntervalAndFuzz(0, &interval, &fuzz);
155 EXPECT_EQ(UpdateCheckScheduler::kTimeoutPeriodicInterval, interval);
Darin Petkov1023a602010-08-30 13:47:51 -0700156 EXPECT_EQ(UpdateCheckScheduler::kTimeoutRegularFuzz, fuzz);
157}
158
159TEST_F(UpdateCheckSchedulerTest, GTimeoutAddSecondsTest) {
160 loop_ = g_main_loop_new(g_main_context_default(), FALSE);
161 // Invokes the actual GLib wrapper method rather than the subclass mock.
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700162 scheduler_.UpdateCheckScheduler::GTimeoutAddSeconds(0, SourceCallback);
163 EXPECT_CALL(source_callback_, Call(&scheduler_)).Times(1);
Darin Petkov1023a602010-08-30 13:47:51 -0700164 g_main_loop_run(loop_);
165 g_main_loop_unref(loop_);
166}
167
168TEST_F(UpdateCheckSchedulerTest, IsBootDeviceRemovableTest) {
169 // Invokes the actual utils wrapper method rather than the subclass mock.
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700170 EXPECT_FALSE(scheduler_.UpdateCheckScheduler::IsBootDeviceRemovable());
Darin Petkov1023a602010-08-30 13:47:51 -0700171}
172
173TEST_F(UpdateCheckSchedulerTest, IsOfficialBuildTest) {
174 // Invokes the actual utils wrapper method rather than the subclass mock.
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700175 EXPECT_TRUE(scheduler_.UpdateCheckScheduler::IsOfficialBuild());
Darin Petkov1023a602010-08-30 13:47:51 -0700176}
177
178TEST_F(UpdateCheckSchedulerTest, RunBootDeviceRemovableTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700179 scheduler_.enabled_ = true;
180 EXPECT_CALL(scheduler_, IsOfficialBuild()).Times(1).WillOnce(Return(true));
181 EXPECT_CALL(scheduler_, IsBootDeviceRemovable())
Darin Petkov1023a602010-08-30 13:47:51 -0700182 .Times(1)
183 .WillOnce(Return(true));
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700184 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, RunNonOfficialBuildTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700190 scheduler_.enabled_ = true;
191 EXPECT_CALL(scheduler_, IsOfficialBuild()).Times(1).WillOnce(Return(false));
192 scheduler_.Run();
193 EXPECT_FALSE(scheduler_.enabled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700194 EXPECT_EQ(NULL, attempter_.update_check_scheduler());
195}
196
197TEST_F(UpdateCheckSchedulerTest, RunTest) {
198 int interval_min, interval_max;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800199 FuzzRange(UpdateCheckScheduler::kTimeoutInitialInterval,
Darin Petkov1023a602010-08-30 13:47:51 -0700200 UpdateCheckScheduler::kTimeoutRegularFuzz,
201 &interval_min,
202 &interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700203 EXPECT_CALL(scheduler_, IsOfficialBuild()).Times(1).WillOnce(Return(true));
204 EXPECT_CALL(scheduler_, IsBootDeviceRemovable())
Darin Petkov1023a602010-08-30 13:47:51 -0700205 .Times(1)
206 .WillOnce(Return(false));
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700207 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700208 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700209 scheduler_.StaticCheck)).Times(1);
210 scheduler_.Run();
211 EXPECT_TRUE(scheduler_.enabled_);
212 EXPECT_EQ(&scheduler_, attempter_.update_check_scheduler());
Darin Petkov1023a602010-08-30 13:47:51 -0700213}
214
215TEST_F(UpdateCheckSchedulerTest, ScheduleCheckDisabledTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700216 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
217 scheduler_.ScheduleCheck(250, 30);
218 EXPECT_EQ(0, scheduler_.last_interval_);
219 EXPECT_FALSE(scheduler_.scheduled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700220}
221
222TEST_F(UpdateCheckSchedulerTest, ScheduleCheckEnabledTest) {
223 int interval_min, interval_max;
224 FuzzRange(100, 10, &interval_min,&interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700225 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700226 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700227 scheduler_.StaticCheck)).Times(1);
228 scheduler_.enabled_ = true;
229 scheduler_.ScheduleCheck(100, 10);
230 EXPECT_EQ(100, scheduler_.last_interval_);
231 EXPECT_TRUE(scheduler_.scheduled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700232}
233
234TEST_F(UpdateCheckSchedulerTest, ScheduleCheckNegativeIntervalTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700235 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(0, scheduler_.StaticCheck))
Darin Petkov1023a602010-08-30 13:47:51 -0700236 .Times(1);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700237 scheduler_.enabled_ = true;
238 scheduler_.ScheduleCheck(-50, 20);
239 EXPECT_TRUE(scheduler_.scheduled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700240}
241
242TEST_F(UpdateCheckSchedulerTest, ScheduleNextCheckDisabledTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700243 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800244 scheduler_.ScheduleNextCheck(false);
Darin Petkov1023a602010-08-30 13:47:51 -0700245}
246
247TEST_F(UpdateCheckSchedulerTest, ScheduleNextCheckEnabledTest) {
248 int interval_min, interval_max;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800249 FuzzRange(UpdateCheckScheduler::kTimeoutPeriodicInterval,
Darin Petkov1023a602010-08-30 13:47:51 -0700250 UpdateCheckScheduler::kTimeoutRegularFuzz,
251 &interval_min,
252 &interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700253 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700254 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700255 scheduler_.StaticCheck)).Times(1);
256 scheduler_.enabled_ = true;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800257 scheduler_.ScheduleNextCheck(false);
Darin Petkov1023a602010-08-30 13:47:51 -0700258}
259
260TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusIdleDisabledTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700261 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
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, SetUpdateStatusIdleEnabledTest) {
266 int interval_min, interval_max;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800267 FuzzRange(UpdateCheckScheduler::kTimeoutPeriodicInterval,
Darin Petkov1023a602010-08-30 13:47:51 -0700268 UpdateCheckScheduler::kTimeoutRegularFuzz,
269 &interval_min,
270 &interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700271 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700272 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700273 scheduler_.StaticCheck)).Times(1);
274 scheduler_.enabled_ = true;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800275 scheduler_.SetUpdateStatus(UPDATE_STATUS_IDLE, kUpdateNoticeUnspecified);
Darin Petkov1023a602010-08-30 13:47:51 -0700276}
277
278TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusNonIdleTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700279 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800280 scheduler_.SetUpdateStatus(UPDATE_STATUS_DOWNLOADING,
281 kUpdateNoticeUnspecified);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700282 scheduler_.enabled_ = true;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800283 scheduler_.SetUpdateStatus(UPDATE_STATUS_DOWNLOADING,
284 kUpdateNoticeUnspecified);
Darin Petkov1023a602010-08-30 13:47:51 -0700285}
286
Darin Petkov2a0e6332010-09-24 14:43:41 -0700287TEST_F(UpdateCheckSchedulerTest, StaticCheckOOBECompleteTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700288 scheduler_.scheduled_ = true;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800289 EXPECT_TRUE(scheduler_.mock_system_state_ != NULL);
290 EXPECT_CALL(*scheduler_.mock_system_state_,
David Zeuthen639aa362014-02-03 16:23:44 -0800291 IsOOBEComplete(_)).Times(1)
292 .WillOnce(DoAll(SetArgumentPointee<0>(Time::UnixEpoch()),
293 Return(true)));
Gilad Arnoldb92f0df2013-01-10 16:32:45 -0800294 EXPECT_CALL(attempter_, Update("", "", false, false, false))
Darin Petkov2a0e6332010-09-24 14:43:41 -0700295 .Times(1)
296 .WillOnce(Assign(&scheduler_.scheduled_, true));
297 scheduler_.enabled_ = true;
298 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
299 UpdateCheckSchedulerUnderTest::StaticCheck(&scheduler_);
300}
301
302TEST_F(UpdateCheckSchedulerTest, StaticCheckOOBENotCompleteTest) {
303 scheduler_.scheduled_ = true;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800304 EXPECT_CALL(*scheduler_.mock_system_state_,
David Zeuthen639aa362014-02-03 16:23:44 -0800305 IsOOBEComplete(_)).Times(1)
306 .WillOnce(DoAll(SetArgumentPointee<0>(Time::UnixEpoch()),
307 Return(false)));
Gilad Arnoldb92f0df2013-01-10 16:32:45 -0800308 EXPECT_CALL(attempter_, Update("", "", _, _, _)).Times(0);
Darin Petkov2a0e6332010-09-24 14:43:41 -0700309 int interval_min, interval_max;
Gilad Arnold1ebd8132012-03-05 10:19:29 -0800310 FuzzRange(UpdateCheckScheduler::kTimeoutInitialInterval,
Darin Petkov2a0e6332010-09-24 14:43:41 -0700311 UpdateCheckScheduler::kTimeoutRegularFuzz,
312 &interval_min,
313 &interval_max);
314 scheduler_.enabled_ = true;
315 EXPECT_CALL(scheduler_,
316 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
317 scheduler_.StaticCheck)).Times(1);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700318 UpdateCheckSchedulerUnderTest::StaticCheck(&scheduler_);
Darin Petkov1023a602010-08-30 13:47:51 -0700319}
320
321} // namespace chromeos_update_engine