From 8518b37ca15bb477266d4270101971ee16675b40 Mon Sep 17 00:00:00 2001 From: Sam Stoelinga Date: Sat, 21 Mar 2020 16:15:34 -0700 Subject: [PATCH] Add unit tests for CheckPushPermissions --- pkg/executor/push.go | 16 +++++---- pkg/executor/push_test.go | 72 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 6 deletions(-) diff --git a/pkg/executor/push.go b/pkg/executor/push.go index 0ff7930fd..e10fed35e 100644 --- a/pkg/executor/push.go +++ b/pkg/executor/push.go @@ -99,6 +99,13 @@ var defaultX509Handler systemCertLoader = func() CertPool { } } +// for testing +var ( + fs = afero.NewOsFs() + execCommand = exec.Command + checkRemotePushPermission = remote.CheckPushPermission +) + // CheckPushPermissions checks that the configured credentials can be used to // push to every specified destination. func CheckPushPermissions(opts *config.KanikoOptions) error { @@ -122,9 +129,8 @@ func CheckPushPermissions(opts *config.KanikoOptions) error { if strings.Contains(destRef.RegistryStr(), "gcr.io") { // Checking for existence of docker.config as it's normally required for // authenticated registries and prevent overwriting user provided docker conf - if _, err := os.Stat("/kaniko/.docker/config.json"); os.IsNotExist(err) { - cmd := exec.Command("docker-credential-gcr", "configure-docker") - if err := cmd.Run(); err != nil { + if _, err := fs.Stat("/kaniko/.docker/config.json"); os.IsNotExist(err) { + if err := execCommand("docker-credential-gcr", "configure-docker").Run(); err != nil { return errors.Wrap(err, "error while configuring docker-credential-gcr helper") } } @@ -138,7 +144,7 @@ func CheckPushPermissions(opts *config.KanikoOptions) error { destRef.Repository.Registry = newReg } tr := makeTransport(opts, registryName, defaultX509Handler) - if err := remote.CheckPushPermission(destRef, creds.GetKeychain(), tr); err != nil { + if err := checkRemotePushPermission(destRef, creds.GetKeychain(), tr); err != nil { return errors.Wrapf(err, "checking push permission for %q", destRef) } checked[destRef.Context().RepositoryStr()] = true @@ -245,8 +251,6 @@ func DoPush(image v1.Image, opts *config.KanikoOptions) error { return writeImageOutputs(image, destRefs) } -var fs = afero.NewOsFs() - func writeImageOutputs(image v1.Image, destRefs []name.Tag) error { dir := os.Getenv("BUILDER_OUTPUT") if dir == "" { diff --git a/pkg/executor/push_test.go b/pkg/executor/push_test.go index 3659f8514..035a66575 100644 --- a/pkg/executor/push_test.go +++ b/pkg/executor/push_test.go @@ -24,11 +24,13 @@ import ( "io/ioutil" "net/http" "os" + "os/exec" "path/filepath" "testing" "github.com/GoogleContainerTools/kaniko/pkg/config" "github.com/GoogleContainerTools/kaniko/testutil" + "github.com/google/go-containerregistry/pkg/authn" "github.com/google/go-containerregistry/pkg/name" "github.com/google/go-containerregistry/pkg/v1/layout" "github.com/google/go-containerregistry/pkg/v1/random" @@ -307,3 +309,73 @@ func Test_makeTransport(t *testing.T) { }) } } + +var called = false + +func fakeExecCommand(command string, args ...string) *exec.Cmd { + called = true + cs := []string{"-test.run=TestHelperProcess", "--", command} + cs = append(cs, args...) + cmd := exec.Command(os.Args[0], cs...) + cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"} + return cmd +} + +func fakeCheckPushPermission(ref name.Reference, kc authn.Keychain, t http.RoundTripper) error { + return nil +} + +func TestCheckPushPermissionsGCR(t *testing.T) { + execCommand = fakeExecCommand + checkRemotePushPermission = fakeCheckPushPermission + defer func() { called = false }() + + opts := config.KanikoOptions{ + Destinations: []string{"gcr.io/test-image"}, + } + fs = afero.NewMemMapFs() + //afero.WriteFile(fs, "/kaniko/.docker/config.json", []byte(""), os.FileMode(0644)) + CheckPushPermissions(&opts) + if called != true { + t.Error("execCommand should have been called") + } +} + +func TestCheckPushPermissionsGCRExistingDockerConf(t *testing.T) { + execCommand = fakeExecCommand + checkRemotePushPermission = fakeCheckPushPermission + defer func() { called = false }() + + opts := config.KanikoOptions{ + Destinations: []string{"gcr.io/test-image"}, + } + fs = afero.NewMemMapFs() + afero.WriteFile(fs, "/kaniko/.docker/config.json", []byte(""), os.FileMode(0644)) + CheckPushPermissions(&opts) + if called != false { + t.Error("execCommand should not have been called") + } +} + +func TestCheckPushPermissionsLocalRegistry(t *testing.T) { + execCommand = fakeExecCommand + checkRemotePushPermission = fakeCheckPushPermission + defer func() { called = false }() + + opts := config.KanikoOptions{ + Destinations: []string{"localhost:5000/test-image"}, + } + fs = afero.NewMemMapFs() + CheckPushPermissions(&opts) + if called != false { + t.Error("execCommand should not have been called") + } +} + +func TestHelperProcess(t *testing.T) { + if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" { + return + } + fmt.Fprintf(os.Stdout, "fake result") + os.Exit(0) +}