From 1d97628fbd79269f2b4a3c0fb2c02bb68730be74 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Fri, 3 Jul 2026 13:51:17 +1000 Subject: [PATCH] test: rpm serve errors, terraform rewriteDownloadURL, pypi merger, s3 stat, pattern-validation 400 --- internal/provider/rpm/rpm_meta_test.go | 22 ++++++++++++++++++++++ internal/server/server_test.go | 4 ++++ internal/storage/storage_test.go | 6 ++++++ internal/virtual/merger_test.go | 17 +++++++++++++++++ 4 files changed, 49 insertions(+) diff --git a/internal/provider/rpm/rpm_meta_test.go b/internal/provider/rpm/rpm_meta_test.go index 3e6d7b9..19d1a69 100644 --- a/internal/provider/rpm/rpm_meta_test.go +++ b/internal/provider/rpm/rpm_meta_test.go @@ -171,6 +171,28 @@ func TestRPMServeRepodata(t *testing.T) { } } +type errRPMReader struct{} + +func (errRPMReader) ListRPMMetadataEntries(context.Context, string) ([]provider.RPMMetadata, error) { + return nil, io.ErrUnexpectedEOF +} +func (errRPMReader) ListFilesByPrefix(context.Context, string, string) ([]provider.FileEntry, error) { + return nil, nil +} +func (errRPMReader) ListPackages(context.Context, string) ([]string, error) { return nil, nil } + +func TestRPMServeMetadataError(t *testing.T) { + p := &Provider{} + for _, path := range []string{"repodata/repomd.xml", "repodata/h-primary.xml.gz", "repodata/h-filelists.xml.gz", "repodata/h-other.xml.gz"} { + w := httptest.NewRecorder() + r := httptest.NewRequest(http.MethodGet, "/"+path, nil) + p.ServeLocalIndex(w, r, errRPMReader{}, "repo", path) + if w.Code != 500 { + t.Errorf("%s with failing reader = %d, want 500", path, w.Code) + } + } +} + func TestRPMFullMetadataXML(t *testing.T) { // A fully-populated entry exercises every optional-field branch in the // primary/filelists/other XML generators. diff --git a/internal/server/server_test.go b/internal/server/server_test.go index cf59063..3b04165 100644 --- a/internal/server/server_test.go +++ b/internal/server/server_test.go @@ -351,6 +351,10 @@ func TestServerValidationErrors(t *testing.T) { if resp, _ := req(t, "POST", "/api/v2/remotes", `not json`); resp.StatusCode != 400 { t.Errorf("invalid json: %d", resp.StatusCode) } + // Invalid regex pattern -> 400 from ValidatePatterns. + if resp, _ := req(t, "POST", "/api/v2/remotes", `{"name":"badre","package_type":"generic","repo_type":"remote","base_url":"https://x","blocklist":["[unterminated"]}`); resp.StatusCode != 400 { + t.Errorf("invalid regex: %d", resp.StatusCode) + } } func TestServerDockerAndHead(t *testing.T) { diff --git a/internal/storage/storage_test.go b/internal/storage/storage_test.go index f927826..0379900 100644 --- a/internal/storage/storage_test.go +++ b/internal/storage/storage_test.go @@ -113,6 +113,12 @@ func TestS3DownloadMissing(t *testing.T) { if _, _, err := testS3.Download(context.Background(), "does/not/exist"); err == nil { t.Error("expected error downloading missing key") } + if _, err := testS3.Stat(context.Background(), "does/not/exist"); err == nil { + t.Error("expected error stat-ing missing key") + } + if exists, err := testS3.Exists(context.Background(), "does/not/exist"); err != nil || exists { + t.Errorf("Exists(missing) = %v, %v; want false, nil", exists, err) + } } func TestCASStore(t *testing.T) { diff --git a/internal/virtual/merger_test.go b/internal/virtual/merger_test.go index 5b610fc..2e117fe 100644 --- a/internal/virtual/merger_test.go +++ b/internal/virtual/merger_test.go @@ -56,6 +56,23 @@ func TestPyPIMerge(t *testing.T) { } } +func TestPyPIMergeNoProxyAndBadLinks(t *testing.T) { + m := &PyPIMerger{} + members := []MemberIndex{{ + RemoteName: "a", + Body: []byte("foo.whl\nno href\nnot a link"), + }} + // No proxy base URL: hrefs are left as-is. + out, err := m.MergeIndexes(members, "") + if err != nil { + t.Fatal(err) + } + s := string(out) + if !strings.Contains(s, ">foo.whl") { + t.Errorf("missing link: %s", s) + } +} + func TestHelmMerge(t *testing.T) { m := &HelmMerger{} memberA := `apiVersion: v1