Skip to content

DiagnosticsHandler CI testing #55292

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using System.Net.Sockets;
using System.Net.WebSockets;
using System.Threading;
using System.Diagnostics;

namespace System.Net.Test.Common
{
Expand All @@ -20,23 +21,60 @@ namespace System.Net.Test.Common
public abstract class LoopbackServerFactory
{
public abstract GenericLoopbackServer CreateServer(GenericLoopbackOptions options = null);
public abstract Task CreateServerAsync(Func<GenericLoopbackServer, Uri, Task> funcAsync, int millisecondsTimeout = 60_000, GenericLoopbackOptions options = null);
public abstract Task CreateServerAsync(Func<GenericLoopbackServer, Uri, Task> funcAsync, int millisecondsTimeout = 60_000, GenericLoopbackOptions options = null, List<(int, long)> times = null, Stopwatch s = null);

public abstract Task<GenericLoopbackConnection> CreateConnectionAsync(SocketWrapper socket, Stream stream, GenericLoopbackOptions options = null);

public abstract Version Version { get; }

// Common helper methods

public Task CreateClientAndServerAsync(Func<Uri, Task> clientFunc, Func<GenericLoopbackServer, Task> serverFunc, int millisecondsTimeout = 60_000, GenericLoopbackOptions options = null)
public Task CreateClientAndServerAsync(Func<Uri, Task> clientFunc, Func<GenericLoopbackServer, Task> serverFunc, int millisecondsTimeout = 60_000, GenericLoopbackOptions options = null, List<(int, long)> times = null, Stopwatch s = null)
{
return CreateServerAsync(async (server, uri) =>
times?.Add((100, s.ElapsedMilliseconds));
var server = CreateServerAsync(async (server, uri) =>
{
Task clientTask = clientFunc(uri);
Task serverTask = serverFunc(server);
times?.Add((101, s.ElapsedMilliseconds));
Task clientTask = Task.Run(async () =>
{
times?.Add((300, s.ElapsedMilliseconds));
try
{
times?.Add((301, s.ElapsedMilliseconds));
await clientFunc(uri);
times?.Add((302, s.ElapsedMilliseconds));
}
catch
{
times?.Add((303, s.ElapsedMilliseconds));
throw;
}
times?.Add((304, s.ElapsedMilliseconds));
});
times?.Add((102, s.ElapsedMilliseconds));
Task serverTask = Task.Run(async () =>
{
times?.Add((400, s.ElapsedMilliseconds));
try
{
times?.Add((401, s.ElapsedMilliseconds));
await serverFunc(server);
times?.Add((402, s.ElapsedMilliseconds));
}
catch
{
times?.Add((403, s.ElapsedMilliseconds));
throw;
}
times?.Add((404, s.ElapsedMilliseconds));
});
times?.Add((103, s.ElapsedMilliseconds));

await new Task[] { clientTask, serverTask }.WhenAllOrAnyFailed().ConfigureAwait(false);
}, options: options).WaitAsync(TimeSpan.FromMilliseconds(millisecondsTimeout));
times?.Add((104, s.ElapsedMilliseconds));
}, options: options, times: times, s: s).WaitAsync(TimeSpan.FromMilliseconds(millisecondsTimeout));
times?.Add((200, s.ElapsedMilliseconds));
return server;
}
}

Expand Down
22 changes: 20 additions & 2 deletions src/libraries/Common/tests/System/Net/Http/Http2LoopbackServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net.Security;
using System.Net.Sockets;
Expand Down Expand Up @@ -222,12 +223,29 @@ private static Http2Options CreateOptions(GenericLoopbackOptions options)
return http2Options;
}

public override async Task CreateServerAsync(Func<GenericLoopbackServer, Uri, Task> funcAsync, int millisecondsTimeout = 60_000, GenericLoopbackOptions options = null)
public override async Task CreateServerAsync(Func<GenericLoopbackServer, Uri, Task> funcAsync, int millisecondsTimeout = 60_000, GenericLoopbackOptions options = null, List<(int, long)> times = null, Stopwatch s = null)
{
using (var server = CreateServer(options))
times?.Add((500, s.ElapsedMilliseconds));
var server = CreateServer(options);
times?.Add((501, s.ElapsedMilliseconds));
try
{
times?.Add((502, s.ElapsedMilliseconds));
await funcAsync(server, server.Address).WaitAsync(TimeSpan.FromMilliseconds(millisecondsTimeout));
times?.Add((503, s.ElapsedMilliseconds));
}
catch
{
times?.Add((504, s.ElapsedMilliseconds));
throw;
}
finally
{
times?.Add((505, s.ElapsedMilliseconds));
server.Dispose();
times?.Add((506, s.ElapsedMilliseconds));
}
times?.Add((507, s.ElapsedMilliseconds));
}

public override Version Version => HttpVersion20.Value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public override GenericLoopbackServer CreateServer(GenericLoopbackOptions option
return new Http3LoopbackServer(_quicImplementationProvider, CreateOptions(options));
}

