2018-01-24 10:16:27 -08:00
// 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.Collections.Generic ;
using System.IO ;
using System.Linq ;
using FluentAssertions ;
using Microsoft.DotNet.Cli ;
using Microsoft.DotNet.Cli.CommandLine ;
using Microsoft.DotNet.Cli.Utils ;
using Microsoft.DotNet.ToolPackage ;
2018-01-28 13:35:04 -08:00
using Microsoft.DotNet.Tools ;
2018-01-24 10:16:27 -08:00
using Microsoft.DotNet.Tools.Install.Tool ;
using Microsoft.DotNet.Tools.Tests.ComponentMocks ;
2018-01-17 19:26:52 -08:00
using Microsoft.DotNet.Tools.Test.Utilities ;
2018-01-24 10:16:27 -08:00
using Microsoft.Extensions.DependencyModel.Tests ;
using Microsoft.Extensions.EnvironmentAbstractions ;
using Newtonsoft.Json ;
using Xunit ;
using Parser = Microsoft . DotNet . Cli . Parser ;
using LocalizableStrings = Microsoft . DotNet . Tools . Install . Tool . LocalizableStrings ;
2018-02-06 13:38:06 -08:00
using System.Runtime.InteropServices ;
2018-01-24 10:16:27 -08:00
2018-01-28 13:35:04 -08:00
namespace Microsoft.DotNet.Tests.Commands
2018-01-24 10:16:27 -08:00
{
public class InstallToolCommandTests
{
2018-01-28 13:35:04 -08:00
private readonly IFileSystem _fileSystem ;
private readonly IToolPackageStore _toolPackageStore ;
private readonly ShellShimRepositoryMock _shellShimRepositoryMock ;
2018-01-24 10:16:27 -08:00
private readonly EnvironmentPathInstructionMock _environmentPathInstructionMock ;
private readonly AppliedOption _appliedCommand ;
private readonly ParseResult _parseResult ;
2018-01-17 19:26:52 -08:00
private readonly BufferedReporter _reporter ;
2018-01-24 10:16:27 -08:00
private const string PathToPlaceShim = "pathToPlace" ;
2018-02-06 13:38:06 -08:00
private const string PathToPlacePackages = PathToPlaceShim + "pkg" ;
private const string PackageId = "global.tool.console.demo" ;
2018-01-28 13:35:04 -08:00
private const string PackageVersion = "1.0.4" ;
2018-01-24 10:16:27 -08:00
public InstallToolCommandTests ( )
{
2018-01-17 19:26:52 -08:00
_reporter = new BufferedReporter ( ) ;
2018-01-28 13:35:04 -08:00
_fileSystem = new FileSystemMockBuilder ( ) . Build ( ) ;
_toolPackageStore = new ToolPackageStoreMock ( new DirectoryPath ( PathToPlacePackages ) , _fileSystem ) ;
_shellShimRepositoryMock = new ShellShimRepositoryMock ( new DirectoryPath ( PathToPlaceShim ) , _fileSystem ) ;
2018-01-24 10:16:27 -08:00
_environmentPathInstructionMock =
2018-01-17 19:26:52 -08:00
new EnvironmentPathInstructionMock ( _reporter , PathToPlaceShim ) ;
2018-01-24 10:16:27 -08:00
2018-02-06 13:38:06 -08:00
ParseResult result = Parser . Instance . Parse ( $"dotnet install tool -g {PackageId}" ) ;
2018-01-24 10:16:27 -08:00
_appliedCommand = result [ "dotnet" ] [ "install" ] [ "tool" ] ;
var parser = Parser . Instance ;
2018-02-06 13:38:06 -08:00
_parseResult = parser . ParseFrom ( "dotnet install" , new [ ] { "tool" , PackageId } ) ;
2018-01-24 10:16:27 -08:00
}
[Fact]
public void WhenRunWithPackageIdItShouldCreateValidShim ( )
{
var installToolCommand = new InstallToolCommand ( _appliedCommand ,
_parseResult ,
2018-01-28 13:35:04 -08:00
_toolPackageStore ,
CreateToolPackageInstaller ( ) ,
_shellShimRepositoryMock ,
_environmentPathInstructionMock ,
_reporter ) ;
2018-01-24 10:16:27 -08:00
2018-01-17 19:26:52 -08:00
installToolCommand . Execute ( ) . Should ( ) . Be ( 0 ) ;
2018-01-24 10:16:27 -08:00
// It is hard to simulate shell behavior. Only Assert shim can point to executable dll
2018-01-28 13:35:04 -08:00
_fileSystem . File . Exists ( ExpectedCommandPath ( ) ) . Should ( ) . BeTrue ( ) ;
var deserializedFakeShim = JsonConvert . DeserializeObject < ShellShimRepositoryMock . FakeShim > (
_fileSystem . File . ReadAllText ( ExpectedCommandPath ( ) ) ) ;
_fileSystem . File . Exists ( deserializedFakeShim . ExecutablePath ) . Should ( ) . BeTrue ( ) ;
2018-01-24 10:16:27 -08:00
}
[Fact]
public void WhenRunWithPackageIdWithSourceItShouldCreateValidShim ( )
{
const string sourcePath = "http://mysouce.com" ;
2018-02-06 13:38:06 -08:00
ParseResult result = Parser . Instance . Parse ( $"dotnet install tool -g {PackageId} --source {sourcePath}" ) ;
2018-01-24 10:16:27 -08:00
AppliedOption appliedCommand = result [ "dotnet" ] [ "install" ] [ "tool" ] ;
ParseResult parseResult =
2018-02-06 13:38:06 -08:00
Parser . Instance . ParseFrom ( "dotnet install" , new [ ] { "tool" , PackageId , "--source" , sourcePath } ) ;
2018-01-24 10:16:27 -08:00
var installToolCommand = new InstallToolCommand ( appliedCommand ,
parseResult ,
2018-01-28 13:35:04 -08:00
_toolPackageStore ,
CreateToolPackageInstaller (
feeds : new MockFeed [ ] {
new MockFeed
2018-01-24 10:16:27 -08:00
{
2018-01-28 13:35:04 -08:00
Type = MockFeedType . Source ,
Uri = sourcePath ,
Packages = new List < MockFeedPackage >
2018-01-24 10:16:27 -08:00
{
2018-01-28 13:35:04 -08:00
new MockFeedPackage
{
PackageId = PackageId ,
Version = PackageVersion
}
2018-01-24 10:16:27 -08:00
}
}
2018-01-28 13:35:04 -08:00
} ) ,
_shellShimRepositoryMock ,
_environmentPathInstructionMock ,
_reporter ) ;
2018-01-24 10:16:27 -08:00
2018-01-17 19:26:52 -08:00
installToolCommand . Execute ( ) . Should ( ) . Be ( 0 ) ;
2018-01-24 10:16:27 -08:00
// It is hard to simulate shell behavior. Only Assert shim can point to executable dll
2018-01-28 13:35:04 -08:00
_fileSystem . File . Exists ( ExpectedCommandPath ( ) )
2018-02-06 13:38:06 -08:00
. Should ( ) . BeTrue ( ) ;
2018-01-28 13:35:04 -08:00
var deserializedFakeShim =
JsonConvert . DeserializeObject < ShellShimRepositoryMock . FakeShim > (
_fileSystem . File . ReadAllText ( ExpectedCommandPath ( ) ) ) ;
_fileSystem . File . Exists ( deserializedFakeShim . ExecutablePath ) . Should ( ) . BeTrue ( ) ;
2018-01-24 10:16:27 -08:00
}
[Fact]
public void WhenRunWithPackageIdItShouldShowPathInstruction ( )
{
var installToolCommand = new InstallToolCommand ( _appliedCommand ,
_parseResult ,
2018-01-28 13:35:04 -08:00
_toolPackageStore ,
CreateToolPackageInstaller ( ) ,
_shellShimRepositoryMock ,
_environmentPathInstructionMock ,
_reporter ) ;
2018-01-24 10:16:27 -08:00
2018-01-17 19:26:52 -08:00
installToolCommand . Execute ( ) . Should ( ) . Be ( 0 ) ;
2018-01-24 10:16:27 -08:00
2018-01-28 13:35:04 -08:00
_reporter . Lines . First ( ) . Should ( ) . Be ( "INSTRUCTION" ) ;
2018-01-24 10:16:27 -08:00
}
[Fact]
2018-01-28 13:35:04 -08:00
public void GivenFailedPackageInstallWhenRunWithPackageIdItShouldFail ( )
2018-01-24 10:16:27 -08:00
{
var installToolCommand = new InstallToolCommand (
_appliedCommand ,
_parseResult ,
2018-01-28 13:35:04 -08:00
_toolPackageStore ,
CreateToolPackageInstaller (
installCallback : ( ) = > throw new ToolPackageException ( "Simulated error" ) ) ,
_shellShimRepositoryMock ,
2018-01-24 10:16:27 -08:00
_environmentPathInstructionMock ,
2018-01-17 19:26:52 -08:00
_reporter ) ;
2018-01-24 10:16:27 -08:00
2018-01-17 19:26:52 -08:00
installToolCommand . Execute ( ) . Should ( ) . Be ( 1 ) ;
2018-01-24 10:16:27 -08:00
2018-01-17 19:26:52 -08:00
_reporter . Lines . Count . Should ( ) . Be ( 2 ) ;
_reporter
. Lines [ 0 ]
. Should ( )
. Contain ( "Simulated error" ) ;
_reporter
. Lines [ 1 ]
. Should ( )
2018-01-28 13:35:04 -08:00
. Contain ( string . Format ( LocalizableStrings . ToolInstallationFailed , PackageId ) ) ;
2018-01-24 10:16:27 -08:00
2018-01-28 13:35:04 -08:00
_fileSystem . Directory . Exists ( Path . Combine ( PathToPlacePackages , PackageId ) ) . Should ( ) . BeFalse ( ) ;
2018-02-06 13:38:06 -08:00
}
[Fact]
public void GivenCreateShimItShouldHaveNoBrokenFolderOnDisk ( )
{
2018-01-28 13:35:04 -08:00
_fileSystem . File . CreateEmptyFile ( ExpectedCommandPath ( ) ) ; // Create conflict shim
2018-02-06 13:38:06 -08:00
var installToolCommand = new InstallToolCommand (
_appliedCommand ,
_parseResult ,
2018-01-28 13:35:04 -08:00
_toolPackageStore ,
CreateToolPackageInstaller ( ) ,
_shellShimRepositoryMock ,
2018-02-06 13:38:06 -08:00
_environmentPathInstructionMock ,
_reporter ) ;
2018-01-28 13:35:04 -08:00
installToolCommand . Execute ( ) . Should ( ) . Be ( 1 ) ;
_reporter
. Lines [ 0 ]
. Should ( )
. Contain (
string . Format (
CommonLocalizableStrings . ShellShimConflict ,
ProjectRestorerMock . FakeCommandName ) ) ;
2018-02-06 13:38:06 -08:00
2018-01-28 13:35:04 -08:00
_fileSystem . Directory . Exists ( Path . Combine ( PathToPlacePackages , PackageId ) ) . Should ( ) . BeFalse ( ) ;
2018-02-06 13:38:06 -08:00
}
2018-01-24 10:16:27 -08:00
[Fact]
2018-01-17 19:26:52 -08:00
public void GivenInCorrectToolConfigurationWhenRunWithPackageIdItShouldFail ( )
2018-01-24 10:16:27 -08:00
{
var installToolCommand = new InstallToolCommand (
_appliedCommand ,
_parseResult ,
2018-01-28 13:35:04 -08:00
_toolPackageStore ,
CreateToolPackageInstaller (
installCallback : ( ) = > throw new ToolConfigurationException ( "Simulated error" ) ) ,
_shellShimRepositoryMock ,
2018-01-24 10:16:27 -08:00
_environmentPathInstructionMock ,
2018-01-17 19:26:52 -08:00
_reporter ) ;
installToolCommand . Execute ( ) . Should ( ) . Be ( 1 ) ;
_reporter . Lines . Count . Should ( ) . Be ( 2 ) ;
2018-01-24 10:16:27 -08:00
2018-01-17 19:26:52 -08:00
_reporter
. Lines [ 0 ]
. Should ( )
. Contain (
string . Format (
LocalizableStrings . InvalidToolConfiguration ,
"Simulated error" ) ) ;
_reporter
. Lines [ 1 ]
. Should ( )
2018-01-28 13:35:04 -08:00
. Contain ( string . Format ( LocalizableStrings . ToolInstallationFailedContactAuthor , PackageId ) ) ;
2018-01-24 10:16:27 -08:00
}
[Fact]
public void WhenRunWithPackageIdItShouldShowSuccessMessage ( )
{
var installToolCommand = new InstallToolCommand (
_appliedCommand ,
_parseResult ,
2018-01-28 13:35:04 -08:00
_toolPackageStore ,
CreateToolPackageInstaller ( ) ,
_shellShimRepositoryMock ,
2018-01-17 19:26:52 -08:00
new EnvironmentPathInstructionMock ( _reporter , PathToPlaceShim , true ) ,
_reporter ) ;
2018-01-24 10:16:27 -08:00
2018-01-17 19:26:52 -08:00
installToolCommand . Execute ( ) . Should ( ) . Be ( 0 ) ;
2018-01-24 10:16:27 -08:00
2018-01-17 19:26:52 -08:00
_reporter
. Lines
2018-01-28 13:35:04 -08:00
. Single ( )
. Should ( )
. Contain ( string . Format (
LocalizableStrings . InstallationSucceeded ,
ProjectRestorerMock . FakeCommandName ,
PackageId ,
PackageVersion ) ) ;
}
private IToolPackageInstaller CreateToolPackageInstaller (
IEnumerable < MockFeed > feeds = null ,
Action installCallback = null )
{
return new ToolPackageInstallerMock (
fileSystem : _fileSystem ,
store : _toolPackageStore ,
projectRestorer : new ProjectRestorerMock (
fileSystem : _fileSystem ,
reporter : _reporter ,
feeds : feeds ) ,
installCallback : installCallback ) ;
2018-01-24 10:16:27 -08:00
}
2018-02-06 13:38:06 -08:00
private static string ExpectedCommandPath ( )
{
var extension = RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) ? ".exe" : string . Empty ;
return Path . Combine (
"pathToPlace" ,
2018-01-28 13:35:04 -08:00
ProjectRestorerMock . FakeCommandName + extension ) ;
2018-02-06 13:38:06 -08:00
}
2018-01-24 10:16:27 -08:00
}
}