GetNativeSearchDirectories.cs 7.3 KB
Newer Older
S
Stephen Toub 已提交
1
// Licensed to the .NET Foundation under one or more agreements.
2 3 4
// The .NET Foundation licenses this file to you under the MIT license.

using System.IO;
V
vitek-karas 已提交
5
using System.Runtime.InteropServices;
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
using Microsoft.DotNet.Cli.Build;
using Microsoft.DotNet.Cli.Build.Framework;
using Xunit;

namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.NativeHosting
{
    public class GetNativeSearchDirectories : IClassFixture<GetNativeSearchDirectories.SharedTestState>
    {
        public class Scenario
        {
            public const string GetForCommandLine = "get_for_command_line";
        }

        private const string GetNativeSearchDirectoriesArg = "get_native_search_directories";

        private readonly SharedTestState sharedState;

        public GetNativeSearchDirectories(SharedTestState sharedTestState)
        {
            sharedState = sharedTestState;
        }

        [Fact]
        public void BasicApp()
        {
            string[] args =
            {
                GetNativeSearchDirectoriesArg,
                Scenario.GetForCommandLine,
                sharedState.HostFxrPath,
                sharedState.DotNet.DotnetExecutablePath,
                sharedState.AppPath
            };

            CommandResult result = sharedState.CreateNativeHostCommand(args, sharedState.DotNet.BinPath)
                .Execute();

43
            string pathSuffix = Path.DirectorySeparatorChar.ToString();
44
            string expectedSearchDirectories =
V
vitek-karas 已提交
45 46
                Path.GetDirectoryName(sharedState.AppPath) + pathSuffix + Path.PathSeparator +
                Path.Combine(sharedState.DotNet.BinPath, "shared", "Microsoft.NETCore.App", SharedTestState.NetCoreAppVersion) + pathSuffix + Path.PathSeparator;
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
            result.Should().Pass()
                .And.HaveStdOutContaining($"Native search directories: '{expectedSearchDirectories}'");
        }

        [Fact]
        public void Invalid_NullBufferWithNonZeroSize()
        {
            string[] args =
            {
                GetNativeSearchDirectoriesArg,
                Scenario.GetForCommandLine,
                sharedState.HostFxrPath,
                "test_NullBufferWithNonZeroSize"
            };

            sharedState.CreateNativeHostCommand(args, sharedState.DotNet.BinPath)
                .Execute()
                .Should().Fail()
                .And.HaveStdOutContaining($"get_native_search_directories (null, 1) returned: 0x{Constants.ErrorCode.InvalidArgFailure:x}")
                .And.HaveStdOutContaining("buffer_size: 0")
                .And.HaveStdOutContaining("hostfxr reported errors:")
                .And.HaveStdOutContaining("hostfxr_get_native_search_directories received an invalid argument.");
        }

        [Fact]
        public void Invalid_NonNullBufferWithNegativeSize()
        {
            string[] args =
            {
                GetNativeSearchDirectoriesArg,
                Scenario.GetForCommandLine,
                sharedState.HostFxrPath,
                "test_NonNullBufferWithNegativeSize"
            };

            sharedState.CreateNativeHostCommand(args, sharedState.DotNet.BinPath)
                .Execute()
                .Should().Fail()
                .And.HaveStdOutContaining($"get_native_search_directories (temp_buffer, -1) returned: 0x{Constants.ErrorCode.InvalidArgFailure:x}")
                .And.HaveStdOutContaining("buffer_size: 0")
                .And.HaveStdOutContaining("hostfxr reported errors:")
                .And.HaveStdOutContaining("hostfxr_get_native_search_directories received an invalid argument.");
        }

        // This test also validates that hostfxr_set_error_writer propagates the custom writer
        // to the hostpolicy.dll for the duration of those calls.
        [Fact]
        public void WithInvalidDepsJson()
        {
            string[] args =
            {
                GetNativeSearchDirectoriesArg,
                Scenario.GetForCommandLine,
                sharedState.HostFxrPath,
                sharedState.DotNet.DotnetExecutablePath,
                sharedState.AppPath
            };

            string depsJsonFile = Path.Combine(sharedState.AppDirectory, "App.deps.json");
            try
            {
                File.WriteAllText(depsJsonFile, "{");

                sharedState.CreateNativeHostCommand(args, sharedState.DotNet.BinPath)
                    .Execute()
                    .Should().Fail()
                    .And.HaveStdOutContaining($"get_native_search_directories (null,0) returned unexpected error code 0x{Constants.ErrorCode.ResolverInitFailure:x} expected HostApiBufferTooSmall (0x80008098).")
                    .And.HaveStdOutContaining("buffer_size: 0")
                    .And.HaveStdOutContaining("hostfxr reported errors:")
                    .And.HaveStdOutContaining($"A JSON parsing exception occurred in [{depsJsonFile}], offset 1 (line 1, column 2): Missing a name for object member.")
                    .And.HaveStdOutContaining($"Error initializing the dependency resolver: An error occurred while parsing: {depsJsonFile}");
            }
            finally
            {
                FileUtils.DeleteFileIfPossible(depsJsonFile);
            }
        }

        [Fact]
        public void CliCommand()
        {
            string[] args =
            {
                GetNativeSearchDirectoriesArg,
                Scenario.GetForCommandLine,
                sharedState.HostFxrPath,
                sharedState.DotNet.DotnetExecutablePath,
                "build"
            };

            CommandResult result = sharedState.CreateNativeHostCommand(args, sharedState.DotNet.BinPath)
                .Execute();

            result.Should().Fail()
                .And.HaveStdOutContaining($"get_native_search_directories (null,0) returned unexpected error code 0x{Constants.ErrorCode.AppArgNotRunnable:x} expected HostApiBufferTooSmall (0x80008098).")
                .And.HaveStdOutContaining("buffer_size: 0")
                .And.HaveStdErrContaining("Application 'build' is not a managed executable.");
        }

        public class SharedTestState : SharedTestStateBase
        {
            public string HostFxrPath { get; }
            public DotNetCli DotNet { get; }
            public string AppDirectory { get; }
            public string AppPath { get; }

            public const string NetCoreAppVersion = "2.2.0";

            public SharedTestState()
            {
                DotNet = new DotNetBuilder(BaseDirectory, Path.Combine(TestArtifact.TestArtifactsPath, "sharedFrameworkPublish"), "mockRuntime")
                    .AddMicrosoftNETCoreAppFrameworkMockCoreClr(NetCoreAppVersion)
                    .Build();

                HostFxrPath = Path.Combine(
                    DotNet.GreatestVersionHostFxrPath,
                    RuntimeInformationExtensions.GetSharedLibraryFileNameForCurrentPlatform("hostfxr"));

                AppDirectory = Path.Combine(BaseDirectory, "app");
                Directory.CreateDirectory(AppDirectory);
                AppPath = Path.Combine(AppDirectory, "App.dll");
                File.WriteAllText(AppPath, string.Empty);

                RuntimeConfig.FromFile(Path.Combine(AppDirectory, "App.runtimeconfig.json"))
                    .WithFramework(new RuntimeConfig.Framework(Constants.MicrosoftNETCoreApp, NetCoreAppVersion))
                    .Save();
            }
        }
    }
}