Merge remote-tracking branch 'origin/dev' into nimullen/vs15.7merge

This commit is contained in:
N. Taylor Mullen 2018-03-08 14:44:14 -08:00
commit 07e672159e
28 changed files with 246 additions and 156 deletions

View File

@ -1,17 +0,0 @@
init:
- git config --global core.autocrlf true
branches:
only:
- dev
- /^release\/.*$/
- /^(.*\/)?ci-.*$/
build_script:
- ps: .\run.ps1 default-build
clone_depth: 1
environment:
global:
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
DOTNET_CLI_TELEMETRY_OPTOUT: 1
test: 'off'
deploy: 'off'
os: Visual Studio 2017 Preview

View File

@ -1,8 +1,6 @@
Razor
=====
AppVeyor: [![AppVeyor](https://ci.appveyor.com/api/projects/status/olbc8ur2jna0v27j/branch/dev?svg=true)](https://ci.appveyor.com/project/aspnetci/razor/branch/dev)
Travis: [![Travis](https://travis-ci.org/aspnet/Razor.svg?branch=dev)](https://travis-ci.org/aspnet/Razor)
The Razor syntax provides a fast, terse, clean and lightweight way to combine server code with HTML to create dynamic web content. This repo contains the parser and the C# code generator for the Razor syntax.

View File

@ -4,22 +4,22 @@
</PropertyGroup>
<PropertyGroup Label="Package Versions">
<BenchmarkDotNetPackageVersion>0.10.11</BenchmarkDotNetPackageVersion>
<InternalAspNetCoreSdkPackageVersion>2.1.0-preview2-15723</InternalAspNetCoreSdkPackageVersion>
<MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>2.1.0-preview2-30192</MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>
<MicrosoftAspNetCoreHtmlAbstractionsPackageVersion>2.1.0-preview2-30192</MicrosoftAspNetCoreHtmlAbstractionsPackageVersion>
<MicrosoftAspNetCoreTestingPackageVersion>2.1.0-preview2-30192</MicrosoftAspNetCoreTestingPackageVersion>
<MicrosoftBuildFrameworkPackageVersion>15.7.0-preview-000011-1378327</MicrosoftBuildFrameworkPackageVersion>
<MicrosoftBuildPackageVersion>15.7.0-preview-000011-1378327</MicrosoftBuildPackageVersion>
<MicrosoftBuildUtilitiesCorePackageVersion>15.7.0-preview-000011-1378327</MicrosoftBuildUtilitiesCorePackageVersion>
<InternalAspNetCoreSdkPackageVersion>2.1.0-preview2-15728</InternalAspNetCoreSdkPackageVersion>
<MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>2.1.0-preview2-30272</MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>
<MicrosoftAspNetCoreHtmlAbstractionsPackageVersion>2.1.0-preview2-30272</MicrosoftAspNetCoreHtmlAbstractionsPackageVersion>
<MicrosoftAspNetCoreTestingPackageVersion>2.1.0-preview2-30272</MicrosoftAspNetCoreTestingPackageVersion>
<MicrosoftBuildFrameworkPackageVersion>15.6.82</MicrosoftBuildFrameworkPackageVersion>
<MicrosoftBuildPackageVersion>15.6.82</MicrosoftBuildPackageVersion>
<MicrosoftBuildUtilitiesCorePackageVersion>15.6.82</MicrosoftBuildUtilitiesCorePackageVersion>
<MicrosoftCodeAnalysisCommonPackageVersion>2.6.1</MicrosoftCodeAnalysisCommonPackageVersion>
<MicrosoftCodeAnalysisCSharpPackageVersion>2.6.1</MicrosoftCodeAnalysisCSharpPackageVersion>
<MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion>2.1.0-preview2-30192</MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion>
<MicrosoftExtensionsCopyOnWriteDictionarySourcesPackageVersion>2.1.0-preview2-30192</MicrosoftExtensionsCopyOnWriteDictionarySourcesPackageVersion>
<MicrosoftExtensionsDependencyModelPackageVersion>2.1.0-preview2-25711-01</MicrosoftExtensionsDependencyModelPackageVersion>
<MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>2.1.0-preview2-30192</MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>
<MicrosoftExtensionsWebEncodersPackageVersion>2.1.0-preview2-30192</MicrosoftExtensionsWebEncodersPackageVersion>
<MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion>2.1.0-preview2-30272</MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion>
<MicrosoftExtensionsCopyOnWriteDictionarySourcesPackageVersion>2.1.0-preview2-30272</MicrosoftExtensionsCopyOnWriteDictionarySourcesPackageVersion>
<MicrosoftExtensionsDependencyModelPackageVersion>2.1.0-preview2-26224-02</MicrosoftExtensionsDependencyModelPackageVersion>
<MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>2.1.0-preview2-30272</MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>
<MicrosoftExtensionsWebEncodersPackageVersion>2.1.0-preview2-30272</MicrosoftExtensionsWebEncodersPackageVersion>
<MicrosoftNETCoreApp20PackageVersion>2.0.0</MicrosoftNETCoreApp20PackageVersion>
<MicrosoftNETCoreApp21PackageVersion>2.1.0-preview2-26130-04</MicrosoftNETCoreApp21PackageVersion>
<MicrosoftNETCoreApp21PackageVersion>2.1.0-preview2-26225-03</MicrosoftNETCoreApp21PackageVersion>
<MicrosoftNETTestSdkPackageVersion>15.6.0</MicrosoftNETTestSdkPackageVersion>
<MicrosoftVisualStudioComponentModelHostPackageVersion>15.0.26606</MicrosoftVisualStudioComponentModelHostPackageVersion>
<MicrosoftVisualStudioEditorPackageVersion>15.6.161-preview</MicrosoftVisualStudioEditorPackageVersion>
@ -42,8 +42,8 @@
<NETStandardLibrary20PackageVersion>2.0.1</NETStandardLibrary20PackageVersion>
<NewtonsoftJsonPackageVersion>10.0.1</NewtonsoftJsonPackageVersion>
<StreamJsonRpcPackageVersion>1.1.92</StreamJsonRpcPackageVersion>
<SystemDiagnosticsDiagnosticSourcePackageVersion>4.5.0-preview2-26130-01</SystemDiagnosticsDiagnosticSourcePackageVersion>
<SystemValueTuplePackageVersion>4.5.0-preview2-26130-01</SystemValueTuplePackageVersion>
<SystemDiagnosticsDiagnosticSourcePackageVersion>4.5.0-preview2-26224-02</SystemDiagnosticsDiagnosticSourcePackageVersion>
<SystemValueTuplePackageVersion>4.5.0-preview2-26224-02</SystemValueTuplePackageVersion>
<VisualStudio_NewtonsoftJsonPackageVersion>9.0.1</VisualStudio_NewtonsoftJsonPackageVersion>
<VSIX_MicrosoftCodeAnalysisCommonPackageVersion>2.7.0-beta3-62512-06</VSIX_MicrosoftCodeAnalysisCommonPackageVersion>
<VSIX_MicrosoftCodeAnalysisCSharpFeaturesPackageVersion>2.7.0-beta3-62512-06</VSIX_MicrosoftCodeAnalysisCSharpFeaturesPackageVersion>

View File

@ -1,10 +1,11 @@
<Project>
<Project>
<Import Project="$(DotNetRestoreSourcePropsPath)" Condition="'$(DotNetRestoreSourcePropsPath)' != ''"/>
<PropertyGroup Label="RestoreSources">
<RestoreSources>$(DotNetRestoreSources)</RestoreSources>
<RestoreSources Condition="'$(DotNetBuildOffline)' != 'true' AND '$(AspNetUniverseBuildOffline)' != 'true' ">
$(RestoreSources);
https://dotnet.myget.org/F/dotnet-core/api/v3/index.json;
https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json;
https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json;
https://dotnet.myget.org/F/msbuild/api/v3/index.json;

View File

@ -1,2 +1,2 @@
version:2.1.0-preview2-15723
commithash:f9bb4be59e39938ec59a6975257e26099b0d03c1
version:2.1.0-preview2-15728
commithash:393377068ddcf51dfee0536536d455f57a828b06

View File

@ -53,7 +53,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
var writer = ServerLogger.IsLoggingEnabled ? new StringWriter() : TextWriter.Null;
var checker = new DefaultExtensionDependencyChecker(Loader, writer);
var checker = new DefaultExtensionDependencyChecker(Loader, writer, writer);
var app = new Application(cancellationToken, Loader, checker, AssemblyReferenceProvider)
{
Out = writer,

View File

@ -26,15 +26,18 @@ namespace Microsoft.AspNetCore.Razor.Tools
private readonly ExtensionAssemblyLoader _loader;
private readonly TextWriter _output;
private readonly TextWriter _error;
private readonly string[] _ignoredAssemblies;
public DefaultExtensionDependencyChecker(
ExtensionAssemblyLoader loader,
TextWriter output,
TextWriter error,
string[] ignoredAssemblies = null)
{
_loader = loader;
_output = output;
_error = error;
_ignoredAssemblies = ignoredAssemblies ?? DefaultIgnoredAssemblies;
}
@ -46,8 +49,8 @@ namespace Microsoft.AspNetCore.Razor.Tools
}
catch (Exception ex)
{
_output.WriteLine("Exception performing Extension dependency check:");
_output.WriteLine(ex.ToString());
_error.WriteLine("Exception performing Extension dependency check:");
_error.WriteLine(ex.ToString());
return false;
}
}
@ -64,7 +67,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
if (!Path.IsPathRooted(item.FilePath))
{
_output.WriteLine($"The file path '{item.FilePath}' is not a rooted path. File paths must be absolute and fully-qualified.");
_error.WriteLine($"The file path '{item.FilePath}' is not a rooted path. File paths must be absolute and fully-qualified.");
return false;
}
@ -83,7 +86,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
}
// If we get here we can't resolve this assembly. This is an error.
_output.WriteLine($"Extension assembly '{item.Identity.Name}' depends on '{reference.ToString()} which is missing.");
_error.WriteLine($"Extension assembly '{item.Identity.Name}' depends on '{reference.ToString()} which is missing.");
return false;
}
}
@ -110,7 +113,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
var item = items[i];
if (item.Mvid != item.Assembly.ManifestModule.ModuleVersionId)
{
_output.WriteLine($"Extension assembly '{item.Identity.Name}' at '{item.FilePath}' has a different ModuleVersionId than loaded assembly '{item.Assembly.FullName}'");
_error.WriteLine($"Extension assembly '{item.Identity.Name}' at '{item.FilePath}' has a different ModuleVersionId than loaded assembly '{item.Assembly.FullName}'");
return false;
}
}

