mirror of
https://github.com//cppla/ServerStatus
synced 2026-08-06 19:53:57 +08:00
86 lines
3.0 KiB
Go
86 lines
3.0 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/expr-lang/expr"
|
|
)
|
|
|
|
func TestNormalizeConfigPreservesCompatibility(t *testing.T) {
|
|
doc := minimalTestConfig()
|
|
doc["future"] = map[string]any{"enabled": true}
|
|
doc["watchdog"] = []any{
|
|
map[string]any{"name": "legacy", "rule": "cpu>90&load_1>5&username!='s01'", "interval": "600", "callback": nil},
|
|
map[string]any{"name": "type", "rule": "tcp_count>600&type='Oracle'", "interval": 60},
|
|
}
|
|
doc["servers"].([]any)[0].(map[string]any)["future_field"] = "kept"
|
|
|
|
normalized, runtime, apiErr := normalizeConfig(doc)
|
|
if apiErr != nil {
|
|
t.Fatal(apiErr)
|
|
}
|
|
if len(runtime.Watchdogs) != 2 || runtime.Watchdogs[0].Normalized != "cpu>90&&load_1>5&&username!='s01'" {
|
|
t.Fatalf("legacy rules were not normalized: %#v", runtime.Watchdogs)
|
|
}
|
|
server := normalized["servers"].([]any)[0].(map[string]any)
|
|
if server["future_field"] != "kept" || normalized["future"] == nil {
|
|
t.Fatal("unknown config fields were discarded")
|
|
}
|
|
if server["monthstart"] != json.Number("1") && server["monthstart"] != 1 {
|
|
t.Fatalf("monthstart not normalized: %#v", server["monthstart"])
|
|
}
|
|
}
|
|
|
|
func TestWatchdogLegacyRulesEvaluate(t *testing.T) {
|
|
rules := []string{
|
|
"online4=0&online6=0",
|
|
"(memory_used/memory_total)*100>90&memory_total>1048576",
|
|
"tcp_count>600&type='Oracle'",
|
|
"(network_out-last_network_out)/1024/1024/1024>18&(username='aliyun1'|username='aliyun2')",
|
|
}
|
|
for index, rule := range rules {
|
|
compiled, err := compileWatchdog(WatchdogConfig{Name: "test", Rule: rule, Interval: 1}, index)
|
|
if err != nil {
|
|
t.Fatalf("rule %q: %v", rule, err)
|
|
}
|
|
environment := watchdogEnvironment(ServerConfig{Username: "aliyun1", Type: "Oracle"}, AgentStats{MemoryTotal: 2_000_000, MemoryUsed: 1_900_000, TCPCount: 700, NetworkOut: 30 << 30}, false, false, 0, 0)
|
|
if _, err := expr.Run(compiled.Program, environment); err != nil {
|
|
t.Fatalf("run %q: %v", rule, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestConfigValidationErrors(t *testing.T) {
|
|
doc := minimalTestConfig()
|
|
doc["servers"] = append(doc["servers"].([]any), doc["servers"].([]any)[0])
|
|
_, _, apiErr := normalizeConfig(doc)
|
|
if apiErr == nil || apiErr.Status != 409 {
|
|
t.Fatalf("expected duplicate username error, got %#v", apiErr)
|
|
}
|
|
|
|
if _, err := decodeDocument([]byte(`{"servers":[]} {"servers":[]}`)); err == nil || !strings.Contains(err.Error(), "more than one") {
|
|
t.Fatalf("expected trailing JSON error, got %v", err)
|
|
}
|
|
}
|
|
|
|
func TestFormattingHelpers(t *testing.T) {
|
|
if got := formatUptime(90061); got != "1 天" {
|
|
t.Fatalf("formatUptime=%q", got)
|
|
}
|
|
if got := formatUptime(3661); got != "01:01:01" {
|
|
t.Fatalf("formatUptime=%q", got)
|
|
}
|
|
if got, err := certificateHost("https://example.com/path"); err != nil || got != "example.com" {
|
|
t.Fatalf("certificateHost=%q", got)
|
|
}
|
|
if got := secondsDuration(0); got != time.Second {
|
|
t.Fatalf("secondsDuration(0)=%s", got)
|
|
}
|
|
if got := secondsDuration(int(^uint(0) >> 1)); got < 365*24*time.Hour {
|
|
t.Fatalf("large interval overflowed or was truncated: %s", got)
|
|
}
|
|
}
|