test: local upload store-failure branches (kill minio mid-test)

This commit is contained in:
2026-07-03 13:53:13 +10:00
parent 1d97628fbd
commit 2ae12d9aef
+88
View File
@@ -0,0 +1,88 @@
package v2
import (
"context"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
"github.com/go-chi/chi/v5"
"git.unkin.net/unkin/artifactapi/internal/database"
"git.unkin.net/unkin/artifactapi/internal/storage"
"git.unkin.net/unkin/artifactapi/internal/testsupport"
"git.unkin.net/unkin/artifactapi/pkg/models"
)
// TestLocalUploadStoreFailure covers the upload handlers' store-error branches
// by killing the object store after a successful upload.
func TestLocalUploadStoreFailure(t *testing.T) {
if testDSN == "" {
t.Skip("Docker unavailable")
}
ctx := context.Background()
db, err := database.New(testDSN)
if err != nil {
t.Fatal(err)
}
defer db.Close()
conn, termMinio, err := testsupport.StartMinio(ctx)
if err != nil {
t.Skip("minio unavailable")
}
var store *storage.S3
for i := 0; i < 20; i++ {
if store, err = storage.NewS3(conn.Endpoint, conn.AccessKey, conn.SecretKey, "fault", false, ""); err == nil {
break
}
time.Sleep(500 * time.Millisecond)
}
if err != nil {
termMinio()
t.Fatal(err)
}
for _, pt := range []models.PackageType{models.PackageGeneric, models.PackagePyPI} {
if err := db.CreateRemote(ctx, &models.Remote{Name: "fault-" + string(pt), PackageType: pt, RepoType: models.RepoTypeLocal}); err != nil {
t.Fatal(err)
}
}
h := NewLocalHandler(db, store)
router := chi.NewRouter()
router.Route("/remotes/{name}/files", func(r chi.Router) {
r.Put("/*", h.Routes().ServeHTTP)
})
srv := httptest.NewServer(router)
defer srv.Close()
put := func(name, path, body string) int {
rq, _ := http.NewRequest("PUT", srv.URL+"/remotes/"+name+"/files/"+path, strings.NewReader(body))
resp, err := http.DefaultClient.Do(rq)
if err != nil {
t.Fatalf("put: %v", err)
}
resp.Body.Close()
return resp.StatusCode
}
// Sanity: uploads succeed while the store is up.
if c := put("fault-generic", "ok.bin", "data"); c != 201 {
t.Fatalf("generic upload while up = %d", c)
}
if c := put("fault-pypi", "foo-1.0-py3-none-any.whl", "wheel"); c != 201 {
t.Fatalf("pypi upload while up = %d", c)
}
// Kill the store; subsequent CAS.Store calls fail -> 500.
termMinio()
if c := put("fault-generic", "after.bin", "data"); c != 500 {
t.Errorf("generic upload after store down = %d, want 500", c)
}
if c := put("fault-pypi", "bar-1.0-py3-none-any.whl", "wheel"); c != 500 {
t.Errorf("pypi upload after store down = %d, want 500", c)
}
}