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 }