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 "webrtc/base/fileutils.h" 12#include "webrtc/base/gunit.h" 13#include "webrtc/base/pathutils.h" 14#include "webrtc/base/stream.h" 15 16namespace rtc { 17 18/////////////////////////////////////////////////////////////////////////////// 19// TestStream 20/////////////////////////////////////////////////////////////////////////////// 21 22class TestStream : public StreamInterface { 23 public: 24 TestStream() : pos_(0) { } 25 26 virtual StreamState GetState() const { return SS_OPEN; } 27 virtual StreamResult Read(void* buffer, size_t buffer_len, 28 size_t* read, int* error) { 29 unsigned char* uc_buffer = static_cast<unsigned char*>(buffer); 30 for (size_t i = 0; i < buffer_len; ++i) { 31 uc_buffer[i] = static_cast<unsigned char>(pos_++); 32 } 33 if (read) 34 *read = buffer_len; 35 return SR_SUCCESS; 36 } 37 virtual StreamResult Write(const void* data, size_t data_len, 38 size_t* written, int* error) { 39 if (error) 40 *error = -1; 41 return SR_ERROR; 42 } 43 virtual void Close() { } 44 virtual bool SetPosition(size_t position) { 45 pos_ = position; 46 return true; 47 } 48 virtual bool GetPosition(size_t* position) const { 49 if (position) *position = pos_; 50 return true; 51 } 52 virtual bool GetSize(size_t* size) const { 53 return false; 54 } 55 virtual bool GetAvailable(size_t* size) const { 56 return false; 57 } 58 59 private: 60 size_t pos_; 61}; 62 63bool VerifyTestBuffer(unsigned char* buffer, size_t len, 64 unsigned char value) { 65 bool passed = true; 66 for (size_t i = 0; i < len; ++i) { 67 if (buffer[i] != value++) { 68 passed = false; 69 break; 70 } 71 } 72 // Ensure that we don't pass again without re-writing 73 memset(buffer, 0, len); 74 return passed; 75} 76 77void SeekTest(StreamInterface* stream, const unsigned char value) { 78 size_t bytes; 79 unsigned char buffer[13] = { 0 }; 80 const size_t kBufSize = sizeof(buffer); 81 82 EXPECT_EQ(stream->Read(buffer, kBufSize, &bytes, NULL), SR_SUCCESS); 83 EXPECT_EQ(bytes, kBufSize); 84 EXPECT_TRUE(VerifyTestBuffer(buffer, kBufSize, value)); 85 EXPECT_TRUE(stream->GetPosition(&bytes)); 86 EXPECT_EQ(13U, bytes); 87 88 EXPECT_TRUE(stream->SetPosition(7)); 89 90 EXPECT_EQ(stream->Read(buffer, kBufSize, &bytes, NULL), SR_SUCCESS); 91 EXPECT_EQ(bytes, kBufSize); 92 EXPECT_TRUE(VerifyTestBuffer(buffer, kBufSize, value + 7)); 93 EXPECT_TRUE(stream->GetPosition(&bytes)); 94 EXPECT_EQ(20U, bytes); 95} 96 97TEST(FifoBufferTest, TestAll) { 98 const size_t kSize = 16; 99 const char in[kSize * 2 + 1] = "0123456789ABCDEFGHIJKLMNOPQRSTUV"; 100 char out[kSize * 2]; 101 void* p; 102 const void* q; 103 size_t bytes; 104 FifoBuffer buf(kSize); 105 StreamInterface* stream = &buf; 106 107 // Test assumptions about base state 108 EXPECT_EQ(SS_OPEN, stream->GetState()); 109 EXPECT_EQ(SR_BLOCK, stream->Read(out, kSize, &bytes, NULL)); 110 EXPECT_TRUE(NULL != stream->GetReadData(&bytes)); 111 EXPECT_EQ((size_t)0, bytes); 112 stream->ConsumeReadData(0); 113 EXPECT_TRUE(NULL != stream->GetWriteBuffer(&bytes)); 114 EXPECT_EQ(kSize, bytes); 115 stream->ConsumeWriteBuffer(0); 116 117 // Try a full write 118 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize, &bytes, NULL)); 119 EXPECT_EQ(kSize, bytes); 120 121 // Try a write that should block 122 EXPECT_EQ(SR_BLOCK, stream->Write(in, kSize, &bytes, NULL)); 123 124 // Try a full read 125 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize, &bytes, NULL)); 126 EXPECT_EQ(kSize, bytes); 127 EXPECT_EQ(0, memcmp(in, out, kSize)); 128 129 // Try a read that should block 130 EXPECT_EQ(SR_BLOCK, stream->Read(out, kSize, &bytes, NULL)); 131 132 // Try a too-big write 133 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize * 2, &bytes, NULL)); 134 EXPECT_EQ(bytes, kSize); 135 136 // Try a too-big read 137 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize * 2, &bytes, NULL)); 138 EXPECT_EQ(kSize, bytes); 139 EXPECT_EQ(0, memcmp(in, out, kSize)); 140 141 // Try some small writes and reads 142 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, NULL)); 143 EXPECT_EQ(kSize / 2, bytes); 144 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL)); 145 EXPECT_EQ(kSize / 2, bytes); 146 EXPECT_EQ(0, memcmp(in, out, kSize / 2)); 147 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, NULL)); 148 EXPECT_EQ(kSize / 2, bytes); 149 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, NULL)); 150 EXPECT_EQ(kSize / 2, bytes); 151 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL)); 152 EXPECT_EQ(kSize / 2, bytes); 153 EXPECT_EQ(0, memcmp(in, out, kSize / 2)); 154 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL)); 155 EXPECT_EQ(kSize / 2, bytes); 156 EXPECT_EQ(0, memcmp(in, out, kSize / 2)); 157 158 // Try wraparound reads and writes in the following pattern 159 // WWWWWWWWWWWW.... 0123456789AB.... 160 // RRRRRRRRXXXX.... ........89AB.... 161 // WWWW....XXXXWWWW 4567....89AB0123 162 // XXXX....RRRRXXXX 4567........0123 163 // XXXXWWWWWWWWXXXX 4567012345670123 164 // RRRRXXXXXXXXRRRR ....01234567.... 165 // ....RRRRRRRR.... ................ 166 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize * 3 / 4, &bytes, NULL)); 167 EXPECT_EQ(kSize * 3 / 4, bytes); 168 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL)); 169 EXPECT_EQ(kSize / 2, bytes); 170 EXPECT_EQ(0, memcmp(in, out, kSize / 2)); 171 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, NULL)); 172 EXPECT_EQ(kSize / 2, bytes); 173 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 4, &bytes, NULL)); 174 EXPECT_EQ(kSize / 4 , bytes); 175 EXPECT_EQ(0, memcmp(in + kSize / 2, out, kSize / 4)); 176 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, NULL)); 177 EXPECT_EQ(kSize / 2, bytes); 178 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL)); 179 EXPECT_EQ(kSize / 2 , bytes); 180 EXPECT_EQ(0, memcmp(in, out, kSize / 2)); 181 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL)); 182 EXPECT_EQ(kSize / 2 , bytes); 183 EXPECT_EQ(0, memcmp(in, out, kSize / 2)); 184 185 // Use GetWriteBuffer to reset the read_position for the next tests 186 stream->GetWriteBuffer(&bytes); 187 stream->ConsumeWriteBuffer(0); 188 189 // Try using GetReadData to do a full read 190 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize, &bytes, NULL)); 191 q = stream->GetReadData(&bytes); 192 EXPECT_TRUE(NULL != q); 193 EXPECT_EQ(kSize, bytes); 194 EXPECT_EQ(0, memcmp(q, in, kSize)); 195 stream->ConsumeReadData(kSize); 196 EXPECT_EQ(SR_BLOCK, stream->Read(out, kSize, &bytes, NULL)); 197 198 // Try using GetReadData to do some small reads 199 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize, &bytes, NULL)); 200 q = stream->GetReadData(&bytes); 201 EXPECT_TRUE(NULL != q); 202 EXPECT_EQ(kSize, bytes); 203 EXPECT_EQ(0, memcmp(q, in, kSize / 2)); 204 stream->ConsumeReadData(kSize / 2); 205 q = stream->GetReadData(&bytes); 206 EXPECT_TRUE(NULL != q); 207 EXPECT_EQ(kSize / 2, bytes); 208 EXPECT_EQ(0, memcmp(q, in + kSize / 2, kSize / 2)); 209 stream->ConsumeReadData(kSize / 2); 210 EXPECT_EQ(SR_BLOCK, stream->Read(out, kSize, &bytes, NULL)); 211 212 // Try using GetReadData in a wraparound case 213 // WWWWWWWWWWWWWWWW 0123456789ABCDEF 214 // RRRRRRRRRRRRXXXX ............CDEF 215 // WWWWWWWW....XXXX 01234567....CDEF 216 // ............RRRR 01234567........ 217 // RRRRRRRR........ ................ 218 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize, &bytes, NULL)); 219 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize * 3 / 4, &bytes, NULL)); 220 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, NULL)); 221 q = stream->GetReadData(&bytes); 222 EXPECT_TRUE(NULL != q); 223 EXPECT_EQ(kSize / 4, bytes); 224 EXPECT_EQ(0, memcmp(q, in + kSize * 3 / 4, kSize / 4)); 225 stream->ConsumeReadData(kSize / 4); 226 q = stream->GetReadData(&bytes); 227 EXPECT_TRUE(NULL != q); 228 EXPECT_EQ(kSize / 2, bytes); 229 EXPECT_EQ(0, memcmp(q, in, kSize / 2)); 230 stream->ConsumeReadData(kSize / 2); 231 232 // Use GetWriteBuffer to reset the read_position for the next tests 233 stream->GetWriteBuffer(&bytes); 234 stream->ConsumeWriteBuffer(0); 235 236 // Try using GetWriteBuffer to do a full write 237 p = stream->GetWriteBuffer(&bytes); 238 EXPECT_TRUE(NULL != p); 239 EXPECT_EQ(kSize, bytes); 240 memcpy(p, in, kSize); 241 stream->ConsumeWriteBuffer(kSize); 242 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize, &bytes, NULL)); 243 EXPECT_EQ(kSize, bytes); 244 EXPECT_EQ(0, memcmp(in, out, kSize)); 245 246 // Try using GetWriteBuffer to do some small writes 247 p = stream->GetWriteBuffer(&bytes); 248 EXPECT_TRUE(NULL != p); 249 EXPECT_EQ(kSize, bytes); 250 memcpy(p, in, kSize / 2); 251 stream->ConsumeWriteBuffer(kSize / 2); 252 p = stream->GetWriteBuffer(&bytes); 253 EXPECT_TRUE(NULL != p); 254 EXPECT_EQ(kSize / 2, bytes); 255 memcpy(p, in + kSize / 2, kSize / 2); 256 stream->ConsumeWriteBuffer(kSize / 2); 257 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize, &bytes, NULL)); 258 EXPECT_EQ(kSize, bytes); 259 EXPECT_EQ(0, memcmp(in, out, kSize)); 260 261 // Try using GetWriteBuffer in a wraparound case 262 // WWWWWWWWWWWW.... 0123456789AB.... 263 // RRRRRRRRXXXX.... ........89AB.... 264 // ........XXXXWWWW ........89AB0123 265 // WWWW....XXXXXXXX 4567....89AB0123 266 // RRRR....RRRRRRRR ................ 267 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize * 3 / 4, &bytes, NULL)); 268 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL)); 269 p = stream->GetWriteBuffer(&bytes); 270 EXPECT_TRUE(NULL != p); 271 EXPECT_EQ(kSize / 4, bytes); 272 memcpy(p, in, kSize / 4); 273 stream->ConsumeWriteBuffer(kSize / 4); 274 p = stream->GetWriteBuffer(&bytes); 275 EXPECT_TRUE(NULL != p); 276 EXPECT_EQ(kSize / 2, bytes); 277 memcpy(p, in + kSize / 4, kSize / 4); 278 stream->ConsumeWriteBuffer(kSize / 4); 279 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize * 3 / 4, &bytes, NULL)); 280 EXPECT_EQ(kSize * 3 / 4, bytes); 281 EXPECT_EQ(0, memcmp(in + kSize / 2, out, kSize / 4)); 282 EXPECT_EQ(0, memcmp(in, out + kSize / 4, kSize / 4)); 283 284 // Check that the stream is now empty 285 EXPECT_EQ(SR_BLOCK, stream->Read(out, kSize, &bytes, NULL)); 286 287 // Try growing the buffer 288 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize, &bytes, NULL)); 289 EXPECT_EQ(kSize, bytes); 290 EXPECT_TRUE(buf.SetCapacity(kSize * 2)); 291 EXPECT_EQ(SR_SUCCESS, stream->Write(in + kSize, kSize, &bytes, NULL)); 292 EXPECT_EQ(kSize, bytes); 293 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize * 2, &bytes, NULL)); 294 EXPECT_EQ(kSize * 2, bytes); 295 EXPECT_EQ(0, memcmp(in, out, kSize * 2)); 296 297 // Try shrinking the buffer 298 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize, &bytes, NULL)); 299 EXPECT_EQ(kSize, bytes); 300 EXPECT_TRUE(buf.SetCapacity(kSize)); 301 EXPECT_EQ(SR_BLOCK, stream->Write(in, kSize, &bytes, NULL)); 302 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize, &bytes, NULL)); 303 EXPECT_EQ(kSize, bytes); 304 EXPECT_EQ(0, memcmp(in, out, kSize)); 305 306 // Write to the stream, close it, read the remaining bytes 307 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, NULL)); 308 stream->Close(); 309 EXPECT_EQ(SS_CLOSED, stream->GetState()); 310 EXPECT_EQ(SR_EOS, stream->Write(in, kSize / 2, &bytes, NULL)); 311 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL)); 312 EXPECT_EQ(0, memcmp(in, out, kSize / 2)); 313 EXPECT_EQ(SR_EOS, stream->Read(out, kSize / 2, &bytes, NULL)); 314} 315 316TEST(FifoBufferTest, FullBufferCheck) { 317 FifoBuffer buff(10); 318 buff.ConsumeWriteBuffer(10); 319 320 size_t free; 321 EXPECT_TRUE(buff.GetWriteBuffer(&free) != NULL); 322 EXPECT_EQ(0U, free); 323} 324 325TEST(FifoBufferTest, WriteOffsetAndReadOffset) { 326 const size_t kSize = 16; 327 const char in[kSize * 2 + 1] = "0123456789ABCDEFGHIJKLMNOPQRSTUV"; 328 char out[kSize * 2]; 329 FifoBuffer buf(kSize); 330 331 // Write 14 bytes. 332 EXPECT_EQ(SR_SUCCESS, buf.Write(in, 14, NULL, NULL)); 333 334 // Make sure data is in |buf|. 335 size_t buffered; 336 EXPECT_TRUE(buf.GetBuffered(&buffered)); 337 EXPECT_EQ(14u, buffered); 338 339 // Read 10 bytes. 340 buf.ConsumeReadData(10); 341 342 // There should be now 12 bytes of available space. 343 size_t remaining; 344 EXPECT_TRUE(buf.GetWriteRemaining(&remaining)); 345 EXPECT_EQ(12u, remaining); 346 347 // Write at offset 12, this should fail. 348 EXPECT_EQ(SR_BLOCK, buf.WriteOffset(in, 10, 12, NULL)); 349 350 // Write 8 bytes at offset 4, this wraps around the buffer. 351 EXPECT_EQ(SR_SUCCESS, buf.WriteOffset(in, 8, 4, NULL)); 352 353 // Number of available space remains the same until we call 354 // ConsumeWriteBuffer(). 355 EXPECT_TRUE(buf.GetWriteRemaining(&remaining)); 356 EXPECT_EQ(12u, remaining); 357 buf.ConsumeWriteBuffer(12); 358 359 // There's 4 bytes bypassed and 4 bytes no read so skip them and verify the 360 // 8 bytes written. 361 size_t read; 362 EXPECT_EQ(SR_SUCCESS, buf.ReadOffset(out, 8, 8, &read)); 363 EXPECT_EQ(8u, read); 364 EXPECT_EQ(0, memcmp(out, in, 8)); 365 366 // There should still be 16 bytes available for reading. 367 EXPECT_TRUE(buf.GetBuffered(&buffered)); 368 EXPECT_EQ(16u, buffered); 369 370 // Read at offset 16, this should fail since we don't have that much data. 371 EXPECT_EQ(SR_BLOCK, buf.ReadOffset(out, 10, 16, NULL)); 372} 373 374} // namespace rtc 375