public override async Task CreateServerAsync(Func<GenericLoopbackServer, Uri, Task> funcAsync, int millisecondsTimeout = 60000, GenericLoopbackOptions options = null)
public override async Task CreateServerAsync(Func<GenericLoopbackServer, Uri, Task> funcAsync, int millisecondsTimeout = 60000, GenericLoopbackOptions options = null, List<(int, long)> times = null, Stopwatch s = null)
{
using GenericLoopbackServer server = CreateServer(options);
await funcAsync(server, server.Address).WaitAsync(TimeSpan.FromMilliseconds(millisecondsTimeout));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net.Security;
using System.Net.Sockets;
Expand Down Expand Up @@ -206,7 +207,7 @@ private static HttpAgnosticOptions CreateOptions(GenericLoopbackOptions options)
return httpOptions;
}

public override async Task CreateServerAsync(Func<GenericLoopbackServer, Uri, Task> funcAsync, int millisecondsTimeout = 60_000, GenericLoopbackOptions options = null)
public override async Task CreateServerAsync(Func<GenericLoopbackServer, Uri, Task> funcAsync, int millisecondsTimeout = 60_000, GenericLoopbackOptions options = null, List<(int, long)> times = null, Stopwatch s = null)
{
using (var server = CreateServer(options))
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Sockets;
using System.Net.Test.Common;
Expand Down Expand Up @@ -153,9 +155,82 @@ public async Task HttpClientHandler_MultipleAuthenticateHeaders_Succeeds(string
var options = new LoopbackServer.Options { Domain = Domain, Username = Username, Password = Password };
await LoopbackServer.CreateServerAsync(async (server, url) =>
{
HttpClientHandler handler = CreateHttpClientHandler();
Task serverTask = server.AcceptConnectionPerformAuthenticationAndCloseAsync(authenticateHeader);
await TestHelper.WhenAllCompletedOrAnyFailed(CreateAndValidateRequest(handler, url, HttpStatusCode.OK, s_credentials), serverTask);
Stopwatch s = Stopwatch.StartNew();
ConcurrentQueue<(string, long)> list = new ConcurrentQueue<(string, long)>();
try
{
HttpClientHandler handler = CreateHttpClientHandler();

Task serverTask = Task.Run(async () =>
{
list.Enqueue(("ServerStart", s.ElapsedMilliseconds));
try
{
await server.AcceptConnectionPerformAuthenticationAndCloseAsync(authenticateHeader);
list.Enqueue(("ServerStop", s.ElapsedMilliseconds));
}
catch
{
list.Enqueue(("ServerException", s.ElapsedMilliseconds));
throw;
}
finally
{
list.Enqueue(("ServerExit", s.ElapsedMilliseconds));
}
});

Task clientTask = Task.Run(async () =>
{
list.Enqueue(("ClientStart", s.ElapsedMilliseconds));
try
{
handler.Credentials = s_credentials;

HttpClient client = CreateHttpClient(handler);
list.Enqueue(("CreateHttpClient", s.ElapsedMilliseconds));
try
{
list.Enqueue(("BeforeGetAsync", s.ElapsedMilliseconds));
HttpResponseMessage response = await client.GetAsync(url);
list.Enqueue(("AfterGetAsync", s.ElapsedMilliseconds));
try
{
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}
finally
{
list.Enqueue(("GetAsyncFinally1", s.ElapsedMilliseconds));
response.Dispose();
list.Enqueue(("GetAsyncFinally2", s.ElapsedMilliseconds));
}
}
finally
{
list.Enqueue(("CreateHttpClientFinally1", s.ElapsedMilliseconds));
client.Dispose();
list.Enqueue(("CreateHttpClientFinally2", s.ElapsedMilliseconds));
}

list.Enqueue(("ClientStop", s.ElapsedMilliseconds));
}
catch
{
list.Enqueue(("ClientException", s.ElapsedMilliseconds));
throw;
}
finally
{
list.Enqueue(("ClientExit", s.ElapsedMilliseconds));
}
});

await TestHelper.WhenAllCompletedOrAnyFailed(clientTask, serverTask);
}
catch (Exception ex)
{
throw new Exception(string.Join('\n', list.Select(l => $"{l.Item1,20} {l.Item2}")), ex);
}
}, options);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,34 +151,72 @@ await LoopbackServerFactory.CreateClientAndServerAsync(
[Fact]
public async Task GetAsync_AddMultipleCookieHeaders_CookiesSent()
{
await LoopbackServerFactory.CreateClientAndServerAsync(
async uri =>
{
using (HttpClient client = CreateHttpClient())
List<(int, long)> times = new List<(int, long)>();
Stopwatch s = Stopwatch.StartNew();

try
{
times.Add((0, s.ElapsedMilliseconds));

await LoopbackServerFactory.CreateClientAndServerAsync(
async uri =>
{
var requestMessage = new HttpRequestMessage(HttpMethod.Get, uri) { Version = UseVersion };
requestMessage.Headers.Add("Cookie", "A=1");
requestMessage.Headers.Add("Cookie", "B=2");
requestMessage.Headers.Add("Cookie", "C=3");
times.Add((10, s.ElapsedMilliseconds));
HttpClient client = CreateHttpClient();
times.Add((11, s.ElapsedMilliseconds));
try
{
var requestMessage = new HttpRequestMessage(HttpMethod.Get, uri) { Version = UseVersion };
requestMessage.Headers.Add("Cookie", "A=1");
requestMessage.Headers.Add("Cookie", "B=2");
requestMessage.Headers.Add("Cookie", "C=3");
times.Add((12, s.ElapsedMilliseconds));

await client.SendAsync(TestAsync, requestMessage);
}
},
async server =>
{
HttpRequestData requestData = await server.HandleRequestAsync();
await client.SendAsync(TestAsync, requestMessage)
.WaitAsync(TimeSpan.FromSeconds(10));

times.Add((13, s.ElapsedMilliseconds));
}
catch
{
times.Add((14, s.ElapsedMilliseconds));
throw;
}
finally
{
times.Add((15, s.ElapsedMilliseconds));
client.Dispose();
}
},
async server =>
{
times.Add((20, s.ElapsedMilliseconds));

HttpRequestData requestData = await server.HandleRequestAsync()
.WaitAsync(TimeSpan.FromSeconds(15));

times.Add((21, s.ElapsedMilliseconds));

// Multiple Cookie header values are treated as any other header values and are
// concatenated using ", " as the separator.

string cookieHeaderValue = requestData.GetSingleHeaderValue("Cookie");

var cookieValues = cookieHeaderValue.Split(new string[] { ", " }, StringSplitOptions.None);
Assert.Contains("A=1", cookieValues);
Assert.Contains("B=2", cookieValues);
Assert.Contains("C=3", cookieValues);
Assert.Equal(3, cookieValues.Count());
});
var cookieValues = cookieHeaderValue.Split(new string[] { ", " }, StringSplitOptions.None);
Assert.Contains("A=1", cookieValues);
Assert.Contains("B=2", cookieValues);
Assert.Contains("C=3", cookieValues);
Assert.Equal(3, cookieValues.Count());

times.Add((22, s.ElapsedMilliseconds));
},
millisecondsTimeout: 300_000);
}
catch (Exception ex)
{
times.Add((1, s.ElapsedMilliseconds));
throw new Exception(string.Join('\n', times.Select(t => $"{t.Item1,2} {t.Item2}")), ex);
}
}

private string GetCookieValue(HttpRequestData request)
Expand Down
3 changes: 2 additions & 1 deletion src/libraries/Common/tests/System/Net/Http/LoopbackServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using System.Threading.Tasks;
using System.Net.WebSockets;
using Xunit;
using System.Diagnostics;

namespace System.Net.Test.Common
{
Expand Down Expand Up @@ -1086,7 +1087,7 @@ public override GenericLoopbackServer CreateServer(GenericLoopbackOptions option
return loopbackServer;
}

public override Task CreateServerAsync(Func<GenericLoopbackServer, Uri, Task> funcAsync, int millisecondsTimeout = 60_000, GenericLoopbackOptions options = null)
public override Task CreateServerAsync(Func<GenericLoopbackServer, Uri, Task> funcAsync, int millisecondsTimeout = 60_000, GenericLoopbackOptions options = null, List<(int, long)> times = null, Stopwatch s = null)
{
return LoopbackServer.CreateServerAsync((server, uri) => funcAsync(server, uri), options: CreateOptions(options));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public static async Task WhenAllOrAnyFailed(this Task[] tasks)
// in the error we throw.
try
{
await Task.WhenAll(tasks).WaitAsync(TimeSpan.FromSeconds(3)); // arbitrary delay; can be dialed up or down in the future
await Task.WhenAll(tasks).WaitAsync(TimeSpan.FromSeconds(20)); // arbitrary delay; can be dialed up or down in the future
}
catch { }

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<linker>
<assembly fullname="System.Net.Http">
<type fullname="System.Net.Http.DiagnosticsHandler">
<method signature="System.Boolean IsGloballyEnabled()" body="stub" value="false" feature="System.Net.Http.EnableActivityPropagation" featurevalue="false" />
<method signature="System.Boolean get_IsGloballyEnabled()" body="stub" value="false" feature="System.Net.Http.EnableActivityPropagation" featurevalue="false" />
</type>
<type fullname="System.Net.Http.HttpClient">
<method signature="System.Boolean IsNativeHandlerEnabled()" body="stub" value="true" feature="System.Net.Http.UseNativeHttpHandler" featurevalue="true" />
Expand Down
1 change: 0 additions & 1 deletion src/libraries/System.Net.Http/src/System.Net.Http.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,6 @@
<!-- Common -->
<ItemGroup>
<Compile Include="System\Net\Http\DiagnosticsHandler.cs" />
<Compile Include="System\Net\Http\DiagnosticsHandlerLoggingStrings.cs" />
<Compile Include="System\Net\Http\GlobalHttpSettings.cs" />
<Compile Include="System\Net\Http\SocketsHttpHandler\SocketsHttpPlaintextStreamFilterContext.cs" />
<Compile Include="$(CommonPath)System\Threading\Tasks\TaskCompletionSourceWithCancellation.cs"
Expand Down
Loading