blob: 6fa1076de9af232295dfa1255f238ab36275adc2 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2017 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/quartc/quartc_stream.h"
6
7#include <memory>
8#include <type_traits>
9#include <utility>
10
11#include "testing/gmock/include/gmock/gmock.h"
12#include "testing/gtest/include/gtest/gtest.h"
13#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
14#include "net/third_party/quiche/src/quic/core/frames/quic_stream_frame.h"
15#include "net/third_party/quiche/src/quic/core/quic_alarm_factory.h"
16#include "net/third_party/quiche/src/quic/core/quic_buffer_allocator.h"
17#include "net/third_party/quiche/src/quic/core/quic_config.h"
18#include "net/third_party/quiche/src/quic/core/quic_connection.h"
19#include "net/third_party/quiche/src/quic/core/quic_crypto_stream.h"
20#include "net/third_party/quiche/src/quic/core/quic_data_writer.h"
21#include "net/third_party/quiche/src/quic/core/quic_error_codes.h"
22#include "net/third_party/quiche/src/quic/core/quic_packet_writer.h"
23#include "net/third_party/quiche/src/quic/core/quic_session.h"
24#include "net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator.h"
25#include "net/third_party/quiche/src/quic/core/quic_time.h"
26#include "net/third_party/quiche/src/quic/core/quic_types.h"
27#include "net/third_party/quiche/src/quic/core/quic_utils.h"
28#include "net/third_party/quiche/src/quic/core/quic_versions.h"
29#include "net/third_party/quiche/src/quic/core/quic_write_blocked_list.h"
30#include "net/third_party/quiche/src/quic/platform/api/quic_clock.h"
31#include "net/third_party/quiche/src/quic/platform/api/quic_endian.h"
32#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
33#include "net/third_party/quiche/src/quic/platform/api/quic_ip_address.h"
34#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
35#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
36#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
37#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
38#include "net/third_party/quiche/src/quic/platform/api/quic_test_mem_slice_vector.h"
39#include "net/third_party/quiche/src/quic/quartc/quartc_factory.h"
40#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
41#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
42#include "net/third_party/quiche/src/spdy/core/spdy_protocol.h"
43
44namespace quic {
45
46namespace {
47
48static const QuicStreamId kStreamId = 5;
49
50// MockQuicSession that does not create streams and writes data from
51// QuicStream to a string.
52class MockQuicSession : public QuicSession {
53 public:
54 MockQuicSession(QuicConnection* connection,
55 const QuicConfig& config,
vasilvvc48c8712019-03-11 13:38:16 -070056 std::string* write_buffer)
QUICHE teama6ef0a62019-03-07 20:34:33 -050057 : QuicSession(connection,
58 nullptr /*visitor*/,
59 config,
60 CurrentSupportedVersions()),
61 write_buffer_(write_buffer) {}
62
63 ~MockQuicSession() override {}
64
65 // Writes outgoing data from QuicStream to a string.
66 QuicConsumedData WritevData(QuicStream* stream,
67 QuicStreamId id,
68 size_t write_length,
69 QuicStreamOffset offset,
70 StreamSendingState state) override {
71 if (!writable_) {
72 return QuicConsumedData(0, false);
73 }
74
75 // WritevData does not pass down a iovec, data is saved in stream before
76 // data is consumed. Retrieve data from stream.
77 char* buf = new char[write_length];
78 QuicDataWriter writer(write_length, buf, NETWORK_BYTE_ORDER);
79 if (write_length > 0) {
80 stream->WriteStreamData(offset, write_length, &writer);
81 }
82 write_buffer_->append(buf, write_length);
83 delete[] buf;
84 return QuicConsumedData(write_length, state != StreamSendingState::NO_FIN);
85 }
86
87 QuartcStream* CreateIncomingStream(QuicStreamId id) override {
88 return nullptr;
89 }
90
91 QuartcStream* CreateIncomingStream(PendingStream pending) override {
92 return nullptr;
93 }
94
95 const QuicCryptoStream* GetCryptoStream() const override { return nullptr; }
96 QuicCryptoStream* GetMutableCryptoStream() override { return nullptr; }
97 bool ShouldKeepConnectionAlive() const override {
98 return GetNumOpenDynamicStreams() > 0;
99 }
100
101 // Called by QuicStream when they want to close stream.
102 void SendRstStream(QuicStreamId id,
103 QuicRstStreamErrorCode error,
104 QuicStreamOffset bytes_written) override {}
105
106 // Sets whether data is written to buffer, or else if this is write blocked.
107 void set_writable(bool writable) { writable_ = writable; }
108
109 // Tracks whether the stream is write blocked and its priority.
110 void RegisterReliableStream(QuicStreamId stream_id,
111 spdy::SpdyPriority priority) {
112 write_blocked_streams()->RegisterStream(stream_id,
113 /*is_static_stream=*/false,
114 priority);
115 }
116
117 // The session take ownership of the stream.
118 void ActivateReliableStream(std::unique_ptr<QuicStream> stream) {
119 ActivateStream(std::move(stream));
120 }
121
122 private:
123 // Stores written data from ReliableQuicStreamAdapter.
vasilvvc48c8712019-03-11 13:38:16 -0700124 std::string* write_buffer_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500125 // Whether data is written to write_buffer_.
126 bool writable_ = true;
127};
128
129// Packet writer that does nothing. This is required for QuicConnection but
130// isn't used for writing data.
131class DummyPacketWriter : public QuicPacketWriter {
132 public:
133 DummyPacketWriter() {}
134
135 // QuicPacketWriter overrides.
136 WriteResult WritePacket(const char* buffer,
137 size_t buf_len,
138 const QuicIpAddress& self_address,
139 const QuicSocketAddress& peer_address,
140 PerPacketOptions* options) override {
141 return WriteResult(WRITE_STATUS_ERROR, 0);
142 }
143
144 bool IsWriteBlocked() const override { return false; }
145
146 void SetWritable() override {}
147
148 QuicByteCount GetMaxPacketSize(
149 const QuicSocketAddress& peer_address) const override {
150 return 0;
151 }
152
153 bool SupportsReleaseTime() const override { return false; }
154
155 bool IsBatchMode() const override { return false; }
156
157 char* GetNextWriteLocation(const QuicIpAddress& self_address,
158 const QuicSocketAddress& peer_address) override {
159 return nullptr;
160 }
161
162 WriteResult Flush() override { return WriteResult(WRITE_STATUS_OK, 0); }
163};
164
165class MockQuartcStreamDelegate : public QuartcStream::Delegate {
166 public:
vasilvvc48c8712019-03-11 13:38:16 -0700167 MockQuartcStreamDelegate(QuicStreamId id, std::string* read_buffer)
QUICHE teama6ef0a62019-03-07 20:34:33 -0500168 : id_(id), read_buffer_(read_buffer) {}
169
170 void OnBufferChanged(QuartcStream* stream) override {
171 last_bytes_buffered_ = stream->BufferedDataBytes();
172 last_bytes_pending_retransmission_ = stream->BytesPendingRetransmission();
173 }
174
175 size_t OnReceived(QuartcStream* stream,
176 iovec* iov,
177 size_t iov_length,
178 bool fin) override {
179 EXPECT_EQ(id_, stream->id());
180 EXPECT_EQ(stream->ReadOffset(), read_buffer_->size());
181 size_t bytes_consumed = 0;
182 for (size_t i = 0; i < iov_length; ++i) {
183 read_buffer_->append(static_cast<const char*>(iov[i].iov_base),
184 iov[i].iov_len);
185 bytes_consumed += iov[i].iov_len;
186 }
187 return bytes_consumed;
188 }
189
190 void OnClose(QuartcStream* stream) override { closed_ = true; }
191
192 bool closed() { return closed_; }
193
194 QuicByteCount last_bytes_buffered() { return last_bytes_buffered_; }
195 QuicByteCount last_bytes_pending_retransmission() {
196 return last_bytes_pending_retransmission_;
197 }
198
199 protected:
200 QuicStreamId id_;
201 // Data read by the QuicStream.
vasilvvc48c8712019-03-11 13:38:16 -0700202 std::string* read_buffer_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500203 // Whether the QuicStream is closed.
204 bool closed_ = false;
205
206 // Last amount of data observed as buffered.
207 QuicByteCount last_bytes_buffered_ = 0;
208 QuicByteCount last_bytes_pending_retransmission_ = 0;
209};
210
211class QuartcStreamTest : public QuicTest, public QuicConnectionHelperInterface {
212 public:
213 QuartcStreamTest() {
214 // Required to correctly handle StopReading().
215 SetQuicReloadableFlag(quic_stop_reading_when_level_triggered, true);
216 }
217
218 ~QuartcStreamTest() override = default;
219
220 void CreateReliableQuicStream() {
221 // Arbitrary values for QuicConnection.
222 Perspective perspective = Perspective::IS_SERVER;
223 QuicIpAddress ip;
224 ip.FromString("0.0.0.0");
225 bool owns_writer = true;
226
227 alarm_factory_ = QuicMakeUnique<test::MockAlarmFactory>();
228
229 connection_ = QuicMakeUnique<QuicConnection>(
230 QuicUtils::CreateZeroConnectionId(
231 CurrentSupportedVersions()[0].transport_version),
232 QuicSocketAddress(ip, 0), this /*QuicConnectionHelperInterface*/,
233 alarm_factory_.get(), new DummyPacketWriter(), owns_writer, perspective,
234 ParsedVersionOfIndex(CurrentSupportedVersions(), 0));
235 clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
236 session_ = QuicMakeUnique<MockQuicSession>(connection_.get(), QuicConfig(),
237 &write_buffer_);
238 mock_stream_delegate_ =
239 QuicMakeUnique<MockQuartcStreamDelegate>(kStreamId, &read_buffer_);
240 stream_ = new QuartcStream(kStreamId, session_.get());
241 stream_->SetDelegate(mock_stream_delegate_.get());
242 session_->ActivateReliableStream(std::unique_ptr<QuartcStream>(stream_));
243 }
244
245 const QuicClock* GetClock() const override { return &clock_; }
246
247 QuicRandom* GetRandomGenerator() override {
248 return QuicRandom::GetInstance();
249 }
250
251 QuicBufferAllocator* GetStreamSendBufferAllocator() override {
252 return &buffer_allocator_;
253 }
254
255 protected:
256 // The QuicSession will take the ownership.
257 QuartcStream* stream_;
258 std::unique_ptr<MockQuartcStreamDelegate> mock_stream_delegate_;
259 std::unique_ptr<MockQuicSession> session_;
260 // Data written by the ReliableQuicStreamAdapterTest.
vasilvvc48c8712019-03-11 13:38:16 -0700261 std::string write_buffer_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500262 // Data read by the ReliableQuicStreamAdapterTest.
vasilvvc48c8712019-03-11 13:38:16 -0700263 std::string read_buffer_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500264 std::unique_ptr<QuicAlarmFactory> alarm_factory_;
265 std::unique_ptr<QuicConnection> connection_;
266 // Used to implement the QuicConnectionHelperInterface.
267 SimpleBufferAllocator buffer_allocator_;
268 MockClock clock_;
269};
270
271// Write an entire string.
272TEST_F(QuartcStreamTest, WriteDataWhole) {
273 CreateReliableQuicStream();
274 char message[] = "Foo bar";
275 test::QuicTestMemSliceVector data({std::make_pair(message, 7)});
276 stream_->WriteMemSlices(data.span(), /*fin=*/false);
277 EXPECT_EQ("Foo bar", write_buffer_);
278}
279
280// Write part of a string.
281TEST_F(QuartcStreamTest, WriteDataPartial) {
282 CreateReliableQuicStream();
283 char message[] = "Foo bar";
284 test::QuicTestMemSliceVector data({std::make_pair(message, 5)});
285 stream_->WriteMemSlices(data.span(), /*fin=*/false);
286 EXPECT_EQ("Foo b", write_buffer_);
287}
288
289// Test that a QuartcStream buffers writes correctly.
290TEST_F(QuartcStreamTest, StreamBuffersData) {
291 CreateReliableQuicStream();
292
293 char message[] = "Foo bar";
294 test::QuicTestMemSliceVector data({std::make_pair(message, 7)});
295
296 // The stream is not yet writable, so data will be buffered.
297 session_->set_writable(false);
298 stream_->WriteMemSlices(data.span(), /*fin=*/false);
299
300 // Check that data is buffered.
301 EXPECT_TRUE(stream_->HasBufferedData());
302 EXPECT_EQ(7u, stream_->BufferedDataBytes());
303
304 // Check that the stream told its delegate about the buffer change.
305 EXPECT_EQ(7u, mock_stream_delegate_->last_bytes_buffered());
306
307 // Check that none of the data was written yet.
308 // Note that |write_buffer_| actually holds data written by the QuicSession
309 // (not data buffered by the stream).
310 EXPECT_EQ(0ul, write_buffer_.size());
311
312 char message1[] = "xyzzy";
313 test::QuicTestMemSliceVector data1({std::make_pair(message1, 5)});
314
315 // More writes go into the buffer.
316 stream_->WriteMemSlices(data1.span(), /*fin=*/false);
317
318 EXPECT_TRUE(stream_->HasBufferedData());
319 EXPECT_EQ(12u, stream_->BufferedDataBytes());
320 EXPECT_EQ(12u, mock_stream_delegate_->last_bytes_buffered());
321 EXPECT_EQ(0ul, write_buffer_.size());
322
323 // The stream becomes writable, so it sends the buffered data.
324 session_->set_writable(true);
325 stream_->OnCanWrite();
326
327 EXPECT_FALSE(stream_->HasBufferedData());
328 EXPECT_EQ(0u, stream_->BufferedDataBytes());
329 EXPECT_EQ(0u, mock_stream_delegate_->last_bytes_buffered());
330 EXPECT_EQ("Foo barxyzzy", write_buffer_);
331}
332
333// Finish writing to a stream.
334// It delivers the fin bit and closes the write-side as soon as possible.
335TEST_F(QuartcStreamTest, FinishWriting) {
336 CreateReliableQuicStream();
337
338 session_->set_writable(false);
339 stream_->FinishWriting();
340 EXPECT_FALSE(stream_->fin_sent());
341
342 // Fin is sent as soon as the stream becomes writable.
343 session_->set_writable(true);
344 stream_->OnCanWrite();
345 EXPECT_TRUE(stream_->fin_sent());
346 EXPECT_TRUE(stream_->write_side_closed());
347}
348
349// Read an entire string.
350TEST_F(QuartcStreamTest, ReadDataWhole) {
351 CreateReliableQuicStream();
352 QuicStreamFrame frame(kStreamId, false, 0, "Hello, World!");
353 stream_->OnStreamFrame(frame);
354
355 EXPECT_EQ("Hello, World!", read_buffer_);
356}
357
358// Read part of a string.
359TEST_F(QuartcStreamTest, ReadDataPartial) {
360 CreateReliableQuicStream();
361 QuicStreamFrame frame(kStreamId, false, 0, "Hello, World!");
362 frame.data_length = 5;
363 stream_->OnStreamFrame(frame);
364
365 EXPECT_EQ("Hello", read_buffer_);
366}
367
368// Streams do not call OnReceived() after StopReading().
369// Note: this is tested here because Quartc relies on this behavior.
370TEST_F(QuartcStreamTest, StopReading) {
371 CreateReliableQuicStream();
372 stream_->StopReading();
373
374 QuicStreamFrame frame(kStreamId, false, 0, "Hello, World!");
375 stream_->OnStreamFrame(frame);
376
377 EXPECT_EQ(0ul, read_buffer_.size());
378
379 QuicStreamFrame frame2(kStreamId, true, 0, "Hello, World!");
380 stream_->OnStreamFrame(frame2);
381
382 EXPECT_EQ(0ul, read_buffer_.size());
383 EXPECT_TRUE(stream_->fin_received());
384}
385
386// Test that closing the stream results in a callback.
387TEST_F(QuartcStreamTest, CloseStream) {
388 CreateReliableQuicStream();
389 EXPECT_FALSE(mock_stream_delegate_->closed());
390 stream_->OnClose();
391 EXPECT_TRUE(mock_stream_delegate_->closed());
392}
393
394// Both sending and receiving fin automatically closes a stream.
395TEST_F(QuartcStreamTest, CloseOnFins) {
396 CreateReliableQuicStream();
397 QuicStreamFrame frame(kStreamId, true, 0, 0);
398 stream_->OnStreamFrame(frame);
399
400 test::QuicTestMemSliceVector data({});
401 stream_->WriteMemSlices(data.span(), /*fin=*/true);
402
403 // Check that the OnClose() callback occurred.
404 EXPECT_TRUE(mock_stream_delegate_->closed());
405}
406
407TEST_F(QuartcStreamTest, TestCancelOnLossDisabled) {
408 CreateReliableQuicStream();
409
410 // This should be the default state.
411 EXPECT_FALSE(stream_->cancel_on_loss());
412
413 char message[] = "Foo bar";
414 test::QuicTestMemSliceVector data({std::make_pair(message, 7)});
415 stream_->WriteMemSlices(data.span(), /*fin=*/false);
416
417 EXPECT_EQ("Foo bar", write_buffer_);
418
419 stream_->OnStreamFrameLost(0, 7, false);
420 stream_->OnCanWrite();
421
422 EXPECT_EQ("Foo barFoo bar", write_buffer_);
423 EXPECT_EQ(stream_->stream_error(), QUIC_STREAM_NO_ERROR);
424}
425
426TEST_F(QuartcStreamTest, TestCancelOnLossEnabled) {
427 CreateReliableQuicStream();
428 stream_->set_cancel_on_loss(true);
429
430 char message[] = "Foo bar";
431 test::QuicTestMemSliceVector data({std::make_pair(message, 7)});
432 stream_->WriteMemSlices(data.span(), /*fin=*/false);
433
434 EXPECT_EQ("Foo bar", write_buffer_);
435
436 stream_->OnStreamFrameLost(0, 7, false);
437 stream_->OnCanWrite();
438
439 EXPECT_EQ("Foo bar", write_buffer_);
440 EXPECT_EQ(stream_->stream_error(), QUIC_STREAM_CANCELLED);
441}
442
443TEST_F(QuartcStreamTest, MaxRetransmissionsAbsent) {
444 CreateReliableQuicStream();
445
446 // This should be the default state.
447 EXPECT_EQ(stream_->max_retransmission_count(),
448 std::numeric_limits<int>::max());
449
450 char message[] = "Foo bar";
451 test::QuicTestMemSliceVector data({std::make_pair(message, 7)});
452 stream_->WriteMemSlices(data.span(), /*fin=*/false);
453
454 EXPECT_EQ("Foo bar", write_buffer_);
455
456 stream_->OnStreamFrameLost(0, 7, false);
457 stream_->OnCanWrite();
458
459 EXPECT_EQ("Foo barFoo bar", write_buffer_);
460 EXPECT_EQ(stream_->stream_error(), QUIC_STREAM_NO_ERROR);
461}
462
463TEST_F(QuartcStreamTest, MaxRetransmissionsSet) {
464 CreateReliableQuicStream();
465 stream_->set_max_retransmission_count(2);
466
467 char message[] = "Foo bar";
468 test::QuicTestMemSliceVector data({std::make_pair(message, 7)});
469 stream_->WriteMemSlices(data.span(), /*fin=*/false);
470
471 EXPECT_EQ("Foo bar", write_buffer_);
472
473 stream_->OnStreamFrameLost(0, 7, false);
474 stream_->OnCanWrite();
475
476 EXPECT_EQ("Foo barFoo bar", write_buffer_);
477
478 stream_->OnStreamFrameLost(0, 7, false);
479 stream_->OnCanWrite();
480
481 EXPECT_EQ("Foo barFoo barFoo bar", write_buffer_);
482
483 stream_->OnStreamFrameLost(0, 7, false);
484 stream_->OnCanWrite();
485
486 EXPECT_EQ("Foo barFoo barFoo bar", write_buffer_);
487 EXPECT_EQ(stream_->stream_error(), QUIC_STREAM_CANCELLED);
488}
489
490TEST_F(QuartcStreamTest, MaxRetransmissionsDisjointFrames) {
491 CreateReliableQuicStream();
492 stream_->set_max_retransmission_count(2);
493
494 char message[] = "Foo bar";
495 test::QuicTestMemSliceVector data({std::make_pair(message, 7)});
496 stream_->WriteMemSlices(data.span(), /*fin=*/false);
497
498 EXPECT_EQ("Foo bar", write_buffer_);
499
500 // Retransmit bytes [0, 3].
501 stream_->OnStreamFrameLost(0, 4, false);
502 stream_->OnCanWrite();
503
504 EXPECT_EQ("Foo barFoo ", write_buffer_);
505
506 // Retransmit bytes [4, 6]. Everything has been retransmitted once.
507 stream_->OnStreamFrameLost(4, 3, false);
508 stream_->OnCanWrite();
509
510 EXPECT_EQ("Foo barFoo bar", write_buffer_);
511
512 // Retransmit bytes [0, 6]. Everything can be retransmitted a second time.
513 stream_->OnStreamFrameLost(0, 7, false);
514 stream_->OnCanWrite();
515
516 EXPECT_EQ("Foo barFoo barFoo bar", write_buffer_);
517}
518
519TEST_F(QuartcStreamTest, MaxRetransmissionsOverlappingFrames) {
520 CreateReliableQuicStream();
521 stream_->set_max_retransmission_count(2);
522
523 char message[] = "Foo bar";
524 test::QuicTestMemSliceVector data({std::make_pair(message, 7)});
525 stream_->WriteMemSlices(data.span(), /*fin=*/false);
526
527 EXPECT_EQ("Foo bar", write_buffer_);
528
529 // Retransmit bytes 0 to 3.
530 stream_->OnStreamFrameLost(0, 4, false);
531 stream_->OnCanWrite();
532
533 EXPECT_EQ("Foo barFoo ", write_buffer_);
534
535 // Retransmit bytes 3 to 6. Byte 3 has been retransmitted twice.
536 stream_->OnStreamFrameLost(3, 4, false);
537 stream_->OnCanWrite();
538
539 EXPECT_EQ("Foo barFoo bar", write_buffer_);
540
541 // Retransmit byte 3 a third time. This should cause cancellation.
542 stream_->OnStreamFrameLost(3, 1, false);
543 stream_->OnCanWrite();
544
545 EXPECT_EQ("Foo barFoo bar", write_buffer_);
546 EXPECT_EQ(stream_->stream_error(), QUIC_STREAM_CANCELLED);
547}
548
549TEST_F(QuartcStreamTest, MaxRetransmissionsWithAckedFrame) {
550 CreateReliableQuicStream();
551 stream_->set_max_retransmission_count(1);
552
553 char message[] = "Foo bar";
554 test::QuicTestMemSliceVector data({std::make_pair(message, 7)});
555 stream_->WriteMemSlices(data.span(), /*fin=*/false);
556
557 EXPECT_EQ("Foo bar", write_buffer_);
558
559 // Retransmit bytes [0, 7).
560 stream_->OnStreamFrameLost(0, 7, false);
561 stream_->OnCanWrite();
562
563 EXPECT_EQ("Foo barFoo bar", write_buffer_);
564
565 // Ack bytes [0, 7). These bytes should be pruned from the data tracked by
566 // the stream.
567 QuicByteCount newly_acked_length = 0;
568 stream_->OnStreamFrameAcked(0, 7, false, QuicTime::Delta::FromMilliseconds(1),
569 &newly_acked_length);
570 EXPECT_EQ(7u, newly_acked_length);
571 stream_->OnCanWrite();
572
573 EXPECT_EQ("Foo barFoo bar", write_buffer_);
574
575 // Retransmit bytes [0, 7) again.
576 // QUIC will never mark frames as lost after they've been acked, but this lets
577 // us test that QuartcStream stopped tracking these bytes after the acked.
578 stream_->OnStreamFrameLost(0, 7, false);
579 stream_->OnCanWrite();
580
581 // QuartcStream should be cancelled, but it stopped tracking the lost bytes
582 // after they were acked, so it's not.
583 EXPECT_EQ(stream_->stream_error(), QUIC_STREAM_NO_ERROR);
584}
585
586TEST_F(QuartcStreamTest, TestBytesPendingRetransmission) {
587 CreateReliableQuicStream();
588 stream_->set_cancel_on_loss(false);
589
590 char message[] = "Foo bar";
591 test::QuicTestMemSliceVector data({std::make_pair(message, 7)});
592 stream_->WriteMemSlices(data.span(), /*fin=*/false);
593
594 EXPECT_EQ("Foo bar", write_buffer_);
595
596 stream_->OnStreamFrameLost(0, 4, false);
597 EXPECT_EQ(stream_->BytesPendingRetransmission(), 4u);
598 EXPECT_EQ(mock_stream_delegate_->last_bytes_pending_retransmission(), 4u);
599
600 stream_->OnStreamFrameLost(4, 3, false);
601 EXPECT_EQ(stream_->BytesPendingRetransmission(), 7u);
602 EXPECT_EQ(mock_stream_delegate_->last_bytes_pending_retransmission(), 7u);
603
604 stream_->OnCanWrite();
605 EXPECT_EQ(stream_->BytesPendingRetransmission(), 0u);
606 EXPECT_EQ(mock_stream_delegate_->last_bytes_pending_retransmission(), 0u);
607
608 EXPECT_EQ("Foo barFoo bar", write_buffer_);
609 EXPECT_EQ(stream_->stream_error(), QUIC_STREAM_NO_ERROR);
610}
611
612TEST_F(QuartcStreamTest, TestBytesPendingRetransmissionWithCancelOnLoss) {
613 CreateReliableQuicStream();
614 stream_->set_cancel_on_loss(true);
615
616 char message[] = "Foo bar";
617 test::QuicTestMemSliceVector data({std::make_pair(message, 7)});
618 stream_->WriteMemSlices(data.span(), /*fin=*/false);
619
620 EXPECT_EQ("Foo bar", write_buffer_);
621
622 stream_->OnStreamFrameLost(0, 4, false);
623 EXPECT_EQ(stream_->BytesPendingRetransmission(), 0u);
624 EXPECT_EQ(mock_stream_delegate_->last_bytes_pending_retransmission(), 0u);
625
626 stream_->OnStreamFrameLost(4, 3, false);
627 EXPECT_EQ(stream_->BytesPendingRetransmission(), 0u);
628 EXPECT_EQ(mock_stream_delegate_->last_bytes_pending_retransmission(), 0u);
629
630 stream_->OnCanWrite();
631 EXPECT_EQ(stream_->BytesPendingRetransmission(), 0u);
632 EXPECT_EQ(mock_stream_delegate_->last_bytes_pending_retransmission(), 0u);
633
634 EXPECT_EQ("Foo bar", write_buffer_);
635 EXPECT_EQ(stream_->stream_error(), QUIC_STREAM_CANCELLED);
636}
637
638} // namespace
639
640} // namespace quic