98 lines
2.5 KiB
Go
98 lines
2.5 KiB
Go
// ABOUTME: Tests for the collector's summary integration.
|
|
// ABOUTME: Validates that run summaries are emitted on shutdown and handles missing writer gracefully.
|
|
package collector
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"log/slog"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"edp.buildth.ing/DevFW-CICD/forgejo-runner-optimiser/internal/output"
|
|
"edp.buildth.ing/DevFW-CICD/forgejo-runner-optimiser/internal/summary"
|
|
)
|
|
|
|
func TestCollector_EmitsSummaryOnShutdown(t *testing.T) {
|
|
// Use testdata/proc as the proc filesystem
|
|
procPath := "testdata/proc"
|
|
|
|
// Metrics output (regular collection output)
|
|
var metricsOut bytes.Buffer
|
|
metricsWriter := output.NewLoggerWriter(output.LoggerConfig{
|
|
Output: &metricsOut,
|
|
Format: output.LogFormatJSON,
|
|
Level: slog.LevelInfo,
|
|
})
|
|
|
|
// Summary output
|
|
var summaryOut bytes.Buffer
|
|
sw := summary.NewSummaryWriter(&summaryOut, "json")
|
|
|
|
// Silence app logs
|
|
appLogger := slog.New(slog.NewTextHandler(&bytes.Buffer{}, nil))
|
|
|
|
c := New(Config{
|
|
ProcPath: procPath,
|
|
Interval: 50 * time.Millisecond,
|
|
TopN: 5,
|
|
}, metricsWriter, appLogger)
|
|
|
|
c.SetSummaryWriter(sw)
|
|
|
|
// Run collector briefly then cancel
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
go func() {
|
|
// Let at least 2 collection cycles run
|
|
time.Sleep(150 * time.Millisecond)
|
|
cancel()
|
|
}()
|
|
|
|
_ = c.Run(ctx)
|
|
|
|
// Verify summary was emitted
|
|
summaryOutput := summaryOut.String()
|
|
if !strings.Contains(summaryOutput, "run_summary") {
|
|
t.Errorf("expected 'run_summary' in output, got: %s", summaryOutput)
|
|
}
|
|
if !strings.Contains(summaryOutput, "duration_seconds") {
|
|
t.Errorf("expected 'duration_seconds' in output, got: %s", summaryOutput)
|
|
}
|
|
if !strings.Contains(summaryOutput, "sample_count") {
|
|
t.Errorf("expected 'sample_count' in output, got: %s", summaryOutput)
|
|
}
|
|
}
|
|
|
|
func TestCollector_NoSummaryWithoutWriter(t *testing.T) {
|
|
procPath := "testdata/proc"
|
|
|
|
var metricsOut bytes.Buffer
|
|
metricsWriter := output.NewLoggerWriter(output.LoggerConfig{
|
|
Output: &metricsOut,
|
|
Format: output.LogFormatJSON,
|
|
Level: slog.LevelInfo,
|
|
})
|
|
|
|
appLogger := slog.New(slog.NewTextHandler(&bytes.Buffer{}, nil))
|
|
|
|
c := New(Config{
|
|
ProcPath: procPath,
|
|
Interval: 50 * time.Millisecond,
|
|
TopN: 5,
|
|
}, metricsWriter, appLogger)
|
|
|
|
// Deliberately do NOT set a summary writer
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
go func() {
|
|
time.Sleep(100 * time.Millisecond)
|
|
cancel()
|
|
}()
|
|
|
|
// Should not panic
|
|
err := c.Run(ctx)
|
|
if err != context.Canceled {
|
|
t.Errorf("expected context.Canceled, got: %v", err)
|
|
}
|
|
}
|