2016-09-22 15:56:36 -05: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.
2016-11-01 09:29:50 -07:00
using System ;
using System.Linq ;
using System.Linq.Expressions ;
using System.Reflection ;
2017-01-31 16:47:41 -08:00
using System.Runtime.InteropServices ;
2016-09-22 15:56:36 -05:00
using FluentAssertions ;
2016-11-01 09:29:50 -07:00
using Microsoft.DotNet.Configurer ;
using Microsoft.DotNet.Tools.MSBuild ;
2016-09-22 15:56:36 -05:00
using Microsoft.DotNet.Tools.Test.Utilities ;
2016-11-01 09:29:50 -07:00
using NuGet.Protocol ;
2016-09-22 15:56:36 -05:00
using Xunit ;
2017-02-01 14:12:34 -08:00
using Xunit.Abstractions ;
2016-11-01 09:29:50 -07:00
using MSBuildCommand = Microsoft . DotNet . Tools . Test . Utilities . MSBuildCommand ;
2016-09-22 15:56:36 -05:00
2016-09-23 11:11:44 -05:00
namespace Microsoft.DotNet.Cli.MSBuild.Tests
2016-09-22 15:56:36 -05:00
{
public class GivenDotnetMSBuildBuildsProjects : TestBase
{
2017-02-01 14:12:34 -08:00
private readonly ITestOutputHelper _output ;
public GivenDotnetMSBuildBuildsProjects ( ITestOutputHelper output )
{
_output = output ;
}
2016-09-22 15:56:36 -05:00
[Fact]
public void ItRunsSpecifiedTargetsWithPropertiesCorrectly ( )
{
var testInstance = TestAssetsManager
. CreateTestInstance ( "MSBuildBareBonesProject" ) ;
var testProjectDirectory = testInstance . TestRoot ;
new MSBuildCommand ( )
. WithWorkingDirectory ( testProjectDirectory )
. ExecuteWithCapturedOutput ( "/t:SayHello" )
. Should ( )
. Pass ( )
. And
. HaveStdOutContaining ( "Hello, from MSBuild!" ) ;
new MSBuildCommand ( )
. WithWorkingDirectory ( testProjectDirectory )
. ExecuteWithCapturedOutput ( "/t:SayGoodbye" )
. Should ( )
. Pass ( )
. And
. HaveStdOutContaining ( "Goodbye, from MSBuild. :'(" ) ;
new MSBuildCommand ( )
. WithWorkingDirectory ( testProjectDirectory )
. ExecuteWithCapturedOutput ( "/t:SayThis /p:This=GreatScott" )
. Should ( )
. Pass ( )
. And
. HaveStdOutContaining ( "You want me to say 'GreatScott'" ) ;
}
2016-10-11 17:29:09 -07:00
[Theory]
2016-10-27 18:46:43 -07:00
[InlineData("build", true)]
[InlineData("clean", true)]
[InlineData("pack", true)]
[InlineData("publish", true)]
[InlineData("restore", true)]
public void When_help_is_invoked_Then_MSBuild_extra_options_text_is_included_in_output ( string commandName , bool isMSBuildCommand )
2016-10-11 17:29:09 -07:00
{
2016-12-16 23:59:58 -08:00
const string MSBuildHelpText = " Any extra options that should be passed to MSBuild. See 'dotnet msbuild -h' for available options." ;
2016-10-11 17:29:09 -07:00
var projectDirectory = TestAssetsManager . CreateTestDirectory ( "ItContainsMSBuildHelpText" ) ;
var result = new TestCommand ( "dotnet" )
. WithWorkingDirectory ( projectDirectory . Path )
. ExecuteWithCapturedOutput ( $"{commandName} --help" ) ;
2016-11-01 09:29:50 -07:00
2016-10-11 17:29:09 -07:00
result . ExitCode . Should ( ) . Be ( 0 ) ;
if ( isMSBuildCommand )
{
result . StdOut . Should ( ) . Contain ( MSBuildHelpText ) ;
}
else
{
result . StdOut . Should ( ) . NotContain ( MSBuildHelpText ) ;
}
}
2017-01-31 16:47:41 -08:00
[Fact]
public void WhenRestoreSourcesStartsWithUnixPathThenHttpsSourceIsParsedCorrectly ( )
{
if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) )
{
return ;
}
// this is a workaround for https://github.com/Microsoft/msbuild/issues/1622
2017-02-01 14:12:34 -08:00
var testInstance = TestAssets . Get ( "LibraryWithUnresolvablePackageReference" )
2017-01-31 16:47:41 -08:00
. CreateInstance ( )
2017-02-01 14:12:34 -08:00
. WithSourceFiles ( ) ;
2017-01-31 16:47:41 -08:00
var root = testInstance . Root ;
var somePathThatExists = "/usr/local/bin" ;
var result = new DotnetCommand ( )
. WithWorkingDirectory ( root )
2017-02-01 14:12:34 -08:00
. Execute ( $"msbuild /p:RestoreSources={somePathThatExists};https://api.nuget.org/v3/index.json /t:restore LibraryWithUnresolvablePackageReference.csproj" ) ;
_output . WriteLine ( $"[STDOUT]\n{result.StdOut}\n[STDERR]\n{result.StdErr}" ) ;
result . Should ( ) . Fail ( ) ;
2017-06-01 21:31:14 -07:00
result . StdOut . Should ( ) . ContainVisuallySameFragment ( @"source(s): /usr/local/bin, nuget.org" ) ;
2017-01-31 16:47:41 -08:00
}
2016-12-19 22:11:39 -08:00
[Fact]
public void WhenDotnetRunHelpIsInvokedAppArgumentsTextIsIncludedInOutput ( )
{
const string AppArgumentsText = "Arguments passed to the application that is being run." ;
var projectDirectory = TestAssetsManager . CreateTestDirectory ( "RunContainsAppArgumentsText" ) ;
var result = new TestCommand ( "dotnet" )
. WithWorkingDirectory ( projectDirectory . Path )
. ExecuteWithCapturedOutput ( "run --help" ) ;
2017-01-31 16:47:41 -08:00
2016-12-19 22:11:39 -08:00
result . ExitCode . Should ( ) . Be ( 0 ) ;
result . StdOut . Should ( ) . Contain ( AppArgumentsText ) ;
}
2016-11-01 09:29:50 -07:00
[Fact]
public void WhenTelemetryIsEnabledTheLoggerIsAddedToTheCommandLine ( )
{
2016-11-14 14:26:03 -08:00
Telemetry telemetry ;
string [ ] allArgs = GetArgsForMSBuild ( ( ) = > true , out telemetry ) ;
// telemetry will still be disabled if environmental variable is set
if ( telemetry . Enabled )
{
allArgs . Should ( ) . NotBeNull ( ) ;
2016-11-01 09:29:50 -07:00
2016-11-14 14:26:03 -08:00
allArgs . Should ( ) . Contain (
value = > value . IndexOf ( "/Logger" , StringComparison . OrdinalIgnoreCase ) > = 0 ,
"The MSBuild logger argument should be specified when telemetry is enabled." ) ;
}
2016-11-01 09:29:50 -07:00
}
[Fact]
public void WhenTelemetryIsDisabledTheLoggerIsNotAddedToTheCommandLine ( )
{
string [ ] allArgs = GetArgsForMSBuild ( ( ) = > false ) ;
allArgs . Should ( ) . NotBeNull ( ) ;
2016-11-02 13:06:44 -07:00
allArgs . Should ( ) . NotContain (
value = > value . IndexOf ( "/Logger" , StringComparison . OrdinalIgnoreCase ) > = 0 ,
$"The MSBuild logger argument should not be specified when telemetry is disabled." ) ;
2016-11-01 09:29:50 -07:00
}
private string [ ] GetArgsForMSBuild ( Func < bool > sentinelExists )
{
2016-11-14 14:26:03 -08:00
Telemetry telemetry ;
return GetArgsForMSBuild ( sentinelExists , out telemetry ) ;
}
private string [ ] GetArgsForMSBuild ( Func < bool > sentinelExists , out Telemetry telemetry )
{
telemetry = new Telemetry ( new MockNuGetCacheSentinel ( sentinelExists ) ) ;
2016-11-01 09:29:50 -07:00
MSBuildForwardingApp msBuildForwardingApp = new MSBuildForwardingApp ( Enumerable . Empty < string > ( ) ) ;
2016-11-02 13:06:44 -07:00
FieldInfo forwardingAppFieldInfo = msBuildForwardingApp
. GetType ( )
. GetField ( "_forwardingApp" , BindingFlags . Instance | BindingFlags . NonPublic ) ;
2016-11-01 09:29:50 -07:00
ForwardingApp forwardingApp = forwardingAppFieldInfo ? . GetValue ( msBuildForwardingApp ) as ForwardingApp ;
2016-11-02 13:06:44 -07:00
FieldInfo allArgsFieldinfo = forwardingApp ?
. GetType ( )
. GetField ( "_allArgs" , BindingFlags . Instance | BindingFlags . NonPublic ) ;
2016-11-01 09:29:50 -07:00
return allArgsFieldinfo ? . GetValue ( forwardingApp ) as string [ ] ;
}
}
public sealed class MockNuGetCacheSentinel : INuGetCacheSentinel
{
private readonly Func < bool > _exists ;
public MockNuGetCacheSentinel ( Func < bool > exists = null )
{
_exists = exists ? ? ( ( ) = > true ) ;
}
public void Dispose ( )
{
}
public bool InProgressSentinelAlreadyExists ( ) = > false ;
public bool Exists ( ) = > _exists ( ) ;
public void CreateIfNotExists ( )
{
}
2016-09-22 15:56:36 -05:00
}
}