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