summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--internal/goprecords/report.go105
-rw-r--r--internal/goprecords/report_test.go38
2 files changed, 93 insertions, 50 deletions
diff --git a/internal/goprecords/report.go b/internal/goprecords/report.go
index 7d04ce3..6724c47 100644
--- a/internal/goprecords/report.go
+++ b/internal/goprecords/report.go
@@ -6,6 +6,55 @@ import (
"sort"
)
+type metricExtractor struct {
+ hostSortKey func(*HostAggregate) uint64
+ aggSortKey func(*Aggregate) uint64
+ hostHuman func(*HostAggregate) string
+ aggHuman func(*Aggregate) string
+}
+
+var uptimeMetricExtractor = metricExtractor{
+ hostSortKey: func(h *HostAggregate) uint64 { return h.Uptime },
+ aggSortKey: func(a *Aggregate) uint64 { return a.Uptime },
+ hostHuman: func(h *HostAggregate) string { return formatDuration(h.Uptime) },
+ aggHuman: func(a *Aggregate) string { return formatDuration(a.Uptime) },
+}
+
+var metricExtractors = map[Metric]metricExtractor{
+ MetricBoots: {
+ hostSortKey: func(h *HostAggregate) uint64 { return h.Boots },
+ aggSortKey: func(a *Aggregate) uint64 { return a.Boots },
+ hostHuman: func(h *HostAggregate) string { return formatInt(h.Boots) },
+ aggHuman: func(a *Aggregate) string { return formatInt(a.Boots) },
+ },
+ MetricUptime: uptimeMetricExtractor,
+ MetricScore: {
+ hostSortKey: func(h *HostAggregate) uint64 { return h.MetaScore() },
+ aggSortKey: func(a *Aggregate) uint64 { return a.MetaScore() },
+ hostHuman: func(h *HostAggregate) string { return formatInt(h.MetaScore()) },
+ aggHuman: func(a *Aggregate) string { return formatInt(a.MetaScore()) },
+ },
+ MetricDowntime: {
+ hostSortKey: func(h *HostAggregate) uint64 { return h.Downtime() },
+ aggSortKey: func(a *Aggregate) uint64 { return a.Uptime },
+ hostHuman: func(h *HostAggregate) string { return formatDuration(h.Downtime()) },
+ aggHuman: func(a *Aggregate) string { return formatDuration(a.Uptime) },
+ },
+ MetricLifespan: {
+ hostSortKey: func(h *HostAggregate) uint64 { return h.Lifespan() },
+ aggSortKey: func(a *Aggregate) uint64 { return a.Uptime },
+ hostHuman: func(h *HostAggregate) string { return formatDuration(h.Lifespan()) },
+ aggHuman: func(a *Aggregate) string { return formatDuration(a.Uptime) },
+ },
+}
+
+func extractorFor(m Metric) metricExtractor {
+ if e, ok := metricExtractors[m]; ok {
+ return e
+ }
+ return uptimeMetricExtractor
+}
+
// WriteReports renders reports to w based on the given config.
func WriteReports(w io.Writer, aggregates *Aggregates, cfg ReportConfig) error {
if !cfg.All {
@@ -133,22 +182,9 @@ func (r reportBuilder) buildHostTable() ([]tableRow, bool) {
key uint64
}
var list []keyVal
+ ex := extractorFor(r.metric)
for _, h := range r.aggregates.Host {
- var k uint64
- switch r.metric {
- case MetricUptime:
- k = h.Uptime
- case MetricBoots:
- k = h.Boots
- case MetricScore:
- k = h.MetaScore()
- case MetricDowntime:
- k = h.Downtime()
- case MetricLifespan:
- k = h.Lifespan()
- default:
- k = h.Uptime
- }
+ k := ex.hostSortKey(h)
list = append(list, keyVal{h, k})
}
sort.Slice(list, func(i, j int) bool { return list[i].key > list[j].key })
@@ -185,18 +221,9 @@ func (r reportBuilder) buildCategoryTable() ([]tableRow, bool) {
key uint64
}
var list []keyVal
+ ex := extractorFor(r.metric)
for _, a := range m {
- var k uint64
- switch r.metric {
- case MetricUptime:
- k = a.Uptime
- case MetricBoots:
- k = a.Boots
- case MetricScore:
- k = a.MetaScore()
- default:
- k = a.Uptime
- }
+ k := ex.aggSortKey(a)
list = append(list, keyVal{agg: a, key: k})
}
sort.Slice(list, func(i, j int) bool { return list[i].key > list[j].key })
@@ -220,31 +247,9 @@ func (r reportBuilder) buildCategoryTable() ([]tableRow, bool) {
}
func (r reportBuilder) humanStrHost(h *HostAggregate) string {
- switch r.metric {
- case MetricUptime:
- return formatDuration(h.Uptime)
- case MetricBoots:
- return formatInt(h.Boots)
- case MetricScore:
- return formatInt(h.MetaScore())
- case MetricDowntime:
- return formatDuration(h.Downtime())
- case MetricLifespan:
- return formatDuration(h.Lifespan())
- default:
- return formatDuration(h.Uptime)
- }
+ return extractorFor(r.metric).hostHuman(h)
}
func (r reportBuilder) humanStrAgg(a *Aggregate) string {
- switch r.metric {
- case MetricUptime:
- return formatDuration(a.Uptime)
- case MetricBoots:
- return formatInt(a.Boots)
- case MetricScore:
- return formatInt(a.MetaScore())
- default:
- return formatDuration(a.Uptime)
- }
+ return extractorFor(r.metric).aggHuman(a)
}
diff --git a/internal/goprecords/report_test.go b/internal/goprecords/report_test.go
index a2ec5e9..a227528 100644
--- a/internal/goprecords/report_test.go
+++ b/internal/goprecords/report_test.go
@@ -173,6 +173,44 @@ func TestReportGemtext(t *testing.T) {
}
}
+func TestExtractorForUnknownMetricFallsBackToUptime(t *testing.T) {
+ h := NewHostAggregate("h", "k")
+ h.Uptime = 999
+ h.Boots = 1
+ a := NewAggregate("k")
+ a.Uptime = 888
+ a.Boots = 2
+ unknown := Metric(255)
+ ex := extractorFor(unknown)
+ if got := ex.hostSortKey(h); got != h.Uptime {
+ t.Errorf("host sort key: got %d want %d", got, h.Uptime)
+ }
+ if got := ex.aggSortKey(a); got != a.Uptime {
+ t.Errorf("agg sort key: got %d want %d", got, a.Uptime)
+ }
+ if got := ex.hostHuman(h); got != formatDuration(h.Uptime) {
+ t.Errorf("host human: got %q want %q", got, formatDuration(h.Uptime))
+ }
+ if got := ex.aggHuman(a); got != formatDuration(a.Uptime) {
+ t.Errorf("agg human: got %q want %q", got, formatDuration(a.Uptime))
+ }
+}
+
+func TestExtractorForAggDowntimeLifespanUsesUptime(t *testing.T) {
+ a := NewAggregate("k")
+ a.Uptime = 42
+ a.Boots = 7
+ for _, m := range []Metric{MetricDowntime, MetricLifespan} {
+ ex := extractorFor(m)
+ if got := ex.aggSortKey(a); got != a.Uptime {
+ t.Errorf("%v agg sort key: got %d want %d", m, got, a.Uptime)
+ }
+ if got := ex.aggHuman(a); got != formatDuration(a.Uptime) {
+ t.Errorf("%v agg human: got %q want %q", m, got, formatDuration(a.Uptime))
+ }
+ }
+}
+
func TestReportMetrics(t *testing.T) {
aggs := &Aggregates{
Host: make(map[string]*HostAggregate),