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

View File

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

View File

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

View File

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

View File

@ -26,15 +26,18 @@ namespace Microsoft.AspNetCore.Razor.Tools
private readonly ExtensionAssemblyLoader _loader; private readonly ExtensionAssemblyLoader _loader;
private readonly TextWriter _output; private readonly TextWriter _output;
private readonly TextWriter _error;
private readonly string[] _ignoredAssemblies; private readonly string[] _ignoredAssemblies;
public DefaultExtensionDependencyChecker( public DefaultExtensionDependencyChecker(
ExtensionAssemblyLoader loader, ExtensionAssemblyLoader loader,
TextWriter output, TextWriter output,
TextWriter error,
string[] ignoredAssemblies = null) string[] ignoredAssemblies = null)
{ {
_loader = loader; _loader = loader;
_output = output; _output = output;
_error = error;
_ignoredAssemblies = ignoredAssemblies ?? DefaultIgnoredAssemblies; _ignoredAssemblies = ignoredAssemblies ?? DefaultIgnoredAssemblies;
} }
@ -46,8 +49,8 @@ namespace Microsoft.AspNetCore.Razor.Tools
} }
catch (Exception ex) catch (Exception ex)
{ {
_output.WriteLine("Exception performing Extension dependency check:"); _error.WriteLine("Exception performing Extension dependency check:");
_output.WriteLine(ex.ToString()); _error.WriteLine(ex.ToString());
return false; return false;
} }
} }
@ -64,7 +67,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
if (!Path.IsPathRooted(item.FilePath)) 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; 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. // 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; return false;
} }
} }
@ -110,7 +113,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
var item = items[i]; var item = items[i];
if (item.Mvid != item.Assembly.ManifestModule.ModuleVersionId) 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; return false;
} }
} }

View File

@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
// Prevent shadow copying. // Prevent shadow copying.
var loader = new DefaultExtensionAssemblyLoader(baseDirectory: null); 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( var application = new Application(
cancel.Token, cancel.Token,

View File

@ -57,19 +57,21 @@ namespace Microsoft.AspNetCore.Razor.Tools
var process = Process.GetProcessById(response.ServerProcessId); var process = Process.GetProcessById(response.ServerProcessId);
process.WaitForExit(); process.WaitForExit();
} }
catch (Exception) catch (Exception ex)
{ {
// There is an inherent race here with the server process. If it has already shutdown // 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); 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. // Ignore an exception that occurred while the server was shutting down.
Error.Write(ex);
} }
return 0; return 0;

View File

@ -59,9 +59,9 @@ Copyright (c) .NET Foundation. All rights reserved.
<IncludeRazorContentInPack Condition="'$(IncludeRazorContentInPack)'==''">false</IncludeRazorContentInPack> <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> </PropertyGroup>
<ItemGroup Condition="'$(EnableDefaultItems)' == 'true' And '$(EnableDefaultContentItems)' == 'true'"> <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. Default values for properties that affect Razor targets to the standard build lifecycle.
--> -->
<PropertyGroup Condition="'$(RazorCompileOnBuild)'==''"> <PropertyGroup Condition="'$(RazorCompileOnBuild)'==''">
<RazorCompileOnBuild>false</RazorCompileOnBuild> <RazorCompileOnBuild>true</RazorCompileOnBuild>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(RazorCompileOnPublish)'==''"> <PropertyGroup Condition="'$(RazorCompileOnPublish)'==''">

View File

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

View File

