fix(configuration): resolve Low code-review findings (Configuration-004,005,007,010,011)
- Configuration-004: NodePermissions stored as int to match the EF HasConversion<int>() in OtOpcUaConfigDbContext.ConfigureNodeAcl. - Configuration-005: serialise LiteDbConfigCache.PutAsync so concurrent Put for the same (ClusterId, GenerationId) cannot duplicate rows. - Configuration-007: rethrow OperationCanceledException from GenerationApplier.ApplyPass when the caller's token is cancelled. - Configuration-010: scrub secrets and drop the full exception object from the ResilientConfigReader fallback warning log. - Configuration-011: pin the previously-uncovered GenerationApplier cancellation and path-length / publish-validation paths. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
using ZB.MOM.WW.OtOpcUa.Configuration.Enums;
|
||||
|
||||
namespace ZB.MOM.WW.OtOpcUa.Configuration.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// Pins the underlying type of <see cref="NodePermissions"/> to <c>int</c> so the SQL
|
||||
/// storage type (<c>HasConversion<int>()</c> in <c>OtOpcUaConfigDbContext</c>) and the
|
||||
/// XML doc ("Stored as int") cannot drift back into the latent <c>uint→int</c> overflow
|
||||
/// trap caught by Configuration-004.
|
||||
/// </summary>
|
||||
[Trait("Category", "Unit")]
|
||||
public sealed class NodePermissionsTests
|
||||
{
|
||||
[Fact]
|
||||
public void Underlying_type_is_int_so_it_matches_HasConversion_in_DbContext()
|
||||
{
|
||||
// Configuration-004: NodePermissions was declared : uint while NodeAcl.PermissionFlags
|
||||
// is persisted via HasConversion<int>(). A bit-31 grant would overflow int and corrupt
|
||||
// the round-trip. Lock the underlying type to int.
|
||||
typeof(NodePermissions).GetEnumUnderlyingType().ShouldBe(typeof(int));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void All_defined_bits_round_trip_through_int_cast_without_loss()
|
||||
{
|
||||
// Belt-and-braces: every declared bit must survive a (int) round-trip — fails today
|
||||
// if anyone re-introduces a bit-31 flag while the underlying type is uint.
|
||||
foreach (NodePermissions value in Enum.GetValues<NodePermissions>())
|
||||
{
|
||||
var asInt = (int)value;
|
||||
var roundTripped = (NodePermissions)asInt;
|
||||
roundTripped.ShouldBe(value);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Bitwise_combinations_round_trip_through_int_storage()
|
||||
{
|
||||
// The PermissionFlags column stores int; combinations of bits must survive the conversion.
|
||||
var combo = NodePermissions.Engineer | NodePermissions.MethodCall;
|
||||
var stored = (int)combo;
|
||||
var rebuilt = (NodePermissions)stored;
|
||||
rebuilt.ShouldBe(combo);
|
||||
rebuilt.HasFlag(NodePermissions.WriteTune).ShouldBeTrue();
|
||||
rebuilt.HasFlag(NodePermissions.MethodCall).ShouldBeTrue();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user