View File

@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
// Prevent shadow copying.
var loader = new DefaultExtensionAssemblyLoader(baseDirectory: null);
var checker = new DefaultExtensionDependencyChecker(loader, Console.Error);
var checker = new DefaultExtensionDependencyChecker(loader, Console.Out, Console.Error);
var application = new Application(
cancel.Token,

View File

@ -57,19 +57,21 @@ namespace Microsoft.AspNetCore.Razor.Tools
var process = Process.GetProcessById(response.ServerProcessId);
process.WaitForExit();
}
catch (Exception)
catch (Exception ex)
{
// There is an inherent race here with the server process. If it has already shutdown
// by the time we try to access it then the operation has succeed.
// by the time we try to access it then the operation has succeeded.
Error.Write(ex);
}
Out.Write("Server pid:{0} shut down", response.ServerProcessId);
}
}
}
catch (Exception) when (IsServerRunning())
catch (Exception ex) when (IsServerRunning())
{
// Ignore an exception that occurred while the server was shutting down.
Error.Write(ex);
}
return 0;

View File

@ -59,9 +59,9 @@ Copyright (c) .NET Foundation. All rights reserved.
<IncludeRazorContentInPack Condition="'$(IncludeRazorContentInPack)'==''">false</IncludeRazorContentInPack>
<!--
Set to true to allow a Razor code generation to use a persistent build server process.
Set to false to disable Razor code generation from using a persistent build server process.
-->
<UseRazorBuildServer Condition="'$(UseRazorBuildServer)'==''">false</UseRazorBuildServer>
<UseRazorBuildServer Condition="'$(UseRazorBuildServer)'==''">true</UseRazorBuildServer>
</PropertyGroup>
<ItemGroup Condition="'$(EnableDefaultItems)' == 'true' And '$(EnableDefaultContentItems)' == 'true'">

View File

