Skip to content

CI test #92354

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 7 commits into from
Closed

CI test #92354

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
10 changes: 0 additions & 10 deletions eng/test-configuration.json

This file was deleted.

4 changes: 2 additions & 2 deletions src/libraries/Common/tests/System/Net/Http/DribbleStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ public override async Task WriteAsync(byte[] buffer, int offset, int count, Canc
{
for (int i = 0; i < count; i++)
{
await _wrapped.WriteAsync(buffer, offset + i, 1);
await _wrapped.FlushAsync();
await _wrapped.WriteAsync(buffer, offset + i, 1, cancellationToken);
await _wrapped.FlushAsync(cancellationToken);
await Task.Yield(); // introduce short delays, enough to send packets individually but not so long as to extend test duration significantly
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ await LoopbackServer.CreateServerAsync(async (origServer, origUrl) =>
{
await LoopbackServer.CreateServerAsync(async (redirectServer, redirectUrl) =>
{
Task<HttpResponseMessage> getResponseTask = client.GetAsync(origUrl);
Task<HttpResponseMessage> getResponseTask = client.GetAsync(TestAsync, origUrl);

Task redirectTask = redirectServer.AcceptConnectionSendResponseAndCloseAsync();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Generic;
#if !NETCOREAPP
using System.Diagnostics;
#endif
using System.IO;
using System.Net.Test.Common;
using System.Threading;
using System.Threading.Tasks;
using Xunit.Abstractions;
Expand All @@ -28,9 +27,14 @@ public abstract partial class HttpClientHandlerTestBase : FileCleanupTestBase

public HttpClientHandlerTestBase(ITestOutputHelper output)
{
_output = output;
if (output is not null)
{
_output = new TestOutputWithTimestampHelper(output);
}
}

public void EnableDebugLogs() => HttpDebug.DebugThisTest(_output);

protected virtual HttpClient CreateHttpClient() => CreateHttpClient(CreateHttpClientHandler());

protected HttpClient CreateHttpClient(HttpMessageHandler handler) =>
Expand Down Expand Up @@ -126,6 +130,25 @@ protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage
return response;
}
}

private sealed class TestOutputWithTimestampHelper(ITestOutputHelper output) : ITestOutputHelper
{
private readonly Stopwatch _stopwatch = Stopwatch.StartNew();

private string TimestampPrefix
{
get
{
TimeSpan elapsed = _stopwatch.Elapsed;

return $"[{(int)elapsed.TotalSeconds}.{elapsed.Milliseconds:D4}]";
}
}

public void WriteLine(string message) => output.WriteLine($"{TimestampPrefix} {message}");

public void WriteLine(string format, params object[] args) => output.WriteLine($"{TimestampPrefix} {format}", args);
}
}

public static class HttpClientExtensions
Expand Down Expand Up @@ -238,5 +261,10 @@ public static Task<byte[]> GetByteArrayAsync(this HttpClient client, bool async,
return client.GetByteArrayAsync(uri);
#endif
}

public static Task<HttpResponseMessage> GetAsync(this HttpClient client, bool async, Uri uri, HttpCompletionOption completionOption = default, CancellationToken cancellationToken = default)
{
return SendAsync(client, async, new HttpRequestMessage(HttpMethod.Get, uri), completionOption, cancellationToken);
}
}
}
47 changes: 47 additions & 0 deletions src/libraries/Common/tests/System/Net/Http/HttpDebug.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Runtime.CompilerServices;
using System.Threading;
using TestUtilities;
using Xunit.Abstractions;

namespace System.Net.Test.Common
{
public static class HttpDebug
{
private sealed class State(ITestOutputHelper output)
{
private int _logCounter;

public void WriteLine(string message)
{
// Avoid overwhelming the logs on noisy tests
if (Interlocked.Increment(ref _logCounter) < 10_000)
{
output.WriteLine(message);
}
}
}

private static readonly Lazy<TestEventListener> s_eventListener = new(
() => new TestEventListener(WriteLine, TestEventListener.NetworkingEvents),
LazyThreadSafetyMode.ExecutionAndPublication);

private static readonly AsyncLocal<State?> s_scope = new();

private static State? Scope => s_scope.Value;

public static void DebugThisTest(ITestOutputHelper output)
{
s_scope.Value = new State(output);
_ = s_eventListener.Value;
}

public static void WriteLine(string message) =>
Scope?.WriteLine(message);

public static void Log(string message, [CallerMemberName] string? memberName = null, [CallerLineNumber] int lineNumber = 0) =>
Scope?.WriteLine($"[{memberName} #{lineNumber}] {message}");
}
}
117 changes: 100 additions & 17 deletions src/libraries/Common/tests/System/Net/Http/HttpProtocolTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,8 @@ await LoopbackServer.CreateServerAsync(async (server, url) =>
{
using (HttpClient client = CreateHttpClient())
{
Task<HttpResponseMessage> getResponseTask = client.GetAsync(url);
Task<HttpResponseMessage> getResponseTask = client.GetAsync(TestAsync, url);

await TestHelper.WhenAllCompletedOrAnyFailed(
getResponseTask,
server.AcceptConnectionSendCustomResponseAndCloseAsync(
Expand Down Expand Up @@ -356,34 +357,116 @@ await LoopbackServer.CreateServerAsync(async (server, url) =>
Task ignoredServerTask = server.AcceptConnectionSendCustomResponseAndCloseAsync(
responseString + "\r\nConnection: close\r\nContent-Length: 0\r\n\r\n");

await Assert.ThrowsAsync<HttpRequestException>(() => client.GetAsync(url));
await Assert.ThrowsAsync<HttpRequestException>(() => client.GetAsync(TestAsync, url));
}
}, new LoopbackServer.Options { StreamWrapper = GetStream });
}

[Theory]
[InlineData("\r\n")]
[InlineData("\n")]
public async Task GetAsync_ResponseHasNormalLineEndings_Success_1(string lineEnding)
{
for (int i = 0; i < 10; i++) await GetAsync_ResponseHasNormalLineEndings_Success(lineEnding);
}

[Theory]
[InlineData("\r\n")]
[InlineData("\n")]
public async Task GetAsync_ResponseHasNormalLineEndings_Success_2(string lineEnding)
{
for (int i = 0; i < 10; i++) await GetAsync_ResponseHasNormalLineEndings_Success(lineEnding);
}

[Theory]
[InlineData("\r\n")]
[InlineData("\n")]
public async Task GetAsync_ResponseHasNormalLineEndings_Success_3(string lineEnding)
{
for (int i = 0; i < 10; i++) await GetAsync_ResponseHasNormalLineEndings_Success(lineEnding);
}

[Theory]
[InlineData("\r\n")]
[InlineData("\n")]
public async Task GetAsync_ResponseHasNormalLineEndings_Success_4(string lineEnding)
{
for (int i = 0; i < 10; i++) await GetAsync_ResponseHasNormalLineEndings_Success(lineEnding);
}

[Theory]
[InlineData("\r\n")]
[InlineData("\n")]
public async Task GetAsync_ResponseHasNormalLineEndings_Success_5(string lineEnding)
{
for (int i = 0; i < 10; i++) await GetAsync_ResponseHasNormalLineEndings_Success(lineEnding);
}

[Theory]
[InlineData("\r\n")]
[InlineData("\n")]
public async Task GetAsync_ResponseHasNormalLineEndings_Success_6(string lineEnding)
{
for (int i = 0; i < 10; i++) await GetAsync_ResponseHasNormalLineEndings_Success(lineEnding);
}

[Theory]
[InlineData("\r\n")]
[InlineData("\n")]
public async Task GetAsync_ResponseHasNormalLineEndings_Success_7(string lineEnding)
{
for (int i = 0; i < 10; i++) await GetAsync_ResponseHasNormalLineEndings_Success(lineEnding);
}

[Theory]
[InlineData("\r\n")]
[InlineData("\n")]
public async Task GetAsync_ResponseHasNormalLineEndings_Success_8(string lineEnding)
{
for (int i = 0; i < 10; i++) await GetAsync_ResponseHasNormalLineEndings_Success(lineEnding);
}

[Theory]
[InlineData("\r\n")]
[InlineData("\n")]
public async Task GetAsync_ResponseHasNormalLineEndings_Success_9(string lineEnding)
{
for (int i = 0; i < 10; i++) await GetAsync_ResponseHasNormalLineEndings_Success(lineEnding);
}

[Theory]
[InlineData("\r\n")]
[InlineData("\n")]
public async Task GetAsync_ResponseHasNormalLineEndings_Success_10(string lineEnding)
{
for (int i = 0; i < 10; i++) await GetAsync_ResponseHasNormalLineEndings_Success(lineEnding);
}

[Theory]
[InlineData("\r\n")]
[InlineData("\n")]
public async Task GetAsync_ResponseHasNormalLineEndings_Success(string lineEnding)
{
await LoopbackServer.CreateServerAsync(async (server, url) =>
EnableDebugLogs();

await LoopbackServer.CreateClientAndServerAsync(async url =>
{
using (HttpClient client = CreateHttpClient())
{
Task<HttpResponseMessage> getResponseTask = client.GetAsync(url);
Task<List<string>> serverTask = server.AcceptConnectionSendCustomResponseAndCloseAsync(
$"HTTP/1.1 200 OK{lineEnding}Connection: close\r\nDate: {DateTimeOffset.UtcNow:R}{lineEnding}Server: TestServer{lineEnding}Content-Length: 0{lineEnding}{lineEnding}");
using HttpClient client = CreateHttpClient();

await TestHelper.WhenAllCompletedOrAnyFailed(getResponseTask, serverTask);
using HttpResponseMessage response = await client.GetAsync(TestAsync, url)
.WaitAsync(TestHelper.PassingTestTimeout);

using (HttpResponseMessage response = await getResponseTask)
{
Assert.Equal(200, (int)response.StatusCode);
Assert.Equal("OK", response.ReasonPhrase);
Assert.Equal("TestServer", response.Headers.Server.ToString());
}
}
}, new LoopbackServer.Options { StreamWrapper = GetStream });
Assert.Equal(200, (int)response.StatusCode);
Assert.Equal("OK", response.ReasonPhrase);
Assert.Equal("TestServer", response.Headers.Server.ToString());
},
async server =>
{
await server.AcceptConnectionSendCustomResponseAndCloseAsync(
$"HTTP/1.1 200 OK{lineEnding}Connection: close{lineEnding}Date: {DateTimeOffset.UtcNow:R}{lineEnding}Server: TestServer{lineEnding}Content-Length: 0{lineEnding}{lineEnding}")
.WaitAsync(TestHelper.PassingTestTimeout);
},
new LoopbackServer.Options { StreamWrapper = GetStream });
}

public static IEnumerable<object[]> GetAsync_Chunked_VaryingSizeChunks_ReceivedCorrectly_MemberData()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ await LoopbackServer.CreateServerAsync(async (server, serverUrl) =>

using (HttpClient client = CreateHttpClient(handler))
{
Task<HttpResponseMessage> getResponseTask = client.GetAsync(uri);
Task<HttpResponseMessage> getResponseTask = client.GetAsync(TestAsync, uri);
Task<List<string>> serverTask = server.AcceptConnectionSendResponseAndCloseAsync();

await TestHelper.WhenAllCompletedOrAnyFailed(getResponseTask, serverTask);
Expand Down
25 changes: 18 additions & 7 deletions src/libraries/Common/tests/TestUtilities/TestEventListener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,18 +88,29 @@ protected override void OnEventSourceCreated(EventSource eventSource)

protected override void OnEventWritten(EventWrittenEventArgs eventData)
{
StringBuilder sb = new StringBuilder().
#if NETCOREAPP2_2_OR_GREATER || NETSTANDARD2_1_OR_GREATER
Append($"{eventData.TimeStamp:HH:mm:ss.fffffff}[{eventData.EventName}] ");
#else
Append($"[{eventData.EventName}] ");
#endif
string sourceName = eventData.EventSource.Name
.Replace("Private.InternalDiagnostics.System.Net.", "")
.Replace("System.Net.", "");

StringBuilder sb = new StringBuilder()
.Append($"[{sourceName}/{eventData.EventName}] ");

for (int i = 0; i < eventData.Payload?.Count; i++)
{
if (i > 0)
sb.Append(", ");
sb.Append(eventData.PayloadNames?[i]).Append(": ").Append(eventData.Payload[i]);

string? payloadName = eventData.PayloadNames?[i];
object payload = eventData.Payload[i];

if (payload is byte[] buffer)
{
payload = BitConverter.ToString(buffer).Replace("-", "");
}

sb.Append(payloadName).Append(": ").Append(payload);
}

try
{
_writeFunc(sb.ToString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@
Link="Common\System\Net\Http\Http2Frames.cs" />
<Compile Include="$(CommonTestPath)System\Net\Http\HPackEncoder.cs"
Link="Common\System\Net\Http\HPackEncoder.cs" />
<Compile Include="$(CommonTestPath)System\Net\Http\HttpDebug.cs"
Link="Common\System\Net\Http\HttpDebug.cs" />
<Compile Include="$(CommonTestPath)System\Net\Http\Http2LoopbackServer.cs"
Link="Common\System\Net\Http\Http2LoopbackServer.cs" />
<Compile Include="$(CommonTestPath)System\Net\Http\Http2LoopbackConnection.cs"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -719,7 +719,7 @@ protected override void Dispose(bool disposing)

protected Task<HttpResponseMessage> SendAsync(HttpMessageInvoker invoker, HttpRequestMessage request, CancellationToken cancellationToken = default) =>
TestHttpMessageInvoker ?
invoker.SendAsync(request, cancellationToken) :
(TestAsync ? invoker.SendAsync(request, cancellationToken) : Task.Run(() => invoker.Send(request, cancellationToken))) :
((HttpClient)invoker).SendAsync(TestAsync, request, cancellationToken);

protected HttpMessageInvoker CreateHttpMessageInvoker(HttpMessageHandler? handler = null) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@
Link="Common\System\Net\TestWebProxies.cs" />
<Compile Include="$(CommonTestPath)System\Net\VerboseTestLogging.cs"
Link="Common\System\Net\VerboseTestLogging.cs" />
<Compile Include="$(CommonTestPath)System\Net\Http\HttpDebug.cs"
Link="Common\System\Net\Http\HttpDebug.cs" />
<Compile Include="$(CommonTestPath)System\Net\Http\HttpAgnosticLoopbackServer.cs"
Link="Common\System\Net\Http\HttpAgnosticLoopbackServer.cs" />
<Compile Include="$(CommonTestPath)System\Net\Http\LoopbackProxyServer.cs"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
<Compile Include="$(CommonTestPath)System\Net\EventSourceTestLogging.cs" Link="Common\System\Net\EventSourceTestLogging.cs" />
<Compile Include="$(CommonTestPath)System\Net\Http\LoopbackProxyServer.cs" Link="Common\System\Net\Http\LoopbackProxyServer.cs" />
<Compile Include="$(CommonTestPath)System\Net\Http\LoopbackServer.cs" Link="Common\System\Net\Http\LoopbackServer.cs" />
<Compile Include="$(CommonTestPath)System\Net\Http\HttpDebug.cs" Link="Common\System\Net\Http\HttpDebug.cs" />
<Compile Include="$(CommonTestPath)System\Net\Http\Http2LoopbackServer.cs" Link="Common\System\Net\Http\Http2LoopbackServer.cs" />
<Compile Include="$(CommonTestPath)System\Net\Http\Http2LoopbackConnection.cs" Link="Common\System\Net\Http\Http2LoopbackConnection.cs" />
<Compile Include="$(CommonTestPath)System\Net\Http\Http2Frames.cs" Link="Common\System\Net\Http\Http2Frames.cs" />
Expand Down