Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add runtime property HOSTFXR_PATH #55369

Merged
merged 5 commits into from
Jul 13, 2021
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 @@ -14,7 +14,14 @@ public static void Main(string[] args)

foreach (string propertyName in args)
{
Console.WriteLine($"AppContext.GetData({propertyName}) = {System.AppContext.GetData(propertyName)}");
var propertyValue = (string)System.AppContext.GetData(propertyName);
if (string.IsNullOrEmpty(propertyValue))
{
Console.WriteLine($"Property '{propertyName}' was not found.");
continue;
}

Console.WriteLine($"AppContext.GetData({propertyName}) = {propertyValue}");
}
}
}
Expand Down
16 changes: 16 additions & 0 deletions src/installer/tests/HostActivation.Tests/DotNetBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,22 @@ public DotNetBuilder AddMicrosoftNETCoreAppFrameworkMockCoreClr(string version,
return this;
}

public DotNetBuilder AddMockSDK(
string version,
string MNAVersion)
{
string path = Path.Combine(_path, "sdk", version);
Directory.CreateDirectory(path);

using var _ = File.Create(Path.Combine(path, "dotnet.dll"));

RuntimeConfig dotnetRuntimeConfig = new RuntimeConfig(Path.Combine(path, "dotnet.runtimeconfig.json"));
dotnetRuntimeConfig.WithFramework(new RuntimeConfig.Framework("Microsoft.NETCore.App", MNAVersion));
dotnetRuntimeConfig.Save();

return this;
}

public DotNetCli Build()
{
return new DotNetCli(_path);
Expand Down
58 changes: 46 additions & 12 deletions src/installer/tests/HostActivation.Tests/RuntimeProperties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.IO;
using Microsoft.DotNet.Cli.Build;
using Xunit;

namespace Microsoft.DotNet.CoreSetup.Test.HostActivation
Expand All @@ -25,9 +26,7 @@ public void AppConfigProperty_AppCanGetData()
var dotnet = fixture.BuiltDotnet;
var appDll = fixture.TestProject.AppDll;
dotnet.Exec(appDll, sharedState.AppTestPropertyName)
.EnvironmentVariable("COREHOST_TRACE", "1")
.CaptureStdErr()
.CaptureStdOut()
.EnableTracingAndCaptureOutputs()
.Execute()
.Should().Pass()
.And.HaveStdErrContaining($"Property {sharedState.AppTestPropertyName} = {sharedState.AppTestPropertyValue}")
Expand All @@ -43,9 +42,7 @@ public void FrameworkConfigProperty_AppCanGetData()
var dotnet = fixture.BuiltDotnet;
var appDll = fixture.TestProject.AppDll;
dotnet.Exec(appDll, sharedState.FrameworkTestPropertyName)
.EnvironmentVariable("COREHOST_TRACE", "1")
.CaptureStdErr()
.CaptureStdOut()
.EnableTracingAndCaptureOutputs()
.Execute()
.Should().Pass()
.And.HaveStdErrContaining($"Property {sharedState.FrameworkTestPropertyName} = {sharedState.FrameworkTestPropertyValue}")
Expand All @@ -65,15 +62,39 @@ public void DuplicateConfigProperty_AppConfigValueUsed()
var dotnet = fixture.BuiltDotnet;
var appDll = fixture.TestProject.AppDll;
dotnet.Exec(appDll, sharedState.FrameworkTestPropertyName)
.EnvironmentVariable("COREHOST_TRACE", "1")
.CaptureStdErr()
.CaptureStdOut()
.EnableTracingAndCaptureOutputs()
.Execute()
.Should().Pass()
.And.HaveStdErrContaining($"Property {sharedState.FrameworkTestPropertyName} = {sharedState.AppTestPropertyValue}")
.And.HaveStdOutContaining($"AppContext.GetData({sharedState.FrameworkTestPropertyName}) = {sharedState.AppTestPropertyValue}");
}

[Fact]
public void HostFxrPathProperty_SetWhenRunningSDKCommand()
{
var dotnet = sharedState.MockSDK;
dotnet.Exec("--info")
.EnableTracingAndCaptureOutputs()
.Execute()
.Should().Pass()
.And.HaveStdErrContaining($"Property {sharedState.HostFxrPathPropertyName} = {dotnet.GreatestVersionHostFxrFilePath}");
}

