| OLD | NEW |
| (Empty) |
| 1 // Copyright 2007-2009 Google Inc. | |
| 2 // | |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
| 4 // you may not use this file except in compliance with the License. | |
| 5 // You may obtain a copy of the License at | |
| 6 // | |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | |
| 8 // | |
| 9 // Unless required by applicable law or agreed to in writing, software | |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 12 // See the License for the specific language governing permissions and | |
| 13 // limitations under the License. | |
| 14 // ======================================================================== | |
| 15 | |
| 16 | |
| 17 #include <iostream> | |
| 18 #include "base/scoped_ptr.h" | |
| 19 #include "omaha/base/queue_timer.h" | |
| 20 #include "omaha/base/scoped_any.h" | |
| 21 #include "omaha/base/timer.h" | |
| 22 #include "omaha/testing/unit_test.h" | |
| 23 | |
| 24 namespace omaha { | |
| 25 | |
| 26 class QueueTimerTest : public testing::Test { | |
| 27 protected: | |
| 28 QueueTimerTest() | |
| 29 : timer_queue_(NULL), | |
| 30 cnt_(0), | |
| 31 max_cnt_(0) {} | |
| 32 | |
| 33 virtual void SetUp() { | |
| 34 cnt_ = 0; | |
| 35 timer_queue_ = ::CreateTimerQueue(); | |
| 36 ASSERT_TRUE(timer_queue_); | |
| 37 reset(ev_, ::CreateEvent(NULL, true, false, NULL)); | |
| 38 } | |
| 39 | |
| 40 virtual void TearDown() { | |
| 41 // First destroy the timer, otherwise the timer could fire and | |
| 42 // access invalid test case state. | |
| 43 queue_timer_.reset(); | |
| 44 reset(ev_); | |
| 45 ASSERT_TRUE(::DeleteTimerQueueEx(timer_queue_, INVALID_HANDLE_VALUE)); | |
| 46 cnt_ = 0; | |
| 47 max_cnt_ = 0; | |
| 48 } | |
| 49 | |
| 50 // Handles the alarm mode of the timer queue, where the timer fires once. | |
| 51 static void AlarmCallback(QueueTimer* queue_timer); | |
| 52 | |
| 53 // Handles the periodic timer. | |
| 54 static void TimerCallback(QueueTimer* queue_timer); | |
| 55 | |
| 56 HANDLE timer_queue_; | |
| 57 scoped_ptr<QueueTimer> queue_timer_; | |
| 58 scoped_event ev_; | |
| 59 volatile int cnt_; | |
| 60 volatile int max_cnt_; | |
| 61 }; | |
| 62 | |
| 63 void QueueTimerTest::AlarmCallback(QueueTimer* queue_timer) { | |
| 64 ASSERT_TRUE(queue_timer); | |
| 65 void* ctx = queue_timer->ctx(); | |
| 66 QueueTimerTest* test = static_cast<QueueTimerTest*>(ctx); | |
| 67 test->cnt_ = 1; | |
| 68 ASSERT_TRUE(::SetEvent(get(test->ev_))); | |
| 69 } | |
| 70 | |
| 71 void QueueTimerTest::TimerCallback(QueueTimer* queue_timer) { | |
| 72 ASSERT_TRUE(queue_timer); | |
| 73 void* ctx = queue_timer->ctx(); | |
| 74 QueueTimerTest* test = static_cast<QueueTimerTest*>(ctx); | |
| 75 | |
| 76 // Wait max_cnt_ ticks before signaling. | |
| 77 ++test->cnt_; | |
| 78 if (test->cnt_ == test->max_cnt_) { | |
| 79 ::SetEvent(get(test->ev_)); | |
| 80 } | |
| 81 } | |
| 82 | |
| 83 TEST_F(QueueTimerTest, QuickAlarm) { | |
| 84 queue_timer_.reset(new QueueTimer(timer_queue_, | |
| 85 &QueueTimerTest::AlarmCallback, | |
| 86 this)); | |
| 87 const int kWaitTimeMaxMs = 1000; | |
| 88 | |
| 89 // Set the timer to fire once right away. | |
| 90 LowResTimer timer(true); | |
| 91 ASSERT_HRESULT_SUCCEEDED( | |
| 92 queue_timer_->Start(0, 0, WT_EXECUTEINTIMERTHREAD | WT_EXECUTEONLYONCE)); | |
| 93 EXPECT_EQ(WAIT_OBJECT_0, ::WaitForSingleObject(get(ev_), kWaitTimeMaxMs)); | |
| 94 EXPECT_EQ(1, cnt_); | |
| 95 | |
| 96 // Expect the alarm to fire quickly. | |
| 97 EXPECT_GE(50u, timer.GetMilliseconds()); | |
| 98 } | |
| 99 | |
| 100 // The test takes about 50 seconds to run. | |
| 101 TEST_F(QueueTimerTest, Alarm) { | |
| 102 if (!ShouldRunEnormousTest()) { | |
| 103 return; | |
| 104 } | |
| 105 | |
| 106 queue_timer_.reset(new QueueTimer(timer_queue_, | |
| 107 &QueueTimerTest::AlarmCallback, | |
| 108 this)); | |
| 109 const int kWaitTimeMaxMs = 60 * 1000; // 60 seconds. | |
| 110 | |
| 111 // Set the timer to fire once after 5 sec, 10 sec, 15 sec, 20 sec and wait. | |
| 112 LowResTimer timer(false); | |
| 113 for (int i = 1; i <= 4; ++i) { | |
| 114 const int time_interval_ms = 5 * 1000 * i; | |
| 115 SCOPED_TRACE(testing::Message() << "time_interval_ms=" << time_interval_ms); | |
| 116 | |
| 117 timer.Start(); | |
| 118 ASSERT_HRESULT_SUCCEEDED( | |
| 119 queue_timer_->Start(time_interval_ms, 0, WT_EXECUTEONLYONCE)); | |
| 120 EXPECT_EQ(WAIT_OBJECT_0, ::WaitForSingleObject(get(ev_), kWaitTimeMaxMs)); | |
| 121 | |
| 122 int actual_time_ms = timer.GetMilliseconds(); | |
| 123 timer.Reset(); | |
| 124 | |
| 125 // Expect the alarm to fire anytime between a narrow interval. | |
| 126 EXPECT_EQ(1, cnt_); | |
| 127 EXPECT_LE(time_interval_ms - 50, actual_time_ms); | |
| 128 EXPECT_GE(time_interval_ms + 150, actual_time_ms); | |
| 129 | |
| 130 cnt_ = 0; | |
| 131 ::ResetEvent(get(ev_)); | |
| 132 } | |
| 133 | |
| 134 // Set the timer to fire once after 2000 ms but do not wait for it to fire. | |
| 135 ASSERT_HRESULT_SUCCEEDED( | |
| 136 queue_timer_->Start(2000, 0, WT_EXECUTEONLYONCE)); | |
| 137 EXPECT_EQ(WAIT_TIMEOUT, ::WaitForSingleObject(get(ev_), 100)); | |
| 138 EXPECT_EQ(0, cnt_); | |
| 139 } | |
| 140 | |
| 141 // The test takes about 35 seconds to run. | |
| 142 TEST_F(QueueTimerTest, Timer) { | |
| 143 if (!ShouldRunEnormousTest()) { | |
| 144 return; | |
| 145 } | |
| 146 | |
| 147 queue_timer_.reset(new QueueTimer(timer_queue_, | |
| 148 &QueueTimerTest::TimerCallback, | |
| 149 this)); | |
| 150 const int kWaitTimeMaxMs = 60 * 1000; // 60 seconds. | |
| 151 | |
| 152 max_cnt_ = 4; | |
| 153 | |
| 154 // Set the timer to fire at 10 seconds intervals with an initial delay of | |
| 155 // 5 seconds. | |
| 156 LowResTimer timer(true); | |
| 157 ASSERT_HRESULT_SUCCEEDED(queue_timer_->Start(5000, 10000, WT_EXECUTEDEFAULT)); | |
| 158 EXPECT_EQ(WAIT_OBJECT_0, ::WaitForSingleObject(get(ev_), kWaitTimeMaxMs)); | |
| 159 | |
| 160 int actual_time_ms = timer.GetMilliseconds(); | |
| 161 | |
| 162 EXPECT_EQ(4, cnt_); | |
| 163 EXPECT_LE(35 * 1000 - 50, actual_time_ms); | |
| 164 EXPECT_GE(35 * 1000 + 350, actual_time_ms); | |
| 165 | |
| 166 // Tests it can't start periodic timers more than one time. | |
| 167 ASSERT_EQ(E_UNEXPECTED, queue_timer_->Start(25, 50, WT_EXECUTEDEFAULT)); | |
| 168 } | |
| 169 | |
| 170 } // namespace omaha | |
| 171 | |
| OLD | NEW |