Files
ollama--ollama/llm/llama_binary_test.go
T
2026-07-13 11:56:09 +08:00

176 lines
5.4 KiB
Go

package llm
import (
"os"
"path/filepath"
"runtime"
"slices"
"testing"
)
func TestLlamaCppBinaryCandidates(t *testing.T) {
root := t.TempDir()
tests := []struct {
name string
search llamaCppBinarySearch
want []string
wantFirst string
}{
{
name: "linux production layout",
search: llamaCppBinarySearch{
executable: filepath.Join(root, "linux", "bin", "ollama"),
goos: "linux",
goarch: "amd64",
},
want: []string{filepath.Join(root, "linux", "lib", "ollama", "llama-server")},
wantFirst: filepath.Join(root, "linux", "lib", "ollama", "llama-server"),
},
{
name: "windows production layout",
search: llamaCppBinarySearch{
executable: filepath.Join(root, "windows", "ollama.exe"),
goos: "windows",
goarch: "amd64",
},
want: []string{filepath.Join(root, "windows", "lib", "ollama", "llama-server.exe")},
wantFirst: filepath.Join(root, "windows", "lib", "ollama", "llama-server.exe"),
},
{
name: "darwin production layout",
search: llamaCppBinarySearch{
executable: filepath.Join(root, "Ollama.app", "Contents", "Resources", "ollama"),
goos: "darwin",
goarch: "arm64",
},
want: []string{filepath.Join(root, "Ollama.app", "Contents", "Resources", "llama-server")},
wantFirst: filepath.Join(root, "Ollama.app", "Contents", "Resources", "llama-server"),
},
{
name: "darwin standard install layout",
search: llamaCppBinarySearch{
executable: filepath.Join(root, "darwin", "bin", "ollama"),
goos: "darwin",
goarch: "arm64",
},
want: []string{filepath.Join(root, "darwin", "lib", "ollama", "llama-server")},
},
{
name: "windows standard install layout",
search: llamaCppBinarySearch{
executable: filepath.Join(root, "windows", "bin", "ollama.exe"),
goos: "windows",
goarch: "amd64",
},
want: []string{filepath.Join(root, "windows", "lib", "ollama", "llama-server.exe")},
},
{
name: "local per-architecture dist layout",
search: llamaCppBinarySearch{
executable: filepath.Join(root, "dist", "darwin-arm64", "ollama"),
goos: "darwin",
goarch: "arm64",
},
want: []string{filepath.Join(root, "dist", "darwin-arm64", "lib", "ollama", "llama-server")},
},
{
name: "local top-level executable on linux",
search: llamaCppBinarySearch{
executable: filepath.Join(root, "ollama"),
workingDir: root,
goos: "linux",
goarch: "amd64",
},
want: []string{
filepath.Join(root, "build", "lib", "ollama", "llama-server"),
filepath.Join(root, "dist", "linux-amd64", "lib", "ollama", "llama-server"),
filepath.Join(root, "dist", "linux_amd64", "lib", "ollama", "llama-server"),
},
},
{
name: "local top-level executable on windows",
search: llamaCppBinarySearch{
executable: filepath.Join(root, "ollama.exe"),
workingDir: root,
goos: "windows",
goarch: "amd64",
},
want: []string{
filepath.Join(root, "build", "lib", "ollama", "llama-server.exe"),
filepath.Join(root, "dist", "windows-amd64", "lib", "ollama", "llama-server.exe"),
},
},
{
name: "local top-level executable on darwin",
search: llamaCppBinarySearch{
executable: filepath.Join(root, "ollama"),
workingDir: root,
goos: "darwin",
goarch: "arm64",
},
want: []string{
filepath.Join(root, "build", "lib", "ollama", "llama-server"),
filepath.Join(root, "dist", "darwin-arm64", "lib", "ollama", "llama-server"),
filepath.Join(root, "dist", "darwin", "llama-server"),
},
},
{
name: "explicit lib path stays first",
search: llamaCppBinarySearch{
libOllamaPath: filepath.Join(root, "install", "lib", "ollama"),
executable: filepath.Join(root, "app", "ollama"),
workingDir: filepath.Join(root, "work"),
goos: "linux",
goarch: "amd64",
},
want: []string{filepath.Join(root, "install", "lib", "ollama", "llama-server")},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
candidates := llamaCppBinaryCandidates("llama-server", tt.search)
if tt.wantFirst != "" && candidates[0] != tt.wantFirst {
t.Fatalf("first candidate = %q, want %q; all candidates: %v", candidates[0], tt.wantFirst, candidates)
}
if tt.search.libOllamaPath != "" && candidates[0] != tt.want[0] {
t.Fatalf("first candidate = %q, want %q; all candidates: %v", candidates[0], tt.want[0], candidates)
}
for _, want := range tt.want {
if !slices.Contains(candidates, want) {
t.Fatalf("missing candidate %q; all candidates: %v", want, candidates)
}
}
})
}
}
func TestFindLlamaCppBinaryPrefersPlatformBuildOutput(t *testing.T) {
root := t.TempDir()
cpuDir := filepath.Join(root, "build", "llama-server-cpu", "bin")
cudaDir := filepath.Join(root, "build", "llama-server-cuda", "bin")
for _, dir := range []string{cpuDir, cudaDir} {
if err := os.MkdirAll(dir, 0o755); err != nil {
t.Fatal(err)
}
}
name := llamaCppBinaryName("llama-quantize", runtime.GOOS)
cpuBin := filepath.Join(cpuDir, name)
cudaBin := filepath.Join(cudaDir, name)
for _, path := range []string{cpuBin, cudaBin} {
if err := os.WriteFile(path, nil, 0o755); err != nil {
t.Fatal(err)
}
}
got, _, err := findLlamaCppBinary("llama-quantize", llamaCppBinarySearch{workingDir: root})
if err != nil {
t.Fatal(err)
}
if got != cudaBin {
t.Fatalf("findLlamaCppBinary = %q, want %q", got, cudaBin)
}
}