1// Copyright (c) 2012 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/quic/quic_connection_helper.h"
6
7#include "net/quic/test_tools/mock_clock.h"
8#include "net/quic/test_tools/mock_random.h"
9#include "net/quic/test_tools/test_task_runner.h"
10#include "testing/gtest/include/gtest/gtest.h"
11
12namespace net {
13namespace test {
14namespace {
15
16class TestDelegate : public QuicAlarm::Delegate {
17 public:
18  TestDelegate() : fired_(false) {}
19
20  virtual QuicTime OnAlarm() OVERRIDE {
21    fired_ = true;
22    return QuicTime::Zero();
23  }
24
25  bool fired() const { return fired_; }
26  void Clear() { fired_= false; }
27
28 private:
29  bool fired_;
30};
31
32class QuicConnectionHelperTest : public ::testing::Test {
33 protected:
34  QuicConnectionHelperTest()
35      : runner_(new TestTaskRunner(&clock_)),
36        helper_(runner_.get(), &clock_, &random_generator_) {
37  }
38
39  scoped_refptr<TestTaskRunner> runner_;
40  QuicConnectionHelper helper_;
41  MockClock clock_;
42  MockRandom random_generator_;
43};
44
45TEST_F(QuicConnectionHelperTest, GetClock) {
46  EXPECT_EQ(&clock_, helper_.GetClock());
47}
48
49TEST_F(QuicConnectionHelperTest, GetRandomGenerator) {
50  EXPECT_EQ(&random_generator_, helper_.GetRandomGenerator());
51}
52
53TEST_F(QuicConnectionHelperTest, CreateAlarm) {
54  TestDelegate* delegate = new TestDelegate();
55  scoped_ptr<QuicAlarm> alarm(helper_.CreateAlarm(delegate));
56
57  QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
58  alarm->Set(clock_.Now().Add(delta));
59
60  // Verify that the alarm task has been posted.
61  ASSERT_EQ(1u, runner_->GetPostedTasks().size());
62  EXPECT_EQ(base::TimeDelta::FromMicroseconds(delta.ToMicroseconds()),
63            runner_->GetPostedTasks()[0].delay);
64
65  runner_->RunNextTask();
66  EXPECT_EQ(QuicTime::Zero().Add(delta), clock_.Now());
67  EXPECT_TRUE(delegate->fired());
68}
69
70TEST_F(QuicConnectionHelperTest, CreateAlarmAndCancel) {
71  TestDelegate* delegate = new TestDelegate();
72  scoped_ptr<QuicAlarm> alarm(helper_.CreateAlarm(delegate));
73
74  QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
75  alarm->Set(clock_.Now().Add(delta));
76  alarm->Cancel();
77
78  // The alarm task should still be posted.
79  ASSERT_EQ(1u, runner_->GetPostedTasks().size());
80  EXPECT_EQ(base::TimeDelta::FromMicroseconds(delta.ToMicroseconds()),
81            runner_->GetPostedTasks()[0].delay);
82
83  runner_->RunNextTask();
84  EXPECT_EQ(QuicTime::Zero().Add(delta), clock_.Now());
85  EXPECT_FALSE(delegate->fired());
86}
87
88TEST_F(QuicConnectionHelperTest, CreateAlarmAndReset) {
89  TestDelegate* delegate = new TestDelegate();
90  scoped_ptr<QuicAlarm> alarm(helper_.CreateAlarm(delegate));
91
92  QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1);
93  alarm->Set(clock_.Now().Add(delta));
94  alarm->Cancel();
95  QuicTime::Delta new_delta = QuicTime::Delta::FromMicroseconds(3);
96  alarm->Set(clock_.Now().Add(new_delta));
97
98  // The alarm task should still be posted.
99  ASSERT_EQ(1u, runner_->GetPostedTasks().size());
100  EXPECT_EQ(base::TimeDelta::FromMicroseconds(delta.ToMicroseconds()),
101            runner_->GetPostedTasks()[0].delay);
102
103  runner_->RunNextTask();
104  EXPECT_EQ(QuicTime::Zero().Add(delta), clock_.Now());
105  EXPECT_FALSE(delegate->fired());
106
107  // The alarm task should be posted again.
108  ASSERT_EQ(1u, runner_->GetPostedTasks().size());
109
110  runner_->RunNextTask();
111  EXPECT_EQ(QuicTime::Zero().Add(new_delta), clock_.Now());
112  EXPECT_TRUE(delegate->fired());
113}
114
115TEST_F(QuicConnectionHelperTest, CreateAlarmAndResetEarlier) {
116  TestDelegate* delegate = new TestDelegate();
117  scoped_ptr<QuicAlarm> alarm(helper_.CreateAlarm(delegate));
118
119  QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(3);
120  alarm->Set(clock_.Now().Add(delta));
121  alarm->Cancel();
122  QuicTime::Delta new_delta = QuicTime::Delta::FromMicroseconds(1);
123  alarm->Set(clock_.Now().Add(new_delta));
124
125  // Both alarm tasks will be posted.
126  ASSERT_EQ(2u, runner_->GetPostedTasks().size());
127
128  // The earlier task will execute and will fire the alarm->
129  runner_->RunNextTask();
130  EXPECT_EQ(QuicTime::Zero().Add(new_delta), clock_.Now());
131  EXPECT_TRUE(delegate->fired());
132  delegate->Clear();
133
134  // The latter task is still posted.
135  ASSERT_EQ(1u, runner_->GetPostedTasks().size());
136
137  // When the latter task is executed, the weak ptr will be invalid and
138  // the alarm will not fire.
139  runner_->RunNextTask();
140  EXPECT_EQ(QuicTime::Zero().Add(delta), clock_.Now());
141  EXPECT_FALSE(delegate->fired());
142}
143
144}  // namespace
145}  // namespace test
146}  // namespace net
147