Compare commits

..

7 Commits

Author SHA1 Message Date
Roy Han
5f0403d208 Isolated Deletions 2024-05-31 17:40:11 -07:00
Roy Han
5a3cb1064a Clean Up Delete Tests 2024-05-31 16:44:54 -07:00
Roy Han
77487ada72 Err Check 2024-05-31 13:12:26 -07:00
Roy Han
a946b6f020 Adjust Response and Blob Check 2024-05-31 13:08:59 -07:00
Roy Han
c62df6b3bf Check Blob 2024-05-31 12:07:52 -07:00
Roy Han
e8788ae8dd Specify DNE error 2024-05-31 09:45:47 -07:00
Roy Han
8774e5d6a9 Deletion Unit Test 2024-05-30 16:44:17 -07:00
2 changed files with 101 additions and 43 deletions

View File

@@ -65,6 +65,13 @@ func Test_Routes(t *testing.T) {
assert.Nil(t, err)
}
// Test Model Digests
blobs := []string{
"sha256:a4e5e156ddec27e286f75328784d7106b60a4eb1d246e950a001a3f944fbda99",
"sha256:4f9d252f34ae677363956ffc6dd2d10918a539c5c91f5ee2fe889d9178be6ae3",
"sha256:0f239b83e9e2aad7cd997a5bb44124937a32ac1f4e98e95a2f46e7b966bfc878",
}
testCases := []testCase{
{
Name: "Version Handler",
@@ -120,6 +127,94 @@ func Test_Routes(t *testing.T) {
assert.Equal(t, modelList.Models[0].Name, "test-model:latest")
},
},
{
Name: "Show Model Handler",
Method: http.MethodPost,
Path: "/api/show",
Setup: func(t *testing.T, req *http.Request) {
createTestModel(t, "show-model")
showReq := api.ShowRequest{Model: "show-model"}
jsonData, err := json.Marshal(showReq)
assert.Nil(t, err)
req.Body = io.NopCloser(bytes.NewReader(jsonData))
},
Expected: func(t *testing.T, resp *http.Response) {
contentType := resp.Header.Get("Content-Type")
assert.Equal(t, contentType, "application/json; charset=utf-8")
body, err := io.ReadAll(resp.Body)
assert.Nil(t, err)
var showResp api.ShowResponse
err = json.Unmarshal(body, &showResp)
assert.Nil(t, err)
var params []string
paramsSplit := strings.Split(showResp.Parameters, "\n")
for _, p := range paramsSplit {
params = append(params, strings.Join(strings.Fields(p), " "))
}
sort.Strings(params)
expectedParams := []string{
"seed 42",
"stop \"bar\"",
"stop \"foo\"",
"top_p 0.9",
}
assert.Equal(t, expectedParams, params)
},
},
{
Name: "Delete Handler (multiple blob reference)",
Method: http.MethodDelete,
Path: "/api/delete",
Setup: func(t *testing.T, req *http.Request) {
deleteReq := api.DeleteRequest{Model: "test-model"}
jsonData, err := json.Marshal(deleteReq)
assert.Nil(t, err)
req.Body = io.NopCloser(bytes.NewReader(jsonData))
},
Expected: func(t *testing.T, resp *http.Response) {
_, err := io.ReadAll(resp.Body)
assert.Nil(t, err)
assert.Equal(t, resp.StatusCode, 200)
_, err = GetModel("test-model")
assert.True(t, os.IsNotExist(err))
model, _ := GetModel("show-model")
assert.Equal(t, "show-model:latest", model.ShortName)
for i, blob := range blobs {
blobPath, _ := GetBlobsPath(blob)
_, err := os.Stat(blobPath)
assert.False(t, os.IsNotExist(err))
blobs[i] = blobPath
}
},
},
{
Name: "Delete Handler (single blob reference)",
Method: http.MethodDelete,
Path: "/api/delete",
Setup: func(t *testing.T, req *http.Request) {
deleteReq := api.DeleteRequest{Model: "show-model"}
jsonData, err := json.Marshal(deleteReq)
assert.Nil(t, err)
req.Body = io.NopCloser(bytes.NewReader(jsonData))
},
Expected: func(t *testing.T, resp *http.Response) {
_, err := io.ReadAll(resp.Body)
assert.Nil(t, err)
_, err = GetModel("show-model")
assert.True(t, os.IsNotExist(err))
for _, blob := range blobs {
_, err := os.Stat(blob)
assert.True(t, os.IsNotExist(err))
}
},
},
{
Name: "Create Model Handler",
Method: http.MethodPost,
@@ -171,42 +266,6 @@ func Test_Routes(t *testing.T) {
assert.Equal(t, "beefsteak:latest", model.ShortName)
},
},
{
Name: "Show Model Handler",
Method: http.MethodPost,
Path: "/api/show",
Setup: func(t *testing.T, req *http.Request) {
createTestModel(t, "show-model")
showReq := api.ShowRequest{Model: "show-model"}
jsonData, err := json.Marshal(showReq)
assert.Nil(t, err)
req.Body = io.NopCloser(bytes.NewReader(jsonData))
},
Expected: func(t *testing.T, resp *http.Response) {
contentType := resp.Header.Get("Content-Type")
assert.Equal(t, contentType, "application/json; charset=utf-8")
body, err := io.ReadAll(resp.Body)
assert.Nil(t, err)
var showResp api.ShowResponse
err = json.Unmarshal(body, &showResp)
assert.Nil(t, err)
var params []string
paramsSplit := strings.Split(showResp.Parameters, "\n")
for _, p := range paramsSplit {
params = append(params, strings.Join(strings.Fields(p), " "))
}
sort.Strings(params)
expectedParams := []string{
"seed 42",
"stop \"bar\"",
"stop \"foo\"",
"top_p 0.9",
}
assert.Equal(t, expectedParams, params)
},
},
}
t.Setenv("OLLAMA_MODELS", t.TempDir())

View File

@@ -10,7 +10,6 @@ import (
"log/slog"
"path/filepath"
"strings"
"unicode"
)
// Errors
@@ -319,14 +318,14 @@ func isValidPart(kind partKind, s string) bool {
if !isValidLen(kind, s) {
return false
}
for i, c := range s {
for i := range s {
if i == 0 {
if !isAlphanumericOrUnderscore(c) {
if !isAlphanumericOrUnderscore(s[i]) {
return false
}
continue
}
switch c {
switch s[i] {
case '_', '-':
case '.':
if kind == kindNamespace {
@@ -337,7 +336,7 @@ func isValidPart(kind partKind, s string) bool {
return false
}
default:
if !isAlphanumericOrUnderscore(c) {
if !isAlphanumericOrUnderscore(s[i]) {
return false
}
}
@@ -345,8 +344,8 @@ func isValidPart(kind partKind, s string) bool {
return true
}
func isAlphanumericOrUnderscore(c rune) bool {
return unicode.IsLetter(c) || unicode.IsDigit(c) || c == '_'
func isAlphanumericOrUnderscore(c byte) bool {
return c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z' || c >= '0' && c <= '9' || c == '_'
}
func cutLast(s, sep string) (before, after string, ok bool) {