QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 1 | // Copyright 2013 The Chromium 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 "net/third_party/quiche/src/quic/core/quic_alarm.h" |
| 6 | |
| 7 | #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" |
| 8 | |
| 9 | using testing::Invoke; |
| 10 | |
| 11 | namespace quic { |
| 12 | namespace test { |
| 13 | namespace { |
| 14 | |
| 15 | class MockDelegate : public QuicAlarm::Delegate { |
| 16 | public: |
| 17 | MOCK_METHOD0(OnAlarm, void()); |
| 18 | }; |
| 19 | |
| 20 | class DestructiveDelegate : public QuicAlarm::Delegate { |
| 21 | public: |
| 22 | DestructiveDelegate() : alarm_(nullptr) {} |
| 23 | |
| 24 | void set_alarm(QuicAlarm* alarm) { alarm_ = alarm; } |
| 25 | |
| 26 | void OnAlarm() override { |
| 27 | DCHECK(alarm_); |
| 28 | delete alarm_; |
| 29 | } |
| 30 | |
| 31 | private: |
| 32 | QuicAlarm* alarm_; |
| 33 | }; |
| 34 | |
| 35 | class TestAlarm : public QuicAlarm { |
| 36 | public: |
| 37 | explicit TestAlarm(QuicAlarm::Delegate* delegate) |
| 38 | : QuicAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate)) {} |
| 39 | |
| 40 | bool scheduled() const { return scheduled_; } |
| 41 | |
| 42 | void FireAlarm() { |
| 43 | scheduled_ = false; |
| 44 | Fire(); |
| 45 | } |
| 46 | |
| 47 | protected: |
| 48 | void SetImpl() override { |
| 49 | DCHECK(deadline().IsInitialized()); |
| 50 | scheduled_ = true; |
| 51 | } |
| 52 | |
| 53 | void CancelImpl() override { |
| 54 | DCHECK(!deadline().IsInitialized()); |
| 55 | scheduled_ = false; |
| 56 | } |
| 57 | |
| 58 | private: |
| 59 | bool scheduled_; |
| 60 | }; |
| 61 | |
| 62 | class DestructiveAlarm : public QuicAlarm { |
| 63 | public: |
| 64 | explicit DestructiveAlarm(DestructiveDelegate* delegate) |
| 65 | : QuicAlarm(QuicArenaScopedPtr<DestructiveDelegate>(delegate)) {} |
| 66 | |
| 67 | void FireAlarm() { Fire(); } |
| 68 | |
| 69 | protected: |
| 70 | void SetImpl() override {} |
| 71 | |
| 72 | void CancelImpl() override {} |
| 73 | }; |
| 74 | |
| 75 | class QuicAlarmTest : public QuicTest { |
| 76 | public: |
| 77 | QuicAlarmTest() |
| 78 | : delegate_(new MockDelegate()), |
| 79 | alarm_(delegate_), |
| 80 | deadline_(QuicTime::Zero() + QuicTime::Delta::FromSeconds(7)), |
| 81 | deadline2_(QuicTime::Zero() + QuicTime::Delta::FromSeconds(14)), |
| 82 | new_deadline_(QuicTime::Zero()) {} |
| 83 | |
| 84 | void ResetAlarm() { alarm_.Set(new_deadline_); } |
| 85 | |
| 86 | MockDelegate* delegate_; // not owned |
| 87 | TestAlarm alarm_; |
| 88 | QuicTime deadline_; |
| 89 | QuicTime deadline2_; |
| 90 | QuicTime new_deadline_; |
| 91 | }; |
| 92 | |
| 93 | TEST_F(QuicAlarmTest, IsSet) { |
| 94 | EXPECT_FALSE(alarm_.IsSet()); |
| 95 | } |
| 96 | |
| 97 | TEST_F(QuicAlarmTest, Set) { |
| 98 | QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7); |
| 99 | alarm_.Set(deadline); |
| 100 | EXPECT_TRUE(alarm_.IsSet()); |
| 101 | EXPECT_TRUE(alarm_.scheduled()); |
| 102 | EXPECT_EQ(deadline, alarm_.deadline()); |
| 103 | } |
| 104 | |
| 105 | TEST_F(QuicAlarmTest, Cancel) { |
| 106 | QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7); |
| 107 | alarm_.Set(deadline); |
| 108 | alarm_.Cancel(); |
| 109 | EXPECT_FALSE(alarm_.IsSet()); |
| 110 | EXPECT_FALSE(alarm_.scheduled()); |
| 111 | EXPECT_EQ(QuicTime::Zero(), alarm_.deadline()); |
| 112 | } |
| 113 | |
| 114 | TEST_F(QuicAlarmTest, Update) { |
| 115 | QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7); |
| 116 | alarm_.Set(deadline); |
| 117 | QuicTime new_deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(8); |
| 118 | alarm_.Update(new_deadline, QuicTime::Delta::Zero()); |
| 119 | EXPECT_TRUE(alarm_.IsSet()); |
| 120 | EXPECT_TRUE(alarm_.scheduled()); |
| 121 | EXPECT_EQ(new_deadline, alarm_.deadline()); |
| 122 | } |
| 123 | |
| 124 | TEST_F(QuicAlarmTest, UpdateWithZero) { |
| 125 | QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7); |
| 126 | alarm_.Set(deadline); |
| 127 | alarm_.Update(QuicTime::Zero(), QuicTime::Delta::Zero()); |
| 128 | EXPECT_FALSE(alarm_.IsSet()); |
| 129 | EXPECT_FALSE(alarm_.scheduled()); |
| 130 | EXPECT_EQ(QuicTime::Zero(), alarm_.deadline()); |
| 131 | } |
| 132 | |
| 133 | TEST_F(QuicAlarmTest, Fire) { |
| 134 | QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7); |
| 135 | alarm_.Set(deadline); |
| 136 | EXPECT_CALL(*delegate_, OnAlarm()); |
| 137 | alarm_.FireAlarm(); |
| 138 | EXPECT_FALSE(alarm_.IsSet()); |
| 139 | EXPECT_FALSE(alarm_.scheduled()); |
| 140 | EXPECT_EQ(QuicTime::Zero(), alarm_.deadline()); |
| 141 | } |
| 142 | |
| 143 | TEST_F(QuicAlarmTest, FireAndResetViaSet) { |
| 144 | alarm_.Set(deadline_); |
| 145 | new_deadline_ = deadline2_; |
| 146 | EXPECT_CALL(*delegate_, OnAlarm()) |
| 147 | .WillOnce(Invoke(this, &QuicAlarmTest::ResetAlarm)); |
| 148 | alarm_.FireAlarm(); |
| 149 | EXPECT_TRUE(alarm_.IsSet()); |
| 150 | EXPECT_TRUE(alarm_.scheduled()); |
| 151 | EXPECT_EQ(deadline2_, alarm_.deadline()); |
| 152 | } |
| 153 | |
| 154 | TEST_F(QuicAlarmTest, FireDestroysAlarm) { |
| 155 | DestructiveDelegate* delegate(new DestructiveDelegate); |
| 156 | DestructiveAlarm* alarm = new DestructiveAlarm(delegate); |
| 157 | delegate->set_alarm(alarm); |
| 158 | QuicTime deadline = QuicTime::Zero() + QuicTime::Delta::FromSeconds(7); |
| 159 | alarm->Set(deadline); |
| 160 | // This should not crash, even though it will destroy alarm. |
| 161 | alarm->FireAlarm(); |
| 162 | } |
| 163 | |
| 164 | } // namespace |
| 165 | } // namespace test |
| 166 | } // namespace quic |