use super::*;
#[test]
fn geometry_is_the_converted_contract() {
assert_eq!(SAMPLE_RATE_HZ, 16_000);
assert_eq!(WINDOW_SAMPLES, 6 * SAMPLE_RATE_HZ as usize);
assert_eq!(N_MELS, 72);
assert_eq!(N_FRAMES, 401);
assert_eq!(EMBEDDING_DIM, 192);
}
#[cfg(feature = "speaker")]
#[test]
fn identity_and_diarization_embedding_dims_are_different_numbers() {
assert_ne!(EMBEDDING_DIM, crate::audio::speaker::embed::EMBEDDING_DIM);
assert_eq!(
EMBEDDING_DIM,
crate::audio::speaker::calibrate::Scoring::IdentityCosine.row_len(),
"the identity score source must take exactly this door's raw row"
);
}
#[test]
fn feature_names_are_the_converted_ones() {
assert_eq!(names::MEL, "mel");
assert_eq!(names::EMBEDDING, "embedding");
}
#[test]
fn default_compute_is_the_measured_cpu_and_gpu() {
assert_eq!(DEFAULT_COMPUTE, ComputeUnits::CpuAndGpu);
assert_ne!(DEFAULT_COMPUTE, ComputeUnits::All);
}
#[test]
fn options_default_equals_new() {
assert_eq!(EmbedderOptions::default(), EmbedderOptions::new());
assert_eq!(EmbedderOptions::new().compute(), DEFAULT_COMPUTE);
}
#[test]
fn options_with_and_set_compute() {
let opts = EmbedderOptions::new().with_compute(ComputeUnits::CpuAndNeuralEngine);
assert_eq!(opts.compute(), ComputeUnits::CpuAndNeuralEngine);
let mut opts = EmbedderOptions::new();
opts.set_compute(ComputeUnits::CpuOnly);
assert_eq!(opts.compute(), ComputeUnits::CpuOnly);
}
#[cfg(feature = "serde")]
#[test]
fn options_serde_roundtrip_and_pinned_spelling() {
let opts = EmbedderOptions::new().with_compute(ComputeUnits::All);
let json = serde_json::to_string(&opts).unwrap();
assert_eq!(json, "{\"compute\":\"all\"}");
let back: EmbedderOptions = serde_json::from_str(&json).unwrap();
assert_eq!(back, opts);
}
#[cfg(feature = "serde")]
#[test]
fn options_missing_compute_defaults_to_the_measured_placement() {
let opts: EmbedderOptions = serde_json::from_str("{}").unwrap();
assert_eq!(opts.compute(), DEFAULT_COMPUTE);
}
#[cfg(feature = "serde")]
#[test]
fn options_unknown_compute_spelling_is_rejected() {
assert!(serde_json::from_str::<EmbedderOptions>("{\"compute\":\"gpu\"}").is_err());
}
use crate::{AxisRange, FeatureInfo, ModelDescription, model::RawShapeConstraint};
fn fixed(name: &str, shape: &[usize], dtype: DataType) -> FeatureInfo {
multi_array(name, shape, dtype, false, 2, vec![shape.to_vec()], shape)
}
fn multi_array(
name: &str,
shape: &[usize],
dtype: DataType,
optional: bool,
raw_type: isize,
enumerated: Vec<Vec<usize>>,
pinned: &[usize],
) -> FeatureInfo {
FeatureInfo::from_parts(
name.to_string(),
shape.to_vec(),
Some(dtype),
optional,
Some(RawShapeConstraint::new(
raw_type,
enumerated,
pinned.iter().map(|d| AxisRange::new(*d, 1)).collect(),
)),
)
}
fn redimnet_description() -> ModelDescription {
ModelDescription::from_parts(
vec![fixed(names::MEL, &[1, N_MELS, N_FRAMES], DataType::F32)],
vec![fixed(names::EMBEDDING, &[1, EMBEDDING_DIM], DataType::F32)],
Vec::new(),
)
}
fn check(description: &ModelDescription) -> Result<()> {
crate::model::contract::check_load_contract(description, &identity_contract())
.map_err(contract_violation)
}
#[test]
fn the_contract_accepts_the_converted_geometry() {
assert!(check(&redimnet_description()).is_ok());
}
#[test]
fn the_contract_refuses_a_differently_spelled_feature() {
let description = ModelDescription::from_parts(
vec![fixed("audio", &[1, N_MELS, N_FRAMES], DataType::F32)],
vec![fixed(names::EMBEDDING, &[1, EMBEDDING_DIM], DataType::F32)],
Vec::new(),
);
let err = check(&description).unwrap_err();
assert!(
matches!(&err, Error::ContractMismatch(m)
if m.feature() == names::MEL && m.actual() == "missing"),
"{err}"
);
}
#[test]
fn the_contract_refuses_a_flexible_mel_declaring_its_exact_numbers() {
let description = ModelDescription::from_parts(
vec![multi_array(
names::MEL,
&[1, N_MELS, N_FRAMES],
DataType::F32,
false,
3,
Vec::new(),
&[1, N_MELS, N_FRAMES],
)],
vec![fixed(names::EMBEDDING, &[1, EMBEDDING_DIM], DataType::F32)],
Vec::new(),
);
let err = check(&description).unwrap_err();
assert!(
matches!(&err, Error::ContractMismatch(m) if m.feature() == names::MEL),
"{err}"
);
assert!(err.to_string().contains("range"), "{err}");
}
#[test]
fn the_contract_refuses_a_right_shaped_fp16_graph() {
let description = ModelDescription::from_parts(
vec![fixed(names::MEL, &[1, N_MELS, N_FRAMES], DataType::F16)],
vec![fixed(names::EMBEDDING, &[1, EMBEDDING_DIM], DataType::F32)],
Vec::new(),
);
let err = check(&description).unwrap_err();
assert!(
matches!(&err, Error::ContractMismatch(m) if m.feature() == names::MEL),
"{err}"
);
assert!(err.to_string().contains("float16"), "{err}");
}
#[test]
fn the_contract_refuses_a_transposed_shape_of_the_same_size() {
let description = ModelDescription::from_parts(
vec![fixed(names::MEL, &[1, N_FRAMES, N_MELS], DataType::F32)],
vec![fixed(names::EMBEDDING, &[1, EMBEDDING_DIM], DataType::F32)],
Vec::new(),
);
assert!(matches!(
check(&description),
Err(Error::ContractMismatch(_))
));
}
#[test]
fn the_contract_refuses_the_diarization_embedding_width() {
let description = ModelDescription::from_parts(
vec![fixed(names::MEL, &[1, N_MELS, N_FRAMES], DataType::F32)],
vec![fixed(names::EMBEDDING, &[1, 256], DataType::F32)],
Vec::new(),
);
let err = check(&description).unwrap_err();
assert!(
matches!(&err, Error::ContractMismatch(m) if m.feature() == names::EMBEDDING),
"{err}"
);
}
#[test]
fn the_contract_refuses_an_extra_required_input() {
let description = ModelDescription::from_parts(
vec![
fixed(names::MEL, &[1, N_MELS, N_FRAMES], DataType::F32),
fixed("speaker_mask", &[1, N_FRAMES], DataType::F32),
],
vec![fixed(names::EMBEDDING, &[1, EMBEDDING_DIM], DataType::F32)],
Vec::new(),
);
assert!(
matches!(check(&description), Err(Error::UnsatisfiableInput(name)) if name == "speaker_mask")
);
}
#[test]
fn the_contract_accepts_an_extra_optional_input() {
let description = ModelDescription::from_parts(
vec![
fixed(names::MEL, &[1, N_MELS, N_FRAMES], DataType::F32),
multi_array(
"mask",
&[1, N_FRAMES],
DataType::F32,
true,
2,
vec![vec![1, N_FRAMES]],
&[1, N_FRAMES],
),
],
vec![fixed(names::EMBEDDING, &[1, EMBEDDING_DIM], DataType::F32)],
Vec::new(),
);
assert!(check(&description).is_ok());
}
#[test]
fn the_contract_refuses_a_graph_that_declares_state() {
let description = ModelDescription::from_parts(
vec![fixed(names::MEL, &[1, N_MELS, N_FRAMES], DataType::F32)],
vec![fixed(names::EMBEDDING, &[1, EMBEDDING_DIM], DataType::F32)],
vec![fixed("kv_cache", &[1, 8], DataType::F32)],
);
assert!(
matches!(check(&description), Err(Error::UnsatisfiableState(name)) if name == "kv_cache")
);
}
#[test]
fn the_identity_contract_refuses_the_vendored_silero_bundle() {
let bundle = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
.join("../Models/vadkit/silero-vad-unified-256ms-v6.2.1.mlmodelc");
assert!(
bundle.is_dir(),
"the vendored silero bundle is committed, so this gate is NOT model-gated; \
looked for {}",
bundle.display()
);
let model = Model::load(&bundle, ComputeUnits::CpuOnly).expect("the committed bundle loads");
assert!(
!model.description().inputs().is_empty(),
"silero declares inputs"
);
assert!(
model.description().input(names::MEL).is_none(),
"silero declares no `mel`, which is what makes it this gate's model"
);
let description = model.description();
for feature in description.inputs().iter().chain(description.outputs()) {
assert_eq!(
feature.shape_constraint(),
Some(crate::ShapeConstraint::Fixed),
"{}: `hasShapeFlexibility: \"0\"` must still reach the snapshot as `Fixed`",
feature.name()
);
}
let violation = Checked::new(model, &identity_contract())
.expect_err("silero does not satisfy the identity contract");
assert!(
matches!(&violation, ContractViolation::Missing(m) if m.feature() == names::MEL),
"expected `mel` missing, got {violation}"
);
}
#[test]
fn validate_window_input_requires_an_exact_window() {
assert!(validate_window_input(&vec![0.0f32; WINDOW_SAMPLES]).is_ok());
for len in [0usize, 1, WINDOW_SAMPLES - 1, WINDOW_SAMPLES + 1] {
let err = validate_window_input(&vec![0.0f32; len]).unwrap_err();
assert!(
matches!(err, Error::WindowLength(w) if w.got() == len && w.expected() == WINDOW_SAMPLES),
"len {len}: got {err:?}"
);
}
}
#[test]
fn validate_window_input_reports_the_first_non_finite_sample() {
let mut samples = vec![0.0f32; WINDOW_SAMPLES];
samples[4_100] = f32::INFINITY;
samples[41] = f32::NAN;
assert!(matches!(
validate_window_input(&samples),
Err(Error::NonFiniteInput(41))
));
}
#[test]
fn validate_window_input_checks_length_before_finiteness() {
let short = vec![f32::NAN; 16];
assert!(matches!(
validate_window_input(&short),
Err(Error::WindowLength(_))
));
}
#[test]
fn finite_embedding_check_reports_the_index() {
let mut row = [0.0f32; EMBEDDING_DIM];
assert!(check_finite_embedding(&row).is_ok());
row[7] = f32::NEG_INFINITY;
assert!(matches!(
check_finite_embedding(&row),
Err(Error::NonFiniteOutput(7))
));
}