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

154 lines
4.4 KiB
Go

package tests
import (
"context"
"os"
"os/exec"
"path/filepath"
"testing"
"github.com/jfraeys/fetch_ml/internal/fileutil"
tests "github.com/jfraeys/fetch_ml/tests/fixtures"
)
// TestExampleProjects validates that all example projects have valid structure
func TestExampleProjects(t *testing.T) {
// Use fixtures for examples directory operations
examplesDir := tests.NewExamplesDir("../fixtures/examples")
projects := []string{
"standard_ml_project",
"sklearn_project",
"xgboost_project",
"pytorch_project",
"tensorflow_project",
"statsmodels_project",
}
for _, project := range projects {
t.Run(project, func(t *testing.T) {
projectDir := examplesDir.GetPath(project)
// Check project directory exists
t.Logf("Checking project directory: %s", projectDir)
if _, err := os.Stat(projectDir); os.IsNotExist(err) {
t.Fatalf("Example project %s does not exist", project)
}
// 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)
}
}
// Validate train.py is executable
trainPath := filepath.Join(projectDir, "train.py")
info, err := os.Stat(trainPath)
if err != nil {
t.Fatalf("Cannot stat train.py: %v", err)
}
if info.Mode().Perm()&0111 == 0 {
t.Errorf("train.py should be executable in project %s", project)
}
})
}
}
// Helper function to execute commands and return output
func executeCommand(name string, args ...string) (string, error) {
cmd := exec.CommandContext(context.Background(), name, args...)
output, err := cmd.CombinedOutput()
return string(output), err
}
// TestExampleExecution tests that examples can be executed (dry run)
func TestExampleExecution(t *testing.T) {
examplesDir := "../fixtures/examples"
projects := []string{
"standard_ml_project",
"sklearn_project",
}
for _, project := range projects {
t.Run(project, func(t *testing.T) {
projectDir := filepath.Join(examplesDir, project)
trainScript := filepath.Join(projectDir, "train.py")
// Test script syntax by checking if it can be parsed
output, err := executeCommand("python3", "-m", "py_compile", trainScript)
if err != nil {
t.Errorf("Failed to compile %s: %v", project, err)
}
// If compilation succeeds, the syntax is valid
if len(output) > 0 {
t.Logf("Compilation output for %s: %s", project, output)
}
})
}
}
// TestPodmanWorkspaceSync tests example projects structure using temporary directory
func TestPodmanWorkspaceSync(t *testing.T) {
// Use fixtures for examples directory operations
examplesDir := tests.NewExamplesDir("../fixtures/examples")
// Use temporary directory for test workspace
tempDir := t.TempDir()
podmanDir := filepath.Join(tempDir, "podman/workspace")
// Copy examples to temp workspace
if err := os.MkdirAll(podmanDir, 0750); err != nil {
t.Fatalf("Failed to create test workspace: %v", err)
}
// Get list of example projects using fixtures
entries, err := os.ReadDir("../fixtures/examples")
if err != nil {
t.Fatalf("Failed to read examples directory: %v", err)
}
for _, entry := range entries {
if !entry.IsDir() {
continue
}
projectName := entry.Name()
// Copy project to temp workspace using fixtures
dstDir := filepath.Join(podmanDir, projectName)
err := examplesDir.CopyProject(projectName, dstDir)
if err != nil {
t.Fatalf("Failed to copy %s to test workspace: %v", projectName, err)
}
t.Run(projectName, func(t *testing.T) {
// Compare key files
files := []string{"train.py", "requirements.txt"}
for _, file := range files {
exampleFile := filepath.Join(examplesDir.GetPath(projectName), file)
podmanFile := filepath.Join(podmanDir, projectName, file)
exampleContent, err1 := fileutil.SecureFileRead(exampleFile)
podmanContent, err2 := fileutil.SecureFileRead(podmanFile)
if err1 != nil {
t.Errorf("Cannot read %s from examples/: %v", file, err1)
continue
}
if err2 != nil {
t.Errorf("Cannot read %s from test workspace: %v", file, err2)
continue
}
if string(exampleContent) != string(podmanContent) {
t.Errorf("File %s differs between examples/ and test workspace for project %s", file, projectName)
}
}
})
}
}