From 377d39cfea9b40b59652cff9e2d1b3060ae06448 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Sat, 5 Feb 2022 20:54:49 +0100 Subject: [PATCH 01/72] Add GC (CoreCLR) `TimeSpan` overloads --- src/coreclr/System.Private.CoreLib/src/System/GC.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/coreclr/System.Private.CoreLib/src/System/GC.cs b/src/coreclr/System.Private.CoreLib/src/System/GC.cs index 7597672f683164..e5705e10689fd4 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/GC.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/GC.cs @@ -428,6 +428,12 @@ public static GCNotificationStatus WaitForFullGCApproach(int millisecondsTimeout return (GCNotificationStatus)_WaitForFullGCApproach(millisecondsTimeout); } + public static GCNotificationStatus WaitForFullGCApproach(TimeSpan timeout) + { + int millisecondsTimeout = (int)timeout.TotalMilliseconds; + return (GCNotificationStatus)_WaitForFullGCApproach(millisecondsTimeout); + } + public static GCNotificationStatus WaitForFullGCComplete() { return (GCNotificationStatus)_WaitForFullGCComplete(-1); @@ -440,6 +446,12 @@ public static GCNotificationStatus WaitForFullGCComplete(int millisecondsTimeout return (GCNotificationStatus)_WaitForFullGCComplete(millisecondsTimeout); } + public static GCNotificationStatus WaitForFullGCComplete(TimeSpan timeout) + { + int millisecondsTimeout = (int)timeout.TotalMilliseconds; + return (GCNotificationStatus)_WaitForFullGCComplete(millisecondsTimeout); + } + private enum StartNoGCRegionStatus { Succeeded = 0, From 4d5b6322559546857b2ac5faef684e9f926ab2c2 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Sat, 5 Feb 2022 21:03:04 +0100 Subject: [PATCH 02/72] Add `CancellationToken` overload for `Wait` --- .../src/System/Threading/Tasks/Task.cs | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs index 6b5c05d37231bd..20e0bceebc0903 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs @@ -2650,6 +2650,42 @@ public bool Wait(TimeSpan timeout) return Wait((int)totalMilliseconds, default); } + /// + /// Waits for the to complete execution. + /// + /// + /// A that represents the number of milliseconds to wait, or a that represents -1 milliseconds to wait indefinitely. + /// + /// + /// A to observe while waiting for the task to complete. + /// + /// + /// true if the completed execution within the allotted time; otherwise, false. + /// + /// + /// The was canceled -or- an exception was thrown during the execution of the . + /// + /// + /// is a negative number other than -1 milliseconds, which represents an + /// infinite time-out -or- timeout is greater than + /// . + /// + /// + /// The was canceled. + /// + public bool Wait(TimeSpan timeout, CancellationToken cancellationToken) + { + long totalMilliseconds = (long)timeout.TotalMilliseconds; + if (totalMilliseconds is < (-1) or > int.MaxValue) + { + ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.timeout); + } + + return Wait((int)totalMilliseconds, cancellationToken); + } + /// /// Waits for the to complete execution. /// From 3477de9303eb529eb861bcf83c42346f6e191de8 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Sat, 5 Feb 2022 21:14:58 +0100 Subject: [PATCH 03/72] Add `MatchTimeout` property to `RegularExpressionAttribute` --- .../DataAnnotations/RegularExpressionAttribute.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/RegularExpressionAttribute.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/RegularExpressionAttribute.cs index cf2ec8a7697c20..130205fac36c38 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/RegularExpressionAttribute.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/RegularExpressionAttribute.cs @@ -31,6 +31,11 @@ public RegularExpressionAttribute([StringSyntax(StringSyntaxAttribute.Regex)] st /// public int MatchTimeoutInMilliseconds { get; set; } + /// + /// Gets or sets the timeout to use when matching the regular expression pattern + /// + public TimeSpan MatchTimeout => TimeSpan.FromMilliseconds(MatchTimeoutInMilliseconds); + /// /// Gets the regular expression pattern to use /// From ca4e786d6268eac2dce07930056454a951e53431 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Sat, 5 Feb 2022 21:32:20 +0100 Subject: [PATCH 04/72] Add tests for `RegularExpressionAttribute.MatchTimeout` --- .../DataAnnotations/RegularExpressionAttributeTests.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/libraries/System.ComponentModel.Annotations/tests/System/ComponentModel/DataAnnotations/RegularExpressionAttributeTests.cs b/src/libraries/System.ComponentModel.Annotations/tests/System/ComponentModel/DataAnnotations/RegularExpressionAttributeTests.cs index 78ac307027f371..c82d88d7a26d9a 100644 --- a/src/libraries/System.ComponentModel.Annotations/tests/System/ComponentModel/DataAnnotations/RegularExpressionAttributeTests.cs +++ b/src/libraries/System.ComponentModel.Annotations/tests/System/ComponentModel/DataAnnotations/RegularExpressionAttributeTests.cs @@ -56,6 +56,15 @@ public static void MatchTimeoutInMilliseconds_GetSet_ReturnsExpected(int newValu Assert.Equal(newValue, attribute.MatchTimeoutInMilliseconds); } + [Theory] + [InlineData(12345)] + [InlineData(-1)] + public static void MatchTimeout_Get_ReturnsExpected(int newValue) + { + var attribute = new RegularExpressionAttribute("SomePattern") { MatchTimeoutInMilliseconds = newValue }; + Assert.Equal(TimeSpan.FromMilliseconds(newValue), attribute.MatchTimeout); + } + [Theory] [InlineData(null)] [InlineData("")] From 98664c6ffae99dd3cb064a990a05b14dbad619ed Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Sat, 5 Feb 2022 21:41:17 +0100 Subject: [PATCH 05/72] Add `TimeSpan` overloads for `WaitForInputIdle` and `WaitForExit` --- .../src/System/Diagnostics/Process.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs index e75dd7961866f8..43a3ef926d269a 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs @@ -829,6 +829,12 @@ public bool WaitForInputIdle(int milliseconds) return WaitForInputIdleCore(milliseconds); } + public bool WaitForInputIdle(TimeSpan timeout) + { + int milliseconds = (int)timeout.TotalMilliseconds; + return WaitForInputIdleCore(milliseconds); + } + public ISynchronizeInvoke? SynchronizingObject { get; set; } /// @@ -1425,6 +1431,16 @@ public bool WaitForExit(int milliseconds) return exited; } + /// + /// Instructs the Process component to wait the specified number of milliseconds for + /// the associated process to exit. + /// + public bool WaitForExit(TimeSpan timeout) + { + int milliseconds = (int)timeout.TotalMilliseconds; + return WaitForExit(milliseconds); + } + /// /// Instructs the Process component to wait for the associated process to exit, or /// for the to be canceled. From 94412fd9fafc1d35a8b57df04bda585b6a782c7f Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Sat, 5 Feb 2022 21:55:01 +0100 Subject: [PATCH 06/72] Add `TimeSpan` overload for `Timer` constructor --- .../System.Private.CoreLib/src/System/Threading/Timer.cs | 8 ++++++++ .../System.Threading.Timer/tests/TimerConstructorTests.cs | 1 + 2 files changed, 9 insertions(+) diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Timer.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Timer.cs index 108034d778d423..52082cee0d5975 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Timer.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Timer.cs @@ -881,6 +881,14 @@ public Timer(TimerCallback callback) TimerSetup(callback, this, DueTime, Period); } + public Timer(TimeSpan interval) + { + unchecked + { + TimerSetup(_ => { }, this, (uint)-1, (uint)(int)interval.TotalMilliseconds); + } + } + [MemberNotNull(nameof(_timer))] private void TimerSetup(TimerCallback callback, object? state, diff --git a/src/libraries/System.Threading.Timer/tests/TimerConstructorTests.cs b/src/libraries/System.Threading.Timer/tests/TimerConstructorTests.cs index b8af1fd2038fe1..43281dc7127702 100644 --- a/src/libraries/System.Threading.Timer/tests/TimerConstructorTests.cs +++ b/src/libraries/System.Threading.Timer/tests/TimerConstructorTests.cs @@ -56,6 +56,7 @@ public void Timer_AllConstructorsCanBeUsedSuccessfully() new Timer(_ => { }, null, Timeout, Timeout).Dispose(); new Timer(_ => { }, null, (long)Timeout, (long)Timeout).Dispose(); new Timer(_ => { }, null, (uint)Timeout, (uint)Timeout).Dispose(); + new Timer(TimeSpan.FromMilliseconds(Timeout)).Dispose(); new Timer(_ => { }, null, TimeSpan.FromMilliseconds(Timeout), TimeSpan.FromMilliseconds(Timeout)).Dispose(); } } From 31b2210e54d507283e47ea96b975e1c3bf94017d Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Sat, 5 Feb 2022 22:05:49 +0100 Subject: [PATCH 07/72] Add `TimeSpan` overload for `ServiceBase.RequestAdditionalTime` --- .../src/System/ServiceProcess/ServiceBase.cs | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs b/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs index c8dcaa55b8936c..0fccc8db3a2db6 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs +++ b/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs @@ -72,6 +72,31 @@ public unsafe void RequestAdditionalTime(int milliseconds) } } + /// + /// When this method is called from OnStart, OnStop, OnPause or OnContinue, + /// the specified wait hint is passed to the + /// Service Control Manager to avoid having the service marked as not responding. + /// + /// + public unsafe void RequestAdditionalTime(TimeSpan time) + { + int milliseconds = (int)time.TotalMilliseconds; + fixed (SERVICE_STATUS* pStatus = &_status) + { + if (_status.currentState != ServiceControlStatus.STATE_CONTINUE_PENDING && + _status.currentState != ServiceControlStatus.STATE_START_PENDING && + _status.currentState != ServiceControlStatus.STATE_STOP_PENDING && + _status.currentState != ServiceControlStatus.STATE_PAUSE_PENDING) + { + throw new InvalidOperationException(SR.NotInPendingState); + } + + _status.waitHint = milliseconds; + _status.checkPoint++; + SetServiceStatus(_statusHandle, pStatus); + } + } + /// /// Indicates whether to report Start, Stop, Pause, and Continue commands in the event. /// From a3d856b64cab2e215c47453ed2cebda92d2e5f20 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Sat, 5 Feb 2022 22:12:59 +0100 Subject: [PATCH 08/72] Add `TimeSpan` overload for `NetworkStream.Close` --- .../src/System/Net/Sockets/NetworkStream.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs index e7b8b4e8745300..123986d448703a 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs @@ -341,6 +341,12 @@ public void Close(int timeout) Dispose(); } + public void Close(TimeSpan timeout) + { + int milliseconds = (int)timeout.TotalMilliseconds; + Close(milliseconds); + } + protected override void Dispose(bool disposing) { if (Interlocked.Exchange(ref _disposed, 1) != 0) From 77e959bb57d39f6fefbb5916980f3da0572778de Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Sat, 5 Feb 2022 22:31:36 +0100 Subject: [PATCH 09/72] Add `TimeSpan` overloads for `Socket.Poll` and `Socket.Select` --- .../src/System/Net/Sockets/Socket.cs | 16 +++++++++++ .../ArgumentValidationTests.cs | 27 +++++++++++++++++++ .../tests/FunctionalTests/Connect.cs | 21 +++++++++++++++ 3 files changed, 64 insertions(+) diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs index f3ecb8e64a9f05..2701a5c75294ff 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs @@ -2181,6 +2181,14 @@ public bool Poll(int microSeconds, SelectMode mode) return status; } + public bool Poll(TimeSpan timeout, SelectMode mode) + { + int milliseconds = (int)timeout.TotalMilliseconds; + int microseconds = milliseconds / 1000; + + return Poll(microseconds, mode); + } + // Determines the status of a socket. public static void Select(IList? checkRead, IList? checkWrite, IList? checkError, int microSeconds) { @@ -2212,6 +2220,14 @@ public static void Select(IList? checkRead, IList? checkWrite, IList? checkError } } + public static void Select(IList? checkRead, IList? checkWrite, IList? checkError, TimeSpan timeout) + { + int milliseconds = (int)timeout.TotalMilliseconds; + int microseconds = milliseconds / 1000; + + Select(checkRead, checkWrite, checkError, microseconds); + } + public IAsyncResult BeginConnect(EndPoint remoteEP, AsyncCallback? callback, object? state) => TaskToApm.Begin(ConnectAsync(remoteEP), callback, state); diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ArgumentValidationTests.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/ArgumentValidationTests.cs index 41fe74b0c4f757..f242e30114e123 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ArgumentValidationTests.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/ArgumentValidationTests.cs @@ -355,6 +355,22 @@ public void Select_NullOrEmptyLists_Throws_ArgumentNull() Assert.Throws(() => Socket.Select(emptyList, emptyList, emptyList, -1)); } + [Fact] + public void Select_NullOrEmptyLists_Throws_ArgumentNull_TimeSpan() + { + TimeSpan infinity = TimeSpan.FromMilliseconds(-1); + var emptyList = new List(); + + Assert.Throws(() => Socket.Select(null, null, null, infinity)); + Assert.Throws(() => Socket.Select(emptyList, null, null, infinity)); + Assert.Throws(() => Socket.Select(null, emptyList, null, infinity)); + Assert.Throws(() => Socket.Select(emptyList, emptyList, null, infinity)); + Assert.Throws(() => Socket.Select(null, null, emptyList, infinity)); + Assert.Throws(() => Socket.Select(emptyList, null, emptyList, infinity)); + Assert.Throws(() => Socket.Select(null, emptyList, emptyList, infinity)); + Assert.Throws(() => Socket.Select(emptyList, emptyList, emptyList, infinity)); + } + [Fact] public void Select_LargeList_Throws_ArgumentOutOfRange() { @@ -365,6 +381,17 @@ public void Select_LargeList_Throws_ArgumentOutOfRange() Assert.Throws(() => Socket.Select(null, null, largeList, -1)); } + [Fact] + public void Select_LargeList_Throws_ArgumentOutOfRange_TimeSpan() + { + TimeSpan infinity = TimeSpan.FromMilliseconds(-1); + var largeList = new LargeList(); + + Assert.Throws(() => Socket.Select(largeList, null, null, infinity)); + Assert.Throws(() => Socket.Select(null, largeList, null, infinity)); + Assert.Throws(() => Socket.Select(null, null, largeList, infinity)); + } + [Fact] public void AcceptAsync_NullAsyncEventArgs_Throws_ArgumentNull() { diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs index 39506cee57fdaf..c03beb2fe8710c 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs @@ -359,6 +359,27 @@ public async Task FailedConnect_ConnectedReturnsFalse() Assert.False(socket.Connected); } + + [Fact] + public async Task FailedConnect_ConnectedReturnsFalse_TimeSpan() + { + TimeSpan timeSpan = TimeSpan.FromMilliseconds(5_000_000L * 1000); + using Socket socket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + + // Connect to port 1 where we expect no server to be listening. + SocketException se = await Assert.ThrowsAnyAsync(() => ConnectAsync(socket, new IPEndPoint(IPAddress.Loopback, 1))); + + + if (se.SocketErrorCode != SocketError.ConnectionRefused) + { + Assert.Equal(SocketError.WouldBlock, se.SocketErrorCode); + + // Give the non-blocking connect some time to complete. + socket.Poll(timeSpan, SelectMode.SelectWrite); + } + + Assert.False(socket.Connected); + } } // The test class is declared non-parallel because of possible IPv4/IPv6 port-collision on Unix: From ea86b6704285bee09fe329da3e8390cb8d87368d Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Sat, 5 Feb 2022 22:52:48 +0100 Subject: [PATCH 10/72] Add `TimeSpan` overload for `FileSystemWatcher.WaitForChanged` --- .../src/System/IO/FileSystemWatcher.cs | 6 +++ .../tests/FileSystemWatcher.WaitForChanged.cs | 51 +++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.cs b/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.cs index 8ea51f94eaf6d7..a56ddbbf0b47fe 100644 --- a/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.cs +++ b/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.cs @@ -619,6 +619,12 @@ public WaitForChangedResult WaitForChanged(WatcherChangeTypes changeType, int ti WaitForChangedResult.TimedOutResult; } + public WaitForChangedResult WaitForChanged(WatcherChangeTypes changeType, TimeSpan timeout) + { + int milliseconds = (int)timeout.TotalMilliseconds; + return WaitForChanged(changeType, milliseconds); + } + /// /// Stops and starts this object. /// diff --git a/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.WaitForChanged.cs b/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.WaitForChanged.cs index cce5f54469f2dd..f083407d06f96d 100644 --- a/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.WaitForChanged.cs +++ b/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.WaitForChanged.cs @@ -124,6 +124,57 @@ public void NonZeroTimeout_NoActivity_TimesOut(WatcherChangeTypes changeType, bo } } + [Theory] + [InlineData(false)] + [InlineData(true)] + public void ZeroTimeout_TimesOut_TimeSpan(bool enabledBeforeWait) + { + TimeSpan timeout = TimeSpan.FromMilliseconds(0); + + using var testDirectory = new TempDirectory(GetTestFilePath()); + using var dir = new TempDirectory(Path.Combine(testDirectory.Path, GetTestFileName())); + using var fsw = new FileSystemWatcher(testDirectory.Path); + + if (enabledBeforeWait) fsw.EnableRaisingEvents = true; + AssertTimedOut(fsw.WaitForChanged(WatcherChangeTypes.All, timeout)); + Assert.Equal(enabledBeforeWait, fsw.EnableRaisingEvents); + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public void NonZeroTimeout_NoEvents_TimesOut_TimeSpan(bool enabledBeforeWait) + { + TimeSpan timeout = TimeSpan.FromMilliseconds(1); + + using var testDirectory = new TempDirectory(GetTestFilePath()); + using var dir = new TempDirectory(Path.Combine(testDirectory.Path, GetTestFileName())); + using var fsw = new FileSystemWatcher(testDirectory.Path); + + if (enabledBeforeWait) fsw.EnableRaisingEvents = true; + AssertTimedOut(fsw.WaitForChanged(0, timeout)); + Assert.Equal(enabledBeforeWait, fsw.EnableRaisingEvents); + } + + [Theory] + [InlineData(WatcherChangeTypes.Deleted, false)] + [InlineData(WatcherChangeTypes.Created, true)] + [InlineData(WatcherChangeTypes.Changed, false)] + [InlineData(WatcherChangeTypes.Renamed, true)] + [InlineData(WatcherChangeTypes.All, true)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/58418", typeof(PlatformDetection), nameof(PlatformDetection.IsMacCatalyst), nameof(PlatformDetection.IsArm64Process))] + public void NonZeroTimeout_NoActivity_TimesOut_TimeSpan(WatcherChangeTypes changeType, bool enabledBeforeWait) + { + TimeSpan timeout = TimeSpan.FromMilliseconds(1); + using var testDirectory = new TempDirectory(GetTestFilePath()); + using var dir = new TempDirectory(Path.Combine(testDirectory.Path, GetTestFileName())); + using var fsw = new FileSystemWatcher(testDirectory.Path); + + if (enabledBeforeWait) fsw.EnableRaisingEvents = true; + AssertTimedOut(fsw.WaitForChanged(changeType, timeout)); + Assert.Equal(enabledBeforeWait, fsw.EnableRaisingEvents); + } + [Theory] [OuterLoop("This test has a longer than average timeout and may fail intermittently")] [InlineData(WatcherChangeTypes.Created)] From 517b8e7da8f89d04b0ae54736d2a07fb7912a6b2 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Sat, 5 Feb 2022 23:07:04 +0100 Subject: [PATCH 11/72] Add `TimeSpan` overloads for `NamedPipeClientStram.Connect` and `NamedPipeClientStram.ConnectAsync` --- .../src/System/IO/Pipes/NamedPipeClientStream.cs | 12 ++++++++++++ .../tests/NamedPipeTests/NamedPipeTest.Specific.cs | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.cs b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.cs index a0240686342174..5e81437564d9c9 100644 --- a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.cs +++ b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.cs @@ -129,6 +129,12 @@ public void Connect(int timeout) ConnectInternal(timeout, CancellationToken.None, Environment.TickCount); } + public void Connect(TimeSpan timeout) + { + int milliseconds = (int)timeout.TotalMilliseconds; + Connect(milliseconds); + } + private void ConnectInternal(int timeout, CancellationToken cancellationToken, int startTime) { // This is the main connection loop. It will loop until the timeout expires. @@ -197,6 +203,12 @@ public Task ConnectAsync(int timeout, CancellationToken cancellationToken) return Task.Run(() => ConnectInternal(timeout, cancellationToken, startTime), cancellationToken); } + public Task ConnectAsync(TimeSpan timeout, CancellationToken cancellationToken = default) + { + int milliseconds = (int)timeout.TotalMilliseconds; + return ConnectAsync(milliseconds, cancellationToken); + } + // override because named pipe clients can't get/set properties when waiting to connect // or broken protected internal override void CheckPipePropertyOperations() diff --git a/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Specific.cs b/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Specific.cs index 220be9d65ca8a8..7775ab80ae3dce 100644 --- a/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Specific.cs +++ b/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Specific.cs @@ -38,6 +38,18 @@ public async Task ConnectToNonExistentServer_Throws_TimeoutException() } } + [Fact] + public async Task ConnectToNonExistentServer_Throws_TimeoutException_TimeSpan() + { + using (NamedPipeClientStream client = new NamedPipeClientStream(".", "notthere")) + { + var ctx = new CancellationTokenSource(); + Assert.Throws(() => client.Connect(TimeSpan.FromMilliseconds(60))); // 60 to be over internal 50 interval + await Assert.ThrowsAsync(() => client.ConnectAsync(TimeSpan.FromMilliseconds(50))); + await Assert.ThrowsAsync(() => client.ConnectAsync(TimeSpan.FromMilliseconds(60), ctx.Token)); // testing Token overload; ctx is not canceled in this test + } + } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public async Task CancelConnectToNonExistentServer_Throws_OperationCanceledException() { From 47cb9f8cb41e06919fc17b46cc0d2f52d1cb7541 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Sat, 5 Feb 2022 23:31:51 +0100 Subject: [PATCH 12/72] Add `TimeSpan` overloads for `Ping.Send` and `Ping.SendPingAsync` --- .../src/System/Net/NetworkInformation/Ping.cs | 34 +++++ .../tests/FunctionalTests/PingTest.cs | 141 ++++++++++++++++++ 2 files changed, 175 insertions(+) diff --git a/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs b/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs index 51bde54c68e3a1..93761cf1f12f17 100644 --- a/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs +++ b/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs @@ -237,6 +237,18 @@ public PingReply Send(IPAddress address, int timeout, byte[] buffer, PingOptions } } + public PingReply Send(IPAddress address, TimeSpan timeout, byte[]? buffer = null, PingOptions? options = null) + { + int milliseconds = (int)timeout.TotalMilliseconds; + return Send(address, milliseconds, buffer ?? DefaultSendBuffer, options); + } + + public PingReply Send(string hostNameOrAddress, TimeSpan timeout, byte[]? buffer = null, PingOptions? options = null) + { + int milliseconds = (int)timeout.TotalMilliseconds; + return Send(hostNameOrAddress, milliseconds, buffer ?? DefaultSendBuffer, options); + } + public void SendAsync(string hostNameOrAddress, object? userToken) { SendAsync(hostNameOrAddress, DefaultTimeout, DefaultSendBuffer, userToken); @@ -324,6 +336,28 @@ public Task SendPingAsync(IPAddress address, int timeout, byte[] buff return SendPingAsyncInternal(address, timeout, buffer, options); } + public Task SendPingAsync(IPAddress address, TimeSpan timeout, byte[]? buffer = null, + PingOptions? options = null, CancellationToken cancellationToken = default) + { + int milliseconds = (int)timeout.TotalMilliseconds; + + cancellationToken.ThrowIfCancellationRequested(); + Task task = SendPingAsync(address, milliseconds, buffer ?? DefaultSendBuffer, options); + + return task.WaitAsync(cancellationToken); + } + + public Task SendPingAsync(string hostNameOrAddress, TimeSpan timeout, byte[]? buffer = null, + PingOptions? options = null, CancellationToken cancellationToken = default) + { + int milliseconds = (int)timeout.TotalMilliseconds; + + cancellationToken.ThrowIfCancellationRequested(); + Task task = SendPingAsync(hostNameOrAddress, milliseconds, buffer ?? DefaultSendBuffer, options); + + return task.WaitAsync(cancellationToken); + } + private async Task SendPingAsyncInternal(IPAddress address, int timeout, byte[] buffer, PingOptions? options) { // Need to snapshot the address here, so we're sure that it's not changed between now diff --git a/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs b/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs index 57a0a33c44609a..94f9a4fe415c4e 100644 --- a/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs +++ b/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs @@ -129,6 +129,56 @@ public async Task SendPingAsync_InvalidArgs() AssertExtensions.Throws("buffer", () => { p.Send(TestSettings.LocalHost, 1, new byte[65501]); }); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + public async Task SendPingAsync_InvalidArgs_TimeSpan() + { + IPAddress localIpAddress = await TestSettings.GetLocalIPAddressAsync(); + Ping p = new Ping(); + + // Null address + AssertExtensions.Throws("address", () => { p.SendPingAsync((IPAddress)null); }); + AssertExtensions.Throws("hostNameOrAddress", () => { p.SendPingAsync((string)null); }); + AssertExtensions.Throws("address", () => { p.SendAsync((IPAddress)null, null); }); + AssertExtensions.Throws("hostNameOrAddress", () => { p.SendAsync((string)null, null); }); + AssertExtensions.Throws("address", () => { p.Send((IPAddress)null); }); + AssertExtensions.Throws("hostNameOrAddress", () => { p.Send((string)null); }); + + // Invalid address + AssertExtensions.Throws("address", () => { p.SendPingAsync(IPAddress.Any); }); + AssertExtensions.Throws("address", () => { p.SendPingAsync(IPAddress.IPv6Any); }); + AssertExtensions.Throws("address", () => { p.SendAsync(IPAddress.Any, null); }); + AssertExtensions.Throws("address", () => { p.SendAsync(IPAddress.IPv6Any, null); }); + AssertExtensions.Throws("address", () => { p.Send(IPAddress.Any); }); + AssertExtensions.Throws("address", () => { p.Send(IPAddress.IPv6Any); }); + + // Negative timeout + TimeSpan negativeTimeout = TimeSpan.FromMilliseconds(-1); + AssertExtensions.Throws("timeout", () => { p.SendPingAsync(localIpAddress, negativeTimeout); }); + AssertExtensions.Throws("timeout", () => { p.SendPingAsync(TestSettings.LocalHost, negativeTimeout); }); + AssertExtensions.Throws("timeout", () => { p.SendAsync(localIpAddress, negativeTimeout, null); }); + AssertExtensions.Throws("timeout", () => { p.SendAsync(TestSettings.LocalHost, negativeTimeout, null); }); + AssertExtensions.Throws("timeout", () => { p.Send(localIpAddress, negativeTimeout); }); + AssertExtensions.Throws("timeout", () => { p.Send(TestSettings.LocalHost, negativeTimeout); }); + + // Null byte[] + TimeSpan zeroTimeout = TimeSpan.FromMilliseconds(0); + AssertExtensions.Throws("buffer", () => { p.SendPingAsync(localIpAddress, zeroTimeout, null); }); + AssertExtensions.Throws("buffer", () => { p.SendPingAsync(TestSettings.LocalHost, zeroTimeout, null); }); + AssertExtensions.Throws("buffer", () => { p.SendAsync(localIpAddress, zeroTimeout, null, null); }); + AssertExtensions.Throws("buffer", () => { p.SendAsync(TestSettings.LocalHost, zeroTimeout, null, null); }); + AssertExtensions.Throws("buffer", () => { p.Send(localIpAddress, zeroTimeout, null); }); + AssertExtensions.Throws("buffer", () => { p.Send(TestSettings.LocalHost, zeroTimeout, null); }); + + // Too large byte[] + TimeSpan oneTimeout = TimeSpan.FromMilliseconds(1); + AssertExtensions.Throws("buffer", () => { p.SendPingAsync(localIpAddress, oneTimeout, new byte[65501]); }); + AssertExtensions.Throws("buffer", () => { p.SendPingAsync(TestSettings.LocalHost, oneTimeout, new byte[65501]); }); + AssertExtensions.Throws("buffer", () => { p.SendAsync(localIpAddress, oneTimeout, new byte[65501], null); }); + AssertExtensions.Throws("buffer", () => { p.SendAsync(TestSettings.LocalHost, oneTimeout, new byte[65501], null); }); + AssertExtensions.Throws("buffer", () => { p.Send(localIpAddress, oneTimeout, new byte[65501]); }); + AssertExtensions.Throws("buffer", () => { p.Send(TestSettings.LocalHost, oneTimeout, new byte[65501]); }); + } + [Theory] [InlineData(AddressFamily.InterNetwork)] [InlineData(AddressFamily.InterNetworkV6)] @@ -149,6 +199,27 @@ public void SendPingWithIPAddress(AddressFamily addressFamily) }); } + [Theory] + [InlineData(AddressFamily.InterNetwork)] + [InlineData(AddressFamily.InterNetworkV6)] + public void SendPingWithIPAddress(AddressFamily addressFamily) + { + IPAddress localIpAddress = TestSettings.GetLocalIPAddress(addressFamily); + if (localIpAddress == null) + { + // No local address for given address family. + return; + } + + TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); + SendBatchPing( + ping => ping.Send(localIpAddress, pingTimeout), + pingReply => + { + PingResultValidator(pingReply, localIpAddress); + }); + } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] [InlineData(AddressFamily.InterNetwork)] [InlineData(AddressFamily.InterNetworkV6)] @@ -228,6 +299,20 @@ await SendBatchPingAsync( }); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + public async Task SendPingAsyncWithIPAddressAndTimeout_TimeSpan() + { + IPAddress localIpAddress = await TestSettings.GetLocalIPAddressAsync(); + + TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); + await SendBatchPingAsync( + ping => ping.SendPingAsync(localIpAddress, pingTimeout), + pingReply => + { + PingResultValidator(pingReply, localIpAddress); + }); + } + [Fact] public void SendPingWithIPAddressAndTimeoutAndBuffer() { @@ -258,6 +343,22 @@ await SendBatchPingAsync( }); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + public async Task SendPingAsyncWithIPAddressAndTimeoutAndBuffer_TimeSpan() + { + IPAddress localIpAddress = await TestSettings.GetLocalIPAddressAsync(); + byte[] buffer = GetPingPayload(localIpAddress.AddressFamily); + + TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); + await SendBatchPingAsync( + ping => ping.SendPingAsync(localIpAddress, pingTimeout, buffer), + (pingReply) => + { + PingResultValidator(pingReply, localIpAddress); + Assert.Equal(buffer, pingReply.Buffer); + }); + } + [PlatformSpecific(TestPlatforms.Windows)] [Fact] public void SendPingWithIPAddressAndTimeoutAndBufferAndPingOptions() @@ -276,6 +377,26 @@ public void SendPingWithIPAddressAndTimeoutAndBufferAndPingOptions() }); } + [PlatformSpecific(TestPlatforms.Windows)] + [Fact] + public void SendPingWithIPAddressAndTimeoutAndBufferAndPingOptions_TimeSpan() + { + IPAddress localIpAddress = TestSettings.GetLocalIPAddress(); + + var options = new PingOptions(); + byte[] buffer = TestSettings.PayloadAsBytes; + + TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); + SendBatchPing( + ping => ping.Send(localIpAddress, pingTimeout, buffer, options), + pingReply => + { + PingResultValidator(pingReply, localIpAddress); + Assert.Equal(buffer, pingReply.Buffer); + Assert.InRange(pingReply.RoundtripTime, 0, long.MaxValue); + }); + } + [PlatformSpecific(TestPlatforms.Windows)] [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public async Task SendPingAsyncWithIPAddressAndTimeoutAndBufferAndPingOptions() @@ -294,6 +415,26 @@ await SendBatchPingAsync( }); } + [PlatformSpecific(TestPlatforms.Windows)] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + public async Task SendPingAsyncWithIPAddressAndTimeoutAndBufferAndPingOptions_TimeSpan() + { + IPAddress localIpAddress = await TestSettings.GetLocalIPAddressAsync(); + + var options = new PingOptions(); + byte[] buffer = TestSettings.PayloadAsBytes; + + TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); + await SendBatchPingAsync( + ping => ping.SendPingAsync(localIpAddress, pingTimeout, buffer, options), + pingReply => + { + PingResultValidator(pingReply, localIpAddress); + Assert.Equal(buffer, pingReply.Buffer); + Assert.InRange(pingReply.RoundtripTime, 0, long.MaxValue); + }); + } + [PlatformSpecific(TestPlatforms.AnyUnix)] [Theory] [InlineData(AddressFamily.InterNetwork)] From 829d4129548d2f2e45a5eb76758f1f669e15da9f Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Sat, 5 Feb 2022 23:53:44 +0100 Subject: [PATCH 13/72] Add more tests for `Ping.Send` and `Ping.SendPingAsync` --- .../tests/FunctionalTests/PingTest.cs | 313 +++++++++++++++++- 1 file changed, 311 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs b/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs index 94f9a4fe415c4e..7514c7458b283a 100644 --- a/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs +++ b/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs @@ -285,6 +285,20 @@ public void SendPingWithIPAddressAndTimeout() PingResultValidator(pingReply, localIpAddress); }); } + [Fact] + + public void SendPingWithIPAddressAndTimeout_TimeSpan() + { + IPAddress localIpAddress = TestSettings.GetLocalIPAddress(); + + TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); + SendBatchPing( + ping => ping.Send(localIpAddress, pingTimeout), + pingReply => + { + PingResultValidator(pingReply, localIpAddress); + }); + } [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public async Task SendPingAsyncWithIPAddressAndTimeout() @@ -328,6 +342,22 @@ public void SendPingWithIPAddressAndTimeoutAndBuffer() }); } + [Fact] + public void SendPingWithIPAddressAndTimeoutAndBuffer_TimeSpan() + { + IPAddress localIpAddress = TestSettings.GetLocalIPAddress(); + byte[] buffer = GetPingPayload(localIpAddress.AddressFamily); + + TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); + SendBatchPing( + ping => ping.Send(localIpAddress, pingTimeout, buffer), + pingReply => + { + PingResultValidator(pingReply, localIpAddress); + Assert.Equal(buffer, pingReply.Buffer); + }); + } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public async Task SendPingAsyncWithIPAddressAndTimeoutAndBuffer() { @@ -352,7 +382,7 @@ public async Task SendPingAsyncWithIPAddressAndTimeoutAndBuffer_TimeSpan() TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); await SendBatchPingAsync( ping => ping.SendPingAsync(localIpAddress, pingTimeout, buffer), - (pingReply) => + pingReply => { PingResultValidator(pingReply, localIpAddress); Assert.Equal(buffer, pingReply.Buffer); @@ -459,6 +489,31 @@ public void SendPingWithIPAddressAndTimeoutAndBufferAndPingOptions_Unix(AddressF }); } + [PlatformSpecific(TestPlatforms.AnyUnix)] + [Theory] + [InlineData(AddressFamily.InterNetwork)] + [InlineData(AddressFamily.InterNetworkV6)] + public void SendPingWithIPAddressAndTimeoutAndBufferAndPingOptions_Unix_TimeSpan(AddressFamily addressFamily) + { + IPAddress localIpAddress = TestSettings.GetLocalIPAddress(addressFamily); + if (localIpAddress == null) + { + // No local address for given address family. + return; + } + + byte[] buffer = GetPingPayload(localIpAddress.AddressFamily); + + TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); + SendBatchPing( + ping => ping.Send(localIpAddress, pingTimeout, buffer, new PingOptions()), + pingReply => + { + PingResultValidator(pingReply, localIpAddress); + Assert.Equal(buffer, pingReply.Buffer); + }); + } + [PlatformSpecific(TestPlatforms.AnyUnix)] [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] [InlineData(AddressFamily.InterNetwork)] @@ -483,6 +538,31 @@ await SendBatchPingAsync( }); } + [PlatformSpecific(TestPlatforms.AnyUnix)] + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [InlineData(AddressFamily.InterNetwork)] + [InlineData(AddressFamily.InterNetworkV6)] + public async Task SendPingAsyncWithIPAddressAndTimeoutAndBufferAndPingOptions_Unix_TimeSpan(AddressFamily addressFamily) + { + IPAddress localIpAddress = await TestSettings.GetLocalIPAddressAsync(addressFamily); + if (localIpAddress == null) + { + // No local address for given address family. + return; + } + + byte[] buffer = GetPingPayload(localIpAddress.AddressFamily); + + TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); + await SendBatchPingAsync( + ping => ping.SendPingAsync(localIpAddress, pingTimeout, buffer, new PingOptions()), + pingReply => + { + PingResultValidator(pingReply, localIpAddress); + Assert.Equal(buffer, pingReply.Buffer); + }); + } + [Fact] public void SendPingWithHost() { @@ -522,6 +602,20 @@ public void SendPingWithHostAndTimeout() }); } + [Fact] + public void SendPingWithHostAndTimeout_TimeSpan() + { + IPAddress[] localIpAddresses = TestSettings.GetLocalIPAddresses(); + + TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); + SendBatchPing( + ping => ping.Send(TestSettings.LocalHost, pingTimeout), + pingReply => + { + PingResultValidator(pingReply, localIpAddresses); + }); + } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public async Task SendPingAsyncWithHostAndTimeout() { @@ -535,6 +629,20 @@ await SendBatchPingAsync( }); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + public async Task SendPingAsyncWithHostAndTimeout_TimeSpan() + { + IPAddress[] localIpAddresses = await TestSettings.GetLocalIPAddressesAsync(); + + TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); + await SendBatchPingAsync( + ping => ping.SendPingAsync(TestSettings.LocalHost, pingTimeout), + pingReply => + { + PingResultValidator(pingReply, localIpAddresses); + }); + } + [Fact] public void SendPingWithHostAndTimeoutAndBuffer() { @@ -550,6 +658,22 @@ public void SendPingWithHostAndTimeoutAndBuffer() }); } + [Fact] + public void SendPingWithHostAndTimeoutAndBuffer_TimeSpan() + { + IPAddress localIpAddress = TestSettings.GetLocalIPAddress(); + byte[] buffer = GetPingPayload(localIpAddress.AddressFamily); + + TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); + SendBatchPing( + ping => ping.Send(TestSettings.LocalHost, pingTimeout, buffer), + pingReply => + { + PingResultValidator(pingReply, localIpAddress); + Assert.Equal(buffer, pingReply.Buffer); + }); + } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public async Task SendPingAsyncWithHostAndTimeoutAndBuffer() { @@ -565,6 +689,22 @@ await SendBatchPingAsync( }); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + public async Task SendPingAsyncWithHostAndTimeoutAndBuffer_TimeSpan() + { + IPAddress localIpAddress = await TestSettings.GetLocalIPAddressAsync(); + byte[] buffer = GetPingPayload(localIpAddress.AddressFamily); + + TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); + await SendBatchPingAsync( + ping => ping.SendPingAsync(TestSettings.LocalHost, pingTimeout, buffer), + pingReply => + { + PingResultValidator(pingReply, localIpAddress); + Assert.Equal(buffer, pingReply.Buffer); + }); + } + [Fact] public void SendPingWithHostAndTimeoutAndBufferAndPingOptions() { @@ -580,6 +720,22 @@ public void SendPingWithHostAndTimeoutAndBufferAndPingOptions() }); } + [Fact] + public void SendPingWithHostAndTimeoutAndBufferAndPingOptions_TimeSpan() + { + IPAddress localIpAddress = TestSettings.GetLocalIPAddress(); + byte[] buffer = GetPingPayload(localIpAddress.AddressFamily); + + TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); + SendBatchPing( + ping => ping.Send(TestSettings.LocalHost, pingTimeout, buffer, new PingOptions()), + pingReply => + { + PingResultValidator(pingReply, localIpAddress); + Assert.Equal(buffer, pingReply.Buffer); + }); + } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public async Task SendPingAsyncWithHostAndTimeoutAndBufferAndPingOptions() { @@ -596,6 +752,23 @@ await SendBatchPingAsync( }); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + public async Task SendPingAsyncWithHostAndTimeoutAndBufferAndPingOptions_TimeSpan() + { + IPAddress localIpAddress = await TestSettings.GetLocalIPAddressAsync(); + byte[] buffer = GetPingPayload(localIpAddress.AddressFamily); + + TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); + await SendBatchPingAsync( + ping => ping.SendPingAsync(TestSettings.LocalHost, pingTimeout, buffer, new PingOptions()), + pingReply => + { + PingResultValidator(pingReply, localIpAddress); + + Assert.Equal(buffer, pingReply.Buffer); + }); + } + [ConditionalFact(nameof(DoesNotUsePingUtility))] public async Task SendPingWithIPAddressAndBigSize() { @@ -619,6 +792,29 @@ public async Task SendPingWithIPAddressAndBigSize() } } + [ConditionalFact(nameof(DoesNotUsePingUtility))] + public async Task SendPingWithIPAddressAndBigSize_TimeSpan() + { + IPAddress localIpAddress = TestSettings.GetLocalIPAddress(); + + using Ping p = new(); + TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); + + // Assert.DoesNotThrow + PingReply pingReply = await p.SendPingAsync(localIpAddress, pingTimeout, new byte[10001]); + + // Depending on platform the call may either succeed, report timeout or report too big packet. It + // should not throw wrapped SocketException though which is what this test guards. + // + // On Windows 10 the maximum ping size seems essentially limited to 65500 bytes and thus any buffer + // size on the loopback ping succeeds. On macOS anything bigger than 8184 will report packet too + // big error. + if (OperatingSystem.IsMacOS()) + { + Assert.Equal(IPStatus.PacketTooBig, pingReply.Status); + } + } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public async Task SendPings_ReuseInstance_Hostname() { @@ -790,7 +986,7 @@ public async Task SendPingAsyncWithHostAndTtlAndFragmentPingOptions(bool fragmen byte[] buffer = GetPingPayload(localIpAddresses[0].AddressFamily); - PingOptions options = new PingOptions(); + PingOptions options = new PingOptions(); options.Ttl = 32; options.DontFragment = fragment; @@ -802,6 +998,26 @@ await SendBatchPingAsync( }); } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [InlineData(true)] + [InlineData(false)] + public async Task SendPingAsyncWithHostAndTtlAndFragmentPingOptions_TimeSpan(bool fragment) + { + IPAddress[] localIpAddresses = await TestSettings.GetLocalIPAddressesAsync(); + + byte[] buffer = GetPingPayload(localIpAddresses[0].AddressFamily); + + PingOptions options = new() { Ttl = 32, DontFragment = fragment }; + + TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); + await SendBatchPingAsync( + ping => ping.SendPingAsync(TestSettings.LocalHost, pingTimeout, buffer, options), + pingReply => + { + PingResultValidator(pingReply, localIpAddresses); + }); + } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] [OuterLoop] // Depends on external host and assumption that network respects and does not change TTL public async Task SendPingToExternalHostWithLowTtlTest() @@ -833,6 +1049,40 @@ public async Task SendPingToExternalHostWithLowTtlTest() Assert.NotEqual(IPAddress.Any, pingReply.Address); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [OuterLoop] // Depends on external host and assumption that network respects and does not change TTL + public async Task SendPingToExternalHostWithLowTtlTest_TimeSpan() + { + string host = System.Net.Test.Common.Configuration.Ping.PingHost; + PingReply pingReply; + PingOptions options = new(); + bool reachable = false; + + Ping ping = new(); + TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); + for (int i = 0; i < s_pingcount; i++) + { + pingReply = await ping.SendPingAsync(host, pingTimeout, TestSettings.PayloadAsBytesShort); + if (pingReply.Status != IPStatus.Success) + { + continue; + } + + reachable = true; + break; + } + if (!reachable) + { + throw new SkipTestException($"Host {host} is not reachable. Skipping test."); + } + + options.Ttl = 1; + // This should always fail unless host is one IP hop away. + pingReply = await ping.SendPingAsync(host, pingTimeout, TestSettings.PayloadAsBytesShort, options); + Assert.True(pingReply.Status is IPStatus.TimeExceeded or IPStatus.TtlExpired); + Assert.NotEqual(IPAddress.Any, pingReply.Address); + } + [Fact] [OuterLoop] public void Ping_TimedOut_Sync_Success() @@ -945,6 +1195,43 @@ public void SendPing_LocaleEnvVarsMustBeIgnored(AddressFamily addressFamily, str }, localIpAddress.ToString(), new RemoteInvokeOptions { StartInfo = remoteInvokeStartInfo }).Dispose(); } + [PlatformSpecific(TestPlatforms.AnyUnix)] + [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + [InlineData(AddressFamily.InterNetwork, "ja_JP.UTF8", null, null)] + [InlineData(AddressFamily.InterNetwork, "en_US.UTF8", "ja_JP.UTF8", null)] + [InlineData(AddressFamily.InterNetwork, "en_US.UTF8", null, "ja_JP.UTF8")] + [InlineData(AddressFamily.InterNetworkV6, "ja_JP.UTF8", null, null)] + [InlineData(AddressFamily.InterNetworkV6, "en_US.UTF8", "ja_JP.UTF8", null)] + [InlineData(AddressFamily.InterNetworkV6, "en_US.UTF8", null, "ja_JP.UTF8")] + public void SendPing_LocaleEnvVarsMustBeIgnored_TimeSpan(AddressFamily addressFamily, string envVar_LANG, string envVar_LC_MESSAGES, string envVar_LC_ALL) + { + IPAddress localIpAddress = TestSettings.GetLocalIPAddress(addressFamily); + if (localIpAddress == null) + { + // No local address for given address family. + return; + } + + var remoteInvokeStartInfo = new ProcessStartInfo { EnvironmentVariables = + { + ["LANG"] = envVar_LANG, + ["LC_MESSAGES"] = envVar_LC_MESSAGES, + ["LC_ALL"] = envVar_LC_ALL + } + }; + + TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); + RemoteExecutor.Invoke(address => + { + SendBatchPing( + ping => ping.Send(address, pingTimeout), + (pingReply) => + { + PingResultValidator(pingReply, new[] { IPAddress.Parse(address) }, null); + }); + }, localIpAddress.ToString(), new RemoteInvokeOptions { StartInfo = remoteInvokeStartInfo }).Dispose(); + } + [PlatformSpecific(TestPlatforms.AnyUnix)] [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] [InlineData(AddressFamily.InterNetwork, "ja_JP.UTF8", null, null)] @@ -989,6 +1276,17 @@ public void SendPing_CustomPayload_InsufficientPrivileges_Throws() Assert.Throws(() => ping.Send(TestSettings.LocalHost, TestSettings.PingTimeout, buffer)); } + [ConditionalFact(nameof(UsesPingUtility))] + public void SendPing_CustomPayload_InsufficientPrivileges_Throws_TimeSpan() + { + IPAddress[] localIpAddresses = TestSettings.GetLocalIPAddresses(); + + byte[] buffer = TestSettings.PayloadAsBytes; + TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); + Ping ping = new(); + Assert.Throws(() => ping.Send(TestSettings.LocalHost, pingTimeout, buffer)); + } + [ConditionalFact(nameof(UsesPingUtility))] public async Task SendPingAsync_CustomPayload_InsufficientPrivileges_Throws() { @@ -998,5 +1296,16 @@ public async Task SendPingAsync_CustomPayload_InsufficientPrivileges_Throws() Ping ping = new Ping(); await Assert.ThrowsAsync(() => ping.SendPingAsync(TestSettings.LocalHost, TestSettings.PingTimeout, buffer)); } + + [ConditionalFact(nameof(UsesPingUtility))] + public async Task SendPingAsync_CustomPayload_InsufficientPrivileges_Throws_TimeSpan() + { + IPAddress[] localIpAddresses = TestSettings.GetLocalIPAddresses(); + + byte[] buffer = TestSettings.PayloadAsBytes; + TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); + Ping ping = new(); + await Assert.ThrowsAsync(() => ping.SendPingAsync(TestSettings.LocalHost, pingTimeout, buffer)); + } } } From f413126ea1eda81396646cbb70f3857ee8f27398 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Sun, 6 Feb 2022 00:08:54 +0100 Subject: [PATCH 14/72] Add tests for `NamedPipeClientStream.Connect` and `NamedPipeClientStream.ConnectAsync` --- .../NamedPipeTest.CurrentUserOnly.Windows.cs | 25 +++++++++++++- .../NamedPipeTests/NamedPipeTest.Specific.cs | 34 ++++++++++++++++--- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.CurrentUserOnly.Windows.cs b/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.CurrentUserOnly.Windows.cs index 439454502655d8..8e3810b1fe2342 100644 --- a/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.CurrentUserOnly.Windows.cs +++ b/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.CurrentUserOnly.Windows.cs @@ -167,7 +167,7 @@ public void Allow_Connection_UnderDifferentUsers_ForClientReading() { string name = PipeStreamConformanceTests.GetUniquePipeName(); using (var server = new NamedPipeServerStream( - name, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous)) + name, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous)) { Task serverTask = server.WaitForConnectionAsync(CancellationToken.None); @@ -182,5 +182,28 @@ public void Allow_Connection_UnderDifferentUsers_ForClientReading() Assert.True(serverTask.Wait(10_000)); } } + + [OuterLoop] + [ConditionalFact(nameof(IsAdminOnSupportedWindowsVersions))] + public void Allow_Connection_UnderDifferentUsers_ForClientReading_TimeSpan() + { + string name = PipeStreamConformanceTests.GetUniquePipeName(); + using (var server = new NamedPipeServerStream( + name, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous)) + { + Task serverTask = server.WaitForConnectionAsync(CancellationToken.None); + + _testAccountImpersonator.RunImpersonated(() => + { + using (var client = new NamedPipeClientStream(".", name, PipeDirection.In)) + { + TimeSpan timeout = TimeSpan.FromMilliseconds(10_000); + client.Connect(timeout); + } + }); + + Assert.True(serverTask.Wait(10_000)); + } + } } } diff --git a/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Specific.cs b/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Specific.cs index 7775ab80ae3dce..f13b46290245fb 100644 --- a/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Specific.cs +++ b/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Specific.cs @@ -25,6 +25,16 @@ public void InvalidConnectTimeout_Throws_ArgumentOutOfRangeException() AssertExtensions.Throws("timeout", () => { client.ConnectAsync(-111); }); } } + [Fact] + public void InvalidConnectTimeout_Throws_ArgumentOutOfRangeException_TimeSpan() + { + using (NamedPipeClientStream client = new NamedPipeClientStream("client1")) + { + TimeSpan negativeTimeout = TimeSpan.FromMilliseconds(-111); + AssertExtensions.Throws("timeout", () => client.Connect(negativeTimeout)); + AssertExtensions.Throws("timeout", () => { client.ConnectAsync(negativeTimeout); }); + } + } [Fact] public async Task ConnectToNonExistentServer_Throws_TimeoutException() @@ -616,6 +626,17 @@ public void ClientConnect_Throws_Timeout_When_Pipe_Not_Found() } } + [Fact] + public void ClientConnect_Throws_Timeout_When_Pipe_Not_Found_TimeSpan() + { + string pipeName = PipeStreamConformanceTests.GetUniquePipeName(); + using (NamedPipeClientStream client = new NamedPipeClientStream(pipeName)) + { + TimeSpan timeout = TimeSpan.FromMilliseconds(91); + Assert.Throws(() => client.Connect(timeout)); + } + } + [Theory] [MemberData(nameof(GetCancellationTokens))] public async Task ClientConnectAsync_Throws_Timeout_When_Pipe_Not_Found(CancellationToken cancellationToken) @@ -623,7 +644,8 @@ public async Task ClientConnectAsync_Throws_Timeout_When_Pipe_Not_Found(Cancella string pipeName = PipeStreamConformanceTests.GetUniquePipeName(); using (NamedPipeClientStream client = new NamedPipeClientStream(pipeName)) { - Task waitingClient = client.ConnectAsync(92, cancellationToken); + TimeSpan timeout = TimeSpan.FromMilliseconds(92); + Task waitingClient = client.ConnectAsync(timeout, cancellationToken); await Assert.ThrowsAsync(() => { return waitingClient; }); } } @@ -638,7 +660,7 @@ public void ClientConnect_Throws_Timeout_When_Pipe_Busy() using (NamedPipeClientStream firstClient = new NamedPipeClientStream(pipeName)) using (NamedPipeClientStream secondClient = new NamedPipeClientStream(pipeName)) { - const int timeout = 10_000; + TimeSpan timeout = TimeSpan.FromMilliseconds(10_000); Task[] clientAndServerTasks = new[] { firstClient.ConnectAsync(timeout), @@ -647,7 +669,8 @@ public void ClientConnect_Throws_Timeout_When_Pipe_Busy() Assert.True(Task.WaitAll(clientAndServerTasks, timeout)); - Assert.Throws(() => secondClient.Connect(93)); + TimeSpan connectionTimeout = TimeSpan.FromMilliseconds(93); + Assert.Throws(() => secondClient.Connect(connectionTimeout)); } } @@ -662,7 +685,7 @@ public async Task ClientConnectAsync_With_Cancellation_Throws_Timeout_When_Pipe_ using (NamedPipeClientStream firstClient = new NamedPipeClientStream(pipeName)) using (NamedPipeClientStream secondClient = new NamedPipeClientStream(pipeName)) { - const int timeout = 10_000; + TimeSpan timeout = TimeSpan.FromMilliseconds(10_000); Task[] clientAndServerTasks = new[] { firstClient.ConnectAsync(timeout), @@ -671,7 +694,8 @@ public async Task ClientConnectAsync_With_Cancellation_Throws_Timeout_When_Pipe_ Assert.True(Task.WaitAll(clientAndServerTasks, timeout)); - Task waitingClient = secondClient.ConnectAsync(94, cancellationToken); + TimeSpan connectionTimeout = TimeSpan.FromMilliseconds(94); + Task waitingClient = secondClient.ConnectAsync(connectionTimeout, cancellationToken); await Assert.ThrowsAsync(() => { return waitingClient; }); } } From 516041cf77b16e90cbf878734e8a467df5f7c715 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Sun, 6 Feb 2022 00:20:53 +0100 Subject: [PATCH 15/72] Add more `Task.Wait` tests --- .../tests/Task/TaskAPMTest.cs | 27 +++++++++++ .../tests/Task/TaskContinueWithTests.cs | 47 +++++++++++++++++-- 2 files changed, 71 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Threading.Tasks/tests/Task/TaskAPMTest.cs b/src/libraries/System.Threading.Tasks/tests/Task/TaskAPMTest.cs index fa01ab6b75c892..804989e2071c2b 100644 --- a/src/libraries/System.Threading.Tasks/tests/Task/TaskAPMTest.cs +++ b/src/libraries/System.Threading.Tasks/tests/Task/TaskAPMTest.cs @@ -89,6 +89,33 @@ public void PollUntilCompleteTechnique(bool hasReturnType) Assert.False(asyncResult.CompletedSynchronously, "Should not have completed synchronously."); } + [Theory] + [OuterLoop] + [InlineData(true)] + [InlineData(false)] + public void PollUntilCompleteTechnique_TimeSpan(bool hasReturnType) + { + _hasReturnType = hasReturnType; + + LongTask longTask; + if (_hasReturnType) + longTask = new LongTask(LongTaskMilliseconds); + else + longTask = new LongTask(LongTaskMilliseconds); + + IAsyncResult asyncResult = longTask.BeginDoTask(null, null); + var mres = new ManualResetEventSlim(); + + TimeSpan timeout = TimeSpan.FromMilliseconds(1); + while (!asyncResult.IsCompleted) + { + mres.Wait(timeout); + } + + AssertTaskCompleted(asyncResult); + Assert.False(asyncResult.CompletedSynchronously, "Should not have completed synchronously."); + } + [Theory] [OuterLoop] [InlineData(true)] diff --git a/src/libraries/System.Threading.Tasks/tests/Task/TaskContinueWithTests.cs b/src/libraries/System.Threading.Tasks/tests/Task/TaskContinueWithTests.cs index 39db9ced79c818..a24f496903c5c2 100644 --- a/src/libraries/System.Threading.Tasks/tests/Task/TaskContinueWithTests.cs +++ b/src/libraries/System.Threading.Tasks/tests/Task/TaskContinueWithTests.cs @@ -266,9 +266,9 @@ public static void RunContinuationCancelTest() CancellationTokenSource ctsForT2 = new CancellationTokenSource(); Task t2 = t1.ContinueWith((ContinuedTask) => - { - Assert.True(false, string.Format("RunContinuationCancelTest: > Failed! t2 should not have run.")); - }, ctsForT2.Token); + { + Assert.True(false, string.Format("RunContinuationCancelTest: > Failed! t2 should not have run.")); + }, ctsForT2.Token); Task t3 = t2.ContinueWith((ContinuedTask) => { @@ -295,6 +295,47 @@ public static void RunContinuationCancelTest() } } + // Test what happens when you cancel a task in the middle of a continuation chain. + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + public static void RunContinuationCancelTest_TimeSpan() + { + bool t1Ran = false; + bool t3Ran = false; + + Task t1 = new Task(delegate { t1Ran = true; }); + + CancellationTokenSource ctsForT2 = new CancellationTokenSource(); + Task t2 = t1.ContinueWith((ContinuedTask) => + { + Assert.True(false, string.Format("RunContinuationCancelTest: > Failed! t2 should not have run.")); + }, ctsForT2.Token); + + Task t3 = t2.ContinueWith((ContinuedTask) => + { + t3Ran = true; + }); + + // Cancel the middle task in the chain. Should fire off t3. + ctsForT2.Cancel(); + + // Start the first task in the chain. Should hold off from kicking off (canceled) t2. + t1.Start(); + + TimeSpan timeout = TimeSpan.FromMilliseconds(5000); + t1.Wait(timeout); // should be more than enough time for either of these + t3.Wait(timeout); + + if (!t1Ran) + { + Assert.True(false, string.Format("RunContinuationCancelTest: > Failed! t1 should have run.")); + } + + if (!t3Ran) + { + Assert.True(false, string.Format("RunContinuationCancelTest: > Failed! t3 should have run.")); + } + } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public static void RunContinueWithExceptionTestsNoState() { From 74fb1d92636be807fc2d094899ba727c886996d0 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Sun, 6 Feb 2022 00:50:28 +0100 Subject: [PATCH 16/72] Add ref --- .../ref/System.ComponentModel.Annotations.cs | 1 + .../ref/System.Diagnostics.Process.cs | 2 ++ .../ref/System.IO.FileSystem.Watcher.cs | 1 + src/libraries/System.IO.Pipes/ref/System.IO.Pipes.cs | 2 ++ src/libraries/System.Net.Ping/ref/System.Net.Ping.cs | 4 ++++ src/libraries/System.Net.Sockets/ref/System.Net.Sockets.cs | 3 +++ src/libraries/System.Runtime/ref/System.Runtime.cs | 4 ++++ .../ref/System.ServiceProcess.ServiceController.cs | 1 + 8 files changed, 18 insertions(+) diff --git a/src/libraries/System.ComponentModel.Annotations/ref/System.ComponentModel.Annotations.cs b/src/libraries/System.ComponentModel.Annotations/ref/System.ComponentModel.Annotations.cs index cc7dfb6120ef18..c6a9b98a8eba03 100644 --- a/src/libraries/System.ComponentModel.Annotations/ref/System.ComponentModel.Annotations.cs +++ b/src/libraries/System.ComponentModel.Annotations/ref/System.ComponentModel.Annotations.cs @@ -237,6 +237,7 @@ public partial class RegularExpressionAttribute : System.ComponentModel.DataAnno { public RegularExpressionAttribute([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute(System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.Regex)] string pattern) { } public int MatchTimeoutInMilliseconds { get { throw null; } set { } } + public System.TimeSpan MatchTimeout { get { throw null; } } public string Pattern { get { throw null; } } public override string FormatErrorMessage(string name) { throw null; } public override bool IsValid(object? value) { throw null; } diff --git a/src/libraries/System.Diagnostics.Process/ref/System.Diagnostics.Process.cs b/src/libraries/System.Diagnostics.Process/ref/System.Diagnostics.Process.cs index d6975bd7274153..5dcecba7702110 100644 --- a/src/libraries/System.Diagnostics.Process/ref/System.Diagnostics.Process.cs +++ b/src/libraries/System.Diagnostics.Process/ref/System.Diagnostics.Process.cs @@ -168,9 +168,11 @@ public void Refresh() { } public override string ToString() { throw null; } public void WaitForExit() { } public bool WaitForExit(int milliseconds) { throw null; } + public bool WaitForExit(System.TimeSpan timeout) { throw null; } public System.Threading.Tasks.Task WaitForExitAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public bool WaitForInputIdle() { throw null; } public bool WaitForInputIdle(int milliseconds) { throw null; } + public bool WaitForInputIdle(System.TimeSpan timeout) { throw null; } } [System.ComponentModel.DesignerAttribute("System.Diagnostics.Design.ProcessModuleDesigner, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] public partial class ProcessModule : System.ComponentModel.Component diff --git a/src/libraries/System.IO.FileSystem.Watcher/ref/System.IO.FileSystem.Watcher.cs b/src/libraries/System.IO.FileSystem.Watcher/ref/System.IO.FileSystem.Watcher.cs index 1f926bff17f315..d640d89cfe3888 100644 --- a/src/libraries/System.IO.FileSystem.Watcher/ref/System.IO.FileSystem.Watcher.cs +++ b/src/libraries/System.IO.FileSystem.Watcher/ref/System.IO.FileSystem.Watcher.cs @@ -50,6 +50,7 @@ protected void OnError(System.IO.ErrorEventArgs e) { } protected void OnRenamed(System.IO.RenamedEventArgs e) { } public System.IO.WaitForChangedResult WaitForChanged(System.IO.WatcherChangeTypes changeType) { throw null; } public System.IO.WaitForChangedResult WaitForChanged(System.IO.WatcherChangeTypes changeType, int timeout) { throw null; } + public System.IO.WaitForChangedResult WaitForChanged(System.IO.WatcherChangeTypes changeType, System.TimeSpan timeout) { throw null; } } public partial class InternalBufferOverflowException : System.SystemException { diff --git a/src/libraries/System.IO.Pipes/ref/System.IO.Pipes.cs b/src/libraries/System.IO.Pipes/ref/System.IO.Pipes.cs index 3966988ecad2d1..a7432dbc5a2177 100644 --- a/src/libraries/System.IO.Pipes/ref/System.IO.Pipes.cs +++ b/src/libraries/System.IO.Pipes/ref/System.IO.Pipes.cs @@ -54,9 +54,11 @@ public sealed partial class NamedPipeClientStream : System.IO.Pipes.PipeStream protected internal override void CheckPipePropertyOperations() { } public void Connect() { } public void Connect(int timeout) { } + public void Connect(System.TimeSpan timeout) { } public System.Threading.Tasks.Task ConnectAsync() { throw null; } public System.Threading.Tasks.Task ConnectAsync(int timeout) { throw null; } public System.Threading.Tasks.Task ConnectAsync(int timeout, System.Threading.CancellationToken cancellationToken) { throw null; } + public System.Threading.Tasks.Task ConnectAsync(System.TimeSpan timeout, System.Threading.CancellationToken cancellationToken) { throw null; } public System.Threading.Tasks.Task ConnectAsync(System.Threading.CancellationToken cancellationToken) { throw null; } ~NamedPipeClientStream() { } } diff --git a/src/libraries/System.Net.Ping/ref/System.Net.Ping.cs b/src/libraries/System.Net.Ping/ref/System.Net.Ping.cs index 82dcd06b86b9b7..71d2e314241d63 100644 --- a/src/libraries/System.Net.Ping/ref/System.Net.Ping.cs +++ b/src/libraries/System.Net.Ping/ref/System.Net.Ping.cs @@ -47,6 +47,8 @@ protected void OnPingCompleted(System.Net.NetworkInformation.PingCompletedEventA public System.Net.NetworkInformation.PingReply Send(string hostNameOrAddress, int timeout) { throw null; } public System.Net.NetworkInformation.PingReply Send(string hostNameOrAddress, int timeout, byte[] buffer) { throw null; } public System.Net.NetworkInformation.PingReply Send(string hostNameOrAddress, int timeout, byte[] buffer, System.Net.NetworkInformation.PingOptions? options) { throw null; } + public System.Net.NetworkInformation.PingReply Send(System.Net.IPAddress address, System.TimeSpan timeout, byte[]? buffer, System.Net.NetworkInformation.PingOptions? options) { throw null; } + public System.Net.NetworkInformation.PingReply Send(string hostNameOrAddress, System.TimeSpan timeout, byte[]? buffer, System.Net.NetworkInformation.PingOptions? options) { throw null; } public void SendAsync(System.Net.IPAddress address, int timeout, byte[] buffer, System.Net.NetworkInformation.PingOptions? options, object? userToken) { } public void SendAsync(System.Net.IPAddress address, int timeout, byte[] buffer, object? userToken) { } public void SendAsync(System.Net.IPAddress address, int timeout, object? userToken) { } @@ -64,6 +66,8 @@ public void SendAsyncCancel() { } public System.Threading.Tasks.Task SendPingAsync(string hostNameOrAddress, int timeout) { throw null; } public System.Threading.Tasks.Task SendPingAsync(string hostNameOrAddress, int timeout, byte[] buffer) { throw null; } public System.Threading.Tasks.Task SendPingAsync(string hostNameOrAddress, int timeout, byte[] buffer, System.Net.NetworkInformation.PingOptions? options) { throw null; } + public System.Threading.Tasks.Task SendPingAsync(System.Net.IPAddress address, System.TimeSpan timeout, byte[]? buffer, System.Net.NetworkInformation.PingOptions? options, System.Threading.CancellationToken cancellationToken) { throw null; } + public System.Threading.Tasks.Task SendPingAsync(string hostNameOrAddress, System.TimeSpan timeout, byte[]? buffer, System.Net.NetworkInformation.PingOptions? options, System.Threading.CancellationToken cancellationToken) { throw null; } } public partial class PingCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs { diff --git a/src/libraries/System.Net.Sockets/ref/System.Net.Sockets.cs b/src/libraries/System.Net.Sockets/ref/System.Net.Sockets.cs index e813cca044ee04..b160c2df18c1a4 100644 --- a/src/libraries/System.Net.Sockets/ref/System.Net.Sockets.cs +++ b/src/libraries/System.Net.Sockets/ref/System.Net.Sockets.cs @@ -154,6 +154,7 @@ public override void Write(System.ReadOnlySpan buffer) { } public override System.Threading.Tasks.Task WriteAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; } public override System.Threading.Tasks.ValueTask WriteAsync(System.ReadOnlyMemory buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public override void WriteByte(byte value) { } + public void Close(System.TimeSpan timeout) { } } public enum ProtocolFamily { @@ -371,6 +372,7 @@ public void GetSocketOption(System.Net.Sockets.SocketOptionLevel optionLevel, Sy public void Listen() { } public void Listen(int backlog) { } public bool Poll(int microSeconds, System.Net.Sockets.SelectMode mode) { throw null; } + public bool Poll(System.TimeSpan timeout, System.Net.Sockets.SelectMode mode) { throw null; } public int Receive(byte[] buffer) { throw null; } public int Receive(byte[] buffer, int offset, int size, System.Net.Sockets.SocketFlags socketFlags) { throw null; } public int Receive(byte[] buffer, int offset, int size, System.Net.Sockets.SocketFlags socketFlags, out System.Net.Sockets.SocketError errorCode) { throw null; } @@ -408,6 +410,7 @@ public void Listen(int backlog) { } public System.Threading.Tasks.ValueTask ReceiveMessageFromAsync(System.Memory buffer, System.Net.Sockets.SocketFlags socketFlags, System.Net.EndPoint remoteEndPoint, System.Threading.CancellationToken cancellationToken = default) { throw null; } public bool ReceiveMessageFromAsync(System.Net.Sockets.SocketAsyncEventArgs e) { throw null; } public static void Select(System.Collections.IList? checkRead, System.Collections.IList? checkWrite, System.Collections.IList? checkError, int microSeconds) { } + public static void Select(System.Collections.IList? checkRead, System.Collections.IList? checkWrite, System.Collections.IList? checkError, System.TimeSpan timeout) { } public int Send(byte[] buffer) { throw null; } public int Send(byte[] buffer, int offset, int size, System.Net.Sockets.SocketFlags socketFlags) { throw null; } public int Send(byte[] buffer, int offset, int size, System.Net.Sockets.SocketFlags socketFlags, out System.Net.Sockets.SocketError errorCode) { throw null; } diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 4bd98a48d68db6..ae1448726c426b 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -2947,8 +2947,10 @@ public static void SuppressFinalize(object obj) { } public static bool TryStartNoGCRegion(long totalSize, long lohSize, bool disallowFullBlockingGC) { throw null; } public static System.GCNotificationStatus WaitForFullGCApproach() { throw null; } public static System.GCNotificationStatus WaitForFullGCApproach(int millisecondsTimeout) { throw null; } + public static System.GCNotificationStatus WaitForFullGCApproach(System.TimeSpan timeout) { throw null; } public static System.GCNotificationStatus WaitForFullGCComplete() { throw null; } public static System.GCNotificationStatus WaitForFullGCComplete(int millisecondsTimeout) { throw null; } + public static System.GCNotificationStatus WaitForFullGCComplete(System.TimeSpan timeout) { throw null; } public static void WaitForPendingFinalizers() { } } public enum GCCollectionMode @@ -14875,6 +14877,7 @@ public static partial class Timeout } public sealed partial class Timer : System.MarshalByRefObject, System.IAsyncDisposable, System.IDisposable { + public Timer(System.TimeSpan interval) { } public Timer(System.Threading.TimerCallback callback) { } public Timer(System.Threading.TimerCallback callback, object? state, int dueTime, int period) { } public Timer(System.Threading.TimerCallback callback, object? state, long dueTime, long period) { } @@ -15016,6 +15019,7 @@ public void Wait() { } public bool Wait(int millisecondsTimeout, System.Threading.CancellationToken cancellationToken) { throw null; } public void Wait(System.Threading.CancellationToken cancellationToken) { } public bool Wait(System.TimeSpan timeout) { throw null; } + public bool Wait(System.TimeSpan timeout, System.Threading.CancellationToken cancellationToken) { throw null; } [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] public static void WaitAll(params System.Threading.Tasks.Task[] tasks) { } [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] diff --git a/src/libraries/System.ServiceProcess.ServiceController/ref/System.ServiceProcess.ServiceController.cs b/src/libraries/System.ServiceProcess.ServiceController/ref/System.ServiceProcess.ServiceController.cs index 5846cec5477c90..5361cd6c8d3adb 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/ref/System.ServiceProcess.ServiceController.cs +++ b/src/libraries/System.ServiceProcess.ServiceController/ref/System.ServiceProcess.ServiceController.cs @@ -51,6 +51,7 @@ protected virtual void OnShutdown() { } protected virtual void OnStart(string[] args) { } protected virtual void OnStop() { } public void RequestAdditionalTime(int milliseconds) { } + public void RequestAdditionalTime(System.TimeSpan time) { } public static void Run(System.ServiceProcess.ServiceBase service) { } public static void Run(System.ServiceProcess.ServiceBase[] services) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] From 7deaa98edaecebd1f169d8807036c1a463d3693a Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Thu, 10 Feb 2022 20:35:09 +0100 Subject: [PATCH 17/72] Refactor RunContinuationCancelTest_TimeSpan test --- .../tests/Task/TaskContinueWithTests.cs | 25 +++++++------------ 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/src/libraries/System.Threading.Tasks/tests/Task/TaskContinueWithTests.cs b/src/libraries/System.Threading.Tasks/tests/Task/TaskContinueWithTests.cs index a24f496903c5c2..26edff03786f46 100644 --- a/src/libraries/System.Threading.Tasks/tests/Task/TaskContinueWithTests.cs +++ b/src/libraries/System.Threading.Tasks/tests/Task/TaskContinueWithTests.cs @@ -302,38 +302,31 @@ public static void RunContinuationCancelTest_TimeSpan() bool t1Ran = false; bool t3Ran = false; - Task t1 = new Task(delegate { t1Ran = true; }); + Task t1 = new(delegate { t1Ran = true; }); - CancellationTokenSource ctsForT2 = new CancellationTokenSource(); - Task t2 = t1.ContinueWith((ContinuedTask) => + CancellationTokenSource ctsForT2 = new(); + Task t2 = t1.ContinueWith(_ => { - Assert.True(false, string.Format("RunContinuationCancelTest: > Failed! t2 should not have run.")); + Assert.True(false, "t2 should not have run."); }, ctsForT2.Token); - Task t3 = t2.ContinueWith((ContinuedTask) => + Task t3 = t2.ContinueWith(_ => { t3Ran = true; }); - // Cancel the middle task in the chain. Should fire off t3. + // Cancel the middle task in the chain. Should fire off t3. ctsForT2.Cancel(); - // Start the first task in the chain. Should hold off from kicking off (canceled) t2. + // Start the first task in the chain. Should hold off from kicking off (canceled) t2. t1.Start(); TimeSpan timeout = TimeSpan.FromMilliseconds(5000); t1.Wait(timeout); // should be more than enough time for either of these t3.Wait(timeout); - if (!t1Ran) - { - Assert.True(false, string.Format("RunContinuationCancelTest: > Failed! t1 should have run.")); - } - - if (!t3Ran) - { - Assert.True(false, string.Format("RunContinuationCancelTest: > Failed! t3 should have run.")); - } + Assert.True(t1Ran, "t1 should have run."); + Assert.True(t3Ran, "t3 should have run."); } [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] From 6827e20cc673dec5f8a728687beea6e79ad889ce Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Thu, 10 Feb 2022 20:37:46 +0100 Subject: [PATCH 18/72] Remove redundant code duplication --- .../src/System/ServiceProcess/ServiceBase.cs | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs b/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs index 0fccc8db3a2db6..c5e13ab448fb85 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs +++ b/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs @@ -81,20 +81,7 @@ public unsafe void RequestAdditionalTime(int milliseconds) public unsafe void RequestAdditionalTime(TimeSpan time) { int milliseconds = (int)time.TotalMilliseconds; - fixed (SERVICE_STATUS* pStatus = &_status) - { - if (_status.currentState != ServiceControlStatus.STATE_CONTINUE_PENDING && - _status.currentState != ServiceControlStatus.STATE_START_PENDING && - _status.currentState != ServiceControlStatus.STATE_STOP_PENDING && - _status.currentState != ServiceControlStatus.STATE_PAUSE_PENDING) - { - throw new InvalidOperationException(SR.NotInPendingState); - } - - _status.waitHint = milliseconds; - _status.checkPoint++; - SetServiceStatus(_statusHandle, pStatus); - } + RequestAdditionalTime(milliseconds); } /// From 615b66e33ed733f1cb2b3e946580190e2c0e0e25 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Thu, 10 Feb 2022 20:39:22 +0100 Subject: [PATCH 19/72] Remove extra line --- .../System.Net.Sockets/tests/FunctionalTests/Connect.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs index c03beb2fe8710c..740d8f344d39e0 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs @@ -369,7 +369,6 @@ public async Task FailedConnect_ConnectedReturnsFalse_TimeSpan() // Connect to port 1 where we expect no server to be listening. SocketException se = await Assert.ThrowsAnyAsync(() => ConnectAsync(socket, new IPEndPoint(IPAddress.Loopback, 1))); - if (se.SocketErrorCode != SocketError.ConnectionRefused) { Assert.Equal(SocketError.WouldBlock, se.SocketErrorCode); From 6413304431ab1ef298b4b5b2c7899d299883938f Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Thu, 10 Feb 2022 20:41:23 +0100 Subject: [PATCH 20/72] Use meaningful timeSpan --- .../System.Net.Sockets/tests/FunctionalTests/Connect.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs index 740d8f344d39e0..e339d2c60f6c79 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs @@ -363,7 +363,7 @@ public async Task FailedConnect_ConnectedReturnsFalse() [Fact] public async Task FailedConnect_ConnectedReturnsFalse_TimeSpan() { - TimeSpan timeSpan = TimeSpan.FromMilliseconds(5_000_000L * 1000); + TimeSpan timeSpan = TimeSpan.FromSeconds(30); using Socket socket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // Connect to port 1 where we expect no server to be listening. From 004914c4b429a0677e9f419fd0182fac6be1164c Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Thu, 10 Feb 2022 20:44:52 +0100 Subject: [PATCH 21/72] Use Timeout.InfiniteTimeSpan --- .../tests/FunctionalTests/ArgumentValidationTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ArgumentValidationTests.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/ArgumentValidationTests.cs index f242e30114e123..20e074da80f9f2 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ArgumentValidationTests.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/ArgumentValidationTests.cs @@ -358,7 +358,7 @@ public void Select_NullOrEmptyLists_Throws_ArgumentNull() [Fact] public void Select_NullOrEmptyLists_Throws_ArgumentNull_TimeSpan() { - TimeSpan infinity = TimeSpan.FromMilliseconds(-1); + TimeSpan infinity = Timeout.InfiniteTimeSpan; var emptyList = new List(); Assert.Throws(() => Socket.Select(null, null, null, infinity)); @@ -384,7 +384,7 @@ public void Select_LargeList_Throws_ArgumentOutOfRange() [Fact] public void Select_LargeList_Throws_ArgumentOutOfRange_TimeSpan() { - TimeSpan infinity = TimeSpan.FromMilliseconds(-1); + TimeSpan infinity = Timeout.InfiniteTimeSpan; var largeList = new LargeList(); Assert.Throws(() => Socket.Select(largeList, null, null, infinity)); From 091c2899e306cfa813d6dab02554a93560a5f251 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Thu, 10 Feb 2022 20:52:46 +0100 Subject: [PATCH 22/72] Inline method call Co-authored-by: Dan Moseley --- .../System.Net.Sockets/src/System/Net/Sockets/Socket.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs index 2701a5c75294ff..38f1ca05a21451 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs @@ -2220,13 +2220,7 @@ public static void Select(IList? checkRead, IList? checkWrite, IList? checkError } } - public static void Select(IList? checkRead, IList? checkWrite, IList? checkError, TimeSpan timeout) - { - int milliseconds = (int)timeout.TotalMilliseconds; - int microseconds = milliseconds / 1000; - - Select(checkRead, checkWrite, checkError, microseconds); - } + public static void Select(IList? checkRead, IList? checkWrite, IList? checkError, TimeSpan timeout) => Select(checkRead, checkWrite, checkError, timeout.TotalMilliseconds / 1000); public IAsyncResult BeginConnect(EndPoint remoteEP, AsyncCallback? callback, object? state) => TaskToApm.Begin(ConnectAsync(remoteEP), callback, state); From 70c4efabb80a63627f24dbf1283343d0f0681412 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Thu, 10 Feb 2022 20:53:05 +0100 Subject: [PATCH 23/72] Use checked `Close` Co-authored-by: Dan Moseley --- .../src/System/Net/Sockets/NetworkStream.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs index 123986d448703a..87f7155fb4b095 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs @@ -341,11 +341,7 @@ public void Close(int timeout) Dispose(); } - public void Close(TimeSpan timeout) - { - int milliseconds = (int)timeout.TotalMilliseconds; - Close(milliseconds); - } + public void Close(TimeSpan timeout) => Close(checked((int)timeout.TotalMilliseconds)) protected override void Dispose(bool disposing) { From eeeb61b66dfc2d1c62fcdbb2021212b735814523 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Thu, 10 Feb 2022 21:01:30 +0100 Subject: [PATCH 24/72] Use expression body style in System.Net.Ping --- .../src/System/Net/NetworkInformation/Ping.cs | 36 +++++-------------- 1 file changed, 8 insertions(+), 28 deletions(-) diff --git a/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs b/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs index 93761cf1f12f17..98cc7d21e70978 100644 --- a/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs +++ b/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs @@ -237,17 +237,11 @@ public PingReply Send(IPAddress address, int timeout, byte[] buffer, PingOptions } } - public PingReply Send(IPAddress address, TimeSpan timeout, byte[]? buffer = null, PingOptions? options = null) - { - int milliseconds = (int)timeout.TotalMilliseconds; - return Send(address, milliseconds, buffer ?? DefaultSendBuffer, options); - } + public PingReply Send(IPAddress address, TimeSpan timeout, byte[]? buffer = null, PingOptions? options = null) => + Send(address, checked((int)timeout.TotalMilliseconds), buffer ?? DefaultSendBuffer, options); - public PingReply Send(string hostNameOrAddress, TimeSpan timeout, byte[]? buffer = null, PingOptions? options = null) - { - int milliseconds = (int)timeout.TotalMilliseconds; - return Send(hostNameOrAddress, milliseconds, buffer ?? DefaultSendBuffer, options); - } + public PingReply Send(string hostNameOrAddress, TimeSpan timeout, byte[]? buffer = null, + PingOptions? options = null) => Send(hostNameOrAddress, checked((int)timeout.TotalMilliseconds), buffer ?? DefaultSendBuffer, options); public void SendAsync(string hostNameOrAddress, object? userToken) { @@ -337,26 +331,12 @@ public Task SendPingAsync(IPAddress address, int timeout, byte[] buff } public Task SendPingAsync(IPAddress address, TimeSpan timeout, byte[]? buffer = null, - PingOptions? options = null, CancellationToken cancellationToken = default) - { - int milliseconds = (int)timeout.TotalMilliseconds; - - cancellationToken.ThrowIfCancellationRequested(); - Task task = SendPingAsync(address, milliseconds, buffer ?? DefaultSendBuffer, options); - - return task.WaitAsync(cancellationToken); - } + PingOptions? options = null, CancellationToken cancellationToken = default) => + SendPingAsync(address, checked((int)timeout.TotalMilliseconds), buffer ?? DefaultSendBuffer, options); public Task SendPingAsync(string hostNameOrAddress, TimeSpan timeout, byte[]? buffer = null, - PingOptions? options = null, CancellationToken cancellationToken = default) - { - int milliseconds = (int)timeout.TotalMilliseconds; - - cancellationToken.ThrowIfCancellationRequested(); - Task task = SendPingAsync(hostNameOrAddress, milliseconds, buffer ?? DefaultSendBuffer, options); - - return task.WaitAsync(cancellationToken); - } + PingOptions? options = null, CancellationToken cancellationToken = default) => + SendPingAsync(hostNameOrAddress, checked((int)timeout.TotalMilliseconds), buffer ?? DefaultSendBuffer, options); private async Task SendPingAsyncInternal(IPAddress address, int timeout, byte[] buffer, PingOptions? options) { From 74468217e35e5873b167fc6aad71527a13102103 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Thu, 10 Feb 2022 21:02:42 +0100 Subject: [PATCH 25/72] Implement CancellationTokenHandling to `SendPingAsync` --- .../src/System/Net/NetworkInformation/Ping.cs | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs b/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs index 98cc7d21e70978..5b04f04716ca41 100644 --- a/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs +++ b/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs @@ -331,12 +331,26 @@ public Task SendPingAsync(IPAddress address, int timeout, byte[] buff } public Task SendPingAsync(IPAddress address, TimeSpan timeout, byte[]? buffer = null, - PingOptions? options = null, CancellationToken cancellationToken = default) => - SendPingAsync(address, checked((int)timeout.TotalMilliseconds), buffer ?? DefaultSendBuffer, options); + PingOptions? options = null, CancellationToken cancellationToken = default) + { + int milliseconds = checked((int)timeout.TotalMilliseconds); + + cancellationToken.ThrowIfCancellationRequested(); + Task task = SendPingAsync(address, milliseconds, buffer ?? DefaultSendBuffer, options); + + return task.WaitAsync(cancellationToken); + } public Task SendPingAsync(string hostNameOrAddress, TimeSpan timeout, byte[]? buffer = null, - PingOptions? options = null, CancellationToken cancellationToken = default) => - SendPingAsync(hostNameOrAddress, checked((int)timeout.TotalMilliseconds), buffer ?? DefaultSendBuffer, options); + PingOptions? options = null, CancellationToken cancellationToken = default) + { + int milliseconds = checked((int)timeout.TotalMilliseconds); + + cancellationToken.ThrowIfCancellationRequested(); + Task task = SendPingAsync(hostNameOrAddress, milliseconds, buffer ?? DefaultSendBuffer, options); + + return task.WaitAsync(cancellationToken); + } private async Task SendPingAsyncInternal(IPAddress address, int timeout, byte[] buffer, PingOptions? options) { From 5fba0ab2614516482c5760d81329e0366c43f916 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Thu, 10 Feb 2022 21:06:03 +0100 Subject: [PATCH 26/72] Fix PingTest --- .../tests/FunctionalTests/PingTest.cs | 52 +------------------ 1 file changed, 1 insertion(+), 51 deletions(-) diff --git a/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs b/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs index 7514c7458b283a..cd48babe3afae0 100644 --- a/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs +++ b/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs @@ -129,56 +129,6 @@ public async Task SendPingAsync_InvalidArgs() AssertExtensions.Throws("buffer", () => { p.Send(TestSettings.LocalHost, 1, new byte[65501]); }); } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - public async Task SendPingAsync_InvalidArgs_TimeSpan() - { - IPAddress localIpAddress = await TestSettings.GetLocalIPAddressAsync(); - Ping p = new Ping(); - - // Null address - AssertExtensions.Throws("address", () => { p.SendPingAsync((IPAddress)null); }); - AssertExtensions.Throws("hostNameOrAddress", () => { p.SendPingAsync((string)null); }); - AssertExtensions.Throws("address", () => { p.SendAsync((IPAddress)null, null); }); - AssertExtensions.Throws("hostNameOrAddress", () => { p.SendAsync((string)null, null); }); - AssertExtensions.Throws("address", () => { p.Send((IPAddress)null); }); - AssertExtensions.Throws("hostNameOrAddress", () => { p.Send((string)null); }); - - // Invalid address - AssertExtensions.Throws("address", () => { p.SendPingAsync(IPAddress.Any); }); - AssertExtensions.Throws("address", () => { p.SendPingAsync(IPAddress.IPv6Any); }); - AssertExtensions.Throws("address", () => { p.SendAsync(IPAddress.Any, null); }); - AssertExtensions.Throws("address", () => { p.SendAsync(IPAddress.IPv6Any, null); }); - AssertExtensions.Throws("address", () => { p.Send(IPAddress.Any); }); - AssertExtensions.Throws("address", () => { p.Send(IPAddress.IPv6Any); }); - - // Negative timeout - TimeSpan negativeTimeout = TimeSpan.FromMilliseconds(-1); - AssertExtensions.Throws("timeout", () => { p.SendPingAsync(localIpAddress, negativeTimeout); }); - AssertExtensions.Throws("timeout", () => { p.SendPingAsync(TestSettings.LocalHost, negativeTimeout); }); - AssertExtensions.Throws("timeout", () => { p.SendAsync(localIpAddress, negativeTimeout, null); }); - AssertExtensions.Throws("timeout", () => { p.SendAsync(TestSettings.LocalHost, negativeTimeout, null); }); - AssertExtensions.Throws("timeout", () => { p.Send(localIpAddress, negativeTimeout); }); - AssertExtensions.Throws("timeout", () => { p.Send(TestSettings.LocalHost, negativeTimeout); }); - - // Null byte[] - TimeSpan zeroTimeout = TimeSpan.FromMilliseconds(0); - AssertExtensions.Throws("buffer", () => { p.SendPingAsync(localIpAddress, zeroTimeout, null); }); - AssertExtensions.Throws("buffer", () => { p.SendPingAsync(TestSettings.LocalHost, zeroTimeout, null); }); - AssertExtensions.Throws("buffer", () => { p.SendAsync(localIpAddress, zeroTimeout, null, null); }); - AssertExtensions.Throws("buffer", () => { p.SendAsync(TestSettings.LocalHost, zeroTimeout, null, null); }); - AssertExtensions.Throws("buffer", () => { p.Send(localIpAddress, zeroTimeout, null); }); - AssertExtensions.Throws("buffer", () => { p.Send(TestSettings.LocalHost, zeroTimeout, null); }); - - // Too large byte[] - TimeSpan oneTimeout = TimeSpan.FromMilliseconds(1); - AssertExtensions.Throws("buffer", () => { p.SendPingAsync(localIpAddress, oneTimeout, new byte[65501]); }); - AssertExtensions.Throws("buffer", () => { p.SendPingAsync(TestSettings.LocalHost, oneTimeout, new byte[65501]); }); - AssertExtensions.Throws("buffer", () => { p.SendAsync(localIpAddress, oneTimeout, new byte[65501], null); }); - AssertExtensions.Throws("buffer", () => { p.SendAsync(TestSettings.LocalHost, oneTimeout, new byte[65501], null); }); - AssertExtensions.Throws("buffer", () => { p.Send(localIpAddress, oneTimeout, new byte[65501]); }); - AssertExtensions.Throws("buffer", () => { p.Send(TestSettings.LocalHost, oneTimeout, new byte[65501]); }); - } - [Theory] [InlineData(AddressFamily.InterNetwork)] [InlineData(AddressFamily.InterNetworkV6)] @@ -202,7 +152,7 @@ public void SendPingWithIPAddress(AddressFamily addressFamily) [Theory] [InlineData(AddressFamily.InterNetwork)] [InlineData(AddressFamily.InterNetworkV6)] - public void SendPingWithIPAddress(AddressFamily addressFamily) + public void SendPingWithIPAddress_TimeSpan(AddressFamily addressFamily) { IPAddress localIpAddress = TestSettings.GetLocalIPAddress(addressFamily); if (localIpAddress == null) From 738b9e26207a918d3f9384c5d2bcbf7a7f29c080 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Thu, 10 Feb 2022 21:10:37 +0100 Subject: [PATCH 27/72] Use expression-body method style for `GC` --- src/coreclr/System.Private.CoreLib/src/System/GC.cs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/GC.cs b/src/coreclr/System.Private.CoreLib/src/System/GC.cs index e5705e10689fd4..65a8dbb9e20e2d 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/GC.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/GC.cs @@ -428,11 +428,7 @@ public static GCNotificationStatus WaitForFullGCApproach(int millisecondsTimeout return (GCNotificationStatus)_WaitForFullGCApproach(millisecondsTimeout); } - public static GCNotificationStatus WaitForFullGCApproach(TimeSpan timeout) - { - int millisecondsTimeout = (int)timeout.TotalMilliseconds; - return (GCNotificationStatus)_WaitForFullGCApproach(millisecondsTimeout); - } + public static GCNotificationStatus WaitForFullGCApproach(TimeSpan timeout) => WaitForFullGCApproach(checked((int)timeout.TotalMilliseconds)); public static GCNotificationStatus WaitForFullGCComplete() { @@ -446,11 +442,7 @@ public static GCNotificationStatus WaitForFullGCComplete(int millisecondsTimeout return (GCNotificationStatus)_WaitForFullGCComplete(millisecondsTimeout); } - public static GCNotificationStatus WaitForFullGCComplete(TimeSpan timeout) - { - int millisecondsTimeout = (int)timeout.TotalMilliseconds; - return (GCNotificationStatus)_WaitForFullGCComplete(millisecondsTimeout); - } + public static GCNotificationStatus WaitForFullGCComplete(TimeSpan timeout) => WaitForFullGCComplete(checked((int)timeout.TotalMilliseconds)); private enum StartNoGCRegionStatus { From e6d68f99669d7cd80f2f55df2a2873a5e0ca6d90 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Thu, 10 Feb 2022 21:13:23 +0100 Subject: [PATCH 28/72] Use expression-body method style for `Process` --- .../src/System/Diagnostics/Process.cs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs index 43a3ef926d269a..a6c5064d417b46 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs @@ -829,11 +829,7 @@ public bool WaitForInputIdle(int milliseconds) return WaitForInputIdleCore(milliseconds); } - public bool WaitForInputIdle(TimeSpan timeout) - { - int milliseconds = (int)timeout.TotalMilliseconds; - return WaitForInputIdleCore(milliseconds); - } + public bool WaitForInputIdle(TimeSpan timeout) => WaitForInputIdle(checked((int)timeout.TotalMilliseconds)); public ISynchronizeInvoke? SynchronizingObject { get; set; } @@ -1435,11 +1431,7 @@ public bool WaitForExit(int milliseconds) /// Instructs the Process component to wait the specified number of milliseconds for /// the associated process to exit. /// - public bool WaitForExit(TimeSpan timeout) - { - int milliseconds = (int)timeout.TotalMilliseconds; - return WaitForExit(milliseconds); - } + public bool WaitForExit(TimeSpan timeout) => WaitForExit(checked((int)timeout.TotalMilliseconds)); /// /// Instructs the Process component to wait for the associated process to exit, or From 4a35788f2771b8a6f42bd3a2edea19762c76d2c4 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Thu, 10 Feb 2022 21:15:37 +0100 Subject: [PATCH 29/72] Use expression-body method style for `FileSystemWatcher` --- .../src/System/IO/FileSystemWatcher.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.cs b/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.cs index a56ddbbf0b47fe..b70ade40ebe7bb 100644 --- a/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.cs +++ b/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.cs @@ -619,11 +619,8 @@ public WaitForChangedResult WaitForChanged(WatcherChangeTypes changeType, int ti WaitForChangedResult.TimedOutResult; } - public WaitForChangedResult WaitForChanged(WatcherChangeTypes changeType, TimeSpan timeout) - { - int milliseconds = (int)timeout.TotalMilliseconds; - return WaitForChanged(changeType, milliseconds); - } + public WaitForChangedResult WaitForChanged(WatcherChangeTypes changeType, TimeSpan timeout) => + WaitForChanged(changeType, checked((int)timeout.TotalMilliseconds)); /// /// Stops and starts this object. From 486a7617a95dfa0cd0f593957fdeef88d4d85336 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Thu, 10 Feb 2022 21:20:33 +0100 Subject: [PATCH 30/72] Use expression-body method style for `NamedPipeStream` --- .../src/System/IO/Pipes/NamedPipeClientStream.cs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.cs b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.cs index 5e81437564d9c9..f60bfb246de7db 100644 --- a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.cs +++ b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.cs @@ -129,11 +129,7 @@ public void Connect(int timeout) ConnectInternal(timeout, CancellationToken.None, Environment.TickCount); } - public void Connect(TimeSpan timeout) - { - int milliseconds = (int)timeout.TotalMilliseconds; - Connect(milliseconds); - } + public void Connect(TimeSpan timeout) => Connect(checked((int)timeout.TotalMilliseconds)); private void ConnectInternal(int timeout, CancellationToken cancellationToken, int startTime) { @@ -203,11 +199,8 @@ public Task ConnectAsync(int timeout, CancellationToken cancellationToken) return Task.Run(() => ConnectInternal(timeout, cancellationToken, startTime), cancellationToken); } - public Task ConnectAsync(TimeSpan timeout, CancellationToken cancellationToken = default) - { - int milliseconds = (int)timeout.TotalMilliseconds; - return ConnectAsync(milliseconds, cancellationToken); - } + public Task ConnectAsync(TimeSpan timeout, CancellationToken cancellationToken = default) => + ConnectAsync(checked((int)timeout.TotalMilliseconds), cancellationToken); // override because named pipe clients can't get/set properties when waiting to connect // or broken From 9ffe1ae0a1af7506e51149b57e000125a9890845 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Thu, 10 Feb 2022 21:28:27 +0100 Subject: [PATCH 31/72] Fix `NamedPipeTest.Specific` --- .../tests/NamedPipeTests/NamedPipeTest.Specific.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Specific.cs b/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Specific.cs index f13b46290245fb..8acd5bebcf8fbd 100644 --- a/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Specific.cs +++ b/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Specific.cs @@ -30,9 +30,10 @@ public void InvalidConnectTimeout_Throws_ArgumentOutOfRangeException_TimeSpan() { using (NamedPipeClientStream client = new NamedPipeClientStream("client1")) { + var ctx = new CancellationTokenSource(); TimeSpan negativeTimeout = TimeSpan.FromMilliseconds(-111); AssertExtensions.Throws("timeout", () => client.Connect(negativeTimeout)); - AssertExtensions.Throws("timeout", () => { client.ConnectAsync(negativeTimeout); }); + AssertExtensions.Throws("timeout", () => { client.ConnectAsync(negativeTimeout, ctx.Token); }); } } @@ -55,7 +56,7 @@ public async Task ConnectToNonExistentServer_Throws_TimeoutException_TimeSpan() { var ctx = new CancellationTokenSource(); Assert.Throws(() => client.Connect(TimeSpan.FromMilliseconds(60))); // 60 to be over internal 50 interval - await Assert.ThrowsAsync(() => client.ConnectAsync(TimeSpan.FromMilliseconds(50))); + await Assert.ThrowsAsync(() => client.ConnectAsync(TimeSpan.FromMilliseconds(50), ctx.Token)); await Assert.ThrowsAsync(() => client.ConnectAsync(TimeSpan.FromMilliseconds(60), ctx.Token)); // testing Token overload; ctx is not canceled in this test } } @@ -660,10 +661,11 @@ public void ClientConnect_Throws_Timeout_When_Pipe_Busy() using (NamedPipeClientStream firstClient = new NamedPipeClientStream(pipeName)) using (NamedPipeClientStream secondClient = new NamedPipeClientStream(pipeName)) { + var ctx = new CancellationTokenSource(); TimeSpan timeout = TimeSpan.FromMilliseconds(10_000); Task[] clientAndServerTasks = new[] { - firstClient.ConnectAsync(timeout), + firstClient.ConnectAsync(timeout, ctx.Token), Task.Run(() => server.WaitForConnection()) }; @@ -688,7 +690,7 @@ public async Task ClientConnectAsync_With_Cancellation_Throws_Timeout_When_Pipe_ TimeSpan timeout = TimeSpan.FromMilliseconds(10_000); Task[] clientAndServerTasks = new[] { - firstClient.ConnectAsync(timeout), + firstClient.ConnectAsync(timeout, cancellationToken), Task.Run(() => server.WaitForConnection()) }; From 7d4af1d77147101084b2f786d582aef54a518d97 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Thu, 10 Feb 2022 21:33:42 +0100 Subject: [PATCH 32/72] Use expression-body method style for `NetworkStream` and `Socket` Co-Authored-By: Dan Moseley --- .../src/System/Net/Sockets/NetworkStream.cs | 2 +- .../src/System/Net/Sockets/Socket.cs | 11 +++-------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs index 87f7155fb4b095..b40a889eb91949 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs @@ -341,7 +341,7 @@ public void Close(int timeout) Dispose(); } - public void Close(TimeSpan timeout) => Close(checked((int)timeout.TotalMilliseconds)) + public void Close(TimeSpan timeout) => Close(checked((int)timeout.TotalMilliseconds)); protected override void Dispose(bool disposing) { diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs index 38f1ca05a21451..3aaf6531f08b11 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs @@ -2181,13 +2181,8 @@ public bool Poll(int microSeconds, SelectMode mode) return status; } - public bool Poll(TimeSpan timeout, SelectMode mode) - { - int milliseconds = (int)timeout.TotalMilliseconds; - int microseconds = milliseconds / 1000; - - return Poll(microseconds, mode); - } + public bool Poll(TimeSpan timeout, SelectMode mode) => + Poll(checked((int)timeout.TotalMilliseconds) / 1000, mode); // Determines the status of a socket. public static void Select(IList? checkRead, IList? checkWrite, IList? checkError, int microSeconds) @@ -2220,7 +2215,7 @@ public static void Select(IList? checkRead, IList? checkWrite, IList? checkError } } - public static void Select(IList? checkRead, IList? checkWrite, IList? checkError, TimeSpan timeout) => Select(checkRead, checkWrite, checkError, timeout.TotalMilliseconds / 1000); + public static void Select(IList? checkRead, IList? checkWrite, IList? checkError, TimeSpan timeout) => Select(checkRead, checkWrite, checkError, checked((int)timeout.TotalMilliseconds) / 1000); public IAsyncResult BeginConnect(EndPoint remoteEP, AsyncCallback? callback, object? state) => TaskToApm.Begin(ConnectAsync(remoteEP), callback, state); From 27fa0ce1928cbd23941b27e4dbb300ea52dc0271 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Thu, 10 Feb 2022 21:54:19 +0100 Subject: [PATCH 33/72] Fix syntax errors in `PingTest` --- .../tests/FunctionalTests/PingTest.cs | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs b/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs index cd48babe3afae0..479a1793852d86 100644 --- a/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs +++ b/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs @@ -163,7 +163,7 @@ public void SendPingWithIPAddress_TimeSpan(AddressFamily addressFamily) TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); SendBatchPing( - ping => ping.Send(localIpAddress, pingTimeout), + ping => ping.Send(localIpAddress, pingTimeout, default, default), pingReply => { PingResultValidator(pingReply, localIpAddress); @@ -243,7 +243,7 @@ public void SendPingWithIPAddressAndTimeout_TimeSpan() TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); SendBatchPing( - ping => ping.Send(localIpAddress, pingTimeout), + ping => ping.Send(localIpAddress, pingTimeout, default, default), pingReply => { PingResultValidator(pingReply, localIpAddress); @@ -270,7 +270,7 @@ public async Task SendPingAsyncWithIPAddressAndTimeout_TimeSpan() TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); await SendBatchPingAsync( - ping => ping.SendPingAsync(localIpAddress, pingTimeout), + ping => ping.SendPingAsync(localIpAddress, pingTimeout, default, default, default), pingReply => { PingResultValidator(pingReply, localIpAddress); @@ -300,7 +300,7 @@ public void SendPingWithIPAddressAndTimeoutAndBuffer_TimeSpan() TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); SendBatchPing( - ping => ping.Send(localIpAddress, pingTimeout, buffer), + ping => ping.Send(localIpAddress, pingTimeout, buffer, default), pingReply => { PingResultValidator(pingReply, localIpAddress); @@ -331,7 +331,7 @@ public async Task SendPingAsyncWithIPAddressAndTimeoutAndBuffer_TimeSpan() TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); await SendBatchPingAsync( - ping => ping.SendPingAsync(localIpAddress, pingTimeout, buffer), + ping => ping.SendPingAsync(localIpAddress, pingTimeout, buffer, default, default), pingReply => { PingResultValidator(pingReply, localIpAddress); @@ -406,7 +406,7 @@ public async Task SendPingAsyncWithIPAddressAndTimeoutAndBufferAndPingOptions_Ti TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); await SendBatchPingAsync( - ping => ping.SendPingAsync(localIpAddress, pingTimeout, buffer, options), + ping => ping.SendPingAsync(localIpAddress, pingTimeout, buffer, options, default), pingReply => { PingResultValidator(pingReply, localIpAddress); @@ -505,7 +505,7 @@ public async Task SendPingAsyncWithIPAddressAndTimeoutAndBufferAndPingOptions_Un TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); await SendBatchPingAsync( - ping => ping.SendPingAsync(localIpAddress, pingTimeout, buffer, new PingOptions()), + ping => ping.SendPingAsync(localIpAddress, pingTimeout, buffer, new PingOptions(), default), pingReply => { PingResultValidator(pingReply, localIpAddress); @@ -559,7 +559,7 @@ public void SendPingWithHostAndTimeout_TimeSpan() TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); SendBatchPing( - ping => ping.Send(TestSettings.LocalHost, pingTimeout), + ping => ping.Send(TestSettings.LocalHost, pingTimeout, default, default), pingReply => { PingResultValidator(pingReply, localIpAddresses); @@ -586,7 +586,7 @@ public async Task SendPingAsyncWithHostAndTimeout_TimeSpan() TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); await SendBatchPingAsync( - ping => ping.SendPingAsync(TestSettings.LocalHost, pingTimeout), + ping => ping.SendPingAsync(TestSettings.LocalHost, pingTimeout, default, default, default), pingReply => { PingResultValidator(pingReply, localIpAddresses); @@ -616,7 +616,7 @@ public void SendPingWithHostAndTimeoutAndBuffer_TimeSpan() TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); SendBatchPing( - ping => ping.Send(TestSettings.LocalHost, pingTimeout, buffer), + ping => ping.Send(TestSettings.LocalHost, pingTimeout, buffer, default), pingReply => { PingResultValidator(pingReply, localIpAddress); @@ -647,7 +647,7 @@ public async Task SendPingAsyncWithHostAndTimeoutAndBuffer_TimeSpan() TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); await SendBatchPingAsync( - ping => ping.SendPingAsync(TestSettings.LocalHost, pingTimeout, buffer), + ping => ping.SendPingAsync(TestSettings.LocalHost, pingTimeout, buffer, default, default), pingReply => { PingResultValidator(pingReply, localIpAddress); @@ -710,7 +710,7 @@ public async Task SendPingAsyncWithHostAndTimeoutAndBufferAndPingOptions_TimeSpa TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); await SendBatchPingAsync( - ping => ping.SendPingAsync(TestSettings.LocalHost, pingTimeout, buffer, new PingOptions()), + ping => ping.SendPingAsync(TestSettings.LocalHost, pingTimeout, buffer, new PingOptions(), default), pingReply => { PingResultValidator(pingReply, localIpAddress); @@ -751,7 +751,7 @@ public async Task SendPingWithIPAddressAndBigSize_TimeSpan() TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); // Assert.DoesNotThrow - PingReply pingReply = await p.SendPingAsync(localIpAddress, pingTimeout, new byte[10001]); + PingReply pingReply = await p.SendPingAsync(localIpAddress, pingTimeout, new byte[10001], default, default); // Depending on platform the call may either succeed, report timeout or report too big packet. It // should not throw wrapped SocketException though which is what this test guards. @@ -961,7 +961,7 @@ public async Task SendPingAsyncWithHostAndTtlAndFragmentPingOptions_TimeSpan(boo TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); await SendBatchPingAsync( - ping => ping.SendPingAsync(TestSettings.LocalHost, pingTimeout, buffer, options), + ping => ping.SendPingAsync(TestSettings.LocalHost, pingTimeout, buffer, options, default), pingReply => { PingResultValidator(pingReply, localIpAddresses); @@ -1012,7 +1012,7 @@ public async Task SendPingToExternalHostWithLowTtlTest_TimeSpan() TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); for (int i = 0; i < s_pingcount; i++) { - pingReply = await ping.SendPingAsync(host, pingTimeout, TestSettings.PayloadAsBytesShort); + pingReply = await ping.SendPingAsync(host, pingTimeout, TestSettings.PayloadAsBytesShort, default, default); if (pingReply.Status != IPStatus.Success) { continue; @@ -1028,7 +1028,7 @@ public async Task SendPingToExternalHostWithLowTtlTest_TimeSpan() options.Ttl = 1; // This should always fail unless host is one IP hop away. - pingReply = await ping.SendPingAsync(host, pingTimeout, TestSettings.PayloadAsBytesShort, options); + pingReply = await ping.SendPingAsync(host, pingTimeout, TestSettings.PayloadAsBytesShort, options, default); Assert.True(pingReply.Status is IPStatus.TimeExceeded or IPStatus.TtlExpired); Assert.NotEqual(IPAddress.Any, pingReply.Address); } @@ -1174,7 +1174,7 @@ public void SendPing_LocaleEnvVarsMustBeIgnored_TimeSpan(AddressFamily addressFa RemoteExecutor.Invoke(address => { SendBatchPing( - ping => ping.Send(address, pingTimeout), + ping => ping.Send(address, pingTimeout, default, default), (pingReply) => { PingResultValidator(pingReply, new[] { IPAddress.Parse(address) }, null); @@ -1234,7 +1234,7 @@ public void SendPing_CustomPayload_InsufficientPrivileges_Throws_TimeSpan() byte[] buffer = TestSettings.PayloadAsBytes; TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); Ping ping = new(); - Assert.Throws(() => ping.Send(TestSettings.LocalHost, pingTimeout, buffer)); + Assert.Throws(() => ping.Send(TestSettings.LocalHost, pingTimeout, buffer, default)); } [ConditionalFact(nameof(UsesPingUtility))] @@ -1255,7 +1255,7 @@ public async Task SendPingAsync_CustomPayload_InsufficientPrivileges_Throws_Time byte[] buffer = TestSettings.PayloadAsBytes; TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); Ping ping = new(); - await Assert.ThrowsAsync(() => ping.SendPingAsync(TestSettings.LocalHost, pingTimeout, buffer)); + await Assert.ThrowsAsync(() => ping.SendPingAsync(TestSettings.LocalHost, pingTimeout, buffer, default, default)); } } } From abea06fe2c72cdf1097542cd140a443ebe7c635e Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Thu, 10 Feb 2022 22:03:58 +0100 Subject: [PATCH 34/72] Add `GC` implementation for NativeAOT (CoreRT) --- .../System.Private.CoreLib/src/System/GC.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.cs index c9578dfee08036..69de70ae3d4500 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.cs @@ -215,6 +215,14 @@ public static GCNotificationStatus WaitForFullGCApproach(int millisecondsTimeout return (GCNotificationStatus)RuntimeImports.RhWaitForFullGCApproach(millisecondsTimeout); } + /// + /// Returns the status of a registered notification about whether a blocking garbage collection + /// is imminent. May wait up to a given timeout for a full collection. + /// + /// The timeout on waiting for a full collection + /// The status of a registered full GC notification + public static GCNotificationStatus WaitForFullGCApproach(TimeSpan timeout) => WaitForFullGCApproach(checked((int)timeout.TotalMilliseconds)); + /// /// Returns the status of a registered notification about whether a blocking garbage collection /// has completed. May wait indefinitely for a full collection. @@ -243,6 +251,14 @@ public static GCNotificationStatus WaitForFullGCComplete(int millisecondsTimeout return (GCNotificationStatus)RuntimeImports.RhWaitForFullGCComplete(millisecondsTimeout); } + /// + /// Returns the status of a registered notification about whether a blocking garbage collection + /// has completed. May wait up to a specified timeout for a full collection. + /// + /// The timeout on waiting for a full collection + /// + public static GCNotificationStatus WaitForFullGCComplete(TimeSpan timeout) => WaitForFullGCComplete(checked((int)timeout.TotalMilliseconds)); + /// /// Cancels an outstanding full GC notification. /// From 340e5eba9825e55e8ba72410e792249072fe64b4 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Fri, 11 Feb 2022 16:38:54 +0100 Subject: [PATCH 35/72] Add Mono `GC` implementation --- src/mono/System.Private.CoreLib/src/System/GC.Mono.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/mono/System.Private.CoreLib/src/System/GC.Mono.cs b/src/mono/System.Private.CoreLib/src/System/GC.Mono.cs index a92ebab49920d7..87a23327b63475 100644 --- a/src/mono/System.Private.CoreLib/src/System/GC.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/GC.Mono.cs @@ -204,6 +204,9 @@ public static GCNotificationStatus WaitForFullGCApproach(int millisecondsTimeout return _WaitForFullGCApproach(millisecondsTimeout); } + public static GCNotificationStatus WaitForFullGCApproach(TimeSpan timeout) => + WaitForFullGCApproach(checked((int)timeout.TotalMilliseconds)); + public static GCNotificationStatus WaitForFullGCComplete() { return _WaitForFullGCComplete(-1); @@ -216,6 +219,9 @@ public static GCNotificationStatus WaitForFullGCComplete(int millisecondsTimeout return _WaitForFullGCComplete(millisecondsTimeout); } + public static GCNotificationStatus WaitForFullGCComplete(TimeSpan timeout) => + WaitForFullGCComplete(checked((int)timeout.TotalMilliseconds)); + private static bool StartNoGCRegion(long totalSize, bool hasLohSize, long lohSize, bool disallowFullBlockingGC) { throw new NotImplementedException(); From 0ff42de68d8f8a0de97d2143cbdd6d5e221549f2 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Fri, 11 Feb 2022 16:58:16 +0100 Subject: [PATCH 36/72] Next try to fix `RemoteExecutor` tests --- .../System.Net.Ping/tests/FunctionalTests/PingTest.cs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs b/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs index 479a1793852d86..038bdc9e11ac31 100644 --- a/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs +++ b/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs @@ -50,7 +50,7 @@ private void PingResultValidator(PingReply pingReply, IPAddress localIpAddress) private void PingResultValidator(PingReply pingReply, IPAddress[] localIpAddresses) => PingResultValidator(pingReply, localIpAddresses, null); - private static void PingResultValidator(PingReply pingReply, IPAddress[] localIpAddresses, ITestOutputHelper output) + private static void PingResultValidator(PingReply pingReply, IPAddress[] localIpAddresses, ITestOutputHelper? output) { Assert.Equal(IPStatus.Success, pingReply.Status); if (localIpAddresses.Any(addr => pingReply.Address.Equals(addr))) @@ -1156,11 +1156,6 @@ public void SendPing_LocaleEnvVarsMustBeIgnored(AddressFamily addressFamily, str public void SendPing_LocaleEnvVarsMustBeIgnored_TimeSpan(AddressFamily addressFamily, string envVar_LANG, string envVar_LC_MESSAGES, string envVar_LC_ALL) { IPAddress localIpAddress = TestSettings.GetLocalIPAddress(addressFamily); - if (localIpAddress == null) - { - // No local address for given address family. - return; - } var remoteInvokeStartInfo = new ProcessStartInfo { EnvironmentVariables = { @@ -1175,7 +1170,7 @@ public void SendPing_LocaleEnvVarsMustBeIgnored_TimeSpan(AddressFamily addressFa { SendBatchPing( ping => ping.Send(address, pingTimeout, default, default), - (pingReply) => + pingReply => { PingResultValidator(pingReply, new[] { IPAddress.Parse(address) }, null); }); From e61acf08724f2ac5c27ce0a82daa21a369cc812b Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Fri, 11 Feb 2022 17:59:08 +0100 Subject: [PATCH 37/72] Fix `RemoteExecutor` tests --- .../tests/FunctionalTests/PingTest.cs | 55 ++++++++++++++----- 1 file changed, 42 insertions(+), 13 deletions(-) diff --git a/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs b/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs index 038bdc9e11ac31..23ffa26c512f22 100644 --- a/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs +++ b/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs @@ -3,6 +3,7 @@ using Microsoft.DotNet.XUnitExtensions; using System.Diagnostics; +using System.Globalization; using System.Linq; using System.Net.Sockets; using System.Net.Test.Common; @@ -1164,12 +1165,13 @@ public void SendPing_LocaleEnvVarsMustBeIgnored_TimeSpan(AddressFamily addressFa ["LC_ALL"] = envVar_LC_ALL } }; - - TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); + RemoteExecutor.Invoke(address => { + TimeSpan timeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); + SendBatchPing( - ping => ping.Send(address, pingTimeout, default, default), + ping => ping.Send(address, timeout, default, default), pingReply => { PingResultValidator(pingReply, new[] { IPAddress.Parse(address) }, null); @@ -1188,25 +1190,52 @@ public void SendPing_LocaleEnvVarsMustBeIgnored_TimeSpan(AddressFamily addressFa public void SendPingAsync_LocaleEnvVarsMustBeIgnored(AddressFamily addressFamily, string envVar_LANG, string envVar_LC_MESSAGES, string envVar_LC_ALL) { IPAddress localIpAddress = TestSettings.GetLocalIPAddress(addressFamily); - if (localIpAddress == null) + + var remoteInvokeStartInfo = new ProcessStartInfo { EnvironmentVariables = + { + ["LANG"] = envVar_LANG, ["LC_MESSAGES"] = envVar_LC_MESSAGES, + ["LC_ALL"] = envVar_LC_ALL + } + }; + + RemoteExecutor.Invoke(async address => { - // No local address for given address family. - return; - } + await SendBatchPingAsync( + (ping) => ping.SendPingAsync(address), + (pingReply) => + { + PingResultValidator(pingReply, new[] { IPAddress.Parse(address) }, null); + }); + }, localIpAddress.ToString(), new RemoteInvokeOptions { StartInfo = remoteInvokeStartInfo }).Dispose(); + } - var remoteInvokeStartInfo = new ProcessStartInfo(); + [PlatformSpecific(TestPlatforms.AnyUnix)] + [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + [InlineData(AddressFamily.InterNetwork, "ja_JP.UTF8", null, null)] + [InlineData(AddressFamily.InterNetwork, "en_US.UTF8", "ja_JP.UTF8", null)] + [InlineData(AddressFamily.InterNetwork, "en_US.UTF8", null, "ja_JP.UTF8")] + [InlineData(AddressFamily.InterNetworkV6, "ja_JP.UTF8", null, null)] + [InlineData(AddressFamily.InterNetworkV6, "en_US.UTF8", "ja_JP.UTF8", null)] + [InlineData(AddressFamily.InterNetworkV6, "en_US.UTF8", null, "ja_JP.UTF8")] + public void SendPingAsync_LocaleEnvVarsMustBeIgnored_TimeSpan(AddressFamily addressFamily, string envVar_LANG, string envVar_LC_MESSAGES, string envVar_LC_ALL) + { + IPAddress localIpAddress = TestSettings.GetLocalIPAddress(addressFamily); - remoteInvokeStartInfo.EnvironmentVariables["LANG"] = envVar_LANG; - remoteInvokeStartInfo.EnvironmentVariables["LC_MESSAGES"] = envVar_LC_MESSAGES; - remoteInvokeStartInfo.EnvironmentVariables["LC_ALL"] = envVar_LC_ALL; + var remoteInvokeStartInfo = new ProcessStartInfo { EnvironmentVariables = + { + ["LANG"] = envVar_LANG, ["LC_MESSAGES"] = envVar_LC_MESSAGES, + ["LC_ALL"] = envVar_LC_ALL + } + }; RemoteExecutor.Invoke(async address => { + TimeSpan timeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); await SendBatchPingAsync( - (ping) => ping.SendPingAsync(address), + ping => ping.SendPingAsync(address, timeout, default, default, default), (pingReply) => { - PingResultValidator(pingReply, new IPAddress[] { IPAddress.Parse(address) }, null); + PingResultValidator(pingReply, new[] { IPAddress.Parse(address) }, null); }); }, localIpAddress.ToString(), new RemoteInvokeOptions { StartInfo = remoteInvokeStartInfo }).Dispose(); } From 5279de8ba3ead7a4aaac3b1b5efcfec5cf14113c Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Fri, 11 Feb 2022 18:46:38 +0100 Subject: [PATCH 38/72] Fix net48 tests --- ...em.ComponentModel.Annotations.Tests.csproj | 1 + .../RegularExpressionAttributeTests.Core.cs | 20 +++++++++++++++++++ .../RegularExpressionAttributeTests.cs | 11 +--------- 3 files changed, 22 insertions(+), 10 deletions(-) create mode 100644 src/libraries/System.ComponentModel.Annotations/tests/System/ComponentModel/DataAnnotations/RegularExpressionAttributeTests.Core.cs diff --git a/src/libraries/System.ComponentModel.Annotations/tests/System.ComponentModel.Annotations.Tests.csproj b/src/libraries/System.ComponentModel.Annotations/tests/System.ComponentModel.Annotations.Tests.csproj index d4e20cee535409..ea79a73bf74a66 100644 --- a/src/libraries/System.ComponentModel.Annotations/tests/System.ComponentModel.Annotations.Tests.csproj +++ b/src/libraries/System.ComponentModel.Annotations/tests/System.ComponentModel.Annotations.Tests.csproj @@ -28,6 +28,7 @@ + diff --git a/src/libraries/System.ComponentModel.Annotations/tests/System/ComponentModel/DataAnnotations/RegularExpressionAttributeTests.Core.cs b/src/libraries/System.ComponentModel.Annotations/tests/System/ComponentModel/DataAnnotations/RegularExpressionAttributeTests.Core.cs new file mode 100644 index 00000000000000..78bb2e5e028fd6 --- /dev/null +++ b/src/libraries/System.ComponentModel.Annotations/tests/System/ComponentModel/DataAnnotations/RegularExpressionAttributeTests.Core.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.ComponentModel.DataAnnotations; +using Xunit; + +namespace System.ComponentModel.Annotations.Tests.System.ComponentModel.DataAnnotations +{ + public sealed partial class RegularExpressionAttributeTests + { + [Theory] + [InlineData(12345)] + [InlineData(-1)] + public static void MatchTimeout_Get_ReturnsExpected(int newValue) + { + var attribute = new RegularExpressionAttribute("SomePattern") { MatchTimeoutInMilliseconds = newValue }; + Assert.Equal(TimeSpan.FromMilliseconds(newValue), attribute.MatchTimeout); + } + } +} diff --git a/src/libraries/System.ComponentModel.Annotations/tests/System/ComponentModel/DataAnnotations/RegularExpressionAttributeTests.cs b/src/libraries/System.ComponentModel.Annotations/tests/System/ComponentModel/DataAnnotations/RegularExpressionAttributeTests.cs index c82d88d7a26d9a..45a9da9712f262 100644 --- a/src/libraries/System.ComponentModel.Annotations/tests/System/ComponentModel/DataAnnotations/RegularExpressionAttributeTests.cs +++ b/src/libraries/System.ComponentModel.Annotations/tests/System/ComponentModel/DataAnnotations/RegularExpressionAttributeTests.cs @@ -7,7 +7,7 @@ namespace System.ComponentModel.DataAnnotations.Tests { - public class RegularExpressionAttributeTests : ValidationAttributeTestBase + public sealed partial class RegularExpressionAttributeTests : ValidationAttributeTestBase { protected override IEnumerable ValidValues() { @@ -56,15 +56,6 @@ public static void MatchTimeoutInMilliseconds_GetSet_ReturnsExpected(int newValu Assert.Equal(newValue, attribute.MatchTimeoutInMilliseconds); } - [Theory] - [InlineData(12345)] - [InlineData(-1)] - public static void MatchTimeout_Get_ReturnsExpected(int newValue) - { - var attribute = new RegularExpressionAttribute("SomePattern") { MatchTimeoutInMilliseconds = newValue }; - Assert.Equal(TimeSpan.FromMilliseconds(newValue), attribute.MatchTimeout); - } - [Theory] [InlineData(null)] [InlineData("")] From aad5405ad9f87ee437e59b9be762c3db35de4421 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Sat, 12 Feb 2022 00:26:45 +0100 Subject: [PATCH 39/72] Move ref into only-core ref & add cond. compilation --- .../ref/System.ServiceProcess.ServiceController.cs | 1 - .../ref/System.ServiceProcess.ServiceController.netcoreapp.cs | 4 ++++ .../src/System/ServiceProcess/ServiceBase.cs | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.ServiceProcess.ServiceController/ref/System.ServiceProcess.ServiceController.cs b/src/libraries/System.ServiceProcess.ServiceController/ref/System.ServiceProcess.ServiceController.cs index 5361cd6c8d3adb..5846cec5477c90 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/ref/System.ServiceProcess.ServiceController.cs +++ b/src/libraries/System.ServiceProcess.ServiceController/ref/System.ServiceProcess.ServiceController.cs @@ -51,7 +51,6 @@ protected virtual void OnShutdown() { } protected virtual void OnStart(string[] args) { } protected virtual void OnStop() { } public void RequestAdditionalTime(int milliseconds) { } - public void RequestAdditionalTime(System.TimeSpan time) { } public static void Run(System.ServiceProcess.ServiceBase service) { } public static void Run(System.ServiceProcess.ServiceBase[] services) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] diff --git a/src/libraries/System.ServiceProcess.ServiceController/ref/System.ServiceProcess.ServiceController.netcoreapp.cs b/src/libraries/System.ServiceProcess.ServiceController/ref/System.ServiceProcess.ServiceController.netcoreapp.cs index 1298a7c23d6909..42be0a6c2c64f1 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/ref/System.ServiceProcess.ServiceController.netcoreapp.cs +++ b/src/libraries/System.ServiceProcess.ServiceController/ref/System.ServiceProcess.ServiceController.netcoreapp.cs @@ -6,6 +6,10 @@ namespace System.ServiceProcess { + public partial class ServiceBase : System.ComponentModel.Component + { + public void RequestAdditionalTime(System.TimeSpan time) { } + } public partial class ServiceController : System.ComponentModel.Component { public void Stop(bool stopDependentServices) { } diff --git a/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs b/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs index c5e13ab448fb85..a6b5042e295648 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs +++ b/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs @@ -72,6 +72,7 @@ public unsafe void RequestAdditionalTime(int milliseconds) } } +#if NETCOREAPP /// /// When this method is called from OnStart, OnStop, OnPause or OnContinue, /// the specified wait hint is passed to the @@ -83,6 +84,7 @@ public unsafe void RequestAdditionalTime(TimeSpan time) int milliseconds = (int)time.TotalMilliseconds; RequestAdditionalTime(milliseconds); } +#endif /// /// Indicates whether to report Start, Stop, Pause, and Continue commands in the event. From 1529601b5b9691252ef9f7eafe1c64387114a407 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Mon, 14 Feb 2022 21:02:01 +0100 Subject: [PATCH 40/72] Move `Timer`-`TimeSpan` overload in the right assembly --- .../ref/System.ComponentModel.TypeConverter.cs | 1 + .../src/System/Timers/Timer.cs | 7 +++++++ .../System.Private.CoreLib/src/System/Threading/Timer.cs | 8 -------- src/libraries/System.Runtime/ref/System.Runtime.cs | 1 - 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/libraries/System.ComponentModel.TypeConverter/ref/System.ComponentModel.TypeConverter.cs b/src/libraries/System.ComponentModel.TypeConverter/ref/System.ComponentModel.TypeConverter.cs index 8fe3c9a37f8217..7fb2fb41745565 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/ref/System.ComponentModel.TypeConverter.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/ref/System.ComponentModel.TypeConverter.cs @@ -2306,6 +2306,7 @@ public partial class Timer : System.ComponentModel.Component, System.ComponentMo { public Timer() { } public Timer(double interval) { } + public Timer(System.TimeSpan interval) { } [System.ComponentModel.DefaultValueAttribute(true)] public bool AutoReset { get { throw null; } set { } } [System.ComponentModel.DefaultValueAttribute(false)] diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/Timers/Timer.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/Timers/Timer.cs index 0dc77a54ccda65..76b0ce4554e4ff 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/Timers/Timer.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/Timers/Timer.cs @@ -59,6 +59,13 @@ public Timer(double interval) : this() _interval = (int)roundedInterval; } + /// + /// Initializes a new instance of the class, setting the property to the specified period. + /// + public Timer(TimeSpan timeSpan) : this(timeSpan.TotalMilliseconds) + { + } + /// /// Gets or sets a value indicating whether the Timer raises the Tick event each time the specified /// Interval has elapsed, when Enabled is set to true. diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Timer.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Timer.cs index 52082cee0d5975..108034d778d423 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Timer.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Timer.cs @@ -881,14 +881,6 @@ public Timer(TimerCallback callback) TimerSetup(callback, this, DueTime, Period); } - public Timer(TimeSpan interval) - { - unchecked - { - TimerSetup(_ => { }, this, (uint)-1, (uint)(int)interval.TotalMilliseconds); - } - } - [MemberNotNull(nameof(_timer))] private void TimerSetup(TimerCallback callback, object? state, diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index ae1448726c426b..7d58da1146a13f 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -14877,7 +14877,6 @@ public static partial class Timeout } public sealed partial class Timer : System.MarshalByRefObject, System.IAsyncDisposable, System.IDisposable { - public Timer(System.TimeSpan interval) { } public Timer(System.Threading.TimerCallback callback) { } public Timer(System.Threading.TimerCallback callback, object? state, int dueTime, int period) { } public Timer(System.Threading.TimerCallback callback, object? state, long dueTime, long period) { } From c3ea515f546b821fa4cc13f5d6618ec43bf05fbe Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Mon, 14 Feb 2022 21:05:32 +0100 Subject: [PATCH 41/72] Update `Task.Wait` so that it verifies the `CancellationToken` before argument validation --- .../System.Private.CoreLib/src/System/Threading/Tasks/Task.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs index 20e0bceebc0903..1ddc8fc916a30c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs @@ -2677,6 +2677,8 @@ public bool Wait(TimeSpan timeout) /// public bool Wait(TimeSpan timeout, CancellationToken cancellationToken) { + cancellationToken.ThrowIfCancellationRequested(); + long totalMilliseconds = (long)timeout.TotalMilliseconds; if (totalMilliseconds is < (-1) or > int.MaxValue) { From 53bed23493e0bf230916209443ab406796aa5a30 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Mon, 14 Feb 2022 22:07:40 +0100 Subject: [PATCH 42/72] Use `ToTimeoutMilliseconds` instead of a checked cast to int --- .../System.Private.CoreLib/src/System/GC.cs | 5 ++-- .../System.Private.CoreLib/src/System/GC.cs | 14 +++++------ .../src/System/Timers/Timer.cs | 2 +- .../src/Resources/Strings.resx | 6 +++++ .../src/Resources/Strings.resx | 6 +++++ .../src/System/Diagnostics/Process.cs | 17 +++++++++++++- .../src/Resources/Strings.resx | 6 +++++ .../src/System/IO/FileSystemWatcher.cs | 17 +++++++++++++- .../src/Resources/Strings.resx | 6 +++++ .../System/IO/Pipes/NamedPipeClientStream.cs | 19 +++++++++++++-- .../src/Resources/Strings.resx | 6 +++++ .../src/System/Net/NetworkInformation/Ping.cs | 23 +++++++++++++++---- .../src/Resources/Strings.resx | 6 +++++ .../src/System/Net/Sockets/NetworkStream.cs | 17 +++++++++++++- .../src/System/Net/Sockets/Socket.cs | 20 ++++++++++++++-- .../src/Resources/Strings.resx | 6 +++++ .../src/System/ServiceProcess/ServiceBase.cs | 17 +++++++++++--- .../src/System/GC.Mono.cs | 5 ++-- 18 files changed, 172 insertions(+), 26 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/GC.cs b/src/coreclr/System.Private.CoreLib/src/System/GC.cs index 65a8dbb9e20e2d..0c8dc65e99a389 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/GC.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/GC.cs @@ -16,6 +16,7 @@ using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Threading; using Internal.Runtime.CompilerServices; namespace System @@ -428,7 +429,7 @@ public static GCNotificationStatus WaitForFullGCApproach(int millisecondsTimeout return (GCNotificationStatus)_WaitForFullGCApproach(millisecondsTimeout); } - public static GCNotificationStatus WaitForFullGCApproach(TimeSpan timeout) => WaitForFullGCApproach(checked((int)timeout.TotalMilliseconds)); + public static GCNotificationStatus WaitForFullGCApproach(TimeSpan timeout) => WaitForFullGCApproach(WaitHandle.ToTimeoutMilliseconds(timeout)); public static GCNotificationStatus WaitForFullGCComplete() { @@ -442,7 +443,7 @@ public static GCNotificationStatus WaitForFullGCComplete(int millisecondsTimeout return (GCNotificationStatus)_WaitForFullGCComplete(millisecondsTimeout); } - public static GCNotificationStatus WaitForFullGCComplete(TimeSpan timeout) => WaitForFullGCComplete(checked((int)timeout.TotalMilliseconds)); + public static GCNotificationStatus WaitForFullGCComplete(TimeSpan timeout) => WaitForFullGCComplete(WaitHandle.ToTimeoutMilliseconds(timeout)); private enum StartNoGCRegionStatus { diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.cs index 69de70ae3d4500..e045150bfe77fc 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.cs @@ -216,12 +216,12 @@ public static GCNotificationStatus WaitForFullGCApproach(int millisecondsTimeout } /// - /// Returns the status of a registered notification about whether a blocking garbage collection - /// is imminent. May wait up to a given timeout for a full collection. + /// Returns, in a specified time-out period, the status of a registered notification for determining whether a full, + /// blocking garbage collection by the common language runtime is imminent. /// /// The timeout on waiting for a full collection /// The status of a registered full GC notification - public static GCNotificationStatus WaitForFullGCApproach(TimeSpan timeout) => WaitForFullGCApproach(checked((int)timeout.TotalMilliseconds)); + public static GCNotificationStatus WaitForFullGCApproach(TimeSpan timeout) => WaitForFullGCApproach(WaitHandle.ToTimeoutMilliseconds(timeout)); /// /// Returns the status of a registered notification about whether a blocking garbage collection @@ -252,12 +252,12 @@ public static GCNotificationStatus WaitForFullGCComplete(int millisecondsTimeout } /// - /// Returns the status of a registered notification about whether a blocking garbage collection - /// has completed. May wait up to a specified timeout for a full collection. + /// Returns, in a specified time-out period, the status of a registered notification for determining whether a full, + /// blocking garbage collection by common language the runtime has completed. /// /// The timeout on waiting for a full collection - /// - public static GCNotificationStatus WaitForFullGCComplete(TimeSpan timeout) => WaitForFullGCComplete(checked((int)timeout.TotalMilliseconds)); + /// The status of the registered garbage collection notification. + public static GCNotificationStatus WaitForFullGCComplete(TimeSpan timeout) => WaitForFullGCComplete(WaitHandle.ToTimeoutMilliseconds(timeout)); /// /// Cancels an outstanding full GC notification. diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/Timers/Timer.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/Timers/Timer.cs index 76b0ce4554e4ff..826257de2e7cf0 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/Timers/Timer.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/Timers/Timer.cs @@ -62,7 +62,7 @@ public Timer(double interval) : this() /// /// Initializes a new instance of the class, setting the property to the specified period. /// - public Timer(TimeSpan timeSpan) : this(timeSpan.TotalMilliseconds) + public Timer(TimeSpan interval) : this(interval.TotalMilliseconds) { } diff --git a/src/libraries/System.Diagnostics.EventLog/src/Resources/Strings.resx b/src/libraries/System.Diagnostics.EventLog/src/Resources/Strings.resx index e0aec25828364b..9b0c8387d9c213 100644 --- a/src/libraries/System.Diagnostics.EventLog/src/Resources/Strings.resx +++ b/src/libraries/System.Diagnostics.EventLog/src/Resources/Strings.resx @@ -239,4 +239,10 @@ Log {0} has already been registered as a source on the local computer. + + Number must be either non-negative and less than or equal to Int32.MaxValue or -1. + + + Argument must be less than or equal to 2^31 - 1 milliseconds. + diff --git a/src/libraries/System.Diagnostics.Process/src/Resources/Strings.resx b/src/libraries/System.Diagnostics.Process/src/Resources/Strings.resx index ddbeed29f973ac..aaf04572c4549b 100644 --- a/src/libraries/System.Diagnostics.Process/src/Resources/Strings.resx +++ b/src/libraries/System.Diagnostics.Process/src/Resources/Strings.resx @@ -299,6 +299,12 @@ Non-negative number required. + + Number must be either non-negative and less than or equal to Int32.MaxValue or -1. + + + Argument must be less than or equal to 2^31 - 1 milliseconds. + The Process object must have the UseShellExecute property set to false in order to start a process as a user. diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs index a6c5064d417b46..d7cd2098a35ca6 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs @@ -1431,7 +1431,22 @@ public bool WaitForExit(int milliseconds) /// Instructs the Process component to wait the specified number of milliseconds for /// the associated process to exit. /// - public bool WaitForExit(TimeSpan timeout) => WaitForExit(checked((int)timeout.TotalMilliseconds)); + public bool WaitForExit(TimeSpan timeout) => WaitForExit(ToTimeoutMilliseconds(timeout)); + + private static int ToTimeoutMilliseconds(TimeSpan timeout) + { + long timeoutMilliseconds = (long)timeout.TotalMilliseconds; + if (timeoutMilliseconds < -1) + { + throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1); + } + + if (timeoutMilliseconds > int.MaxValue) + { + throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_LessEqualToIntegerMaxVal); + } + return (int)timeoutMilliseconds; + } /// /// Instructs the Process component to wait for the associated process to exit, or diff --git a/src/libraries/System.IO.FileSystem.Watcher/src/Resources/Strings.resx b/src/libraries/System.IO.FileSystem.Watcher/src/Resources/Strings.resx index c16582a79cc7f3..6c9757c79fe519 100644 --- a/src/libraries/System.IO.FileSystem.Watcher/src/Resources/Strings.resx +++ b/src/libraries/System.IO.FileSystem.Watcher/src/Resources/Strings.resx @@ -140,6 +140,12 @@ Specified file length was too large for the file system. + + Number must be either non-negative and less than or equal to Int32.MaxValue or -1. + + + Argument must be less than or equal to 2^31 - 1 milliseconds. + The specified file name or path is too long, or a component of the specified path is too long. diff --git a/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.cs b/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.cs index b70ade40ebe7bb..a4612657f6cff1 100644 --- a/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.cs +++ b/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.cs @@ -620,7 +620,22 @@ public WaitForChangedResult WaitForChanged(WatcherChangeTypes changeType, int ti } public WaitForChangedResult WaitForChanged(WatcherChangeTypes changeType, TimeSpan timeout) => - WaitForChanged(changeType, checked((int)timeout.TotalMilliseconds)); + WaitForChanged(changeType, ToTimeoutMilliseconds(timeout)); + + private static int ToTimeoutMilliseconds(TimeSpan timeout) + { + long timeoutMilliseconds = (long)timeout.TotalMilliseconds; + if (timeoutMilliseconds < -1) + { + throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1); + } + + if (timeoutMilliseconds > int.MaxValue) + { + throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_LessEqualToIntegerMaxVal); + } + return (int)timeoutMilliseconds; + } /// /// Stops and starts this object. diff --git a/src/libraries/System.IO.Pipes/src/Resources/Strings.resx b/src/libraries/System.IO.Pipes/src/Resources/Strings.resx index 166aacdb95798c..38425717192384 100644 --- a/src/libraries/System.IO.Pipes/src/Resources/Strings.resx +++ b/src/libraries/System.IO.Pipes/src/Resources/Strings.resx @@ -123,6 +123,12 @@ Invalid PipeAccessRights value. + + Number must be either non-negative and less than or equal to Int32.MaxValue or -1. + + + Argument must be less than or equal to 2^31 - 1 milliseconds. + This flag may not be set on a pipe. diff --git a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.cs b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.cs index f60bfb246de7db..7e2bba18ef52a3 100644 --- a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.cs +++ b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.cs @@ -129,7 +129,7 @@ public void Connect(int timeout) ConnectInternal(timeout, CancellationToken.None, Environment.TickCount); } - public void Connect(TimeSpan timeout) => Connect(checked((int)timeout.TotalMilliseconds)); + public void Connect(TimeSpan timeout) => Connect(ToTimeoutMilliseconds(timeout)); private void ConnectInternal(int timeout, CancellationToken cancellationToken, int startTime) { @@ -200,7 +200,22 @@ public Task ConnectAsync(int timeout, CancellationToken cancellationToken) } public Task ConnectAsync(TimeSpan timeout, CancellationToken cancellationToken = default) => - ConnectAsync(checked((int)timeout.TotalMilliseconds), cancellationToken); + ConnectAsync(ToTimeoutMilliseconds(timeout), cancellationToken); + + private static int ToTimeoutMilliseconds(TimeSpan timeout) + { + long timeoutMilliseconds = (long)timeout.TotalMilliseconds; + if (timeoutMilliseconds < -1) + { + throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1); + } + + if (timeoutMilliseconds > int.MaxValue) + { + throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_LessEqualToIntegerMaxVal); + } + return (int)timeoutMilliseconds; + } // override because named pipe clients can't get/set properties when waiting to connect // or broken diff --git a/src/libraries/System.Net.Ping/src/Resources/Strings.resx b/src/libraries/System.Net.Ping/src/Resources/Strings.resx index a2a8a43068beb6..2a08c10a0c2d8c 100644 --- a/src/libraries/System.Net.Ping/src/Resources/Strings.resx +++ b/src/libraries/System.Net.Ping/src/Resources/Strings.resx @@ -90,4 +90,10 @@ Unable to send custom ping payload. Run program under privileged user account or grant cap_net_raw capability using setcap(8). + + Number must be either non-negative and less than or equal to Int32.MaxValue or -1. + + + Argument must be less than or equal to 2^31 - 1 milliseconds. + diff --git a/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs b/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs index 5b04f04716ca41..7e25a3f98388ba 100644 --- a/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs +++ b/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs @@ -238,10 +238,10 @@ public PingReply Send(IPAddress address, int timeout, byte[] buffer, PingOptions } public PingReply Send(IPAddress address, TimeSpan timeout, byte[]? buffer = null, PingOptions? options = null) => - Send(address, checked((int)timeout.TotalMilliseconds), buffer ?? DefaultSendBuffer, options); + Send(address, ToTimeoutMilliseconds(timeout), buffer ?? DefaultSendBuffer, options); public PingReply Send(string hostNameOrAddress, TimeSpan timeout, byte[]? buffer = null, - PingOptions? options = null) => Send(hostNameOrAddress, checked((int)timeout.TotalMilliseconds), buffer ?? DefaultSendBuffer, options); + PingOptions? options = null) => Send(hostNameOrAddress, ToTimeoutMilliseconds(timeout), buffer ?? DefaultSendBuffer, options); public void SendAsync(string hostNameOrAddress, object? userToken) { @@ -344,9 +344,9 @@ public Task SendPingAsync(IPAddress address, TimeSpan timeout, byte[] public Task SendPingAsync(string hostNameOrAddress, TimeSpan timeout, byte[]? buffer = null, PingOptions? options = null, CancellationToken cancellationToken = default) { - int milliseconds = checked((int)timeout.TotalMilliseconds); - cancellationToken.ThrowIfCancellationRequested(); + + int milliseconds = ToTimeoutMilliseconds(timeout); Task task = SendPingAsync(hostNameOrAddress, milliseconds, buffer ?? DefaultSendBuffer, options); return task.WaitAsync(cancellationToken); @@ -391,6 +391,21 @@ public Task SendPingAsync(string hostNameOrAddress, int timeout, byte return GetAddressAndSendAsync(hostNameOrAddress, timeout, buffer, options); } + private static int ToTimeoutMilliseconds(TimeSpan timeout) + { + long timeoutMilliseconds = (long)timeout.TotalMilliseconds; + if (timeoutMilliseconds < -1) + { + throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1); + } + + if (timeoutMilliseconds > int.MaxValue) + { + throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_LessEqualToIntegerMaxVal); + } + return (int)timeoutMilliseconds; + } + public void SendAsyncCancel() { lock (_lockObject) diff --git a/src/libraries/System.Net.Sockets/src/Resources/Strings.resx b/src/libraries/System.Net.Sockets/src/Resources/Strings.resx index 57d1a94b6ae6bd..3940f8ce4a4273 100644 --- a/src/libraries/System.Net.Sockets/src/Resources/Strings.resx +++ b/src/libraries/System.Net.Sockets/src/Resources/Strings.resx @@ -255,6 +255,12 @@ Argument '{2}' must be between {0} and {1}. + + Number must be either non-negative and less than or equal to Int32.MaxValue or -1. + + + Argument must be less than or equal to 2^31 - 1 milliseconds. + Sockets on this platform are invalid for use after a failed connection attempt. diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs index b40a889eb91949..72f22cfee4b992 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs @@ -341,7 +341,22 @@ public void Close(int timeout) Dispose(); } - public void Close(TimeSpan timeout) => Close(checked((int)timeout.TotalMilliseconds)); + public void Close(TimeSpan timeout) => Close(ToTimeoutMilliseconds(timeout)); + + private static int ToTimeoutMilliseconds(TimeSpan timeout) + { + long timeoutMilliseconds = (long)timeout.TotalMilliseconds; + if (timeoutMilliseconds < -1) + { + throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1); + } + + if (timeoutMilliseconds > int.MaxValue) + { + throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_LessEqualToIntegerMaxVal); + } + return (int)timeoutMilliseconds; + } protected override void Dispose(bool disposing) { diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs index 3aaf6531f08b11..2085d7b6440ef4 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs @@ -2182,7 +2182,7 @@ public bool Poll(int microSeconds, SelectMode mode) } public bool Poll(TimeSpan timeout, SelectMode mode) => - Poll(checked((int)timeout.TotalMilliseconds) / 1000, mode); + Poll(ToTimeoutMicroseconds(timeout), mode); // Determines the status of a socket. public static void Select(IList? checkRead, IList? checkWrite, IList? checkError, int microSeconds) @@ -2215,7 +2215,23 @@ public static void Select(IList? checkRead, IList? checkWrite, IList? checkError } } - public static void Select(IList? checkRead, IList? checkWrite, IList? checkError, TimeSpan timeout) => Select(checkRead, checkWrite, checkError, checked((int)timeout.TotalMilliseconds) / 1000); + public static void Select(IList? checkRead, IList? checkWrite, IList? checkError, TimeSpan timeout) => Select(checkRead, checkWrite, checkError, ToTimeoutMicroseconds(timeout)); + + private static int ToTimeoutMicroseconds(TimeSpan timeout) + { + long timeoutMilliseconds = (long)timeout.TotalMilliseconds; + if (timeoutMilliseconds < -1) + { + throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1); + } + + if (timeoutMilliseconds > int.MaxValue) + { + throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_LessEqualToIntegerMaxVal); + } + + return (int)timeoutMilliseconds / 1000; + } public IAsyncResult BeginConnect(EndPoint remoteEP, AsyncCallback? callback, object? state) => TaskToApm.Begin(ConnectAsync(remoteEP), callback, state); diff --git a/src/libraries/System.ServiceProcess.ServiceController/src/Resources/Strings.resx b/src/libraries/System.ServiceProcess.ServiceController/src/Resources/Strings.resx index aa322b1624ad46..d1646add4be0f0 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/src/Resources/Strings.resx +++ b/src/libraries/System.ServiceProcess.ServiceController/src/Resources/Strings.resx @@ -162,4 +162,10 @@ Cannot control '{0}' service on computer '{1}'. + + Number must be either non-negative and less than or equal to Int32.MaxValue or -1. + + + Argument must be less than or equal to 2^31 - 1 milliseconds. + diff --git a/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs b/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs index a6b5042e295648..5433e6f32a6b00 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs +++ b/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs @@ -79,10 +79,21 @@ public unsafe void RequestAdditionalTime(int milliseconds) /// Service Control Manager to avoid having the service marked as not responding. /// /// - public unsafe void RequestAdditionalTime(TimeSpan time) + public void RequestAdditionalTime(TimeSpan time) => RequestAdditionalTime(ToTimeoutMilliseconds(time)); + + private static int ToTimeoutMilliseconds(TimeSpan timeout) { - int milliseconds = (int)time.TotalMilliseconds; - RequestAdditionalTime(milliseconds); + long timeoutMilliseconds = (long)timeout.TotalMilliseconds; + if (timeoutMilliseconds < -1) + { + throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1); + } + + if (timeoutMilliseconds > int.MaxValue) + { + throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_LessEqualToIntegerMaxVal); + } + return (int)timeoutMilliseconds; } #endif diff --git a/src/mono/System.Private.CoreLib/src/System/GC.Mono.cs b/src/mono/System.Private.CoreLib/src/System/GC.Mono.cs index 87a23327b63475..4464eed788f367 100644 --- a/src/mono/System.Private.CoreLib/src/System/GC.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/GC.Mono.cs @@ -5,6 +5,7 @@ using System.Runtime.CompilerServices; using Internal.Runtime.CompilerServices; using System.Diagnostics.Tracing; +using System.Threading; namespace System { @@ -205,7 +206,7 @@ public static GCNotificationStatus WaitForFullGCApproach(int millisecondsTimeout } public static GCNotificationStatus WaitForFullGCApproach(TimeSpan timeout) => - WaitForFullGCApproach(checked((int)timeout.TotalMilliseconds)); + WaitForFullGCApproach(WaitHandle.ToTimeoutMilliseconds(timeout)); public static GCNotificationStatus WaitForFullGCComplete() { @@ -220,7 +221,7 @@ public static GCNotificationStatus WaitForFullGCComplete(int millisecondsTimeout } public static GCNotificationStatus WaitForFullGCComplete(TimeSpan timeout) => - WaitForFullGCComplete(checked((int)timeout.TotalMilliseconds)); + WaitForFullGCComplete(WaitHandle.ToTimeoutMilliseconds(timeout)); private static bool StartNoGCRegion(long totalSize, bool hasLohSize, long lohSize, bool disallowFullBlockingGC) { From 80f10be7575ff38555fb3c26beac77cb3104f738 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Tue, 15 Feb 2022 17:30:55 +0100 Subject: [PATCH 43/72] Remove redundant TimerConstructor test --- .../System.Threading.Timer/tests/TimerConstructorTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libraries/System.Threading.Timer/tests/TimerConstructorTests.cs b/src/libraries/System.Threading.Timer/tests/TimerConstructorTests.cs index 43281dc7127702..b8af1fd2038fe1 100644 --- a/src/libraries/System.Threading.Timer/tests/TimerConstructorTests.cs +++ b/src/libraries/System.Threading.Timer/tests/TimerConstructorTests.cs @@ -56,7 +56,6 @@ public void Timer_AllConstructorsCanBeUsedSuccessfully() new Timer(_ => { }, null, Timeout, Timeout).Dispose(); new Timer(_ => { }, null, (long)Timeout, (long)Timeout).Dispose(); new Timer(_ => { }, null, (uint)Timeout, (uint)Timeout).Dispose(); - new Timer(TimeSpan.FromMilliseconds(Timeout)).Dispose(); new Timer(_ => { }, null, TimeSpan.FromMilliseconds(Timeout), TimeSpan.FromMilliseconds(Timeout)).Dispose(); } } From 6805ad47facc845a67c60fc202065390ff7ef844 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Tue, 15 Feb 2022 17:57:30 +0100 Subject: [PATCH 44/72] Add setter to `RegularExpressionAttribute.MatchTimeout` --- .../ref/System.ComponentModel.Annotations.cs | 2 +- .../src/Resources/Strings.resx | 6 ++++++ .../RegularExpressionAttribute.cs | 20 ++++++++++++++++++- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.ComponentModel.Annotations/ref/System.ComponentModel.Annotations.cs b/src/libraries/System.ComponentModel.Annotations/ref/System.ComponentModel.Annotations.cs index c6a9b98a8eba03..319f43c65d1da3 100644 --- a/src/libraries/System.ComponentModel.Annotations/ref/System.ComponentModel.Annotations.cs +++ b/src/libraries/System.ComponentModel.Annotations/ref/System.ComponentModel.Annotations.cs @@ -237,7 +237,7 @@ public partial class RegularExpressionAttribute : System.ComponentModel.DataAnno { public RegularExpressionAttribute([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute(System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.Regex)] string pattern) { } public int MatchTimeoutInMilliseconds { get { throw null; } set { } } - public System.TimeSpan MatchTimeout { get { throw null; } } + public System.TimeSpan MatchTimeout { get { throw null; } set { } } public string Pattern { get { throw null; } } public override string FormatErrorMessage(string name) { throw null; } public override bool IsValid(object? value) { throw null; } diff --git a/src/libraries/System.ComponentModel.Annotations/src/Resources/Strings.resx b/src/libraries/System.ComponentModel.Annotations/src/Resources/Strings.resx index e20eea0c0669c5..8e57fb646d730d 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/Resources/Strings.resx +++ b/src/libraries/System.ComponentModel.Annotations/src/Resources/Strings.resx @@ -216,4 +216,10 @@ The value for property '{0}' must be of type '{1}'. + + Number must be either non-negative and less than or equal to Int32.MaxValue or -1. + + + Argument must be less than or equal to 2^31 - 1 milliseconds. + diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/RegularExpressionAttribute.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/RegularExpressionAttribute.cs index 130205fac36c38..23d8504b35cc60 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/RegularExpressionAttribute.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/RegularExpressionAttribute.cs @@ -34,7 +34,25 @@ public RegularExpressionAttribute([StringSyntax(StringSyntaxAttribute.Regex)] st /// /// Gets or sets the timeout to use when matching the regular expression pattern /// - public TimeSpan MatchTimeout => TimeSpan.FromMilliseconds(MatchTimeoutInMilliseconds); + public TimeSpan MatchTimeout + { + get => TimeSpan.FromMilliseconds(MatchTimeoutInMilliseconds); + set + { + long timeoutMilliseconds = (long)value.TotalMilliseconds; + if (timeoutMilliseconds < -1) + { + throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_NeedNonNegOrNegative1); + } + + if (timeoutMilliseconds > int.MaxValue) + { + throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_LessEqualToIntegerMaxVal); + } + + MatchTimeoutInMilliseconds = (int)timeoutMilliseconds; + } + } /// /// Gets the regular expression pattern to use From f5e484420b1e78673ac4253f753ef8d6d2a50ff5 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Tue, 15 Feb 2022 18:00:40 +0100 Subject: [PATCH 45/72] Use `ToTimeoutMilliseconds` in `WaitForInputIdle` --- .../src/System/Diagnostics/Process.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs index d7cd2098a35ca6..72350da8ebddba 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs @@ -829,7 +829,7 @@ public bool WaitForInputIdle(int milliseconds) return WaitForInputIdleCore(milliseconds); } - public bool WaitForInputIdle(TimeSpan timeout) => WaitForInputIdle(checked((int)timeout.TotalMilliseconds)); + public bool WaitForInputIdle(TimeSpan timeout) => WaitForInputIdle(ToTimeoutMilliseconds(timeout)); public ISynchronizeInvoke? SynchronizingObject { get; set; } From ff9c0e6e4edea0d784998dcc81ba714add7d271e Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Thu, 10 Mar 2022 19:03:07 +0100 Subject: [PATCH 46/72] Use legacy syntax instead of pattern matching --- .../System.Private.CoreLib/src/System/Threading/Tasks/Task.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs index 4f1e7ad16fdd56..c087c4ae06818a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs @@ -2678,7 +2678,7 @@ public bool Wait(TimeSpan timeout, CancellationToken cancellationToken) cancellationToken.ThrowIfCancellationRequested(); long totalMilliseconds = (long)timeout.TotalMilliseconds; - if (totalMilliseconds is < (-1) or > int.MaxValue) + if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.timeout); } From 099aacbffe3238a476107c204511a435981b288c Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Fri, 18 Mar 2022 18:11:47 +0100 Subject: [PATCH 47/72] Remove setter from `RegularExpressionAttribute.MatchTimeout` /cc @bartonjs --- .../ref/System.ComponentModel.Annotations.cs | 2 +- .../RegularExpressionAttribute.cs | 22 ++----------------- 2 files changed, 3 insertions(+), 21 deletions(-) diff --git a/src/libraries/System.ComponentModel.Annotations/ref/System.ComponentModel.Annotations.cs b/src/libraries/System.ComponentModel.Annotations/ref/System.ComponentModel.Annotations.cs index 319f43c65d1da3..c6a9b98a8eba03 100644 --- a/src/libraries/System.ComponentModel.Annotations/ref/System.ComponentModel.Annotations.cs +++ b/src/libraries/System.ComponentModel.Annotations/ref/System.ComponentModel.Annotations.cs @@ -237,7 +237,7 @@ public partial class RegularExpressionAttribute : System.ComponentModel.DataAnno { public RegularExpressionAttribute([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute(System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.Regex)] string pattern) { } public int MatchTimeoutInMilliseconds { get { throw null; } set { } } - public System.TimeSpan MatchTimeout { get { throw null; } set { } } + public System.TimeSpan MatchTimeout { get { throw null; } } public string Pattern { get { throw null; } } public override string FormatErrorMessage(string name) { throw null; } public override bool IsValid(object? value) { throw null; } diff --git a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/RegularExpressionAttribute.cs b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/RegularExpressionAttribute.cs index 23d8504b35cc60..b21d843d060f7d 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/RegularExpressionAttribute.cs +++ b/src/libraries/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/RegularExpressionAttribute.cs @@ -32,27 +32,9 @@ public RegularExpressionAttribute([StringSyntax(StringSyntaxAttribute.Regex)] st public int MatchTimeoutInMilliseconds { get; set; } /// - /// Gets or sets the timeout to use when matching the regular expression pattern + /// Gets the timeout to use when matching the regular expression pattern /// - public TimeSpan MatchTimeout - { - get => TimeSpan.FromMilliseconds(MatchTimeoutInMilliseconds); - set - { - long timeoutMilliseconds = (long)value.TotalMilliseconds; - if (timeoutMilliseconds < -1) - { - throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_NeedNonNegOrNegative1); - } - - if (timeoutMilliseconds > int.MaxValue) - { - throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_LessEqualToIntegerMaxVal); - } - - MatchTimeoutInMilliseconds = (int)timeoutMilliseconds; - } - } + public TimeSpan MatchTimeout => TimeSpan.FromMilliseconds(MatchTimeoutInMilliseconds); /// /// Gets the regular expression pattern to use From d659806e362674b6fbadddfd233407face884ccf Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Fri, 18 Mar 2022 19:41:32 +0100 Subject: [PATCH 48/72] Centralize `GC` methods --- .../System.Private.CoreLib.csproj | 10 +++---- .../src/System/{GC.cs => GC.CoreCLR.cs} | 5 ---- .../src/System.Private.CoreLib.csproj | 2 +- .../src/System/{GC.cs => GC.CoreRT.cs} | 18 +------------ .../System.Private.CoreLib.Shared.projitems | 3 ++- .../System.Private.CoreLib/src/System/GC.cs | 27 +++++++++++++++++++ .../src/System/GC.Mono.cs | 6 ----- 7 files changed, 34 insertions(+), 37 deletions(-) rename src/coreclr/System.Private.CoreLib/src/System/{GC.cs => GC.CoreCLR.cs} (98%) rename src/coreclr/nativeaot/System.Private.CoreLib/src/System/{GC.cs => GC.CoreRT.cs} (96%) create mode 100644 src/libraries/System.Private.CoreLib/src/System/GC.cs diff --git a/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj index adf2908c581ab9..357c03960299c8 100644 --- a/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -143,7 +143,7 @@ - + @@ -317,7 +317,7 @@ - + @@ -331,11 +331,7 @@ - + diff --git a/src/coreclr/System.Private.CoreLib/src/System/GC.cs b/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs similarity index 98% rename from src/coreclr/System.Private.CoreLib/src/System/GC.cs rename to src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs index ea4ee245712c61..901c45296d479a 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/GC.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs @@ -357,7 +357,6 @@ public static long GetTotalMemory(bool forceFullCollection) [MethodImpl(MethodImplOptions.InternalCall)] public static extern long GetAllocatedBytesForCurrentThread(); - /// /// Get a count of the bytes allocated over the lifetime of the process. /// If true, gather a precise number, otherwise gather a fairly count. Gathering a precise value triggers at a significant performance penalty. @@ -424,8 +423,6 @@ public static GCNotificationStatus WaitForFullGCApproach(int millisecondsTimeout return (GCNotificationStatus)_WaitForFullGCApproach(millisecondsTimeout); } - public static GCNotificationStatus WaitForFullGCApproach(TimeSpan timeout) => WaitForFullGCApproach(WaitHandle.ToTimeoutMilliseconds(timeout)); - public static GCNotificationStatus WaitForFullGCComplete() { return (GCNotificationStatus)_WaitForFullGCComplete(-1); @@ -438,8 +435,6 @@ public static GCNotificationStatus WaitForFullGCComplete(int millisecondsTimeout return (GCNotificationStatus)_WaitForFullGCComplete(millisecondsTimeout); } - public static GCNotificationStatus WaitForFullGCComplete(TimeSpan timeout) => WaitForFullGCComplete(WaitHandle.ToTimeoutMilliseconds(timeout)); - private enum StartNoGCRegionStatus { Succeeded = 0, diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj index 523b6b8c3a814d..2b562e55213dbc 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj @@ -169,7 +169,7 @@ - + diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.CoreRT.cs similarity index 96% rename from src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.CoreRT.cs index e045150bfe77fc..783f75f41ef6a4 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.CoreRT.cs @@ -58,7 +58,7 @@ internal enum EndNoGCRegionStatus AllocationExceeded = 3 } - public static class GC + public static partial class GC { public static int GetGeneration(object obj) { @@ -215,14 +215,6 @@ public static GCNotificationStatus WaitForFullGCApproach(int millisecondsTimeout return (GCNotificationStatus)RuntimeImports.RhWaitForFullGCApproach(millisecondsTimeout); } - /// - /// Returns, in a specified time-out period, the status of a registered notification for determining whether a full, - /// blocking garbage collection by the common language runtime is imminent. - /// - /// The timeout on waiting for a full collection - /// The status of a registered full GC notification - public static GCNotificationStatus WaitForFullGCApproach(TimeSpan timeout) => WaitForFullGCApproach(WaitHandle.ToTimeoutMilliseconds(timeout)); - /// /// Returns the status of a registered notification about whether a blocking garbage collection /// has completed. May wait indefinitely for a full collection. @@ -251,14 +243,6 @@ public static GCNotificationStatus WaitForFullGCComplete(int millisecondsTimeout return (GCNotificationStatus)RuntimeImports.RhWaitForFullGCComplete(millisecondsTimeout); } - /// - /// Returns, in a specified time-out period, the status of a registered notification for determining whether a full, - /// blocking garbage collection by common language the runtime has completed. - /// - /// The timeout on waiting for a full collection - /// The status of the registered garbage collection notification. - public static GCNotificationStatus WaitForFullGCComplete(TimeSpan timeout) => WaitForFullGCComplete(WaitHandle.ToTimeoutMilliseconds(timeout)); - /// /// Cancels an outstanding full GC notification. /// diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 3a846e7828eab4..35c16eb7412ecf 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -309,6 +309,7 @@ + @@ -2382,4 +2383,4 @@ - + \ No newline at end of file diff --git a/src/libraries/System.Private.CoreLib/src/System/GC.cs b/src/libraries/System.Private.CoreLib/src/System/GC.cs new file mode 100644 index 00000000000000..9dde60df71c701 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/GC.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Threading; + +namespace System +{ + public static partial class GC + { + /// + /// Returns, in a specified time-out period, the status of a registered notification for determining whether a full, + /// blocking garbage collection by the common language runtime is imminent. + /// + /// The timeout on waiting for a full collection + /// The status of a registered full GC notification + public static GCNotificationStatus WaitForFullGCApproach(TimeSpan timeout) + => WaitForFullGCApproach(WaitHandle.ToTimeoutMilliseconds(timeout)); + + /// + /// Returns the status of a registered notification about whether a blocking garbage collection + /// has completed. May wait indefinitely for a full collection. + /// + /// The status of a registered full GC notification + public static GCNotificationStatus WaitForFullGCComplete(TimeSpan timeout) + => WaitForFullGCComplete(WaitHandle.ToTimeoutMilliseconds(timeout)); + } +} diff --git a/src/mono/System.Private.CoreLib/src/System/GC.Mono.cs b/src/mono/System.Private.CoreLib/src/System/GC.Mono.cs index eff761b4b162ec..eb5e0210c5df27 100644 --- a/src/mono/System.Private.CoreLib/src/System/GC.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/GC.Mono.cs @@ -204,9 +204,6 @@ public static GCNotificationStatus WaitForFullGCApproach(int millisecondsTimeout return _WaitForFullGCApproach(millisecondsTimeout); } - public static GCNotificationStatus WaitForFullGCApproach(TimeSpan timeout) => - WaitForFullGCApproach(WaitHandle.ToTimeoutMilliseconds(timeout)); - public static GCNotificationStatus WaitForFullGCComplete() { return _WaitForFullGCComplete(-1); @@ -219,9 +216,6 @@ public static GCNotificationStatus WaitForFullGCComplete(int millisecondsTimeout return _WaitForFullGCComplete(millisecondsTimeout); } - public static GCNotificationStatus WaitForFullGCComplete(TimeSpan timeout) => - WaitForFullGCComplete(WaitHandle.ToTimeoutMilliseconds(timeout)); - private static bool StartNoGCRegion(long totalSize, bool hasLohSize, long lohSize, bool disallowFullBlockingGC) { throw new NotImplementedException(); From eef5d7186c3b89aa9cd3645f3dd8e40c5ee2729d Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Fri, 18 Mar 2022 20:19:01 +0100 Subject: [PATCH 49/72] Apply suggestions Co-Authored-By: Dan Moseley --- .../src/Resources/Strings.resx | 2 +- .../System.Diagnostics.EventLog/src/Resources/Strings.resx | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/libraries/System.ComponentModel.Annotations/src/Resources/Strings.resx b/src/libraries/System.ComponentModel.Annotations/src/Resources/Strings.resx index 8e57fb646d730d..f75775f097b73c 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/Resources/Strings.resx +++ b/src/libraries/System.ComponentModel.Annotations/src/Resources/Strings.resx @@ -217,7 +217,7 @@ The value for property '{0}' must be of type '{1}'. - Number must be either non-negative and less than or equal to Int32.MaxValue or -1. + Number must either be -1, or 0 through Int32.MaxValue inclusive. Argument must be less than or equal to 2^31 - 1 milliseconds. diff --git a/src/libraries/System.Diagnostics.EventLog/src/Resources/Strings.resx b/src/libraries/System.Diagnostics.EventLog/src/Resources/Strings.resx index 9b0c8387d9c213..e0aec25828364b 100644 --- a/src/libraries/System.Diagnostics.EventLog/src/Resources/Strings.resx +++ b/src/libraries/System.Diagnostics.EventLog/src/Resources/Strings.resx @@ -239,10 +239,4 @@ Log {0} has already been registered as a source on the local computer. - - Number must be either non-negative and less than or equal to Int32.MaxValue or -1. - - - Argument must be less than or equal to 2^31 - 1 milliseconds. - From b9aca93d6ad46261e608ad88fe8816f5db1a4de9 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Fri, 18 Mar 2022 20:41:48 +0100 Subject: [PATCH 50/72] Add doc comment to `Process.WaitForInputIdle` --- .../src/System/Diagnostics/Process.cs | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs index b39f727566e9d4..3231ac5c3f73a3 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs @@ -826,6 +826,37 @@ public bool WaitForInputIdle(int milliseconds) return WaitForInputIdleCore(milliseconds); } + /// + /// Causes the component to wait the specified for the associated process to enter an idle state. + /// This overload applies only to processes with a user interface and, therefore, a message loop. + /// + /// The amount of time, in milliseconds, to wait for the associated process to become idle. + /// if the associated process has reached an idle state; otherwise, . + /// + /// The process does not have a graphical interface. + /// + /// -or- + /// + /// An unknown error occurred. The process failed to enter an idle state. + /// + /// -or- + /// + /// The process has already exited. + /// + /// -or- + /// + /// No process is associated with this object. + /// + /// + /// Use to force the processing of your application + /// to wait until the message loop has returned to the idle state. + /// When a process with a user interface is executing, its message loop executes every time + /// a Windows message is sent to the process by the operating system. + /// The process then returns to the message loop. A process is said to be in an idle state + /// when it is waiting for messages inside of a message loop. + /// This state is useful, for example, when your application needs to wait for a starting process + /// to finish creating its main window before the application communicates with that window. + /// public bool WaitForInputIdle(TimeSpan timeout) => WaitForInputIdle(ToTimeoutMilliseconds(timeout)); public ISynchronizeInvoke? SynchronizingObject { get; set; } From ca7edd24ba0c043f74481c20df2cd2eeeff6797f Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Fri, 18 Mar 2022 20:52:59 +0100 Subject: [PATCH 51/72] Reduce test duplication to reduce opportunities to flake out Co-Authored-By: Dan Moseley --- .../tests/FileSystemWatcher.WaitForChanged.cs | 91 +++++-------------- 1 file changed, 25 insertions(+), 66 deletions(-) diff --git a/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.WaitForChanged.cs b/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.WaitForChanged.cs index f083407d06f96d..87da9225591146 100644 --- a/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.WaitForChanged.cs +++ b/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.WaitForChanged.cs @@ -76,105 +76,64 @@ public static void WaitForChangedResult_TimedOut_Roundtrip() } [Theory] - [InlineData(false)] - [InlineData(true)] - public void ZeroTimeout_TimesOut(bool enabledBeforeWait) + [InlineData(false, true)] + [InlineData(true, false)] + public void ZeroTimeout_TimesOut(bool enabledBeforeWait, bool useTimeSpan) { using (var testDirectory = new TempDirectory(GetTestFilePath())) using (var dir = new TempDirectory(Path.Combine(testDirectory.Path, GetTestFileName()))) using (var fsw = new FileSystemWatcher(testDirectory.Path)) { if (enabledBeforeWait) fsw.EnableRaisingEvents = true; - AssertTimedOut(fsw.WaitForChanged(WatcherChangeTypes.All, 0)); + + const int timeoutMillis = 0; + AssertTimedOut(useTimeSpan + ? fsw.WaitForChanged(WatcherChangeTypes.All, TimeSpan.FromMilliseconds(timeoutMillis)) + : fsw.WaitForChanged(WatcherChangeTypes.All, timeoutMillis)); Assert.Equal(enabledBeforeWait, fsw.EnableRaisingEvents); } } [Theory] - [InlineData(false)] - [InlineData(true)] - public void NonZeroTimeout_NoEvents_TimesOut(bool enabledBeforeWait) + [InlineData(false, false)] + [InlineData(true, true)] + public void NonZeroTimeout_NoEvents_TimesOut(bool enabledBeforeWait, bool useTimeSpan) { using (var testDirectory = new TempDirectory(GetTestFilePath())) using (var dir = new TempDirectory(Path.Combine(testDirectory.Path, GetTestFileName()))) using (var fsw = new FileSystemWatcher(testDirectory.Path)) { if (enabledBeforeWait) fsw.EnableRaisingEvents = true; - AssertTimedOut(fsw.WaitForChanged(0, 1)); + const int timeoutMillis = 1; + AssertTimedOut(useTimeSpan + ? fsw.WaitForChanged(0, TimeSpan.FromMilliseconds(timeoutMillis)) + : fsw.WaitForChanged(0, timeoutMillis)); Assert.Equal(enabledBeforeWait, fsw.EnableRaisingEvents); } } [Theory] - [InlineData(WatcherChangeTypes.Deleted, false)] - [InlineData(WatcherChangeTypes.Created, true)] - [InlineData(WatcherChangeTypes.Changed, false)] - [InlineData(WatcherChangeTypes.Renamed, true)] - [InlineData(WatcherChangeTypes.All, true)] + [InlineData(WatcherChangeTypes.Deleted, false, true)] + [InlineData(WatcherChangeTypes.Created, true, false)] + [InlineData(WatcherChangeTypes.Changed, false, true)] + [InlineData(WatcherChangeTypes.Renamed, true, false)] + [InlineData(WatcherChangeTypes.All, true, true)] [ActiveIssue("https://github.com/dotnet/runtime/issues/58418", typeof(PlatformDetection), nameof(PlatformDetection.IsMacCatalyst), nameof(PlatformDetection.IsArm64Process))] - public void NonZeroTimeout_NoActivity_TimesOut(WatcherChangeTypes changeType, bool enabledBeforeWait) + public void NonZeroTimeout_NoActivity_TimesOut(WatcherChangeTypes changeType, bool enabledBeforeWait, bool useTimeSpan) { using (var testDirectory = new TempDirectory(GetTestFilePath())) using (var dir = new TempDirectory(Path.Combine(testDirectory.Path, GetTestFileName()))) using (var fsw = new FileSystemWatcher(testDirectory.Path)) { if (enabledBeforeWait) fsw.EnableRaisingEvents = true; - AssertTimedOut(fsw.WaitForChanged(changeType, 1)); + const int timeoutMillis = 1; + AssertTimedOut(useTimeSpan + ? fsw.WaitForChanged(changeType, TimeSpan.FromMilliseconds(timeoutMillis)) + : fsw.WaitForChanged(changeType, timeoutMillis)); Assert.Equal(enabledBeforeWait, fsw.EnableRaisingEvents); } } - [Theory] - [InlineData(false)] - [InlineData(true)] - public void ZeroTimeout_TimesOut_TimeSpan(bool enabledBeforeWait) - { - TimeSpan timeout = TimeSpan.FromMilliseconds(0); - - using var testDirectory = new TempDirectory(GetTestFilePath()); - using var dir = new TempDirectory(Path.Combine(testDirectory.Path, GetTestFileName())); - using var fsw = new FileSystemWatcher(testDirectory.Path); - - if (enabledBeforeWait) fsw.EnableRaisingEvents = true; - AssertTimedOut(fsw.WaitForChanged(WatcherChangeTypes.All, timeout)); - Assert.Equal(enabledBeforeWait, fsw.EnableRaisingEvents); - } - - [Theory] - [InlineData(false)] - [InlineData(true)] - public void NonZeroTimeout_NoEvents_TimesOut_TimeSpan(bool enabledBeforeWait) - { - TimeSpan timeout = TimeSpan.FromMilliseconds(1); - - using var testDirectory = new TempDirectory(GetTestFilePath()); - using var dir = new TempDirectory(Path.Combine(testDirectory.Path, GetTestFileName())); - using var fsw = new FileSystemWatcher(testDirectory.Path); - - if (enabledBeforeWait) fsw.EnableRaisingEvents = true; - AssertTimedOut(fsw.WaitForChanged(0, timeout)); - Assert.Equal(enabledBeforeWait, fsw.EnableRaisingEvents); - } - - [Theory] - [InlineData(WatcherChangeTypes.Deleted, false)] - [InlineData(WatcherChangeTypes.Created, true)] - [InlineData(WatcherChangeTypes.Changed, false)] - [InlineData(WatcherChangeTypes.Renamed, true)] - [InlineData(WatcherChangeTypes.All, true)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/58418", typeof(PlatformDetection), nameof(PlatformDetection.IsMacCatalyst), nameof(PlatformDetection.IsArm64Process))] - public void NonZeroTimeout_NoActivity_TimesOut_TimeSpan(WatcherChangeTypes changeType, bool enabledBeforeWait) - { - TimeSpan timeout = TimeSpan.FromMilliseconds(1); - using var testDirectory = new TempDirectory(GetTestFilePath()); - using var dir = new TempDirectory(Path.Combine(testDirectory.Path, GetTestFileName())); - using var fsw = new FileSystemWatcher(testDirectory.Path); - - if (enabledBeforeWait) fsw.EnableRaisingEvents = true; - AssertTimedOut(fsw.WaitForChanged(changeType, timeout)); - Assert.Equal(enabledBeforeWait, fsw.EnableRaisingEvents); - } - [Theory] [OuterLoop("This test has a longer than average timeout and may fail intermittently")] [InlineData(WatcherChangeTypes.Created)] From 3a47e9d4c586bff2d3a1b89e2cddb49bbee021e9 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Fri, 18 Mar 2022 21:05:59 +0100 Subject: [PATCH 52/72] Reduce test duplication for NamedPipes Co-Authored-By: Dan Moseley --- .../NamedPipeTest.CurrentUserOnly.Windows.cs | 38 +++++---------- .../NamedPipeTests/NamedPipeTest.Specific.cs | 46 ++++--------------- 2 files changed, 20 insertions(+), 64 deletions(-) diff --git a/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.CurrentUserOnly.Windows.cs b/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.CurrentUserOnly.Windows.cs index 8e3810b1fe2342..e4f9a045759a7c 100644 --- a/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.CurrentUserOnly.Windows.cs +++ b/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.CurrentUserOnly.Windows.cs @@ -162,30 +162,10 @@ public void Connection_UnderDifferentUsers_BehavesAsExpected( } [OuterLoop] - [ConditionalFact(nameof(IsAdminOnSupportedWindowsVersions))] - public void Allow_Connection_UnderDifferentUsers_ForClientReading() - { - string name = PipeStreamConformanceTests.GetUniquePipeName(); - using (var server = new NamedPipeServerStream( - name, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous)) - { - Task serverTask = server.WaitForConnectionAsync(CancellationToken.None); - - _testAccountImpersonator.RunImpersonated(() => - { - using (var client = new NamedPipeClientStream(".", name, PipeDirection.In)) - { - client.Connect(10_000); - } - }); - - Assert.True(serverTask.Wait(10_000)); - } - } - - [OuterLoop] - [ConditionalFact(nameof(IsAdminOnSupportedWindowsVersions))] - public void Allow_Connection_UnderDifferentUsers_ForClientReading_TimeSpan() + [ConditionalTheory(nameof(IsAdminOnSupportedWindowsVersions))] + [InlineData(false)] + [InlineData(true)] + public void Allow_Connection_UnderDifferentUsers_ForClientReading(bool useTimeSpan) { string name = PipeStreamConformanceTests.GetUniquePipeName(); using (var server = new NamedPipeServerStream( @@ -197,8 +177,14 @@ public void Allow_Connection_UnderDifferentUsers_ForClientReading_TimeSpan() { using (var client = new NamedPipeClientStream(".", name, PipeDirection.In)) { - TimeSpan timeout = TimeSpan.FromMilliseconds(10_000); - client.Connect(timeout); + if (useTimeSpan) + { + client.Connect(TimeSpan.FromMilliseconds(10_000)); + } + else + { + client.Connect(10_000); + } } }); diff --git a/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Specific.cs b/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Specific.cs index 8acd5bebcf8fbd..e285f3b651e85b 100644 --- a/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Specific.cs +++ b/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Specific.cs @@ -16,24 +16,14 @@ namespace System.IO.Pipes.Tests /// public class NamedPipeTest_Specific { - [Fact] public void InvalidConnectTimeout_Throws_ArgumentOutOfRangeException() { using (NamedPipeClientStream client = new NamedPipeClientStream("client1")) { AssertExtensions.Throws("timeout", () => client.Connect(-111)); AssertExtensions.Throws("timeout", () => { client.ConnectAsync(-111); }); - } - } - [Fact] - public void InvalidConnectTimeout_Throws_ArgumentOutOfRangeException_TimeSpan() - { - using (NamedPipeClientStream client = new NamedPipeClientStream("client1")) - { - var ctx = new CancellationTokenSource(); - TimeSpan negativeTimeout = TimeSpan.FromMilliseconds(-111); - AssertExtensions.Throws("timeout", () => client.Connect(negativeTimeout)); - AssertExtensions.Throws("timeout", () => { client.ConnectAsync(negativeTimeout, ctx.Token); }); + AssertExtensions.Throws("timeout", () => client.Connect(TimeSpan.FromMilliseconds(-111))); + AssertExtensions.Throws("timeout", () => { client.ConnectAsync(TimeSpan.FromMilliseconds(-111)); }); } } @@ -43,21 +33,12 @@ public async Task ConnectToNonExistentServer_Throws_TimeoutException() using (NamedPipeClientStream client = new NamedPipeClientStream(".", "notthere")) { var ctx = new CancellationTokenSource(); - Assert.Throws(() => client.Connect(60)); // 60 to be over internal 50 interval - await Assert.ThrowsAsync(() => client.ConnectAsync(50)); - await Assert.ThrowsAsync(() => client.ConnectAsync(60, ctx.Token)); // testing Token overload; ctx is not canceled in this test - } - } - - [Fact] - public async Task ConnectToNonExistentServer_Throws_TimeoutException_TimeSpan() - { - using (NamedPipeClientStream client = new NamedPipeClientStream(".", "notthere")) - { - var ctx = new CancellationTokenSource(); - Assert.Throws(() => client.Connect(TimeSpan.FromMilliseconds(60))); // 60 to be over internal 50 interval - await Assert.ThrowsAsync(() => client.ConnectAsync(TimeSpan.FromMilliseconds(50), ctx.Token)); - await Assert.ThrowsAsync(() => client.ConnectAsync(TimeSpan.FromMilliseconds(60), ctx.Token)); // testing Token overload; ctx is not canceled in this test + Assert.Throws(() => + client.Connect(TimeSpan.FromMilliseconds(60))); // 60 to be over internal 50 interval + await Assert.ThrowsAsync(() => client.ConnectAsync(TimeSpan.FromMilliseconds(50))); + await Assert.ThrowsAsync(() => + client.ConnectAsync(TimeSpan.FromMilliseconds(60), + ctx.Token)); // testing Token overload; ctx is not canceled in this test } } @@ -627,17 +608,6 @@ public void ClientConnect_Throws_Timeout_When_Pipe_Not_Found() } } - [Fact] - public void ClientConnect_Throws_Timeout_When_Pipe_Not_Found_TimeSpan() - { - string pipeName = PipeStreamConformanceTests.GetUniquePipeName(); - using (NamedPipeClientStream client = new NamedPipeClientStream(pipeName)) - { - TimeSpan timeout = TimeSpan.FromMilliseconds(91); - Assert.Throws(() => client.Connect(timeout)); - } - } - [Theory] [MemberData(nameof(GetCancellationTokens))] public async Task ClientConnectAsync_Throws_Timeout_When_Pipe_Not_Found(CancellationToken cancellationToken) From a46972253f4d586b54f41d6f404f5ec5a2de6947 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Fri, 18 Mar 2022 21:20:02 +0100 Subject: [PATCH 53/72] Reduce PingTests Co-Authored-By: Dan Moseley --- .../tests/FunctionalTests/PingTest.cs | 431 +----------------- 1 file changed, 4 insertions(+), 427 deletions(-) diff --git a/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs b/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs index 6bc438c5dd5d1a..7359923f2fdeac 100644 --- a/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs +++ b/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs @@ -106,10 +106,14 @@ public async Task SendPingAsync_InvalidArgs() // Negative timeout AssertExtensions.Throws("timeout", () => { p.SendPingAsync(localIpAddress, -1); }); AssertExtensions.Throws("timeout", () => { p.SendPingAsync(TestSettings.LocalHost, -1); }); + AssertExtensions.Throws("timeout", () => { p.SendPingAsync(localIpAddress, TimeSpan.FromMilliseconds(-1)); }); + AssertExtensions.Throws("timeout", () => { p.SendPingAsync(TestSettings.LocalHost, TimeSpan.FromMilliseconds(-1)); }); AssertExtensions.Throws("timeout", () => { p.SendAsync(localIpAddress, -1, null); }); AssertExtensions.Throws("timeout", () => { p.SendAsync(TestSettings.LocalHost, -1, null); }); AssertExtensions.Throws("timeout", () => { p.Send(localIpAddress, -1); }); AssertExtensions.Throws("timeout", () => { p.Send(TestSettings.LocalHost, -1); }); + AssertExtensions.Throws("timeout", () => { p.Send(localIpAddress, TimeSpan.FromMilliseconds(-1)); }); + AssertExtensions.Throws("timeout", () => { p.Send(TestSettings.LocalHost, TimeSpan.FromMilliseconds(-1)); }); // Null byte[] AssertExtensions.Throws("buffer", () => { p.SendPingAsync(localIpAddress, 0, null); }); @@ -148,27 +152,6 @@ public void SendPingWithIPAddress(AddressFamily addressFamily) }); } - [Theory] - [InlineData(AddressFamily.InterNetwork)] - [InlineData(AddressFamily.InterNetworkV6)] - public void SendPingWithIPAddress_TimeSpan(AddressFamily addressFamily) - { - IPAddress localIpAddress = TestSettings.GetLocalIPAddress(addressFamily); - if (localIpAddress == null) - { - // No local address for given address family. - return; - } - - TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); - SendBatchPing( - ping => ping.Send(localIpAddress, pingTimeout, default, default), - pingReply => - { - PingResultValidator(pingReply, localIpAddress); - }); - } - [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] [InlineData(AddressFamily.InterNetwork)] [InlineData(AddressFamily.InterNetworkV6)] @@ -234,20 +217,6 @@ public void SendPingWithIPAddressAndTimeout() PingResultValidator(pingReply, localIpAddress); }); } - [Fact] - - public void SendPingWithIPAddressAndTimeout_TimeSpan() - { - IPAddress localIpAddress = TestSettings.GetLocalIPAddress(); - - TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); - SendBatchPing( - ping => ping.Send(localIpAddress, pingTimeout, default, default), - pingReply => - { - PingResultValidator(pingReply, localIpAddress); - }); - } [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public async Task SendPingAsyncWithIPAddressAndTimeout() @@ -262,20 +231,6 @@ await SendBatchPingAsync( }); } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - public async Task SendPingAsyncWithIPAddressAndTimeout_TimeSpan() - { - IPAddress localIpAddress = await TestSettings.GetLocalIPAddressAsync(); - - TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); - await SendBatchPingAsync( - ping => ping.SendPingAsync(localIpAddress, pingTimeout, default, default, default), - pingReply => - { - PingResultValidator(pingReply, localIpAddress); - }); - } - [Fact] public void SendPingWithIPAddressAndTimeoutAndBuffer() { @@ -291,22 +246,6 @@ public void SendPingWithIPAddressAndTimeoutAndBuffer() }); } - [Fact] - public void SendPingWithIPAddressAndTimeoutAndBuffer_TimeSpan() - { - IPAddress localIpAddress = TestSettings.GetLocalIPAddress(); - byte[] buffer = GetPingPayload(localIpAddress.AddressFamily); - - TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); - SendBatchPing( - ping => ping.Send(localIpAddress, pingTimeout, buffer, default), - pingReply => - { - PingResultValidator(pingReply, localIpAddress); - Assert.Equal(buffer, pingReply.Buffer); - }); - } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public async Task SendPingAsyncWithIPAddressAndTimeoutAndBuffer() { @@ -322,22 +261,6 @@ await SendBatchPingAsync( }); } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - public async Task SendPingAsyncWithIPAddressAndTimeoutAndBuffer_TimeSpan() - { - IPAddress localIpAddress = await TestSettings.GetLocalIPAddressAsync(); - byte[] buffer = GetPingPayload(localIpAddress.AddressFamily); - - TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); - await SendBatchPingAsync( - ping => ping.SendPingAsync(localIpAddress, pingTimeout, buffer, default, default), - pingReply => - { - PingResultValidator(pingReply, localIpAddress); - Assert.Equal(buffer, pingReply.Buffer); - }); - } - [PlatformSpecific(TestPlatforms.Windows)] [Fact] public void SendPingWithIPAddressAndTimeoutAndBufferAndPingOptions() @@ -356,26 +279,6 @@ public void SendPingWithIPAddressAndTimeoutAndBufferAndPingOptions() }); } - [PlatformSpecific(TestPlatforms.Windows)] - [Fact] - public void SendPingWithIPAddressAndTimeoutAndBufferAndPingOptions_TimeSpan() - { - IPAddress localIpAddress = TestSettings.GetLocalIPAddress(); - - var options = new PingOptions(); - byte[] buffer = TestSettings.PayloadAsBytes; - - TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); - SendBatchPing( - ping => ping.Send(localIpAddress, pingTimeout, buffer, options), - pingReply => - { - PingResultValidator(pingReply, localIpAddress); - Assert.Equal(buffer, pingReply.Buffer); - Assert.InRange(pingReply.RoundtripTime, 0, long.MaxValue); - }); - } - [PlatformSpecific(TestPlatforms.Windows)] [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public async Task SendPingAsyncWithIPAddressAndTimeoutAndBufferAndPingOptions() @@ -394,26 +297,6 @@ await SendBatchPingAsync( }); } - [PlatformSpecific(TestPlatforms.Windows)] - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - public async Task SendPingAsyncWithIPAddressAndTimeoutAndBufferAndPingOptions_TimeSpan() - { - IPAddress localIpAddress = await TestSettings.GetLocalIPAddressAsync(); - - var options = new PingOptions(); - byte[] buffer = TestSettings.PayloadAsBytes; - - TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); - await SendBatchPingAsync( - ping => ping.SendPingAsync(localIpAddress, pingTimeout, buffer, options, default), - pingReply => - { - PingResultValidator(pingReply, localIpAddress); - Assert.Equal(buffer, pingReply.Buffer); - Assert.InRange(pingReply.RoundtripTime, 0, long.MaxValue); - }); - } - [PlatformSpecific(TestPlatforms.AnyUnix)] [Theory] [InlineData(AddressFamily.InterNetwork)] @@ -438,31 +321,6 @@ public void SendPingWithIPAddressAndTimeoutAndBufferAndPingOptions_Unix(AddressF }); } - [PlatformSpecific(TestPlatforms.AnyUnix)] - [Theory] - [InlineData(AddressFamily.InterNetwork)] - [InlineData(AddressFamily.InterNetworkV6)] - public void SendPingWithIPAddressAndTimeoutAndBufferAndPingOptions_Unix_TimeSpan(AddressFamily addressFamily) - { - IPAddress localIpAddress = TestSettings.GetLocalIPAddress(addressFamily); - if (localIpAddress == null) - { - // No local address for given address family. - return; - } - - byte[] buffer = GetPingPayload(localIpAddress.AddressFamily); - - TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); - SendBatchPing( - ping => ping.Send(localIpAddress, pingTimeout, buffer, new PingOptions()), - pingReply => - { - PingResultValidator(pingReply, localIpAddress); - Assert.Equal(buffer, pingReply.Buffer); - }); - } - [PlatformSpecific(TestPlatforms.AnyUnix)] [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] [InlineData(AddressFamily.InterNetwork)] @@ -487,31 +345,6 @@ await SendBatchPingAsync( }); } - [PlatformSpecific(TestPlatforms.AnyUnix)] - [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - [InlineData(AddressFamily.InterNetwork)] - [InlineData(AddressFamily.InterNetworkV6)] - public async Task SendPingAsyncWithIPAddressAndTimeoutAndBufferAndPingOptions_Unix_TimeSpan(AddressFamily addressFamily) - { - IPAddress localIpAddress = await TestSettings.GetLocalIPAddressAsync(addressFamily); - if (localIpAddress == null) - { - // No local address for given address family. - return; - } - - byte[] buffer = GetPingPayload(localIpAddress.AddressFamily); - - TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); - await SendBatchPingAsync( - ping => ping.SendPingAsync(localIpAddress, pingTimeout, buffer, new PingOptions(), default), - pingReply => - { - PingResultValidator(pingReply, localIpAddress); - Assert.Equal(buffer, pingReply.Buffer); - }); - } - [Fact] public void SendPingWithHost() { @@ -551,20 +384,6 @@ public void SendPingWithHostAndTimeout() }); } - [Fact] - public void SendPingWithHostAndTimeout_TimeSpan() - { - IPAddress[] localIpAddresses = TestSettings.GetLocalIPAddresses(); - - TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); - SendBatchPing( - ping => ping.Send(TestSettings.LocalHost, pingTimeout, default, default), - pingReply => - { - PingResultValidator(pingReply, localIpAddresses); - }); - } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public async Task SendPingAsyncWithHostAndTimeout() { @@ -578,20 +397,6 @@ await SendBatchPingAsync( }); } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - public async Task SendPingAsyncWithHostAndTimeout_TimeSpan() - { - IPAddress[] localIpAddresses = await TestSettings.GetLocalIPAddressesAsync(); - - TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); - await SendBatchPingAsync( - ping => ping.SendPingAsync(TestSettings.LocalHost, pingTimeout, default, default, default), - pingReply => - { - PingResultValidator(pingReply, localIpAddresses); - }); - } - [Fact] public void SendPingWithHostAndTimeoutAndBuffer() { @@ -607,22 +412,6 @@ public void SendPingWithHostAndTimeoutAndBuffer() }); } - [Fact] - public void SendPingWithHostAndTimeoutAndBuffer_TimeSpan() - { - IPAddress localIpAddress = TestSettings.GetLocalIPAddress(); - byte[] buffer = GetPingPayload(localIpAddress.AddressFamily); - - TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); - SendBatchPing( - ping => ping.Send(TestSettings.LocalHost, pingTimeout, buffer, default), - pingReply => - { - PingResultValidator(pingReply, localIpAddress); - Assert.Equal(buffer, pingReply.Buffer); - }); - } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public async Task SendPingAsyncWithHostAndTimeoutAndBuffer() { @@ -638,22 +427,6 @@ await SendBatchPingAsync( }); } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - public async Task SendPingAsyncWithHostAndTimeoutAndBuffer_TimeSpan() - { - IPAddress localIpAddress = await TestSettings.GetLocalIPAddressAsync(); - byte[] buffer = GetPingPayload(localIpAddress.AddressFamily); - - TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); - await SendBatchPingAsync( - ping => ping.SendPingAsync(TestSettings.LocalHost, pingTimeout, buffer, default, default), - pingReply => - { - PingResultValidator(pingReply, localIpAddress); - Assert.Equal(buffer, pingReply.Buffer); - }); - } - [Fact] public void SendPingWithHostAndTimeoutAndBufferAndPingOptions() { @@ -669,22 +442,6 @@ public void SendPingWithHostAndTimeoutAndBufferAndPingOptions() }); } - [Fact] - public void SendPingWithHostAndTimeoutAndBufferAndPingOptions_TimeSpan() - { - IPAddress localIpAddress = TestSettings.GetLocalIPAddress(); - byte[] buffer = GetPingPayload(localIpAddress.AddressFamily); - - TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); - SendBatchPing( - ping => ping.Send(TestSettings.LocalHost, pingTimeout, buffer, new PingOptions()), - pingReply => - { - PingResultValidator(pingReply, localIpAddress); - Assert.Equal(buffer, pingReply.Buffer); - }); - } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public async Task SendPingAsyncWithHostAndTimeoutAndBufferAndPingOptions() { @@ -701,23 +458,6 @@ await SendBatchPingAsync( }); } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - public async Task SendPingAsyncWithHostAndTimeoutAndBufferAndPingOptions_TimeSpan() - { - IPAddress localIpAddress = await TestSettings.GetLocalIPAddressAsync(); - byte[] buffer = GetPingPayload(localIpAddress.AddressFamily); - - TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); - await SendBatchPingAsync( - ping => ping.SendPingAsync(TestSettings.LocalHost, pingTimeout, buffer, new PingOptions(), default), - pingReply => - { - PingResultValidator(pingReply, localIpAddress); - - Assert.Equal(buffer, pingReply.Buffer); - }); - } - [ConditionalFact(nameof(DoesNotUsePingUtility))] public async Task SendPingWithIPAddressAndBigSize() { @@ -741,29 +481,6 @@ public async Task SendPingWithIPAddressAndBigSize() } } - [ConditionalFact(nameof(DoesNotUsePingUtility))] - public async Task SendPingWithIPAddressAndBigSize_TimeSpan() - { - IPAddress localIpAddress = TestSettings.GetLocalIPAddress(); - - using Ping p = new(); - TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); - - // Assert.DoesNotThrow - PingReply pingReply = await p.SendPingAsync(localIpAddress, pingTimeout, new byte[10001], default, default); - - // Depending on platform the call may either succeed, report timeout or report too big packet. It - // should not throw wrapped SocketException though which is what this test guards. - // - // On Windows 10 the maximum ping size seems essentially limited to 65500 bytes and thus any buffer - // size on the loopback ping succeeds. On macOS anything bigger than 8184 will report packet too - // big error. - if (OperatingSystem.IsMacOS()) - { - Assert.Equal(IPStatus.PacketTooBig, pingReply.Status); - } - } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public async Task SendPings_ReuseInstance_Hostname() { @@ -946,26 +663,6 @@ await SendBatchPingAsync( }); } - [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - [InlineData(true)] - [InlineData(false)] - public async Task SendPingAsyncWithHostAndTtlAndFragmentPingOptions_TimeSpan(bool fragment) - { - IPAddress[] localIpAddresses = await TestSettings.GetLocalIPAddressesAsync(); - - byte[] buffer = GetPingPayload(localIpAddresses[0].AddressFamily); - - PingOptions options = new() { Ttl = 32, DontFragment = fragment }; - - TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); - await SendBatchPingAsync( - ping => ping.SendPingAsync(TestSettings.LocalHost, pingTimeout, buffer, options, default), - pingReply => - { - PingResultValidator(pingReply, localIpAddresses); - }); - } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] [OuterLoop] // Depends on external host and assumption that network respects and does not change TTL public async Task SendPingToExternalHostWithLowTtlTest() @@ -999,40 +696,6 @@ public async Task SendPingToExternalHostWithLowTtlTest() Assert.NotEqual(IPAddress.Any, pingReply.Address); } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - [OuterLoop] // Depends on external host and assumption that network respects and does not change TTL - public async Task SendPingToExternalHostWithLowTtlTest_TimeSpan() - { - string host = System.Net.Test.Common.Configuration.Ping.PingHost; - PingReply pingReply; - PingOptions options = new(); - bool reachable = false; - - Ping ping = new(); - TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); - for (int i = 0; i < s_pingcount; i++) - { - pingReply = await ping.SendPingAsync(host, pingTimeout, TestSettings.PayloadAsBytesShort, default, default); - if (pingReply.Status != IPStatus.Success) - { - continue; - } - - reachable = true; - break; - } - if (!reachable) - { - throw new SkipTestException($"Host {host} is not reachable. Skipping test."); - } - - options.Ttl = 1; - // This should always fail unless host is one IP hop away. - pingReply = await ping.SendPingAsync(host, pingTimeout, TestSettings.PayloadAsBytesShort, options, default); - Assert.True(pingReply.Status is IPStatus.TimeExceeded or IPStatus.TtlExpired); - Assert.NotEqual(IPAddress.Any, pingReply.Address); - } - [Fact] [OuterLoop] public void Ping_TimedOut_Sync_Success() @@ -1145,39 +808,6 @@ public void SendPing_LocaleEnvVarsMustBeIgnored(AddressFamily addressFamily, str }, localIpAddress.ToString(), new RemoteInvokeOptions { StartInfo = remoteInvokeStartInfo }).Dispose(); } - [PlatformSpecific(TestPlatforms.AnyUnix)] - [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] - [InlineData(AddressFamily.InterNetwork, "ja_JP.UTF8", null, null)] - [InlineData(AddressFamily.InterNetwork, "en_US.UTF8", "ja_JP.UTF8", null)] - [InlineData(AddressFamily.InterNetwork, "en_US.UTF8", null, "ja_JP.UTF8")] - [InlineData(AddressFamily.InterNetworkV6, "ja_JP.UTF8", null, null)] - [InlineData(AddressFamily.InterNetworkV6, "en_US.UTF8", "ja_JP.UTF8", null)] - [InlineData(AddressFamily.InterNetworkV6, "en_US.UTF8", null, "ja_JP.UTF8")] - public void SendPing_LocaleEnvVarsMustBeIgnored_TimeSpan(AddressFamily addressFamily, string envVar_LANG, string envVar_LC_MESSAGES, string envVar_LC_ALL) - { - IPAddress localIpAddress = TestSettings.GetLocalIPAddress(addressFamily); - - var remoteInvokeStartInfo = new ProcessStartInfo { EnvironmentVariables = - { - ["LANG"] = envVar_LANG, - ["LC_MESSAGES"] = envVar_LC_MESSAGES, - ["LC_ALL"] = envVar_LC_ALL - } - }; - - RemoteExecutor.Invoke(address => - { - TimeSpan timeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); - - SendBatchPing( - ping => ping.Send(address, timeout, default, default), - pingReply => - { - PingResultValidator(pingReply, new[] { IPAddress.Parse(address) }, null); - }); - }, localIpAddress.ToString(), new RemoteInvokeOptions { StartInfo = remoteInvokeStartInfo }).Dispose(); - } - [PlatformSpecific(TestPlatforms.AnyUnix)] [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] [InlineData(AddressFamily.InterNetwork, "ja_JP.UTF8", null, null)] @@ -1208,37 +838,6 @@ await SendBatchPingAsync( }, localIpAddress.ToString(), new RemoteInvokeOptions { StartInfo = remoteInvokeStartInfo }).Dispose(); } - [PlatformSpecific(TestPlatforms.AnyUnix)] - [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] - [InlineData(AddressFamily.InterNetwork, "ja_JP.UTF8", null, null)] - [InlineData(AddressFamily.InterNetwork, "en_US.UTF8", "ja_JP.UTF8", null)] - [InlineData(AddressFamily.InterNetwork, "en_US.UTF8", null, "ja_JP.UTF8")] - [InlineData(AddressFamily.InterNetworkV6, "ja_JP.UTF8", null, null)] - [InlineData(AddressFamily.InterNetworkV6, "en_US.UTF8", "ja_JP.UTF8", null)] - [InlineData(AddressFamily.InterNetworkV6, "en_US.UTF8", null, "ja_JP.UTF8")] - public void SendPingAsync_LocaleEnvVarsMustBeIgnored_TimeSpan(AddressFamily addressFamily, string envVar_LANG, string envVar_LC_MESSAGES, string envVar_LC_ALL) - { - IPAddress localIpAddress = TestSettings.GetLocalIPAddress(addressFamily); - - var remoteInvokeStartInfo = new ProcessStartInfo { EnvironmentVariables = - { - ["LANG"] = envVar_LANG, ["LC_MESSAGES"] = envVar_LC_MESSAGES, - ["LC_ALL"] = envVar_LC_ALL - } - }; - - RemoteExecutor.Invoke(async address => - { - TimeSpan timeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); - await SendBatchPingAsync( - ping => ping.SendPingAsync(address, timeout, default, default, default), - (pingReply) => - { - PingResultValidator(pingReply, new[] { IPAddress.Parse(address) }, null); - }); - }, localIpAddress.ToString(), new RemoteInvokeOptions { StartInfo = remoteInvokeStartInfo }).Dispose(); - } - [ConditionalFact(nameof(UsesPingUtility))] public void SendPing_CustomPayload_InsufficientPrivileges_Throws() { @@ -1249,17 +848,6 @@ public void SendPing_CustomPayload_InsufficientPrivileges_Throws() Assert.Throws(() => ping.Send(TestSettings.LocalHost, TestSettings.PingTimeout, buffer)); } - [ConditionalFact(nameof(UsesPingUtility))] - public void SendPing_CustomPayload_InsufficientPrivileges_Throws_TimeSpan() - { - IPAddress[] localIpAddresses = TestSettings.GetLocalIPAddresses(); - - byte[] buffer = TestSettings.PayloadAsBytes; - TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); - Ping ping = new(); - Assert.Throws(() => ping.Send(TestSettings.LocalHost, pingTimeout, buffer, default)); - } - [ConditionalFact(nameof(UsesPingUtility))] public async Task SendPingAsync_CustomPayload_InsufficientPrivileges_Throws() { @@ -1269,16 +857,5 @@ public async Task SendPingAsync_CustomPayload_InsufficientPrivileges_Throws() Ping ping = new Ping(); await Assert.ThrowsAsync(() => ping.SendPingAsync(TestSettings.LocalHost, TestSettings.PingTimeout, buffer)); } - - [ConditionalFact(nameof(UsesPingUtility))] - public async Task SendPingAsync_CustomPayload_InsufficientPrivileges_Throws_TimeSpan() - { - IPAddress[] localIpAddresses = TestSettings.GetLocalIPAddresses(); - - byte[] buffer = TestSettings.PayloadAsBytes; - TimeSpan pingTimeout = TimeSpan.FromMilliseconds(TestSettings.PingTimeout); - Ping ping = new(); - await Assert.ThrowsAsync(() => ping.SendPingAsync(TestSettings.LocalHost, pingTimeout, buffer, default, default)); - } } } From 6251c56ea5405b2886346d834270b43ce0a4ad61 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Fri, 18 Mar 2022 21:22:44 +0100 Subject: [PATCH 54/72] Re-order `System.Net.Sockets` ref assembly entry --- src/libraries/System.Net.Sockets/ref/System.Net.Sockets.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Net.Sockets/ref/System.Net.Sockets.cs b/src/libraries/System.Net.Sockets/ref/System.Net.Sockets.cs index b160c2df18c1a4..3eec205b412966 100644 --- a/src/libraries/System.Net.Sockets/ref/System.Net.Sockets.cs +++ b/src/libraries/System.Net.Sockets/ref/System.Net.Sockets.cs @@ -136,6 +136,7 @@ public NetworkStream(System.Net.Sockets.Socket socket, System.IO.FileAccess acce public override System.IAsyncResult BeginRead(byte[] buffer, int offset, int count, System.AsyncCallback? callback, object? state) { throw null; } public override System.IAsyncResult BeginWrite(byte[] buffer, int offset, int count, System.AsyncCallback? callback, object? state) { throw null; } public void Close(int timeout) { } + public void Close(System.TimeSpan timeout) { } protected override void Dispose(bool disposing) { } public override int EndRead(System.IAsyncResult asyncResult) { throw null; } public override void EndWrite(System.IAsyncResult asyncResult) { } @@ -154,7 +155,6 @@ public override void Write(System.ReadOnlySpan buffer) { } public override System.Threading.Tasks.Task WriteAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; } public override System.Threading.Tasks.ValueTask WriteAsync(System.ReadOnlyMemory buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public override void WriteByte(byte value) { } - public void Close(System.TimeSpan timeout) { } } public enum ProtocolFamily { From a888f6ef7fd4e2309900e17e7e623f0d6243aff4 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Fri, 18 Mar 2022 21:31:00 +0100 Subject: [PATCH 55/72] Fix time unit conversion in `NetworkStream` & `Socket` --- .../src/System/Net/Sockets/NetworkStream.cs | 12 ++++++------ .../src/System/Net/Sockets/Socket.cs | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs index daf857dd6d3447..150a2e475ec502 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs @@ -337,21 +337,21 @@ public void Close(int timeout) Dispose(); } - public void Close(TimeSpan timeout) => Close(ToTimeoutMilliseconds(timeout)); + public void Close(TimeSpan timeout) => Close(ToTimeoutSeconds(timeout)); - private static int ToTimeoutMilliseconds(TimeSpan timeout) + private static int ToTimeoutSeconds(TimeSpan timeout) { - long timeoutMilliseconds = (long)timeout.TotalMilliseconds; - if (timeoutMilliseconds < -1) + long timeoutSeconds = (long)timeout.TotalSeconds; + if (timeoutSeconds < -1) { throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1); } - if (timeoutMilliseconds > int.MaxValue) + if (timeoutSeconds > int.MaxValue) { throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_LessEqualToIntegerMaxVal); } - return (int)timeoutMilliseconds; + return (int)timeoutSeconds; } protected override void Dispose(bool disposing) diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs index 84aac45f775a83..0aab13133774aa 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs @@ -2178,18 +2178,18 @@ public static void Select(IList? checkRead, IList? checkWrite, IList? checkError private static int ToTimeoutMicroseconds(TimeSpan timeout) { - long timeoutMilliseconds = (long)timeout.TotalMilliseconds; - if (timeoutMilliseconds < -1) + long timeoutMicroseconds = (long)timeout.TotalMilliseconds * 1000; + if (timeoutMicroseconds < -1) { throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1); } - if (timeoutMilliseconds > int.MaxValue) + if (timeoutMicroseconds > int.MaxValue) { throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_LessEqualToIntegerMaxVal); } - return (int)timeoutMilliseconds / 1000; + return (int)timeoutMicroseconds; } public IAsyncResult BeginConnect(EndPoint remoteEP, AsyncCallback? callback, object? state) => From c6a6c05543158131aa84fc0ff600063a71e1a5c2 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Fri, 18 Mar 2022 21:34:15 +0100 Subject: [PATCH 56/72] Use new overload in `Task.Wait(TimeSpan)` --- .../src/System/Threading/Tasks/Task.cs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs index c087c4ae06818a..edd4ebe5725b6e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs @@ -2637,16 +2637,7 @@ public void Wait() /// infinite time-out -or- timeout is greater than /// . /// - public bool Wait(TimeSpan timeout) - { - long totalMilliseconds = (long)timeout.TotalMilliseconds; - if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue) - { - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.timeout); - } - - return Wait((int)totalMilliseconds, default); - } + public bool Wait(TimeSpan timeout) => Wait(timeout, default); /// /// Waits for the to complete execution. From cfba2b9e170cdda74d2c6d3ecf15184429f60c51 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Fri, 18 Mar 2022 21:39:43 +0100 Subject: [PATCH 57/72] Remove redundant test --- .../tests/Task/TaskAPMTest.cs | 27 ------------------- 1 file changed, 27 deletions(-) diff --git a/src/libraries/System.Threading.Tasks/tests/Task/TaskAPMTest.cs b/src/libraries/System.Threading.Tasks/tests/Task/TaskAPMTest.cs index 804989e2071c2b..fa01ab6b75c892 100644 --- a/src/libraries/System.Threading.Tasks/tests/Task/TaskAPMTest.cs +++ b/src/libraries/System.Threading.Tasks/tests/Task/TaskAPMTest.cs @@ -89,33 +89,6 @@ public void PollUntilCompleteTechnique(bool hasReturnType) Assert.False(asyncResult.CompletedSynchronously, "Should not have completed synchronously."); } - [Theory] - [OuterLoop] - [InlineData(true)] - [InlineData(false)] - public void PollUntilCompleteTechnique_TimeSpan(bool hasReturnType) - { - _hasReturnType = hasReturnType; - - LongTask longTask; - if (_hasReturnType) - longTask = new LongTask(LongTaskMilliseconds); - else - longTask = new LongTask(LongTaskMilliseconds); - - IAsyncResult asyncResult = longTask.BeginDoTask(null, null); - var mres = new ManualResetEventSlim(); - - TimeSpan timeout = TimeSpan.FromMilliseconds(1); - while (!asyncResult.IsCompleted) - { - mres.Wait(timeout); - } - - AssertTaskCompleted(asyncResult); - Assert.False(asyncResult.CompletedSynchronously, "Should not have completed synchronously."); - } - [Theory] [OuterLoop] [InlineData(true)] From 75b855428261d3ae946665735ae6f72a82bc44a4 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Fri, 18 Mar 2022 22:11:17 +0100 Subject: [PATCH 58/72] Fix ping tests --- .../System.Net.Ping/tests/FunctionalTests/PingTest.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs b/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs index 7359923f2fdeac..832a43eb722e77 100644 --- a/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs +++ b/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs @@ -106,14 +106,14 @@ public async Task SendPingAsync_InvalidArgs() // Negative timeout AssertExtensions.Throws("timeout", () => { p.SendPingAsync(localIpAddress, -1); }); AssertExtensions.Throws("timeout", () => { p.SendPingAsync(TestSettings.LocalHost, -1); }); - AssertExtensions.Throws("timeout", () => { p.SendPingAsync(localIpAddress, TimeSpan.FromMilliseconds(-1)); }); - AssertExtensions.Throws("timeout", () => { p.SendPingAsync(TestSettings.LocalHost, TimeSpan.FromMilliseconds(-1)); }); + AssertExtensions.Throws("timeout", () => { p.SendPingAsync(localIpAddress, TimeSpan.FromMilliseconds(-1), default, default, default); }); + AssertExtensions.Throws("timeout", () => { p.SendPingAsync(TestSettings.LocalHost, TimeSpan.FromMilliseconds(-1), default, default, default); }); AssertExtensions.Throws("timeout", () => { p.SendAsync(localIpAddress, -1, null); }); AssertExtensions.Throws("timeout", () => { p.SendAsync(TestSettings.LocalHost, -1, null); }); AssertExtensions.Throws("timeout", () => { p.Send(localIpAddress, -1); }); AssertExtensions.Throws("timeout", () => { p.Send(TestSettings.LocalHost, -1); }); - AssertExtensions.Throws("timeout", () => { p.Send(localIpAddress, TimeSpan.FromMilliseconds(-1)); }); - AssertExtensions.Throws("timeout", () => { p.Send(TestSettings.LocalHost, TimeSpan.FromMilliseconds(-1)); }); + AssertExtensions.Throws("timeout", () => { p.Send(localIpAddress, TimeSpan.FromMilliseconds(-1), default, default); }); + AssertExtensions.Throws("timeout", () => { p.Send(TestSettings.LocalHost, TimeSpan.FromMilliseconds(-1), default, default); }); // Null byte[] AssertExtensions.Throws("buffer", () => { p.SendPingAsync(localIpAddress, 0, null); }); From 03aa02d2705bea49ca795698dd547734a642e24d Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Fri, 18 Mar 2022 22:27:04 +0100 Subject: [PATCH 59/72] Fix Pipe tests --- .../NamedPipeTests/NamedPipeTest.Specific.cs | 5 +++-- .../FunctionalTests/ArgumentValidationTests.cs | 18 +++++++++--------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Specific.cs b/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Specific.cs index e285f3b651e85b..91c24ed3556202 100644 --- a/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Specific.cs +++ b/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Specific.cs @@ -16,6 +16,7 @@ namespace System.IO.Pipes.Tests /// public class NamedPipeTest_Specific { + [Fact] public void InvalidConnectTimeout_Throws_ArgumentOutOfRangeException() { using (NamedPipeClientStream client = new NamedPipeClientStream("client1")) @@ -23,7 +24,7 @@ public void InvalidConnectTimeout_Throws_ArgumentOutOfRangeException() AssertExtensions.Throws("timeout", () => client.Connect(-111)); AssertExtensions.Throws("timeout", () => { client.ConnectAsync(-111); }); AssertExtensions.Throws("timeout", () => client.Connect(TimeSpan.FromMilliseconds(-111))); - AssertExtensions.Throws("timeout", () => { client.ConnectAsync(TimeSpan.FromMilliseconds(-111)); }); + AssertExtensions.Throws("timeout", () => { client.ConnectAsync(TimeSpan.FromMilliseconds(-111), default); }); } } @@ -35,7 +36,7 @@ public async Task ConnectToNonExistentServer_Throws_TimeoutException() var ctx = new CancellationTokenSource(); Assert.Throws(() => client.Connect(TimeSpan.FromMilliseconds(60))); // 60 to be over internal 50 interval - await Assert.ThrowsAsync(() => client.ConnectAsync(TimeSpan.FromMilliseconds(50))); + await Assert.ThrowsAsync(() => client.ConnectAsync(TimeSpan.FromMilliseconds(50), default)); await Assert.ThrowsAsync(() => client.ConnectAsync(TimeSpan.FromMilliseconds(60), ctx.Token)); // testing Token overload; ctx is not canceled in this test diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ArgumentValidationTests.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/ArgumentValidationTests.cs index 20e074da80f9f2..821173a5a7a380 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ArgumentValidationTests.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/ArgumentValidationTests.cs @@ -358,17 +358,17 @@ public void Select_NullOrEmptyLists_Throws_ArgumentNull() [Fact] public void Select_NullOrEmptyLists_Throws_ArgumentNull_TimeSpan() { - TimeSpan infinity = Timeout.InfiniteTimeSpan; + TimeSpan nonInfinity = TimeSpan.FromMilliseconds(1); var emptyList = new List(); - Assert.Throws(() => Socket.Select(null, null, null, infinity)); - Assert.Throws(() => Socket.Select(emptyList, null, null, infinity)); - Assert.Throws(() => Socket.Select(null, emptyList, null, infinity)); - Assert.Throws(() => Socket.Select(emptyList, emptyList, null, infinity)); - Assert.Throws(() => Socket.Select(null, null, emptyList, infinity)); - Assert.Throws(() => Socket.Select(emptyList, null, emptyList, infinity)); - Assert.Throws(() => Socket.Select(null, emptyList, emptyList, infinity)); - Assert.Throws(() => Socket.Select(emptyList, emptyList, emptyList, infinity)); + Assert.Throws(() => Socket.Select(null, null, null, nonInfinity)); + Assert.Throws(() => Socket.Select(emptyList, null, null, nonInfinity)); + Assert.Throws(() => Socket.Select(null, emptyList, null, nonInfinity)); + Assert.Throws(() => Socket.Select(emptyList, emptyList, null, nonInfinity)); + Assert.Throws(() => Socket.Select(null, null, emptyList, nonInfinity)); + Assert.Throws(() => Socket.Select(emptyList, null, emptyList, nonInfinity)); + Assert.Throws(() => Socket.Select(null, emptyList, emptyList, nonInfinity)); + Assert.Throws(() => Socket.Select(emptyList, emptyList, emptyList, nonInfinity)); } [Fact] From 25484a4422df2e875ced3545acb872498af809a6 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Sat, 19 Mar 2022 13:16:01 +0100 Subject: [PATCH 60/72] Use simpler validation and remove redundant resx-resources --- .../src/Resources/Strings.resx | 6 ------ .../src/Resources/Strings.resx | 6 ------ .../src/System/Diagnostics/Process.cs | 13 ++++--------- .../src/Resources/Strings.resx | 6 ------ .../src/System/IO/FileSystemWatcher.cs | 13 ++++--------- .../System.IO.Pipes/src/Resources/Strings.resx | 6 ------ .../src/System/IO/Pipes/NamedPipeClientStream.cs | 13 ++++--------- .../System.Net.Ping/src/Resources/Strings.resx | 6 ------ .../src/System/Net/NetworkInformation/Ping.cs | 13 ++++--------- .../System.Net.Sockets/src/Resources/Strings.resx | 6 ------ .../src/System/Net/Sockets/NetworkStream.cs | 13 ++++--------- .../src/System/Net/Sockets/Socket.cs | 14 ++++---------- .../src/Resources/Strings.resx | 6 ------ .../src/System/ServiceProcess/ServiceBase.cs | 13 ++++--------- 14 files changed, 28 insertions(+), 106 deletions(-) diff --git a/src/libraries/System.ComponentModel.Annotations/src/Resources/Strings.resx b/src/libraries/System.ComponentModel.Annotations/src/Resources/Strings.resx index f75775f097b73c..e20eea0c0669c5 100644 --- a/src/libraries/System.ComponentModel.Annotations/src/Resources/Strings.resx +++ b/src/libraries/System.ComponentModel.Annotations/src/Resources/Strings.resx @@ -216,10 +216,4 @@ The value for property '{0}' must be of type '{1}'. - - Number must either be -1, or 0 through Int32.MaxValue inclusive. - - - Argument must be less than or equal to 2^31 - 1 milliseconds. - diff --git a/src/libraries/System.Diagnostics.Process/src/Resources/Strings.resx b/src/libraries/System.Diagnostics.Process/src/Resources/Strings.resx index 70119b23f37e92..84f7006f981b14 100644 --- a/src/libraries/System.Diagnostics.Process/src/Resources/Strings.resx +++ b/src/libraries/System.Diagnostics.Process/src/Resources/Strings.resx @@ -296,12 +296,6 @@ Non-negative number required. - - Number must be either non-negative and less than or equal to Int32.MaxValue or -1. - - - Argument must be less than or equal to 2^31 - 1 milliseconds. - The Process object must have the UseShellExecute property set to false in order to start a process as a user. diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs index 3231ac5c3f73a3..7e4c4953f4d057 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.cs @@ -1455,17 +1455,12 @@ public bool WaitForExit(int milliseconds) private static int ToTimeoutMilliseconds(TimeSpan timeout) { - long timeoutMilliseconds = (long)timeout.TotalMilliseconds; - if (timeoutMilliseconds < -1) + long totalMilliseconds = (long)timeout.TotalMilliseconds; + if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue) { - throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1); + throw new ArgumentOutOfRangeException(nameof(timeout)); } - - if (timeoutMilliseconds > int.MaxValue) - { - throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_LessEqualToIntegerMaxVal); - } - return (int)timeoutMilliseconds; + return (int)totalMilliseconds; } /// diff --git a/src/libraries/System.IO.FileSystem.Watcher/src/Resources/Strings.resx b/src/libraries/System.IO.FileSystem.Watcher/src/Resources/Strings.resx index 6c9757c79fe519..c16582a79cc7f3 100644 --- a/src/libraries/System.IO.FileSystem.Watcher/src/Resources/Strings.resx +++ b/src/libraries/System.IO.FileSystem.Watcher/src/Resources/Strings.resx @@ -140,12 +140,6 @@ Specified file length was too large for the file system. - - Number must be either non-negative and less than or equal to Int32.MaxValue or -1. - - - Argument must be less than or equal to 2^31 - 1 milliseconds. - The specified file name or path is too long, or a component of the specified path is too long. diff --git a/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.cs b/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.cs index 6d7b6676f2fe55..654bd3ab856c8f 100644 --- a/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.cs +++ b/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.cs @@ -623,17 +623,12 @@ public WaitForChangedResult WaitForChanged(WatcherChangeTypes changeType, TimeSp private static int ToTimeoutMilliseconds(TimeSpan timeout) { - long timeoutMilliseconds = (long)timeout.TotalMilliseconds; - if (timeoutMilliseconds < -1) + long totalMilliseconds = (long)timeout.TotalMilliseconds; + if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue) { - throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1); + throw new ArgumentOutOfRangeException(nameof(timeout)); } - - if (timeoutMilliseconds > int.MaxValue) - { - throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_LessEqualToIntegerMaxVal); - } - return (int)timeoutMilliseconds; + return (int)totalMilliseconds; } /// diff --git a/src/libraries/System.IO.Pipes/src/Resources/Strings.resx b/src/libraries/System.IO.Pipes/src/Resources/Strings.resx index c4c5f89bcfdc5d..4d2752edab8b07 100644 --- a/src/libraries/System.IO.Pipes/src/Resources/Strings.resx +++ b/src/libraries/System.IO.Pipes/src/Resources/Strings.resx @@ -123,12 +123,6 @@ Invalid PipeAccessRights value. - - Number must be either non-negative and less than or equal to Int32.MaxValue or -1. - - - Argument must be less than or equal to 2^31 - 1 milliseconds. - This flag may not be set on a pipe. diff --git a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.cs b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.cs index bcded6d6c826aa..1667631bda0f67 100644 --- a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.cs +++ b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.cs @@ -200,17 +200,12 @@ public Task ConnectAsync(TimeSpan timeout, CancellationToken cancellationToken = private static int ToTimeoutMilliseconds(TimeSpan timeout) { - long timeoutMilliseconds = (long)timeout.TotalMilliseconds; - if (timeoutMilliseconds < -1) + long totalMilliseconds = (long)timeout.TotalMilliseconds; + if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue) { - throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1); + throw new ArgumentOutOfRangeException(nameof(timeout)); } - - if (timeoutMilliseconds > int.MaxValue) - { - throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_LessEqualToIntegerMaxVal); - } - return (int)timeoutMilliseconds; + return (int)totalMilliseconds; } // override because named pipe clients can't get/set properties when waiting to connect diff --git a/src/libraries/System.Net.Ping/src/Resources/Strings.resx b/src/libraries/System.Net.Ping/src/Resources/Strings.resx index 2a08c10a0c2d8c..a2a8a43068beb6 100644 --- a/src/libraries/System.Net.Ping/src/Resources/Strings.resx +++ b/src/libraries/System.Net.Ping/src/Resources/Strings.resx @@ -90,10 +90,4 @@ Unable to send custom ping payload. Run program under privileged user account or grant cap_net_raw capability using setcap(8). - - Number must be either non-negative and less than or equal to Int32.MaxValue or -1. - - - Argument must be less than or equal to 2^31 - 1 milliseconds. - diff --git a/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs b/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs index eeb46fad2a974a..1bf92d9762a3b7 100644 --- a/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs +++ b/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs @@ -387,17 +387,12 @@ public Task SendPingAsync(string hostNameOrAddress, int timeout, byte private static int ToTimeoutMilliseconds(TimeSpan timeout) { - long timeoutMilliseconds = (long)timeout.TotalMilliseconds; - if (timeoutMilliseconds < -1) + long totalMilliseconds = (long)timeout.TotalMilliseconds; + if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue) { - throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1); - } - - if (timeoutMilliseconds > int.MaxValue) - { - throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_LessEqualToIntegerMaxVal); + throw new ArgumentOutOfRangeException(nameof(timeout)); } - return (int)timeoutMilliseconds; + return (int)totalMilliseconds; } public void SendAsyncCancel() diff --git a/src/libraries/System.Net.Sockets/src/Resources/Strings.resx b/src/libraries/System.Net.Sockets/src/Resources/Strings.resx index 3940f8ce4a4273..57d1a94b6ae6bd 100644 --- a/src/libraries/System.Net.Sockets/src/Resources/Strings.resx +++ b/src/libraries/System.Net.Sockets/src/Resources/Strings.resx @@ -255,12 +255,6 @@ Argument '{2}' must be between {0} and {1}. - - Number must be either non-negative and less than or equal to Int32.MaxValue or -1. - - - Argument must be less than or equal to 2^31 - 1 milliseconds. - Sockets on this platform are invalid for use after a failed connection attempt. diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs index 150a2e475ec502..299091bf28f3dd 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs @@ -341,17 +341,12 @@ public void Close(int timeout) private static int ToTimeoutSeconds(TimeSpan timeout) { - long timeoutSeconds = (long)timeout.TotalSeconds; - if (timeoutSeconds < -1) + long totalSeconds = (long)timeout.TotalSeconds; + if (totalSeconds < -1 || totalSeconds > int.MaxValue) { - throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1); - } - - if (timeoutSeconds > int.MaxValue) - { - throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_LessEqualToIntegerMaxVal); + throw new ArgumentOutOfRangeException(nameof(timeout)); } - return (int)timeoutSeconds; + return (int)totalSeconds; } protected override void Dispose(bool disposing) diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs index 0aab13133774aa..9ff78acd01e86f 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs @@ -2178,18 +2178,12 @@ public static void Select(IList? checkRead, IList? checkWrite, IList? checkError private static int ToTimeoutMicroseconds(TimeSpan timeout) { - long timeoutMicroseconds = (long)timeout.TotalMilliseconds * 1000; - if (timeoutMicroseconds < -1) + long totalMicroseconds = (long)timeout.TotalMilliseconds * 1000; + if (totalMicroseconds < -1 || totalMicroseconds > int.MaxValue) { - throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1); - } - - if (timeoutMicroseconds > int.MaxValue) - { - throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_LessEqualToIntegerMaxVal); + throw new ArgumentOutOfRangeException(nameof(timeout)); } - - return (int)timeoutMicroseconds; + return (int)totalMicroseconds; } public IAsyncResult BeginConnect(EndPoint remoteEP, AsyncCallback? callback, object? state) => diff --git a/src/libraries/System.ServiceProcess.ServiceController/src/Resources/Strings.resx b/src/libraries/System.ServiceProcess.ServiceController/src/Resources/Strings.resx index d1646add4be0f0..aa322b1624ad46 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/src/Resources/Strings.resx +++ b/src/libraries/System.ServiceProcess.ServiceController/src/Resources/Strings.resx @@ -162,10 +162,4 @@ Cannot control '{0}' service on computer '{1}'. - - Number must be either non-negative and less than or equal to Int32.MaxValue or -1. - - - Argument must be less than or equal to 2^31 - 1 milliseconds. - diff --git a/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs b/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs index 5433e6f32a6b00..30ddabaed3dc9b 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs +++ b/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs @@ -83,17 +83,12 @@ public unsafe void RequestAdditionalTime(int milliseconds) private static int ToTimeoutMilliseconds(TimeSpan timeout) { - long timeoutMilliseconds = (long)timeout.TotalMilliseconds; - if (timeoutMilliseconds < -1) + long totalMilliseconds = (long)timeout.TotalMilliseconds; + if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue) { - throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1); + throw new ArgumentOutOfRangeException(nameof(timeout)); } - - if (timeoutMilliseconds > int.MaxValue) - { - throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_LessEqualToIntegerMaxVal); - } - return (int)timeoutMilliseconds; + return (int)totalMilliseconds; } #endif From 4c06f93ddf3210d1cb351cc73200a1318c93e9d2 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Sat, 19 Mar 2022 13:20:58 +0100 Subject: [PATCH 61/72] Remove unintentional changes --- .../System.Private.CoreLib.csproj | 10 +++++++--- .../System.Private.CoreLib/src/System/GC.CoreCLR.cs | 2 +- src/mono/System.Private.CoreLib/src/System/GC.Mono.cs | 1 - 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj index 357c03960299c8..036936d4f58f9d 100644 --- a/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -143,7 +143,7 @@ - + @@ -317,7 +317,7 @@ - + @@ -331,7 +331,11 @@ - + diff --git a/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs index 901c45296d479a..4f2fbd89bc29bb 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs @@ -16,7 +16,6 @@ using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using System.Threading; namespace System { @@ -357,6 +356,7 @@ public static long GetTotalMemory(bool forceFullCollection) [MethodImpl(MethodImplOptions.InternalCall)] public static extern long GetAllocatedBytesForCurrentThread(); + /// /// Get a count of the bytes allocated over the lifetime of the process. /// If true, gather a precise number, otherwise gather a fairly count. Gathering a precise value triggers at a significant performance penalty. diff --git a/src/mono/System.Private.CoreLib/src/System/GC.Mono.cs b/src/mono/System.Private.CoreLib/src/System/GC.Mono.cs index eb5e0210c5df27..0ca9fc56fa5bb4 100644 --- a/src/mono/System.Private.CoreLib/src/System/GC.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/GC.Mono.cs @@ -4,7 +4,6 @@ using System.Runtime; using System.Runtime.CompilerServices; using System.Diagnostics.Tracing; -using System.Threading; namespace System { From ea03c06116153e8cd131d6351824e38fa7fdcb0d Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Fri, 25 Mar 2022 18:13:56 +0100 Subject: [PATCH 62/72] Use `timeout.Ticks / 10` instead of floating-point multiplication --- .../System.Net.Sockets/src/System/Net/Sockets/Socket.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs index 9ff78acd01e86f..d0478278b83277 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs @@ -2178,7 +2178,7 @@ public static void Select(IList? checkRead, IList? checkWrite, IList? checkError private static int ToTimeoutMicroseconds(TimeSpan timeout) { - long totalMicroseconds = (long)timeout.TotalMilliseconds * 1000; + long totalMicroseconds = timeout.Ticks / 10; if (totalMicroseconds < -1 || totalMicroseconds > int.MaxValue) { throw new ArgumentOutOfRangeException(nameof(timeout)); From 4d2e0231a5409a48a5986f110477417761ff1484 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Fri, 25 Mar 2022 18:16:30 +0100 Subject: [PATCH 63/72] Style fix --- .../System.Net.Ping/tests/FunctionalTests/PingTest.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs b/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs index 832a43eb722e77..7f3214b1d862b4 100644 --- a/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs +++ b/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs @@ -820,9 +820,11 @@ public void SendPingAsync_LocaleEnvVarsMustBeIgnored(AddressFamily addressFamily { IPAddress localIpAddress = TestSettings.GetLocalIPAddress(addressFamily); - var remoteInvokeStartInfo = new ProcessStartInfo { EnvironmentVariables = + var remoteInvokeStartInfo = new ProcessStartInfo { + EnvironmentVariables = { - ["LANG"] = envVar_LANG, ["LC_MESSAGES"] = envVar_LC_MESSAGES, + ["LANG"] = envVar_LANG, + ["LC_MESSAGES"] = envVar_LC_MESSAGES, ["LC_ALL"] = envVar_LC_ALL } }; From bba4bd3b91169ce1b8f7abf521a8d8a34b831711 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Fri, 25 Mar 2022 18:19:12 +0100 Subject: [PATCH 64/72] Improve naming: `timeoutMillis` -> `timeoutMilliseconds` Co-Authored-By: Dan Moseley --- .../tests/FileSystemWatcher.WaitForChanged.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.WaitForChanged.cs b/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.WaitForChanged.cs index 87da9225591146..d01adbd6ceed43 100644 --- a/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.WaitForChanged.cs +++ b/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.WaitForChanged.cs @@ -86,10 +86,10 @@ public void ZeroTimeout_TimesOut(bool enabledBeforeWait, bool useTimeSpan) { if (enabledBeforeWait) fsw.EnableRaisingEvents = true; - const int timeoutMillis = 0; + const int timeoutMilliseconds = 0; AssertTimedOut(useTimeSpan - ? fsw.WaitForChanged(WatcherChangeTypes.All, TimeSpan.FromMilliseconds(timeoutMillis)) - : fsw.WaitForChanged(WatcherChangeTypes.All, timeoutMillis)); + ? fsw.WaitForChanged(WatcherChangeTypes.All, TimeSpan.FromMilliseconds(timeoutMilliseconds)) + : fsw.WaitForChanged(WatcherChangeTypes.All, timeoutMilliseconds)); Assert.Equal(enabledBeforeWait, fsw.EnableRaisingEvents); } } @@ -104,10 +104,10 @@ public void NonZeroTimeout_NoEvents_TimesOut(bool enabledBeforeWait, bool useTim using (var fsw = new FileSystemWatcher(testDirectory.Path)) { if (enabledBeforeWait) fsw.EnableRaisingEvents = true; - const int timeoutMillis = 1; + const int timeoutMilliseconds = 1; AssertTimedOut(useTimeSpan - ? fsw.WaitForChanged(0, TimeSpan.FromMilliseconds(timeoutMillis)) - : fsw.WaitForChanged(0, timeoutMillis)); + ? fsw.WaitForChanged(0, TimeSpan.FromMilliseconds(timeoutMilliseconds)) + : fsw.WaitForChanged(0, timeoutMilliseconds)); Assert.Equal(enabledBeforeWait, fsw.EnableRaisingEvents); } } @@ -126,10 +126,10 @@ public void NonZeroTimeout_NoActivity_TimesOut(WatcherChangeTypes changeType, bo using (var fsw = new FileSystemWatcher(testDirectory.Path)) { if (enabledBeforeWait) fsw.EnableRaisingEvents = true; - const int timeoutMillis = 1; + const int timeoutMilliseconds = 1; AssertTimedOut(useTimeSpan - ? fsw.WaitForChanged(changeType, TimeSpan.FromMilliseconds(timeoutMillis)) - : fsw.WaitForChanged(changeType, timeoutMillis)); + ? fsw.WaitForChanged(changeType, TimeSpan.FromMilliseconds(timeoutMilliseconds)) + : fsw.WaitForChanged(changeType, timeoutMilliseconds)); Assert.Equal(enabledBeforeWait, fsw.EnableRaisingEvents); } } From c774885a60c96f0594ef9856184500ae626fff30 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Fri, 25 Mar 2022 19:36:05 +0100 Subject: [PATCH 65/72] Add tests --- .../tests/ProcessTests.cs | 12 ++ .../tests/FileSystemWatcher.WaitForChanged.cs | 16 +++ .../NamedPipeTests/NamedPipeTest.Specific.cs | 6 +- .../src/System/Net/NetworkInformation/Ping.cs | 2 +- .../tests/FunctionalTests/PingTest.cs | 4 + .../ArgumentValidationTests.cs | 7 +- .../tests/ServiceBaseTests.cs | 14 +++ .../System.Threading.Tasks.sln | 115 ++++++++++-------- .../tests/System.Threading.Tasks.Tests.csproj | 1 + .../tests/Task/TaskArgumentValidationTests.cs | 21 ++++ 10 files changed, 140 insertions(+), 58 deletions(-) create mode 100644 src/libraries/System.Threading.Tasks/tests/Task/TaskArgumentValidationTests.cs diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessTests.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessTests.cs index 441036b8380fe2..eb9cda4d6653cf 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessTests.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessTests.cs @@ -74,6 +74,18 @@ private void AssertNonZeroAllZeroDarwin(long value) } } + [Theory] + [InlineData(-2)] + [InlineData((long)int.MaxValue + 1)] + public void TestWaitForExitValidation(long milliseconds) + { + CreateDefaultProcess(); + TimeSpan timeout = TimeSpan.FromMilliseconds(milliseconds); + + ArgumentOutOfRangeException exception = Assert.Throws(() => _process.WaitForExit(timeout)); + Assert.Contains("timeout", exception.Message); + } + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] [PlatformSpecific(TestPlatforms.Windows)] // Expected behavior varies on Windows and Unix public void TestBasePriorityOnWindows() diff --git a/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.WaitForChanged.cs b/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.WaitForChanged.cs index d01adbd6ceed43..eb831730f2d9a2 100644 --- a/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.WaitForChanged.cs +++ b/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.WaitForChanged.cs @@ -75,6 +75,22 @@ public static void WaitForChangedResult_TimedOut_Roundtrip() Assert.True(result.TimedOut); } + [Theory] + [InlineData(-2)] + [InlineData((long)int.MaxValue + 1)] + public void TimeSpan_ArgumentValidation(long milliseconds) + { + TimeSpan timeout = TimeSpan.FromMilliseconds(milliseconds); + using var testDirectory = new TempDirectory(GetTestFilePath()); + using var _ = new TempDirectory(Path.Combine(testDirectory.Path, GetTestFileName())); + using var fsw = new FileSystemWatcher(testDirectory.Path); + + ArgumentOutOfRangeException exception = + Assert.Throws( + () => fsw.WaitForChanged(WatcherChangeTypes.All, timeout)); + Assert.Contains("timeout", exception.Message); + } + [Theory] [InlineData(false, true)] [InlineData(true, false)] diff --git a/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Specific.cs b/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Specific.cs index 91c24ed3556202..64744e5a4e4fbb 100644 --- a/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Specific.cs +++ b/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.Specific.cs @@ -23,8 +23,10 @@ public void InvalidConnectTimeout_Throws_ArgumentOutOfRangeException() { AssertExtensions.Throws("timeout", () => client.Connect(-111)); AssertExtensions.Throws("timeout", () => { client.ConnectAsync(-111); }); - AssertExtensions.Throws("timeout", () => client.Connect(TimeSpan.FromMilliseconds(-111))); - AssertExtensions.Throws("timeout", () => { client.ConnectAsync(TimeSpan.FromMilliseconds(-111), default); }); + AssertExtensions.Throws("timeout", () => client.Connect(TimeSpan.FromMilliseconds(-2))); + AssertExtensions.Throws("timeout", () => { client.ConnectAsync(TimeSpan.FromMilliseconds(-2), default); }); + AssertExtensions.Throws("timeout", () => client.Connect(TimeSpan.FromMilliseconds((long)int.MaxValue + 1))); + AssertExtensions.Throws("timeout", () => { client.ConnectAsync(TimeSpan.FromMilliseconds((long)int.MaxValue + 1), default); }); } } diff --git a/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs b/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs index 1bf92d9762a3b7..9de325f6081f9c 100644 --- a/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs +++ b/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs @@ -327,7 +327,7 @@ public Task SendPingAsync(IPAddress address, int timeout, byte[] buff public Task SendPingAsync(IPAddress address, TimeSpan timeout, byte[]? buffer = null, PingOptions? options = null, CancellationToken cancellationToken = default) { - int milliseconds = checked((int)timeout.TotalMilliseconds); + int milliseconds = ToTimeoutMilliseconds(timeout); cancellationToken.ThrowIfCancellationRequested(); Task task = SendPingAsync(address, milliseconds, buffer ?? DefaultSendBuffer, options); diff --git a/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs b/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs index 7f3214b1d862b4..2dd00ce9772df7 100644 --- a/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs +++ b/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs @@ -108,12 +108,16 @@ public async Task SendPingAsync_InvalidArgs() AssertExtensions.Throws("timeout", () => { p.SendPingAsync(TestSettings.LocalHost, -1); }); AssertExtensions.Throws("timeout", () => { p.SendPingAsync(localIpAddress, TimeSpan.FromMilliseconds(-1), default, default, default); }); AssertExtensions.Throws("timeout", () => { p.SendPingAsync(TestSettings.LocalHost, TimeSpan.FromMilliseconds(-1), default, default, default); }); + AssertExtensions.Throws("timeout", () => { p.SendPingAsync(localIpAddress, TimeSpan.FromMilliseconds((long)int.MaxValue + 1), default, default, default); }); + AssertExtensions.Throws("timeout", () => { p.SendPingAsync(TestSettings.LocalHost, TimeSpan.FromMilliseconds((long)int.MaxValue + 1), default, default, default); }); AssertExtensions.Throws("timeout", () => { p.SendAsync(localIpAddress, -1, null); }); AssertExtensions.Throws("timeout", () => { p.SendAsync(TestSettings.LocalHost, -1, null); }); AssertExtensions.Throws("timeout", () => { p.Send(localIpAddress, -1); }); AssertExtensions.Throws("timeout", () => { p.Send(TestSettings.LocalHost, -1); }); AssertExtensions.Throws("timeout", () => { p.Send(localIpAddress, TimeSpan.FromMilliseconds(-1), default, default); }); AssertExtensions.Throws("timeout", () => { p.Send(TestSettings.LocalHost, TimeSpan.FromMilliseconds(-1), default, default); }); + AssertExtensions.Throws("timeout", () => { p.Send(localIpAddress, TimeSpan.FromMilliseconds((long)int.MaxValue + 1), default, default); }); + AssertExtensions.Throws("timeout", () => { p.Send(TestSettings.LocalHost, TimeSpan.FromMilliseconds((long)int.MaxValue + 1), default, default); }); // Null byte[] AssertExtensions.Throws("buffer", () => { p.SendPingAsync(localIpAddress, 0, null); }); diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ArgumentValidationTests.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/ArgumentValidationTests.cs index 821173a5a7a380..31da90800351ab 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ArgumentValidationTests.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/ArgumentValidationTests.cs @@ -384,12 +384,17 @@ public void Select_LargeList_Throws_ArgumentOutOfRange() [Fact] public void Select_LargeList_Throws_ArgumentOutOfRange_TimeSpan() { - TimeSpan infinity = Timeout.InfiniteTimeSpan; var largeList = new LargeList(); + TimeSpan infinity = Timeout.InfiniteTimeSpan; Assert.Throws(() => Socket.Select(largeList, null, null, infinity)); Assert.Throws(() => Socket.Select(null, largeList, null, infinity)); Assert.Throws(() => Socket.Select(null, null, largeList, infinity)); + + TimeSpan negative = TimeSpan.FromMilliseconds(-1); + Assert.Throws(() => Socket.Select(largeList, null, null, negative)); + Assert.Throws(() => Socket.Select(null, largeList, null, negative)); + Assert.Throws(() => Socket.Select(null, null, largeList, negative)); } [Fact] diff --git a/src/libraries/System.ServiceProcess.ServiceController/tests/ServiceBaseTests.cs b/src/libraries/System.ServiceProcess.ServiceController/tests/ServiceBaseTests.cs index 247d600b86c768..a22fdb59a2d8f5 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/tests/ServiceBaseTests.cs +++ b/src/libraries/System.ServiceProcess.ServiceController/tests/ServiceBaseTests.cs @@ -72,6 +72,20 @@ private void Cleanup() } } +#if NETCOREAPP + [Theory] + [InlineData(-2)] + [InlineData((long)int.MaxValue + 1)] + public void RequestAdditionalTime_Throws_ArgumentOutOfRangeException(long milliseconds) + { + TimeSpan timeout = TimeSpan.FromMilliseconds(milliseconds); + using var serviceBase = new ServiceBase(); + ArgumentOutOfRangeException exception = + Assert.Throws(() => serviceBase.RequestAdditionalTime(timeout)); + Assert.Contains("timeout", exception.Message); + } +#endif + [ConditionalFact(nameof(IsProcessElevated))] public void TestOnStartThenStop() { diff --git a/src/libraries/System.Threading.Tasks/System.Threading.Tasks.sln b/src/libraries/System.Threading.Tasks/System.Threading.Tasks.sln index 944cf041453306..8380331fb70223 100644 --- a/src/libraries/System.Threading.Tasks/System.Threading.Tasks.sln +++ b/src/libraries/System.Threading.Tasks/System.Threading.Tasks.sln @@ -1,4 +1,8 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.1.32210.238 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib", "..\..\coreclr\System.Private.CoreLib\System.Private.CoreLib.csproj", "{2738C2DB-E488-4EA2-B981-ADB8C520DCA6}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}" @@ -24,18 +28,27 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ref", "ref", "{AF511BE2-5550-4D73-921E-500E98B26AA0}" EndProject Global + GlobalSection(SharedMSBuildProjectFiles) = preSolution + ..\System.Private.CoreLib\src\System.Private.CoreLib.Shared.projitems*{2738c2db-e488-4ea2-b981-adb8c520dca6}*SharedItemsImports = 5 + EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution + Checked|Any CPU = Checked|Any CPU + Checked|x64 = Checked|x64 + Checked|x86 = Checked|x86 Debug|Any CPU = Debug|Any CPU Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU Release|x64 = Release|x64 Release|x86 = Release|x86 - Checked|Any CPU = Checked|Any CPU - Checked|x64 = Checked|x64 - Checked|x86 = Checked|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Checked|Any CPU.ActiveCfg = Checked|x64 + {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Checked|Any CPU.Build.0 = Checked|x64 + {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Checked|x64.ActiveCfg = Checked|x64 + {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Checked|x64.Build.0 = Checked|x64 + {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Checked|x86.ActiveCfg = Checked|x86 + {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Checked|x86.Build.0 = Checked|x86 {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Debug|Any CPU.ActiveCfg = Debug|x64 {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Debug|Any CPU.Build.0 = Debug|x64 {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Debug|x64.ActiveCfg = Debug|x64 @@ -48,12 +61,12 @@ Global {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Release|x64.Build.0 = Release|x64 {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Release|x86.ActiveCfg = Release|x86 {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Release|x86.Build.0 = Release|x86 - {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Checked|Any CPU.ActiveCfg = Checked|x64 - {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Checked|Any CPU.Build.0 = Checked|x64 - {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Checked|x64.ActiveCfg = Checked|x64 - {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Checked|x64.Build.0 = Checked|x64 - {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Checked|x86.ActiveCfg = Checked|x86 - {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Checked|x86.Build.0 = Checked|x86 + {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Checked|Any CPU.Build.0 = Debug|Any CPU + {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Checked|x64.ActiveCfg = Debug|Any CPU + {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Checked|x64.Build.0 = Debug|Any CPU + {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Checked|x86.ActiveCfg = Debug|Any CPU + {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Checked|x86.Build.0 = Debug|Any CPU {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Debug|Any CPU.Build.0 = Debug|Any CPU {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -66,12 +79,12 @@ Global {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Release|x64.Build.0 = Release|Any CPU {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Release|x86.ActiveCfg = Release|Any CPU {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Release|x86.Build.0 = Release|Any CPU - {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Checked|Any CPU.Build.0 = Debug|Any CPU - {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Checked|x64.ActiveCfg = Debug|Any CPU - {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Checked|x64.Build.0 = Debug|Any CPU - {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Checked|x86.ActiveCfg = Debug|Any CPU - {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Checked|x86.Build.0 = Debug|Any CPU + {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Checked|Any CPU.Build.0 = Debug|Any CPU + {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Checked|x64.ActiveCfg = Debug|Any CPU + {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Checked|x64.Build.0 = Debug|Any CPU + {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Checked|x86.ActiveCfg = Debug|Any CPU + {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Checked|x86.Build.0 = Debug|Any CPU {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Debug|Any CPU.Build.0 = Debug|Any CPU {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -84,12 +97,12 @@ Global {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Release|x64.Build.0 = Release|Any CPU {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Release|x86.ActiveCfg = Release|Any CPU {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Release|x86.Build.0 = Release|Any CPU - {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Checked|Any CPU.Build.0 = Debug|Any CPU - {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Checked|x64.ActiveCfg = Debug|Any CPU - {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Checked|x64.Build.0 = Debug|Any CPU - {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Checked|x86.ActiveCfg = Debug|Any CPU - {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Checked|x86.Build.0 = Debug|Any CPU + {879D329A-C5F7-46DE-887F-12928E015C8C}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {879D329A-C5F7-46DE-887F-12928E015C8C}.Checked|Any CPU.Build.0 = Debug|Any CPU + {879D329A-C5F7-46DE-887F-12928E015C8C}.Checked|x64.ActiveCfg = Debug|Any CPU + {879D329A-C5F7-46DE-887F-12928E015C8C}.Checked|x64.Build.0 = Debug|Any CPU + {879D329A-C5F7-46DE-887F-12928E015C8C}.Checked|x86.ActiveCfg = Debug|Any CPU + {879D329A-C5F7-46DE-887F-12928E015C8C}.Checked|x86.Build.0 = Debug|Any CPU {879D329A-C5F7-46DE-887F-12928E015C8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {879D329A-C5F7-46DE-887F-12928E015C8C}.Debug|Any CPU.Build.0 = Debug|Any CPU {879D329A-C5F7-46DE-887F-12928E015C8C}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -102,12 +115,12 @@ Global {879D329A-C5F7-46DE-887F-12928E015C8C}.Release|x64.Build.0 = Release|Any CPU {879D329A-C5F7-46DE-887F-12928E015C8C}.Release|x86.ActiveCfg = Release|Any CPU {879D329A-C5F7-46DE-887F-12928E015C8C}.Release|x86.Build.0 = Release|Any CPU - {879D329A-C5F7-46DE-887F-12928E015C8C}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {879D329A-C5F7-46DE-887F-12928E015C8C}.Checked|Any CPU.Build.0 = Debug|Any CPU - {879D329A-C5F7-46DE-887F-12928E015C8C}.Checked|x64.ActiveCfg = Debug|Any CPU - {879D329A-C5F7-46DE-887F-12928E015C8C}.Checked|x64.Build.0 = Debug|Any CPU - {879D329A-C5F7-46DE-887F-12928E015C8C}.Checked|x86.ActiveCfg = Debug|Any CPU - {879D329A-C5F7-46DE-887F-12928E015C8C}.Checked|x86.Build.0 = Debug|Any CPU + {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Checked|Any CPU.Build.0 = Debug|Any CPU + {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Checked|x64.ActiveCfg = Debug|Any CPU + {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Checked|x64.Build.0 = Debug|Any CPU + {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Checked|x86.ActiveCfg = Debug|Any CPU + {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Checked|x86.Build.0 = Debug|Any CPU {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Debug|Any CPU.Build.0 = Debug|Any CPU {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -120,12 +133,12 @@ Global {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Release|x64.Build.0 = Release|Any CPU {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Release|x86.ActiveCfg = Release|Any CPU {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Release|x86.Build.0 = Release|Any CPU - {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Checked|Any CPU.Build.0 = Debug|Any CPU - {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Checked|x64.ActiveCfg = Debug|Any CPU - {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Checked|x64.Build.0 = Debug|Any CPU - {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Checked|x86.ActiveCfg = Debug|Any CPU - {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Checked|x86.Build.0 = Debug|Any CPU + {8C762956-7AB1-4806-9144-5E13771CB22B}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {8C762956-7AB1-4806-9144-5E13771CB22B}.Checked|Any CPU.Build.0 = Debug|Any CPU + {8C762956-7AB1-4806-9144-5E13771CB22B}.Checked|x64.ActiveCfg = Debug|Any CPU + {8C762956-7AB1-4806-9144-5E13771CB22B}.Checked|x64.Build.0 = Debug|Any CPU + {8C762956-7AB1-4806-9144-5E13771CB22B}.Checked|x86.ActiveCfg = Debug|Any CPU + {8C762956-7AB1-4806-9144-5E13771CB22B}.Checked|x86.Build.0 = Debug|Any CPU {8C762956-7AB1-4806-9144-5E13771CB22B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8C762956-7AB1-4806-9144-5E13771CB22B}.Debug|Any CPU.Build.0 = Debug|Any CPU {8C762956-7AB1-4806-9144-5E13771CB22B}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -138,12 +151,12 @@ Global {8C762956-7AB1-4806-9144-5E13771CB22B}.Release|x64.Build.0 = Release|Any CPU {8C762956-7AB1-4806-9144-5E13771CB22B}.Release|x86.ActiveCfg = Release|Any CPU {8C762956-7AB1-4806-9144-5E13771CB22B}.Release|x86.Build.0 = Release|Any CPU - {8C762956-7AB1-4806-9144-5E13771CB22B}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {8C762956-7AB1-4806-9144-5E13771CB22B}.Checked|Any CPU.Build.0 = Debug|Any CPU - {8C762956-7AB1-4806-9144-5E13771CB22B}.Checked|x64.ActiveCfg = Debug|Any CPU - {8C762956-7AB1-4806-9144-5E13771CB22B}.Checked|x64.Build.0 = Debug|Any CPU - {8C762956-7AB1-4806-9144-5E13771CB22B}.Checked|x86.ActiveCfg = Debug|Any CPU - {8C762956-7AB1-4806-9144-5E13771CB22B}.Checked|x86.Build.0 = Debug|Any CPU + {53FBD913-F587-441B-951A-195F65041CF7}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {53FBD913-F587-441B-951A-195F65041CF7}.Checked|Any CPU.Build.0 = Debug|Any CPU + {53FBD913-F587-441B-951A-195F65041CF7}.Checked|x64.ActiveCfg = Debug|Any CPU + {53FBD913-F587-441B-951A-195F65041CF7}.Checked|x64.Build.0 = Debug|Any CPU + {53FBD913-F587-441B-951A-195F65041CF7}.Checked|x86.ActiveCfg = Debug|Any CPU + {53FBD913-F587-441B-951A-195F65041CF7}.Checked|x86.Build.0 = Debug|Any CPU {53FBD913-F587-441B-951A-195F65041CF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {53FBD913-F587-441B-951A-195F65041CF7}.Debug|Any CPU.Build.0 = Debug|Any CPU {53FBD913-F587-441B-951A-195F65041CF7}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -156,12 +169,12 @@ Global {53FBD913-F587-441B-951A-195F65041CF7}.Release|x64.Build.0 = Release|Any CPU {53FBD913-F587-441B-951A-195F65041CF7}.Release|x86.ActiveCfg = Release|Any CPU {53FBD913-F587-441B-951A-195F65041CF7}.Release|x86.Build.0 = Release|Any CPU - {53FBD913-F587-441B-951A-195F65041CF7}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {53FBD913-F587-441B-951A-195F65041CF7}.Checked|Any CPU.Build.0 = Debug|Any CPU - {53FBD913-F587-441B-951A-195F65041CF7}.Checked|x64.ActiveCfg = Debug|Any CPU - {53FBD913-F587-441B-951A-195F65041CF7}.Checked|x64.Build.0 = Debug|Any CPU - {53FBD913-F587-441B-951A-195F65041CF7}.Checked|x86.ActiveCfg = Debug|Any CPU - {53FBD913-F587-441B-951A-195F65041CF7}.Checked|x86.Build.0 = Debug|Any CPU + {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Checked|Any CPU.Build.0 = Debug|Any CPU + {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Checked|x64.ActiveCfg = Debug|Any CPU + {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Checked|x64.Build.0 = Debug|Any CPU + {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Checked|x86.ActiveCfg = Debug|Any CPU + {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Checked|x86.Build.0 = Debug|Any CPU {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Debug|Any CPU.Build.0 = Debug|Any CPU {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -174,25 +187,19 @@ Global {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Release|x64.Build.0 = Release|Any CPU {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Release|x86.ActiveCfg = Release|Any CPU {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Release|x86.Build.0 = Release|Any CPU - {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Checked|Any CPU.Build.0 = Debug|Any CPU - {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Checked|x64.ActiveCfg = Debug|Any CPU - {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Checked|x64.Build.0 = Debug|Any CPU - {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Checked|x86.ActiveCfg = Debug|Any CPU - {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Checked|x86.Build.0 = Debug|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {2738C2DB-E488-4EA2-B981-ADB8C520DCA6} = {9BDEA799-400E-4D1B-B34A-5E910B50FA69} - {53FBD913-F587-441B-951A-195F65041CF7} = {9BDEA799-400E-4D1B-B34A-5E910B50FA69} {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7} = {6C2B5085-E5A0-4732-90D5-BA35E9702990} - {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8} = {6C2B5085-E5A0-4732-90D5-BA35E9702990} {A0477DE6-08C7-4793-A8B6-9974F2675AC7} = {BC4D3352-CF0C-44FA-8829-2845DEA0CC75} {879D329A-C5F7-46DE-887F-12928E015C8C} = {BC4D3352-CF0C-44FA-8829-2845DEA0CC75} {25E8CA91-84A5-4917-90A2-5E077734B0B7} = {BC4D3352-CF0C-44FA-8829-2845DEA0CC75} {8C762956-7AB1-4806-9144-5E13771CB22B} = {AF511BE2-5550-4D73-921E-500E98B26AA0} + {53FBD913-F587-441B-951A-195F65041CF7} = {9BDEA799-400E-4D1B-B34A-5E910B50FA69} + {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8} = {6C2B5085-E5A0-4732-90D5-BA35E9702990} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E940CED0-8CEA-4945-9F90-D6AE2236982C} diff --git a/src/libraries/System.Threading.Tasks/tests/System.Threading.Tasks.Tests.csproj b/src/libraries/System.Threading.Tasks/tests/System.Threading.Tasks.Tests.csproj index 2253b5e87e79d9..ca9d7b875714f1 100644 --- a/src/libraries/System.Threading.Tasks/tests/System.Threading.Tasks.Tests.csproj +++ b/src/libraries/System.Threading.Tasks/tests/System.Threading.Tasks.Tests.csproj @@ -7,6 +7,7 @@ + diff --git a/src/libraries/System.Threading.Tasks/tests/Task/TaskArgumentValidationTests.cs b/src/libraries/System.Threading.Tasks/tests/Task/TaskArgumentValidationTests.cs new file mode 100644 index 00000000000000..155b3d8c60d48d --- /dev/null +++ b/src/libraries/System.Threading.Tasks/tests/Task/TaskArgumentValidationTests.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; + +namespace System.Threading.Tasks.Tests +{ + public sealed class TaskArgumentValidationTests + { + [Theory] + [InlineData(-2)] + [InlineData((long)int.MaxValue + 1)] + public void Task_Wait_ArgumentOutOfRange(long milliseconds) + { + TimeSpan timeout = TimeSpan.FromMilliseconds(milliseconds); + Task task = Task.Run(static () => {}); + ArgumentOutOfRangeException exception = Assert.Throws(() => task.Wait(timeout)); + Assert.Contains("timeout", exception.Message); + } + } +} From 2f4706747772c02d3ec7f0bec045b7663069e2af Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Fri, 25 Mar 2022 19:38:01 +0100 Subject: [PATCH 66/72] Fix file ending --- .../src/System.Private.CoreLib.Shared.projitems | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 35c16eb7412ecf..8889b675d14f9c 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -2383,4 +2383,4 @@ - \ No newline at end of file + From 0d0015fa5d3684f7d219c893da96c9f06606b995 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Fri, 25 Mar 2022 19:41:50 +0100 Subject: [PATCH 67/72] Fix sol file --- .../System.Threading.Tasks.sln | 115 ++++++++---------- 1 file changed, 54 insertions(+), 61 deletions(-) diff --git a/src/libraries/System.Threading.Tasks/System.Threading.Tasks.sln b/src/libraries/System.Threading.Tasks/System.Threading.Tasks.sln index 8380331fb70223..944cf041453306 100644 --- a/src/libraries/System.Threading.Tasks/System.Threading.Tasks.sln +++ b/src/libraries/System.Threading.Tasks/System.Threading.Tasks.sln @@ -1,8 +1,4 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.1.32210.238 -MinimumVisualStudioVersion = 10.0.40219.1 +Microsoft Visual Studio Solution File, Format Version 12.00 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib", "..\..\coreclr\System.Private.CoreLib\System.Private.CoreLib.csproj", "{2738C2DB-E488-4EA2-B981-ADB8C520DCA6}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}" @@ -28,27 +24,18 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ref", "ref", "{AF511BE2-5550-4D73-921E-500E98B26AA0}" EndProject Global - GlobalSection(SharedMSBuildProjectFiles) = preSolution - ..\System.Private.CoreLib\src\System.Private.CoreLib.Shared.projitems*{2738c2db-e488-4ea2-b981-adb8c520dca6}*SharedItemsImports = 5 - EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution - Checked|Any CPU = Checked|Any CPU - Checked|x64 = Checked|x64 - Checked|x86 = Checked|x86 Debug|Any CPU = Debug|Any CPU Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU Release|x64 = Release|x64 Release|x86 = Release|x86 + Checked|Any CPU = Checked|Any CPU + Checked|x64 = Checked|x64 + Checked|x86 = Checked|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Checked|Any CPU.ActiveCfg = Checked|x64 - {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Checked|Any CPU.Build.0 = Checked|x64 - {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Checked|x64.ActiveCfg = Checked|x64 - {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Checked|x64.Build.0 = Checked|x64 - {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Checked|x86.ActiveCfg = Checked|x86 - {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Checked|x86.Build.0 = Checked|x86 {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Debug|Any CPU.ActiveCfg = Debug|x64 {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Debug|Any CPU.Build.0 = Debug|x64 {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Debug|x64.ActiveCfg = Debug|x64 @@ -61,12 +48,12 @@ Global {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Release|x64.Build.0 = Release|x64 {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Release|x86.ActiveCfg = Release|x86 {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Release|x86.Build.0 = Release|x86 - {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Checked|Any CPU.Build.0 = Debug|Any CPU - {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Checked|x64.ActiveCfg = Debug|Any CPU - {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Checked|x64.Build.0 = Debug|Any CPU - {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Checked|x86.ActiveCfg = Debug|Any CPU - {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Checked|x86.Build.0 = Debug|Any CPU + {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Checked|Any CPU.ActiveCfg = Checked|x64 + {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Checked|Any CPU.Build.0 = Checked|x64 + {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Checked|x64.ActiveCfg = Checked|x64 + {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Checked|x64.Build.0 = Checked|x64 + {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Checked|x86.ActiveCfg = Checked|x86 + {2738C2DB-E488-4EA2-B981-ADB8C520DCA6}.Checked|x86.Build.0 = Checked|x86 {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Debug|Any CPU.Build.0 = Debug|Any CPU {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -79,12 +66,12 @@ Global {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Release|x64.Build.0 = Release|Any CPU {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Release|x86.ActiveCfg = Release|Any CPU {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Release|x86.Build.0 = Release|Any CPU - {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Checked|Any CPU.Build.0 = Debug|Any CPU - {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Checked|x64.ActiveCfg = Debug|Any CPU - {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Checked|x64.Build.0 = Debug|Any CPU - {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Checked|x86.ActiveCfg = Debug|Any CPU - {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Checked|x86.Build.0 = Debug|Any CPU + {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Checked|Any CPU.Build.0 = Debug|Any CPU + {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Checked|x64.ActiveCfg = Debug|Any CPU + {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Checked|x64.Build.0 = Debug|Any CPU + {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Checked|x86.ActiveCfg = Debug|Any CPU + {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7}.Checked|x86.Build.0 = Debug|Any CPU {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Debug|Any CPU.Build.0 = Debug|Any CPU {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -97,12 +84,12 @@ Global {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Release|x64.Build.0 = Release|Any CPU {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Release|x86.ActiveCfg = Release|Any CPU {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Release|x86.Build.0 = Release|Any CPU - {879D329A-C5F7-46DE-887F-12928E015C8C}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {879D329A-C5F7-46DE-887F-12928E015C8C}.Checked|Any CPU.Build.0 = Debug|Any CPU - {879D329A-C5F7-46DE-887F-12928E015C8C}.Checked|x64.ActiveCfg = Debug|Any CPU - {879D329A-C5F7-46DE-887F-12928E015C8C}.Checked|x64.Build.0 = Debug|Any CPU - {879D329A-C5F7-46DE-887F-12928E015C8C}.Checked|x86.ActiveCfg = Debug|Any CPU - {879D329A-C5F7-46DE-887F-12928E015C8C}.Checked|x86.Build.0 = Debug|Any CPU + {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Checked|Any CPU.Build.0 = Debug|Any CPU + {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Checked|x64.ActiveCfg = Debug|Any CPU + {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Checked|x64.Build.0 = Debug|Any CPU + {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Checked|x86.ActiveCfg = Debug|Any CPU + {A0477DE6-08C7-4793-A8B6-9974F2675AC7}.Checked|x86.Build.0 = Debug|Any CPU {879D329A-C5F7-46DE-887F-12928E015C8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {879D329A-C5F7-46DE-887F-12928E015C8C}.Debug|Any CPU.Build.0 = Debug|Any CPU {879D329A-C5F7-46DE-887F-12928E015C8C}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -115,12 +102,12 @@ Global {879D329A-C5F7-46DE-887F-12928E015C8C}.Release|x64.Build.0 = Release|Any CPU {879D329A-C5F7-46DE-887F-12928E015C8C}.Release|x86.ActiveCfg = Release|Any CPU {879D329A-C5F7-46DE-887F-12928E015C8C}.Release|x86.Build.0 = Release|Any CPU - {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Checked|Any CPU.Build.0 = Debug|Any CPU - {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Checked|x64.ActiveCfg = Debug|Any CPU - {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Checked|x64.Build.0 = Debug|Any CPU - {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Checked|x86.ActiveCfg = Debug|Any CPU - {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Checked|x86.Build.0 = Debug|Any CPU + {879D329A-C5F7-46DE-887F-12928E015C8C}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {879D329A-C5F7-46DE-887F-12928E015C8C}.Checked|Any CPU.Build.0 = Debug|Any CPU + {879D329A-C5F7-46DE-887F-12928E015C8C}.Checked|x64.ActiveCfg = Debug|Any CPU + {879D329A-C5F7-46DE-887F-12928E015C8C}.Checked|x64.Build.0 = Debug|Any CPU + {879D329A-C5F7-46DE-887F-12928E015C8C}.Checked|x86.ActiveCfg = Debug|Any CPU + {879D329A-C5F7-46DE-887F-12928E015C8C}.Checked|x86.Build.0 = Debug|Any CPU {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Debug|Any CPU.Build.0 = Debug|Any CPU {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -133,12 +120,12 @@ Global {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Release|x64.Build.0 = Release|Any CPU {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Release|x86.ActiveCfg = Release|Any CPU {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Release|x86.Build.0 = Release|Any CPU - {8C762956-7AB1-4806-9144-5E13771CB22B}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {8C762956-7AB1-4806-9144-5E13771CB22B}.Checked|Any CPU.Build.0 = Debug|Any CPU - {8C762956-7AB1-4806-9144-5E13771CB22B}.Checked|x64.ActiveCfg = Debug|Any CPU - {8C762956-7AB1-4806-9144-5E13771CB22B}.Checked|x64.Build.0 = Debug|Any CPU - {8C762956-7AB1-4806-9144-5E13771CB22B}.Checked|x86.ActiveCfg = Debug|Any CPU - {8C762956-7AB1-4806-9144-5E13771CB22B}.Checked|x86.Build.0 = Debug|Any CPU + {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Checked|Any CPU.Build.0 = Debug|Any CPU + {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Checked|x64.ActiveCfg = Debug|Any CPU + {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Checked|x64.Build.0 = Debug|Any CPU + {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Checked|x86.ActiveCfg = Debug|Any CPU + {25E8CA91-84A5-4917-90A2-5E077734B0B7}.Checked|x86.Build.0 = Debug|Any CPU {8C762956-7AB1-4806-9144-5E13771CB22B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8C762956-7AB1-4806-9144-5E13771CB22B}.Debug|Any CPU.Build.0 = Debug|Any CPU {8C762956-7AB1-4806-9144-5E13771CB22B}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -151,12 +138,12 @@ Global {8C762956-7AB1-4806-9144-5E13771CB22B}.Release|x64.Build.0 = Release|Any CPU {8C762956-7AB1-4806-9144-5E13771CB22B}.Release|x86.ActiveCfg = Release|Any CPU {8C762956-7AB1-4806-9144-5E13771CB22B}.Release|x86.Build.0 = Release|Any CPU - {53FBD913-F587-441B-951A-195F65041CF7}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {53FBD913-F587-441B-951A-195F65041CF7}.Checked|Any CPU.Build.0 = Debug|Any CPU - {53FBD913-F587-441B-951A-195F65041CF7}.Checked|x64.ActiveCfg = Debug|Any CPU - {53FBD913-F587-441B-951A-195F65041CF7}.Checked|x64.Build.0 = Debug|Any CPU - {53FBD913-F587-441B-951A-195F65041CF7}.Checked|x86.ActiveCfg = Debug|Any CPU - {53FBD913-F587-441B-951A-195F65041CF7}.Checked|x86.Build.0 = Debug|Any CPU + {8C762956-7AB1-4806-9144-5E13771CB22B}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {8C762956-7AB1-4806-9144-5E13771CB22B}.Checked|Any CPU.Build.0 = Debug|Any CPU + {8C762956-7AB1-4806-9144-5E13771CB22B}.Checked|x64.ActiveCfg = Debug|Any CPU + {8C762956-7AB1-4806-9144-5E13771CB22B}.Checked|x64.Build.0 = Debug|Any CPU + {8C762956-7AB1-4806-9144-5E13771CB22B}.Checked|x86.ActiveCfg = Debug|Any CPU + {8C762956-7AB1-4806-9144-5E13771CB22B}.Checked|x86.Build.0 = Debug|Any CPU {53FBD913-F587-441B-951A-195F65041CF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {53FBD913-F587-441B-951A-195F65041CF7}.Debug|Any CPU.Build.0 = Debug|Any CPU {53FBD913-F587-441B-951A-195F65041CF7}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -169,12 +156,12 @@ Global {53FBD913-F587-441B-951A-195F65041CF7}.Release|x64.Build.0 = Release|Any CPU {53FBD913-F587-441B-951A-195F65041CF7}.Release|x86.ActiveCfg = Release|Any CPU {53FBD913-F587-441B-951A-195F65041CF7}.Release|x86.Build.0 = Release|Any CPU - {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Checked|Any CPU.Build.0 = Debug|Any CPU - {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Checked|x64.ActiveCfg = Debug|Any CPU - {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Checked|x64.Build.0 = Debug|Any CPU - {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Checked|x86.ActiveCfg = Debug|Any CPU - {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Checked|x86.Build.0 = Debug|Any CPU + {53FBD913-F587-441B-951A-195F65041CF7}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {53FBD913-F587-441B-951A-195F65041CF7}.Checked|Any CPU.Build.0 = Debug|Any CPU + {53FBD913-F587-441B-951A-195F65041CF7}.Checked|x64.ActiveCfg = Debug|Any CPU + {53FBD913-F587-441B-951A-195F65041CF7}.Checked|x64.Build.0 = Debug|Any CPU + {53FBD913-F587-441B-951A-195F65041CF7}.Checked|x86.ActiveCfg = Debug|Any CPU + {53FBD913-F587-441B-951A-195F65041CF7}.Checked|x86.Build.0 = Debug|Any CPU {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Debug|Any CPU.Build.0 = Debug|Any CPU {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -187,19 +174,25 @@ Global {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Release|x64.Build.0 = Release|Any CPU {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Release|x86.ActiveCfg = Release|Any CPU {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Release|x86.Build.0 = Release|Any CPU + {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Checked|Any CPU.Build.0 = Debug|Any CPU + {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Checked|x64.ActiveCfg = Debug|Any CPU + {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Checked|x64.Build.0 = Debug|Any CPU + {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Checked|x86.ActiveCfg = Debug|Any CPU + {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8}.Checked|x86.Build.0 = Debug|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {2738C2DB-E488-4EA2-B981-ADB8C520DCA6} = {9BDEA799-400E-4D1B-B34A-5E910B50FA69} + {53FBD913-F587-441B-951A-195F65041CF7} = {9BDEA799-400E-4D1B-B34A-5E910B50FA69} {695A5828-6CFC-4BE1-AE4E-6EC9796B4FC7} = {6C2B5085-E5A0-4732-90D5-BA35E9702990} + {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8} = {6C2B5085-E5A0-4732-90D5-BA35E9702990} {A0477DE6-08C7-4793-A8B6-9974F2675AC7} = {BC4D3352-CF0C-44FA-8829-2845DEA0CC75} {879D329A-C5F7-46DE-887F-12928E015C8C} = {BC4D3352-CF0C-44FA-8829-2845DEA0CC75} {25E8CA91-84A5-4917-90A2-5E077734B0B7} = {BC4D3352-CF0C-44FA-8829-2845DEA0CC75} {8C762956-7AB1-4806-9144-5E13771CB22B} = {AF511BE2-5550-4D73-921E-500E98B26AA0} - {53FBD913-F587-441B-951A-195F65041CF7} = {9BDEA799-400E-4D1B-B34A-5E910B50FA69} - {A8372DA8-B1DD-41ED-AD2C-C74DD5EE51D8} = {6C2B5085-E5A0-4732-90D5-BA35E9702990} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E940CED0-8CEA-4945-9F90-D6AE2236982C} From 77f921f1a1d5118603019f0d650ade8d5e499ba8 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Sat, 26 Mar 2022 18:40:43 +0100 Subject: [PATCH 68/72] Inline `ToTimeoutMilliseconds` --- .../src/System/Net/NetworkInformation/Ping.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs b/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs index 9de325f6081f9c..106501c913642c 100644 --- a/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs +++ b/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.cs @@ -327,10 +327,8 @@ public Task SendPingAsync(IPAddress address, int timeout, byte[] buff public Task SendPingAsync(IPAddress address, TimeSpan timeout, byte[]? buffer = null, PingOptions? options = null, CancellationToken cancellationToken = default) { - int milliseconds = ToTimeoutMilliseconds(timeout); - cancellationToken.ThrowIfCancellationRequested(); - Task task = SendPingAsync(address, milliseconds, buffer ?? DefaultSendBuffer, options); + Task task = SendPingAsync(address, ToTimeoutMilliseconds(timeout), buffer ?? DefaultSendBuffer, options); return task.WaitAsync(cancellationToken); } @@ -339,9 +337,7 @@ public Task SendPingAsync(string hostNameOrAddress, TimeSpan timeout, PingOptions? options = null, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); - - int milliseconds = ToTimeoutMilliseconds(timeout); - Task task = SendPingAsync(hostNameOrAddress, milliseconds, buffer ?? DefaultSendBuffer, options); + Task task = SendPingAsync(hostNameOrAddress, ToTimeoutMilliseconds(timeout), buffer ?? DefaultSendBuffer, options); return task.WaitAsync(cancellationToken); } From a97f7d31f10f6d8d6354b4877b63846b061acece Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Sat, 26 Mar 2022 18:43:12 +0100 Subject: [PATCH 69/72] Fix coding style --- src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs b/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs index 2dd00ce9772df7..1e1d1568943b63 100644 --- a/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs +++ b/src/libraries/System.Net.Ping/tests/FunctionalTests/PingTest.cs @@ -839,7 +839,7 @@ await SendBatchPingAsync( (ping) => ping.SendPingAsync(address), (pingReply) => { - PingResultValidator(pingReply, new[] { IPAddress.Parse(address) }, null); + PingResultValidator(pingReply, new IPAddress[] { IPAddress.Parse(address) }, null); }); }, localIpAddress.ToString(), new RemoteInvokeOptions { StartInfo = remoteInvokeStartInfo }).Dispose(); } From 7cdf76cff2471221a40b5986eb21b7b73e5201b1 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Sat, 26 Mar 2022 18:50:06 +0100 Subject: [PATCH 70/72] Improve test maintainability of `System.Net.Sockets` --- .../tests/FunctionalTests/Connect.cs | 35 +++++++------------ 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs index e339d2c60f6c79..954e70fa7fe980 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs @@ -341,8 +341,10 @@ public async Task ConnectHostNameAndPort_CancelDuringConnect_Throws() } } - [Fact] - public async Task FailedConnect_ConnectedReturnsFalse() + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task FailedConnect_ConnectedReturnsFalse(bool useTimeSpan) { using Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); @@ -354,27 +356,14 @@ public async Task FailedConnect_ConnectedReturnsFalse() Assert.Equal(SocketError.WouldBlock, se.SocketErrorCode); // Give the non-blocking connect some time to complete. - socket.Poll(5_000_000 /* microSeconds */, SelectMode.SelectWrite); - } - - Assert.False(socket.Connected); - } - - [Fact] - public async Task FailedConnect_ConnectedReturnsFalse_TimeSpan() - { - TimeSpan timeSpan = TimeSpan.FromSeconds(30); - using Socket socket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - - // Connect to port 1 where we expect no server to be listening. - SocketException se = await Assert.ThrowsAnyAsync(() => ConnectAsync(socket, new IPEndPoint(IPAddress.Loopback, 1))); - - if (se.SocketErrorCode != SocketError.ConnectionRefused) - { - Assert.Equal(SocketError.WouldBlock, se.SocketErrorCode); - - // Give the non-blocking connect some time to complete. - socket.Poll(timeSpan, SelectMode.SelectWrite); + if (useTimeSpan) + { + socket.Poll(TimeSpan.FromMilliseconds(5000), SelectMode.SelectWrite); + } + else + { + socket.Poll(5_000_000 /* microSeconds */, SelectMode.SelectWrite); + } } Assert.False(socket.Connected); From 4a73007446a6e9b0b57121e2aa19c56660542905 Mon Sep 17 00:00:00 2001 From: Robin Lindner Date: Sat, 26 Mar 2022 19:10:45 +0100 Subject: [PATCH 71/72] Apply suggestions --- .../tests/ProcessTests.cs | 5 +- .../tests/FileSystemWatcher.WaitForChanged.cs | 5 +- .../System.Private.CoreLib/src/System/GC.cs | 3 +- .../src/System/Threading/Tasks/Task.cs | 5 +- .../src/System/ServiceProcess/ServiceBase.cs | 10 ++-- .../tests/ServiceBaseTests.cs | 4 +- .../tests/Task/TaskArgumentValidationTests.cs | 3 +- .../tests/Task/TaskContinueWithTests.cs | 53 ++++++------------- 8 files changed, 27 insertions(+), 61 deletions(-) diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessTests.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessTests.cs index eb9cda4d6653cf..90dc6a8b4ba8f6 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessTests.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessTests.cs @@ -80,10 +80,7 @@ private void AssertNonZeroAllZeroDarwin(long value) public void TestWaitForExitValidation(long milliseconds) { CreateDefaultProcess(); - TimeSpan timeout = TimeSpan.FromMilliseconds(milliseconds); - - ArgumentOutOfRangeException exception = Assert.Throws(() => _process.WaitForExit(timeout)); - Assert.Contains("timeout", exception.Message); + Assert.Throws("timeout", () => _process.WaitForExit(TimeSpan.FromMilliseconds(milliseconds))); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] diff --git a/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.WaitForChanged.cs b/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.WaitForChanged.cs index eb831730f2d9a2..f2558953d26086 100644 --- a/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.WaitForChanged.cs +++ b/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.WaitForChanged.cs @@ -85,10 +85,7 @@ public void TimeSpan_ArgumentValidation(long milliseconds) using var _ = new TempDirectory(Path.Combine(testDirectory.Path, GetTestFileName())); using var fsw = new FileSystemWatcher(testDirectory.Path); - ArgumentOutOfRangeException exception = - Assert.Throws( - () => fsw.WaitForChanged(WatcherChangeTypes.All, timeout)); - Assert.Contains("timeout", exception.Message); + Assert.Throws("timeout", () => fsw.WaitForChanged(WatcherChangeTypes.All, timeout)); } [Theory] diff --git a/src/libraries/System.Private.CoreLib/src/System/GC.cs b/src/libraries/System.Private.CoreLib/src/System/GC.cs index 9dde60df71c701..de53aa1296c5a3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/GC.cs +++ b/src/libraries/System.Private.CoreLib/src/System/GC.cs @@ -11,7 +11,7 @@ public static partial class GC /// Returns, in a specified time-out period, the status of a registered notification for determining whether a full, /// blocking garbage collection by the common language runtime is imminent. /// - /// The timeout on waiting for a full collection + /// The timeout on waiting for a full GC approach /// The status of a registered full GC notification public static GCNotificationStatus WaitForFullGCApproach(TimeSpan timeout) => WaitForFullGCApproach(WaitHandle.ToTimeoutMilliseconds(timeout)); @@ -20,6 +20,7 @@ public static GCNotificationStatus WaitForFullGCApproach(TimeSpan timeout) /// Returns the status of a registered notification about whether a blocking garbage collection /// has completed. May wait indefinitely for a full collection. /// + /// The timeout on waiting for a full collection /// The status of a registered full GC notification public static GCNotificationStatus WaitForFullGCComplete(TimeSpan timeout) => WaitForFullGCComplete(WaitHandle.ToTimeoutMilliseconds(timeout)); diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs index edd4ebe5725b6e..f3aa1a57fd48aa 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs @@ -2642,10 +2642,7 @@ public void Wait() /// /// Waits for the to complete execution. /// - /// - /// A that represents the number of milliseconds to wait, or a that represents -1 milliseconds to wait indefinitely. - /// + /// The time to wait, or to wait indefinitely /// /// A to observe while waiting for the task to complete. /// diff --git a/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs b/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs index 30ddabaed3dc9b..74e95338d51a73 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs +++ b/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs @@ -78,15 +78,15 @@ public unsafe void RequestAdditionalTime(int milliseconds) /// the specified wait hint is passed to the /// Service Control Manager to avoid having the service marked as not responding. /// - /// - public void RequestAdditionalTime(TimeSpan time) => RequestAdditionalTime(ToTimeoutMilliseconds(time)); + /// The requested additional time + public void RequestAdditionalTime(TimeSpan time) => RequestAdditionalTime(ToIntMilliseconds(time)); - private static int ToTimeoutMilliseconds(TimeSpan timeout) + private static int ToIntMilliseconds(TimeSpan time) { - long totalMilliseconds = (long)timeout.TotalMilliseconds; + long totalMilliseconds = (long)time.TotalMilliseconds; if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue) { - throw new ArgumentOutOfRangeException(nameof(timeout)); + throw new ArgumentOutOfRangeException(nameof(time)); } return (int)totalMilliseconds; } diff --git a/src/libraries/System.ServiceProcess.ServiceController/tests/ServiceBaseTests.cs b/src/libraries/System.ServiceProcess.ServiceController/tests/ServiceBaseTests.cs index a22fdb59a2d8f5..c841b9e8ec12ca 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/tests/ServiceBaseTests.cs +++ b/src/libraries/System.ServiceProcess.ServiceController/tests/ServiceBaseTests.cs @@ -80,9 +80,7 @@ public void RequestAdditionalTime_Throws_ArgumentOutOfRangeException(long millis { TimeSpan timeout = TimeSpan.FromMilliseconds(milliseconds); using var serviceBase = new ServiceBase(); - ArgumentOutOfRangeException exception = - Assert.Throws(() => serviceBase.RequestAdditionalTime(timeout)); - Assert.Contains("timeout", exception.Message); + Assert.Throws("time", () => serviceBase.RequestAdditionalTime(timeout)); } #endif diff --git a/src/libraries/System.Threading.Tasks/tests/Task/TaskArgumentValidationTests.cs b/src/libraries/System.Threading.Tasks/tests/Task/TaskArgumentValidationTests.cs index 155b3d8c60d48d..99892193107546 100644 --- a/src/libraries/System.Threading.Tasks/tests/Task/TaskArgumentValidationTests.cs +++ b/src/libraries/System.Threading.Tasks/tests/Task/TaskArgumentValidationTests.cs @@ -14,8 +14,7 @@ public void Task_Wait_ArgumentOutOfRange(long milliseconds) { TimeSpan timeout = TimeSpan.FromMilliseconds(milliseconds); Task task = Task.Run(static () => {}); - ArgumentOutOfRangeException exception = Assert.Throws(() => task.Wait(timeout)); - Assert.Contains("timeout", exception.Message); + Assert.Throws("timeout", () => task.Wait(timeout)); } } } diff --git a/src/libraries/System.Threading.Tasks/tests/Task/TaskContinueWithTests.cs b/src/libraries/System.Threading.Tasks/tests/Task/TaskContinueWithTests.cs index 3f669c2cde0110..11d2e326bcc6f8 100644 --- a/src/libraries/System.Threading.Tasks/tests/Task/TaskContinueWithTests.cs +++ b/src/libraries/System.Threading.Tasks/tests/Task/TaskContinueWithTests.cs @@ -256,8 +256,10 @@ public static void RunContinueWithParamsTest_IllegalArgs() } // Test what happens when you cancel a task in the middle of a continuation chain. - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - public static void RunContinuationCancelTest() + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [InlineData(false)] + [InlineData(true)] + public static void RunContinuationCancelTest(bool useTimeSpan) { bool t1Ran = false; bool t3Ran = false; @@ -281,8 +283,17 @@ public static void RunContinuationCancelTest() // Start the first task in the chain. Should hold off from kicking off (canceled) t2. t1.Start(); - t1.Wait(5000); // should be more than enough time for either of these - t3.Wait(5000); + if (useTimeSpan) + { + TimeSpan timeout = TimeSpan.FromMilliseconds(5000); + t1.Wait(timeout); + t3.Wait(timeout); + } + else + { + t1.Wait(5000); // should be more than enough time for either of these + t3.Wait(5000); + } if (!t1Ran) { @@ -295,40 +306,6 @@ public static void RunContinuationCancelTest() } } - // Test what happens when you cancel a task in the middle of a continuation chain. - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] - public static void RunContinuationCancelTest_TimeSpan() - { - bool t1Ran = false; - bool t3Ran = false; - - Task t1 = new(delegate { t1Ran = true; }); - - CancellationTokenSource ctsForT2 = new(); - Task t2 = t1.ContinueWith(_ => - { - Assert.True(false, "t2 should not have run."); - }, ctsForT2.Token); - - Task t3 = t2.ContinueWith(_ => - { - t3Ran = true; - }); - - // Cancel the middle task in the chain. Should fire off t3. - ctsForT2.Cancel(); - - // Start the first task in the chain. Should hold off from kicking off (canceled) t2. - t1.Start(); - - TimeSpan timeout = TimeSpan.FromMilliseconds(5000); - t1.Wait(timeout); // should be more than enough time for either of these - t3.Wait(timeout); - - Assert.True(t1Ran, "t1 should have run."); - Assert.True(t3Ran, "t3 should have run."); - } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public static void RunContinueWithExceptionTestsNoState() { From f56905d562a63041c8e01efb6738baff12e34f16 Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Sun, 27 Mar 2022 16:49:45 -0600 Subject: [PATCH 72/72] Update src/libraries/System.ServiceProcess.ServiceController/tests/ServiceBaseTests.cs --- .../tests/ServiceBaseTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.ServiceProcess.ServiceController/tests/ServiceBaseTests.cs b/src/libraries/System.ServiceProcess.ServiceController/tests/ServiceBaseTests.cs index c841b9e8ec12ca..67954fda143349 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/tests/ServiceBaseTests.cs +++ b/src/libraries/System.ServiceProcess.ServiceController/tests/ServiceBaseTests.cs @@ -78,9 +78,9 @@ private void Cleanup() [InlineData((long)int.MaxValue + 1)] public void RequestAdditionalTime_Throws_ArgumentOutOfRangeException(long milliseconds) { - TimeSpan timeout = TimeSpan.FromMilliseconds(milliseconds); + TimeSpan time = TimeSpan.FromMilliseconds(milliseconds); using var serviceBase = new ServiceBase(); - Assert.Throws("time", () => serviceBase.RequestAdditionalTime(timeout)); + Assert.Throws("time", () => serviceBase.RequestAdditionalTime(time)); } #endif