{
private SharedTestState sharedTestState;
private string startupHookVarName = "DOTNET_STARTUP_HOOKS";
+ private string startupHookRuntimeConfigName = "STARTUP_HOOKS";
private string startupHookSupport = "System.StartupHookProvider.IsSupported";
public StartupHooks(StartupHooks.SharedTestState fixture)
.And.HaveStdOutContaining("Hello World");
}
+ [Fact]
+ public void Muxer_activation_of_RuntimeConfig_StartupHook_Succeeds()
+ {
+ var fixture = sharedTestState.PortableAppFixture.Copy();
+ var dotnet = fixture.BuiltDotnet;
+ var appDll = fixture.TestProject.AppDll;
+
+ var startupHookFixture = sharedTestState.StartupHookFixture.Copy();
+ var startupHookDll = startupHookFixture.TestProject.AppDll;
+
+ RuntimeConfig.FromFile(fixture.TestProject.RuntimeConfigJson)
+ .WithProperty(startupHookRuntimeConfigName, startupHookDll)
+ .Save();
+
+ // RuntimeConfig defined startup hook
+ dotnet.Exec(appDll)
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should().Pass()
+ .And.HaveStdOutContaining("Hello from startup hook!")
+ .And.HaveStdOutContaining("Hello World");
+ }
+
+ [Fact]
+ public void Muxer_activation_of_RuntimeConfig_And_Environment_StartupHooks_SucceedsInExpectedOrder()
+ {
+ var fixture = sharedTestState.PortableAppFixture.Copy();
+ var dotnet = fixture.BuiltDotnet;
+ var appDll = fixture.TestProject.AppDll;
+
+ var startupHookFixture = sharedTestState.StartupHookFixture.Copy();
+ var startupHookDll = startupHookFixture.TestProject.AppDll;
+
+ RuntimeConfig.FromFile(fixture.TestProject.RuntimeConfigJson)
+ .WithProperty(startupHookRuntimeConfigName, startupHookDll)
+ .Save();
+
+ var startupHook2Fixture = sharedTestState.StartupHookWithDependencyFixture.Copy();
+ var startupHook2Dll = startupHook2Fixture.TestProject.AppDll;
+
+ // include any char to counter output from other threads such as in #57243
+ const string wildcardPattern = @"[\r\n\s.]*";
+
+ // RuntimeConfig and Environment startup hooks in expected order
+ dotnet.Exec(appDll)
+ .EnvironmentVariable(startupHookVarName, startupHook2Dll)
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should().Pass()
+ .And.HaveStdOutMatching("Hello from startup hook with dependency!" +
+ wildcardPattern +
+ "Hello from startup hook!" +
+ wildcardPattern +
+ "Hello World");
+ }
+
// Empty startup hook variable
[Fact]
public void Muxer_activation_of_Empty_StartupHook_Variable_Succeeds()
pal::string_t startup_hooks;
if (pal::getenv(_X("DOTNET_STARTUP_HOOKS"), &startup_hooks))
{
- if (!coreclr_properties.add(common_property::StartUpHooks, startup_hooks.c_str()))
+ const pal::char_t *config_startup_hooks;
+ if (coreclr_properties.try_get(common_property::StartUpHooks, &config_startup_hooks))
{
- log_duplicate_property_error(coreclr_property_bag_t::common_property_to_string(common_property::StartUpHooks));
- return StatusCode::LibHostDuplicateProperty;
+ // env startup hooks shoold have precedence over config startup hooks
+ // therefore append config_startup_hooks AFTER startup_hooks
+ startup_hooks.push_back(PATH_SEPARATOR);
+ startup_hooks.append(config_startup_hooks);
}
+
+ coreclr_properties.add(common_property::StartUpHooks, startup_hooks.c_str());
}
// Single-File Bundle Probe
if (!coreclr_properties.add(common_property::BundleProbe, ptr_stream.str().c_str()))
{
- log_duplicate_property_error(coreclr_property_bag_t::common_property_to_string(common_property::StartUpHooks));
+ log_duplicate_property_error(coreclr_property_bag_t::common_property_to_string(common_property::BundleProbe));
return StatusCode::LibHostDuplicateProperty;
}
}
if (!coreclr_properties.add(common_property::PInvokeOverride, ptr_stream.str().c_str()))
{
- log_duplicate_property_error(coreclr_property_bag_t::common_property_to_string(common_property::StartUpHooks));
+ log_duplicate_property_error(coreclr_property_bag_t::common_property_to_string(common_property::PInvokeOverride));
return StatusCode::LibHostDuplicateProperty;
}
}
#if defined(HOSTPOLICY_EMBEDDED)
if (!coreclr_properties.add(common_property::HostPolicyEmbedded, _X("true")))
{
- log_duplicate_property_error(coreclr_property_bag_t::common_property_to_string(common_property::StartUpHooks));
+ log_duplicate_property_error(coreclr_property_bag_t::common_property_to_string(common_property::HostPolicyEmbedded));
return StatusCode::LibHostDuplicateProperty;
}
#endif