[Fact]
public void HostFxrPathProperty_NotVisibleFromApp()
{
var fixture = sharedState.RuntimePropertiesFixture
.Copy();

var dotnet = fixture.BuiltDotnet;
var appDll = fixture.TestProject.AppDll;
dotnet.Exec(appDll, sharedState.HostFxrPathPropertyName)
.EnableTracingAndCaptureOutputs()
.Execute()
.Should().Pass()
.And.HaveStdOutContaining($"Property '{sharedState.HostFxrPathPropertyName}' was not found.");
}

[Fact]
public void DuplicateCommonProperty_Fails()
{
Expand All @@ -88,9 +109,7 @@ public void DuplicateCommonProperty_Fails()
var dotnet = fixture.BuiltDotnet;
var appDll = fixture.TestProject.AppDll;
dotnet.Exec(appDll)
.EnvironmentVariable("COREHOST_TRACE", "1")
.CaptureStdErr()
.CaptureStdOut()
.EnableTracingAndCaptureOutputs()
.Execute()
.Should().Fail()
.And.HaveStdErrContaining($"Duplicate runtime property found: {name}");
Expand All @@ -100,11 +119,13 @@ public class SharedTestState : IDisposable
{
public TestProjectFixture RuntimePropertiesFixture { get; }
public RepoDirectoriesProvider RepoDirectories { get; }
public DotNetCli MockSDK { get; }

public string AppTestPropertyName => "APP_TEST_PROPERTY";
public string AppTestPropertyValue => "VALUE_FROM_APP";
public string FrameworkTestPropertyName => "FRAMEWORK_TEST_PROPERTY";
public string FrameworkTestPropertyValue => "VALUE_FROM_FRAMEWORK";
public string HostFxrPathPropertyName => "HOSTFXR_PATH";

private readonly string copiedDotnet;

Expand All @@ -113,6 +134,19 @@ public SharedTestState()
copiedDotnet = Path.Combine(TestArtifact.TestArtifactsPath, "runtimeProperties");
SharedFramework.CopyDirectory(Path.Combine(TestArtifact.TestArtifactsPath, "sharedFrameworkPublish"), copiedDotnet);

MockSDK = new DotNetBuilder(copiedDotnet, Path.Combine(TestArtifact.TestArtifactsPath, "sharedFrameworkPublish"), "exe")
.AddMicrosoftNETCoreAppFrameworkMockCoreClr("9999.0.0")
.AddMockSDK("9999.0.0-dev", "9999.0.0")
.Build();

File.WriteAllText(Path.Combine(MockSDK.BinPath, "global.json"),
@"
{
""sdk"": {
""version"": ""9999.0.0-dev""
}
}");

RepoDirectories = new RepoDirectoriesProvider(builtDotnet: copiedDotnet);

RuntimePropertiesFixture = new TestProjectFixture("RuntimeProperties", RepoDirectories)
Expand Down
9 changes: 8 additions & 1 deletion src/native/corehost/fxr/corehost_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ corehost_init_t::corehost_init_t(
const pal::string_t& additional_deps_serialized,
const std::vector<pal::string_t>& probe_paths,
const host_mode_t mode,
const fx_definition_vector_t& fx_definitions)
const fx_definition_vector_t& fx_definitions,
const std::vector<std::pair<pal::string_t, pal::string_t>>& additional_properties)
: m_tfm(get_app(fx_definitions).get_runtime_config().get_tfm())
, m_deps_file(deps_file)
, m_additional_deps_serialized(additional_deps_serialized)
Expand All @@ -35,6 +36,12 @@ corehost_init_t::corehost_init_t(
{
make_cstr_arr(m_probe_paths, &m_probe_paths_cstr);

for (const auto& additional_property : additional_properties)
{
m_clr_keys.push_back(additional_property.first);
m_clr_values.push_back(additional_property.second);
}

size_t fx_count = fx_definitions.size();
m_fx_names.reserve(fx_count);
m_fx_dirs.reserve(fx_count);
Expand Down
3 changes: 2 additions & 1 deletion src/native/corehost/fxr/corehost_init.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ class corehost_init_t
const pal::string_t& additional_deps_serialized,
const std::vector<pal::string_t>& probe_paths,
const host_mode_t mode,
const fx_definition_vector_t& fx_definitions);
const fx_definition_vector_t& fx_definitions,
const std::vector<std::pair<pal::string_t, pal::string_t>>& additional_properties);

const host_interface_t& get_host_init_data();

Expand Down
23 changes: 21 additions & 2 deletions src/native/corehost/fxr/fx_muxer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ namespace
const pal::string_t &app_candidate,
const opt_map_t &opts,
host_mode_t mode,
const bool is_sdk_command,
/*out*/ pal::string_t &hostpolicy_dir,
/*out*/ std::unique_ptr<corehost_init_t> &init)
{
Expand Down Expand Up @@ -473,6 +474,16 @@ namespace
}
}

