fix(configuration): resolve Medium code-review findings (Configuration-002, -003, -006, -009)
Configuration-002: sp_PublishGeneration is transaction-nesting aware (BEGIN TRANSACTION vs SAVE TRANSACTION on @@TRANCOUNT) so a caller's outer transaction survives a publish failure; sp_ValidateDraft wrapped in TRY/CATCH. Configuration-003: ValidatePathLength uses the cluster's actual Enterprise/Site lengths when available, falling back to the conservative approximation. Configuration-006: ResilientConfigReader treats a command-timeout TaskCanceledException as a fault (not caller cancellation) and falls back. Configuration-009: removed the checked-in plaintext sa connection string; CreateDbContext now requires OTOPCUA_CONFIG_CONNECTION. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -232,4 +232,90 @@ public sealed class DraftValidatorTests
|
||||
Enabled = enabled,
|
||||
CreatedBy = "t",
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
// ValidatePathLength — Enterprise/Site length precision (Configuration-003)
|
||||
// ------------------------------------------------------------------------------------
|
||||
|
||||
[Fact]
|
||||
public void PathLength_uses_actual_Enterprise_Site_when_provided()
|
||||
{
|
||||
// Craft a snapshot where the 32+32 approximation would flag PathTooLong but the
|
||||
// actual Enterprise/Site lengths would not. Equipment name intentionally exceeds the
|
||||
// UNS-segment 32-char limit (it would also trigger UnsSegmentInvalid — that is fine;
|
||||
// both checks are independent and the test is filtering only on PathTooLong).
|
||||
//
|
||||
// approx: 32+32 + 32+32+90 +4 = 222 > 200 → would flag PathTooLong
|
||||
// actual: 2 +1 + 32+32+90 +4 = 161 ≤ 200 → no PathTooLong
|
||||
var areaId = "area-a";
|
||||
var lineId = "line-b";
|
||||
var uuid = Guid.NewGuid();
|
||||
var eqName = new string('x', 90); // 90 chars — exceeds UNS regex but that's a separate error
|
||||
|
||||
var snapshot = new DraftSnapshot
|
||||
{
|
||||
GenerationId = 1,
|
||||
ClusterId = "c",
|
||||
Enterprise = "zb", // 2 chars (actual)
|
||||
Site = "s", // 1 char (actual)
|
||||
UnsAreas = [new UnsArea { UnsAreaId = areaId, ClusterId = "c", Name = new string('a', 32) }],
|
||||
UnsLines = [new UnsLine { UnsLineId = lineId, UnsAreaId = areaId, Name = new string('b', 32) }],
|
||||
Equipment =
|
||||
[
|
||||
new Equipment
|
||||
{
|
||||
EquipmentUuid = uuid,
|
||||
EquipmentId = DraftValidator.DeriveEquipmentId(uuid),
|
||||
Name = eqName,
|
||||
DriverInstanceId = "d",
|
||||
UnsLineId = lineId,
|
||||
MachineCode = "m",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
var errors = DraftValidator.Validate(snapshot);
|
||||
|
||||
errors.ShouldNotContain(e => e.Code == "PathTooLong",
|
||||
"actual Enterprise='zb' + Site='s' keeps total path at 161 chars — under the 200-char limit");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PathLength_conservative_fallback_when_Enterprise_Site_absent()
|
||||
{
|
||||
// Without Enterprise/Site on the snapshot the validator assumes 32+32.
|
||||
// A path whose segments sum to 93 chars (area=32 + line=32 + eq=29) fits
|
||||
// under 200 even with the 32+32 approximation (32+32+93+4 = 161 ≤ 200) and
|
||||
// must NOT be flagged — the fallback must not over-penalise valid paths that
|
||||
// would also be valid under real Enterprise/Site values.
|
||||
var areaId = "area-x";
|
||||
var lineId = "line-y";
|
||||
var uuid = Guid.NewGuid();
|
||||
|
||||
var snapshot = new DraftSnapshot
|
||||
{
|
||||
GenerationId = 1,
|
||||
ClusterId = "c",
|
||||
// Enterprise and Site deliberately omitted — conservative fallback path
|
||||
UnsAreas = [new UnsArea { UnsAreaId = areaId, ClusterId = "c", Name = new string('a', 32) }],
|
||||
UnsLines = [new UnsLine { UnsLineId = lineId, UnsAreaId = areaId, Name = new string('b', 32) }],
|
||||
Equipment =
|
||||
[
|
||||
new Equipment
|
||||
{
|
||||
EquipmentUuid = uuid,
|
||||
EquipmentId = DraftValidator.DeriveEquipmentId(uuid),
|
||||
Name = new string('c', 29),
|
||||
DriverInstanceId = "d",
|
||||
UnsLineId = lineId,
|
||||
MachineCode = "m",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
var errors = DraftValidator.Validate(snapshot);
|
||||
|
||||
errors.ShouldNotContain(e => e.Code == "PathTooLong",
|
||||
"conservative 32+32+32+32+29+4 = 161 chars is still under the 200-char limit");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user