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

[QUIC] Added tests to check IsSupported. #81481

Merged
merged 6 commits into from
Feb 10, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public static partial class PlatformDetection
public static bool IsUbuntu => IsDistroAndVersion("ubuntu");
public static bool IsDebian => IsDistroAndVersion("debian");
public static bool IsAlpine => IsDistroAndVersion("alpine");
public static bool IsAlpine313 => IsDistroAndVersion("alpine", 3, 13);
public static bool IsAlpine314 => IsDistroAndVersion("alpine", 3, 14);
public static bool IsDebian8 => IsDistroAndVersion("debian", 8);
public static bool IsDebian9 => IsDistroAndVersion("debian", 9);
public static bool IsDebian10 => IsDistroAndVersion("debian", 10);
Expand All @@ -29,6 +31,7 @@ public static partial class PlatformDetection
public static bool IsUbuntu1804 => IsDistroAndVersion("ubuntu", 18, 04);
public static bool IsUbuntu1810OrHigher => IsDistroAndVersionOrHigher("ubuntu", 18, 10);
public static bool IsMariner => IsDistroAndVersion("mariner");
public static bool IsMariner1 => IsDistroAndVersion("mariner", 1);
public static bool IsSLES => IsDistroAndVersion("sles");
public static bool IsTizen => IsDistroAndVersion("tizen");
public static bool IsFedora => IsDistroAndVersion("fedora");
Expand All @@ -52,6 +55,7 @@ public static partial class PlatformDetection
public static bool IsRedHatFamily => IsRedHatFamilyAndVersion();
public static bool IsNotRedHatFamily => !IsRedHatFamily;
public static bool IsRedHatFamily7 => IsRedHatFamilyAndVersion(7);
public static bool IsCentos7 => IsDistroAndVersion("centos", 7);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we use the IsRedHatFamily7 above?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It includes RHEL (or rather excludes from testing) as well. So no, I don't think that's advisable as we want exact list of images that are failing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

they should be basically identical. but I guess they are not:
dotnet/arcade#10253 (comment)

Perhaps something we should investigate. We have at least one of the runs in container so it should be easy to check.

public static bool IsNotFedoraOrRedHatFamily => !IsFedora && !IsRedHatFamily;
public static bool IsNotDebian10 => !IsDebian10;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ private static bool GetLinqExpressionsBuiltWithIsInterpretingOnly()
public static bool IsLineNumbersSupported => !IsNativeAot;

public static bool IsInContainer => GetIsInContainer();
public static bool IsNotInContainer => !IsInContainer;
public static bool SupportsComInterop => IsWindows && IsNotMonoRuntime && !IsNativeAot; // matches definitions in clr.featuredefines.props

#if NETCOREAPP
Expand Down Expand Up @@ -199,6 +200,7 @@ private static bool GetLinqExpressionsBuiltWithIsInterpretingOnly()
public static bool IsDebuggerTypeProxyAttributeSupported => !IsNativeAot;
public static bool HasAssemblyFiles => !string.IsNullOrEmpty(typeof(PlatformDetection).Assembly.Location);
public static bool HasHostExecutable => HasAssemblyFiles; // single-file don't have a host
public static bool IsSingleFile => !HasAssemblyFiles;

private static volatile Tuple<bool> s_lazyNonZeroLowerBoundArraySupported;
public static bool IsNonZeroLowerBoundArraySupported
Expand Down
81 changes: 71 additions & 10 deletions src/libraries/System.Net.Quic/readme.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
# MsQuic

