func/cmd/build_test.go

155 lines
4.2 KiB
Go

package cmd
import (
"errors"
"testing"
fn "knative.dev/kn-plugin-func"
"knative.dev/kn-plugin-func/mock"
)
// TestBuild_ImageFlag ensures that the image flag is used when specified.
func TestBuild_ImageFlag(t *testing.T) {
var (
args = []string{"--image", "docker.io/tigerteam/foo"}
builder = mock.NewBuilder()
)
root := fromTempDirectory(t)
if err := fn.New().Create(fn.Function{Runtime: "go", Root: root, Registry: TestRegistry}); err != nil {
t.Fatal(err)
}
cmd := NewBuildCmd(NewClientFactory(func() *fn.Client {
return fn.New(fn.WithBuilder(builder))
}))
// Execute the command
cmd.SetArgs(args)
err := cmd.Execute()
if err != nil {
t.Fatal(err)
}
// Now load the function and ensure that the image is set correctly.
f, err := fn.NewFunction(root)
if err != nil {
t.Fatal(err)
}
if f.Image != "docker.io/tigerteam/foo" {
t.Fatalf("Expected image to be 'docker.io/tigerteam/foo', but got '%v'", f.Image)
}
}
// TestDeploy_RegistryOrImageRequired ensures that when no registry or image are
// provided (or exist on the function already), and the client has not been
// instantiated with a default registry, an ErrRegistryRequired is received.
func TestBuild_RegistryOrImageRequired(t *testing.T) {
root := fromTempDirectory(t)
if err := fn.New().Create(fn.Function{Runtime: "go", Root: root}); err != nil {
t.Fatal(err)
}
cmd := NewBuildCmd(NewClientFactory(func() *fn.Client {
return fn.New()
}))
cmd.SetArgs([]string{}) // this explicit clearing of args may not be necessary
if err := cmd.Execute(); err != nil {
if !errors.Is(err, ErrRegistryRequired) {
t.Fatalf("expected ErrRegistryRequired, got error: %v", err)
}
}
// earlire test covers the --registry only case, test here that --image
// also succeeds.
cmd.SetArgs([]string{"--image=example.com/alice/myfunc"})
if err := cmd.Execute(); err != nil {
t.Fatal(err)
}
}
// TestBuild_InvalidRegistry ensures that providing an invalid resitry
// fails with the expected error.
func TestBuild_InvalidRegistry(t *testing.T) {
testInvalidRegistry(NewBuildCmd, t)
}
// TestBuild_RegistryLoads ensures that a function with a defined registry
// will use this when recalculating .Image on build when no --image is
// explicitly provided.
func TestBuild_RegistryLoads(t *testing.T) {
testRegistryLoads(NewBuildCmd, t)
}
// TestBuild_BuilderPersists ensures that the builder chosen is read from
// the function by default, and is able to be overridden by flags/env vars.
func TestBuild_BuilderPersists(t *testing.T) {
testBuilderPersists(NewBuildCmd, t)
}
// TestBuild_ValidateBuilder ensures that the validation function correctly
// identifies valid and invalid builder short names.
func TestBuild_BuilderValidated(t *testing.T) {
testBuilderValidated(NewBuildCmd, t)
}
// TestBuild_Push ensures that the build command properly pushes and respects
// the --push flag.
// - Push triggered after a successful build
// - Push not triggered after an unsuccessful build
// - Push can be disabled
func TestBuild_Push(t *testing.T) {
root := fromTempDirectory(t)
f := fn.Function{
Root: root,
Name: "myfunc",
Runtime: "go",
Registry: "example.com/alice",
}
if err := fn.New().Create(f); err != nil {
t.Fatal(err)
}
var (
builder = mock.NewBuilder()
pusher = mock.NewPusher()
cmd = NewBuildCmd(NewClientFactory(func() *fn.Client {
return fn.New(fn.WithRegistry(TestRegistry), fn.WithBuilder(builder), fn.WithPusher(pusher))
}))
)
if err := cmd.Execute(); err != nil {
t.Fatal(err)
}
// Assert there was no push
if pusher.PushInvoked {
t.Fatal("push should not be invoked by default")
}
// Execute with push enabled
cmd.SetArgs([]string{"--push"})
if err := cmd.Execute(); err != nil {
t.Fatal(err)
}
// Assert there was a push
if !pusher.PushInvoked {
t.Fatal("push should be invoked when requested and a successful build")
}
// Exeute with push enabled but with a failed build
builder.BuildFn = func(f fn.Function) error {
return errors.New("mock error")
}
pusher.PushInvoked = false
_ = cmd.Execute() // expected error
// Assert push was not invoked when the build failed
if pusher.PushInvoked {
t.Fatal("push should not be invoked on a failed build")
}
}