1 /*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "rtc_base/memory/fifo_buffer.h"
12
13 #include <string.h>
14
15 #include "test/gtest.h"
16
17 namespace rtc {
18
TEST(FifoBufferTest,TestAll)19 TEST(FifoBufferTest, TestAll) {
20 const size_t kSize = 16;
21 const char in[kSize * 2 + 1] = "0123456789ABCDEFGHIJKLMNOPQRSTUV";
22 char out[kSize * 2];
23 void* p;
24 const void* q;
25 size_t bytes;
26 FifoBuffer buf(kSize);
27
28 // Test assumptions about base state
29 EXPECT_EQ(SS_OPEN, buf.GetState());
30 EXPECT_EQ(SR_BLOCK, buf.Read(out, kSize, &bytes, nullptr));
31 EXPECT_TRUE(nullptr != buf.GetWriteBuffer(&bytes));
32 EXPECT_EQ(kSize, bytes);
33 buf.ConsumeWriteBuffer(0);
34
35 // Try a full write
36 EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize, &bytes, nullptr));
37 EXPECT_EQ(kSize, bytes);
38
39 // Try a write that should block
40 EXPECT_EQ(SR_BLOCK, buf.Write(in, kSize, &bytes, nullptr));
41
42 // Try a full read
43 EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize, &bytes, nullptr));
44 EXPECT_EQ(kSize, bytes);
45 EXPECT_EQ(0, memcmp(in, out, kSize));
46
47 // Try a read that should block
48 EXPECT_EQ(SR_BLOCK, buf.Read(out, kSize, &bytes, nullptr));
49
50 // Try a too-big write
51 EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize * 2, &bytes, nullptr));
52 EXPECT_EQ(bytes, kSize);
53
54 // Try a too-big read
55 EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize * 2, &bytes, nullptr));
56 EXPECT_EQ(kSize, bytes);
57 EXPECT_EQ(0, memcmp(in, out, kSize));
58
59 // Try some small writes and reads
60 EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize / 2, &bytes, nullptr));
61 EXPECT_EQ(kSize / 2, bytes);
62 EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize / 2, &bytes, nullptr));
63 EXPECT_EQ(kSize / 2, bytes);
64 EXPECT_EQ(0, memcmp(in, out, kSize / 2));
65 EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize / 2, &bytes, nullptr));
66 EXPECT_EQ(kSize / 2, bytes);
67 EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize / 2, &bytes, nullptr));
68 EXPECT_EQ(kSize / 2, bytes);
69 EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize / 2, &bytes, nullptr));
70 EXPECT_EQ(kSize / 2, bytes);
71 EXPECT_EQ(0, memcmp(in, out, kSize / 2));
72 EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize / 2, &bytes, nullptr));
73 EXPECT_EQ(kSize / 2, bytes);
74 EXPECT_EQ(0, memcmp(in, out, kSize / 2));
75
76 // Try wraparound reads and writes in the following pattern
77 // WWWWWWWWWWWW.... 0123456789AB....
78 // RRRRRRRRXXXX.... ........89AB....
79 // WWWW....XXXXWWWW 4567....89AB0123
80 // XXXX....RRRRXXXX 4567........0123
81 // XXXXWWWWWWWWXXXX 4567012345670123
82 // RRRRXXXXXXXXRRRR ....01234567....
83 // ....RRRRRRRR.... ................
84 EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize * 3 / 4, &bytes, nullptr));
85 EXPECT_EQ(kSize * 3 / 4, bytes);
86 EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize / 2, &bytes, nullptr));
87 EXPECT_EQ(kSize / 2, bytes);
88 EXPECT_EQ(0, memcmp(in, out, kSize / 2));
89 EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize / 2, &bytes, nullptr));
90 EXPECT_EQ(kSize / 2, bytes);
91 EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize / 4, &bytes, nullptr));
92 EXPECT_EQ(kSize / 4, bytes);
93 EXPECT_EQ(0, memcmp(in + kSize / 2, out, kSize / 4));
94 EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize / 2, &bytes, nullptr));
95 EXPECT_EQ(kSize / 2, bytes);
96 EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize / 2, &bytes, nullptr));
97 EXPECT_EQ(kSize / 2, bytes);
98 EXPECT_EQ(0, memcmp(in, out, kSize / 2));
99 EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize / 2, &bytes, nullptr));
100 EXPECT_EQ(kSize / 2, bytes);
101 EXPECT_EQ(0, memcmp(in, out, kSize / 2));
102
103 // Use GetWriteBuffer to reset the read_position for the next tests
104 buf.GetWriteBuffer(&bytes);
105 buf.ConsumeWriteBuffer(0);
106
107 // Try using GetReadData to do a full read
108 EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize, &bytes, nullptr));
109 q = buf.GetReadData(&bytes);
110 EXPECT_TRUE(nullptr != q);
111 EXPECT_EQ(kSize, bytes);
112 EXPECT_EQ(0, memcmp(q, in, kSize));
113 buf.ConsumeReadData(kSize);
114 EXPECT_EQ(SR_BLOCK, buf.Read(out, kSize, &bytes, nullptr));
115
116 // Try using GetReadData to do some small reads
117 EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize, &bytes, nullptr));
118 q = buf.GetReadData(&bytes);
119 EXPECT_TRUE(nullptr != q);
120 EXPECT_EQ(kSize, bytes);
121 EXPECT_EQ(0, memcmp(q, in, kSize / 2));
122 buf.ConsumeReadData(kSize / 2);
123 q = buf.GetReadData(&bytes);
124 EXPECT_TRUE(nullptr != q);
125 EXPECT_EQ(kSize / 2, bytes);
126 EXPECT_EQ(0, memcmp(q, in + kSize / 2, kSize / 2));
127 buf.ConsumeReadData(kSize / 2);
128 EXPECT_EQ(SR_BLOCK, buf.Read(out, kSize, &bytes, nullptr));
129
130 // Try using GetReadData in a wraparound case
131 // WWWWWWWWWWWWWWWW 0123456789ABCDEF
132 // RRRRRRRRRRRRXXXX ............CDEF
133 // WWWWWWWW....XXXX 01234567....CDEF
134 // ............RRRR 01234567........
135 // RRRRRRRR........ ................
136 EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize, &bytes, nullptr));
137 EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize * 3 / 4, &bytes, nullptr));
138 EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize / 2, &bytes, nullptr));
139 q = buf.GetReadData(&bytes);
140 EXPECT_TRUE(nullptr != q);
141 EXPECT_EQ(kSize / 4, bytes);
142 EXPECT_EQ(0, memcmp(q, in + kSize * 3 / 4, kSize / 4));
143 buf.ConsumeReadData(kSize / 4);
144 q = buf.GetReadData(&bytes);
145 EXPECT_TRUE(nullptr != q);
146 EXPECT_EQ(kSize / 2, bytes);
147 EXPECT_EQ(0, memcmp(q, in, kSize / 2));
148 buf.ConsumeReadData(kSize / 2);
149
150 // Use GetWriteBuffer to reset the read_position for the next tests
151 buf.GetWriteBuffer(&bytes);
152 buf.ConsumeWriteBuffer(0);
153
154 // Try using GetWriteBuffer to do a full write
155 p = buf.GetWriteBuffer(&bytes);
156 EXPECT_TRUE(nullptr != p);
157 EXPECT_EQ(kSize, bytes);
158 memcpy(p, in, kSize);
159 buf.ConsumeWriteBuffer(kSize);
160 EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize, &bytes, nullptr));
161 EXPECT_EQ(kSize, bytes);
162 EXPECT_EQ(0, memcmp(in, out, kSize));
163
164 // Try using GetWriteBuffer to do some small writes
165 p = buf.GetWriteBuffer(&bytes);
166 EXPECT_TRUE(nullptr != p);
167 EXPECT_EQ(kSize, bytes);
168 memcpy(p, in, kSize / 2);
169 buf.ConsumeWriteBuffer(kSize / 2);
170 p = buf.GetWriteBuffer(&bytes);
171 EXPECT_TRUE(nullptr != p);
172 EXPECT_EQ(kSize / 2, bytes);
173 memcpy(p, in + kSize / 2, kSize / 2);
174 buf.ConsumeWriteBuffer(kSize / 2);
175 EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize, &bytes, nullptr));
176 EXPECT_EQ(kSize, bytes);
177 EXPECT_EQ(0, memcmp(in, out, kSize));
178
179 // Try using GetWriteBuffer in a wraparound case
180 // WWWWWWWWWWWW.... 0123456789AB....
181 // RRRRRRRRXXXX.... ........89AB....
182 // ........XXXXWWWW ........89AB0123
183 // WWWW....XXXXXXXX 4567....89AB0123
184 // RRRR....RRRRRRRR ................
185 EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize * 3 / 4, &bytes, nullptr));
186 EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize / 2, &bytes, nullptr));
187 p = buf.GetWriteBuffer(&bytes);
188 EXPECT_TRUE(nullptr != p);
189 EXPECT_EQ(kSize / 4, bytes);
190 memcpy(p, in, kSize / 4);
191 buf.ConsumeWriteBuffer(kSize / 4);
192 p = buf.GetWriteBuffer(&bytes);
193 EXPECT_TRUE(nullptr != p);
194 EXPECT_EQ(kSize / 2, bytes);
195 memcpy(p, in + kSize / 4, kSize / 4);
196 buf.ConsumeWriteBuffer(kSize / 4);
197 EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize * 3 / 4, &bytes, nullptr));
198 EXPECT_EQ(kSize * 3 / 4, bytes);
199 EXPECT_EQ(0, memcmp(in + kSize / 2, out, kSize / 4));
200 EXPECT_EQ(0, memcmp(in, out + kSize / 4, kSize / 4));
201
202 // Check that the stream is now empty
203 EXPECT_EQ(SR_BLOCK, buf.Read(out, kSize, &bytes, nullptr));
204
205 // Try growing the buffer
206 EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize, &bytes, nullptr));
207 EXPECT_EQ(kSize, bytes);
208 EXPECT_TRUE(buf.SetCapacity(kSize * 2));
209 EXPECT_EQ(SR_SUCCESS, buf.Write(in + kSize, kSize, &bytes, nullptr));
210 EXPECT_EQ(kSize, bytes);
211 EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize * 2, &bytes, nullptr));
212 EXPECT_EQ(kSize * 2, bytes);
213 EXPECT_EQ(0, memcmp(in, out, kSize * 2));
214
215 // Try shrinking the buffer
216 EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize, &bytes, nullptr));
217 EXPECT_EQ(kSize, bytes);
218 EXPECT_TRUE(buf.SetCapacity(kSize));
219 EXPECT_EQ(SR_BLOCK, buf.Write(in, kSize, &bytes, nullptr));
220 EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize, &bytes, nullptr));
221 EXPECT_EQ(kSize, bytes);
222 EXPECT_EQ(0, memcmp(in, out, kSize));
223
224 // Write to the stream, close it, read the remaining bytes
225 EXPECT_EQ(SR_SUCCESS, buf.Write(in, kSize / 2, &bytes, nullptr));
226 buf.Close();
227 EXPECT_EQ(SS_CLOSED, buf.GetState());
228 EXPECT_EQ(SR_EOS, buf.Write(in, kSize / 2, &bytes, nullptr));
229 EXPECT_EQ(SR_SUCCESS, buf.Read(out, kSize / 2, &bytes, nullptr));
230 EXPECT_EQ(0, memcmp(in, out, kSize / 2));
231 EXPECT_EQ(SR_EOS, buf.Read(out, kSize / 2, &bytes, nullptr));
232 }
233
TEST(FifoBufferTest,FullBufferCheck)234 TEST(FifoBufferTest, FullBufferCheck) {
235 FifoBuffer buff(10);
236 buff.ConsumeWriteBuffer(10);
237
238 size_t free;
239 EXPECT_TRUE(buff.GetWriteBuffer(&free) != nullptr);
240 EXPECT_EQ(0U, free);
241 }
242
TEST(FifoBufferTest,WriteOffsetAndReadOffset)243 TEST(FifoBufferTest, WriteOffsetAndReadOffset) {
244 const size_t kSize = 16;
245 const char in[kSize * 2 + 1] = "0123456789ABCDEFGHIJKLMNOPQRSTUV";
246 char out[kSize * 2];
247 FifoBuffer buf(kSize);
248
249 // Write 14 bytes.
250 EXPECT_EQ(SR_SUCCESS, buf.Write(in, 14, nullptr, nullptr));
251
252 // Make sure data is in |buf|.
253 size_t buffered;
254 EXPECT_TRUE(buf.GetBuffered(&buffered));
255 EXPECT_EQ(14u, buffered);
256
257 // Read 10 bytes.
258 buf.ConsumeReadData(10);
259
260 // There should be now 12 bytes of available space.
261 size_t remaining;
262 EXPECT_TRUE(buf.GetWriteRemaining(&remaining));
263 EXPECT_EQ(12u, remaining);
264
265 // Write at offset 12, this should fail.
266 EXPECT_EQ(SR_BLOCK, buf.WriteOffset(in, 10, 12, nullptr));
267
268 // Write 8 bytes at offset 4, this wraps around the buffer.
269 EXPECT_EQ(SR_SUCCESS, buf.WriteOffset(in, 8, 4, nullptr));
270
271 // Number of available space remains the same until we call
272 // ConsumeWriteBuffer().
273 EXPECT_TRUE(buf.GetWriteRemaining(&remaining));
274 EXPECT_EQ(12u, remaining);
275 buf.ConsumeWriteBuffer(12);
276
277 // There's 4 bytes bypassed and 4 bytes no read so skip them and verify the
278 // 8 bytes written.
279 size_t read;
280 EXPECT_EQ(SR_SUCCESS, buf.ReadOffset(out, 8, 8, &read));
281 EXPECT_EQ(8u, read);
282 EXPECT_EQ(0, memcmp(out, in, 8));
283
284 // There should still be 16 bytes available for reading.
285 EXPECT_TRUE(buf.GetBuffered(&buffered));
286 EXPECT_EQ(16u, buffered);
287
288 // Read at offset 16, this should fail since we don't have that much data.
289 EXPECT_EQ(SR_BLOCK, buf.ReadOffset(out, 10, 16, nullptr));
290 }
291
292 } // namespace rtc
293