`System.Net.Quic` depends on [MsQuic](https://github.com/microsoft/msquic), Microsoft, cross-platform, native implementation of the [QUIC](https://datatracker.ietf.org/wg/quic/about/) protocol.
Currently, `System.Net.Quic` depends on [**msquic@3e40721bff04845208bc07eb4ee0c5e421e6388d**](https://github.com/microsoft/msquic/commit/3e40721bff04845208bc07eb4ee0c5e421e6388d) revision.
Currently, `System.Net.Quic` depends on [**MsQuic 2.1+**](https://github.com/microsoft/msquic/tree/release/2.1).

## Usage

MsQuic library in now being published so there's no need to compile it yourself.

For a reference, the packaging repository is in https://github.com/dotnet/msquic.
MsQuic library is officially published by [MsQuic](https://github.com/microsoft/msquic) so there's no need to compile it yourself.

### Windows
Prerequisites:
- Latest [Windows Insider Builds](https://insider.windows.com/en-us/), Insiders Fast build. This is required for SChannel support for QUIC.
- Windows 11 or Windows Server 2022 or Windows 10 Insiders Fast build. This is required for SChannel support for QUIC.
- To confirm you have a new enough build, run winver on command line and confirm you version is greater than Version 2004 (OS Build 20145.1000).
- Turned on TLS 1.3
- It is turned on by default, to confirm you can check the appropriate registry `Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols` (empty means default which means enabled).

During the build, the `msquic.dll` is automatically downloaded and placed in correct directories in order to be picked up by the runtime. It is also published as part of the runtime for Windows.
During the build, the `msquic.dll` is automatically downloaded and placed in correct directories in order to be picked up by the runtime. It is also published as part of the .NET runtime for Windows.

### Linux

On Linux, `libmsquic` is published via Microsoft official Linux package repository `packages.microsoft.com`. In order to consume it, you have to add it manually, see https://docs.microsoft.com/en-us/windows-server/administration/linux-package-repository-for-microsoft-software. After that, you should be able to install it via the package manager of your distro, e.g. for Ubuntu:
On Linux, `libmsquic` is published via official Microsoft Linux package repository `packages.microsoft.com`. In order to consume packages from it, you have to add it manually, see https://docs.microsoft.com/en-us/windows-server/administration/linux-package-repository-for-microsoft-software. After that, you should be able to install `libmsquic` via the package manager of your distro, e.g. for Ubuntu:
```
apt install libmsquic
```
Expand Down Expand Up @@ -56,7 +54,70 @@ yes | cp -rf bin/Debug/libmsquic.* <path-to-runtime>/src/libraries/System.Net.Qu

#### Windows
Prerequisites:
- Latest [Windows Insider Builds](https://insider.windows.com/en-us/), Insiders Fast build. This is required for SChannel support for QUIC.
- To confirm you have a new enough build, run `winver` on command line and confirm you version is greater than Version 2004 (OS Build 20145.1000).
- Windows 11 or Windows Server 2022 or Windows 10 Insiders Fast build. This is required for SChannel support for QUIC.
- To confirm you have a new enough build, run winver on command line and confirm you version is greater than Version 2004 (OS Build 20145.1000).

Follow the instructions from [msquic build documentation](https://github.com/microsoft/msquic/blob/main/docs/BUILD.md).

## Packaging

It differs greatly between Linux and Windows as we ship `libmsquic.dll` as part of .NET runtime on Windows. Whereas, `libmsquic` package must be manually installed on Linux distributions.

On top of that, we can consume officially released MsQuic builds, e.g. [MsQuic releases](https://github.com/microsoft/msquic/releases). As well as our own builds of the current MsQuic main branch via [dotnet/msquic](https://github.com/dotnet/msquic).

### Linux

For officially released Linux packages, we use [packages.microsoft.com](https://packages.microsoft.com/). MsQuic team themselves are publishing packages there, e.g. https://packages.microsoft.com/ubuntu/22.04/prod/pool/main/libm/libmsquic/.

Or, msquic can be compiled, either from a release branch or main. Then it must be copied inside `System.Net.Quic/src` directory, or installed into your system, see [fpm](https://github.com/jordansissel/fpm) to create your own package.

#### Testing

Testing on Linux is done with the help of docker images whose definition can be found in [dotnet/dotnet-buildtools-prereqs-docker](https://github.com/dotnet/dotnet-buildtools-prereqs-docker).

To consume a release version of the package, the docker image definition will contain:
```docker
RUN curl -LO https://packages.microsoft.com/keys/microsoft.asc && \
echo 2cfd20a306b2fa5e25522d78f2ef50a1f429d35fd30bd983e2ebffc2b80944fa microsoft.asc | sha256sum --check - && \
apt-key add microsoft.asc && \
rm microsoft.asc && \
apt-add-repository https://packages.microsoft.com/debian/11/prod && \
apt-get update && \
apt-get install -y libmsquic
```
Source: https://github.com/dotnet/dotnet-buildtools-prereqs-docker/blob/efbcd1079edef4698ada1676a5e33c4c9672f85a/src/debian/11/helix/amd64/Dockerfile#L44-L52

To consume the current main branch of msquic, we pull code from [dotnet/msquic](https://github.com/dotnet/msquic) and build it locally in our docker image:
```docker
WORKDIR /msquic
RUN apt-get update -y && \
apt-get upgrade -y && \
apt-get install -y cmake clang ruby-dev gem lttng-tools libssl-dev libnuma-dev && \
gem install fpm
RUN git clone --recursive https://github.com/dotnet/msquic
RUN cd msquic/src/msquic && \
mkdir build && \
cmake -B build -DCMAKE_BUILD_TYPE=Release -DQUIC_ENABLE_LOGGING=false -DQUIC_USE_SYSTEM_LIBCRYPTO=true -DQUIC_BUILD_TOOLS=off -DQUIC_BUILD_TEST=off -DQUIC_BUILD_PERF=off && \
cd build && \
cmake --build . --config Release
RUN cd msquic/src/msquic/build/bin/Release && \
rm libmsquic.so && \
fpm -f -s dir -t deb -n libmsquic -v $( find -type f | cut -d "." -f 4- ) \
--license MIT --url https://github.com/microsoft/msquic --log error \
$( ls ./* | cut -d "/" -f 2 | sed -r "s/(.*)/\1=\/usr\/lib\/\1/g" ) && \
dpkg -i libmsquic_*.deb
```

Source:
https://github.com/dotnet/runtime/blob/bd540938a4830ee91dec5ee2d39545b2f69a19d5/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile#L4-L21

Note that to propagate newest sources / package to the docker image used for the test runs, it must be rebuilt by [dotnet-buildtools-prereqs-docker-all](https://dev.azure.com/dnceng/internal/_build?definitionId=1183&_a=summary) pipeline with `noCache = true` variable. And since [#76630](https://github.com/dotnet/runtime/pull/76630), the newest image will get automatically picked up by the dotnet/runtime infra.

### Windows

Officially released `msquic.dll` is published to NuGet.org, see [Microsoft.Native.Quic.MsQuic.Schannel](https://www.nuget.org/packages/Microsoft.Native.Quic.MsQuic.Schannel).

To consume MsQuic from the current main branch, we use [dotnet/msquic](https://github.com/dotnet/msquic) repository which will build and publish `msquic.dll` to the transport feed, e.g. [dotnet8-transport](https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet8-transport). And from there, it'll get flown into this repository via [Darc subscription](https://github.com/dotnet/arcade/blob/main/Documentation/Darc.md). See https://github.com/dotnet/runtime/blob/bd540938a4830ee91dec5ee2d39545b2f69a19d5/eng/Version.Details.xml#L7-L10 and maestro-bot PR: https://github.com/dotnet/runtime/pull/71900.


Follow the instructions from msquic build documentation.
System.Net.Quic [project file](https://github.com/dotnet/runtime/blob/0304f1f5157a8280fa093bdfc7cfb8d9f62e016f/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj) allows switching between those two options with [`UseQuicTransportPackage` property](https://github.com/dotnet/runtime/blob/0304f1f5157a8280fa093bdfc7cfb8d9f62e016f/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj#L15).
3 changes: 1 addition & 2 deletions src/libraries/System.Net.Quic/src/System.Net.Quic.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@
<Compile Include="$(CommonPath)System\Net\SocketAddress.cs" Link="Common\System\Net\SocketAddress.cs" />
<Compile Include="$(CommonPath)System\Net\IPAddressParserStatics.cs" Link="Common\System\Net\IPAddressParserStatics.cs" />
<Compile Include="$(CommonPath)System\Net\Internals\IPEndPointExtensions.cs" Link="Common\System\Net\Internals\IPEndPointExtensions.cs" />
<Compile Include="$(CommonPath)System\Net\Security\TlsAlertMessage.cs"
Link="Common\System\Net\Security\TlsAlertMessage.cs" />
<Compile Include="$(CommonPath)System\Net\Security\TlsAlertMessage.cs" Link="Common\System\Net\Security\TlsAlertMessage.cs" />
</ItemGroup>
<!-- Unsupported platforms -->
<ItemGroup Condition="'$(TargetPlatformIdentifier)' == ''">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// 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.Net.Security;
using System.Threading.Tasks;
using Xunit;
Expand All @@ -20,21 +21,47 @@ public void UnsupportedPlatforms_ThrowsPlatformNotSupportedException()
Assert.ThrowsAsync<PlatformNotSupportedException>(async () => await CreateQuicConnection(new IPEndPoint(IPAddress.Loopback, 0)));
}

[ActiveIssue("https://github.com/dotnet/runtime/issues/73290", typeof(PlatformDetection), nameof(PlatformDetection.IsSingleFile))]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsWindows), nameof(PlatformDetection.SupportsTls13))]
public void SupportedWindowsPlatforms_IsSupportedIsTrue()
{
if (PlatformDetection.HasAssemblyFiles)
Assert.True(QuicListener.IsSupported);
Assert.True(QuicConnection.IsSupported);
}

[ActiveIssue("https://github.com/dotnet/runtime/issues/81901", typeof(PlatformDetection), nameof(PlatformDetection.IsAlpine314), nameof(PlatformDetection.IsInContainer))]
[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsLinux))]
public async Task SupportedLinuxPlatformsWithMsquic_IsSupportedIsTrue()
{
using Process find = new Process();
find.StartInfo.FileName = "find";
find.StartInfo.Arguments = "/usr/ -iname libmsquic.so*";
find.StartInfo.RedirectStandardOutput = true;
find.Start();
string output = await find.StandardOutput.ReadToEndAsync();
_output.WriteLine(output);
await find.WaitForExitAsync();
if (output.Contains("libmsquic.so"))
{
Assert.True(QuicListener.IsSupported);
Assert.True(QuicConnection.IsSupported);
}
else
{
// The above if check can be deleted when https://github.com/dotnet/runtime/issues/73290
// gets fixed and this test starts failing.
Assert.False(QuicListener.IsSupported);
Assert.False(QuicConnection.IsSupported);
_output.WriteLine("No msquic library found.");
carlossanlop marked this conversation as resolved.
Show resolved Hide resolved
}
}

[ActiveIssue("https://github.com/dotnet/runtime/issues/81901", typeof(PlatformDetection), nameof(PlatformDetection.IsAlpine313), nameof(PlatformDetection.IsInContainer))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/81901", typeof(PlatformDetection), nameof(PlatformDetection.IsAlpine314), nameof(PlatformDetection.IsInContainer))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/81901", typeof(PlatformDetection), nameof(PlatformDetection.IsMariner1), nameof(PlatformDetection.IsInContainer))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/81901", typeof(PlatformDetection), nameof(PlatformDetection.IsCentos7), nameof(PlatformDetection.IsInContainer))]
[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsLinux))]
public void SupportedLinuxPlatforms_IsSupportedIsTrue()
{
_output.WriteLine($"Running on {PlatformDetection.GetDistroVersionString()}");
Assert.True(QuicListener.IsSupported);
Assert.True(QuicConnection.IsSupported);
}
}
}