Fix Razor server shutdown on Windows.
On Windows, the Razor server correctly creates the pid file with `FileAccess.Write` and `FileOptions.DeleteOnClose`. This requires a share mode of `FileShare.Write | FileShare.Delete` to open. However, the `dotnet build-server shutdown` command was opening the file with `FileShare.Read`. As a result, an `IOException` was being thrown and was not handled. This change first opens the file with the appropriate share access and also properly handles a failure to access or read the contents of the pid file. Additionally, an integration test was added to test that Razor server shutdown works as expected. Fixes #9158.
This commit is contained in:
parent
04066cb5d8
commit
b2b3947c68
23 changed files with 260 additions and 6 deletions
|
@ -0,0 +1,16 @@
|
||||||
|
@page
|
||||||
|
@model TestRazorApp.MyFeature.Pages.Page1Model
|
||||||
|
@{
|
||||||
|
Layout = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
<title>Page1</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,17 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
|
||||||
|
namespace TestRazorApp.MyFeature.Pages
|
||||||
|
{
|
||||||
|
public class Page1Model : PageModel
|
||||||
|
{
|
||||||
|
public void OnGet()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
TestAssets/TestProjects/TestRazorApp/TestRazorApp.csproj
Normal file
11
TestAssets/TestProjects/TestRazorApp/TestRazorApp.csproj
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
||||||
|
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), testAsset.props))\testAsset.props" />
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="$(MicrosoftAspNetCoreAllPackageVersion)" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
|
@ -12,15 +12,19 @@ namespace Microsoft.DotNet.BuildServer
|
||||||
{
|
{
|
||||||
internal class BuildServerProvider : IBuildServerProvider
|
internal class BuildServerProvider : IBuildServerProvider
|
||||||
{
|
{
|
||||||
|
public const string PidFileDirectoryVariableName = "DOTNET_BUILD_PIDFILE_DIRECTORY";
|
||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
private readonly IEnvironmentProvider _environmentProvider;
|
private readonly IEnvironmentProvider _environmentProvider;
|
||||||
|
private readonly IReporter _reporter;
|
||||||
|
|
||||||
public BuildServerProvider(
|
public BuildServerProvider(
|
||||||
IFileSystem fileSystem = null,
|
IFileSystem fileSystem = null,
|
||||||
IEnvironmentProvider environmentProvider = null)
|
IEnvironmentProvider environmentProvider = null,
|
||||||
|
IReporter reporter = null)
|
||||||
{
|
{
|
||||||
_fileSystem = fileSystem ?? FileSystemWrapper.Default;
|
_fileSystem = fileSystem ?? FileSystemWrapper.Default;
|
||||||
_environmentProvider = environmentProvider ?? new EnvironmentProvider();
|
_environmentProvider = environmentProvider ?? new EnvironmentProvider();
|
||||||
|
_reporter = reporter ?? Reporter.Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<IBuildServer> EnumerateBuildServers(ServerEnumerationFlags flags = ServerEnumerationFlags.All)
|
public IEnumerable<IBuildServer> EnumerateBuildServers(ServerEnumerationFlags flags = ServerEnumerationFlags.All)
|
||||||
|
@ -59,7 +63,7 @@ namespace Microsoft.DotNet.BuildServer
|
||||||
if ((flags & ServerEnumerationFlags.Razor) == ServerEnumerationFlags.Razor &&
|
if ((flags & ServerEnumerationFlags.Razor) == ServerEnumerationFlags.Razor &&
|
||||||
Path.GetFileName(path).StartsWith(RazorPidFile.FilePrefix))
|
Path.GetFileName(path).StartsWith(RazorPidFile.FilePrefix))
|
||||||
{
|
{
|
||||||
var file = RazorPidFile.Read(new FilePath(path), _fileSystem);
|
var file = ReadRazorPidFile(new FilePath(path));
|
||||||
if (file != null)
|
if (file != null)
|
||||||
{
|
{
|
||||||
yield return new RazorServer(file);
|
yield return new RazorServer(file);
|
||||||
|
@ -70,7 +74,7 @@ namespace Microsoft.DotNet.BuildServer
|
||||||
|
|
||||||
public DirectoryPath GetPidFileDirectory()
|
public DirectoryPath GetPidFileDirectory()
|
||||||
{
|
{
|
||||||
var directory = _environmentProvider.GetEnvironmentVariable("DOTNET_BUILD_PIDFILE_DIRECTORY");
|
var directory = _environmentProvider.GetEnvironmentVariable(PidFileDirectoryVariableName);
|
||||||
if (!string.IsNullOrEmpty(directory))
|
if (!string.IsNullOrEmpty(directory))
|
||||||
{
|
{
|
||||||
return new DirectoryPath(directory);
|
return new DirectoryPath(directory);
|
||||||
|
@ -82,5 +86,22 @@ namespace Microsoft.DotNet.BuildServer
|
||||||
"pids",
|
"pids",
|
||||||
"build"));
|
"build"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private RazorPidFile ReadRazorPidFile(FilePath path)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return RazorPidFile.Read(path, _fileSystem);
|
||||||
|
}
|
||||||
|
catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException)
|
||||||
|
{
|
||||||
|
_reporter.WriteLine(
|
||||||
|
string.Format(
|
||||||
|
LocalizableStrings.FailedToReadPidFile,
|
||||||
|
path.Value,
|
||||||
|
ex.Message).Yellow());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,4 +129,7 @@
|
||||||
<data name="ShutdownCommandFailed" xml:space="preserve">
|
<data name="ShutdownCommandFailed" xml:space="preserve">
|
||||||
<value>The shutdown command failed: {0}</value>
|
<value>The shutdown command failed: {0}</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="FailedToReadPidFile" xml:space="preserve">
|
||||||
|
<value>Failed to read pid file '{0}': {1}</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
|
@ -33,7 +33,13 @@ namespace Microsoft.DotNet.BuildServer
|
||||||
{
|
{
|
||||||
fileSystem = fileSystem ?? FileSystemWrapper.Default;
|
fileSystem = fileSystem ?? FileSystemWrapper.Default;
|
||||||
|
|
||||||
using (var stream = fileSystem.File.OpenRead(path.Value))
|
using (var stream = fileSystem.File.OpenFile(
|
||||||
|
path.Value,
|
||||||
|
FileMode.Open,
|
||||||
|
FileAccess.Read,
|
||||||
|
FileShare.Write | FileShare.Delete,
|
||||||
|
4096,
|
||||||
|
FileOptions.None))
|
||||||
using (var reader = new StreamReader(stream, Encoding.UTF8))
|
using (var reader = new StreamReader(stream, Encoding.UTF8))
|
||||||
{
|
{
|
||||||
if (!int.TryParse(reader.ReadLine(), out var processId))
|
if (!int.TryParse(reader.ReadLine(), out var processId))
|
||||||
|
|
|
@ -22,6 +22,11 @@
|
||||||
<target state="new">The shutdown command failed: {0}</target>
|
<target state="new">The shutdown command failed: {0}</target>
|
||||||
<note />
|
<note />
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="FailedToReadPidFile">
|
||||||
|
<source>Failed to read pid file '{0}': {1}</source>
|
||||||
|
<target state="new">Failed to read pid file '{0}': {1}</target>
|
||||||
|
<note />
|
||||||
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
|
@ -22,6 +22,11 @@
|
||||||
<target state="new">The shutdown command failed: {0}</target>
|
<target state="new">The shutdown command failed: {0}</target>
|
||||||
<note />
|
<note />
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="FailedToReadPidFile">
|
||||||
|
<source>Failed to read pid file '{0}': {1}</source>
|
||||||
|
<target state="new">Failed to read pid file '{0}': {1}</target>
|
||||||
|
<note />
|
||||||
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
|
@ -22,6 +22,11 @@
|
||||||
<target state="new">The shutdown command failed: {0}</target>
|
<target state="new">The shutdown command failed: {0}</target>
|
||||||
<note />
|
<note />
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="FailedToReadPidFile">
|
||||||
|
<source>Failed to read pid file '{0}': {1}</source>
|
||||||
|
<target state="new">Failed to read pid file '{0}': {1}</target>
|
||||||
|
<note />
|
||||||
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
|
@ -22,6 +22,11 @@
|
||||||
<target state="new">The shutdown command failed: {0}</target>
|
<target state="new">The shutdown command failed: {0}</target>
|
||||||
<note />
|
<note />
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="FailedToReadPidFile">
|
||||||
|
<source>Failed to read pid file '{0}': {1}</source>
|
||||||
|
<target state="new">Failed to read pid file '{0}': {1}</target>
|
||||||
|
<note />
|
||||||
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
|
@ -22,6 +22,11 @@
|
||||||
<target state="new">The shutdown command failed: {0}</target>
|
<target state="new">The shutdown command failed: {0}</target>
|
||||||
<note />
|
<note />
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="FailedToReadPidFile">
|
||||||
|
<source>Failed to read pid file '{0}': {1}</source>
|
||||||
|
<target state="new">Failed to read pid file '{0}': {1}</target>
|
||||||
|
<note />
|
||||||
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
|
@ -22,6 +22,11 @@
|
||||||
<target state="new">The shutdown command failed: {0}</target>
|
<target state="new">The shutdown command failed: {0}</target>
|
||||||
<note />
|
<note />
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="FailedToReadPidFile">
|
||||||
|
<source>Failed to read pid file '{0}': {1}</source>
|
||||||
|
<target state="new">Failed to read pid file '{0}': {1}</target>
|
||||||
|
<note />
|
||||||
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
|
@ -22,6 +22,11 @@
|
||||||
<target state="new">The shutdown command failed: {0}</target>
|
<target state="new">The shutdown command failed: {0}</target>
|
||||||
<note />
|
<note />
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="FailedToReadPidFile">
|
||||||
|
<source>Failed to read pid file '{0}': {1}</source>
|
||||||
|
<target state="new">Failed to read pid file '{0}': {1}</target>
|
||||||
|
<note />
|
||||||
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
|
@ -22,6 +22,11 @@
|
||||||
<target state="new">The shutdown command failed: {0}</target>
|
<target state="new">The shutdown command failed: {0}</target>
|
||||||
<note />
|
<note />
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="FailedToReadPidFile">
|
||||||
|
<source>Failed to read pid file '{0}': {1}</source>
|
||||||
|
<target state="new">Failed to read pid file '{0}': {1}</target>
|
||||||
|
<note />
|
||||||
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
|
@ -22,6 +22,11 @@
|
||||||
<target state="new">The shutdown command failed: {0}</target>
|
<target state="new">The shutdown command failed: {0}</target>
|
||||||
<note />
|
<note />
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="FailedToReadPidFile">
|
||||||
|
<source>Failed to read pid file '{0}': {1}</source>
|
||||||
|
<target state="new">Failed to read pid file '{0}': {1}</target>
|
||||||
|
<note />
|
||||||
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
|
@ -22,6 +22,11 @@
|
||||||
<target state="new">The shutdown command failed: {0}</target>
|
<target state="new">The shutdown command failed: {0}</target>
|
||||||
<note />
|
<note />
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="FailedToReadPidFile">
|
||||||
|
<source>Failed to read pid file '{0}': {1}</source>
|
||||||
|
<target state="new">Failed to read pid file '{0}': {1}</target>
|
||||||
|
<note />
|
||||||
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
|
@ -22,6 +22,11 @@
|
||||||
<target state="new">The shutdown command failed: {0}</target>
|
<target state="new">The shutdown command failed: {0}</target>
|
||||||
<note />
|
<note />
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="FailedToReadPidFile">
|
||||||
|
<source>Failed to read pid file '{0}': {1}</source>
|
||||||
|
<target state="new">Failed to read pid file '{0}': {1}</target>
|
||||||
|
<note />
|
||||||
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
|
@ -22,6 +22,11 @@
|
||||||
<target state="new">The shutdown command failed: {0}</target>
|
<target state="new">The shutdown command failed: {0}</target>
|
||||||
<note />
|
<note />
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="FailedToReadPidFile">
|
||||||
|
<source>Failed to read pid file '{0}': {1}</source>
|
||||||
|
<target state="new">Failed to read pid file '{0}': {1}</target>
|
||||||
|
<note />
|
||||||
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
|
@ -22,6 +22,11 @@
|
||||||
<target state="new">The shutdown command failed: {0}</target>
|
<target state="new">The shutdown command failed: {0}</target>
|
||||||
<note />
|
<note />
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="FailedToReadPidFile">
|
||||||
|
<source>Failed to read pid file '{0}': {1}</source>
|
||||||
|
<target state="new">Failed to read pid file '{0}': {1}</target>
|
||||||
|
<note />
|
||||||
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
|
using Microsoft.DotNet.Cli.Utils;
|
||||||
|
|
||||||
|
namespace Microsoft.DotNet.Tools.Test.Utilities
|
||||||
|
{
|
||||||
|
public sealed class BuildServerCommand : DotnetCommand
|
||||||
|
{
|
||||||
|
public override CommandResult Execute(string args = "")
|
||||||
|
{
|
||||||
|
return base.Execute($"build-server {args}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override CommandResult ExecuteWithCapturedOutput(string args = "")
|
||||||
|
{
|
||||||
|
return base.ExecuteWithCapturedOutput($"build-server {args}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -94,6 +94,11 @@ namespace Microsoft.Extensions.DependencyModel.Tests
|
||||||
int bufferSize,
|
int bufferSize,
|
||||||
FileOptions fileOptions)
|
FileOptions fileOptions)
|
||||||
{
|
{
|
||||||
|
if (fileMode == FileMode.Open && fileAccess == FileAccess.Read)
|
||||||
|
{
|
||||||
|
return OpenRead(path);
|
||||||
|
}
|
||||||
|
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,9 @@ using FluentAssertions;
|
||||||
using Microsoft.DotNet.BuildServer;
|
using Microsoft.DotNet.BuildServer;
|
||||||
using Microsoft.DotNet.Cli.Utils;
|
using Microsoft.DotNet.Cli.Utils;
|
||||||
using Microsoft.DotNet.Configurer;
|
using Microsoft.DotNet.Configurer;
|
||||||
|
using Microsoft.DotNet.Tools.Test.Utilities;
|
||||||
using Microsoft.Extensions.DependencyModel.Tests;
|
using Microsoft.Extensions.DependencyModel.Tests;
|
||||||
|
using Microsoft.Extensions.EnvironmentAbstractions;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using LocalizableStrings = Microsoft.DotNet.BuildServer.LocalizableStrings;
|
using LocalizableStrings = Microsoft.DotNet.BuildServer.LocalizableStrings;
|
||||||
|
@ -129,12 +131,59 @@ namespace Microsoft.DotNet.Tests.BuildServerTests
|
||||||
razorServer.PidFile.PipeName.Should().Be(PipeName);
|
razorServer.PidFile.PipeName.Should().Be(PipeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(typeof(UnauthorizedAccessException))]
|
||||||
|
[InlineData(typeof(IOException))]
|
||||||
|
public void GivenAnExceptionAccessingTheRazorPidFileItPrintsAWarning(Type exceptionType)
|
||||||
|
{
|
||||||
|
const int ProcessId = 1234;
|
||||||
|
const string ErrorMessage = "failed!";
|
||||||
|
|
||||||
|
string pidDirectory = Path.GetFullPath("var/pids/build");
|
||||||
|
string pidFilePath = Path.Combine(pidDirectory, $"{RazorPidFile.FilePrefix}{ProcessId}");
|
||||||
|
|
||||||
|
var directoryMock = new Mock<IDirectory>();
|
||||||
|
directoryMock.Setup(d => d.Exists(pidDirectory)).Returns(true);
|
||||||
|
directoryMock.Setup(d => d.EnumerateFiles(pidDirectory, "*")).Returns(new [] { pidFilePath });
|
||||||
|
|
||||||
|
var fileMock = new Mock<IFile>();
|
||||||
|
fileMock
|
||||||
|
.Setup(f => f.OpenFile(
|
||||||
|
pidFilePath,
|
||||||
|
FileMode.Open,
|
||||||
|
FileAccess.Read,
|
||||||
|
FileShare.Write | FileShare.Delete,
|
||||||
|
4096,
|
||||||
|
FileOptions.None))
|
||||||
|
.Throws((Exception)Activator.CreateInstance(exceptionType, new object[] { ErrorMessage } ));
|
||||||
|
|
||||||
|
var fileSystemMock = new Mock<IFileSystem>();
|
||||||
|
fileSystemMock.SetupGet(fs => fs.Directory).Returns(directoryMock.Object);
|
||||||
|
fileSystemMock.SetupGet(fs => fs.File).Returns(fileMock.Object);
|
||||||
|
|
||||||
|
var reporter = new BufferedReporter();
|
||||||
|
|
||||||
|
var provider = new BuildServerProvider(
|
||||||
|
fileSystemMock.Object,
|
||||||
|
CreateEnvironmentProviderMock(pidDirectory).Object,
|
||||||
|
reporter);
|
||||||
|
|
||||||
|
var servers = provider.EnumerateBuildServers(ServerEnumerationFlags.Razor).ToArray();
|
||||||
|
servers.Should().BeEmpty();
|
||||||
|
|
||||||
|
reporter.Lines.Should().Equal(
|
||||||
|
string.Format(
|
||||||
|
LocalizableStrings.FailedToReadPidFile,
|
||||||
|
pidFilePath,
|
||||||
|
ErrorMessage).Yellow());
|
||||||
|
}
|
||||||
|
|
||||||
private Mock<IEnvironmentProvider> CreateEnvironmentProviderMock(string value = null)
|
private Mock<IEnvironmentProvider> CreateEnvironmentProviderMock(string value = null)
|
||||||
{
|
{
|
||||||
var provider = new Mock<IEnvironmentProvider>(MockBehavior.Strict);
|
var provider = new Mock<IEnvironmentProvider>(MockBehavior.Strict);
|
||||||
|
|
||||||
provider
|
provider
|
||||||
.Setup(p => p.GetEnvironmentVariable("DOTNET_BUILD_PIDFILE_DIRECTORY"))
|
.Setup(p => p.GetEnvironmentVariable(BuildServerProvider.PidFileDirectoryVariableName))
|
||||||
.Returns(value);
|
.Returns(value);
|
||||||
|
|
||||||
return provider;
|
return provider;
|
||||||
|
|
|
@ -10,17 +10,21 @@ using Microsoft.DotNet.BuildServer;
|
||||||
using Microsoft.DotNet.Cli;
|
using Microsoft.DotNet.Cli;
|
||||||
using Microsoft.DotNet.Cli.CommandLine;
|
using Microsoft.DotNet.Cli.CommandLine;
|
||||||
using Microsoft.DotNet.Cli.Utils;
|
using Microsoft.DotNet.Cli.Utils;
|
||||||
|
using Microsoft.DotNet.TestFramework;
|
||||||
using Microsoft.DotNet.Tools.BuildServer;
|
using Microsoft.DotNet.Tools.BuildServer;
|
||||||
using Microsoft.DotNet.Tools.BuildServer.Shutdown;
|
using Microsoft.DotNet.Tools.BuildServer.Shutdown;
|
||||||
using Microsoft.DotNet.Tools.Test.Utilities;
|
using Microsoft.DotNet.Tools.Test.Utilities;
|
||||||
|
using Microsoft.Extensions.EnvironmentAbstractions;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using Parser = Microsoft.DotNet.Cli.Parser;
|
using Parser = Microsoft.DotNet.Cli.Parser;
|
||||||
|
using CommandLocalizableStrings = Microsoft.DotNet.BuildServer.LocalizableStrings;
|
||||||
using LocalizableStrings = Microsoft.DotNet.Tools.BuildServer.Shutdown.LocalizableStrings;
|
using LocalizableStrings = Microsoft.DotNet.Tools.BuildServer.Shutdown.LocalizableStrings;
|
||||||
|
using TestBuildServerCommand = Microsoft.DotNet.Tools.Test.Utilities.BuildServerCommand;
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Tests.Commands
|
namespace Microsoft.DotNet.Tests.Commands
|
||||||
{
|
{
|
||||||
public class BuildServerShutdownCommandTests
|
public class BuildServerShutdownCommandTests : TestBase
|
||||||
{
|
{
|
||||||
private readonly BufferedReporter _reporter = new BufferedReporter();
|
private readonly BufferedReporter _reporter = new BufferedReporter();
|
||||||
|
|
||||||
|
@ -157,6 +161,43 @@ namespace Microsoft.DotNet.Tests.Commands
|
||||||
VerifyShutdownCalls(mocks);
|
VerifyShutdownCalls(mocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GivenARunningRazorServerItShutsDownSuccessfully()
|
||||||
|
{
|
||||||
|
var pipeName = Path.GetRandomFileName();
|
||||||
|
var pidDirectory = Path.GetFullPath(Path.Combine(TempRoot.Root, Path.GetRandomFileName()));
|
||||||
|
|
||||||
|
var testInstance = TestAssets.Get("TestRazorApp")
|
||||||
|
.CreateInstance()
|
||||||
|
.WithSourceFiles();
|
||||||
|
|
||||||
|
new BuildCommand()
|
||||||
|
.WithWorkingDirectory(testInstance.Root)
|
||||||
|
.WithEnvironmentVariable(BuildServerProvider.PidFileDirectoryVariableName, pidDirectory)
|
||||||
|
.Execute($"/p:_RazorBuildServerPipeName={pipeName}")
|
||||||
|
.Should()
|
||||||
|
.Pass();
|
||||||
|
|
||||||
|
var files = Directory.GetFiles(pidDirectory, RazorPidFile.FilePrefix + "*");
|
||||||
|
files.Length.Should().Be(1);
|
||||||
|
|
||||||
|
var pidFile = RazorPidFile.Read(new FilePath(files.First()));
|
||||||
|
pidFile.PipeName.Should().Be(pipeName);
|
||||||
|
|
||||||
|
new TestBuildServerCommand()
|
||||||
|
.WithWorkingDirectory(testInstance.Root)
|
||||||
|
.WithEnvironmentVariable(BuildServerProvider.PidFileDirectoryVariableName, pidDirectory)
|
||||||
|
.ExecuteWithCapturedOutput("shutdown --razor")
|
||||||
|
.Should()
|
||||||
|
.Pass()
|
||||||
|
.And
|
||||||
|
.HaveStdOutContaining(
|
||||||
|
string.Format(
|
||||||
|
LocalizableStrings.ShutDownSucceededWithPid,
|
||||||
|
CommandLocalizableStrings.RazorServer,
|
||||||
|
pidFile.ProcessId));
|
||||||
|
}
|
||||||
|
|
||||||
private BuildServerShutdownCommand CreateCommand(
|
private BuildServerShutdownCommand CreateCommand(
|
||||||
string options = "",
|
string options = "",
|
||||||
IBuildServerProvider serverProvider = null,
|
IBuildServerProvider serverProvider = null,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue