Skip to content

Test Formatting assemblies w/ net6.0 #384

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

Merged
merged 3 commits into from
Feb 13, 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
28 changes: 13 additions & 15 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
[Bb]in
[Oo]bj
[Tt]est[Rr]esults
*.suo
*.user
.msbuild/
.vs/
bin/
obj/
packages/

*.[Cc]ache
*[Rr]esharper*
packages
NuGet.exe
_[Ss]cripts
*.binlog
*.exe
*.dll
*.nupkg
*.dot[Cc]over
*.vsp
*.psess
*.exe
*.nupkg
*.orig
*.psess
*.sln.ide
.vs/
project.lock.json
*.suo
*.user
*.vsp
*[Rr]esharper*
*launchSettings.json
10 changes: 5 additions & 5 deletions Runtime.msbuild
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,12 @@
XmlPath=$(TestResultsDirectory)%(_TestDLLsXunit.FileName)-XunitResults.xml</Properties>
</_XunitProject>

<_VSTestDLLs Include="bin\$(Configuration)\test\*\netcoreapp*\*.Test.dll"
Condition=" '$(BuildPortable)' == 'true' "/>
<_XunitProject Include="tools\WebStack.testing.targets"
Condition=" '$(BuildPortable)' == 'true' ">
<_VSTestDLLs Include="bin\$(Configuration)\test\NetCore\**\*.Test.dll;
bin\$(Configuration)\test\NetStandard\**\*.Test.dll"
Exclude="bin\$(Configuration)\test\Net*\net4*\*.Test.dll" />
<_XunitProject Include="tools\WebStack.testing.targets" Condition=" '$(BuildPortable)' == 'true' ">
<Properties>TestAssembly=%(_VSTestDLLs.FullPath);
XmlPath=$(TestResultsDirectory)%(_VSTestDLLs.FileName)-NetCoreApp-XunitResults.xml;
XmlPath=$(TestResultsDirectory)%(_VSTestDLLs.FileName)-$([System.String]::Copy('%(_VSTestDLLs.RecursiveDir)').Trim('\\'))-XunitResults.xml;
UseVSTest=true</Properties>
</_XunitProject>
</ItemGroup>
Expand Down
6 changes: 6 additions & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,16 @@ jobs:
- checkout: self
clean: true
displayName: Checkout

- task: UseDotNet@2
displayName: Get .NET SDK
inputs:
useGlobalJson: true
- task: UseDotNet@2
displayName: Get .NET 2.1 runtime
inputs:
packageType: runtime
version: '2.1.x'

- script: .\build.cmd EnableSkipStrongNames
displayName: Enable SkipStrongNames
Expand Down
38 changes: 21 additions & 17 deletions build.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
pushd %~dp0
setlocal

if exist bin goto build
if exist bin goto Build
mkdir bin

:Build

