节点在线、应用在线、配置在线使用令牌查询
大石头 authored at 2021-12-16 19:49:30
4.11 KiB
Stardust
package metrics

import (
	"context"
	"errors"
	"strings"
	"testing"
	"time"
)

type fakeProber struct {
	cpu       float64
	cpuErr    error
	memory    MemoryStat
	memoryErr error
	disk      DiskStat
	diskErr   error
	drives    []Drive
	drivesErr error
	sent      uint64
	recv      uint64
	netErr    error
	procCount uint64
	procErr   error
	procNames []string
	namesErr  error
	uptime    uint64
	uptimeErr error
	load      float64
	loadErr   error
}

func (f *fakeProber) CPUPercent(context.Context) (float64, error) { return f.cpu, f.cpuErr }
func (f *fakeProber) Memory(context.Context) (MemoryStat, error)  { return f.memory, f.memoryErr }
func (f *fakeProber) DiskUsage(context.Context, string) (DiskStat, error) {
	return f.disk, f.diskErr
}
func (f *fakeProber) Drives(context.Context) ([]Drive, error) { return f.drives, f.drivesErr }
func (f *fakeProber) NetTotals(context.Context) (uint64, uint64, error) {
	return f.sent, f.recv, f.netErr
}
func (f *fakeProber) ProcessCount(context.Context) (uint64, error) { return f.procCount, f.procErr }
func (f *fakeProber) ProcessNames(context.Context) ([]string, error) {
	return f.procNames, f.namesErr
}
func (f *fakeProber) Uptime(context.Context) (uint64, error) { return f.uptime, f.uptimeErr }
func (f *fakeProber) Load(context.Context) (float64, error)  { return f.load, f.loadErr }

func TestCollectFailureFallsBackToZero(t *testing.T) {
	err := errors.New("not supported")
	prober := &fakeProber{
		cpuErr:    err,
		memoryErr: err,
		diskErr:   err,
		drivesErr: err,
		netErr:    err,
		procErr:   err,
		namesErr:  err,
		uptimeErr: err,
		loadErr:   err,
	}
	collector := NewWithProber(t.TempDir(), prober)

	snap := collector.Collect(context.Background())
	if snap != (Snapshot{}) {
		t.Fatalf("expected zero snapshot on failures, got %+v", snap)
	}
}

func TestCollectValues(t *testing.T) {
	prober := &fakeProber{
		cpu:       85.5,
		memory:    MemoryStat{Total: 1000, Available: 400, Free: 200},
		disk:      DiskStat{Total: 5000, Free: 2500},
		drives:    []Drive{{Path: "/", Fs: "ext4", Total: 1 << 30, Free: 1 << 29}, {Path: "/data", Fs: "xfs", Total: 0, Free: 0}},
		sent:      1000,
		recv:      2000,
		procCount: 42,
		procNames: []string{"nginx", "dotnet", "nginx", "systemd", "os$"},
		uptime:    3600,
		load:      0.75,
	}
	collector := NewWithProber("/data", prober)
	now := time.Unix(1700000000, 0)
	collector.now = func() time.Time { return now }

	first := collector.Collect(context.Background())
	if first.CPUPercent != 85.5 || first.Memory != 1000 || first.AvailableMemory != 400 || first.FreeMemory != 200 {
		t.Fatalf("unexpected cpu/memory: %+v", first)
	}
	if first.TotalSize != 5000 || first.AvailableFreeSpace != 2500 {
		t.Fatalf("unexpected disk: %+v", first)
	}
	if first.DriveSize != 1<<30 {
		t.Fatalf("DriveSize = %d", first.DriveSize)
	}
	if !strings.Contains(first.DriveInfo, "/[ext4]=") {
		t.Fatalf("DriveInfo = %q", first.DriveInfo)
	}
	if first.UplinkSpeed != 0 || first.DownlinkSpeed != 0 {
		t.Fatalf("first sample should have zero speeds: %+v", first)
	}
	if first.ProcessCount != 42 || first.Processes != "dotnet,nginx,systemd" {
		t.Fatalf("unexpected processes: %q count=%d", first.Processes, first.ProcessCount)
	}
	if first.Uptime != 3600 || first.SystemLoad != 0.75 {
		t.Fatalf("unexpected uptime/load: %+v", first)
	}

	now = now.Add(10 * time.Second)
	prober.sent += 1024
	prober.recv += 2048
	second := collector.Collect(context.Background())
	if second.UplinkSpeed != 102 || second.DownlinkSpeed != 204 {
		t.Fatalf("unexpected speeds: up=%d down=%d", second.UplinkSpeed, second.DownlinkSpeed)
	}
}

func TestCollectClampsCPU(t *testing.T) {
	prober := &fakeProber{cpu: 150}
	collector := NewWithProber(t.TempDir(), prober)
	if got := collector.Collect(context.Background()).CPUPercent; got != 100 {
		t.Fatalf("CPUPercent = %v, want 100", got)
	}
}

func TestFormatSize(t *testing.T) {
	cases := map[uint64]string{
		0:          "0B",
		512:        "512B",
		1536:       "1.5K",
		2 << 20:    "2M",
		50 << 30:   "50G",
		1024 << 30: "1T",
	}
	for input, want := range cases {
		if got := FormatSize(input); got != want {
			t.Fatalf("FormatSize(%d) = %q, want %q", input, got, want)
		}
	}
}