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