std::vector<std::pair<pal::string_t, pal::string_t>> additional_properties;
if (is_sdk_command)
{
pal::string_t fxr_path;
pal::get_own_module_path(&fxr_path);

// We pass the loaded hostfxr path to the SDK can load it without relying on dlopen/LoadLibrary to find it.
additional_properties.push_back(std::make_pair(_X("HOSTFXR_PATH"), fxr_path));
}

const known_options opts_probe_path = known_options::additional_probing_path;
std::vector<pal::string_t> spec_probe_paths = opts.count(opts_probe_path) ? opts.find(opts_probe_path)->second : std::vector<pal::string_t>();
std::vector<pal::string_t> probe_realpaths = get_probe_realpaths(fx_definitions, spec_probe_paths);
Expand All @@ -485,7 +496,7 @@ namespace
return StatusCode::CoreHostLibMissingFailure;
}

init.reset(new corehost_init_t(host_command, host_info, deps_file, additional_deps_serialized, probe_realpaths, mode, fx_definitions));
init.reset(new corehost_init_t(host_command, host_info, deps_file, additional_deps_serialized, probe_realpaths, mode, fx_definitions, additional_properties));

return StatusCode::Success;
}
Expand All @@ -498,6 +509,7 @@ namespace
int new_argc,
const pal::char_t** new_argv,
host_mode_t mode,
const bool is_sdk_command,
pal::char_t out_buffer[],
int32_t buffer_size,
int32_t* required_buffer_size)
Expand All @@ -510,6 +522,7 @@ namespace
app_candidate,
opts,
mode,
is_sdk_command,
hostpolicy_dir,
init);
if (rc != StatusCode::Success)
Expand Down Expand Up @@ -572,6 +585,7 @@ int fx_muxer_t::execute(
argv,
new_argoff,
mode,
false /*is_sdk_command*/,
result_buffer,
buffer_size,
required_buffer_size);
Expand Down Expand Up @@ -621,7 +635,8 @@ namespace
}

const pal::string_t additional_deps_serialized;
init.reset(new corehost_init_t(pal::string_t{}, host_info, deps_file, additional_deps_serialized, probe_realpaths, mode, fx_definitions));
const std::vector<std::pair<pal::string_t, pal::string_t>> additional_properties;
init.reset(new corehost_init_t(pal::string_t{}, host_info, deps_file, additional_deps_serialized, probe_realpaths, mode, fx_definitions, additional_properties));

return StatusCode::Success;
}
Expand Down Expand Up @@ -725,6 +740,7 @@ int fx_muxer_t::initialize_for_app(
host_info.app_path,
opts,
mode,
false /*is_sdk_command*/,
hostpolicy_dir,
init);
if (rc != StatusCode::Success)
Expand Down Expand Up @@ -978,6 +994,7 @@ int fx_muxer_t::handle_exec_host_command(
const pal::char_t* argv[],
int argoff,
host_mode_t mode,
const bool is_sdk_command,
pal::char_t result_buffer[],
int32_t buffer_size,
int32_t* required_buffer_size)
Expand Down Expand Up @@ -1006,6 +1023,7 @@ int fx_muxer_t::handle_exec_host_command(
new_argc,
new_argv,
mode,
is_sdk_command,
result_buffer,
buffer_size,
required_buffer_size);
Expand Down Expand Up @@ -1096,6 +1114,7 @@ int fx_muxer_t::handle_cli(
new_argv.data(),
new_argoff,
host_mode_t::muxer,
true /*is_sdk_command*/,
nullptr /*result_buffer*/,
0 /*buffer_size*/,
nullptr/*required_buffer_size*/);
Expand Down
1 change: 1 addition & 0 deletions src/native/corehost/fxr/fx_muxer.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class fx_muxer_t
const pal::char_t* argv[],
int argoff,
host_mode_t mode,
const bool is_sdk_command,
pal::char_t result_buffer[],
int32_t buffer_size,
int32_t* required_buffer_size);
Expand Down