blob: b2f4690f9a55e565c630fae28b040ac970e2d349 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// 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
9using testing::Invoke;
10
11namespace quic {
12namespace test {
13namespace {
14
15class MockDelegate : public QuicAlarm::Delegate {
16 public:
17 MOCK_METHOD0(OnAlarm, void());
18};
19
20class 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
35class 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
62class 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
75class 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
93TEST_F(QuicAlarmTest, IsSet) {
94 EXPECT_FALSE(alarm_.IsSet());
95}
96
97TEST_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
105TEST_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
114TEST_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
124TEST_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
133TEST_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
143TEST_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
154TEST_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