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.
5 #include "net/quic/quic_session.h"
6 #include "net/quic/quic_connection.h"
10 #include "base/hash_tables.h"
11 #include "net/quic/test_tools/quic_test_utils.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h"
18 using testing::InSequence
;
24 class TestCryptoStream
: public QuicCryptoStream
{
26 explicit TestCryptoStream(QuicSession
* session
)
27 : QuicCryptoStream(session
) {
30 void OnHandshakeMessage(const CryptoHandshakeMessage
& message
) {
31 SetHandshakeComplete(QUIC_NO_ERROR
);
35 class TestStream
: public ReliableQuicStream
{
37 TestStream(QuicStreamId id
, QuicSession
* session
)
38 : ReliableQuicStream(id
, session
) {
41 virtual uint32
ProcessData(const char* data
, uint32 data_len
) {
45 MOCK_METHOD0(OnCanWrite
, void());
48 class TestSession
: public QuicSession
{
50 TestSession(QuicConnection
* connection
, bool is_server
)
51 : QuicSession(connection
, is_server
),
52 crypto_stream_(this) {
55 virtual QuicCryptoStream
* GetCryptoStream() {
56 return &crypto_stream_
;
59 virtual TestStream
* CreateOutgoingReliableStream() {
60 TestStream
* stream
= new TestStream(GetNextStreamId(), this);
61 ActivateStream(stream
);
65 virtual TestStream
* CreateIncomingReliableStream(QuicStreamId id
) {
66 return new TestStream(id
, this);
69 bool IsClosedStream(QuicStreamId id
) {
70 return QuicSession::IsClosedStream(id
);
73 ReliableQuicStream
* GetIncomingReliableStream(QuicStreamId stream_id
) {
74 return QuicSession::GetIncomingReliableStream(stream_id
);
77 // Helper method for gmock
78 void MarkTwoWriteBlocked() {
79 this->MarkWriteBlocked(2);
82 TestCryptoStream crypto_stream_
;
85 class QuicSessionTest
: public ::testing::Test
{
89 connection_(new MockConnection(guid_
, IPEndPoint())),
90 session_(connection_
, true) {
93 void CheckClosedStreams() {
94 for (int i
= kCryptoStreamId
; i
< 100; i
++) {
95 if (closed_streams_
.count(i
) == 0) {
96 EXPECT_FALSE(session_
.IsClosedStream(i
)) << " stream id: " << i
;
98 EXPECT_TRUE(session_
.IsClosedStream(i
)) << " stream id: " << i
;
103 void CloseStream(QuicStreamId id
) {
104 session_
.CloseStream(id
);
105 closed_streams_
.insert(id
);
109 MockConnection
* connection_
;
110 TestSession session_
;
111 QuicConnectionVisitorInterface
* visitor_
;
112 hash_map
<QuicStreamId
, ReliableQuicStream
*>* streams_
;
113 set
<QuicStreamId
> closed_streams_
;
116 TEST_F(QuicSessionTest
, IsCryptoHandshakeComplete
) {
117 EXPECT_FALSE(session_
.IsCryptoHandshakeComplete());
118 CryptoHandshakeMessage message
;
119 session_
.crypto_stream_
.OnHandshakeMessage(message
);
120 EXPECT_TRUE(session_
.IsCryptoHandshakeComplete());
123 TEST_F(QuicSessionTest
, IsClosedStreamDefault
) {
124 // Ensure that no streams are initially closed.
125 for (int i
= kCryptoStreamId
; i
< 100; i
++) {
126 EXPECT_FALSE(session_
.IsClosedStream(i
));
130 TEST_F(QuicSessionTest
, IsClosedStreamLocallyCreated
) {
131 TestStream
* stream2
= session_
.CreateOutgoingReliableStream();
132 EXPECT_EQ(2u, stream2
->id());
133 TestStream
* stream4
= session_
.CreateOutgoingReliableStream();
134 EXPECT_EQ(4u, stream4
->id());
136 CheckClosedStreams();
138 CheckClosedStreams();
140 CheckClosedStreams();
143 TEST_F(QuicSessionTest
, IsClosedStreamPeerCreated
) {
144 session_
.GetIncomingReliableStream(3);
145 session_
.GetIncomingReliableStream(5);
147 CheckClosedStreams();
149 CheckClosedStreams();
151 // Create stream id 9, and implicitly 7
152 session_
.GetIncomingReliableStream(9);
153 CheckClosedStreams();
154 // Close 9, but make sure 7 is still not closed
156 CheckClosedStreams();
159 TEST_F(QuicSessionTest
, StreamIdTooLarge
) {
160 session_
.GetIncomingReliableStream(3);
161 EXPECT_CALL(*connection_
, SendConnectionClose(QUIC_INVALID_STREAM_ID
));
162 session_
.GetIncomingReliableStream(105);
165 TEST_F(QuicSessionTest
, OnCanWrite
) {
166 TestStream
* stream2
= session_
.CreateOutgoingReliableStream();
167 TestStream
* stream4
= session_
.CreateOutgoingReliableStream();
168 TestStream
* stream6
= session_
.CreateOutgoingReliableStream();
170 session_
.MarkWriteBlocked(2);
171 session_
.MarkWriteBlocked(6);
172 session_
.MarkWriteBlocked(4);
175 EXPECT_CALL(*stream2
, OnCanWrite()).WillOnce(
176 // Reregister, to test the loop limit.
177 testing::InvokeWithoutArgs(&session_
, &TestSession::MarkTwoWriteBlocked
));
178 EXPECT_CALL(*stream6
, OnCanWrite());
179 EXPECT_CALL(*stream4
, OnCanWrite());
181 EXPECT_FALSE(session_
.OnCanWrite());
184 TEST_F(QuicSessionTest
, OnCanWriteWithClosedStream
) {
185 TestStream
* stream2
= session_
.CreateOutgoingReliableStream();
186 TestStream
* stream4
= session_
.CreateOutgoingReliableStream();
187 session_
.CreateOutgoingReliableStream(); // stream 6
189 session_
.MarkWriteBlocked(2);
190 session_
.MarkWriteBlocked(6);
191 session_
.MarkWriteBlocked(4);
195 EXPECT_CALL(*stream2
, OnCanWrite());
196 EXPECT_CALL(*stream4
, OnCanWrite());
197 EXPECT_TRUE(session_
.OnCanWrite());