Skip to content

Commit

Permalink
Test
Browse files Browse the repository at this point in the history
  • Loading branch information
MihaZupan committed Jun 24, 2024
1 parent 35437dd commit 35a136c
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

namespace System.Net.Http.Functional.Tests
{
[ActiveIssue("Foo")]
public abstract class DiagnosticsTest : HttpClientHandlerTestBase
{
private const string EnableActivityPropagationEnvironmentVariableSettingName = "DOTNET_SYSTEM_NET_HTTP_ENABLEACTIVITYPROPAGATION";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Microsoft.DotNet.RemoteExecutor;
using Xunit;
using Xunit.Abstractions;
using TestUtilities;

namespace System.Net.Http.Functional.Tests
{
Expand All @@ -18,6 +19,11 @@ public abstract class SocketsHttpHandler_Cancellation_Test : HttpClientHandler_C
{
protected SocketsHttpHandler_Cancellation_Test(ITestOutputHelper output) : base(output) { }

[Fact] public async Task ValidateConnectTimeout2() => await ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection(true);
[Fact] public async Task ValidateConnectTimeout3() => await ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection(true);
[Fact][OuterLoop] public async Task ValidateConnectTimeout4() => await ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection(true);
[Fact][OuterLoop] public async Task ValidateConnectTimeout5() => await ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection(true);

private async Task ValidateConnectTimeout(HttpMessageInvoker invoker, Uri uri, int minElapsed, int maxElapsed)
{
var sw = Stopwatch.StartNew();
Expand Down Expand Up @@ -81,6 +87,11 @@ public async Task ConnectTimeout_ConnectCallbackTimesOut_Throws(bool useSsl)
options: new GenericLoopbackOptions() { UseSsl = useSsl });
}

[Fact] public async Task ConnectTimeout_PlaintextStreamFilterTimesOut_Throws2() => await ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection(true);
[Fact] public async Task ConnectTimeout_PlaintextStreamFilterTimesOut_Throws3() => await ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection(true);
[Fact][OuterLoop] public async Task ConnectTimeout_PlaintextStreamFilterTimesOut_Throws4() => await ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection(true);
[Fact][OuterLoop] public async Task ConnectTimeout_PlaintextStreamFilterTimesOut_Throws5() => await ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection(true);

[OuterLoop]
[Fact]
public async Task ConnectTimeout_PlaintextStreamFilterTimesOut_Throws()
Expand All @@ -107,36 +118,35 @@ public async Task ConnectTimeout_PlaintextStreamFilterTimesOut_Throws()
options: new GenericLoopbackOptions() { UseSsl = false });
}

[OuterLoop]
[Fact] public async Task ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection2() => await ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection(true);
[Fact] public async Task ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection3() => await ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection(true);

[Fact][OuterLoop] public async Task ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection4() => await ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection(true);
[Fact][OuterLoop] public async Task ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection5() => await ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection(true);

[Theory]
[InlineData(true)]
[InlineData(false)]
public async Task ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection(bool useSsl)
{
if (UseVersion == HttpVersion.Version30)
if (UseVersion.Major != 1 || !TestAsync || !useSsl)
{
// HTTP3 does not support ConnectCallback
return;
}

if (!TestAsync)
{
// Test relies on ordering of async operations, so we can't test the sync case
return;
}
using var listener = new TestEventListener(_output, TestEventListener.NetworkingEvents);

await LoopbackServerFactory.CreateClientAndServerAsync(async uri =>
{
int connectCount = 0;
TaskCompletionSource tcsFirstConnectionInitiated = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
TaskCompletionSource tcsFirstRequestCanceled = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
var tcsFirstConnectionInitiated = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
var tcsFirstRequestCanceled = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
using (var handler = CreateHttpClientHandler(allowAllCertificates: true))
using (var client = CreateHttpClient(handler))
using (HttpClientHandler handler = CreateHttpClientHandler())
using (HttpClient client = CreateHttpClient(handler))
{
var socketsHandler = GetUnderlyingSocketsHttpHandler(handler);
socketsHandler.ConnectCallback = async (context, token) =>
GetUnderlyingSocketsHttpHandler(handler).ConnectCallback = async (context, token) =>
{
// Note we force serialization of connection creation by waiting on tcsFirstConnectionInitiated below,
// so we don't need to worry about concurrent access to connectCount.
Expand All @@ -145,6 +155,8 @@ public async Task ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSu
Assert.True(connectCount <= 2);
_output.WriteLine($"Connection count {connectCount}");
if (isFirstConnection)
{
tcsFirstConnectionInitiated.SetResult();
Expand All @@ -157,6 +169,8 @@ public async Task ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSu
// Wait until first request is cancelled and has completed
await tcsFirstRequestCanceled.Task;
_output.WriteLine($"After tcsFirstRequestCanceled {isFirstConnection}");
if (isFirstConnection)
{
// Fail the first connection attempt
Expand All @@ -170,27 +184,34 @@ public async Task ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSu
};
using CancellationTokenSource cts = new CancellationTokenSource();
Task<HttpResponseMessage> t1 = client.SendAsync(new HttpRequestMessage(HttpMethod.Get, uri) { Version = UseVersion, VersionPolicy = HttpVersionPolicy.RequestVersionExact }, cts.Token);
Task<HttpResponseMessage> t1 = client.SendAsync(CreateRequest(HttpMethod.Get, uri, UseVersion, exactVersion: true), cts.Token);
_output.WriteLine("t1");
// Wait for the connection attempt to be initiated before we send the second request, to avoid races in connection creation
await tcsFirstConnectionInitiated.Task;
Task<HttpResponseMessage> t2 = client.SendAsync(new HttpRequestMessage(HttpMethod.Get, uri) { Version = UseVersion, VersionPolicy = HttpVersionPolicy.RequestVersionExact }, default);
Task<HttpResponseMessage> t2 = client.SendAsync(CreateRequest(HttpMethod.Get, uri, UseVersion, exactVersion: true), CancellationToken.None);
_output.WriteLine("t2");
// Cancel the first message and wait for it to complete
cts.Cancel();
await Assert.ThrowsAnyAsync<OperationCanceledException>(() => t1);
_output.WriteLine("ThrowsAnyAsync");
// Signal connections to proceed
tcsFirstRequestCanceled.SetResult();
// Second request should succeed, even though the first connection failed
HttpResponseMessage resp2 = await t2;
_output.WriteLine("resp2");
Assert.Equal(HttpStatusCode.OK, resp2.StatusCode);
Assert.Equal("Hello world", await resp2.Content.ReadAsStringAsync());
Assert.True(connectCount == 2);
}
}, async server =>
{
await server.AcceptConnectionSendResponseAndCloseAsync(content: "Hello world");
await server.HandleRequestAsync(content: "Hello world");
_output.WriteLine("Server done");
},
options: new GenericLoopbackOptions() { UseSsl = useSsl });
}
Expand Down Expand Up @@ -393,6 +414,11 @@ public async Task PendingConnectionTimeout_HighValue_PendingConnectionIsNotCance
}, UseVersion.ToString(), timeout.ToString()).DisposeAsync();
}

[Fact] public async Task PendingConnectionTimeout_HighValue_PendingConnectionIsNotCancelled2() => await ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection(true);
[Fact] public async Task PendingConnectionTimeout_HighValue_PendingConnectionIsNotCancelled3() => await ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection(true);
[Fact] [OuterLoop] public async Task PendingConnectionTimeout_HighValue_PendingConnectionIsNotCancelled4() => await ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection(true);
[Fact] [OuterLoop] public async Task PendingConnectionTimeout_HighValue_PendingConnectionIsNotCancelled5() => await ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection(true);

private sealed class SetTcsContent : StreamContent
{
private readonly TaskCompletionSource<bool> _tcs;
Expand Down

0 comments on commit 35a136c

Please sign in to comment.