github.com/GoogleContainerTools/skaffold@v1.39.18/pkg/skaffold/runner/v1/build_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 v1
    18  
    19  import (
    20  	"context"
    21  	"errors"
    22  	"io/ioutil"
    23  	"testing"
    24  
    25  	"k8s.io/client-go/tools/clientcmd/api"
    26  
    27  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/config"
    28  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/graph"
    29  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubernetes/client"
    30  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/runner"
    31  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest"
    32  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
    33  	"github.com/GoogleContainerTools/skaffold/testutil"
    34  )
    35  
    36  func TestTest(t *testing.T) {
    37  	tests := []struct {
    38  		description     string
    39  		testBench       *TestBench
    40  		cfg             []*latest.Artifact
    41  		artifacts       []graph.Artifact
    42  		expectedActions []Actions
    43  		shouldErr       bool
    44  	}{
    45  		{
    46  			description: "test no error",
    47  			testBench:   &TestBench{},
    48  			cfg:         []*latest.Artifact{{ImageName: "img1"}, {ImageName: "img2"}},
    49  			artifacts: []graph.Artifact{
    50  				{ImageName: "img1", Tag: "img1:tag1"},
    51  				{ImageName: "img2", Tag: "img2:tag2"},
    52  			},
    53  			expectedActions: []Actions{{
    54  				Tested: []string{"img1:tag1", "img2:tag2"},
    55  			}},
    56  		},
    57  		{
    58  			description:     "no artifacts",
    59  			testBench:       &TestBench{},
    60  			artifacts:       []graph.Artifact(nil),
    61  			expectedActions: []Actions{{}},
    62  		},
    63  		{
    64  			description: "missing tag",
    65  			testBench:   &TestBench{},
    66  			cfg:         []*latest.Artifact{{ImageName: "image1"}},
    67  			artifacts:   []graph.Artifact{{ImageName: "image1"}},
    68  			expectedActions: []Actions{{
    69  				Tested: []string{""},
    70  			}},
    71  		},
    72  		{
    73  			description:     "test error",
    74  			testBench:       &TestBench{testErrors: []error{errors.New("")}},
    75  			expectedActions: []Actions{{}},
    76  			shouldErr:       true,
    77  		},
    78  	}
    79  	for _, test := range tests {
    80  		testutil.Run(t, test.description, func(t *testutil.T) {
    81  			runner := createRunner(t, test.testBench, nil, test.cfg, nil)
    82  
    83  			err := runner.Test(context.Background(), ioutil.Discard, test.artifacts)
    84  
    85  			t.CheckError(test.shouldErr, err)
    86  
    87  			t.CheckErrorAndDeepEqual(test.shouldErr, err, test.expectedActions, test.testBench.Actions())
    88  		})
    89  	}
    90  }
    91  
    92  func TestBuildTestDeploy(t *testing.T) {
    93  	tests := []struct {
    94  		description     string
    95  		testBench       *TestBench
    96  		shouldErr       bool
    97  		expectedActions []Actions
    98  	}{
    99  		{
   100  			description: "run no error",
   101  			testBench:   &TestBench{},
   102  			expectedActions: []Actions{{
   103  				Built:    []string{"img:1"},
   104  				Tested:   []string{"img:1"},
   105  				Deployed: []string{"img:1"},
   106  			}},
   107  		},
   108  		{
   109  			description:     "run build error",
   110  			testBench:       &TestBench{buildErrors: []error{errors.New("")}},
   111  			shouldErr:       true,
   112  			expectedActions: []Actions{{}},
   113  		},
   114  		{
   115  			description: "run test error",
   116  			testBench:   &TestBench{testErrors: []error{errors.New("")}},
   117  			shouldErr:   true,
   118  			expectedActions: []Actions{{
   119  				Built: []string{"img:1"},
   120  			}},
   121  		},
   122  		{
   123  			description: "run deploy error",
   124  			testBench:   &TestBench{deployErrors: []error{errors.New("")}},
   125  			shouldErr:   true,
   126  			expectedActions: []Actions{{
   127  				Built:  []string{"img:1"},
   128  				Tested: []string{"img:1"},
   129  			}},
   130  		},
   131  	}
   132  	for _, test := range tests {
   133  		testutil.Run(t, test.description, func(t *testutil.T) {
   134  			t.SetupFakeKubernetesContext(api.Config{CurrentContext: "cluster1"})
   135  			t.Override(&client.Client, mockK8sClient)
   136  
   137  			ctx := context.Background()
   138  			artifacts := []*latest.Artifact{{
   139  				ImageName: "img",
   140  			}}
   141  
   142  			runner := createRunner(t, test.testBench, nil, artifacts, nil)
   143  			bRes, err := runner.Build(ctx, ioutil.Discard, artifacts)
   144  			if err == nil {
   145  				err = runner.Test(ctx, ioutil.Discard, bRes)
   146  				if err == nil {
   147  					err = runner.DeployAndLog(ctx, ioutil.Discard, bRes)
   148  				}
   149  			}
   150  
   151  			t.CheckErrorAndDeepEqual(test.shouldErr, err, test.expectedActions, test.testBench.Actions())
   152  		})
   153  	}
   154  }
   155  
   156  func TestBuildDryRun(t *testing.T) {
   157  	testutil.Run(t, "", func(t *testutil.T) {
   158  		testBench := &TestBench{}
   159  		artifacts := []*latest.Artifact{
   160  			{ImageName: "img1"},
   161  			{ImageName: "img2"},
   162  		}
   163  		runner := createRunner(t, testBench, nil, artifacts, nil)
   164  		runner.runCtx.Opts.DryRun = true
   165  
   166  		bRes, err := runner.Build(context.Background(), ioutil.Discard, artifacts)
   167  
   168  		t.CheckNoError(err)
   169  		t.CheckDeepEqual([]graph.Artifact{
   170  			{ImageName: "img1", Tag: "img1:latest"},
   171  			{ImageName: "img2", Tag: "img2:latest"}}, bRes)
   172  		// Nothing was built, tested or deployed
   173  		t.CheckDeepEqual([]Actions{{}}, testBench.Actions())
   174  	})
   175  }
   176  
   177  func TestBuildPushFlag(t *testing.T) {
   178  	testutil.Run(t, "", func(t *testutil.T) {
   179  		testBench := &TestBench{}
   180  		artifacts := []*latest.Artifact{
   181  			{ImageName: "img1"},
   182  			{ImageName: "img2"},
   183  		}
   184  		runner := createRunner(t, testBench, nil, artifacts, nil)
   185  		runner.runCtx.Opts.PushImages = config.NewBoolOrUndefined(util.BoolPtr(true))
   186  
   187  		_, err := runner.Build(context.Background(), ioutil.Discard, artifacts)
   188  
   189  		t.CheckNoError(err)
   190  	})
   191  }
   192  
   193  func TestDigestSources(t *testing.T) {
   194  	artifacts := []*latest.Artifact{
   195  		{ImageName: "img1"},
   196  	}
   197  
   198  	tests := []struct {
   199  		name         string
   200  		digestSource string
   201  		expected     []graph.Artifact
   202  	}{
   203  		{
   204  			name:         "digest source none",
   205  			digestSource: "none",
   206  			expected:     []graph.Artifact{},
   207  		},
   208  		{
   209  			name:         "digest source tag",
   210  			digestSource: "tag",
   211  			expected: []graph.Artifact{
   212  				{ImageName: "img1", Tag: "img1:latest"},
   213  			},
   214  		},
   215  		{
   216  			name:         "digest source remote",
   217  			digestSource: "remote",
   218  			expected: []graph.Artifact{
   219  				{ImageName: "img1", Tag: "img1:latest"},
   220  			},
   221  		},
   222  	}
   223  	for _, test := range tests {
   224  		testutil.Run(t, test.name, func(t *testutil.T) {
   225  			testBench := &TestBench{}
   226  			runner := createRunner(t, testBench, nil, artifacts, nil)
   227  			runner.runCtx.Opts.DigestSource = test.digestSource
   228  			runner.runCtx.Opts.RenderOnly = true
   229  
   230  			bRes, err := runner.Build(context.Background(), ioutil.Discard, artifacts)
   231  
   232  			t.CheckNoError(err)
   233  			t.CheckDeepEqual(test.expected, bRes)
   234  			t.CheckDeepEqual([]Actions{{}}, testBench.Actions())
   235  		})
   236  	}
   237  }
   238  
   239  func TestCheckWorkspaces(t *testing.T) {
   240  	tmpDir := testutil.NewTempDir(t).Touch("file")
   241  	tmpFile := tmpDir.Path("file")
   242  
   243  	tests := []struct {
   244  		description string
   245  		artifacts   []*latest.Artifact
   246  		shouldErr   bool
   247  	}{
   248  		{
   249  			description: "no workspace",
   250  			artifacts: []*latest.Artifact{
   251  				{
   252  					ImageName: "image",
   253  				},
   254  			},
   255  		},
   256  		{
   257  			description: "directory that exists",
   258  			artifacts: []*latest.Artifact{
   259  				{
   260  					ImageName: "image",
   261  					Workspace: tmpDir.Root(),
   262  				},
   263  			},
   264  		},
   265  		{
   266  			description: "error on non-existent location",
   267  			artifacts: []*latest.Artifact{
   268  				{
   269  					ImageName: "image",
   270  					Workspace: "doesnotexist",
   271  				},
   272  			},
   273  			shouldErr: true,
   274  		},
   275  		{
   276  			description: "error on file",
   277  			artifacts: []*latest.Artifact{
   278  				{
   279  					ImageName: "image",
   280  					Workspace: tmpFile,
   281  				},
   282  			},
   283  			shouldErr: true,
   284  		},
   285  	}
   286  	for _, test := range tests {
   287  		testutil.Run(t, test.description, func(t *testutil.T) {
   288  			err := runner.CheckWorkspaces(test.artifacts)
   289  			t.CheckError(test.shouldErr, err)
   290  		})
   291  	}
   292  }