Skip to content

Commit

Permalink
Add runtime property HOSTFXR_PATH (#55369)
Browse files Browse the repository at this point in the history
* Add property HOSTFXR_PATH

* Comment

* PR feedback

* Use get_own_module_path since we are on hostfxr

* Dispose FileStream
  • Loading branch information
mateoatr authored Jul 13, 2021
1 parent f82b730 commit ae64899
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 17 deletions.
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 AddFramework(
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

0 comments on commit ae64899

Please sign in to comment.