Skip to content

Commit 4fa9cff

Browse files
committed
test(image-service): add tests for checkImageURL and fix issues encountered on the way
1 parent 607776e commit 4fa9cff

File tree

2 files changed

+48
-9
lines changed

2 files changed

+48
-9
lines changed

cmd/metal-api/internal/service/image-service.go

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import (
55
"fmt"
66
"log/slog"
77
"net/http"
8-
"net/url"
98
"strconv"
9+
"strings"
1010
"time"
1111

1212
"github.com/metal-stack/metal-api/cmd/metal-api/internal/datastore"
@@ -351,12 +351,9 @@ func (r *imageResource) createImage(request *restful.Request, response *restful.
351351
}
352352

353353
func checkImageURL(id, inputURL string, ociCredentials authn.Authenticator) error {
354-
parsedURL, err := url.Parse(inputURL)
355-
if err != nil {
356-
return fmt.Errorf("image:%s with url:%s could not be parsed. error:%w", id, inputURL, err)
357-
}
354+
parsedURL := strings.Split(inputURL, "://")
358355

359-
switch parsedURL.Scheme {
356+
switch parsedURL[0] {
360357
case "http", "https":
361358
res, err := http.Head(inputURL)
362359
if err != nil {
@@ -366,7 +363,7 @@ func checkImageURL(id, inputURL string, ociCredentials authn.Authenticator) erro
366363
return fmt.Errorf("image:%s is not accessible under:%s status:%s", id, inputURL, res.Status)
367364
}
368365
case "oci":
369-
ref, err := name.ParseReference(inputURL)
366+
ref, err := name.ParseReference(parsedURL[1])
370367
if err != nil {
371368
return fmt.Errorf("image reference:%s could not be parsed. error:%w", inputURL, err)
372369
}
@@ -375,12 +372,12 @@ func checkImageURL(id, inputURL string, ociCredentials authn.Authenticator) erro
375372
ociCredentials = authn.Anonymous
376373
}
377374

378-
_, err = remote.Head(ref, remote.WithAuth(ociCredentials))
375+
_, err = remote.Image(ref, remote.WithAuth(ociCredentials))
379376
if err != nil {
380377
return fmt.Errorf("image:%s is not accessible under:%s error:%w", id, inputURL, err)
381378
}
382379
default:
383-
return fmt.Errorf("image:%s with url:%s has unkown protocol. error:%w", id, inputURL, err)
380+
return fmt.Errorf("image:%s with url:%s has unkown protocol", id, inputURL)
384381
}
385382

386383
return nil

cmd/metal-api/internal/service/image-service_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,48 @@ func TestDeleteImage(t *testing.T) {
108108
require.Equal(t, testdata.Img3.Name, *result.Name)
109109
}
110110

111+
func TestCheckImageURL(t *testing.T) {
112+
t.Run("Invalid URL", func(t *testing.T) {
113+
err := checkImageURL("testID", "http://invalid-ürl", nil)
114+
require.EqualError(t, err, "image:testID is not accessible under:http://invalid-ürl error:Head \"http://invalid-%C3%BCrl\": dial tcp: lookup xn--invalid-rl-heb: no such host")
115+
})
116+
117+
t.Run("HTTP URL with successful HEAD request", func(t *testing.T) {
118+
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
119+
w.WriteHeader(http.StatusOK)
120+
}))
121+
defer server.Close()
122+
123+
err := checkImageURL("testID", server.URL, nil)
124+
require.NoError(t, err)
125+
})
126+
127+
t.Run("HTTP URL with unsuccessful HEAD request", func(t *testing.T) {
128+
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
129+
w.WriteHeader(http.StatusNotFound)
130+
}))
131+
defer server.Close()
132+
133+
err := checkImageURL("testID", server.URL, nil)
134+
require.EqualError(t, err, "image:testID is not accessible under:"+server.URL+" status:404 Not Found")
135+
})
136+
137+
t.Run("Unsupported scheme", func(t *testing.T) {
138+
err := checkImageURL("testID", "ftp://unsupported.url", nil)
139+
require.EqualError(t, err, "image:testID with url:ftp://unsupported.url has unkown protocol")
140+
})
141+
142+
t.Run("valid OCI URL", func(t *testing.T) {
143+
err := checkImageURL("testID", "oci://ghcr.io/metal-stack/debian:latest", nil)
144+
require.NoError(t, err)
145+
})
146+
147+
t.Run("OCI URL with invalid reference", func(t *testing.T) {
148+
err := checkImageURL("testID", "oci://inva lid", nil)
149+
require.EqualError(t, err, "image reference:oci://inva lid could not be parsed. error:could not parse reference: inva lid")
150+
})
151+
}
152+
111153
func TestCreateImage(t *testing.T) {
112154
ds, mock := datastore.InitMockDB(t)
113155
testdata.InitMockDBData(mock)

0 commit comments

Comments
 (0)