Chromium Code Reviews| Index: net/spdy/spdy_write_queue_unittest.cc |
| diff --git a/net/spdy/spdy_write_queue_unittest.cc b/net/spdy/spdy_write_queue_unittest.cc |
| index 6d6cb3cd3b57fe0d1ac253f6b5ca570477517260..0ae12a096984d0b01d1ff5d721a352c5bf69807d 100644 |
| --- a/net/spdy/spdy_write_queue_unittest.cc |
| +++ b/net/spdy/spdy_write_queue_unittest.cc |
| @@ -23,6 +23,11 @@ namespace net { |
| namespace { |
| +using std::string; |
| + |
| +const char kOriginal[] = "original"; |
| +const char kRequed[] = "requed"; |
|
willchan no longer on Chromium
2014/05/07 21:27:47
spelling nazi here, requed=>requeued :)
Johnny
2014/05/08 02:49:14
Done.
|
| + |
| class SpdyWriteQueueTest : public ::testing::Test {}; |
| // Makes a SpdyFrameProducer producing a frame with the data in the |
| @@ -44,6 +49,34 @@ scoped_ptr<SpdyBufferProducer> IntToProducer(int i) { |
| return StringToProducer(base::IntToString(i)); |
| } |
| +// Producer whose produced buffer will enqueue yet another buffer into the |
| +// SpdyWriteQueue upon destruction. |
| +class RequeingBufferProducer : public SpdyBufferProducer { |
| + public: |
| + RequeingBufferProducer(SpdyWriteQueue* queue) { |
| + buffer_.reset(new SpdyBuffer(kOriginal, arraysize(kOriginal))); |
| + buffer_->AddConsumeCallback( |
| + base::Bind(RequeingBufferProducer::ConsumeCallback, queue)); |
| + } |
| + |
| + virtual scoped_ptr<SpdyBuffer> ProduceBuffer() OVERRIDE { |
| + return buffer_.Pass(); |
| + } |
| + |
| + static void ConsumeCallback(SpdyWriteQueue* queue, |
| + size_t size, |
| + SpdyBuffer::ConsumeSource source) { |
| + scoped_ptr<SpdyBufferProducer> producer(new SimpleBufferProducer( |
| + scoped_ptr<SpdyBuffer>(new SpdyBuffer(kRequed, arraysize(kRequed))))); |
| + |
| + queue->Enqueue( |
| + MEDIUM, RST_STREAM, producer.Pass(), base::WeakPtr<SpdyStream>()); |
| + } |
| + |
| + private: |
| + scoped_ptr<SpdyBuffer> buffer_; |
| +}; |
| + |
| // Produces a frame with the given producer and returns a copy of its |
| // data as a string. |
| std::string ProducerToString(scoped_ptr<SpdyBufferProducer> producer) { |
| @@ -247,6 +280,96 @@ TEST_F(SpdyWriteQueueTest, Clear) { |
| EXPECT_FALSE(write_queue.Dequeue(&frame_type, &frame_producer, &stream)); |
| } |
| +TEST_F(SpdyWriteQueueTest, RequeingProducerWithoutReentrance) { |
| + SpdyWriteQueue queue; |
| + queue.Enqueue( |
| + DEFAULT_PRIORITY, |
| + SYN_STREAM, |
| + scoped_ptr<SpdyBufferProducer>(new RequeingBufferProducer(&queue)), |
| + base::WeakPtr<SpdyStream>()); |
| + { |
| + SpdyFrameType frame_type; |
| + scoped_ptr<SpdyBufferProducer> producer; |
| + base::WeakPtr<SpdyStream> stream; |
| + |
| + EXPECT_TRUE(queue.Dequeue(&frame_type, &producer, &stream)); |
| + EXPECT_TRUE(queue.IsEmpty()); |
| + EXPECT_EQ(string(kOriginal), producer->ProduceBuffer()->GetRemainingData()); |
| + } |
| + // |producer| was destroyed, and a buffer is re-queued. |
| + EXPECT_FALSE(queue.IsEmpty()); |
| + |
| + SpdyFrameType frame_type; |
| + scoped_ptr<SpdyBufferProducer> producer; |
| + base::WeakPtr<SpdyStream> stream; |
| + |
| + EXPECT_TRUE(queue.Dequeue(&frame_type, &producer, &stream)); |
| + EXPECT_EQ(string(kRequed), producer->ProduceBuffer()->GetRemainingData()); |
| +} |
| + |
| +TEST_F(SpdyWriteQueueTest, ReentranceOnClear) { |
| + SpdyWriteQueue queue; |
| + queue.Enqueue( |
| + DEFAULT_PRIORITY, |
| + SYN_STREAM, |
| + scoped_ptr<SpdyBufferProducer>(new RequeingBufferProducer(&queue)), |
| + base::WeakPtr<SpdyStream>()); |
| + |
| + queue.Clear(); |
| + EXPECT_FALSE(queue.IsEmpty()); |
| + |
| + SpdyFrameType frame_type; |
| + scoped_ptr<SpdyBufferProducer> producer; |
| + base::WeakPtr<SpdyStream> stream; |
| + |
| + EXPECT_TRUE(queue.Dequeue(&frame_type, &producer, &stream)); |
| + EXPECT_EQ(string(kRequed), producer->ProduceBuffer()->GetRemainingData()); |
| +} |
| + |
| +TEST_F(SpdyWriteQueueTest, ReentranceOnRemovePendingWritesAfter) { |
| + scoped_ptr<SpdyStream> stream(MakeTestStream(DEFAULT_PRIORITY)); |
| + stream->set_stream_id(2); |
| + |
| + SpdyWriteQueue queue; |
| + queue.Enqueue( |
| + DEFAULT_PRIORITY, |
| + SYN_STREAM, |
| + scoped_ptr<SpdyBufferProducer>(new RequeingBufferProducer(&queue)), |
| + stream->GetWeakPtr()); |
| + |
| + queue.RemovePendingWritesForStreamsAfter(1); |
| + EXPECT_FALSE(queue.IsEmpty()); |
| + |
| + SpdyFrameType frame_type; |
| + scoped_ptr<SpdyBufferProducer> producer; |
| + base::WeakPtr<SpdyStream> weak_stream; |
| + |
| + EXPECT_TRUE(queue.Dequeue(&frame_type, &producer, &weak_stream)); |
| + EXPECT_EQ(string(kRequed), producer->ProduceBuffer()->GetRemainingData()); |
| +} |
| + |
| +TEST_F(SpdyWriteQueueTest, ReentranceOnRemovePendingWritesForStream) { |
| + scoped_ptr<SpdyStream> stream(MakeTestStream(DEFAULT_PRIORITY)); |
| + stream->set_stream_id(2); |
| + |
| + SpdyWriteQueue queue; |
| + queue.Enqueue( |
| + DEFAULT_PRIORITY, |
| + SYN_STREAM, |
| + scoped_ptr<SpdyBufferProducer>(new RequeingBufferProducer(&queue)), |
| + stream->GetWeakPtr()); |
| + |
| + queue.RemovePendingWritesForStream(stream->GetWeakPtr()); |
| + EXPECT_FALSE(queue.IsEmpty()); |
| + |
| + SpdyFrameType frame_type; |
| + scoped_ptr<SpdyBufferProducer> producer; |
| + base::WeakPtr<SpdyStream> weak_stream; |
| + |
| + EXPECT_TRUE(queue.Dequeue(&frame_type, &producer, &weak_stream)); |
| + EXPECT_EQ(string(kRequed), producer->ProduceBuffer()->GetRemainingData()); |
| +} |
| + |
| } // namespace |
| } // namespace net |