Change testing strategy for build server shutdown test
This commit is contained in:
parent
8674dd9236
commit
8e62dbcae9
|
|
@ -8,6 +8,7 @@ using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Razor.Language;
|
using Microsoft.AspNetCore.Razor.Language;
|
||||||
using Microsoft.AspNetCore.Razor.Tools;
|
using Microsoft.AspNetCore.Razor.Tools;
|
||||||
|
using Microsoft.AspNetCore.Testing;
|
||||||
using Microsoft.AspNetCore.Testing.xunit;
|
using Microsoft.AspNetCore.Testing.xunit;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using Moq;
|
using Moq;
|
||||||
|
|
@ -143,28 +144,62 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
||||||
// it reaches server creation part.
|
// it reaches server creation part.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skipping on linux/mac because of https://github.com/aspnet/Razor/issues/2507.
|
// Skipping on MacOS because of https://github.com/dotnet/corefx/issues/33141.
|
||||||
|
// Skipping on Linux because of https://github.com/aspnet/Razor/issues/2525.
|
||||||
[ConditionalFact]
|
[ConditionalFact]
|
||||||
[OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)]
|
[OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)]
|
||||||
[InitializeTestProject("SimpleMvc")]
|
[InitializeTestProject("SimpleMvc")]
|
||||||
public async Task ManualServerShutdown_NoPipeName_ShutsDownServer()
|
public async Task ManualServerShutdown_NoPipeName_ShutsDownServer()
|
||||||
{
|
{
|
||||||
var toolAssembly = typeof(Application).Assembly.Location;
|
// We are trying to test whether the correct pipe name is generated (from the location of rzc tool)
|
||||||
var result = await DotnetMSBuild(
|
// when we don't explicitly specify a pipe name.
|
||||||
"Build",
|
|
||||||
$"/p:_RazorForceBuildServer=true /p:_RazorToolAssembly={toolAssembly}",
|
|
||||||
suppressBuildServer: true); // We don't want to specify a pipe name
|
|
||||||
|
|
||||||
Assert.BuildPassed(result);
|
// Publish rzc tool to a temporary path. This is the location based on which the pipe name is generated.
|
||||||
|
var solutionRoot = TestPathUtilities.GetSolutionRootDirectory("Razor");
|
||||||
|
var toolAssemblyDirectory = Path.Combine(solutionRoot, "src", "Microsoft.AspNetCore.Razor.Tools");
|
||||||
|
var toolAssemblyPath = Path.Combine(toolAssemblyDirectory, "Microsoft.AspNetCore.Razor.Tools.csproj");
|
||||||
|
var projectDirectory = new TestProjectDirectory(solutionRoot, toolAssemblyDirectory, toolAssemblyPath);
|
||||||
|
var publishDir = Path.Combine(Path.GetTempPath(), "Razor", Path.GetRandomFileName(), "RzcPublish");
|
||||||
|
var publishResult = await MSBuildProcessManager.RunProcessAsync(projectDirectory, $"/t:Publish /p:PublishDir=\"{publishDir}\"");
|
||||||
|
|
||||||
// Shutdown the server
|
try
|
||||||
var output = new StringWriter();
|
{
|
||||||
var error = new StringWriter();
|
// Make sure publish succeeded.
|
||||||
var application = new Application(CancellationToken.None, Mock.Of<ExtensionAssemblyLoader>(), Mock.Of<ExtensionDependencyChecker>(), (path, properties) => Mock.Of<PortableExecutableReference>(), output, error);
|
Assert.BuildPassed(publishResult);
|
||||||
var exitCode = application.Execute("shutdown", "-w");
|
|
||||||
|
|
||||||
Assert.Equal(0, exitCode);
|
// Run the build using the published tool
|
||||||
Assert.Contains("shut down completed", output.ToString());
|
var toolAssembly = Path.Combine(publishDir, "rzc.dll");
|
||||||
|
var result = await DotnetMSBuild(
|
||||||
|
"Build",
|
||||||
|
$"/p:_RazorForceBuildServer=true /p:_RazorToolAssembly={toolAssembly}",
|
||||||
|
suppressBuildServer: true); // We don't want to specify a pipe name
|
||||||
|
|
||||||
|
Assert.BuildPassed(result);
|
||||||
|
|
||||||
|
// Manually shutdown the server
|
||||||
|
var processStartInfo = new ProcessStartInfo()
|
||||||
|
{
|
||||||
|
WorkingDirectory = publishDir,
|
||||||
|
UseShellExecute = false,
|
||||||
|
RedirectStandardError = true,
|
||||||
|
RedirectStandardOutput = true,
|
||||||
|
FileName = "dotnet",
|
||||||
|
Arguments = $"{toolAssembly} shutdown -w"
|
||||||
|
};
|
||||||
|
|
||||||
|
var logFilePath = Path.Combine(publishDir, "out.log");
|
||||||
|
processStartInfo.Environment.Add("RAZORBUILDSERVER_LOG", logFilePath);
|
||||||
|
var shutdownResult = await MSBuildProcessManager.RunProcessCoreAsync(processStartInfo);
|
||||||
|
|
||||||
|
Assert.Equal(0, shutdownResult.ExitCode);
|
||||||
|
var output = await File.ReadAllTextAsync(logFilePath);
|
||||||
|
Assert.Contains("shut down completed", output);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// Finally delete the temporary publish directory
|
||||||
|
ProjectDirectory.CleanupDirectory(publishDir);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -195,5 +230,13 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
||||||
fixture.Dispose();
|
fixture.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class TestProjectDirectory : ProjectDirectory
|
||||||
|
{
|
||||||
|
public TestProjectDirectory(string solutionPath, string directoryPath, string projectFilePath)
|
||||||
|
: base(solutionPath, directoryPath, projectFilePath)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,12 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
||||||
{
|
{
|
||||||
internal static class MSBuildProcessManager
|
internal static class MSBuildProcessManager
|
||||||
{
|
{
|
||||||
public static Task<MSBuildResult> RunProcessAsync(
|
public static async Task<MSBuildResult> RunProcessAsync(
|
||||||
ProjectDirectory project,
|
ProjectDirectory project,
|
||||||
string arguments,
|
string arguments,
|
||||||
TimeSpan? timeout = null,
|
TimeSpan? timeout = null,
|
||||||
MSBuildProcessKind msBuildProcessKind = MSBuildProcessKind.Dotnet)
|
MSBuildProcessKind msBuildProcessKind = MSBuildProcessKind.Dotnet)
|
||||||
{
|
{
|
||||||
timeout = timeout ?? TimeSpan.FromSeconds(120);
|
|
||||||
|
|
||||||
var processStartInfo = new ProcessStartInfo()
|
var processStartInfo = new ProcessStartInfo()
|
||||||
{
|
{
|
||||||
WorkingDirectory = project.DirectoryPath,
|
WorkingDirectory = project.DirectoryPath,
|
||||||
|
|
@ -44,6 +42,17 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
||||||
processStartInfo.Arguments = $"msbuild {arguments}";
|
processStartInfo.Arguments = $"msbuild {arguments}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var processResult = await RunProcessCoreAsync(processStartInfo, timeout);
|
||||||
|
|
||||||
|
return new MSBuildResult(project, processResult.FileName, processResult.Arguments, processResult.ExitCode, processResult.Output);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static Task<ProcessResult> RunProcessCoreAsync(
|
||||||
|
ProcessStartInfo processStartInfo,
|
||||||
|
TimeSpan? timeout = null)
|
||||||
|
{
|
||||||
|
timeout = timeout ?? TimeSpan.FromSeconds(120);
|
||||||
|
|
||||||
var process = new Process()
|
var process = new Process()
|
||||||
{
|
{
|
||||||
StartInfo = processStartInfo,
|
StartInfo = processStartInfo,
|
||||||
|
|
@ -57,10 +66,10 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
||||||
process.OutputDataReceived += Process_OutputDataReceived;
|
process.OutputDataReceived += Process_OutputDataReceived;
|
||||||
|
|
||||||
process.Start();
|
process.Start();
|
||||||
process.BeginErrorReadLine();
|
|
||||||
process.BeginOutputReadLine();
|
process.BeginOutputReadLine();
|
||||||
|
process.BeginErrorReadLine();
|
||||||
|
|
||||||
var timeoutTask = Task.Delay(timeout.Value).ContinueWith<MSBuildResult>((t) =>
|
var timeoutTask = Task.Delay(timeout.Value).ContinueWith<ProcessResult>((t) =>
|
||||||
{
|
{
|
||||||
// Don't timeout during debug sessions
|
// Don't timeout during debug sessions
|
||||||
while (Debugger.IsAttached)
|
while (Debugger.IsAttached)
|
||||||
|
|
@ -98,11 +107,11 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
||||||
outputString = output.ToString();
|
outputString = output.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = new MSBuildResult(project, process.StartInfo.FileName, process.StartInfo.Arguments, process.ExitCode, outputString);
|
var result = new ProcessResult(process.StartInfo.FileName, process.StartInfo.Arguments, process.ExitCode, outputString);
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
|
|
||||||
return Task.WhenAny<MSBuildResult>(waitTask, timeoutTask).Unwrap();
|
return Task.WhenAny<ProcessResult>(waitTask, timeoutTask).Unwrap();
|
||||||
|
|
||||||
void Process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
|
void Process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
|
||||||
{
|
{
|
||||||
|
|
@ -120,5 +129,24 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class ProcessResult
|
||||||
|
{
|
||||||
|
public ProcessResult(string fileName, string arguments, int exitCode, string output)
|
||||||
|
{
|
||||||
|
FileName = fileName;
|
||||||
|
Arguments = arguments;
|
||||||
|
ExitCode = exitCode;
|
||||||
|
Output = output;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Arguments { get; }
|
||||||
|
|
||||||
|
public string FileName { get; }
|
||||||
|
|
||||||
|
public int ExitCode { get; }
|
||||||
|
|
||||||
|
public string Output { get; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,7 @@ $@"<Project>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ProjectDirectory(string solutionPath, string directoryPath, string projectFilePath)
|
protected ProjectDirectory(string solutionPath, string directoryPath, string projectFilePath)
|
||||||
{
|
{
|
||||||
SolutionPath = solutionPath;
|
SolutionPath = solutionPath;
|
||||||
DirectoryPath = directoryPath;
|
DirectoryPath = directoryPath;
|
||||||
|
|
@ -164,7 +164,7 @@ $@"<Project>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CleanupDirectory(string filePath)
|
internal static void CleanupDirectory(string filePath)
|
||||||
{
|
{
|
||||||
var tries = 5;
|
var tries = 5;
|
||||||
var sleep = TimeSpan.FromSeconds(3);
|
var sleep = TimeSpan.FromSeconds(3);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue