fetch_ml/tests/unit/config/constants_test.go
Jeremie Fraeys ea15af1833 Fix multi-user authentication and clean up debug code
- 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.
2025-12-06 12:35:32 -05:00

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)
}
}
}
}