Files
foxhunt/testing/integration/integration/ppo_integration.rs
jgrusewski 9c3d741a08 refactor: restructure repo — crates/, bin/, testing/ layout
Move 17 library crates into crates/, CLI binary into bin/fxt,
consolidate 10 test crates into testing/, split config crate
from deployment config files.

Root directory reduced from 38+ to ~17 directories.
All Cargo.toml paths and build.rs proto refs updated.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 11:56:00 +01:00

89 lines
2.5 KiB
Rust

//! PPO model integration test
//!
//! Verifies: create model -> forward pass -> valid output with padding
//! Uses lightweight config for fast execution (<10s)
use ml::ensemble::adapters::PpoInferenceAdapter;
use ml::ensemble::inference_adapter::{FeatureVector, ModelInferenceAdapter};
use ml::ppo::ppo::PPOConfig;
fn small_ppo_config() -> PPOConfig {
PPOConfig {
state_dim: 64,
num_actions: 45,
policy_hidden_dims: vec![32, 32],
value_hidden_dims: vec![32, 32],
..Default::default()
}
}
#[test]
fn test_ppo_adapter_produces_valid_prediction() {
let adapter =
PpoInferenceAdapter::new(small_ppo_config()).expect("PpoInferenceAdapter::new should succeed");
assert_eq!(adapter.model_name(), "PPO");
assert!(adapter.is_ready());
// 51-dim input gets zero-padded to state_dim=64
let fv = FeatureVector {
values: vec![0.1; 51],
timestamp: 1_700_000_000_000_000,
};
let pred = adapter.predict(&fv).expect("PPO predict should succeed");
assert!(
pred.direction >= -1.0 && pred.direction <= 1.0,
"direction {} out of [-1,1]",
pred.direction
);
assert!(
pred.confidence >= 0.0 && pred.confidence <= 1.0,
"confidence {} out of [0,1]",
pred.confidence
);
assert!(pred.direction.is_finite(), "direction must not be NaN/Inf");
assert!(
pred.confidence.is_finite(),
"confidence must not be NaN/Inf"
);
}
#[test]
fn test_ppo_deterministic_inference() {
let adapter =
PpoInferenceAdapter::new(small_ppo_config()).expect("PpoInferenceAdapter::new should succeed");
let fv = FeatureVector {
values: vec![0.3; 51],
timestamp: 1_700_000_000_000_000,
};
let pred1 = adapter.predict(&fv).expect("predict 1");
let pred2 = adapter.predict(&fv).expect("predict 2");
assert_eq!(
pred1.direction, pred2.direction,
"PPO inference should be deterministic"
);
}
#[test]
fn test_ppo_handles_short_input() {
let adapter =
PpoInferenceAdapter::new(small_ppo_config()).expect("PpoInferenceAdapter::new should succeed");
// 10-dim input (much shorter than state_dim=64) should still work via padding
let fv = FeatureVector {
values: vec![0.5; 10],
timestamp: 1_700_000_000_000_000,
};
let pred = adapter
.predict(&fv)
.expect("PPO should handle short input via padding");
assert!(pred.direction.is_finite());
assert!(pred.confidence.is_finite());
}