1 // Copyright (c) 2013 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.
5 #include "net/spdy/spdy_read_queue.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/stl_util.h"
13 #include "net/spdy/spdy_buffer.h"
14 #include "testing/gtest/include/gtest/gtest.h"
20 const char kData
[] = "SPDY read queue test data.\0Some more data.";
21 const size_t kDataSize
= arraysize(kData
);
23 // Enqueues |data| onto |queue| in chunks of at most |max_buffer_size|
25 void EnqueueString(const std::string
& data
,
26 size_t max_buffer_size
,
27 SpdyReadQueue
* queue
) {
28 ASSERT_GT(data
.size(), 0u);
29 ASSERT_GT(max_buffer_size
, 0u);
30 size_t old_total_size
= queue
->GetTotalSize();
31 for (size_t i
= 0; i
< data
.size();) {
32 size_t buffer_size
= std::min(data
.size() - i
, max_buffer_size
);
34 scoped_ptr
<SpdyBuffer
>(new SpdyBuffer(data
.data() + i
, buffer_size
)));
36 EXPECT_FALSE(queue
->IsEmpty());
37 EXPECT_EQ(old_total_size
+ i
, queue
->GetTotalSize());
41 // Dequeues all bytes in |queue| in chunks of at most
42 // |max_buffer_size| bytes and returns the data as a string.
43 std::string
DrainToString(size_t max_buffer_size
, SpdyReadQueue
* queue
) {
46 // Pad the buffer so we can detect out-of-bound writes.
47 size_t padding
= std::max(static_cast<size_t>(4096), queue
->GetTotalSize());
48 size_t buffer_size_with_padding
= padding
+ max_buffer_size
+ padding
;
49 scoped_ptr
<char[]> buffer(new char[buffer_size_with_padding
]);
50 std::memset(buffer
.get(), 0, buffer_size_with_padding
);
51 char* buffer_data
= buffer
.get() + padding
;
53 while (!queue
->IsEmpty()) {
54 size_t old_total_size
= queue
->GetTotalSize();
55 EXPECT_GT(old_total_size
, 0u);
56 size_t dequeued_bytes
= queue
->Dequeue(buffer_data
, max_buffer_size
);
58 // Make sure |queue| doesn't write past either end of its given
60 for (int i
= 1; i
<= static_cast<int>(padding
); ++i
) {
61 EXPECT_EQ('\0', buffer_data
[-i
]) << -i
;
63 for (size_t i
= 0; i
< padding
; ++i
) {
64 EXPECT_EQ('\0', buffer_data
[max_buffer_size
+ i
]) << i
;
67 data
.append(buffer_data
, dequeued_bytes
);
68 EXPECT_EQ(dequeued_bytes
, std::min(max_buffer_size
, dequeued_bytes
));
69 EXPECT_EQ(queue
->GetTotalSize(), old_total_size
- dequeued_bytes
);
71 EXPECT_TRUE(queue
->IsEmpty());
75 // Enqueue a test string with the given enqueue/dequeue max buffer
77 void RunEnqueueDequeueTest(size_t enqueue_max_buffer_size
,
78 size_t dequeue_max_buffer_size
) {
79 std::string
data(kData
, kDataSize
);
80 SpdyReadQueue read_queue
;
81 EnqueueString(data
, enqueue_max_buffer_size
, &read_queue
);
82 const std::string
& drained_data
=
83 DrainToString(dequeue_max_buffer_size
, &read_queue
);
84 EXPECT_EQ(data
, drained_data
);
87 class SpdyReadQueueTest
: public ::testing::Test
{};
89 // Call RunEnqueueDequeueTest() with various buffer size combinatinos.
91 TEST_F(SpdyReadQueueTest
, LargeEnqueueAndDequeueBuffers
) {
92 RunEnqueueDequeueTest(2 * kDataSize
, 2 * kDataSize
);
95 TEST_F(SpdyReadQueueTest
, OneByteEnqueueAndDequeueBuffers
) {
96 RunEnqueueDequeueTest(1, 1);
99 TEST_F(SpdyReadQueueTest
, CoprimeBufferSizes
) {
100 RunEnqueueDequeueTest(2, 3);
101 RunEnqueueDequeueTest(3, 2);