1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System.Diagnostics; 6 using System.IO.PortsTests; 7 using System.Threading; 8 using System.Threading.Tasks; 9 using Legacy.Support; 10 using Xunit; 11 using Xunit.NetCore.Extensions; 12 13 namespace System.IO.Ports.Tests 14 { 15 public class SerialStream_WriteTimeout_Property : PortsTest 16 { 17 // The default number of bytes to write with when testing timeout with Write(byte[], int, int) 18 private static readonly int s_DEFAULT_WRITE_BYTE_ARRAY_SIZE = TCSupport.MinimumBlockingByteCount; 19 20 // The large number of bytes to write with when testing timeout with Write(byte[], int, int) 21 // This needs to be large enough for Write timeout 22 private const int DEFAULT_WRITE_BYTE_LARGE_ARRAY_SIZE = 1024 * 100; 23 24 // The BaudRate to use to make Write timeout when writing DEFAULT_WRITE_BYTE_LARGE_ARRAY_SIZE bytes 25 private const int LARGEWRITE_BAUDRATE = 1200; 26 27 // The timeout to use to make Write timeout when writing DEFAULT_WRITE_BYTE_LARGE_ARRAY_SIZE 28 private const int LARGEWRITE_TIMEOUT = 750; 29 30 // The default byte to call with WriteByte 31 private const byte DEFAULT_WRITE_BYTE = 33; 32 33 // The amount of time to wait when expecting an long timeout 34 private const int DEFAULT_WAIT_LONG_TIMEOUT = 250; 35 36 // The maximum acceptable time allowed when a write method should timeout immediately 37 private const int MAX_ACCEPTABLE_ZERO_TIMEOUT = 100; 38 39 // The maximum acceptable time allowed when a write method should timeout immediately when it is called for the first time 40 private const int MAX_ACCEPTABLE_WARMUP_ZERO_TIMEOUT = 1000; 41 42 // The maximum acceptable percentage difference allowed when a write method is called for the first time 43 private const double MAX_ACCEPTABLE_WARMUP_PERCENTAGE_DIFFERENCE = .5; 44 45 // The maximum acceptable percentage difference allowed 46 private const double MAX_ACCEPTABLE_PERCENTAGE_DIFFERENCE = .15; 47 48 private const int SUCCESSIVE_WriteTimeout_SOMEDATA = 950; 49 50 private const int NUM_TRYS = 5; 51 WriteMethodDelegate(Stream stream)52 private delegate void WriteMethodDelegate(Stream stream); 53 54 #region Test Cases 55 56 [ConditionalFact(nameof(HasOneSerialPort))] WriteTimeout_DefaultValue()57 public void WriteTimeout_DefaultValue() 58 { 59 using (SerialPort com = new SerialPort(TCSupport.LocalMachineSerialInfo.FirstAvailablePortName)) 60 { 61 com.Open(); 62 Stream stream = com.BaseStream; 63 64 Debug.WriteLine("Verifying the default value of WriteTimeout"); 65 66 Assert.True(stream.WriteTimeout == -1, 67 string.Format( 68 "Err_1707azhpbn Verifying the default value of WriteTimeout Expected={0} Actual={1} FAILED", -1, 69 stream.WriteTimeout)); 70 } 71 } 72 73 [ConditionalFact(nameof(HasOneSerialPort))] WriteTimeout_AfterClose()74 public void WriteTimeout_AfterClose() 75 { 76 Debug.WriteLine("Verifying setting WriteTimeout after the SerialPort was closed"); 77 78 VerifyException(2048, null, typeof(ObjectDisposedException)); 79 } 80 81 [ConditionalFact(nameof(HasOneSerialPort))] WriteTimeout_Int32MinValue()82 public void WriteTimeout_Int32MinValue() 83 { 84 Debug.WriteLine("Verifying Int32.MinValue WriteTimeout"); 85 86 VerifyException(int.MinValue, typeof(ArgumentOutOfRangeException)); 87 } 88 89 [ConditionalFact(nameof(HasOneSerialPort))] WriteTimeout_NEG2()90 public void WriteTimeout_NEG2() 91 { 92 Debug.WriteLine("Verifying -2 WriteTimeout"); 93 94 VerifyException(-2, typeof(ArgumentOutOfRangeException)); 95 } 96 97 [ConditionalFact(nameof(HasOneSerialPort))] WriteTimeout_ZERO()98 public void WriteTimeout_ZERO() 99 { 100 Debug.WriteLine("Verifying 0 WriteTimeout"); 101 102 VerifyException(0, typeof(ArgumentOutOfRangeException)); 103 } 104 105 [ConditionalFact(nameof(HasOneSerialPort), nameof(HasHardwareFlowControl))] WriteTimeout_Default_Write_byte_int_int()106 public void WriteTimeout_Default_Write_byte_int_int() 107 { 108 Debug.WriteLine("Verifying default WriteTimeout with Write(byte[] buffer, int offset, int count)"); 109 110 VerifyDefaultTimeout(Write_byte_int_int); 111 } 112 113 [ConditionalFact(nameof(HasOneSerialPort), nameof(HasSingleByteTransmitBlocking))] WriteTimeout_Default_WriteByte()114 public void WriteTimeout_Default_WriteByte() 115 { 116 Debug.WriteLine("Verifying default WriteTimeout with WriteByte()"); 117 118 VerifyDefaultTimeout(WriteByte); 119 } 120 121 [ConditionalFact(nameof(HasOneSerialPort), nameof(HasHardwareFlowControl))] WriteTimeout_Infinite_Write_byte_int_int()122 public void WriteTimeout_Infinite_Write_byte_int_int() 123 { 124 Debug.WriteLine("Verifying infinite WriteTimeout with Write(byte[] buffer, int offset, int count)"); 125 126 VerifyLongTimeout(Write_byte_int_int, -1); 127 } 128 129 [ConditionalFact(nameof(HasOneSerialPort), nameof(HasSingleByteTransmitBlocking))] WriteTimeout_Infinite_WriteByte()130 public void WriteTimeout_Infinite_WriteByte() 131 { 132 Debug.WriteLine("Verifying infinite WriteTimeout with WriteByte()"); 133 134 VerifyLongTimeout(WriteByte, -1); 135 } 136 137 [ConditionalFact(nameof(HasOneSerialPort), nameof(HasHardwareFlowControl))] WriteTimeout_Int32MaxValue_Write_byte_int_int()138 public void WriteTimeout_Int32MaxValue_Write_byte_int_int() 139 { 140 Debug.WriteLine("Verifying Int32.MaxValue WriteTimeout with Write(byte[] buffer, int offset, int count)"); 141 142 VerifyLongTimeout(Write_byte_int_int, int.MaxValue - 1); 143 } 144 145 [ConditionalFact(nameof(HasOneSerialPort), nameof(HasSingleByteTransmitBlocking))] WriteTimeout_Int32MaxValue_WriteByte()146 public void WriteTimeout_Int32MaxValue_WriteByte() 147 { 148 Debug.WriteLine("Verifying Int32.MaxValue WriteTimeout with WriteByte()"); 149 150 VerifyLongTimeout(WriteByte, int.MaxValue - 1); 151 } 152 153 [Trait(XunitConstants.Category, XunitConstants.IgnoreForCI)] // Timing-sensitive 154 [ConditionalFact(nameof(HasOneSerialPort), nameof(HasHardwareFlowControl))] WriteTimeout_750_Write_byte_int_int()155 public void WriteTimeout_750_Write_byte_int_int() 156 { 157 Debug.WriteLine("Verifying 750 WriteTimeout with Write(byte[] buffer, int offset, int count)"); 158 159 VerifyTimeout(Write_byte_int_int, 750); 160 } 161 162 [Trait(XunitConstants.Category, XunitConstants.IgnoreForCI)] // Timing-sensitive 163 [ConditionalFact(nameof(HasOneSerialPort), nameof(HasSingleByteTransmitBlocking))] WriteTimeout_750_WriteByte()164 public void WriteTimeout_750_WriteByte() 165 { 166 Debug.WriteLine("Verifying 750 WriteTimeout with WriteByte()"); 167 168 VerifyTimeout(WriteByte, 750); 169 } 170 171 [Trait(XunitConstants.Category, XunitConstants.IgnoreForCI)] // Timing-sensitive 172 [ConditionalFact(nameof(HasOneSerialPort), nameof(HasHardwareFlowControl))] SuccessiveWriteTimeoutNoData_Write_byte_int_int()173 public void SuccessiveWriteTimeoutNoData_Write_byte_int_int() 174 { 175 using (SerialPort com = new SerialPort(TCSupport.LocalMachineSerialInfo.FirstAvailablePortName)) 176 { 177 com.Open(); 178 com.Handshake = Handshake.RequestToSend; 179 Stream stream = com.BaseStream; 180 stream.WriteTimeout = 850; 181 182 Debug.WriteLine("Verifying WriteTimeout={0} with successive call to Write(byte[], int, int) and no data", stream.WriteTimeout); 183 184 Assert.Throws<TimeoutException>(() => stream.Write(new byte[s_DEFAULT_WRITE_BYTE_ARRAY_SIZE], 0, s_DEFAULT_WRITE_BYTE_ARRAY_SIZE)); 185 186 VerifyTimeout(Write_byte_int_int, stream); 187 } 188 } 189 190 [ConditionalFact(nameof(HasNullModem), nameof(HasHardwareFlowControl))] SuccessiveWriteTimeoutSomeData_Write_byte_int_int()191 public void SuccessiveWriteTimeoutSomeData_Write_byte_int_int() 192 { 193 using (var com1 = new SerialPort(TCSupport.LocalMachineSerialInfo.FirstAvailablePortName)) 194 { 195 var asyncEnableRts = new AsyncEnableRts(); 196 var t = new Task(asyncEnableRts.EnableRTS); 197 198 com1.Open(); 199 com1.Handshake = Handshake.RequestToSend; 200 Stream stream = com1.BaseStream; 201 stream.WriteTimeout = SUCCESSIVE_WriteTimeout_SOMEDATA; 202 203 Debug.WriteLine( 204 "Verifying WriteTimeout={0} with successive call to Write(byte[], int, int) and some data being received in the first call", 205 stream.WriteTimeout); 206 207 // Call EnableRTS asynchronously this will enable RTS in the middle of the following write call allowing it to succeed 208 // before the timeout is reached 209 t.Start(); 210 TCSupport.WaitForTaskToStart(t); 211 try 212 { 213 stream.Write(new byte[s_DEFAULT_WRITE_BYTE_ARRAY_SIZE], 0, s_DEFAULT_WRITE_BYTE_ARRAY_SIZE); 214 } 215 catch (TimeoutException) 216 { 217 } 218 219 asyncEnableRts.Stop(); 220 221 TCSupport.WaitForTaskCompletion(t); 222 223 // Make sure there is no bytes in the buffer so the next call to write will timeout 224 com1.DiscardInBuffer(); 225 226 VerifyTimeout(Write_byte_int_int, stream); 227 } 228 } 229 230 [Trait(XunitConstants.Category, XunitConstants.IgnoreForCI)] // Timing-sensitive 231 [ConditionalFact(nameof(HasOneSerialPort), nameof(HasSingleByteTransmitBlocking))] SuccessiveWriteTimeoutNoData_WriteByte()232 public void SuccessiveWriteTimeoutNoData_WriteByte() 233 { 234 using (SerialPort com = new SerialPort(TCSupport.LocalMachineSerialInfo.FirstAvailablePortName)) 235 { 236 com.Open(); 237 com.Handshake = Handshake.RequestToSend; 238 Stream stream = com.BaseStream; 239 stream.WriteTimeout = 850; 240 241 Debug.WriteLine("Verifying WriteTimeout={0} with successive call to WriteByte() and no data", 242 stream.WriteTimeout); 243 244 Assert.Throws<TimeoutException>(() => stream.WriteByte(DEFAULT_WRITE_BYTE)); 245 246 VerifyTimeout(WriteByte, stream); 247 } 248 } 249 250 [ConditionalFact(nameof(HasNullModem), nameof(HasHardwareFlowControl))] SuccessiveWriteTimeoutSomeData_WriteByte()251 public void SuccessiveWriteTimeoutSomeData_WriteByte() 252 { 253 using (var com1 = new SerialPort(TCSupport.LocalMachineSerialInfo.FirstAvailablePortName)) 254 { 255 var asyncEnableRts = new AsyncEnableRts(); 256 var t = new Task(asyncEnableRts.EnableRTS); 257 258 com1.Open(); 259 com1.Handshake = Handshake.RequestToSend; 260 Stream stream = com1.BaseStream; 261 stream.WriteTimeout = SUCCESSIVE_WriteTimeout_SOMEDATA; 262 263 Debug.WriteLine( 264 "Verifying WriteTimeout={0} with successive call to WriteByte() and some data being received in the first call", 265 stream.WriteTimeout); 266 267 // Call EnableRTS asynchronously this will enable RTS in the middle of the following write call allowing it to succeed 268 // before the timeout is reached 269 t.Start(); 270 TCSupport.WaitForTaskToStart(t); 271 try 272 { 273 stream.WriteByte(DEFAULT_WRITE_BYTE); 274 } 275 catch (TimeoutException) 276 { 277 } 278 279 asyncEnableRts.Stop(); 280 281 TCSupport.WaitForTaskCompletion(t); 282 283 // Make sure there is no bytes in the buffer so the next call to write will timeout 284 com1.DiscardInBuffer(); 285 286 VerifyTimeout(WriteByte, stream); 287 } 288 } 289 290 [ConditionalFact(nameof(HasOneSerialPort), nameof(HasHardwareFlowControl))] WriteTimeout_0_Write_byte_int_int()291 public void WriteTimeout_0_Write_byte_int_int() 292 { 293 Debug.WriteLine("Verifying 0 WriteTimeout with Write(byte[] buffer, int offset, int count)"); 294 Verify0Timeout(Write_byte_int_int); 295 } 296 297 [ConditionalFact(nameof(HasOneSerialPort), nameof(HasHardwareFlowControl))] WriteTimeout_0_WriteByte()298 public void WriteTimeout_0_WriteByte() 299 { 300 Debug.WriteLine("Verifying 0 WriteTimeout with WriteByte()"); 301 Verify0Timeout(WriteByte); 302 } 303 304 [ConditionalFact(nameof(HasOneSerialPort), nameof(HasHardwareFlowControl))] WriteTimeout_LargeWrite()305 public void WriteTimeout_LargeWrite() 306 { 307 using (SerialPort com = new SerialPort(TCSupport.LocalMachineSerialInfo.FirstAvailablePortName)) 308 { 309 com.Open(); 310 com.BaudRate = LARGEWRITE_BAUDRATE; 311 com.Handshake = Handshake.RequestToSend; 312 Stream stream = com.BaseStream; 313 stream.WriteTimeout = LARGEWRITE_TIMEOUT; 314 315 Debug.WriteLine("Verifying {0} WriteTimeout with Write(byte[] , int, int) and writing {1} bytes", LARGEWRITE_TIMEOUT, DEFAULT_WRITE_BYTE_LARGE_ARRAY_SIZE); 316 317 VerifyTimeout(Write_byte_int_int_Large, stream); 318 } 319 } 320 321 private class AsyncEnableRts 322 { 323 private bool _stop; 324 EnableRTS()325 public void EnableRTS() 326 { 327 lock (this) 328 { 329 using (var com2 = new SerialPort(TCSupport.LocalMachineSerialInfo.SecondAvailablePortName)) 330 { 331 int sleepPeriod = SUCCESSIVE_WriteTimeout_SOMEDATA / 2; 332 333 // Sleep some random period with of a maximum duration of half the largest possible timeout value for a write method on COM1 334 Thread.Sleep(sleepPeriod); 335 336 com2.Open(); 337 com2.RtsEnable = true; 338 339 while (!_stop) 340 Monitor.Wait(this); 341 342 com2.RtsEnable = false; 343 } 344 } 345 } 346 Stop()347 public void Stop() 348 { 349 lock (this) 350 { 351 _stop = true; 352 Monitor.Pulse(this); 353 } 354 } 355 } 356 #endregion 357 358 #region Verification for Test Cases 359 VerifyDefaultTimeout(WriteMethodDelegate writeMethod)360 private void VerifyDefaultTimeout(WriteMethodDelegate writeMethod) 361 { 362 using (SerialPort com1 = TCSupport.InitFirstSerialPort()) 363 { 364 Debug.WriteLine("Serial port being used : " + com1.PortName); 365 366 367 com1.Open(); 368 com1.Handshake = Handshake.RequestToSend; 369 com1.BaseStream.ReadTimeout = 1; 370 371 Assert.Equal(-1, com1.BaseStream.WriteTimeout); 372 373 VerifyLongTimeout(writeMethod, com1); 374 } 375 } 376 VerifyLongTimeout(WriteMethodDelegate writeMethod, int writeTimeout)377 private void VerifyLongTimeout(WriteMethodDelegate writeMethod, int writeTimeout) 378 { 379 using (SerialPort com1 = TCSupport.InitFirstSerialPort()) 380 { 381 com1.Open(); 382 com1.Handshake = Handshake.RequestToSend; 383 com1.BaseStream.ReadTimeout = 1; 384 com1.BaseStream.WriteTimeout = 1; 385 386 com1.BaseStream.WriteTimeout = writeTimeout; 387 388 Assert.Equal(writeTimeout, com1.BaseStream.WriteTimeout); 389 390 VerifyLongTimeout(writeMethod, com1); 391 } 392 } 393 VerifyLongTimeout(WriteMethodDelegate writeMethod, SerialPort com1)394 private void VerifyLongTimeout(WriteMethodDelegate writeMethod, SerialPort com1) 395 { 396 var writeThread = new WriteDelegateThread(com1.BaseStream, writeMethod); 397 var t = new Task(writeThread.CallWrite); 398 399 t.Start(); 400 Thread.Sleep(DEFAULT_WAIT_LONG_TIMEOUT); 401 Assert.False(t.IsCompleted, 402 string.Format("Err_17071ahpa!!! {0} terminated with a long timeout of {1}ms", writeMethod.Method.Name, com1.BaseStream.WriteTimeout)); 403 com1.Handshake = Handshake.None; 404 TCSupport.WaitForTaskCompletion(t); 405 } 406 VerifyTimeout(WriteMethodDelegate writeMethod, int WriteTimeout)407 private void VerifyTimeout(WriteMethodDelegate writeMethod, int WriteTimeout) 408 { 409 using (var com1 = new SerialPort(TCSupport.LocalMachineSerialInfo.FirstAvailablePortName)) 410 411 { 412 com1.Open(); 413 com1.Handshake = Handshake.RequestToSend; 414 com1.BaseStream.ReadTimeout = 1; 415 com1.BaseStream.WriteTimeout = 1; 416 417 com1.BaseStream.WriteTimeout = WriteTimeout; 418 419 Assert.Equal(WriteTimeout, com1.BaseStream.WriteTimeout); 420 421 VerifyTimeout(writeMethod, com1.BaseStream); 422 } 423 } 424 VerifyTimeout(WriteMethodDelegate writeMethod, Stream stream)425 private void VerifyTimeout(WriteMethodDelegate writeMethod, Stream stream) 426 { 427 var timer = new Stopwatch(); 428 int expectedTime = stream.WriteTimeout; 429 int actualTime; 430 double percentageDifference; 431 432 433 // Warmup the write method. When called for the first time the write method seems to take much longer then subsequent calls 434 timer.Start(); 435 try 436 { 437 writeMethod(stream); 438 } 439 catch (TimeoutException) { } 440 timer.Stop(); 441 actualTime = (int)timer.ElapsedMilliseconds; 442 percentageDifference = Math.Abs((expectedTime - actualTime) / (double)expectedTime); 443 444 // Verify that the percentage difference between the expected and actual timeout is less then maxPercentageDifference 445 Assert.True(percentageDifference <= MAX_ACCEPTABLE_WARMUP_PERCENTAGE_DIFFERENCE, 446 string.Format("Err_88558amuph!!!: The write method timedout in {0} expected {1} percentage difference: {2} when called for the first time", 447 actualTime, expectedTime, percentageDifference)); 448 449 actualTime = 0; 450 timer.Reset(); 451 452 // Perform the actual test verifying that the write method times out in approximately WriteTimeout milliseconds 453 Thread.CurrentThread.Priority = ThreadPriority.Highest; 454 455 for (var i = 0; i < NUM_TRYS; i++) 456 { 457 timer.Start(); 458 try { writeMethod(stream); } 459 catch (TimeoutException) { } 460 timer.Stop(); 461 462 actualTime += (int)timer.ElapsedMilliseconds; 463 timer.Reset(); 464 } 465 466 Thread.CurrentThread.Priority = ThreadPriority.Normal; 467 actualTime /= NUM_TRYS; 468 percentageDifference = Math.Abs((expectedTime - actualTime) / (double)expectedTime); 469 470 // Verify that the percentage difference between the expected and actual timeout is less then maxPercentageDifference 471 Assert.True(percentageDifference <= MAX_ACCEPTABLE_PERCENTAGE_DIFFERENCE, 472 string.Format("Err_56485ahpbz!!!: The write method timedout in {0} expected {1} percentage difference: {2}", actualTime, expectedTime, percentageDifference)); 473 } 474 Verify0Timeout(WriteMethodDelegate writeMethod)475 private void Verify0Timeout(WriteMethodDelegate writeMethod) 476 { 477 using (var com1 = new SerialPort(TCSupport.LocalMachineSerialInfo.FirstAvailablePortName)) 478 479 { 480 com1.Open(); 481 com1.Handshake = Handshake.RequestToSend; 482 com1.BaseStream.ReadTimeout = 1; 483 com1.BaseStream.WriteTimeout = 1; 484 485 com1.BaseStream.WriteTimeout = 1; 486 487 Assert.Equal(1, com1.BaseStream.WriteTimeout); 488 489 Verify0Timeout(writeMethod, com1.BaseStream); 490 } 491 } 492 Verify0Timeout(WriteMethodDelegate writeMethod, Stream stream)493 private void Verify0Timeout(WriteMethodDelegate writeMethod, Stream stream) 494 { 495 var timer = new Stopwatch(); 496 int actualTime; 497 498 // Warmup the write method. When called for the first time the write method seems to take much longer then subsequent calls 499 timer.Start(); 500 try 501 { 502 writeMethod(stream); 503 } 504 catch (TimeoutException) { } 505 timer.Stop(); 506 actualTime = (int)timer.ElapsedMilliseconds; 507 508 // Verify that the time the method took to timeout is less then the maximum acceptable time 509 Assert.True(actualTime <= MAX_ACCEPTABLE_WARMUP_ZERO_TIMEOUT, 510 string.Format("Err_277a0ahpsb!!!: With a timeout of 0 the write method timedout in {0} expected something less then {1} when called for the first time", 511 actualTime, MAX_ACCEPTABLE_WARMUP_ZERO_TIMEOUT)); 512 513 actualTime = 0; 514 timer.Reset(); 515 516 // Perform the actual test verifying that the write method times out in approximately WriteTimeout milliseconds 517 Thread.CurrentThread.Priority = ThreadPriority.Highest; 518 519 for (var i = 0; i < NUM_TRYS; i++) 520 { 521 timer.Start(); 522 try { writeMethod(stream); } 523 catch (TimeoutException) { } 524 timer.Stop(); 525 526 actualTime += (int)timer.ElapsedMilliseconds; 527 timer.Reset(); 528 } 529 530 Thread.CurrentThread.Priority = ThreadPriority.Normal; 531 actualTime /= NUM_TRYS; 532 533 // Verify that the time the method took to timeout is less then the maximum acceptable time 534 Assert.True(actualTime <= MAX_ACCEPTABLE_ZERO_TIMEOUT, 535 string.Format("Err_112389ahbp!!!: With a timeout of 0 the write method timedout in {0} expected something less then {1}", 536 actualTime, MAX_ACCEPTABLE_ZERO_TIMEOUT)); 537 } 538 VerifyException(int readTimeout, Type expectedException)539 private void VerifyException(int readTimeout, Type expectedException) 540 { 541 VerifyException(readTimeout, expectedException, expectedException); 542 } 543 VerifyException(int readTimeout, Type expectedExceptionAfterOpen, Type expectedExceptionAfterClose)544 private void VerifyException(int readTimeout, Type expectedExceptionAfterOpen, Type expectedExceptionAfterClose) 545 { 546 using (SerialPort com = new SerialPort(TCSupport.LocalMachineSerialInfo.FirstAvailablePortName)) 547 { 548 com.Open(); 549 Stream stream = com.BaseStream; 550 551 VerifyException(stream, readTimeout, expectedExceptionAfterOpen); 552 553 com.Close(); 554 555 VerifyException(stream, readTimeout, expectedExceptionAfterClose); 556 } 557 } 558 VerifyException(Stream stream, int WriteTimeout, Type expectedException)559 private void VerifyException(Stream stream, int WriteTimeout, Type expectedException) 560 { 561 int origWriteTimeout = stream.WriteTimeout; 562 563 if (expectedException == null) 564 { 565 stream.WriteTimeout = WriteTimeout; 566 Assert.Equal(WriteTimeout, stream.WriteTimeout); 567 } 568 else 569 { 570 Assert.Throws(expectedException, () => stream.WriteTimeout = WriteTimeout); 571 Assert.Equal(origWriteTimeout, stream.WriteTimeout); 572 } 573 } 574 Write_byte_int_int(Stream stream)575 private void Write_byte_int_int(Stream stream) 576 { 577 stream.Write(new byte[s_DEFAULT_WRITE_BYTE_ARRAY_SIZE], 0, s_DEFAULT_WRITE_BYTE_ARRAY_SIZE); 578 } 579 Write_byte_int_int_Large(Stream stream)580 private void Write_byte_int_int_Large(Stream stream) 581 { 582 stream.Write(new byte[DEFAULT_WRITE_BYTE_LARGE_ARRAY_SIZE], 0, DEFAULT_WRITE_BYTE_LARGE_ARRAY_SIZE); 583 } 584 WriteByte(Stream stream)585 private void WriteByte(Stream stream) 586 { 587 stream.WriteByte(DEFAULT_WRITE_BYTE); 588 } 589 590 private class WriteDelegateThread 591 { WriteDelegateThread(Stream stream, WriteMethodDelegate writeMethod)592 public WriteDelegateThread(Stream stream, WriteMethodDelegate writeMethod) 593 { 594 _stream = stream; 595 _writeMethod = writeMethod; 596 } 597 CallWrite()598 public void CallWrite() 599 { 600 _writeMethod(_stream); 601 } 602 603 private readonly WriteMethodDelegate _writeMethod; 604 private readonly Stream _stream; 605 } 606 607 #endregion 608 } 609 } 610