d6d2a24ddc
Applies gofmt to the 18 files that were already unformatted at HEAD (pre-existing debt — 122 insertions / 122 deletions, whitespace plus import-block reorderings only; `git diff -w` confirms no semantic changes). Kept on its own branch so the functional change set (see the review-hardening PR) stays reviewable without formatting noise. Verified: go build, go vet, go test ./... pass on this branch; a merge simulation with the functional branch produces a clean 3-way merge with all tests green. Reviewed-on: #4 Co-authored-by: David Gwilliam <dhgwilliam@gmail.com> Co-committed-by: David Gwilliam <dhgwilliam@gmail.com>
115 lines
2.6 KiB
Go
115 lines
2.6 KiB
Go
package metrics
|
|
|
|
import (
|
|
"io"
|
|
"net/http/httptest"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/david/knox/internal/db"
|
|
"github.com/prometheus/client_golang/prometheus/testutil"
|
|
)
|
|
|
|
func tmpKdb(t *testing.T) *db.KnoxDB {
|
|
t.Helper()
|
|
k, err := db.Open(filepath.Join(t.TempDir(), "index.db"))
|
|
if err != nil {
|
|
t.Fatalf("open db: %v", err)
|
|
}
|
|
t.Cleanup(func() { k.Close() })
|
|
return k
|
|
}
|
|
|
|
func seed(t *testing.T, k *db.KnoxDB, src string, n int) {
|
|
t.Helper()
|
|
for i := 0; i < n; i++ {
|
|
_, _, err := k.RecordObservation(db.ObservationRecord{
|
|
Fingerprint: "fp-" + src + "-" + string(rune('a'+i)),
|
|
SourceID: src,
|
|
SourcePath: src,
|
|
Project: "test",
|
|
ContentType: "test",
|
|
Title: src,
|
|
Summary: "s",
|
|
CreatedAt: "2026-08-29T00:00:00Z",
|
|
Confidence: 0.9,
|
|
IngesterVersion: "itest/v1",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("seed: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestMetricsSnapshot(t *testing.T) {
|
|
k := tmpKdb(t)
|
|
seed(t, k, "git", 2)
|
|
seed(t, k, "browser-history", 3)
|
|
|
|
s, err := k.MetricsSnapshot()
|
|
if err != nil {
|
|
t.Fatalf("snapshot: %v", err)
|
|
}
|
|
if s.Observations != 5 {
|
|
t.Errorf("observations = %d, want 5", s.Observations)
|
|
}
|
|
if s.BySource["git"] != 2 || s.BySource["browser-history"] != 3 {
|
|
t.Errorf("by source = %v", s.BySource)
|
|
}
|
|
if s.KnowledgeVector[k.NodeID()] == 0 {
|
|
t.Errorf("knowledge vector missing own node")
|
|
}
|
|
if s.ByOriginNode[k.NodeID()] != 5 {
|
|
t.Errorf("by origin node = %v", s.ByOriginNode)
|
|
}
|
|
}
|
|
|
|
func TestMetricsScrape(t *testing.T) {
|
|
k := tmpKdb(t)
|
|
seed(t, k, "git", 2)
|
|
|
|
m := New(k, "testnode")
|
|
h := m.Handler()
|
|
|
|
rec := httptest.NewRecorder()
|
|
h.ServeHTTP(rec, httptest.NewRequest("GET", "/metrics", nil))
|
|
|
|
body, _ := io.ReadAll(rec.Body)
|
|
out := string(body)
|
|
for _, want := range []string{
|
|
`knox_node_info{name="testnode"`,
|
|
`knox_observations_total{source_id="git"} 2`,
|
|
`knox_gossip_pulls_total 0`,
|
|
"go_goroutines",
|
|
"process_cpu_seconds_total",
|
|
} {
|
|
if !strings.Contains(out, want) {
|
|
t.Errorf("scrape output missing %q", want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestMetricsCounters(t *testing.T) {
|
|
k := tmpKdb(t)
|
|
m := New(k, "t")
|
|
|
|
// Manually drive counters through the Metrics API.
|
|
m.IncrementPull(3)
|
|
m.IncrementPush(7)
|
|
m.IncrementErrors()
|
|
|
|
if got := testutil.ToFloat64(m.pullsTotal); got != 1 {
|
|
t.Errorf("pullsTotal = %v, want 1", got)
|
|
}
|
|
if got := testutil.ToFloat64(m.obsPulledTotal); got != 3 {
|
|
t.Errorf("obsPulled = %v, want 3", got)
|
|
}
|
|
if got := testutil.ToFloat64(m.obsPushedTotal); got != 7 {
|
|
t.Errorf("obsPushed = %v, want 7", got)
|
|
}
|
|
if got := testutil.ToFloat64(m.errorsTotal); got != 1 {
|
|
t.Errorf("errorsTotal = %v, want 1", got)
|
|
}
|
|
}
|