@ -12,23 +12,32 @@ using Xunit;
namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
{ {
public class BuildIntegrationTest : MSBuildIntegrationTestBase public class BuildIntegrationTest : MSBuildIntegrationTestBase, IClassFixture<BuildServerTestFixture>
{ {
public BuildIntegrationTest(BuildServerTestFixture buildServer)
: base(buildServer)
{
}
[Fact] [Fact]
[InitializeTestProject("SimpleMvc")] [InitializeTestProject("SimpleMvc")]
public Task Build_SimpleMvc_UsingDotnetMSBuild_CanBuildSuccessfully() public Task Build_SimpleMvc_UsingDotnetMSBuildAndWithoutBuildServer_CanBuildSuccessfully()
=> Build_SimpleMvc_CanBuildSuccessfully(MSBuildProcessKind.Dotnet); => Build_SimpleMvc_WithoutBuildServer_CanBuildSuccessfully(MSBuildProcessKind.Dotnet);
[ConditionalFact] [ConditionalFact]
[OSSkipCondition(OperatingSystems.Linux)] [OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)] [OSSkipCondition(OperatingSystems.MacOSX)]
[InitializeTestProject("SimpleMvc")] [InitializeTestProject("SimpleMvc")]
public Task Build_SimpleMvc_UsingDesktopMSBuild_CanBuildSuccessfully() public Task Build_SimpleMvc_UsingDesktopMSBuildAndWithoutBuildServer_CanBuildSuccessfully()
=> Build_SimpleMvc_CanBuildSuccessfully(MSBuildProcessKind.Desktop); => 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.BuildPassed(result);
Assert.FileExists(result, OutputPath, "SimpleMvc.dll"); 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); 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.BuildPassed(result);
Assert.FileExists(result, OutputPath, "SimpleMvc.dll"); Assert.FileExists(result, OutputPath, "SimpleMvc.dll");
@ -61,9 +70,9 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[Fact] [Fact]
[InitializeTestProject("SimpleMvc")] [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.BuildPassed(result);
Assert.FileExists(result, OutputPath, "SimpleMvc.dll"); Assert.FileExists(result, OutputPath, "SimpleMvc.dll");
@ -79,7 +88,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
// Introducing a C# semantic error // Introducing a C# semantic error
ReplaceContent("@{ var foo = \"\".Substring(\"bleh\"); }", "Views", "Home", "Index.cshtml"); 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); Assert.BuildFailed(result);
@ -95,7 +104,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[InitializeTestProject("SimplePages")] [InitializeTestProject("SimplePages")]
public async Task Build_Works_WhenFilesAtDifferentPathsHaveSameNamespaceHierarchy() public async Task Build_Works_WhenFilesAtDifferentPathsHaveSameNamespaceHierarchy()
{ {
var result = await DotnetMSBuild("Build", "/p:RazorCompileOnBuild=true"); var result = await DotnetMSBuild("Build");
Assert.BuildPassed(result); Assert.BuildPassed(result);
@ -108,7 +117,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
public async Task Build_RazorOutputPath_SetToNonDefault() public async Task Build_RazorOutputPath_SetToNonDefault()
{ {
var customOutputPath = Path.Combine("bin", Configuration, TargetFramework, "Razor"); 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); Assert.BuildPassed(result);
@ -124,7 +133,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
public async Task Build_MvcRazorOutputPath_SetToNonDefault() public async Task Build_MvcRazorOutputPath_SetToNonDefault()
{ {
var customOutputPath = Path.Combine("bin", Configuration, TargetFramework, "Razor"); 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); Assert.BuildPassed(result);
@ -139,7 +148,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[InitializeTestProject("SimpleMvc")] [InitializeTestProject("SimpleMvc")]
public async Task Build_SkipsCopyingBinariesToOutputDirectory_IfCopyBuildOutputToOutputDirectory_IsUnset() 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); Assert.BuildPassed(result);
@ -154,7 +163,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[InitializeTestProject("SimpleMvc")] [InitializeTestProject("SimpleMvc")]
public async Task Build_SkipsCopyingBinariesToOutputDirectory_IfCopyOutputSymbolsToOutputDirectory_IsUnset() 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); Assert.BuildPassed(result);
@ -168,7 +177,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[InitializeTestProject("SimpleMvc")] [InitializeTestProject("SimpleMvc")]
public async Task Build_Works_WhenSymbolsAreNotGenerated() 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); Assert.BuildPassed(result);
@ -184,7 +193,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[InitializeTestProject("AppWithP2PReference", "ClassLibrary")] [InitializeTestProject("AppWithP2PReference", "ClassLibrary")]
public async Task Build_WithP2P_CopiesRazorAssembly() public async Task Build_WithP2P_CopiesRazorAssembly()
{ {
var result = await DotnetMSBuild("Build", "/p:RazorCompileOnBuild=true"); var result = await DotnetMSBuild("Build");
Assert.BuildPassed(result); Assert.BuildPassed(result);
@ -211,7 +220,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
AddProjectFileContent(additionalProjectContent); AddProjectFileContent(additionalProjectContent);
Directory.CreateDirectory(Path.Combine(Project.DirectoryPath, "..", "LinkedDir")); 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); Assert.BuildPassed(result);

View File

@ -7,13 +7,18 @@ using Xunit;
namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
{ {
public class BuildIntrospectionTest : MSBuildIntegrationTestBase public class BuildIntrospectionTest : MSBuildIntegrationTestBase, IClassFixture<BuildServerTestFixture>
{ {
public BuildIntrospectionTest(BuildServerTestFixture buildServer)
: base(buildServer)
{
}
[Fact] [Fact]
[InitializeTestProject("SimpleMvc")] [InitializeTestProject("SimpleMvc")]
public async Task RazorSdk_AddsCshtmlFilesToUpToDateCheckInput() public async Task RazorSdk_AddsCshtmlFilesToUpToDateCheckInput()
{ {
var result = await DotnetMSBuild("_IntrospectUpToDateCheckInput", "/p:RazorCompileOnBuild=true"); var result = await DotnetMSBuild("_IntrospectUpToDateCheckInput");
Assert.BuildPassed(result); Assert.BuildPassed(result);
Assert.BuildOutputContainsLine(result, $"UpToDateCheckInput: {Path.Combine("Views", "Home", "Index.cshtml")}"); 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> public class BuildServerIntegrationTest : MSBuildIntegrationTestBase, IClassFixture<BuildServerTestFixture>
{ {
private readonly string _pipeName; public BuildServerIntegrationTest(BuildServerTestFixture buildServer)
: base(buildServer)
public BuildServerIntegrationTest(BuildServerTestFixture fixture)
{ {
_pipeName = fixture.PipeName;
} }
[Fact] [Fact]
@ -32,7 +30,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
{ {
var result = await DotnetMSBuild( var result = await DotnetMSBuild(
"Build", "Build",
$"/p:RazorCompileOnBuild=true /p:UseRazorBuildServer=true /p:_RazorBuildServerPipeName={_pipeName} /p:_RazorForceBuildServer=true", "/p:_RazorForceBuildServer=true",
msBuildProcessKind: msBuildProcessKind); msBuildProcessKind: msBuildProcessKind);
Assert.BuildPassed(result); Assert.BuildPassed(result);
@ -59,7 +57,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
{ {
var result = await DotnetMSBuild( var result = await DotnetMSBuild(
"Build", "Build",
$"/p:RazorCompileOnBuild=true /p:UseRazorBuildServer=true /p:_RazorBuildServerPipeName={_pipeName} /p:_RazorForceBuildServer=true"); "/p:_RazorForceBuildServer=true");
Assert.BuildPassed(result); Assert.BuildPassed(result);
Assert.FileExists(result, OutputPath, "SimpleMvc.dll"); Assert.FileExists(result, OutputPath, "SimpleMvc.dll");
@ -74,7 +72,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
{ {
var result = await DotnetMSBuild( var result = await DotnetMSBuild(
"Build", "Build",
$"/p:RazorCompileOnBuild=true /p:UseRazorBuildServer=true /p:_RazorBuildServerPipeName={_pipeName} /p:_RazorForceBuildServer=true"); "/p:_RazorForceBuildServer=true");
Assert.BuildPassed(result); Assert.BuildPassed(result);
Assert.FileExists(result, OutputPath, "Whitespace in name.dll"); Assert.FileExists(result, OutputPath, "Whitespace in name.dll");

View File

@ -31,16 +31,23 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
// Shutdown the build server. // Shutdown the build server.
using (var cts = new CancellationTokenSource(_defaultShutdownTimeout)) using (var cts = new CancellationTokenSource(_defaultShutdownTimeout))
{ {
var writer = new StringWriter();
cts.Token.Register(() => 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); var exitCode = application.Execute("shutdown", "-w", "-p", PipeName);
if (exitCode != 0) if (exitCode != 0)
{ {
var output = application.Error.ToString(); var output = writer.ToString();
throw new InvalidOperationException( throw new InvalidOperationException(
$"Build server at pipe {PipeName} failed to shutdown with exit code {exitCode}. Output: {output}"); $"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 namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
{ {
public class ConfigurationMetadataIntegrationTest : MSBuildIntegrationTestBase public class ConfigurationMetadataIntegrationTest : MSBuildIntegrationTestBase, IClassFixture<BuildServerTestFixture>
{ {
public ConfigurationMetadataIntegrationTest(BuildServerTestFixture buildServer)
: base(buildServer)
{
}
[Fact] [Fact]
[InitializeTestProject("SimpleMvc")] [InitializeTestProject("SimpleMvc")]
public async Task Build_WithMvc_AddsConfigurationMetadata() public async Task Build_WithMvc_AddsConfigurationMetadata()
{ {
var result = await DotnetMSBuild("Build", $"/p:RazorCompileOnBuild=true"); var result = await DotnetMSBuild("Build");
Assert.BuildPassed(result); Assert.BuildPassed(result);
@ -39,7 +44,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[InitializeTestProject("SimpleMvc")] [InitializeTestProject("SimpleMvc")]
public async Task Build_WithGenerateRazorAssemblyInfo_False_SuppressesConfigurationMetadata() 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); Assert.BuildPassed(result);
@ -67,7 +72,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
{ {
TargetFramework = "netstandard2.0"; TargetFramework = "netstandard2.0";
var result = await DotnetMSBuild("Build", $"/p:RazorCompileOnBuild=true"); var result = await DotnetMSBuild("Build");
Assert.BuildPassed(result); Assert.BuildPassed(result);

View File

@ -6,15 +6,20 @@ using Xunit;
namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
{ {
public class DesignTimeBuildIntegrationTest : MSBuildIntegrationTestBase public class DesignTimeBuildIntegrationTest : MSBuildIntegrationTestBase, IClassFixture<BuildServerTestFixture>
{ {
public DesignTimeBuildIntegrationTest(BuildServerTestFixture buildServer)
: base(buildServer)
{
}
[Fact] [Fact]
[InitializeTestProject("SimpleMvc")] [InitializeTestProject("SimpleMvc")]
public async Task DesignTimeBuild_DoesNotRunRazorTargets() public async Task DesignTimeBuild_DoesNotRunRazorTargets()
{ {
// Using Compile here instead of CompileDesignTime because the latter is only defined when using // 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 // 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.BuildPassed(result);
Assert.FileDoesNotExist(result, OutputPath, "SimpleMvc.dll"); 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>(); private static readonly AsyncLocal<ProjectDirectory> _project = new AsyncLocal<ProjectDirectory>();
protected MSBuildIntegrationTestBase() protected MSBuildIntegrationTestBase(BuildServerTestFixture buildServer)
{ {
BuildServer = buildServer;
} }
#if DEBUG #if DEBUG
@ -44,19 +45,35 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
protected string TargetFramework { get; set; } = "netcoreapp2.0"; protected string TargetFramework { get; set; } = "netcoreapp2.0";
protected BuildServerTestFixture BuildServer { get; set; }
internal Task<MSBuildResult> DotnetMSBuild( internal Task<MSBuildResult> DotnetMSBuild(
string target, string target,
string args = null, string args = null,
bool suppressRestore = false, bool suppressRestore = false,
bool suppressTimeout = false, bool suppressTimeout = false,
bool suppressBuildServer = false,
MSBuildProcessKind msBuildProcessKind = MSBuildProcessKind.Dotnet) MSBuildProcessKind msBuildProcessKind = MSBuildProcessKind.Dotnet)
{ {
var timeout = suppressTimeout ? (TimeSpan?)Timeout.InfiniteTimeSpan : null; 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( return MSBuildProcessManager.RunProcessAsync(
Project, Project,
$"{restoreArgument} /t:{target} /p:Configuration={Configuration} {args}", buildArguments,
timeout, timeout,
msBuildProcessKind); msBuildProcessKind);
} }

View File

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

View File

@ -7,8 +7,13 @@ using Xunit;
namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
{ {
public class PublishIntegrationTest : MSBuildIntegrationTestBase public class PublishIntegrationTest : MSBuildIntegrationTestBase, IClassFixture<BuildServerTestFixture>
{ {
public PublishIntegrationTest(BuildServerTestFixture buildServer)
: base(buildServer)
{
}
[Fact] [Fact]
[InitializeTestProject("SimpleMvc")] [InitializeTestProject("SimpleMvc")]
public async Task Publish_RazorCompileOnPublish_IsDefault() public async Task Publish_RazorCompileOnPublish_IsDefault()
@ -17,9 +22,6 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
Assert.BuildPassed(result); 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.dll");
Assert.FileExists(result, PublishOutputPath, "SimpleMvc.pdb"); Assert.FileExists(result, PublishOutputPath, "SimpleMvc.pdb");
Assert.FileExists(result, PublishOutputPath, "SimpleMvc.Views.dll"); Assert.FileExists(result, PublishOutputPath, "SimpleMvc.Views.dll");
@ -32,9 +34,9 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[Fact] [Fact]
[InitializeTestProject("SimpleMvc")] [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); Assert.BuildPassed(result);
@ -57,7 +59,26 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[InitializeTestProject("SimpleMvc")] [InitializeTestProject("SimpleMvc")]
public async Task Publish_WithRazorCompileOnPublish_PublishesAssembly() 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); Assert.BuildPassed(result);
@ -96,9 +117,6 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
Assert.BuildPassed(result); 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.dll");
Assert.FileExists(result, PublishOutputPath, "SimpleMvc.pdb"); Assert.FileExists(result, PublishOutputPath, "SimpleMvc.pdb");
Assert.FileExists(result, PublishOutputPath, "SimpleMvc.Views.dll"); 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); 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); Assert.BuildPassed(result);
@ -162,7 +180,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[InitializeTestProject("SimpleMvc")] [InitializeTestProject("SimpleMvc")]
public async Task Publish_SkipsCopyingBinariesToOutputDirectory_IfCopyBuildOutputToOutputDirectory_IsUnset() 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); Assert.BuildPassed(result);
@ -177,7 +195,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[InitializeTestProject("SimpleMvc")] [InitializeTestProject("SimpleMvc")]
public async Task Publish_SkipsCopyingBinariesToOutputDirectory_IfCopyOutputSymbolsToOutputDirectory_IsUnset() 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); Assert.BuildPassed(result);
@ -191,7 +209,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[InitializeTestProject("SimpleMvc")] [InitializeTestProject("SimpleMvc")]
public async Task Publish_Works_WhenSymbolsAreNotGenerated() 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); Assert.BuildPassed(result);
@ -207,13 +225,10 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[InitializeTestProject("SimpleMvc")] [InitializeTestProject("SimpleMvc")]
public async Task Publish_IncludeCshtmlAndRefAssemblies_CopiesFiles() 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.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.dll");
Assert.FileExists(result, PublishOutputPath, "SimpleMvc.pdb"); Assert.FileExists(result, PublishOutputPath, "SimpleMvc.pdb");
Assert.FileExists(result, PublishOutputPath, "SimpleMvc.Views.dll"); Assert.FileExists(result, PublishOutputPath, "SimpleMvc.Views.dll");
@ -228,13 +243,10 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[InitializeTestProject("SimpleMvc")] [InitializeTestProject("SimpleMvc")]
public async Task Publish_MvcRazorExcludeFilesFromPublish_False_CopiesFiles() 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.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.dll");
Assert.FileExists(result, PublishOutputPath, "SimpleMvc.pdb"); Assert.FileExists(result, PublishOutputPath, "SimpleMvc.pdb");
Assert.FileExists(result, PublishOutputPath, "SimpleMvc.Views.dll"); Assert.FileExists(result, PublishOutputPath, "SimpleMvc.Views.dll");
@ -249,7 +261,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[InitializeTestProject("AppWithP2PReference", "ClassLibrary")] [InitializeTestProject("AppWithP2PReference", "ClassLibrary")]
public async Task Publish_WithP2P_AndRazorCompileOnBuild_CopiesRazorAssembly() public async Task Publish_WithP2P_AndRazorCompileOnBuild_CopiesRazorAssembly()
{ {
var result = await DotnetMSBuild("Publish", "/p:RazorCompileOnBuild=true"); var result = await DotnetMSBuild("Publish");
Assert.BuildPassed(result); Assert.BuildPassed(result);
@ -267,15 +279,10 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[InitializeTestProject("AppWithP2PReference", "ClassLibrary")] [InitializeTestProject("AppWithP2PReference", "ClassLibrary")]
public async Task Publish_WithP2P_AndRazorCompileOnPublish_CopiesRazorAssembly() public async Task Publish_WithP2P_AndRazorCompileOnPublish_CopiesRazorAssembly()
{ {
var result = await DotnetMSBuild("Publish", "/p:RazorCompileOnPublish=true"); var result = await DotnetMSBuild("Publish");
Assert.BuildPassed(result); 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.dll");
Assert.FileExists(result, PublishOutputPath, "AppWithP2PReference.pdb"); Assert.FileExists(result, PublishOutputPath, "AppWithP2PReference.pdb");
Assert.FileExists(result, PublishOutputPath, "AppWithP2PReference.Views.dll"); Assert.FileExists(result, PublishOutputPath, "AppWithP2PReference.Views.dll");

View File

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

View File

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

View File

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

View File

@ -26,7 +26,8 @@ namespace Microsoft.AspNetCore.Razor.Tools
internal static ServerData CreateServer( internal static ServerData CreateServer(
string pipeName = null, string pipeName = null,
CompilerHost compilerHost = null, CompilerHost compilerHost = null,
ConnectionHost connectionHost = null) ConnectionHost connectionHost = null,
Action<object, EventArgs> onListening = null)
{ {
pipeName = pipeName ?? Guid.NewGuid().ToString(); pipeName = pipeName ?? Guid.NewGuid().ToString();
compilerHost = compilerHost ?? CompilerHost.Create(); compilerHost = compilerHost ?? CompilerHost.Create();
@ -40,6 +41,10 @@ namespace Microsoft.AspNetCore.Razor.Tools
{ {
var eventBus = new TestableEventBus(); var eventBus = new TestableEventBus();
eventBus.Listening += (sender, e) => { serverListenSource.TrySetResult(true); }; eventBus.Listening += (sender, e) => { serverListenSource.TrySetResult(true); };
if (onListening != null)
{
eventBus.Listening += (sender, e) => onListening(sender, e);
}
try try
{ {
RunServer( 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 /// A shutdown request should not abort an existing compilation. It should be allowed to run to
/// completion. /// completion.
/// </summary> /// </summary>
// Skipping temporarily on non-windows. https://github.com/aspnet/Razor/issues/1991 [Fact]
[ConditionalFact]
[OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)]
public async Task ServerRunning_ShutdownRequest_DoesNotAbortCompilation() public async Task ServerRunning_ShutdownRequest_DoesNotAbortCompilation()
{ {
// Arrange // Arrange
var completionSource = new TaskCompletionSource<bool>(); var startCompilationSource = new TaskCompletionSource<bool>();
var finishCompilationSource = new TaskCompletionSource<bool>();
var host = CreateCompilerHost(c => c.ExecuteFunc = (req, ct) => 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. // We want this to keep running even after the shutdown is seen.
completionSource.Task.Wait(); finishCompilationSource.Task.Wait();
return EmptyServerResponse; return EmptyServerResponse;
}); });
@ -134,13 +136,16 @@ namespace Microsoft.AspNetCore.Razor.Tools
{ {
var compileTask = ServerUtilities.Send(serverData.PipeName, EmptyServerRequest); var compileTask = ServerUtilities.Send(serverData.PipeName, EmptyServerRequest);
// Wait for the request to go through and trigger compilation.
await startCompilationSource.Task;
// Act // Act
// The compilation is now in progress, send the shutdown. // The compilation is now in progress, send the shutdown.
await ServerUtilities.SendShutdown(serverData.PipeName); await ServerUtilities.SendShutdown(serverData.PipeName);
Assert.False(compileTask.IsCompleted); Assert.False(compileTask.IsCompleted);
// Now let the task complete. // Now let the task complete.
completionSource.SetResult(true); finishCompilationSource.SetResult(true);
// Assert // Assert
var response = await compileTask; var response = await compileTask;
@ -154,17 +159,19 @@ namespace Microsoft.AspNetCore.Razor.Tools
/// <summary> /// <summary>
/// Multiple clients should be able to send shutdown requests to the server. /// Multiple clients should be able to send shutdown requests to the server.
/// </summary> /// </summary>
// Skipping temporarily on non-windows. https://github.com/aspnet/Razor/issues/1991 [Fact]
[ConditionalFact]
[OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)]
public async Task ServerRunning_MultipleShutdownRequests_HandlesSuccessfully() public async Task ServerRunning_MultipleShutdownRequests_HandlesSuccessfully()
{ {
// Arrange // Arrange
var completionSource = new TaskCompletionSource<bool>(); var startCompilationSource = new TaskCompletionSource<bool>();
var finishCompilationSource = new TaskCompletionSource<bool>();
var host = CreateCompilerHost(c => c.ExecuteFunc = (req, ct) => 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. // We want this to keep running even after the shutdown is seen.
completionSource.Task.Wait(); finishCompilationSource.Task.Wait();
return EmptyServerResponse; return EmptyServerResponse;
}); });
@ -172,6 +179,9 @@ namespace Microsoft.AspNetCore.Razor.Tools
{ {
var compileTask = ServerUtilities.Send(serverData.PipeName, EmptyServerRequest); var compileTask = ServerUtilities.Send(serverData.PipeName, EmptyServerRequest);
// Wait for the request to go through and trigger compilation.
await startCompilationSource.Task;
// Act // Act
for (var i = 0; i < 10; i++) for (var i = 0; i < 10; i++)
{ {
@ -182,7 +192,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
} }
// Now let the task complete. // Now let the task complete.
completionSource.SetResult(true); finishCompilationSource.SetResult(true);
// Assert // Assert
var response = await compileTask; 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] [ConditionalFact]
[OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)] [OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)]
public async Task ServerRunning_CancelCompilation_CancelsSuccessfully() public async Task ServerRunning_CancelCompilation_CancelsSuccessfully()
@ -213,18 +223,28 @@ namespace Microsoft.AspNetCore.Razor.Tools
return new RejectedServerResponse(); 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++) for (var i = 0; i < requestCount; i++)
{ {
var task = ServerUtilities.Send(serverData.PipeName, EmptyServerRequest); // Wait for the server to start listening.
tasks.Add(task); 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 // Act
// Wait until all of the connections are being processed by the server. // Wait until all of the connections are being processed by the server.
completionSource.Task.Wait(); await completionSource.Task;
// Now cancel // Now cancel
var stats = await serverData.CancelAndCompleteAsync(); var stats = await serverData.CancelAndCompleteAsync();
@ -233,10 +253,13 @@ namespace Microsoft.AspNetCore.Razor.Tools
Assert.Equal(requestCount, stats.Connections); Assert.Equal(requestCount, stats.Connections);
Assert.Equal(requestCount, count); 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. // 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)</PackageVersion>
<PackageVersion Condition="'$(IsFinalBuild)' == 'true' AND '$(VersionSuffix)' != 'rtm' ">$(VersionPrefix)-$(VersionSuffix)-final</PackageVersion> <PackageVersion Condition="'$(IsFinalBuild)' == 'true' AND '$(VersionSuffix)' != 'rtm' ">$(VersionPrefix)-$(VersionSuffix)-final</PackageVersion>
<BuildNumber Condition="'$(BuildNumber)' == ''">t000</BuildNumber> <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> <VersionSuffix Condition="'$(VersionSuffix)' != '' And '$(BuildNumber)' != ''">$(VersionSuffix)-$(BuildNumber)</VersionSuffix>
<!-- VS for Mac does not like letters in package versions --> <!-- VS for Mac does not like letters in package versions -->
<AddinBuildNumber Condition="'$(BuildNumber)' == 't000'">99999</AddinBuildNumber> <AddinBuildNumber Condition="'$(BuildNumber)' == 't000'">99999</AddinBuildNumber>