elsa-core/test/unit/Elsa.Hosting.Management.UnitTests/Services/ConfiguredApplicationInstanceNameProviderTests.cs
Sipke Schoorstra 103028452f
feat: introduce HTTP webhooks module
Adds a new `Elsa.Http.Webhooks` module, enabling workflows to receive incoming webhook events and dispatch outgoing webhooks. This integrates the WebhooksCore library.

Further improvements include:
- Enhanced validation for configured application instance names, providing clearer feedback, especially regarding Azure Service Bus entity name limits.
- Improved API error reporting for shell reload operations, distinguishing between blueprint not found (404) and other failures (503).
- Updated release announcement rendering to dynamically reference the correct major.minor release line for feedback messages.
2026-08-03 02:08:15 +02:00

228 lines
7.1 KiB
C#

using Elsa.Hosting.Management.Options;
using Elsa.Hosting.Management.Services;
using Microsoft.Extensions.Logging.Abstractions;
namespace Elsa.Hosting.Management.UnitTests.Services;
public class ConfiguredApplicationInstanceNameProviderTests
{
private static int ConfiguredInstanceNameMaxLength => ConfiguredApplicationInstanceNameProvider.ConfiguredInstanceNameMaxLength;
[Fact]
public void ExplicitInstanceName_IsUsedDirectly()
{
var provider = CreateProvider(new()
{
InstanceName = "pod-0",
InstanceNameEnvironmentVariable = "ELSA_TEST_INSTANCE_NAME"
});
Assert.Equal("pod-0", provider.GetName());
}
[Fact]
public void ExplicitInstanceName_IsTrimmed()
{
var provider = CreateProvider(new()
{
InstanceName = " pod-0 "
});
Assert.Equal("pod-0", provider.GetName());
}
[Fact]
public void ExplicitInstanceName_TakesPrecedenceOverEnvironmentVariable()
{
var variable = NewVariableName();
Environment.SetEnvironmentVariable(variable, "from-env");
try
{
var provider = CreateProvider(new()
{
InstanceName = "explicit",
InstanceNameEnvironmentVariable = variable
});
Assert.Equal("explicit", provider.GetName());
}
finally
{
Environment.SetEnvironmentVariable(variable, null);
}
}
[Fact]
public void EnvironmentVariable_IsUsedWhenInstanceNameNotSet()
{
var variable = NewVariableName();
Environment.SetEnvironmentVariable(variable, "pod-7");
try
{
var provider = CreateProvider(new()
{
InstanceNameEnvironmentVariable = variable
});
Assert.Equal("pod-7", provider.GetName());
}
finally
{
Environment.SetEnvironmentVariable(variable, null);
}
}
[Fact]
public void EnvironmentVariableName_IsTrimmed()
{
var variable = NewVariableName();
Environment.SetEnvironmentVariable(variable, "pod-7");
try
{
var provider = CreateProvider(new()
{
InstanceNameEnvironmentVariable = $" {variable} "
});
Assert.Equal("pod-7", provider.GetName());
}
finally
{
Environment.SetEnvironmentVariable(variable, null);
}
}
[Fact]
public void EnvironmentVariable_ValueIsTrimmed()
{
var variable = NewVariableName();
Environment.SetEnvironmentVariable(variable, " pod-7 ");
try
{
var provider = CreateProvider(new()
{
InstanceNameEnvironmentVariable = variable
});
Assert.Equal("pod-7", provider.GetName());
}
finally
{
Environment.SetEnvironmentVariable(variable, null);
}
}
[Fact]
public void NoConfiguration_FallsBackToRandomName()
{
var name1 = CreateProvider(new()).GetName();
var name2 = CreateProvider(new()).GetName();
Assert.False(string.IsNullOrWhiteSpace(name1));
Assert.False(string.IsNullOrWhiteSpace(name2));
Assert.Matches(@"^[0-9a-f]+$", name1);
Assert.Matches(@"^[0-9a-f]+$", name2);
Assert.NotEqual(name1, name2);
}
[Fact]
public void EnvironmentVariableConfiguredButEmpty_FallsBackToRandomName()
{
var variable = NewVariableName();
Environment.SetEnvironmentVariable(variable, null);
var name1 = CreateProvider(new() { InstanceNameEnvironmentVariable = variable }).GetName();
var name2 = CreateProvider(new() { InstanceNameEnvironmentVariable = variable }).GetName();
Assert.False(string.IsNullOrWhiteSpace(name1));
Assert.False(string.IsNullOrWhiteSpace(name2));
Assert.Matches(@"^[0-9a-f]+$", name1);
Assert.Matches(@"^[0-9a-f]+$", name2);
Assert.NotEqual(name1, name2);
}
[Fact]
public void ExplicitInstanceName_AtMaximumLength_IsAccepted()
{
var instanceName = new string('a', ConfiguredInstanceNameMaxLength);
var provider = CreateProvider(new() { InstanceName = instanceName });
Assert.Equal(instanceName, provider.GetName());
}
[Fact]
public void ExplicitInstanceName_TooLong_IsShortenedDeterministically()
{
var instanceName = "nexxbiz-executor-api-v3-1-extra-long-replica-0001";
var name1 = CreateProvider(new() { InstanceName = instanceName }).GetName();
var name2 = CreateProvider(new() { InstanceName = instanceName }).GetName();
Assert.Equal(name1, name2);
Assert.True(name1.Length <= ConfiguredInstanceNameMaxLength);
Assert.StartsWith(instanceName[..8], name1);
Assert.NotEqual(instanceName, name1);
}
[Theory]
[InlineData("pod 0")]
[InlineData("pöd-0")]
[InlineData("-pod-0")]
[InlineData("pod-0-")]
public void ExplicitInstanceName_InvalidCharacters_Throws(string instanceName)
{
var exception = Assert.Throws<InvalidOperationException>(() => CreateProvider(new() { InstanceName = instanceName }));
Assert.Contains("contains invalid characters", exception.Message);
}
[Fact]
public void ExplicitInstanceName_InvalidCharactersAndTooLong_ReportsBothProblems()
{
var instanceName = new string('a', ConfiguredInstanceNameMaxLength) + " b";
var exception = Assert.Throws<InvalidOperationException>(() => CreateProvider(new() { InstanceName = instanceName }));
Assert.Contains("contains invalid characters", exception.Message);
Assert.Contains($"{ConfiguredInstanceNameMaxLength} characters or fewer", exception.Message);
Assert.Contains("Azure Service Bus", exception.Message);
}
[Fact]
public void EnvironmentVariableValue_TooLong_IsShortenedDeterministically()
{
var variable = NewVariableName();
var instanceName = "nexxbiz-executor-api-v3-1-extra-long-replica-0001";
Environment.SetEnvironmentVariable(variable, instanceName);
try
{
var name1 = CreateProvider(new() { InstanceNameEnvironmentVariable = variable }).GetName();
var name2 = CreateProvider(new() { InstanceNameEnvironmentVariable = variable }).GetName();
Assert.Equal(name1, name2);
Assert.True(name1.Length <= ConfiguredInstanceNameMaxLength);
Assert.NotEqual(instanceName, name1);
}
finally
{
Environment.SetEnvironmentVariable(variable, null);
}
}
private static ConfiguredApplicationInstanceNameProvider CreateProvider(ApplicationInstanceOptions options)
{
return new ConfiguredApplicationInstanceNameProvider(
Microsoft.Extensions.Options.Options.Create(options),
new RandomIntIdentityGenerator(),
NullLogger<ConfiguredApplicationInstanceNameProvider>.Instance);
}
private static string NewVariableName() => "ELSA_TEST_INSTANCE_" + Guid.NewGuid().ToString("N");
}