use std::path::{Path, PathBuf};
use std::time::Duration;
use tokio::process::Command;
const SERVER_BIN: &str = "vllm-mlx";
const MIN_VERSION: (u64, u64, u64) = (0, 6, 0);
const PIP_SPEC: &str = "vllm-mlx>=0.6.0";
#[derive(Debug, thiserror::Error)]
pub enum RuntimeError {
#[error(
"`uv` is required to provision the vllm-mlx runtime but was not found on PATH; {remedy}"
)]
UvMissing { remedy: String },
#[error("provisioning step `{step}` failed: {detail}")]
Provision { step: &'static str, detail: String },
#[error("vllm-mlx still not found after provisioning into {0}")]
NotFoundAfterInstall(PathBuf),
#[error("{0}")]
NeverInstall(String),
}
const INSTALL_COMMAND: &str = "uv tool install vllm-mlx";
const UPGRADE_COMMAND: &str = "uv tool install --upgrade vllm-mlx";
const UV_DOCS: &str = "https://docs.astral.sh/uv/";
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) enum Lookup {
Ready(PathBuf),
Outdated((u64, u64, u64), PathBuf),
Missing,
}
impl Lookup {
fn absence(&self) -> Option<String> {
match self {
Lookup::Ready(_) => None,
Lookup::Missing => Some(format!(
"the vllm-mlx runtime is not installed, and this request never installs one. \
Install it with `{INSTALL_COMMAND}`"
)),
Lookup::Outdated(version, binary) => Some(format!(
"{}, and this request never upgrades it. {}",
outdated_at(*version, binary),
match upgrade_command(binary) {
Some(command) => format!("Upgrade it with `{command}`"),
None => format!("Upgrade it with the tool that installed it, {OR_OVERRIDE}"),
}
)),
}
}
}
const OR_OVERRIDE: &str = "or set `CAR_VLLM_MLX_BIN` to the path of a newer vllm-mlx binary";
fn outdated_at((major, minor, patch): (u64, u64, u64), binary: &Path) -> String {
let (min_major, min_minor, min_patch) = MIN_VERSION;
format!(
"the installed vllm-mlx runtime at `{}` is {major}.{minor}.{patch}, older than the \
{min_major}.{min_minor}.{min_patch} CAR needs",
binary.display()
)
}
fn upgrade_command(binary: &Path) -> Option<String> {
let real = |p: &Path| car_winenv::canonicalize(p).unwrap_or_else(|_| p.to_path_buf());
let resolved = real(binary);
let under = |root: &Path| binary.starts_with(root) || resolved.starts_with(real(root));
let installed_by_uv = |root: &Path| {
[
(binary, root.to_path_buf()),
(resolved.as_path(), real(root)),
]
.into_iter()
.any(|(path, root)| {
path.strip_prefix(&root)
.ok()
.and_then(|rest| rest.components().next())
.is_some_and(|tool| root.join(tool).join("uv-receipt.toml").is_file())
})
};
if uv_tool_roots().iter().any(|root| installed_by_uv(root)) {
return Some(UPGRADE_COMMAND.into());
}
let root = managed_root()?;
under(&root).then(|| {
format!(
"uv pip install --python \"{}\" \"{PIP_SPEC}\"",
crate::managed_venv::interpreter(&root).display()
)
})
}
pub(crate) const RECHECK_AFTER: Duration = Duration::from_secs(30);
static REMEMBERED: std::sync::Mutex<Option<(Lookup, std::time::Instant)>> =
std::sync::Mutex::new(None);
fn still_stands(remembered: Option<&(Lookup, std::time::Instant)>) -> Option<Lookup> {
let (lookup, at) = remembered?;
if at.elapsed() >= RECHECK_AFTER {
return None;
}
match lookup {
Lookup::Ready(server) if !server.is_file() || interpreter_gone(server) => None,
known => Some(known.clone()),
}
}
fn interpreter_gone(binary: &Path) -> bool {
use std::io::BufRead;
let Ok(file) = std::fs::File::open(binary) else {
return true;
};
let mut first = Vec::new();
if std::io::BufReader::new(file)
.read_until(b'\n', &mut first)
.is_err()
{
return true;
}
let Some(shebang) = first.strip_prefix(b"#!") else {
return false;
};
String::from_utf8_lossy(shebang)
.split_whitespace()
.next()
.is_some_and(|interpreter| !Path::new(interpreter).exists())
}
pub(crate) async fn status() -> Lookup {
#[cfg(test)]
if let Some(scope) = test_runtime::current() {
return scope.status();
}
if let Some(known) = still_stands(
REMEMBERED
.lock()
.unwrap_or_else(|p| p.into_inner())
.as_ref(),
) {
return known;
}
let found = tokio::task::spawn_blocking(lookup)
.await
.unwrap_or(Lookup::Missing);
*REMEMBERED.lock().unwrap_or_else(|p| p.into_inner()) =
Some((found.clone(), std::time::Instant::now()));
found
}
pub(crate) fn not_ready_error(
schema: &crate::schema::ModelSchema,
lookup: &Lookup,
) -> crate::InferenceError {
let why = lookup
.absence()
.unwrap_or_else(|| "the vllm-mlx runtime is not ready".into());
crate::InferenceError::NoEligibleModel {
excluded_models: format!(
"{name} runs on the vllm-mlx runtime: {why}, or connect a provider's API key so a \
model that is ready can be used",
name = schema.name
),
}
}
#[cfg(test)]
pub(crate) mod test_runtime {
use super::Lookup;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::{Arc, Mutex};
tokio::task_local! {
static SCOPE: Arc<State>;
}
pub(super) fn current() -> Option<Arc<State>> {
SCOPE.try_with(Arc::clone).ok()
}
pub(crate) struct State {
found: Mutex<Lookup>,
remembered: Mutex<Option<(Lookup, std::time::Instant)>>,
lookups: AtomicUsize,
provisions: AtomicUsize,
}
impl State {
pub(crate) fn new(found: Lookup) -> Arc<Self> {
Arc::new(Self {
found: Mutex::new(found),
remembered: Mutex::new(None),
lookups: AtomicUsize::new(0),
provisions: AtomicUsize::new(0),
})
}
pub(crate) async fn run<F: std::future::Future>(self: &Arc<Self>, future: F) -> F::Output {
SCOPE.scope(self.clone(), future).await
}
pub(crate) fn set(&self, found: Lookup) {
*self.found.lock().unwrap() = found;
}
pub(crate) fn lookups(&self) -> usize {
self.lookups.load(Ordering::SeqCst)
}
pub(crate) fn provisions(&self) -> usize {
self.provisions.load(Ordering::SeqCst)
}
pub(crate) fn age_remembered(&self) {
if let Some((_, at)) = self.remembered.lock().unwrap().as_mut() {
*at -= super::RECHECK_AFTER;
}
}
pub(super) fn look(&self) -> Lookup {
self.lookups.fetch_add(1, Ordering::SeqCst);
self.found.lock().unwrap().clone()
}
pub(super) fn status(&self) -> Lookup {
let mut remembered = self.remembered.lock().unwrap();
if let Some(known) = super::still_stands(remembered.as_ref()) {
return known;
}
let found = self.look();
*remembered = Some((found.clone(), std::time::Instant::now()));
found
}
pub(super) fn count_provision(&self) {
self.provisions.fetch_add(1, Ordering::SeqCst);
}
}
}
#[derive(Debug, Clone)]
pub struct VllmRuntime {
pub server: PathBuf,
}
fn managed_root() -> Option<PathBuf> {
std::env::var_os("HOME").map(|h| PathBuf::from(h).join(".car").join("visual-runtime"))
}
fn managed_server_bin() -> Option<PathBuf> {
managed_root().map(|r| crate::managed_venv::venv_program(&r, SERVER_BIN))
}
fn env_dir(name: &str) -> Option<PathBuf> {
std::env::var_os(name)
.map(PathBuf::from)
.filter(|p| p.is_absolute())
}
fn uv_tool_bin_dirs() -> Vec<PathBuf> {
let mut dirs: Vec<PathBuf> = [
env_dir("UV_TOOL_BIN_DIR"),
env_dir("XDG_BIN_HOME"),
env_dir("XDG_DATA_HOME").map(|d| d.join("..").join("bin")),
]
.into_iter()
.flatten()
.collect();
if let Some(home) = std::env::var_os("HOME").map(PathBuf::from) {
dirs.push(home.join(".local").join("bin"));
}
dirs
}
fn uv_tool_roots() -> Vec<PathBuf> {
let mut roots: Vec<PathBuf> = [
env_dir("UV_TOOL_DIR"),
env_dir("XDG_DATA_HOME").map(|d| d.join("uv").join("tools")),
]
.into_iter()
.flatten()
.collect();
if let Some(home) = std::env::var_os("HOME").map(PathBuf::from) {
roots.push(home.join(".local").join("share").join("uv").join("tools"));
}
roots
}
fn search_dirs() -> Vec<PathBuf> {
let mut dirs: Vec<PathBuf> = std::env::var_os("PATH")
.map(|paths| std::env::split_paths(&paths).collect())
.unwrap_or_default();
dirs.extend(uv_tool_bin_dirs());
dirs.extend(
uv_tool_roots()
.into_iter()
.map(|root| crate::managed_venv::venv_bin_dir(&root.join(SERVER_BIN))),
);
if let Some(home) = std::env::var_os("HOME").map(PathBuf::from) {
dirs.push(crate::managed_venv::venv_bin_dir(
&home.join(".car").join("visual-runtime"),
));
}
dedupe(dirs)
}
fn dedupe(paths: Vec<PathBuf>) -> Vec<PathBuf> {
let mut out = Vec::new();
for p in paths {
if !out.contains(&p) {
out.push(p);
}
}
out
}
pub fn resolve_existing() -> Option<PathBuf> {
match lookup() {
Lookup::Ready(server) => Some(server),
Lookup::Outdated(..) | Lookup::Missing => None,
}
}
fn lookup() -> Lookup {
if let Some(p) = std::env::var_os("CAR_VLLM_MLX_BIN").map(PathBuf::from) {
if p.is_file() {
return absolutize(&p).map_or(Lookup::Missing, Lookup::Ready);
}
}
let mut candidates: Vec<(PathBuf, Option<(u64, u64, u64)>)> = Vec::new();
let mut seen: Vec<PathBuf> = Vec::new();
for dir in search_dirs() {
let candidate = dir.join(SERVER_BIN);
if !candidate.is_file() {
continue;
}
let canon = car_winenv::canonicalize(&candidate).unwrap_or_else(|_| candidate.clone());
if seen.contains(&canon) {
continue;
}
seen.push(canon);
let version = binary_version(&candidate);
candidates.push((candidate, version));
}
let newest = candidates
.iter()
.filter_map(|(path, version)| version.map(|v| (v, path.clone())))
.max_by(|(a, _), (b, _)| a.cmp(b));
match best_candidate(candidates).and_then(|path| absolutize(&path)) {
Some(server) => Lookup::Ready(server),
None => newest.map_or(Lookup::Missing, |(version, path)| {
Lookup::Outdated(version, path)
}),
}
}
fn best_candidate(candidates: Vec<(PathBuf, Option<(u64, u64, u64)>)>) -> Option<PathBuf> {
candidates
.into_iter()
.filter_map(|(path, version)| version.map(|v| (v, path)))
.filter(|(version, _)| *version >= MIN_VERSION)
.max_by(|(a, _), (b, _)| a.cmp(b))
.map(|(_, path)| path)
}
fn binary_version(binary: &Path) -> Option<(u64, u64, u64)> {
let head = std::fs::read_to_string(binary).ok()?;
let interp = head.lines().next()?.strip_prefix("#!")?.trim();
let out = std::process::Command::new(interp)
.args([
"-c",
"import importlib.metadata as m; print(m.version('vllm-mlx'))",
])
.output()
.ok()?;
if !out.status.success() {
return None;
}
parse_semver(String::from_utf8_lossy(&out.stdout).trim())
}
fn parse_semver(s: &str) -> Option<(u64, u64, u64)> {
let lead = |part: &str| -> u64 {
part.chars()
.take_while(|c| c.is_ascii_digit())
.collect::<String>()
.parse()
.unwrap_or(0)
};
let mut it = s.split('.');
let major = it.next()?.trim().parse().ok()?;
Some((
major,
lead(it.next().unwrap_or("0")),
lead(it.next().unwrap_or("0")),
))
}
fn absolutize(p: &Path) -> Option<PathBuf> {
car_winenv::canonicalize(p)
.ok()
.or_else(|| Some(p.to_path_buf()))
}
pub async fn ensure_runtime() -> Result<VllmRuntime, RuntimeError> {
#[cfg(test)]
let found = match test_runtime::current() {
Some(scope) => scope.look(),
None => lookup(),
};
#[cfg(not(test))]
let found = lookup();
if let Lookup::Ready(server) = found {
return Ok(VllmRuntime { server });
}
provision(&found).await?;
let server = managed_server_bin()
.filter(|p| p.is_file())
.or_else(resolve_existing)
.ok_or_else(|| RuntimeError::NotFoundAfterInstall(managed_root().unwrap_or_default()))?;
Ok(VllmRuntime { server })
}
async fn provision(found: &Lookup) -> Result<(), RuntimeError> {
#[cfg(test)]
let scope = test_runtime::current();
#[cfg(test)]
if let Some(scope) = &scope {
scope.count_provision();
}
if crate::registry::never_download_in_scope() {
return Err(RuntimeError::NeverInstall(found.absence().unwrap_or_else(
|| "this request never installs the vllm-mlx runtime".into(),
)));
}
#[cfg(test)]
if scope.is_some() {
return Err(RuntimeError::Provision {
step: "test",
detail: "this test installs no runtime".into(),
});
}
if cfg!(test) {
return Err(RuntimeError::Provision {
step: "test",
detail: "tests never install the runtime".into(),
});
}
if which("uv").is_none() {
return Err(uv_missing(found));
}
let root = managed_root().ok_or_else(|| RuntimeError::Provision {
step: "resolve-home",
detail: "HOME is not set".into(),
})?;
let outcome = crate::managed_venv::ensure_venv(&root, "python3")
.await
.map_err(|e| RuntimeError::Provision {
step: "venv",
detail: e.to_string(),
})?;
if outcome == crate::managed_venv::VenvOutcome::Recreated {
tracing::warn!(
root = %root.display(),
"managed Python runtime had an unusable interpreter; rebuilt it \
(installed packages were discarded and are being reinstalled)"
);
}
let venv_python = crate::managed_venv::interpreter(&root);
run_uv(
"pip-install",
&[
"pip".into(),
"install".into(),
"--python".into(),
venv_python.display().to_string(),
PIP_SPEC.into(),
],
)
.await?;
Ok(())
}
fn uv_missing(found: &Lookup) -> RuntimeError {
let remedy = match found {
Lookup::Outdated(version, binary) => {
let at = outdated_at(*version, binary);
match upgrade_command(binary) {
Some(command) => {
format!("{at}; install uv ({UV_DOCS}) and run `{command}`, {OR_OVERRIDE}")
}
None => format!("{at}; upgrade it with the tool that installed it, {OR_OVERRIDE}"),
}
}
Lookup::Ready(_) | Lookup::Missing => format!(
"install uv ({UV_DOCS}) and run `{INSTALL_COMMAND}`, or set `CAR_VLLM_MLX_BIN` to \
the path of a vllm-mlx binary"
),
};
RuntimeError::UvMissing { remedy }
}
async fn run_uv(step: &'static str, args: &[String]) -> Result<(), RuntimeError> {
let output = Command::new("uv")
.args(args)
.kill_on_drop(true)
.output()
.await
.map_err(|e| RuntimeError::Provision {
step,
detail: e.to_string(),
})?;
if output.status.success() {
Ok(())
} else {
Err(RuntimeError::Provision {
step,
detail: format!(
"uv exited with {}: {}",
output.status,
String::from_utf8_lossy(&output.stderr).trim()
),
})
}
}
fn hf_download_command(hf: &Path, repo: &str, disable_xet: bool) -> Command {
let mut cmd = Command::new(hf);
crate::hf_cache::apply_with_token(&mut cmd);
cmd.arg("download").arg(repo).kill_on_drop(true);
if disable_xet {
cmd.env("HF_HUB_DISABLE_XET", "1");
}
cmd
}
pub async fn download_repo(repo: &str) -> Result<(), RuntimeError> {
ensure_runtime().await?;
let hf = managed_root()
.map(|r| crate::managed_venv::venv_program(&r, "hf"))
.filter(|p| p.is_file())
.ok_or_else(|| RuntimeError::Provision {
step: "resolve-hf-cli",
detail: "the managed runtime has no `hf` CLI".into(),
})?;
for disable_xet in [false, true] {
let output = hf_download_command(&hf, repo, disable_xet)
.output()
.await
.map_err(|e| RuntimeError::Provision {
step: "hf-download",
detail: e.to_string(),
})?;
if output.status.success() {
return Ok(());
}
if disable_xet {
return Err(RuntimeError::Provision {
step: "hf-download",
detail: format!(
"hf download {repo} failed: {}",
String::from_utf8_lossy(&output.stderr).trim()
),
});
}
tracing::warn!(repo, "hf download failed; retrying with Xet disabled");
}
unreachable!("the loop returns on both iterations")
}
pub fn serviceable() -> bool {
resolve_existing().is_some() || which("uv").is_some()
}
pub fn runtime_ready() -> bool {
matches!(lookup(), Lookup::Ready(_))
}
pub fn runtime_unready_reason() -> Option<String> {
lookup().absence()
}
pub(crate) fn which(name: &str) -> Option<PathBuf> {
std::env::var_os("PATH")?
.to_str()?
.split(':')
.map(|d| Path::new(d).join(name))
.find(|p| p.is_file())
}
#[cfg(all(test, unix))]
pub(crate) fn test_python_interpreter() -> Option<PathBuf> {
let launcher = which("python3")?;
let output = std::process::Command::new(launcher)
.args(["-c", "import sys; print(sys.executable)"])
.output()
.ok()?;
if !output.status.success() {
return None;
}
let resolved = PathBuf::from(String::from_utf8(output.stdout).ok()?.trim());
let healthy = std::process::Command::new(&resolved)
.args(["-c", ""])
.status()
.is_ok_and(|status| status.success());
healthy.then_some(resolved)
}
pub async fn health_ok(endpoint: &str, timeout: Duration) -> bool {
use tokio::io::{AsyncReadExt, AsyncWriteExt};
let Ok(url) = reqwest::Url::parse(endpoint) else {
return false;
};
if url.scheme() != "http" {
return false;
}
let Some(host) = url.host_str() else {
return false;
};
let Some(port) = url.port_or_known_default() else {
return false;
};
let probe = async {
let mut stream = tokio::net::TcpStream::connect((host, port)).await.ok()?;
let request =
format!("GET /health HTTP/1.1\r\nHost: {host}:{port}\r\nConnection: close\r\n\r\n");
stream.write_all(request.as_bytes()).await.ok()?;
let mut response = Vec::with_capacity(128);
while !response.windows(2).any(|window| window == b"\r\n") {
if response.len() >= 1024 {
return None;
}
let mut chunk = [0u8; 128];
let count = stream.read(&mut chunk).await.ok()?;
if count == 0 {
return None;
}
response.extend_from_slice(&chunk[..count]);
}
let status = std::str::from_utf8(&response)
.ok()?
.lines()
.next()?
.split_whitespace()
.nth(1)?
.parse::<u16>()
.ok()?;
Some((200..300).contains(&status))
};
matches!(tokio::time::timeout(timeout, probe).await, Ok(Some(true)))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn managed_paths_are_under_dot_car() {
if std::env::var_os("HOME").is_none() {
return; }
let root = managed_root().unwrap();
assert!(
root.ends_with(".car/visual-runtime"),
"root: {}",
root.display()
);
let bin = managed_server_bin().unwrap();
assert_eq!(bin, crate::managed_venv::venv_program(&root, SERVER_BIN));
assert!(bin.starts_with(&root), "bin: {}", bin.display());
}
#[test]
fn search_dirs_include_path_and_managed() {
let dirs = search_dirs();
if let Some(root) = managed_root() {
assert!(
dirs.iter()
.any(|d| d == &crate::managed_venv::venv_bin_dir(&root)),
"managed bin dir missing from search set"
);
}
}
#[test]
fn parse_semver_handles_plain_and_prerelease() {
assert_eq!(parse_semver("0.3.0"), Some((0, 3, 0)));
assert_eq!(parse_semver("1.2.10"), Some((1, 2, 10)));
assert_eq!(parse_semver("0.6.3rc1"), Some((0, 6, 3)));
assert_eq!(parse_semver("0.2"), Some((0, 2, 0)));
assert!(parse_semver("not-a-version").is_none());
assert!((0, 2, 9) < MIN_VERSION);
assert!((0, 4, 1) < MIN_VERSION);
assert!((0, 6, 0) >= MIN_VERSION);
assert!((0, 6, 3) >= MIN_VERSION);
}
pub(super) struct RestoredEnvironment(Vec<(&'static str, Option<std::ffi::OsString>)>);
impl RestoredEnvironment {
pub(super) fn capture(names: &[&'static str]) -> Self {
Self(
names
.iter()
.map(|name| (*name, std::env::var_os(name)))
.collect(),
)
}
}
impl Drop for RestoredEnvironment {
fn drop(&mut self) {
for (name, value) in &self.0 {
match value {
Some(value) => std::env::set_var(name, value),
None => std::env::remove_var(name),
}
}
}
}
#[test]
fn env_override_resolves_when_file_exists() {
let _environment = crate::openrouter::test_environment_scope();
let _restore = RestoredEnvironment::capture(&["CAR_VLLM_MLX_BIN"]);
let tmp = tempfile::TempDir::new().unwrap();
let binary = tmp.path().join(SERVER_BIN);
std::fs::write(&binary, b"fixture").unwrap();
std::env::set_var("CAR_VLLM_MLX_BIN", &binary);
assert_eq!(resolve_existing(), absolutize(&binary));
std::env::set_var("CAR_VLLM_MLX_BIN", "/nonexistent/vllm-mlx-xyz");
let resolved = resolve_existing();
assert!(
resolved
.as_ref()
.map(|p| !p.ends_with("vllm-mlx-xyz"))
.unwrap_or(true),
"non-file override must not be returned"
);
}
#[test]
fn uv_tool_dirs_named_by_the_environment_are_searched() {
let _environment = crate::openrouter::test_environment_scope();
let _restore = RestoredEnvironment::capture(&["UV_TOOL_BIN_DIR", "UV_TOOL_DIR"]);
let tmp = tempfile::TempDir::new().unwrap();
let bin = tmp.path().join("uv-bin");
let tools = tmp.path().join("uv-tools");
std::env::set_var("UV_TOOL_BIN_DIR", &bin);
std::env::set_var("UV_TOOL_DIR", &tools);
let dirs = search_dirs();
assert!(dirs.contains(&bin), "{dirs:?}");
let tool_env = crate::managed_venv::venv_bin_dir(&tools.join(SERVER_BIN));
assert!(dirs.contains(&tool_env), "{dirs:?}");
}
#[test]
fn missing_uv_names_a_fix_that_works_for_what_was_found() {
let _environment = crate::openrouter::test_environment_scope();
let _restore = RestoredEnvironment::capture(&["UV_TOOL_DIR"]);
let tmp = tempfile::TempDir::new().unwrap();
let tools = tmp.path().join("uv-tools");
std::env::set_var("UV_TOOL_DIR", &tools);
let from_uv = tools.join(SERVER_BIN).join("bin").join(SERVER_BIN);
std::fs::create_dir_all(tools.join(SERVER_BIN)).unwrap();
std::fs::write(tools.join(SERVER_BIN).join("uv-receipt.toml"), "[tool]\n").unwrap();
let from_pip = tmp.path().join("Library/Python/3.12/bin").join(SERVER_BIN);
let from_pipx = tools.join("pipx-venv").join("bin").join(SERVER_BIN);
let missing = uv_missing(&Lookup::Missing).to_string();
assert!(missing.contains("`uv tool install vllm-mlx`"), "{missing}");
assert!(missing.contains("`CAR_VLLM_MLX_BIN`"), "{missing}");
let uv_texts = [
uv_missing(&Lookup::Outdated((0, 4, 1), from_uv.clone())).to_string(),
Lookup::Outdated((0, 4, 1), from_uv.clone())
.absence()
.unwrap(),
];
for text in &uv_texts {
assert!(
text.contains("`uv tool install --upgrade vllm-mlx`")
&& text.contains(&from_uv.display().to_string()),
"{text}"
);
}
let mut pip_texts = Vec::new();
for other in [&from_pip, &from_pipx] {
for text in [
uv_missing(&Lookup::Outdated((0, 4, 1), other.clone())).to_string(),
Lookup::Outdated((0, 4, 1), other.clone())
.absence()
.unwrap(),
] {
assert!(
!text.contains("uv tool install")
&& text.contains("the tool that installed it")
&& text.contains("`CAR_VLLM_MLX_BIN`")
&& text.contains(&other.display().to_string()),
"{text}"
);
pip_texts.push(text);
}
}
if let Some(root) = managed_root() {
let managed = managed_server_bin().unwrap();
let text = Lookup::Outdated((0, 4, 1), managed).absence().unwrap();
let interpreter = crate::managed_venv::interpreter(&root);
assert!(
text.contains(&format!(
"`uv pip install --python \"{}\" \"{PIP_SPEC}\"`",
interpreter.display()
)),
"{text}"
);
}
for text in uv_texts.iter().chain(&pip_texts).chain([&missing]) {
assert!(!text.contains("`pip install"), "{text}");
}
}
#[tokio::test]
async fn health_probe_accepts_a_fragmented_http_status_line() {
use tokio::io::{AsyncReadExt, AsyncWriteExt};
let listener = tokio::net::TcpListener::bind(("127.0.0.1", 0))
.await
.unwrap();
let address = listener.local_addr().unwrap();
let server = tokio::spawn(async move {
let (mut stream, _) = listener.accept().await.unwrap();
let mut request = [0u8; 256];
let _ = stream.read(&mut request).await.unwrap();
stream.write_all(b"HTTP/1.1 2").await.unwrap();
tokio::time::sleep(Duration::from_millis(25)).await;
stream
.write_all(b"00 OK\r\nContent-Length: 0\r\n\r\n")
.await
.unwrap();
});
assert!(health_ok(&format!("http://{address}"), crate::LOADED_WAIT).await);
server.await.unwrap();
}
}
#[cfg(test)]
mod resolution_tests {
use super::*;
fn p(s: &str) -> PathBuf {
PathBuf::from(s)
}
#[test]
fn highest_version_wins_not_first_above_the_floor() {
let picked = best_candidate(vec![
(p("/home/u/.local/bin/vllm-mlx"), Some((0, 6, 0))),
(
p("/home/u/.car/visual-runtime/bin/vllm-mlx"),
Some((0, 6, 2)),
),
]);
assert_eq!(picked, Some(p("/home/u/.car/visual-runtime/bin/vllm-mlx")));
}
#[test]
fn below_the_floor_is_rejected_even_when_it_is_the_only_one() {
assert_eq!(
best_candidate(vec![(p("/a/vllm-mlx"), Some((0, 2, 8)))]),
None
);
assert_eq!(
best_candidate(vec![(p("/a/vllm-mlx"), Some((0, 4, 1)))]),
None
);
}
#[test]
fn an_undeterminable_version_is_not_selected() {
assert_eq!(best_candidate(vec![(p("/a/vllm-mlx"), None)]), None);
assert_eq!(
best_candidate(vec![
(p("/a/vllm-mlx"), None),
(p("/b/vllm-mlx"), Some((0, 6, 0))),
]),
Some(p("/b/vllm-mlx"))
);
}
#[test]
fn no_candidates_means_provision() {
assert_eq!(best_candidate(vec![]), None);
}
#[tokio::test(flavor = "multi_thread")]
async fn routing_reuses_a_found_runtime_until_it_is_stale() {
let tmp = tempfile::TempDir::new().unwrap();
let python = tmp.path().join("python");
std::fs::write(&python, b"").unwrap();
let server = tmp.path().join(SERVER_BIN);
std::fs::write(&server, format!("#!{}\n", python.display())).unwrap();
let runtime = test_runtime::State::new(Lookup::Ready(server.clone()));
let ready = Lookup::Ready(server.clone());
assert_eq!(runtime.run(status()).await, ready);
assert_eq!(runtime.run(status()).await, ready);
assert_eq!(
runtime.lookups(),
1,
"the second call used what the first found"
);
std::fs::remove_file(&python).unwrap();
runtime.run(status()).await;
assert_eq!(
runtime.lookups(),
2,
"a dead interpreter is looked up again"
);
runtime.age_remembered();
runtime.run(status()).await;
assert_eq!(runtime.lookups(), 3, "so is one 30 seconds old");
}
#[tokio::test(flavor = "multi_thread")]
async fn server_start_looks_again_whatever_routing_remembered() {
let tmp = tempfile::TempDir::new().unwrap();
let server = tmp.path().join(SERVER_BIN);
std::fs::write(&server, b"fixture").unwrap();
let runtime = test_runtime::State::new(Lookup::Ready(server.clone()));
assert_eq!(runtime.run(status()).await, Lookup::Ready(server));
runtime.set(Lookup::Missing);
let refused = runtime
.run(crate::registry::never_download_scope(
true,
ensure_runtime(),
))
.await
.expect_err("server start looked again and found no runtime");
assert!(
refused.to_string().contains("not installed")
&& refused.to_string().contains("`uv tool install vllm-mlx`"),
"{refused}"
);
assert_eq!(runtime.lookups(), 2);
assert_eq!(
runtime.provisions(),
1,
"the backstop refused at provisioning"
);
}
#[tokio::test(flavor = "multi_thread")]
async fn an_outdated_runtime_is_named_with_the_upgrade_command() {
let _environment = crate::openrouter::test_environment_scope_async().await;
let _restore = super::tests::RestoredEnvironment::capture(&["UV_TOOL_DIR"]);
let tmp = tempfile::TempDir::new().unwrap();
std::env::set_var("UV_TOOL_DIR", tmp.path());
let from_uv = tmp.path().join(SERVER_BIN).join("bin").join(SERVER_BIN);
std::fs::create_dir_all(tmp.path().join(SERVER_BIN)).unwrap();
std::fs::write(
tmp.path().join(SERVER_BIN).join("uv-receipt.toml"),
"[tool]\n",
)
.unwrap();
let runtime = test_runtime::State::new(Lookup::Outdated((0, 4, 1), from_uv));
let schema = crate::registry::builtin_catalog()
.into_iter()
.find(crate::schema::ModelSchema::is_car_managed_vllm_mlx)
.expect("managed vllm fixture schema");
let found = runtime.run(status()).await;
let refusal = not_ready_error(&schema, &found).to_string();
let backstop = runtime
.run(crate::registry::never_download_scope(
true,
ensure_runtime(),
))
.await
.unwrap_err()
.to_string();
for text in [&refusal, &backstop] {
assert!(
text.contains("is 0.4.1, older than the 0.6.0 CAR needs")
&& text.contains("`uv tool install --upgrade vllm-mlx`"),
"{text}"
);
}
assert!(refusal.contains(&schema.name), "{refusal}");
assert_eq!(
runtime.provisions(),
1,
"the backstop refused at provisioning"
);
}
}
#[cfg(all(test, unix))]
mod hf_token_tests {
use super::*;
use crate::hf_cache::token_probe::{Probe, WITH_TOKEN};
async fn recorded_for(credentials: &[(&str, &str)]) -> String {
let probe = Probe::new();
let hf = probe.dir().join("hf");
probe.fake_program(&hf);
let mut cmd = car_secrets::with_child_credentials(credentials, || {
hf_download_command(&hf, "org/repo", false)
});
cmd.output().await.unwrap();
probe.recorded()
}
#[tokio::test]
async fn hf_download_is_handed_the_token() {
assert_eq!(recorded_for(WITH_TOKEN).await, "yes");
}
#[tokio::test]
async fn hf_download_gets_no_token_when_there_is_none() {
assert_eq!(recorded_for(&[]).await, "no");
}
}