Complete Phase 7 runner orchestration

This commit is contained in:
2026-05-11 14:22:22 +00:00
parent 30606f5c49
commit 28fe899aa1
8 changed files with 760 additions and 83 deletions

View File

@@ -5,6 +5,8 @@ import (
"fmt"
"os"
"time"
"gitea.maximumdirect.net/eric/audita/internal/framework/proposals"
)
type ProcessReport struct {
@@ -26,6 +28,28 @@ type ProcessReport struct {
NormalizationSkipped NormalizationSkipped `json:"normalization_skipped,omitempty"`
Chunking *ChunkingSummary `json:"chunking,omitempty"`
Diagnostics *DiagnosticsMetadata `json:"diagnostics,omitempty"`
ModulesSummary *ModulesSummary `json:"modules_summary,omitempty"`
ModuleResults []ModuleReport `json:"module_results,omitempty"`
}
type ModuleReport struct {
ModuleKey string `json:"module_key"`
ModuleInstance string `json:"module_instance"`
ReplacementPolicy string `json:"replacement_policy,omitempty"`
Status string `json:"status"`
ProposalCount int `json:"proposal_count"`
AppliedChanges []proposals.AppliedChange `json:"applied_changes,omitempty"`
SkippedChanges []proposals.SkippedChange `json:"skipped_changes,omitempty"`
ErrorMessage string `json:"error_message,omitempty"`
StartedAt *time.Time `json:"started_at,omitempty"`
CompletedAt *time.Time `json:"completed_at,omitempty"`
}
type ModulesSummary struct {
ModuleCount int `json:"module_count"`
TotalAppliedChanges int `json:"total_applied_changes"`
TotalSkippedChanges int `json:"total_skipped_changes"`
FailedModuleInstance string `json:"failed_module_instance,omitempty"`
}
type DiagnosticsMetadata struct {

View File

@@ -0,0 +1,91 @@
package reporting
import (
"encoding/json"
"testing"
"time"
"gitea.maximumdirect.net/eric/audita/internal/framework/proposals"
)
func TestProcessReportModuleResultsJSONSuccessAndSkipped(t *testing.T) {
now := time.Now().UTC()
report := ProcessReport{
Phase: "phase7-runner",
Status: "success",
ModuleResults: []ModuleReport{
{
ModuleKey: "grammar",
ModuleInstance: "grammar_1",
ReplacementPolicy: "require_unique",
Status: "success",
ProposalCount: 2,
AppliedChanges: []proposals.AppliedChange{{
ProposalIndex: 0,
ModuleKey: "grammar",
}},
SkippedChanges: []proposals.SkippedChange{{
ProposalIndex: 1,
ModuleKey: "grammar",
SkipReason: proposals.SkipReasonMissingOriginalText,
}},
StartedAt: &now,
CompletedAt: &now,
},
},
ModulesSummary: &ModulesSummary{ModuleCount: 1, TotalAppliedChanges: 1, TotalSkippedChanges: 1},
}
b, err := json.Marshal(report)
if err != nil {
t.Fatalf("marshal report: %v", err)
}
if !json.Valid(b) {
t.Fatalf("expected valid json")
}
var parsed ProcessReport
if err := json.Unmarshal(b, &parsed); err != nil {
t.Fatalf("unmarshal report: %v", err)
}
if len(parsed.ModuleResults) != 1 {
t.Fatalf("expected one module result, got %d", len(parsed.ModuleResults))
}
if parsed.ModulesSummary == nil || parsed.ModulesSummary.TotalSkippedChanges != 1 {
t.Fatalf("unexpected module summary: %+v", parsed.ModulesSummary)
}
}
func TestProcessReportModuleResultsJSONFailedModule(t *testing.T) {
now := time.Now().UTC()
report := ProcessReport{
Phase: "phase7-runner",
Status: "failed",
ModuleResults: []ModuleReport{
{
ModuleKey: "grammar",
ModuleInstance: "grammar_1",
Status: "failed",
ErrorMessage: "boom",
StartedAt: &now,
CompletedAt: &now,
},
},
ModulesSummary: &ModulesSummary{ModuleCount: 1, FailedModuleInstance: "grammar_1"},
}
b, err := json.Marshal(report)
if err != nil {
t.Fatalf("marshal report: %v", err)
}
var decoded map[string]any
if err := json.Unmarshal(b, &decoded); err != nil {
t.Fatalf("unmarshal map: %v", err)
}
if _, ok := decoded["module_results"]; !ok {
t.Fatalf("expected module_results field")
}
if _, ok := decoded["modules_summary"]; !ok {
t.Fatalf("expected modules_summary field")
}
}