Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
17ddbce
init
Jul 21, 2020
2afc76f
Http2 ping
Aug 3, 2020
c590b7c
Merge remote-tracking branch 'upstream/master' into jajahoda/httpping
Aug 3, 2020
eb37332
clean up
Aug 3, 2020
712479f
enable tests
Aug 3, 2020
95bc2f3
Fix mac build
Aug 3, 2020
de89629
Merge branch 'master' of github.com:dotnet/runtime into jajahoda/http…
Aug 3, 2020
b3e4b3d
Split HttpHandlerDefaults
Aug 4, 2020
e06f092
Merge branch 'master' of github.com:dotnet/runtime into jajahoda/http…
Aug 4, 2020
6e2f371
Merge remote-tracking branch 'origin/jajahoda/httpping' into jajahoda…
Aug 4, 2020
b7ed6ce
Fix mac build
Aug 4, 2020
20f44cf
Fix browser and test csproj
Aug 4, 2020
b684730
Apply PR comments
Aug 5, 2020
014c8d6
Merge remote-tracking branch 'upstream/master' into jajahoda/httpping
Aug 5, 2020
60a757d
Remove Http2KeepAlice class
Aug 5, 2020
886a2da
fix trace message
Aug 5, 2020
863f636
ProcessPingAck no longer return bool
Aug 5, 2020
a987919
Apply suggestions from code review
aik-jahoda Aug 6, 2020
b221f43
Add argument out of ramnge message
Aug 6, 2020
be468cd
Merge branch 'jajahoda/httpping' of github.com:aik-jahoda/runtime int…
Aug 6, 2020
db89b58
Apply PR comments
Aug 6, 2020
02785d6
SocketsHttpHandler setters
Aug 6, 2020
d354a29
Merge remote-tracking branch 'upstream/master' into jajahoda/httpping
Aug 7, 2020
b83cfc3
Update src/libraries/Common/tests/System/Net/Http/Http2LoopbackConnec…
aik-jahoda Aug 7, 2020
63e3d3f
Update src/libraries/System.Net.Http/src/Resources/Strings.resx
aik-jahoda Aug 7, 2020
258f1c4
Apply suggestions from code review
aik-jahoda Aug 7, 2020
2695f2e
PR comments
Aug 7, 2020
0ea45e8
Merge branch 'master' into jajahoda/httpping
ManickaP Aug 11, 2020
7078d8e
Addressed the last batch of PR feedback.
ManickaP Aug 11, 2020
9c1b6e7
Merge branch 'master' into jajahoda/httpping
ManickaP Aug 12, 2020
86c8413
Fixed KeepAlive test dependency on frame chronology.
ManickaP Aug 12, 2020
c10beb9
Fixed FW compilation.
ManickaP Aug 12, 2020
b9c6b33
Split and moved tests to theirs proper places.
ManickaP Aug 12, 2020
40e0e5c
More test fixing for super slow CI.
ManickaP Aug 12, 2020
3a753b7
Exception texts.
ManickaP Aug 13, 2020
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
Prev Previous commit
Next Next commit
Fixed KeepAlive test dependency on frame chronology.
On slower platforms, PINGs were coming sooner than requests themselves causing errors while reading the request and receiving PING frame instead of HEADERS frame.
  • Loading branch information
ManickaP committed Aug 12, 2020
commit 86c8413a826208793320a861ea858e329b4d9abf
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public class Http2LoopbackConnection : GenericLoopbackConnection
private Stream _connectionStream;
private TaskCompletionSource<bool> _ignoredSettingsAckPromise;
private bool _ignoreWindowUpdates;
private TaskCompletionSource<PingFrame> _expectPingFrame;
private readonly TimeSpan _timeout;
private int _lastStreamId;

Expand Down Expand Up @@ -186,6 +187,13 @@ private async Task<Frame> ReadFrameAsync(CancellationToken cancellationToken)
return await ReadFrameAsync(cancellationToken).ConfigureAwait(false);
}

if (_expectPingFrame != null && header.Type == FrameType.Ping)
{
_expectPingFrame.SetResult(PingFrame.ReadFrom(header, data));
_expectPingFrame = null;
return await ReadFrameAsync(cancellationToken).ConfigureAwait(false);
}

// Construct the correct frame type and return it.
switch (header.Type)
{
Expand Down Expand Up @@ -245,6 +253,15 @@ public void IgnoreWindowUpdates()
_ignoreWindowUpdates = true;
}

// Set up loopback server to expect PING frames among other frames.
// Once PING frame is read in ReadFrameAsync, the returned task is completed.
// The returned task is canceled in ReadPingAsync if no PING frame has been read so far.
public Task<PingFrame> ExpectPingFrameAsync()
{
_expectPingFrame ??= new TaskCompletionSource<PingFrame>();
return _expectPingFrame.Task;
}

