github.com/GoogleContainerTools/skaffold/v2@v2.13.2/integration/diagnose_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 integration
    18  
    19  import (
    20  	"bytes"
    21  	"fmt"
    22  	"os"
    23  	"path/filepath"
    24  	"testing"
    25  	"text/template"
    26  
    27  	"github.com/GoogleContainerTools/skaffold/v2/integration/skaffold"
    28  	"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/schema/latest"
    29  	"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/schema/util"
    30  	"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/yaml"
    31  	"github.com/GoogleContainerTools/skaffold/v2/testutil"
    32  )
    33  
    34  func TestDiagnoseExamples(t *testing.T) {
    35  	examples, err := folders("examples")
    36  	failNowIfError(t, err)
    37  	if len(examples) == 0 {
    38  		t.Fatal("didn't find any example")
    39  	}
    40  
    41  	for _, example := range examples {
    42  		t.Run(example, func(t *testing.T) {
    43  			MarkIntegrationTest(t, CanRunWithoutGcp)
    44  			dir := filepath.Join("examples", example)
    45  
    46  			if _, err := os.Stat(filepath.Join(dir, "skaffold.yaml")); os.IsNotExist(err) {
    47  				t.Skip("skipping diagnose in " + dir)
    48  			}
    49  
    50  			skaffold.Diagnose().InDir(dir).RunOrFail(t)
    51  		})
    52  	}
    53  }
    54  
    55  func TestDiagnose(t *testing.T) {
    56  	tests := []struct {
    57  		description string
    58  		dir         string
    59  		outputFile  string
    60  		args        []string
    61  		envs        map[string]string
    62  	}{
    63  		{
    64  			description: "single skaffold.yaml outside of source dir",
    65  			dir:         "testdata/diagnose/temp-config",
    66  			outputFile:  "abc.txt",
    67  		},
    68  		{
    69  			description: "apply replacements to templates in skaffold.yaml",
    70  			dir:         "testdata/diagnose/direct-templates",
    71  			outputFile:  "abc.txt",
    72  			args:        []string{"--enable-templating"},
    73  			envs:        map[string]string{"AAA": "aaa"},
    74  		},
    75  	}
    76  
    77  	for _, test := range tests {
    78  		MarkIntegrationTest(t, CanRunWithoutGcp)
    79  		testutil.Run(t, test.description, func(t *testutil.T) {
    80  			if test.envs != nil {
    81  				for k, v := range test.envs {
    82  					t.Setenv(k, v)
    83  				}
    84  			}
    85  			tmpDir := testutil.NewTempDir(t.T)
    86  			configContents, err := os.ReadFile(filepath.Join(test.dir, "skaffold.yaml"))
    87  			t.CheckNoError(err)
    88  			templ, err := os.ReadFile(filepath.Join(test.dir, "diagnose.tmpl"))
    89  			t.CheckNoError(err)
    90  			tmpDir.Write("skaffold.yaml", string(configContents))
    91  			args := []string{"--yaml-only", "--output", tmpDir.Path(test.outputFile), "-f", tmpDir.Path("skaffold.yaml")}
    92  			args = append(args, test.args...)
    93  			skaffold.Diagnose(args...).
    94  				InDir(test.dir).RunOrFail(t.T)
    95  			outTemplate := template.Must(template.New("tmpl").Parse(string(templ)))
    96  			cwd, err := filepath.Abs(test.dir)
    97  			t.CheckNoError(err)
    98  			expected := &bytes.Buffer{}
    99  			outTemplate.Execute(expected, map[string]string{"Root": cwd})
   100  
   101  			outputPath := tmpDir.Path(test.outputFile)
   102  			out, err := os.ReadFile(outputPath)
   103  			t.CheckNoError(err)
   104  			t.CheckDeepEqual(expected.String(), string(out), testutil.YamlObj(t.T))
   105  		})
   106  	}
   107  }
   108  
   109  // During the schema upgrade(v2beta28->v2beta29),  Skaffold injects setTemplate fields into the configuration if a legacy Helm deployer is configured.
   110  // These injected fields contain templates, and we want to ensure that when expanding them with Go templates, the original field values remain unchanged
   111  // when environment variables are not set.  This is important because users who use the skaffold diagnose command on the old schema
   112  // with Helm might not be aware  of the existence of these templated fields, leading to templating failures.
   113  func TestDiagnoseTemplatingNotAllEnvsSet(t *testing.T) {
   114  	tests := []struct {
   115  		description string
   116  		dir         string
   117  		outputFile  string
   118  		args        []string
   119  		envs        map[string]string
   120  	}{
   121  		{
   122  			description: "apply replacements to templates in skaffold.yaml",
   123  			dir:         "testdata/diagnose/not-all-envs-set",
   124  			outputFile:  "abc.txt",
   125  			args:        []string{"--enable-templating"},
   126  			envs:        map[string]string{"AAA": "aaa"},
   127  		},
   128  	}
   129  
   130  	for _, test := range tests {
   131  		MarkIntegrationTest(t, CanRunWithoutGcp)
   132  		testutil.Run(t, test.description, func(t *testutil.T) {
   133  			if test.envs != nil {
   134  				for k, v := range test.envs {
   135  					t.Setenv(k, v)
   136  				}
   137  			}
   138  			tmpDir := testutil.NewTempDir(t.T)
   139  			configContents, err := os.ReadFile(filepath.Join(test.dir, "skaffold.yaml"))
   140  			t.CheckNoError(err)
   141  			tmpDir.Write("skaffold.yaml", string(configContents))
   142  			outputPath := tmpDir.Path(test.outputFile)
   143  			args := []string{"--yaml-only", "--output", outputPath, "-f", tmpDir.Path("skaffold.yaml")}
   144  			args = append(args, test.args...)
   145  			skaffold.Diagnose(args...).
   146  				InDir(test.dir).RunOrFail(t.T)
   147  			out, err := os.ReadFile(outputPath)
   148  			t.CheckNoError(err)
   149  			var conf latest.SkaffoldConfig
   150  			yaml.Unmarshal(out, &conf)
   151  			// templates unchanged
   152  			t.CheckDeepEqual(conf.Deploy.LegacyHelmDeploy.Releases[0].SetValueTemplates, util.FlatMap{"image.repository": "{{.IMAGE_REPO_test_image}}",
   153  				"image.tag": "{{.IMAGE_TAG_test_image}}@{{.IMAGE_DIGEST_test_image}}",
   154  			})
   155  			cwd, err := filepath.Abs(test.dir)
   156  			t.CheckNoError(err)
   157  
   158  			// templates successfully expanded.
   159  			t.CheckDeepEqual(conf.Deploy.LegacyHelmDeploy.Releases[0].ValuesFiles[0], cwd+"/aaa/test-values.yaml")
   160  		})
   161  	}
   162  }
   163  
   164  func folders(root string) ([]string, error) {
   165  	var folders []string
   166  
   167  	files, err := os.ReadDir(root)
   168  	if err != nil {
   169  		return nil, err
   170  	}
   171  
   172  	for _, f := range files {
   173  		if f.IsDir() {
   174  			folders = append(folders, f.Name())
   175  		}
   176  	}
   177  
   178  	return folders, err
   179  }
   180  
   181  func TestMultiConfigDiagnose(t *testing.T) {
   182  	tests := []struct {
   183  		description string
   184  		dir         string
   185  		cpSkaffold  bool
   186  	}{
   187  		{
   188  			description: "single skaffold.yaml outside of source dir",
   189  			dir:         "testdata/diagnose/temp-config",
   190  			cpSkaffold:  true,
   191  		},
   192  		{
   193  			description: "multi skaffold.yaml outside of source dir",
   194  			dir:         "testdata/diagnose/multi-config",
   195  			cpSkaffold:  true,
   196  		},
   197  		{
   198  			description: "multi skaffold.yaml",
   199  			dir:         "testdata/diagnose/multi-config",
   200  			cpSkaffold:  false,
   201  		},
   202  	}
   203  	for _, test := range tests {
   204  		testutil.Run(t, test.description, func(t *testutil.T) {
   205  			MarkIntegrationTest(t.T, CanRunWithoutGcp)
   206  			args := []string{}
   207  			if test.cpSkaffold {
   208  				tmpDir := t.NewTempDir()
   209  				configContents, err := os.ReadFile(filepath.Join(test.dir, "skaffold.yaml"))
   210  				t.CheckNoError(err)
   211  				tmpDir.Write("skaffold.yaml", string(configContents))
   212  				args = append(args, fmt.Sprintf("-f=%s", tmpDir.Path("skaffold.yaml")))
   213  			}
   214  			out := skaffold.Diagnose(append(args, "--yaml-only")...).InDir(test.dir).RunOrFailOutput(t.T)
   215  			templ, err := os.ReadFile(filepath.Join(test.dir, "diagnose.tmpl"))
   216  			t.CheckNoError(err)
   217  			outTemplate := template.Must(template.New("tmpl").Parse(string(templ)))
   218  			cwd, err := filepath.Abs(test.dir)
   219  			t.CheckNoError(err)
   220  			expected := &bytes.Buffer{}
   221  			outTemplate.Execute(expected, map[string]string{"Root": cwd})
   222  			t.CheckDeepEqual(expected.String(), string(out), testutil.YamlObj(t.T))
   223  		})
   224  	}
   225  }