github.com/GoogleContainerTools/skaffold@v1.39.18/pkg/skaffold/build/custom/script_test.go (about)

     1  /*
     2  Copyright 2019 The Skaffold Authors
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package custom
    18  
    19  import (
    20  	"context"
    21  	"io/ioutil"
    22  	"os/exec"
    23  	"runtime"
    24  	"testing"
    25  
    26  	v1 "github.com/opencontainers/image-spec/specs-go/v1"
    27  
    28  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/platform"
    29  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest"
    30  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
    31  	"github.com/GoogleContainerTools/skaffold/testutil"
    32  )
    33  
    34  func TestRetrieveEnv(t *testing.T) {
    35  	tests := []struct {
    36  		description   string
    37  		tag           string
    38  		pushImages    bool
    39  		buildContext  string
    40  		additionalEnv []string
    41  		environ       []string
    42  		platforms     platform.Matcher
    43  		expected      []string
    44  	}{
    45  
    46  		{
    47  			description:  "make sure tags are correct",
    48  			tag:          "gcr.io/image/tag:mytag",
    49  			environ:      nil,
    50  			buildContext: "/some/path",
    51  			platforms:    platform.Matcher{Platforms: []v1.Platform{{OS: "linux", Architecture: "amd64"}, {OS: "linux", Architecture: "arm64"}}},
    52  			expected:     []string{"IMAGE=gcr.io/image/tag:mytag", "PUSH_IMAGE=false", "BUILD_CONTEXT=/some/path", "PLATFORMS=linux/amd64,linux/arm64", "SKIP_TEST=false", "IMAGE_REPO=gcr.io/image/tag", "IMAGE_TAG=mytag"},
    53  		}, {
    54  			description:  "make sure environ is correctly applied",
    55  			tag:          "gcr.io/image/tag:anothertag",
    56  			environ:      []string{"PATH=/path", "HOME=/root"},
    57  			buildContext: "/some/path",
    58  			expected:     []string{"IMAGE=gcr.io/image/tag:anothertag", "PUSH_IMAGE=false", "BUILD_CONTEXT=/some/path", "PLATFORMS=", "SKIP_TEST=false", "IMAGE_REPO=gcr.io/image/tag", "IMAGE_TAG=anothertag", "PATH=/path", "HOME=/root"},
    59  		}, {
    60  			description: "all platforms",
    61  			tag:         "gcr.io/image/push:tag",
    62  			pushImages:  true,
    63  			platforms:   platform.All,
    64  			expected:    []string{"IMAGE=gcr.io/image/push:tag", "PUSH_IMAGE=true", "BUILD_CONTEXT=", "PLATFORMS=all", "SKIP_TEST=false", "IMAGE_REPO=gcr.io/image/push", "IMAGE_TAG=tag"},
    65  		}, {
    66  			description: "push image is true",
    67  			tag:         "gcr.io/image/push:tag",
    68  			pushImages:  true,
    69  			expected:    []string{"IMAGE=gcr.io/image/push:tag", "PUSH_IMAGE=true", "BUILD_CONTEXT=", "PLATFORMS=", "SKIP_TEST=false", "IMAGE_REPO=gcr.io/image/push", "IMAGE_TAG=tag"},
    70  		}, {
    71  			description:   "add additional env",
    72  			tag:           "gcr.io/image/push:tag",
    73  			pushImages:    true,
    74  			additionalEnv: []string{"KUBECONTEXT=mycluster"},
    75  			expected:      []string{"IMAGE=gcr.io/image/push:tag", "PUSH_IMAGE=true", "BUILD_CONTEXT=", "PLATFORMS=", "SKIP_TEST=false", "IMAGE_REPO=gcr.io/image/push", "IMAGE_TAG=tag", "KUBECONTEXT=mycluster"},
    76  		},
    77  	}
    78  	for _, test := range tests {
    79  		testutil.Run(t, test.description, func(t *testutil.T) {
    80  			t.Override(&util.OSEnviron, func() []string { return test.environ })
    81  			t.Override(&buildContext, func(string) (string, error) { return test.buildContext, nil })
    82  
    83  			builder := NewArtifactBuilder(nil, nil, test.pushImages, false, test.additionalEnv)
    84  			actual, err := builder.retrieveEnv(&latest.Artifact{}, test.tag, test.platforms)
    85  
    86  			t.CheckNoError(err)
    87  			t.CheckDeepEqual(test.expected, actual)
    88  		})
    89  	}
    90  }
    91  
    92  func TestRetrieveCmd(t *testing.T) {
    93  	tests := []struct {
    94  		description       string
    95  		artifact          *latest.Artifact
    96  		tag               string
    97  		env               []string
    98  		expected          *exec.Cmd
    99  		expectedOnWindows *exec.Cmd
   100  	}{
   101  		{
   102  			description: "artifact with workspace set",
   103  			artifact: &latest.Artifact{
   104  				Workspace: "workspace",
   105  				ArtifactType: latest.ArtifactType{
   106  					CustomArtifact: &latest.CustomArtifact{
   107  						BuildCommand: "./build.sh",
   108  					},
   109  				},
   110  			},
   111  			tag:               "image:tag",
   112  			expected:          expectedCmd("workspace", "sh", []string{"-c", "./build.sh"}, []string{"IMAGE=image:tag", "PUSH_IMAGE=false", "BUILD_CONTEXT=workspace", "PLATFORMS=", "SKIP_TEST=true", "IMAGE_REPO=image", "IMAGE_TAG=tag"}),
   113  			expectedOnWindows: expectedCmd("workspace", "cmd.exe", []string{"/C", "./build.sh"}, []string{"IMAGE=image:tag", "PUSH_IMAGE=false", "BUILD_CONTEXT=workspace", "PLATFORMS=", "SKIP_TEST=true", "IMAGE_REPO=image", "IMAGE_TAG=tag"}),
   114  		},
   115  		{
   116  			description: "buildcommand with multiple args",
   117  			artifact: &latest.Artifact{
   118  				ArtifactType: latest.ArtifactType{
   119  					CustomArtifact: &latest.CustomArtifact{
   120  						BuildCommand: "./build.sh --flag=$IMAGES --anotherflag",
   121  					},
   122  				},
   123  			},
   124  			tag:               "image:tag",
   125  			expected:          expectedCmd("", "sh", []string{"-c", "./build.sh --flag=$IMAGES --anotherflag"}, []string{"IMAGE=image:tag", "PUSH_IMAGE=false", "BUILD_CONTEXT=", "PLATFORMS=", "SKIP_TEST=true", "IMAGE_REPO=image", "IMAGE_TAG=tag"}),
   126  			expectedOnWindows: expectedCmd("", "cmd.exe", []string{"/C", "./build.sh --flag=$IMAGES --anotherflag"}, []string{"IMAGE=image:tag", "PUSH_IMAGE=false", "BUILD_CONTEXT=", "PLATFORMS=", "SKIP_TEST=true", "IMAGE_REPO=image", "IMAGE_TAG=tag"}),
   127  		},
   128  		{
   129  			description: "buildcommand with go template",
   130  			artifact: &latest.Artifact{
   131  				ArtifactType: latest.ArtifactType{
   132  					CustomArtifact: &latest.CustomArtifact{
   133  						BuildCommand: "./build.sh --flag={{ .FLAG }}",
   134  					},
   135  				},
   136  			},
   137  			tag:               "image:tag",
   138  			env:               []string{"FLAG=some-flag"},
   139  			expected:          expectedCmd("", "sh", []string{"-c", "./build.sh --flag=some-flag"}, []string{"IMAGE=image:tag", "PUSH_IMAGE=false", "BUILD_CONTEXT=", "PLATFORMS=", "SKIP_TEST=true", "IMAGE_REPO=image", "IMAGE_TAG=tag", "FLAG=some-flag"}),
   140  			expectedOnWindows: expectedCmd("", "cmd.exe", []string{"/C", "./build.sh --flag=some-flag"}, []string{"IMAGE=image:tag", "PUSH_IMAGE=false", "BUILD_CONTEXT=", "PLATFORMS=", "SKIP_TEST=true", "IMAGE_REPO=image", "IMAGE_TAG=tag", "FLAG=some-flag"}),
   141  		},
   142  	}
   143  	for _, test := range tests {
   144  		testutil.Run(t, test.description, func(t *testutil.T) {
   145  			t.Override(&util.OSEnviron, func() []string { return test.env })
   146  			t.Override(&buildContext, func(string) (string, error) { return test.artifact.Workspace, nil })
   147  
   148  			builder := NewArtifactBuilder(nil, nil, false, true, nil)
   149  			cmd, err := builder.retrieveCmd(context.Background(), ioutil.Discard, test.artifact, test.tag, platform.Matcher{})
   150  
   151  			t.CheckNoError(err)
   152  			if runtime.GOOS == "windows" {
   153  				t.CheckDeepEqual(test.expectedOnWindows.Args, cmd.Args)
   154  				t.CheckDeepEqual(test.expectedOnWindows.Dir, cmd.Dir)
   155  				t.CheckDeepEqual(test.expectedOnWindows.Env, cmd.Env)
   156  			} else {
   157  				t.CheckDeepEqual(test.expected.Args, cmd.Args)
   158  				t.CheckDeepEqual(test.expected.Dir, cmd.Dir)
   159  				t.CheckDeepEqual(test.expected.Env, cmd.Env)
   160  			}
   161  		})
   162  	}
   163  }
   164  
   165  func expectedCmd(dir, buildCommand string, args, env []string) *exec.Cmd {
   166  	cmd := exec.Command(buildCommand, args...)
   167  	cmd.Dir = dir
   168  	cmd.Env = env
   169  	return cmd
   170  }