1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package mutate_test
16
17 import (
18 "testing"
19 "time"
20
21 v1 "github.com/google/go-containerregistry/pkg/v1"
22 "github.com/google/go-containerregistry/pkg/v1/mutate"
23 "github.com/google/go-containerregistry/pkg/v1/random"
24 )
25
26 func layerDigests(t *testing.T, img v1.Image) []string {
27 layers, err := img.Layers()
28 if err != nil {
29 t.Fatalf("oldBase.Layers: %v", err)
30 }
31 layerDigests := make([]string, len(layers))
32 for i, l := range layers {
33 dig, err := l.Digest()
34 if err != nil {
35 t.Fatalf("layer.Digest %d: %v", i, err)
36 }
37 t.Log(dig)
38 layerDigests[i] = dig.String()
39 }
40 return layerDigests
41 }
42
43
44
45 func TestRebase(t *testing.T) {
46
47 const oldBaseLayerCount = 5
48 oldBase, err := random.Image(100, oldBaseLayerCount)
49 if err != nil {
50 t.Fatalf("random.Image (oldBase): %v", err)
51 }
52 t.Log("Old base:")
53 _ = layerDigests(t, oldBase)
54
55
56 top, err := random.Image(100, 1)
57 if err != nil {
58 t.Fatalf("random.Image (top): %v", err)
59 }
60 topLayers, err := top.Layers()
61 if err != nil {
62 t.Fatalf("top.Layers: %v", err)
63 }
64 orig, err := mutate.Append(oldBase,
65 mutate.Addendum{
66 Layer: nil,
67 History: v1.History{
68 Author: "me",
69 Created: v1.Time{Time: time.Now()},
70 CreatedBy: "test-empty",
71 Comment: "this is an empty test",
72 EmptyLayer: true,
73 },
74 },
75 mutate.Addendum{
76 Layer: topLayers[0],
77 History: v1.History{
78 Author: "me",
79 Created: v1.Time{Time: time.Now()},
80 CreatedBy: "test",
81 Comment: "this is a test",
82 },
83 },
84 )
85 if err != nil {
86 t.Fatalf("Append: %v", err)
87 }
88
89 t.Log("Original:")
90 origLayerDigests := layerDigests(t, orig)
91
92
93 newBase, err := random.Image(100, 3)
94 if err != nil {
95 t.Fatalf("random.Image (newBase): %v", err)
96 }
97 t.Log("New base:")
98 newBaseLayerDigests := layerDigests(t, newBase)
99
100
101 newBaseConfigFile, err := newBase.ConfigFile()
102 if err != nil {
103 t.Fatalf("newBase.ConfigFile: %v", err)
104 }
105 newBaseConfigFile.Architecture = "arm"
106 newBaseConfigFile.OS = "windows"
107 newBaseConfigFile.OSVersion = "10.0.17763.1339"
108
109 newBase, err = mutate.ConfigFile(newBase, newBaseConfigFile)
110 if err != nil {
111 t.Fatalf("ConfigFile (newBase): %v", err)
112 }
113
114
115 rebased, err := mutate.Rebase(orig, oldBase, newBase)
116 if err != nil {
117 t.Fatalf("Rebase: %v", err)
118 }
119
120 rebasedBaseLayers, err := rebased.Layers()
121 if err != nil {
122 t.Fatalf("rebased.Layers: %v", err)
123 }
124 rebasedLayerDigests := make([]string, len(rebasedBaseLayers))
125 t.Log("Rebased image layer digests:")
126 for i, l := range rebasedBaseLayers {
127 dig, err := l.Digest()
128 if err != nil {
129 t.Fatalf("layer.Digest (rebased base layer %d): %v", i, err)
130 }
131 t.Log(dig)
132 rebasedLayerDigests[i] = dig.String()
133 }
134
135
136 wantLayerDigests := append(newBaseLayerDigests, origLayerDigests[len(origLayerDigests)-1])
137 if len(rebasedLayerDigests) != len(wantLayerDigests) {
138 t.Fatalf("Rebased image contained %d layers, want %d", len(rebasedLayerDigests), len(wantLayerDigests))
139 }
140 for i, rl := range rebasedLayerDigests {
141 if got, want := rl, wantLayerDigests[i]; got != want {
142 t.Errorf("Layer %d mismatch, got %q, want %q", i, got, want)
143 }
144 }
145
146
147 origConfig, err := orig.ConfigFile()
148 if err != nil {
149 t.Fatalf("orig.ConfigFile: %v", err)
150 }
151 newBaseConfig, err := newBase.ConfigFile()
152 if err != nil {
153 t.Fatalf("newBase.ConfigFile: %v", err)
154 }
155 rebasedConfig, err := rebased.ConfigFile()
156 if err != nil {
157 t.Fatalf("rebased.ConfigFile: %v", err)
158 }
159 wantHistories := append(newBaseConfig.History, origConfig.History[oldBaseLayerCount:]...)
160 if len(wantHistories) != len(rebasedConfig.History) {
161 t.Fatalf("Rebased image contained %d history, want %d", len(rebasedConfig.History), len(wantHistories))
162 }
163 for i, rh := range rebasedConfig.History {
164 if got, want := rh.Comment, wantHistories[i].Comment; got != want {
165 t.Errorf("Layer %d mismatch, got %q, want %q", i, got, want)
166 }
167 }
168
169
170 if rebasedConfig.Architecture != newBaseConfig.Architecture {
171 t.Errorf("ConfigFile property Architecture mismatch, got %q, want %q", rebasedConfig.Architecture, newBaseConfig.Architecture)
172 }
173 if rebasedConfig.OS != newBaseConfig.OS {
174 t.Errorf("ConfigFile property OS mismatch, got %q, want %q", rebasedConfig.OS, newBaseConfig.OS)
175 }
176 if rebasedConfig.OSVersion != newBaseConfig.OSVersion {
177 t.Errorf("ConfigFile property OSVersion mismatch, got %q, want %q", rebasedConfig.OSVersion, newBaseConfig.OSVersion)
178 }
179 }
180
View as plain text