@ -79,7 +79,7 @@ Copyright (c) .NET Foundation. All rights reserved.
Default values for properties that affect Razor targets to the standard build lifecycle.
-->
<PropertyGroup Condition="'$(RazorCompileOnBuild)'==''">
<RazorCompileOnBuild>false</RazorCompileOnBuild>
<RazorCompileOnBuild>true</RazorCompileOnBuild>
</PropertyGroup>
<PropertyGroup Condition="'$(RazorCompileOnPublish)'==''">

View File

@ -10,8 +10,13 @@ using Xunit;
namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
{
public class BuildIncrementalismTest : MSBuildIntegrationTestBase
public class BuildIncrementalismTest : MSBuildIntegrationTestBase, IClassFixture<BuildServerTestFixture>
{
public BuildIncrementalismTest(BuildServerTestFixture buildServer)
: base(buildServer)
{
}
[Fact]
[InitializeTestProject("SimpleMvc")]
public async Task BuildIncremental_SimpleMvc_PersistsTargetInputFile()
@ -20,7 +25,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
var thumbprintLookup = new Dictionary<string, FileThumbPrint>();
// Act 1
var result = await DotnetMSBuild("Build", $"/p:RazorCompileOnBuild=true");
var result = await DotnetMSBuild("Build");
var directoryPath = Path.Combine(result.Project.DirectoryPath, IntermediateOutputPath);
var filesToIgnore = new[]
@ -45,7 +50,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
// We want to make sure nothing changed between multiple incremental builds.
using (var razorGenDirectoryLock = LockDirectory(RazorIntermediateOutputPath))
{
result = await DotnetMSBuild("Build", $"/p:RazorCompileOnBuild=true");
result = await DotnetMSBuild("Build");
}
Assert.BuildPassed(result);
@ -63,7 +68,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
{
// Act - 1
var expectedTagHelperCacheContent = @"""Name"":""SimpleMvc.SimpleTagHelper""";
var result = await DotnetMSBuild("Build", "/p:RazorCompileOnBuild=true");
var result = await DotnetMSBuild("Build");
var file = Path.Combine(Project.DirectoryPath, "SimpleTagHelper.cs");
var tagHelperOutputCache = Path.Combine(IntermediateOutputPath, "SimpleMvc.TagHelpers.output.cache");
var generatedFile = Path.Combine(RazorIntermediateOutputPath, "Views", "Home", "Index.cs");
@ -76,7 +81,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
// Act - 2
// Update the source content and build. We should expect the outputs to be regenerated.
ReplaceContent(string.Empty, file);
result = await DotnetMSBuild("Build", "/p:RazorCompileOnBuild=true");
result = await DotnetMSBuild("Build");
// Assert - 2
Assert.BuildPassed(result);

View File

@ -12,23 +12,32 @@ using Xunit;
namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
{
public class BuildIntegrationTest : MSBuildIntegrationTestBase
public class BuildIntegrationTest : MSBuildIntegrationTestBase, IClassFixture<BuildServerTestFixture>
{
public BuildIntegrationTest(BuildServerTestFixture buildServer)
: base(buildServer)
{
}
[Fact]
[InitializeTestProject("SimpleMvc")]
public Task Build_SimpleMvc_UsingDotnetMSBuild_CanBuildSuccessfully()
=> Build_SimpleMvc_CanBuildSuccessfully(MSBuildProcessKind.Dotnet);
public Task Build_SimpleMvc_UsingDotnetMSBuildAndWithoutBuildServer_CanBuildSuccessfully()
=> Build_SimpleMvc_WithoutBuildServer_CanBuildSuccessfully(MSBuildProcessKind.Dotnet);
[ConditionalFact]
[OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)]
[InitializeTestProject("SimpleMvc")]
public Task Build_SimpleMvc_UsingDesktopMSBuild_CanBuildSuccessfully()
=> Build_SimpleMvc_CanBuildSuccessfully(MSBuildProcessKind.Desktop);
public Task Build_SimpleMvc_UsingDesktopMSBuildAndWithoutBuildServer_CanBuildSuccessfully()
=> Build_SimpleMvc_WithoutBuildServer_CanBuildSuccessfully(MSBuildProcessKind.Desktop);
private async Task Build_SimpleMvc_CanBuildSuccessfully(MSBuildProcessKind msBuildProcessKind)
// This test is identical to the ones in BuildServerIntegrationTest except this one explicitly disables the Razor build server.
private async Task Build_SimpleMvc_WithoutBuildServer_CanBuildSuccessfully(MSBuildProcessKind msBuildProcessKind)
{
var result = await DotnetMSBuild("Build", "/p:RazorCompileOnBuild=true", msBuildProcessKind: msBuildProcessKind);
var result = await DotnetMSBuild("Build",
"/p:UseRazorBuildServer=false",
suppressBuildServer: true,
msBuildProcessKind: msBuildProcessKind);
Assert.BuildPassed(result);
Assert.FileExists(result, OutputPath, "SimpleMvc.dll");
@ -50,7 +59,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
{
Directory.Delete(Path.Combine(Project.DirectoryPath, "Views"), recursive: true);
var result = await DotnetMSBuild("Build", "/p:RazorCompileOnBuild=true");
var result = await DotnetMSBuild("Build");
Assert.BuildPassed(result);
Assert.FileExists(result, OutputPath, "SimpleMvc.dll");
@ -61,9 +70,9 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[Fact]
[InitializeTestProject("SimpleMvc")]
public async Task Build_SimpleMvc_NoopsWithRazorCompileOnPublish()
public async Task Build_SimpleMvc_NoopsWithRazorCompileOnBuild_False()
{
var result = await DotnetMSBuild("Build", "/p:RazorCompileOnPublish=true");
var result = await DotnetMSBuild("Build", "/p:RazorCompileOnBuild=false");
Assert.BuildPassed(result);
Assert.FileExists(result, OutputPath, "SimpleMvc.dll");
@ -79,7 +88,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
// Introducing a C# semantic error
ReplaceContent("@{ var foo = \"\".Substring(\"bleh\"); }", "Views", "Home", "Index.cshtml");
var result = await DotnetMSBuild("Build", "/p:RazorCompileOnBuild=true");
var result = await DotnetMSBuild("Build");
Assert.BuildFailed(result);
@ -95,7 +104,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[InitializeTestProject("SimplePages")]
public async Task Build_Works_WhenFilesAtDifferentPathsHaveSameNamespaceHierarchy()
{
var result = await DotnetMSBuild("Build", "/p:RazorCompileOnBuild=true");
var result = await DotnetMSBuild("Build");
Assert.BuildPassed(result);
@ -108,7 +117,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
public async Task Build_RazorOutputPath_SetToNonDefault()
{
var customOutputPath = Path.Combine("bin", Configuration, TargetFramework, "Razor");
var result = await DotnetMSBuild("Build", $"/p:RazorCompileOnBuild=true /p:RazorOutputPath={customOutputPath}");
var result = await DotnetMSBuild("Build", $"/p:RazorOutputPath={customOutputPath}");
Assert.BuildPassed(result);
@ -124,7 +133,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
public async Task Build_MvcRazorOutputPath_SetToNonDefault()
{
var customOutputPath = Path.Combine("bin", Configuration, TargetFramework, "Razor");
var result = await DotnetMSBuild("Build", $"/p:RazorCompileOnBuild=true /p:MvcRazorOutputPath={customOutputPath}");
var result = await DotnetMSBuild("Build", $"/p:MvcRazorOutputPath={customOutputPath}");
Assert.BuildPassed(result);
@ -139,7 +148,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[InitializeTestProject("SimpleMvc")]
public async Task Build_SkipsCopyingBinariesToOutputDirectory_IfCopyBuildOutputToOutputDirectory_IsUnset()
{
var result = await DotnetMSBuild("Build", "/p:RazorCompileOnBuild=true /p:CopyBuildOutputToOutputDirectory=false");
var result = await DotnetMSBuild("Build", "/p:CopyBuildOutputToOutputDirectory=false");
Assert.BuildPassed(result);
@ -154,7 +163,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[InitializeTestProject("SimpleMvc")]
public async Task Build_SkipsCopyingBinariesToOutputDirectory_IfCopyOutputSymbolsToOutputDirectory_IsUnset()
{
var result = await DotnetMSBuild("Build", "/p:RazorCompileOnBuild=true /p:CopyOutputSymbolsToOutputDirectory=false");
var result = await DotnetMSBuild("Build", "/p:CopyOutputSymbolsToOutputDirectory=false");
Assert.BuildPassed(result);
@ -168,7 +177,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[InitializeTestProject("SimpleMvc")]
public async Task Build_Works_WhenSymbolsAreNotGenerated()
{
var result = await DotnetMSBuild("Build", "/p:RazorCompileOnBuild=true /p:DebugType=none");
var result = await DotnetMSBuild("Build", "/p:DebugType=none");
Assert.BuildPassed(result);
@ -184,7 +193,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[InitializeTestProject("AppWithP2PReference", "ClassLibrary")]
public async Task Build_WithP2P_CopiesRazorAssembly()
{
var result = await DotnetMSBuild("Build", "/p:RazorCompileOnBuild=true");
var result = await DotnetMSBuild("Build");
Assert.BuildPassed(result);
@ -211,7 +220,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
AddProjectFileContent(additionalProjectContent);
Directory.CreateDirectory(Path.Combine(Project.DirectoryPath, "..", "LinkedDir"));
var result = await DotnetMSBuild("Build", "/t:_IntrospectRazorEmbeddedResources /p:RazorCompileOnBuild=true /p:EmbedRazorGenerateSources=true");
var result = await DotnetMSBuild("Build", "/t:_IntrospectRazorEmbeddedResources /p:EmbedRazorGenerateSources=true");
Assert.BuildPassed(result);

View File

@ -7,13 +7,18 @@ using Xunit;
namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
{
public class BuildIntrospectionTest : MSBuildIntegrationTestBase
public class BuildIntrospectionTest : MSBuildIntegrationTestBase, IClassFixture<BuildServerTestFixture>
{
public BuildIntrospectionTest(BuildServerTestFixture buildServer)
: base(buildServer)
{
}
[Fact]
[InitializeTestProject("SimpleMvc")]
public async Task RazorSdk_AddsCshtmlFilesToUpToDateCheckInput()
{
var result = await DotnetMSBuild("_IntrospectUpToDateCheckInput", "/p:RazorCompileOnBuild=true");
var result = await DotnetMSBuild("_IntrospectUpToDateCheckInput");
Assert.BuildPassed(result);
Assert.BuildOutputContainsLine(result, $"UpToDateCheckInput: {Path.Combine("Views", "Home", "Index.cshtml")}");

View File

@ -10,11 +10,9 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
{
public class BuildServerIntegrationTest : MSBuildIntegrationTestBase, IClassFixture<BuildServerTestFixture>
{
private readonly string _pipeName;
public BuildServerIntegrationTest(BuildServerTestFixture fixture)
public BuildServerIntegrationTest(BuildServerTestFixture buildServer)
: base(buildServer)
{
_pipeName = fixture.PipeName;
}
[Fact]
@ -32,7 +30,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
{
var result = await DotnetMSBuild(
"Build",
$"/p:RazorCompileOnBuild=true /p:UseRazorBuildServer=true /p:_RazorBuildServerPipeName={_pipeName} /p:_RazorForceBuildServer=true",
"/p:_RazorForceBuildServer=true",
msBuildProcessKind: msBuildProcessKind);
Assert.BuildPassed(result);
@ -59,7 +57,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
{
var result = await DotnetMSBuild(
"Build",
$"/p:RazorCompileOnBuild=true /p:UseRazorBuildServer=true /p:_RazorBuildServerPipeName={_pipeName} /p:_RazorForceBuildServer=true");
"/p:_RazorForceBuildServer=true");
Assert.BuildPassed(result);
Assert.FileExists(result, OutputPath, "SimpleMvc.dll");
@ -74,7 +72,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
{
var result = await DotnetMSBuild(
"Build",
$"/p:RazorCompileOnBuild=true /p:UseRazorBuildServer=true /p:_RazorBuildServerPipeName={_pipeName} /p:_RazorForceBuildServer=true");
"/p:_RazorForceBuildServer=true");
Assert.BuildPassed(result);
Assert.FileExists(result, OutputPath, "Whitespace in name.dll");

View File

@ -31,16 +31,23 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
// Shutdown the build server.
using (var cts = new CancellationTokenSource(_defaultShutdownTimeout))
{
var writer = new StringWriter();
cts.Token.Register(() =>
{
throw new TimeoutException($"Shutting down the build server at pipe {PipeName} took longer than expected.");
var output = writer.ToString();
throw new TimeoutException($"Shutting down the build server at pipe {PipeName} took longer than expected.{Environment.NewLine}Output: {output}.");
});
var application = new Application(cts.Token, Mock.Of<ExtensionAssemblyLoader>(), Mock.Of<ExtensionDependencyChecker>(), (path, properties) => Mock.Of<PortableExecutableReference>());
var application = new Application(cts.Token, Mock.Of<ExtensionAssemblyLoader>(), Mock.Of<ExtensionDependencyChecker>(), (path, properties) => Mock.Of<PortableExecutableReference>())
{
Out = writer,
Error = writer,
};
var exitCode = application.Execute("shutdown", "-w", "-p", PipeName);
if (exitCode != 0)
{
var output = application.Error.ToString();
var output = writer.ToString();
throw new InvalidOperationException(
$"Build server at pipe {PipeName} failed to shutdown with exit code {exitCode}. Output: {output}");
}

View File

@ -7,13 +7,18 @@ using Xunit;
namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
{
public class ConfigurationMetadataIntegrationTest : MSBuildIntegrationTestBase
public class ConfigurationMetadataIntegrationTest : MSBuildIntegrationTestBase, IClassFixture<BuildServerTestFixture>
{
public ConfigurationMetadataIntegrationTest(BuildServerTestFixture buildServer)
: base(buildServer)
{
}
[Fact]
[InitializeTestProject("SimpleMvc")]
public async Task Build_WithMvc_AddsConfigurationMetadata()
{
var result = await DotnetMSBuild("Build", $"/p:RazorCompileOnBuild=true");
var result = await DotnetMSBuild("Build");
Assert.BuildPassed(result);
@ -39,7 +44,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[InitializeTestProject("SimpleMvc")]
public async Task Build_WithGenerateRazorAssemblyInfo_False_SuppressesConfigurationMetadata()
{
var result = await DotnetMSBuild("Build", $"/p:RazorCompileOnBuild=true /p:GenerateRazorAssemblyInfo=false");
var result = await DotnetMSBuild("Build", "/p:GenerateRazorAssemblyInfo=false");
Assert.BuildPassed(result);
@ -67,7 +72,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
{
TargetFramework = "netstandard2.0";
var result = await DotnetMSBuild("Build", $"/p:RazorCompileOnBuild=true");
var result = await DotnetMSBuild("Build");
Assert.BuildPassed(result);

View File

@ -6,15 +6,20 @@ using Xunit;
namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
{
public class DesignTimeBuildIntegrationTest : MSBuildIntegrationTestBase
public class DesignTimeBuildIntegrationTest : MSBuildIntegrationTestBase, IClassFixture<BuildServerTestFixture>
{
public DesignTimeBuildIntegrationTest(BuildServerTestFixture buildServer)
: base(buildServer)
{
}
[Fact]
[InitializeTestProject("SimpleMvc")]
public async Task DesignTimeBuild_DoesNotRunRazorTargets()
{
// Using Compile here instead of CompileDesignTime because the latter is only defined when using
// the VS targets. This is a close enough simulation for an SDK project
var result = await DotnetMSBuild("Compile", "/p:RazorCompileOnBuild=true /p:DesignTimeBuild=true /clp:PerformanceSummary");
var result = await DotnetMSBuild("Compile", "/p:DesignTimeBuild=true /clp:PerformanceSummary");
Assert.BuildPassed(result);
Assert.FileDoesNotExist(result, OutputPath, "SimpleMvc.dll");

View File

@ -15,8 +15,9 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
{
private static readonly AsyncLocal<ProjectDirectory> _project = new AsyncLocal<ProjectDirectory>();
protected MSBuildIntegrationTestBase()
protected MSBuildIntegrationTestBase(BuildServerTestFixture buildServer)
{
BuildServer = buildServer;
}
#if DEBUG
@ -44,19 +45,35 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
protected string TargetFramework { get; set; } = "netcoreapp2.0";
protected BuildServerTestFixture BuildServer { get; set; }
internal Task<MSBuildResult> DotnetMSBuild(
string target,
string args = null,
bool suppressRestore = false,
bool suppressTimeout = false,
bool suppressBuildServer = false,
MSBuildProcessKind msBuildProcessKind = MSBuildProcessKind.Dotnet)
{
var timeout = suppressTimeout ? (TimeSpan?)Timeout.InfiniteTimeSpan : null;
var restoreArgument = suppressRestore ? "" : "/restore";
var buildArgumentList = new List<string>();
if (!suppressRestore)
{
buildArgumentList.Add("/restore");
}
if (!suppressBuildServer)
{
buildArgumentList.Add($"/p:_RazorBuildServerPipeName={BuildServer.PipeName}");
}
buildArgumentList.Add($"/t:{target} /p:Configuration={Configuration} {args}");
var buildArguments = string.Join(" ", buildArgumentList);
return MSBuildProcessManager.RunProcessAsync(
Project,
$"{restoreArgument} /t:{target} /p:Configuration={Configuration} {args}",
buildArguments,
timeout,
msBuildProcessKind);
}

View File

@ -8,14 +8,19 @@ using Xunit;
namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
{
public class PackIntegrationTest : MSBuildIntegrationTestBase
public class PackIntegrationTest : MSBuildIntegrationTestBase, IClassFixture<BuildServerTestFixture>
{
public PackIntegrationTest(BuildServerTestFixture buildServer)
: base(buildServer)
{
}
[Fact]
[InitializeTestProject("ClassLibrary")]
public async Task Pack_Works_IncludesRazorAssembly()
{
TargetFramework = "netstandard2.0";
var result = await DotnetMSBuild("Pack", "/p:RazorCompileOnBuild=true");
var result = await DotnetMSBuild("Pack");
Assert.BuildPassed(result);
@ -85,7 +90,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
public async Task Pack_IncludesRazorFilesAsContent_WhenIncludeRazorContentInPack_IsSet()
{
TargetFramework = "netstandard2.0";
var result = await DotnetMSBuild("Pack", "/p:RazorCompileOnBuild=true /p:IncludeRazorContentInPack=true");
var result = await DotnetMSBuild("Pack", "/p:IncludeRazorContentInPack=true");
Assert.BuildPassed(result);

View File

@ -7,8 +7,13 @@ using Xunit;
namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
{
public class PublishIntegrationTest : MSBuildIntegrationTestBase
public class PublishIntegrationTest : MSBuildIntegrationTestBase, IClassFixture<BuildServerTestFixture>
{
public PublishIntegrationTest(BuildServerTestFixture buildServer)
: base(buildServer)
{
}
[Fact]
[InitializeTestProject("SimpleMvc")]
public async Task Publish_RazorCompileOnPublish_IsDefault()
@ -17,9 +22,6 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
Assert.BuildPassed(result);
Assert.FileDoesNotExist(result, OutputPath, "SimpleMvc.Views.dll");
Assert.FileDoesNotExist(result, OutputPath, "SimpleMvc.Views.pdb");
Assert.FileExists(result, PublishOutputPath, "SimpleMvc.dll");
Assert.FileExists(result, PublishOutputPath, "SimpleMvc.pdb");
Assert.FileExists(result, PublishOutputPath, "SimpleMvc.Views.dll");
@ -32,9 +34,9 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[Fact]
[InitializeTestProject("SimpleMvc")]
public async Task Publish_WithRazorCompileOnBuild_PublishesAssembly()
public async Task Publish_PublishesAssembly()
{
var result = await DotnetMSBuild("Publish", "/p:RazorCompileOnBuild=true");
var result = await DotnetMSBuild("Publish");
Assert.BuildPassed(result);
@ -57,7 +59,26 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[InitializeTestProject("SimpleMvc")]
public async Task Publish_WithRazorCompileOnPublish_PublishesAssembly()
{
var result = await DotnetMSBuild("Publish", "/p:RazorCompileOnPublish=true");
var result = await DotnetMSBuild("Publish");
Assert.BuildPassed(result);
Assert.FileExists(result, PublishOutputPath, "SimpleMvc.dll");
Assert.FileExists(result, PublishOutputPath, "SimpleMvc.pdb");
Assert.FileExists(result, PublishOutputPath, "SimpleMvc.Views.dll");
Assert.FileExists(result, PublishOutputPath, "SimpleMvc.Views.pdb");
// By default refs and .cshtml files will not be copied on publish
Assert.FileCountEquals(result, 0, Path.Combine(PublishOutputPath, "refs"), "*.dll");
Assert.FileCountEquals(result, 0, Path.Combine(PublishOutputPath, "Views"), "*.cshtml");
}
[Fact]
[InitializeTestProject("SimpleMvc")]
public async Task Publish_WithRazorCompileOnBuildFalse_PublishesAssembly()
{
// RazorCompileOnBuild is turned off, but RazorCompileOnPublish should still be enabled
var result = await DotnetMSBuild("Publish", "/p:RazorCompileOnBuild=false");
Assert.BuildPassed(result);
@ -96,9 +117,6 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
Assert.BuildPassed(result);
Assert.FileDoesNotExist(result, OutputPath, "SimpleMvc.Views.dll");
Assert.FileDoesNotExist(result, OutputPath, "SimpleMvc.Views.pdb");
Assert.FileExists(result, PublishOutputPath, "SimpleMvc.dll");
Assert.FileExists(result, PublishOutputPath, "SimpleMvc.pdb");
Assert.FileExists(result, PublishOutputPath, "SimpleMvc.Views.dll");
@ -115,7 +133,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
{
Directory.Delete(Path.Combine(Project.DirectoryPath, "Views"), recursive: true);
var result = await DotnetMSBuild("Publish", "/p:RazorCompileOnBuild=true");
var result = await DotnetMSBuild("Publish");
Assert.BuildPassed(result);
@ -162,7 +180,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[InitializeTestProject("SimpleMvc")]
public async Task Publish_SkipsCopyingBinariesToOutputDirectory_IfCopyBuildOutputToOutputDirectory_IsUnset()
{
var result = await DotnetMSBuild("Publish", "/p:RazorCompileOnBuild=true /p:CopyBuildOutputToPublishDirectory=false");
var result = await DotnetMSBuild("Publish", "/p:CopyBuildOutputToPublishDirectory=false");
Assert.BuildPassed(result);
@ -177,7 +195,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[InitializeTestProject("SimpleMvc")]
public async Task Publish_SkipsCopyingBinariesToOutputDirectory_IfCopyOutputSymbolsToOutputDirectory_IsUnset()
{
var result = await DotnetMSBuild("Publish", "/p:RazorCompileOnBuild=true /p:CopyOutputSymbolsToPublishDirectory=false");
var result = await DotnetMSBuild("Publish", "/p:CopyOutputSymbolsToPublishDirectory=false");
Assert.BuildPassed(result);
@ -191,7 +209,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[InitializeTestProject("SimpleMvc")]
public async Task Publish_Works_WhenSymbolsAreNotGenerated()
{
var result = await DotnetMSBuild("Publish", "/p:RazorCompileOnBuild=true /p:DebugType=none");
var result = await DotnetMSBuild("Publish", "/p:DebugType=none");
Assert.BuildPassed(result);
@ -207,13 +225,10 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[InitializeTestProject("SimpleMvc")]
public async Task Publish_IncludeCshtmlAndRefAssemblies_CopiesFiles()
{
var result = await DotnetMSBuild("Publish", "/p:RazorCompileOnPublish=true /p:CopyRazorGenerateFilesToPublishDirectory=true /p:CopyRefAssembliesToPublishDirectory=true");
var result = await DotnetMSBuild("Publish", "/p:CopyRazorGenerateFilesToPublishDirectory=true /p:CopyRefAssembliesToPublishDirectory=true");
Assert.BuildPassed(result);
Assert.FileDoesNotExist(result, OutputPath, "SimpleMvc.Views.dll");
Assert.FileDoesNotExist(result, OutputPath, "SimpleMvc.Views.pdb");
Assert.FileExists(result, PublishOutputPath, "SimpleMvc.dll");
Assert.FileExists(result, PublishOutputPath, "SimpleMvc.pdb");
Assert.FileExists(result, PublishOutputPath, "SimpleMvc.Views.dll");
@ -228,13 +243,10 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[InitializeTestProject("SimpleMvc")]
public async Task Publish_MvcRazorExcludeFilesFromPublish_False_CopiesFiles()
{
var result = await DotnetMSBuild("Publish", "/p:RazorCompileOnPublish=true /p:MvcRazorExcludeViewFilesFromPublish=false /p:MvcRazorExcludeRefAssembliesFromPublish=false");
var result = await DotnetMSBuild("Publish", "/p:MvcRazorExcludeViewFilesFromPublish=false /p:MvcRazorExcludeRefAssembliesFromPublish=false");
Assert.BuildPassed(result);
Assert.FileDoesNotExist(result, OutputPath, "SimpleMvc.Views.dll");
Assert.FileDoesNotExist(result, OutputPath, "SimpleMvc.Views.pdb");
Assert.FileExists(result, PublishOutputPath, "SimpleMvc.dll");
Assert.FileExists(result, PublishOutputPath, "SimpleMvc.pdb");
Assert.FileExists(result, PublishOutputPath, "SimpleMvc.Views.dll");
@ -249,7 +261,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[InitializeTestProject("AppWithP2PReference", "ClassLibrary")]
public async Task Publish_WithP2P_AndRazorCompileOnBuild_CopiesRazorAssembly()
{
var result = await DotnetMSBuild("Publish", "/p:RazorCompileOnBuild=true");
var result = await DotnetMSBuild("Publish");
Assert.BuildPassed(result);
@ -267,15 +279,10 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[InitializeTestProject("AppWithP2PReference", "ClassLibrary")]
public async Task Publish_WithP2P_AndRazorCompileOnPublish_CopiesRazorAssembly()
{
var result = await DotnetMSBuild("Publish", "/p:RazorCompileOnPublish=true");
var result = await DotnetMSBuild("Publish");
Assert.BuildPassed(result);
Assert.FileDoesNotExist(result, OutputPath, "AppWithP2PReference.Views.dll");
Assert.FileDoesNotExist(result, OutputPath, "AppWithP2PReference.Views.pdb");
Assert.FileDoesNotExist(result, OutputPath, "ClassLibrary.Views.dll");
Assert.FileDoesNotExist(result, OutputPath, "ClassLibrary.Views.pdb");
Assert.FileExists(result, PublishOutputPath, "AppWithP2PReference.dll");
Assert.FileExists(result, PublishOutputPath, "AppWithP2PReference.pdb");
Assert.FileExists(result, PublishOutputPath, "AppWithP2PReference.Views.dll");

View File

@ -9,8 +9,13 @@ using Xunit;
namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
{
public class RazorCompileIntegrationTest : MSBuildIntegrationTestBase
public class RazorCompileIntegrationTest : MSBuildIntegrationTestBase, IClassFixture<BuildServerTestFixture>
{
public RazorCompileIntegrationTest(BuildServerTestFixture buildServer)
: base(buildServer)
{
}
[Fact]
[InitializeTestProject("SimpleMvc")]
public async Task RazorCompile_Success_CompilesAssembly()

View File

@ -10,10 +10,15 @@ using Xunit;
namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
{
public class RazorGenerateIntegrationTest : MSBuildIntegrationTestBase
public class RazorGenerateIntegrationTest : MSBuildIntegrationTestBase, IClassFixture<BuildServerTestFixture>
{
private const string RazorGenerateTarget = "RazorGenerate";
public RazorGenerateIntegrationTest(BuildServerTestFixture buildServer)
: base(buildServer)
{
}
[Fact]
[InitializeTestProject("SimpleMvc")]
public async Task RazorGenerate_Success_GeneratesFilesOnDisk()

View File

@ -1,4 +1,5 @@
{
"methodDisplay": "method",
"shadowCopy": false
"shadowCopy": false,
"maxParallelThreads": -1
}

View File

@ -21,7 +21,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
var alphaFilePath = LoaderTestResources.Alpha.WriteToFile(directory.DirectoryPath, "Alpha.dll");
var loader = new TestDefaultExtensionAssemblyLoader(Path.Combine(directory.DirectoryPath, "shadow"));
var checker = new DefaultExtensionDependencyChecker(loader, output);
var checker = new DefaultExtensionDependencyChecker(loader, output, output);
// Act
var result = checker.Check(new[] { alphaFilePath, });
@ -45,7 +45,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
var deltaFilePath = LoaderTestResources.Delta.WriteToFile(directory.DirectoryPath, "Delta.dll");
var loader = new TestDefaultExtensionAssemblyLoader(Path.Combine(directory.DirectoryPath, "shadow"));
var checker = new DefaultExtensionDependencyChecker(loader, output);
var checker = new DefaultExtensionDependencyChecker(loader, output, output);
// Act
var result = checker.Check(new[] { alphaFilePath, betaFilePath, gammaFilePath, deltaFilePath, });
@ -70,7 +70,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
var deltaFilePath = LoaderTestResources.Delta.WriteToFile(directory.DirectoryPath, "Delta.dll");
var loader = new TestDefaultExtensionAssemblyLoader(Path.Combine(directory.DirectoryPath, "shadow"));
var checker = new DefaultExtensionDependencyChecker(loader, output);
var checker = new DefaultExtensionDependencyChecker(loader, output, output);
// This will cause the loader to cache some inconsistent information.
loader.LoadFromPath(alphaFilePath);
@ -98,7 +98,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
loader
.Setup(l => l.LoadFromPath(It.IsAny<string>()))
.Throws(new InvalidOperationException());
var checker = new DefaultExtensionDependencyChecker(loader.Object, output);
var checker = new DefaultExtensionDependencyChecker(loader.Object, output, output);
// Act
var result = checker.Check(new[] { deltaFilePath, });

View File

@ -26,7 +26,8 @@ namespace Microsoft.AspNetCore.Razor.Tools
internal static ServerData CreateServer(
string pipeName = null,
CompilerHost compilerHost = null,
ConnectionHost connectionHost = null)
ConnectionHost connectionHost = null,
Action<object, EventArgs> onListening = null)
{
pipeName = pipeName ?? Guid.NewGuid().ToString();
compilerHost = compilerHost ?? CompilerHost.Create();
@ -40,6 +41,10 @@ namespace Microsoft.AspNetCore.Razor.Tools
{
var eventBus = new TestableEventBus();
eventBus.Listening += (sender, e) => { serverListenSource.TrySetResult(true); };
if (onListening != null)
{
eventBus.Listening += (sender, e) => onListening(sender, e);
}
try
{
RunServer(

View File

@ -116,17 +116,19 @@ namespace Microsoft.AspNetCore.Razor.Tools
/// A shutdown request should not abort an existing compilation. It should be allowed to run to
/// completion.
/// </summary>
// Skipping temporarily on non-windows. https://github.com/aspnet/Razor/issues/1991
[ConditionalFact]
[OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)]
[Fact]
public async Task ServerRunning_ShutdownRequest_DoesNotAbortCompilation()
{
// Arrange
var completionSource = new TaskCompletionSource<bool>();
var startCompilationSource = new TaskCompletionSource<bool>();
var finishCompilationSource = new TaskCompletionSource<bool>();
var host = CreateCompilerHost(c => c.ExecuteFunc = (req, ct) =>
{
// At this point, the connection has been accepted and the compilation has started.
startCompilationSource.SetResult(true);
// We want this to keep running even after the shutdown is seen.
completionSource.Task.Wait();
finishCompilationSource.Task.Wait();
return EmptyServerResponse;
});
@ -134,13 +136,16 @@ namespace Microsoft.AspNetCore.Razor.Tools
{
var compileTask = ServerUtilities.Send(serverData.PipeName, EmptyServerRequest);
// Wait for the request to go through and trigger compilation.
await startCompilationSource.Task;
// Act
// The compilation is now in progress, send the shutdown.
await ServerUtilities.SendShutdown(serverData.PipeName);
Assert.False(compileTask.IsCompleted);
// Now let the task complete.
completionSource.SetResult(true);
finishCompilationSource.SetResult(true);
// Assert
var response = await compileTask;
@ -154,17 +159,19 @@ namespace Microsoft.AspNetCore.Razor.Tools
/// <summary>
/// Multiple clients should be able to send shutdown requests to the server.
/// </summary>
// Skipping temporarily on non-windows. https://github.com/aspnet/Razor/issues/1991
[ConditionalFact]
[OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)]
[Fact]
public async Task ServerRunning_MultipleShutdownRequests_HandlesSuccessfully()
{
// Arrange
var completionSource = new TaskCompletionSource<bool>();
var startCompilationSource = new TaskCompletionSource<bool>();
var finishCompilationSource = new TaskCompletionSource<bool>();
var host = CreateCompilerHost(c => c.ExecuteFunc = (req, ct) =>
{
// At this point, the connection has been accepted and the compilation has started.
startCompilationSource.SetResult(true);
// We want this to keep running even after the shutdown is seen.
completionSource.Task.Wait();
finishCompilationSource.Task.Wait();
return EmptyServerResponse;
});
@ -172,6 +179,9 @@ namespace Microsoft.AspNetCore.Razor.Tools
{
var compileTask = ServerUtilities.Send(serverData.PipeName, EmptyServerRequest);
// Wait for the request to go through and trigger compilation.
await startCompilationSource.Task;
// Act
for (var i = 0; i < 10; i++)
{
@ -182,7 +192,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
}
// Now let the task complete.
completionSource.SetResult(true);
finishCompilationSource.SetResult(true);
// Assert
var response = await compileTask;
@ -193,7 +203,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
}
}
// Skipping temporarily on non-windows. https://github.com/aspnet/Razor/issues/1991
// https://github.com/aspnet/Razor/issues/1991
[ConditionalFact]
[OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)]
public async Task ServerRunning_CancelCompilation_CancelsSuccessfully()
@ -213,18 +223,28 @@ namespace Microsoft.AspNetCore.Razor.Tools
return new RejectedServerResponse();
});
using (var serverData = ServerUtilities.CreateServer(compilerHost: host))
var semaphore = new SemaphoreSlim(1);
Action<object, EventArgs> onListening = (s, e) =>
{
var tasks = new List<Task<ServerResponse>>();
semaphore.Release();
};
using (var serverData = ServerUtilities.CreateServer(compilerHost: host, onListening: onListening))
{
// Send all the requests.
var clients = new List<Client>();
for (var i = 0; i < requestCount; i++)
{
var task = ServerUtilities.Send(serverData.PipeName, EmptyServerRequest);
tasks.Add(task);
// Wait for the server to start listening.
await semaphore.WaitAsync(TimeSpan.FromMinutes(1));
var client = await Client.ConnectAsync(serverData.PipeName, timeout: null, cancellationToken: default);
await EmptyServerRequest.WriteAsync(client.Stream);
clients.Add(client);
}
// Act
// Wait until all of the connections are being processed by the server.
completionSource.Task.Wait();
await completionSource.Task;
// Now cancel
var stats = await serverData.CancelAndCompleteAsync();
@ -233,10 +253,13 @@ namespace Microsoft.AspNetCore.Razor.Tools
Assert.Equal(requestCount, stats.Connections);
Assert.Equal(requestCount, count);
foreach (var task in tasks)
// Read the server response to each client.
foreach (var client in clients)
{
var task = ServerResponse.ReadAsync(client.Stream);
// We expect this to throw because the stream is already closed.
await Assert.ThrowsAsync<EndOfStreamException>(() => task);
await Assert.ThrowsAnyAsync<IOException>(() => task);
client.Dispose();
}
}
}

View File

@ -5,7 +5,8 @@
<PackageVersion Condition="'$(IsFinalBuild)' == 'true' AND '$(VersionSuffix)' == 'rtm' ">$(VersionPrefix)</PackageVersion>
<PackageVersion Condition="'$(IsFinalBuild)' == 'true' AND '$(VersionSuffix)' != 'rtm' ">$(VersionPrefix)-$(VersionSuffix)-final</PackageVersion>
<BuildNumber Condition="'$(BuildNumber)' == ''">t000</BuildNumber>
<VersionSuffix Condition="'$(VersionSuffix)' != '' And '$(FeatureBranchVersionSuffix)' != ''">$(VersionSuffix)-$([System.Text.RegularExpressions.Regex]::Replace('$(FeatureBranchVersionSuffix)', '[^\w-]', '-'))</VersionSuffix>
<FeatureBranchVersionPrefix Condition="'$(FeatureBranchVersionPrefix)' == ''">a-</FeatureBranchVersionPrefix>
<VersionSuffix Condition="'$(VersionSuffix)' != '' And '$(FeatureBranchVersionSuffix)' != ''">$(FeatureBranchVersionPrefix)$(VersionSuffix)-$([System.Text.RegularExpressions.Regex]::Replace('$(FeatureBranchVersionSuffix)', '[^\w-]', '-'))</VersionSuffix>
<VersionSuffix Condition="'$(VersionSuffix)' != '' And '$(BuildNumber)' != ''">$(VersionSuffix)-$(BuildNumber)</VersionSuffix>
<!-- VS for Mac does not like letters in package versions -->
<AddinBuildNumber Condition="'$(BuildNumber)' == 't000'">99999</AddinBuildNumber>