Skip to content

Commit 06589fb

Browse files
authored
Do not fail tests immediately (#368)
- combine `RegexReplace` into `PrintTestRunSummary` task - remove unused `WarnOnNoMatch` parameter; inline other parameters - capture test summary in `msbuild` logs - avoid `System.Console` use in the task - fail task if any tests fail - collect `xunit` task exit codes in case of catastrophic problems (not test failures) - fail build if `PrintTestRunSummary` doesn't but errors occurred also: - do not test assemblies in parallel; reduce port contention issues - avoid `CallTarget` task nits: - clean some trailing whitespace in C# sources - mostly files I expect to update soon - reduce `NuGet.exe restore` verbosity; no longer debugging that - add console summary when using build.cmd - reduce duplication in `RestorePackages` target - only restore NetCore projects when `$(BuildPortable)` is `true` - restore src NetStandard project transitively through NetStandard.Test project - pass more properties w/ `Restore` target invocation
1 parent 0b0f6bf commit 06589fb

37 files changed

+299
-320
lines changed

Runtime.msbuild

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<BuildPortable Condition=" '$(BuildPortable)' == '' ">true</BuildPortable>
1212
<BuildInParallel Condition=" '$(BuildInParallel)' == '' And $(MSBuildNodeCount) &gt; 1 ">true</BuildInParallel>
1313
<BuildInParallel Condition=" '$(BuildInParallel)' == '' ">false</BuildInParallel>
14-
<TestInParallel Condition=" '$(TestInParallel)' == '' ">$(BuildInParallel)</TestInParallel>
14+
<TestInParallel Condition=" '$(TestInParallel)' == '' ">false</TestInParallel>
1515
<TestResultsDirectory>$(MSBuildThisFileDirectory)bin\$(Configuration)\test\TestResults\</TestResultsDirectory>
1616
<SkipStrongNamesExe>$(MSBuildThisFileDirectory)packages\Microsoft.Web.SkipStrongNames.1.0.0\tools\SkipStrongNames.exe</SkipStrongNamesExe>
1717
<SkipStrongNamesXml>$(MSBuildThisFileDirectory)tools\SkipStrongNames.xml</SkipStrongNamesXml>
@@ -65,25 +65,24 @@
6565

6666
<Target Name="RestorePackages" DependsOnTargets="DownloadNuGet">
6767
<ItemGroup>
68-
<_NuGetPackagesAndSolutions Include="src\System.Net.Http.Formatting.NetCore\packages.config;
69-
test\System.Net.Http.Formatting.NetCore.Test\packages.config;
70-
Runtime.sln" />
68+
<_NuGetPackagesAndSolutions Include="Runtime.sln" />
7169

7270
<!-- Avoid restoring RuntimePortable.sln directly. -->
7371
<_NuGetPackagesAndSolutions Include="src\System.Net.Http.Formatting.NetCore\packages.config;
7472
test\System.Net.Http.Formatting.NetCore.Test\packages.config"
7573
Condition=" '$(BuildPortable)' == 'true' " />
76-
<_ProjectsToRestore Include="src\System.Net.Http.Formatting.NetStandard\System.Net.Http.Formatting.NetStandard.csproj;
77-
test\System.Net.Http.Formatting.NetStandard.Test\System.Net.Http.Formatting.NetStandard.Test.csproj"
74+
<_ProjectsToRestore Include="test\System.Net.Http.Formatting.NetStandard.Test\System.Net.Http.Formatting.NetStandard.Test.csproj"
7875
Condition=" '$(BuildPortable)' == 'true' " />
7976
</ItemGroup>
8077

8178
<Message Text="Restoring NuGet packages..." Importance="High" />
8279
<Exec Command='"$(NuGetExe)" restore "%(_NuGetPackagesAndSolutions.Identity)" ^
8380
-PackagesDirectory packages -NonInteractive ^
84-
-Verbosity normal -ConfigFile "$(MSBuildThisFileDirectory)\.nuget\NuGet.Config"' />
85-
<MSBuild Projects="@(_ProjectsToRestore)" Targets="Restore" Properties="Configuration=$(Configuration)"
86-
Condition=" '$(BuildPortable)' == 'true' " />
81+
-Verbosity quiet -ConfigFile "$(MSBuildThisFileDirectory)\.nuget\NuGet.Config"' />
82+
<MSBuild Projects="@(_ProjectsToRestore)" Targets="Restore"
83+
BuildInParallel="$(BuildInParallel)"
84+
Condition=" '$(BuildPortable)' == 'true' "
85+
Properties="Configuration=$(Configuration);CodeAnalysis=$(CodeAnalysis);StyleCopEnabled=$(StyleCopEnabled);VisualStudioVersion=$(VisualStudioVersion)" />
8786
</Target>
8887

8988
<!-- Pick the right Microsoft.Web.FxCop package to use and copy it to a standard location. -->
@@ -110,9 +109,7 @@
110109
Properties="Configuration=$(Configuration);CodeAnalysis=$(CodeAnalysis);StyleCopEnabled=$(StyleCopEnabled);VisualStudioVersion=$(VisualStudioVersion)" />
111110
</Target>
112111

113-
<Target Name="UnitTest" DependsOnTargets="CheckSkipStrongNames;Build">
114-
<CallTarget Targets="RunTests;PrintTestRunSummary" RunEachTargetSeparately="True" />
115-
</Target>
112+
<Target Name="UnitTest" DependsOnTargets="Build;PrintTestRunSummary" />
116113

117114
<Target Name="RunTests" DependsOnTargets="CheckSkipStrongNames">
118115
<ItemGroup>
@@ -128,7 +125,9 @@
128125
<RemoveDir Directories="$(TestResultsDirectory)" />
129126
<MakeDir Directories="$(TestResultsDirectory)" />
130127

131-
<MSBuild Projects="@(_XunitProject)" BuildInParallel="$(TestInParallel)" Targets="Xunit" />
128+
<MSBuild Projects="@(_XunitProject)" BuildInParallel="$(TestInParallel)" Targets="Xunit">
129+
<Output TaskParameter="TargetOutputs" ItemName="_ExitCodes" />
130+
</MSBuild>
132131

133132
<!-- Failures in this project will fail build. But, results will not be included in test run summary. -->
134133
<MSBuild
@@ -145,7 +144,11 @@
145144
<Error Text="Unit tests will not run correctly unless SkipStrongNames is Enabled. Current status: $(Status). Run build.cmd EnableSkipStrongNames to fix this problem." Condition="'$(Status)' != 'Enabled'" />
146145
</Target>
147146

148-
<Target Name="PrintTestRunSummary">
147+
<Target Name="PrintTestRunSummary" DependsOnTargets="RunTests">
149148
<PrintTestRunSummary TestResultsDirectory="$(TestResultsDirectory)" />
149+
150+
<!-- PrintTestRunSummary stops MSBuild if tests failed. But the Xunit target may fail for other reasons... -->
151+
<Error Text="Testing failed with exit code '%(Code)':%0A@(_ExitCodes -> ' %(Identity)', '%0A')"
152+
Condition=" '%(Code)' != '0' " />
150153
</Target>
151154
</Project>

build.cmd

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,14 @@ if exist "%InstallDir%\MSBuild\15.0\Bin\MSBuild.exe" (
4040

4141
if "%1" == "" goto BuildDefaults
4242

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

4748
:BuildDefaults
48-
%MSBuild% Runtime.msbuild /m /nr:false /p:Platform="Any CPU" /p:Desktop=true /v:M /fl /flp:LogFile=bin\msbuild.log;Verbosity=Normal
49+
%MSBuild% Runtime.msbuild /m /nr:false /p:Platform="Any CPU" /p:Desktop=true /v:M ^
50+
/fl /fileLoggerParameters:LogFile=bin\msbuild.log;Verbosity=Normal /consoleLoggerParameters:Summary
4951
if %ERRORLEVEL% neq 0 goto BuildFail
5052
goto BuildSuccess
5153

src/Common/CollectionExtensions.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public static T[] AppendAndReallocate<T>(this T[] array, T value)
2727
}
2828

2929
/// <summary>
30-
/// Return the enumerable as an Array, copying if required. Optimized for common case where it is an Array.
30+
/// Return the enumerable as an Array, copying if required. Optimized for common case where it is an Array.
3131
/// Avoid mutating the return value.
3232
/// </summary>
3333
public static T[] AsArray<T>(this IEnumerable<T> values)
@@ -43,7 +43,7 @@ public static T[] AsArray<T>(this IEnumerable<T> values)
4343
}
4444

