summaryrefslogtreecommitdiffstats
path: root/chromium/net/spdy/spdy_write_queue_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/spdy/spdy_write_queue_unittest.cc')
-rw-r--r--chromium/net/spdy/spdy_write_queue_unittest.cc124
1 files changed, 124 insertions, 0 deletions
diff --git a/chromium/net/spdy/spdy_write_queue_unittest.cc b/chromium/net/spdy/spdy_write_queue_unittest.cc
index 6d6cb3cd3b5..2ab415acde5 100644
--- a/chromium/net/spdy/spdy_write_queue_unittest.cc
+++ b/chromium/net/spdy/spdy_write_queue_unittest.cc
@@ -23,6 +23,11 @@ namespace net {
namespace {
+using std::string;
+
+const char kOriginal[] = "original";
+const char kRequeued[] = "requeued";
+
class SpdyWriteQueueTest : public ::testing::Test {};
// Makes a SpdyFrameProducer producing a frame with the data in the
@@ -44,6 +49,35 @@ 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(kRequeued, arraysize(kRequeued)))));
+
+ 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 +281,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(kRequeued), 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(kRequeued), 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(kRequeued), 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(kRequeued), producer->ProduceBuffer()->GetRemainingData());
+}
+
} // namespace
} // namespace net