1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package static
17
18 import (
19 "errors"
20 "io"
21 "strings"
22 "testing"
23
24 "github.com/google/go-cmp/cmp"
25 v1 "github.com/google/go-containerregistry/pkg/v1"
26 "github.com/google/go-containerregistry/pkg/v1/types"
27 )
28
29 func TestNewFile(t *testing.T) {
30 payload := "this is the content!"
31 f, err := NewFile([]byte(payload), WithLayerMediaType("foo"), WithAnnotations(map[string]string{"foo": "bar"}))
32 if err != nil {
33 t.Fatalf("NewFile() = %v", err)
34 }
35
36 timestampedFile, err := NewFile([]byte(payload), WithLayerMediaType("foo"), WithAnnotations(map[string]string{"foo": "bar"}), WithRecordCreationTimestamp(true))
37
38 if err != nil {
39 t.Fatalf("NewFile() = %v", err)
40 }
41
42 layers, err := f.Layers()
43 if err != nil {
44 t.Fatalf("Layers() = %v", err)
45 } else if got, want := len(layers), 1; got != want {
46 t.Fatalf("len(Layers()) = %d, wanted %d", got, want)
47 }
48 l := layers[0]
49
50 t.Run("check size", func(t *testing.T) {
51 wantSize := int64(len(payload))
52 gotSize, err := l.Size()
53 if err != nil {
54 t.Fatalf("Size() = %v", err)
55 }
56 if gotSize != wantSize {
57 t.Errorf("Size() = %d, wanted %d", gotSize, wantSize)
58 }
59 })
60
61 t.Run("check media type", func(t *testing.T) {
62 wantMT := types.MediaType("foo")
63 gotMT, err := f.FileMediaType()
64 if err != nil {
65 t.Fatalf("MediaType() = %v", err)
66 }
67 if gotMT != wantMT {
68 t.Errorf("MediaType() = %s, wanted %s", gotMT, wantMT)
69 }
70 })
71
72 t.Run("check hashes", func(t *testing.T) {
73 wantHash, _, err := v1.SHA256(strings.NewReader(payload))
74 if err != nil {
75 t.Fatalf("SHA256() = %v", err)
76 }
77
78 gotDigest, err := l.Digest()
79 if err != nil {
80 t.Fatalf("Digest() = %v", err)
81 }
82 if !cmp.Equal(gotDigest, wantHash) {
83 t.Errorf("Digest = %s", cmp.Diff(gotDigest, wantHash))
84 }
85
86 gotDiffID, err := l.DiffID()
87 if err != nil {
88 t.Fatalf("DiffID() = %v", err)
89 }
90 if !cmp.Equal(gotDiffID, wantHash) {
91 t.Errorf("DiffID = %s", cmp.Diff(gotDiffID, wantHash))
92 }
93 })
94
95 t.Run("check content", func(t *testing.T) {
96 comp, err := l.Compressed()
97 if err != nil {
98 t.Fatalf("Compressed() = %v", err)
99 }
100 defer comp.Close()
101 compContent, err := io.ReadAll(comp)
102 if err != nil {
103 t.Fatalf("ReadAll() = %v", err)
104 }
105 if got, want := string(compContent), payload; got != want {
106 t.Errorf("Compressed() = %s, wanted %s", got, want)
107 }
108
109 uncomp, err := l.Uncompressed()
110 if err != nil {
111 t.Fatalf("Uncompressed() = %v", err)
112 }
113 defer uncomp.Close()
114 uncompContent, err := io.ReadAll(uncomp)
115 if err != nil {
116 t.Fatalf("ReadAll() = %v", err)
117 }
118 if got, want := string(uncompContent), payload; got != want {
119 t.Errorf("Uncompressed() = %s, wanted %s", got, want)
120 }
121
122 gotPayload, err := f.Payload()
123 if err != nil {
124 t.Fatalf("Payload() = %v", err)
125 }
126 if got, want := string(gotPayload), payload; got != want {
127 t.Errorf("Payload() = %s, wanted %s", got, want)
128 }
129 })
130
131 t.Run("check date", func(t *testing.T) {
132 fileCfg, err := f.ConfigFile()
133 if err != nil {
134 t.Fatalf("ConfigFile() = %v", err)
135 }
136 if !fileCfg.Created.Time.IsZero() {
137 t.Errorf("Date of Signature was not Zero")
138 }
139 tsCfg, err := timestampedFile.ConfigFile()
140 if err != nil {
141 t.Fatalf("ConfigFile() = %v", err)
142 }
143 if tsCfg.Created.Time.IsZero() {
144 t.Errorf("Date of Signature was Zero")
145 }
146 })
147
148 t.Run("check annotations", func(t *testing.T) {
149 m, err := f.Manifest()
150 if err != nil {
151 t.Fatalf("Manifest() = %v", err)
152 }
153 gotAnnotations := m.Annotations
154 if got, want := gotAnnotations["foo"], "bar"; got != want {
155 t.Errorf("Annotations = %s, wanted %s", got, want)
156 }
157 })
158
159 t.Run("huge file payload", func(t *testing.T) {
160
161 f := file{
162 layer: &mockLayer{200000000},
163 }
164 want := errors.New("size of layer (200000000) exceeded the limit (134217728)")
165 _, err = f.Payload()
166 if err == nil || want.Error() != err.Error() {
167 t.Errorf("Payload() = %v, wanted %v", err, want)
168 }
169
170 t.Setenv("COSIGN_MAX_ATTACHMENT_SIZE", "512MiB")
171 _, err = f.Payload()
172 if err != nil {
173 t.Errorf("Payload() = %v, wanted nil", err)
174 }
175 })
176 }
177
178 type mockLayer struct {
179 size int64
180 }
181
182 func (m *mockLayer) Size() (int64, error) {
183 return m.size, nil
184 }
185
186 func (m *mockLayer) Uncompressed() (io.ReadCloser, error) {
187 return io.NopCloser(strings.NewReader("data")), nil
188 }
189
190 func (m *mockLayer) Digest() (v1.Hash, error) { panic("not implemented") }
191 func (m *mockLayer) DiffID() (v1.Hash, error) { panic("not implemented") }
192 func (m *mockLayer) Compressed() (io.ReadCloser, error) { panic("not implemented") }
193 func (m *mockLayer) MediaType() (types.MediaType, error) { panic("not implemented") }
194
View as plain text