[QUIC] Added tests to check IsSupported. (#81481)
authorMarie Píchová <11718369+ManickaP@users.noreply.github.com>
Fri, 10 Feb 2023 17:08:43 +0000 (18:08 +0100)
committerGitHub <noreply@github.com>
Fri, 10 Feb 2023 17:08:43 +0000 (18:08 +0100)
* Added tests to check IsSupported.

* Use find to locate msquic lib; Use ActiveIssue to skip win test on singlefile

* Strict test for Linux containers to check where we're missing libmsquic

* Updated readme

* Some more matrix testing of msquic presence

* Suppressed failing tests against failing containers

src/libraries/Common/tests/TestUtilities/System/PlatformDetection.Unix.cs
src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs
src/libraries/System.Net.Quic/readme.md
src/libraries/System.Net.Quic/src/System.Net.Quic.csproj
src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicPlatformDetectionTests.cs

index 45b892c..abbe823 100644 (file)
@@ -19,6 +19,8 @@ namespace System
         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);
@@ -29,6 +31,7 @@ namespace System
         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");
@@ -52,6 +55,7 @@ namespace System
         public static bool IsRedHatFamily => IsRedHatFamilyAndVersion();
         public static bool IsNotRedHatFamily => !IsRedHatFamily;
         public static bool IsRedHatFamily7 => IsRedHatFamilyAndVersion(7);
+        public static bool IsCentos7 => IsDistroAndVersion("centos", 7);
         public static bool IsNotFedoraOrRedHatFamily => !IsFedora && !IsRedHatFamily;
         public static bool IsNotDebian10 => !IsDebian10;
 
index 006ee5b..6e43ad2 100644 (file)
@@ -154,6 +154,7 @@ namespace System
         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
@@ -201,6 +202,7 @@ namespace System
         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
index 2b5a5d5..234c246 100644 (file)
@@ -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
 ```
@@ -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).
\ No newline at end of file
index 7741c7a..b7b6b7e 100644 (file)
@@ -30,8 +30,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)' == ''">
index 5e9a5be..86c6c6a 100644 (file)
@@ -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;
@@ -20,21 +21,47 @@ namespace System.Net.Quic.Tests
             Assert.ThrowsAsync<PlatformNotSupportedException>(async () => await CreateQuicConnection(new IPEndPoint(IPAddress.Loopback, 0)));
         }
 
+        [ActiveIssue("https://github.com/dotnet/runtime/issues/73290", typeof(PlatformDetection), nameof(PlatformDetection.IsSingleFile))]
         [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.");
             }
         }
+
+        [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);
+        }
     }
 }