test(metis): cover harbor error and prune paths

This commit is contained in:
codex 2026-04-21 05:13:02 -03:00
parent c7a264e0e8
commit db2ee619be

View File

@ -165,6 +165,206 @@ func TestServiceHarborErrorBranches(t *testing.T) {
}
}
func TestServiceHarborAdditionalErrorBranches(t *testing.T) {
base := Settings{
HarborUsername: "admin",
HarborPassword: "pw",
HarborProject: "metis",
HarborRegistry: "registry.example",
}
app := &App{settings: base}
app.settings.HarborAPIBase = "://bad-url"
if err := app.ensureHarborProject(); err == nil {
t.Fatal("expected invalid Harbor lookup URL to fail")
}
if err := app.pruneHarborArtifacts("node", 1); err == nil {
t.Fatal("expected invalid Harbor prune URL to fail")
}
app.settings.HarborAPIBase = "http://127.0.0.1:1/api/v2.0"
if err := app.ensureHarborProject(); err == nil {
t.Fatal("expected Harbor lookup connection failure")
}
if err := app.pruneHarborArtifacts("node", 1); err == nil {
t.Fatal("expected Harbor artifact connection failure")
}
badProjectJSON := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
_, _ = w.Write([]byte(`{bad-json`))
}))
defer badProjectJSON.Close()
app.settings.HarborAPIBase = badProjectJSON.URL
if err := app.ensureHarborProject(); err == nil {
t.Fatal("expected malformed Harbor project response to fail")
}
createFailed := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch {
case r.Method == http.MethodGet && r.URL.Path == "/projects":
_, _ = w.Write([]byte(`[]`))
case r.Method == http.MethodPost && r.URL.Path == "/projects":
http.Error(w, "create failed", http.StatusInternalServerError)
default:
http.NotFound(w, r)
}
}))
defer createFailed.Close()
app.settings.HarborAPIBase = createFailed.URL
if err := app.ensureHarborProject(); err == nil {
t.Fatal("expected Harbor project create failure")
}
createConflict := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch {
case r.Method == http.MethodGet && r.URL.Path == "/projects":
_, _ = w.Write([]byte(`[]`))
case r.Method == http.MethodPost && r.URL.Path == "/projects":
w.WriteHeader(http.StatusConflict)
default:
http.NotFound(w, r)
}
}))
defer createConflict.Close()
app.settings.HarborAPIBase = createConflict.URL
if err := app.ensureHarborProject(); err != nil {
t.Fatalf("expected Harbor project conflict to be accepted: %v", err)
}
postDropped := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch {
case r.Method == http.MethodGet && r.URL.Path == "/projects":
_, _ = w.Write([]byte(`[]`))
case r.Method == http.MethodPost && r.URL.Path == "/projects":
conn, _, err := w.(http.Hijacker).Hijack()
if err != nil {
t.Fatalf("hijack Harbor POST: %v", err)
}
_ = conn.Close()
default:
http.NotFound(w, r)
}
}))
defer postDropped.Close()
app.settings.HarborAPIBase = postDropped.URL
if err := app.ensureHarborProject(); err == nil {
t.Fatal("expected dropped Harbor project create connection")
}
}
func TestServiceHarborPruneAdditionalBranches(t *testing.T) {
base := Settings{
HarborAPIBase: "http://unused",
HarborUsername: "admin",
HarborPassword: "pw",
HarborProject: "metis",
HarborRegistry: "registry.example",
}
for name, status := range map[string]int{
"missing": http.StatusNotFound,
"broken": http.StatusServiceUnavailable,
} {
t.Run(name, func(t *testing.T) {
harbor := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet && strings.Contains(r.URL.Path, "/artifacts") {
http.Error(w, name, status)
return
}
http.NotFound(w, r)
}))
defer harbor.Close()
app := &App{settings: base}
app.settings.HarborAPIBase = harbor.URL
err := app.pruneHarborArtifacts("node", 1)
if status == http.StatusNotFound && err != nil {
t.Fatalf("expected missing repository to be ignored: %v", err)
}
if status != http.StatusNotFound && err == nil {
t.Fatal("expected artifact list failure")
}
})
}
badArtifacts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet && strings.Contains(r.URL.Path, "/artifacts") {
_, _ = w.Write([]byte(`{bad-json`))
return
}
http.NotFound(w, r)
}))
defer badArtifacts.Close()
app := &App{settings: base}
app.settings.HarborAPIBase = badArtifacts.URL
if err := app.pruneHarborArtifacts("node", 1); err == nil {
t.Fatal("expected malformed artifact list to fail")
}
deletes := 0
pruneOK := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch {
case r.Method == http.MethodGet && strings.Contains(r.URL.Path, "/artifacts"):
_ = json.NewEncoder(w).Encode([]map[string]any{
{"digest": "sha256:oldest", "push_time": "2026-04-01T08:00:00Z"},
{"digest": "sha256:newest", "push_time": "2026-04-01T10:00:00Z"},
})
case r.Method == http.MethodDelete && strings.Contains(r.URL.Path, "/artifacts/"):
deletes++
w.WriteHeader(http.StatusOK)
default:
http.NotFound(w, r)
}
}))
defer pruneOK.Close()
app.settings.HarborAPIBase = pruneOK.URL
if err := app.pruneHarborArtifacts("node", 1); err != nil {
t.Fatalf("expected old artifact prune to succeed: %v", err)
}
if deletes != 1 {
t.Fatalf("expected one old artifact delete, got %d", deletes)
}
pruneDeleteFailed := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch {
case r.Method == http.MethodGet && strings.Contains(r.URL.Path, "/artifacts"):
_ = json.NewEncoder(w).Encode([]map[string]any{
{"digest": "sha256:stale", "push_time": "2026-04-01T08:00:00Z"},
})
case r.Method == http.MethodDelete && strings.Contains(r.URL.Path, "/artifacts/"):
http.Error(w, "delete failed", http.StatusInternalServerError)
default:
http.NotFound(w, r)
}
}))
defer pruneDeleteFailed.Close()
app.settings.HarborAPIBase = pruneDeleteFailed.URL
if err := app.pruneHarborArtifacts("node", 0); err == nil {
t.Fatal("expected artifact delete failure")
}
deleteDropped := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch {
case r.Method == http.MethodGet && strings.Contains(r.URL.Path, "/artifacts"):
_ = json.NewEncoder(w).Encode([]map[string]any{
{"digest": "sha256:stale", "push_time": "2026-04-01T08:00:00Z"},
})
case r.Method == http.MethodDelete && strings.Contains(r.URL.Path, "/artifacts/"):
conn, _, err := w.(http.Hijacker).Hijack()
if err != nil {
t.Fatalf("hijack Harbor DELETE: %v", err)
}
_ = conn.Close()
default:
http.NotFound(w, r)
}
}))
defer deleteDropped.Close()
app.settings.HarborAPIBase = deleteDropped.URL
if err := app.pruneHarborArtifacts("node", 0); err == nil {
t.Fatal("expected dropped Harbor artifact delete connection")
}
}
func TestServiceClusterAndRemotePodBranches(t *testing.T) {
origTokenPath := kubeServiceAccountTokenPath
origCAPath := kubeServiceAccountCAPath