Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(309)

Unified Diff: net/spdy/spdy_write_queue_unittest.cc

Issue 269423003: Guard SpdyWriteQueue::Enqueue, and test all reentrancy points. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: requed => requeued Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/spdy/spdy_write_queue.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..2ab415acde57a1a4042e2519adafa753cbcff547 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 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
« no previous file with comments | « net/spdy/spdy_write_queue.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698