diff --git a/docs/development.md b/docs/development.md index 12c69c204..8513c85d1 100644 --- a/docs/development.md +++ b/docs/development.md @@ -206,35 +206,6 @@ To run tests, use `go test`: go test ./... ``` -> NOTE: In rare circumstances, you may need to change a package using the new -> "synctest" package in go1.24. -> -> If you do not have the "synctest" package enabled, you will not see build or -> test failures resulting from your change(s), if any, locally, but CI will -> break. -> -> If you see failures in CI, you can either keep pushing changes to see if the -> CI build passes, or you can enable the "synctest" package locally to see the -> failures before pushing. -> -> To enable the "synctest" package for testing, run the following command: -> -> ```shell -> GOEXPERIMENT=synctest go test ./... -> ``` -> -> If you wish to enable synctest for all go commands, you can set the -> `GOEXPERIMENT` environment variable in your shell profile or by using: -> -> ```shell -> go env -w GOEXPERIMENT=synctest -> ``` -> -> Which will enable the "synctest" package for all go commands without needing -> to set it for all shell sessions. -> -> The synctest package is not required for production builds. - ## Library detection Ollama looks for acceleration libraries in the following paths relative to the `ollama` executable: diff --git a/go.mod b/go.mod index bf18ae8d3..ce433674b 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/ollama/ollama -go 1.24.1 +go 1.26.0 require ( github.com/TheTitanrain/w32 v0.0.0-20180517000239-4f5cfb03fabf diff --git a/server/internal/internal/backoff/backoff_synctest_test.go b/server/internal/internal/backoff/backoff_synctest_test.go index cf17ce80a..c59620f8b 100644 --- a/server/internal/internal/backoff/backoff_synctest_test.go +++ b/server/internal/internal/backoff/backoff_synctest_test.go @@ -1,5 +1,3 @@ -//go:build goexperiment.synctest - package backoff import ( @@ -11,7 +9,7 @@ import ( ) func TestLoop(t *testing.T) { - synctest.Run(func() { + synctest.Test(t, func(t *testing.T) { last := -1 ctx, cancel := context.WithCancel(t.Context()) diff --git a/server/internal/internal/backoff/backoff_test.go b/server/internal/internal/backoff/backoff_test.go index f474118f0..1d6d19c2c 100644 --- a/server/internal/internal/backoff/backoff_test.go +++ b/server/internal/internal/backoff/backoff_test.go @@ -1,11 +1,7 @@ -//go:build goexperiment.synctest - package backoff import ( "testing" - "testing/synctest" - "time" ) func TestLoopAllocs(t *testing.T) { @@ -26,14 +22,3 @@ func TestLoopAllocs(t *testing.T) { } } } - -func BenchmarkLoop(b *testing.B) { - ctx := b.Context() - synctest.Run(func() { - for n := range Loop(ctx, 100*time.Millisecond) { - if n == b.N { - break - } - } - }) -} diff --git a/server/internal/internal/syncs/line_test.go b/server/internal/internal/syncs/line_test.go index 94114a565..50256bec2 100644 --- a/server/internal/internal/syncs/line_test.go +++ b/server/internal/internal/syncs/line_test.go @@ -1,5 +1,3 @@ -//go:build goexperiment.synctest - package syncs import ( @@ -12,7 +10,7 @@ import ( func TestPipelineReadWriterTo(t *testing.T) { for range 10 { - synctest.Run(func() { + synctest.Test(t, func(t *testing.T) { q := NewRelayReader() tickets := []struct { diff --git a/x/imagegen/transfer/transfer_test.go b/x/imagegen/transfer/transfer_test.go index 589148125..d85f513a9 100644 --- a/x/imagegen/transfer/transfer_test.go +++ b/x/imagegen/transfer/transfer_test.go @@ -798,81 +798,6 @@ func verifyBlob(t *testing.T, dir string, blob Blob, expected []byte) { // ==================== Parallelism Tests ==================== -func TestDownloadParallelism(t *testing.T) { - // Create many blobs to test parallelism - serverDir := t.TempDir() - numBlobs := 10 - blobs := make([]Blob, numBlobs) - blobData := make([][]byte, numBlobs) - - for i := range numBlobs { - blobs[i], blobData[i] = createTestBlob(t, serverDir, 1024+i*100) - } - - var activeRequests atomic.Int32 - var maxConcurrent atomic.Int32 - - server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - current := activeRequests.Add(1) - defer activeRequests.Add(-1) - - // Track max concurrent requests - for { - old := maxConcurrent.Load() - if current <= old || maxConcurrent.CompareAndSwap(old, current) { - break - } - } - - // Simulate network latency to ensure parallelism is visible - time.Sleep(50 * time.Millisecond) - - digest := filepath.Base(r.URL.Path) - path := filepath.Join(serverDir, digestToPath(digest)) - data, err := os.ReadFile(path) - if err != nil { - http.NotFound(w, r) - return - } - w.WriteHeader(http.StatusOK) - w.Write(data) - })) - defer server.Close() - - clientDir := t.TempDir() - - start := time.Now() - err := Download(context.Background(), DownloadOptions{ - Blobs: blobs, - BaseURL: server.URL, - DestDir: clientDir, - Concurrency: 4, - }) - elapsed := time.Since(start) - - if err != nil { - t.Fatalf("Download failed: %v", err) - } - - // Verify all blobs downloaded - for i, blob := range blobs { - verifyBlob(t, clientDir, blob, blobData[i]) - } - - // Verify parallelism was used - if maxConcurrent.Load() < 2 { - t.Errorf("Max concurrent requests was %d, expected at least 2 for parallelism", maxConcurrent.Load()) - } - - // With 10 blobs at 50ms each, sequential would take ~500ms - // Parallel with 4 workers should take ~150ms (relax to 1s for CI variance) - if elapsed > time.Second { - t.Errorf("Downloads took %v, expected faster with parallelism", elapsed) - } - - t.Logf("Downloaded %d blobs in %v with max %d concurrent requests", numBlobs, elapsed, maxConcurrent.Load()) -} - func TestUploadParallelism(t *testing.T) { clientDir := t.TempDir() numBlobs := 10 @@ -1244,53 +1169,6 @@ func TestUploadEmptyBlobList(t *testing.T) { } } -func TestDownloadManyBlobs(t *testing.T) { - // Test with many blobs to verify high concurrency works - serverDir := t.TempDir() - numBlobs := 50 - blobs := make([]Blob, numBlobs) - blobData := make([][]byte, numBlobs) - - for i := range numBlobs { - blobs[i], blobData[i] = createTestBlob(t, serverDir, 512) // Small blobs - } - - server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - digest := filepath.Base(r.URL.Path) - path := filepath.Join(serverDir, digestToPath(digest)) - data, err := os.ReadFile(path) - if err != nil { - http.NotFound(w, r) - return - } - w.WriteHeader(http.StatusOK) - w.Write(data) - })) - defer server.Close() - - clientDir := t.TempDir() - - start := time.Now() - err := Download(context.Background(), DownloadOptions{ - Blobs: blobs, - BaseURL: server.URL, - DestDir: clientDir, - Concurrency: 16, - }) - elapsed := time.Since(start) - - if err != nil { - t.Fatalf("Download failed: %v", err) - } - - // Verify all blobs - for i, blob := range blobs { - verifyBlob(t, clientDir, blob, blobData[i]) - } - - t.Logf("Downloaded %d blobs in %v", numBlobs, elapsed) -} - func TestUploadRetryOnFailure(t *testing.T) { clientDir := t.TempDir() blob, _ := createTestBlob(t, clientDir, 1024)