Files
foxhunt/fxt/tests/e2e/test_fixtures.rs
jgrusewski 2da5bafc0e refactor: rename tli→fxt, delete legacy scripts/RunPod/deploy artifacts
- Rename tli/ directory to fxt/, update package + binary name to "fxt"
- Replace all `use tli::` → `use fxt::` across 52 Rust files
- Update build.rs proto paths (tli/proto → fxt/proto) in 6 services
- Update Dockerfiles, CI workflows, deploy.sh for new paths
- Delete ~170 legacy shell scripts (kept 15 essential ones)
- Delete RunPod Python client (runpod/), tests (tests/runpod/)
- Delete foxhunt-deploy crate (RunPod-only deployment tool)
- Delete terraform/runpod/ (moved to Scaleway)
- Delete ML Python hyperopt scripts (replaced by Rust Argmin PSO)
- Delete .gitlab-ci.yml (using GitHub + Gitea)
- Remove foxhunt-deploy from workspace members

504 files changed, -74,355 lines of legacy code removed.
Workspace compiles clean (0 errors, 0 warnings).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 10:32:21 +01:00

186 lines
5.2 KiB
Rust

//! Test Fixtures and Helpers for E2E Tests
//!
//! Provides reusable test data, helper functions, and utilities for E2E testing.
use std::collections::HashMap;
use fxt::proto::ml_training::{TrainingJobSummary, TrainingStatus};
/// Create a test training job with default values
pub fn create_test_job(
job_id: &str,
model_type: &str,
status: TrainingStatus,
) -> TrainingJobSummary {
create_test_job_with_times(
job_id,
model_type,
status,
chrono::Utc::now().timestamp(),
0,
0,
)
}
/// Create a test training job with specific timestamps
pub fn create_test_job_with_times(
job_id: &str,
model_type: &str,
status: TrainingStatus,
created_at: i64,
started_at: i64,
completed_at: i64,
) -> TrainingJobSummary {
TrainingJobSummary {
job_id: job_id.to_string(),
model_type: model_type.to_string(),
status: status as i32,
created_at,
started_at,
completed_at,
description: format!("Test {} job for {}", model_type, job_id),
final_loss: 0.123,
best_validation_score: 0.456,
tags: create_test_tags(),
}
}
/// Create standard test tags
pub fn create_test_tags() -> HashMap<String, String> {
let mut tags = HashMap::new();
tags.insert("env".to_string(), "test".to_string());
tags.insert("version".to_string(), "1.0".to_string());
tags
}
/// Create a batch of test jobs for testing list/filter operations
pub fn create_test_job_batch() -> Vec<TrainingJobSummary> {
let base_time = chrono::Utc::now().timestamp();
vec![
create_test_job_with_times(
"train_tft_es_20251022_140000",
"TFT",
TrainingStatus::Running,
base_time,
base_time + 60,
0,
),
create_test_job_with_times(
"train_dqn_nq_20251022_133000",
"DQN",
TrainingStatus::Completed,
base_time - 3600,
base_time - 3540,
base_time - 3336,
),
create_test_job_with_times(
"train_ppo_es_20251022_130000",
"PPO",
TrainingStatus::Completed,
base_time - 7200,
base_time - 7140,
base_time - 7133,
),
create_test_job_with_times(
"train_mamba2_6e_20251022_120000",
"MAMBA_2",
TrainingStatus::Failed,
base_time - 14400,
base_time - 14340,
base_time - 14200,
),
create_test_job_with_times(
"train_tft_zn_20251022_110000",
"TFT",
TrainingStatus::Stopped,
base_time - 18000,
base_time - 17940,
base_time - 17800,
),
]
}
/// Helper function to extract job IDs from job list
pub fn extract_job_ids(jobs: &[TrainingJobSummary]) -> Vec<String> {
jobs.iter().map(|j| j.job_id.clone()).collect()
}
/// Helper function to filter jobs by status
pub fn filter_by_status(jobs: &[TrainingJobSummary], status: TrainingStatus) -> Vec<TrainingJobSummary> {
jobs.iter()
.filter(|j| j.status == status as i32)
.cloned()
.collect()
}
/// Helper function to filter jobs by model type
pub fn filter_by_model(jobs: &[TrainingJobSummary], model_type: &str) -> Vec<TrainingJobSummary> {
jobs.iter()
.filter(|j| j.model_type == model_type)
.cloned()
.collect()
}
/// Validate job structure
pub fn validate_job_structure(job: &TrainingJobSummary) -> bool {
!job.job_id.is_empty()
&& !job.model_type.is_empty()
&& job.status >= 0
&& job.created_at > 0
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_create_test_job() {
let job = create_test_job("test_1", "TFT", TrainingStatus::Pending);
assert_eq!(job.job_id, "test_1");
assert_eq!(job.model_type, "TFT");
assert_eq!(job.status, TrainingStatus::Pending as i32);
}
#[test]
fn test_create_test_job_batch() {
let jobs = create_test_job_batch();
assert_eq!(jobs.len(), 5);
assert_eq!(jobs[0].model_type, "TFT");
assert_eq!(jobs[1].model_type, "DQN");
assert_eq!(jobs[2].model_type, "PPO");
}
#[test]
fn test_filter_by_status() {
let jobs = create_test_job_batch();
let completed = filter_by_status(&jobs, TrainingStatus::Completed);
assert_eq!(completed.len(), 2);
}
#[test]
fn test_filter_by_model() {
let jobs = create_test_job_batch();
let tft_jobs = filter_by_model(&jobs, "TFT");
assert_eq!(tft_jobs.len(), 2);
}
#[test]
fn test_validate_job_structure() {
let job = create_test_job("test_1", "TFT", TrainingStatus::Pending);
assert!(validate_job_structure(&job));
let invalid_job = TrainingJobSummary {
job_id: "".to_string(),
..job
};
assert!(!validate_job_structure(&invalid_job));
}
#[test]
fn test_extract_job_ids() {
let jobs = create_test_job_batch();
let ids = extract_job_ids(&jobs);
assert_eq!(ids.len(), 5);
assert!(ids.contains(&"train_tft_es_20251022_140000".to_string()));
}
}