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