fix: verify apply duplicate and capture runtime failures
This commit is contained in:
+13
-4
@@ -34,6 +34,7 @@ internal static class ScriptDrivenFirstApplyAutomation
|
||||
private static string? selectedTargetSnapshotId;
|
||||
private static bool prepared;
|
||||
private static bool terminal;
|
||||
private static string? applyExceptionText;
|
||||
|
||||
internal static void Prepare()
|
||||
{
|
||||
@@ -97,7 +98,15 @@ internal static class ScriptDrivenFirstApplyAutomation
|
||||
{
|
||||
if (!prepared || terminal || runs.Count == 0) return;
|
||||
var last = runs[^1];
|
||||
runs[^1] = last with { ApplyOutcome = outcome.ToString() };
|
||||
runs[^1] = outcome == PipeAnnotationWriteOutcome.AlreadyExists
|
||||
? last with { ApplyOutcome = outcome.ToString(), Create = 0, Skip = 1 }
|
||||
: last with { ApplyOutcome = outcome.ToString() };
|
||||
}
|
||||
internal static void RecordApplyFailure(System.Exception exception)
|
||||
{
|
||||
if (!prepared || terminal) return;
|
||||
applyExceptionText = exception.ToString();
|
||||
Write(false, "AUTOMATION_APPLY_COMMAND_FAILED");
|
||||
}
|
||||
|
||||
internal static bool TryGetPreparedContext(Document? commandDocument, out PlantRuntimeContext context)
|
||||
@@ -121,9 +130,9 @@ internal static class ScriptDrivenFirstApplyAutomation
|
||||
if (runs.Any(x => !x.WillStart || !x.Ended || x.Failed || x.Cancelled)) throw new InvalidOperationException("AUTOMATION_PXP_OA_NOT_ENDED");
|
||||
if (runs.Any(x => string.IsNullOrWhiteSpace(x.PlanId))) throw new InvalidOperationException("PXP_OA_PLAN_RESULT_NOT_CAPTURED");
|
||||
if (!string.Equals(runs[0].PlanId, runs[1].PlanId, StringComparison.Ordinal)) throw new InvalidOperationException("AUTOMATION_PLAN_IDS_DIFFER");
|
||||
if (runs.Any(x => x.Create != 1)) throw new InvalidOperationException("AUTOMATION_PREVIEW_CREATE_NOT_ONE");
|
||||
if (runs[0].Candidates.Count == 0) throw new InvalidOperationException("AUTOMATION_NO_ELIGIBLE_CANDIDATE");
|
||||
var apply = string.Equals(config!.Phase, "Apply", StringComparison.OrdinalIgnoreCase);
|
||||
if ((!apply && runs.Any(x => x.Create != 1)) || (apply && (runs[0].Create != 1 || runs[1].Create != 0))) throw new InvalidOperationException("AUTOMATION_CREATE_COUNTS_INVALID");
|
||||
if (runs[0].Candidates.Count == 0) throw new InvalidOperationException("AUTOMATION_NO_ELIGIBLE_CANDIDATE");
|
||||
if (apply)
|
||||
{
|
||||
if (runs[0].PermitAccepted != true) throw new InvalidOperationException("AUTOMATION_APPLY_PERMIT_NOT_ACCEPTED");
|
||||
@@ -222,7 +231,7 @@ internal static class ScriptDrivenFirstApplyAutomation
|
||||
var first = runs.ElementAtOrDefault(0); var second = runs.ElementAtOrDefault(1);
|
||||
var apply = string.Equals(config.Phase, "Apply", StringComparison.OrdinalIgnoreCase);
|
||||
var afterUndo = apply && terminal ? Counts(database!) : null;
|
||||
var evidence = new FirstApplyAutomationEvidence { Phase = config.Phase, Completed = completed, Prepared = prepared, FunctionalEvidenceCompleted = completed, ErrorCode = error, DbmodBefore = dbmodBaseline, DbmodAfterCommand1 = first?.DbmodAfter, DbmodAfterCommand2 = second?.DbmodAfter, DbmodAfterUndo = apply && terminal ? Dbmod() : null, Baseline = baseline, AfterCommand1 = first?.After, AfterCommand2 = second?.After, AfterUndo = afterUndo, CompletedCommands = runs.Where(x => x.Ended).Select(x => "PXP-OA").Concat(apply && commandEvents.Any(x => string.Equals(x, "Ended:UNDO", StringComparison.OrdinalIgnoreCase)) ? ["UNDO"] : []).ToArray(), PlanIdRun1 = first?.PlanId, PlanIdRun2 = second?.PlanId, PlanIdsEqual = first is not null && second is not null ? string.Equals(first.PlanId, second.PlanId, StringComparison.Ordinal) : null, EligibleCandidateCount = first?.Candidates.Count, SelectedCandidateHash = first?.Candidates.OrderBy(x => x, StringComparer.Ordinal).FirstOrDefault(), ViewHash = first?.View, CreateRun1 = first?.Create, CreateRun2 = second?.Create, SkipRun2 = second?.Skip, ApplyOutcomeRun1 = first?.ApplyOutcome, ApplyOutcomeRun2 = second?.ApplyOutcome, PermitAccepted = first?.PermitAccepted, CommandsCompleted = runs.Count == 2 && runs.All(x => x.Ended) && (!apply || commandEvents.Any(x => string.Equals(x, "Ended:UNDO", StringComparison.OrdinalIgnoreCase))), InspectorsCompleted = baseline is not null && first?.After is not null && second?.After is not null && (!apply || afterUndo is not null), EvidenceFlushed = true, CurrentState = terminal ? (completed ? "Completed" : "Failed") : "Prepared", StateTransitions = transitions, PxpOaDiscovery = discovery, Sentinels = sentinels, CommandEvents = commandEvents, CommandCorrelations = correlations };
|
||||
var evidence = new FirstApplyAutomationEvidence { Phase = config.Phase, Completed = completed, Prepared = prepared, FunctionalEvidenceCompleted = completed, ErrorCode = error, DbmodBefore = dbmodBaseline, DbmodAfterCommand1 = first?.DbmodAfter, DbmodAfterCommand2 = second?.DbmodAfter, DbmodAfterUndo = apply && terminal ? Dbmod() : null, Baseline = baseline, AfterCommand1 = first?.After, AfterCommand2 = second?.After, AfterUndo = afterUndo, CompletedCommands = runs.Where(x => x.Ended).Select(x => "PXP-OA").Concat(apply && commandEvents.Any(x => string.Equals(x, "Ended:UNDO", StringComparison.OrdinalIgnoreCase)) ? ["UNDO"] : []).ToArray(), PlanIdRun1 = first?.PlanId, PlanIdRun2 = second?.PlanId, PlanIdsEqual = first is not null && second is not null ? string.Equals(first.PlanId, second.PlanId, StringComparison.Ordinal) : null, EligibleCandidateCount = first?.Candidates.Count, SelectedCandidateHash = first?.Candidates.OrderBy(x => x, StringComparer.Ordinal).FirstOrDefault(), ViewHash = first?.View, CreateRun1 = first?.Create, CreateRun2 = second?.Create, SkipRun2 = second?.Skip, ApplyOutcomeRun1 = first?.ApplyOutcome, ApplyOutcomeRun2 = second?.ApplyOutcome, PermitAccepted = first?.PermitAccepted, CommandsCompleted = runs.Count == 2 && runs.All(x => x.Ended) && (!apply || commandEvents.Any(x => string.Equals(x, "Ended:UNDO", StringComparison.OrdinalIgnoreCase))), InspectorsCompleted = baseline is not null && first?.After is not null && second?.After is not null && (!apply || afterUndo is not null), EvidenceFlushed = true, ExceptionText = applyExceptionText, CurrentState = terminal ? (completed ? "Completed" : "Failed") : "Prepared", StateTransitions = transitions, PxpOaDiscovery = discovery, Sentinels = sentinels, CommandEvents = commandEvents, CommandCorrelations = correlations };
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(config.EvidencePath)!);
|
||||
var temp = config.EvidencePath + ".tmp"; File.WriteAllText(temp, JsonSerializer.Serialize(evidence)); File.Move(temp, config.EvidencePath, true);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user