Skip to content

Commit

Permalink
Add RuntimeInformation.RuntimeIdentifier (#34206)
Browse files Browse the repository at this point in the history
* Add RuntimeInformation.RuntimeIdentifier

This value returns the Runtime Identifier (RID) of the current machine.

Contributes to #26780

* Include XML doc comments for the new property.

* Consistently check for AppContext strings.
  • Loading branch information
eerhardt authored Mar 28, 2020
1 parent fa70639 commit 65d5a72
Show file tree
Hide file tree
Showing 12 changed files with 126 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ private static void ProcessStartupHooks()
// Initialize tracing before any user code can be called.
System.Diagnostics.Tracing.RuntimeEventSource.Initialize();

string? startupHooksVariable = (string?)AppContext.GetData("STARTUP_HOOKS");
string? startupHooksVariable = AppContext.GetData("STARTUP_HOOKS") as string;
if (startupHooksVariable == null)
{
return;
Expand Down
3 changes: 2 additions & 1 deletion src/installer/corehost/cli/hostpolicy/coreclr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,8 @@ namespace
_X("JIT_PATH"),
_X("STARTUP_HOOKS"),
_X("APP_PATHS"),
_X("APP_NI_PATHS")
_X("APP_NI_PATHS"),
_X("RUNTIME_IDENTIFIER")
};

static_assert((sizeof(PropertyNameMapping) / sizeof(*PropertyNameMapping)) == static_cast<size_t>(common_property::Last), "Invalid property count");
Expand Down
1 change: 1 addition & 0 deletions src/installer/corehost/cli/hostpolicy/coreclr.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ enum class common_property
StartUpHooks,
AppPaths,
AppNIPaths,
RuntimeIdentifier,

// Sentinel value - new values should be defined above
Last
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ int hostpolicy_context_t::initialize(hostpolicy_init_t &hostpolicy_init, const a
coreclr_properties.add(common_property::FxDepsFile, fx_deps_str.c_str());
coreclr_properties.add(common_property::ProbingDirectories, resolver.get_lookup_probe_directories().c_str());
coreclr_properties.add(common_property::FxProductVersion, clr_library_version.c_str());
coreclr_properties.add(common_property::RuntimeIdentifier, get_current_runtime_id(true /*use_fallback*/).c_str());

if (!clrjit_path.empty())
coreclr_properties.add(common_property::JitPath, clrjit_path.c_str());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public static partial class AppContext
public static string BaseDirectory =>
// The value of APP_CONTEXT_BASE_DIRECTORY key has to be a string and it is not allowed to be any other type.
// Otherwise the caller will get invalid cast exception
(string?)GetData("APP_CONTEXT_BASE_DIRECTORY") ??
GetData("APP_CONTEXT_BASE_DIRECTORY") as string ??
(s_defaultBaseDirectory ??= GetBaseDirectoryCore());

public static string? TargetFrameworkName =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ public static Version Version
{
// FX_PRODUCT_VERSION is expected to be set by the host
// Use AssemblyInformationalVersionAttribute as fallback if the exact product version is not specified by the host
string? versionString = (string?)AppContext.GetData("FX_PRODUCT_VERSION") ??
string? versionString = AppContext.GetData("FX_PRODUCT_VERSION") as string ??
typeof(object).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion;

ReadOnlySpan<char> versionSpan = versionString.AsSpan();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ private static bool ShouldUseUapResourceManagement(Assembly resourcesAssembly)
return false;

// Check to see if the assembly is under PLATFORM_RESOURCE_ROOTS. If it is, then we should use satellite assembly lookup for it.
string? platformResourceRoots = (string?)AppContext.GetData("PLATFORM_RESOURCE_ROOTS");
string? platformResourceRoots = AppContext.GetData("PLATFORM_RESOURCE_ROOTS") as string;
if (!string.IsNullOrEmpty(platformResourceRoots))
{
string resourceAssemblyPath = resourcesAssembly.Location;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public enum Architecture
}
public static partial class RuntimeInformation
{
public static string RuntimeIdentifier { get { throw null; } }
public static string FrameworkDescription { get { throw null; } }
public static System.Runtime.InteropServices.Architecture OSArchitecture { get { throw null; } }
public static string OSDescription { get { throw null; } }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ public static partial class RuntimeInformation
{
private const string FrameworkName = ".NET Core";
private static string? s_frameworkDescription;
private static string? s_runtimeIdentifier;

public static string FrameworkDescription
{
get
{
if (s_frameworkDescription == null)
{
string? versionString = (string?)AppContext.GetData("FX_PRODUCT_VERSION");
string? versionString = AppContext.GetData("FX_PRODUCT_VERSION") as string;

if (versionString == null)
{
Expand All @@ -41,5 +42,18 @@ public static string FrameworkDescription
return s_frameworkDescription;
}
}

/// <summary>
/// Returns an opaque string that identifies the platform on which an app is running.
/// </summary>
/// <remarks>
/// The property returns a string that identifies the operating system, typically including version,
/// and processor architecture of the currently executing process.
/// Since this string is opaque, it is not recommended to parse the string into its constituent parts.
///
/// For more information, see https://docs.microsoft.com/dotnet/core/rid-catalog.
/// </remarks>
public static string RuntimeIdentifier =>
s_runtimeIdentifier ??= AppContext.GetData("RUNTIME_IDENTIFIER") as string ?? "unknown";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ public void DumpRuntimeInformationToConsole()
string osd = RuntimeInformation.OSDescription.Trim();
string osv = Environment.OSVersion.ToString();
string osa = RuntimeInformation.OSArchitecture.ToString();
Console.WriteLine($"### OS: Distro={dvs} Description={osd} Version={osv} Arch={osa}");
string rid = RuntimeInformation.RuntimeIdentifier;
Console.WriteLine($"### OS: Distro={dvs} Description={osd} Version={osv} Arch={osa} Rid={rid}");

string lcr = PlatformDetection.LibcRelease;
string lcv = PlatformDetection.LibcVersion;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.IO;
using System.Linq;
using Microsoft.DotNet.RemoteExecutor;
using Xunit;

namespace System.Runtime.InteropServices.RuntimeInformationTests
{
public class RuntimeIdentifierTests
{
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/26780")] // need a new testhost
public void VerifyOSRid()
{
Assert.NotNull(RuntimeInformation.RuntimeIdentifier);
Assert.Same(RuntimeInformation.RuntimeIdentifier, RuntimeInformation.RuntimeIdentifier);
Assert.EndsWith(RuntimeInformation.ProcessArchitecture.ToString(), RuntimeInformation.RuntimeIdentifier, StringComparison.OrdinalIgnoreCase);
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/26780")] // need a new testhost
public void VerifyEnvironmentVariable()
{
RemoteInvokeOptions options = new RemoteInvokeOptions();
options.StartInfo.EnvironmentVariables.Add("DOTNET_RUNTIME_ID", "overridenFromEnv-rid");

RemoteExecutor.Invoke(() =>
{
Assert.Equal("overridenFromEnv-rid", RuntimeInformation.RuntimeIdentifier);
}, options).Dispose();
}

[Fact]
public void VerifyAppContextVariable()
{
RemoteExecutor.Invoke(() =>
{
AppDomain.CurrentDomain.SetData("RUNTIME_IDENTIFIER", "overriden-rid");

Assert.Equal("overriden-rid", RuntimeInformation.RuntimeIdentifier);
}).Dispose();
}

[Fact]
public void VerifyAppContextVariableUnknown()
{
RemoteExecutor.Invoke(() =>
{
AppDomain.CurrentDomain.SetData("RUNTIME_IDENTIFIER", null);

Assert.Equal("unknown", RuntimeInformation.RuntimeIdentifier);
}).Dispose();

RemoteExecutor.Invoke(() =>
{
AppDomain.CurrentDomain.SetData("RUNTIME_IDENTIFIER", new object());

Assert.Equal("unknown", RuntimeInformation.RuntimeIdentifier);
}).Dispose();
}

[Fact, PlatformSpecific(TestPlatforms.Windows)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/26780")] // need a new testhost
public void VerifyWindowsRid()
{
Assert.StartsWith("win", RuntimeInformation.RuntimeIdentifier, StringComparison.OrdinalIgnoreCase);
}

[Fact, PlatformSpecific(TestPlatforms.Linux)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/26780")] // need a new testhost
public void VerifyLinuxRid()
{
string expectedOSName = File.ReadAllLines("/etc/os-release")
.First(line => line.StartsWith("ID=", StringComparison.OrdinalIgnoreCase))
.Substring("ID=".Length)
.Trim();

Assert.StartsWith(expectedOSName, RuntimeInformation.RuntimeIdentifier, StringComparison.OrdinalIgnoreCase);
}

[Fact, PlatformSpecific(TestPlatforms.FreeBSD)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/26780")] // need a new testhost
public void VerifyFreeBSDRid()
{
Assert.StartsWith("freebsd", RuntimeInformation.RuntimeIdentifier, StringComparison.OrdinalIgnoreCase);
}

[Fact, PlatformSpecific(TestPlatforms.OSX)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/26780")] // need a new testhost
public void VerifyOSXRid()
{
Assert.StartsWith("osx", RuntimeInformation.RuntimeIdentifier, StringComparison.OrdinalIgnoreCase);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<IncludeRemoteExecutor>true</IncludeRemoteExecutor>
<TargetFrameworks>$(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<Compile Include="CheckArchitectureTests.cs" />
<Compile Include="CheckPlatformTests.cs" />
<Compile Include="RuntimeIdentifierTests.cs" />
<Compile Include="DescriptionNameTests.cs" />
<Compile Include="$(CommonPath)Interop\Linux\cgroups\Interop.cgroups.cs">
<Link>Common\Interop\Linux\Interop.cgroups.cs</Link>
Expand Down

0 comments on commit 65d5a72

Please sign in to comment.