- Fix YAML tags in auth config struct (json -> yaml) - Update CLI configs to use pre-hashed API keys - Remove double hashing in WebSocket client - Fix port mapping (9102 -> 9103) in CLI commands - Update permission keys to use jobs:read, jobs:create, etc. - Clean up all debug logging from CLI and server - All user roles now authenticate correctly: * Admin: Can queue jobs and see all jobs * Researcher: Can queue jobs and see own jobs * Analyst: Can see status (read-only access) Multi-user authentication is now fully functional.
188 lines
5.3 KiB
Go
188 lines
5.3 KiB
Go
package config
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/jfraeys/fetch_ml/internal/config"
|
|
)
|
|
|
|
func TestDefaultConstants(t *testing.T) {
|
|
t.Parallel() // Enable parallel execution
|
|
|
|
// Test default values
|
|
tests := []struct {
|
|
name string
|
|
actual any
|
|
expected any
|
|
}{
|
|
{"DefaultSSHPort", config.DefaultSSHPort, 22},
|
|
{"DefaultRedisPort", config.DefaultRedisPort, 6379},
|
|
{"DefaultRedisAddr", config.DefaultRedisAddr, "localhost:6379"},
|
|
{"DefaultBasePath", config.DefaultBasePath, "/mnt/nas/jobs"},
|
|
{"DefaultTrainScript", config.DefaultTrainScript, "train.py"},
|
|
{"DefaultDataDir", config.DefaultDataDir, "/data/active"},
|
|
{"DefaultLocalDataDir", config.DefaultLocalDataDir, "./data/active"},
|
|
{"DefaultNASDataDir", config.DefaultNASDataDir, "/mnt/datasets"},
|
|
{"DefaultMaxWorkers", config.DefaultMaxWorkers, 2},
|
|
{"DefaultPollInterval", config.DefaultPollInterval, 5},
|
|
{"DefaultMaxAgeHours", config.DefaultMaxAgeHours, 24},
|
|
{"DefaultMaxSizeGB", config.DefaultMaxSizeGB, 100},
|
|
{"DefaultCleanupInterval", config.DefaultCleanupInterval, 60},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if tt.actual != tt.expected {
|
|
t.Errorf("Expected %s to be %v, got %v", tt.name, tt.expected, tt.actual)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRedisKeyConstants(t *testing.T) {
|
|
t.Parallel() // Enable parallel execution
|
|
|
|
// Test Redis key prefixes
|
|
tests := []struct {
|
|
name string
|
|
actual string
|
|
expected string
|
|
}{
|
|
{"RedisTaskQueueKey", config.RedisTaskQueueKey, "ml:queue"},
|
|
{"RedisTaskPrefix", config.RedisTaskPrefix, "ml:task:"},
|
|
{"RedisJobMetricsPrefix", config.RedisJobMetricsPrefix, "ml:metrics:"},
|
|
{"RedisTaskStatusPrefix", config.RedisTaskStatusPrefix, "ml:status:"},
|
|
{"RedisWorkerHeartbeat", config.RedisWorkerHeartbeat, "ml:workers:heartbeat"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if tt.actual != tt.expected {
|
|
t.Errorf("Expected %s to be %s, got %s", tt.name, tt.expected, tt.actual)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestTaskStatusConstants(t *testing.T) {
|
|
t.Parallel() // Enable parallel execution
|
|
|
|
// Test task status constants
|
|
tests := []struct {
|
|
name string
|
|
actual string
|
|
expected string
|
|
}{
|
|
{"TaskStatusQueued", config.TaskStatusQueued, "queued"},
|
|
{"TaskStatusRunning", config.TaskStatusRunning, "running"},
|
|
{"TaskStatusCompleted", config.TaskStatusCompleted, "completed"},
|
|
{"TaskStatusFailed", config.TaskStatusFailed, "failed"},
|
|
{"TaskStatusCancelled", config.TaskStatusCancelled, "cancelled"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if tt.actual != tt.expected {
|
|
t.Errorf("Expected %s to be %s, got %s", tt.name, tt.expected, tt.actual)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestJobStatusConstants(t *testing.T) {
|
|
t.Parallel() // Enable parallel execution
|
|
|
|
// Test job status constants
|
|
tests := []struct {
|
|
name string
|
|
actual string
|
|
expected string
|
|
}{
|
|
{"JobStatusPending", config.JobStatusPending, "pending"},
|
|
{"JobStatusQueued", config.JobStatusQueued, "queued"},
|
|
{"JobStatusRunning", config.JobStatusRunning, "running"},
|
|
{"JobStatusFinished", config.JobStatusFinished, "finished"},
|
|
{"JobStatusFailed", config.JobStatusFailed, "failed"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if tt.actual != tt.expected {
|
|
t.Errorf("Expected %s to be %s, got %s", tt.name, tt.expected, tt.actual)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestPodmanConstants(t *testing.T) {
|
|
t.Parallel() // Enable parallel execution
|
|
|
|
// Test Podman defaults
|
|
tests := []struct {
|
|
name string
|
|
actual string
|
|
expected string
|
|
}{
|
|
{"DefaultPodmanMemory", config.DefaultPodmanMemory, "8g"},
|
|
{"DefaultPodmanCPUs", config.DefaultPodmanCPUs, "2"},
|
|
{"DefaultContainerWorkspace", config.DefaultContainerWorkspace, "/workspace"},
|
|
{"DefaultContainerResults", config.DefaultContainerResults, "/workspace/results"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if tt.actual != tt.expected {
|
|
t.Errorf("Expected %s to be %s, got %s", tt.name, tt.expected, tt.actual)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestConstantsConsistency(t *testing.T) {
|
|
t.Parallel() // Enable parallel execution
|
|
|
|
// Test that related constants are consistent
|
|
if config.DefaultRedisAddr != "localhost:6379" {
|
|
t.Errorf("Expected DefaultRedisAddr to use DefaultRedisPort, got %s", config.DefaultRedisAddr)
|
|
}
|
|
|
|
// Test that Redis key prefixes are consistent
|
|
if config.RedisTaskPrefix == config.RedisJobMetricsPrefix {
|
|
t.Error("Redis task prefix and metrics prefix should be different")
|
|
}
|
|
|
|
// Test that status constants don't overlap
|
|
taskStatuses := []string{
|
|
config.TaskStatusQueued,
|
|
config.TaskStatusRunning,
|
|
config.TaskStatusCompleted,
|
|
config.TaskStatusFailed,
|
|
config.TaskStatusCancelled,
|
|
}
|
|
|
|
jobStatuses := []string{
|
|
config.JobStatusPending,
|
|
config.JobStatusQueued,
|
|
config.JobStatusRunning,
|
|
config.JobStatusFinished,
|
|
config.JobStatusFailed,
|
|
}
|
|
|
|
// Check for duplicates within task statuses
|
|
for i, status1 := range taskStatuses {
|
|
for j, status2 := range taskStatuses {
|
|
if i != j && status1 == status2 {
|
|
t.Errorf("Duplicate task status found: %s", status1)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check for duplicates within job statuses
|
|
for i, status1 := range jobStatuses {
|
|
for j, status2 := range jobStatuses {
|
|
if i != j && status1 == status2 {
|
|
t.Errorf("Duplicate job status found: %s", status1)
|
|
}
|
|
}
|
|
}
|
|
}
|