| 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
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..ca028e45fef8476605bd2a5ea5a95fda7d932250
|
| --- /dev/null
|
| +++ b/net/spdy/spdy_write_queue_unittest.cc
|
| @@ -0,0 +1,182 @@
|
| +// Copyright (c) 2013 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "net/spdy/spdy_write_queue.h"
|
| +
|
| +#include <cstddef>
|
| +#include <cstring>
|
| +#include <string>
|
| +
|
| +#include "base/basictypes.h"
|
| +#include "base/memory/ref_counted.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| +#include "base/strings/string_number_conversions.h"
|
| +#include "net/base/net_log.h"
|
| +#include "net/base/request_priority.h"
|
| +#include "net/spdy/spdy_stream.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace net {
|
| +
|
| +namespace {
|
| +
|
| +class SpdyWriteQueueTest : public ::testing::Test {};
|
| +
|
| +// Makes a SpdyFrameProducer producing a frame with the data in the
|
| +// given string.
|
| +scoped_ptr<SpdyFrameProducer> StringToProducer(const std::string& s) {
|
| + scoped_ptr<char[]> data(new char[s.size()]);
|
| + std::memcpy(data.get(), s.data(), s.size());
|
| + return scoped_ptr<SpdyFrameProducer>(
|
| + new SimpleFrameProducer(
|
| + scoped_ptr<SpdyFrame>(
|
| + new SpdyFrame(data.release(), s.size(), true))));
|
| +}
|
| +
|
| +// Makes a SpdyFrameProducer producing a frame with the data in the
|
| +// given int (converted to a string).
|
| +scoped_ptr<SpdyFrameProducer> IntToProducer(int i) {
|
| + return StringToProducer(base::IntToString(i));
|
| +}
|
| +
|
| +// Produces a frame with the given producer and returns a copy of its
|
| +// data as a string.
|
| +std::string ProducerToString(scoped_ptr<SpdyFrameProducer> producer) {
|
| + scoped_ptr<SpdyFrame> frame = producer->ProduceFrame();
|
| + return std::string(frame->data(), frame->size());
|
| +}
|
| +
|
| +// Produces a frame with the given producer and returns a copy of its
|
| +// data as an int (converted from a string).
|
| +int ProducerToInt(scoped_ptr<SpdyFrameProducer> producer) {
|
| + int i = 0;
|
| + EXPECT_TRUE(base::StringToInt(ProducerToString(producer.Pass()), &i));
|
| + return i;
|
| +}
|
| +
|
| +// Makes a SpdyStream with the given priority and a NULL SpdySession
|
| +// -- be careful to not call any functions that expect the session to
|
| +// be there.
|
| +SpdyStream* MakeTestStream(RequestPriority priority) {
|
| + return new SpdyStream(NULL, "", priority, 0, 0, false, BoundNetLog());
|
| +}
|
| +
|
| +// Add some frame producers of different priority. The producers
|
| +// should be dequeued in priority order with their associated stream.
|
| +TEST_F(SpdyWriteQueueTest, DequeuesByPriority) {
|
| + SpdyWriteQueue write_queue;
|
| +
|
| + scoped_ptr<SpdyFrameProducer> producer_low = StringToProducer("LOW");
|
| + scoped_ptr<SpdyFrameProducer> producer_medium = StringToProducer("MEDIUM");
|
| + scoped_ptr<SpdyFrameProducer> producer_highest = StringToProducer("HIGHEST");
|
| +
|
| + // A NULL stream should still work.
|
| + scoped_refptr<SpdyStream> stream_low(NULL);
|
| + scoped_refptr<SpdyStream> stream_medium(MakeTestStream(MEDIUM));
|
| + scoped_refptr<SpdyStream> stream_highest(MakeTestStream(HIGHEST));
|
| +
|
| + write_queue.Enqueue(LOW, producer_low.Pass(), stream_low);
|
| + write_queue.Enqueue(MEDIUM, producer_medium.Pass(), stream_medium);
|
| + write_queue.Enqueue(HIGHEST, producer_highest.Pass(), stream_highest);
|
| +
|
| + scoped_ptr<SpdyFrameProducer> frame_producer;
|
| + scoped_refptr<SpdyStream> stream;
|
| + ASSERT_TRUE(write_queue.Dequeue(&frame_producer, &stream));
|
| + EXPECT_EQ("HIGHEST", ProducerToString(frame_producer.Pass()));
|
| + EXPECT_EQ(stream_highest, stream);
|
| +
|
| + ASSERT_TRUE(write_queue.Dequeue(&frame_producer, &stream));
|
| + EXPECT_EQ("MEDIUM", ProducerToString(frame_producer.Pass()));
|
| + EXPECT_EQ(stream_medium, stream);
|
| +
|
| + ASSERT_TRUE(write_queue.Dequeue(&frame_producer, &stream));
|
| + EXPECT_EQ("LOW", ProducerToString(frame_producer.Pass()));
|
| + EXPECT_EQ(stream_low, stream);
|
| +
|
| + EXPECT_FALSE(write_queue.Dequeue(&frame_producer, &stream));
|
| +}
|
| +
|
| +// Add some frame producers with the same priority. The producers
|
| +// should be dequeued in FIFO order with their associated stream.
|
| +TEST_F(SpdyWriteQueueTest, DequeuesFIFO) {
|
| + SpdyWriteQueue write_queue;
|
| +
|
| + scoped_ptr<SpdyFrameProducer> producer1 = IntToProducer(1);
|
| + scoped_ptr<SpdyFrameProducer> producer2 = IntToProducer(2);
|
| + scoped_ptr<SpdyFrameProducer> producer3 = IntToProducer(3);
|
| +
|
| + scoped_refptr<SpdyStream> stream1(MakeTestStream(DEFAULT_PRIORITY));
|
| + scoped_refptr<SpdyStream> stream2(MakeTestStream(DEFAULT_PRIORITY));
|
| + scoped_refptr<SpdyStream> stream3(MakeTestStream(DEFAULT_PRIORITY));
|
| +
|
| + write_queue.Enqueue(DEFAULT_PRIORITY, producer1.Pass(), stream1);
|
| + write_queue.Enqueue(DEFAULT_PRIORITY, producer2.Pass(), stream2);
|
| + write_queue.Enqueue(DEFAULT_PRIORITY, producer3.Pass(), stream3);
|
| +
|
| + scoped_ptr<SpdyFrameProducer> frame_producer;
|
| + scoped_refptr<SpdyStream> stream;
|
| + ASSERT_TRUE(write_queue.Dequeue(&frame_producer, &stream));
|
| + EXPECT_EQ(1, ProducerToInt(frame_producer.Pass()));
|
| + EXPECT_EQ(stream1, stream);
|
| +
|
| + ASSERT_TRUE(write_queue.Dequeue(&frame_producer, &stream));
|
| + EXPECT_EQ(2, ProducerToInt(frame_producer.Pass()));
|
| + EXPECT_EQ(stream2, stream);
|
| +
|
| + ASSERT_TRUE(write_queue.Dequeue(&frame_producer, &stream));
|
| + EXPECT_EQ(3, ProducerToInt(frame_producer.Pass()));
|
| + EXPECT_EQ(stream3, stream);
|
| +
|
| + EXPECT_FALSE(write_queue.Dequeue(&frame_producer, &stream));
|
| +}
|
| +
|
| +// Enqueue a bunch of writes and then call
|
| +// RemovePendingWritesForStream() on one of the streams. No dequeued
|
| +// write should be for that stream.
|
| +TEST_F(SpdyWriteQueueTest, RemovePendingWritesForStream) {
|
| + SpdyWriteQueue write_queue;
|
| +
|
| + scoped_refptr<SpdyStream> stream1(MakeTestStream(DEFAULT_PRIORITY));
|
| + scoped_refptr<SpdyStream> stream2(MakeTestStream(DEFAULT_PRIORITY));
|
| +
|
| + for (int i = 0; i < 100; ++i) {
|
| + scoped_refptr<SpdyStream> stream = ((i % 3) == 0) ? stream1 : stream2;
|
| + write_queue.Enqueue(DEFAULT_PRIORITY, IntToProducer(i), stream);
|
| + }
|
| +
|
| + write_queue.RemovePendingWritesForStream(stream2);
|
| +
|
| + for (int i = 0; i < 100; i += 3) {
|
| + scoped_ptr<SpdyFrameProducer> frame_producer;
|
| + scoped_refptr<SpdyStream> stream;
|
| + ASSERT_TRUE(write_queue.Dequeue(&frame_producer, &stream));
|
| + EXPECT_EQ(i, ProducerToInt(frame_producer.Pass()));
|
| + EXPECT_EQ(stream1, stream);
|
| + }
|
| +
|
| + scoped_ptr<SpdyFrameProducer> frame_producer;
|
| + scoped_refptr<SpdyStream> stream;
|
| + EXPECT_FALSE(write_queue.Dequeue(&frame_producer, &stream));
|
| +}
|
| +
|
| +// Enqueue a bunch of writes and then call Clear(). The write queue
|
| +// should clean up the memory properly, and Dequeue() should return
|
| +// false.
|
| +TEST_F(SpdyWriteQueueTest, Clear) {
|
| + SpdyWriteQueue write_queue;
|
| +
|
| + for (int i = 0; i < 100; ++i) {
|
| + write_queue.Enqueue(DEFAULT_PRIORITY, IntToProducer(i), NULL);
|
| + }
|
| +
|
| + write_queue.Clear();
|
| +
|
| + scoped_ptr<SpdyFrameProducer> frame_producer;
|
| + scoped_refptr<SpdyStream> stream;
|
| + EXPECT_FALSE(write_queue.Dequeue(&frame_producer, &stream));
|
| +}
|
| +
|
| +}
|
| +
|
| +} // namespace net
|
|
|