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