| /* | 
 |  *  Copyright 2016 The WebRTC Project Authors. All rights reserved. | 
 |  * | 
 |  *  Use of this source code is governed by a BSD-style license | 
 |  *  that can be found in the LICENSE file in the root of the source | 
 |  *  tree. An additional intellectual property rights grant can be found | 
 |  *  in the file PATENTS.  All contributing project authors may | 
 |  *  be found in the AUTHORS file in the root of the source tree. | 
 |  */ | 
 |  | 
 | #include <memory> | 
 |  | 
 | #include "webrtc/p2p/quic/quicconnectionhelper.h" | 
 |  | 
 | #include "net/quic/quic_time.h" | 
 | #include "webrtc/rtc_base/gunit.h" | 
 |  | 
 | using cricket::QuicAlarm; | 
 | using cricket::QuicConnectionHelper; | 
 |  | 
 | using net::QuicClock; | 
 | using net::QuicTime; | 
 | using net::QuicWallTime; | 
 |  | 
 | // Clock that can be set to arbitrary times. | 
 | class MockClock : public QuicClock { | 
 |  public: | 
 |   MockClock() : now_(QuicTime::Zero()) {} | 
 |  | 
 |   void AdvanceTime(QuicTime::Delta delta) { now_ = now_.Add(delta); } | 
 |  | 
 |   QuicTime Now() const override { return now_; } | 
 |  | 
 |   QuicTime ApproximateNow() const override { return now_; } | 
 |  | 
 |   QuicWallTime WallNow() const override { | 
 |     return QuicWallTime::FromUNIXSeconds( | 
 |         now_.Subtract(QuicTime::Zero()).ToSeconds()); | 
 |   } | 
 |  | 
 |   base::TimeTicks NowInTicks() const { | 
 |     base::TimeTicks ticks; | 
 |     return ticks + base::TimeDelta::FromMicroseconds( | 
 |                        now_.Subtract(QuicTime::Zero()).ToMicroseconds()); | 
 |   } | 
 |  | 
 |  private: | 
 |   QuicTime now_; | 
 | }; | 
 |  | 
 | // Implements OnAlarm() event which alarm triggers. | 
 | class MockAlarmDelegate : public QuicAlarm::Delegate { | 
 |  public: | 
 |   MockAlarmDelegate() : fired_(false) {} | 
 |  | 
 |   void OnAlarm() override { fired_ = true; } | 
 |  | 
 |   bool fired() const { return fired_; } | 
 |   void Clear() { fired_ = false; } | 
 |  | 
 |  private: | 
 |   bool fired_; | 
 | }; | 
 |  | 
 | class QuicAlarmTest : public ::testing::Test { | 
 |  public: | 
 |   QuicAlarmTest() | 
 |       : delegate_(new MockAlarmDelegate()), | 
 |         alarm_(new QuicAlarm( | 
 |             &clock_, | 
 |             rtc::Thread::Current(), | 
 |             net::QuicArenaScopedPtr<net::QuicAlarm::Delegate>(delegate_))) {} | 
 |  | 
 |   // Make the alarm fire after the given microseconds (us). Negative values | 
 |   // imply the alarm should fire immediately. | 
 |   void SetTime(int us) { | 
 |     QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(us); | 
 |     alarm_->Set(clock_.Now().Add(delta)); | 
 |   } | 
 |  | 
 |   // Make rtc::Thread::Current() process the next message. | 
 |   void ProcessNextMessage() { rtc::Thread::Current()->ProcessMessages(0); } | 
 |  | 
 |  protected: | 
 |   // Handles event that alarm fires. | 
 |   MockAlarmDelegate* delegate_; | 
 |   // Used for setting clock time relative to alarm. | 
 |   MockClock clock_; | 
 |  | 
 |   std::unique_ptr<QuicAlarm> alarm_; | 
 | }; | 
 |  | 
 | // Test that the alarm is fired. | 
 | TEST_F(QuicAlarmTest, FireAlarm) { | 
 |   SetTime(-1); | 
 |   ProcessNextMessage(); | 
 |   ASSERT_TRUE(delegate_->fired()); | 
 |   ASSERT_EQ(QuicTime::Zero(), alarm_->deadline()); | 
 | } | 
 |  | 
 | // Test cancellation of alarm when it is set to fire. | 
 | TEST_F(QuicAlarmTest, CancelAlarmAfterSet) { | 
 |   // TODO(mikescarlett): Test will fail in the future if | 
 |   // rtc::Thread::PostDelayed calls the delegate synchronously for times <= 0. | 
 |   // Rewrite this when rtc::Thread is able to use a mock clock. | 
 |   SetTime(-1); | 
 |   alarm_->Cancel(); | 
 |   ProcessNextMessage(); | 
 |   ASSERT_FALSE(delegate_->fired()); | 
 | } | 
 |  | 
 | // Test cancellation of alarm when it is not set to fire. | 
 | TEST_F(QuicAlarmTest, CancelAlarmBeforeSet) { | 
 |   alarm_->Cancel(); | 
 |   ProcessNextMessage(); | 
 |   ASSERT_FALSE(delegate_->fired()); | 
 | } | 
 |  | 
 | // Test that timing for posting task is accurate. | 
 | TEST_F(QuicAlarmTest, AlarmGetDelay) { | 
 |   SetTime(1000000); | 
 |   EXPECT_EQ(1000, alarm_->GetDelay()); | 
 |   clock_.AdvanceTime(QuicTime::Delta::FromMicroseconds(300000)); | 
 |   EXPECT_EQ(700, alarm_->GetDelay()); | 
 | } |