4545
/// <summary>
46-
/// Return the enumerable as a Collection of T, copying if required. Optimized for the common case where it is
46+
/// Return the enumerable as a Collection of T, copying if required. Optimized for the common case where it is
4747
/// a Collection of T and avoiding a copy if it implements IList of T. Avoid mutating the return value.
4848
/// </summary>
4949
public static Collection<T> AsCollection<T>(this IEnumerable<T> enumerable)
@@ -78,9 +78,9 @@ public static IList<T> AsIList<T>(this IEnumerable<T> enumerable)
7878
}
7979
return new List<T>(enumerable);
8080
}
81-
81+
8282
/// <summary>
83-
/// Return the enumerable as a List of T, copying if required. Optimized for common case where it is an List of T
83+
/// Return the enumerable as a List of T, copying if required. Optimized for common case where it is an List of T
8484
/// or a ListWrapperCollection of T. Avoid mutating the return value.
8585
/// </summary>
8686
public static List<T> AsList<T>(this IEnumerable<T> enumerable)

src/Common/CommonWebApiResources.Designer.cs

Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Common/Error.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ internal static ArgumentException ArgumentUriNotAbsolute(string parameterName, U
7474
}
7575

7676
/// <summary>
77-
/// Creates an <see cref="ArgumentException"/> with a message saying that the argument must be an absolute URI
77+
/// Creates an <see cref="ArgumentException"/> with a message saying that the argument must be an absolute URI
7878
/// without a query or fragment identifier and then logs it with <see cref="F:TraceLevel.Error"/>.
7979
/// </summary>
8080
/// <param name="parameterName">The name of the parameter that caused the current exception.</param>