public async Task ReadRstStreamAsync(int streamId)
{
Frame frame = await ReadFrameAsync(_timeout);
Expand Down Expand Up @@ -677,6 +694,9 @@ public async Task PingPong()

public async Task<PingFrame> ReadPingAsync(TimeSpan timeout)
{
_expectPingFrame?.TrySetCanceled();
_expectPingFrame = null;

Frame frame = await ReadFrameAsync(timeout).ConfigureAwait(false);
Assert.NotNull(frame);
Assert.Equal(FrameType.Ping, frame.Type);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,26 +307,31 @@ public void SettersExceptions()

public static IEnumerable<object[]> KeepAliveTestDataSource()
{
yield return new object[] { Timeout.InfiniteTimeSpan, TimeSpan.FromSeconds(0), HttpKeepAlivePingPolicy.Always, false, false, false };
yield return new object[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(0), HttpKeepAlivePingPolicy.WithActiveRequests, true, false, false };
yield return new object[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(0), HttpKeepAlivePingPolicy.Always, true, true, false };
yield return new object[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(5), HttpKeepAlivePingPolicy.WithActiveRequests, true, true, true };
yield return new object[] { Timeout.InfiniteTimeSpan, HttpKeepAlivePingPolicy.Always, false };
yield return new object[] { TimeSpan.FromSeconds(1), HttpKeepAlivePingPolicy.WithActiveRequests, false };
yield return new object[] { TimeSpan.FromSeconds(1), HttpKeepAlivePingPolicy.Always, false };
yield return new object[] { TimeSpan.FromSeconds(1), HttpKeepAlivePingPolicy.WithActiveRequests, true };
}

[OuterLoop("Significant delay.")]
[Theory]
[MemberData(nameof(KeepAliveTestDataSource))]
public async Task KeepAlive(TimeSpan keepAlivePingDelay, TimeSpan pongDelay, HttpKeepAlivePingPolicy keepAlivePingPolicy, bool expectStreamPing,
bool expectPingWithoutStream, bool expectRequestFail)
public async Task KeepAlive(TimeSpan keepAlivePingDelay, HttpKeepAlivePingPolicy keepAlivePingPolicy, bool expectRequestFail)
{
var pingTimeout = keepAlivePingDelay.Add(TimeSpan.FromSeconds(4));
TimeSpan pingTimeout = TimeSpan.FromSeconds(5);
// Simulate failure by delaying the pong, otherwise send it immediately.
TimeSpan pongDelay = expectRequestFail ? pingTimeout * 2 : TimeSpan.Zero;
// Pings are send only if KeepAlivePingDelay is not infinite.
bool expectStreamPing = keepAlivePingDelay != Timeout.InfiniteTimeSpan;
// Pings (regardless ongoing communication) are send only if sending is on and policy is set to always.
bool expectPingWithoutStream = expectStreamPing && keepAlivePingPolicy == HttpKeepAlivePingPolicy.Always;

await Http2LoopbackServer.CreateClientAndServerAsync(
async uri =>
{
SocketsHttpHandler handler = new SocketsHttpHandler()
{
KeepAlivePingTimeout = TimeSpan.FromSeconds(1),
KeepAlivePingTimeout = pingTimeout,
KeepAlivePingPolicy = keepAlivePingPolicy,
KeepAlivePingDelay = keepAlivePingDelay
};
Expand All @@ -339,16 +344,23 @@ await Http2LoopbackServer.CreateClientAndServerAsync(
await client.GetStringAsync(uri);
// Request under the test scope.
if (expectRequestFail)
{
await Assert.ThrowsAsync<HttpRequestException>(() => client.GetStringAsync(uri));
}
else
{
await client.GetStringAsync(uri);
}

// Let connection live for a while.
await Task.Delay(pingTimeout);
},
async server =>
{
using Http2LoopbackConnection connection = await server.EstablishConnectionAsync();

Task<PingFrame> receivePingTask = expectStreamPing ? connection.ExpectPingFrameAsync() : null;

// Warmup the connection.
int streamId1 = await connection.ReadRequestHeaderAsync();
await connection.SendDefaultResponseAsync(streamId1);
Expand All @@ -363,7 +375,15 @@ await Http2LoopbackServer.CreateClientAndServerAsync(
}
else
{
PingFrame ping = await connection.ReadPingAsync(pingTimeout);
PingFrame ping;
if (receivePingTask != null && receivePingTask.IsCompleted)
{
ping = await receivePingTask;
}
else
{
ping = await connection.ReadPingAsync(pingTimeout);
}
await Task.Delay(pongDelay);

await connection.SendPingAckAsync(ping.Data);
Expand All @@ -372,7 +392,7 @@ await Http2LoopbackServer.CreateClientAndServerAsync(
// Send response and close the stream.
if (expectRequestFail)
{
await Assert.ThrowsAsync<IOException>(() => connection.SendDefaultResponseAsync(streamId2));
await Assert.ThrowsAsync<NetworkException>(() => connection.SendDefaultResponseAsync(streamId2));
// As stream is closed we don't want to continue with sending data.
return;
}
Expand Down