consolidation of some of the modules, localization fixes, product advisories work, qa work
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using StellaOps.TaskRunner.Core.Execution;
|
||||
using StellaOps.TaskRunner.Core.Planning;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.TaskRunner.Tests;
|
||||
|
||||
public sealed class PackRunGateStateUpdaterTests
|
||||
{
|
||||
private static readonly DateTimeOffset RequestedAt = DateTimeOffset.UnixEpoch;
|
||||
private static readonly DateTimeOffset UpdateTimestamp = DateTimeOffset.UnixEpoch.AddMinutes(5);
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Apply_ApprovedGate_ClearsReasonAndSucceeds()
|
||||
{
|
||||
var plan = BuildApprovalPlan();
|
||||
var graph = new PackRunExecutionGraphBuilder().Build(plan);
|
||||
var state = CreateInitialState(plan, graph);
|
||||
var coordinator = PackRunApprovalCoordinator.Create(plan, RequestedAt);
|
||||
coordinator.Approve("security-review", "approver-1", UpdateTimestamp);
|
||||
|
||||
var result = PackRunGateStateUpdater.Apply(state, graph, coordinator, UpdateTimestamp);
|
||||
|
||||
Assert.False(result.HasBlockingFailure);
|
||||
Assert.Equal(UpdateTimestamp, result.State.UpdatedAt);
|
||||
|
||||
var gate = result.State.Steps["approval"];
|
||||
Assert.Equal(PackRunStepExecutionStatus.Succeeded, gate.Status);
|
||||
Assert.Null(gate.StatusReason);
|
||||
Assert.Equal(UpdateTimestamp, gate.LastTransitionAt);
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Apply_RejectedGate_FlagsFailure()
|
||||
{
|
||||
var plan = BuildApprovalPlan();
|
||||
var graph = new PackRunExecutionGraphBuilder().Build(plan);
|
||||
var state = CreateInitialState(plan, graph);
|
||||
var coordinator = PackRunApprovalCoordinator.Create(plan, RequestedAt);
|
||||
coordinator.Reject("security-review", "approver-1", UpdateTimestamp, "not-safe");
|
||||
|
||||
var result = PackRunGateStateUpdater.Apply(state, graph, coordinator, UpdateTimestamp);
|
||||
|
||||
Assert.True(result.HasBlockingFailure);
|
||||
Assert.Equal(UpdateTimestamp, result.State.UpdatedAt);
|
||||
|
||||
var gate = result.State.Steps["approval"];
|
||||
Assert.Equal(PackRunStepExecutionStatus.Failed, gate.Status);
|
||||
Assert.StartsWith("approval-rejected", gate.StatusReason, StringComparison.Ordinal);
|
||||
Assert.Equal(UpdateTimestamp, gate.LastTransitionAt);
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Apply_PolicyGate_ClearsPendingReason()
|
||||
{
|
||||
var plan = BuildPolicyPlan();
|
||||
var graph = new PackRunExecutionGraphBuilder().Build(plan);
|
||||
var state = CreateInitialState(plan, graph);
|
||||
var coordinator = PackRunApprovalCoordinator.Create(plan, RequestedAt);
|
||||
|
||||
var result = PackRunGateStateUpdater.Apply(state, graph, coordinator, UpdateTimestamp);
|
||||
|
||||
Assert.False(result.HasBlockingFailure);
|
||||
|
||||
var gate = result.State.Steps["policy-check"];
|
||||
Assert.Equal(PackRunStepExecutionStatus.Succeeded, gate.Status);
|
||||
Assert.Null(gate.StatusReason);
|
||||
Assert.Equal(UpdateTimestamp, gate.LastTransitionAt);
|
||||
|
||||
var prepare = result.State.Steps["prepare"];
|
||||
Assert.Equal(PackRunStepExecutionStatus.Pending, prepare.Status);
|
||||
Assert.Null(prepare.StatusReason);
|
||||
}
|
||||
|
||||
private static TaskPackPlan BuildApprovalPlan()
|
||||
{
|
||||
var manifest = TestManifests.Load(TestManifests.Sample);
|
||||
var planner = new TaskPackPlanner();
|
||||
var inputs = new Dictionary<string, System.Text.Json.Nodes.JsonNode?>
|
||||
{
|
||||
["dryRun"] = System.Text.Json.Nodes.JsonValue.Create(false)
|
||||
};
|
||||
|
||||
return planner.Plan(manifest, inputs).Plan!;
|
||||
}
|
||||
|
||||
private static TaskPackPlan BuildPolicyPlan()
|
||||
{
|
||||
var manifest = TestManifests.Load(TestManifests.PolicyGate);
|
||||
var planner = new TaskPackPlanner();
|
||||
return planner.Plan(manifest).Plan!;
|
||||
}
|
||||
|
||||
private static PackRunState CreateInitialState(TaskPackPlan plan, PackRunExecutionGraph graph)
|
||||
{
|
||||
var steps = new Dictionary<string, PackRunStepStateRecord>(StringComparer.Ordinal);
|
||||
|
||||
foreach (var step in EnumerateSteps(graph.Steps))
|
||||
{
|
||||
var status = PackRunStepExecutionStatus.Pending;
|
||||
string? reason = null;
|
||||
|
||||
if (!step.Enabled)
|
||||
{
|
||||
status = PackRunStepExecutionStatus.Skipped;
|
||||
reason = "disabled";
|
||||
}
|
||||
else if (step.Kind == PackRunStepKind.GateApproval)
|
||||
{
|
||||
reason = "requires-approval";
|
||||
}
|
||||
else if (step.Kind == PackRunStepKind.GatePolicy)
|
||||
{
|
||||
reason = "requires-policy";
|
||||
}
|
||||
|
||||
steps[step.Id] = new PackRunStepStateRecord(
|
||||
step.Id,
|
||||
step.Kind,
|
||||
step.Enabled,
|
||||
step.ContinueOnError,
|
||||
step.MaxParallel,
|
||||
step.ApprovalId,
|
||||
step.GateMessage,
|
||||
status,
|
||||
Attempts: 0,
|
||||
LastTransitionAt: null,
|
||||
NextAttemptAt: null,
|
||||
StatusReason: reason);
|
||||
}
|
||||
|
||||
return PackRunState.Create("run-1", plan.Hash, plan, graph.FailurePolicy, RequestedAt, steps, RequestedAt);
|
||||
}
|
||||
|
||||
private static IEnumerable<PackRunExecutionStep> EnumerateSteps(IReadOnlyList<PackRunExecutionStep> steps)
|
||||
{
|
||||
foreach (var step in steps)
|
||||
{
|
||||
yield return step;
|
||||
|
||||
if (step.Children.Count > 0)
|
||||
{
|
||||
foreach (var child in EnumerateSteps(step.Children))
|
||||
{
|
||||
yield return child;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user