90 lines
4.3 KiB
Go
90 lines
4.3 KiB
Go
package diagnostics
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"gitea.maximumdirect.net/eric/notarius/internal/framework/contracts"
|
|
)
|
|
|
|
func TestAggregatorMergesByOriginAndPreservesFirstOccurrenceOrder(t *testing.T) {
|
|
aggregator := Aggregator{}
|
|
for _, group := range []contracts.DiagnosticGroup{
|
|
groupForAggregation("first", "message one", contracts.DiagnosticDispositionAdvisory, contracts.DiagnosticCategoryDataQuality, "dnd/spells"),
|
|
groupForAggregation("second", "message two", contracts.DiagnosticDispositionWarning, contracts.DiagnosticCategoryFallback, "dnd/items"),
|
|
groupForAggregation("third", "message three", contracts.DiagnosticDispositionAdvisory, contracts.DiagnosticCategoryDataQuality, "dnd/spells"),
|
|
} {
|
|
if err := aggregator.Add(group); err != nil {
|
|
t.Fatalf("Add() error = %v", err)
|
|
}
|
|
}
|
|
collection := aggregator.Collection()
|
|
if len(collection.Groups) != 2 {
|
|
t.Fatalf("group count = %d, want 2", len(collection.Groups))
|
|
}
|
|
if got := []string{collection.Groups[0].Origin.ModuleKey, collection.Groups[1].Origin.ModuleKey}; !equalStrings(got, []string{"dnd/spells", "dnd/items"}) {
|
|
t.Fatalf("group order = %#v, want first occurrence order", got)
|
|
}
|
|
if collection.Groups[0].OccurrenceCount != 2 || collection.Groups[0].OmittedSampleCount != 0 {
|
|
t.Fatalf("merged group = %#v, want two represented occurrences", collection.Groups[0])
|
|
}
|
|
if got := []string{collection.Groups[0].Samples[0].Scope, collection.Groups[0].Samples[1].Scope}; !equalStrings(got, []string{"first", "third"}) {
|
|
t.Fatalf("merged samples = %#v, want first occurrence order", got)
|
|
}
|
|
}
|
|
|
|
func TestAggregatorEnforcesWarningBoundAndTruncatesOnlyNonWarnings(t *testing.T) {
|
|
warnings := Aggregator{}
|
|
for index := 0; index < MaxWarningGroups; index++ {
|
|
group := groupForAggregation("scope", "message", contracts.DiagnosticDispositionWarning, contracts.DiagnosticCategoryFallback, "module")
|
|
group.ReasonCode = "warning-" + string(rune('a'+index))
|
|
if err := warnings.Add(group); err != nil {
|
|
t.Fatalf("warning Add(%d) error = %v", index, err)
|
|
}
|
|
}
|
|
if err := warnings.Add(groupForAggregation("overflow", "overflow", contracts.DiagnosticDispositionWarning, contracts.DiagnosticCategoryFallback, "overflow")); err == nil {
|
|
t.Fatal("warning overflow error = nil, want error")
|
|
}
|
|
|
|
nonWarnings := Aggregator{}
|
|
for index := 0; index < MaxNonWarningGroups+3; index++ {
|
|
group := groupForAggregation("scope", "message", contracts.DiagnosticDispositionAdvisory, contracts.DiagnosticCategoryDataQuality, "module")
|
|
group.ReasonCode = "advisory-" + string(rune('a'+index))
|
|
if err := nonWarnings.Add(group); err != nil {
|
|
t.Fatalf("non-warning Add(%d) error = %v", index, err)
|
|
}
|
|
}
|
|
collection := nonWarnings.Collection()
|
|
if len(collection.Groups) != MaxNonWarningGroups || !collection.Truncated || collection.UnrepresentedOccurrenceCount != 3 {
|
|
t.Fatalf("collection = %#v, want bounded non-warning groups and three unrepresented occurrences", collection)
|
|
}
|
|
}
|
|
|
|
func TestAggregatorRejectsOccurrenceTotalOverflow(t *testing.T) {
|
|
aggregator := Aggregator{}
|
|
first := groupForAggregation("first", "first", contracts.DiagnosticDispositionAdvisory, contracts.DiagnosticCategoryDataQuality, "first")
|
|
first.OccurrenceCount = maximumInt()
|
|
first.OmittedSampleCount = maximumInt() - 1
|
|
if err := aggregator.Add(first); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
second := groupForAggregation("second", "second", contracts.DiagnosticDispositionAdvisory, contracts.DiagnosticCategoryDataQuality, "second")
|
|
if err := aggregator.Add(second); err == nil {
|
|
t.Fatal("Add() occurrence total overflow error = nil")
|
|
}
|
|
collection := aggregator.Collection()
|
|
if len(collection.Groups) != 1 || collection.Groups[0].OccurrenceCount != maximumInt() {
|
|
t.Fatalf("collection changed after rejected overflow = %#v", collection)
|
|
}
|
|
}
|
|
|
|
func groupForAggregation(scope string, message string, disposition contracts.DiagnosticDisposition, category contracts.DiagnosticCategory, module string) contracts.DiagnosticGroup {
|
|
return contracts.DiagnosticGroup{
|
|
Disposition: disposition,
|
|
Category: category,
|
|
ReasonCode: "source_unrelated",
|
|
Origin: contracts.DiagnosticOrigin{Stage: contracts.DiagnosticOriginStageExtract, StepID: "extract", LaneID: "spells", ModuleKey: module},
|
|
OccurrenceCount: 1,
|
|
Samples: []contracts.DiagnosticSample{{Scope: scope, Message: message}},
|
|
}
|
|
}
|