REM Find the most recent 32bit MSBuild.exe on the system. Require v16.0 (installed with VS2019) or later.
REM Use `vswhere` for the search because it can find all VS installations.
REM Require VS2019 (v16.0) on the system. Use `vswhere` for the search because it can find all VS installations.
set vswhere="%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe"
if not exist %vswhere% (
set vswhere="%ProgramFiles%\Microsoft Visual Studio\Installer\vswhere.exe"
Expand All @@ -24,28 +23,33 @@ if not exist %vswhere% (
goto BuildFail
)

REM We're fine w/ any .NET SDK newer than 2.1.500 but also need a 2.1.x runtime. Microsoft.Net.Core.Component.SDK.2.1
REM actually checks for only the runtime these days.
set InstallDir=
for /f "usebackq tokens=*" %%i in (`%vswhere% -version 16 -latest -prerelease -products * ^
-requires Microsoft.Component.MSBuild ^
-requires Microsoft.NetCore.Component.SDK ^
-requires Microsoft.Net.Core.Component.SDK.2.1 ^
-requires Microsoft.Net.Component.4.5.TargetingPack ^
-requires Microsoft.Net.Component.4.5.2.TargetingPack ^
-requires Microsoft.Net.Component.4.6.2.TargetingPack ^
-property installationPath`) do (
set InstallDir="%%i"
)

if not DEFINED InstallDir (
echo "Could not find a VS2019 installation with the necessary components (MSBuild, .NET Core 2.1 Runtime, .NET SDK). Please install VS2019 or the missing components."
)

if exist %InstallDir%\MSBuild\Current\Bin\MSBuild.exe (
set MSBuild=%InstallDir%\MSBuild\Current\Bin\MSBuild.exe
) else (
echo Could not find MSBuild.exe. Please install the VS2019 BuildTools component or a workload that includes it.
echo "Could not find a VS2019 installation with the necessary components (targeting packs for v4.5, v4.5.2, and v4.6.2)."
echo Please install VS2019 or the missing components.
goto BuildFail
)

REM Find or install MSBuild. Need v17.4 due to our .NET SDK choice.
set "MSBuildVersion=17.4.1"
set "Command=[System.Threading.Thread]::CurrentThread.CurrentCulture = ''"
set "Command=%Command%; [System.Threading.Thread]::CurrentThread.CurrentUICulture = ''"
set "Command=%Command%; try { & '%~dp0eng\GetXCopyMSBuild.ps1' %MSBuildVersion%; exit $LASTEXITCODE }"
set "Command=%Command% catch { write-host $_; exit 1 }"
PowerShell -NoProfile -NoLogo -ExecutionPolicy Bypass -Command "%Command%"
if %ERRORLEVEL% neq 0 goto BuildFail

REM Add MSBuild to the path.
set "PATH=%CD%\.msbuild\%MSBuildVersion%\tools\MSBuild\Current\Bin\;%PATH%"

REM Configure NuGet operations to work w/in this repo i.e. do not pollute system packages folder.
REM Note this causes two copies of packages restored using packages.config to land in this folder e.g.
REM StyleCpy.5.0.0/ and stylecop/5.0.0/.
Expand All @@ -56,13 +60,13 @@ if DEFINED CI (set Desktop=false) else if DEFINED TEAMCITY_VERSION (set Desktop=

if "%1" == "" goto BuildDefaults

%MSBuild% Runtime.msbuild /m /nr:false /p:Platform="Any CPU" /p:Desktop=%Desktop% /v:M ^
MSBuild Runtime.msbuild /m /nr:false /p:Platform="Any CPU" /p:Desktop=%Desktop% /v:M ^
/fl /fileLoggerParameters:LogFile=bin\msbuild.log;Verbosity=Normal /consoleLoggerParameters:Summary /t:%*
if %ERRORLEVEL% neq 0 goto BuildFail
goto BuildSuccess

:BuildDefaults
%MSBuild% Runtime.msbuild /m /nr:false /p:Platform="Any CPU" /p:Desktop=%Desktop% /v:M ^
MSBuild Runtime.msbuild /m /nr:false /p:Platform="Any CPU" /p:Desktop=%Desktop% /v:M ^
/fl /fileLoggerParameters:LogFile=bin\msbuild.log;Verbosity=Normal /consoleLoggerParameters:Summary
if %ERRORLEVEL% neq 0 goto BuildFail
goto BuildSuccess
Expand Down
42 changes: 42 additions & 0 deletions eng/GetXCopyMSBuild.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Lifted from https://github.com/dotnet/arcade/blob/main/eng/common/tools.ps1
Copy link
Member Author

Choose a reason for hiding this comment

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

@MattGal this is pretty much what you suggested in dotnet/arcade#12402. Incorporating it in build.cmd was the only bit I added.

Copy link

Choose a reason for hiding this comment

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

Looks good to me.


[CmdletBinding(DefaultParameterSetName='Groups')]
param(
[string]$Version = '17.4.1'
)

Set-StrictMode -Version 2
$ErrorActionPreference = 'Stop'

function Create-Directory ([string[]] $path) {
New-Item -Path $path -Force -ItemType 'Directory' | Out-Null
}

function Unzip([string]$zipfile, [string]$outpath) {
Add-Type -AssemblyName System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::ExtractToDirectory($zipfile, $outpath)
}

function InitializeXCopyMSBuild([string]$packageVersion, [bool]$install, [string]$ToolsDir) {
$packageName = 'RoslynTools.MSBuild'
$packageDir = Join-Path $ToolsDir $packageVersion
$packagePath = Join-Path $packageDir "$packageName.$packageVersion.nupkg"

if (!(Test-Path $packageDir)) {
if (!$install) {
return $null
}

Create-Directory $packageDir

Write-Host "Downloading $packageName $packageVersion"
$ProgressPreference = 'SilentlyContinue' # Don't display the console progress UI - it's a huge perf hit
Invoke-WebRequest "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/flat2/$packageName/$packageVersion/$packageName.$packageVersion.nupkg" -OutFile $packagePath

Unzip $packagePath $packageDir
}

return Join-Path $packageDir 'tools'
}

InitializeXCopyMSBuild -packageVersion $Version -install $true -ToolsDir (join-path $PWD .msbuild)
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "2.1.818",
"version": "6.0.405",
"rollForward": "major"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ protected override void Dispose(bool disposing)
}
}

