Skip to content

Commit 04ebfde

Browse files
committed
Add a new func to return ImageConfig with a new mapped image field
The current GetMappedImageConfigs returns the map with only mapped image config. The new func GetImageConfigsWithMappedImage will return original image information along with mapped one. Signed-off-by: Vu Dinh <[email protected]>
1 parent 1b675e1 commit 04ebfde

File tree

2 files changed

+134
-0
lines changed

2 files changed

+134
-0
lines changed

test/utils/image/manifest.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ type Config struct {
5252
version string
5353
}
5454

55+
type ConfigWithMapped struct {
56+
Config
57+
mapped Config
58+
}
59+
5560
// SetRegistry sets an image registry in a Config struct
5661
func (i *Config) SetRegistry(registry string) {
5762
i.registry = registry
@@ -285,6 +290,32 @@ func GetMappedImageConfigs(originalImageConfigs map[ImageID]Config, repo string)
285290
return configs
286291
}
287292

293+
func GetImageConfigsWithMappedImage(originalImageConfigs map[ImageID]Config, repo string) map[ImageID]ConfigWithMapped {
294+
configs := make(map[ImageID]ConfigWithMapped)
295+
for i, config := range originalImageConfigs {
296+
switch i {
297+
case InvalidRegistryImage, AuthenticatedAlpine,
298+
AuthenticatedWindowsNanoServer, AgnhostPrivate:
299+
// These images are special and can't be run out of the cloud - some because they
300+
// are authenticated, and others because they are not real images. Tests that depend
301+
// on these images can't be run without access to the public internet.
302+
configs[i] = ConfigWithMapped{
303+
Config: config,
304+
}
305+
continue
306+
}
307+
308+
// Build a new tag with the ImageID, a hash of the image spec (to be unique) and
309+
// shorten and make the pull spec "safe" so it will fit in the tag
310+
mappedConfig := getRepositoryMappedConfig(i, config, repo)
311+
configs[i] = ConfigWithMapped{
312+
Config: config,
313+
mapped: mappedConfig,
314+
}
315+
}
316+
return configs
317+
}
318+
288319
var (
289320
reCharSafe = regexp.MustCompile(`[^\w]`)
290321
reDashes = regexp.MustCompile(`-+`)

test/utils/image/manifest_test.go

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package image
1919
import (
2020
"fmt"
2121
"reflect"
22+
"strings"
2223
"testing"
2324

2425
"github.com/google/go-cmp/cmp"
@@ -172,3 +173,105 @@ func TestGetMappedImageConfigs(t *testing.T) {
172173
t.Fatal(cmp.Diff(expected, actual))
173174
}
174175
}
176+
177+
func TestGetImageConfigsWithMappedImage(t *testing.T) {
178+
tests := []struct {
179+
name string
180+
originalImageConfigs map[ImageID]Config
181+
repo string
182+
specialImages []ImageID // Images that should not be mapped
183+
}{
184+
{
185+
name: "maps normal images to new repository",
186+
originalImageConfigs: map[ImageID]Config{
187+
Agnhost: {registry: "registry.k8s.io/e2e-test-images", name: "agnhost", version: "2.47"},
188+
BusyBox: {registry: "registry.k8s.io/e2e-test-images", name: "busybox", version: "1.36.1-1"},
189+
},
190+
repo: "quay.io/test/repo",
191+
specialImages: []ImageID{},
192+
},
193+
{
194+
name: "does not map special images",
195+
originalImageConfigs: map[ImageID]Config{
196+
InvalidRegistryImage: {registry: "invalid.registry.k8s.io/invalid", name: "alpine", version: "3.1"},
197+
AuthenticatedAlpine: {registry: "gcr.io/authenticated-image-pulling", name: "alpine", version: "3.7"},
198+
AuthenticatedWindowsNanoServer: {registry: "gcr.io/authenticated-image-pulling", name: "windows-nanoserver", version: "v1"},
199+
AgnhostPrivate: {registry: "gcr.io/k8s-authenticated-test", name: "agnhost", version: "2.6"},
200+
},
201+
repo: "quay.io/test/repo",
202+
specialImages: []ImageID{InvalidRegistryImage, AuthenticatedAlpine, AuthenticatedWindowsNanoServer, AgnhostPrivate},
203+
},
204+
{
205+
name: "handles mixed normal and special images",
206+
originalImageConfigs: map[ImageID]Config{
207+
Nginx: {registry: "registry.k8s.io/e2e-test-images", name: "nginx", version: "1.14-4"},
208+
AuthenticatedAlpine: {registry: "gcr.io/authenticated-image-pulling", name: "alpine", version: "3.7"},
209+
Pause: {registry: "registry.k8s.io", name: "pause", version: "3.9"},
210+
InvalidRegistryImage: {registry: "invalid.registry.k8s.io/invalid", name: "alpine", version: "3.1"},
211+
},
212+
repo: "my-registry.io/my-repo",
213+
specialImages: []ImageID{AuthenticatedAlpine, InvalidRegistryImage},
214+
},
215+
{
216+
name: "handles empty input",
217+
originalImageConfigs: map[ImageID]Config{},
218+
repo: "quay.io/test/repo",
219+
specialImages: []ImageID{},
220+
},
221+
}
222+
223+
for _, tt := range tests {
224+
t.Run(tt.name, func(t *testing.T) {
225+
result := GetImageConfigsWithMappedImage(tt.originalImageConfigs, tt.repo)
226+
227+
if len(result) != len(tt.originalImageConfigs) {
228+
t.Errorf("expected %d mapped configs, got %d", len(tt.originalImageConfigs), len(result))
229+
}
230+
231+
for imageID, originalConfig := range tt.originalImageConfigs {
232+
actualConfigWithMapped, exists := result[imageID]
233+
if !exists {
234+
t.Errorf("expected imageID %v to be present in result", imageID)
235+
continue
236+
}
237+
238+
// Check that original config is preserved
239+
actualOriginalImage := actualConfigWithMapped.Config.GetE2EImage()
240+
expectedOriginalImage := originalConfig.GetE2EImage()
241+
if actualOriginalImage != expectedOriginalImage {
242+
t.Errorf("original config mismatch for imageID %v: expected %q, got %q", imageID, expectedOriginalImage, actualOriginalImage)
243+
}
244+
245+
// Check if this is a special image that should not be mapped
246+
isSpecial := false
247+
for _, specialID := range tt.specialImages {
248+
if imageID == specialID {
249+
isSpecial = true
250+
break
251+
}
252+
}
253+
254+
actualMappedImage := actualConfigWithMapped.mapped.GetE2EImage()
255+
if isSpecial {
256+
// Special images should have empty mapped config (which results in "/:")
257+
if actualMappedImage != "/:" {
258+
t.Errorf("special image %v should have empty mapped config (resulting in '/:'), got %q", imageID, actualMappedImage)
259+
}
260+
} else {
261+
// Normal images should have a mapped config that's different from original
262+
if actualMappedImage == "" || actualMappedImage == "/:" {
263+
t.Errorf("normal image %v should have non-empty mapped config, got %q", imageID, actualMappedImage)
264+
}
265+
if actualMappedImage == actualOriginalImage {
266+
t.Errorf("mapped image should be different from original for imageID %v", imageID)
267+
}
268+
// Verify the mapped image uses the new repository
269+
expectedRepoPrefix := strings.Split(tt.repo, "/")[0]
270+
if !strings.HasPrefix(actualMappedImage, expectedRepoPrefix) {
271+
t.Errorf("mapped image %q should start with repository %q", actualMappedImage, expectedRepoPrefix)
272+
}
273+
}
274+
}
275+
})
276+
}
277+
}

0 commit comments

Comments
 (0)