github.com/GoogleContainerTools/skaffold@v1.39.18/pkg/skaffold/inspect/buildEnv/add_local_test.go (about)

     1  /*
     2  Copyright 2021 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 inspect
    18  
    19  import (
    20  	"bytes"
    21  	"context"
    22  	"errors"
    23  	"fmt"
    24  	"testing"
    25  
    26  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/config"
    27  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/inspect"
    28  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/parser"
    29  	sErrors "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/errors"
    30  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest"
    31  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
    32  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util/stringslice"
    33  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/yaml"
    34  	"github.com/GoogleContainerTools/skaffold/testutil"
    35  )
    36  
    37  func TestAddLocalBuildEnv(t *testing.T) {
    38  	tests := []struct {
    39  		description     string
    40  		profile         string
    41  		modules         []string
    42  		buildEnvOpts    inspect.BuildEnvOptions
    43  		expectedConfigs []string
    44  		err             error
    45  		expectedErrMsg  string
    46  	}{
    47  		{
    48  			description:  "add to default pipeline",
    49  			buildEnvOpts: inspect.BuildEnvOptions{Push: util.BoolPtr(true), TryImportMissing: util.BoolPtr(false), UseDockerCLI: util.BoolPtr(false), UseBuildkit: nil, Concurrency: 2},
    50  			expectedConfigs: []string{
    51  				`apiVersion: ""
    52  kind: ""
    53  metadata:
    54    name: cfg1_0
    55  build:
    56    local:
    57      push: true
    58      concurrency: 2
    59  profiles:
    60  - name: p1
    61    build:
    62      cluster: {}
    63  ---
    64  apiVersion: ""
    65  kind: ""
    66  metadata:
    67    name: cfg1_1
    68  requires:
    69  - path: path/to/cfg2
    70  build:
    71    local:
    72      push: true
    73      concurrency: 2
    74  profiles:
    75  - name: p1
    76    build:
    77      cluster: {}
    78  `, ``,
    79  			},
    80  		},
    81  		{
    82  			description:  "add to existing profile",
    83  			profile:      "p1",
    84  			buildEnvOpts: inspect.BuildEnvOptions{Push: util.BoolPtr(true), TryImportMissing: util.BoolPtr(false), UseDockerCLI: util.BoolPtr(false), UseBuildkit: nil, Concurrency: 2},
    85  			expectedConfigs: []string{
    86  				`apiVersion: ""
    87  kind: ""
    88  metadata:
    89    name: cfg1_0
    90  build:
    91    googleCloudBuild: {}
    92  profiles:
    93  - name: p1
    94    build:
    95      local:
    96        push: true
    97        concurrency: 2
    98  ---
    99  apiVersion: ""
   100  kind: ""
   101  metadata:
   102    name: cfg1_1
   103  requires:
   104  - path: path/to/cfg2
   105  build:
   106    googleCloudBuild: {}
   107  profiles:
   108  - name: p1
   109    build:
   110      local:
   111        push: true
   112        concurrency: 2
   113  `, `apiVersion: ""
   114  kind: ""
   115  metadata:
   116    name: cfg2
   117  build:
   118    googleCloudBuild: {}
   119  profiles:
   120  - name: p1
   121    build:
   122      local:
   123        push: true
   124        concurrency: 2
   125  `,
   126  			},
   127  		},
   128  		{
   129  			description:  "add to new profile",
   130  			profile:      "p2",
   131  			buildEnvOpts: inspect.BuildEnvOptions{Push: util.BoolPtr(true), TryImportMissing: util.BoolPtr(false), UseDockerCLI: util.BoolPtr(false), UseBuildkit: nil, Concurrency: 2},
   132  			expectedConfigs: []string{
   133  				`apiVersion: ""
   134  kind: ""
   135  metadata:
   136    name: cfg1_0
   137  build:
   138    googleCloudBuild: {}
   139  profiles:
   140  - name: p1
   141    build:
   142      cluster: {}
   143  - name: p2
   144    build:
   145      local:
   146        push: true
   147        concurrency: 2
   148  ---
   149  apiVersion: ""
   150  kind: ""
   151  metadata:
   152    name: cfg1_1
   153  requires:
   154  - path: path/to/cfg2
   155  build:
   156    googleCloudBuild: {}
   157  profiles:
   158  - name: p1
   159    build:
   160      cluster: {}
   161  - name: p2
   162    build:
   163      local:
   164        push: true
   165        concurrency: 2
   166  `, `apiVersion: ""
   167  kind: ""
   168  metadata:
   169    name: cfg2
   170  build:
   171    googleCloudBuild: {}
   172  profiles:
   173  - name: p1
   174    build:
   175      googleCloudBuild: {}
   176  - name: p2
   177    build:
   178      local:
   179        push: true
   180        concurrency: 2
   181  `,
   182  			},
   183  		},
   184  		{
   185  			description:  "add to new profile in selected modules",
   186  			modules:      []string{"cfg1_1"},
   187  			profile:      "p2",
   188  			buildEnvOpts: inspect.BuildEnvOptions{Push: util.BoolPtr(true), TryImportMissing: util.BoolPtr(false), UseDockerCLI: util.BoolPtr(false), UseBuildkit: nil, Concurrency: 2},
   189  			expectedConfigs: []string{
   190  				`apiVersion: ""
   191  kind: ""
   192  metadata:
   193    name: cfg1_0
   194  build:
   195    googleCloudBuild: {}
   196  profiles:
   197  - name: p1
   198    build:
   199      cluster: {}
   200  ---
   201  apiVersion: ""
   202  kind: ""
   203  metadata:
   204    name: cfg1_1
   205  requires:
   206  - path: path/to/cfg2
   207  build:
   208    googleCloudBuild: {}
   209  profiles:
   210  - name: p1
   211    build:
   212      cluster: {}
   213  - name: p2
   214    build:
   215      local:
   216        push: true
   217        concurrency: 2
   218  `, `apiVersion: ""
   219  kind: ""
   220  metadata:
   221    name: cfg2
   222  build:
   223    googleCloudBuild: {}
   224  profiles:
   225  - name: p1
   226    build:
   227      googleCloudBuild: {}
   228  - name: p2
   229    build:
   230      local:
   231        push: true
   232        concurrency: 2
   233  `, "",
   234  			},
   235  		},
   236  		{
   237  			description:  "add to new profile in nested module",
   238  			modules:      []string{"cfg2"},
   239  			profile:      "p2",
   240  			buildEnvOpts: inspect.BuildEnvOptions{Push: util.BoolPtr(true), TryImportMissing: util.BoolPtr(false), UseDockerCLI: util.BoolPtr(false), UseBuildkit: nil, Concurrency: 2},
   241  			expectedConfigs: []string{"",
   242  				`apiVersion: ""
   243  kind: ""
   244  metadata:
   245    name: cfg2
   246  build:
   247    googleCloudBuild: {}
   248  profiles:
   249  - name: p1
   250    build:
   251      googleCloudBuild: {}
   252  - name: p2
   253    build:
   254      local:
   255        push: true
   256        concurrency: 2
   257  `,
   258  			},
   259  		},
   260  		{
   261  			description:    "actionable error",
   262  			err:            sErrors.MainConfigFileNotFoundErr("path/to/skaffold.yaml", fmt.Errorf("failed to read file : %q", "skaffold.yaml")),
   263  			expectedErrMsg: `{"errorCode":"CONFIG_FILE_NOT_FOUND_ERR","errorMessage":"unable to find configuration file \"path/to/skaffold.yaml\": failed to read file : \"skaffold.yaml\". Check that the specified configuration file exists at \"path/to/skaffold.yaml\"."}` + "\n",
   264  		},
   265  		{
   266  			description:    "generic error",
   267  			err:            errors.New("some error occurred"),
   268  			expectedErrMsg: `{"errorCode":"INSPECT_UNKNOWN_ERR","errorMessage":"some error occurred"}` + "\n",
   269  		},
   270  	}
   271  	for _, test := range tests {
   272  		testutil.Run(t, test.description, func(t *testutil.T) {
   273  			configSet := parser.SkaffoldConfigSet{
   274  				&parser.SkaffoldConfigEntry{SkaffoldConfig: &latest.SkaffoldConfig{
   275  					Metadata: latest.Metadata{Name: "cfg1_0"},
   276  					Pipeline: latest.Pipeline{Build: latest.BuildConfig{BuildType: latest.BuildType{GoogleCloudBuild: &latest.GoogleCloudBuild{}}}},
   277  					Profiles: []latest.Profile{
   278  						{Name: "p1", Pipeline: latest.Pipeline{Build: latest.BuildConfig{BuildType: latest.BuildType{Cluster: &latest.ClusterDetails{}}}}},
   279  					}}, SourceFile: pathToCfg1, IsRootConfig: true, SourceIndex: 0},
   280  				&parser.SkaffoldConfigEntry{SkaffoldConfig: &latest.SkaffoldConfig{
   281  					Metadata:     latest.Metadata{Name: "cfg1_1"},
   282  					Dependencies: []latest.ConfigDependency{{Path: pathToCfg2}},
   283  					Pipeline:     latest.Pipeline{Build: latest.BuildConfig{BuildType: latest.BuildType{GoogleCloudBuild: &latest.GoogleCloudBuild{}}}},
   284  					Profiles: []latest.Profile{
   285  						{Name: "p1", Pipeline: latest.Pipeline{Build: latest.BuildConfig{BuildType: latest.BuildType{Cluster: &latest.ClusterDetails{}}}}},
   286  					}}, SourceFile: pathToCfg1, IsRootConfig: true, SourceIndex: 1},
   287  				&parser.SkaffoldConfigEntry{SkaffoldConfig: &latest.SkaffoldConfig{
   288  					Metadata: latest.Metadata{Name: "cfg2"},
   289  					Pipeline: latest.Pipeline{Build: latest.BuildConfig{BuildType: latest.BuildType{GoogleCloudBuild: &latest.GoogleCloudBuild{}}}},
   290  					Profiles: []latest.Profile{
   291  						{Name: "p1", Pipeline: latest.Pipeline{Build: latest.BuildConfig{BuildType: latest.BuildType{GoogleCloudBuild: &latest.GoogleCloudBuild{}}}}},
   292  					}}, SourceFile: pathToCfg2, SourceIndex: 0},
   293  			}
   294  			t.Override(&inspect.GetConfigSet, func(ctx context.Context, opts config.SkaffoldOptions) (parser.SkaffoldConfigSet, error) {
   295  				if test.err != nil {
   296  					return nil, test.err
   297  				}
   298  				var sets parser.SkaffoldConfigSet
   299  				if len(opts.ConfigurationFilter) == 0 || stringslice.Contains(opts.ConfigurationFilter, "cfg2") || stringslice.Contains(opts.ConfigurationFilter, "cfg1_1") {
   300  					sets = append(sets, configSet[2])
   301  				}
   302  				if len(opts.ConfigurationFilter) == 0 || stringslice.Contains(opts.ConfigurationFilter, "cfg1_0") {
   303  					sets = append(sets, configSet[0])
   304  				}
   305  				if len(opts.ConfigurationFilter) == 0 || stringslice.Contains(opts.ConfigurationFilter, "cfg1_1") {
   306  					sets = append(sets, configSet[1])
   307  				}
   308  				return sets, nil
   309  			})
   310  			t.Override(&inspect.ReadFileFunc, func(filename string) ([]byte, error) {
   311  				if filename == pathToCfg1 {
   312  					return yaml.MarshalWithSeparator([]*latest.SkaffoldConfig{configSet[0].SkaffoldConfig, configSet[1].SkaffoldConfig})
   313  				} else if filename == pathToCfg2 {
   314  					return yaml.MarshalWithSeparator([]*latest.SkaffoldConfig{configSet[2].SkaffoldConfig})
   315  				}
   316  				t.FailNow()
   317  				return nil, nil
   318  			})
   319  			var actualCfg1, actualCfg2 string
   320  			t.Override(&inspect.WriteFileFunc, func(filename string, data []byte) error {
   321  				switch filename {
   322  				case pathToCfg1:
   323  					actualCfg1 = string(data)
   324  				case pathToCfg2:
   325  					actualCfg2 = string(data)
   326  				default:
   327  					t.FailNow()
   328  				}
   329  				return nil
   330  			})
   331  
   332  			var buf bytes.Buffer
   333  			err := AddLocalBuildEnv(context.Background(), &buf, inspect.Options{OutFormat: "json", Modules: test.modules, Profile: test.profile, BuildEnvOptions: test.buildEnvOpts})
   334  			t.CheckError(test.err != nil, err)
   335  			if test.err == nil {
   336  				t.CheckDeepEqual(test.expectedConfigs[0], actualCfg1, testutil.YamlObj(t.T))
   337  				t.CheckDeepEqual(test.expectedConfigs[1], actualCfg2, testutil.YamlObj(t.T))
   338  			} else {
   339  				t.CheckDeepEqual(test.expectedErrMsg, buf.String())
   340  			}
   341  		})
   342  	}
   343  }