use tempfile::tempdir;
use super::*;
use crate::registry::Backend;
use crate::registry::BackendSupport;
use crate::registry::Catalog;
use crate::registry::Support;
#[test]
fn a_dtype_the_registry_refuses_is_refused_before_anything_is_fetched() {
let dir = tempdir().unwrap();
let spec = dir.path().to_str().unwrap();
let descriptor = crate::registry::rerank::lookup("BAAI/bge-reranker-v2-m3").expect("registered");
match TextCrossEncoder::builder(spec)
.descriptor(descriptor)
.device(Device::Cpu)
.dtype(DType::F16)
.build()
{
Err(err @ CanddingError::UnsupportedOnDevice { .. }) => {
assert!(err.to_string().contains("accelerator-only"), "{err}");
let CanddingError::UnsupportedOnDevice {
model,
backend,
dtype,
} = err
else {
unreachable!()
};
assert_eq!(
(model.as_str(), backend, dtype),
(spec, Backend::Cpu, DType::F16)
);
}
Ok(_) => panic!("a CPU F16 request against a dtype the row refuses must be refused"),
Err(other) => panic!("unexpected error: {other}"),
}
}
#[test]
fn an_unregistered_id_is_refused_by_name() {
match TextCrossEncoder::builder("org/definitely-not-registered").build() {
Err(CanddingError::UnregisteredModel { id, catalog }) => {
assert_eq!(id, "org/definitely-not-registered");
assert_eq!(catalog, Catalog::Rerank);
}
Ok(_) => panic!("an unregistered id must be refused"),
Err(other) => panic!("unexpected error: {other}"),
}
}
#[test]
fn a_pair_entry_refuses_an_instruction_by_name() {
let model = stub_model(Box::new(PanicsIfCalled), 512, 8);
let empty: [&str; 0] = [];
let refusals = [
model
.rerank_with_instruction("a", &["a b"], "judge it", None)
.err(),
model.rerank_with_instruction("a", &empty, "", None).err(),
model
.pair_token_count_with_instruction("a", &["a b"], "judge it")
.err(),
];
for refused in refusals {
match refused {
Some(err @ CanddingError::InstructionOnPairInput { .. }) => {
let message = err.to_string();
assert!(message.contains("stub/rerank"), "{message}");
assert!(message.contains("instruction"), "{message}");
}
other => panic!("expected an instruction refusal, got {other:?}"),
}
}
assert_eq!(model.pair_token_count("a", &["a b"]).unwrap(), [6]);
}
#[test]
fn the_dtype_check_reads_the_device_s_own_cell() {
let (v, u) = (Support::Verified, Support::Unsupported);
for (f16, refused) in [
(
BackendSupport {
cpu: u,
metal: v,
cuda: v,
},
true,
),
(
BackendSupport {
cpu: v,
metal: u,
cuda: u,
},
false,
),
] {
let dir = tempfile::tempdir().unwrap();
let mut descriptor =
crate::registry::rerank::lookup("BAAI/bge-reranker-v2-m3").expect("registered");
descriptor.dtype_backends.f16 = f16;
let err = TextCrossEncoder::builder(dir.path().to_str().unwrap())
.descriptor(descriptor)
.device(Device::Cpu)
.dtype(DType::F16)
.build()
.err()
.expect("an empty directory loads nothing");
let on_the_cpu = matches!(
err,
CanddingError::UnsupportedOnDevice {
backend: Backend::Cpu,
dtype: DType::F16,
..
}
);
assert_eq!(on_the_cpu, refused, "{f16:?}: {err}");
assert!(
!matches!(err, CanddingError::UnsupportedDtype { .. }),
"{f16:?}: {err}"
);
}
}