1
0
mirror of https://github.com/ko-build/ko.git synced 2024-12-15 09:04:09 +02:00
ko-build/pkg/publish/default_test.go
2019-03-22 15:02:13 -04:00

224 lines
7.2 KiB
Go

// Copyright 2018 Google LLC All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package publish
import (
"crypto/md5"
"encoding/hex"
"fmt"
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
"github.com/google/go-containerregistry/pkg/name"
"github.com/google/go-containerregistry/pkg/v1/random"
)
func TestDefault(t *testing.T) {
img, err := random.Image(1024, 1)
if err != nil {
t.Fatalf("random.Image() = %v", err)
}
base := "blah"
importpath := "github.com/Google/go-containerregistry/cmd/crane"
expectedRepo := fmt.Sprintf("%s/%s", base, strings.ToLower(importpath))
headPathPrefix := fmt.Sprintf("/v2/%s/blobs/", expectedRepo)
initiatePath := fmt.Sprintf("/v2/%s/blobs/uploads/", expectedRepo)
manifestPath := fmt.Sprintf("/v2/%s/manifests/latest", expectedRepo)
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodHead && strings.HasPrefix(r.URL.Path, headPathPrefix) && r.URL.Path != initiatePath {
http.Error(w, "NotFound", http.StatusNotFound)
return
}
switch r.URL.Path {
case "/v2/":
w.WriteHeader(http.StatusOK)
case initiatePath:
if r.Method != http.MethodPost {
t.Errorf("Method; got %v, want %v", r.Method, http.MethodPost)
}
http.Error(w, "Mounted", http.StatusCreated)
case manifestPath:
if r.Method != http.MethodPut {
t.Errorf("Method; got %v, want %v", r.Method, http.MethodPut)
}
http.Error(w, "Created", http.StatusCreated)
default:
t.Fatalf("Unexpected path: %v", r.URL.Path)
}
}))
defer server.Close()
u, err := url.Parse(server.URL)
if err != nil {
t.Fatalf("url.Parse(%v) = %v", server.URL, err)
}
tag, err := name.NewTag(fmt.Sprintf("%s/%s:latest", u.Host, expectedRepo))
if err != nil {
t.Fatalf("NewTag() = %v", err)
}
repoName := fmt.Sprintf("%s/%s", u.Host, base)
def, err := NewDefault(repoName)
if err != nil {
t.Errorf("NewDefault() = %v", err)
}
if d, err := def.Publish(img, importpath); err != nil {
t.Errorf("Publish() = %v", err)
} else if !strings.HasPrefix(d.String(), tag.Repository.String()) {
t.Errorf("Publish() = %v, wanted prefix %v", d, tag.Repository)
}
}
func md5Hash(s string) string {
// md5 as hex.
hasher := md5.New()
hasher.Write([]byte(s))
return hex.EncodeToString(hasher.Sum(nil))
}
func TestDefaultWithCustomNamer(t *testing.T) {
img, err := random.Image(1024, 1)
if err != nil {
t.Fatalf("random.Image() = %v", err)
}
base := "blah"
importpath := "github.com/Google/go-containerregistry/cmd/crane"
expectedRepo := fmt.Sprintf("%s/%s", base, md5Hash(strings.ToLower(importpath)))
headPathPrefix := fmt.Sprintf("/v2/%s/blobs/", expectedRepo)
initiatePath := fmt.Sprintf("/v2/%s/blobs/uploads/", expectedRepo)
manifestPath := fmt.Sprintf("/v2/%s/manifests/latest", expectedRepo)
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodHead && strings.HasPrefix(r.URL.Path, headPathPrefix) && r.URL.Path != initiatePath {
http.Error(w, "NotFound", http.StatusNotFound)
return
}
switch r.URL.Path {
case "/v2/":
w.WriteHeader(http.StatusOK)
case initiatePath:
if r.Method != http.MethodPost {
t.Errorf("Method; got %v, want %v", r.Method, http.MethodPost)
}
http.Error(w, "Mounted", http.StatusCreated)
case manifestPath:
if r.Method != http.MethodPut {
t.Errorf("Method; got %v, want %v", r.Method, http.MethodPut)
}
http.Error(w, "Created", http.StatusCreated)
default:
t.Fatalf("Unexpected path: %v", r.URL.Path)
}
}))
defer server.Close()
u, err := url.Parse(server.URL)
if err != nil {
t.Fatalf("url.Parse(%v) = %v", server.URL, err)
}
tag, err := name.NewTag(fmt.Sprintf("%s/%s:latest", u.Host, expectedRepo))
if err != nil {
t.Fatalf("NewTag() = %v", err)
}
repoName := fmt.Sprintf("%s/%s", u.Host, base)
def, err := NewDefault(repoName, WithNamer(md5Hash))
if err != nil {
t.Errorf("NewDefault() = %v", err)
}
if d, err := def.Publish(img, importpath); err != nil {
t.Errorf("Publish() = %v", err)
} else if !strings.HasPrefix(d.String(), repoName) {
t.Errorf("Publish() = %v, wanted prefix %v", d, tag.Repository)
} else if !strings.HasSuffix(d.Context().String(), md5Hash(strings.ToLower(importpath))) {
t.Errorf("Publish() = %v, wanted suffix %v", d.Context(), md5Hash(importpath))
}
}
func TestDefaultWithTags(t *testing.T) {
img, err := random.Image(1024, 1)
if err != nil {
t.Fatalf("random.Image() = %v", err)
}
base := "blah"
importpath := "github.com/Google/go-containerregistry/cmd/crane"
expectedRepo := fmt.Sprintf("%s/%s", base, strings.ToLower(importpath))
headPathPrefix := fmt.Sprintf("/v2/%s/blobs/", expectedRepo)
initiatePath := fmt.Sprintf("/v2/%s/blobs/uploads/", expectedRepo)
manifestPath := fmt.Sprintf("/v2/%s/manifests/", expectedRepo)
createdTags := make(map[string]struct{})
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodHead && strings.HasPrefix(r.URL.Path, headPathPrefix) && r.URL.Path != initiatePath {
http.Error(w, "NotFound", http.StatusNotFound)
return
}
switch {
case r.URL.Path == "/v2/":
w.WriteHeader(http.StatusOK)
case r.URL.Path == initiatePath:
if r.Method != http.MethodPost {
t.Errorf("Method; got %v, want %v", r.Method, http.MethodPost)
}
http.Error(w, "Mounted", http.StatusCreated)
case strings.HasPrefix(r.URL.Path, manifestPath):
if r.Method != http.MethodPut {
t.Errorf("Method; got %v, want %v", r.Method, http.MethodPut)
}
createdTags[strings.TrimPrefix(r.URL.Path, manifestPath)] = struct{}{}
http.Error(w, "Created", http.StatusCreated)
default:
t.Fatalf("Unexpected path: %v", r.URL.Path)
}
}))
defer server.Close()
u, err := url.Parse(server.URL)
if err != nil {
t.Fatalf("url.Parse(%v) = %v", server.URL, err)
}
tag, err := name.NewTag(fmt.Sprintf("%s/%s:notLatest", u.Host, expectedRepo))
if err != nil {
t.Fatalf("NewTag() = %v", err)
}
repoName := fmt.Sprintf("%s/%s", u.Host, base)
def, err := NewDefault(repoName, WithTags([]string{"notLatest", "v1.2.3"}))
if err != nil {
t.Errorf("NewDefault() = %v", err)
}
if d, err := def.Publish(img, importpath); err != nil {
t.Errorf("Publish() = %v", err)
} else if !strings.HasPrefix(d.String(), repoName) {
t.Errorf("Publish() = %v, wanted prefix %v", d, tag.Repository)
} else if !strings.HasSuffix(d.Context().String(), strings.ToLower(importpath)) {
t.Errorf("Publish() = %v, wanted suffix %v", d.Context(), md5Hash(importpath))
}
if _, ok := createdTags["notLatest"]; !ok {
t.Errorf("Tag notLatest was not created.")
}
if _, ok := createdTags["v1.2.3"]; !ok {
t.Errorf("Tag v1.2.3 was not created.")
}
}