feat(mesh): RoleParser accepts cluster-{ClusterId} roles; consolidate the driver-role literal
Phase 6 (per-cluster mesh split) needs nodes to carry a cluster-scoped role like cluster-SITE-A; RoleParser previously rejected anything outside the fixed admin/driver/dev set. Adds IsClusterRole/ ClusterIdFromRole plus well-known-role constants, and points the three duplicate "driver" string literals (RedundancyStateActor, ClusterNodeAddressReconcilerActor, ServiceCollectionExtensions) at the new RoleParser.Driver so the value has one source, without renaming any existing DriverRole symbol. Claude-Session: https://claude.ai/code/session_01GASWkNEi68FSCtvr6rLoEW
This commit is contained in:
@@ -57,4 +57,57 @@ public sealed class RoleParserTests
|
||||
{
|
||||
Should.Throw<ArgumentException>(() => RoleParser.Parse("admin,master"));
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a single cluster-scoped role is accepted.</summary>
|
||||
[Theory]
|
||||
[InlineData("cluster-MAIN")]
|
||||
[InlineData("cluster-SITE-A")]
|
||||
public void Cluster_role_accepted(string role)
|
||||
{
|
||||
RoleParser.Parse(role).ShouldBe(new[] { role.ToLowerInvariant() });
|
||||
}
|
||||
|
||||
/// <summary>Verifies that cluster roles mix freely with the fixed roles.</summary>
|
||||
[Fact]
|
||||
public void Fixed_and_cluster_roles_mix()
|
||||
{
|
||||
RoleParser.Parse("driver,cluster-SITE-A").ShouldBe(new[] { "driver", "cluster-site-a" });
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a cluster role with an empty ClusterId ("cluster-") is rejected.</summary>
|
||||
[Fact]
|
||||
public void Empty_cluster_id_throws()
|
||||
{
|
||||
Should.Throw<ArgumentException>(() => RoleParser.Parse("cluster-"));
|
||||
}
|
||||
|
||||
/// <summary>Verifies IsClusterRole returns true for valid cluster roles and false otherwise.</summary>
|
||||
[Theory]
|
||||
[InlineData("cluster-MAIN", true)]
|
||||
[InlineData("cluster-SITE-A", true)]
|
||||
[InlineData("cluster-", false)]
|
||||
[InlineData("driver", false)]
|
||||
[InlineData("admin", false)]
|
||||
[InlineData("clusterx", false)]
|
||||
public void IsClusterRole_classifies_correctly(string role, bool expected)
|
||||
{
|
||||
RoleParser.IsClusterRole(role).ShouldBe(expected);
|
||||
}
|
||||
|
||||
/// <summary>Verifies ClusterIdFromRole extracts the ClusterId suffix.</summary>
|
||||
[Fact]
|
||||
public void ClusterIdFromRole_extracts_suffix()
|
||||
{
|
||||
RoleParser.ClusterIdFromRole("cluster-SITE-A").ShouldBe("SITE-A");
|
||||
}
|
||||
|
||||
/// <summary>Verifies the three well-known role constants match the historical literal values.</summary>
|
||||
[Fact]
|
||||
public void Well_known_role_constants()
|
||||
{
|
||||
RoleParser.Admin.ShouldBe("admin");
|
||||
RoleParser.Driver.ShouldBe("driver");
|
||||
RoleParser.Dev.ShouldBe("dev");
|
||||
RoleParser.ClusterRolePrefix.ShouldBe("cluster-");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user