Pulse/internal/config/host_metadata_test.go
rcourtman ed78509f92 Fix flaky tests and improve coverage across alerts, api, and config packages
- Fix deadlock and race conditions in internal/alerts
- Add comprehensive error path tests for internal/config
- Fix 401 handling in internal/api
- Fix Docker Swarm task filtering test logic
2026-01-03 18:36:17 +00:00

132 lines
3.4 KiB
Go

package config
import (
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestNewHostMetadataStore(t *testing.T) {
tempDir := t.TempDir()
store := NewHostMetadataStore(tempDir, nil)
assert.NotNil(t, store)
assert.Empty(t, store.GetAll())
}
func TestHostMetadataStore_CRUD(t *testing.T) {
tempDir := t.TempDir()
store := NewHostMetadataStore(tempDir, nil)
hostID := "host1"
meta := &HostMetadata{
ID: hostID,
Description: "Test Host",
Tags: []string{"tag1", "tag2"},
}
// Create
err := store.Set(hostID, meta)
require.NoError(t, err)
// Read
readMeta := store.Get(hostID)
require.NotNil(t, readMeta)
assert.Equal(t, meta.Description, readMeta.Description)
assert.Equal(t, meta.Tags, readMeta.Tags)
// Persistence Check
store2 := NewHostMetadataStore(tempDir, nil)
readMeta2 := store2.Get(hostID)
require.NotNil(t, readMeta2)
assert.Equal(t, meta.Description, readMeta2.Description)
// Update
meta.Description = "Updated Host"
err = store.Set(hostID, meta)
require.NoError(t, err)
assert.Equal(t, "Updated Host", store.Get(hostID).Description)
// GetAll
all := store.GetAll()
assert.Len(t, all, 1)
assert.Contains(t, all, hostID)
// Delete
err = store.Delete(hostID)
require.NoError(t, err)
assert.Nil(t, store.Get(hostID))
// Persistence Check after delete
store3 := NewHostMetadataStore(tempDir, nil)
assert.Nil(t, store3.Get(hostID))
}
func TestHostMetadataStore_ReplaceAll(t *testing.T) {
tempDir := t.TempDir()
store := NewHostMetadataStore(tempDir, nil)
newMetadata := map[string]*HostMetadata{
"host1": {Description: "Host 1"},
"host2": {Description: "Host 2", Tags: nil}, // Test nil tags handling
}
err := store.ReplaceAll(newMetadata)
require.NoError(t, err)
assert.Equal(t, "Host 1", store.Get("host1").Description)
assert.Equal(t, "Host 2", store.Get("host2").Description)
assert.NotNil(t, store.Get("host2").Tags) // Should contain empty slice, not nil
// Verify nil items strictly skipped or handled
err = store.ReplaceAll(map[string]*HostMetadata{
"host3": nil,
})
require.NoError(t, err)
assert.Nil(t, store.Get("host3"))
}
func TestHostMetadataStore_Set_Nil(t *testing.T) {
store := NewHostMetadataStore(t.TempDir(), nil)
err := store.Set("host1", nil)
assert.Error(t, err)
}
func TestHostMetadataStore_Load_Error(t *testing.T) {
tempDir := t.TempDir()
filePath := filepath.Join(tempDir, "host_metadata.json")
require.NoError(t, os.WriteFile(filePath, []byte("{invalid-json"), 0644))
store := NewHostMetadataStore(tempDir, nil)
// It logs warning but returns store.
assert.NotNil(t, store)
assert.Empty(t, store.GetAll())
// Explicit load call
err := store.Load()
assert.Error(t, err)
}
func TestHostMetadataStore_Save_Error(t *testing.T) {
// Use a read-only directory to simulate save error
tempDir := t.TempDir()
readOnlyDir := filepath.Join(tempDir, "readonly")
require.NoError(t, os.Mkdir(readOnlyDir, 0555))
store := NewHostMetadataStore(readOnlyDir, nil)
// Try to fail save
// Making the directory strictly read-only might work,
// but t.TempDir cleanup might fail if we don't fix permissions.
// Alternative: Point to a file as directory.
badPath := filepath.Join(tempDir, "file")
require.NoError(t, os.WriteFile(badPath, []byte("content"), 0644))
store.dataPath = badPath // Hack internal field for testing failure
err := store.Set("host1", &HostMetadata{})
assert.Error(t, err)
}