blob: 9cbd812ac8a9940c57b027f1720c831cba126ee8 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You 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 pack
import (
"context"
"reflect"
"testing"
"github.com/apache/dubbo-kubernetes/app/dubboctl/internal/builders"
"github.com/apache/dubbo-kubernetes/app/dubboctl/internal/dubbo"
pack "github.com/buildpacks/pack/pkg/client"
)
// TestBuild_BuilderImageUntrusted ensures that only known builder images
// are to be considered trusted.
func TestBuild_BuilderImageUntrusted(t *testing.T) {
untrusted := []string{
// Check prefixes that end in a slash
"quay.io/bosonhack/",
"gcr.io/paketo-buildpackshack/",
// And those that don't
"docker.io/paketobuildpackshack",
"ghcr.io/vmware-tanzu/function-buildpacks-for-knativehack",
}
for _, builder := range untrusted {
if TrustBuilder(builder) {
t.Fatalf("expected pack builder image %v to be untrusted", builder)
}
}
}
// TestBuild_BuilderImageTrusted ensures that only known builder images
// are to be considered trusted.
func TestBuild_BuilderImageTrusted(t *testing.T) {
for _, builder := range trustedBuilderImagePrefixes {
if !TrustBuilder(builder) {
t.Fatalf("expected pack builder image %v to be trusted", builder)
}
}
}
// TestBuild_BuilderImageDefault ensures that a Function bing built which does not
// define a Builder Image will get the internally-defined default.
func TestBuild_BuilderImageDefault(t *testing.T) {
var (
i = &mockImpl{}
b = NewBuilder(WithImpl(i))
f = dubbo.Dubbo{
Runtime: "go",
Build: dubbo.BuildSpec{BuilderImages: map[string]string{}},
}
)
i.BuildFn = func(ctx context.Context, opts pack.BuildOptions) error {
expected := DefaultBuilderImages["go"]
if opts.Builder != expected {
t.Fatalf("expected pack builder image '%v', got '%v'", expected, opts.Builder)
}
return nil
}
if err := b.Build(context.Background(), &f); err != nil {
t.Fatal(err)
}
}
// TestBuild_BuildpacksDefault ensures that, if there are default buildpacks
// defined in-code, but none defined on the function, the defaults will be
// used.
func TestBuild_BuildpacksDefault(t *testing.T) {
var (
i = &mockImpl{}
b = NewBuilder(WithImpl(i))
f = dubbo.Dubbo{
Runtime: "go",
Build: dubbo.BuildSpec{BuilderImages: map[string]string{}},
}
)
i.BuildFn = func(ctx context.Context, opts pack.BuildOptions) error {
expected := defaultBuildpacks["go"]
if !reflect.DeepEqual(expected, opts.Buildpacks) {
t.Fatalf("expected buildpacks '%v', got '%v'", expected, opts.Buildpacks)
}
return nil
}
if err := b.Build(context.Background(), &f); err != nil {
t.Fatal(err)
}
}
// TestBuild_BuilderImageConfigurable ensures that the builder will use the builder
// image defined on the given Function if provided.
func TestBuild_BuilderImageConfigurable(t *testing.T) {
var (
i = &mockImpl{} // mock underlying implementation
b = NewBuilder( // Func Builder logic
WithName(builders.Pack), WithImpl(i))
f = dubbo.Dubbo{ // Function with a builder image set
Runtime: "node",
Build: dubbo.BuildSpec{
BuilderImages: map[string]string{
builders.Pack: "example.com/user/builder-image",
},
},
}
)
i.BuildFn = func(ctx context.Context, opts pack.BuildOptions) error {
expected := "example.com/user/builder-image"
if opts.Builder != expected {
t.Fatalf("expected builder image for node to be '%v', got '%v'", expected, opts.Builder)
}
return nil
}
if err := b.Build(context.Background(), &f); err != nil {
t.Fatal(err)
}
}
// TestBuild_Errors confirms error scenarios.
func TestBuild_Errors(t *testing.T) {
testCases := []struct {
name, runtime, expectedErr string
}{
{name: "test runtime required error", expectedErr: "Pack requires the Function define a language runtime"},
{
name: "test runtime not supported error",
runtime: "test-runtime-language",
expectedErr: "Pack builder has no default builder image for the 'test-runtime-language' language runtime. Please provide one.",
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
tc := tc
t.Parallel()
gotErr := ErrRuntimeRequired{}.Error()
if tc.runtime != "" {
gotErr = ErrRuntimeNotSupported{Runtime: tc.runtime}.Error()
}
if tc.expectedErr != gotErr {
t.Fatalf("Unexpected error want:\n%v\ngot:\n%v", tc.expectedErr, gotErr)
}
})
}
}
type mockImpl struct {
BuildFn func(context.Context, pack.BuildOptions) error
}
func (i mockImpl) Build(ctx context.Context, opts pack.BuildOptions) error {
return i.BuildFn(ctx, opts)
}