| // 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" |
| ) |
| |
| import ( |
| pack "github.com/buildpacks/pack/pkg/client" |
| ) |
| |
| import ( |
| "github.com/apache/dubbo-kubernetes/app/dubboctl/internal/builders" |
| "github.com/apache/dubbo-kubernetes/app/dubboctl/internal/dubbo" |
| ) |
| |
| // 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) |
| } |