1 // Copyright 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.
4
5 // The test buffer data is 52 bytes, wrap position is set to 20 (this is
6 // arbitrarily chosen). The total buffer size is allocated dynamically based on
7 // the actual header size. This gives:
8 // Header of some size, non-wrapping part 20 bytes, wrapping part 32 bytes.
9 // As input data, a 14 byte array is used and repeatedly written. It's chosen
10 // not to be an integer factor smaller than the wrapping part. This ensures that
11 // the wrapped data isn't repeated at the same position.
12 // Note that desipte the number of wraps (if one or more), the reference output
13 // data is the same since the offset at each wrap is always the same.
14
15 #include "base/memory/scoped_ptr.h"
16 #include "chrome/common/partial_circular_buffer.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 const uint32 kWrapPosition = 20;
20 const uint8 kInputData[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
21 const uint8 kOutputRefDataWrap[] =
22 // The 20 bytes in the non-wrapping part.
23 {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 1, 2, 3, 4, 5, 6,
24 // The 32 bytes in wrapping part.
25 11, 12, 13, 14,
26 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
27 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
28
29 class PartialCircularBufferTest : public testing::Test {
30 public:
PartialCircularBufferTest()31 PartialCircularBufferTest() {
32 PartialCircularBuffer::BufferData test_struct;
33 buffer_header_size_ =
34 &test_struct.data[0] - reinterpret_cast<uint8*>(&test_struct);
35
36 buffer_.reset(new uint8[buffer_header_size_ + sizeof(kOutputRefDataWrap)]);
37 }
38
InitWriteBuffer(bool append)39 void InitWriteBuffer(bool append) {
40 pcb_write_.reset(new PartialCircularBuffer(
41 buffer_.get(),
42 buffer_header_size_ + sizeof(kOutputRefDataWrap),
43 kWrapPosition,
44 append));
45 }
46
WriteToBuffer(int num)47 void WriteToBuffer(int num) {
48 for (int i = 0; i < num; ++i)
49 pcb_write_->Write(kInputData, sizeof(kInputData));
50 }
51
InitReadBuffer()52 void InitReadBuffer() {
53 pcb_read_.reset(new PartialCircularBuffer(
54 buffer_.get(), buffer_header_size_ + sizeof(kOutputRefDataWrap)));
55 }
56
57 protected:
58 scoped_ptr<PartialCircularBuffer> pcb_write_;
59 scoped_ptr<PartialCircularBuffer> pcb_read_;
60 scoped_ptr<uint8[]> buffer_;
61 uint32 buffer_header_size_;
62
63 DISALLOW_COPY_AND_ASSIGN(PartialCircularBufferTest);
64 };
65
TEST_F(PartialCircularBufferTest,NoWrapBeginningPartOnly)66 TEST_F(PartialCircularBufferTest, NoWrapBeginningPartOnly) {
67 InitWriteBuffer(false);
68 WriteToBuffer(1);
69 InitReadBuffer();
70
71 uint8 output_data[sizeof(kInputData)] = {0};
72 EXPECT_EQ(sizeof(output_data),
73 pcb_read_->Read(output_data, sizeof(output_data)));
74
75 EXPECT_EQ(0, memcmp(kInputData, output_data, sizeof(kInputData)));
76
77 EXPECT_EQ(0u, pcb_read_->Read(output_data, sizeof(output_data)));
78 }
79
TEST_F(PartialCircularBufferTest,NoWrapBeginningAndEndParts)80 TEST_F(PartialCircularBufferTest, NoWrapBeginningAndEndParts) {
81 InitWriteBuffer(false);
82 WriteToBuffer(2);
83 InitReadBuffer();
84
85 uint8 output_data[2 * sizeof(kInputData)] = {0};
86 EXPECT_EQ(sizeof(output_data),
87 pcb_read_->Read(output_data, sizeof(output_data)));
88
89 const uint8 output_ref_data[2 * sizeof(kInputData)] =
90 {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
91 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
92 EXPECT_EQ(0, memcmp(output_ref_data, output_data, sizeof(output_data)));
93
94 EXPECT_EQ(0u, pcb_read_->Read(output_data, sizeof(output_data)));
95 }
96
TEST_F(PartialCircularBufferTest,WrapOnce)97 TEST_F(PartialCircularBufferTest, WrapOnce) {
98 InitWriteBuffer(false);
99 WriteToBuffer(4);
100 InitReadBuffer();
101
102 uint8 output_data[sizeof(kOutputRefDataWrap)] = {0};
103 EXPECT_EQ(sizeof(output_data),
104 pcb_read_->Read(output_data, sizeof(output_data)));
105
106 EXPECT_EQ(0, memcmp(kOutputRefDataWrap, output_data, sizeof(output_data)));
107
108 EXPECT_EQ(0u, pcb_read_->Read(output_data, sizeof(output_data)));
109 }
110
TEST_F(PartialCircularBufferTest,WrapTwice)111 TEST_F(PartialCircularBufferTest, WrapTwice) {
112 InitWriteBuffer(false);
113 WriteToBuffer(7);
114 InitReadBuffer();
115
116 uint8 output_data[sizeof(kOutputRefDataWrap)] = {0};
117 EXPECT_EQ(sizeof(output_data),
118 pcb_read_->Read(output_data, sizeof(output_data)));
119
120 EXPECT_EQ(0, memcmp(kOutputRefDataWrap, output_data, sizeof(output_data)));
121
122 EXPECT_EQ(0u, pcb_read_->Read(output_data, sizeof(output_data)));
123 }
124
TEST_F(PartialCircularBufferTest,WrapOnceSmallerOutputBuffer)125 TEST_F(PartialCircularBufferTest, WrapOnceSmallerOutputBuffer) {
126 InitWriteBuffer(false);
127 WriteToBuffer(4);
128 InitReadBuffer();
129
130 uint8 output_data[sizeof(kOutputRefDataWrap)] = {0};
131 const uint32 size_per_read = 16;
132 uint32 read = 0;
133 for (; read + size_per_read <= sizeof(output_data); read += size_per_read) {
134 EXPECT_EQ(size_per_read,
135 pcb_read_->Read(output_data + read, size_per_read));
136 }
137 EXPECT_EQ(sizeof(output_data) - read,
138 pcb_read_->Read(output_data + read, size_per_read));
139
140 EXPECT_EQ(0, memcmp(kOutputRefDataWrap, output_data, sizeof(output_data)));
141
142 EXPECT_EQ(0u, pcb_read_->Read(output_data, sizeof(output_data)));
143 }
144
TEST_F(PartialCircularBufferTest,WrapOnceWithAppend)145 TEST_F(PartialCircularBufferTest, WrapOnceWithAppend) {
146 InitWriteBuffer(false);
147 WriteToBuffer(2);
148 InitWriteBuffer(true);
149 WriteToBuffer(2);
150 InitReadBuffer();
151
152 uint8 output_data[sizeof(kOutputRefDataWrap)] = {0};
153 EXPECT_EQ(sizeof(output_data),
154 pcb_read_->Read(output_data, sizeof(output_data)));
155
156 EXPECT_EQ(0, memcmp(kOutputRefDataWrap, output_data, sizeof(output_data)));
157
158 EXPECT_EQ(0u, pcb_read_->Read(output_data, sizeof(output_data)));
159 }
160
TEST_F(PartialCircularBufferTest,WrapTwiceWithAppend)161 TEST_F(PartialCircularBufferTest, WrapTwiceWithAppend) {
162 InitWriteBuffer(false);
163 WriteToBuffer(4);
164 InitWriteBuffer(true);
165 WriteToBuffer(3);
166 InitReadBuffer();
167
168 uint8 output_data[sizeof(kOutputRefDataWrap)] = {0};
169 EXPECT_EQ(sizeof(output_data),
170 pcb_read_->Read(output_data, sizeof(output_data)));
171
172 EXPECT_EQ(0, memcmp(kOutputRefDataWrap, output_data, sizeof(output_data)));
173
174 EXPECT_EQ(0u, pcb_read_->Read(output_data, sizeof(output_data)));
175 }
176
TEST_F(PartialCircularBufferTest,WrapOnceThenOverwriteWithNoWrap)177 TEST_F(PartialCircularBufferTest, WrapOnceThenOverwriteWithNoWrap) {
178 InitWriteBuffer(false);
179 WriteToBuffer(4);
180 InitWriteBuffer(false);
181 WriteToBuffer(1);
182 InitReadBuffer();
183
184 uint8 output_data[sizeof(kInputData)] = {0};
185 EXPECT_EQ(sizeof(output_data),
186 pcb_read_->Read(output_data, sizeof(output_data)));
187
188 EXPECT_EQ(0, memcmp(kInputData, output_data, sizeof(kInputData)));
189
190 EXPECT_EQ(0u, pcb_read_->Read(output_data, sizeof(output_data)));
191 }
192