github.com/GoogleContainerTools/skaffold@v1.39.18/pkg/skaffold/tag/custom_template_test.go (about)

     1  /*
     2  Copyright 2020 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 tag
    18  
    19  import (
    20  	"context"
    21  	"testing"
    22  	"time"
    23  
    24  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest"
    25  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
    26  	"github.com/GoogleContainerTools/skaffold/testutil"
    27  )
    28  
    29  func TestTagTemplate_GenerateTag(t *testing.T) {
    30  	aLocalTimeStamp := time.Date(2015, 03, 07, 11, 06, 39, 123456789, time.Local)
    31  
    32  	dateTimeExample := &dateTimeTagger{
    33  		Format:   "2006-01-02",
    34  		TimeZone: "UTC",
    35  		timeFn:   func() time.Time { return aLocalTimeStamp },
    36  	}
    37  
    38  	envTemplateExample, _ := NewEnvTemplateTagger("{{.FOO}}")
    39  	invalidEnvTemplate, _ := NewEnvTemplateTagger("{{.BAR}}")
    40  	env := []string{"FOO=BAR"}
    41  
    42  	customTemplateExample, _ := NewCustomTemplateTagger("", nil)
    43  
    44  	tests := []struct {
    45  		description string
    46  		template    string
    47  		customMap   map[string]Tagger
    48  		expected    string
    49  		shouldErr   bool
    50  	}{
    51  		{
    52  			description: "empty template",
    53  		},
    54  		{
    55  			description: "only text",
    56  			template:    "foo-bar",
    57  			expected:    "foo-bar",
    58  		},
    59  		{
    60  			description: "only component (dateTime) in template, providing more components than necessary",
    61  			template:    "{{.FOO}}",
    62  			customMap:   map[string]Tagger{"FOO": dateTimeExample, "BAR": envTemplateExample},
    63  			expected:    "2015-03-07",
    64  		},
    65  		{
    66  			description: "envTemplate and sha256 as components",
    67  			template:    "foo-{{.FOO}}-{{.BAR}}",
    68  			customMap:   map[string]Tagger{"FOO": envTemplateExample, "BAR": &ChecksumTagger{}},
    69  			expected:    "foo-BAR-latest",
    70  		},
    71  		{
    72  			description: "using customTemplate as a component",
    73  			template:    "{{.FOO}}",
    74  			customMap:   map[string]Tagger{"FOO": customTemplateExample},
    75  			shouldErr:   true,
    76  		},
    77  		{
    78  			description: "faulty component, envTemplate has undefined references",
    79  			template:    "{{.FOO}}",
    80  			customMap:   map[string]Tagger{"FOO": invalidEnvTemplate},
    81  			shouldErr:   true,
    82  		},
    83  		{
    84  			description: "missing required components",
    85  			template:    "{{.FOO}}",
    86  			shouldErr:   true,
    87  		},
    88  		{
    89  			description: "default component name SHA",
    90  			template:    "{{.SHA}}",
    91  			expected:    "latest",
    92  		},
    93  		{
    94  			description: "override default components",
    95  			template:    "{{.GIT}}-{{.DATE}}-{{.SHA}}",
    96  			customMap:   map[string]Tagger{"GIT": dateTimeExample, "DATE": envTemplateExample, "SHA": dateTimeExample},
    97  			expected:    "2015-03-07-BAR-2015-03-07",
    98  		},
    99  	}
   100  	for _, test := range tests {
   101  		testutil.Run(t, test.description, func(t *testutil.T) {
   102  			t.Override(&util.OSEnviron, func() []string { return env })
   103  
   104  			c, err := NewCustomTemplateTagger(test.template, test.customMap)
   105  
   106  			t.CheckNoError(err)
   107  
   108  			image := latest.Artifact{
   109  				ImageName: "test",
   110  			}
   111  			tag, err := c.GenerateTag(context.Background(), image)
   112  
   113  			t.CheckErrorAndDeepEqual(test.shouldErr, err, test.expected, tag)
   114  		})
   115  	}
   116  }
   117  
   118  func TestCustomTemplate_NewCustomTemplateTagger(t *testing.T) {
   119  	tests := []struct {
   120  		description string
   121  		template    string
   122  		customMap   map[string]Tagger
   123  		shouldErr   bool
   124  	}{
   125  		{
   126  			description: "valid template with nil map",
   127  			template:    "{{.FOO}}",
   128  		},
   129  		{
   130  			description: "valid template with atleast one mapping",
   131  			template:    "{{.FOO}}",
   132  			customMap:   map[string]Tagger{"FOO": &ChecksumTagger{}},
   133  		},
   134  		{
   135  			description: "invalid template with nil mapping",
   136  			template:    "{{.FOO",
   137  			shouldErr:   true,
   138  		},
   139  		{
   140  			description: "invalid template with atleast one mapping",
   141  			template:    "{{.FOO",
   142  			customMap:   map[string]Tagger{"FOO": &ChecksumTagger{}},
   143  			shouldErr:   true,
   144  		},
   145  	}
   146  	for _, test := range tests {
   147  		testutil.Run(t, test.description, func(t *testutil.T) {
   148  			_, err := NewCustomTemplateTagger(test.template, test.customMap)
   149  			t.CheckError(test.shouldErr, err)
   150  		})
   151  	}
   152  }
   153  
   154  func TestCustomTemplate_ExecuteCustomTemplate(t *testing.T) {
   155  	tests := []struct {
   156  		description string
   157  		template    string
   158  		customMap   map[string]string
   159  		expected    string
   160  		shouldErr   bool
   161  	}{
   162  		{
   163  			description: "empty template",
   164  		},
   165  		{
   166  			description: "only text",
   167  			template:    "foo-bar",
   168  			expected:    "foo-bar",
   169  		},
   170  		{
   171  			description: "only component",
   172  			template:    "{{.FOO}}",
   173  			expected:    "2016-02-05",
   174  			customMap:   map[string]string{"FOO": "2016-02-05"},
   175  		},
   176  		{
   177  			description: "both text and components",
   178  			template:    "foo-{{.BAR}}",
   179  			expected:    "foo-2016-02-05",
   180  			customMap:   map[string]string{"BAR": "2016-02-05"},
   181  		},
   182  		{
   183  			description: "component has value with len 0",
   184  			template:    "foo-{{.BAR}}",
   185  			expected:    "foo-",
   186  			customMap:   map[string]string{"BAR": ""},
   187  		},
   188  		{
   189  			description: "undefined component",
   190  			template:    "foo-{{.BAR}}",
   191  			customMap:   map[string]string{"FOO": "2016-02-05"},
   192  			shouldErr:   true,
   193  		},
   194  	}
   195  	for _, test := range tests {
   196  		testutil.Run(t, test.description, func(t *testutil.T) {
   197  			testTemplate, err := ParseCustomTemplate(test.template)
   198  			t.CheckNoError(err)
   199  
   200  			got, err := ExecuteCustomTemplate(testTemplate.Option("missingkey=error"), test.customMap)
   201  			t.CheckErrorAndDeepEqual(test.shouldErr, err, test.expected, got)
   202  		})
   203  	}
   204  }
   205  
   206  func TestCustomTemplate_ParseCustomTemplate(t *testing.T) {
   207  	tests := []struct {
   208  		description string
   209  		template    string
   210  		shouldErr   bool
   211  	}{
   212  		{
   213  			description: "valid template",
   214  			template:    "{{.FOO}}",
   215  		},
   216  		{
   217  			description: "invalid template",
   218  			template:    "{{.FOO",
   219  			shouldErr:   true,
   220  		},
   221  	}
   222  	for _, test := range tests {
   223  		testutil.Run(t, test.description, func(t *testutil.T) {
   224  			_, err := ParseCustomTemplate(test.template)
   225  			t.CheckError(test.shouldErr, err)
   226  		})
   227  	}
   228  }