fetch_ml/tests/e2e/sync_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

125 lines
3.5 KiB
Go

package tests
import (
"os"
"path/filepath"
"testing"
tests "github.com/jfraeys/fetch_ml/tests/fixtures"
)
// TestActualPodmanSync performs sync to a temporary directory for testing
// This test uses a temporary directory instead of podman/workspace
func TestActualPodmanSync(t *testing.T) {
if testing.Short() {
t.Skip("Skipping actual podman sync in short mode")
}
tempDir := t.TempDir()
podmanDir := filepath.Join(tempDir, "workspace")
// Ensure workspace exists
if err := os.MkdirAll(podmanDir, 0750); err != nil {
t.Fatalf("Failed to create test workspace: %v", err)
}
// Use fixtures for examples directory operations
examplesDir := tests.NewExamplesDir(filepath.Join("..", "fixtures", "examples"))
// Get all example projects
projects, err := examplesDir.ListProjects()
if err != nil {
t.Fatalf("Failed to list projects: %v", err)
}
for _, projectName := range projects {
t.Run("Sync_"+projectName, func(t *testing.T) {
// Remove existing destination
dstDir := filepath.Join(podmanDir, projectName)
if err := os.RemoveAll(dstDir); err != nil {
t.Fatalf("Failed to remove existing %s: %v", projectName, err)
}
// Copy project
if err := examplesDir.CopyProject(projectName, dstDir); err != nil {
t.Fatalf("Failed to copy %s to test workspace: %v", projectName, err)
}
// Verify copy
requiredFiles := []string{"train.py", "requirements.txt", "README.md"}
for _, file := range requiredFiles {
dstFile := filepath.Join(dstDir, file)
if _, err := os.Stat(dstFile); os.IsNotExist(err) {
t.Errorf("Missing file %s in copied project %s", file, projectName)
}
}
t.Logf("Successfully synced %s to test workspace", projectName)
})
}
t.Logf("Test workspace sync completed")
}
// TestPodmanWorkspaceValidation validates example projects structure
func TestPodmanWorkspaceValidation(t *testing.T) {
// Use temporary directory for validation
tempDir := t.TempDir()
podmanDir := filepath.Join(tempDir, "workspace")
examplesDir := filepath.Join("..", "fixtures", "examples")
// Copy examples to temp workspace for validation
if err := os.MkdirAll(podmanDir, 0750); err != nil {
t.Fatalf("Failed to create test workspace: %v", err)
}
// Copy examples to temp workspace
entries, err := os.ReadDir(examplesDir)
if err != nil {
t.Fatalf("Failed to read examples directory: %v", err)
}
for _, entry := range entries {
if !entry.IsDir() {
continue
}
srcDir := filepath.Join(examplesDir, entry.Name())
dstDir := filepath.Join(podmanDir, entry.Name())
if err := tests.CopyDir(srcDir, dstDir); err != nil {
t.Fatalf("Failed to copy %s: %v", entry.Name(), err)
}
}
// Expected projects
expectedProjects := []string{
"standard_ml_project",
"sklearn_project",
"pytorch_project",
"tensorflow_project",
"xgboost_project",
"statsmodels_project",
}
// Check each expected project
for _, project := range expectedProjects {
t.Run("Validate_"+project, func(t *testing.T) {
projectDir := filepath.Join(podmanDir, project)
// Check project directory exists
if _, err := os.Stat(projectDir); os.IsNotExist(err) {
t.Errorf("Expected project %s not found in test workspace", project)
return
}
// Check required files
requiredFiles := []string{"train.py", "requirements.txt", "README.md"}
for _, file := range requiredFiles {
filePath := filepath.Join(projectDir, file)
if _, err := os.Stat(filePath); os.IsNotExist(err) {
t.Errorf("Missing required file %s in project %s", file, project)
}
}
})
}
t.Logf("Test workspace validation completed")
}