Index: update_check_scheduler_unittest.cc |
diff --git a/update_check_scheduler_unittest.cc b/update_check_scheduler_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..8a0ca19e091cbb6573a303bb2c94430ea3e2a873 |
--- /dev/null |
+++ b/update_check_scheduler_unittest.cc |
@@ -0,0 +1,238 @@ |
+// Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include <gtest/gtest.h> |
+ |
+#include "update_engine/update_attempter_mock.h" |
+#include "update_engine/update_check_scheduler.h" |
+ |
+using std::string; |
+using testing::_; |
+using testing::AllOf; |
+using testing::Ge; |
+using testing::Le; |
+using testing::MockFunction; |
+using testing::Return; |
+ |
+namespace chromeos_update_engine { |
+ |
+namespace { |
+void FuzzRange(int interval, int fuzz, int* interval_min, int* interval_max) { |
+ *interval_min = interval - fuzz / 2; |
+ *interval_max = interval + fuzz - fuzz / 2; |
+} |
+} // namespace {} |
+ |
+// Test a subclass rather than the main class directly so that we can mock out |
+// GLib and utils in tests. There're explicit unit test for the wrapper methods. |
+class UpdateCheckSchedulerUnderTest : public UpdateCheckScheduler { |
+ public: |
+ UpdateCheckSchedulerUnderTest(UpdateAttempter* update_attempter) |
+ : UpdateCheckScheduler(update_attempter) {} |
+ |
+ MOCK_METHOD2(GTimeoutAddSeconds, guint(guint seconds, GSourceFunc function)); |
+ MOCK_METHOD0(IsBootDeviceRemovable, bool()); |
+ MOCK_METHOD0(IsOfficialBuild, bool()); |
+}; |
+ |
+class UpdateCheckSchedulerTest : public ::testing::Test { |
+ protected: |
+ virtual void SetUp() { |
+ test_ = this; |
+ loop_ = NULL; |
+ scheduler_.reset(new UpdateCheckSchedulerUnderTest(&attempter_)); |
+ EXPECT_EQ(&attempter_, scheduler_->update_attempter_); |
+ EXPECT_FALSE(scheduler_->enabled_); |
+ EXPECT_FALSE(scheduler_->scheduled_); |
+ EXPECT_EQ(0, scheduler_->last_interval_); |
+ } |
+ |
+ virtual void TearDown() { |
+ test_ = NULL; |
+ loop_ = NULL; |
+ scheduler_.reset(NULL); |
+ } |
+ |
+ static gboolean SourceCallback(gpointer data) { |
+ g_main_loop_quit(test_->loop_); |
+ // Forwards the call to the function mock so that expectations can be set. |
+ return test_->source_callback_.Call(data); |
+ } |
+ |
+ scoped_ptr<UpdateCheckSchedulerUnderTest> scheduler_; |
+ UpdateAttempterMock attempter_; |
+ MockFunction<gboolean(gpointer data)> source_callback_; |
+ GMainLoop* loop_; |
+ static UpdateCheckSchedulerTest* test_; |
+}; |
+ |
+UpdateCheckSchedulerTest* UpdateCheckSchedulerTest::test_ = NULL; |
+ |
+TEST_F(UpdateCheckSchedulerTest, CanScheduleTest) { |
+ EXPECT_FALSE(scheduler_->CanSchedule()); |
+ scheduler_->enabled_ = true; |
+ EXPECT_TRUE(scheduler_->CanSchedule()); |
+ scheduler_->scheduled_ = true; |
+ EXPECT_FALSE(scheduler_->CanSchedule()); |
+ scheduler_->enabled_ = false; |
+ EXPECT_FALSE(scheduler_->CanSchedule()); |
+} |
+ |
+TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzBackoffTest) { |
+ int interval, fuzz; |
+ attempter_.set_http_response_code(500); |
+ int last_interval = UpdateCheckScheduler::kTimeoutPeriodic + 50; |
+ scheduler_->last_interval_ = last_interval; |
+ scheduler_->ComputeNextIntervalAndFuzz(&interval, &fuzz); |
+ EXPECT_EQ(2 * last_interval, interval); |
+ EXPECT_EQ(2 * last_interval, fuzz); |
+ |
+ attempter_.set_http_response_code(503); |
+ last_interval = UpdateCheckScheduler::kTimeoutMaxBackoff / 2 + 1; |
+ scheduler_->last_interval_ = last_interval; |
+ scheduler_->ComputeNextIntervalAndFuzz(&interval, &fuzz); |
+ EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoff, interval); |
+ EXPECT_EQ(UpdateCheckScheduler::kTimeoutMaxBackoff, fuzz); |
+} |
+ |
+TEST_F(UpdateCheckSchedulerTest, ComputeNextIntervalAndFuzzTest) { |
+ int interval, fuzz; |
+ scheduler_->ComputeNextIntervalAndFuzz(&interval, &fuzz); |
+ EXPECT_EQ(UpdateCheckScheduler::kTimeoutPeriodic, interval); |
+ EXPECT_EQ(UpdateCheckScheduler::kTimeoutRegularFuzz, fuzz); |
+} |
+ |
+TEST_F(UpdateCheckSchedulerTest, GTimeoutAddSecondsTest) { |
+ loop_ = g_main_loop_new(g_main_context_default(), FALSE); |
+ // Invokes the actual GLib wrapper method rather than the subclass mock. |
+ scheduler_->UpdateCheckScheduler::GTimeoutAddSeconds(0, SourceCallback); |
+ EXPECT_CALL(source_callback_, Call(scheduler_.get())).Times(1); |
+ g_main_loop_run(loop_); |
+ g_main_loop_unref(loop_); |
+} |
+ |
+TEST_F(UpdateCheckSchedulerTest, IsBootDeviceRemovableTest) { |
+ // Invokes the actual utils wrapper method rather than the subclass mock. |
+ EXPECT_FALSE(scheduler_->UpdateCheckScheduler::IsBootDeviceRemovable()); |
+} |
+ |
+TEST_F(UpdateCheckSchedulerTest, IsOfficialBuildTest) { |
+ // Invokes the actual utils wrapper method rather than the subclass mock. |
+ EXPECT_TRUE(scheduler_->UpdateCheckScheduler::IsOfficialBuild()); |
+} |
+ |
+TEST_F(UpdateCheckSchedulerTest, RunBootDeviceRemovableTest) { |
+ scheduler_->enabled_ = true; |
+ EXPECT_CALL(*scheduler_, IsOfficialBuild()).Times(1).WillOnce(Return(true)); |
+ EXPECT_CALL(*scheduler_, IsBootDeviceRemovable()) |
+ .Times(1) |
+ .WillOnce(Return(true)); |
+ scheduler_->Run(); |
+ EXPECT_FALSE(scheduler_->enabled_); |
+ EXPECT_EQ(NULL, attempter_.update_check_scheduler()); |
+} |
+ |
+TEST_F(UpdateCheckSchedulerTest, RunNonOfficialBuildTest) { |
+ scheduler_->enabled_ = true; |
+ EXPECT_CALL(*scheduler_, IsOfficialBuild()).Times(1).WillOnce(Return(false)); |
+ scheduler_->Run(); |
+ EXPECT_FALSE(scheduler_->enabled_); |
+ EXPECT_EQ(NULL, attempter_.update_check_scheduler()); |
+} |
+ |
+TEST_F(UpdateCheckSchedulerTest, RunTest) { |
+ int interval_min, interval_max; |
+ FuzzRange(UpdateCheckScheduler::kTimeoutOnce, |
+ UpdateCheckScheduler::kTimeoutRegularFuzz, |
+ &interval_min, |
+ &interval_max); |
+ EXPECT_CALL(*scheduler_, IsOfficialBuild()).Times(1).WillOnce(Return(true)); |
+ EXPECT_CALL(*scheduler_, IsBootDeviceRemovable()) |
+ .Times(1) |
+ .WillOnce(Return(false)); |
+ EXPECT_CALL(*scheduler_, |
+ GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)), |
+ scheduler_->StaticCheck)).Times(1); |
+ scheduler_->Run(); |
+ EXPECT_TRUE(scheduler_->enabled_); |
+ EXPECT_EQ(scheduler_.get(), attempter_.update_check_scheduler()); |
+} |
+ |
+TEST_F(UpdateCheckSchedulerTest, ScheduleCheckDisabledTest) { |
+ EXPECT_CALL(*scheduler_, GTimeoutAddSeconds(_, _)).Times(0); |
+ scheduler_->ScheduleCheck(250, 30); |
+ EXPECT_EQ(0, scheduler_->last_interval_); |
+ EXPECT_FALSE(scheduler_->scheduled_); |
+} |
+ |
+TEST_F(UpdateCheckSchedulerTest, ScheduleCheckEnabledTest) { |
+ int interval_min, interval_max; |
+ FuzzRange(100, 10, &interval_min,&interval_max); |
+ EXPECT_CALL(*scheduler_, |
+ GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)), |
+ scheduler_->StaticCheck)).Times(1); |
+ scheduler_->enabled_ = true; |
+ scheduler_->ScheduleCheck(100, 10); |
+ EXPECT_EQ(100, scheduler_->last_interval_); |
+ EXPECT_TRUE(scheduler_->scheduled_); |
+} |
+ |
+TEST_F(UpdateCheckSchedulerTest, ScheduleCheckNegativeIntervalTest) { |
+ EXPECT_CALL(*scheduler_, GTimeoutAddSeconds(0, scheduler_->StaticCheck)) |
+ .Times(1); |
+ scheduler_->enabled_ = true; |
+ scheduler_->ScheduleCheck(-50, 20); |
+ EXPECT_TRUE(scheduler_->scheduled_); |
+} |
+ |
+TEST_F(UpdateCheckSchedulerTest, ScheduleNextCheckDisabledTest) { |
+ EXPECT_CALL(*scheduler_, GTimeoutAddSeconds(_, _)).Times(0); |
+ scheduler_->ScheduleNextCheck(); |
+} |
+ |
+TEST_F(UpdateCheckSchedulerTest, ScheduleNextCheckEnabledTest) { |
+ int interval_min, interval_max; |
+ FuzzRange(UpdateCheckScheduler::kTimeoutPeriodic, |
+ UpdateCheckScheduler::kTimeoutRegularFuzz, |
+ &interval_min, |
+ &interval_max); |
+ EXPECT_CALL(*scheduler_, |
+ GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)), |
+ scheduler_->StaticCheck)).Times(1); |
+ scheduler_->enabled_ = true; |
+ scheduler_->ScheduleNextCheck(); |
+} |
+ |
+TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusIdleDisabledTest) { |
+ EXPECT_CALL(*scheduler_, GTimeoutAddSeconds(_, _)).Times(0); |
+ scheduler_->SetUpdateStatus(UPDATE_STATUS_IDLE); |
+} |
+ |
+TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusIdleEnabledTest) { |
+ int interval_min, interval_max; |
+ FuzzRange(UpdateCheckScheduler::kTimeoutPeriodic, |
+ UpdateCheckScheduler::kTimeoutRegularFuzz, |
+ &interval_min, |
+ &interval_max); |
+ EXPECT_CALL(*scheduler_, |
+ GTimeoutAddSeconds(AllOf(Ge(interval_min), Le(interval_max)), |
+ scheduler_->StaticCheck)).Times(1); |
+ scheduler_->enabled_ = true; |
+ scheduler_->SetUpdateStatus(UPDATE_STATUS_IDLE); |
+} |
+ |
+TEST_F(UpdateCheckSchedulerTest, SetUpdateStatusNonIdleTest) { |
+ EXPECT_CALL(*scheduler_, GTimeoutAddSeconds(_, _)).Times(0); |
+ scheduler_->SetUpdateStatus(UPDATE_STATUS_DOWNLOADING); |
+ scheduler_->enabled_ = true; |
+ scheduler_->SetUpdateStatus(UPDATE_STATUS_DOWNLOADING); |
+} |
+ |
+TEST_F(UpdateCheckSchedulerTest, StaticCheckTest) { |
+ scheduler_->scheduled_ = true; |
+ EXPECT_CALL(attempter_, Update("", "")).Times(1); |
+ UpdateCheckSchedulerUnderTest::StaticCheck(scheduler_.get()); |
+} |
+ |
+} // namespace chromeos_update_engine |