test: Add tests for API helper functions
- isRecentlyAutoRegistered: expiry logic, cleanup behavior - clearAutoRegistered: key deletion, empty input handling - normalizeDockerAgentArch: all arch variants, case handling, trimming
This commit is contained in:
parent
80702a51bf
commit
3233c48986
2 changed files with 266 additions and 0 deletions
196
internal/api/config_handlers_auto_reg_test.go
Normal file
196
internal/api/config_handlers_auto_reg_test.go
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/rcourtman/pulse-go-rewrite/internal/config"
|
||||
)
|
||||
|
||||
func TestIsRecentlyAutoRegistered(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
nodeType string
|
||||
nodeName string
|
||||
setup func(*ConfigHandlers)
|
||||
want bool
|
||||
checkGone bool // verify entry was cleaned up
|
||||
}{
|
||||
{
|
||||
name: "empty nodeType returns false",
|
||||
nodeType: "",
|
||||
nodeName: "node1",
|
||||
setup: nil,
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "empty nodeName returns false",
|
||||
nodeType: "pve",
|
||||
nodeName: "",
|
||||
setup: nil,
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "key not in map returns false",
|
||||
nodeType: "pve",
|
||||
nodeName: "nonexistent",
|
||||
setup: nil,
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "recent registration returns true",
|
||||
nodeType: "pve",
|
||||
nodeName: "node1",
|
||||
setup: func(h *ConfigHandlers) {
|
||||
h.recentAutoRegistered["pve:node1"] = time.Now()
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "expired registration returns false and cleans up",
|
||||
nodeType: "pve",
|
||||
nodeName: "node1",
|
||||
setup: func(h *ConfigHandlers) {
|
||||
h.recentAutoRegistered["pve:node1"] = time.Now().Add(-3 * time.Minute)
|
||||
},
|
||||
want: false,
|
||||
checkGone: true,
|
||||
},
|
||||
{
|
||||
name: "different keys are independent",
|
||||
nodeType: "pbs",
|
||||
nodeName: "node2",
|
||||
setup: func(h *ConfigHandlers) {
|
||||
h.recentAutoRegistered["pve:node1"] = time.Now()
|
||||
},
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cfg := &config.Config{
|
||||
DataPath: t.TempDir(),
|
||||
ConfigPath: t.TempDir(),
|
||||
}
|
||||
h := newTestConfigHandlers(t, cfg)
|
||||
|
||||
if tt.setup != nil {
|
||||
tt.setup(h)
|
||||
}
|
||||
|
||||
got := h.isRecentlyAutoRegistered(tt.nodeType, tt.nodeName)
|
||||
if got != tt.want {
|
||||
t.Errorf("isRecentlyAutoRegistered(%q, %q) = %v, want %v", tt.nodeType, tt.nodeName, got, tt.want)
|
||||
}
|
||||
|
||||
if tt.checkGone {
|
||||
key := tt.nodeType + ":" + tt.nodeName
|
||||
h.recentAutoRegMutex.Lock()
|
||||
_, exists := h.recentAutoRegistered[key]
|
||||
h.recentAutoRegMutex.Unlock()
|
||||
if exists {
|
||||
t.Errorf("expected key %q to be cleaned up, but it still exists", key)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestClearAutoRegistered(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
nodeType string
|
||||
nodeName string
|
||||
setup func(*ConfigHandlers)
|
||||
check func(*testing.T, *ConfigHandlers)
|
||||
}{
|
||||
{
|
||||
name: "empty nodeType is safe",
|
||||
nodeType: "",
|
||||
nodeName: "node1",
|
||||
setup: func(h *ConfigHandlers) {
|
||||
h.recentAutoRegistered["pve:node1"] = time.Now()
|
||||
},
|
||||
check: func(t *testing.T, h *ConfigHandlers) {
|
||||
h.recentAutoRegMutex.Lock()
|
||||
defer h.recentAutoRegMutex.Unlock()
|
||||
if _, exists := h.recentAutoRegistered["pve:node1"]; !exists {
|
||||
t.Error("expected pve:node1 to still exist")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "empty nodeName is safe",
|
||||
nodeType: "pve",
|
||||
nodeName: "",
|
||||
setup: func(h *ConfigHandlers) {
|
||||
h.recentAutoRegistered["pve:node1"] = time.Now()
|
||||
},
|
||||
check: func(t *testing.T, h *ConfigHandlers) {
|
||||
h.recentAutoRegMutex.Lock()
|
||||
defer h.recentAutoRegMutex.Unlock()
|
||||
if _, exists := h.recentAutoRegistered["pve:node1"]; !exists {
|
||||
t.Error("expected pve:node1 to still exist")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "successfully clears existing entry",
|
||||
nodeType: "pve",
|
||||
nodeName: "node1",
|
||||
setup: func(h *ConfigHandlers) {
|
||||
h.recentAutoRegistered["pve:node1"] = time.Now()
|
||||
},
|
||||
check: func(t *testing.T, h *ConfigHandlers) {
|
||||
h.recentAutoRegMutex.Lock()
|
||||
defer h.recentAutoRegMutex.Unlock()
|
||||
if _, exists := h.recentAutoRegistered["pve:node1"]; exists {
|
||||
t.Error("expected pve:node1 to be cleared")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "non-existent key does not error",
|
||||
nodeType: "pve",
|
||||
nodeName: "nonexistent",
|
||||
setup: nil,
|
||||
check: func(t *testing.T, h *ConfigHandlers) {
|
||||
// Just verify no panic occurred and map is still valid
|
||||
h.recentAutoRegMutex.Lock()
|
||||
defer h.recentAutoRegMutex.Unlock()
|
||||
if h.recentAutoRegistered == nil {
|
||||
t.Error("map should not be nil")
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cfg := &config.Config{
|
||||
DataPath: t.TempDir(),
|
||||
ConfigPath: t.TempDir(),
|
||||
}
|
||||
h := newTestConfigHandlers(t, cfg)
|
||||
|
||||
if tt.setup != nil {
|
||||
tt.setup(h)
|
||||
}
|
||||
|
||||
h.clearAutoRegistered(tt.nodeType, tt.nodeName)
|
||||
|
||||
if tt.check != nil {
|
||||
tt.check(t, h)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
70
internal/api/router_arch_test.go
Normal file
70
internal/api/router_arch_test.go
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
package api
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestNormalizeDockerAgentArch(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
expected string
|
||||
}{
|
||||
// Empty string
|
||||
{"empty string", "", ""},
|
||||
|
||||
// amd64 variants
|
||||
{"linux-amd64", "linux-amd64", "linux-amd64"},
|
||||
{"amd64", "amd64", "linux-amd64"},
|
||||
{"x86_64", "x86_64", "linux-amd64"},
|
||||
{"x86-64", "x86-64", "linux-amd64"},
|
||||
|
||||
// arm64 variants
|
||||
{"linux-arm64", "linux-arm64", "linux-arm64"},
|
||||
{"arm64", "arm64", "linux-arm64"},
|
||||
{"aarch64", "aarch64", "linux-arm64"},
|
||||
|
||||
// armv7 variants
|
||||
{"linux-armv7", "linux-armv7", "linux-armv7"},
|
||||
{"armv7", "armv7", "linux-armv7"},
|
||||
{"armv7l", "armv7l", "linux-armv7"},
|
||||
{"armhf", "armhf", "linux-armv7"},
|
||||
|
||||
// armv6 variants
|
||||
{"linux-armv6", "linux-armv6", "linux-armv6"},
|
||||
{"armv6", "armv6", "linux-armv6"},
|
||||
{"armv6l", "armv6l", "linux-armv6"},
|
||||
|
||||
// 386 variants
|
||||
{"linux-386", "linux-386", "linux-386"},
|
||||
{"386", "386", "linux-386"},
|
||||
{"i386", "i386", "linux-386"},
|
||||
{"i686", "i686", "linux-386"},
|
||||
|
||||
// Unknown architecture
|
||||
{"unknown arch", "unknown", ""},
|
||||
{"invalid arch", "powerpc", ""},
|
||||
{"mips", "mips", ""},
|
||||
|
||||
// Case insensitivity
|
||||
{"AMD64 uppercase", "AMD64", "linux-amd64"},
|
||||
{"X86_64 uppercase", "X86_64", "linux-amd64"},
|
||||
{"AARCH64 uppercase", "AARCH64", "linux-arm64"},
|
||||
{"ARMV7 uppercase", "ARMV7", "linux-armv7"},
|
||||
{"mixed case LinuX-AmD64", "LinuX-AmD64", "linux-amd64"},
|
||||
|
||||
// Whitespace trimming
|
||||
{"leading space", " amd64", "linux-amd64"},
|
||||
{"trailing space", "amd64 ", "linux-amd64"},
|
||||
{"both spaces", " amd64 ", "linux-amd64"},
|
||||
{"tabs", "\tamd64\t", "linux-amd64"},
|
||||
{"mixed whitespace", " \t arm64 \t ", "linux-arm64"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := normalizeDockerAgentArch(tt.input)
|
||||
if result != tt.expected {
|
||||
t.Errorf("normalizeDockerAgentArch(%q) = %q, want %q", tt.input, result, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue