fix(management-service): resolve ManagementService-005,008,010,011 — supervision strategy, configured command timeout, remove stale ResolveRoles path; ManagementService-012 deferred
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
using Akka.Actor;
|
||||
using ScadaLink.ManagementService;
|
||||
|
||||
namespace ScadaLink.ManagementService.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// Tests for the <see cref="ManagementActor"/> supervision strategy
|
||||
/// (finding ManagementService-005). The project convention is that long-lived
|
||||
/// coordinator-style actors declare an explicit Resume-based strategy.
|
||||
/// </summary>
|
||||
public class ManagementActorSupervisionTests
|
||||
{
|
||||
[Fact]
|
||||
public void CreateSupervisorStrategy_ReturnsOneForOneStrategy()
|
||||
{
|
||||
var strategy = ManagementActor.CreateSupervisorStrategy();
|
||||
|
||||
Assert.IsType<OneForOneStrategy>(strategy);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateSupervisorStrategy_ResumesOnArbitraryException()
|
||||
{
|
||||
var strategy = (OneForOneStrategy)ManagementActor.CreateSupervisorStrategy();
|
||||
|
||||
var directive = strategy.Decider.Decide(new InvalidOperationException("boom"));
|
||||
|
||||
Assert.Equal(Directive.Resume, directive);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateSupervisorStrategy_ResumesIndefinitely()
|
||||
{
|
||||
var strategy = (OneForOneStrategy)ManagementActor.CreateSupervisorStrategy();
|
||||
|
||||
// Coordinator actors should not give up: unbounded retries.
|
||||
Assert.Equal(-1, strategy.MaxNumberOfRetries);
|
||||
}
|
||||
}
|
||||
@@ -715,6 +715,33 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
// continuation rather than escaping or being silently dropped.
|
||||
// ========================================================================
|
||||
|
||||
// ========================================================================
|
||||
// ResolveRolesCommand dead-code removal (finding ManagementService-011 / -008)
|
||||
//
|
||||
// The two-step ResolveRoles + command flow is retired: the HTTP endpoint does
|
||||
// LDAP auth and role resolution itself. The actor must no longer dispatch
|
||||
// ResolveRolesCommand — a stray ClusterClient sender hitting it gets a uniform
|
||||
// ManagementError rather than an unauthenticated role-mapping enumeration.
|
||||
// ========================================================================
|
||||
|
||||
[Fact]
|
||||
public void ResolveRolesCommand_IsNoLongerDispatched_ReturnsManagementError()
|
||||
{
|
||||
var secRepo = Substitute.For<ISecurityRepository>();
|
||||
_services.AddScoped(_ => secRepo);
|
||||
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(new ResolveRolesCommand(new[] { "cn=admins" }));
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
var response = ExpectMsg<ManagementError>(TimeSpan.FromSeconds(5));
|
||||
Assert.Equal(envelope.CorrelationId, response.CorrelationId);
|
||||
Assert.Equal("COMMAND_FAILED", response.ErrorCode);
|
||||
// No role-mapping data is enumerated/leaked back to the caller.
|
||||
secRepo.DidNotReceiveWithAnyArgs().GetAllMappingsAsync(default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UnknownCommandType_FaultMappedToManagementError()
|
||||
{
|
||||
|
||||
@@ -62,4 +62,41 @@ public class ManagementEndpointsTests
|
||||
Assert.False(result.Success);
|
||||
Assert.Equal("BAD_REQUEST", result.ErrorCode);
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// Command-timeout configuration (finding ManagementService-010)
|
||||
//
|
||||
// ManagementServiceOptions.CommandTimeout must actually drive the Ask
|
||||
// timeout instead of a hard-coded 30s constant.
|
||||
// ========================================================================
|
||||
|
||||
[Fact]
|
||||
public void ResolveAskTimeout_UsesConfiguredCommandTimeout()
|
||||
{
|
||||
var options = new ManagementServiceOptions { CommandTimeout = TimeSpan.FromSeconds(75) };
|
||||
|
||||
var timeout = ManagementEndpoints.ResolveAskTimeout(options);
|
||||
|
||||
Assert.Equal(TimeSpan.FromSeconds(75), timeout);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolveAskTimeout_WithNullOptions_FallsBackToDefault()
|
||||
{
|
||||
var timeout = ManagementEndpoints.ResolveAskTimeout(null);
|
||||
|
||||
Assert.Equal(TimeSpan.FromSeconds(30), timeout);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolveAskTimeout_WithNonPositiveTimeout_FallsBackToDefault()
|
||||
{
|
||||
// A misconfigured zero/negative timeout would make every Ask fail
|
||||
// immediately; fall back to the safe default instead.
|
||||
var options = new ManagementServiceOptions { CommandTimeout = TimeSpan.Zero };
|
||||
|
||||
var timeout = ManagementEndpoints.ResolveAskTimeout(options);
|
||||
|
||||
Assert.Equal(TimeSpan.FromSeconds(30), timeout);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user