blob: 413453aa778cd68ea2a7708ec489dc7d62eb307e [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 Petkov1023a602010-08-30 13:47:51 -070051 }
52
53 virtual void TearDown() {
54 test_ = NULL;
55 loop_ = NULL;
Darin Petkov1023a602010-08-30 13:47:51 -070056 }
57
58 static gboolean SourceCallback(gpointer data) {
59 g_main_loop_quit(test_->loop_);
60 // Forwards the call to the function mock so that expectations can be set.
61 return test_->source_callback_.Call(data);
62 }
63
Darin Petkovf42cc1c2010-09-01 09:03:02 -070064 UpdateCheckSchedulerUnderTest scheduler_;
Darin Petkov1023a602010-08-30 13:47:51 -070065 UpdateAttempterMock attempter_;
66 MockFunction<gboolean(gpointer data)> source_callback_;
67 GMainLoop* loop_;
68 static UpdateCheckSchedulerTest* test_;
69};
70
71UpdateCheckSchedulerTest* UpdateCheckSchedulerTest::test_ = NULL;
72
73TEST_F(UpdateCheckSchedulerTest, CanScheduleTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -070074 EXPECT_FALSE(scheduler_.CanSchedule());
75 scheduler_.enabled_ = true;
76 EXPECT_TRUE(scheduler_.CanSchedule());
77 scheduler_.scheduled_ = true;
78 EXPECT_FALSE(scheduler_.CanSchedule());
79 scheduler_.enabled_ = false;
80 EXPECT_FALSE(scheduler_.CanSchedule());
Darin Petkov1023a602010-08-30 13:47:51 -070081}
82
83TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzBackoffTest) {
84 int interval, fuzz;
85 attempter_.set_http_response_code(500);
86 int last_interval = UpdateCheckScheduler::kTimeoutPeriodic + 50;
Darin Petkovf42cc1c2010-09-01 09:03:02 -070087 scheduler_.last_interval_ = last_interval;
88 scheduler_.ComputeNextIntervalAndFuzz(&interval, &fuzz);
Darin Petkov1023a602010-08-30 13:47:51 -070089 EXPECT_EQ(2 * last_interval, interval);
90 EXPECT_EQ(2 * last_interval, fuzz);
91
92 attempter_.set_http_response_code(503);
93 last_interval = UpdateCheckScheduler::kTimeoutMaxBackoff / 2 + 1;
Darin Petkovf42cc1c2010-09-01 09:03:02 -070094 scheduler_.last_interval_ = last_interval;
95 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
100TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzTest) {
101 int interval, fuzz;
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700102 scheduler_.ComputeNextIntervalAndFuzz(&interval, &fuzz);
Darin Petkov1023a602010-08-30 13:47:51 -0700103 EXPECT_EQ(UpdateCheckScheduler::kTimeoutPeriodic, interval);
104 EXPECT_EQ(UpdateCheckScheduler::kTimeoutRegularFuzz, fuzz);
105}
106
107TEST_F(UpdateCheckSchedulerTest, GTimeoutAddSecondsTest) {
108 loop_ = g_main_loop_new(g_main_context_default(), FALSE);
109 // Invokes the actual GLib wrapper method rather than the subclass mock.
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700110 scheduler_.UpdateCheckScheduler::GTimeoutAddSeconds(0, SourceCallback);
111 EXPECT_CALL(source_callback_, Call(&scheduler_)).Times(1);
Darin Petkov1023a602010-08-30 13:47:51 -0700112 g_main_loop_run(loop_);
113 g_main_loop_unref(loop_);
114}
115
116TEST_F(UpdateCheckSchedulerTest, IsBootDeviceRemovableTest) {
117 // Invokes the actual utils wrapper method rather than the subclass mock.
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700118 EXPECT_FALSE(scheduler_.UpdateCheckScheduler::IsBootDeviceRemovable());
Darin Petkov1023a602010-08-30 13:47:51 -0700119}
120
121TEST_F(UpdateCheckSchedulerTest, IsOfficialBuildTest) {
122 // Invokes the actual utils wrapper method rather than the subclass mock.
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700123 EXPECT_TRUE(scheduler_.UpdateCheckScheduler::IsOfficialBuild());
Darin Petkov1023a602010-08-30 13:47:51 -0700124}
125
126TEST_F(UpdateCheckSchedulerTest, RunBootDeviceRemovableTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700127 scheduler_.enabled_ = true;
128 EXPECT_CALL(scheduler_, IsOfficialBuild()).Times(1).WillOnce(Return(true));
129 EXPECT_CALL(scheduler_, IsBootDeviceRemovable())
Darin Petkov1023a602010-08-30 13:47:51 -0700130 .Times(1)
131 .WillOnce(Return(true));
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700132 scheduler_.Run();
133 EXPECT_FALSE(scheduler_.enabled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700134 EXPECT_EQ(NULL, attempter_.update_check_scheduler());
135}
136
137TEST_F(UpdateCheckSchedulerTest, RunNonOfficialBuildTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700138 scheduler_.enabled_ = true;
139 EXPECT_CALL(scheduler_, IsOfficialBuild()).Times(1).WillOnce(Return(false));
140 scheduler_.Run();
141 EXPECT_FALSE(scheduler_.enabled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700142 EXPECT_EQ(NULL, attempter_.update_check_scheduler());
143}
144
145TEST_F(UpdateCheckSchedulerTest, RunTest) {
146 int interval_min, interval_max;
147 FuzzRange(UpdateCheckScheduler::kTimeoutOnce,
148 UpdateCheckScheduler::kTimeoutRegularFuzz,
149 &interval_min,
150 &interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700151 EXPECT_CALL(scheduler_, IsOfficialBuild()).Times(1).WillOnce(Return(true));
152 EXPECT_CALL(scheduler_, IsBootDeviceRemovable())
Darin Petkov1023a602010-08-30 13:47:51 -0700153 .Times(1)
154 .WillOnce(Return(false));
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700155 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700156 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700157 scheduler_.StaticCheck)).Times(1);
158 scheduler_.Run();
159 EXPECT_TRUE(scheduler_.enabled_);
160 EXPECT_EQ(&scheduler_, attempter_.update_check_scheduler());
Darin Petkov1023a602010-08-30 13:47:51 -0700161}
162
163TEST_F(UpdateCheckSchedulerTest, ScheduleCheckDisabledTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700164 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
165 scheduler_.ScheduleCheck(250, 30);
166 EXPECT_EQ(0, scheduler_.last_interval_);
167 EXPECT_FALSE(scheduler_.scheduled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700168}
169
170TEST_F(UpdateCheckSchedulerTest, ScheduleCheckEnabledTest) {
171 int interval_min, interval_max;
172 FuzzRange(100, 10, &interval_min,&interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700173 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700174 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700175 scheduler_.StaticCheck)).Times(1);
176 scheduler_.enabled_ = true;
177 scheduler_.ScheduleCheck(100, 10);
178 EXPECT_EQ(100, scheduler_.last_interval_);
179 EXPECT_TRUE(scheduler_.scheduled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700180}
181
182TEST_F(UpdateCheckSchedulerTest, ScheduleCheckNegativeIntervalTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700183 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(0, scheduler_.StaticCheck))
Darin Petkov1023a602010-08-30 13:47:51 -0700184 .Times(1);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700185 scheduler_.enabled_ = true;
186 scheduler_.ScheduleCheck(-50, 20);
187 EXPECT_TRUE(scheduler_.scheduled_);
Darin Petkov1023a602010-08-30 13:47:51 -0700188}
189
190TEST_F(UpdateCheckSchedulerTest, ScheduleNextCheckDisabledTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700191 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
192 scheduler_.ScheduleNextCheck();
Darin Petkov1023a602010-08-30 13:47:51 -0700193}
194
195TEST_F(UpdateCheckSchedulerTest, ScheduleNextCheckEnabledTest) {
196 int interval_min, interval_max;
197 FuzzRange(UpdateCheckScheduler::kTimeoutPeriodic,
198 UpdateCheckScheduler::kTimeoutRegularFuzz,
199 &interval_min,
200 &interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700201 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700202 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700203 scheduler_.StaticCheck)).Times(1);
204 scheduler_.enabled_ = true;
205 scheduler_.ScheduleNextCheck();
Darin Petkov1023a602010-08-30 13:47:51 -0700206}
207
208TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusIdleDisabledTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700209 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
210 scheduler_.SetUpdateStatus(UPDATE_STATUS_IDLE);
Darin Petkov1023a602010-08-30 13:47:51 -0700211}
212
213TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusIdleEnabledTest) {
214 int interval_min, interval_max;
215 FuzzRange(UpdateCheckScheduler::kTimeoutPeriodic,
216 UpdateCheckScheduler::kTimeoutRegularFuzz,
217 &interval_min,
218 &interval_max);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700219 EXPECT_CALL(scheduler_,
Darin Petkov1023a602010-08-30 13:47:51 -0700220 GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)),
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700221 scheduler_.StaticCheck)).Times(1);
222 scheduler_.enabled_ = true;
223 scheduler_.SetUpdateStatus(UPDATE_STATUS_IDLE);
Darin Petkov1023a602010-08-30 13:47:51 -0700224}
225
226TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusNonIdleTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700227 EXPECT_CALL(scheduler_, GTimeoutAddSeconds(_, _)).Times(0);
228 scheduler_.SetUpdateStatus(UPDATE_STATUS_DOWNLOADING);
229 scheduler_.enabled_ = true;
230 scheduler_.SetUpdateStatus(UPDATE_STATUS_DOWNLOADING);
Darin Petkov1023a602010-08-30 13:47:51 -0700231}
232
233TEST_F(UpdateCheckSchedulerTest, StaticCheckTest) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700234 scheduler_.scheduled_ = true;
Darin Petkov1023a602010-08-30 13:47:51 -0700235 EXPECT_CALL(attempter_, Update("", "")).Times(1);
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700236 UpdateCheckSchedulerUnderTest::StaticCheck(&scheduler_);
Darin Petkov1023a602010-08-30 13:47:51 -0700237}
238
239} // namespace chromeos_update_engine