Files
wehub-resource-sync 1b8708893a
Security Scan / tests (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:12:26 +08:00

157 lines
4.1 KiB
Go

package ollama_test
import (
"encoding/json"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"strings"
"testing"
"github.com/labstack/echo/v4"
"github.com/mudler/LocalAI/core/config"
"github.com/mudler/LocalAI/core/http/endpoints/ollama"
"github.com/mudler/LocalAI/core/schema"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
func TestOllamaEndpoints(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Ollama Endpoints Suite")
}
var _ = Describe("Ollama endpoint handlers", func() {
var e *echo.Echo
BeforeEach(func() {
e = echo.New()
})
Describe("HeartbeatEndpoint", func() {
It("returns 'Ollama is running' on GET /", func() {
req := httptest.NewRequest(http.MethodGet, "/", nil)
rec := httptest.NewRecorder()
c := e.NewContext(req, rec)
handler := ollama.HeartbeatEndpoint()
Expect(handler(c)).To(Succeed())
Expect(rec.Code).To(Equal(http.StatusOK))
Expect(rec.Body.String()).To(Equal("Ollama is running"))
})
It("returns 200 on HEAD /", func() {
req := httptest.NewRequest(http.MethodHead, "/", nil)
rec := httptest.NewRecorder()
c := e.NewContext(req, rec)
handler := ollama.HeartbeatEndpoint()
Expect(handler(c)).To(Succeed())
Expect(rec.Code).To(Equal(http.StatusOK))
})
})
Describe("VersionEndpoint", func() {
It("returns a JSON object with version field", func() {
req := httptest.NewRequest(http.MethodGet, "/api/version", nil)
rec := httptest.NewRecorder()
c := e.NewContext(req, rec)
handler := ollama.VersionEndpoint()
Expect(handler(c)).To(Succeed())
Expect(rec.Code).To(Equal(http.StatusOK))
Expect(rec.Body.String()).To(ContainSubstring(`"version"`))
Expect(rec.Body.String()).To(MatchRegexp(`\d+\.\d+\.\d+`))
})
})
Describe("ShowModelEndpoint", func() {
var (
tmpDir string
bcl *config.ModelConfigLoader
)
BeforeEach(func() {
var err error
tmpDir, err = os.MkdirTemp("", "ollama-show-test-*")
Expect(err).ToNot(HaveOccurred())
bcl = config.NewModelConfigLoader(tmpDir)
})
AfterEach(func() {
_ = os.RemoveAll(tmpDir)
})
writeConfig := func(name, yaml string) {
path := filepath.Join(tmpDir, name+".yaml")
Expect(os.WriteFile(path, []byte(yaml), 0o644)).To(Succeed())
Expect(bcl.ReadModelConfig(path)).To(Succeed())
}
callShow := func(name string) *schema.OllamaShowResponse {
req := httptest.NewRequest(http.MethodPost, "/api/show",
strings.NewReader(`{"name":"`+name+`"}`))
req.Header.Set("Content-Type", "application/json")
rec := httptest.NewRecorder()
c := e.NewContext(req, rec)
handler := ollama.ShowModelEndpoint(bcl)
Expect(handler(c)).To(Succeed())
Expect(rec.Code).To(Equal(http.StatusOK))
var resp schema.OllamaShowResponse
Expect(json.Unmarshal(rec.Body.Bytes(), &resp)).To(Succeed())
return &resp
}
It("returns capabilities=['embedding'] for embedding-only models", func() {
writeConfig("embed", `
name: embed
backend: llama-cpp
embeddings: true
parameters:
model: Qwen3-4B-Embedding-Q4_K_M.gguf
`)
resp := callShow("embed")
Expect(resp.Capabilities).To(ConsistOf("embedding"))
})
It("returns capabilities=['completion'] for plain chat models", func() {
writeConfig("chat", `
name: chat
backend: llama-cpp
template:
chat: "{{ .Input }}"
parameters:
model: Llama-3-8B-Q4_K_M.gguf
`)
resp := callShow("chat")
Expect(resp.Capabilities).To(ContainElement("completion"))
Expect(resp.Capabilities).ToNot(ContainElement("embedding"))
})
It("populates details.parameter_size and details.quantization_level from the GGUF filename", func() {
writeConfig("qwen", `
name: qwen
backend: llama-cpp
template:
chat: "{{ .Input }}"
parameters:
model: Qwen3-4B-Instruct-Q4_K_M.gguf
`)
resp := callShow("qwen")
Expect(resp.Details.ParameterSize).To(Equal("4B"))
Expect(resp.Details.QuantizationLevel).To(Equal("Q4_K_M"))
Expect(resp.Details.Format).To(Equal("gguf"))
Expect(resp.Details.Families).ToNot(BeEmpty())
})
})
Describe("ListModelsEndpoint", func() {
It("includes capabilities and details for each listed model in /api/tags", func() {
Skip("covered by per-entry tests; integration smoke test")
})
})
})