Skip to content
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

Unify QuicTestBase and add test repros for flaky under-stress failures #52050

Merged
merged 1 commit into from
May 4, 2021
Merged
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

This file was deleted.

91 changes: 85 additions & 6 deletions src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,9 @@

namespace System.Net.Quic.Tests
{
[ConditionalClass(typeof(MsQuicTests), nameof(IsMsQuicSupported))]
public class MsQuicTests : MsQuicTestBase
[ConditionalClass(typeof(QuicTestBase<MsQuicProviderFactory>), nameof(IsSupported))]
public class MsQuicTests : QuicTestBase<MsQuicProviderFactory>
{
public static bool IsMsQuicSupported => QuicImplementationProviders.MsQuic.IsSupported;

private static ReadOnlyMemory<byte> s_data = Encoding.UTF8.GetBytes("Hello world!");

[Fact]
Expand Down Expand Up @@ -80,7 +78,7 @@ public async Task SetListenerTimeoutWorksWithSmallTimeout()
await Assert.ThrowsAsync<QuicOperationAbortedException>(async () => await serverConnection.AcceptStreamAsync().AsTask().WaitAsync(TimeSpan.FromSeconds(100)));
}

[ActiveIssue("https://github.com/dotnet/runtime/issues/49157")]
[ActiveIssue("https://github.com/dotnet/runtime/issues/52047")]
[Theory]
[MemberData(nameof(WriteData))]
public async Task WriteTests(int[][] writes, WriteType writeType)
Expand Down Expand Up @@ -172,7 +170,6 @@ public enum WriteType
GatheredSequence
}

// will induce failure (byte mixing) in QuicStreamTests_MsQuicProvider.LargeDataSentAndReceived if run in parallel with it
[Fact]
public async Task CallDifferentWriteMethodsWorks()
{
Expand Down Expand Up @@ -296,5 +293,87 @@ public BufferSegment Append(ReadOnlyMemory<byte> memory)
return segment;
}
}

[ActiveIssue("https://github.com/dotnet/runtime/issues/52047")]
[Fact]
public async Task ByteMixingOrNativeAVE_MinimalFailingTest()
{
const int writeSize = 64 * 1024;
const int NumberOfWrites = 512;
byte[] data1 = new byte[writeSize * NumberOfWrites];
byte[] data2 = new byte[writeSize * NumberOfWrites];
Array.Fill(data1, (byte)1);
Array.Fill(data2, (byte)2);

Task t1 = RunTest(data1);
Task t2 = RunTest(data2);

async Task RunTest(byte[] data)
{
await RunClientServer(
iterations: 20,
serverFunction: async connection =>
{
await using QuicStream stream = await connection.AcceptStreamAsync();

byte[] buffer = new byte[data.Length];
int bytesRead = await ReadAll(stream, buffer);
Assert.Equal(data.Length, bytesRead);
AssertArrayEqual(data, buffer);

for (int pos = 0; pos < data.Length; pos += writeSize)
{
await stream.WriteAsync(data[pos..(pos + writeSize)]);
}
await stream.WriteAsync(Memory<byte>.Empty, endStream: true);

await stream.ShutdownCompleted();
},
clientFunction: async connection =>
{
await using QuicStream stream = connection.OpenBidirectionalStream();

for (int pos = 0; pos < data.Length; pos += writeSize)
{
await stream.WriteAsync(data[pos..(pos + writeSize)]);
}
await stream.WriteAsync(Memory<byte>.Empty, endStream: true);

byte[] buffer = new byte[data.Length];
int bytesRead = await ReadAll(stream, buffer);
Assert.Equal(data.Length, bytesRead);
AssertArrayEqual(data, buffer);

await stream.ShutdownCompleted();
}
);
}

await (new[] { t1, t2 }).WhenAllOrAnyFailed(millisecondsTimeout: 1000000);
}

[ActiveIssue("https://github.com/dotnet/runtime/issues/52048")]
[Fact]
public async Task ManagedAVE_MinimalFailingTest()
{
async Task GetStreamIdWithoutStartWorks()
{
using QuicListener listener = CreateQuicListener();
using QuicConnection clientConnection = CreateQuicConnection(listener.ListenEndPoint);

ValueTask clientTask = clientConnection.ConnectAsync();
using QuicConnection serverConnection = await listener.AcceptConnectionAsync();
await clientTask;

using QuicStream clientStream = clientConnection.OpenBidirectionalStream();
Assert.Equal(0, clientStream.StreamId);

// TODO: stream that is opened by client but left unaccepted by server may cause AccessViolationException in its Finalizer
}

await GetStreamIdWithoutStartWorks();

GC.Collect();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ public async Task GetStreamIdWithoutStartWorks()
await clientConnection.CloseAsync(0);
}

[ActiveIssue("https://github.com/dotnet/runtime/issues/49157")]
[ActiveIssue("https://github.com/dotnet/runtime/issues/52047")]
[Fact]
public async Task LargeDataSentAndReceived()
{
Expand Down Expand Up @@ -348,7 +348,7 @@ private static async Task SendAndReceiveEOFAsync(QuicStream s1, QuicStream s2)
Assert.Equal(0, bytesRead);
}

[ActiveIssue("https://github.com/dotnet/runtime/issues/49157")]
[ActiveIssue("https://github.com/dotnet/runtime/issues/52047")]
[Theory]
[MemberData(nameof(ReadWrite_Random_Success_Data))]
public async Task ReadWrite_Random_Success(int readSize, int writeSize)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Generic;
using System.Net.Quic.Implementations;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Net.Quic.Implementations;
using Xunit;
using System.Threading;
using System.Text;

namespace System.Net.Quic.Tests
{
Expand All @@ -21,12 +22,20 @@ public abstract class QuicTestBase<T>

public static SslApplicationProtocol ApplicationProtocol { get; } = new SslApplicationProtocol("quictest");

public X509Certificate2 ServerCertificate = System.Net.Test.Common.Configuration.Certificates.GetServerCertificate();

public bool RemoteCertificateValidationCallback(object sender, X509Certificate? certificate, X509Chain? chain, SslPolicyErrors sslPolicyErrors)
{
Assert.Equal(ServerCertificate.GetCertHash(), certificate?.GetCertHash());
return true;
}

public SslServerAuthenticationOptions GetSslServerAuthenticationOptions()
{
return new SslServerAuthenticationOptions()
{
ApplicationProtocols = new List<SslApplicationProtocol>() { ApplicationProtocol },
ServerCertificate = System.Net.Test.Common.Configuration.Certificates.GetServerCertificate()
ServerCertificate = ServerCertificate
};
}

Expand All @@ -35,7 +44,7 @@ public SslClientAuthenticationOptions GetSslClientAuthenticationOptions()
return new SslClientAuthenticationOptions()
{
ApplicationProtocols = new List<SslApplicationProtocol>() { ApplicationProtocol },
RemoteCertificateValidationCallback = (sender, certificate, chain, errors) => { return true; }
RemoteCertificateValidationCallback = RemoteCertificateValidationCallback
};
}

Expand Down