Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Redisign HTTP/2 KeepAlive PING tests#56736

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from1 commit
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
PrevPrevious commit
NextNext commit
wip
  • Loading branch information
@antonfirsov
antonfirsov committedJul 30, 2021
commitd46695cba91d280a49a2db0df7a76e6b0a9091b8
Original file line numberDiff line numberDiff line change
Expand Up@@ -1206,7 +1206,7 @@ private Task SendSettingsAckAsync() =>
private Task SendPingAsync(long pingContent, bool isAck = false) =>
PerformWriteAsync(FrameHeader.Size + FrameHeader.PingLength, (thisRef: this, pingContent, isAck), static (state, writeBuffer) =>
{
if (NetEventSource.Log.IsEnabled()) state.thisRef.Trace("Started writing.");
if (NetEventSource.Log.IsEnabled()) state.thisRef.Trace($"Started writing. {nameof(pingContent)}={state.pingContent}");

Debug.Assert(sizeof(long) == FrameHeader.PingLength);

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -121,6 +121,7 @@ public HttpConnectionPoolManager(HttpConnectionSettings settings)

_heartBeatTimer = new Timer(static state =>
{
if (NetEventSource.Log.IsEnabled()) NetEventSource.Log.HandlerMessage(-1, -1, -1, "HeartBeatTimer", "HEARTBEAT!");
var wr = (WeakReference<HttpConnectionPoolManager>)state!;
if (wr.TryGetTarget(out HttpConnectionPoolManager? thisRef))
{
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics;
using System.IO;
using System.Diagnostics.Tracing;
using System.Linq;
using System.Net.Test.Common;
using System.Text;
using System.Threading;
using System.Threading.Channels;
using System.Threading.Tasks;
using Microsoft.DotNet.RemoteExecutor;
using Microsoft.VisualStudio.TestPlatform.Utilities;
using Xunit;
using Xunit.Abstractions;
using static System.Net.Test.Common.LoopbackServer;

namespace System.Net.Http.Functional.Tests
{
Expand All@@ -28,15 +27,20 @@ public sealed class SocketsHttpHandler_Http2KeepAlivePing_Test : HttpClientHandl

protected override Version UseVersion => HttpVersion20.Value;

private LogHttpEventListener _listener;

public SocketsHttpHandler_Http2KeepAlivePing_Test(ITestOutputHelper output) : base(output)
{
_listener = new LogHttpEventListener(output);
}

[Theory]
[InlineData(HttpKeepAlivePingPolicy.Always)]
[InlineData(HttpKeepAlivePingPolicy.WithActiveRequests)]
public async Task KeepAlivePingDelay_Infinite_NoKeepAlivePingIsSent(HttpKeepAlivePingPolicy policy)
{
_listener.Enabled = true;

TaskCompletionSource serverFinished = new TaskCompletionSource();
TimeSpan testTimeout = TimeSpan.FromSeconds(60);

Expand DownExpand Up@@ -102,10 +106,12 @@ await Http2LoopbackServer.CreateClientAndServerAsync(async uri =>
}

[Theory]
[InlineData(HttpKeepAlivePingPolicy.Always)]
//[InlineData(HttpKeepAlivePingPolicy.Always)]
[InlineData(HttpKeepAlivePingPolicy.WithActiveRequests)]
public async Task KeepAliveConfigured_KeepAlivePingsAreSentAccordingToPolicy(HttpKeepAlivePingPolicy policy)
{
_listener.Enabled = true;

TaskCompletionSource serverFinished = new TaskCompletionSource();
TimeSpan testTimeout = TimeSpan.FromSeconds(60);

Expand All@@ -123,10 +129,12 @@ await Http2LoopbackServer.CreateClientAndServerAsync(async uri =>
client.DefaultRequestVersion = HttpVersion.Version20;

// Warmup request to create connection:
await client.GetStringAsync(uri).WaitAsync(testTimeout);
HttpResponseMessage response0 = await client.GetAsync(uri).WaitAsync(testTimeout);
Assert.Equal(HttpStatusCode.OK, response0.StatusCode);

// Actual request:
await client.GetStringAsync(uri).WaitAsync(testTimeout);
HttpResponseMessage response1 = await client.GetAsync(uri).WaitAsync(testTimeout);
Assert.Equal(HttpStatusCode.OK, response1.StatusCode);

// Let connection live until server finishes:
await serverFinished.Task.WaitAsync(testTimeout);
Expand All@@ -152,6 +160,7 @@ await Http2LoopbackServer.CreateClientAndServerAsync(async uri =>

// Simulate inactive period:
await Task.Delay(10_000);
await EnsureDidNotReceiveUnexpectedFrames();

// We may receive one RTT PING because of HEADERS.
// We expect to receive at least one keep alive ping upon that:
Expand All@@ -161,20 +170,37 @@ await Http2LoopbackServer.CreateClientAndServerAsync(async uri =>
// Finish the response:
await connection.SendDefaultResponseAsync(streamId2);

// Simulate inactive period:
await Task.Delay(10_000);

if (policy == HttpKeepAlivePingPolicy.Always)
{
// Simulate inactive period:
await Task.Delay(10_000);
await EnsureDidNotReceiveUnexpectedFrames();

// We may receive one RTT PING because of HEADERS.
// We expect to receive at least one keep alive ping upon that:
Assert.True(pingCounter > 1);
}
else
{
// We can receive one more RTT PING because of DATA, but should receive no KeepAlive PINGs
Assert.True(pingCounter <= 1);
//Assert.True(pingCounter <= 1);
}

async Task EnsureDidNotReceiveUnexpectedFrames()
{
try
{
var frame = await connection.ReadFrameAsync(TimeSpan.FromSeconds(1));
if (frame != null)
{
throw new Exception("Got unexpected frame: " + frame);
}
}
catch (OperationCanceledException)
{
}
}


serverFinished.SetResult();
}).WaitAsync(testTimeout);
Expand DownExpand Up@@ -481,4 +507,85 @@ async Task ProcessIncomingFramesAsync(CancellationToken cancellationToken)
static void Wait(TimeSpan dt) { if (dt != TimeSpan.Zero) Thread.Sleep(dt); }
}
}

public sealed class LogHttpEventListener : EventListener
{
private Channel<string> _messagesChannel = Channel.CreateUnbounded<string>();
private Task _processMessages;
private CancellationTokenSource _stopProcessing;
private ITestOutputHelper _log;

public StringBuilder Log2 { get; }

public LogHttpEventListener(ITestOutputHelper log)
{
_log = log;
_messagesChannel = Channel.CreateUnbounded<string>();
_processMessages = ProcessMessagesAsync();
_stopProcessing = new CancellationTokenSource();
Log2 = new StringBuilder(1024 * 1024);
}

public bool Enabled { get; set; }
public Predicate<string> Filter { get; set; } = _ => true;

protected override void OnEventSourceCreated(EventSource eventSource)
{
if (eventSource.Name == "Private.InternalDiagnostics.System.Net.Http")
{
EnableEvents(eventSource, EventLevel.LogAlways);
}
}

private async Task ProcessMessagesAsync()
{
await Task.Yield();

try
{
await foreach (string message in _messagesChannel.Reader.ReadAllAsync(_stopProcessing.Token))
{
if (Filter(message))
{
_log.WriteLine(message);
Log2.AppendLine(message);
}
}
}
catch (OperationCanceledException)
{
return;
}
}

public ValueTask WriteAsync(string message) => _messagesChannel.Writer.WriteAsync(message);

protected override async void OnEventWritten(EventWrittenEventArgs eventData)
{
if (!Enabled) return;

var sb = new StringBuilder().Append($"{eventData.TimeStamp:HH:mm:ss.fffffff}[{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]);
}
await _messagesChannel.Writer.WriteAsync(sb.ToString());
}

public override void Dispose()
{
base.Dispose();
var timeout = TimeSpan.FromSeconds(2);

if (!_processMessages.Wait(timeout))
{
_stopProcessing.Cancel();
_processMessages.Wait(timeout);
}
}
}
}

[8]ページ先頭

©2009-2025 Movatter.jp