Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.DotNet.Cli.Build;
using Microsoft.DotNet.Cli.Build.Framework;
using Microsoft.DotNet.CoreSetup.Test;
using Microsoft.DotNet.CoreSetup.Test.HostActivation;
Expand Down Expand Up @@ -146,6 +147,44 @@ public void EnvironmentVariable_DotnetRootPathExistsButHasNoHost()
}
}

[Fact]
public void EnvironmentVariable_DotNetInfo_ListEnvironment()
{
var dotnet = new DotNetCli(sharedTestState.RepoDirectories.BuiltDotnet);

var command = dotnet.Exec("--info")
.CaptureStdOut();

var envVars = new (string Architecture, string Path)[] {
("arm64", "/arm64/dotnet/root"),
("x64", "/x64/dotnet/root"),
("x86", "/x86/dotnet/root")
};
foreach(var envVar in envVars)
{
command = command.DotNetRoot(envVar.Path, envVar.Architecture);
}

string dotnetRootNoArch = "/dotnet/root";
command = command.DotNetRoot(dotnetRootNoArch);

(string Architecture, string Path) unknownEnvVar = ("unknown", "/unknown/dotnet/root");
command = command.DotNetRoot(unknownEnvVar.Path, unknownEnvVar.Architecture);

var result = command.Execute();
result.Should().Pass()
.And.HaveStdOutContaining("Environment variables:")
.And.HaveStdOutMatching($@"{Constants.DotnetRoot.EnvironmentVariable}\s*\[{dotnetRootNoArch}\]")
.And.NotHaveStdOutContaining($"{Constants.DotnetRoot.ArchitectureEnvironmentVariablePrefix}{unknownEnvVar.Architecture.ToUpper()}")
.And.NotHaveStdOutContaining($"[{unknownEnvVar.Path}]");

foreach ((string architecture, string path) in envVars)
{
result.Should()
.HaveStdOutMatching($@"{Constants.DotnetRoot.ArchitectureEnvironmentVariablePrefix}{architecture.ToUpper()}\s*\[{path}\]");
}
}

[Fact]
public void RegisteredInstallLocation_ArchSpecificLocationIsPickedFirst()
{
Expand Down Expand Up @@ -241,6 +280,49 @@ public void InstallLocationFile_MissingFile()
}
}

[Fact]
public void RegisteredInstallLocation_DotNetInfo_ListOtherArchitectures()
{
using (var testArtifact = new TestArtifact(SharedFramework.CalculateUniqueTestDirectory(Path.Combine(TestArtifact.TestArtifactsPath, "listOtherArchs"))))
{
var dotnet = new DotNetBuilder(testArtifact.Location, sharedTestState.RepoDirectories.BuiltDotnet, "exe").Build();
using (var registeredInstallLocationOverride = new RegisteredInstallLocationOverride(dotnet.GreatestVersionHostFxrFilePath))
{
var installLocations = new (string, string)[] {
("arm64", "/arm64/install/path"),
("x64", "/x64/install/path"),
("x86", "/x86/install/path")
};
(string Architecture, string Path) unknownArchInstall = ("unknown", "/unknown/install/path");
registeredInstallLocationOverride.SetInstallLocation(installLocations);
registeredInstallLocationOverride.SetInstallLocation(unknownArchInstall);

var result = dotnet.Exec("--info")
.CaptureStdOut()
.ApplyRegisteredInstallLocationOverride(registeredInstallLocationOverride)
.Execute();

result.Should().Pass()
.And.HaveStdOutContaining("Other architectures found:")
.And.NotHaveStdOutContaining(unknownArchInstall.Architecture)
.And.NotHaveStdOutContaining($"[{unknownArchInstall.Path}]");

string pathOverride = OperatingSystem.IsWindows() // Host uses short form of base key for Windows
? registeredInstallLocationOverride.PathValueOverride.Replace(Microsoft.Win32.Registry.CurrentUser.Name, "HKCU")
: registeredInstallLocationOverride.PathValueOverride;
pathOverride = System.Text.RegularExpressions.Regex.Escape(pathOverride);
foreach ((string arch, string path) in installLocations)
{
if (arch == sharedTestState.RepoDirectories.BuildArchitecture)
continue;

result.Should()
.HaveStdOutMatching($@"{arch}\s*\[{path}\]\r?$\s*registered at \[{pathOverride}.*{arch}.*\]", System.Text.RegularExpressions.RegexOptions.Multiline);
}
}
}
}