src/System.Net.Http.Formatting/ByteRangeStreamContent.cs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ namespace System.Net.Http
1313
{
1414
/// <summary>
1515
/// <see cref="HttpContent"/> implementation which provides a byte range view over a stream used to generate HTTP
16-
/// 206 (Partial Content) byte range responses. The <see cref="ByteRangeStreamContent"/> supports one or more
17-
/// byte ranges regardless of whether the ranges are consecutive or not. If there is only one range then a
16+
/// 206 (Partial Content) byte range responses. The <see cref="ByteRangeStreamContent"/> supports one or more
17+
/// byte ranges regardless of whether the ranges are consecutive or not. If there is only one range then a
1818
/// single partial response body containing a Content-Range header is generated. If there are more than one
1919
/// ranges then a multipart/byteranges response is generated where each body part contains a range indicated
2020
/// by the associated Content-Range header field.
@@ -33,9 +33,9 @@ public class ByteRangeStreamContent : HttpContent
3333

3434
/// <summary>
3535
/// <see cref="HttpContent"/> implementation which provides a byte range view over a stream used to generate HTTP
36-
/// 206 (Partial Content) byte range responses. If none of the requested ranges overlap with the current extend
37-
/// of the selected resource represented by the <paramref name="content"/> parameter then an
38-
/// <see cref="InvalidByteRangeException"/> is thrown indicating the valid Content-Range of the content.
36+
/// 206 (Partial Content) byte range responses. If none of the requested ranges overlap with the current extend
37+
/// of the selected resource represented by the <paramref name="content"/> parameter then an
38+
/// <see cref="InvalidByteRangeException"/> is thrown indicating the valid Content-Range of the content.
3939
/// </summary>
4040
/// <param name="content">The stream over which to generate a byte range view.</param>
4141
/// <param name="range">The range or ranges, typically obtained from the Range HTTP request header field.</param>
@@ -47,9 +47,9 @@ public ByteRangeStreamContent(Stream content, RangeHeaderValue range, string med
4747

4848
/// <summary>
4949
/// <see cref="HttpContent"/> implementation which provides a byte range view over a stream used to generate HTTP
50-
/// 206 (Partial Content) byte range responses. If none of the requested ranges overlap with the current extend
51-
/// of the selected resource represented by the <paramref name="content"/> parameter then an
52-
/// <see cref="InvalidByteRangeException"/> is thrown indicating the valid Content-Range of the content.
50+
/// 206 (Partial Content) byte range responses. If none of the requested ranges overlap with the current extend
51+
/// of the selected resource represented by the <paramref name="content"/> parameter then an
52+
/// <see cref="InvalidByteRangeException"/> is thrown indicating the valid Content-Range of the content.
5353
/// </summary>
5454
/// <param name="content">The stream over which to generate a byte range view.</param>
5555
/// <param name="range">The range or ranges, typically obtained from the Range HTTP request header field.</param>
@@ -62,9 +62,9 @@ public ByteRangeStreamContent(Stream content, RangeHeaderValue range, string med
6262

6363
/// <summary>
6464
/// <see cref="HttpContent"/> implementation which provides a byte range view over a stream used to generate HTTP
65-
/// 206 (Partial Content) byte range responses. If none of the requested ranges overlap with the current extend
66-
/// of the selected resource represented by the <paramref name="content"/> parameter then an
67-
/// <see cref="InvalidByteRangeException"/> is thrown indicating the valid Content-Range of the content.
65+
/// 206 (Partial Content) byte range responses. If none of the requested ranges overlap with the current extend
66+
/// of the selected resource represented by the <paramref name="content"/> parameter then an
67+
/// <see cref="InvalidByteRangeException"/> is thrown indicating the valid Content-Range of the content.
6868
/// </summary>
6969
/// <param name="content">The stream over which to generate a byte range view.</param>
7070
/// <param name="range">The range or ranges, typically obtained from the Range HTTP request header field.</param>
@@ -76,9 +76,9 @@ public ByteRangeStreamContent(Stream content, RangeHeaderValue range, MediaTypeH
7676

7777
/// <summary>
7878
/// <see cref="HttpContent"/> implementation which provides a byte range view over a stream used to generate HTTP
79-
/// 206 (Partial Content) byte range responses. If none of the requested ranges overlap with the current extend
80-
/// of the selected resource represented by the <paramref name="content"/> parameter then an
81-
/// <see cref="InvalidByteRangeException"/> is thrown indicating the valid Content-Range of the content.
79+
/// 206 (Partial Content) byte range responses. If none of the requested ranges overlap with the current extend
80+
/// of the selected resource represented by the <paramref name="content"/> parameter then an
81+
/// <see cref="InvalidByteRangeException"/> is thrown indicating the valid Content-Range of the content.
8282
/// </summary>
8383
/// <param name="content">The stream over which to generate a byte range view.</param>
8484
/// <param name="range">The range or ranges, typically obtained from the Range HTTP request header field.</param>

src/System.Net.Http.Formatting/Formatting/BufferedMediaTypeFormatter.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
namespace System.Net.Http.Formatting
1414
{
1515
/// <summary>
16-
/// Base class for writing a synchronous formatter on top of the asynchronous formatter infrastructure.
16+
/// Base class for writing a synchronous formatter on top of the asynchronous formatter infrastructure.
1717
/// This does not guarantee non-blocking threads. The only way to guarantee that we don't block a thread on IO is
1818
/// to use the asynchronous <see cref="MediaTypeFormatter"/>.
1919
/// </summary>
@@ -219,13 +219,13 @@ private static Stream GetBufferStream(Stream innerStream, int bufferSize)
219219
{
220220
Contract.Assert(innerStream != null);
221221

222-
// We wrap the inner stream in a non-closing delegating stream so that we allow the user
222+
// We wrap the inner stream in a non-closing delegating stream so that we allow the user
223223
// to use the using (...) pattern yet not break the contract of formatters not closing
224224
// the inner stream.
225225
Stream nonClosingStream = new NonClosingDelegatingStream(innerStream);
226226

227-
// This uses a naive buffering. BufferedStream() will block the thread while it drains the buffer.
228-
// We can explore a smarter implementation that async drains the buffer.
227+
// This uses a naive buffering. BufferedStream() will block the thread while it drains the buffer.
228+
// We can explore a smarter implementation that async drains the buffer.
229229
return new BufferedStream(nonClosingStream, bufferSize);
230230
}
231231
}

0 commit comments

Comments
 (0)