blob: 3aea760c8027fc31e7f72917112f49b0960414e9 [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;
13using testing::Ge;
14using testing::Le;
15using testing::MockFunction;
16using testing::Return;
17
18namespace chromeos_update_engine {
19
20namespace {
21void FuzzRange(int interval, int fuzz, int* interval_min, int* interval_max) {
22 *interval_min = interval - fuzz / 2;
23 *interval_max = interval + fuzz - fuzz / 2;
24}
25} // namespace {}
26
27// Test a subclass rather than the main class directly so that we can mock out
28// GLib and utils in tests. There're explicit unit test for the wrapper methods.
29class UpdateCheckSchedulerUnderTest : public UpdateCheckScheduler {
30 public:
31 UpdateCheckSchedulerUnderTest(UpdateAttempter* update_attempter)
32 : UpdateCheckScheduler(update_attempter) {}
33
34 MOCK_METHOD2(GTimeoutAddSeconds, guint(guint seconds, GSourceFunc function));
35 MOCK_METHOD0(IsBootDeviceRemovable, bool());
36 MOCK_METHOD0(IsOfficialBuild, bool());
37};
38
39class UpdateCheckSchedulerTest : public ::testing::Test {
Darin Petkovf42cc1c2010-09-01 09:03:02 -070040 public:
41 UpdateCheckSchedulerTest() : scheduler_(&attempter_) {}
42
Darin Petkov1023a602010-08-30 13:47:51 -070043 protected:
44 virtual void SetUp() {
45 test_ = this;
46 loop_ = NULL;
Darin Petkovf42cc1c2010-09-01 09:03:02 -070047 EXPECT_EQ(&attempter_, scheduler_.update_attempter_);
48 EXPECT_FALSE(scheduler_.enabled_);
49 EXPECT_FALSE(scheduler_.scheduled_);
50 EXPECT_EQ(0, scheduler_.last_interval_);
Darin Petkov85ced132010-09-01 10:20:56 -070051 EXPECT_EQ(0, scheduler_.poll_interval_);
Darin Petkov1023a602010-08-30 13:47:51 -070052 }
53
54 virtual void TearDown() {
55 test_ = NULL;
56 loop_ = NULL;
Darin Petkov1023a602010-08-30 13:47:51 -070057 }
58
59 static gboolean SourceCallback(gpointer data) {
60 g_main_loop_quit(test_->loop_);
61 // Forwards the call to the function mock so that expectations can be set.
62 return test_->source_callback_.Call(data);
63 }
64
Darin Petkovf42cc1c2010-09-01 09:03:02 -070065 UpdateCheckSchedulerUnderTest scheduler_;
Darin Petkov1023a602010-08-30 13:47:51 -070066 UpdateAttempterMock attempter_;
67 MockFunction<gboolean(gpointer data)> source_callback_;
68 GMainLoop* loop_;
69 static UpdateCheckSchedulerTest* test_;
70};
71
72UpdateCheckSchedulerTest* UpdateCheckSchedulerTest::test_ = NULL;
73
74TEST_F(UpdateCheckSchedulerTest, CanScheduleTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -070075 EXPECT_FALSE(scheduler_.CanSchedule());
76 scheduler_.enabled_ = true;
77 EXPECT_TRUE(scheduler_.CanSchedule());
78 scheduler_.scheduled_ = true;
79 EXPECT_FALSE(scheduler_.CanSchedule());
80 scheduler_.enabled_ = false;
81 EXPECT_FALSE(scheduler_.CanSchedule());
Darin Petkov1023a602010-08-30 13:47:51 -070082}
83
84TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzBackoffTest) {
85 int interval, fuzz;
86 attempter_.set_http_response_code(500);
87 int last_interval = UpdateCheckScheduler::kTimeoutPeriodic + 50;
Darin Petkovf42cc1c2010-09-01 09:03:02 -070088 scheduler_.last_interval_ = last_interval;
89 scheduler_.ComputeNextIntervalAndFuzz(&interval, &fuzz);
Darin Petkov1023a602010-08-30 13:47:51 -070090 EXPECT_EQ(2 * last_interval, interval);
91 EXPECT_EQ(2 * last_interval, fuzz);
92
93 attempter_.set_http_response_code(503);
Darin Petkov85ced132010-09-01 10:20:56 -070094 scheduler_.last_interval_ = UpdateCheckScheduler::kTimeoutMaxBackoff / 2 + 1;
Darin Petkovf42cc1c2010-09-01 09:03:02 -070095 scheduler_.ComputeNextIntervalAndFuzz(&interval, &fuzz);
Darin Petkov1023a602010-08-30 13:47:51 -070096 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoff, interval);
97 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoff, fuzz);
98}
99
Darin Petkov85ced132010-09-01 10:20:56 -0700100TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzPollTest) {
101 int interval, fuzz;
102 int poll_interval = UpdateCheckScheduler::kTimeoutPeriodic + 50;
103 scheduler_.set_poll_interval(poll_interval);
104 scheduler_.ComputeNextIntervalAndFuzz(&interval, &fuzz);
105 EXPECT_EQ(poll_interval, interval);
106 EXPECT_EQ(poll_interval, fuzz);
107
108 scheduler_.set_poll_interval(UpdateCheckScheduler::kTimeoutMaxBackoff + 1);
109 scheduler_.ComputeNextIntervalAndFuzz(&interval, &fuzz);
110 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoff, interval);
111 EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoff, fuzz);
112
113 scheduler_.set_poll_interval(UpdateCheckScheduler::kTimeoutPeriodic - 1);
114 scheduler_.ComputeNextIntervalAndFuzz(&interval, &fuzz);
115 EXPECT_EQ(UpdateCheckScheduler::kTimeoutPeriodic, interval);
116 EXPECT_EQ(UpdateCheckScheduler::kTimeoutRegularFuzz, fuzz);
117}
118
119TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzPriorityTest) {
120 int interval, fuzz;
121 attempter_.set_http_response_code(500);
122 scheduler_.last_interval_ = UpdateCheckScheduler::kTimeoutPeriodic + 50;
123 int poll_interval = UpdateCheckScheduler::kTimeoutPeriodic + 100;
124 scheduler_.set_poll_interval(poll_interval);
125 scheduler_.ComputeNextIntervalAndFuzz(&interval, &fuzz);
126 EXPECT_EQ(poll_interval, interval);
127 EXPECT_EQ(poll_interval, fuzz);
128}
129
Darin Petkov1023a602010-08-30 13:47:51 -0700130TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzTest) {
131 int interval, fuzz;
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700132 scheduler_.ComputeNextIntervalAndFuzz(&interval, &fuzz);
Darin Petkov1023a602010-08-30 13:47:51 -0700133 EXPECT_EQ(UpdateCheckScheduler::kTimeoutPeriodic, interval);
134 EXPECT_EQ(UpdateCheckScheduler::kTimeoutRegularFuzz, fuzz);
135}
136
137TEST_F(UpdateCheckSchedulerTest, GTimeoutAddSecondsTest) {
138 loop_ = g_main_loop_new(g_main_context_default(), FALSE);
139 // Invokes the actual GLib wrapper method rather than the subclass mock.
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700140 scheduler_.UpdateCheckScheduler::GTimeoutAddSeconds(0, SourceCallback);
141 EXPECT_CALL(source_callback_, Call(&scheduler_)).Times(1);
Darin Petkov1023a602010-08-30 13:47:51 -0700142 g_main_loop_run(loop_);
143 g_main_loop_unref(loop_);
144}
145
146TEST_F(UpdateCheckSchedulerTest, IsBootDeviceRemovableTest) {
147 // Invokes the actual utils wrapper method rather than the subclass mock.
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700148 EXPECT_FALSE(scheduler_.UpdateCheckScheduler::IsBootDeviceRemovable());
Darin Petkov1023a602010-08-30 13:47:51 -0700149}
150
151TEST_F(UpdateCheckSchedulerTest, IsOfficialBuildTest) {
152 // Invokes the actual utils wrapper method rather than the subclass mock.
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700153 EXPECT_TRUE(scheduler_.UpdateCheckScheduler::IsOfficialBuild());
Darin Petkov1023a602010-08-30 13:47:51 -0700154}
155
156TEST_F(UpdateCheckSchedulerTest, RunBootDeviceRemovableTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700157 scheduler_.enabled_ = true;
158 EXPECT_CALL(scheduler_, IsOfficialBuild()).Times(1).WillOnce(Return(true));
159 EXPECT_CALL(scheduler_, IsBootDeviceRemovable())
Darin Petkov1023a602010-08-30 13:47:51 -0700160 .Times(1)
161 .WillOnce(Return(true));
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700162 scheduler_.Run();
163 EXPECT_FALSE(scheduler_.enabled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700164 EXPECT_EQ(NULL, attempter_.update_check_scheduler());
165}
166
167TEST_F(UpdateCheckSchedulerTest, RunNonOfficialBuildTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700168 scheduler_.enabled_ = true;
169 EXPECT_CALL(scheduler_, IsOfficialBuild()).Times(1).WillOnce(Return(false));
170 scheduler_.Run();
171 EXPECT_FALSE(scheduler_.enabled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700172 EXPECT_EQ(NULL, attempter_.update_check_scheduler());
173}
174
175TEST_F(UpdateCheckSchedulerTest, RunTest) {
176 int interval_min, interval_max;
177 FuzzRange(UpdateCheckScheduler::kTimeoutOnce,
178 UpdateCheckScheduler::kTimeoutRegularFuzz,
179 &interval_min,
180 &interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700181 EXPECT_CALL(scheduler_, IsOfficialBuild()).Times(1).WillOnce(Return(true));
182 EXPECT_CALL(scheduler_, IsBootDeviceRemovable())
Darin Petkov1023a602010-08-30 13:47:51 -0700183 .Times(1)
184 .WillOnce(Return(false));
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700185 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700186 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700187 scheduler_.StaticCheck)).Times(1);
188 scheduler_.Run();
189 EXPECT_TRUE(scheduler_.enabled_);
190 EXPECT_EQ(&scheduler_, attempter_.update_check_scheduler());
Darin Petkov1023a602010-08-30 13:47:51 -0700191}
192
193TEST_F(UpdateCheckSchedulerTest, ScheduleCheckDisabledTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700194 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
195 scheduler_.ScheduleCheck(250, 30);
196 EXPECT_EQ(0, scheduler_.last_interval_);
197 EXPECT_FALSE(scheduler_.scheduled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700198}
199
200TEST_F(UpdateCheckSchedulerTest, ScheduleCheckEnabledTest) {
201 int interval_min, interval_max;
202 FuzzRange(100, 10, &interval_min,&interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700203 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700204 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700205 scheduler_.StaticCheck)).Times(1);
206 scheduler_.enabled_ = true;
207 scheduler_.ScheduleCheck(100, 10);
208 EXPECT_EQ(100, scheduler_.last_interval_);
209 EXPECT_TRUE(scheduler_.scheduled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700210}
211
212TEST_F(UpdateCheckSchedulerTest, ScheduleCheckNegativeIntervalTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700213 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(0, scheduler_.StaticCheck))
Darin Petkov1023a602010-08-30 13:47:51 -0700214 .Times(1);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700215 scheduler_.enabled_ = true;
216 scheduler_.ScheduleCheck(-50, 20);
217 EXPECT_TRUE(scheduler_.scheduled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700218}
219
220TEST_F(UpdateCheckSchedulerTest, ScheduleNextCheckDisabledTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700221 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
222 scheduler_.ScheduleNextCheck();
Darin Petkov1023a602010-08-30 13:47:51 -0700223}
224
225TEST_F(UpdateCheckSchedulerTest, ScheduleNextCheckEnabledTest) {
226 int interval_min, interval_max;
227 FuzzRange(UpdateCheckScheduler::kTimeoutPeriodic,
228 UpdateCheckScheduler::kTimeoutRegularFuzz,
229 &interval_min,
230 &interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700231 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700232 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700233 scheduler_.StaticCheck)).Times(1);
234 scheduler_.enabled_ = true;
235 scheduler_.ScheduleNextCheck();
Darin Petkov1023a602010-08-30 13:47:51 -0700236}
237
238TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusIdleDisabledTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700239 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
240 scheduler_.SetUpdateStatus(UPDATE_STATUS_IDLE);
Darin Petkov1023a602010-08-30 13:47:51 -0700241}
242
243TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusIdleEnabledTest) {
244 int interval_min, interval_max;
245 FuzzRange(UpdateCheckScheduler::kTimeoutPeriodic,
246 UpdateCheckScheduler::kTimeoutRegularFuzz,
247 &interval_min,
248 &interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700249 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700250 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700251 scheduler_.StaticCheck)).Times(1);
252 scheduler_.enabled_ = true;
253 scheduler_.SetUpdateStatus(UPDATE_STATUS_IDLE);
Darin Petkov1023a602010-08-30 13:47:51 -0700254}
255
256TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusNonIdleTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700257 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
258 scheduler_.SetUpdateStatus(UPDATE_STATUS_DOWNLOADING);
259 scheduler_.enabled_ = true;
260 scheduler_.SetUpdateStatus(UPDATE_STATUS_DOWNLOADING);
Darin Petkov1023a602010-08-30 13:47:51 -0700261}
262
263TEST_F(UpdateCheckSchedulerTest, StaticCheckTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700264 scheduler_.scheduled_ = true;
Darin Petkov1023a602010-08-30 13:47:51 -0700265 EXPECT_CALL(attempter_, Update("", "")).Times(1);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700266 UpdateCheckSchedulerUnderTest::StaticCheck(&scheduler_);
Darin Petkov1023a602010-08-30 13:47:51 -0700267}
268
269} // namespace chromeos_update_engine