Merge pull request #9160 from peterhuene/fix-pid-file-share-mode

Fix Razor server shutdown on Windows.
This commit is contained in:
Peter Huene 2018-04-30 14:47:31 -07:00 committed by GitHub
commit b23259c30f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 260 additions and 6 deletions

View file

@ -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}");
}
}
}

View file

@ -94,6 +94,11 @@ namespace Microsoft.Extensions.DependencyModel.Tests
int bufferSize,
FileOptions fileOptions)
{
if (fileMode == FileMode.Open && fileAccess == FileAccess.Read)
{
return OpenRead(path);
}
throw new NotImplementedException();
}

View file

@ -9,7 +9,9 @@ using FluentAssertions;
using Microsoft.DotNet.BuildServer;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Configurer;
using Microsoft.DotNet.Tools.Test.Utilities;
using Microsoft.Extensions.DependencyModel.Tests;
using Microsoft.Extensions.EnvironmentAbstractions;
using Moq;
using Xunit;
using LocalizableStrings = Microsoft.DotNet.BuildServer.LocalizableStrings;
@ -129,12 +131,59 @@ namespace Microsoft.DotNet.Tests.BuildServerTests
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)
{
var provider = new Mock<IEnvironmentProvider>(MockBehavior.Strict);
provider
.Setup(p => p.GetEnvironmentVariable("DOTNET_BUILD_PIDFILE_DIRECTORY"))
.Setup(p => p.GetEnvironmentVariable(BuildServerProvider.PidFileDirectoryVariableName))
.Returns(value);
return provider;

View file

@ -10,17 +10,21 @@ using Microsoft.DotNet.BuildServer;
using Microsoft.DotNet.Cli;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.TestFramework;
using Microsoft.DotNet.Tools.BuildServer;
using Microsoft.DotNet.Tools.BuildServer.Shutdown;
using Microsoft.DotNet.Tools.Test.Utilities;
using Microsoft.Extensions.EnvironmentAbstractions;
using Moq;
using Xunit;
using Parser = Microsoft.DotNet.Cli.Parser;
using CommandLocalizableStrings = Microsoft.DotNet.BuildServer.LocalizableStrings;
using LocalizableStrings = Microsoft.DotNet.Tools.BuildServer.Shutdown.LocalizableStrings;
using TestBuildServerCommand = Microsoft.DotNet.Tools.Test.Utilities.BuildServerCommand;
namespace Microsoft.DotNet.Tests.Commands
{
public class BuildServerShutdownCommandTests
public class BuildServerShutdownCommandTests : TestBase
{
private readonly BufferedReporter _reporter = new BufferedReporter();
@ -157,6 +161,43 @@ namespace Microsoft.DotNet.Tests.Commands
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(
string options = "",
IBuildServerProvider serverProvider = null,