11import { describe , it , expect } from "vitest" ;
2- import { buildRuntimeProbe , buildServerCommand , describeSpawnFailure } from "./local-server-manager" ;
2+ import { buildRuntimeProbe , buildServerCommand , describeSpawnFailure , identityMatches , explainStartupFailure } from "./local-server-manager" ;
33
44describe ( "buildServerCommand" , ( ) => {
55 it ( "builds an mlx_lm.server invocation with the default python" , ( ) => {
6- const { command, args } = buildServerCommand ( "mlx" , "mlx-community/Llama-3.2-3B-Instruct-4bit" , { } ) ;
6+ const { command, args } = buildServerCommand ( "mlx" , "mlx-community/Llama-3.2-3B-Instruct-4bit" , { } , "darwin" , 49151 ) ;
77 expect ( command ) . toBe ( "python3" ) ;
88 expect ( args ) . toContain ( "mlx_lm.server" ) ;
99 expect ( args ) . toContain ( "mlx-community/Llama-3.2-3B-Instruct-4bit" ) ;
@@ -12,54 +12,67 @@ describe("buildServerCommand", () => {
1212 } ) ;
1313
1414 it ( "respects a custom python interpreter path" , ( ) => {
15- const { command } = buildServerCommand ( "mlx" , "some/model" , { mlxPythonPath : "/opt/python/bin/python3.12" } ) ;
15+ const { command } = buildServerCommand ( "mlx" , "some/model" , { mlxPythonPath : "/opt/python/bin/python3.12" } , "darwin" , 49151 ) ;
1616 expect ( command ) . toBe ( "/opt/python/bin/python3.12" ) ;
1717 } ) ;
1818
1919 it ( "builds a llama-server invocation with full GPU offload for rocm" , ( ) => {
2020 const { command, args } = buildServerCommand ( "rocm" , "/models/llama.gguf" , {
2121 rocmServerPath : "/opt/rocm-llama/llama-server" ,
22- } ) ;
22+ } , "linux" , 49152 ) ;
2323 expect ( command ) . toBe ( "/opt/rocm-llama/llama-server" ) ;
2424 expect ( args ) . toEqual (
2525 expect . arrayContaining ( [ "-m" , "/models/llama.gguf" , "--n-gpu-layers" , "999" ] )
2626 ) ;
2727 } ) ;
2828
2929 it ( "falls back to PATH lookup when no rocm binary path is configured" , ( ) => {
30- const { command } = buildServerCommand ( "rocm" , "/models/llama.gguf" , { } ) ;
30+ const { command } = buildServerCommand ( "rocm" , "/models/llama.gguf" , { } , "linux" , 49152 ) ;
3131 expect ( command ) . toBe ( "llama-server" ) ;
3232 } ) ;
3333
34- it ( "uses distinct fixed ports per backend so both can run at once " , ( ) => {
35- const mlx = buildServerCommand ( "mlx" , "m" , { } ) ;
36- const rocm = buildServerCommand ( "rocm" , "m" , { } ) ;
37- const vllm = buildServerCommand ( "vllm" , "m" , { } ) ;
34+ it ( "uses the dynamically allocated port supplied to each backend " , ( ) => {
35+ const mlx = buildServerCommand ( "mlx" , "m" , { } , "darwin" , 49151 ) ;
36+ const rocm = buildServerCommand ( "rocm" , "m" , { } , "linux" , 49152 ) ;
37+ const vllm = buildServerCommand ( "vllm" , "m" , { } , "linux" , 49153 ) ;
3838 const portOf = ( args : string [ ] ) => args [ args . indexOf ( "--port" ) + 1 ] ;
3939 expect ( portOf ( mlx . args ) ) . not . toBe ( portOf ( rocm . args ) ) ;
4040 expect ( new Set ( [ portOf ( mlx . args ) , portOf ( rocm . args ) , portOf ( vllm . args ) ] ) . size ) . toBe ( 3 ) ;
4141 } ) ;
4242
4343 it ( "builds a managed vLLM OpenAI server command" , ( ) => {
44- const { command, args } = buildServerCommand ( "vllm" , "meta-llama/Llama-3.1-8B-Instruct" , { } , "linux" ) ;
44+ const { command, args } = buildServerCommand ( "vllm" , "meta-llama/Llama-3.1-8B-Instruct" , { } , "linux" , 49153 ) ;
4545 expect ( command ) . toBe ( "vllm" ) ;
4646 expect ( args ) . toEqual (
4747 expect . arrayContaining ( [ "serve" , "meta-llama/Llama-3.1-8B-Instruct" , "--host" , "127.0.0.1" ] )
4848 ) ;
4949 } ) ;
5050
5151 it ( "allows a vLLM command override without requiring one" , ( ) => {
52- const { command } = buildServerCommand ( "vllm" , "some/model" , { vllmCommand : "/opt/vllm/bin/vllm" } ) ;
52+ const { command } = buildServerCommand ( "vllm" , "some/model" , { vllmCommand : "/opt/vllm/bin/vllm" } , "linux" , 49153 ) ;
5353 expect ( command ) . toBe ( "/opt/vllm/bin/vllm" ) ;
5454 } ) ;
5555
5656 it ( "launches vLLM through WSL automatically on Windows" , ( ) => {
57- const { command, args } = buildServerCommand ( "vllm" , "some/model" , { } , "win32" ) ;
57+ const { command, args } = buildServerCommand ( "vllm" , "some/model" , { } , "win32" , 49153 ) ;
5858 expect ( command ) . toBe ( "wsl.exe" ) ;
5959 expect ( args . slice ( 0 , 4 ) ) . toEqual ( [ "--" , "vllm" , "serve" , "some/model" ] ) ;
6060 } ) ;
6161} ) ;
6262
63+ describe ( "runtime identity health" , ( ) => {
64+ it ( "requires an OpenAI model list containing the expected model" , ( ) => {
65+ expect ( identityMatches ( { data : [ { id : "meta-llama/Llama-3.1-8B-Instruct" } ] } , "meta-llama/Llama-3.1-8B-Instruct" ) ) . toBe ( true ) ;
66+ expect ( identityMatches ( { status : "ok" } , "meta-llama/Llama-3.1-8B-Instruct" ) ) . toBe ( false ) ;
67+ expect ( identityMatches ( { data : [ { id : "another-model" } ] } , "meta-llama/Llama-3.1-8B-Instruct" ) ) . toBe ( false ) ;
68+ } ) ;
69+
70+ it ( "turns common startup logs into actionable explanations" , ( ) => {
71+ expect ( explainStartupFailure ( "vllm" , [ "CUDA out of memory" ] ) ) . toMatch ( / R A M o r V R A M / ) ;
72+ expect ( explainStartupFailure ( "mlx" , [ "ModuleNotFoundError: No module named mlx_lm" ] ) ) . toMatch ( / p i p i n s t a l l m l x - l m / ) ;
73+ } ) ;
74+ } ) ;
75+
6376describe ( "describeSpawnFailure" , ( ) => {
6477 it ( "points mlx failures at the mlx-lm install" , ( ) => {
6578 expect ( describeSpawnFailure ( "mlx" ) ) . toMatch ( / m l x - l m / ) ;
0 commit comments