1 /* 2 * libjingle 3 * Copyright 2004--2011, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include "talk/base/gunit.h" 29 #include "talk/base/stream.h" 30 31 namespace talk_base { 32 33 /////////////////////////////////////////////////////////////////////////////// 34 // TestStream 35 /////////////////////////////////////////////////////////////////////////////// 36 37 class TestStream : public StreamInterface { 38 public: 39 TestStream() : pos_(0) { } 40 41 virtual StreamState GetState() const { return SS_OPEN; } 42 virtual StreamResult Read(void* buffer, size_t buffer_len, 43 size_t* read, int* error) { 44 unsigned char* uc_buffer = static_cast<unsigned char*>(buffer); 45 for (size_t i = 0; i < buffer_len; ++i) { 46 uc_buffer[i] = static_cast<unsigned char>(pos_++); 47 } 48 if (read) 49 *read = buffer_len; 50 return SR_SUCCESS; 51 } 52 virtual StreamResult Write(const void* data, size_t data_len, 53 size_t* written, int* error) { 54 if (error) 55 *error = -1; 56 return SR_ERROR; 57 } 58 virtual void Close() { } 59 virtual bool SetPosition(size_t position) { 60 pos_ = position; 61 return true; 62 } 63 virtual bool GetPosition(size_t* position) const { 64 if (position) *position = pos_; 65 return true; 66 } 67 virtual bool GetSize(size_t* size) const { 68 return false; 69 } 70 virtual bool GetAvailable(size_t* size) const { 71 return false; 72 } 73 74 private: 75 size_t pos_; 76 }; 77 78 bool VerifyTestBuffer(unsigned char* buffer, size_t len, 79 unsigned char value) { 80 bool passed = true; 81 for (size_t i = 0; i < len; ++i) { 82 if (buffer[i] != value++) { 83 passed = false; 84 break; 85 } 86 } 87 // Ensure that we don't pass again without re-writing 88 memset(buffer, 0, len); 89 return passed; 90 } 91 92 void SeekTest(StreamInterface* stream, const unsigned char value) { 93 size_t bytes; 94 unsigned char buffer[13] = { 0 }; 95 const size_t kBufSize = sizeof(buffer); 96 97 EXPECT_EQ(stream->Read(buffer, kBufSize, &bytes, NULL), SR_SUCCESS); 98 EXPECT_EQ(bytes, kBufSize); 99 EXPECT_TRUE(VerifyTestBuffer(buffer, kBufSize, value)); 100 EXPECT_TRUE(stream->GetPosition(&bytes)); 101 EXPECT_EQ(13U, bytes); 102 103 EXPECT_TRUE(stream->SetPosition(7)); 104 105 EXPECT_EQ(stream->Read(buffer, kBufSize, &bytes, NULL), SR_SUCCESS); 106 EXPECT_EQ(bytes, kBufSize); 107 EXPECT_TRUE(VerifyTestBuffer(buffer, kBufSize, value + 7)); 108 EXPECT_TRUE(stream->GetPosition(&bytes)); 109 EXPECT_EQ(20U, bytes); 110 } 111 112 TEST(StreamSegment, TranslatesPosition) { 113 TestStream* test = new TestStream; 114 // Verify behavior of original stream 115 SeekTest(test, 0); 116 StreamSegment* segment = new StreamSegment(test); 117 // Verify behavior of adapted stream (all values offset by 20) 118 SeekTest(segment, 20); 119 delete segment; 120 } 121 122 TEST(StreamSegment, SupportsArtificialTermination) { 123 TestStream* test = new TestStream; 124 125 size_t bytes; 126 unsigned char buffer[5000] = { 0 }; 127 const size_t kBufSize = sizeof(buffer); 128 129 { 130 StreamInterface* stream = test; 131 132 // Read a lot of bytes 133 EXPECT_EQ(stream->Read(buffer, kBufSize, &bytes, NULL), SR_SUCCESS); 134 EXPECT_EQ(bytes, kBufSize); 135 EXPECT_TRUE(VerifyTestBuffer(buffer, kBufSize, 0)); 136 137 // Test seeking far ahead 138 EXPECT_TRUE(stream->SetPosition(12345)); 139 140 // Read a bunch more bytes 141 EXPECT_EQ(stream->Read(buffer, kBufSize, &bytes, NULL), SR_SUCCESS); 142 EXPECT_EQ(bytes, kBufSize); 143 EXPECT_TRUE(VerifyTestBuffer(buffer, kBufSize, 12345 % 256)); 144 } 145 146 // Create a segment of test stream in range [100,600) 147 EXPECT_TRUE(test->SetPosition(100)); 148 StreamSegment* segment = new StreamSegment(test, 500); 149 150 { 151 StreamInterface* stream = segment; 152 153 EXPECT_EQ(stream->Read(buffer, kBufSize, &bytes, NULL), SR_SUCCESS); 154 EXPECT_EQ(500U, bytes); 155 EXPECT_TRUE(VerifyTestBuffer(buffer, 500, 100)); 156 EXPECT_EQ(stream->Read(buffer, kBufSize, &bytes, NULL), SR_EOS); 157 158 // Test seeking past "end" of stream 159 EXPECT_FALSE(stream->SetPosition(12345)); 160 EXPECT_FALSE(stream->SetPosition(501)); 161 162 // Test seeking to end (edge case) 163 EXPECT_TRUE(stream->SetPosition(500)); 164 EXPECT_EQ(stream->Read(buffer, kBufSize, &bytes, NULL), SR_EOS); 165 166 // Test seeking to start 167 EXPECT_TRUE(stream->SetPosition(0)); 168 EXPECT_EQ(stream->Read(buffer, kBufSize, &bytes, NULL), SR_SUCCESS); 169 EXPECT_EQ(500U, bytes); 170 EXPECT_TRUE(VerifyTestBuffer(buffer, 500, 100)); 171 EXPECT_EQ(stream->Read(buffer, kBufSize, &bytes, NULL), SR_EOS); 172 } 173 174 delete segment; 175 } 176 177 TEST(FifoBufferTest, TestAll) { 178 const size_t kSize = 16; 179 const char in[kSize * 2 + 1] = "0123456789ABCDEFGHIJKLMNOPQRSTUV"; 180 char out[kSize * 2]; 181 void* p; 182 const void* q; 183 size_t bytes; 184 FifoBuffer buf(kSize); 185 StreamInterface* stream = &buf; 186 187 // Test assumptions about base state 188 EXPECT_EQ(SS_OPEN, stream->GetState()); 189 EXPECT_EQ(SR_BLOCK, stream->Read(out, kSize, &bytes, NULL)); 190 EXPECT_TRUE(NULL != stream->GetReadData(&bytes)); 191 EXPECT_EQ((size_t)0, bytes); 192 stream->ConsumeReadData(0); 193 EXPECT_TRUE(NULL != stream->GetWriteBuffer(&bytes)); 194 EXPECT_EQ(kSize, bytes); 195 stream->ConsumeWriteBuffer(0); 196 197 // Try a full write 198 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize, &bytes, NULL)); 199 EXPECT_EQ(kSize, bytes); 200 201 // Try a write that should block 202 EXPECT_EQ(SR_BLOCK, stream->Write(in, kSize, &bytes, NULL)); 203 204 // Try a full read 205 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize, &bytes, NULL)); 206 EXPECT_EQ(kSize, bytes); 207 EXPECT_EQ(0, memcmp(in, out, kSize)); 208 209 // Try a read that should block 210 EXPECT_EQ(SR_BLOCK, stream->Read(out, kSize, &bytes, NULL)); 211 212 // Try a too-big write 213 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize * 2, &bytes, NULL)); 214 EXPECT_EQ(bytes, kSize); 215 216 // Try a too-big read 217 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize * 2, &bytes, NULL)); 218 EXPECT_EQ(kSize, bytes); 219 EXPECT_EQ(0, memcmp(in, out, kSize)); 220 221 // Try some small writes and reads 222 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, NULL)); 223 EXPECT_EQ(kSize / 2, bytes); 224 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL)); 225 EXPECT_EQ(kSize / 2, bytes); 226 EXPECT_EQ(0, memcmp(in, out, kSize / 2)); 227 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, NULL)); 228 EXPECT_EQ(kSize / 2, bytes); 229 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, NULL)); 230 EXPECT_EQ(kSize / 2, bytes); 231 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL)); 232 EXPECT_EQ(kSize / 2, bytes); 233 EXPECT_EQ(0, memcmp(in, out, kSize / 2)); 234 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL)); 235 EXPECT_EQ(kSize / 2, bytes); 236 EXPECT_EQ(0, memcmp(in, out, kSize / 2)); 237 238 // Try wraparound reads and writes in the following pattern 239 // WWWWWWWWWWWW.... 0123456789AB.... 240 // RRRRRRRRXXXX.... ........89AB.... 241 // WWWW....XXXXWWWW 4567....89AB0123 242 // XXXX....RRRRXXXX 4567........0123 243 // XXXXWWWWWWWWXXXX 4567012345670123 244 // RRRRXXXXXXXXRRRR ....01234567.... 245 // ....RRRRRRRR.... ................ 246 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize * 3 / 4, &bytes, NULL)); 247 EXPECT_EQ(kSize * 3 / 4, bytes); 248 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL)); 249 EXPECT_EQ(kSize / 2, bytes); 250 EXPECT_EQ(0, memcmp(in, out, kSize / 2)); 251 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, NULL)); 252 EXPECT_EQ(kSize / 2, bytes); 253 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 4, &bytes, NULL)); 254 EXPECT_EQ(kSize / 4 , bytes); 255 EXPECT_EQ(0, memcmp(in + kSize / 2, out, kSize / 4)); 256 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, NULL)); 257 EXPECT_EQ(kSize / 2, bytes); 258 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL)); 259 EXPECT_EQ(kSize / 2 , bytes); 260 EXPECT_EQ(0, memcmp(in, out, kSize / 2)); 261 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL)); 262 EXPECT_EQ(kSize / 2 , bytes); 263 EXPECT_EQ(0, memcmp(in, out, kSize / 2)); 264 265 // Use GetWriteBuffer to reset the read_position for the next tests 266 stream->GetWriteBuffer(&bytes); 267 stream->ConsumeWriteBuffer(0); 268 269 // Try using GetReadData to do a full read 270 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize, &bytes, NULL)); 271 q = stream->GetReadData(&bytes); 272 EXPECT_TRUE(NULL != q); 273 EXPECT_EQ(kSize, bytes); 274 EXPECT_EQ(0, memcmp(q, in, kSize)); 275 stream->ConsumeReadData(kSize); 276 EXPECT_EQ(SR_BLOCK, stream->Read(out, kSize, &bytes, NULL)); 277 278 // Try using GetReadData to do some small reads 279 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize, &bytes, NULL)); 280 q = stream->GetReadData(&bytes); 281 EXPECT_TRUE(NULL != q); 282 EXPECT_EQ(kSize, bytes); 283 EXPECT_EQ(0, memcmp(q, in, kSize / 2)); 284 stream->ConsumeReadData(kSize / 2); 285 q = stream->GetReadData(&bytes); 286 EXPECT_TRUE(NULL != q); 287 EXPECT_EQ(kSize / 2, bytes); 288 EXPECT_EQ(0, memcmp(q, in + kSize / 2, kSize / 2)); 289 stream->ConsumeReadData(kSize / 2); 290 EXPECT_EQ(SR_BLOCK, stream->Read(out, kSize, &bytes, NULL)); 291 292 // Try using GetReadData in a wraparound case 293 // WWWWWWWWWWWWWWWW 0123456789ABCDEF 294 // RRRRRRRRRRRRXXXX ............CDEF 295 // WWWWWWWW....XXXX 01234567....CDEF 296 // ............RRRR 01234567........ 297 // RRRRRRRR........ ................ 298 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize, &bytes, NULL)); 299 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize * 3 / 4, &bytes, NULL)); 300 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, NULL)); 301 q = stream->GetReadData(&bytes); 302 EXPECT_TRUE(NULL != q); 303 EXPECT_EQ(kSize / 4, bytes); 304 EXPECT_EQ(0, memcmp(q, in + kSize * 3 / 4, kSize / 4)); 305 stream->ConsumeReadData(kSize / 4); 306 q = stream->GetReadData(&bytes); 307 EXPECT_TRUE(NULL != q); 308 EXPECT_EQ(kSize / 2, bytes); 309 EXPECT_EQ(0, memcmp(q, in, kSize / 2)); 310 stream->ConsumeReadData(kSize / 2); 311 312 // Use GetWriteBuffer to reset the read_position for the next tests 313 stream->GetWriteBuffer(&bytes); 314 stream->ConsumeWriteBuffer(0); 315 316 // Try using GetWriteBuffer to do a full write 317 p = stream->GetWriteBuffer(&bytes); 318 EXPECT_TRUE(NULL != p); 319 EXPECT_EQ(kSize, bytes); 320 memcpy(p, in, kSize); 321 stream->ConsumeWriteBuffer(kSize); 322 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize, &bytes, NULL)); 323 EXPECT_EQ(kSize, bytes); 324 EXPECT_EQ(0, memcmp(in, out, kSize)); 325 326 // Try using GetWriteBuffer to do some small writes 327 p = stream->GetWriteBuffer(&bytes); 328 EXPECT_TRUE(NULL != p); 329 EXPECT_EQ(kSize, bytes); 330 memcpy(p, in, kSize / 2); 331 stream->ConsumeWriteBuffer(kSize / 2); 332 p = stream->GetWriteBuffer(&bytes); 333 EXPECT_TRUE(NULL != p); 334 EXPECT_EQ(kSize / 2, bytes); 335 memcpy(p, in + kSize / 2, kSize / 2); 336 stream->ConsumeWriteBuffer(kSize / 2); 337 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize, &bytes, NULL)); 338 EXPECT_EQ(kSize, bytes); 339 EXPECT_EQ(0, memcmp(in, out, kSize)); 340 341 // Try using GetWriteBuffer in a wraparound case 342 // WWWWWWWWWWWW.... 0123456789AB.... 343 // RRRRRRRRXXXX.... ........89AB.... 344 // ........XXXXWWWW ........89AB0123 345 // WWWW....XXXXXXXX 4567....89AB0123 346 // RRRR....RRRRRRRR ................ 347 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize * 3 / 4, &bytes, NULL)); 348 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL)); 349 p = stream->GetWriteBuffer(&bytes); 350 EXPECT_TRUE(NULL != p); 351 EXPECT_EQ(kSize / 4, bytes); 352 memcpy(p, in, kSize / 4); 353 stream->ConsumeWriteBuffer(kSize / 4); 354 p = stream->GetWriteBuffer(&bytes); 355 EXPECT_TRUE(NULL != p); 356 EXPECT_EQ(kSize / 2, bytes); 357 memcpy(p, in + kSize / 4, kSize / 4); 358 stream->ConsumeWriteBuffer(kSize / 4); 359 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize * 3 / 4, &bytes, NULL)); 360 EXPECT_EQ(kSize * 3 / 4, bytes); 361 EXPECT_EQ(0, memcmp(in + kSize / 2, out, kSize / 4)); 362 EXPECT_EQ(0, memcmp(in, out + kSize / 4, kSize / 4)); 363 364 // Check that the stream is now empty 365 EXPECT_EQ(SR_BLOCK, stream->Read(out, kSize, &bytes, NULL)); 366 367 // Try growing the buffer 368 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize, &bytes, NULL)); 369 EXPECT_EQ(kSize, bytes); 370 EXPECT_TRUE(buf.SetCapacity(kSize * 2)); 371 EXPECT_EQ(SR_SUCCESS, stream->Write(in + kSize, kSize, &bytes, NULL)); 372 EXPECT_EQ(kSize, bytes); 373 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize * 2, &bytes, NULL)); 374 EXPECT_EQ(kSize * 2, bytes); 375 EXPECT_EQ(0, memcmp(in, out, kSize * 2)); 376 377 // Try shrinking the buffer 378 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize, &bytes, NULL)); 379 EXPECT_EQ(kSize, bytes); 380 EXPECT_TRUE(buf.SetCapacity(kSize)); 381 EXPECT_EQ(SR_BLOCK, stream->Write(in, kSize, &bytes, NULL)); 382 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize, &bytes, NULL)); 383 EXPECT_EQ(kSize, bytes); 384 EXPECT_EQ(0, memcmp(in, out, kSize)); 385 386 // Write to the stream, close it, read the remaining bytes 387 EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, NULL)); 388 stream->Close(); 389 EXPECT_EQ(SS_CLOSED, stream->GetState()); 390 EXPECT_EQ(SR_EOS, stream->Write(in, kSize / 2, &bytes, NULL)); 391 EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL)); 392 EXPECT_EQ(0, memcmp(in, out, kSize / 2)); 393 EXPECT_EQ(SR_EOS, stream->Read(out, kSize / 2, &bytes, NULL)); 394 } 395 396 TEST(FifoBufferTest, FullBufferCheck) { 397 FifoBuffer buff(10); 398 buff.ConsumeWriteBuffer(10); 399 400 size_t free; 401 EXPECT_TRUE(buff.GetWriteBuffer(&free) != NULL); 402 EXPECT_EQ(0U, free); 403 } 404 405 TEST(FifoBufferTest, WriteOffsetAndReadOffset) { 406 const size_t kSize = 16; 407 const char in[kSize * 2 + 1] = "0123456789ABCDEFGHIJKLMNOPQRSTUV"; 408 char out[kSize * 2]; 409 FifoBuffer buf(kSize); 410 411 // Write 14 bytes. 412 EXPECT_EQ(SR_SUCCESS, buf.Write(in, 14, NULL, NULL)); 413 414 // Make sure data is in |buf|. 415 size_t buffered; 416 EXPECT_TRUE(buf.GetBuffered(&buffered)); 417 EXPECT_EQ(14u, buffered); 418 419 // Read 10 bytes. 420 buf.ConsumeReadData(10); 421 422 // There should be now 12 bytes of available space. 423 size_t remaining; 424 EXPECT_TRUE(buf.GetWriteRemaining(&remaining)); 425 EXPECT_EQ(12u, remaining); 426 427 // Write at offset 12, this should fail. 428 EXPECT_EQ(SR_BLOCK, buf.WriteOffset(in, 10, 12, NULL)); 429 430 // Write 8 bytes at offset 4, this wraps around the buffer. 431 EXPECT_EQ(SR_SUCCESS, buf.WriteOffset(in, 8, 4, NULL)); 432 433 // Number of available space remains the same until we call 434 // ConsumeWriteBuffer(). 435 EXPECT_TRUE(buf.GetWriteRemaining(&remaining)); 436 EXPECT_EQ(12u, remaining); 437 buf.ConsumeWriteBuffer(12); 438 439 // There's 4 bytes bypassed and 4 bytes no read so skip them and verify the 440 // 8 bytes written. 441 size_t read; 442 EXPECT_EQ(SR_SUCCESS, buf.ReadOffset(out, 8, 8, &read)); 443 EXPECT_EQ(8u, read); 444 EXPECT_EQ(0, memcmp(out, in, 8)); 445 446 // There should still be 16 bytes available for reading. 447 EXPECT_TRUE(buf.GetBuffered(&buffered)); 448 EXPECT_EQ(16u, buffered); 449 450 // Read at offset 16, this should fail since we don't have that much data. 451 EXPECT_EQ(SR_BLOCK, buf.ReadOffset(out, 10, 16, NULL)); 452 } 453 454 TEST(AsyncWriteTest, TestWrite) { 455 FifoBuffer* buf = new FifoBuffer(100); 456 AsyncWriteStream stream(buf, Thread::Current()); 457 EXPECT_EQ(SS_OPEN, stream.GetState()); 458 459 // Write "abc". Will go to the logging thread, which is the current 460 // thread. 461 stream.Write("abc", 3, NULL, NULL); 462 char bytes[100]; 463 size_t count; 464 // Messages on the thread's queue haven't been processed, so "abc" 465 // hasn't been written yet. 466 EXPECT_NE(SR_SUCCESS, buf->ReadOffset(&bytes, 3, 0, &count)); 467 // Now we process the messages on the thread's queue, so "abc" has 468 // been written. 469 EXPECT_TRUE_WAIT(SR_SUCCESS == buf->ReadOffset(&bytes, 3, 0, &count), 10); 470 EXPECT_EQ(3u, count); 471 EXPECT_EQ(0, memcmp(bytes, "abc", 3)); 472 473 // Write "def". Will go to the logging thread, which is the current 474 // thread. 475 stream.Write("d", 1, &count, NULL); 476 stream.Write("e", 1, &count, NULL); 477 stream.Write("f", 1, &count, NULL); 478 EXPECT_EQ(1u, count); 479 // Messages on the thread's queue haven't been processed, so "def" 480 // hasn't been written yet. 481 EXPECT_NE(SR_SUCCESS, buf->ReadOffset(&bytes, 3, 3, &count)); 482 // Flush() causes the message to be processed, so "def" has now been 483 // written. 484 stream.Flush(); 485 EXPECT_EQ(SR_SUCCESS, buf->ReadOffset(&bytes, 3, 3, &count)); 486 EXPECT_EQ(3u, count); 487 EXPECT_EQ(0, memcmp(bytes, "def", 3)); 488 489 // Write "xyz". Will go to the logging thread, which is the current 490 // thread. 491 stream.Write("xyz", 3, &count, NULL); 492 EXPECT_EQ(3u, count); 493 // Messages on the thread's queue haven't been processed, so "xyz" 494 // hasn't been written yet. 495 EXPECT_NE(SR_SUCCESS, buf->ReadOffset(&bytes, 3, 6, &count)); 496 // Close() causes the message to be processed, so "xyz" has now been 497 // written. 498 stream.Close(); 499 EXPECT_EQ(SR_SUCCESS, buf->ReadOffset(&bytes, 3, 6, &count)); 500 EXPECT_EQ(3u, count); 501 EXPECT_EQ(0, memcmp(bytes, "xyz", 3)); 502 EXPECT_EQ(SS_CLOSED, stream.GetState()); 503 504 // Is't closed, so the writes should fail. 505 EXPECT_EQ(SR_ERROR, stream.Write("000", 3, NULL, NULL)); 506 507 } 508 509 } // namespace talk_base 510