Skip to content

Commit abf96c8

Browse files
rzikmgithub-actions
authored andcommitted
Add test for dispose parallel with handshake.
1 parent 95fbdec commit abf96c8

File tree

1 file changed

+52
-0
lines changed

1 file changed

+52
-0
lines changed

src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamDisposeTest.cs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,5 +102,57 @@ await TestConfiguration.WhenAllOrAnyFailedWithTimeout(
102102
await Assert.ThrowsAnyAsync<ObjectDisposedException>(() => client.ReadAsync(readBuffer, cts.Token).AsTask());
103103
}
104104
}
105+
106+
[Fact]
107+
[OuterLoop("Computationally expensive")]
108+
public async Task Dispose_ParallelWithHandshake_ThrowsODE()
109+
{
110+
using CancellationTokenSource cts = new CancellationTokenSource();
111+
cts.CancelAfter(TestConfiguration.PassingTestTimeout);
112+
113+
await Parallel.ForEachAsync(System.Linq.Enumerable.Range(0, 10000), cts.Token, async (i, token) =>
114+
{
115+
(SslStream client, SslStream server) = TestHelper.GetConnectedSslStreams();
116+
using (client)
117+
using (server)
118+
using (X509Certificate2 serverCertificate = Configuration.Certificates.GetServerCertificate())
119+
using (X509Certificate2 clientCertificate = Configuration.Certificates.GetClientCertificate())
120+
{
121+
SslClientAuthenticationOptions clientOptions = new SslClientAuthenticationOptions()
122+
{
123+
TargetHost = Guid.NewGuid().ToString("N"),
124+
RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true,
125+
};
126+
127+
SslServerAuthenticationOptions serverOptions = new SslServerAuthenticationOptions()
128+
{
129+
ServerCertificate = serverCertificate,
130+
};
131+
132+
var clientTask = Task.Run(() => client.AuthenticateAsClientAsync(clientOptions, cts.Token));
133+
var serverTask = Task.Run(() => server.AuthenticateAsServerAsync(serverOptions, cts.Token));
134+
135+
// Dispose the instances while the handshake is in progress.
136+
client.Dispose();
137+
server.Dispose();
138+
139+
await ValidateExceptionAsync(clientTask);
140+
await ValidateExceptionAsync(serverTask);
141+
}
142+
});
143+
144+
static async Task ValidateExceptionAsync(Task task)
145+
{
146+
try
147+
{
148+
await task;
149+
}
150+
// either we disposed the stream, or the other side does and we get unexpected EOF
151+
catch (Exception ex) when (ex is ObjectDisposedException or IOException)
152+
{
153+
return;
154+
}
155+
}
156+
}
105157
}
106158
}

0 commit comments

Comments
 (0)