2026-08-15 01:27:23 +08:00

172 lines
4.9 KiB
Go

package collect
import (
"strings"
"testing"
"git.opencomputing.cn/yumoqing/host-metrics-collector/internal/model"
)
type fakeSystem struct {
cpu float64
percpu []float64
mem float64
load float64
disks []DiskUsageStat
diskio map[string]DiskIOCounter
netio map[string]NetIOCounter
procs []ProcessStat
}
func (f fakeSystem) CPUUsage() (float64, error) { return f.cpu, nil }
func (f fakeSystem) PerCPUUsage() ([]float64, error) { return f.percpu, nil }
func (f fakeSystem) MemUsedPercent() (float64, error) { return f.mem, nil }
func (f fakeSystem) Load1() (float64, error) { return f.load, nil }
func (f fakeSystem) DiskUsages() ([]DiskUsageStat, error) { return f.disks, nil }
func (f fakeSystem) DiskIOCounters() (map[string]DiskIOCounter, error) {
return f.diskio, nil
}
func (f fakeSystem) NetIOCounters() (map[string]NetIOCounter, error) { return f.netio, nil }
func (f fakeSystem) Processes() ([]ProcessStat, error) { return f.procs, nil }
func newTestCollector() *Collector {
sys := fakeSystem{
cpu: 42.5,
percpu: []float64{10, 20},
mem: 66.6,
load: 0.7,
disks: []DiskUsageStat{{Mountpoint: "/", UsedPercent: 80}},
diskio: map[string]DiskIOCounter{"sda": {ReadBytes: 100, WriteBytes: 200}},
netio: map[string]NetIOCounter{"eth0": {BytesSent: 1000, BytesRecv: 2000, DropOut: 1, DropIn: 2}},
procs: []ProcessStat{{PID: 1, Name: "init", CPUPercent: 1.2, MemBytes: 4096}},
}
return NewCollector(sys, "h-001", "web")
}
func TestCollectCore(t *testing.T) {
c := newTestCollector()
samples, err := c.CollectCore()
if err != nil {
t.Fatalf("CollectCore returned error: %v", err)
}
if len(samples) != 5 { // 1 overall + 2 per-core + mem + load
t.Fatalf("expected 5 samples, got %d", len(samples))
}
byName := map[string][]model.Sample{}
for _, s := range samples {
byName[s.Name] = append(byName[s.Name], s)
}
if got := byName[model.MetricCPUUsage]; len(got) != 3 {
t.Fatalf("expected 3 cpu.usage samples, got %d", len(got))
}
if got := byName[model.MetricMemUsedPercent][0].Value; got != 66.6 {
t.Fatalf("mem used percent = %v, want 66.6", got)
}
if got := byName[model.MetricLoad1m][0].Value; got != 0.7 {
t.Fatalf("load1m = %v, want 0.7", got)
}
for _, s := range samples {
if s.Labels[model.LabelHostID] != "h-001" {
t.Fatalf("missing host_id label: %#v", s.Labels)
}
if s.Labels[model.LabelMetricGroup] != model.GroupCore {
t.Fatalf("wrong metric_group: %#v", s.Labels)
}
}
}
func TestCollectDisk(t *testing.T) {
c := newTestCollector()
samples, err := c.CollectDisk()
if err != nil {
t.Fatalf("CollectDisk returned error: %v", err)
}
if len(samples) != 3 { // 1 used_percent + 2 io counters
t.Fatalf("expected 3 samples, got %d", len(samples))
}
var sawUsed, sawRead, sawWrite bool
for _, s := range samples {
switch s.Name {
case model.MetricDiskUsedPercent:
sawUsed = true
if s.Labels["mountpoint"] != "/" {
t.Fatalf("mountpoint = %q", s.Labels["mountpoint"])
}
case model.MetricDiskIOReadBytes:
sawRead = true
if s.Value != 100 {
t.Fatalf("read bytes = %v", s.Value)
}
case model.MetricDiskIOWriteBytes:
sawWrite = true
}
}
if !sawUsed || !sawRead || !sawWrite {
t.Fatalf("missing disk samples: used=%v read=%v write=%v", sawUsed, sawRead, sawWrite)
}
}
func TestCollectNetwork(t *testing.T) {
c := newTestCollector()
samples, err := c.CollectNetwork()
if err != nil {
t.Fatalf("CollectNetwork returned error: %v", err)
}
if len(samples) != 3 {
t.Fatalf("expected 3 samples, got %d", len(samples))
}
for _, s := range samples {
if s.Labels["interface"] != "eth0" {
t.Fatalf("interface = %q", s.Labels["interface"])
}
if s.Name == model.MetricNetPktDrop && s.Value != 3 {
t.Fatalf("pkt drop = %v, want 3", s.Value)
}
}
}
func TestCollectProcess(t *testing.T) {
c := newTestCollector()
samples, err := c.CollectProcess()
if err != nil {
t.Fatalf("CollectProcess returned error: %v", err)
}
if len(samples) != 3 { // count + cpu + mem
t.Fatalf("expected 3 samples, got %d", len(samples))
}
for _, s := range samples {
if s.Name == model.MetricProcessCount && s.Value != 1 {
t.Fatalf("process count = %v, want 1", s.Value)
}
if s.Name == model.MetricProcessMem && s.Value != 4096 {
t.Fatalf("process mem = %v, want 4096", s.Value)
}
}
}
func TestDetectLevel(t *testing.T) {
cases := map[string]string{
"ERROR something": "ERROR",
"fatal error": "FATAL",
"warn: x": "WARN",
"info msg": "INFO",
"plain": "INFO",
}
for in, want := range cases {
if got := detectLevel(in); got != want {
t.Errorf("detectLevel(%q) = %q, want %q", in, got, want)
}
}
}
func TestCollectorLabelsCarryService(t *testing.T) {
c := newTestCollector()
samples, _ := c.CollectCore()
for _, s := range samples {
if !strings.Contains(s.Labels[model.LabelService], "web") {
t.Fatalf("service label missing: %#v", s.Labels)
}
}
}