#if NETCOREAPP3_1 || NET5_0_OR_GREATER || NETSTANDARD2_1
#if NETCOREAPP3_1_OR_GREATER || NETSTANDARD2_1
public override ValueTask DisposeAsync()
{
if (_innerStream is null)
Expand Down
19 changes: 14 additions & 5 deletions test/Microsoft.TestCommon/ExceptionAssertions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ public static async Task<ArgumentNullException> ThrowsArgumentNullAsync(Func<Tas
/// <exception cref="ThrowsException">Thrown when an exception was not thrown, or when an exception of the incorrect type is thrown</exception>
public static ArgumentException ThrowsArgumentNullOrEmpty(Action testCode, string paramName)
{
return Throws<ArgumentException>(testCode, "Value cannot be null or empty.\r\nParameter name: " + paramName, allowDerivedExceptions: false);
return Throws<ArgumentException>(testCode, "Value cannot be null or empty." + GetParameterMessage(paramName), allowDerivedExceptions: false);
}

/// <summary>
Expand Down Expand Up @@ -327,7 +327,7 @@ public static ArgumentOutOfRangeException ThrowsArgumentOutOfRange(Action testCo
{
if (exceptionMessage != null)
{
exceptionMessage = exceptionMessage + "\r\nParameter name: " + paramName;
exceptionMessage = exceptionMessage + GetParameterMessage(paramName);
if (actualValue != null)
{
exceptionMessage += String.Format(CultureReplacer.DefaultCulture, "\r\nActual value was {0}.", actualValue);
Expand Down Expand Up @@ -360,7 +360,7 @@ public static async Task<ArgumentOutOfRangeException> ThrowsArgumentOutOfRangeAs
{
if (exceptionMessage != null)
{
exceptionMessage = exceptionMessage + "\r\nParameter name: " + paramName;
exceptionMessage = exceptionMessage + GetParameterMessage(paramName);
if (actualValue != null)
{
exceptionMessage += String.Format(CultureReplacer.DefaultCulture, "\r\nActual value was {0}.", actualValue);
Expand Down Expand Up @@ -500,8 +500,8 @@ public static HttpException ThrowsHttpException(Action testCode, string exceptio
public static ArgumentException ThrowsInvalidEnumArgument(Action testCode, string paramName, int invalidValue, Type enumType, bool allowDerivedExceptions = false)
{
string message = String.Format(CultureReplacer.DefaultCulture,
"The value of argument '{0}' ({1}) is invalid for Enum type '{2}'.{3}Parameter name: {0}",
paramName, invalidValue, enumType.Name, Environment.NewLine);
"The value of argument '{0}' ({1}) is invalid for Enum type '{2}'.{3}",
paramName, invalidValue, enumType.Name, GetParameterMessage(paramName));

#if NETFX_CORE // InvalidEnumArgumentException not available in netstandard1.3.
return Throws<Error.InvalidEnumArgumentException>(testCode, message, allowDerivedExceptions);
Expand Down Expand Up @@ -581,6 +581,15 @@ public static async Task<TException> ThrowsAsync<TException>(
return ex;
}

private static string GetParameterMessage(string parameterName)
{
#if NETCOREAPP3_1_OR_GREATER
return " (Parameter '" + parameterName + "')";
#else
return Environment.NewLine + "Parameter name: " + parameterName;
#endif
}

// We've re-implemented all the xUnit.net Throws code so that we can get this
// updated implementation of RecordException which silently unwraps any instances
// of AggregateException. In addition to unwrapping exceptions, this method ensures
Expand Down
2 changes: 1 addition & 1 deletion test/Microsoft.TestCommon/Microsoft.TestCommon.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory),Runtime.sln))\tools\WebStack.settings.targets" />
<PropertyGroup>
<TargetFrameworks>net462;netcoreapp2.1</TargetFrameworks>
<TargetFrameworks>net462;netcoreapp2.1;net6.0</TargetFrameworks>
<Configurations>$(Configurations);CodeAnalysis</Configurations>
<DefineConstants
Condition=" '$(NetFX_Core)' == 'true' ">$(DefineConstants);NETFX_CORE</DefineConstants>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory),Runtime.sln))\tools\WebStack.settings.targets" />
<PropertyGroup>
<TargetFrameworks>netcoreapp2.1;net462</TargetFrameworks>
<TargetFrameworks>net462;netcoreapp2.1;net6.0</TargetFrameworks>
<RootNamespace>System.Net.Http</RootNamespace>
<OutputPath>..\..\bin\$(Configuration)\Test\NetCore\</OutputPath>
<Configurations>$(Configurations);CodeAnalysis</Configurations>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory),Runtime.sln))\tools\WebStack.settings.targets" />
<PropertyGroup>
<TargetFrameworks>netcoreapp2.1;net462</TargetFrameworks>
<TargetFrameworks>net462;netcoreapp2.1;net6.0</TargetFrameworks>
<RootNamespace>System.Net.Http</RootNamespace>
<OutputPath>..\..\bin\$(Configuration)\Test\NetStandard\</OutputPath>
<Configurations>$(Configurations);CodeAnalysis</Configurations>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,12 @@ public async Task FormatterThrowsOnReadWithInvalidContent()
// Act & Assert
await Assert.ThrowsAsync<JsonReaderException>(
() => formatter.ReadFromStreamAsync(variationType, stream, content, null),
"Could not convert to decimal: 7.92281625142643E+28. Path 'Value'.");
#if NETCOREAPP3_1_OR_GREATER
"Could not convert to decimal: 7.922816251426434E+28. Path 'Value'."
#else
"Could not convert to decimal: 7.92281625142643E+28. Path 'Value'."
#endif
);
}

