Pulse/cmd/pulse-sensor-proxy/metrics_test.go

227 lines
4.8 KiB
Go

package main
import "testing"
func TestSanitizeNodeLabel(t *testing.T) {
tests := []struct {
name string
input string
want string
}{
// Basic cases
{
name: "simple hostname",
input: "node1",
want: "node1",
},
{
name: "hostname with hyphen",
input: "node-1",
want: "node-1",
},
{
name: "hostname with underscore",
input: "node_1",
want: "node_1",
},
{
name: "hostname with dot",
input: "node.local",
want: "node.local",
},
{
name: "fqdn",
input: "node1.example.com",
want: "node1.example.com",
},
// Case conversion
{
name: "uppercase converted to lowercase",
input: "Node1",
want: "node1",
},
{
name: "mixed case",
input: "MyNode-Server",
want: "mynode-server",
},
{
name: "all uppercase",
input: "PRODSERVER01",
want: "prodserver01",
},
// Special character handling
{
name: "space replaced with underscore",
input: "node 1",
want: "node_1",
},
{
name: "colon replaced with underscore",
input: "node:1",
want: "node_1",
},
{
name: "at sign replaced with underscore",
input: "user@node",
want: "user_node",
},
{
name: "forward slash replaced",
input: "path/to/node",
want: "path_to_node",
},
{
name: "multiple special chars",
input: "node!@#$%^&*()+=[]{}|\\:;<>,?/~`",
want: "node___________________________",
},
{
name: "unicode replaced with underscore",
input: "节点1",
want: "__1",
},
{
name: "emoji replaced",
input: "server🔥hot",
want: "server_hot",
},
// Length limits
{
name: "exactly 63 chars preserved",
input: "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0",
want: "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0",
},
{
name: "longer than 63 chars truncated",
input: "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789",
want: "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0",
},
{
name: "very long hostname truncated",
input: "this-is-a-very-long-hostname-that-exceeds-the-prometheus-label-value-limit-of-sixty-three-characters",
want: "this-is-a-very-long-hostname-that-exceeds-the-prometheus-label-",
},
// Edge cases
{
name: "empty string returns unknown",
input: "",
want: "unknown",
},
{
name: "all special chars returns unknown",
input: "!@#$%",
want: "_____",
},
{
name: "single char",
input: "a",
want: "a",
},
{
name: "numbers only",
input: "12345",
want: "12345",
},
{
name: "hyphen start preserved",
input: "-node",
want: "-node",
},
{
name: "underscore start preserved",
input: "_node",
want: "_node",
},
{
name: "dot start preserved",
input: ".hidden",
want: ".hidden",
},
// Realistic node names
{
name: "proxmox node style",
input: "pve-node1",
want: "pve-node1",
},
{
name: "ip address style",
input: "192.168.1.100",
want: "192.168.1.100",
},
{
name: "kubernetes node",
input: "k8s-worker-01.cluster.local",
want: "k8s-worker-01.cluster.local",
},
{
name: "docker container id prefix",
input: "abc123def456",
want: "abc123def456",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := sanitizeNodeLabel(tt.input)
if got != tt.want {
t.Errorf("sanitizeNodeLabel(%q) = %q, want %q", tt.input, got, tt.want)
}
})
}
}
func TestSanitizeNodeLabel_MaxLength(t *testing.T) {
// Test that all outputs are <= 63 chars
longInputs := []string{
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"very-long-hostname-with-many-hyphens-and-lots-of-segments-here",
"node123456789012345678901234567890123456789012345678901234567890",
}
for _, input := range longInputs {
result := sanitizeNodeLabel(input)
if len(result) > 63 {
t.Errorf("sanitizeNodeLabel(%q) length = %d, want <= 63", input, len(result))
}
}
}
func TestSanitizeNodeLabel_NeverEmpty(t *testing.T) {
// Test that output is never empty
emptyishInputs := []string{
"",
" ",
}
for _, input := range emptyishInputs {
result := sanitizeNodeLabel(input)
if result == "" {
t.Errorf("sanitizeNodeLabel(%q) returned empty string, should return 'unknown' or sanitized value", input)
}
}
}
func TestSanitizeNodeLabel_Idempotent(t *testing.T) {
// Applying sanitize twice should give same result as once
inputs := []string{
"node1",
"Node@Server",
"test.node.local",
"mixed-CASE_name.123",
}
for _, input := range inputs {
once := sanitizeNodeLabel(input)
twice := sanitizeNodeLabel(once)
if once != twice {
t.Errorf("sanitizeNodeLabel is not idempotent: sanitizeNodeLabel(%q) = %q, sanitizeNodeLabel(%q) = %q",
input, once, once, twice)
}
}
}