1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package mutate_test
16
17 import (
18 "log"
19 "strings"
20 "testing"
21
22 "github.com/google/go-cmp/cmp"
23 v1 "github.com/google/go-containerregistry/pkg/v1"
24 "github.com/google/go-containerregistry/pkg/v1/empty"
25 "github.com/google/go-containerregistry/pkg/v1/mutate"
26 "github.com/google/go-containerregistry/pkg/v1/partial"
27 "github.com/google/go-containerregistry/pkg/v1/random"
28 "github.com/google/go-containerregistry/pkg/v1/types"
29 "github.com/google/go-containerregistry/pkg/v1/validate"
30 )
31
32 func TestAppendIndex(t *testing.T) {
33 base, err := random.Index(1024, 3, 3)
34 if err != nil {
35 t.Fatal(err)
36 }
37 idx, err := random.Index(2048, 1, 2)
38 if err != nil {
39 t.Fatal(err)
40 }
41 img, err := random.Image(4096, 5)
42 if err != nil {
43 t.Fatal(err)
44 }
45 l, err := random.Layer(1024, types.OCIUncompressedRestrictedLayer)
46 if err != nil {
47 t.Fatal(err)
48 }
49
50 weirdHash := v1.Hash{
51 Algorithm: "sha256",
52 Hex: strings.Repeat("0", 64),
53 }
54
55 add := mutate.AppendManifests(base, mutate.IndexAddendum{
56 Add: idx,
57 Descriptor: v1.Descriptor{
58 URLs: []string{"index.example.com"},
59 },
60 }, mutate.IndexAddendum{
61 Add: img,
62 Descriptor: v1.Descriptor{
63 URLs: []string{"image.example.com"},
64 },
65 }, mutate.IndexAddendum{
66 Add: l,
67 Descriptor: v1.Descriptor{
68 MediaType: types.MediaType("application/xml"),
69 URLs: []string{"blob.example.com"},
70 },
71 }, mutate.IndexAddendum{
72 Add: l,
73 Descriptor: v1.Descriptor{
74 URLs: []string{"layer.example.com"},
75 Size: 1337,
76 Digest: weirdHash,
77 Platform: &v1.Platform{
78 OS: "haiku",
79 Architecture: "toaster",
80 },
81 Annotations: map[string]string{"weird": "true"},
82 },
83 })
84
85 if err := validate.Index(add); err != nil {
86 t.Errorf("Validate() = %v", err)
87 }
88
89 got, err := add.MediaType()
90 if err != nil {
91 t.Fatal(err)
92 }
93 want, err := base.MediaType()
94 if err != nil {
95 t.Fatal(err)
96 }
97 if got != want {
98 t.Errorf("MediaType() = %s != %s", got, want)
99 }
100
101
102 m, err := add.IndexManifest()
103 if err != nil {
104 log.Fatal(err)
105 }
106
107 for i, want := range map[int]string{
108 3: "index.example.com",
109 4: "image.example.com",
110 5: "blob.example.com",
111 6: "layer.example.com",
112 } {
113 if got := m.Manifests[i].URLs[0]; got != want {
114 t.Errorf("wrong URLs[0] for Manifests[%d]: %s != %s", i, got, want)
115 }
116 }
117
118 if got, want := m.Manifests[5].MediaType, types.MediaType("application/xml"); got != want {
119 t.Errorf("wrong MediaType for layer: %s != %s", got, want)
120 }
121
122 if got, want := m.Manifests[6].MediaType, types.OCIUncompressedRestrictedLayer; got != want {
123 t.Errorf("wrong MediaType for layer: %s != %s", got, want)
124 }
125
126
127 add = mutate.AppendManifests(add, mutate.IndexAddendum{
128 Add: add,
129 })
130 if err := validate.Index(add); err != nil {
131 t.Errorf("Validate() = %v", err)
132 }
133
134
135 add = mutate.AppendManifests(empty.Index, mutate.IndexAddendum{
136 Add: add,
137 })
138 if err := validate.Index(add); err != nil {
139 t.Errorf("Validate() = %v", err)
140 }
141 }
142
143 func TestIndexImmutability(t *testing.T) {
144 base, err := random.Index(1024, 3, 3)
145 if err != nil {
146 t.Fatal(err)
147 }
148 ii, err := random.Index(2048, 1, 2)
149 if err != nil {
150 t.Fatal(err)
151 }
152 i, err := random.Image(4096, 5)
153 if err != nil {
154 t.Fatal(err)
155 }
156 idx := mutate.AppendManifests(base, mutate.IndexAddendum{
157 Add: ii,
158 Descriptor: v1.Descriptor{
159 URLs: []string{"index.example.com"},
160 },
161 }, mutate.IndexAddendum{
162 Add: i,
163 Descriptor: v1.Descriptor{
164 URLs: []string{"image.example.com"},
165 },
166 })
167
168 t.Run("index manifest", func(t *testing.T) {
169
170 changed, err := idx.IndexManifest()
171 if err != nil {
172 t.Errorf("IndexManifest() = %v", err)
173 }
174 want := changed.DeepCopy()
175 changed.MediaType = types.DockerManifestList
176
177 if got, err := idx.IndexManifest(); err != nil {
178 t.Errorf("IndexManifest() = %v", err)
179 } else if !cmp.Equal(got, want) {
180 t.Errorf("IndexManifest changed! %s", cmp.Diff(got, want))
181 }
182 })
183 }
184
185
186
187
188
189 func TestAppend_ArtifactType(t *testing.T) {
190 for _, c := range []struct {
191 desc, configMediaType, wantArtifactType string
192 }{{
193 desc: "standard config.mediaType, no artifactType",
194 configMediaType: string(types.DockerConfigJSON),
195 wantArtifactType: "",
196 }, {
197 desc: "non-standard config.mediaType, want artifactType",
198 configMediaType: "application/vnd.custom.something",
199 wantArtifactType: "application/vnd.custom.something",
200 }} {
201 t.Run(c.desc, func(t *testing.T) {
202 img, err := random.Image(1, 1)
203 if err != nil {
204 t.Fatalf("random.Image: %v", err)
205 }
206 img = mutate.ConfigMediaType(img, types.MediaType(c.configMediaType))
207 idx := mutate.AppendManifests(empty.Index, mutate.IndexAddendum{
208 Add: img,
209 })
210 mf, err := idx.IndexManifest()
211 if err != nil {
212 t.Fatalf("IndexManifest: %v", err)
213 }
214 if got := mf.Manifests[0].ArtifactType; got != c.wantArtifactType {
215 t.Errorf("manifest artifactType: got %q, want %q", got, c.wantArtifactType)
216 }
217
218 desc, err := partial.Descriptor(img)
219 if err != nil {
220 t.Fatalf("partial.Descriptor: %v", err)
221 }
222 if got := desc.ArtifactType; got != c.wantArtifactType {
223 t.Errorf("descriptor artifactType: got %q, want %q", got, c.wantArtifactType)
224 }
225
226 gotAT, err := partial.ArtifactType(img)
227 if err != nil {
228 t.Fatalf("partial.ArtifactType: %v", err)
229 }
230 if gotAT != c.wantArtifactType {
231 t.Errorf("partial.ArtifactType: got %q, want %q", gotAT, c.wantArtifactType)
232 }
233 })
234 }
235 }
236
View as plain text