[Theory]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using System.Text;
using System.Threading.Tasks;
using Microsoft.TestCommon;
using Moq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

Expand Down Expand Up @@ -576,6 +577,29 @@ public override Task WriteToStreamAsync_UsesCorrectCharacterEncoding(string cont
formatter, content, formattedContent, mediaType, encoding, isDefaultEncoding);
}

#if NET6_0_OR_GREATER
// Cannot Mock a Stream and let JsonWriter write to it. Writer will use ReadOnlySpan in this case and such
// parameters are not currently mockable. See moq/moq4#829, moq/moq4#979, and dotnet/runtime#45152.
// Override here avoids the Mock<Stream> and should confirm this Stream is not closed. Also adds an
// additional check of the written text.
Comment on lines +581 to +584
Copy link
Member Author

Choose a reason for hiding this comment

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

@stephentoub this relates to one of our email conversations. Thanks for your pointer to dotnet/runtime#45152 and helping me understand what's happening.

Thoughts from all reviewers much appreciated: Should I simply replace MediaTypeFormatterTestBase.WriteToStreamAsync_WhenObjectIsNull_WritesDataButDoesNotCloseStream along these lines❔ Would need a protected property containing the expected Stream content for a null value. But I'm thinking verifying what's written makes sense. I'm also thinking the BSON case might be more difficult to confirm.

[Fact]
public override async Task WriteToStreamAsync_WhenObjectIsNull_WritesDataButDoesNotCloseStream()
{
// Arrange
JsonMediaTypeFormatter formatter = CreateFormatter();
Stream stream = new MemoryStream();
HttpContent content = new StringContent(String.Empty);

// Act
await formatter.WriteToStreamAsync(typeof(SampleType), null, stream, content, null);

// Assert (stream will throw if it has been closed)
stream.Position = 0;
using var reader = new StreamReader(stream);
Assert.Equal("null", reader.ReadToEnd());
}
#endif

public class TestJsonMediaTypeFormatter : JsonMediaTypeFormatter
{
public TestJsonMediaTypeFormatter()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,10 @@ public async Task SendAsync_DoesNotInsertSendProgressWithoutEntityOrHandlerPrese
}

[Theory]
#if !NET6_0_OR_GREATER // https://github.com/aspnet/AspNetWebStack/issues/386
[InlineData(false, false)]
[InlineData(false, true)]
#endif
[InlineData(true, false)]
[InlineData(true, true)]
public async Task SendAsync_InsertsReceiveProgressWhenResponseEntityPresent(bool insertResponseEntity, bool addReceiveProgressHandler)
Expand Down
Loading