1ade191cb6
Previously, Razor server discovery for the `build-server shutdown` command was implemented by invoking MSBuild on a project file in the current directory to evaluate the path to the Razor server dll. This was problematic since it would only discover a single running Razor server instance and required that the user run the `build-server shutdown` command from a specific location. Razor's server now writes a "pid file" to a well-known location (`~/.dotnet/pids/build`) which the command can now enumerate to discover, and shutdown, the running Razor servers. This commit changes the Razor server discovery to use the pid files and removes the requirement that users need to run the command in specific directories to work. Fixes #9084.
109 lines
4.2 KiB
C#
109 lines
4.2 KiB
C#
// 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 System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using FluentAssertions;
|
|
using Microsoft.DotNet.BuildServer;
|
|
using Microsoft.DotNet.Cli;
|
|
using Microsoft.DotNet.Cli.Utils;
|
|
using Microsoft.DotNet.Tools;
|
|
using Microsoft.Extensions.DependencyModel.Tests;
|
|
using Microsoft.Extensions.EnvironmentAbstractions;
|
|
using Moq;
|
|
using NuGet.Frameworks;
|
|
using Xunit;
|
|
using LocalizableStrings = Microsoft.DotNet.BuildServer.LocalizableStrings;
|
|
|
|
namespace Microsoft.DotNet.Tests.BuildServerTests
|
|
{
|
|
public class RazorServerTests
|
|
{
|
|
[Fact]
|
|
public void GivenAFailedShutdownCommandItThrows()
|
|
{
|
|
const int ProcessId = 1234;
|
|
const string ServerPath = "path/to/rzc.dll";
|
|
const string PipeName = "some-pipe-name";
|
|
const string ErrorMessage = "error!";
|
|
|
|
string pidDirectory = Path.GetFullPath("var/pids/build");
|
|
string pidFilePath = Path.Combine(pidDirectory, $"{RazorPidFile.FilePrefix}{ProcessId}");
|
|
|
|
var fileSystemMock = new FileSystemMockBuilder()
|
|
.AddFile(pidFilePath, "")
|
|
.Build();
|
|
|
|
fileSystemMock.File.Exists(pidFilePath).Should().BeTrue();
|
|
|
|
var server = new RazorServer(
|
|
pidFile: new RazorPidFile(
|
|
path: new FilePath(pidFilePath),
|
|
processId: ProcessId,
|
|
serverPath: new FilePath(ServerPath),
|
|
pipeName: PipeName),
|
|
commandFactory: CreateCommandFactoryMock(ServerPath, PipeName, exitCode: 1, stdErr: ErrorMessage).Object,
|
|
fileSystem: fileSystemMock);
|
|
|
|
Action a = () => server.Shutdown();
|
|
|
|
a.ShouldThrow<BuildServerException>().WithMessage(
|
|
string.Format(
|
|
LocalizableStrings.ShutdownCommandFailed,
|
|
ErrorMessage));
|
|
|
|
fileSystemMock.File.Exists(pidFilePath).Should().BeTrue();
|
|
}
|
|
|
|
[Fact]
|
|
public void GivenASuccessfulShutdownItDoesNotThrow()
|
|
{
|
|
const int ProcessId = 1234;
|
|
const string ServerPath = "path/to/rzc.dll";
|
|
const string PipeName = "some-pipe-name";
|
|
|
|
string pidDirectory = Path.GetFullPath("var/pids/build");
|
|
string pidFilePath = Path.Combine(pidDirectory, $"{RazorPidFile.FilePrefix}{ProcessId}");
|
|
|
|
var fileSystemMock = new FileSystemMockBuilder()
|
|
.AddFile(pidFilePath, "")
|
|
.Build();
|
|
|
|
fileSystemMock.File.Exists(pidFilePath).Should().BeTrue();
|
|
|
|
var server = new RazorServer(
|
|
pidFile: new RazorPidFile(
|
|
path: new FilePath(pidFilePath),
|
|
processId: ProcessId,
|
|
serverPath: new FilePath(ServerPath),
|
|
pipeName: PipeName),
|
|
commandFactory: CreateCommandFactoryMock(ServerPath, PipeName).Object,
|
|
fileSystem: fileSystemMock);
|
|
|
|
server.Shutdown();
|
|
|
|
fileSystemMock.File.Exists(pidFilePath).Should().BeFalse();
|
|
}
|
|
|
|
private Mock<ICommandFactory> CreateCommandFactoryMock(string serverPath, string pipeName, int exitCode = 0, string stdErr = "")
|
|
{
|
|
var commandMock = new Mock<ICommand>(MockBehavior.Strict);
|
|
commandMock.Setup(c => c.CaptureStdOut()).Returns(commandMock.Object);
|
|
commandMock.Setup(c => c.CaptureStdErr()).Returns(commandMock.Object);
|
|
commandMock.Setup(c => c.Execute()).Returns(new CommandResult(null, exitCode, "", stdErr));
|
|
|
|
var commandFactoryMock = new Mock<ICommandFactory>(MockBehavior.Strict);
|
|
commandFactoryMock
|
|
.Setup(
|
|
f => f.Create(
|
|
"exec",
|
|
new string[] { serverPath, "shutdown", "-w", "-p", pipeName },
|
|
It.IsAny<NuGetFramework>(),
|
|
Constants.DefaultConfiguration))
|
|
.Returns(commandMock.Object);
|
|
|
|
return commandFactoryMock;
|
|
}
|
|
}
|
|
}
|