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) } } }