public class SharedTestState : IDisposable
{
public string BaseDirectory { get; }
Expand Down
2 changes: 1 addition & 1 deletion src/installer/tests/HostActivation.Tests/SDKLookup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public void SdkLookup_Global_Json_Single_Digit_Patch_Rollup()
.Should().Fail()
.And.NotFindCompatibleSdk(globalJsonPath, requestedVersion)
.And.FindAnySdk(false)
.And.HaveStdErrContaining("aka.ms/dotnet-download")
.And.HaveStdErrContaining("aka.ms/dotnet/download")
.And.NotHaveStdErrContaining("Checking if resolved SDK dir");

// Add SDK versions
Expand Down
30 changes: 11 additions & 19 deletions src/installer/tests/TestUtils/DotNetCli.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public partial class DotNetCli
{
public string BinPath { get; }
public string GreatestVersionSharedFxPath { get; }
public string GreatestVersionHostFxrPath { get; }
public string GreatestVersionHostFxrPath { get; }
public string GreatestVersionHostFxrFilePath { get => Path.Combine(
GreatestVersionHostFxrPath,
RuntimeInformationExtensions.GetSharedLibraryFileNameForCurrentPlatform("hostfxr")); }
Expand All @@ -29,30 +29,22 @@ public DotNetCli(string binPath)
BinPath = binPath;

var sharedFxBaseDirectory = Path.Combine(BinPath, "shared", "Microsoft.NETCore.App");
if (!Directory.Exists(sharedFxBaseDirectory))
if (Directory.Exists(sharedFxBaseDirectory))
{
GreatestVersionSharedFxPath = null;
return;
var sharedFxVersionDirectories = Directory.EnumerateDirectories(sharedFxBaseDirectory);
GreatestVersionSharedFxPath = sharedFxVersionDirectories
.OrderByDescending(p => p.ToLower())
.First();
}

var hostFxrBaseDirectory = Path.Combine(BinPath, "host", "fxr");

if (!Directory.Exists(hostFxrBaseDirectory))
if (Directory.Exists(hostFxrBaseDirectory))
{
GreatestVersionHostFxrPath = null;
return;
var hostFxrVersionDirectories = Directory.EnumerateDirectories(hostFxrBaseDirectory);
GreatestVersionHostFxrPath = hostFxrVersionDirectories
.OrderByDescending(p => p.ToLower())
.First();
}

var sharedFxVersionDirectories = Directory.EnumerateDirectories(sharedFxBaseDirectory);

GreatestVersionSharedFxPath = sharedFxVersionDirectories
.OrderByDescending(p => p.ToLower())
.First();

var hostFxrVersionDirectories = Directory.EnumerateDirectories(hostFxrBaseDirectory);
GreatestVersionHostFxrPath = hostFxrVersionDirectories
.OrderByDescending(p => p.ToLower())
.First();
}

public Command Exec(string command, params string[] args)
Expand Down
2 changes: 1 addition & 1 deletion src/native/corehost/apphost/apphost.windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ namespace
pal::string_t get_apphost_details_message()
{
pal::string_t msg = _X("Architecture: ");
msg.append(get_arch());
msg.append(get_current_arch_name());
msg.append(_X("\n")
_X("App host version: ") _STRINGIFY(COMMON_HOST_PKG_VER) _X("\n\n"));
return msg;
Expand Down
4 changes: 2 additions & 2 deletions src/native/corehost/corehost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ void need_newer_framework_error(const pal::string_t& dotnet_root, const pal::str
_X("Download the .NET runtime:\n")
_X("%s&apphost_version=%s"),
host_path.c_str(),
get_arch(),
get_current_arch_name(),
_STRINGIFY(COMMON_HOST_PKG_VER),
dotnet_root.c_str(),
get_download_url().c_str(),
Expand Down Expand Up @@ -225,7 +225,7 @@ int exe_start(const int argc, const pal::char_t* argv[])
else
{
// An outdated hostfxr can only be found for framework-related apps.
trace::error(_X("The required library %s does not support single-file apps."), fxr.fxr_path().c_str());
trace::error(_X("The required library %s does not support single-file apps."), fxr.fxr_path().c_str());
need_newer_framework_error(fxr.dotnet_root(), host_path);
rc = StatusCode::FrameworkMissingFailure;
}
Expand Down
2 changes: 1 addition & 1 deletion src/native/corehost/deps_format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ pal::string_t deps_json_t::get_current_rid(const rid_fallback_graph_t& rid_fallb
// We do the same even when the RID is empty.
if (currentRid.empty() || (rid_fallback_graph.count(currentRid) == 0))
{
currentRid = pal::get_current_os_fallback_rid() + pal::string_t(_X("-")) + get_arch();
currentRid = pal::get_current_os_fallback_rid() + pal::string_t(_X("-")) + get_current_arch_name();

trace::info(_X("Falling back to base HostRID: %s"), currentRid.c_str());
}
Expand Down
58 changes: 40 additions & 18 deletions src/native/corehost/fxr/command_line.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "command_line.h"
#include <error_codes.h>
#include "framework_info.h"
#include "install_info.h"
#include <pal.h>
#include "sdk_info.h"
#include <trace.h>
Expand Down Expand Up @@ -279,37 +280,58 @@ int command_line::parse_args_for_sdk_command(
return parse_args(host_info, 1, argc, argv, false, host_mode_t::muxer, new_argoff, app_candidate, opts);
}

void command_line::print_muxer_info(const pal::string_t &dotnet_root)
void command_line::print_muxer_info(const pal::string_t &dotnet_root, const pal::string_t &global_json_path)
{
trace::println();
trace::println(_X("Host:"));
trace::println(_X(" Version: %s"), _STRINGIFY(HOST_FXR_PKG_VER));
trace::println(_X(" Architecture: %s"), get_arch());

pal::string_t commit = _STRINGIFY(REPO_COMMIT_HASH);
trace::println(_X(" Commit: %s"), commit.substr(0, 10).c_str());

trace::println();
trace::println(_X(".NET SDKs installed:"));
trace::println(_X("\n")
_X("Host:\n")
_X(" Version: ") _STRINGIFY(HOST_FXR_PKG_VER) _X("\n")
_X(" Architecture: %s\n")
_X(" Commit: %s"),
get_current_arch_name(),
commit.substr(0, 10).c_str());

trace::println(_X("\n")
_X(".NET SDKs installed:"));
if (!sdk_info::print_all_sdks(dotnet_root, _X(" ")))
{
trace::println(_X(" No SDKs were found."));
}

trace::println();
trace::println(_X(".NET runtimes installed:"));
trace::println(_X("\n")
_X(".NET runtimes installed:"));
if (!framework_info::print_all_frameworks(dotnet_root, _X(" ")))
{
trace::println(_X(" No runtimes were found."));
}

trace::println();
trace::println(_X("Download .NET:"));
trace::println(_X(" %s"), DOTNET_CORE_DOWNLOAD_URL);
trace::println(_X("\n")
_X("Other architectures found:"));
if (!install_info::print_other_architectures(_X(" ")))
{
trace::println(_X(" None"));
}

trace::println();
trace::println(_X("Learn about .NET Runtimes and SDKs:"));
trace::println(_X(" %s"), DOTNET_INFO_URL);}
trace::println(_X("\n")
_X("Environment variables:"));
if (!install_info::print_environment(_X(" ")))
{
trace::println(_X(" Not set"));
}

trace::println(_X("\n")
_X("global.json file:\n")
_X(" %s"),
global_json_path.empty() ? _X("Not found") : global_json_path.c_str());

trace::println(_X("\n")
_X("Learn more:\n")
_X(" ") DOTNET_INFO_URL);

trace::println(_X("\n")
_X("Download .NET:\n")
_X(" ") DOTNET_CORE_DOWNLOAD_URL);
}

void command_line::print_muxer_usage(bool is_sdk_present)
{
Expand Down
2 changes: 1 addition & 1 deletion src/native/corehost/fxr/command_line.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ namespace command_line
/*out*/ pal::string_t &app_candidate,
/*out*/ opt_map_t &opts);

void print_muxer_info(const pal::string_t &dotnet_root);
void print_muxer_info(const pal::string_t &dotnet_root, const pal::string_t &global_json_path);
void print_muxer_usage(bool is_sdk_present);
};

Expand Down
2 changes: 2 additions & 0 deletions src/native/corehost/fxr/files.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ list(APPEND SOURCES
${CMAKE_CURRENT_LIST_DIR}/fx_resolver.messages.cpp
${CMAKE_CURRENT_LIST_DIR}/framework_info.cpp
${CMAKE_CURRENT_LIST_DIR}/host_context.cpp
${CMAKE_CURRENT_LIST_DIR}/install_info.cpp
${CMAKE_CURRENT_LIST_DIR}/sdk_info.cpp
${CMAKE_CURRENT_LIST_DIR}/sdk_resolver.cpp
)
Expand All @@ -31,6 +32,7 @@ list(APPEND HEADERS
${CMAKE_CURRENT_LIST_DIR}/fx_resolver.h
${CMAKE_CURRENT_LIST_DIR}/framework_info.h
${CMAKE_CURRENT_LIST_DIR}/host_context.h
${CMAKE_CURRENT_LIST_DIR}/install_info.h
${CMAKE_CURRENT_LIST_DIR}/sdk_info.h
${CMAKE_CURRENT_LIST_DIR}/sdk_resolver.h
)
Expand Down
8 changes: 3 additions & 5 deletions src/native/corehost/fxr/fx_muxer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ void append_probe_realpath(const pal::string_t& path, std::vector<pal::string_t>

if (pos_placeholder != pal::string_t::npos)
{
pal::string_t segment = get_arch();
pal::string_t segment = get_current_arch_name();
segment.push_back(DIR_SEPARATOR);
segment.append(tfm);
probe_path.replace(pos_placeholder, placeholder.length(), segment);
Expand Down Expand Up @@ -1066,8 +1066,7 @@ int fx_muxer_t::handle_cli(
}
else if (pal::strcasecmp(_X("--info"), argv[1]) == 0)
{
resolver.print_global_file_path();
command_line::print_muxer_info(host_info.dotnet_root);
command_line::print_muxer_info(host_info.dotnet_root, resolver.global_file_path());
return StatusCode::Success;
}

Expand Down Expand Up @@ -1124,8 +1123,7 @@ int fx_muxer_t::handle_cli(

if (pal::strcasecmp(_X("--info"), argv[1]) == 0)
{
resolver.print_global_file_path();
command_line::print_muxer_info(host_info.dotnet_root);
command_line::print_muxer_info(host_info.dotnet_root, resolver.global_file_path());
}

return result;
Expand Down
2 changes: 1 addition & 1 deletion src/native/corehost/fxr/fx_resolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ StatusCode fx_resolver_t::read_framework(
_X("App: %s\n")
_X("Architecture: %s"),
app_display_name != nullptr ? app_display_name : host_info.host_path.c_str(),
get_arch());
get_current_arch_name());
display_missing_framework_error(fx_name, new_effective_fx_ref.get_fx_version(), pal::string_t(), host_info.dotnet_root, disable_multilevel_lookup);
return FrameworkMissingFailure;
}
Expand Down
4 changes: 2 additions & 2 deletions src/native/corehost/fxr/fx_resolver.messages.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,11 @@ void fx_resolver_t::display_missing_framework_error(
// Display the error message about missing FX.
if (fx_version.length())
{
trace::error(_X("Framework: '%s', version '%s' (%s)"), fx_name.c_str(), fx_version.c_str(), get_arch());
trace::error(_X("Framework: '%s', version '%s' (%s)"), fx_name.c_str(), fx_version.c_str(), get_current_arch_name());
}
else
{
trace::error(_X("Framework: '%s', (%s)"), fx_name.c_str(), get_arch());
trace::error(_X("Framework: '%s', (%s)"), fx_name.c_str(), get_current_arch_name());
}

trace::error(_X(".NET location: %s\n"), dotnet_root.c_str());
Expand Down
Loading